aboutsummaryrefslogtreecommitdiff
path: root/contrib/bind9/lib/dns
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bind9/lib/dns')
-rw-r--r--contrib/bind9/lib/dns/Makefile.in186
-rw-r--r--contrib/bind9/lib/dns/acache.c1800
-rw-r--r--contrib/bind9/lib/dns/acl.c633
-rw-r--r--contrib/bind9/lib/dns/adb.c4148
-rw-r--r--contrib/bind9/lib/dns/api9
-rw-r--r--contrib/bind9/lib/dns/byaddr.c318
-rw-r--r--contrib/bind9/lib/dns/cache.c1280
-rw-r--r--contrib/bind9/lib/dns/callbacks.c115
-rw-r--r--contrib/bind9/lib/dns/client.c3043
-rw-r--r--contrib/bind9/lib/dns/clientinfo.c38
-rw-r--r--contrib/bind9/lib/dns/compress.c341
-rw-r--r--contrib/bind9/lib/dns/db.c1027
-rw-r--r--contrib/bind9/lib/dns/dbiterator.c143
-rw-r--r--contrib/bind9/lib/dns/dbtable.c292
-rw-r--r--contrib/bind9/lib/dns/diff.c661
-rw-r--r--contrib/bind9/lib/dns/dispatch.c3859
-rw-r--r--contrib/bind9/lib/dns/dlz.c655
-rw-r--r--contrib/bind9/lib/dns/dns64.c301
-rw-r--r--contrib/bind9/lib/dns/dnssec.c1884
-rw-r--r--contrib/bind9/lib/dns/ds.c183
-rw-r--r--contrib/bind9/lib/dns/dst_api.c1862
-rw-r--r--contrib/bind9/lib/dns/dst_internal.h254
-rw-r--r--contrib/bind9/lib/dns/dst_lib.c67
-rw-r--r--contrib/bind9/lib/dns/dst_openssl.h60
-rw-r--r--contrib/bind9/lib/dns/dst_parse.c727
-rw-r--r--contrib/bind9/lib/dns/dst_parse.h142
-rw-r--r--contrib/bind9/lib/dns/dst_result.c89
-rw-r--r--contrib/bind9/lib/dns/ecdb.c827
-rw-r--r--contrib/bind9/lib/dns/forward.c215
-rw-r--r--contrib/bind9/lib/dns/gen-unix.h97
-rw-r--r--contrib/bind9/lib/dns/gen.c910
-rw-r--r--contrib/bind9/lib/dns/gssapi_link.c394
-rw-r--r--contrib/bind9/lib/dns/gssapictx.c872
-rw-r--r--contrib/bind9/lib/dns/hmac_link.c1734
-rw-r--r--contrib/bind9/lib/dns/include/Makefile.in25
-rw-r--r--contrib/bind9/lib/dns/include/dns/Makefile.in52
-rw-r--r--contrib/bind9/lib/dns/include/dns/acache.h448
-rw-r--r--contrib/bind9/lib/dns/include/dns/acl.h239
-rw-r--r--contrib/bind9/lib/dns/include/dns/adb.h634
-rw-r--r--contrib/bind9/lib/dns/include/dns/bit.h39
-rw-r--r--contrib/bind9/lib/dns/include/dns/byaddr.h171
-rw-r--r--contrib/bind9/lib/dns/include/dns/cache.h311
-rw-r--r--contrib/bind9/lib/dns/include/dns/callbacks.h95
-rw-r--r--contrib/bind9/lib/dns/include/dns/cert.h69
-rw-r--r--contrib/bind9/lib/dns/include/dns/client.h621
-rw-r--r--contrib/bind9/lib/dns/include/dns/clientinfo.h85
-rw-r--r--contrib/bind9/lib/dns/include/dns/compress.h269
-rw-r--r--contrib/bind9/lib/dns/include/dns/db.h1573
-rw-r--r--contrib/bind9/lib/dns/include/dns/dbiterator.h297
-rw-r--r--contrib/bind9/lib/dns/include/dns/dbtable.h165
-rw-r--r--contrib/bind9/lib/dns/include/dns/diff.h291
-rw-r--r--contrib/bind9/lib/dns/include/dns/dispatch.h563
-rw-r--r--contrib/bind9/lib/dns/include/dns/dlz.h346
-rw-r--r--contrib/bind9/lib/dns/include/dns/dlz_dlopen.h171
-rw-r--r--contrib/bind9/lib/dns/include/dns/dns64.h175
-rw-r--r--contrib/bind9/lib/dns/include/dns/dnssec.h350
-rw-r--r--contrib/bind9/lib/dns/include/dns/ds.h69
-rw-r--r--contrib/bind9/lib/dns/include/dns/ecdb.h54
-rw-r--r--contrib/bind9/lib/dns/include/dns/events.h86
-rw-r--r--contrib/bind9/lib/dns/include/dns/fixedname.h86
-rw-r--r--contrib/bind9/lib/dns/include/dns/forward.h133
-rw-r--r--contrib/bind9/lib/dns/include/dns/iptable.h72
-rw-r--r--contrib/bind9/lib/dns/include/dns/journal.h309
-rw-r--r--contrib/bind9/lib/dns/include/dns/keydata.h55
-rw-r--r--contrib/bind9/lib/dns/include/dns/keyflags.h54
-rw-r--r--contrib/bind9/lib/dns/include/dns/keytable.h457
-rw-r--r--contrib/bind9/lib/dns/include/dns/keyvalues.h112
-rw-r--r--contrib/bind9/lib/dns/include/dns/lib.h59
-rw-r--r--contrib/bind9/lib/dns/include/dns/log.h110
-rw-r--r--contrib/bind9/lib/dns/include/dns/lookup.h137
-rw-r--r--contrib/bind9/lib/dns/include/dns/master.h324
-rw-r--r--contrib/bind9/lib/dns/include/dns/masterdump.h372
-rw-r--r--contrib/bind9/lib/dns/include/dns/message.h1379
-rw-r--r--contrib/bind9/lib/dns/include/dns/name.h1364
-rw-r--r--contrib/bind9/lib/dns/include/dns/ncache.h191
-rw-r--r--contrib/bind9/lib/dns/include/dns/nsec.h116
-rw-r--r--contrib/bind9/lib/dns/include/dns/nsec3.h262
-rw-r--r--contrib/bind9/lib/dns/include/dns/opcode.h51
-rw-r--r--contrib/bind9/lib/dns/include/dns/order.h99
-rw-r--r--contrib/bind9/lib/dns/include/dns/peer.h219
-rw-r--r--contrib/bind9/lib/dns/include/dns/portlist.h101
-rw-r--r--contrib/bind9/lib/dns/include/dns/private.h72
-rw-r--r--contrib/bind9/lib/dns/include/dns/rbt.h942
-rw-r--r--contrib/bind9/lib/dns/include/dns/rcode.h113
-rw-r--r--contrib/bind9/lib/dns/include/dns/rdata.h774
-rw-r--r--contrib/bind9/lib/dns/include/dns/rdataclass.h81
-rw-r--r--contrib/bind9/lib/dns/include/dns/rdatalist.h124
-rw-r--r--contrib/bind9/lib/dns/include/dns/rdataset.h682
-rw-r--r--contrib/bind9/lib/dns/include/dns/rdatasetiter.h170
-rw-r--r--contrib/bind9/lib/dns/include/dns/rdataslab.h170
-rw-r--r--contrib/bind9/lib/dns/include/dns/rdatatype.h84
-rw-r--r--contrib/bind9/lib/dns/include/dns/request.h381
-rw-r--r--contrib/bind9/lib/dns/include/dns/resolver.h580
-rw-r--r--contrib/bind9/lib/dns/include/dns/result.h196
-rw-r--r--contrib/bind9/lib/dns/include/dns/rootns.h45
-rw-r--r--contrib/bind9/lib/dns/include/dns/rpz.h204
-rw-r--r--contrib/bind9/lib/dns/include/dns/rriterator.h187
-rw-r--r--contrib/bind9/lib/dns/include/dns/sdb.h219
-rw-r--r--contrib/bind9/lib/dns/include/dns/sdlz.h376
-rw-r--r--contrib/bind9/lib/dns/include/dns/secalg.h78
-rw-r--r--contrib/bind9/lib/dns/include/dns/secproto.h71
-rw-r--r--contrib/bind9/lib/dns/include/dns/soa.h103
-rw-r--r--contrib/bind9/lib/dns/include/dns/ssu.h212
-rw-r--r--contrib/bind9/lib/dns/include/dns/stats.h376
-rw-r--r--contrib/bind9/lib/dns/include/dns/tcpmsg.h147
-rw-r--r--contrib/bind9/lib/dns/include/dns/time.h78
-rw-r--r--contrib/bind9/lib/dns/include/dns/timer.h52
-rw-r--r--contrib/bind9/lib/dns/include/dns/tkey.h252
-rw-r--r--contrib/bind9/lib/dns/include/dns/tsec.h137
-rw-r--r--contrib/bind9/lib/dns/include/dns/tsig.h294
-rw-r--r--contrib/bind9/lib/dns/include/dns/ttl.h78
-rw-r--r--contrib/bind9/lib/dns/include/dns/types.h399
-rw-r--r--contrib/bind9/lib/dns/include/dns/update.h64
-rw-r--r--contrib/bind9/lib/dns/include/dns/validator.h261
-rw-r--r--contrib/bind9/lib/dns/include/dns/version.h28
-rw-r--r--contrib/bind9/lib/dns/include/dns/view.h1114
-rw-r--r--contrib/bind9/lib/dns/include/dns/xfrin.h111
-rw-r--r--contrib/bind9/lib/dns/include/dns/zone.h2104
-rw-r--r--contrib/bind9/lib/dns/include/dns/zonekey.h42
-rw-r--r--contrib/bind9/lib/dns/include/dns/zt.h215
-rw-r--r--contrib/bind9/lib/dns/include/dst/Makefile.in37
-rw-r--r--contrib/bind9/lib/dns/include/dst/dst.h929
-rw-r--r--contrib/bind9/lib/dns/include/dst/gssapi.h214
-rw-r--r--contrib/bind9/lib/dns/include/dst/lib.h41
-rw-r--r--contrib/bind9/lib/dns/include/dst/result.h73
-rw-r--r--contrib/bind9/lib/dns/iptable.c189
-rw-r--r--contrib/bind9/lib/dns/journal.c2337
-rw-r--r--contrib/bind9/lib/dns/key.c192
-rw-r--r--contrib/bind9/lib/dns/keydata.c89
-rw-r--r--contrib/bind9/lib/dns/keytable.c674
-rw-r--r--contrib/bind9/lib/dns/lib.c168
-rw-r--r--contrib/bind9/lib/dns/log.c101
-rw-r--r--contrib/bind9/lib/dns/lookup.c498
-rw-r--r--contrib/bind9/lib/dns/master.c3005
-rw-r--r--contrib/bind9/lib/dns/masterdump.c1912
-rw-r--r--contrib/bind9/lib/dns/message.c3552
-rw-r--r--contrib/bind9/lib/dns/name.c2506
-rw-r--r--contrib/bind9/lib/dns/ncache.c756
-rw-r--r--contrib/bind9/lib/dns/nsec.c451
-rw-r--r--contrib/bind9/lib/dns/nsec3.c2087
-rw-r--r--contrib/bind9/lib/dns/openssl_link.c392
-rw-r--r--contrib/bind9/lib/dns/openssldh_link.c678
-rw-r--r--contrib/bind9/lib/dns/openssldsa_link.c659
-rw-r--r--contrib/bind9/lib/dns/opensslecdsa_link.c607
-rw-r--r--contrib/bind9/lib/dns/opensslgost_link.c445
-rw-r--r--contrib/bind9/lib/dns/opensslrsa_link.c1491
-rw-r--r--contrib/bind9/lib/dns/order.c167
-rw-r--r--contrib/bind9/lib/dns/peer.c712
-rw-r--r--contrib/bind9/lib/dns/portlist.c266
-rw-r--r--contrib/bind9/lib/dns/private.c371
-rw-r--r--contrib/bind9/lib/dns/rbt.c2679
-rw-r--r--contrib/bind9/lib/dns/rbtdb.c9343
-rw-r--r--contrib/bind9/lib/dns/rbtdb.h57
-rw-r--r--contrib/bind9/lib/dns/rbtdb64.c23
-rw-r--r--contrib/bind9/lib/dns/rbtdb64.h45
-rw-r--r--contrib/bind9/lib/dns/rcode.c515
-rw-r--r--contrib/bind9/lib/dns/rdata.c2175
-rw-r--r--contrib/bind9/lib/dns/rdata/any_255/tsig_250.c603
-rw-r--r--contrib/bind9/lib/dns/rdata/any_255/tsig_250.h38
-rw-r--r--contrib/bind9/lib/dns/rdata/ch_3/a_1.c320
-rw-r--r--contrib/bind9/lib/dns/rdata/ch_3/a_1.h34
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/afsdb_18.c313
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/afsdb_18.h34
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/cert_37.c287
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/cert_37.h34
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/cname_5.c237
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/cname_5.h29
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/dlv_32769.c355
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/dlv_32769.h33
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/dname_39.c237
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/dname_39.h32
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/dnskey_48.c361
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/dnskey_48.h37
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/ds_43.c355
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/ds_43.h35
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/eui48_108.c215
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/eui48_108.h26
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/eui64_109.c220
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/eui64_109.h26
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/gpos_27.c257
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/gpos_27.h37
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/hinfo_13.c228
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/hinfo_13.h32
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/hip_55.c506
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/hip_55.h47
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/ipseckey_45.c501
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/ipseckey_45.h35
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/isdn_20.c239
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/isdn_20.h35
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/key_25.c348
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/key_25.h37
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/keydata_65533.c395
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/keydata_65533.h35
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/l32_105.c233
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/l32_105.h27
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/l64_106.c228
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/l64_106.h27
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/loc_29.c804
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/loc_29.h43
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/lp_107.c275
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/lp_107.h28
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/mb_7.c239
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/mb_7.h30
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/md_3.c241
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/md_3.h31
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/mf_4.c240
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/mf_4.h30
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/mg_8.c235
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/mg_8.h30
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/minfo_14.c329
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/minfo_14.h31
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/mr_9.c236
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/mr_9.h30
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/mx_15.c323
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/mx_15.h31
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/naptr_35.c671
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/naptr_35.h40
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/nid_104.c228
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/nid_104.h27
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/ns_2.c256
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/ns_2.h31
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/nsec3_50.c505
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/nsec3_50.h118
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/nsec3param_51.c319
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/nsec3param_51.h38
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/nsec_47.c396
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/nsec_47.h34
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/null_10.c193
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/null_10.h32
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/nxt_30.c333
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/nxt_30.h34
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/opt_41.c289
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/opt_41.h55
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/proforma.c190
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/proforma.h30
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/ptr_12.c295
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/ptr_12.h30
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/rp_17.c318
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/rp_17.h34
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/rrsig_46.c593
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/rrsig_46.h41
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/rt_21.c316
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/rt_21.h33
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/sig_24.c585
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/sig_24.h42
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/soa_6.c449
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/soa_6.h37
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/spf_99.c242
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/spf_99.h51
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/sshfp_44.c270
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/sshfp_44.h35
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/tkey_249.c565
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/tkey_249.h41
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/tlsa_52.c290
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/tlsa_52.h35
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/txt_16.c250
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/txt_16.h52
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/unspec_103.c194
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/unspec_103.h31
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/uri_256.c331
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/uri_256.h31
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/x25_19.c224
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/x25_19.h33
-rw-r--r--contrib/bind9/lib/dns/rdata/hs_4/a_1.c237
-rw-r--r--contrib/bind9/lib/dns/rdata/hs_4/a_1.h29
-rw-r--r--contrib/bind9/lib/dns/rdata/in_1/a6_38.c466
-rw-r--r--contrib/bind9/lib/dns/rdata/in_1/a6_38.h34
-rw-r--r--contrib/bind9/lib/dns/rdata/in_1/a_1.c241
-rw-r--r--contrib/bind9/lib/dns/rdata/in_1/a_1.h29
-rw-r--r--contrib/bind9/lib/dns/rdata/in_1/aaaa_28.c237
-rw-r--r--contrib/bind9/lib/dns/rdata/in_1/aaaa_28.h31
-rw-r--r--contrib/bind9/lib/dns/rdata/in_1/apl_42.c458
-rw-r--r--contrib/bind9/lib/dns/rdata/in_1/apl_42.h56
-rw-r--r--contrib/bind9/lib/dns/rdata/in_1/dhcid_49.c237
-rw-r--r--contrib/bind9/lib/dns/rdata/in_1/dhcid_49.h30
-rw-r--r--contrib/bind9/lib/dns/rdata/in_1/kx_36.c293
-rw-r--r--contrib/bind9/lib/dns/rdata/in_1/kx_36.h33
-rw-r--r--contrib/bind9/lib/dns/rdata/in_1/nsap-ptr_23.c250
-rw-r--r--contrib/bind9/lib/dns/rdata/in_1/nsap-ptr_23.h32
-rw-r--r--contrib/bind9/lib/dns/rdata/in_1/nsap_22.c259
-rw-r--r--contrib/bind9/lib/dns/rdata/in_1/nsap_22.h33
-rw-r--r--contrib/bind9/lib/dns/rdata/in_1/px_26.c379
-rw-r--r--contrib/bind9/lib/dns/rdata/in_1/px_26.h34
-rw-r--r--contrib/bind9/lib/dns/rdata/in_1/srv_33.c378
-rw-r--r--contrib/bind9/lib/dns/rdata/in_1/srv_33.h37
-rw-r--r--contrib/bind9/lib/dns/rdata/in_1/wks_11.c383
-rw-r--r--contrib/bind9/lib/dns/rdata/in_1/wks_11.h32
-rw-r--r--contrib/bind9/lib/dns/rdata/rdatastructpre.h42
-rw-r--r--contrib/bind9/lib/dns/rdata/rdatastructsuf.h22
-rw-r--r--contrib/bind9/lib/dns/rdatalist.c369
-rw-r--r--contrib/bind9/lib/dns/rdatalist_p.h64
-rw-r--r--contrib/bind9/lib/dns/rdataset.c802
-rw-r--r--contrib/bind9/lib/dns/rdatasetiter.c80
-rw-r--r--contrib/bind9/lib/dns/rdataslab.c1109
-rw-r--r--contrib/bind9/lib/dns/request.c1499
-rw-r--r--contrib/bind9/lib/dns/resolver.c9040
-rw-r--r--contrib/bind9/lib/dns/result.c284
-rw-r--r--contrib/bind9/lib/dns/rootns.c528
-rw-r--r--contrib/bind9/lib/dns/rpz.c1192
-rw-r--r--contrib/bind9/lib/dns/rriterator.c204
-rw-r--r--contrib/bind9/lib/dns/sdb.c1596
-rw-r--r--contrib/bind9/lib/dns/sdlz.c2103
-rw-r--r--contrib/bind9/lib/dns/soa.c147
-rw-r--r--contrib/bind9/lib/dns/spnego.asn152
-rw-r--r--contrib/bind9/lib/dns/spnego.c1820
-rw-r--r--contrib/bind9/lib/dns/spnego.h71
-rw-r--r--contrib/bind9/lib/dns/spnego_asn1.c867
-rwxr-xr-xcontrib/bind9/lib/dns/spnego_asn1.pl200
-rw-r--r--contrib/bind9/lib/dns/ssu.c613
-rw-r--r--contrib/bind9/lib/dns/ssu_external.c264
-rw-r--r--contrib/bind9/lib/dns/stats.c404
-rw-r--r--contrib/bind9/lib/dns/tcpmsg.c243
-rw-r--r--contrib/bind9/lib/dns/time.c203
-rw-r--r--contrib/bind9/lib/dns/timer.c60
-rw-r--r--contrib/bind9/lib/dns/tkey.c1460
-rw-r--r--contrib/bind9/lib/dns/tsec.c160
-rw-r--r--contrib/bind9/lib/dns/tsig.c1883
-rw-r--r--contrib/bind9/lib/dns/ttl.c217
-rw-r--r--contrib/bind9/lib/dns/update.c1865
-rw-r--r--contrib/bind9/lib/dns/validator.c3960
-rw-r--r--contrib/bind9/lib/dns/version.c28
-rw-r--r--contrib/bind9/lib/dns/view.c1845
-rw-r--r--contrib/bind9/lib/dns/xfrin.c1556
-rw-r--r--contrib/bind9/lib/dns/zone.c16753
-rw-r--r--contrib/bind9/lib/dns/zonekey.c55
-rw-r--r--contrib/bind9/lib/dns/zt.c539
326 files changed, 0 insertions, 172486 deletions
diff --git a/contrib/bind9/lib/dns/Makefile.in b/contrib/bind9/lib/dns/Makefile.in
deleted file mode 100644
index b712ab1cd874..000000000000
--- a/contrib/bind9/lib/dns/Makefile.in
+++ /dev/null
@@ -1,186 +0,0 @@
-# Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
-# Copyright (C) 1998-2003 Internet Software Consortium.
-#
-# Permission to use, copy, modify, and/or distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-# LOSS OF USE, DATA OR PROFITS, WHETHER IN 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.180 2011/10/11 00:09:03 each Exp $
-
-srcdir = @srcdir@
-VPATH = @srcdir@
-top_srcdir = @top_srcdir@
-
-# Attempt to disable parallel processing.
-.NOTPARALLEL:
-.NO_PARALLEL:
-
-@BIND9_VERSION@
-
-@LIBDNS_API@
-
-@BIND9_MAKE_INCLUDES@
-
-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_GSSAPI@ ${USE_ISC_SPNEGO}
-
-CWARNINGS =
-
-ISCLIBS = ../../lib/isc/libisc.@A@
-
-ISCDEPLIBS = ../../lib/isc/libisc.@A@
-
-LIBS = @LIBS@
-
-# Alphabetically
-
-OPENSSLGOSTLINKOBJS = opensslgost_link.@O@
-OPENSSLLINKOBJS = openssl_link.@O@ openssldh_link.@O@ openssldsa_link.@O@ \
- opensslecdsa_link.@O@ @OPENSSLGOSTLINKOBJS@ \
- opensslrsa_link.@O@
-
-DSTOBJS = @DST_EXTRA_OBJS@ @OPENSSLLINKOBJS@ \
- dst_api.@O@ dst_lib.@O@ dst_parse.@O@ dst_result.@O@ \
- gssapi_link.@O@ gssapictx.@O@ hmac_link.@O@ key.@O@
-
-# Alphabetically
-DNSOBJS = acache.@O@ acl.@O@ adb.@O@ byaddr.@O@ \
- cache.@O@ callbacks.@O@ clientinfo.@O@ compress.@O@ \
- db.@O@ dbiterator.@O@ dbtable.@O@ diff.@O@ dispatch.@O@ \
- dlz.@O@ dns64.@O@ dnssec.@O@ ds.@O@ forward.@O@ iptable.@O@ \
- journal.@O@ keydata.@O@ keytable.@O@ \
- 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@ 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@ 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@ \
- tsec.@O@ tsig.@O@ ttl.@O@ update.@O@ validator.@O@ \
- version.@O@ view.@O@ xfrin.@O@ zone.@O@ zonekey.@O@ zt.@O@
-
-OBJS= ${DNSOBJS} ${OTHEROBJS} ${DSTOBJS}
-
-# Alphabetically
-OPENSSLGOSTLINKSRCS = opensslgost_link.c
-OPENSSLLINKSRCS = openssl_link.c openssldh_link.c openssldsa_link.c \
- opensslecdsa_link.c @OPENSSLGOSTLINKSRCS@ opensslrsa_link.c
-
-DSTSRCS = @DST_EXTRA_SRCS@ @OPENSSLLINKSRCS@ \
- dst_api.c dst_lib.c dst_parse.c \
- dst_result.c gssapi_link.c gssapictx.c \
- hmac_link.c key.c
-
-DNSSRCS = acache.c acl.c adb.c byaddr.c \
- cache.c callbacks.c clientinfo.c compress.c \
- db.c dbiterator.c dbtable.c diff.c dispatch.c \
- dlz.c dns64.c dnssec.c ds.c forward.c iptable.c journal.c \
- keydata.c keytable.c lib.c log.c lookup.c \
- 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 \
- rdataset.c rdatasetiter.c rdataslab.c request.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 \
- tsec.c tsig.c ttl.c update.c validator.c \
- version.c view.c xfrin.c zone.c zonekey.c zt.c ${OTHERSRCS}
-
-SRCS = ${DSTSRCS} ${DNSSRCS}
-
-SUBDIRS = include
-TARGETS = include/dns/enumtype.h include/dns/enumclass.h \
- include/dns/rdatastruct.h timestamp
-TESTDIRS = @UNITTESTS@
-
-DEPENDEXTRA = ./gen -F include/dns/rdatastruct.h \
- -s ${srcdir} -d >> Makefile ;
-
-@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
-
-libdns.@SA@: ${OBJS}
- ${AR} ${ARFLAGS} $@ ${OBJS}
- ${RANLIB} $@
-
-libdns.la: ${OBJS}
- ${LIBTOOL_MODE_LINK} \
- ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libdns.la -rpath ${libdir} \
- -version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \
- ${OBJS} ${ISCLIBS} @DNS_CRYPTO_LIBS@ ${LIBS}
-
-timestamp: libdns.@A@
- touch timestamp
-
-installdirs:
- $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${libdir}
-
-install:: timestamp installdirs
- ${LIBTOOL_MODE_INSTALL} ${INSTALL_DATA} libdns.@A@ ${DESTDIR}${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: gen.c
- ${BUILD_CC} ${BUILD_CFLAGS} -I${top_srcdir}/lib/isc/include \
- ${BUILD_CPPFLAGS} ${BUILD_LDFLAGS} -o $@ ${srcdir}/gen.c ${BUILD_LIBS}
-
-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
-
-spnego.@O@: spnego_asn1.c spnego.h
diff --git a/contrib/bind9/lib/dns/acache.c b/contrib/bind9/lib/dns/acache.c
deleted file mode 100644
index 6df9b9838635..000000000000
--- a/contrib/bind9/lib/dns/acache.c
+++ /dev/null
@@ -1,1800 +0,0 @@
-/*
- * Copyright (C) 2004-2008, 2012, 2013 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: acache.c,v 1.22 2008/02/07 23:46:54 tbox Exp $ */
-
-#include <config.h>
-
-#include <isc/atomic.h>
-#include <isc/event.h>
-#include <isc/hash.h>
-#include <isc/magic.h>
-#include <isc/mem.h>
-#include <isc/mutex.h>
-#include <isc/random.h>
-#include <isc/refcount.h>
-#include <isc/rwlock.h>
-#include <isc/serial.h>
-#include <isc/task.h>
-#include <isc/time.h>
-#include <isc/timer.h>
-
-#include <dns/acache.h>
-#include <dns/db.h>
-#include <dns/events.h>
-#include <dns/log.h>
-#include <dns/message.h>
-#include <dns/name.h>
-#include <dns/rdataset.h>
-#include <dns/result.h>
-#include <dns/zone.h>
-
-#define ACACHE_MAGIC ISC_MAGIC('A', 'C', 'H', 'E')
-#define DNS_ACACHE_VALID(acache) ISC_MAGIC_VALID(acache, ACACHE_MAGIC)
-
-#define ACACHEENTRY_MAGIC ISC_MAGIC('A', 'C', 'E', 'T')
-#define DNS_ACACHEENTRY_VALID(entry) ISC_MAGIC_VALID(entry, ACACHEENTRY_MAGIC)
-
-#define DBBUCKETS 67
-
-#if 0
-#define ATRACE(m) isc_log_write(dns_lctx, \
- DNS_LOGCATEGORY_DATABASE, \
- DNS_LOGMODULE_ACACHE, \
- ISC_LOG_DEBUG(3), \
- "acache %p: %s", acache, (m))
-#define AATRACE(a,m) isc_log_write(dns_lctx, \
- DNS_LOGCATEGORY_DATABASE, \
- DNS_LOGMODULE_ACACHE, \
- ISC_LOG_DEBUG(3), \
- "acache %p: %s", (a), (m))
-#else
-#define ATRACE(m)
-#define AATRACE(a, m)
-#endif
-
-/*
- * The following variables control incremental cleaning.
- * MINSIZE is how many bytes is the floor for dns_acache_setcachesize().
- * CLEANERINCREMENT is how many entries are examined in one pass.
- * (XXX simply derived from definitions in cache.c There may be better
- * constants here.)
- */
-#define DNS_ACACHE_MINSIZE 2097152U /* Bytes. 2097152 = 2 MB */
-#define DNS_ACACHE_CLEANERINCREMENT 1000 /* Number of entries. */
-
-#define DEFAULT_ACACHE_ENTRY_LOCK_COUNT 1009 /*%< Should be prime. */
-
-#if defined(ISC_RWLOCK_USEATOMIC) && defined(ISC_PLATFORM_HAVEATOMICSTORE)
-#define ACACHE_USE_RWLOCK 1
-#endif
-
-#ifdef ACACHE_USE_RWLOCK
-#define ACACHE_INITLOCK(l) isc_rwlock_init((l), 0, 0)
-#define ACACHE_DESTROYLOCK(l) isc_rwlock_destroy(l)
-#define ACACHE_LOCK(l, t) RWLOCK((l), (t))
-#define ACACHE_UNLOCK(l, t) RWUNLOCK((l), (t))
-
-#define acache_storetime(entry, t) \
- (isc_atomic_store((isc_int32_t *)&(entry)->lastused, (t)))
-#else
-#define ACACHE_INITLOCK(l) isc_mutex_init(l)
-#define ACACHE_DESTROYLOCK(l) DESTROYLOCK(l)
-#define ACACHE_LOCK(l, t) LOCK(l)
-#define ACACHE_UNLOCK(l, t) UNLOCK(l)
-
-#define acache_storetime(entry, t) ((entry)->lastused = (t))
-#endif
-
-/* Locked by acache lock */
-typedef struct dbentry {
- ISC_LINK(struct dbentry) link;
-
- dns_db_t *db;
- ISC_LIST(dns_acacheentry_t) originlist;
- ISC_LIST(dns_acacheentry_t) referlist;
-} dbentry_t;
-
-typedef ISC_LIST(dbentry_t) dbentrylist_t;
-
-typedef struct acache_cleaner acache_cleaner_t;
-
-typedef enum {
- cleaner_s_idle, /* Waiting for cleaning-interval to expire. */
- cleaner_s_busy, /* Currently cleaning. */
- cleaner_s_done /* Freed enough memory after being overmem. */
-} cleaner_state_t;
-
-/*
- * Convenience macros for comprehensive assertion checking.
- */
-#define CLEANER_IDLE(c) ((c)->state == cleaner_s_idle && \
- (c)->resched_event != NULL)
-#define CLEANER_BUSY(c) ((c)->state == cleaner_s_busy && \
- (c)->resched_event == NULL)
-
-struct acache_cleaner {
- isc_mutex_t lock;
- /*
- * Locks overmem_event, overmem. (See cache.c)
- */
-
- dns_acache_t *acache;
- unsigned int cleaning_interval; /* The cleaning-interval
- from named.conf,
- in seconds. */
-
- isc_stdtime_t last_cleanup_time; /* The time when the last
- cleanup task completed */
-
- isc_timer_t *cleaning_timer;
- isc_event_t *resched_event; /* Sent by cleaner task to
- itself to reschedule */
- isc_event_t *overmem_event;
-
- dns_acacheentry_t *current_entry; /* The bookmark entry to
- restart the cleaning.
- Locked by acache lock. */
- int increment; /* Number of entries to
- clean in one increment */
-
- unsigned long ncleaned; /* Number of entries cleaned
- up (for logging purposes) */
- cleaner_state_t state; /* Idle/Busy/Done. */
- isc_boolean_t overmem; /* The acache is in an overmem
- state. */
-};
-
-struct dns_acachestats {
- unsigned int hits;
- unsigned int queries;
- unsigned int misses;
- unsigned int adds;
- unsigned int deleted;
- unsigned int cleaned;
- unsigned int cleaner_runs;
- unsigned int overmem;
- unsigned int overmem_nocreates;
- unsigned int nomem;
-};
-
-/*
- * The actual acache object.
- */
-
-struct dns_acache {
- unsigned int magic;
-
- isc_mem_t *mctx;
- isc_refcount_t refs;
-
-#ifdef ACACHE_USE_RWLOCK
- isc_rwlock_t *entrylocks;
-#else
- isc_mutex_t *entrylocks;
-#endif
-
- isc_mutex_t lock;
-
- int live_cleaners;
- acache_cleaner_t cleaner;
- ISC_LIST(dns_acacheentry_t) entries;
- unsigned int dbentries;
- dbentrylist_t dbbucket[DBBUCKETS];
-
- isc_boolean_t shutting_down;
-
- isc_task_t *task;
- isc_event_t cevent;
- isc_boolean_t cevent_sent;
-
- dns_acachestats_t stats;
-};
-
-struct dns_acacheentry {
- unsigned int magic;
-
- unsigned int locknum;
- isc_refcount_t references;
-
- dns_acache_t *acache;
-
- /* Data for Management of cache entries */
- ISC_LINK(dns_acacheentry_t) link;
- ISC_LINK(dns_acacheentry_t) olink;
- ISC_LINK(dns_acacheentry_t) rlink;
-
- dns_db_t *origdb; /* reference to the DB
- holding this entry */
-
- /* Cache data */
- dns_zone_t *zone; /* zone this entry
- belongs to */
- dns_db_t *db; /* DB this entry belongs to */
- dns_dbversion_t *version; /* the version of the DB */
- dns_dbnode_t *node; /* node this entry
- belongs to */
- dns_name_t *foundname; /* corresponding DNS name
- and rdataset */
-
- /* Callback function and its argument */
- void (*callback)(dns_acacheentry_t *, void **);
- void *cbarg;
-
- /* Timestamp of the last time this entry is referred to */
- isc_stdtime32_t lastused;
-};
-
-/*
- * Internal functions (and prototypes).
- */
-static inline isc_boolean_t check_noentry(dns_acache_t *acache);
-static void destroy(dns_acache_t *acache);
-static void shutdown_entries(dns_acache_t *acache);
-static void shutdown_buckets(dns_acache_t *acache);
-static void destroy_entry(dns_acacheentry_t *ent);
-static inline void unlink_dbentries(dns_acache_t *acache,
- dns_acacheentry_t *ent);
-static inline isc_result_t finddbent(dns_acache_t *acache,
- dns_db_t *db, dbentry_t **dbentryp);
-static inline void clear_entry(dns_acache_t *acache, dns_acacheentry_t *entry);
-static isc_result_t acache_cleaner_init(dns_acache_t *acache,
- isc_timermgr_t *timermgr,
- acache_cleaner_t *cleaner);
-static void acache_cleaning_timer_action(isc_task_t *task, isc_event_t *event);
-static void acache_incremental_cleaning_action(isc_task_t *task,
- isc_event_t *event);
-static void acache_overmem_cleaning_action(isc_task_t *task,
- isc_event_t *event);
-static void acache_cleaner_shutdown_action(isc_task_t *task,
- isc_event_t *event);
-
-/*
- * acache should be locked. If it is not, the stats can get out of whack,
- * which is not a big deal for us since this is for debugging / stats
- */
-static void
-reset_stats(dns_acache_t *acache) {
- acache->stats.hits = 0;
- acache->stats.queries = 0;
- acache->stats.misses = 0;
- acache->stats.adds = 0;
- acache->stats.deleted = 0;
- acache->stats.cleaned = 0;
- acache->stats.overmem = 0;
- acache->stats.overmem_nocreates = 0;
- acache->stats.nomem = 0;
-}
-
-/*
- * The acache must be locked before calling.
- */
-static inline isc_boolean_t
-check_noentry(dns_acache_t *acache) {
- if (ISC_LIST_EMPTY(acache->entries) && acache->dbentries == 0) {
- return (ISC_TRUE);
- }
-
- return (ISC_FALSE);
-}
-
-/*
- * The acache must be locked before calling.
- */
-static void
-shutdown_entries(dns_acache_t *acache) {
- dns_acacheentry_t *entry, *entry_next;
-
- REQUIRE(DNS_ACACHE_VALID(acache));
- INSIST(acache->shutting_down);
-
- /*
- * Release the dependency of all entries, and detach them.
- */
- for (entry = ISC_LIST_HEAD(acache->entries);
- entry != NULL;
- entry = entry_next) {
- entry_next = ISC_LIST_NEXT(entry, link);
-
- ACACHE_LOCK(&acache->entrylocks[entry->locknum],
- isc_rwlocktype_write);
-
- /*
- * If the cleaner holds this entry, it will be unlinked and
- * freed in the cleaner later.
- */
- if (acache->cleaner.current_entry != entry)
- ISC_LIST_UNLINK(acache->entries, entry, link);
- unlink_dbentries(acache, entry);
- if (entry->callback != NULL) {
- (entry->callback)(entry, &entry->cbarg);
- entry->callback = NULL;
- }
-
- ACACHE_UNLOCK(&acache->entrylocks[entry->locknum],
- isc_rwlocktype_write);
-
- if (acache->cleaner.current_entry != entry)
- dns_acache_detachentry(&entry);
- }
-}
-
-/*
- * The acache must be locked before calling.
- */
-static void
-shutdown_buckets(dns_acache_t *acache) {
- int i;
- dbentry_t *dbent;
-
- REQUIRE(DNS_ACACHE_VALID(acache));
- INSIST(acache->shutting_down);
-
- for (i = 0; i < DBBUCKETS; i++) {
- while ((dbent = ISC_LIST_HEAD(acache->dbbucket[i])) != NULL) {
- INSIST(ISC_LIST_EMPTY(dbent->originlist) &&
- ISC_LIST_EMPTY(dbent->referlist));
- ISC_LIST_UNLINK(acache->dbbucket[i], dbent, link);
-
- dns_db_detach(&dbent->db);
-
- isc_mem_put(acache->mctx, dbent, sizeof(*dbent));
-
- acache->dbentries--;
- }
- }
-
- INSIST(acache->dbentries == 0);
-}
-
-static void
-shutdown_task(isc_task_t *task, isc_event_t *ev) {
- dns_acache_t *acache;
-
- UNUSED(task);
-
- acache = ev->ev_arg;
- INSIST(DNS_ACACHE_VALID(acache));
-
- isc_event_free(&ev);
-
- LOCK(&acache->lock);
-
- shutdown_entries(acache);
- shutdown_buckets(acache);
-
- UNLOCK(&acache->lock);
-
- dns_acache_detach(&acache);
-}
-
-/* The acache and the entry must be locked before calling. */
-static inline void
-unlink_dbentries(dns_acache_t *acache, dns_acacheentry_t *ent) {
- isc_result_t result;
- dbentry_t *dbent;
-
- if (ISC_LINK_LINKED(ent, olink)) {
- INSIST(ent->origdb != NULL);
- dbent = NULL;
- result = finddbent(acache, ent->origdb, &dbent);
- INSIST(result == ISC_R_SUCCESS);
-
- ISC_LIST_UNLINK(dbent->originlist, ent, olink);
- }
- if (ISC_LINK_LINKED(ent, rlink)) {
- INSIST(ent->db != NULL);
- dbent = NULL;
- result = finddbent(acache, ent->db, &dbent);
- INSIST(result == ISC_R_SUCCESS);
-
- ISC_LIST_UNLINK(dbent->referlist, ent, rlink);
- }
-}
-
-/* There must not be a reference to this entry. */
-static void
-destroy_entry(dns_acacheentry_t *entry) {
- dns_acache_t *acache;
-
- REQUIRE(DNS_ACACHEENTRY_VALID(entry));
-
- acache = entry->acache;
- REQUIRE(DNS_ACACHE_VALID(acache));
-
- /*
- * Since there is no reference to this entry, it is safe to call
- * clear_entry() here.
- */
- clear_entry(acache, entry);
-
- isc_mem_put(acache->mctx, entry, sizeof(*entry));
-
- dns_acache_detach(&acache);
-}
-
-static void
-destroy(dns_acache_t *acache) {
- int i;
-
- REQUIRE(DNS_ACACHE_VALID(acache));
-
- ATRACE("destroy");
-
- isc_mem_setwater(acache->mctx, NULL, NULL, 0, 0);
-
- if (acache->cleaner.overmem_event != NULL)
- isc_event_free(&acache->cleaner.overmem_event);
-
- if (acache->cleaner.resched_event != NULL)
- isc_event_free(&acache->cleaner.resched_event);
-
- if (acache->task != NULL)
- isc_task_detach(&acache->task);
-
- for (i = 0; i < DEFAULT_ACACHE_ENTRY_LOCK_COUNT; i++)
- ACACHE_DESTROYLOCK(&acache->entrylocks[i]);
- isc_mem_put(acache->mctx, acache->entrylocks,
- sizeof(*acache->entrylocks) *
- DEFAULT_ACACHE_ENTRY_LOCK_COUNT);
-
- DESTROYLOCK(&acache->cleaner.lock);
-
- DESTROYLOCK(&acache->lock);
- acache->magic = 0;
-
- isc_mem_putanddetach(&acache->mctx, acache, sizeof(*acache));
-}
-
-static inline isc_result_t
-finddbent(dns_acache_t *acache, dns_db_t *db, dbentry_t **dbentryp) {
- int bucket;
- dbentry_t *dbentry;
-
- REQUIRE(DNS_ACACHE_VALID(acache));
- REQUIRE(db != NULL);
- REQUIRE(dbentryp != NULL && *dbentryp == NULL);
-
- /*
- * The caller must be holding the acache lock.
- */
-
- bucket = isc_hash_calc((const unsigned char *)&db,
- sizeof(db), ISC_TRUE) % DBBUCKETS;
-
- for (dbentry = ISC_LIST_HEAD(acache->dbbucket[bucket]);
- dbentry != NULL;
- dbentry = ISC_LIST_NEXT(dbentry, link)) {
- if (dbentry->db == db)
- break;
- }
-
- *dbentryp = dbentry;
-
- if (dbentry == NULL)
- return (ISC_R_NOTFOUND);
- else
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-clear_entry(dns_acache_t *acache, dns_acacheentry_t *entry) {
- REQUIRE(DNS_ACACHE_VALID(acache));
- REQUIRE(DNS_ACACHEENTRY_VALID(entry));
-
- /*
- * The caller must be holing the entry lock.
- */
-
- if (entry->foundname) {
- dns_rdataset_t *rdataset, *rdataset_next;
-
- for (rdataset = ISC_LIST_HEAD(entry->foundname->list);
- rdataset != NULL;
- rdataset = rdataset_next) {
- rdataset_next = ISC_LIST_NEXT(rdataset, link);
- ISC_LIST_UNLINK(entry->foundname->list,
- rdataset, link);
- dns_rdataset_disassociate(rdataset);
- isc_mem_put(acache->mctx, rdataset, sizeof(*rdataset));
- }
- if (dns_name_dynamic(entry->foundname))
- dns_name_free(entry->foundname, acache->mctx);
- isc_mem_put(acache->mctx, entry->foundname,
- sizeof(*entry->foundname));
- entry->foundname = NULL;
- }
-
- if (entry->node != NULL) {
- INSIST(entry->db != NULL);
- dns_db_detachnode(entry->db, &entry->node);
- }
- if (entry->version != NULL) {
- INSIST(entry->db != NULL);
- dns_db_closeversion(entry->db, &entry->version, ISC_FALSE);
- }
- if (entry->db != NULL)
- dns_db_detach(&entry->db);
- if (entry->zone != NULL)
- dns_zone_detach(&entry->zone);
-
- if (entry->origdb != NULL)
- dns_db_detach(&entry->origdb);
-}
-
-static isc_result_t
-acache_cleaner_init(dns_acache_t *acache, isc_timermgr_t *timermgr,
- acache_cleaner_t *cleaner)
-{
- int result;
-
- ATRACE("acache cleaner init");
-
- result = isc_mutex_init(&cleaner->lock);
- if (result != ISC_R_SUCCESS)
- goto fail;
-
- cleaner->increment = DNS_ACACHE_CLEANERINCREMENT;
- cleaner->state = cleaner_s_idle;
- cleaner->acache = acache;
- cleaner->overmem = ISC_FALSE;
-
- cleaner->cleaning_timer = NULL;
- cleaner->resched_event = NULL;
- cleaner->overmem_event = NULL;
- cleaner->current_entry = NULL;
-
- if (timermgr != NULL) {
- cleaner->acache->live_cleaners++;
-
- result = isc_task_onshutdown(acache->task,
- acache_cleaner_shutdown_action,
- acache);
- if (result != ISC_R_SUCCESS) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "acache cleaner: "
- "isc_task_onshutdown() failed: %s",
- dns_result_totext(result));
- goto cleanup;
- }
-
- cleaner->cleaning_interval = 0; /* Initially turned off. */
- isc_stdtime_get(&cleaner->last_cleanup_time);
- result = isc_timer_create(timermgr, isc_timertype_inactive,
- NULL, NULL,
- acache->task,
- acache_cleaning_timer_action,
- cleaner, &cleaner->cleaning_timer);
- if (result != ISC_R_SUCCESS) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_timer_create() failed: %s",
- dns_result_totext(result));
- result = ISC_R_UNEXPECTED;
- goto cleanup;
- }
-
- cleaner->resched_event =
- isc_event_allocate(acache->mctx, cleaner,
- DNS_EVENT_ACACHECLEAN,
- acache_incremental_cleaning_action,
- cleaner, sizeof(isc_event_t));
- if (cleaner->resched_event == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup;
- }
-
- cleaner->overmem_event =
- isc_event_allocate(acache->mctx, cleaner,
- DNS_EVENT_ACACHEOVERMEM,
- acache_overmem_cleaning_action,
- cleaner, sizeof(isc_event_t));
- if (cleaner->overmem_event == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup;
- }
- }
-
- return (ISC_R_SUCCESS);
-
- cleanup:
- if (cleaner->overmem_event != NULL)
- isc_event_free(&cleaner->overmem_event);
- if (cleaner->resched_event != NULL)
- isc_event_free(&cleaner->resched_event);
- if (cleaner->cleaning_timer != NULL)
- isc_timer_detach(&cleaner->cleaning_timer);
- cleaner->acache->live_cleaners--;
- DESTROYLOCK(&cleaner->lock);
- fail:
- return (result);
-}
-
-static void
-begin_cleaning(acache_cleaner_t *cleaner) {
- dns_acacheentry_t *head;
- dns_acache_t *acache = cleaner->acache;
-
- /*
- * This function does not have to lock the cleaner, since critical
- * parameters (except current_entry, which is locked by acache lock,)
- * are only used in a single task context.
- */
-
- REQUIRE(CLEANER_IDLE(cleaner));
- INSIST(DNS_ACACHE_VALID(acache));
- INSIST(cleaner->current_entry == NULL);
-
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_ACACHE, ISC_LOG_DEBUG(1),
- "begin acache cleaning, mem inuse %lu",
- (unsigned long)isc_mem_inuse(cleaner->acache->mctx));
-
- LOCK(&acache->lock);
-
- head = ISC_LIST_HEAD(acache->entries);
- if (head != NULL)
- dns_acache_attachentry(head, &cleaner->current_entry);
-
- UNLOCK(&acache->lock);
-
- if (cleaner->current_entry != NULL) {
- cleaner->ncleaned = 0;
- cleaner->state = cleaner_s_busy;
- isc_task_send(acache->task, &cleaner->resched_event);
- }
-
- return;
-}
-
-static void
-end_cleaning(acache_cleaner_t *cleaner, isc_event_t *event) {
- dns_acache_t *acache = cleaner->acache;
-
- REQUIRE(CLEANER_BUSY(cleaner));
- REQUIRE(event != NULL);
- REQUIRE(DNS_ACACHEENTRY_VALID(cleaner->current_entry));
-
- /* No need to lock the cleaner (see begin_cleaning()). */
-
- LOCK(&acache->lock);
-
- /*
- * Even if the cleaner has the last reference to the entry, which means
- * the entry has been unused, it may still be linked if unlinking the
- * entry has been delayed due to the reference.
- */
- if (isc_refcount_current(&cleaner->current_entry->references) == 1) {
- INSIST(cleaner->current_entry->callback == NULL);
-
- if (ISC_LINK_LINKED(cleaner->current_entry, link)) {
- ISC_LIST_UNLINK(acache->entries,
- cleaner->current_entry, link);
- }
- }
- dns_acache_detachentry(&cleaner->current_entry);
-
- if (cleaner->overmem)
- acache->stats.overmem++;
- acache->stats.cleaned += cleaner->ncleaned;
- acache->stats.cleaner_runs++;
-
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ACACHE,
- ISC_LOG_NOTICE,
- "acache %p stats: hits=%d misses=%d queries=%d "
- "adds=%d deleted=%d "
- "cleaned=%d cleaner_runs=%d overmem=%d "
- "overmem_nocreates=%d nomem=%d",
- acache,
- acache->stats.hits, acache->stats.misses,
- acache->stats.queries,
- acache->stats.adds, acache->stats.deleted,
- acache->stats.cleaned, acache->stats.cleaner_runs,
- acache->stats.overmem, acache->stats.overmem_nocreates,
- acache->stats.nomem);
- reset_stats(acache);
-
- isc_stdtime_get(&cleaner->last_cleanup_time);
-
- UNLOCK(&acache->lock);
-
- dns_acache_setcleaninginterval(cleaner->acache,
- cleaner->cleaning_interval);
-
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ACACHE,
- ISC_LOG_DEBUG(1), "end acache cleaning, "
- "%lu entries cleaned, mem inuse %lu",
- cleaner->ncleaned,
- (unsigned long)isc_mem_inuse(cleaner->acache->mctx));
-
- if (cleaner->overmem) {
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_ACACHE, ISC_LOG_NOTICE,
- "acache is still in overmem state "
- "after cleaning");
- }
-
- cleaner->ncleaned = 0;
- cleaner->state = cleaner_s_idle;
- cleaner->resched_event = event;
-}
-
-/*
- * This is run once for every acache-cleaning-interval as defined
- * in named.conf.
- */
-static void
-acache_cleaning_timer_action(isc_task_t *task, isc_event_t *event) {
- acache_cleaner_t *cleaner = event->ev_arg;
-
- UNUSED(task);
-
- INSIST(event->ev_type == ISC_TIMEREVENT_TICK);
-
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ACACHE,
- ISC_LOG_DEBUG(1), "acache cleaning timer fired, "
- "cleaner state = %d", cleaner->state);
-
- if (cleaner->state == cleaner_s_idle)
- begin_cleaning(cleaner);
-
- isc_event_free(&event);
-}
-
-/* The caller must hold entry lock. */
-static inline isc_boolean_t
-entry_stale(acache_cleaner_t *cleaner, dns_acacheentry_t *entry,
- isc_stdtime32_t now32, unsigned int interval)
-{
- /*
- * If the callback has been canceled, we definitely do not need the
- * entry.
- */
- if (entry->callback == NULL)
- return (ISC_TRUE);
-
- if (interval > cleaner->cleaning_interval)
- interval = cleaner->cleaning_interval;
-
- if (entry->lastused + interval < now32)
- return (ISC_TRUE);
-
- /*
- * If the acache is in the overmem state, probabilistically decide if
- * the entry should be purged, based on the time passed from its last
- * use and the cleaning interval.
- */
- if (cleaner->overmem) {
- unsigned int passed;
- isc_uint32_t val;
-
- if (isc_serial_ge(now32, entry->lastused))
- passed = now32 - entry->lastused; /* <= interval */
- else
- passed = 0;
-
- if (passed > interval / 2)
- return (ISC_TRUE);
- isc_random_get(&val);
- if (passed > interval / 4)
- return (ISC_TF(val % 4 == 0));
- return (ISC_TF(val % 8 == 0));
- }
-
- return (ISC_FALSE);
-}
-
-/*
- * Do incremental cleaning.
- */
-static void
-acache_incremental_cleaning_action(isc_task_t *task, isc_event_t *event) {
- acache_cleaner_t *cleaner = event->ev_arg;
- dns_acache_t *acache = cleaner->acache;
- dns_acacheentry_t *entry, *next = NULL;
- int n_entries;
- isc_stdtime32_t now32, last32;
- isc_stdtime_t now;
- unsigned int interval;
-
- INSIST(DNS_ACACHE_VALID(acache));
- INSIST(task == acache->task);
- INSIST(event->ev_type == DNS_EVENT_ACACHECLEAN);
-
- if (cleaner->state == cleaner_s_done) {
- cleaner->state = cleaner_s_busy;
- end_cleaning(cleaner, event);
- return;
- }
-
- INSIST(CLEANER_BUSY(cleaner));
-
- n_entries = cleaner->increment;
-
- isc_stdtime_get(&now);
- isc_stdtime_convert32(now, &now32);
-
- LOCK(&acache->lock);
-
- entry = cleaner->current_entry;
- isc_stdtime_convert32(cleaner->last_cleanup_time, &last32);
- if (isc_serial_ge(now32, last32))
- interval = now32 - last32;
- else
- interval = 0;
-
- while (n_entries-- > 0) {
- isc_boolean_t is_stale = ISC_FALSE;
-
- INSIST(entry != NULL);
-
- next = ISC_LIST_NEXT(entry, link);
-
- ACACHE_LOCK(&acache->entrylocks[entry->locknum],
- isc_rwlocktype_write);
-
- is_stale = entry_stale(cleaner, entry, now32, interval);
- if (is_stale) {
- ISC_LIST_UNLINK(acache->entries, entry, link);
- unlink_dbentries(acache, entry);
- if (entry->callback != NULL)
- (entry->callback)(entry, &entry->cbarg);
- entry->callback = NULL;
-
- cleaner->ncleaned++;
- }
-
- ACACHE_UNLOCK(&acache->entrylocks[entry->locknum],
- isc_rwlocktype_write);
-
- if (is_stale)
- dns_acache_detachentry(&entry);
-
- if (next == NULL) {
- if (cleaner->overmem) {
- entry = ISC_LIST_HEAD(acache->entries);
- if (entry != NULL) {
- /*
- * If we are still in the overmem
- * state, keep cleaning. In case we
- * exit from the loop immediately after
- * this, reset next to the head entry
- * as we'll expect it will be never
- * NULL.
- */
- isc_log_write(dns_lctx,
- DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_ACACHE,
- ISC_LOG_DEBUG(1),
- "acache cleaner: "
- "still overmem, "
- "reset and try again");
- next = entry;
- continue;
- }
- }
-
- UNLOCK(&acache->lock);
- end_cleaning(cleaner, event);
- return;
- }
-
- entry = next;
- }
-
- /*
- * We have successfully performed a cleaning increment but have
- * not gone through the entire cache. Remember the entry that will
- * be the starting point in the next clean-up, and reschedule another
- * batch. If it fails, just try to continue anyway.
- */
- INSIST(next != NULL);
- dns_acache_detachentry(&cleaner->current_entry);
- dns_acache_attachentry(next, &cleaner->current_entry);
-
- UNLOCK(&acache->lock);
-
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ACACHE,
- ISC_LOG_DEBUG(1), "acache cleaner: checked %d entries, "
- "mem inuse %lu, sleeping", cleaner->increment,
- (unsigned long)isc_mem_inuse(cleaner->acache->mctx));
-
- isc_task_send(task, &event);
- INSIST(CLEANER_BUSY(cleaner));
-
- return;
-}
-
-/*
- * This is called when the acache either surpasses its upper limit
- * or shrinks beyond its lower limit.
- */
-static void
-acache_overmem_cleaning_action(isc_task_t *task, isc_event_t *event) {
- acache_cleaner_t *cleaner = event->ev_arg;
- isc_boolean_t want_cleaning = ISC_FALSE;
-
- UNUSED(task);
-
- INSIST(event->ev_type == DNS_EVENT_ACACHEOVERMEM);
- INSIST(cleaner->overmem_event == NULL);
-
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ACACHE,
- ISC_LOG_DEBUG(1), "overmem_cleaning_action called, "
- "overmem = %d, state = %d", cleaner->overmem,
- cleaner->state);
-
- LOCK(&cleaner->lock);
-
- if (cleaner->overmem) {
- if (cleaner->state == cleaner_s_idle)
- want_cleaning = ISC_TRUE;
- } else {
- if (cleaner->state == cleaner_s_busy)
- /*
- * end_cleaning() can't be called here because
- * then both cleaner->overmem_event and
- * cleaner->resched_event will point to this
- * event. Set the state to done, and then
- * when the acache_incremental_cleaning_action() event
- * is posted, it will handle the end_cleaning.
- */
- cleaner->state = cleaner_s_done;
- }
-
- cleaner->overmem_event = event;
-
- UNLOCK(&cleaner->lock);
-
- if (want_cleaning)
- begin_cleaning(cleaner);
-}
-
-static void
-water(void *arg, int mark) {
- dns_acache_t *acache = arg;
- isc_boolean_t overmem = ISC_TF(mark == ISC_MEM_HIWATER);
-
- REQUIRE(DNS_ACACHE_VALID(acache));
-
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_ACACHE, ISC_LOG_DEBUG(1),
- "acache memory reaches %s watermark, mem inuse %lu",
- overmem ? "high" : "low",
- (unsigned long)isc_mem_inuse(acache->mctx));
-
- LOCK(&acache->cleaner.lock);
-
- if (acache->cleaner.overmem != overmem) {
- acache->cleaner.overmem = overmem;
-
- if (acache->cleaner.overmem_event != NULL)
- isc_task_send(acache->task,
- &acache->cleaner.overmem_event);
- isc_mem_waterack(acache->mctx, mark);
- }
-
- UNLOCK(&acache->cleaner.lock);
-}
-
-/*
- * The cleaner task is shutting down; do the necessary cleanup.
- */
-static void
-acache_cleaner_shutdown_action(isc_task_t *task, isc_event_t *event) {
- dns_acache_t *acache = event->ev_arg;
- isc_boolean_t should_free = ISC_FALSE;
-
- INSIST(task == acache->task);
- INSIST(event->ev_type == ISC_TASKEVENT_SHUTDOWN);
- INSIST(DNS_ACACHE_VALID(acache));
-
- ATRACE("acache cleaner shutdown");
-
- if (CLEANER_BUSY(&acache->cleaner))
- end_cleaning(&acache->cleaner, event);
- else
- isc_event_free(&event);
-
- LOCK(&acache->lock);
-
- acache->live_cleaners--;
- INSIST(acache->live_cleaners == 0);
-
- if (isc_refcount_current(&acache->refs) == 0) {
- INSIST(check_noentry(acache) == ISC_TRUE);
- should_free = ISC_TRUE;
- }
-
- /*
- * By detaching the timer in the context of its task,
- * we are guaranteed that there will be no further timer
- * events.
- */
- if (acache->cleaner.cleaning_timer != NULL)
- isc_timer_detach(&acache->cleaner.cleaning_timer);
-
- /* Make sure we don't reschedule anymore. */
- (void)isc_task_purge(task, NULL, DNS_EVENT_ACACHECLEAN, NULL);
-
- UNLOCK(&acache->lock);
-
- if (should_free)
- destroy(acache);
-}
-
-/*
- * Public functions.
- */
-
-isc_result_t
-dns_acache_create(dns_acache_t **acachep, isc_mem_t *mctx,
- isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr)
-{
- int i;
- isc_result_t result;
- dns_acache_t *acache;
-
- REQUIRE(acachep != NULL && *acachep == NULL);
- REQUIRE(mctx != NULL);
- REQUIRE(taskmgr != NULL);
-
- acache = isc_mem_get(mctx, sizeof(*acache));
- if (acache == NULL)
- return (ISC_R_NOMEMORY);
-
- ATRACE("create");
-
- result = isc_refcount_init(&acache->refs, 1);
- if (result != ISC_R_SUCCESS) {
- isc_mem_put(mctx, acache, sizeof(*acache));
- return (result);
- }
-
- result = isc_mutex_init(&acache->lock);
- if (result != ISC_R_SUCCESS) {
- isc_refcount_decrement(&acache->refs, NULL);
- isc_refcount_destroy(&acache->refs);
- isc_mem_put(mctx, acache, sizeof(*acache));
- return (result);
- }
-
- acache->mctx = NULL;
- isc_mem_attach(mctx, &acache->mctx);
- ISC_LIST_INIT(acache->entries);
-
- acache->shutting_down = ISC_FALSE;
-
- acache->task = NULL;
- acache->entrylocks = NULL;
-
- result = isc_task_create(taskmgr, 1, &acache->task);
- if (result != ISC_R_SUCCESS) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_task_create() failed(): %s",
- dns_result_totext(result));
- result = ISC_R_UNEXPECTED;
- goto cleanup;
- }
- isc_task_setname(acache->task, "acachetask", acache);
- ISC_EVENT_INIT(&acache->cevent, sizeof(acache->cevent), 0, NULL,
- DNS_EVENT_ACACHECONTROL, shutdown_task, NULL,
- NULL, NULL, NULL);
- acache->cevent_sent = ISC_FALSE;
-
- acache->dbentries = 0;
- for (i = 0; i < DBBUCKETS; i++)
- ISC_LIST_INIT(acache->dbbucket[i]);
-
- acache->entrylocks = isc_mem_get(mctx, sizeof(*acache->entrylocks) *
- DEFAULT_ACACHE_ENTRY_LOCK_COUNT);
- if (acache->entrylocks == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup;
- }
- for (i = 0; i < DEFAULT_ACACHE_ENTRY_LOCK_COUNT; i++) {
- result = ACACHE_INITLOCK(&acache->entrylocks[i]);
- if (result != ISC_R_SUCCESS) {
- while (i-- > 0)
- ACACHE_DESTROYLOCK(&acache->entrylocks[i]);
- isc_mem_put(mctx, acache->entrylocks,
- sizeof(*acache->entrylocks) *
- DEFAULT_ACACHE_ENTRY_LOCK_COUNT);
- acache->entrylocks = NULL;
- goto cleanup;
- }
- }
-
- acache->live_cleaners = 0;
- result = acache_cleaner_init(acache, timermgr, &acache->cleaner);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- acache->stats.cleaner_runs = 0;
- reset_stats(acache);
-
- acache->magic = ACACHE_MAGIC;
-
- *acachep = acache;
- return (ISC_R_SUCCESS);
-
- cleanup:
- if (acache->task != NULL)
- isc_task_detach(&acache->task);
- DESTROYLOCK(&acache->lock);
- isc_refcount_decrement(&acache->refs, NULL);
- isc_refcount_destroy(&acache->refs);
- if (acache->entrylocks != NULL) {
- for (i = 0; i < DEFAULT_ACACHE_ENTRY_LOCK_COUNT; i++)
- ACACHE_DESTROYLOCK(&acache->entrylocks[i]);
- isc_mem_put(mctx, acache->entrylocks,
- sizeof(*acache->entrylocks) *
- DEFAULT_ACACHE_ENTRY_LOCK_COUNT);
- }
- isc_mem_put(mctx, acache, sizeof(*acache));
- isc_mem_detach(&mctx);
-
- return (result);
-}
-
-void
-dns_acache_attach(dns_acache_t *source, dns_acache_t **targetp) {
- REQUIRE(DNS_ACACHE_VALID(source));
- REQUIRE(targetp != NULL && *targetp == NULL);
-
- AATRACE(source, "attach");
-
- isc_refcount_increment(&source->refs, NULL);
-
- *targetp = source;
-}
-
-void
-dns_acache_countquerymiss(dns_acache_t *acache) {
- acache->stats.misses++; /* XXXSK danger: unlocked! */
- acache->stats.queries++; /* XXXSK danger: unlocked! */
-}
-
-void
-dns_acache_detach(dns_acache_t **acachep) {
- dns_acache_t *acache;
- unsigned int refs;
- isc_boolean_t should_free = ISC_FALSE;
-
- REQUIRE(acachep != NULL && DNS_ACACHE_VALID(*acachep));
- acache = *acachep;
-
- ATRACE("detach");
-
- isc_refcount_decrement(&acache->refs, &refs);
- if (refs == 0) {
- INSIST(check_noentry(acache) == ISC_TRUE);
- should_free = ISC_TRUE;
- }
-
- *acachep = NULL;
-
- /*
- * If we're exiting and the cleaner task exists, let it free the cache.
- */
- if (should_free && acache->live_cleaners > 0) {
- isc_task_shutdown(acache->task);
- should_free = ISC_FALSE;
- }
-
- if (should_free)
- destroy(acache);
-}
-
-void
-dns_acache_shutdown(dns_acache_t *acache) {
- REQUIRE(DNS_ACACHE_VALID(acache));
-
- LOCK(&acache->lock);
-
- ATRACE("shutdown");
-
- if (!acache->shutting_down) {
- isc_event_t *event;
- dns_acache_t *acache_evarg = NULL;
-
- INSIST(!acache->cevent_sent);
-
- acache->shutting_down = ISC_TRUE;
-
- isc_mem_setwater(acache->mctx, NULL, NULL, 0, 0);
-
- /*
- * Self attach the object in order to prevent it from being
- * destroyed while waiting for the event.
- */
- dns_acache_attach(acache, &acache_evarg);
- event = &acache->cevent;
- event->ev_arg = acache_evarg;
- isc_task_send(acache->task, &event);
- acache->cevent_sent = ISC_TRUE;
- }
-
- UNLOCK(&acache->lock);
-}
-
-isc_result_t
-dns_acache_setdb(dns_acache_t *acache, dns_db_t *db) {
- int bucket;
- dbentry_t *dbentry;
- isc_result_t result = ISC_R_SUCCESS;
-
- REQUIRE(DNS_ACACHE_VALID(acache));
- REQUIRE(db != NULL);
-
- ATRACE("setdb");
-
- LOCK(&acache->lock);
-
- dbentry = NULL;
- result = finddbent(acache, db, &dbentry);
- if (result == ISC_R_SUCCESS) {
- result = ISC_R_EXISTS;
- goto end;
- }
- result = ISC_R_SUCCESS;
-
- dbentry = isc_mem_get(acache->mctx, sizeof(*dbentry));
- if (dbentry == NULL) {
- result = ISC_R_NOMEMORY;
- goto end;
- }
-
- ISC_LINK_INIT(dbentry, link);
- ISC_LIST_INIT(dbentry->originlist);
- ISC_LIST_INIT(dbentry->referlist);
-
- dbentry->db = NULL;
- dns_db_attach(db, &dbentry->db);
-
- bucket = isc_hash_calc((const unsigned char *)&db,
- sizeof(db), ISC_TRUE) % DBBUCKETS;
-
- ISC_LIST_APPEND(acache->dbbucket[bucket], dbentry, link);
-
- acache->dbentries++;
-
- end:
- UNLOCK(&acache->lock);
-
- return (result);
-}
-
-isc_result_t
-dns_acache_putdb(dns_acache_t *acache, dns_db_t *db) {
- int bucket;
- isc_result_t result;
- dbentry_t *dbentry;
- dns_acacheentry_t *entry;
-
- REQUIRE(DNS_ACACHE_VALID(acache));
- REQUIRE(db != NULL);
-
- ATRACE("putdb");
-
- LOCK(&acache->lock);
-
- dbentry = NULL;
- result = finddbent(acache, db, &dbentry);
- if (result != ISC_R_SUCCESS) {
- /*
- * The entry may have not been created due to memory shortage.
- */
- UNLOCK(&acache->lock);
- return (ISC_R_NOTFOUND);
- }
-
- /*
- * Release corresponding cache entries: for each entry, release all
- * links the entry has, and then callback to the entry holder (if any).
- * If no other external references exist (this can happen if the
- * original holder has canceled callback,) destroy it here.
- */
- while ((entry = ISC_LIST_HEAD(dbentry->originlist)) != NULL) {
- ACACHE_LOCK(&acache->entrylocks[entry->locknum],
- isc_rwlocktype_write);
-
- /*
- * Releasing olink first would avoid finddbent() in
- * unlink_dbentries().
- */
- ISC_LIST_UNLINK(dbentry->originlist, entry, olink);
- if (acache->cleaner.current_entry != entry)
- ISC_LIST_UNLINK(acache->entries, entry, link);
- unlink_dbentries(acache, entry);
-
- if (entry->callback != NULL)
- (entry->callback)(entry, &entry->cbarg);
- entry->callback = NULL;
-
- ACACHE_UNLOCK(&acache->entrylocks[entry->locknum],
- isc_rwlocktype_write);
-
- if (acache->cleaner.current_entry != entry)
- dns_acache_detachentry(&entry);
- }
- while ((entry = ISC_LIST_HEAD(dbentry->referlist)) != NULL) {
- ACACHE_LOCK(&acache->entrylocks[entry->locknum],
- isc_rwlocktype_write);
-
- ISC_LIST_UNLINK(dbentry->referlist, entry, rlink);
- if (acache->cleaner.current_entry != entry)
- ISC_LIST_UNLINK(acache->entries, entry, link);
- unlink_dbentries(acache, entry);
-
- if (entry->callback != NULL)
- (entry->callback)(entry, &entry->cbarg);
- entry->callback = NULL;
-
- ACACHE_UNLOCK(&acache->entrylocks[entry->locknum],
- isc_rwlocktype_write);
-
- if (acache->cleaner.current_entry != entry)
- dns_acache_detachentry(&entry);
- }
-
- INSIST(ISC_LIST_EMPTY(dbentry->originlist) &&
- ISC_LIST_EMPTY(dbentry->referlist));
-
- bucket = isc_hash_calc((const unsigned char *)&db,
- sizeof(db), ISC_TRUE) % DBBUCKETS;
- ISC_LIST_UNLINK(acache->dbbucket[bucket], dbentry, link);
- dns_db_detach(&dbentry->db);
-
- isc_mem_put(acache->mctx, dbentry, sizeof(*dbentry));
-
- acache->dbentries--;
-
- acache->stats.deleted++;
-
- UNLOCK(&acache->lock);
-
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_acache_createentry(dns_acache_t *acache, dns_db_t *origdb,
- void (*callback)(dns_acacheentry_t *, void **),
- void *cbarg, dns_acacheentry_t **entryp)
-{
- dns_acacheentry_t *newentry;
- isc_result_t result;
- isc_uint32_t r;
-
- REQUIRE(DNS_ACACHE_VALID(acache));
- REQUIRE(entryp != NULL && *entryp == NULL);
- REQUIRE(origdb != NULL);
-
- /*
- * Should we exceed our memory limit for some reason (for
- * example, if the cleaner does not run aggressively enough),
- * then we will not create additional entries.
- *
- * XXXSK: It might be better to lock the acache->cleaner->lock,
- * but locking may be an expensive bottleneck. If we misread
- * the value, we will occasionally refuse to create a few
- * cache entries, or create a few that we should not. I do not
- * expect this to happen often, and it will not have very bad
- * effects when it does. So no lock for now.
- */
- if (acache->cleaner.overmem) {
- acache->stats.overmem_nocreates++; /* XXXSK danger: unlocked! */
- return (ISC_R_NORESOURCES);
- }
-
- newentry = isc_mem_get(acache->mctx, sizeof(*newentry));
- if (newentry == NULL) {
- acache->stats.nomem++; /* XXXMLG danger: unlocked! */
- return (ISC_R_NOMEMORY);
- }
-
- isc_random_get(&r);
- newentry->locknum = r % DEFAULT_ACACHE_ENTRY_LOCK_COUNT;
-
- result = isc_refcount_init(&newentry->references, 1);
- if (result != ISC_R_SUCCESS) {
- isc_mem_put(acache->mctx, newentry, sizeof(*newentry));
- return (result);
- };
-
- ISC_LINK_INIT(newentry, link);
- ISC_LINK_INIT(newentry, olink);
- ISC_LINK_INIT(newentry, rlink);
-
- newentry->acache = NULL;
- dns_acache_attach(acache, &newentry->acache);
-
- newentry->zone = NULL;
- newentry->db = NULL;
- newentry->version = NULL;
- newentry->node = NULL;
- newentry->foundname = NULL;
-
- newentry->callback = callback;
- newentry->cbarg = cbarg;
- newentry->origdb = NULL;
- dns_db_attach(origdb, &newentry->origdb);
-
- isc_stdtime_get(&newentry->lastused);
-
- newentry->magic = ACACHEENTRY_MAGIC;
-
- *entryp = newentry;
-
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_acache_getentry(dns_acacheentry_t *entry, dns_zone_t **zonep,
- dns_db_t **dbp, dns_dbversion_t **versionp,
- dns_dbnode_t **nodep, dns_name_t *fname,
- dns_message_t *msg, isc_stdtime_t now)
-{
- isc_result_t result = ISC_R_SUCCESS;
- dns_rdataset_t *erdataset;
- isc_stdtime32_t now32;
- dns_acache_t *acache;
- int locknum;
-
- REQUIRE(DNS_ACACHEENTRY_VALID(entry));
- REQUIRE(zonep == NULL || *zonep == NULL);
- REQUIRE(dbp != NULL && *dbp == NULL);
- REQUIRE(versionp != NULL && *versionp == NULL);
- REQUIRE(nodep != NULL && *nodep == NULL);
- REQUIRE(fname != NULL);
- REQUIRE(msg != NULL);
- acache = entry->acache;
- REQUIRE(DNS_ACACHE_VALID(acache));
-
- locknum = entry->locknum;
- ACACHE_LOCK(&acache->entrylocks[locknum], isc_rwlocktype_read);
-
- isc_stdtime_convert32(now, &now32);
- acache_storetime(entry, now32);
-
- if (entry->zone != NULL && zonep != NULL)
- dns_zone_attach(entry->zone, zonep);
-
- if (entry->db == NULL) {
- *dbp = NULL;
- *versionp = NULL;
- } else {
- dns_db_attach(entry->db, dbp);
- dns_db_attachversion(entry->db, entry->version, versionp);
- }
- if (entry->node == NULL)
- *nodep = NULL;
- else {
- dns_db_attachnode(entry->db, entry->node, nodep);
-
- INSIST(entry->foundname != NULL);
- dns_name_copy(entry->foundname, fname, NULL);
- for (erdataset = ISC_LIST_HEAD(entry->foundname->list);
- erdataset != NULL;
- erdataset = ISC_LIST_NEXT(erdataset, link)) {
- dns_rdataset_t *ardataset;
-
- ardataset = NULL;
- result = dns_message_gettemprdataset(msg, &ardataset);
- if (result != ISC_R_SUCCESS) {
- ACACHE_UNLOCK(&acache->entrylocks[locknum],
- isc_rwlocktype_read);
- goto fail;
- }
-
- /*
- * XXXJT: if we simply clone the rdataset, we'll get
- * lost wrt cyclic ordering. We'll need an additional
- * trick to get the latest counter from the original
- * header.
- */
- dns_rdataset_init(ardataset);
- dns_rdataset_clone(erdataset, ardataset);
- ISC_LIST_APPEND(fname->list, ardataset, link);
- }
- }
-
- entry->acache->stats.hits++; /* XXXMLG danger: unlocked! */
- entry->acache->stats.queries++;
-
- ACACHE_UNLOCK(&acache->entrylocks[locknum], isc_rwlocktype_read);
-
- return (result);
-
- fail:
- while ((erdataset = ISC_LIST_HEAD(fname->list)) != NULL) {
- ISC_LIST_UNLINK(fname->list, erdataset, link);
- dns_rdataset_disassociate(erdataset);
- dns_message_puttemprdataset(msg, &erdataset);
- }
- if (*nodep != NULL)
- dns_db_detachnode(*dbp, nodep);
- if (*versionp != NULL)
- dns_db_closeversion(*dbp, versionp, ISC_FALSE);
- if (*dbp != NULL)
- dns_db_detach(dbp);
- if (zonep != NULL && *zonep != NULL)
- dns_zone_detach(zonep);
-
- return (result);
-}
-
-isc_result_t
-dns_acache_setentry(dns_acache_t *acache, dns_acacheentry_t *entry,
- dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
- dns_dbnode_t *node, dns_name_t *fname)
-{
- isc_result_t result;
- dbentry_t *odbent;
- dbentry_t *rdbent = NULL;
- isc_boolean_t close_version = ISC_FALSE;
- dns_acacheentry_t *dummy_entry = NULL;
-
- REQUIRE(DNS_ACACHE_VALID(acache));
- REQUIRE(DNS_ACACHEENTRY_VALID(entry));
-
- LOCK(&acache->lock); /* XXX: need to lock it here for ordering */
- ACACHE_LOCK(&acache->entrylocks[entry->locknum], isc_rwlocktype_write);
-
- /* Set zone */
- if (zone != NULL)
- dns_zone_attach(zone, &entry->zone);
- /* Set DB */
- if (db != NULL)
- dns_db_attach(db, &entry->db);
- /*
- * Set DB version. If the version is not given by the caller,
- * which is the case for glue or cache DBs, use the current version.
- */
- if (version == NULL) {
- if (db != NULL) {
- dns_db_currentversion(db, &version);
- close_version = ISC_TRUE;
- }
- }
- if (version != NULL) {
- INSIST(db != NULL);
- dns_db_attachversion(db, version, &entry->version);
- }
- if (close_version)
- dns_db_closeversion(db, &version, ISC_FALSE);
- /* Set DB node. */
- if (node != NULL) {
- INSIST(db != NULL);
- dns_db_attachnode(db, node, &entry->node);
- }
-
- /*
- * Set list of the corresponding rdatasets, if given.
- * To minimize the overhead and memory consumption, we'll do this for
- * positive cache only, in which case the DB node is non NULL.
- * We do not want to cache incomplete information, so give up the
- * entire entry when a memory shortage happen during the process.
- */
- if (node != NULL) {
- dns_rdataset_t *ardataset, *crdataset;
-
- entry->foundname = isc_mem_get(acache->mctx,
- sizeof(*entry->foundname));
-
- if (entry->foundname == NULL) {
- result = ISC_R_NOMEMORY;
- goto fail;
- }
- dns_name_init(entry->foundname, NULL);
- result = dns_name_dup(fname, acache->mctx,
- entry->foundname);
- if (result != ISC_R_SUCCESS)
- goto fail;
-
- for (ardataset = ISC_LIST_HEAD(fname->list);
- ardataset != NULL;
- ardataset = ISC_LIST_NEXT(ardataset, link)) {
- crdataset = isc_mem_get(acache->mctx,
- sizeof(*crdataset));
- if (crdataset == NULL) {
- result = ISC_R_NOMEMORY;
- goto fail;
- }
-
- dns_rdataset_init(crdataset);
- dns_rdataset_clone(ardataset, crdataset);
- ISC_LIST_APPEND(entry->foundname->list, crdataset,
- link);
- }
- }
-
- odbent = NULL;
- result = finddbent(acache, entry->origdb, &odbent);
- if (result != ISC_R_SUCCESS)
- goto fail;
- if (db != NULL) {
- rdbent = NULL;
- result = finddbent(acache, db, &rdbent);
- if (result != ISC_R_SUCCESS)
- goto fail;
- }
-
- ISC_LIST_APPEND(acache->entries, entry, link);
- ISC_LIST_APPEND(odbent->originlist, entry, olink);
- if (rdbent != NULL)
- ISC_LIST_APPEND(rdbent->referlist, entry, rlink);
-
- /*
- * The additional cache needs an implicit reference to entries in its
- * link.
- */
- dns_acache_attachentry(entry, &dummy_entry);
-
- ACACHE_UNLOCK(&acache->entrylocks[entry->locknum],
- isc_rwlocktype_write);
-
- acache->stats.adds++;
- UNLOCK(&acache->lock);
-
- return (ISC_R_SUCCESS);
-
- fail:
- clear_entry(acache, entry);
-
- ACACHE_UNLOCK(&acache->entrylocks[entry->locknum],
- isc_rwlocktype_write);
- UNLOCK(&acache->lock);
-
- return (result);
-}
-
-isc_boolean_t
-dns_acache_cancelentry(dns_acacheentry_t *entry) {
- dns_acache_t *acache;
- isc_boolean_t callback_active;
-
- REQUIRE(DNS_ACACHEENTRY_VALID(entry));
-
- acache = entry->acache;
- callback_active = ISC_TF(entry->cbarg != NULL);
-
- INSIST(DNS_ACACHE_VALID(entry->acache));
-
- LOCK(&acache->lock);
- ACACHE_LOCK(&acache->entrylocks[entry->locknum], isc_rwlocktype_write);
-
- /*
- * Release dependencies stored in this entry as much as possible.
- * The main link cannot be released, since the acache object has
- * a reference to this entry; the empty entry will be released in
- * the next cleaning action.
- */
- unlink_dbentries(acache, entry);
- clear_entry(entry->acache, entry);
-
- entry->callback = NULL;
- entry->cbarg = NULL;
-
- ACACHE_UNLOCK(&acache->entrylocks[entry->locknum],
- isc_rwlocktype_write);
- UNLOCK(&acache->lock);
-
- return (callback_active);
-}
-
-void
-dns_acache_attachentry(dns_acacheentry_t *source,
- dns_acacheentry_t **targetp)
-{
- REQUIRE(DNS_ACACHEENTRY_VALID(source));
- REQUIRE(targetp != NULL && *targetp == NULL);
-
- isc_refcount_increment(&source->references, NULL);
-
- *targetp = source;
-}
-
-void
-dns_acache_detachentry(dns_acacheentry_t **entryp) {
- dns_acacheentry_t *entry;
- unsigned int refs;
-
- REQUIRE(entryp != NULL && DNS_ACACHEENTRY_VALID(*entryp));
- entry = *entryp;
-
- isc_refcount_decrement(&entry->references, &refs);
-
- /*
- * If there are no references to the entry, the entry must have been
- * unlinked and can be destroyed safely.
- */
- if (refs == 0) {
- INSIST(!ISC_LINK_LINKED(entry, link));
- (*entryp)->acache->stats.deleted++;
- destroy_entry(entry);
- }
-
- *entryp = NULL;
-}
-
-void
-dns_acache_setcleaninginterval(dns_acache_t *acache, unsigned int t) {
- isc_interval_t interval;
- isc_result_t result;
-
- REQUIRE(DNS_ACACHE_VALID(acache));
-
- ATRACE("dns_acache_setcleaninginterval");
-
- LOCK(&acache->lock);
-
- /*
- * It may be the case that the acache has already shut down.
- * If so, it has no timer. (Not sure if this can really happen.)
- */
- if (acache->cleaner.cleaning_timer == NULL)
- goto unlock;
-
- acache->cleaner.cleaning_interval = t;
-
- if (t == 0) {
- result = isc_timer_reset(acache->cleaner.cleaning_timer,
- isc_timertype_inactive,
- NULL, NULL, ISC_TRUE);
- } else {
- isc_interval_set(&interval, acache->cleaner.cleaning_interval,
- 0);
- result = isc_timer_reset(acache->cleaner.cleaning_timer,
- isc_timertype_ticker,
- NULL, &interval, ISC_FALSE);
- }
- if (result != ISC_R_SUCCESS)
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_ACACHE, ISC_LOG_WARNING,
- "could not set acache cleaning interval: %s",
- isc_result_totext(result));
- else
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_ACACHE, ISC_LOG_NOTICE,
- "acache %p cleaning interval set to %d.",
- acache, t);
-
- unlock:
- UNLOCK(&acache->lock);
-}
-
-/*
- * This function was derived from cache.c:dns_cache_setcachesize(). See the
- * function for more details about the logic.
- */
-void
-dns_acache_setcachesize(dns_acache_t *acache, size_t size) {
- size_t hiwater, lowater;
-
- REQUIRE(DNS_ACACHE_VALID(acache));
-
- if (size != 0U && size < DNS_ACACHE_MINSIZE)
- size = DNS_ACACHE_MINSIZE;
-
- hiwater = size - (size >> 3);
- lowater = size - (size >> 2);
-
- if (size == 0U || hiwater == 0U || lowater == 0U)
- isc_mem_setwater(acache->mctx, water, acache, 0, 0);
- else
- isc_mem_setwater(acache->mctx, water, acache,
- hiwater, lowater);
-}
diff --git a/contrib/bind9/lib/dns/acl.c b/contrib/bind9/lib/dns/acl.c
deleted file mode 100644
index 3221d30c2b52..000000000000
--- a/contrib/bind9/lib/dns/acl.c
+++ /dev/null
@@ -1,633 +0,0 @@
-/*
- * Copyright (C) 2004-2009, 2011, 2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2002 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: acl.c,v 1.55 2011/06/17 23:47:49 tbox Exp $ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <isc/mem.h>
-#include <isc/once.h>
-#include <isc/string.h>
-#include <isc/util.h>
-
-#include <dns/acl.h>
-#include <dns/iptable.h>
-
-/*
- * Create a new ACL, including an IP table and an array with room
- * for 'n' ACL elements. The elements are uninitialized and the
- * length is 0.
- */
-isc_result_t
-dns_acl_create(isc_mem_t *mctx, int n, dns_acl_t **target) {
- isc_result_t result;
- dns_acl_t *acl;
-
- /*
- * Work around silly limitation of isc_mem_get().
- */
- if (n == 0)
- n = 1;
-
- acl = isc_mem_get(mctx, sizeof(*acl));
- if (acl == NULL)
- return (ISC_R_NOMEMORY);
-
- acl->mctx = NULL;
- isc_mem_attach(mctx, &acl->mctx);
-
- acl->name = NULL;
-
- result = isc_refcount_init(&acl->refcount, 1);
- if (result != ISC_R_SUCCESS) {
- isc_mem_put(mctx, acl, sizeof(*acl));
- return (result);
- }
-
- result = dns_iptable_create(mctx, &acl->iptable);
- if (result != ISC_R_SUCCESS) {
- isc_mem_put(mctx, acl, sizeof(*acl));
- return (result);
- }
-
- acl->elements = NULL;
- acl->alloc = 0;
- acl->length = 0;
- acl->has_negatives = ISC_FALSE;
-
- ISC_LINK_INIT(acl, nextincache);
- /*
- * Must set magic early because we use dns_acl_detach() to clean up.
- */
- acl->magic = DNS_ACL_MAGIC;
-
- acl->elements = isc_mem_get(mctx, n * sizeof(dns_aclelement_t));
- if (acl->elements == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup;
- }
- acl->alloc = n;
- memset(acl->elements, 0, n * sizeof(dns_aclelement_t));
- *target = acl;
- return (ISC_R_SUCCESS);
-
- cleanup:
- dns_acl_detach(&acl);
- return (result);
-}
-
-/*
- * Create a new ACL and initialize it with the value "any" or "none",
- * depending on the value of the "neg" parameter.
- * "any" is a positive iptable entry with bit length 0.
- * "none" is the same as "!any".
- */
-static isc_result_t
-dns_acl_anyornone(isc_mem_t *mctx, isc_boolean_t neg, dns_acl_t **target) {
- isc_result_t result;
- dns_acl_t *acl = NULL;
-
- result = dns_acl_create(mctx, 0, &acl);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- result = dns_iptable_addprefix(acl->iptable, NULL, 0, ISC_TF(!neg));
- if (result != ISC_R_SUCCESS) {
- dns_acl_detach(&acl);
- return (result);
- }
-
- *target = acl;
- return (result);
-}
-
-/*
- * Create a new ACL that matches everything.
- */
-isc_result_t
-dns_acl_any(isc_mem_t *mctx, dns_acl_t **target) {
- return (dns_acl_anyornone(mctx, ISC_FALSE, target));
-}
-
-/*
- * Create a new ACL that matches nothing.
- */
-isc_result_t
-dns_acl_none(isc_mem_t *mctx, dns_acl_t **target) {
- return (dns_acl_anyornone(mctx, ISC_TRUE, target));
-}
-
-/*
- * If pos is ISC_TRUE, test whether acl is set to "{ any; }"
- * If pos is ISC_FALSE, test whether acl is set to "{ none; }"
- */
-static isc_boolean_t
-dns_acl_isanyornone(dns_acl_t *acl, isc_boolean_t pos)
-{
- /* Should never happen but let's be safe */
- if (acl == NULL ||
- acl->iptable == NULL ||
- acl->iptable->radix == NULL ||
- acl->iptable->radix->head == NULL ||
- acl->iptable->radix->head->prefix == NULL)
- return (ISC_FALSE);
-
- if (acl->length != 0 || acl->node_count != 1)
- return (ISC_FALSE);
-
- if (acl->iptable->radix->head->prefix->bitlen == 0 &&
- acl->iptable->radix->head->data[0] != NULL &&
- acl->iptable->radix->head->data[0] ==
- acl->iptable->radix->head->data[1] &&
- *(isc_boolean_t *) (acl->iptable->radix->head->data[0]) == pos)
- return (ISC_TRUE);
-
- return (ISC_FALSE); /* All others */
-}
-
-/*
- * Test whether acl is set to "{ any; }"
- */
-isc_boolean_t
-dns_acl_isany(dns_acl_t *acl)
-{
- return (dns_acl_isanyornone(acl, ISC_TRUE));
-}
-
-/*
- * Test whether acl is set to "{ none; }"
- */
-isc_boolean_t
-dns_acl_isnone(dns_acl_t *acl)
-{
- return (dns_acl_isanyornone(acl, ISC_FALSE));
-}
-
-/*
- * Determine whether a given address or signer matches a given ACL.
- * For a match with a positive ACL element or iptable radix entry,
- * return with a positive value in match; for a match with a negated ACL
- * element or radix entry, return with a negative value in match.
- */
-isc_result_t
-dns_acl_match(const isc_netaddr_t *reqaddr,
- const dns_name_t *reqsigner,
- const dns_acl_t *acl,
- const dns_aclenv_t *env,
- int *match,
- const dns_aclelement_t **matchelt)
-{
- isc_uint16_t bitlen, family;
- isc_prefix_t pfx;
- isc_radix_node_t *node = NULL;
- const isc_netaddr_t *addr;
- isc_netaddr_t v4addr;
- isc_result_t result;
- int match_num = -1;
- unsigned int i;
-
- REQUIRE(reqaddr != NULL);
- REQUIRE(matchelt == NULL || *matchelt == NULL);
-
- if (env == NULL || env->match_mapped == ISC_FALSE ||
- reqaddr->family != AF_INET6 ||
- !IN6_IS_ADDR_V4MAPPED(&reqaddr->type.in6))
- addr = reqaddr;
- else {
- isc_netaddr_fromv4mapped(&v4addr, reqaddr);
- addr = &v4addr;
- }
-
- /* Always match with host addresses. */
- family = addr->family;
- bitlen = family == AF_INET6 ? 128 : 32;
- NETADDR_TO_PREFIX_T(addr, pfx, bitlen);
-
- /* Assume no match. */
- *match = 0;
-
- /* Search radix. */
- result = isc_radix_search(acl->iptable->radix, &node, &pfx);
-
- /* Found a match. */
- if (result == ISC_R_SUCCESS && node != NULL) {
- match_num = node->node_num[ISC_IS6(family)];
- if (*(isc_boolean_t *) node->data[ISC_IS6(family)] == ISC_TRUE)
- *match = match_num;
- else
- *match = -match_num;
- }
-
- /* Now search non-radix elements for a match with a lower node_num. */
- for (i = 0; i < acl->length; i++) {
- dns_aclelement_t *e = &acl->elements[i];
-
- /* Already found a better match? */
- if (match_num != -1 && match_num < e->node_num) {
- isc_refcount_destroy(&pfx.refcount);
- return (ISC_R_SUCCESS);
- }
-
- if (dns_aclelement_match(reqaddr, reqsigner,
- e, env, matchelt)) {
- if (match_num == -1 || e->node_num < match_num) {
- if (e->negative == ISC_TRUE)
- *match = -e->node_num;
- else
- *match = e->node_num;
- }
- isc_refcount_destroy(&pfx.refcount);
- return (ISC_R_SUCCESS);
- }
- }
-
- isc_refcount_destroy(&pfx.refcount);
- return (ISC_R_SUCCESS);
-}
-
-/*
- * Merge the contents of one ACL into another. Call dns_iptable_merge()
- * for the IP tables, then concatenate the element arrays.
- *
- * If pos is set to false, then the nested ACL is to be negated. This
- * means reverse the sense of each *positive* element or IP table node,
- * but leave negatives alone, so as to prevent a double-negative causing
- * an unexpected positive match in the parent ACL.
- */
-isc_result_t
-dns_acl_merge(dns_acl_t *dest, dns_acl_t *source, isc_boolean_t pos)
-{
- isc_result_t result;
- unsigned int newalloc, nelem, i;
- int max_node = 0, nodes;
-
- /* Resize the element array if needed. */
- if (dest->length + source->length > dest->alloc) {
- void *newmem;
-
- newalloc = dest->alloc + source->alloc;
- if (newalloc < 4)
- newalloc = 4;
-
- newmem = isc_mem_get(dest->mctx,
- newalloc * sizeof(dns_aclelement_t));
- if (newmem == NULL)
- return (ISC_R_NOMEMORY);
-
- /* Copy in the original elements */
- memcpy(newmem, dest->elements,
- dest->length * sizeof(dns_aclelement_t));
-
- /* Release the memory for the old elements array */
- isc_mem_put(dest->mctx, dest->elements,
- dest->alloc * sizeof(dns_aclelement_t));
- dest->elements = newmem;
- dest->alloc = newalloc;
- }
-
- /*
- * Now copy in the new elements, increasing their node_num
- * values so as to keep the new ACL consistent. If we're
- * negating, then negate positive elements, but keep negative
- * elements the same for security reasons.
- */
- nelem = dest->length;
- dest->length += source->length;
- for (i = 0; i < source->length; i++) {
- if (source->elements[i].node_num > max_node)
- max_node = source->elements[i].node_num;
-
- /* Copy type. */
- dest->elements[nelem + i].type = source->elements[i].type;
-
- /* Adjust node numbering. */
- dest->elements[nelem + i].node_num =
- source->elements[i].node_num + dest->node_count;
-
- /* Duplicate nested acl. */
- if (source->elements[i].type == dns_aclelementtype_nestedacl &&
- source->elements[i].nestedacl != NULL)
- dns_acl_attach(source->elements[i].nestedacl,
- &dest->elements[nelem + i].nestedacl);
-
- /* Duplicate key name. */
- if (source->elements[i].type == dns_aclelementtype_keyname) {
- dns_name_init(&dest->elements[nelem+i].keyname, NULL);
- result = dns_name_dup(&source->elements[i].keyname,
- dest->mctx,
- &dest->elements[nelem+i].keyname);
- if (result != ISC_R_SUCCESS)
- return result;
- }
-
- /* reverse sense of positives if this is a negative acl */
- if (!pos && source->elements[i].negative == ISC_FALSE) {
- dest->elements[nelem + i].negative = ISC_TRUE;
- } else {
- dest->elements[nelem + i].negative =
- source->elements[i].negative;
- }
- }
-
- /*
- * Merge the iptables. Make sure the destination ACL's
- * node_count value is set correctly afterward.
- */
- nodes = max_node + dest->node_count;
- result = dns_iptable_merge(dest->iptable, source->iptable, pos);
- if (result != ISC_R_SUCCESS)
- return (result);
- if (nodes > dest->node_count)
- dest->node_count = nodes;
-
- return (ISC_R_SUCCESS);
-}
-
-/*
- * Like dns_acl_match, but matches against the single ACL element 'e'
- * rather than a complete ACL, and returns ISC_TRUE iff it matched.
- *
- * To determine whether the match was positive or negative, the
- * caller should examine e->negative. Since the element 'e' may be
- * a reference to a named ACL or a nested ACL, a matching element
- * returned through 'matchelt' is not necessarily 'e' itself.
- */
-isc_boolean_t
-dns_aclelement_match(const isc_netaddr_t *reqaddr,
- const dns_name_t *reqsigner,
- const dns_aclelement_t *e,
- const dns_aclenv_t *env,
- const dns_aclelement_t **matchelt)
-{
- dns_acl_t *inner = NULL;
- int indirectmatch;
- isc_result_t result;
-
- switch (e->type) {
- case dns_aclelementtype_keyname:
- if (reqsigner != NULL &&
- dns_name_equal(reqsigner, &e->keyname)) {
- if (matchelt != NULL)
- *matchelt = e;
- return (ISC_TRUE);
- } else {
- return (ISC_FALSE);
- }
-
- case dns_aclelementtype_nestedacl:
- inner = e->nestedacl;
- break;
-
- case dns_aclelementtype_localhost:
- if (env == NULL || env->localhost == NULL)
- return (ISC_FALSE);
- inner = env->localhost;
- break;
-
- case dns_aclelementtype_localnets:
- if (env == NULL || env->localnets == NULL)
- return (ISC_FALSE);
- inner = env->localnets;
- break;
-
- default:
- /* Should be impossible. */
- INSIST(0);
- }
-
- result = dns_acl_match(reqaddr, reqsigner, inner, env,
- &indirectmatch, matchelt);
- INSIST(result == ISC_R_SUCCESS);
-
- /*
- * Treat negative matches in indirect ACLs as "no match".
- * That way, a negated indirect ACL will never become a
- * surprise positive match through double negation.
- * XXXDCL this should be documented.
- */
-
- if (indirectmatch > 0) {
- if (matchelt != NULL)
- *matchelt = e;
- return (ISC_TRUE);
- }
-
- /*
- * A negative indirect match may have set *matchelt, but we don't
- * want it set when we return.
- */
-
- if (matchelt != NULL)
- *matchelt = NULL;
-
- return (ISC_FALSE);
-}
-
-void
-dns_acl_attach(dns_acl_t *source, dns_acl_t **target) {
- REQUIRE(DNS_ACL_VALID(source));
-
- isc_refcount_increment(&source->refcount, NULL);
- *target = source;
-}
-
-static void
-destroy(dns_acl_t *dacl) {
- unsigned int i;
-
- INSIST(!ISC_LINK_LINKED(dacl, nextincache));
-
- for (i = 0; i < dacl->length; i++) {
- dns_aclelement_t *de = &dacl->elements[i];
- if (de->type == dns_aclelementtype_keyname) {
- dns_name_free(&de->keyname, dacl->mctx);
- } else if (de->type == dns_aclelementtype_nestedacl) {
- dns_acl_detach(&de->nestedacl);
- }
- }
- if (dacl->elements != NULL)
- isc_mem_put(dacl->mctx, dacl->elements,
- dacl->alloc * sizeof(dns_aclelement_t));
- if (dacl->name != NULL)
- isc_mem_free(dacl->mctx, dacl->name);
- if (dacl->iptable != NULL)
- dns_iptable_detach(&dacl->iptable);
- isc_refcount_destroy(&dacl->refcount);
- dacl->magic = 0;
- isc_mem_putanddetach(&dacl->mctx, dacl, sizeof(*dacl));
-}
-
-void
-dns_acl_detach(dns_acl_t **aclp) {
- dns_acl_t *acl = *aclp;
- unsigned int refs;
-
- REQUIRE(DNS_ACL_VALID(acl));
-
- isc_refcount_decrement(&acl->refcount, &refs);
- if (refs == 0)
- destroy(acl);
- *aclp = NULL;
-}
-
-
-static isc_once_t insecure_prefix_once = ISC_ONCE_INIT;
-static isc_mutex_t insecure_prefix_lock;
-static isc_boolean_t insecure_prefix_found;
-
-static void
-initialize_action(void) {
- RUNTIME_CHECK(isc_mutex_init(&insecure_prefix_lock) == ISC_R_SUCCESS);
-}
-
-/*
- * Called via isc_radix_walk() to find IP table nodes that are
- * insecure.
- */
-static void
-is_insecure(isc_prefix_t *prefix, void **data) {
- isc_boolean_t secure;
- int bitlen, family;
-
- bitlen = prefix->bitlen;
- family = prefix->family;
-
- /* Negated entries are always secure. */
- secure = * (isc_boolean_t *)data[ISC_IS6(family)];
- if (!secure) {
- return;
- }
-
- /* If loopback prefix found, return */
- switch (family) {
- case AF_INET:
- if (bitlen == 32 &&
- htonl(prefix->add.sin.s_addr) == INADDR_LOOPBACK)
- return;
- break;
- case AF_INET6:
- if (bitlen == 128 && IN6_IS_ADDR_LOOPBACK(&prefix->add.sin6))
- return;
- break;
- default:
- break;
- }
-
- /* Non-negated, non-loopback */
- insecure_prefix_found = ISC_TRUE; /* LOCKED */
- return;
-}
-
-/*
- * Return ISC_TRUE iff the acl 'a' is considered insecure, that is,
- * if it contains IP addresses other than those of the local host.
- * This is intended for applications such as printing warning
- * messages for suspect ACLs; it is not intended for making access
- * control decisions. We make no guarantee that an ACL for which
- * this function returns ISC_FALSE is safe.
- */
-isc_boolean_t
-dns_acl_isinsecure(const dns_acl_t *a) {
- unsigned int i;
- isc_boolean_t insecure;
-
- RUNTIME_CHECK(isc_once_do(&insecure_prefix_once,
- initialize_action) == ISC_R_SUCCESS);
-
- /*
- * Walk radix tree to find out if there are any non-negated,
- * non-loopback prefixes.
- */
- LOCK(&insecure_prefix_lock);
- insecure_prefix_found = ISC_FALSE;
- isc_radix_process(a->iptable->radix, is_insecure);
- insecure = insecure_prefix_found;
- UNLOCK(&insecure_prefix_lock);
- if (insecure)
- return(ISC_TRUE);
-
- /* Now check non-radix elements */
- for (i = 0; i < a->length; i++) {
- dns_aclelement_t *e = &a->elements[i];
-
- /* A negated match can never be insecure. */
- if (e->negative)
- continue;
-
- switch (e->type) {
- case dns_aclelementtype_keyname:
- case dns_aclelementtype_localhost:
- continue;
-
- case dns_aclelementtype_nestedacl:
- if (dns_acl_isinsecure(e->nestedacl))
- return (ISC_TRUE);
- continue;
-
- case dns_aclelementtype_localnets:
- return (ISC_TRUE);
-
- default:
- INSIST(0);
- return (ISC_TRUE);
- }
- }
-
- /* No insecure elements were found. */
- return (ISC_FALSE);
-}
-
-/*
- * Initialize ACL environment, setting up localhost and localnets ACLs
- */
-isc_result_t
-dns_aclenv_init(isc_mem_t *mctx, dns_aclenv_t *env) {
- isc_result_t result;
-
- env->localhost = NULL;
- env->localnets = NULL;
- result = dns_acl_create(mctx, 0, &env->localhost);
- if (result != ISC_R_SUCCESS)
- goto cleanup_nothing;
- result = dns_acl_create(mctx, 0, &env->localnets);
- if (result != ISC_R_SUCCESS)
- goto cleanup_localhost;
- env->match_mapped = ISC_FALSE;
- return (ISC_R_SUCCESS);
-
- cleanup_localhost:
- dns_acl_detach(&env->localhost);
- cleanup_nothing:
- return (result);
-}
-
-void
-dns_aclenv_copy(dns_aclenv_t *t, dns_aclenv_t *s) {
- dns_acl_detach(&t->localhost);
- dns_acl_attach(s->localhost, &t->localhost);
- dns_acl_detach(&t->localnets);
- dns_acl_attach(s->localnets, &t->localnets);
- t->match_mapped = s->match_mapped;
-}
-
-void
-dns_aclenv_destroy(dns_aclenv_t *env) {
- dns_acl_detach(&env->localhost);
- dns_acl_detach(&env->localnets);
-}
diff --git a/contrib/bind9/lib/dns/adb.c b/contrib/bind9/lib/dns/adb.c
deleted file mode 100644
index ef7875dcb46b..000000000000
--- a/contrib/bind9/lib/dns/adb.c
+++ /dev/null
@@ -1,4148 +0,0 @@
-/*
- * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: adb.c,v 1.264 2011/12/05 17:10:51 each Exp $ */
-
-/*! \file
- *
- * \note
- * In finds, if task == NULL, no events will be generated, and no events
- * have been sent. If task != NULL but taskaction == NULL, an event has been
- * posted but not yet freed. If neither are NULL, no event was posted.
- *
- */
-
-#include <config.h>
-
-#include <limits.h>
-
-#include <isc/mutexblock.h>
-#include <isc/netaddr.h>
-#include <isc/random.h>
-#include <isc/stats.h>
-#include <isc/string.h> /* Required for HP/UX (and others?) */
-#include <isc/task.h>
-#include <isc/util.h>
-
-#include <dns/adb.h>
-#include <dns/db.h>
-#include <dns/events.h>
-#include <dns/log.h>
-#include <dns/rdata.h>
-#include <dns/rdataset.h>
-#include <dns/rdatastruct.h>
-#include <dns/rdatatype.h>
-#include <dns/resolver.h>
-#include <dns/result.h>
-#include <dns/stats.h>
-
-#define DNS_ADB_MAGIC ISC_MAGIC('D', 'a', 'd', 'b')
-#define DNS_ADB_VALID(x) ISC_MAGIC_VALID(x, DNS_ADB_MAGIC)
-#define DNS_ADBNAME_MAGIC ISC_MAGIC('a', 'd', 'b', 'N')
-#define DNS_ADBNAME_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBNAME_MAGIC)
-#define DNS_ADBNAMEHOOK_MAGIC ISC_MAGIC('a', 'd', 'N', 'H')
-#define DNS_ADBNAMEHOOK_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBNAMEHOOK_MAGIC)
-#define DNS_ADBLAMEINFO_MAGIC ISC_MAGIC('a', 'd', 'b', 'Z')
-#define DNS_ADBLAMEINFO_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBLAMEINFO_MAGIC)
-#define DNS_ADBENTRY_MAGIC ISC_MAGIC('a', 'd', 'b', 'E')
-#define DNS_ADBENTRY_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBENTRY_MAGIC)
-#define DNS_ADBFETCH_MAGIC ISC_MAGIC('a', 'd', 'F', '4')
-#define DNS_ADBFETCH_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBFETCH_MAGIC)
-#define DNS_ADBFETCH6_MAGIC ISC_MAGIC('a', 'd', 'F', '6')
-#define DNS_ADBFETCH6_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBFETCH6_MAGIC)
-
-/*!
- * 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
- * if the zone has extremely low TTLs.
- */
-#define ADB_CACHE_MINIMUM 10 /*%< seconds */
-#define ADB_CACHE_MAXIMUM 86400 /*%< seconds (86400 = 24 hours) */
-#define ADB_ENTRY_WINDOW 1800 /*%< seconds */
-
-/*%
- * The period in seconds after which an ADB name entry is regarded as stale
- * and forced to be cleaned up.
- * TODO: This should probably be configurable at run-time.
- */
-#ifndef ADB_STALE_MARGIN
-#define ADB_STALE_MARGIN 1800
-#endif
-
-#define FREE_ITEMS 64 /*%< free count for memory pools */
-#define FILL_COUNT 16 /*%< fill count for memory pools */
-
-#define DNS_ADB_INVALIDBUCKET (-1) /*%< invalid bucket address */
-
-#define DNS_ADB_MINADBSIZE (1024U*1024U) /*%< 1 Megabyte */
-
-typedef ISC_LIST(dns_adbname_t) dns_adbnamelist_t;
-typedef struct dns_adbnamehook dns_adbnamehook_t;
-typedef ISC_LIST(dns_adbnamehook_t) dns_adbnamehooklist_t;
-typedef struct dns_adblameinfo dns_adblameinfo_t;
-typedef ISC_LIST(dns_adbentry_t) dns_adbentrylist_t;
-typedef struct dns_adbfetch dns_adbfetch_t;
-typedef struct dns_adbfetch6 dns_adbfetch6_t;
-
-/*% dns adb structure */
-struct dns_adb {
- unsigned int magic;
-
- isc_mutex_t lock;
- isc_mutex_t reflock; /*%< Covers irefcnt, erefcnt */
- isc_mutex_t overmemlock; /*%< Covers overmem */
- isc_mem_t *mctx;
- dns_view_t *view;
-
- isc_taskmgr_t *taskmgr;
- isc_task_t *task;
- isc_task_t *excl;
-
- isc_interval_t tick_interval;
- int next_cleanbucket;
-
- unsigned int irefcnt;
- unsigned int erefcnt;
-
- isc_mutex_t mplock;
- isc_mempool_t *nmp; /*%< dns_adbname_t */
- isc_mempool_t *nhmp; /*%< dns_adbnamehook_t */
- isc_mempool_t *limp; /*%< dns_adblameinfo_t */
- isc_mempool_t *emp; /*%< dns_adbentry_t */
- isc_mempool_t *ahmp; /*%< dns_adbfind_t */
- isc_mempool_t *aimp; /*%< dns_adbaddrinfo_t */
- isc_mempool_t *afmp; /*%< dns_adbfetch_t */
-
- /*!
- * Bucketized locks and lists for names.
- *
- * XXXRTH Have a per-bucket structure that contains all of these?
- */
- 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 and lists for entries.
- *
- * XXXRTH Have a per-bucket structure that contains all of these?
- */
- 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;
-};
-
-/*
- * XXXMLG Document these structures.
- */
-
-/*% dns_adbname structure */
-struct dns_adbname {
- unsigned int magic;
- dns_name_t name;
- dns_adb_t *adb;
- unsigned int partial_result;
- unsigned int flags;
- int lock_bucket;
- dns_name_t target;
- isc_stdtime_t expire_target;
- isc_stdtime_t expire_v4;
- isc_stdtime_t expire_v6;
- unsigned int chains;
- dns_adbnamehooklist_t v4;
- dns_adbnamehooklist_t v6;
- dns_adbfetch_t *fetch_a;
- dns_adbfetch_t *fetch_aaaa;
- unsigned int fetch_err;
- unsigned int fetch6_err;
- dns_adbfindlist_t finds;
- /* for LRU-based management */
- isc_stdtime_t last_used;
-
- ISC_LINK(dns_adbname_t) plink;
-};
-
-/*% The adbfetch structure */
-struct dns_adbfetch {
- unsigned int magic;
- dns_fetch_t *fetch;
- dns_rdataset_t rdataset;
-};
-
-/*%
- * This is a small widget that dangles off a dns_adbname_t. It contains a
- * pointer to the address information about this host, and a link to the next
- * namehook that will contain the next address this host has.
- */
-struct dns_adbnamehook {
- unsigned int magic;
- dns_adbentry_t *entry;
- ISC_LINK(dns_adbnamehook_t) plink;
-};
-
-/*%
- * This is a small widget that holds qname-specific information about an
- * address. Currently limited to lameness, but could just as easily be
- * extended to other types of information about zones.
- */
-struct dns_adblameinfo {
- unsigned int magic;
-
- dns_name_t qname;
- dns_rdatatype_t qtype;
- isc_stdtime_t lame_timer;
-
- ISC_LINK(dns_adblameinfo_t) plink;
-};
-
-/*%
- * An address entry. It holds quite a bit of information about addresses,
- * including edns state (in "flags"), rtt, and of course the address of
- * the host.
- */
-struct dns_adbentry {
- unsigned int magic;
-
- int lock_bucket;
- unsigned int refcnt;
-
- unsigned int flags;
- unsigned int srtt;
- isc_sockaddr_t sockaddr;
-
- isc_stdtime_t expires;
- /*%<
- * A nonzero 'expires' field indicates that the entry should
- * persist until that time. This allows entries found
- * using dns_adb_findaddrinfo() to persist for a limited time
- * even though they are not necessarily associated with a
- * name.
- */
-
- ISC_LIST(dns_adblameinfo_t) lameinfo;
- ISC_LINK(dns_adbentry_t) plink;
-
-};
-
-/*
- * Internal functions (and prototypes).
- */
-static inline dns_adbname_t *new_adbname(dns_adb_t *, dns_name_t *);
-static inline void free_adbname(dns_adb_t *, dns_adbname_t **);
-static inline dns_adbnamehook_t *new_adbnamehook(dns_adb_t *,
- dns_adbentry_t *);
-static inline void free_adbnamehook(dns_adb_t *, dns_adbnamehook_t **);
-static inline dns_adblameinfo_t *new_adblameinfo(dns_adb_t *, dns_name_t *,
- dns_rdatatype_t);
-static inline void free_adblameinfo(dns_adb_t *, dns_adblameinfo_t **);
-static inline dns_adbentry_t *new_adbentry(dns_adb_t *);
-static inline void free_adbentry(dns_adb_t *, dns_adbentry_t **);
-static inline dns_adbfind_t *new_adbfind(dns_adb_t *);
-static inline isc_boolean_t free_adbfind(dns_adb_t *, dns_adbfind_t **);
-static inline dns_adbaddrinfo_t *new_adbaddrinfo(dns_adb_t *, dns_adbentry_t *,
- in_port_t);
-static inline dns_adbfetch_t *new_adbfetch(dns_adb_t *);
-static inline void free_adbfetch(dns_adb_t *, dns_adbfetch_t **);
-static inline dns_adbname_t *find_name_and_lock(dns_adb_t *, dns_name_t *,
- unsigned int, int *);
-static inline dns_adbentry_t *find_entry_and_lock(dns_adb_t *,
- isc_sockaddr_t *, int *,
- isc_stdtime_t);
-static void dump_adb(dns_adb_t *, FILE *, isc_boolean_t debug, isc_stdtime_t);
-static void print_dns_name(FILE *, dns_name_t *);
-static void print_namehook_list(FILE *, const char *legend,
- dns_adbnamehooklist_t *list,
- isc_boolean_t debug,
- isc_stdtime_t now);
-static void print_find_list(FILE *, dns_adbname_t *);
-static void print_fetch_list(FILE *, dns_adbname_t *);
-static inline isc_boolean_t dec_adb_irefcnt(dns_adb_t *);
-static inline void inc_adb_irefcnt(dns_adb_t *);
-static inline void inc_adb_erefcnt(dns_adb_t *);
-static inline void inc_entry_refcnt(dns_adb_t *, dns_adbentry_t *,
- isc_boolean_t);
-static inline isc_boolean_t dec_entry_refcnt(dns_adb_t *, isc_boolean_t,
- dns_adbentry_t *, isc_boolean_t);
-static inline void violate_locking_hierarchy(isc_mutex_t *, isc_mutex_t *);
-static isc_boolean_t clean_namehooks(dns_adb_t *, dns_adbnamehooklist_t *);
-static void clean_target(dns_adb_t *, dns_name_t *);
-static void clean_finds_at_name(dns_adbname_t *, isc_eventtype_t,
- unsigned int);
-static isc_boolean_t check_expire_namehooks(dns_adbname_t *, isc_stdtime_t);
-static isc_boolean_t check_expire_entry(dns_adb_t *, dns_adbentry_t **,
- isc_stdtime_t);
-static void cancel_fetches_at_name(dns_adbname_t *);
-static isc_result_t dbfind_name(dns_adbname_t *, isc_stdtime_t,
- dns_rdatatype_t);
-static isc_result_t fetch_name(dns_adbname_t *, isc_boolean_t,
- dns_rdatatype_t);
-static inline void check_exit(dns_adb_t *);
-static void destroy(dns_adb_t *);
-static isc_boolean_t shutdown_names(dns_adb_t *);
-static isc_boolean_t shutdown_entries(dns_adb_t *);
-static inline void link_name(dns_adb_t *, int, dns_adbname_t *);
-static inline isc_boolean_t unlink_name(dns_adb_t *, dns_adbname_t *);
-static inline void link_entry(dns_adb_t *, int, dns_adbentry_t *);
-static inline isc_boolean_t unlink_entry(dns_adb_t *, dns_adbentry_t *);
-static isc_boolean_t kill_name(dns_adbname_t **, isc_eventtype_t);
-static void water(void *, int);
-static void dump_entry(FILE *, dns_adbentry_t *, isc_boolean_t, isc_stdtime_t);
-
-/*
- * MUST NOT overlap DNS_ADBFIND_* flags!
- */
-#define FIND_EVENT_SENT 0x40000000
-#define FIND_EVENT_FREED 0x80000000
-#define FIND_EVENTSENT(h) (((h)->flags & FIND_EVENT_SENT) != 0)
-#define FIND_EVENTFREED(h) (((h)->flags & FIND_EVENT_FREED) != 0)
-
-#define NAME_NEEDS_POKE 0x80000000
-#define NAME_IS_DEAD 0x40000000
-#define NAME_HINT_OK DNS_ADBFIND_HINTOK
-#define NAME_GLUE_OK DNS_ADBFIND_GLUEOK
-#define NAME_STARTATZONE DNS_ADBFIND_STARTATZONE
-#define NAME_DEAD(n) (((n)->flags & NAME_IS_DEAD) != 0)
-#define NAME_NEEDSPOKE(n) (((n)->flags & NAME_NEEDS_POKE) != 0)
-#define NAME_GLUEOK(n) (((n)->flags & NAME_GLUE_OK) != 0)
-#define NAME_HINTOK(n) (((n)->flags & NAME_HINT_OK) != 0)
-
-/*
- * Private flag(s) for entries.
- * MUST NOT overlap FCTX_ADDRINFO_xxx and DNS_FETCHOPT_NOEDNS0.
- */
-#define ENTRY_IS_DEAD 0x80000000
-
-/*
- * To the name, address classes are all that really exist. If it has a
- * V6 address it doesn't care if it came from a AAAA query.
- */
-#define NAME_HAS_V4(n) (!ISC_LIST_EMPTY((n)->v4))
-#define NAME_HAS_V6(n) (!ISC_LIST_EMPTY((n)->v6))
-#define NAME_HAS_ADDRS(n) (NAME_HAS_V4(n) || NAME_HAS_V6(n))
-
-/*
- * Fetches are broken out into A and AAAA types. In some cases,
- * however, it makes more sense to test for a particular class of fetches,
- * like V4 or V6 above.
- * Note: since we have removed the support of A6 in adb, FETCH_A and FETCH_AAAA
- * are now equal to FETCH_V4 and FETCH_V6, respectively.
- */
-#define NAME_FETCH_A(n) ((n)->fetch_a != NULL)
-#define NAME_FETCH_AAAA(n) ((n)->fetch_aaaa != NULL)
-#define NAME_FETCH_V4(n) (NAME_FETCH_A(n))
-#define NAME_FETCH_V6(n) (NAME_FETCH_AAAA(n))
-#define NAME_FETCH(n) (NAME_FETCH_V4(n) || NAME_FETCH_V6(n))
-
-/*
- * Find options and tests to see if there are addresses on the list.
- */
-#define FIND_WANTEVENT(fn) (((fn)->options & DNS_ADBFIND_WANTEVENT) != 0)
-#define FIND_WANTEMPTYEVENT(fn) (((fn)->options & DNS_ADBFIND_EMPTYEVENT) != 0)
-#define FIND_AVOIDFETCHES(fn) (((fn)->options & DNS_ADBFIND_AVOIDFETCHES) \
- != 0)
-#define FIND_STARTATZONE(fn) (((fn)->options & DNS_ADBFIND_STARTATZONE) \
- != 0)
-#define FIND_HINTOK(fn) (((fn)->options & DNS_ADBFIND_HINTOK) != 0)
-#define FIND_GLUEOK(fn) (((fn)->options & DNS_ADBFIND_GLUEOK) != 0)
-#define FIND_HAS_ADDRS(fn) (!ISC_LIST_EMPTY((fn)->list))
-#define FIND_RETURNLAME(fn) (((fn)->options & DNS_ADBFIND_RETURNLAME) != 0)
-
-/*
- * These are currently used on simple unsigned ints, so they are
- * not really associated with any particular type.
- */
-#define WANT_INET(x) (((x) & DNS_ADBFIND_INET) != 0)
-#define WANT_INET6(x) (((x) & DNS_ADBFIND_INET6) != 0)
-
-#define EXPIRE_OK(exp, now) ((exp == INT_MAX) || (exp < now))
-
-/*
- * Find out if the flags on a name (nf) indicate if it is a hint or
- * glue, and compare this to the appropriate bits set in o, to see if
- * this is ok.
- */
-#define GLUE_OK(nf, o) (!NAME_GLUEOK(nf) || (((o) & DNS_ADBFIND_GLUEOK) != 0))
-#define HINT_OK(nf, o) (!NAME_HINTOK(nf) || (((o) & DNS_ADBFIND_HINTOK) != 0))
-#define GLUEHINT_OK(nf, o) (GLUE_OK(nf, o) || HINT_OK(nf, o))
-#define STARTATZONE_MATCHES(nf, o) (((nf)->flags & NAME_STARTATZONE) == \
- ((o) & DNS_ADBFIND_STARTATZONE))
-
-#define ENTER_LEVEL ISC_LOG_DEBUG(50)
-#define EXIT_LEVEL ENTER_LEVEL
-#define CLEAN_LEVEL ISC_LOG_DEBUG(100)
-#define DEF_LEVEL ISC_LOG_DEBUG(5)
-#define NCACHE_LEVEL ISC_LOG_DEBUG(20)
-
-#define NCACHE_RESULT(r) ((r) == DNS_R_NCACHENXDOMAIN || \
- (r) == DNS_R_NCACHENXRRSET)
-#define AUTH_NX(r) ((r) == DNS_R_NXDOMAIN || \
- (r) == DNS_R_NXRRSET)
-#define NXDOMAIN_RESULT(r) ((r) == DNS_R_NXDOMAIN || \
- (r) == DNS_R_NCACHENXDOMAIN)
-#define NXRRSET_RESULT(r) ((r) == DNS_R_NCACHENXRRSET || \
- (r) == DNS_R_NXRRSET || \
- (r) == DNS_R_HINTNXRRSET)
-
-/*
- * Error state rankings.
- */
-
-#define FIND_ERR_SUCCESS 0 /* highest rank */
-#define FIND_ERR_CANCELED 1
-#define FIND_ERR_FAILURE 2
-#define FIND_ERR_NXDOMAIN 3
-#define FIND_ERR_NXRRSET 4
-#define FIND_ERR_UNEXPECTED 5
-#define FIND_ERR_NOTFOUND 6
-#define FIND_ERR_MAX 7
-
-static const char *errnames[] = {
- "success",
- "canceled",
- "failure",
- "nxdomain",
- "nxrrset",
- "unexpected",
- "not_found"
-};
-
-#define NEWERR(old, new) (ISC_MIN((old), (new)))
-
-static isc_result_t find_err_map[FIND_ERR_MAX] = {
- ISC_R_SUCCESS,
- ISC_R_CANCELED,
- ISC_R_FAILURE,
- DNS_R_NXDOMAIN,
- DNS_R_NXRRSET,
- ISC_R_UNEXPECTED,
- ISC_R_NOTFOUND /* not YET found */
-};
-
-static void
-DP(int level, const char *format, ...) ISC_FORMAT_PRINTF(2, 3);
-
-static void
-DP(int level, const char *format, ...) {
- va_list args;
-
- va_start(args, format);
- isc_log_vwrite(dns_lctx,
- DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ADB,
- level, format, args);
- va_end(args);
-}
-
-/*%
- * Increment resolver-related statistics counters.
- */
-static inline void
-inc_stats(dns_adb_t *adb, isc_statscounter_t counter) {
- if (adb->view->resstats != NULL)
- isc_stats_increment(adb->view->resstats, counter);
-}
-
-static inline dns_ttl_t
-ttlclamp(dns_ttl_t ttl) {
- if (ttl < ADB_CACHE_MINIMUM)
- ttl = ADB_CACHE_MINIMUM;
- if (ttl > ADB_CACHE_MAXIMUM)
- ttl = ADB_CACHE_MAXIMUM;
-
- return (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);
-
- result = isc_task_beginexclusive(task);
- if (result != ISC_R_SUCCESS)
- goto check_exit;
-
- 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);
-
- check_exit:
- 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);
-
- result = isc_task_beginexclusive(task);
- if (result != ISC_R_SUCCESS)
- goto check_exit;
-
- 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);
-
- check_exit:
- 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.
- */
-static isc_result_t
-import_rdataset(dns_adbname_t *adbname, dns_rdataset_t *rdataset,
- isc_stdtime_t now)
-{
- isc_result_t result;
- dns_adb_t *adb;
- dns_adbnamehook_t *nh;
- dns_adbnamehook_t *anh;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- struct in_addr ina;
- struct in6_addr in6a;
- isc_sockaddr_t sockaddr;
- dns_adbentry_t *foundentry; /* NO CLEAN UP! */
- int addr_bucket;
- isc_boolean_t new_addresses_added;
- dns_rdatatype_t rdtype;
- unsigned int findoptions;
- dns_adbnamehooklist_t *hookhead;
-
- INSIST(DNS_ADBNAME_VALID(adbname));
- adb = adbname->adb;
- INSIST(DNS_ADB_VALID(adb));
-
- rdtype = rdataset->type;
- INSIST((rdtype == dns_rdatatype_a) || (rdtype == dns_rdatatype_aaaa));
- if (rdtype == dns_rdatatype_a)
- findoptions = DNS_ADBFIND_INET;
- else
- findoptions = DNS_ADBFIND_INET6;
-
- addr_bucket = DNS_ADB_INVALIDBUCKET;
- new_addresses_added = ISC_FALSE;
-
- nh = NULL;
- result = dns_rdataset_first(rdataset);
- while (result == ISC_R_SUCCESS) {
- dns_rdata_reset(&rdata);
- dns_rdataset_current(rdataset, &rdata);
- if (rdtype == dns_rdatatype_a) {
- INSIST(rdata.length == 4);
- memcpy(&ina.s_addr, rdata.data, 4);
- isc_sockaddr_fromin(&sockaddr, &ina, 0);
- hookhead = &adbname->v4;
- } else {
- INSIST(rdata.length == 16);
- memcpy(in6a.s6_addr, rdata.data, 16);
- isc_sockaddr_fromin6(&sockaddr, &in6a, 0);
- hookhead = &adbname->v6;
- }
-
- INSIST(nh == NULL);
- nh = new_adbnamehook(adb, NULL);
- if (nh == NULL) {
- adbname->partial_result |= findoptions;
- result = ISC_R_NOMEMORY;
- goto fail;
- }
-
- foundentry = find_entry_and_lock(adb, &sockaddr, &addr_bucket,
- now);
- if (foundentry == NULL) {
- dns_adbentry_t *entry;
-
- entry = new_adbentry(adb);
- if (entry == NULL) {
- adbname->partial_result |= findoptions;
- result = ISC_R_NOMEMORY;
- goto fail;
- }
-
- entry->sockaddr = sockaddr;
- entry->refcnt = 1;
-
- nh->entry = entry;
-
- link_entry(adb, addr_bucket, entry);
- } else {
- for (anh = ISC_LIST_HEAD(*hookhead);
- anh != NULL;
- anh = ISC_LIST_NEXT(anh, plink))
- if (anh->entry == foundentry)
- break;
- if (anh == NULL) {
- foundentry->refcnt++;
- nh->entry = foundentry;
- } else
- free_adbnamehook(adb, &nh);
- }
-
- new_addresses_added = ISC_TRUE;
- if (nh != NULL)
- ISC_LIST_APPEND(*hookhead, nh, plink);
- nh = NULL;
- result = dns_rdataset_next(rdataset);
- }
-
- fail:
- if (nh != NULL)
- free_adbnamehook(adb, &nh);
-
- if (addr_bucket != DNS_ADB_INVALIDBUCKET)
- UNLOCK(&adb->entrylocks[addr_bucket]);
-
- if (rdataset->trust == dns_trust_glue ||
- rdataset->trust == dns_trust_additional)
- rdataset->ttl = ADB_CACHE_MINIMUM;
- else if (rdataset->trust == dns_trust_ultimate)
- rdataset->ttl = 0;
- else
- rdataset->ttl = ttlclamp(rdataset->ttl);
-
- if (rdtype == dns_rdatatype_a) {
- DP(NCACHE_LEVEL, "expire_v4 set to MIN(%u,%u) import_rdataset",
- adbname->expire_v4, now + rdataset->ttl);
- adbname->expire_v4 = ISC_MIN(adbname->expire_v4,
- now + rdataset->ttl);
- } else {
- DP(NCACHE_LEVEL, "expire_v6 set to MIN(%u,%u) import_rdataset",
- adbname->expire_v6, now + rdataset->ttl);
- adbname->expire_v6 = ISC_MIN(adbname->expire_v6,
- now + rdataset->ttl);
- }
-
- if (new_addresses_added) {
- /*
- * Lie a little here. This is more or less so code that cares
- * can find out if any new information was added or not.
- */
- return (ISC_R_SUCCESS);
- }
-
- return (result);
-}
-
-/*
- * Requires the name's bucket be locked.
- */
-static isc_boolean_t
-kill_name(dns_adbname_t **n, isc_eventtype_t ev) {
- dns_adbname_t *name;
- isc_boolean_t result = ISC_FALSE;
- isc_boolean_t result4, result6;
- int bucket;
- dns_adb_t *adb;
-
- INSIST(n != NULL);
- name = *n;
- *n = NULL;
- INSIST(DNS_ADBNAME_VALID(name));
- adb = name->adb;
- INSIST(DNS_ADB_VALID(adb));
-
- DP(DEF_LEVEL, "killing name %p", name);
-
- /*
- * If we're dead already, just check to see if we should go
- * away now or not.
- */
- if (NAME_DEAD(name) && !NAME_FETCH(name)) {
- result = unlink_name(adb, name);
- free_adbname(adb, &name);
- if (result)
- result = dec_adb_irefcnt(adb);
- return (result);
- }
-
- /*
- * Clean up the name's various lists. These two are destructive
- * in that they will always empty the list.
- */
- clean_finds_at_name(name, ev, DNS_ADBFIND_ADDRESSMASK);
- result4 = clean_namehooks(adb, &name->v4);
- result6 = clean_namehooks(adb, &name->v6);
- clean_target(adb, &name->target);
- result = ISC_TF(result4 || result6);
-
- /*
- * If fetches are running, cancel them. If none are running, we can
- * just kill the name here.
- */
- if (!NAME_FETCH(name)) {
- INSIST(result == ISC_FALSE);
- result = unlink_name(adb, name);
- free_adbname(adb, &name);
- if (result)
- result = dec_adb_irefcnt(adb);
- } else {
- cancel_fetches_at_name(name);
- if (!NAME_DEAD(name)) {
- bucket = name->lock_bucket;
- ISC_LIST_UNLINK(adb->names[bucket], name, plink);
- ISC_LIST_APPEND(adb->deadnames[bucket], name, plink);
- name->flags |= NAME_IS_DEAD;
- }
- }
- return (result);
-}
-
-/*
- * Requires the name's bucket be locked and no entry buckets be locked.
- */
-static isc_boolean_t
-check_expire_namehooks(dns_adbname_t *name, isc_stdtime_t now) {
- dns_adb_t *adb;
- isc_boolean_t result4 = ISC_FALSE;
- isc_boolean_t result6 = ISC_FALSE;
-
- INSIST(DNS_ADBNAME_VALID(name));
- adb = name->adb;
- INSIST(DNS_ADB_VALID(adb));
-
- /*
- * Check to see if we need to remove the v4 addresses
- */
- if (!NAME_FETCH_V4(name) && EXPIRE_OK(name->expire_v4, now)) {
- if (NAME_HAS_V4(name)) {
- DP(DEF_LEVEL, "expiring v4 for name %p", name);
- result4 = clean_namehooks(adb, &name->v4);
- name->partial_result &= ~DNS_ADBFIND_INET;
- }
- name->expire_v4 = INT_MAX;
- name->fetch_err = FIND_ERR_UNEXPECTED;
- }
-
- /*
- * Check to see if we need to remove the v6 addresses
- */
- if (!NAME_FETCH_V6(name) && EXPIRE_OK(name->expire_v6, now)) {
- if (NAME_HAS_V6(name)) {
- DP(DEF_LEVEL, "expiring v6 for name %p", name);
- result6 = clean_namehooks(adb, &name->v6);
- name->partial_result &= ~DNS_ADBFIND_INET6;
- }
- name->expire_v6 = INT_MAX;
- name->fetch6_err = FIND_ERR_UNEXPECTED;
- }
-
- /*
- * Check to see if we need to remove the alias target.
- */
- if (EXPIRE_OK(name->expire_target, now)) {
- clean_target(adb, &name->target);
- name->expire_target = INT_MAX;
- }
- return (ISC_TF(result4 || result6));
-}
-
-/*
- * Requires the name's bucket be locked.
- */
-static inline void
-link_name(dns_adb_t *adb, int bucket, dns_adbname_t *name) {
- INSIST(name->lock_bucket == DNS_ADB_INVALIDBUCKET);
-
- ISC_LIST_PREPEND(adb->names[bucket], name, plink);
- name->lock_bucket = bucket;
- adb->name_refcnt[bucket]++;
-}
-
-/*
- * Requires the name's bucket be locked.
- */
-static inline isc_boolean_t
-unlink_name(dns_adb_t *adb, dns_adbname_t *name) {
- int bucket;
- isc_boolean_t result = ISC_FALSE;
-
- bucket = name->lock_bucket;
- INSIST(bucket != DNS_ADB_INVALIDBUCKET);
-
- if (NAME_DEAD(name))
- ISC_LIST_UNLINK(adb->deadnames[bucket], name, plink);
- else
- ISC_LIST_UNLINK(adb->names[bucket], name, plink);
- name->lock_bucket = DNS_ADB_INVALIDBUCKET;
- INSIST(adb->name_refcnt[bucket] > 0);
- adb->name_refcnt[bucket]--;
- if (adb->name_sd[bucket] && adb->name_refcnt[bucket] == 0)
- result = ISC_TRUE;
- return (result);
-}
-
-/*
- * Requires the entry's bucket be locked.
- */
-static inline void
-link_entry(dns_adb_t *adb, int bucket, dns_adbentry_t *entry) {
- int i;
- dns_adbentry_t *e;
-
- if (isc_mem_isovermem(adb->mctx)) {
- for (i = 0; i < 2; i++) {
- e = ISC_LIST_TAIL(adb->entries[bucket]);
- if (e == NULL)
- break;
- if (e->refcnt == 0) {
- unlink_entry(adb, e);
- free_adbentry(adb, &e);
- continue;
- }
- INSIST((e->flags & ENTRY_IS_DEAD) == 0);
- e->flags |= ENTRY_IS_DEAD;
- ISC_LIST_UNLINK(adb->entries[bucket], e, plink);
- ISC_LIST_PREPEND(adb->deadentries[bucket], e, plink);
- }
- }
-
- ISC_LIST_PREPEND(adb->entries[bucket], entry, plink);
- entry->lock_bucket = bucket;
- adb->entry_refcnt[bucket]++;
-}
-
-/*
- * Requires the entry's bucket be locked.
- */
-static inline isc_boolean_t
-unlink_entry(dns_adb_t *adb, dns_adbentry_t *entry) {
- int bucket;
- isc_boolean_t result = ISC_FALSE;
-
- bucket = entry->lock_bucket;
- INSIST(bucket != DNS_ADB_INVALIDBUCKET);
-
- if ((entry->flags & ENTRY_IS_DEAD) != 0)
- ISC_LIST_UNLINK(adb->deadentries[bucket], entry, plink);
- else
- ISC_LIST_UNLINK(adb->entries[bucket], entry, plink);
- entry->lock_bucket = DNS_ADB_INVALIDBUCKET;
- INSIST(adb->entry_refcnt[bucket] > 0);
- adb->entry_refcnt[bucket]--;
- if (adb->entry_sd[bucket] && adb->entry_refcnt[bucket] == 0)
- result = ISC_TRUE;
- return (result);
-}
-
-static inline void
-violate_locking_hierarchy(isc_mutex_t *have, isc_mutex_t *want) {
- if (isc_mutex_trylock(want) != ISC_R_SUCCESS) {
- UNLOCK(have);
- LOCK(want);
- LOCK(have);
- }
-}
-
-/*
- * The ADB _MUST_ be locked before calling. Also, exit conditions must be
- * checked after calling this function.
- */
-static isc_boolean_t
-shutdown_names(dns_adb_t *adb) {
- unsigned int bucket;
- isc_boolean_t result = ISC_FALSE;
- dns_adbname_t *name;
- dns_adbname_t *next_name;
-
- for (bucket = 0; bucket < adb->nnames; bucket++) {
- LOCK(&adb->namelocks[bucket]);
- adb->name_sd[bucket] = ISC_TRUE;
-
- name = ISC_LIST_HEAD(adb->names[bucket]);
- if (name == NULL) {
- /*
- * This bucket has no names. We must decrement the
- * irefcnt ourselves, since it will not be
- * automatically triggered by a name being unlinked.
- */
- INSIST(result == ISC_FALSE);
- result = dec_adb_irefcnt(adb);
- } else {
- /*
- * Run through the list. For each name, clean up finds
- * found there, and cancel any fetches running. When
- * all the fetches are canceled, the name will destroy
- * itself.
- */
- while (name != NULL) {
- next_name = ISC_LIST_NEXT(name, plink);
- INSIST(result == ISC_FALSE);
- result = kill_name(&name,
- DNS_EVENT_ADBSHUTDOWN);
- name = next_name;
- }
- }
-
- UNLOCK(&adb->namelocks[bucket]);
- }
- return (result);
-}
-
-/*
- * The ADB _MUST_ be locked before calling. Also, exit conditions must be
- * checked after calling this function.
- */
-static isc_boolean_t
-shutdown_entries(dns_adb_t *adb) {
- unsigned int bucket;
- isc_boolean_t result = ISC_FALSE;
- dns_adbentry_t *entry;
- dns_adbentry_t *next_entry;
-
- for (bucket = 0; bucket < adb->nentries; bucket++) {
- LOCK(&adb->entrylocks[bucket]);
- adb->entry_sd[bucket] = ISC_TRUE;
-
- entry = ISC_LIST_HEAD(adb->entries[bucket]);
- if (adb->entry_refcnt[bucket] == 0) {
- /*
- * This bucket has no entries. We must decrement the
- * irefcnt ourselves, since it will not be
- * automatically triggered by an entry being unlinked.
- */
- result = dec_adb_irefcnt(adb);
- } else {
- /*
- * Run through the list. Cleanup any entries not
- * associated with names, and which are not in use.
- */
- while (entry != NULL) {
- next_entry = ISC_LIST_NEXT(entry, plink);
- if (entry->refcnt == 0 &&
- entry->expires != 0) {
- result = unlink_entry(adb, entry);
- free_adbentry(adb, &entry);
- if (result)
- result = dec_adb_irefcnt(adb);
- }
- entry = next_entry;
- }
- }
-
- UNLOCK(&adb->entrylocks[bucket]);
- }
- return (result);
-}
-
-/*
- * Name bucket must be locked
- */
-static void
-cancel_fetches_at_name(dns_adbname_t *name) {
- if (NAME_FETCH_A(name))
- dns_resolver_cancelfetch(name->fetch_a->fetch);
-
- if (NAME_FETCH_AAAA(name))
- dns_resolver_cancelfetch(name->fetch_aaaa->fetch);
-}
-
-/*
- * Assumes the name bucket is locked.
- */
-static isc_boolean_t
-clean_namehooks(dns_adb_t *adb, dns_adbnamehooklist_t *namehooks) {
- dns_adbentry_t *entry;
- dns_adbnamehook_t *namehook;
- int addr_bucket;
- isc_boolean_t result = ISC_FALSE;
- isc_boolean_t overmem = isc_mem_isovermem(adb->mctx);
-
- addr_bucket = DNS_ADB_INVALIDBUCKET;
- namehook = ISC_LIST_HEAD(*namehooks);
- while (namehook != NULL) {
- INSIST(DNS_ADBNAMEHOOK_VALID(namehook));
-
- /*
- * Clean up the entry if needed.
- */
- entry = namehook->entry;
- if (entry != NULL) {
- INSIST(DNS_ADBENTRY_VALID(entry));
-
- if (addr_bucket != entry->lock_bucket) {
- if (addr_bucket != DNS_ADB_INVALIDBUCKET)
- UNLOCK(&adb->entrylocks[addr_bucket]);
- addr_bucket = entry->lock_bucket;
- INSIST(addr_bucket != DNS_ADB_INVALIDBUCKET);
- LOCK(&adb->entrylocks[addr_bucket]);
- }
-
- result = dec_entry_refcnt(adb, overmem, entry,
- ISC_FALSE);
- }
-
- /*
- * Free the namehook
- */
- namehook->entry = NULL;
- ISC_LIST_UNLINK(*namehooks, namehook, plink);
- free_adbnamehook(adb, &namehook);
-
- namehook = ISC_LIST_HEAD(*namehooks);
- }
-
- if (addr_bucket != DNS_ADB_INVALIDBUCKET)
- UNLOCK(&adb->entrylocks[addr_bucket]);
- return (result);
-}
-
-static void
-clean_target(dns_adb_t *adb, dns_name_t *target) {
- if (dns_name_countlabels(target) > 0) {
- dns_name_free(target, adb->mctx);
- dns_name_init(target, NULL);
- }
-}
-
-static isc_result_t
-set_target(dns_adb_t *adb, dns_name_t *name, dns_name_t *fname,
- dns_rdataset_t *rdataset, dns_name_t *target)
-{
- isc_result_t result;
- dns_namereln_t namereln;
- unsigned int nlabels;
- int order;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_fixedname_t fixed1, fixed2;
- dns_name_t *prefix, *new_target;
-
- REQUIRE(dns_name_countlabels(target) == 0);
-
- if (rdataset->type == dns_rdatatype_cname) {
- dns_rdata_cname_t cname;
-
- /*
- * Copy the CNAME's target into the target name.
- */
- result = dns_rdataset_first(rdataset);
- if (result != ISC_R_SUCCESS)
- return (result);
- dns_rdataset_current(rdataset, &rdata);
- result = dns_rdata_tostruct(&rdata, &cname, NULL);
- if (result != ISC_R_SUCCESS)
- return (result);
- result = dns_name_dup(&cname.cname, adb->mctx, target);
- dns_rdata_freestruct(&cname);
- if (result != ISC_R_SUCCESS)
- return (result);
- } else {
- dns_rdata_dname_t dname;
-
- INSIST(rdataset->type == dns_rdatatype_dname);
- namereln = dns_name_fullcompare(name, fname, &order, &nlabels);
- INSIST(namereln == dns_namereln_subdomain);
- /*
- * Get the target name of the DNAME.
- */
- result = dns_rdataset_first(rdataset);
- if (result != ISC_R_SUCCESS)
- return (result);
- dns_rdataset_current(rdataset, &rdata);
- result = dns_rdata_tostruct(&rdata, &dname, NULL);
- if (result != ISC_R_SUCCESS)
- return (result);
- /*
- * Construct the new target name.
- */
- dns_fixedname_init(&fixed1);
- prefix = dns_fixedname_name(&fixed1);
- dns_fixedname_init(&fixed2);
- new_target = dns_fixedname_name(&fixed2);
- dns_name_split(name, nlabels, prefix, NULL);
- result = dns_name_concatenate(prefix, &dname.dname, new_target,
- NULL);
- dns_rdata_freestruct(&dname);
- if (result != ISC_R_SUCCESS)
- return (result);
- result = dns_name_dup(new_target, adb->mctx, target);
- if (result != ISC_R_SUCCESS)
- return (result);
- }
-
- return (ISC_R_SUCCESS);
-}
-
-/*
- * Assumes nothing is locked, since this is called by the client.
- */
-static void
-event_free(isc_event_t *event) {
- dns_adbfind_t *find;
-
- INSIST(event != NULL);
- find = event->ev_destroy_arg;
- INSIST(DNS_ADBFIND_VALID(find));
-
- LOCK(&find->lock);
- find->flags |= FIND_EVENT_FREED;
- event->ev_destroy_arg = NULL;
- UNLOCK(&find->lock);
-}
-
-/*
- * Assumes the name bucket is locked.
- */
-static void
-clean_finds_at_name(dns_adbname_t *name, isc_eventtype_t evtype,
- unsigned int addrs)
-{
- isc_event_t *ev;
- isc_task_t *task;
- dns_adbfind_t *find;
- dns_adbfind_t *next_find;
- isc_boolean_t process;
- unsigned int wanted, notify;
-
- DP(ENTER_LEVEL,
- "ENTER clean_finds_at_name, name %p, evtype %08x, addrs %08x",
- name, evtype, addrs);
-
- find = ISC_LIST_HEAD(name->finds);
- while (find != NULL) {
- LOCK(&find->lock);
- next_find = ISC_LIST_NEXT(find, plink);
-
- process = ISC_FALSE;
- wanted = find->flags & DNS_ADBFIND_ADDRESSMASK;
- notify = wanted & addrs;
-
- switch (evtype) {
- case DNS_EVENT_ADBMOREADDRESSES:
- DP(ISC_LOG_DEBUG(3), "DNS_EVENT_ADBMOREADDRESSES");
- if ((notify) != 0) {
- find->flags &= ~addrs;
- process = ISC_TRUE;
- }
- break;
- case DNS_EVENT_ADBNOMOREADDRESSES:
- DP(ISC_LOG_DEBUG(3), "DNS_EVENT_ADBNOMOREADDRESSES");
- find->flags &= ~addrs;
- wanted = find->flags & DNS_ADBFIND_ADDRESSMASK;
- if (wanted == 0)
- process = ISC_TRUE;
- break;
- default:
- find->flags &= ~addrs;
- process = ISC_TRUE;
- }
-
- if (process) {
- DP(DEF_LEVEL, "cfan: processing find %p", find);
- /*
- * Unlink the find from the name, letting the caller
- * call dns_adb_destroyfind() on it to clean it up
- * later.
- */
- ISC_LIST_UNLINK(name->finds, find, plink);
- find->adbname = NULL;
- find->name_bucket = DNS_ADB_INVALIDBUCKET;
-
- INSIST(!FIND_EVENTSENT(find));
-
- ev = &find->event;
- task = ev->ev_sender;
- ev->ev_sender = find;
- find->result_v4 = find_err_map[name->fetch_err];
- find->result_v6 = find_err_map[name->fetch6_err];
- ev->ev_type = evtype;
- ev->ev_destroy = event_free;
- ev->ev_destroy_arg = find;
-
- DP(DEF_LEVEL,
- "sending event %p to task %p for find %p",
- ev, task, find);
-
- isc_task_sendanddetach(&task, (isc_event_t **)&ev);
- } else {
- DP(DEF_LEVEL, "cfan: skipping find %p", find);
- }
-
- UNLOCK(&find->lock);
- find = next_find;
- }
-
- DP(ENTER_LEVEL, "EXIT clean_finds_at_name, name %p", name);
-}
-
-static inline void
-check_exit(dns_adb_t *adb) {
- isc_event_t *event;
- /*
- * The caller must be holding the adb lock.
- */
- if (adb->shutting_down) {
- /*
- * If there aren't any external references either, we're
- * done. Send the control event to initiate shutdown.
- */
- INSIST(!adb->cevent_sent); /* Sanity check. */
- event = &adb->cevent;
- isc_task_send(adb->task, &event);
- adb->cevent_sent = ISC_TRUE;
- }
-}
-
-static inline isc_boolean_t
-dec_adb_irefcnt(dns_adb_t *adb) {
- isc_event_t *event;
- isc_task_t *etask;
- isc_boolean_t result = ISC_FALSE;
-
- LOCK(&adb->reflock);
-
- INSIST(adb->irefcnt > 0);
- adb->irefcnt--;
-
- if (adb->irefcnt == 0) {
- event = ISC_LIST_HEAD(adb->whenshutdown);
- while (event != NULL) {
- ISC_LIST_UNLINK(adb->whenshutdown, event, ev_link);
- etask = event->ev_sender;
- event->ev_sender = adb;
- isc_task_sendanddetach(&etask, &event);
- event = ISC_LIST_HEAD(adb->whenshutdown);
- }
- }
-
- if (adb->irefcnt == 0 && adb->erefcnt == 0)
- result = ISC_TRUE;
- UNLOCK(&adb->reflock);
- return (result);
-}
-
-static inline void
-inc_adb_irefcnt(dns_adb_t *adb) {
- LOCK(&adb->reflock);
- adb->irefcnt++;
- UNLOCK(&adb->reflock);
-}
-
-static inline void
-inc_adb_erefcnt(dns_adb_t *adb) {
- LOCK(&adb->reflock);
- adb->erefcnt++;
- UNLOCK(&adb->reflock);
-}
-
-static inline void
-inc_entry_refcnt(dns_adb_t *adb, dns_adbentry_t *entry, isc_boolean_t lock) {
- int bucket;
-
- bucket = entry->lock_bucket;
-
- if (lock)
- LOCK(&adb->entrylocks[bucket]);
-
- entry->refcnt++;
-
- if (lock)
- UNLOCK(&adb->entrylocks[bucket]);
-}
-
-static inline isc_boolean_t
-dec_entry_refcnt(dns_adb_t *adb, isc_boolean_t overmem, dns_adbentry_t *entry,
- isc_boolean_t lock)
-{
- int bucket;
- isc_boolean_t destroy_entry;
- isc_boolean_t result = ISC_FALSE;
-
- bucket = entry->lock_bucket;
-
- if (lock)
- LOCK(&adb->entrylocks[bucket]);
-
- INSIST(entry->refcnt > 0);
- entry->refcnt--;
-
- destroy_entry = ISC_FALSE;
- if (entry->refcnt == 0 &&
- (adb->entry_sd[bucket] || entry->expires == 0 || overmem ||
- (entry->flags & ENTRY_IS_DEAD) != 0)) {
- destroy_entry = ISC_TRUE;
- result = unlink_entry(adb, entry);
- }
-
- if (lock)
- UNLOCK(&adb->entrylocks[bucket]);
-
- if (!destroy_entry)
- return (result);
-
- entry->lock_bucket = DNS_ADB_INVALIDBUCKET;
-
- free_adbentry(adb, &entry);
- if (result)
- result = dec_adb_irefcnt(adb);
-
- return (result);
-}
-
-static inline dns_adbname_t *
-new_adbname(dns_adb_t *adb, dns_name_t *dnsname) {
- dns_adbname_t *name;
-
- name = isc_mempool_get(adb->nmp);
- if (name == NULL)
- return (NULL);
-
- dns_name_init(&name->name, NULL);
- if (dns_name_dup(dnsname, adb->mctx, &name->name) != ISC_R_SUCCESS) {
- isc_mempool_put(adb->nmp, name);
- return (NULL);
- }
- dns_name_init(&name->target, NULL);
- name->magic = DNS_ADBNAME_MAGIC;
- name->adb = adb;
- name->partial_result = 0;
- name->flags = 0;
- name->expire_v4 = INT_MAX;
- name->expire_v6 = INT_MAX;
- name->expire_target = INT_MAX;
- name->chains = 0;
- name->lock_bucket = DNS_ADB_INVALIDBUCKET;
- ISC_LIST_INIT(name->v4);
- ISC_LIST_INIT(name->v6);
- name->fetch_a = NULL;
- name->fetch_aaaa = NULL;
- name->fetch_err = FIND_ERR_UNEXPECTED;
- name->fetch6_err = FIND_ERR_UNEXPECTED;
- ISC_LIST_INIT(name->finds);
- ISC_LINK_INIT(name, plink);
-
- LOCK(&adb->namescntlock);
- adb->namescnt++;
- if (!adb->grownames_sent && adb->excl != NULL &&
- adb->namescnt > (adb->nnames * 8))
- {
- isc_event_t *event = &adb->grownames;
- inc_adb_irefcnt(adb);
- isc_task_send(adb->excl, &event);
- adb->grownames_sent = ISC_TRUE;
- }
- UNLOCK(&adb->namescntlock);
-
- return (name);
-}
-
-static inline void
-free_adbname(dns_adb_t *adb, dns_adbname_t **name) {
- dns_adbname_t *n;
-
- INSIST(name != NULL && DNS_ADBNAME_VALID(*name));
- n = *name;
- *name = NULL;
-
- INSIST(!NAME_HAS_V4(n));
- INSIST(!NAME_HAS_V6(n));
- INSIST(!NAME_FETCH(n));
- INSIST(ISC_LIST_EMPTY(n->finds));
- INSIST(!ISC_LINK_LINKED(n, plink));
- INSIST(n->lock_bucket == DNS_ADB_INVALIDBUCKET);
- INSIST(n->adb == adb);
-
- n->magic = 0;
- 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 *
-new_adbnamehook(dns_adb_t *adb, dns_adbentry_t *entry) {
- dns_adbnamehook_t *nh;
-
- nh = isc_mempool_get(adb->nhmp);
- if (nh == NULL)
- return (NULL);
-
- nh->magic = DNS_ADBNAMEHOOK_MAGIC;
- nh->entry = entry;
- ISC_LINK_INIT(nh, plink);
-
- return (nh);
-}
-
-static inline void
-free_adbnamehook(dns_adb_t *adb, dns_adbnamehook_t **namehook) {
- dns_adbnamehook_t *nh;
-
- INSIST(namehook != NULL && DNS_ADBNAMEHOOK_VALID(*namehook));
- nh = *namehook;
- *namehook = NULL;
-
- INSIST(nh->entry == NULL);
- INSIST(!ISC_LINK_LINKED(nh, plink));
-
- nh->magic = 0;
- isc_mempool_put(adb->nhmp, nh);
-}
-
-static inline dns_adblameinfo_t *
-new_adblameinfo(dns_adb_t *adb, dns_name_t *qname, dns_rdatatype_t qtype) {
- dns_adblameinfo_t *li;
-
- li = isc_mempool_get(adb->limp);
- if (li == NULL)
- return (NULL);
-
- dns_name_init(&li->qname, NULL);
- if (dns_name_dup(qname, adb->mctx, &li->qname) != ISC_R_SUCCESS) {
- isc_mempool_put(adb->limp, li);
- return (NULL);
- }
- li->magic = DNS_ADBLAMEINFO_MAGIC;
- li->lame_timer = 0;
- li->qtype = qtype;
- ISC_LINK_INIT(li, plink);
-
- return (li);
-}
-
-static inline void
-free_adblameinfo(dns_adb_t *adb, dns_adblameinfo_t **lameinfo) {
- dns_adblameinfo_t *li;
-
- INSIST(lameinfo != NULL && DNS_ADBLAMEINFO_VALID(*lameinfo));
- li = *lameinfo;
- *lameinfo = NULL;
-
- INSIST(!ISC_LINK_LINKED(li, plink));
-
- dns_name_free(&li->qname, adb->mctx);
-
- li->magic = 0;
-
- isc_mempool_put(adb->limp, li);
-}
-
-static inline dns_adbentry_t *
-new_adbentry(dns_adb_t *adb) {
- dns_adbentry_t *e;
- isc_uint32_t r;
-
- e = isc_mempool_get(adb->emp);
- if (e == NULL)
- return (NULL);
-
- e->magic = DNS_ADBENTRY_MAGIC;
- e->lock_bucket = DNS_ADB_INVALIDBUCKET;
- e->refcnt = 0;
- e->flags = 0;
- isc_random_get(&r);
- e->srtt = (r & 0x1f) + 1;
- e->expires = 0;
- ISC_LIST_INIT(e->lameinfo);
- ISC_LINK_INIT(e, plink);
- LOCK(&adb->entriescntlock);
- adb->entriescnt++;
- if (!adb->growentries_sent && 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);
-}
-
-static inline void
-free_adbentry(dns_adb_t *adb, dns_adbentry_t **entry) {
- dns_adbentry_t *e;
- dns_adblameinfo_t *li;
-
- INSIST(entry != NULL && DNS_ADBENTRY_VALID(*entry));
- e = *entry;
- *entry = NULL;
-
- INSIST(e->lock_bucket == DNS_ADB_INVALIDBUCKET);
- INSIST(e->refcnt == 0);
- INSIST(!ISC_LINK_LINKED(e, plink));
-
- e->magic = 0;
-
- li = ISC_LIST_HEAD(e->lameinfo);
- while (li != NULL) {
- ISC_LIST_UNLINK(e->lameinfo, li, plink);
- free_adblameinfo(adb, &li);
- li = ISC_LIST_HEAD(e->lameinfo);
- }
-
- isc_mempool_put(adb->emp, e);
- LOCK(&adb->entriescntlock);
- adb->entriescnt--;
- UNLOCK(&adb->entriescntlock);
-}
-
-static inline dns_adbfind_t *
-new_adbfind(dns_adb_t *adb) {
- dns_adbfind_t *h;
- isc_result_t result;
-
- h = isc_mempool_get(adb->ahmp);
- if (h == NULL)
- return (NULL);
-
- /*
- * Public members.
- */
- h->magic = 0;
- h->adb = adb;
- h->partial_result = 0;
- h->options = 0;
- h->flags = 0;
- h->result_v4 = ISC_R_UNEXPECTED;
- h->result_v6 = ISC_R_UNEXPECTED;
- ISC_LINK_INIT(h, publink);
- ISC_LINK_INIT(h, plink);
- ISC_LIST_INIT(h->list);
- h->adbname = NULL;
- h->name_bucket = DNS_ADB_INVALIDBUCKET;
-
- /*
- * private members
- */
- result = isc_mutex_init(&h->lock);
- if (result != ISC_R_SUCCESS) {
- isc_mempool_put(adb->ahmp, h);
- return (NULL);
- }
-
- ISC_EVENT_INIT(&h->event, sizeof(isc_event_t), 0, 0, 0, NULL, NULL,
- NULL, NULL, h);
-
- inc_adb_irefcnt(adb);
- h->magic = DNS_ADBFIND_MAGIC;
- return (h);
-}
-
-static inline dns_adbfetch_t *
-new_adbfetch(dns_adb_t *adb) {
- dns_adbfetch_t *f;
-
- f = isc_mempool_get(adb->afmp);
- if (f == NULL)
- return (NULL);
-
- f->magic = 0;
- f->fetch = NULL;
-
- dns_rdataset_init(&f->rdataset);
-
- f->magic = DNS_ADBFETCH_MAGIC;
-
- return (f);
-}
-
-static inline void
-free_adbfetch(dns_adb_t *adb, dns_adbfetch_t **fetch) {
- dns_adbfetch_t *f;
-
- INSIST(fetch != NULL && DNS_ADBFETCH_VALID(*fetch));
- f = *fetch;
- *fetch = NULL;
-
- f->magic = 0;
-
- if (dns_rdataset_isassociated(&f->rdataset))
- dns_rdataset_disassociate(&f->rdataset);
-
- isc_mempool_put(adb->afmp, f);
-}
-
-static inline isc_boolean_t
-free_adbfind(dns_adb_t *adb, dns_adbfind_t **findp) {
- dns_adbfind_t *find;
-
- INSIST(findp != NULL && DNS_ADBFIND_VALID(*findp));
- find = *findp;
- *findp = NULL;
-
- INSIST(!FIND_HAS_ADDRS(find));
- INSIST(!ISC_LINK_LINKED(find, publink));
- INSIST(!ISC_LINK_LINKED(find, plink));
- INSIST(find->name_bucket == DNS_ADB_INVALIDBUCKET);
- INSIST(find->adbname == NULL);
-
- find->magic = 0;
-
- DESTROYLOCK(&find->lock);
- isc_mempool_put(adb->ahmp, find);
- return (dec_adb_irefcnt(adb));
-}
-
-/*
- * Copy bits from the entry into the newly allocated addrinfo. The entry
- * must be locked, and the reference count must be bumped up by one
- * if this function returns a valid pointer.
- */
-static inline dns_adbaddrinfo_t *
-new_adbaddrinfo(dns_adb_t *adb, dns_adbentry_t *entry, in_port_t port) {
- dns_adbaddrinfo_t *ai;
-
- ai = isc_mempool_get(adb->aimp);
- if (ai == NULL)
- return (NULL);
-
- ai->magic = DNS_ADBADDRINFO_MAGIC;
- ai->sockaddr = entry->sockaddr;
- isc_sockaddr_setport(&ai->sockaddr, port);
- ai->srtt = entry->srtt;
- ai->flags = entry->flags;
- ai->entry = entry;
- ISC_LINK_INIT(ai, publink);
-
- return (ai);
-}
-
-static inline void
-free_adbaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **ainfo) {
- dns_adbaddrinfo_t *ai;
-
- INSIST(ainfo != NULL && DNS_ADBADDRINFO_VALID(*ainfo));
- ai = *ainfo;
- *ainfo = NULL;
-
- INSIST(ai->entry == NULL);
- INSIST(!ISC_LINK_LINKED(ai, publink));
-
- ai->magic = 0;
-
- isc_mempool_put(adb->aimp, ai);
-}
-
-/*
- * Search for the name. NOTE: The bucket is kept locked on both
- * success and failure, so it must always be unlocked by the caller!
- *
- * On the first call to this function, *bucketp must be set to
- * DNS_ADB_INVALIDBUCKET.
- */
-static inline dns_adbname_t *
-find_name_and_lock(dns_adb_t *adb, dns_name_t *name,
- unsigned int options, int *bucketp)
-{
- dns_adbname_t *adbname;
- int bucket;
-
- bucket = dns_name_fullhash(name, ISC_FALSE) % adb->nnames;
-
- if (*bucketp == DNS_ADB_INVALIDBUCKET) {
- LOCK(&adb->namelocks[bucket]);
- *bucketp = bucket;
- } else if (*bucketp != bucket) {
- UNLOCK(&adb->namelocks[*bucketp]);
- LOCK(&adb->namelocks[bucket]);
- *bucketp = bucket;
- }
-
- adbname = ISC_LIST_HEAD(adb->names[bucket]);
- while (adbname != NULL) {
- if (!NAME_DEAD(adbname)) {
- if (dns_name_equal(name, &adbname->name)
- && GLUEHINT_OK(adbname, options)
- && STARTATZONE_MATCHES(adbname, options))
- return (adbname);
- }
- adbname = ISC_LIST_NEXT(adbname, plink);
- }
-
- return (NULL);
-}
-
-/*
- * Search for the address. NOTE: The bucket is kept locked on both
- * success and failure, so it must always be unlocked by the caller.
- *
- * On the first call to this function, *bucketp must be set to
- * DNS_ADB_INVALIDBUCKET. This will cause a lock to occur. On
- * later calls (within the same "lock path") it can be left alone, so
- * if this function is called multiple times locking is only done if
- * the bucket changes.
- */
-static inline dns_adbentry_t *
-find_entry_and_lock(dns_adb_t *adb, isc_sockaddr_t *addr, int *bucketp,
- isc_stdtime_t now)
-{
- dns_adbentry_t *entry, *entry_next;
- int bucket;
-
- bucket = isc_sockaddr_hash(addr, ISC_TRUE) % adb->nentries;
-
- if (*bucketp == DNS_ADB_INVALIDBUCKET) {
- LOCK(&adb->entrylocks[bucket]);
- *bucketp = bucket;
- } else if (*bucketp != bucket) {
- UNLOCK(&adb->entrylocks[*bucketp]);
- LOCK(&adb->entrylocks[bucket]);
- *bucketp = bucket;
- }
-
- /* Search the list, while cleaning up expired entries. */
- for (entry = ISC_LIST_HEAD(adb->entries[bucket]);
- entry != NULL;
- entry = entry_next) {
- entry_next = ISC_LIST_NEXT(entry, plink);
- (void)check_expire_entry(adb, &entry, now);
- if (entry != NULL &&
- isc_sockaddr_equal(addr, &entry->sockaddr)) {
- ISC_LIST_UNLINK(adb->entries[bucket], entry, plink);
- ISC_LIST_PREPEND(adb->entries[bucket], entry, plink);
- return (entry);
- }
- }
-
- return (NULL);
-}
-
-/*
- * Entry bucket MUST be locked!
- */
-static isc_boolean_t
-entry_is_lame(dns_adb_t *adb, dns_adbentry_t *entry, dns_name_t *qname,
- dns_rdatatype_t qtype, isc_stdtime_t now)
-{
- dns_adblameinfo_t *li, *next_li;
- isc_boolean_t is_bad;
-
- is_bad = ISC_FALSE;
-
- li = ISC_LIST_HEAD(entry->lameinfo);
- if (li == NULL)
- return (ISC_FALSE);
- while (li != NULL) {
- next_li = ISC_LIST_NEXT(li, plink);
-
- /*
- * Has the entry expired?
- */
- if (li->lame_timer < now) {
- ISC_LIST_UNLINK(entry->lameinfo, li, plink);
- free_adblameinfo(adb, &li);
- }
-
- /*
- * Order tests from least to most expensive.
- *
- * We do not break out of the main loop here as
- * we use the loop for house keeping.
- */
- if (li != NULL && !is_bad && li->qtype == qtype &&
- dns_name_equal(qname, &li->qname))
- is_bad = ISC_TRUE;
-
- li = next_li;
- }
-
- return (is_bad);
-}
-
-static void
-copy_namehook_lists(dns_adb_t *adb, dns_adbfind_t *find, dns_name_t *qname,
- dns_rdatatype_t qtype, dns_adbname_t *name,
- isc_stdtime_t now)
-{
- dns_adbnamehook_t *namehook;
- dns_adbaddrinfo_t *addrinfo;
- dns_adbentry_t *entry;
- int bucket;
-
- bucket = DNS_ADB_INVALIDBUCKET;
-
- if (find->options & DNS_ADBFIND_INET) {
- namehook = ISC_LIST_HEAD(name->v4);
- while (namehook != NULL) {
- entry = namehook->entry;
- bucket = entry->lock_bucket;
- INSIST(bucket != DNS_ADB_INVALIDBUCKET);
- LOCK(&adb->entrylocks[bucket]);
-
- if (!FIND_RETURNLAME(find)
- && entry_is_lame(adb, entry, qname, qtype, now)) {
- find->options |= DNS_ADBFIND_LAMEPRUNED;
- goto nextv4;
- }
- addrinfo = new_adbaddrinfo(adb, entry, find->port);
- if (addrinfo == NULL) {
- find->partial_result |= DNS_ADBFIND_INET;
- goto out;
- }
- /*
- * Found a valid entry. Add it to the find's list.
- */
- inc_entry_refcnt(adb, entry, ISC_FALSE);
- ISC_LIST_APPEND(find->list, addrinfo, publink);
- addrinfo = NULL;
- nextv4:
- UNLOCK(&adb->entrylocks[bucket]);
- bucket = DNS_ADB_INVALIDBUCKET;
- namehook = ISC_LIST_NEXT(namehook, plink);
- }
- }
-
- if (find->options & DNS_ADBFIND_INET6) {
- namehook = ISC_LIST_HEAD(name->v6);
- while (namehook != NULL) {
- entry = namehook->entry;
- bucket = entry->lock_bucket;
- INSIST(bucket != DNS_ADB_INVALIDBUCKET);
- LOCK(&adb->entrylocks[bucket]);
-
- if (!FIND_RETURNLAME(find)
- && entry_is_lame(adb, entry, qname, qtype, now)) {
- find->options |= DNS_ADBFIND_LAMEPRUNED;
- goto nextv6;
- }
- addrinfo = new_adbaddrinfo(adb, entry, find->port);
- if (addrinfo == NULL) {
- find->partial_result |= DNS_ADBFIND_INET6;
- goto out;
- }
- /*
- * Found a valid entry. Add it to the find's list.
- */
- inc_entry_refcnt(adb, entry, ISC_FALSE);
- ISC_LIST_APPEND(find->list, addrinfo, publink);
- addrinfo = NULL;
- nextv6:
- UNLOCK(&adb->entrylocks[bucket]);
- bucket = DNS_ADB_INVALIDBUCKET;
- namehook = ISC_LIST_NEXT(namehook, plink);
- }
- }
-
- out:
- if (bucket != DNS_ADB_INVALIDBUCKET)
- UNLOCK(&adb->entrylocks[bucket]);
-}
-
-static void
-shutdown_task(isc_task_t *task, isc_event_t *ev) {
- dns_adb_t *adb;
-
- UNUSED(task);
-
- adb = ev->ev_arg;
- INSIST(DNS_ADB_VALID(adb));
-
- isc_event_free(&ev);
- /*
- * Wait for lock around check_exit() call to be released.
- */
- LOCK(&adb->lock);
- UNLOCK(&adb->lock);
- destroy(adb);
-}
-
-/*
- * Name bucket must be locked; adb may be locked; no other locks held.
- */
-static isc_boolean_t
-check_expire_name(dns_adbname_t **namep, isc_stdtime_t now) {
- dns_adbname_t *name;
- isc_boolean_t result = ISC_FALSE;
-
- INSIST(namep != NULL && DNS_ADBNAME_VALID(*namep));
- name = *namep;
-
- if (NAME_HAS_V4(name) || NAME_HAS_V6(name))
- return (result);
- if (NAME_FETCH(name))
- return (result);
- if (!EXPIRE_OK(name->expire_v4, now))
- return (result);
- if (!EXPIRE_OK(name->expire_v6, now))
- return (result);
- if (!EXPIRE_OK(name->expire_target, now))
- return (result);
-
- /*
- * The name is empty. Delete it.
- */
- result = kill_name(&name, DNS_EVENT_ADBEXPIRED);
- *namep = NULL;
-
- /*
- * Our caller, or one of its callers, will be calling check_exit() at
- * some point, so we don't need to do it here.
- */
- return (result);
-}
-
-/*%
- * Examine the tail entry of the LRU list to see if it expires or is stale
- * (unused for some period); if so, the name entry will be freed. If the ADB
- * is in the overmem condition, the tail and the next to tail entries
- * will be unconditionally removed (unless they have an outstanding fetch).
- * We don't care about a race on 'overmem' at the risk of causing some
- * collateral damage or a small delay in starting cleanup, so we don't bother
- * to lock ADB (if it's not locked).
- *
- * Name bucket must be locked; adb may be locked; no other locks held.
- */
-static void
-check_stale_name(dns_adb_t *adb, int bucket, isc_stdtime_t now) {
- int victims, max_victims;
- dns_adbname_t *victim, *next_victim;
- isc_boolean_t overmem = isc_mem_isovermem(adb->mctx);
- int scans = 0;
-
- INSIST(bucket != DNS_ADB_INVALIDBUCKET);
-
- max_victims = overmem ? 2 : 1;
-
- /*
- * We limit the number of scanned entries to 10 (arbitrary choice)
- * in order to avoid examining too many entries when there are many
- * tail entries that have fetches (this should be rare, but could
- * happen).
- */
- victim = ISC_LIST_TAIL(adb->names[bucket]);
- for (victims = 0;
- victim != NULL && victims < max_victims && scans < 10;
- victim = next_victim) {
- INSIST(!NAME_DEAD(victim));
- scans++;
- next_victim = ISC_LIST_PREV(victim, plink);
- (void)check_expire_name(&victim, now);
- if (victim == NULL) {
- victims++;
- goto next;
- }
-
- if (!NAME_FETCH(victim) &&
- (overmem || victim->last_used + ADB_STALE_MARGIN <= now)) {
- RUNTIME_CHECK(kill_name(&victim,
- DNS_EVENT_ADBCANCELED) ==
- ISC_FALSE);
- victims++;
- }
-
- next:
- if (!overmem)
- break;
- }
-}
-
-/*
- * Entry bucket must be locked; adb may be locked; no other locks held.
- */
-static isc_boolean_t
-check_expire_entry(dns_adb_t *adb, dns_adbentry_t **entryp, isc_stdtime_t now)
-{
- dns_adbentry_t *entry;
- isc_boolean_t result = ISC_FALSE;
-
- INSIST(entryp != NULL && DNS_ADBENTRY_VALID(*entryp));
- entry = *entryp;
-
- if (entry->refcnt != 0)
- return (result);
-
- if (entry->expires == 0 || entry->expires > now)
- return (result);
-
- /*
- * The entry is not in use. Delete it.
- */
- DP(DEF_LEVEL, "killing entry %p", entry);
- INSIST(ISC_LINK_LINKED(entry, plink));
- result = unlink_entry(adb, entry);
- free_adbentry(adb, &entry);
- if (result)
- dec_adb_irefcnt(adb);
- *entryp = NULL;
- return (result);
-}
-
-/*
- * ADB must be locked, and no other locks held.
- */
-static isc_boolean_t
-cleanup_names(dns_adb_t *adb, int bucket, isc_stdtime_t now) {
- dns_adbname_t *name;
- dns_adbname_t *next_name;
- isc_boolean_t result = ISC_FALSE;
-
- DP(CLEAN_LEVEL, "cleaning name bucket %d", bucket);
-
- LOCK(&adb->namelocks[bucket]);
- if (adb->name_sd[bucket]) {
- UNLOCK(&adb->namelocks[bucket]);
- return (result);
- }
-
- name = ISC_LIST_HEAD(adb->names[bucket]);
- while (name != NULL) {
- next_name = ISC_LIST_NEXT(name, plink);
- INSIST(result == ISC_FALSE);
- result = check_expire_namehooks(name, now);
- if (!result)
- result = check_expire_name(&name, now);
- name = next_name;
- }
- UNLOCK(&adb->namelocks[bucket]);
- return (result);
-}
-
-/*
- * ADB must be locked, and no other locks held.
- */
-static isc_boolean_t
-cleanup_entries(dns_adb_t *adb, int bucket, isc_stdtime_t now) {
- dns_adbentry_t *entry, *next_entry;
- isc_boolean_t result = ISC_FALSE;
-
- DP(CLEAN_LEVEL, "cleaning entry bucket %d", bucket);
-
- LOCK(&adb->entrylocks[bucket]);
- entry = ISC_LIST_HEAD(adb->entries[bucket]);
- while (entry != NULL) {
- next_entry = ISC_LIST_NEXT(entry, plink);
- INSIST(result == ISC_FALSE);
- result = check_expire_entry(adb, &entry, now);
- entry = next_entry;
- }
- UNLOCK(&adb->entrylocks[bucket]);
- return (result);
-}
-
-static void
-destroy(dns_adb_t *adb) {
- adb->magic = 0;
-
- isc_task_detach(&adb->task);
- if (adb->excl != NULL)
- isc_task_detach(&adb->excl);
-
- isc_mempool_destroy(&adb->nmp);
- isc_mempool_destroy(&adb->nhmp);
- isc_mempool_destroy(&adb->limp);
- isc_mempool_destroy(&adb->emp);
- isc_mempool_destroy(&adb->ahmp);
- isc_mempool_destroy(&adb->aimp);
- isc_mempool_destroy(&adb->afmp);
-
- 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));
-}
-
-
-/*
- * Public functions.
- */
-
-isc_result_t
-dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr,
- isc_taskmgr_t *taskmgr, dns_adb_t **newadb)
-{
- dns_adb_t *adb;
- isc_result_t result;
- unsigned int i;
-
- REQUIRE(mem != NULL);
- REQUIRE(view != NULL);
- REQUIRE(timermgr != NULL); /* this is actually unused */
- REQUIRE(taskmgr != NULL);
- REQUIRE(newadb != NULL && *newadb == NULL);
-
- UNUSED(timermgr);
-
- adb = isc_mem_get(mem, sizeof(dns_adb_t));
- if (adb == NULL)
- return (ISC_R_NOMEMORY);
-
- /*
- * Initialize things here that cannot fail, and especially things
- * that must be NULL for the error return to work properly.
- */
- adb->magic = 0;
- adb->erefcnt = 1;
- adb->irefcnt = 0;
- adb->nmp = NULL;
- adb->nhmp = NULL;
- adb->limp = NULL;
- adb->emp = NULL;
- adb->ahmp = NULL;
- adb->aimp = NULL;
- adb->afmp = NULL;
- adb->task = NULL;
- adb->excl = NULL;
- adb->mctx = NULL;
- adb->view = view;
- adb->taskmgr = taskmgr;
- adb->next_cleanbucket = 0;
- ISC_EVENT_INIT(&adb->cevent, sizeof(adb->cevent), 0, NULL,
- DNS_EVENT_ADBCONTROL, shutdown_task, adb,
- adb, NULL, NULL);
- adb->cevent_sent = ISC_FALSE;
- 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;
-
- result = isc_taskmgr_excltask(adb->taskmgr, &adb->excl);
- if (result != ISC_R_SUCCESS) {
- DP(ISC_LOG_INFO, "adb: task-exclusive mode unavailable, "
- "intializing table sizes to %u\n",
- nbuckets[11]);
- adb->nentries = nbuckets[11];
- adb->nnames= nbuckets[11];
-
- }
-
- isc_mem_attach(mem, &adb->mctx);
-
- result = isc_mutex_init(&adb->lock);
- if (result != ISC_R_SUCCESS)
- goto fail0b;
-
- result = isc_mutex_init(&adb->mplock);
- if (result != ISC_R_SUCCESS)
- goto fail0c;
-
- result = isc_mutex_init(&adb->reflock);
- if (result != ISC_R_SUCCESS)
- goto fail0d;
-
- result = isc_mutex_init(&adb->overmemlock);
- 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, adb->nnames);
- if (result != ISC_R_SUCCESS)
- goto fail1;
- 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 < 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, adb->nentries);
- if (result != ISC_R_SUCCESS)
- goto fail2;
-
- /*
- * Memory pools
- */
-#define MPINIT(t, p, n) do { \
- result = isc_mempool_create(mem, sizeof(t), &(p)); \
- if (result != ISC_R_SUCCESS) \
- goto fail3; \
- isc_mempool_setfreemax((p), FREE_ITEMS); \
- isc_mempool_setfillcount((p), FILL_COUNT); \
- isc_mempool_setname((p), n); \
- isc_mempool_associatelock((p), &adb->mplock); \
-} while (0)
-
- MPINIT(dns_adbname_t, adb->nmp, "adbname");
- MPINIT(dns_adbnamehook_t, adb->nhmp, "adbnamehook");
- MPINIT(dns_adblameinfo_t, adb->limp, "adblameinfo");
- MPINIT(dns_adbentry_t, adb->emp, "adbentry");
- MPINIT(dns_adbfind_t, adb->ahmp, "adbfind");
- MPINIT(dns_adbaddrinfo_t, adb->aimp, "adbaddrinfo");
- MPINIT(dns_adbfetch_t, adb->afmp, "adbfetch");
-
-#undef MPINIT
-
- /*
- * Allocate an internal task.
- */
- result = isc_task_create(adb->taskmgr, 0, &adb->task);
- if (result != ISC_R_SUCCESS)
- goto fail3;
-
- isc_task_setname(adb->task, "ADB", adb);
-
- /*
- * Normal return.
- */
- adb->magic = DNS_ADB_MAGIC;
- *newadb = adb;
- return (ISC_R_SUCCESS);
-
- fail3:
- if (adb->task != NULL)
- isc_task_detach(&adb->task);
-
- /* clean up entrylocks */
- DESTROYMUTEXBLOCK(adb->entrylocks, adb->nentries);
-
- fail2: /* clean up namelocks */
- 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)
- isc_mempool_destroy(&adb->nhmp);
- if (adb->limp != NULL)
- isc_mempool_destroy(&adb->limp);
- if (adb->emp != NULL)
- isc_mempool_destroy(&adb->emp);
- if (adb->ahmp != NULL)
- isc_mempool_destroy(&adb->ahmp);
- if (adb->aimp != NULL)
- isc_mempool_destroy(&adb->aimp);
- if (adb->afmp != NULL)
- isc_mempool_destroy(&adb->afmp);
-
- DESTROYLOCK(&adb->namescntlock);
- fail0g:
- DESTROYLOCK(&adb->entriescntlock);
- fail0f:
- DESTROYLOCK(&adb->overmemlock);
- fail0e:
- DESTROYLOCK(&adb->reflock);
- fail0d:
- DESTROYLOCK(&adb->mplock);
- fail0c:
- DESTROYLOCK(&adb->lock);
- fail0b:
- isc_mem_putanddetach(&adb->mctx, adb, sizeof(dns_adb_t));
-
- return (result);
-}
-
-void
-dns_adb_attach(dns_adb_t *adb, dns_adb_t **adbx) {
-
- REQUIRE(DNS_ADB_VALID(adb));
- REQUIRE(adbx != NULL && *adbx == NULL);
-
- inc_adb_erefcnt(adb);
- *adbx = adb;
-}
-
-void
-dns_adb_detach(dns_adb_t **adbx) {
- dns_adb_t *adb;
- isc_boolean_t need_exit_check;
-
- REQUIRE(adbx != NULL && DNS_ADB_VALID(*adbx));
-
- adb = *adbx;
- *adbx = NULL;
-
- INSIST(adb->erefcnt > 0);
-
- LOCK(&adb->reflock);
- adb->erefcnt--;
- need_exit_check = ISC_TF(adb->erefcnt == 0 && adb->irefcnt == 0);
- UNLOCK(&adb->reflock);
-
- if (need_exit_check) {
- LOCK(&adb->lock);
- INSIST(adb->shutting_down);
- check_exit(adb);
- UNLOCK(&adb->lock);
- }
-}
-
-void
-dns_adb_whenshutdown(dns_adb_t *adb, isc_task_t *task, isc_event_t **eventp) {
- isc_task_t *clone;
- isc_event_t *event;
- isc_boolean_t zeroirefcnt = ISC_FALSE;
-
- /*
- * Send '*eventp' to 'task' when 'adb' has shutdown.
- */
-
- REQUIRE(DNS_ADB_VALID(adb));
- REQUIRE(eventp != NULL);
-
- event = *eventp;
- *eventp = NULL;
-
- LOCK(&adb->lock);
-
- LOCK(&adb->reflock);
- zeroirefcnt = ISC_TF(adb->irefcnt == 0);
-
- if (adb->shutting_down && zeroirefcnt &&
- isc_mempool_getallocated(adb->ahmp) == 0) {
- /*
- * We're already shutdown. Send the event.
- */
- event->ev_sender = adb;
- isc_task_send(task, &event);
- } else {
- clone = NULL;
- isc_task_attach(task, &clone);
- event->ev_sender = clone;
- ISC_LIST_APPEND(adb->whenshutdown, event, ev_link);
- }
-
- UNLOCK(&adb->reflock);
- UNLOCK(&adb->lock);
-}
-
-void
-dns_adb_shutdown(dns_adb_t *adb) {
- isc_boolean_t need_check_exit;
-
- /*
- * Shutdown 'adb'.
- */
-
- LOCK(&adb->lock);
-
- if (!adb->shutting_down) {
- adb->shutting_down = ISC_TRUE;
- isc_mem_setwater(adb->mctx, water, adb, 0, 0);
- need_check_exit = shutdown_names(adb);
- if (!need_check_exit)
- need_check_exit = shutdown_entries(adb);
- if (need_check_exit)
- check_exit(adb);
- }
-
- UNLOCK(&adb->lock);
-}
-
-isc_result_t
-dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
- void *arg, dns_name_t *name, dns_name_t *qname,
- dns_rdatatype_t qtype, unsigned int options,
- isc_stdtime_t now, dns_name_t *target,
- in_port_t port, dns_adbfind_t **findp)
-{
- dns_adbfind_t *find;
- dns_adbname_t *adbname;
- int bucket;
- isc_boolean_t want_event, start_at_zone, alias, have_address;
- isc_result_t result;
- unsigned int wanted_addresses;
- unsigned int wanted_fetches;
- unsigned int query_pending;
-
- REQUIRE(DNS_ADB_VALID(adb));
- if (task != NULL) {
- REQUIRE(action != NULL);
- }
- REQUIRE(name != NULL);
- REQUIRE(qname != NULL);
- REQUIRE(findp != NULL && *findp == NULL);
- REQUIRE(target == NULL || dns_name_hasbuffer(target));
-
- REQUIRE((options & DNS_ADBFIND_ADDRESSMASK) != 0);
-
- result = ISC_R_UNEXPECTED;
- POST(result);
- wanted_addresses = (options & DNS_ADBFIND_ADDRESSMASK);
- wanted_fetches = 0;
- query_pending = 0;
- want_event = ISC_FALSE;
- start_at_zone = ISC_FALSE;
- alias = ISC_FALSE;
-
- if (now == 0)
- isc_stdtime_get(&now);
-
- /*
- * XXXMLG Move this comment somewhere else!
- *
- * Look up the name in our internal database.
- *
- * Possibilities: Note that these are not always exclusive.
- *
- * No name found. In this case, allocate a new name header and
- * an initial namehook or two. If any of these allocations
- * fail, clean up and return ISC_R_NOMEMORY.
- *
- * Name found, valid addresses present. Allocate one addrinfo
- * structure for each found and append it to the linked list
- * of addresses for this header.
- *
- * Name found, queries pending. In this case, if a task was
- * passed in, allocate a job id, attach it to the name's job
- * list and remember to tell the caller that there will be
- * more info coming later.
- */
-
- find = new_adbfind(adb);
- if (find == NULL)
- return (ISC_R_NOMEMORY);
-
- find->port = port;
-
- /*
- * Remember what types of addresses we are interested in.
- */
- find->options = options;
- find->flags |= wanted_addresses;
- if (FIND_WANTEVENT(find)) {
- REQUIRE(task != NULL);
- }
-
- /*
- * Try to see if we know anything about this name at all.
- */
- bucket = DNS_ADB_INVALIDBUCKET;
- adbname = find_name_and_lock(adb, name, find->options, &bucket);
- INSIST(bucket != DNS_ADB_INVALIDBUCKET);
- if (adb->name_sd[bucket]) {
- DP(DEF_LEVEL,
- "dns_adb_createfind: returning ISC_R_SHUTTINGDOWN");
- RUNTIME_CHECK(free_adbfind(adb, &find) == ISC_FALSE);
- result = ISC_R_SHUTTINGDOWN;
- goto out;
- }
-
- /*
- * Nothing found. Allocate a new adbname structure for this name.
- */
- if (adbname == NULL) {
- /*
- * See if there is any stale name at the end of list, and purge
- * it if so.
- */
- check_stale_name(adb, bucket, now);
-
- adbname = new_adbname(adb, name);
- if (adbname == NULL) {
- RUNTIME_CHECK(free_adbfind(adb, &find) == ISC_FALSE);
- result = ISC_R_NOMEMORY;
- goto out;
- }
- link_name(adb, bucket, adbname);
- if (FIND_HINTOK(find))
- adbname->flags |= NAME_HINT_OK;
- if (FIND_GLUEOK(find))
- adbname->flags |= NAME_GLUE_OK;
- if (FIND_STARTATZONE(find))
- adbname->flags |= NAME_STARTATZONE;
- } else {
- /* Move this name forward in the LRU list */
- ISC_LIST_UNLINK(adb->names[bucket], adbname, plink);
- ISC_LIST_PREPEND(adb->names[bucket], adbname, plink);
- }
- adbname->last_used = now;
-
- /*
- * Expire old entries, etc.
- */
- RUNTIME_CHECK(check_expire_namehooks(adbname, now) == ISC_FALSE);
-
- /*
- * Do we know that the name is an alias?
- */
- if (!EXPIRE_OK(adbname->expire_target, now)) {
- /*
- * Yes, it is.
- */
- DP(DEF_LEVEL,
- "dns_adb_createfind: name %p is an alias (cached)",
- adbname);
- alias = ISC_TRUE;
- goto post_copy;
- }
-
- /*
- * Try to populate the name from the database and/or
- * start fetches. First try looking for an A record
- * in the database.
- */
- if (!NAME_HAS_V4(adbname) && EXPIRE_OK(adbname->expire_v4, now)
- && WANT_INET(wanted_addresses)) {
- result = dbfind_name(adbname, now, dns_rdatatype_a);
- if (result == ISC_R_SUCCESS) {
- DP(DEF_LEVEL,
- "dns_adb_createfind: found A for name %p in db",
- adbname);
- goto v6;
- }
-
- /*
- * Did we get a CNAME or DNAME?
- */
- if (result == DNS_R_ALIAS) {
- DP(DEF_LEVEL,
- "dns_adb_createfind: name %p is an alias",
- adbname);
- alias = ISC_TRUE;
- goto post_copy;
- }
-
- /*
- * If the name doesn't exist at all, don't bother with
- * v6 queries; they won't work.
- *
- * If the name does exist but we didn't get our data, go
- * ahead and try AAAA.
- *
- * If the result is neither of these, try a fetch for A.
- */
- if (NXDOMAIN_RESULT(result))
- goto fetch;
- else if (NXRRSET_RESULT(result))
- goto v6;
-
- if (!NAME_FETCH_V4(adbname))
- wanted_fetches |= DNS_ADBFIND_INET;
- }
-
- v6:
- if (!NAME_HAS_V6(adbname) && EXPIRE_OK(adbname->expire_v6, now)
- && WANT_INET6(wanted_addresses)) {
- result = dbfind_name(adbname, now, dns_rdatatype_aaaa);
- if (result == ISC_R_SUCCESS) {
- DP(DEF_LEVEL,
- "dns_adb_createfind: found AAAA for name %p",
- adbname);
- goto fetch;
- }
-
- /*
- * Did we get a CNAME or DNAME?
- */
- if (result == DNS_R_ALIAS) {
- DP(DEF_LEVEL,
- "dns_adb_createfind: name %p is an alias",
- adbname);
- alias = ISC_TRUE;
- goto post_copy;
- }
-
- /*
- * Listen to negative cache hints, and don't start
- * another query.
- */
- if (NCACHE_RESULT(result) || AUTH_NX(result))
- goto fetch;
-
- if (!NAME_FETCH_V6(adbname))
- wanted_fetches |= DNS_ADBFIND_INET6;
- }
-
- fetch:
- if ((WANT_INET(wanted_addresses) && NAME_HAS_V4(adbname)) ||
- (WANT_INET6(wanted_addresses) && NAME_HAS_V6(adbname)))
- have_address = ISC_TRUE;
- else
- have_address = ISC_FALSE;
- if (wanted_fetches != 0 &&
- ! (FIND_AVOIDFETCHES(find) && have_address)) {
- /*
- * We're missing at least one address family. Either the
- * caller hasn't instructed us to avoid fetches, or we don't
- * know anything about any of the address families that would
- * be acceptable so we have to launch fetches.
- */
-
- if (FIND_STARTATZONE(find))
- start_at_zone = ISC_TRUE;
-
- /*
- * Start V4.
- */
- if (WANT_INET(wanted_fetches) &&
- fetch_name(adbname, start_at_zone,
- dns_rdatatype_a) == ISC_R_SUCCESS) {
- DP(DEF_LEVEL,
- "dns_adb_createfind: started A fetch for name %p",
- adbname);
- }
-
- /*
- * Start V6.
- */
- if (WANT_INET6(wanted_fetches) &&
- fetch_name(adbname, start_at_zone,
- dns_rdatatype_aaaa) == ISC_R_SUCCESS) {
- DP(DEF_LEVEL,
- "dns_adb_createfind: "
- "started AAAA fetch for name %p",
- adbname);
- }
- }
-
- /*
- * Run through the name and copy out the bits we are
- * interested in.
- */
- copy_namehook_lists(adb, find, qname, qtype, adbname, now);
-
- post_copy:
- if (NAME_FETCH_V4(adbname))
- query_pending |= DNS_ADBFIND_INET;
- if (NAME_FETCH_V6(adbname))
- query_pending |= DNS_ADBFIND_INET6;
-
- /*
- * Attach to the name's query list if there are queries
- * already running, and we have been asked to.
- */
- want_event = ISC_TRUE;
- if (!FIND_WANTEVENT(find))
- want_event = ISC_FALSE;
- if (FIND_WANTEMPTYEVENT(find) && FIND_HAS_ADDRS(find))
- want_event = ISC_FALSE;
- if ((wanted_addresses & query_pending) == 0)
- want_event = ISC_FALSE;
- if (alias)
- want_event = ISC_FALSE;
- if (want_event) {
- find->adbname = adbname;
- find->name_bucket = bucket;
- ISC_LIST_APPEND(adbname->finds, find, plink);
- find->query_pending = (query_pending & wanted_addresses);
- find->flags &= ~DNS_ADBFIND_ADDRESSMASK;
- find->flags |= (find->query_pending & DNS_ADBFIND_ADDRESSMASK);
- DP(DEF_LEVEL, "createfind: attaching find %p to adbname %p",
- find, adbname);
- } else {
- /*
- * Remove the flag so the caller knows there will never
- * be an event, and set internal flags to fake that
- * the event was sent and freed, so dns_adb_destroyfind() will
- * do the right thing.
- */
- find->query_pending = (query_pending & wanted_addresses);
- find->options &= ~DNS_ADBFIND_WANTEVENT;
- find->flags |= (FIND_EVENT_SENT | FIND_EVENT_FREED);
- find->flags &= ~DNS_ADBFIND_ADDRESSMASK;
- }
-
- find->partial_result |= (adbname->partial_result & wanted_addresses);
- if (alias) {
- if (target != NULL) {
- result = dns_name_copy(&adbname->target, target, NULL);
- if (result != ISC_R_SUCCESS)
- goto out;
- }
- result = DNS_R_ALIAS;
- } else
- result = ISC_R_SUCCESS;
-
- /*
- * Copy out error flags from the name structure into the find.
- */
- find->result_v4 = find_err_map[adbname->fetch_err];
- find->result_v6 = find_err_map[adbname->fetch6_err];
-
- out:
- if (find != NULL) {
- *findp = find;
-
- if (want_event) {
- isc_task_t *taskp;
-
- INSIST((find->flags & DNS_ADBFIND_ADDRESSMASK) != 0);
- taskp = NULL;
- isc_task_attach(task, &taskp);
- find->event.ev_sender = taskp;
- find->event.ev_action = action;
- find->event.ev_arg = arg;
- }
- }
-
- UNLOCK(&adb->namelocks[bucket]);
-
- return (result);
-}
-
-void
-dns_adb_destroyfind(dns_adbfind_t **findp) {
- dns_adbfind_t *find;
- dns_adbentry_t *entry;
- dns_adbaddrinfo_t *ai;
- int bucket;
- dns_adb_t *adb;
- isc_boolean_t overmem;
-
- REQUIRE(findp != NULL && DNS_ADBFIND_VALID(*findp));
- find = *findp;
- *findp = NULL;
-
- LOCK(&find->lock);
-
- DP(DEF_LEVEL, "dns_adb_destroyfind on find %p", find);
-
- adb = find->adb;
- REQUIRE(DNS_ADB_VALID(adb));
-
- REQUIRE(FIND_EVENTFREED(find));
-
- bucket = find->name_bucket;
- INSIST(bucket == DNS_ADB_INVALIDBUCKET);
-
- UNLOCK(&find->lock);
-
- /*
- * The find doesn't exist on any list, and nothing is locked.
- * Return the find to the memory pool, and decrement the adb's
- * reference count.
- */
- overmem = isc_mem_isovermem(adb->mctx);
- ai = ISC_LIST_HEAD(find->list);
- while (ai != NULL) {
- ISC_LIST_UNLINK(find->list, ai, publink);
- entry = ai->entry;
- ai->entry = NULL;
- INSIST(DNS_ADBENTRY_VALID(entry));
- RUNTIME_CHECK(dec_entry_refcnt(adb, overmem, entry, ISC_TRUE) ==
- ISC_FALSE);
- free_adbaddrinfo(adb, &ai);
- ai = ISC_LIST_HEAD(find->list);
- }
-
- /*
- * WARNING: The find is freed with the adb locked. This is done
- * to avoid a race condition where we free the find, some other
- * thread tests to see if it should be destroyed, detects it should
- * be, destroys it, and then we try to lock it for our check, but the
- * lock is destroyed.
- */
- LOCK(&adb->lock);
- if (free_adbfind(adb, &find))
- check_exit(adb);
- UNLOCK(&adb->lock);
-}
-
-void
-dns_adb_cancelfind(dns_adbfind_t *find) {
- isc_event_t *ev;
- isc_task_t *task;
- dns_adb_t *adb;
- int bucket;
- int unlock_bucket;
-
- LOCK(&find->lock);
-
- DP(DEF_LEVEL, "dns_adb_cancelfind on find %p", find);
-
- adb = find->adb;
- REQUIRE(DNS_ADB_VALID(adb));
-
- REQUIRE(!FIND_EVENTFREED(find));
- REQUIRE(FIND_WANTEVENT(find));
-
- bucket = find->name_bucket;
- if (bucket == DNS_ADB_INVALIDBUCKET)
- goto cleanup;
-
- /*
- * We need to get the adbname's lock to unlink the find.
- */
- unlock_bucket = bucket;
- violate_locking_hierarchy(&find->lock, &adb->namelocks[unlock_bucket]);
- bucket = find->name_bucket;
- if (bucket != DNS_ADB_INVALIDBUCKET) {
- ISC_LIST_UNLINK(find->adbname->finds, find, plink);
- find->adbname = NULL;
- find->name_bucket = DNS_ADB_INVALIDBUCKET;
- }
- UNLOCK(&adb->namelocks[unlock_bucket]);
- bucket = DNS_ADB_INVALIDBUCKET;
- POST(bucket);
-
- cleanup:
-
- if (!FIND_EVENTSENT(find)) {
- ev = &find->event;
- task = ev->ev_sender;
- ev->ev_sender = find;
- ev->ev_type = DNS_EVENT_ADBCANCELED;
- ev->ev_destroy = event_free;
- ev->ev_destroy_arg = find;
- find->result_v4 = ISC_R_CANCELED;
- find->result_v6 = ISC_R_CANCELED;
-
- DP(DEF_LEVEL, "sending event %p to task %p for find %p",
- ev, task, find);
-
- isc_task_sendanddetach(&task, (isc_event_t **)&ev);
- }
-
- UNLOCK(&find->lock);
-}
-
-void
-dns_adb_dump(dns_adb_t *adb, FILE *f) {
- unsigned int i;
- isc_stdtime_t now;
-
- REQUIRE(DNS_ADB_VALID(adb));
- REQUIRE(f != NULL);
-
- /*
- * Lock the adb itself, lock all the name buckets, then lock all
- * the entry buckets. This should put the adb into a state where
- * nothing can change, so we can iterate through everything and
- * print at our leisure.
- */
-
- LOCK(&adb->lock);
- isc_stdtime_get(&now);
-
- for (i = 0; i < adb->nnames; i++)
- RUNTIME_CHECK(cleanup_names(adb, i, now) == ISC_FALSE);
- for (i = 0; i < adb->nentries; i++)
- RUNTIME_CHECK(cleanup_entries(adb, i, now) == ISC_FALSE);
-
- dump_adb(adb, f, ISC_FALSE, now);
- UNLOCK(&adb->lock);
-}
-
-static void
-dump_ttl(FILE *f, const char *legend, isc_stdtime_t value, isc_stdtime_t now) {
- if (value == INT_MAX)
- return;
- fprintf(f, " [%s TTL %d]", legend, value - now);
-}
-
-static void
-dump_adb(dns_adb_t *adb, FILE *f, isc_boolean_t debug, isc_stdtime_t now) {
- unsigned int i;
- dns_adbname_t *name;
- dns_adbentry_t *entry;
-
- fprintf(f, ";\n; Address database dump\n;\n");
- if (debug)
- fprintf(f, "; addr %p, erefcnt %u, irefcnt %u, finds out %u\n",
- adb, adb->erefcnt, adb->irefcnt,
- isc_mempool_getallocated(adb->nhmp));
-
- for (i = 0; i < adb->nnames; i++)
- LOCK(&adb->namelocks[i]);
- for (i = 0; i < adb->nentries; i++)
- LOCK(&adb->entrylocks[i]);
-
- /*
- * Dump the names
- */
- for (i = 0; i < adb->nnames; i++) {
- name = ISC_LIST_HEAD(adb->names[i]);
- if (name == NULL)
- continue;
- if (debug)
- fprintf(f, "; bucket %d\n", i);
- for (;
- name != NULL;
- name = ISC_LIST_NEXT(name, plink))
- {
- if (debug)
- fprintf(f, "; name %p (flags %08x)\n",
- name, name->flags);
-
- fprintf(f, "; ");
- print_dns_name(f, &name->name);
- if (dns_name_countlabels(&name->target) > 0) {
- fprintf(f, " alias ");
- print_dns_name(f, &name->target);
- }
-
- dump_ttl(f, "v4", name->expire_v4, now);
- dump_ttl(f, "v6", name->expire_v6, now);
- dump_ttl(f, "target", name->expire_target, now);
-
- fprintf(f, " [v4 %s] [v6 %s]",
- errnames[name->fetch_err],
- errnames[name->fetch6_err]);
-
- fprintf(f, "\n");
-
- print_namehook_list(f, "v4", &name->v4, debug, now);
- print_namehook_list(f, "v6", &name->v6, debug, now);
-
- if (debug)
- print_fetch_list(f, name);
- if (debug)
- print_find_list(f, name);
-
- }
- }
-
- fprintf(f, ";\n; Unassociated entries\n;\n");
-
- for (i = 0; i < adb->nentries; i++) {
- entry = ISC_LIST_HEAD(adb->entries[i]);
- while (entry != NULL) {
- if (entry->refcnt == 0)
- dump_entry(f, entry, debug, now);
- entry = ISC_LIST_NEXT(entry, plink);
- }
- }
-
- /*
- * Unlock everything
- */
- for (i = 0; i < adb->nentries; i++)
- UNLOCK(&adb->entrylocks[i]);
- for (i = 0; i < adb->nnames; i++)
- UNLOCK(&adb->namelocks[i]);
-}
-
-static void
-dump_entry(FILE *f, dns_adbentry_t *entry, isc_boolean_t debug,
- isc_stdtime_t now)
-{
- char addrbuf[ISC_NETADDR_FORMATSIZE];
- char typebuf[DNS_RDATATYPE_FORMATSIZE];
- isc_netaddr_t netaddr;
- dns_adblameinfo_t *li;
-
- isc_netaddr_fromsockaddr(&netaddr, &entry->sockaddr);
- isc_netaddr_format(&netaddr, addrbuf, sizeof(addrbuf));
-
- if (debug)
- fprintf(f, ";\t%p: refcnt %u\n", entry, entry->refcnt);
-
- fprintf(f, ";\t%s [srtt %u] [flags %08x]",
- addrbuf, entry->srtt, entry->flags);
- if (entry->expires != 0)
- fprintf(f, " [ttl %d]", entry->expires - now);
- fprintf(f, "\n");
- for (li = ISC_LIST_HEAD(entry->lameinfo);
- li != NULL;
- li = ISC_LIST_NEXT(li, plink)) {
- fprintf(f, ";\t\t");
- print_dns_name(f, &li->qname);
- dns_rdatatype_format(li->qtype, typebuf, sizeof(typebuf));
- fprintf(f, " %s [lame TTL %d]\n", typebuf,
- li->lame_timer - now);
- }
-}
-
-void
-dns_adb_dumpfind(dns_adbfind_t *find, FILE *f) {
- char tmp[512];
- const char *tmpp;
- dns_adbaddrinfo_t *ai;
- isc_sockaddr_t *sa;
-
- /*
- * Not used currently, in the API Just In Case we
- * want to dump out the name and/or entries too.
- */
-
- LOCK(&find->lock);
-
- fprintf(f, ";Find %p\n", find);
- fprintf(f, ";\tqpending %08x partial %08x options %08x flags %08x\n",
- find->query_pending, find->partial_result,
- find->options, find->flags);
- fprintf(f, ";\tname_bucket %d, name %p, event sender %p\n",
- find->name_bucket, find->adbname, find->event.ev_sender);
-
- ai = ISC_LIST_HEAD(find->list);
- if (ai != NULL)
- fprintf(f, "\tAddresses:\n");
- while (ai != NULL) {
- sa = &ai->sockaddr;
- switch (sa->type.sa.sa_family) {
- case AF_INET:
- tmpp = inet_ntop(AF_INET, &sa->type.sin.sin_addr,
- tmp, sizeof(tmp));
- break;
- case AF_INET6:
- tmpp = inet_ntop(AF_INET6, &sa->type.sin6.sin6_addr,
- tmp, sizeof(tmp));
- break;
- default:
- tmpp = "UnkFamily";
- }
-
- if (tmpp == NULL)
- tmpp = "BadAddress";
-
- fprintf(f, "\t\tentry %p, flags %08x"
- " srtt %u addr %s\n",
- ai->entry, ai->flags, ai->srtt, tmpp);
-
- ai = ISC_LIST_NEXT(ai, publink);
- }
-
- UNLOCK(&find->lock);
-}
-
-static void
-print_dns_name(FILE *f, dns_name_t *name) {
- char buf[DNS_NAME_FORMATSIZE];
-
- INSIST(f != NULL);
-
- dns_name_format(name, buf, sizeof(buf));
- fprintf(f, "%s", buf);
-}
-
-static void
-print_namehook_list(FILE *f, const char *legend, dns_adbnamehooklist_t *list,
- isc_boolean_t debug, isc_stdtime_t now)
-{
- dns_adbnamehook_t *nh;
-
- for (nh = ISC_LIST_HEAD(*list);
- nh != NULL;
- nh = ISC_LIST_NEXT(nh, plink))
- {
- if (debug)
- fprintf(f, ";\tHook(%s) %p\n", legend, nh);
- dump_entry(f, nh->entry, debug, now);
- }
-}
-
-static inline void
-print_fetch(FILE *f, dns_adbfetch_t *ft, const char *type) {
- fprintf(f, "\t\tFetch(%s): %p -> { fetch %p }\n",
- type, ft, ft->fetch);
-}
-
-static void
-print_fetch_list(FILE *f, dns_adbname_t *n) {
- if (NAME_FETCH_A(n))
- print_fetch(f, n->fetch_a, "A");
- if (NAME_FETCH_AAAA(n))
- print_fetch(f, n->fetch_aaaa, "AAAA");
-}
-
-static void
-print_find_list(FILE *f, dns_adbname_t *name) {
- dns_adbfind_t *find;
-
- find = ISC_LIST_HEAD(name->finds);
- while (find != NULL) {
- dns_adb_dumpfind(find, f);
- find = ISC_LIST_NEXT(find, plink);
- }
-}
-
-static isc_result_t
-dbfind_name(dns_adbname_t *adbname, isc_stdtime_t now, dns_rdatatype_t rdtype)
-{
- isc_result_t result;
- dns_rdataset_t rdataset;
- dns_adb_t *adb;
- dns_fixedname_t foundname;
- dns_name_t *fname;
-
- INSIST(DNS_ADBNAME_VALID(adbname));
- adb = adbname->adb;
- INSIST(DNS_ADB_VALID(adb));
- INSIST(rdtype == dns_rdatatype_a || rdtype == dns_rdatatype_aaaa);
-
- dns_fixedname_init(&foundname);
- fname = dns_fixedname_name(&foundname);
- dns_rdataset_init(&rdataset);
-
- if (rdtype == dns_rdatatype_a)
- adbname->fetch_err = FIND_ERR_UNEXPECTED;
- else
- adbname->fetch6_err = FIND_ERR_UNEXPECTED;
-
- /*
- * 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) {
- case DNS_R_GLUE:
- case DNS_R_HINT:
- case ISC_R_SUCCESS:
- /*
- * Found in the database. Even if we can't copy out
- * any information, return success, or else a fetch
- * will be made, which will only make things worse.
- */
- if (rdtype == dns_rdatatype_a)
- adbname->fetch_err = FIND_ERR_SUCCESS;
- else
- adbname->fetch6_err = FIND_ERR_SUCCESS;
- result = import_rdataset(adbname, &rdataset, now);
- break;
- case DNS_R_NXDOMAIN:
- case DNS_R_NXRRSET:
- /*
- * We're authoritative and the data doesn't exist.
- * Make up a negative cache entry so we don't ask again
- * for a while.
- *
- * XXXRTH What time should we use? I'm putting in 30 seconds
- * for now.
- */
- if (rdtype == dns_rdatatype_a) {
- adbname->expire_v4 = now + 30;
- DP(NCACHE_LEVEL,
- "adb name %p: Caching auth negative entry for A",
- adbname);
- if (result == DNS_R_NXDOMAIN)
- adbname->fetch_err = FIND_ERR_NXDOMAIN;
- else
- adbname->fetch_err = FIND_ERR_NXRRSET;
- } else {
- DP(NCACHE_LEVEL,
- "adb name %p: Caching auth negative entry for AAAA",
- adbname);
- adbname->expire_v6 = now + 30;
- if (result == DNS_R_NXDOMAIN)
- adbname->fetch6_err = FIND_ERR_NXDOMAIN;
- else
- adbname->fetch6_err = FIND_ERR_NXRRSET;
- }
- break;
- case DNS_R_NCACHENXDOMAIN:
- case DNS_R_NCACHENXRRSET:
- /*
- * We found a negative cache entry. Pull the TTL from it
- * so we won't ask again for a while.
- */
- rdataset.ttl = ttlclamp(rdataset.ttl);
- if (rdtype == dns_rdatatype_a) {
- adbname->expire_v4 = rdataset.ttl + now;
- if (result == DNS_R_NCACHENXDOMAIN)
- adbname->fetch_err = FIND_ERR_NXDOMAIN;
- else
- adbname->fetch_err = FIND_ERR_NXRRSET;
- DP(NCACHE_LEVEL,
- "adb name %p: Caching negative entry for A (ttl %u)",
- adbname, rdataset.ttl);
- } else {
- DP(NCACHE_LEVEL,
- "adb name %p: Caching negative entry for AAAA (ttl %u)",
- adbname, rdataset.ttl);
- adbname->expire_v6 = rdataset.ttl + now;
- if (result == DNS_R_NCACHENXDOMAIN)
- adbname->fetch6_err = FIND_ERR_NXDOMAIN;
- else
- adbname->fetch6_err = FIND_ERR_NXRRSET;
- }
- break;
- case DNS_R_CNAME:
- case DNS_R_DNAME:
- /*
- * Clear the hint and glue flags, so this will match
- * more often.
- */
- adbname->flags &= ~(DNS_ADBFIND_GLUEOK | DNS_ADBFIND_HINTOK);
-
- rdataset.ttl = ttlclamp(rdataset.ttl);
- clean_target(adb, &adbname->target);
- adbname->expire_target = INT_MAX;
- result = set_target(adb, &adbname->name, fname, &rdataset,
- &adbname->target);
- if (result == ISC_R_SUCCESS) {
- result = DNS_R_ALIAS;
- DP(NCACHE_LEVEL,
- "adb name %p: caching alias target",
- adbname);
- adbname->expire_target = rdataset.ttl + now;
- }
- if (rdtype == dns_rdatatype_a)
- adbname->fetch_err = FIND_ERR_SUCCESS;
- else
- adbname->fetch6_err = FIND_ERR_SUCCESS;
- break;
- }
-
- if (dns_rdataset_isassociated(&rdataset))
- dns_rdataset_disassociate(&rdataset);
-
- return (result);
-}
-
-static void
-fetch_callback(isc_task_t *task, isc_event_t *ev) {
- dns_fetchevent_t *dev;
- dns_adbname_t *name;
- dns_adb_t *adb;
- dns_adbfetch_t *fetch;
- int bucket;
- isc_eventtype_t ev_status;
- isc_stdtime_t now;
- isc_result_t result;
- unsigned int address_type;
- isc_boolean_t want_check_exit = ISC_FALSE;
-
- UNUSED(task);
-
- INSIST(ev->ev_type == DNS_EVENT_FETCHDONE);
- dev = (dns_fetchevent_t *)ev;
- name = ev->ev_arg;
- INSIST(DNS_ADBNAME_VALID(name));
- adb = name->adb;
- INSIST(DNS_ADB_VALID(adb));
-
- bucket = name->lock_bucket;
- LOCK(&adb->namelocks[bucket]);
-
- INSIST(NAME_FETCH_A(name) || NAME_FETCH_AAAA(name));
- address_type = 0;
- if (NAME_FETCH_A(name) && (name->fetch_a->fetch == dev->fetch)) {
- address_type = DNS_ADBFIND_INET;
- fetch = name->fetch_a;
- name->fetch_a = NULL;
- } else if (NAME_FETCH_AAAA(name)
- && (name->fetch_aaaa->fetch == dev->fetch)) {
- address_type = DNS_ADBFIND_INET6;
- fetch = name->fetch_aaaa;
- name->fetch_aaaa = NULL;
- } else
- fetch = NULL;
-
- INSIST(address_type != 0 && fetch != NULL);
-
- dns_resolver_destroyfetch(&fetch->fetch);
- dev->fetch = NULL;
-
- ev_status = DNS_EVENT_ADBNOMOREADDRESSES;
-
- /*
- * Cleanup things we don't care about.
- */
- if (dev->node != NULL)
- dns_db_detachnode(dev->db, &dev->node);
- if (dev->db != NULL)
- dns_db_detach(&dev->db);
-
- /*
- * If this name is marked as dead, clean up, throwing away
- * potentially good data.
- */
- if (NAME_DEAD(name)) {
- free_adbfetch(adb, &fetch);
- isc_event_free(&ev);
-
- want_check_exit = kill_name(&name, DNS_EVENT_ADBCANCELED);
-
- UNLOCK(&adb->namelocks[bucket]);
-
- if (want_check_exit) {
- LOCK(&adb->lock);
- check_exit(adb);
- UNLOCK(&adb->lock);
- }
-
- return;
- }
-
- isc_stdtime_get(&now);
-
- /*
- * If we got a negative cache response, remember it.
- */
- if (NCACHE_RESULT(dev->result)) {
- dev->rdataset->ttl = ttlclamp(dev->rdataset->ttl);
- if (address_type == DNS_ADBFIND_INET) {
- DP(NCACHE_LEVEL, "adb fetch name %p: "
- "caching negative entry for A (ttl %u)",
- name, dev->rdataset->ttl);
- name->expire_v4 = ISC_MIN(name->expire_v4,
- dev->rdataset->ttl + now);
- if (dev->result == DNS_R_NCACHENXDOMAIN)
- name->fetch_err = FIND_ERR_NXDOMAIN;
- else
- name->fetch_err = FIND_ERR_NXRRSET;
- inc_stats(adb, dns_resstatscounter_gluefetchv4fail);
- } else {
- DP(NCACHE_LEVEL, "adb fetch name %p: "
- "caching negative entry for AAAA (ttl %u)",
- name, dev->rdataset->ttl);
- name->expire_v6 = ISC_MIN(name->expire_v6,
- dev->rdataset->ttl + now);
- if (dev->result == DNS_R_NCACHENXDOMAIN)
- name->fetch6_err = FIND_ERR_NXDOMAIN;
- else
- name->fetch6_err = FIND_ERR_NXRRSET;
- inc_stats(adb, dns_resstatscounter_gluefetchv6fail);
- }
- goto out;
- }
-
- /*
- * Handle CNAME/DNAME.
- */
- if (dev->result == DNS_R_CNAME || dev->result == DNS_R_DNAME) {
- dev->rdataset->ttl = ttlclamp(dev->rdataset->ttl);
- clean_target(adb, &name->target);
- name->expire_target = INT_MAX;
- result = set_target(adb, &name->name,
- dns_fixedname_name(&dev->foundname),
- dev->rdataset,
- &name->target);
- if (result == ISC_R_SUCCESS) {
- DP(NCACHE_LEVEL,
- "adb fetch name %p: caching alias target",
- name);
- name->expire_target = dev->rdataset->ttl + now;
- }
- goto check_result;
- }
-
- /*
- * Did we get back junk? If so, and there are no more fetches
- * sitting out there, tell all the finds about it.
- */
- if (dev->result != ISC_R_SUCCESS) {
- char buf[DNS_NAME_FORMATSIZE];
-
- dns_name_format(&name->name, buf, sizeof(buf));
- DP(DEF_LEVEL, "adb: fetch of '%s' %s failed: %s",
- buf, address_type == DNS_ADBFIND_INET ? "A" : "AAAA",
- dns_result_totext(dev->result));
- /* XXXMLG Don't pound on bad servers. */
- if (address_type == DNS_ADBFIND_INET) {
- name->expire_v4 = ISC_MIN(name->expire_v4, now + 300);
- name->fetch_err = FIND_ERR_FAILURE;
- inc_stats(adb, dns_resstatscounter_gluefetchv4fail);
- } else {
- name->expire_v6 = ISC_MIN(name->expire_v6, now + 300);
- name->fetch6_err = FIND_ERR_FAILURE;
- inc_stats(adb, dns_resstatscounter_gluefetchv6fail);
- }
- goto out;
- }
-
- /*
- * We got something potentially useful.
- */
- result = import_rdataset(name, &fetch->rdataset, now);
-
- check_result:
- if (result == ISC_R_SUCCESS) {
- ev_status = DNS_EVENT_ADBMOREADDRESSES;
- if (address_type == DNS_ADBFIND_INET)
- name->fetch_err = FIND_ERR_SUCCESS;
- else
- name->fetch6_err = FIND_ERR_SUCCESS;
- }
-
- out:
- free_adbfetch(adb, &fetch);
- isc_event_free(&ev);
-
- clean_finds_at_name(name, ev_status, address_type);
-
- UNLOCK(&adb->namelocks[bucket]);
-}
-
-static isc_result_t
-fetch_name(dns_adbname_t *adbname,
- isc_boolean_t start_at_zone,
- dns_rdatatype_t type)
-{
- isc_result_t result;
- dns_adbfetch_t *fetch = NULL;
- dns_adb_t *adb;
- dns_fixedname_t fixed;
- dns_name_t *name;
- dns_rdataset_t rdataset;
- dns_rdataset_t *nameservers;
- unsigned int options;
-
- INSIST(DNS_ADBNAME_VALID(adbname));
- adb = adbname->adb;
- INSIST(DNS_ADB_VALID(adb));
-
- INSIST((type == dns_rdatatype_a && !NAME_FETCH_V4(adbname)) ||
- (type == dns_rdatatype_aaaa && !NAME_FETCH_V6(adbname)));
-
- adbname->fetch_err = FIND_ERR_NOTFOUND;
-
- name = NULL;
- nameservers = NULL;
- dns_rdataset_init(&rdataset);
-
- options = DNS_FETCHOPT_NOVALIDATE;
- if (start_at_zone) {
- DP(ENTER_LEVEL,
- "fetch_name: starting at zone for name %p",
- adbname);
- dns_fixedname_init(&fixed);
- name = dns_fixedname_name(&fixed);
- result = dns_view_findzonecut2(adb->view, &adbname->name, name,
- 0, 0, ISC_TRUE, ISC_FALSE,
- &rdataset, NULL);
- if (result != ISC_R_SUCCESS && result != DNS_R_HINT)
- goto cleanup;
- nameservers = &rdataset;
- options |= DNS_FETCHOPT_UNSHARED;
- }
-
- fetch = new_adbfetch(adb);
- if (fetch == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup;
- }
-
- result = dns_resolver_createfetch(adb->view->resolver, &adbname->name,
- type, name, nameservers, NULL,
- options, adb->task, fetch_callback,
- adbname, &fetch->rdataset, NULL,
- &fetch->fetch);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- if (type == dns_rdatatype_a) {
- adbname->fetch_a = fetch;
- inc_stats(adb, dns_resstatscounter_gluefetchv4);
- } else {
- adbname->fetch_aaaa = fetch;
- inc_stats(adb, dns_resstatscounter_gluefetchv6);
- }
- fetch = NULL; /* Keep us from cleaning this up below. */
-
- cleanup:
- if (fetch != NULL)
- free_adbfetch(adb, &fetch);
- if (dns_rdataset_isassociated(&rdataset))
- dns_rdataset_disassociate(&rdataset);
-
- return (result);
-}
-
-/*
- * XXXMLG Needs to take a find argument and an address info, no zone or adb,
- * since these can be extracted from the find itself.
- */
-isc_result_t
-dns_adb_marklame(dns_adb_t *adb, dns_adbaddrinfo_t *addr, dns_name_t *qname,
- dns_rdatatype_t qtype, isc_stdtime_t expire_time)
-{
- dns_adblameinfo_t *li;
- int bucket;
- isc_result_t result = ISC_R_SUCCESS;
-
- REQUIRE(DNS_ADB_VALID(adb));
- REQUIRE(DNS_ADBADDRINFO_VALID(addr));
- REQUIRE(qname != NULL);
-
- bucket = addr->entry->lock_bucket;
- LOCK(&adb->entrylocks[bucket]);
- li = ISC_LIST_HEAD(addr->entry->lameinfo);
- while (li != NULL &&
- (li->qtype != qtype || !dns_name_equal(qname, &li->qname)))
- li = ISC_LIST_NEXT(li, plink);
- if (li != NULL) {
- if (expire_time > li->lame_timer)
- li->lame_timer = expire_time;
- goto unlock;
- }
- li = new_adblameinfo(adb, qname, qtype);
- if (li == NULL) {
- result = ISC_R_NOMEMORY;
- goto unlock;
- }
-
- li->lame_timer = expire_time;
-
- ISC_LIST_PREPEND(addr->entry->lameinfo, li, plink);
- unlock:
- UNLOCK(&adb->entrylocks[bucket]);
-
- return (result);
-}
-
-void
-dns_adb_adjustsrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
- unsigned int rtt, unsigned int factor)
-{
- int bucket;
- unsigned int new_srtt;
- isc_stdtime_t now;
-
- REQUIRE(DNS_ADB_VALID(adb));
- REQUIRE(DNS_ADBADDRINFO_VALID(addr));
- REQUIRE(factor <= 10);
-
- bucket = addr->entry->lock_bucket;
- LOCK(&adb->entrylocks[bucket]);
-
- if (factor == DNS_ADB_RTTADJAGE)
- new_srtt = addr->entry->srtt * 98 / 100;
- else
- new_srtt = (addr->entry->srtt / 10 * factor)
- + (rtt / 10 * (10 - factor));
-
- addr->entry->srtt = new_srtt;
- addr->srtt = new_srtt;
-
- if (addr->entry->expires == 0) {
- isc_stdtime_get(&now);
- addr->entry->expires = now + ADB_ENTRY_WINDOW;
- }
-
- UNLOCK(&adb->entrylocks[bucket]);
-}
-
-void
-dns_adb_changeflags(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
- unsigned int bits, unsigned int mask)
-{
- int bucket;
- isc_stdtime_t now;
-
- REQUIRE(DNS_ADB_VALID(adb));
- REQUIRE(DNS_ADBADDRINFO_VALID(addr));
-
- bucket = addr->entry->lock_bucket;
- LOCK(&adb->entrylocks[bucket]);
-
- addr->entry->flags = (addr->entry->flags & ~mask) | (bits & mask);
- if (addr->entry->expires == 0) {
- isc_stdtime_get(&now);
- addr->entry->expires = now + ADB_ENTRY_WINDOW;
- }
-
- /*
- * Note that we do not update the other bits in addr->flags with
- * the most recent values from addr->entry->flags.
- */
- addr->flags = (addr->flags & ~mask) | (bits & mask);
-
- UNLOCK(&adb->entrylocks[bucket]);
-}
-
-isc_result_t
-dns_adb_findaddrinfo(dns_adb_t *adb, isc_sockaddr_t *sa,
- dns_adbaddrinfo_t **addrp, isc_stdtime_t now)
-{
- int bucket;
- dns_adbentry_t *entry;
- dns_adbaddrinfo_t *addr;
- isc_result_t result;
- in_port_t port;
-
- REQUIRE(DNS_ADB_VALID(adb));
- REQUIRE(addrp != NULL && *addrp == NULL);
-
- UNUSED(now);
-
- result = ISC_R_SUCCESS;
- bucket = DNS_ADB_INVALIDBUCKET;
- entry = find_entry_and_lock(adb, sa, &bucket, now);
- INSIST(bucket != DNS_ADB_INVALIDBUCKET);
- if (adb->entry_sd[bucket]) {
- result = ISC_R_SHUTTINGDOWN;
- goto unlock;
- }
- if (entry == NULL) {
- /*
- * We don't know anything about this address.
- */
- entry = new_adbentry(adb);
- if (entry == NULL) {
- result = ISC_R_NOMEMORY;
- goto unlock;
- }
- entry->sockaddr = *sa;
- link_entry(adb, bucket, entry);
- DP(ENTER_LEVEL, "findaddrinfo: new entry %p", entry);
- } else
- DP(ENTER_LEVEL, "findaddrinfo: found entry %p", entry);
-
- port = isc_sockaddr_getport(sa);
- addr = new_adbaddrinfo(adb, entry, port);
- if (addr == NULL) {
- result = ISC_R_NOMEMORY;
- } else {
- inc_entry_refcnt(adb, entry, ISC_FALSE);
- *addrp = addr;
- }
-
- unlock:
- UNLOCK(&adb->entrylocks[bucket]);
-
- return (result);
-}
-
-void
-dns_adb_freeaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **addrp) {
- dns_adbaddrinfo_t *addr;
- dns_adbentry_t *entry;
- int bucket;
- isc_stdtime_t now;
- isc_boolean_t want_check_exit = ISC_FALSE;
- isc_boolean_t overmem;
-
- REQUIRE(DNS_ADB_VALID(adb));
- REQUIRE(addrp != NULL);
- addr = *addrp;
- REQUIRE(DNS_ADBADDRINFO_VALID(addr));
- entry = addr->entry;
- REQUIRE(DNS_ADBENTRY_VALID(entry));
-
- *addrp = NULL;
- overmem = isc_mem_isovermem(adb->mctx);
-
- bucket = addr->entry->lock_bucket;
- LOCK(&adb->entrylocks[bucket]);
-
- if (entry->expires == 0) {
- isc_stdtime_get(&now);
- entry->expires = now + ADB_ENTRY_WINDOW;
- }
-
- want_check_exit = dec_entry_refcnt(adb, overmem, entry, ISC_FALSE);
-
- UNLOCK(&adb->entrylocks[bucket]);
-
- addr->entry = NULL;
- free_adbaddrinfo(adb, &addr);
-
- if (want_check_exit) {
- LOCK(&adb->lock);
- check_exit(adb);
- UNLOCK(&adb->lock);
- }
-}
-
-void
-dns_adb_flush(dns_adb_t *adb) {
- unsigned int i;
-
- INSIST(DNS_ADB_VALID(adb));
-
- LOCK(&adb->lock);
-
- /*
- * Call our cleanup routines.
- */
- for (i = 0; i < adb->nnames; i++)
- RUNTIME_CHECK(cleanup_names(adb, i, INT_MAX) == ISC_FALSE);
- for (i = 0; i < adb->nentries; i++)
- RUNTIME_CHECK(cleanup_entries(adb, i, INT_MAX) == ISC_FALSE);
-
-#ifdef DUMP_ADB_AFTER_CLEANING
- dump_adb(adb, stdout, ISC_TRUE, INT_MAX);
-#endif
-
- UNLOCK(&adb->lock);
-}
-
-void
-dns_adb_flushname(dns_adb_t *adb, dns_name_t *name) {
- dns_adbname_t *adbname;
- dns_adbname_t *nextname;
- int bucket;
-
- INSIST(DNS_ADB_VALID(adb));
-
- LOCK(&adb->lock);
- bucket = dns_name_hash(name, ISC_FALSE) % adb->nnames;
- LOCK(&adb->namelocks[bucket]);
- adbname = ISC_LIST_HEAD(adb->names[bucket]);
- while (adbname != NULL) {
- nextname = ISC_LIST_NEXT(adbname, plink);
- if (!NAME_DEAD(adbname) &&
- dns_name_equal(name, &adbname->name)) {
- RUNTIME_CHECK(kill_name(&adbname,
- DNS_EVENT_ADBCANCELED) ==
- ISC_FALSE);
- }
- adbname = nextname;
- }
- UNLOCK(&adb->namelocks[bucket]);
- UNLOCK(&adb->lock);
-}
-
-static void
-water(void *arg, int mark) {
- /*
- * We're going to change the way to handle overmem condition: use
- * isc_mem_isovermem() instead of storing the state via this callback,
- * since the latter way tends to cause race conditions.
- * To minimize the change, and in case we re-enable the callback
- * approach, however, keep this function at the moment.
- */
-
- dns_adb_t *adb = arg;
- isc_boolean_t overmem = ISC_TF(mark == ISC_MEM_HIWATER);
-
- REQUIRE(DNS_ADB_VALID(adb));
-
- DP(ISC_LOG_DEBUG(1),
- "adb reached %s water mark", overmem ? "high" : "low");
-}
-
-void
-dns_adb_setadbsize(dns_adb_t *adb, size_t size) {
- size_t hiwater, lowater;
-
- INSIST(DNS_ADB_VALID(adb));
-
- if (size != 0U && size < DNS_ADB_MINADBSIZE)
- size = DNS_ADB_MINADBSIZE;
-
- hiwater = size - (size >> 3); /* Approximately 7/8ths. */
- lowater = size - (size >> 2); /* Approximately 3/4ths. */
-
- if (size == 0U || hiwater == 0U || lowater == 0U)
- isc_mem_setwater(adb->mctx, water, adb, 0, 0);
- else
- isc_mem_setwater(adb->mctx, water, adb, hiwater, lowater);
-}
diff --git a/contrib/bind9/lib/dns/api b/contrib/bind9/lib/dns/api
deleted file mode 100644
index a8881101f4e1..000000000000
--- a/contrib/bind9/lib/dns/api
+++ /dev/null
@@ -1,9 +0,0 @@
-# LIBINTERFACE ranges
-# 9.6: 50-59, 110-119
-# 9.7: 60-79
-# 9.8: 80-89, 120-129
-# 9.9: 90-109
-# 9.9-sub: 130-139
-LIBINTERFACE = 99
-LIBREVISION = 1
-LIBAGE = 0
diff --git a/contrib/bind9/lib/dns/byaddr.c b/contrib/bind9/lib/dns/byaddr.c
deleted file mode 100644
index eb05f9f80f37..000000000000
--- a/contrib/bind9/lib/dns/byaddr.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007, 2009, 2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2000-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: byaddr.c,v 1.41 2009/09/02 23:48:02 tbox Exp $ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <isc/mem.h>
-#include <isc/netaddr.h>
-#include <isc/print.h>
-#include <isc/string.h> /* Required for HP/UX (and others?) */
-#include <isc/task.h>
-#include <isc/util.h>
-
-#include <dns/byaddr.h>
-#include <dns/db.h>
-#include <dns/events.h>
-#include <dns/lookup.h>
-#include <dns/rdata.h>
-#include <dns/rdataset.h>
-#include <dns/rdatastruct.h>
-#include <dns/resolver.h>
-#include <dns/result.h>
-#include <dns/view.h>
-
-/*
- * XXXRTH We could use a static event...
- */
-
-static char hex_digits[] = {
- '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
-};
-
-isc_result_t
-dns_byaddr_createptrname(isc_netaddr_t *address, isc_boolean_t nibble,
- dns_name_t *name)
-{
- /*
- * We dropped bitstring labels, so all lookups will use nibbles.
- */
- UNUSED(nibble);
-
- return (dns_byaddr_createptrname2(address,
- DNS_BYADDROPT_IPV6INT, name));
-}
-
-isc_result_t
-dns_byaddr_createptrname2(isc_netaddr_t *address, unsigned int options,
- dns_name_t *name)
-{
- char textname[128];
- unsigned char *bytes;
- int i;
- char *cp;
- isc_buffer_t buffer;
- unsigned int len;
-
- REQUIRE(address != NULL);
-
- /*
- * We create the text representation and then convert to a
- * dns_name_t. This is not maximally efficient, but it keeps all
- * of the knowledge of wire format in the dns_name_ routines.
- */
-
- bytes = (unsigned char *)(&address->type);
- if (address->family == AF_INET) {
- (void)snprintf(textname, sizeof(textname),
- "%u.%u.%u.%u.in-addr.arpa.",
- (bytes[3] & 0xff),
- (bytes[2] & 0xff),
- (bytes[1] & 0xff),
- (bytes[0] & 0xff));
- } else if (address->family == AF_INET6) {
- cp = textname;
- for (i = 15; i >= 0; i--) {
- *cp++ = hex_digits[bytes[i] & 0x0f];
- *cp++ = '.';
- *cp++ = hex_digits[(bytes[i] >> 4) & 0x0f];
- *cp++ = '.';
- }
- if ((options & DNS_BYADDROPT_IPV6INT) != 0)
- strcpy(cp, "ip6.int.");
- else
- strcpy(cp, "ip6.arpa.");
- } else
- return (ISC_R_NOTIMPLEMENTED);
-
- len = (unsigned int)strlen(textname);
- isc_buffer_init(&buffer, textname, len);
- isc_buffer_add(&buffer, len);
- 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;
- dns_name_t *name;
- dns_rdata_t rdata = DNS_RDATA_INIT;
-
- /*
- * The caller must be holding the byaddr's lock.
- */
-
- result = dns_rdataset_first(rdataset);
- while (result == ISC_R_SUCCESS) {
- dns_rdata_ptr_t ptr;
- dns_rdataset_current(rdataset, &rdata);
- result = dns_rdata_tostruct(&rdata, &ptr, NULL);
- if (result != ISC_R_SUCCESS)
- return (result);
- name = isc_mem_get(byaddr->mctx, sizeof(*name));
- if (name == NULL) {
- dns_rdata_freestruct(&ptr);
- return (ISC_R_NOMEMORY);
- }
- dns_name_init(name, NULL);
- result = dns_name_dup(&ptr.ptr, byaddr->mctx, name);
- dns_rdata_freestruct(&ptr);
- if (result != ISC_R_SUCCESS) {
- isc_mem_put(byaddr->mctx, name, sizeof(*name));
- return (ISC_R_NOMEMORY);
- }
- ISC_LIST_APPEND(byaddr->event->names, name, link);
- dns_rdata_reset(&rdata);
- result = dns_rdataset_next(rdataset);
- }
- if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
-
- return (result);
-}
-
-static void
-lookup_done(isc_task_t *task, isc_event_t *event) {
- dns_byaddr_t *byaddr = event->ev_arg;
- dns_lookupevent_t *levent;
- isc_result_t result;
-
- REQUIRE(event->ev_type == DNS_EVENT_LOOKUPDONE);
- REQUIRE(VALID_BYADDR(byaddr));
- REQUIRE(byaddr->task == task);
-
- UNUSED(task);
-
- levent = (dns_lookupevent_t *)event;
-
- if (levent->result == ISC_R_SUCCESS) {
- result = copy_ptr_targets(byaddr, levent->rdataset);
- byaddr->event->result = result;
- } else
- byaddr->event->result = levent->result;
- isc_event_free(&event);
- isc_task_sendanddetach(&byaddr->task, (isc_event_t **)&byaddr->event);
-}
-
-static void
-bevent_destroy(isc_event_t *event) {
- dns_byaddrevent_t *bevent;
- dns_name_t *name, *next_name;
- isc_mem_t *mctx;
-
- REQUIRE(event->ev_type == DNS_EVENT_BYADDRDONE);
- mctx = event->ev_destroy_arg;
- bevent = (dns_byaddrevent_t *)event;
-
- for (name = ISC_LIST_HEAD(bevent->names);
- name != NULL;
- name = next_name) {
- next_name = ISC_LIST_NEXT(name, link);
- ISC_LIST_UNLINK(bevent->names, name, link);
- dns_name_free(name, mctx);
- isc_mem_put(mctx, name, sizeof(*name));
- }
- isc_mem_put(mctx, event, event->ev_size);
-}
-
-isc_result_t
-dns_byaddr_create(isc_mem_t *mctx, isc_netaddr_t *address, dns_view_t *view,
- unsigned int options, isc_task_t *task,
- isc_taskaction_t action, void *arg, dns_byaddr_t **byaddrp)
-{
- isc_result_t result;
- dns_byaddr_t *byaddr;
- isc_event_t *ievent;
-
- byaddr = isc_mem_get(mctx, sizeof(*byaddr));
- if (byaddr == NULL)
- return (ISC_R_NOMEMORY);
- byaddr->mctx = NULL;
- isc_mem_attach(mctx, &byaddr->mctx);
- byaddr->options = options;
-
- byaddr->event = isc_mem_get(mctx, sizeof(*byaddr->event));
- if (byaddr->event == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup_byaddr;
- }
- ISC_EVENT_INIT(byaddr->event, sizeof(*byaddr->event), 0, NULL,
- DNS_EVENT_BYADDRDONE, action, arg, byaddr,
- bevent_destroy, mctx);
- byaddr->event->result = ISC_R_FAILURE;
- ISC_LIST_INIT(byaddr->event->names);
-
- byaddr->task = NULL;
- isc_task_attach(task, &byaddr->task);
-
- result = isc_mutex_init(&byaddr->lock);
- if (result != ISC_R_SUCCESS)
- goto cleanup_event;
-
- dns_fixedname_init(&byaddr->name);
-
- result = dns_byaddr_createptrname2(address, options,
- dns_fixedname_name(&byaddr->name));
- if (result != ISC_R_SUCCESS)
- goto cleanup_lock;
-
- byaddr->lookup = NULL;
- result = dns_lookup_create(mctx, dns_fixedname_name(&byaddr->name),
- dns_rdatatype_ptr, view, 0, task,
- lookup_done, byaddr, &byaddr->lookup);
- if (result != ISC_R_SUCCESS)
- goto cleanup_lock;
-
- byaddr->canceled = ISC_FALSE;
- byaddr->magic = BYADDR_MAGIC;
-
- *byaddrp = byaddr;
-
- return (ISC_R_SUCCESS);
-
- cleanup_lock:
- DESTROYLOCK(&byaddr->lock);
-
- cleanup_event:
- ievent = (isc_event_t *)byaddr->event;
- isc_event_free(&ievent);
- byaddr->event = NULL;
-
- isc_task_detach(&byaddr->task);
-
- cleanup_byaddr:
- isc_mem_putanddetach(&mctx, byaddr, sizeof(*byaddr));
-
- return (result);
-}
-
-void
-dns_byaddr_cancel(dns_byaddr_t *byaddr) {
- REQUIRE(VALID_BYADDR(byaddr));
-
- LOCK(&byaddr->lock);
-
- if (!byaddr->canceled) {
- byaddr->canceled = ISC_TRUE;
- if (byaddr->lookup != NULL)
- dns_lookup_cancel(byaddr->lookup);
- }
-
- UNLOCK(&byaddr->lock);
-}
-
-void
-dns_byaddr_destroy(dns_byaddr_t **byaddrp) {
- dns_byaddr_t *byaddr;
-
- REQUIRE(byaddrp != NULL);
- byaddr = *byaddrp;
- REQUIRE(VALID_BYADDR(byaddr));
- REQUIRE(byaddr->event == NULL);
- REQUIRE(byaddr->task == NULL);
- dns_lookup_destroy(&byaddr->lookup);
-
- DESTROYLOCK(&byaddr->lock);
- byaddr->magic = 0;
- isc_mem_putanddetach(&byaddr->mctx, byaddr, sizeof(*byaddr));
-
- *byaddrp = NULL;
-}
-#endif /* BIND9 */
diff --git a/contrib/bind9/lib/dns/cache.c b/contrib/bind9/lib/dns/cache.c
deleted file mode 100644
index d0f05b9a09ab..000000000000
--- a/contrib/bind9/lib/dns/cache.c
+++ /dev/null
@@ -1,1280 +0,0 @@
-/*
- * Copyright (C) 2004-2009, 2011, 2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: cache.c,v 1.91 2011/08/26 05:12:56 marka Exp $ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <isc/mem.h>
-#include <isc/string.h>
-#include <isc/task.h>
-#include <isc/time.h>
-#include <isc/timer.h>
-#include <isc/util.h>
-
-#include <dns/cache.h>
-#include <dns/db.h>
-#include <dns/dbiterator.h>
-#include <dns/events.h>
-#include <dns/lib.h>
-#include <dns/log.h>
-#include <dns/masterdump.h>
-#include <dns/rdata.h>
-#include <dns/rdataset.h>
-#include <dns/rdatasetiter.h>
-#include <dns/result.h>
-
-#include "rbtdb.h"
-
-#define CACHE_MAGIC ISC_MAGIC('$', '$', '$', '$')
-#define VALID_CACHE(cache) ISC_MAGIC_VALID(cache, CACHE_MAGIC)
-
-/*!
- * Control incremental cleaning.
- * DNS_CACHE_MINSIZE is how many bytes is the floor for dns_cache_setcachesize().
- * See also DNS_CACHE_CLEANERINCREMENT
- */
-#define DNS_CACHE_MINSIZE 2097152U /*%< Bytes. 2097152 = 2 MB */
-/*!
- * Control incremental cleaning.
- * CLEANERINCREMENT is how many nodes are examined in one pass.
- * See also DNS_CACHE_MINSIZE
- */
-#define DNS_CACHE_CLEANERINCREMENT 1000U /*%< Number of nodes. */
-
-/***
- *** Types
- ***/
-
-/*
- * A cache_cleaner_t encapsulates the state of the periodic
- * cache cleaning.
- */
-
-typedef struct cache_cleaner cache_cleaner_t;
-
-typedef enum {
- cleaner_s_idle, /*%< Waiting for cleaning-interval to expire. */
- cleaner_s_busy, /*%< Currently cleaning. */
- cleaner_s_done /*%< Freed enough memory after being overmem. */
-} cleaner_state_t;
-
-/*
- * Convenience macros for comprehensive assertion checking.
- */
-#define CLEANER_IDLE(c) ((c)->state == cleaner_s_idle && \
- (c)->resched_event != NULL)
-#define CLEANER_BUSY(c) ((c)->state == cleaner_s_busy && \
- (c)->iterator != NULL && \
- (c)->resched_event == NULL)
-
-/*%
- * Accesses to a cache cleaner object are synchronized through
- * task/event serialization, or locked from the cache object.
- */
-struct cache_cleaner {
- isc_mutex_t lock;
- /*%<
- * Locks overmem_event, overmem. Note: never allocate memory
- * while holding this lock - that could lead to deadlock since
- * the lock is take by water() which is called from the memory
- * allocator.
- */
-
- dns_cache_t *cache;
- isc_task_t *task;
- unsigned int cleaning_interval; /*% The cleaning-interval from
- named.conf, in seconds. */
- isc_timer_t *cleaning_timer;
- isc_event_t *resched_event; /*% Sent by cleaner task to
- itself to reschedule */
- isc_event_t *overmem_event;
-
- dns_dbiterator_t *iterator;
- unsigned int increment; /*% Number of names to
- clean in one increment */
- cleaner_state_t state; /*% Idle/Busy. */
- isc_boolean_t overmem; /*% The cache is in an overmem state. */
- isc_boolean_t replaceiterator;
-};
-
-/*%
- * The actual cache object.
- */
-
-struct dns_cache {
- /* Unlocked. */
- unsigned int magic;
- isc_mutex_t lock;
- isc_mutex_t filelock;
- isc_mem_t *mctx; /* Main cache memory */
- isc_mem_t *hmctx; /* Heap memory */
- char *name;
-
- /* Locked by 'lock'. */
- int references;
- int live_tasks;
- dns_rdataclass_t rdclass;
- dns_db_t *db;
- cache_cleaner_t cleaner;
- char *db_type;
- int db_argc;
- char **db_argv;
- size_t size;
-
- /* Locked by 'filelock'. */
- char *filename;
- /* Access to the on-disk cache file is also locked by 'filelock'. */
-};
-
-/***
- *** Functions
- ***/
-
-static isc_result_t
-cache_cleaner_init(dns_cache_t *cache, isc_taskmgr_t *taskmgr,
- isc_timermgr_t *timermgr, cache_cleaner_t *cleaner);
-
-static void
-cleaning_timer_action(isc_task_t *task, isc_event_t *event);
-
-static void
-incremental_cleaning_action(isc_task_t *task, isc_event_t *event);
-
-static void
-cleaner_shutdown_action(isc_task_t *task, isc_event_t *event);
-
-static void
-overmem_cleaning_action(isc_task_t *task, isc_event_t *event);
-
-static inline isc_result_t
-cache_create_db(dns_cache_t *cache, dns_db_t **db) {
- return (dns_db_create(cache->mctx, cache->db_type, dns_rootname,
- dns_dbtype_cache, cache->rdclass,
- cache->db_argc, cache->db_argv, db));
-}
-
-isc_result_t
-dns_cache_create(isc_mem_t *cmctx, 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)
-{
- return (dns_cache_create3(cmctx, cmctx, taskmgr, timermgr, rdclass, "",
- db_type, db_argc, db_argv, cachep));
-}
-
-isc_result_t
-dns_cache_create2(isc_mem_t *cmctx, 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)
-{
- return (dns_cache_create3(cmctx, cmctx, taskmgr, timermgr, rdclass,
- cachename, db_type, db_argc, db_argv,
- cachep));
-}
-
-isc_result_t
-dns_cache_create3(isc_mem_t *cmctx, isc_mem_t *hmctx, 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, extra = 0;
- isc_task_t *dbtask;
-
- REQUIRE(cachep != NULL);
- REQUIRE(*cachep == NULL);
- REQUIRE(cmctx != NULL);
- REQUIRE(hmctx != NULL);
- REQUIRE(cachename != NULL);
-
- cache = isc_mem_get(cmctx, sizeof(*cache));
- if (cache == NULL)
- return (ISC_R_NOMEMORY);
-
- cache->mctx = cache->hmctx = NULL;
- isc_mem_attach(cmctx, &cache->mctx);
- isc_mem_attach(hmctx, &cache->hmctx);
-
- cache->name = NULL;
- if (cachename != NULL) {
- cache->name = isc_mem_strdup(cmctx, 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;
-
- result = isc_mutex_init(&cache->filelock);
- if (result != ISC_R_SUCCESS)
- goto cleanup_lock;
-
- cache->references = 1;
- cache->live_tasks = 0;
- cache->rdclass = rdclass;
-
- cache->db_type = isc_mem_strdup(cmctx, db_type);
- if (cache->db_type == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup_filelock;
- }
-
- /*
- * For databases of type "rbt" we pass hmctx to dns_db_create()
- * via cache->db_argv, followed by the rest of the arguments in
- * db_argv (of which there really shouldn't be any).
- */
- if (strcmp(cache->db_type, "rbt") == 0)
- extra = 1;
-
- cache->db_argc = db_argc + extra;
- cache->db_argv = NULL;
-
- if (cache->db_argc != 0) {
- cache->db_argv = isc_mem_get(cmctx,
- cache->db_argc * sizeof(char *));
- if (cache->db_argv == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup_dbtype;
- }
-
- for (i = 0; i < cache->db_argc; i++)
- cache->db_argv[i] = NULL;
-
- cache->db_argv[0] = (char *) hmctx;
- for (i = extra; i < cache->db_argc; i++) {
- cache->db_argv[i] = isc_mem_strdup(cmctx,
- db_argv[i - extra]);
- if (cache->db_argv[i] == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup_dbargv;
- }
- }
- }
-
- /*
- * Create the database
- */
- cache->db = NULL;
- result = cache_create_db(cache, &cache->db);
- if (result != ISC_R_SUCCESS)
- goto cleanup_dbargv;
- if (taskmgr != NULL) {
- dbtask = NULL;
- result = isc_task_create(taskmgr, 1, &dbtask);
- if (result != ISC_R_SUCCESS)
- goto cleanup_db;
- dns_db_settask(cache->db, dbtask);
- isc_task_detach(&dbtask);
- }
-
- cache->filename = NULL;
-
- cache->magic = CACHE_MAGIC;
-
- /*
- * RBT-type cache DB has its own mechanism of cache cleaning and doesn't
- * need the control of the generic cleaner.
- */
- if (strcmp(db_type, "rbt") == 0)
- result = cache_cleaner_init(cache, NULL, NULL, &cache->cleaner);
- else {
- result = cache_cleaner_init(cache, taskmgr, timermgr,
- &cache->cleaner);
- }
- if (result != ISC_R_SUCCESS)
- goto cleanup_db;
-
- *cachep = cache;
- return (ISC_R_SUCCESS);
-
- cleanup_db:
- dns_db_detach(&cache->db);
- cleanup_dbargv:
- for (i = extra; i < cache->db_argc; i++)
- if (cache->db_argv[i] != NULL)
- isc_mem_free(cmctx, cache->db_argv[i]);
- if (cache->db_argv != NULL)
- isc_mem_put(cmctx, cache->db_argv,
- cache->db_argc * sizeof(char *));
- cleanup_dbtype:
- isc_mem_free(cmctx, cache->db_type);
- cleanup_filelock:
- DESTROYLOCK(&cache->filelock);
- cleanup_lock:
- DESTROYLOCK(&cache->lock);
- cleanup_mem:
- if (cache->name != NULL)
- isc_mem_free(cmctx, cache->name);
- isc_mem_detach(&cache->hmctx);
- isc_mem_putanddetach(&cache->mctx, cache, sizeof(*cache));
- return (result);
-}
-
-static void
-cache_free(dns_cache_t *cache) {
- int i;
-
- REQUIRE(VALID_CACHE(cache));
- REQUIRE(cache->references == 0);
-
- isc_mem_setwater(cache->mctx, NULL, NULL, 0, 0);
-
- if (cache->cleaner.task != NULL)
- isc_task_detach(&cache->cleaner.task);
-
- if (cache->cleaner.overmem_event != NULL)
- isc_event_free(&cache->cleaner.overmem_event);
-
- if (cache->cleaner.resched_event != NULL)
- isc_event_free(&cache->cleaner.resched_event);
-
- if (cache->cleaner.iterator != NULL)
- dns_dbiterator_destroy(&cache->cleaner.iterator);
-
- DESTROYLOCK(&cache->cleaner.lock);
-
- if (cache->filename) {
- isc_mem_free(cache->mctx, cache->filename);
- cache->filename = NULL;
- }
-
- if (cache->db != NULL)
- dns_db_detach(&cache->db);
-
- if (cache->db_argv != NULL) {
- /*
- * We don't free db_argv[0] in "rbt" cache databases
- * as it's a pointer to hmctx
- */
- int extra = 0;
- if (strcmp(cache->db_type, "rbt") == 0)
- extra = 1;
- for (i = extra; i < cache->db_argc; i++)
- if (cache->db_argv[i] != NULL)
- isc_mem_free(cache->mctx, cache->db_argv[i]);
- isc_mem_put(cache->mctx, cache->db_argv,
- cache->db_argc * sizeof(char *));
- }
-
- 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;
- isc_mem_detach(&cache->hmctx);
- isc_mem_putanddetach(&cache->mctx, cache, sizeof(*cache));
-}
-
-
-void
-dns_cache_attach(dns_cache_t *cache, dns_cache_t **targetp) {
-
- REQUIRE(VALID_CACHE(cache));
- REQUIRE(targetp != NULL && *targetp == NULL);
-
- LOCK(&cache->lock);
- cache->references++;
- UNLOCK(&cache->lock);
-
- *targetp = cache;
-}
-
-void
-dns_cache_detach(dns_cache_t **cachep) {
- dns_cache_t *cache;
- isc_boolean_t free_cache = ISC_FALSE;
-
- REQUIRE(cachep != NULL);
- cache = *cachep;
- REQUIRE(VALID_CACHE(cache));
-
- LOCK(&cache->lock);
- REQUIRE(cache->references > 0);
- cache->references--;
- if (cache->references == 0) {
- cache->cleaner.overmem = ISC_FALSE;
- free_cache = ISC_TRUE;
- }
-
- *cachep = NULL;
-
- if (free_cache) {
- /*
- * When the cache is shut down, dump it to a file if one is
- * specified.
- */
- isc_result_t result = dns_cache_dump(cache);
- if (result != ISC_R_SUCCESS)
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_CACHE, ISC_LOG_WARNING,
- "error dumping cache: %s ",
- isc_result_totext(result));
-
- /*
- * If the cleaner task exists, let it free the cache.
- */
- if (cache->live_tasks > 0) {
- isc_task_shutdown(cache->cleaner.task);
- free_cache = ISC_FALSE;
- }
- }
-
- UNLOCK(&cache->lock);
-
- if (free_cache)
- cache_free(cache);
-}
-
-void
-dns_cache_attachdb(dns_cache_t *cache, dns_db_t **dbp) {
- REQUIRE(VALID_CACHE(cache));
- REQUIRE(dbp != NULL && *dbp == NULL);
- REQUIRE(cache->db != NULL);
-
- LOCK(&cache->lock);
- dns_db_attach(cache->db, dbp);
- UNLOCK(&cache->lock);
-
-}
-
-isc_result_t
-dns_cache_setfilename(dns_cache_t *cache, const char *filename) {
- char *newname;
-
- REQUIRE(VALID_CACHE(cache));
- REQUIRE(filename != NULL);
-
- newname = isc_mem_strdup(cache->mctx, filename);
- if (newname == NULL)
- return (ISC_R_NOMEMORY);
-
- LOCK(&cache->filelock);
- if (cache->filename)
- isc_mem_free(cache->mctx, cache->filename);
- cache->filename = newname;
- UNLOCK(&cache->filelock);
-
- return (ISC_R_SUCCESS);
-}
-
-#ifdef BIND9
-isc_result_t
-dns_cache_load(dns_cache_t *cache) {
- isc_result_t result;
-
- REQUIRE(VALID_CACHE(cache));
-
- if (cache->filename == NULL)
- return (ISC_R_SUCCESS);
-
- LOCK(&cache->filelock);
- result = dns_db_load(cache->db, cache->filename);
- UNLOCK(&cache->filelock);
-
- 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
-dns_cache_setcleaninginterval(dns_cache_t *cache, unsigned int t) {
- isc_interval_t interval;
- isc_result_t result;
-
- LOCK(&cache->lock);
-
- /*
- * It may be the case that the cache has already shut down.
- * If so, it has no timer.
- */
- if (cache->cleaner.cleaning_timer == NULL)
- goto unlock;
-
- cache->cleaner.cleaning_interval = t;
-
- if (t == 0) {
- result = isc_timer_reset(cache->cleaner.cleaning_timer,
- isc_timertype_inactive,
- NULL, NULL, ISC_TRUE);
- } else {
- isc_interval_set(&interval, cache->cleaner.cleaning_interval,
- 0);
- result = isc_timer_reset(cache->cleaner.cleaning_timer,
- isc_timertype_ticker,
- NULL, &interval, ISC_FALSE);
- }
- if (result != ISC_R_SUCCESS)
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_CACHE, ISC_LOG_WARNING,
- "could not set cache cleaning interval: %s",
- isc_result_totext(result));
-
- unlock:
- 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.
- */
-
-static isc_result_t
-cache_cleaner_init(dns_cache_t *cache, isc_taskmgr_t *taskmgr,
- isc_timermgr_t *timermgr, cache_cleaner_t *cleaner)
-{
- isc_result_t result;
-
- result = isc_mutex_init(&cleaner->lock);
- if (result != ISC_R_SUCCESS)
- goto fail;
-
- cleaner->increment = DNS_CACHE_CLEANERINCREMENT;
- cleaner->state = cleaner_s_idle;
- cleaner->cache = cache;
- cleaner->iterator = NULL;
- cleaner->overmem = ISC_FALSE;
- cleaner->replaceiterator = ISC_FALSE;
-
- cleaner->task = NULL;
- 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);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- if (taskmgr != NULL && timermgr != NULL) {
- result = isc_task_create(taskmgr, 1, &cleaner->task);
- if (result != ISC_R_SUCCESS) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_task_create() failed: %s",
- dns_result_totext(result));
- result = ISC_R_UNEXPECTED;
- goto cleanup;
- }
- cleaner->cache->live_tasks++;
- isc_task_setname(cleaner->task, "cachecleaner", cleaner);
-
- result = isc_task_onshutdown(cleaner->task,
- cleaner_shutdown_action, cache);
- if (result != ISC_R_SUCCESS) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "cache cleaner: "
- "isc_task_onshutdown() failed: %s",
- dns_result_totext(result));
- goto cleanup;
- }
-
- result = isc_timer_create(timermgr, isc_timertype_inactive,
- NULL, NULL, cleaner->task,
- cleaning_timer_action, cleaner,
- &cleaner->cleaning_timer);
- if (result != ISC_R_SUCCESS) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_timer_create() failed: %s",
- dns_result_totext(result));
- result = ISC_R_UNEXPECTED;
- goto cleanup;
- }
-
- cleaner->resched_event =
- isc_event_allocate(cache->mctx, cleaner,
- DNS_EVENT_CACHECLEAN,
- incremental_cleaning_action,
- cleaner, sizeof(isc_event_t));
- if (cleaner->resched_event == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup;
- }
-
- cleaner->overmem_event =
- isc_event_allocate(cache->mctx, cleaner,
- DNS_EVENT_CACHEOVERMEM,
- overmem_cleaning_action,
- cleaner, sizeof(isc_event_t));
- if (cleaner->overmem_event == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup;
- }
- }
-
- return (ISC_R_SUCCESS);
-
- cleanup:
- if (cleaner->overmem_event != NULL)
- isc_event_free(&cleaner->overmem_event);
- if (cleaner->resched_event != NULL)
- isc_event_free(&cleaner->resched_event);
- if (cleaner->cleaning_timer != NULL)
- isc_timer_detach(&cleaner->cleaning_timer);
- if (cleaner->task != NULL)
- isc_task_detach(&cleaner->task);
- if (cleaner->iterator != NULL)
- dns_dbiterator_destroy(&cleaner->iterator);
- DESTROYLOCK(&cleaner->lock);
- fail:
- return (result);
-}
-
-static void
-begin_cleaning(cache_cleaner_t *cleaner) {
- isc_result_t result = ISC_R_SUCCESS;
-
- REQUIRE(CLEANER_IDLE(cleaner));
-
- /*
- * Create an iterator, if it does not already exist, and
- * position it at the beginning of the cache.
- */
- if (cleaner->iterator == NULL)
- result = dns_db_createiterator(cleaner->cache->db, ISC_FALSE,
- &cleaner->iterator);
- if (result != ISC_R_SUCCESS)
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_CACHE, ISC_LOG_WARNING,
- "cache cleaner could not create "
- "iterator: %s", isc_result_totext(result));
- else {
- dns_dbiterator_setcleanmode(cleaner->iterator, ISC_TRUE);
- result = dns_dbiterator_first(cleaner->iterator);
- }
- if (result != ISC_R_SUCCESS) {
- /*
- * If the result is ISC_R_NOMORE, the database is empty,
- * so there is nothing to be cleaned.
- */
- if (result != ISC_R_NOMORE && cleaner->iterator != NULL) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "cache cleaner: "
- "dns_dbiterator_first() failed: %s",
- dns_result_totext(result));
- dns_dbiterator_destroy(&cleaner->iterator);
- } else if (cleaner->iterator != NULL) {
- result = dns_dbiterator_pause(cleaner->iterator);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- }
- } else {
- /*
- * Pause the iterator to free its lock.
- */
- result = dns_dbiterator_pause(cleaner->iterator);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
-
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_CACHE, ISC_LOG_DEBUG(1),
- "begin cache cleaning, mem inuse %lu",
- (unsigned long)isc_mem_inuse(cleaner->cache->mctx));
- cleaner->state = cleaner_s_busy;
- isc_task_send(cleaner->task, &cleaner->resched_event);
- }
-
- return;
-}
-
-static void
-end_cleaning(cache_cleaner_t *cleaner, isc_event_t *event) {
- isc_result_t result;
-
- REQUIRE(CLEANER_BUSY(cleaner));
- REQUIRE(event != NULL);
-
- result = dns_dbiterator_pause(cleaner->iterator);
- if (result != ISC_R_SUCCESS)
- dns_dbiterator_destroy(&cleaner->iterator);
-
- dns_cache_setcleaninginterval(cleaner->cache,
- cleaner->cleaning_interval);
-
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE,
- ISC_LOG_DEBUG(1), "end cache cleaning, mem inuse %lu",
- (unsigned long)isc_mem_inuse(cleaner->cache->mctx));
-
- cleaner->state = cleaner_s_idle;
- cleaner->resched_event = event;
-}
-
-/*
- * This is run once for every cache-cleaning-interval as defined in named.conf.
- */
-static void
-cleaning_timer_action(isc_task_t *task, isc_event_t *event) {
- cache_cleaner_t *cleaner = event->ev_arg;
-
- UNUSED(task);
-
- INSIST(task == cleaner->task);
- INSIST(event->ev_type == ISC_TIMEREVENT_TICK);
-
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE,
- ISC_LOG_DEBUG(1), "cache cleaning timer fired, "
- "cleaner state = %d", cleaner->state);
-
- if (cleaner->state == cleaner_s_idle)
- begin_cleaning(cleaner);
-
- isc_event_free(&event);
-}
-
-/*
- * This is called when the cache either surpasses its upper limit
- * or shrinks beyond its lower limit.
- */
-static void
-overmem_cleaning_action(isc_task_t *task, isc_event_t *event) {
- cache_cleaner_t *cleaner = event->ev_arg;
- isc_boolean_t want_cleaning = ISC_FALSE;
-
- UNUSED(task);
-
- INSIST(task == cleaner->task);
- INSIST(event->ev_type == DNS_EVENT_CACHEOVERMEM);
- INSIST(cleaner->overmem_event == NULL);
-
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE,
- ISC_LOG_DEBUG(1), "overmem_cleaning_action called, "
- "overmem = %d, state = %d", cleaner->overmem,
- cleaner->state);
-
- LOCK(&cleaner->lock);
-
- if (cleaner->overmem) {
- if (cleaner->state == cleaner_s_idle)
- want_cleaning = ISC_TRUE;
- } else {
- if (cleaner->state == cleaner_s_busy)
- /*
- * end_cleaning() can't be called here because
- * then both cleaner->overmem_event and
- * cleaner->resched_event will point to this
- * event. Set the state to done, and then
- * when the incremental_cleaning_action() event
- * is posted, it will handle the end_cleaning.
- */
- cleaner->state = cleaner_s_done;
- }
-
- cleaner->overmem_event = event;
-
- UNLOCK(&cleaner->lock);
-
- if (want_cleaning)
- begin_cleaning(cleaner);
-}
-
-/*
- * Do incremental cleaning.
- */
-static void
-incremental_cleaning_action(isc_task_t *task, isc_event_t *event) {
- cache_cleaner_t *cleaner = event->ev_arg;
- isc_result_t result;
- unsigned int n_names;
- isc_time_t start;
-
- UNUSED(task);
-
- INSIST(task == cleaner->task);
- INSIST(event->ev_type == DNS_EVENT_CACHECLEAN);
-
- if (cleaner->state == cleaner_s_done) {
- cleaner->state = cleaner_s_busy;
- end_cleaning(cleaner, event);
- LOCK(&cleaner->cache->lock);
- LOCK(&cleaner->lock);
- if (cleaner->replaceiterator) {
- dns_dbiterator_destroy(&cleaner->iterator);
- (void) dns_db_createiterator(cleaner->cache->db,
- ISC_FALSE,
- &cleaner->iterator);
- cleaner->replaceiterator = ISC_FALSE;
- }
- UNLOCK(&cleaner->lock);
- UNLOCK(&cleaner->cache->lock);
- return;
- }
-
- INSIST(CLEANER_BUSY(cleaner));
-
- n_names = cleaner->increment;
-
- REQUIRE(DNS_DBITERATOR_VALID(cleaner->iterator));
-
- isc_time_now(&start);
- while (n_names-- > 0) {
- dns_dbnode_t *node = NULL;
-
- result = dns_dbiterator_current(cleaner->iterator, &node,
- NULL);
- if (result != ISC_R_SUCCESS) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "cache cleaner: dns_dbiterator_current() "
- "failed: %s", dns_result_totext(result));
-
- end_cleaning(cleaner, event);
- return;
- }
-
- /*
- * The node was not needed, but was required by
- * dns_dbiterator_current(). Give up its reference.
- */
- dns_db_detachnode(cleaner->cache->db, &node);
-
- /*
- * Step to the next node.
- */
- result = dns_dbiterator_next(cleaner->iterator);
-
- if (result != ISC_R_SUCCESS) {
- /*
- * Either the end was reached (ISC_R_NOMORE) or
- * some error was signaled. If the cache is still
- * overmem and no error was encountered,
- * keep trying to clean it, otherwise stop cleaning.
- */
- if (result != ISC_R_NOMORE)
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "cache cleaner: "
- "dns_dbiterator_next() "
- "failed: %s",
- dns_result_totext(result));
- else if (cleaner->overmem) {
- result = dns_dbiterator_first(cleaner->
- iterator);
- if (result == ISC_R_SUCCESS) {
- isc_log_write(dns_lctx,
- DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_CACHE,
- ISC_LOG_DEBUG(1),
- "cache cleaner: "
- "still overmem, "
- "reset and try again");
- continue;
- }
- }
-
- end_cleaning(cleaner, event);
- return;
- }
- }
-
- /*
- * We have successfully performed a cleaning increment but have
- * not gone through the entire cache. Free the iterator locks
- * and reschedule another batch. If it fails, just try to continue
- * anyway.
- */
- result = dns_dbiterator_pause(cleaner->iterator);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
-
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE,
- ISC_LOG_DEBUG(1), "cache cleaner: checked %u nodes, "
- "mem inuse %lu, sleeping", cleaner->increment,
- (unsigned long)isc_mem_inuse(cleaner->cache->mctx));
-
- isc_task_send(task, &event);
- INSIST(CLEANER_BUSY(cleaner));
- return;
-}
-
-/*
- * Do immediate cleaning.
- */
-isc_result_t
-dns_cache_clean(dns_cache_t *cache, isc_stdtime_t now) {
- isc_result_t result;
- dns_dbiterator_t *iterator = NULL;
-
- REQUIRE(VALID_CACHE(cache));
-
- result = dns_db_createiterator(cache->db, 0, &iterator);
- if (result != ISC_R_SUCCESS)
- return result;
-
- result = dns_dbiterator_first(iterator);
-
- while (result == ISC_R_SUCCESS) {
- dns_dbnode_t *node = NULL;
- result = dns_dbiterator_current(iterator, &node,
- (dns_name_t *)NULL);
- if (result != ISC_R_SUCCESS)
- break;
-
- /*
- * Check TTLs, mark expired rdatasets stale.
- */
- result = dns_db_expirenode(cache->db, node, now);
- if (result != ISC_R_SUCCESS) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "cache cleaner: dns_db_expirenode() "
- "failed: %s",
- dns_result_totext(result));
- /*
- * Continue anyway.
- */
- }
-
- /*
- * This is where the actual freeing takes place.
- */
- dns_db_detachnode(cache->db, &node);
-
- result = dns_dbiterator_next(iterator);
- }
-
- dns_dbiterator_destroy(&iterator);
-
- if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
-
- return (result);
-}
-
-static void
-water(void *arg, int mark) {
- dns_cache_t *cache = arg;
- isc_boolean_t overmem = ISC_TF(mark == ISC_MEM_HIWATER);
-
- REQUIRE(VALID_CACHE(cache));
-
- LOCK(&cache->cleaner.lock);
-
- if (overmem != cache->cleaner.overmem) {
- dns_db_overmem(cache->db, overmem);
- cache->cleaner.overmem = overmem;
- isc_mem_waterack(cache->mctx, mark);
- }
-
- if (cache->cleaner.overmem_event != NULL)
- isc_task_send(cache->cleaner.task,
- &cache->cleaner.overmem_event);
-
- UNLOCK(&cache->cleaner.lock);
-}
-
-void
-dns_cache_setcachesize(dns_cache_t *cache, size_t size) {
- size_t hiwater, lowater;
-
- REQUIRE(VALID_CACHE(cache));
-
- /*
- * Impose a minimum cache size; pathological things happen if there
- * is too little room.
- */
- if (size != 0U && 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. */
-
- /*
- * If the cache was overmem and cleaning, but now with the new limits
- * it is no longer in an overmem condition, then the next
- * isc_mem_put for cache memory will do the right thing and trigger
- * water().
- */
-
- if (size == 0U || hiwater == 0U || lowater == 0U)
- /*
- * Disable cache memory limiting.
- */
- isc_mem_setwater(cache->mctx, water, cache, 0, 0);
- else
- /*
- * Establish new cache memory limits (either for the first
- * time, or replacing other limits).
- */
- isc_mem_setwater(cache->mctx, water, cache, hiwater, lowater);
-}
-
-size_t
-dns_cache_getcachesize(dns_cache_t *cache) {
- size_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.
- */
-static void
-cleaner_shutdown_action(isc_task_t *task, isc_event_t *event) {
- dns_cache_t *cache = event->ev_arg;
- isc_boolean_t should_free = ISC_FALSE;
-
- UNUSED(task);
-
- INSIST(task == cache->cleaner.task);
- INSIST(event->ev_type == ISC_TASKEVENT_SHUTDOWN);
-
- if (CLEANER_BUSY(&cache->cleaner))
- end_cleaning(&cache->cleaner, event);
- else
- isc_event_free(&event);
-
- LOCK(&cache->lock);
-
- cache->live_tasks--;
- INSIST(cache->live_tasks == 0);
-
- if (cache->references == 0)
- should_free = ISC_TRUE;
-
- /*
- * By detaching the timer in the context of its task,
- * we are guaranteed that there will be no further timer
- * events.
- */
- if (cache->cleaner.cleaning_timer != NULL)
- isc_timer_detach(&cache->cleaner.cleaning_timer);
-
- /* Make sure we don't reschedule anymore. */
- (void)isc_task_purge(task, NULL, DNS_EVENT_CACHECLEAN, NULL);
-
- UNLOCK(&cache->lock);
-
- if (should_free)
- cache_free(cache);
-}
-
-isc_result_t
-dns_cache_flush(dns_cache_t *cache) {
- dns_db_t *db = NULL;
- isc_result_t result;
-
- result = cache_create_db(cache, &db);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- LOCK(&cache->lock);
- LOCK(&cache->cleaner.lock);
- if (cache->cleaner.state == cleaner_s_idle) {
- if (cache->cleaner.iterator != NULL)
- dns_dbiterator_destroy(&cache->cleaner.iterator);
- (void) dns_db_createiterator(db, ISC_FALSE,
- &cache->cleaner.iterator);
- } else {
- if (cache->cleaner.state == cleaner_s_busy)
- cache->cleaner.state = cleaner_s_done;
- cache->cleaner.replaceiterator = ISC_TRUE;
- }
- dns_db_detach(&cache->db);
- cache->db = db;
- UNLOCK(&cache->cleaner.lock);
- UNLOCK(&cache->lock);
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-clearnode(dns_db_t *db, dns_dbnode_t *node) {
- isc_result_t result;
- dns_rdatasetiter_t *iter = NULL;
-
- result = dns_db_allrdatasets(db, node, NULL, (isc_stdtime_t)0, &iter);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- for (result = dns_rdatasetiter_first(iter);
- result == ISC_R_SUCCESS;
- result = dns_rdatasetiter_next(iter))
- {
- dns_rdataset_t rdataset;
- dns_rdataset_init(&rdataset);
-
- dns_rdatasetiter_current(iter, &rdataset);
- result = dns_db_deleterdataset(db, node, NULL,
- rdataset.type, rdataset.covers);
- dns_rdataset_disassociate(&rdataset);
- if (result != ISC_R_SUCCESS && result != DNS_R_UNCHANGED)
- break;
- }
-
- if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
-
- dns_rdatasetiter_destroy(&iter);
- return (result);
-}
-
-static isc_result_t
-cleartree(dns_db_t *db, dns_name_t *name) {
- isc_result_t result, answer = ISC_R_SUCCESS;
- dns_dbiterator_t *iter = NULL;
- dns_dbnode_t *node = NULL;
- dns_fixedname_t fnodename;
- dns_name_t *nodename;
-
- dns_fixedname_init(&fnodename);
- nodename = dns_fixedname_name(&fnodename);
-
- result = dns_db_createiterator(db, 0, &iter);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- result = dns_dbiterator_seek(iter, name);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- while (result == ISC_R_SUCCESS) {
- result = dns_dbiterator_current(iter, &node, nodename);
- if (result == DNS_R_NEWORIGIN)
- result = ISC_R_SUCCESS;
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- /*
- * Are we done?
- */
- if (! dns_name_issubdomain(nodename, name))
- goto cleanup;
-
- /*
- * If clearnode fails record and move onto the next node.
- */
- result = clearnode(db, node);
- if (result != ISC_R_SUCCESS && answer == ISC_R_SUCCESS)
- answer = result;
- dns_db_detachnode(db, &node);
- result = dns_dbiterator_next(iter);
- }
-
- cleanup:
- if (result == ISC_R_NOMORE || result == ISC_R_NOTFOUND)
- result = ISC_R_SUCCESS;
- if (result != ISC_R_SUCCESS && answer == ISC_R_SUCCESS)
- answer = result;
- if (node != NULL)
- dns_db_detachnode(db, &node);
- if (iter != NULL)
- dns_dbiterator_destroy(&iter);
-
- return (answer);
-}
-
-isc_result_t
-dns_cache_flushname(dns_cache_t *cache, dns_name_t *name) {
- return (dns_cache_flushnode(cache, name, ISC_FALSE));
-}
-
-isc_result_t
-dns_cache_flushnode(dns_cache_t *cache, dns_name_t *name,
- isc_boolean_t tree)
-{
- isc_result_t result;
- dns_dbnode_t *node = NULL;
- dns_db_t *db = NULL;
-
- if (dns_name_equal(name, dns_rootname))
- return (dns_cache_flush(cache));
-
- LOCK(&cache->lock);
- if (cache->db != NULL)
- dns_db_attach(cache->db, &db);
- UNLOCK(&cache->lock);
- if (db == NULL)
- return (ISC_R_SUCCESS);
-
- if (tree) {
- result = cleartree(cache->db, name);
- } else {
- result = dns_db_findnode(cache->db, name, ISC_FALSE, &node);
- if (result == ISC_R_NOTFOUND) {
- result = ISC_R_SUCCESS;
- goto cleanup_db;
- }
- if (result != ISC_R_SUCCESS)
- goto cleanup_db;
- result = clearnode(cache->db, node);
- dns_db_detachnode(cache->db, &node);
- }
-
- cleanup_db:
- dns_db_detach(&db);
- return (result);
-}
diff --git a/contrib/bind9/lib/dns/callbacks.c b/contrib/bind9/lib/dns/callbacks.c
deleted file mode 100644
index 0ef17abce7bc..000000000000
--- a/contrib/bind9/lib/dns/callbacks.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007, 2011 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: callbacks.c,v 1.19 2011/12/09 23:47:05 tbox Exp $ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <isc/util.h>
-
-#include <dns/callbacks.h>
-#include <dns/log.h>
-
-static void
-stdio_error_warn_callback(dns_rdatacallbacks_t *, const char *, ...)
- ISC_FORMAT_PRINTF(2, 3);
-
-static void
-isclog_error_callback(dns_rdatacallbacks_t *callbacks, const char *fmt, ...)
- ISC_FORMAT_PRINTF(2, 3);
-
-static void
-isclog_warn_callback(dns_rdatacallbacks_t *callbacks, const char *fmt, ...)
- ISC_FORMAT_PRINTF(2, 3);
-
-/*
- * Private
- */
-
-static void
-stdio_error_warn_callback(dns_rdatacallbacks_t *callbacks,
- const char *fmt, ...)
-{
- va_list ap;
-
- UNUSED(callbacks);
-
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
- fprintf(stderr, "\n");
-}
-
-static void
-isclog_error_callback(dns_rdatacallbacks_t *callbacks, const char *fmt, ...) {
- va_list ap;
-
- UNUSED(callbacks);
-
- va_start(ap, fmt);
- isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL,
- DNS_LOGMODULE_MASTER, /* XXX */
- ISC_LOG_ERROR, fmt, ap);
- va_end(ap);
-}
-
-static void
-isclog_warn_callback(dns_rdatacallbacks_t *callbacks, const char *fmt, ...) {
- va_list ap;
-
- UNUSED(callbacks);
-
- va_start(ap, fmt);
-
- isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL,
- DNS_LOGMODULE_MASTER, /* XXX */
- ISC_LOG_WARNING, fmt, ap);
- va_end(ap);
-}
-
-static void
-dns_rdatacallbacks_initcommon(dns_rdatacallbacks_t *callbacks) {
- REQUIRE(callbacks != NULL);
-
- callbacks->add = NULL;
- callbacks->rawdata = NULL;
- callbacks->zone = NULL;
- callbacks->add_private = NULL;
- callbacks->error_private = NULL;
- callbacks->warn_private = NULL;
-}
-
-/*
- * Public.
- */
-
-void
-dns_rdatacallbacks_init(dns_rdatacallbacks_t *callbacks) {
- dns_rdatacallbacks_initcommon(callbacks);
- callbacks->error = isclog_error_callback;
- callbacks->warn = isclog_warn_callback;
-}
-
-void
-dns_rdatacallbacks_init_stdio(dns_rdatacallbacks_t *callbacks) {
- dns_rdatacallbacks_initcommon(callbacks);
- callbacks->error = stdio_error_warn_callback;
- callbacks->warn = stdio_error_warn_callback;
-}
-
diff --git a/contrib/bind9/lib/dns/client.c b/contrib/bind9/lib/dns/client.c
deleted file mode 100644
index fc551cf9dfe5..000000000000
--- a/contrib/bind9/lib/dns/client.c
+++ /dev/null
@@ -1,3043 +0,0 @@
-/*
- * Copyright (C) 2009-2013 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN 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.14 2011/03/12 04:59:47 tbox 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, 1, 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;
-#if 0
- /* XXXMPA add debug logging support */
- isc_log_t *lctx = NULL;
- isc_logconfig_t *logconfig = NULL;
- unsigned int logdebuglevel = 0;
-#endif
-
- 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;
-#if 0
- result = isc_log_create(mctx, &lctx, &logconfig);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- isc_log_setcontext(lctx);
- dns_log_init(lctx);
- dns_log_setcontext(lctx);
- result = isc_log_usechannel(logconfig, "default_debug", NULL, NULL);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- isc_log_setdebuglevel(lctx, logdebuglevel);
-#endif
- 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->attributes = 0;
-
- 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 tresult, result = ISC_R_SUCCESS;
- 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;
-
- 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 != NULL);
- 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;
- POST(result);
- break;
- }
- }
- }
- if (n == 0) {
- /*
- * We didn't match any rdatasets (which means
- * something went wrong in this
- * implementation).
- */
- result = DNS_R_SERVFAIL; /* better code? */
- POST(result);
- } 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);
- result = dns_rdata_tostruct(&rdata, &rdata_a,
- NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- isc_sockaddr_fromin(sa,
- &rdata_a.in_addr,
- 53);
- dns_rdata_freestruct(&rdata_a);
- break;
- case AF_INET6:
- dns_rdataset_current(rdataset, &rdata);
- result = dns_rdata_tostruct(&rdata, &rdata_aaaa,
- NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- 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;
- POST(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;
- POST(section);
-
- 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/contrib/bind9/lib/dns/clientinfo.c b/contrib/bind9/lib/dns/clientinfo.c
deleted file mode 100644
index fd5a5e281642..000000000000
--- a/contrib/bind9/lib/dns/clientinfo.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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: clientinfo.c,v 1.3 2011/10/11 00:25:12 marka Exp $ */
-
-/*! \file */
-
-#include "config.h"
-
-#include <dns/clientinfo.h>
-
-void
-dns_clientinfomethods_init(dns_clientinfomethods_t *methods,
- dns_clientinfo_sourceip_t sourceip)
-{
- methods->version = DNS_CLIENTINFOMETHODS_VERSION;
- methods->age = DNS_CLIENTINFOMETHODS_AGE;
- methods->sourceip = sourceip;
-}
-
-void
-dns_clientinfo_init(dns_clientinfo_t *ci, void *data) {
- ci->version = DNS_CLIENTINFO_VERSION;
- ci->data = data;
-}
diff --git a/contrib/bind9/lib/dns/compress.c b/contrib/bind9/lib/dns/compress.c
deleted file mode 100644
index 11473ee95f8b..000000000000
--- a/contrib/bind9/lib/dns/compress.c
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: compress.c,v 1.59 2007/06/19 23:47:16 tbox Exp $ */
-
-/*! \file */
-
-#define DNS_NAME_USEINLINE 1
-
-#include <config.h>
-
-#include <isc/mem.h>
-#include <isc/string.h>
-#include <isc/util.h>
-
-#include <dns/compress.h>
-#include <dns/fixedname.h>
-#include <dns/rbt.h>
-#include <dns/result.h>
-
-#define CCTX_MAGIC ISC_MAGIC('C', 'C', 'T', 'X')
-#define VALID_CCTX(x) ISC_MAGIC_VALID(x, CCTX_MAGIC)
-
-#define DCTX_MAGIC ISC_MAGIC('D', 'C', 'T', 'X')
-#define VALID_DCTX(x) ISC_MAGIC_VALID(x, DCTX_MAGIC)
-
-/***
- *** Compression
- ***/
-
-isc_result_t
-dns_compress_init(dns_compress_t *cctx, int edns, isc_mem_t *mctx) {
- unsigned int i;
-
- REQUIRE(cctx != NULL);
- REQUIRE(mctx != NULL); /* See: rdataset.c:towiresorted(). */
-
- cctx->allowed = 0;
- cctx->edns = edns;
- for (i = 0; i < DNS_COMPRESS_TABLESIZE; i++)
- cctx->table[i] = NULL;
- cctx->mctx = mctx;
- cctx->count = 0;
- cctx->magic = CCTX_MAGIC;
- return (ISC_R_SUCCESS);
-}
-
-void
-dns_compress_invalidate(dns_compress_t *cctx) {
- dns_compressnode_t *node;
- unsigned int i;
-
- REQUIRE(VALID_CCTX(cctx));
-
- cctx->magic = 0;
- for (i = 0; i < DNS_COMPRESS_TABLESIZE; i++) {
- while (cctx->table[i] != NULL) {
- node = cctx->table[i];
- cctx->table[i] = cctx->table[i]->next;
- if (node->count < DNS_COMPRESS_INITIALNODES)
- continue;
- isc_mem_put(cctx->mctx, node, sizeof(*node));
- }
- }
- cctx->allowed = 0;
- cctx->edns = -1;
-}
-
-void
-dns_compress_setmethods(dns_compress_t *cctx, unsigned int allowed) {
- REQUIRE(VALID_CCTX(cctx));
-
- cctx->allowed &= ~DNS_COMPRESS_ALL;
- cctx->allowed |= (allowed & DNS_COMPRESS_ALL);
-}
-
-unsigned int
-dns_compress_getmethods(dns_compress_t *cctx) {
- REQUIRE(VALID_CCTX(cctx));
- return (cctx->allowed & DNS_COMPRESS_ALL);
-}
-
-void
-dns_compress_setsensitive(dns_compress_t *cctx, isc_boolean_t sensitive) {
- REQUIRE(VALID_CCTX(cctx));
-
- if (sensitive)
- cctx->allowed |= DNS_COMPRESS_CASESENSITIVE;
- else
- cctx->allowed &= ~DNS_COMPRESS_CASESENSITIVE;
-}
-
-isc_boolean_t
-dns_compress_getsensitive(dns_compress_t *cctx) {
- REQUIRE(VALID_CCTX(cctx));
-
- return (ISC_TF((cctx->allowed & DNS_COMPRESS_CASESENSITIVE) != 0));
-}
-
-int
-dns_compress_getedns(dns_compress_t *cctx) {
- REQUIRE(VALID_CCTX(cctx));
- return (cctx->edns);
-}
-
-#define NODENAME(node, name) \
-do { \
- (name)->length = (node)->r.length; \
- (name)->labels = (node)->labels; \
- (name)->ndata = (node)->r.base; \
- (name)->attributes = DNS_NAMEATTR_ABSOLUTE; \
-} while (0)
-
-/*
- * Find the longest match of name in the table.
- * If match is found return ISC_TRUE. prefix, suffix and offset are updated.
- * If no match is found return ISC_FALSE.
- */
-isc_boolean_t
-dns_compress_findglobal(dns_compress_t *cctx, const dns_name_t *name,
- dns_name_t *prefix, isc_uint16_t *offset)
-{
- dns_name_t tname, nname;
- dns_compressnode_t *node = NULL;
- unsigned int labels, hash, n;
-
- REQUIRE(VALID_CCTX(cctx));
- REQUIRE(dns_name_isabsolute(name) == ISC_TRUE);
- REQUIRE(offset != NULL);
-
- if (cctx->count == 0)
- return (ISC_FALSE);
-
- labels = dns_name_countlabels(name);
- INSIST(labels > 0);
-
- dns_name_init(&tname, NULL);
- dns_name_init(&nname, NULL);
-
- for (n = 0; n < labels - 1; n++) {
- dns_name_getlabelsequence(name, n, labels - n, &tname);
- hash = dns_name_hash(&tname, ISC_FALSE) %
- DNS_COMPRESS_TABLESIZE;
- for (node = cctx->table[hash]; node != NULL; node = node->next)
- {
- NODENAME(node, &nname);
- if ((cctx->allowed & DNS_COMPRESS_CASESENSITIVE) != 0) {
- if (dns_name_caseequal(&nname, &tname))
- break;
- } else {
- if (dns_name_equal(&nname, &tname))
- break;
- }
- }
- if (node != NULL)
- break;
- }
-
- /*
- * If node == NULL, we found no match at all.
- */
- if (node == NULL)
- return (ISC_FALSE);
-
- if (n == 0)
- dns_name_reset(prefix);
- else
- dns_name_getlabelsequence(name, 0, n, prefix);
-
- *offset = node->offset;
- return (ISC_TRUE);
-}
-
-static inline unsigned int
-name_length(const dns_name_t *name) {
- isc_region_t r;
- dns_name_toregion(name, &r);
- return (r.length);
-}
-
-void
-dns_compress_add(dns_compress_t *cctx, const dns_name_t *name,
- const dns_name_t *prefix, isc_uint16_t offset)
-{
- dns_name_t tname;
- unsigned int start;
- unsigned int n;
- unsigned int count;
- unsigned int hash;
- dns_compressnode_t *node;
- unsigned int length;
- unsigned int tlength;
- isc_uint16_t toffset;
-
- REQUIRE(VALID_CCTX(cctx));
- REQUIRE(dns_name_isabsolute(name));
-
- dns_name_init(&tname, NULL);
-
- n = dns_name_countlabels(name);
- count = dns_name_countlabels(prefix);
- if (dns_name_isabsolute(prefix))
- count--;
- start = 0;
- length = name_length(name);
- while (count > 0) {
- if (offset >= 0x4000)
- break;
- dns_name_getlabelsequence(name, start, n, &tname);
- hash = dns_name_hash(&tname, ISC_FALSE) %
- DNS_COMPRESS_TABLESIZE;
- tlength = name_length(&tname);
- toffset = (isc_uint16_t)(offset + (length - tlength));
- /*
- * Create a new node and add it.
- */
- if (cctx->count < DNS_COMPRESS_INITIALNODES)
- node = &cctx->initialnodes[cctx->count];
- else {
- node = isc_mem_get(cctx->mctx,
- sizeof(dns_compressnode_t));
- if (node == NULL)
- return;
- }
- node->count = cctx->count++;
- node->offset = toffset;
- dns_name_toregion(&tname, &node->r);
- node->labels = (isc_uint8_t)dns_name_countlabels(&tname);
- node->next = cctx->table[hash];
- cctx->table[hash] = node;
- start++;
- n--;
- count--;
- }
-}
-
-void
-dns_compress_rollback(dns_compress_t *cctx, isc_uint16_t offset) {
- unsigned int i;
- dns_compressnode_t *node;
-
- REQUIRE(VALID_CCTX(cctx));
-
- for (i = 0; i < DNS_COMPRESS_TABLESIZE; i++) {
- node = cctx->table[i];
- /*
- * This relies on nodes with greater offsets being
- * closer to the beginning of the list, and the
- * items with the greatest offsets being at the end
- * of the initialnodes[] array.
- */
- while (node != NULL && node->offset >= offset) {
- cctx->table[i] = node->next;
- if (node->count >= DNS_COMPRESS_INITIALNODES)
- isc_mem_put(cctx->mctx, node, sizeof(*node));
- cctx->count--;
- node = cctx->table[i];
- }
- }
-}
-
-/***
- *** Decompression
- ***/
-
-void
-dns_decompress_init(dns_decompress_t *dctx, int edns,
- dns_decompresstype_t type) {
-
- REQUIRE(dctx != NULL);
- REQUIRE(edns >= -1 && edns <= 255);
-
- dctx->allowed = DNS_COMPRESS_NONE;
- dctx->edns = edns;
- dctx->type = type;
- dctx->magic = DCTX_MAGIC;
-}
-
-void
-dns_decompress_invalidate(dns_decompress_t *dctx) {
-
- REQUIRE(VALID_DCTX(dctx));
-
- dctx->magic = 0;
-}
-
-void
-dns_decompress_setmethods(dns_decompress_t *dctx, unsigned int allowed) {
-
- REQUIRE(VALID_DCTX(dctx));
-
- switch (dctx->type) {
- case DNS_DECOMPRESS_ANY:
- dctx->allowed = DNS_COMPRESS_ALL;
- break;
- case DNS_DECOMPRESS_NONE:
- dctx->allowed = DNS_COMPRESS_NONE;
- break;
- case DNS_DECOMPRESS_STRICT:
- dctx->allowed = allowed;
- break;
- }
-}
-
-unsigned int
-dns_decompress_getmethods(dns_decompress_t *dctx) {
-
- REQUIRE(VALID_DCTX(dctx));
-
- return (dctx->allowed);
-}
-
-int
-dns_decompress_edns(dns_decompress_t *dctx) {
-
- REQUIRE(VALID_DCTX(dctx));
-
- return (dctx->edns);
-}
-
-dns_decompresstype_t
-dns_decompress_type(dns_decompress_t *dctx) {
-
- REQUIRE(VALID_DCTX(dctx));
-
- return (dctx->type);
-}
diff --git a/contrib/bind9/lib/dns/db.c b/contrib/bind9/lib/dns/db.c
deleted file mode 100644
index bf4a5b37540c..000000000000
--- a/contrib/bind9/lib/dns/db.c
+++ /dev/null
@@ -1,1027 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007-2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001, 2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: db.c,v 1.99.4.1 2011/10/23 20:12:07 vjs Exp $ */
-
-/*! \file */
-
-/***
- *** Imports
- ***/
-
-#include <config.h>
-
-#include <isc/buffer.h>
-#include <isc/mem.h>
-#include <isc/once.h>
-#include <isc/rwlock.h>
-#include <isc/string.h>
-#include <isc/util.h>
-
-#include <dns/callbacks.h>
-#include <dns/clientinfo.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>
-
-/***
- *** Private Types
- ***/
-
-struct dns_dbimplementation {
- const char * name;
- dns_dbcreatefunc_t create;
- isc_mem_t * mctx;
- void * driverarg;
- ISC_LINK(dns_dbimplementation_t) link;
-};
-
-/***
- *** Supported DB Implementations Registry
- ***/
-
-/*
- * Built in database implementations are registered here.
- */
-
-#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) {
- RUNTIME_CHECK(isc_rwlock_init(&implock, 0, 0) == ISC_R_SUCCESS);
-
- rbtimp.name = "rbt";
- rbtimp.create = dns_rbtdb_create;
- rbtimp.mctx = NULL;
- 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 *
-impfind(const char *name) {
- dns_dbimplementation_t *imp;
-
- for (imp = ISC_LIST_HEAD(implementations);
- imp != NULL;
- imp = ISC_LIST_NEXT(imp, link))
- if (strcasecmp(name, imp->name) == 0)
- return (imp);
- return (NULL);
-}
-
-
-/***
- *** Basic DB Methods
- ***/
-
-isc_result_t
-dns_db_create(isc_mem_t *mctx, const char *db_type, dns_name_t *origin,
- dns_dbtype_t type, dns_rdataclass_t rdclass,
- unsigned int argc, char *argv[], dns_db_t **dbp)
-{
- dns_dbimplementation_t *impinfo;
-
- RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
-
- /*
- * Create a new database using implementation 'db_type'.
- */
-
- REQUIRE(dbp != NULL && *dbp == NULL);
- REQUIRE(dns_name_isabsolute(origin));
-
- RWLOCK(&implock, isc_rwlocktype_read);
- impinfo = impfind(db_type);
- if (impinfo != NULL) {
- isc_result_t result;
- result = ((impinfo->create)(mctx, origin, type,
- rdclass, argc, argv,
- impinfo->driverarg, dbp));
- RWUNLOCK(&implock, isc_rwlocktype_read);
- return (result);
- }
-
- RWUNLOCK(&implock, isc_rwlocktype_read);
-
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_DB, ISC_LOG_ERROR,
- "unsupported database type '%s'", db_type);
-
- return (ISC_R_NOTFOUND);
-}
-
-void
-dns_db_attach(dns_db_t *source, dns_db_t **targetp) {
-
- /*
- * Attach *targetp to source.
- */
-
- REQUIRE(DNS_DB_VALID(source));
- REQUIRE(targetp != NULL && *targetp == NULL);
-
- (source->methods->attach)(source, targetp);
-
- ENSURE(*targetp == source);
-}
-
-void
-dns_db_detach(dns_db_t **dbp) {
-
- /*
- * Detach *dbp from its database.
- */
-
- REQUIRE(dbp != NULL);
- REQUIRE(DNS_DB_VALID(*dbp));
-
- ((*dbp)->methods->detach)(dbp);
-
- ENSURE(*dbp == NULL);
-}
-
-isc_result_t
-dns_db_ondestroy(dns_db_t *db, isc_task_t *task, isc_event_t **eventp)
-{
- REQUIRE(DNS_DB_VALID(db));
-
- return (isc_ondestroy_register(&db->ondest, task, eventp));
-}
-
-
-isc_boolean_t
-dns_db_iscache(dns_db_t *db) {
-
- /*
- * Does 'db' have cache semantics?
- */
-
- REQUIRE(DNS_DB_VALID(db));
-
- if ((db->attributes & DNS_DBATTR_CACHE) != 0)
- return (ISC_TRUE);
-
- return (ISC_FALSE);
-}
-
-isc_boolean_t
-dns_db_iszone(dns_db_t *db) {
-
- /*
- * Does 'db' have zone semantics?
- */
-
- REQUIRE(DNS_DB_VALID(db));
-
- if ((db->attributes & (DNS_DBATTR_CACHE|DNS_DBATTR_STUB)) == 0)
- return (ISC_TRUE);
-
- return (ISC_FALSE);
-}
-
-isc_boolean_t
-dns_db_isstub(dns_db_t *db) {
-
- /*
- * Does 'db' have stub semantics?
- */
-
- REQUIRE(DNS_DB_VALID(db));
-
- if ((db->attributes & DNS_DBATTR_STUB) != 0)
- return (ISC_TRUE);
-
- return (ISC_FALSE);
-}
-
-isc_boolean_t
-dns_db_isdnssec(dns_db_t *db) {
-
- /*
- * Is 'db' secure or partially secure?
- */
-
- REQUIRE(DNS_DB_VALID(db));
- REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0);
-
- if (db->methods->isdnssec != NULL)
- return ((db->methods->isdnssec)(db));
- return ((db->methods->issecure)(db));
-}
-
-isc_boolean_t
-dns_db_issecure(dns_db_t *db) {
-
- /*
- * Is 'db' secure?
- */
-
- REQUIRE(DNS_DB_VALID(db));
- REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0);
-
- return ((db->methods->issecure)(db));
-}
-
-isc_boolean_t
-dns_db_ispersistent(dns_db_t *db) {
-
- /*
- * Is 'db' persistent?
- */
-
- REQUIRE(DNS_DB_VALID(db));
-
- return ((db->methods->ispersistent)(db));
-}
-
-dns_name_t *
-dns_db_origin(dns_db_t *db) {
- /*
- * The origin of the database.
- */
-
- REQUIRE(DNS_DB_VALID(db));
-
- return (&db->origin);
-}
-
-dns_rdataclass_t
-dns_db_class(dns_db_t *db) {
- /*
- * The class of the database.
- */
-
- REQUIRE(DNS_DB_VALID(db));
-
- return (db->rdclass);
-}
-
-#ifdef BIND9
-isc_result_t
-dns_db_beginload(dns_db_t *db, dns_addrdatasetfunc_t *addp,
- dns_dbload_t **dbloadp) {
- /*
- * Begin loading 'db'.
- */
-
- REQUIRE(DNS_DB_VALID(db));
- REQUIRE(addp != NULL && *addp == NULL);
- REQUIRE(dbloadp != NULL && *dbloadp == NULL);
-
- return ((db->methods->beginload)(db, addp, dbloadp));
-}
-
-isc_result_t
-dns_db_endload(dns_db_t *db, dns_dbload_t **dbloadp) {
- /*
- * Finish loading 'db'.
- */
-
- REQUIRE(DNS_DB_VALID(db));
- REQUIRE(dbloadp != NULL && *dbloadp != NULL);
-
- return ((db->methods->endload)(db, dbloadp));
-}
-
-isc_result_t
-dns_db_load(dns_db_t *db, const char *filename) {
- 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;
-
- /*
- * Load master file 'filename' into 'db'.
- */
-
- REQUIRE(DNS_DB_VALID(db));
-
- if ((db->attributes & DNS_DBATTR_CACHE) != 0)
- options |= DNS_MASTER_AGETTL;
-
- dns_rdatacallbacks_init(&callbacks);
-
- result = dns_db_beginload(db, &callbacks.add, &callbacks.add_private);
- if (result != ISC_R_SUCCESS)
- return (result);
- result = dns_master_loadfile2(filename, &db->origin, &db->origin,
- db->rdclass, options,
- &callbacks, db->mctx, format);
- eresult = dns_db_endload(db, &callbacks.add_private);
- /*
- * We always call dns_db_endload(), but we only want to return its
- * result if dns_master_loadfile() succeeded. If dns_master_loadfile()
- * failed, we want to return the result code it gave us.
- */
- if (eresult != ISC_R_SUCCESS &&
- (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE))
- result = eresult;
-
- return (result);
-}
-
-isc_result_t
-dns_db_dump(dns_db_t *db, dns_dbversion_t *version, const char *filename) {
- return ((db->methods->dump)(db, version, filename,
- dns_masterformat_text));
-}
-
-isc_result_t
-dns_db_dump2(dns_db_t *db, dns_dbversion_t *version, const char *filename,
- dns_masterformat_t masterformat) {
- /*
- * Dump 'db' into master file 'filename' in the 'masterformat' format.
- * XXXJT: is it okay to modify the interface to the existing "dump"
- * method?
- */
-
- REQUIRE(DNS_DB_VALID(db));
-
- return ((db->methods->dump)(db, version, filename, masterformat));
-}
-#endif /* BIND9 */
-
-/***
- *** Version Methods
- ***/
-
-void
-dns_db_currentversion(dns_db_t *db, dns_dbversion_t **versionp) {
-
- /*
- * Open the current version for reading.
- */
-
- REQUIRE(DNS_DB_VALID(db));
- REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0);
- REQUIRE(versionp != NULL && *versionp == NULL);
-
- (db->methods->currentversion)(db, versionp);
-}
-
-isc_result_t
-dns_db_newversion(dns_db_t *db, dns_dbversion_t **versionp) {
-
- /*
- * Open a new version for reading and writing.
- */
-
- REQUIRE(DNS_DB_VALID(db));
- REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0);
- REQUIRE(versionp != NULL && *versionp == NULL);
-
- return ((db->methods->newversion)(db, versionp));
-}
-
-void
-dns_db_attachversion(dns_db_t *db, dns_dbversion_t *source,
- dns_dbversion_t **targetp)
-{
- /*
- * Attach '*targetp' to 'source'.
- */
-
- REQUIRE(DNS_DB_VALID(db));
- REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0);
- REQUIRE(source != NULL);
- REQUIRE(targetp != NULL && *targetp == NULL);
-
- (db->methods->attachversion)(db, source, targetp);
-
- ENSURE(*targetp != NULL);
-}
-
-void
-dns_db_closeversion(dns_db_t *db, dns_dbversion_t **versionp,
- isc_boolean_t commit)
-{
-
- /*
- * Close version '*versionp'.
- */
-
- REQUIRE(DNS_DB_VALID(db));
- REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0);
- REQUIRE(versionp != NULL && *versionp != NULL);
-
- (db->methods->closeversion)(db, versionp, commit);
-
- ENSURE(*versionp == NULL);
-}
-
-/***
- *** Node Methods
- ***/
-
-isc_result_t
-dns_db_findnode(dns_db_t *db, dns_name_t *name,
- isc_boolean_t create, dns_dbnode_t **nodep)
-{
-
- /*
- * Find the node with name 'name'.
- */
-
- REQUIRE(DNS_DB_VALID(db));
- REQUIRE(nodep != NULL && *nodep == NULL);
-
- if (db->methods->findnode != NULL)
- return ((db->methods->findnode)(db, name, create, nodep));
- else
- return ((db->methods->findnodeext)(db, name, create,
- NULL, NULL, nodep));
-}
-
-isc_result_t
-dns_db_findnodeext(dns_db_t *db, dns_name_t *name,
- isc_boolean_t create, dns_clientinfomethods_t *methods,
- dns_clientinfo_t *clientinfo, dns_dbnode_t **nodep)
-{
- /*
- * Find the node with name 'name', passing 'arg' to the database
- * implementation.
- */
-
- REQUIRE(DNS_DB_VALID(db));
- REQUIRE(nodep != NULL && *nodep == NULL);
-
- if (db->methods->findnodeext != NULL)
- return ((db->methods->findnodeext)(db, name, create,
- methods, clientinfo, nodep));
- else
- return ((db->methods->findnode)(db, name, create, nodep));
-}
-
-isc_result_t
-dns_db_findnsec3node(dns_db_t *db, dns_name_t *name,
- isc_boolean_t create, dns_dbnode_t **nodep)
-{
-
- /*
- * Find the node with name 'name'.
- */
-
- REQUIRE(DNS_DB_VALID(db));
- REQUIRE(nodep != NULL && *nodep == NULL);
-
- return ((db->methods->findnsec3node)(db, name, create, nodep));
-}
-
-isc_result_t
-dns_db_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)
-{
- /*
- * Find the best match for 'name' and 'type' in version 'version'
- * of 'db'.
- */
-
- REQUIRE(DNS_DB_VALID(db));
- REQUIRE(type != dns_rdatatype_rrsig);
- REQUIRE(nodep == NULL || (nodep != NULL && *nodep == NULL));
- REQUIRE(dns_name_hasbuffer(foundname));
- REQUIRE(rdataset == NULL ||
- (DNS_RDATASET_VALID(rdataset) &&
- ! dns_rdataset_isassociated(rdataset)));
- REQUIRE(sigrdataset == NULL ||
- (DNS_RDATASET_VALID(sigrdataset) &&
- ! dns_rdataset_isassociated(sigrdataset)));
-
- if (db->methods->find != NULL)
- return ((db->methods->find)(db, name, version, type,
- options, now, nodep, foundname,
- rdataset, sigrdataset));
- else
- return ((db->methods->findext)(db, name, version, type,
- options, now, nodep, foundname,
- NULL, NULL,
- rdataset, sigrdataset));
-}
-
-isc_result_t
-dns_db_findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
- dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
- dns_dbnode_t **nodep, dns_name_t *foundname,
- dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo,
- dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
-{
-
- /*
- * Find the best match for 'name' and 'type' in version 'version'
- * of 'db', passing in 'arg'.
- */
-
- REQUIRE(DNS_DB_VALID(db));
- REQUIRE(type != dns_rdatatype_rrsig);
- REQUIRE(nodep == NULL || (nodep != NULL && *nodep == NULL));
- REQUIRE(dns_name_hasbuffer(foundname));
- REQUIRE(rdataset == NULL ||
- (DNS_RDATASET_VALID(rdataset) &&
- ! dns_rdataset_isassociated(rdataset)));
- REQUIRE(sigrdataset == NULL ||
- (DNS_RDATASET_VALID(sigrdataset) &&
- ! dns_rdataset_isassociated(sigrdataset)));
-
- if (db->methods->findext != NULL)
- return ((db->methods->findext)(db, name, version, type,
- options, now, nodep, foundname,
- methods, clientinfo,
- rdataset, sigrdataset));
- else
- return ((db->methods->find)(db, name, version, type,
- options, now, nodep, foundname,
- rdataset, sigrdataset));
-}
-
-isc_result_t
-dns_db_findzonecut(dns_db_t *db, dns_name_t *name,
- unsigned int options, isc_stdtime_t now,
- dns_dbnode_t **nodep, dns_name_t *foundname,
- dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
-{
- /*
- * Find the deepest known zonecut which encloses 'name' in 'db'.
- */
-
- REQUIRE(DNS_DB_VALID(db));
- REQUIRE((db->attributes & DNS_DBATTR_CACHE) != 0);
- REQUIRE(nodep == NULL || (nodep != NULL && *nodep == NULL));
- REQUIRE(dns_name_hasbuffer(foundname));
- REQUIRE(sigrdataset == NULL ||
- (DNS_RDATASET_VALID(sigrdataset) &&
- ! dns_rdataset_isassociated(sigrdataset)));
-
- return ((db->methods->findzonecut)(db, name, options, now, nodep,
- foundname, rdataset, sigrdataset));
-}
-
-void
-dns_db_attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) {
-
- /*
- * Attach *targetp to source.
- */
-
- REQUIRE(DNS_DB_VALID(db));
- REQUIRE(source != NULL);
- REQUIRE(targetp != NULL && *targetp == NULL);
-
- (db->methods->attachnode)(db, source, targetp);
-}
-
-void
-dns_db_detachnode(dns_db_t *db, dns_dbnode_t **nodep) {
-
- /*
- * Detach *nodep from its node.
- */
-
- REQUIRE(DNS_DB_VALID(db));
- REQUIRE(nodep != NULL && *nodep != NULL);
-
- (db->methods->detachnode)(db, nodep);
-
- ENSURE(*nodep == NULL);
-}
-
-void
-dns_db_transfernode(dns_db_t *db, dns_dbnode_t **sourcep,
- dns_dbnode_t **targetp)
-{
- REQUIRE(DNS_DB_VALID(db));
- REQUIRE(targetp != NULL && *targetp == NULL);
- /*
- * This doesn't check the implementation magic. If we find that
- * we need such checks in future then this will be done in the
- * method.
- */
- REQUIRE(sourcep != NULL && *sourcep != NULL);
-
- UNUSED(db);
-
- if (db->methods->transfernode == NULL) {
- *targetp = *sourcep;
- *sourcep = NULL;
- } else
- (db->methods->transfernode)(db, sourcep, targetp);
-
- ENSURE(*sourcep == NULL);
-}
-
-isc_result_t
-dns_db_expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) {
-
- /*
- * Mark as stale all records at 'node' which expire at or before 'now'.
- */
-
- REQUIRE(DNS_DB_VALID(db));
- REQUIRE((db->attributes & DNS_DBATTR_CACHE) != 0);
- REQUIRE(node != NULL);
-
- return ((db->methods->expirenode)(db, node, now));
-}
-
-void
-dns_db_printnode(dns_db_t *db, dns_dbnode_t *node, FILE *out) {
- /*
- * Print a textual representation of the contents of the node to
- * 'out'.
- */
-
- REQUIRE(DNS_DB_VALID(db));
- REQUIRE(node != NULL);
-
- (db->methods->printnode)(db, node, out);
-}
-
-/***
- *** DB Iterator Creation
- ***/
-
-isc_result_t
-dns_db_createiterator(dns_db_t *db, unsigned int flags,
- dns_dbiterator_t **iteratorp)
-{
- /*
- * Create an iterator for version 'version' of 'db'.
- */
-
- REQUIRE(DNS_DB_VALID(db));
- REQUIRE(iteratorp != NULL && *iteratorp == NULL);
-
- return (db->methods->createiterator(db, flags, iteratorp));
-}
-
-/***
- *** Rdataset Methods
- ***/
-
-isc_result_t
-dns_db_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
- dns_rdatatype_t type, dns_rdatatype_t covers,
- isc_stdtime_t now, dns_rdataset_t *rdataset,
- dns_rdataset_t *sigrdataset)
-{
- REQUIRE(DNS_DB_VALID(db));
- REQUIRE(node != NULL);
- REQUIRE(DNS_RDATASET_VALID(rdataset));
- REQUIRE(! dns_rdataset_isassociated(rdataset));
- REQUIRE(covers == 0 || type == dns_rdatatype_rrsig);
- REQUIRE(type != dns_rdatatype_any);
- REQUIRE(sigrdataset == NULL ||
- (DNS_RDATASET_VALID(sigrdataset) &&
- ! dns_rdataset_isassociated(sigrdataset)));
-
- return ((db->methods->findrdataset)(db, node, version, type,
- covers, now, rdataset,
- sigrdataset));
-}
-
-isc_result_t
-dns_db_allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
- isc_stdtime_t now, dns_rdatasetiter_t **iteratorp)
-{
- /*
- * Make '*iteratorp' an rdataset iteratator for all rdatasets at
- * 'node' in version 'version' of 'db'.
- */
-
- REQUIRE(DNS_DB_VALID(db));
- REQUIRE(iteratorp != NULL && *iteratorp == NULL);
-
- return ((db->methods->allrdatasets)(db, node, version, now,
- iteratorp));
-}
-
-isc_result_t
-dns_db_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)
-{
- /*
- * Add 'rdataset' to 'node' in version 'version' of 'db'.
- */
-
- REQUIRE(DNS_DB_VALID(db));
- REQUIRE(node != NULL);
- REQUIRE(((db->attributes & DNS_DBATTR_CACHE) == 0 && version != NULL)||
- ((db->attributes & DNS_DBATTR_CACHE) != 0 &&
- version == NULL && (options & DNS_DBADD_MERGE) == 0));
- REQUIRE((options & DNS_DBADD_EXACT) == 0 ||
- (options & DNS_DBADD_MERGE) != 0);
- REQUIRE(DNS_RDATASET_VALID(rdataset));
- REQUIRE(dns_rdataset_isassociated(rdataset));
- REQUIRE(rdataset->rdclass == db->rdclass);
- REQUIRE(addedrdataset == NULL ||
- (DNS_RDATASET_VALID(addedrdataset) &&
- ! dns_rdataset_isassociated(addedrdataset)));
-
- return ((db->methods->addrdataset)(db, node, version, now, rdataset,
- options, addedrdataset));
-}
-
-isc_result_t
-dns_db_subtractrdataset(dns_db_t *db, dns_dbnode_t *node,
- dns_dbversion_t *version, dns_rdataset_t *rdataset,
- unsigned int options, dns_rdataset_t *newrdataset)
-{
- /*
- * Remove any rdata in 'rdataset' from 'node' in version 'version' of
- * 'db'.
- */
-
- REQUIRE(DNS_DB_VALID(db));
- REQUIRE(node != NULL);
- REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0 && version != NULL);
- REQUIRE(DNS_RDATASET_VALID(rdataset));
- REQUIRE(dns_rdataset_isassociated(rdataset));
- REQUIRE(rdataset->rdclass == db->rdclass);
- REQUIRE(newrdataset == NULL ||
- (DNS_RDATASET_VALID(newrdataset) &&
- ! dns_rdataset_isassociated(newrdataset)));
-
- return ((db->methods->subtractrdataset)(db, node, version, rdataset,
- options, newrdataset));
-}
-
-isc_result_t
-dns_db_deleterdataset(dns_db_t *db, dns_dbnode_t *node,
- dns_dbversion_t *version, dns_rdatatype_t type,
- dns_rdatatype_t covers)
-{
- /*
- * Make it so that no rdataset of type 'type' exists at 'node' in
- * version version 'version' of 'db'.
- */
-
- REQUIRE(DNS_DB_VALID(db));
- REQUIRE(node != NULL);
- REQUIRE(((db->attributes & DNS_DBATTR_CACHE) == 0 && version != NULL)||
- ((db->attributes & DNS_DBATTR_CACHE) != 0 && version == NULL));
-
- return ((db->methods->deleterdataset)(db, node, version,
- type, covers));
-}
-
-void
-dns_db_overmem(dns_db_t *db, isc_boolean_t overmem) {
-
- REQUIRE(DNS_DB_VALID(db));
-
- (db->methods->overmem)(db, overmem);
-}
-
-isc_result_t
-dns_db_getsoaserial(dns_db_t *db, dns_dbversion_t *ver, isc_uint32_t *serialp)
-{
- isc_result_t result;
- dns_dbnode_t *node = NULL;
- dns_rdataset_t rdataset;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- isc_buffer_t buffer;
-
- REQUIRE(dns_db_iszone(db) || dns_db_isstub(db));
-
- result = dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- dns_rdataset_init(&rdataset);
- result = dns_db_findrdataset(db, node, ver, dns_rdatatype_soa, 0,
- (isc_stdtime_t)0, &rdataset, NULL);
- if (result != ISC_R_SUCCESS)
- goto freenode;
-
- result = dns_rdataset_first(&rdataset);
- if (result != ISC_R_SUCCESS)
- goto freerdataset;
- dns_rdataset_current(&rdataset, &rdata);
- result = dns_rdataset_next(&rdataset);
- INSIST(result == ISC_R_NOMORE);
-
- INSIST(rdata.length > 20);
- isc_buffer_init(&buffer, rdata.data, rdata.length);
- isc_buffer_add(&buffer, rdata.length);
- isc_buffer_forward(&buffer, rdata.length - 20);
- *serialp = isc_buffer_getuint32(&buffer);
-
- result = ISC_R_SUCCESS;
-
- freerdataset:
- dns_rdataset_disassociate(&rdataset);
-
- freenode:
- dns_db_detachnode(db, &node);
- return (result);
-}
-
-unsigned int
-dns_db_nodecount(dns_db_t *db) {
- REQUIRE(DNS_DB_VALID(db));
-
- return ((db->methods->nodecount)(db));
-}
-
-void
-dns_db_settask(dns_db_t *db, isc_task_t *task) {
- REQUIRE(DNS_DB_VALID(db));
-
- (db->methods->settask)(db, task);
-}
-
-isc_result_t
-dns_db_register(const char *name, dns_dbcreatefunc_t create, void *driverarg,
- isc_mem_t *mctx, dns_dbimplementation_t **dbimp)
-{
- dns_dbimplementation_t *imp;
-
- REQUIRE(name != NULL);
- REQUIRE(dbimp != NULL && *dbimp == NULL);
-
- RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
-
- RWLOCK(&implock, isc_rwlocktype_write);
- imp = impfind(name);
- if (imp != NULL) {
- RWUNLOCK(&implock, isc_rwlocktype_write);
- return (ISC_R_EXISTS);
- }
-
- imp = isc_mem_get(mctx, sizeof(dns_dbimplementation_t));
- if (imp == NULL) {
- RWUNLOCK(&implock, isc_rwlocktype_write);
- return (ISC_R_NOMEMORY);
- }
- imp->name = name;
- imp->create = create;
- imp->mctx = NULL;
- imp->driverarg = driverarg;
- isc_mem_attach(mctx, &imp->mctx);
- ISC_LINK_INIT(imp, link);
- ISC_LIST_APPEND(implementations, imp, link);
- RWUNLOCK(&implock, isc_rwlocktype_write);
-
- *dbimp = imp;
-
- return (ISC_R_SUCCESS);
-}
-
-void
-dns_db_unregister(dns_dbimplementation_t **dbimp) {
- dns_dbimplementation_t *imp;
- isc_mem_t *mctx;
-
- REQUIRE(dbimp != NULL && *dbimp != NULL);
-
- RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
-
- imp = *dbimp;
- *dbimp = NULL;
- RWLOCK(&implock, isc_rwlocktype_write);
- ISC_LIST_UNLINK(implementations, imp, link);
- mctx = imp->mctx;
- isc_mem_put(mctx, imp, sizeof(dns_dbimplementation_t));
- isc_mem_detach(&mctx);
- RWUNLOCK(&implock, isc_rwlocktype_write);
- ENSURE(*dbimp == NULL);
-}
-
-isc_result_t
-dns_db_getoriginnode(dns_db_t *db, dns_dbnode_t **nodep) {
- REQUIRE(DNS_DB_VALID(db));
- REQUIRE(dns_db_iszone(db) == ISC_TRUE);
- REQUIRE(nodep != NULL && *nodep == NULL);
-
- if (db->methods->getoriginnode != NULL)
- return ((db->methods->getoriginnode)(db, nodep));
-
- return (ISC_R_NOTFOUND);
-}
-
-dns_stats_t *
-dns_db_getrrsetstats(dns_db_t *db) {
- REQUIRE(DNS_DB_VALID(db));
-
- if (db->methods->getrrsetstats != NULL)
- return ((db->methods->getrrsetstats)(db));
-
- return (NULL);
-}
-
-isc_result_t
-dns_db_getnsec3parameters(dns_db_t *db, dns_dbversion_t *version,
- dns_hash_t *hash, isc_uint8_t *flags,
- isc_uint16_t *iterations,
- unsigned char *salt, size_t *salt_length)
-{
- REQUIRE(DNS_DB_VALID(db));
- REQUIRE(dns_db_iszone(db) == ISC_TRUE);
-
- if (db->methods->getnsec3parameters != NULL)
- return ((db->methods->getnsec3parameters)(db, version, hash,
- flags, iterations,
- salt, salt_length));
-
- return (ISC_R_NOTFOUND);
-}
-
-isc_result_t
-dns_db_setsigningtime(dns_db_t *db, dns_rdataset_t *rdataset,
- isc_stdtime_t resign)
-{
- if (db->methods->setsigningtime != NULL)
- return ((db->methods->setsigningtime)(db, rdataset, resign));
- return (ISC_R_NOTIMPLEMENTED);
-}
-
-isc_result_t
-dns_db_getsigningtime(dns_db_t *db, dns_rdataset_t *rdataset, dns_name_t *name)
-{
- if (db->methods->getsigningtime != NULL)
- return ((db->methods->getsigningtime)(db, rdataset, name));
- return (ISC_R_NOTFOUND);
-}
-
-void
-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);
-}
-
-isc_result_t
-dns_db_rpz_enabled(dns_db_t *db, dns_rpz_st_t *st)
-{
- if (db->methods->rpz_enabled != NULL)
- return ((db->methods->rpz_enabled)(db, st));
- return (ISC_R_SUCCESS);
-}
-
-void
-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,
- dns_name_t *query_qname)
-{
- if (db->methods->rpz_findips != NULL)
- (db->methods->rpz_findips)(rpz, rpz_type, zone, db, version,
- ardataset, st, query_qname);
-}
diff --git a/contrib/bind9/lib/dns/dbiterator.c b/contrib/bind9/lib/dns/dbiterator.c
deleted file mode 100644
index 8981e49c2646..000000000000
--- a/contrib/bind9/lib/dns/dbiterator.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: dbiterator.c,v 1.18 2007/06/19 23:47:16 tbox Exp $ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <isc/util.h>
-
-#include <dns/dbiterator.h>
-#include <dns/name.h>
-
-void
-dns_dbiterator_destroy(dns_dbiterator_t **iteratorp) {
- /*
- * Destroy '*iteratorp'.
- */
-
- REQUIRE(iteratorp != NULL);
- REQUIRE(DNS_DBITERATOR_VALID(*iteratorp));
-
- (*iteratorp)->methods->destroy(iteratorp);
-
- ENSURE(*iteratorp == NULL);
-}
-
-isc_result_t
-dns_dbiterator_first(dns_dbiterator_t *iterator) {
- /*
- * Move the node cursor to the first node in the database (if any).
- */
-
- REQUIRE(DNS_DBITERATOR_VALID(iterator));
-
- return (iterator->methods->first(iterator));
-}
-
-isc_result_t
-dns_dbiterator_last(dns_dbiterator_t *iterator) {
- /*
- * Move the node cursor to the first node in the database (if any).
- */
-
- REQUIRE(DNS_DBITERATOR_VALID(iterator));
-
- return (iterator->methods->last(iterator));
-}
-
-isc_result_t
-dns_dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name) {
- /*
- * Move the node cursor to the node with name 'name'.
- */
-
- REQUIRE(DNS_DBITERATOR_VALID(iterator));
-
- return (iterator->methods->seek(iterator, name));
-}
-
-isc_result_t
-dns_dbiterator_prev(dns_dbiterator_t *iterator) {
- /*
- * Move the node cursor to the previous node in the database (if any).
- */
-
- REQUIRE(DNS_DBITERATOR_VALID(iterator));
-
- return (iterator->methods->prev(iterator));
-}
-
-isc_result_t
-dns_dbiterator_next(dns_dbiterator_t *iterator) {
- /*
- * Move the node cursor to the next node in the database (if any).
- */
-
- REQUIRE(DNS_DBITERATOR_VALID(iterator));
-
- return (iterator->methods->next(iterator));
-}
-
-isc_result_t
-dns_dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep,
- dns_name_t *name)
-{
- /*
- * Return the current node.
- */
-
- REQUIRE(DNS_DBITERATOR_VALID(iterator));
- REQUIRE(nodep != NULL && *nodep == NULL);
- REQUIRE(name == NULL || dns_name_hasbuffer(name));
-
- return (iterator->methods->current(iterator, nodep, name));
-}
-
-isc_result_t
-dns_dbiterator_pause(dns_dbiterator_t *iterator) {
- /*
- * Pause iteration.
- */
-
- REQUIRE(DNS_DBITERATOR_VALID(iterator));
-
- return (iterator->methods->pause(iterator));
-}
-
-isc_result_t
-dns_dbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name) {
-
- /*
- * Return the origin to which returned node names are relative.
- */
-
- REQUIRE(DNS_DBITERATOR_VALID(iterator));
- REQUIRE(iterator->relative_names);
- REQUIRE(dns_name_hasbuffer(name));
-
- return (iterator->methods->origin(iterator, name));
-}
-
-void
-dns_dbiterator_setcleanmode(dns_dbiterator_t *iterator, isc_boolean_t mode) {
- REQUIRE(DNS_DBITERATOR_VALID(iterator));
-
- iterator->cleaning = mode;
-}
diff --git a/contrib/bind9/lib/dns/dbtable.c b/contrib/bind9/lib/dns/dbtable.c
deleted file mode 100644
index 20092209d58d..000000000000
--- a/contrib/bind9/lib/dns/dbtable.c
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007, 2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * $Id: dbtable.c,v 1.33 2007/06/19 23:47:16 tbox Exp $
- */
-
-/*! \file
- * \author
- * Principal Author: DCL
- */
-
-#include <config.h>
-
-#include <isc/mem.h>
-#include <isc/rwlock.h>
-#include <isc/util.h>
-
-#include <dns/dbtable.h>
-#include <dns/db.h>
-#include <dns/rbt.h>
-#include <dns/result.h>
-
-struct dns_dbtable {
- /* Unlocked. */
- unsigned int magic;
- isc_mem_t * mctx;
- dns_rdataclass_t rdclass;
- isc_mutex_t lock;
- isc_rwlock_t tree_lock;
- /* Locked by lock. */
- unsigned int references;
- /* Locked by tree_lock. */
- dns_rbt_t * rbt;
- dns_db_t * default_db;
-};
-
-#define DBTABLE_MAGIC ISC_MAGIC('D', 'B', '-', '-')
-#define VALID_DBTABLE(dbtable) ISC_MAGIC_VALID(dbtable, DBTABLE_MAGIC)
-
-static void
-dbdetach(void *data, void *arg) {
- dns_db_t *db = data;
-
- UNUSED(arg);
-
- dns_db_detach(&db);
-}
-
-isc_result_t
-dns_dbtable_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
- dns_dbtable_t **dbtablep)
-{
- dns_dbtable_t *dbtable;
- isc_result_t result;
-
- REQUIRE(mctx != NULL);
- REQUIRE(dbtablep != NULL && *dbtablep == NULL);
-
- dbtable = (dns_dbtable_t *)isc_mem_get(mctx, sizeof(*dbtable));
- if (dbtable == NULL)
- return (ISC_R_NOMEMORY);
-
- dbtable->rbt = NULL;
- result = dns_rbt_create(mctx, dbdetach, NULL, &dbtable->rbt);
- if (result != ISC_R_SUCCESS)
- goto clean1;
-
- result = isc_mutex_init(&dbtable->lock);
- if (result != ISC_R_SUCCESS)
- goto clean2;
-
- result = isc_rwlock_init(&dbtable->tree_lock, 0, 0);
- if (result != ISC_R_SUCCESS)
- goto clean3;
-
- dbtable->default_db = NULL;
- dbtable->mctx = NULL;
- isc_mem_attach(mctx, &dbtable->mctx);
- dbtable->rdclass = rdclass;
- dbtable->magic = DBTABLE_MAGIC;
- dbtable->references = 1;
-
- *dbtablep = dbtable;
-
- return (ISC_R_SUCCESS);
-
- clean3:
- DESTROYLOCK(&dbtable->lock);
-
- clean2:
- dns_rbt_destroy(&dbtable->rbt);
-
- clean1:
- isc_mem_putanddetach(&mctx, dbtable, sizeof(*dbtable));
-
- return (result);
-}
-
-static inline void
-dbtable_free(dns_dbtable_t *dbtable) {
- /*
- * Caller must ensure that it is safe to call.
- */
-
- RWLOCK(&dbtable->tree_lock, isc_rwlocktype_write);
-
- if (dbtable->default_db != NULL)
- dns_db_detach(&dbtable->default_db);
-
- dns_rbt_destroy(&dbtable->rbt);
-
- RWUNLOCK(&dbtable->tree_lock, isc_rwlocktype_write);
-
- isc_rwlock_destroy(&dbtable->tree_lock);
-
- dbtable->magic = 0;
-
- isc_mem_putanddetach(&dbtable->mctx, dbtable, sizeof(*dbtable));
-}
-
-void
-dns_dbtable_attach(dns_dbtable_t *source, dns_dbtable_t **targetp) {
- REQUIRE(VALID_DBTABLE(source));
- REQUIRE(targetp != NULL && *targetp == NULL);
-
- LOCK(&source->lock);
-
- INSIST(source->references > 0);
- source->references++;
- INSIST(source->references != 0);
-
- UNLOCK(&source->lock);
-
- *targetp = source;
-}
-
-void
-dns_dbtable_detach(dns_dbtable_t **dbtablep) {
- dns_dbtable_t *dbtable;
- isc_boolean_t free_dbtable = ISC_FALSE;
-
- REQUIRE(dbtablep != NULL);
- dbtable = *dbtablep;
- REQUIRE(VALID_DBTABLE(dbtable));
-
- LOCK(&dbtable->lock);
-
- INSIST(dbtable->references > 0);
- dbtable->references--;
- if (dbtable->references == 0)
- free_dbtable = ISC_TRUE;
-
- UNLOCK(&dbtable->lock);
-
- if (free_dbtable)
- dbtable_free(dbtable);
-
- *dbtablep = NULL;
-}
-
-isc_result_t
-dns_dbtable_add(dns_dbtable_t *dbtable, dns_db_t *db) {
- isc_result_t result;
- dns_db_t *clone;
-
- REQUIRE(VALID_DBTABLE(dbtable));
- REQUIRE(dns_db_class(db) == dbtable->rdclass);
-
- clone = NULL;
- dns_db_attach(db, &clone);
-
- RWLOCK(&dbtable->tree_lock, isc_rwlocktype_write);
- result = dns_rbt_addname(dbtable->rbt, dns_db_origin(clone), clone);
- RWUNLOCK(&dbtable->tree_lock, isc_rwlocktype_write);
-
- return (result);
-}
-
-void
-dns_dbtable_remove(dns_dbtable_t *dbtable, dns_db_t *db) {
- dns_db_t *stored_data = NULL;
- isc_result_t result;
- dns_name_t *name;
-
- REQUIRE(VALID_DBTABLE(dbtable));
-
- name = dns_db_origin(db);
-
- /*
- * There is a requirement that the association of name with db
- * be verified. With the current rbt.c this is expensive to do,
- * because effectively two find operations are being done, but
- * deletion is relatively infrequent.
- * XXXDCL ... this could be cheaper now with dns_rbt_deletenode.
- */
-
- RWLOCK(&dbtable->tree_lock, isc_rwlocktype_write);
-
- result = dns_rbt_findname(dbtable->rbt, name, 0, NULL,
- (void **) (void *)&stored_data);
-
- if (result == ISC_R_SUCCESS) {
- INSIST(stored_data == db);
-
- (void)dns_rbt_deletename(dbtable->rbt, name, ISC_FALSE);
- }
-
- RWUNLOCK(&dbtable->tree_lock, isc_rwlocktype_write);
-}
-
-void
-dns_dbtable_adddefault(dns_dbtable_t *dbtable, dns_db_t *db) {
- REQUIRE(VALID_DBTABLE(dbtable));
- REQUIRE(dbtable->default_db == NULL);
- REQUIRE(dns_name_compare(dns_db_origin(db), dns_rootname) == 0);
-
- RWLOCK(&dbtable->tree_lock, isc_rwlocktype_write);
-
- dbtable->default_db = NULL;
- dns_db_attach(db, &dbtable->default_db);
-
- RWUNLOCK(&dbtable->tree_lock, isc_rwlocktype_write);
-}
-
-void
-dns_dbtable_getdefault(dns_dbtable_t *dbtable, dns_db_t **dbp) {
- REQUIRE(VALID_DBTABLE(dbtable));
- REQUIRE(dbp != NULL && *dbp == NULL);
-
- RWLOCK(&dbtable->tree_lock, isc_rwlocktype_read);
-
- dns_db_attach(dbtable->default_db, dbp);
-
- RWUNLOCK(&dbtable->tree_lock, isc_rwlocktype_read);
-}
-
-void
-dns_dbtable_removedefault(dns_dbtable_t *dbtable) {
- REQUIRE(VALID_DBTABLE(dbtable));
-
- RWLOCK(&dbtable->tree_lock, isc_rwlocktype_write);
-
- dns_db_detach(&dbtable->default_db);
-
- RWUNLOCK(&dbtable->tree_lock, isc_rwlocktype_write);
-}
-
-isc_result_t
-dns_dbtable_find(dns_dbtable_t *dbtable, dns_name_t *name,
- unsigned int options, dns_db_t **dbp)
-{
- dns_db_t *stored_data = NULL;
- isc_result_t result;
- unsigned int rbtoptions = 0;
-
- REQUIRE(dbp != NULL && *dbp == NULL);
-
- if ((options & DNS_DBTABLEFIND_NOEXACT) != 0)
- rbtoptions |= DNS_RBTFIND_NOEXACT;
-
- RWLOCK(&dbtable->tree_lock, isc_rwlocktype_read);
-
- result = dns_rbt_findname(dbtable->rbt, name, rbtoptions, NULL,
- (void **) (void *)&stored_data);
-
- if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH)
- dns_db_attach(stored_data, dbp);
- else if (dbtable->default_db != NULL) {
- dns_db_attach(dbtable->default_db, dbp);
- result = DNS_R_PARTIALMATCH;
- } else
- result = ISC_R_NOTFOUND;
-
- RWUNLOCK(&dbtable->tree_lock, isc_rwlocktype_read);
-
- return (result);
-}
diff --git a/contrib/bind9/lib/dns/diff.c b/contrib/bind9/lib/dns/diff.c
deleted file mode 100644
index ff60d462f372..000000000000
--- a/contrib/bind9/lib/dns/diff.c
+++ /dev/null
@@ -1,661 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007-2009, 2011, 2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2000-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: diff.c,v 1.26 2011/03/25 23:53:02 each Exp $ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <stdlib.h>
-
-#include <isc/buffer.h>
-#include <isc/file.h>
-#include <isc/mem.h>
-#include <isc/string.h>
-#include <isc/util.h>
-
-#include <dns/db.h>
-#include <dns/diff.h>
-#include <dns/log.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>
-
-#define CHECK(op) \
- do { result = (op); \
- if (result != ISC_R_SUCCESS) goto failure; \
- } while (0)
-
-#define DIFF_COMMON_LOGARGS \
- dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_DIFF
-
-static dns_rdatatype_t
-rdata_covers(dns_rdata_t *rdata) {
- return (rdata->type == dns_rdatatype_rrsig ?
- dns_rdata_covers(rdata) : 0);
-}
-
-isc_result_t
-dns_difftuple_create(isc_mem_t *mctx,
- dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
- dns_rdata_t *rdata, dns_difftuple_t **tp)
-{
- dns_difftuple_t *t;
- unsigned int size;
- unsigned char *datap;
-
- REQUIRE(tp != NULL && *tp == NULL);
-
- /*
- * Create a new tuple. The variable-size wire-format name data and
- * rdata immediately follow the dns_difftuple_t structure
- * in memory.
- */
- size = sizeof(*t) + name->length + rdata->length;
- t = isc_mem_allocate(mctx, size);
- if (t == NULL)
- return (ISC_R_NOMEMORY);
- t->mctx = NULL;
- isc_mem_attach(mctx, &t->mctx);
- t->op = op;
-
- datap = (unsigned char *)(t + 1);
-
- memcpy(datap, name->ndata, name->length);
- dns_name_init(&t->name, NULL);
- dns_name_clone(name, &t->name);
- t->name.ndata = datap;
- datap += name->length;
-
- t->ttl = ttl;
-
- memcpy(datap, rdata->data, rdata->length);
- dns_rdata_init(&t->rdata);
- dns_rdata_clone(rdata, &t->rdata);
- t->rdata.data = datap;
- datap += rdata->length;
-
- ISC_LINK_INIT(&t->rdata, link);
- ISC_LINK_INIT(t, link);
- t->magic = DNS_DIFFTUPLE_MAGIC;
-
- INSIST(datap == (unsigned char *)t + size);
-
- *tp = t;
- return (ISC_R_SUCCESS);
-}
-
-void
-dns_difftuple_free(dns_difftuple_t **tp) {
- dns_difftuple_t *t = *tp;
- isc_mem_t *mctx;
-
- REQUIRE(DNS_DIFFTUPLE_VALID(t));
-
- dns_name_invalidate(&t->name);
- t->magic = 0;
- mctx = t->mctx;
- isc_mem_free(mctx, t);
- isc_mem_detach(&mctx);
- *tp = NULL;
-}
-
-isc_result_t
-dns_difftuple_copy(dns_difftuple_t *orig, dns_difftuple_t **copyp) {
- return (dns_difftuple_create(orig->mctx, orig->op, &orig->name,
- orig->ttl, &orig->rdata, copyp));
-}
-
-void
-dns_diff_init(isc_mem_t *mctx, dns_diff_t *diff) {
- diff->mctx = mctx;
- diff->resign = 0;
- ISC_LIST_INIT(diff->tuples);
- diff->magic = DNS_DIFF_MAGIC;
-}
-
-void
-dns_diff_clear(dns_diff_t *diff) {
- dns_difftuple_t *t;
- REQUIRE(DNS_DIFF_VALID(diff));
- while ((t = ISC_LIST_HEAD(diff->tuples)) != NULL) {
- ISC_LIST_UNLINK(diff->tuples, t, link);
- dns_difftuple_free(&t);
- }
- ENSURE(ISC_LIST_EMPTY(diff->tuples));
-}
-
-void
-dns_diff_append(dns_diff_t *diff, dns_difftuple_t **tuplep)
-{
- ISC_LIST_APPEND(diff->tuples, *tuplep, link);
- *tuplep = NULL;
-}
-
-/* XXX this is O(N) */
-
-void
-dns_diff_appendminimal(dns_diff_t *diff, dns_difftuple_t **tuplep)
-{
- dns_difftuple_t *ot, *next_ot;
-
- REQUIRE(DNS_DIFF_VALID(diff));
- REQUIRE(DNS_DIFFTUPLE_VALID(*tuplep));
-
- /*
- * Look for an existing tuple with the same owner name,
- * rdata, and TTL. If we are doing an addition and find a
- * deletion or vice versa, remove both the old and the
- * new tuple since they cancel each other out (assuming
- * that we never delete nonexistent data or add existing
- * data).
- *
- * If we find an old update of the same kind as
- * the one we are doing, there must be a programming
- * error. We report it but try to continue anyway.
- */
- for (ot = ISC_LIST_HEAD(diff->tuples); ot != NULL;
- ot = next_ot)
- {
- next_ot = ISC_LIST_NEXT(ot, link);
- if (dns_name_equal(&ot->name, &(*tuplep)->name) &&
- dns_rdata_compare(&ot->rdata, &(*tuplep)->rdata) == 0 &&
- ot->ttl == (*tuplep)->ttl)
- {
- ISC_LIST_UNLINK(diff->tuples, ot, link);
- if ((*tuplep)->op == ot->op) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "unexpected non-minimal diff");
- } else {
- dns_difftuple_free(tuplep);
- }
- dns_difftuple_free(&ot);
- break;
- }
- }
-
- if (*tuplep != NULL) {
- ISC_LIST_APPEND(diff->tuples, *tuplep, link);
- *tuplep = NULL;
- }
-
- ENSURE(*tuplep == NULL);
-}
-
-static isc_stdtime_t
-setresign(dns_rdataset_t *modified, isc_uint32_t delta) {
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdata_rrsig_t sig;
- isc_stdtime_t when;
- isc_result_t result;
-
- result = dns_rdataset_first(modified);
- INSIST(result == ISC_R_SUCCESS);
- dns_rdataset_current(modified, &rdata);
- (void)dns_rdata_tostruct(&rdata, &sig, NULL);
- if ((rdata.flags & DNS_RDATA_OFFLINE) != 0)
- when = 0;
- else
- when = sig.timeexpire - delta;
- dns_rdata_reset(&rdata);
-
- result = dns_rdataset_next(modified);
- while (result == ISC_R_SUCCESS) {
- dns_rdataset_current(modified, &rdata);
- (void)dns_rdata_tostruct(&rdata, &sig, NULL);
- if ((rdata.flags & DNS_RDATA_OFFLINE) != 0) {
- goto next_rr;
- }
- if (when == 0 || sig.timeexpire - delta < when)
- when = sig.timeexpire - delta;
- next_rr:
- dns_rdata_reset(&rdata);
- result = dns_rdataset_next(modified);
- }
- INSIST(result == ISC_R_NOMORE);
- return (when);
-}
-
-static isc_result_t
-diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver,
- isc_boolean_t warn)
-{
- dns_difftuple_t *t;
- dns_dbnode_t *node = NULL;
- isc_result_t result;
- char namebuf[DNS_NAME_FORMATSIZE];
- char typebuf[DNS_RDATATYPE_FORMATSIZE];
- char classbuf[DNS_RDATACLASS_FORMATSIZE];
-
- REQUIRE(DNS_DIFF_VALID(diff));
- REQUIRE(DNS_DB_VALID(db));
-
- t = ISC_LIST_HEAD(diff->tuples);
- while (t != NULL) {
- dns_name_t *name;
-
- INSIST(node == NULL);
- name = &t->name;
- /*
- * Find the node.
- * We create the node if it does not exist.
- * This will cause an empty node to be created if the diff
- * contains a deletion of an RR at a nonexistent name,
- * but such diffs should never be created in the first
- * place.
- */
-
- while (t != NULL && dns_name_equal(&t->name, name)) {
- dns_rdatatype_t type, covers;
- dns_diffop_t op;
- dns_rdatalist_t rdl;
- dns_rdataset_t rds;
- dns_rdataset_t ardataset;
- dns_rdataset_t *modified = NULL;
-
- op = t->op;
- type = t->rdata.type;
- covers = rdata_covers(&t->rdata);
-
- /*
- * Collect a contiguous set of updates with
- * the same operation (add/delete) and RR type
- * into a single rdatalist so that the
- * database rrset merging/subtraction code
- * can work more efficiently than if each
- * RR were merged into / subtracted from
- * the database separately.
- *
- * This is done by linking rdata structures from the
- * diff into "rdatalist". This uses the rdata link
- * field, not the diff link field, so the structure
- * of the diff itself is not affected.
- */
-
- rdl.type = type;
- rdl.covers = covers;
- rdl.rdclass = t->rdata.rdclass;
- rdl.ttl = t->ttl;
- ISC_LIST_INIT(rdl.rdata);
- ISC_LINK_INIT(&rdl, link);
-
- node = NULL;
- if (type != dns_rdatatype_nsec3 &&
- covers != dns_rdatatype_nsec3)
- CHECK(dns_db_findnode(db, name, ISC_TRUE,
- &node));
- else
- CHECK(dns_db_findnsec3node(db, name, ISC_TRUE,
- &node));
-
- while (t != NULL &&
- dns_name_equal(&t->name, name) &&
- t->op == op &&
- t->rdata.type == type &&
- rdata_covers(&t->rdata) == covers)
- {
- dns_name_format(name, namebuf, sizeof(namebuf));
- dns_rdatatype_format(t->rdata.type, typebuf,
- sizeof(typebuf));
- dns_rdataclass_format(t->rdata.rdclass,
- classbuf,
- sizeof(classbuf));
- if (t->ttl != rdl.ttl && warn)
- isc_log_write(DIFF_COMMON_LOGARGS,
- ISC_LOG_WARNING,
- "'%s/%s/%s': TTL differs in "
- "rdataset, adjusting "
- "%lu -> %lu",
- namebuf, typebuf, classbuf,
- (unsigned long) t->ttl,
- (unsigned long) rdl.ttl);
- ISC_LIST_APPEND(rdl.rdata, &t->rdata, link);
- t = ISC_LIST_NEXT(t, link);
- }
-
- /*
- * Convert the rdatalist into a rdataset.
- */
- dns_rdataset_init(&rds);
- CHECK(dns_rdatalist_tordataset(&rdl, &rds));
- if (rds.type == dns_rdatatype_rrsig)
- switch (op) {
- case DNS_DIFFOP_ADDRESIGN:
- case DNS_DIFFOP_DELRESIGN:
- modified = &ardataset;
- dns_rdataset_init(modified);
- break;
- default:
- break;
- }
- rds.trust = dns_trust_ultimate;
-
- /*
- * Merge the rdataset into the database.
- */
- switch (op) {
- case DNS_DIFFOP_ADD:
- case DNS_DIFFOP_ADDRESIGN:
- result = dns_db_addrdataset(db, node, ver,
- 0, &rds,
- DNS_DBADD_MERGE|
- DNS_DBADD_EXACT|
- DNS_DBADD_EXACTTTL,
- modified);
- break;
- case DNS_DIFFOP_DEL:
- case DNS_DIFFOP_DELRESIGN:
- result = dns_db_subtractrdataset(db, node, ver,
- &rds,
- DNS_DBSUB_EXACT,
- modified);
- break;
- default:
- INSIST(0);
- }
-
- if (result == ISC_R_SUCCESS) {
- if (modified != NULL) {
- isc_stdtime_t resign;
- resign = setresign(modified,
- diff->resign);
- dns_db_setsigningtime(db, modified,
- resign);
- if (diff->resign == 0 &&
- (op == DNS_DIFFOP_ADDRESIGN ||
- op == DNS_DIFFOP_DELRESIGN))
- isc_log_write(
- DIFF_COMMON_LOGARGS,
- ISC_LOG_WARNING,
- "resign requested "
- "with 0 resign "
- "interval");
- }
- } else if (result == DNS_R_UNCHANGED) {
- /*
- * This will not happen when executing a
- * dynamic update, because that code will
- * generate strictly minimal diffs.
- * It may happen when receiving an IXFR
- * from a server that is not as careful.
- * Issue a warning and continue.
- */
- 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,
- "%s/%s: dns_diff_apply: "
- "update with no effect",
- namebuf, classbuf);
- }
- } else if (result == DNS_R_NXRRSET) {
- /*
- * OK.
- */
- } else {
- if (modified != NULL &&
- dns_rdataset_isassociated(modified))
- dns_rdataset_disassociate(modified);
- CHECK(result);
- }
- dns_db_detachnode(db, &node);
- if (modified != NULL &&
- dns_rdataset_isassociated(modified))
- dns_rdataset_disassociate(modified);
- }
- }
- return (ISC_R_SUCCESS);
-
- failure:
- if (node != NULL)
- dns_db_detachnode(db, &node);
- return (result);
-}
-
-isc_result_t
-dns_diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver) {
- return (diff_apply(diff, db, ver, ISC_TRUE));
-}
-
-isc_result_t
-dns_diff_applysilently(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver) {
- return (diff_apply(diff, db, ver, ISC_FALSE));
-}
-
-/* XXX this duplicates lots of code in diff_apply(). */
-
-isc_result_t
-dns_diff_load(dns_diff_t *diff, dns_addrdatasetfunc_t addfunc,
- void *add_private)
-{
- dns_difftuple_t *t;
- isc_result_t result;
-
- REQUIRE(DNS_DIFF_VALID(diff));
-
- t = ISC_LIST_HEAD(diff->tuples);
- while (t != NULL) {
- dns_name_t *name;
-
- name = &t->name;
- while (t != NULL && dns_name_equal(&t->name, name)) {
- dns_rdatatype_t type, covers;
- dns_diffop_t op;
- dns_rdatalist_t rdl;
- dns_rdataset_t rds;
-
- op = t->op;
- type = t->rdata.type;
- covers = rdata_covers(&t->rdata);
-
- rdl.type = type;
- rdl.covers = covers;
- rdl.rdclass = t->rdata.rdclass;
- rdl.ttl = t->ttl;
- ISC_LIST_INIT(rdl.rdata);
- ISC_LINK_INIT(&rdl, link);
-
- while (t != NULL && dns_name_equal(&t->name, name) &&
- t->op == op && t->rdata.type == type &&
- rdata_covers(&t->rdata) == covers)
- {
- ISC_LIST_APPEND(rdl.rdata, &t->rdata, link);
- t = ISC_LIST_NEXT(t, link);
- }
-
- /*
- * Convert the rdatalist into a rdataset.
- */
- dns_rdataset_init(&rds);
- CHECK(dns_rdatalist_tordataset(&rdl, &rds));
- rds.trust = dns_trust_ultimate;
-
- INSIST(op == DNS_DIFFOP_ADD);
- result = (*addfunc)(add_private, name, &rds);
- 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) {
- /*
- * OK.
- */
- } else {
- CHECK(result);
- }
- }
- }
- result = ISC_R_SUCCESS;
- failure:
- return (result);
-}
-
-/*
- * XXX uses qsort(); a merge sort would be more natural for lists,
- * and perhaps safer wrt thread stack overflow.
- */
-isc_result_t
-dns_diff_sort(dns_diff_t *diff, dns_diff_compare_func *compare) {
- unsigned int length = 0;
- unsigned int i;
- dns_difftuple_t **v;
- dns_difftuple_t *p;
- REQUIRE(DNS_DIFF_VALID(diff));
-
- for (p = ISC_LIST_HEAD(diff->tuples);
- p != NULL;
- p = ISC_LIST_NEXT(p, link))
- length++;
- if (length == 0)
- return (ISC_R_SUCCESS);
- v = isc_mem_get(diff->mctx, length * sizeof(dns_difftuple_t *));
- if (v == NULL)
- return (ISC_R_NOMEMORY);
- for (i = 0; i < length; i++) {
- p = ISC_LIST_HEAD(diff->tuples);
- v[i] = p;
- ISC_LIST_UNLINK(diff->tuples, p, link);
- }
- INSIST(ISC_LIST_HEAD(diff->tuples) == NULL);
- qsort(v, length, sizeof(v[0]), compare);
- for (i = 0; i < length; i++) {
- ISC_LIST_APPEND(diff->tuples, v[i], link);
- }
- isc_mem_put(diff->mctx, v, length * sizeof(dns_difftuple_t *));
- return (ISC_R_SUCCESS);
-}
-
-
-/*
- * Create an rdataset containing the single RR of the given
- * tuple. The caller must allocate the rdata, rdataset and
- * an rdatalist structure for it to refer to.
- */
-
-static isc_result_t
-diff_tuple_tordataset(dns_difftuple_t *t, dns_rdata_t *rdata,
- dns_rdatalist_t *rdl, dns_rdataset_t *rds)
-{
- REQUIRE(DNS_DIFFTUPLE_VALID(t));
- REQUIRE(rdl != NULL);
- REQUIRE(rds != NULL);
-
- rdl->type = t->rdata.type;
- rdl->rdclass = t->rdata.rdclass;
- rdl->ttl = t->ttl;
- ISC_LIST_INIT(rdl->rdata);
- ISC_LINK_INIT(rdl, link);
- dns_rdataset_init(rds);
- ISC_LINK_INIT(rdata, link);
- dns_rdata_clone(&t->rdata, rdata);
- ISC_LIST_APPEND(rdl->rdata, rdata, link);
- return (dns_rdatalist_tordataset(rdl, rds));
-}
-
-isc_result_t
-dns_diff_print(dns_diff_t *diff, FILE *file) {
- isc_result_t result;
- dns_difftuple_t *t;
- char *mem = NULL;
- unsigned int size = 2048;
- const char *op = NULL;
-
- REQUIRE(DNS_DIFF_VALID(diff));
-
- mem = isc_mem_get(diff->mctx, size);
- if (mem == NULL)
- return (ISC_R_NOMEMORY);
-
- for (t = ISC_LIST_HEAD(diff->tuples); t != NULL;
- t = ISC_LIST_NEXT(t, link))
- {
- isc_buffer_t buf;
- isc_region_t r;
-
- dns_rdatalist_t rdl;
- dns_rdataset_t rds;
- dns_rdata_t rd = DNS_RDATA_INIT;
-
- result = diff_tuple_tordataset(t, &rd, &rdl, &rds);
- if (result != ISC_R_SUCCESS) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "diff_tuple_tordataset failed: %s",
- dns_result_totext(result));
- result = ISC_R_UNEXPECTED;
- goto cleanup;
- }
- again:
- isc_buffer_init(&buf, mem, size);
- result = dns_rdataset_totext(&rds, &t->name,
- ISC_FALSE, ISC_FALSE, &buf);
-
- if (result == ISC_R_NOSPACE) {
- isc_mem_put(diff->mctx, mem, size);
- size += 1024;
- mem = isc_mem_get(diff->mctx, size);
- if (mem == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup;
- }
- goto again;
- }
-
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- /*
- * Get rid of final newline.
- */
- INSIST(buf.used >= 1 &&
- ((char *) buf.base)[buf.used-1] == '\n');
- buf.used--;
-
- isc_buffer_usedregion(&buf, &r);
- switch (t->op) {
- case DNS_DIFFOP_EXISTS: op = "exists"; break;
- case DNS_DIFFOP_ADD: op = "add"; break;
- case DNS_DIFFOP_DEL: op = "del"; break;
- case DNS_DIFFOP_ADDRESIGN: op = "add re-sign"; break;
- case DNS_DIFFOP_DELRESIGN: op = "del re-sign"; break;
- }
- if (file != NULL)
- fprintf(file, "%s %.*s\n", op, (int) r.length,
- (char *) r.base);
- else
- isc_log_write(DIFF_COMMON_LOGARGS, ISC_LOG_DEBUG(7),
- "%s %.*s", op, (int) r.length,
- (char *) r.base);
- }
- result = ISC_R_SUCCESS;
- cleanup:
- if (mem != NULL)
- isc_mem_put(diff->mctx, mem, size);
- return (result);
-}
diff --git a/contrib/bind9/lib/dns/dispatch.c b/contrib/bind9/lib/dns/dispatch.c
deleted file mode 100644
index 5063914a9b29..000000000000
--- a/contrib/bind9/lib/dns/dispatch.c
+++ /dev/null
@@ -1,3859 +0,0 @@
-/*
- * Copyright (C) 2004-2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: dispatch.c,v 1.175 2011/11/29 01:03:47 marka Exp $ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <stdlib.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-#include <isc/entropy.h>
-#include <isc/mem.h>
-#include <isc/mutex.h>
-#include <isc/portset.h>
-#include <isc/print.h>
-#include <isc/random.h>
-#include <isc/socket.h>
-#include <isc/stats.h>
-#include <isc/string.h>
-#include <isc/task.h>
-#include <isc/time.h>
-#include <isc/util.h>
-
-#include <dns/acl.h>
-#include <dns/dispatch.h>
-#include <dns/events.h>
-#include <dns/log.h>
-#include <dns/message.h>
-#include <dns/portlist.h>
-#include <dns/stats.h>
-#include <dns/tcpmsg.h>
-#include <dns/types.h>
-
-typedef ISC_LIST(dns_dispentry_t) dns_displist_t;
-
-typedef struct dispsocket dispsocket_t;
-typedef ISC_LIST(dispsocket_t) dispsocketlist_t;
-
-typedef struct dispportentry dispportentry_t;
-typedef ISC_LIST(dispportentry_t) dispportlist_t;
-
-/* ARC4 Random generator state */
-typedef struct arc4ctx {
- isc_uint8_t i;
- isc_uint8_t j;
- isc_uint8_t s[256];
- int count;
- isc_entropy_t *entropy; /*%< entropy source for ARC4 */
- isc_mutex_t *lock;
-} arc4ctx_t;
-
-typedef struct dns_qid {
- unsigned int magic;
- unsigned int qid_nbuckets; /*%< hash table size */
- unsigned int qid_increment; /*%< id increment on collision */
- isc_mutex_t lock;
- dns_displist_t *qid_table; /*%< the table itself */
- dispsocketlist_t *sock_table; /*%< socket table */
-} dns_qid_t;
-
-struct dns_dispatchmgr {
- /* Unlocked. */
- unsigned int magic;
- isc_mem_t *mctx;
- dns_acl_t *blackhole;
- dns_portlist_t *portlist;
- isc_stats_t *stats;
- isc_entropy_t *entropy; /*%< entropy source */
-
- /* Locked by "lock". */
- isc_mutex_t lock;
- unsigned int state;
- ISC_LIST(dns_dispatch_t) list;
-
- /* Locked by arc4_lock. */
- isc_mutex_t arc4_lock;
- arc4ctx_t arc4ctx; /*%< ARC4 context for QID */
-
- /* locked by buffer lock */
- dns_qid_t *qid;
- isc_mutex_t buffer_lock;
- unsigned int buffers; /*%< allocated buffers */
- unsigned int buffersize; /*%< size of each buffer */
- unsigned int maxbuffers; /*%< max buffers */
-
- /* Locked internally. */
- isc_mutex_t depool_lock;
- isc_mempool_t *depool; /*%< pool for dispatch events */
- isc_mutex_t rpool_lock;
- isc_mempool_t *rpool; /*%< pool for replies */
- isc_mutex_t dpool_lock;
- isc_mempool_t *dpool; /*%< dispatch allocations */
- isc_mutex_t bpool_lock;
- isc_mempool_t *bpool; /*%< pool for buffers */
- isc_mutex_t spool_lock;
- isc_mempool_t *spool; /*%< pool for dispsocks */
-
- /*%
- * Locked by qid->lock if qid exists; otherwise, can be used without
- * being locked.
- * Memory footprint considerations: this is a simple implementation of
- * available ports, i.e., an ordered array of the actual port numbers.
- * This will require about 256KB of memory in the worst case (128KB for
- * each of IPv4 and IPv6). We could reduce it by representing it as a
- * more sophisticated way such as a list (or array) of ranges that are
- * searched to identify a specific port. Our decision here is the saved
- * memory isn't worth the implementation complexity, considering the
- * fact that the whole BIND9 process (which is mainly named) already
- * requires a pretty large memory footprint. We may, however, have to
- * revisit the decision when we want to use it as a separate module for
- * an environment where memory requirement is severer.
- */
- in_port_t *v4ports; /*%< available ports for IPv4 */
- unsigned int nv4ports; /*%< # of available ports for IPv4 */
- in_port_t *v6ports; /*%< available ports for IPv4 */
- unsigned int nv6ports; /*%< # of available ports for IPv4 */
-};
-
-#define MGR_SHUTTINGDOWN 0x00000001U
-#define MGR_IS_SHUTTINGDOWN(l) (((l)->state & MGR_SHUTTINGDOWN) != 0)
-
-#define IS_PRIVATE(d) (((d)->attributes & DNS_DISPATCHATTR_PRIVATE) != 0)
-
-struct dns_dispentry {
- unsigned int magic;
- dns_dispatch_t *disp;
- dns_messageid_t id;
- in_port_t port;
- unsigned int bucket;
- isc_sockaddr_t host;
- isc_task_t *task;
- isc_taskaction_t action;
- void *arg;
- isc_boolean_t item_out;
- dispsocket_t *dispsocket;
- ISC_LIST(dns_dispatchevent_t) items;
- ISC_LINK(dns_dispentry_t) link;
-};
-
-/*%
- * Maximum number of dispatch sockets that can be pooled for reuse. The
- * appropriate value may vary, but experiments have shown a busy caching server
- * may need more than 1000 sockets concurrently opened. The maximum allowable
- * number of dispatch sockets (per manager) will be set to the double of this
- * value.
- */
-#ifndef DNS_DISPATCH_POOLSOCKS
-#define DNS_DISPATCH_POOLSOCKS 2048
-#endif
-
-/*%
- * Quota to control the number of dispatch sockets. If a dispatch has more
- * than the quota of sockets, new queries will purge oldest ones, so that
- * a massive number of outstanding queries won't prevent subsequent queries
- * (especially if the older ones take longer time and result in timeout).
- */
-#ifndef DNS_DISPATCH_SOCKSQUOTA
-#define DNS_DISPATCH_SOCKSQUOTA 3072
-#endif
-
-struct dispsocket {
- unsigned int magic;
- isc_socket_t *socket;
- dns_dispatch_t *disp;
- isc_sockaddr_t host;
- in_port_t localport; /* XXX: should be removed later */
- dispportentry_t *portentry;
- dns_dispentry_t *resp;
- isc_task_t *task;
- ISC_LINK(dispsocket_t) link;
- unsigned int bucket;
- ISC_LINK(dispsocket_t) blink;
-};
-
-/*%
- * A port table entry. We remember every port we first open in a table with a
- * reference counter so that we can 'reuse' the same port (with different
- * destination addresses) using the SO_REUSEADDR socket option.
- */
-struct dispportentry {
- in_port_t port;
- unsigned int refs;
- ISC_LINK(struct dispportentry) link;
-};
-
-#ifndef DNS_DISPATCH_PORTTABLESIZE
-#define DNS_DISPATCH_PORTTABLESIZE 1024
-#endif
-
-#define INVALID_BUCKET (0xffffdead)
-
-/*%
- * Number of tasks for each dispatch that use separate sockets for different
- * transactions. This must be a power of 2 as it will divide 32 bit numbers
- * to get an uniformly random tasks selection. See get_dispsocket().
- */
-#define MAX_INTERNAL_TASKS 64
-
-struct dns_dispatch {
- /* Unlocked. */
- unsigned int magic; /*%< magic */
- dns_dispatchmgr_t *mgr; /*%< dispatch manager */
- int ntasks;
- /*%
- * internal task buckets. We use multiple tasks to distribute various
- * socket events well when using separate dispatch sockets. We use the
- * 1st task (task[0]) for internal control events.
- */
- isc_task_t *task[MAX_INTERNAL_TASKS];
- isc_socket_t *socket; /*%< isc socket attached to */
- isc_sockaddr_t local; /*%< local address */
- in_port_t localport; /*%< local UDP port */
- unsigned int maxrequests; /*%< max requests */
- isc_event_t *ctlevent;
-
- isc_mutex_t sepool_lock;
- isc_mempool_t *sepool; /*%< pool for socket events */
-
- /*% Locked by mgr->lock. */
- ISC_LINK(dns_dispatch_t) link;
-
- /* Locked by "lock". */
- isc_mutex_t lock; /*%< locks all below */
- isc_sockettype_t socktype;
- unsigned int attributes;
- unsigned int refcount; /*%< number of users */
- dns_dispatchevent_t *failsafe_ev; /*%< failsafe cancel event */
- unsigned int shutting_down : 1,
- shutdown_out : 1,
- connected : 1,
- tcpmsg_valid : 1,
- recv_pending : 1; /*%< is a recv() pending? */
- isc_result_t shutdown_why;
- ISC_LIST(dispsocket_t) activesockets;
- ISC_LIST(dispsocket_t) inactivesockets;
- unsigned int nsockets;
- unsigned int requests; /*%< how many requests we have */
- unsigned int tcpbuffers; /*%< allocated buffers */
- dns_tcpmsg_t tcpmsg; /*%< for tcp streams */
- dns_qid_t *qid;
- arc4ctx_t arc4ctx; /*%< for QID/UDP port num */
- dispportlist_t *port_table; /*%< hold ports 'owned' by us */
- isc_mempool_t *portpool; /*%< port table entries */
-};
-
-#define QID_MAGIC ISC_MAGIC('Q', 'i', 'd', ' ')
-#define VALID_QID(e) ISC_MAGIC_VALID((e), QID_MAGIC)
-
-#define RESPONSE_MAGIC ISC_MAGIC('D', 'r', 's', 'p')
-#define VALID_RESPONSE(e) ISC_MAGIC_VALID((e), RESPONSE_MAGIC)
-
-#define DISPSOCK_MAGIC ISC_MAGIC('D', 's', 'o', 'c')
-#define VALID_DISPSOCK(e) ISC_MAGIC_VALID((e), DISPSOCK_MAGIC)
-
-#define DISPATCH_MAGIC ISC_MAGIC('D', 'i', 's', 'p')
-#define VALID_DISPATCH(e) ISC_MAGIC_VALID((e), DISPATCH_MAGIC)
-
-#define DNS_DISPATCHMGR_MAGIC ISC_MAGIC('D', 'M', 'g', 'r')
-#define VALID_DISPATCHMGR(e) ISC_MAGIC_VALID((e), DNS_DISPATCHMGR_MAGIC)
-
-#define DNS_QID(disp) ((disp)->socktype == isc_sockettype_tcp) ? \
- (disp)->qid : (disp)->mgr->qid
-#define DISP_ARC4CTX(disp) ((disp)->socktype == isc_sockettype_udp) ? \
- (&(disp)->arc4ctx) : (&(disp)->mgr->arc4ctx)
-
-/*%
- * Locking a query port buffer is a bit tricky. We access the buffer without
- * locking until qid is created. Technically, there is a possibility of race
- * between the creation of qid and access to the port buffer; in practice,
- * however, this should be safe because qid isn't created until the first
- * dispatch is created and there should be no contending situation until then.
- */
-#define PORTBUFLOCK(mgr) if ((mgr)->qid != NULL) LOCK(&((mgr)->qid->lock))
-#define PORTBUFUNLOCK(mgr) if ((mgr)->qid != NULL) UNLOCK((&(mgr)->qid->lock))
-
-/*
- * Statics.
- */
-static dns_dispentry_t *entry_search(dns_qid_t *, isc_sockaddr_t *,
- dns_messageid_t, in_port_t, unsigned int);
-static isc_boolean_t destroy_disp_ok(dns_dispatch_t *);
-static void destroy_disp(isc_task_t *task, isc_event_t *event);
-static void destroy_dispsocket(dns_dispatch_t *, dispsocket_t **);
-static void deactivate_dispsocket(dns_dispatch_t *, dispsocket_t *);
-static void udp_exrecv(isc_task_t *, isc_event_t *);
-static void udp_shrecv(isc_task_t *, isc_event_t *);
-static void udp_recv(isc_event_t *, dns_dispatch_t *, dispsocket_t *);
-static void tcp_recv(isc_task_t *, isc_event_t *);
-static isc_result_t startrecv(dns_dispatch_t *, dispsocket_t *);
-static isc_uint32_t dns_hash(dns_qid_t *, isc_sockaddr_t *, dns_messageid_t,
- in_port_t);
-static void free_buffer(dns_dispatch_t *disp, void *buf, unsigned int len);
-static void *allocate_udp_buffer(dns_dispatch_t *disp);
-static inline void free_devent(dns_dispatch_t *disp, dns_dispatchevent_t *ev);
-static inline dns_dispatchevent_t *allocate_devent(dns_dispatch_t *disp);
-static void do_cancel(dns_dispatch_t *disp);
-static dns_dispentry_t *linear_first(dns_qid_t *disp);
-static dns_dispentry_t *linear_next(dns_qid_t *disp,
- dns_dispentry_t *resp);
-static void dispatch_free(dns_dispatch_t **dispp);
-static isc_result_t get_udpsocket(dns_dispatchmgr_t *mgr,
- dns_dispatch_t *disp,
- isc_socketmgr_t *sockmgr,
- isc_sockaddr_t *localaddr,
- isc_socket_t **sockp,
- isc_socket_t *dup_socket);
-static isc_result_t dispatch_createudp(dns_dispatchmgr_t *mgr,
- isc_socketmgr_t *sockmgr,
- isc_taskmgr_t *taskmgr,
- isc_sockaddr_t *localaddr,
- unsigned int maxrequests,
- unsigned int attributes,
- dns_dispatch_t **dispp,
- isc_socket_t *dup_socket);
-static isc_boolean_t destroy_mgr_ok(dns_dispatchmgr_t *mgr);
-static void destroy_mgr(dns_dispatchmgr_t **mgrp);
-static isc_result_t qid_allocate(dns_dispatchmgr_t *mgr, unsigned int buckets,
- unsigned int increment, dns_qid_t **qidp,
- isc_boolean_t needaddrtable);
-static void qid_destroy(isc_mem_t *mctx, dns_qid_t **qidp);
-static isc_result_t open_socket(isc_socketmgr_t *mgr, isc_sockaddr_t *local,
- unsigned int options, isc_socket_t **sockp,
- isc_socket_t *dup_socket);
-static isc_boolean_t portavailable(dns_dispatchmgr_t *mgr, isc_socket_t *sock,
- isc_sockaddr_t *sockaddrp);
-
-#define LVL(x) ISC_LOG_DEBUG(x)
-
-static void
-mgr_log(dns_dispatchmgr_t *mgr, int level, const char *fmt, ...)
- ISC_FORMAT_PRINTF(3, 4);
-
-static void
-mgr_log(dns_dispatchmgr_t *mgr, int level, const char *fmt, ...) {
- char msgbuf[2048];
- va_list ap;
-
- if (! isc_log_wouldlog(dns_lctx, level))
- return;
-
- va_start(ap, fmt);
- vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
- va_end(ap);
-
- isc_log_write(dns_lctx,
- DNS_LOGCATEGORY_DISPATCH, DNS_LOGMODULE_DISPATCH,
- level, "dispatchmgr %p: %s", mgr, msgbuf);
-}
-
-static inline void
-inc_stats(dns_dispatchmgr_t *mgr, isc_statscounter_t counter) {
- if (mgr->stats != NULL)
- isc_stats_increment(mgr->stats, counter);
-}
-
-static void
-dispatch_log(dns_dispatch_t *disp, int level, const char *fmt, ...)
- ISC_FORMAT_PRINTF(3, 4);
-
-static void
-dispatch_log(dns_dispatch_t *disp, int level, const char *fmt, ...) {
- char msgbuf[2048];
- va_list ap;
-
- if (! isc_log_wouldlog(dns_lctx, level))
- return;
-
- va_start(ap, fmt);
- vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
- va_end(ap);
-
- isc_log_write(dns_lctx,
- DNS_LOGCATEGORY_DISPATCH, DNS_LOGMODULE_DISPATCH,
- level, "dispatch %p: %s", disp, msgbuf);
-}
-
-static void
-request_log(dns_dispatch_t *disp, dns_dispentry_t *resp,
- int level, const char *fmt, ...)
- ISC_FORMAT_PRINTF(4, 5);
-
-static void
-request_log(dns_dispatch_t *disp, dns_dispentry_t *resp,
- int level, const char *fmt, ...)
-{
- char msgbuf[2048];
- char peerbuf[256];
- va_list ap;
-
- if (! isc_log_wouldlog(dns_lctx, level))
- return;
-
- va_start(ap, fmt);
- vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
- va_end(ap);
-
- if (VALID_RESPONSE(resp)) {
- isc_sockaddr_format(&resp->host, peerbuf, sizeof(peerbuf));
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DISPATCH,
- DNS_LOGMODULE_DISPATCH, level,
- "dispatch %p response %p %s: %s", disp, resp,
- peerbuf, msgbuf);
- } else {
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DISPATCH,
- DNS_LOGMODULE_DISPATCH, level,
- "dispatch %p req/resp %p: %s", disp, resp,
- msgbuf);
- }
-}
-
-/*%
- * ARC4 random number generator derived from OpenBSD.
- * Only dispatch_random() and dispatch_uniformrandom() are expected
- * to be called from general dispatch routines; the rest of them are subroutines
- * for these two.
- *
- * The original copyright follows:
- * Copyright (c) 1996, David Mazieres <dm@uun.org>
- * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * 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_initrandom(arc4ctx_t *actx, isc_entropy_t *entropy,
- isc_mutex_t *lock)
-{
- int n;
- for (n = 0; n < 256; n++)
- actx->s[n] = n;
- actx->i = 0;
- actx->j = 0;
- actx->count = 0;
- actx->entropy = entropy; /* don't have to attach */
- actx->lock = lock;
-}
-
-static void
-dispatch_arc4addrandom(arc4ctx_t *actx, unsigned char *dat, int datlen) {
- int n;
- isc_uint8_t si;
-
- actx->i--;
- for (n = 0; n < 256; n++) {
- actx->i = (actx->i + 1);
- si = actx->s[actx->i];
- actx->j = (actx->j + si + dat[n % datlen]);
- actx->s[actx->i] = actx->s[actx->j];
- actx->s[actx->j] = si;
- }
- actx->j = actx->i;
-}
-
-static inline isc_uint8_t
-dispatch_arc4get8(arc4ctx_t *actx) {
- isc_uint8_t si, sj;
-
- actx->i = (actx->i + 1);
- si = actx->s[actx->i];
- actx->j = (actx->j + si);
- sj = actx->s[actx->j];
- actx->s[actx->i] = sj;
- actx->s[actx->j] = si;
-
- return (actx->s[(si + sj) & 0xff]);
-}
-
-static inline isc_uint16_t
-dispatch_arc4get16(arc4ctx_t *actx) {
- isc_uint16_t val;
-
- val = dispatch_arc4get8(actx) << 8;
- val |= dispatch_arc4get8(actx);
-
- return (val);
-}
-
-static void
-dispatch_arc4stir(arc4ctx_t *actx) {
- int i;
- union {
- unsigned char rnd[128];
- isc_uint32_t rnd32[32];
- } rnd;
- isc_result_t result;
-
- if (actx->entropy != NULL) {
- /*
- * We accept any quality of random data to avoid blocking.
- */
- result = isc_entropy_getdata(actx->entropy, rnd.rnd,
- sizeof(rnd), NULL, 0);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- } else {
- for (i = 0; i < 32; i++)
- isc_random_get(&rnd.rnd32[i]);
- }
- dispatch_arc4addrandom(actx, rnd.rnd, sizeof(rnd.rnd));
-
- /*
- * Discard early keystream, as per recommendations in:
- * http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps
- */
- for (i = 0; i < 256; i++)
- (void)dispatch_arc4get8(actx);
-
- /*
- * Derived from OpenBSD's implementation. The rationale is not clear,
- * but should be conservative enough in safety, and reasonably large
- * for efficiency.
- */
- actx->count = 1600000;
-}
-
-static isc_uint16_t
-dispatch_random(arc4ctx_t *actx) {
- isc_uint16_t result;
-
- if (actx->lock != NULL)
- LOCK(actx->lock);
-
- actx->count -= sizeof(isc_uint16_t);
- if (actx->count <= 0)
- dispatch_arc4stir(actx);
- result = dispatch_arc4get16(actx);
-
- if (actx->lock != NULL)
- UNLOCK(actx->lock);
-
- 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_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)
- return (0);
-
- /*
- * Ensure the range of random numbers [min, 0xffff] be a multiple of
- * upper_bound and contain at least a half of the 16 bit range.
- */
-
- if (upper_bound > 0x8000)
- min = 1 + ~upper_bound; /* 0x8000 - upper_bound */
- else
- min = (isc_uint16_t)(0x10000 % (isc_uint32_t)upper_bound);
-
- /*
- * This could theoretically loop forever but each retry has
- * p > 0.5 (worst case, usually far better) of selecting a
- * number inside the range we need, so it should rarely need
- * to re-roll.
- */
- for (;;) {
- r = dispatch_random(actx);
- if (r >= min)
- break;
- }
-
- return (r % upper_bound);
-}
-
-/*
- * Return a hash of the destination and message id.
- */
-static isc_uint32_t
-dns_hash(dns_qid_t *qid, isc_sockaddr_t *dest, dns_messageid_t id,
- in_port_t port)
-{
- unsigned int ret;
-
- ret = isc_sockaddr_hash(dest, ISC_TRUE);
- ret ^= (id << 16) | port;
- ret %= qid->qid_nbuckets;
-
- INSIST(ret < qid->qid_nbuckets);
-
- return (ret);
-}
-
-/*
- * Find the first entry in 'qid'. Returns NULL if there are no entries.
- */
-static dns_dispentry_t *
-linear_first(dns_qid_t *qid) {
- dns_dispentry_t *ret;
- unsigned int bucket;
-
- bucket = 0;
-
- while (bucket < qid->qid_nbuckets) {
- ret = ISC_LIST_HEAD(qid->qid_table[bucket]);
- if (ret != NULL)
- return (ret);
- bucket++;
- }
-
- return (NULL);
-}
-
-/*
- * Find the next entry after 'resp' in 'qid'. Return NULL if there are
- * no more entries.
- */
-static dns_dispentry_t *
-linear_next(dns_qid_t *qid, dns_dispentry_t *resp) {
- dns_dispentry_t *ret;
- unsigned int bucket;
-
- ret = ISC_LIST_NEXT(resp, link);
- if (ret != NULL)
- return (ret);
-
- bucket = resp->bucket;
- bucket++;
- while (bucket < qid->qid_nbuckets) {
- ret = ISC_LIST_HEAD(qid->qid_table[bucket]);
- if (ret != NULL)
- return (ret);
- bucket++;
- }
-
- return (NULL);
-}
-
-/*
- * The dispatch must be locked.
- */
-static isc_boolean_t
-destroy_disp_ok(dns_dispatch_t *disp)
-{
- if (disp->refcount != 0)
- return (ISC_FALSE);
-
- if (disp->recv_pending != 0)
- return (ISC_FALSE);
-
- if (!ISC_LIST_EMPTY(disp->activesockets))
- return (ISC_FALSE);
-
- if (disp->shutting_down == 0)
- return (ISC_FALSE);
-
- return (ISC_TRUE);
-}
-
-/*
- * Called when refcount reaches 0 (and safe to destroy).
- *
- * The dispatcher must not be locked.
- * The manager must be locked.
- */
-static void
-destroy_disp(isc_task_t *task, isc_event_t *event) {
- dns_dispatch_t *disp;
- dns_dispatchmgr_t *mgr;
- isc_boolean_t killmgr;
- dispsocket_t *dispsocket;
- int i;
-
- INSIST(event->ev_type == DNS_EVENT_DISPATCHCONTROL);
-
- UNUSED(task);
-
- disp = event->ev_arg;
- mgr = disp->mgr;
-
- LOCK(&mgr->lock);
- ISC_LIST_UNLINK(mgr->list, disp, link);
-
- dispatch_log(disp, LVL(90),
- "shutting down; detaching from sock %p, task %p",
- disp->socket, disp->task[0]); /* XXXX */
-
- if (disp->sepool != NULL) {
- isc_mempool_destroy(&disp->sepool);
- (void)isc_mutex_destroy(&disp->sepool_lock);
- }
-
- if (disp->socket != NULL)
- isc_socket_detach(&disp->socket);
- while ((dispsocket = ISC_LIST_HEAD(disp->inactivesockets)) != NULL) {
- ISC_LIST_UNLINK(disp->inactivesockets, dispsocket, link);
- destroy_dispsocket(disp, &dispsocket);
- }
- for (i = 0; i < disp->ntasks; i++)
- isc_task_detach(&disp->task[i]);
- isc_event_free(&event);
-
- dispatch_free(&disp);
-
- killmgr = destroy_mgr_ok(mgr);
- UNLOCK(&mgr->lock);
- if (killmgr)
- destroy_mgr(&mgr);
-}
-
-/*%
- * Manipulate port table per dispatch: find an entry for a given port number,
- * create a new entry, and decrement a given entry with possible clean-up.
- */
-static dispportentry_t *
-port_search(dns_dispatch_t *disp, in_port_t port) {
- dispportentry_t *portentry;
-
- REQUIRE(disp->port_table != NULL);
-
- portentry = ISC_LIST_HEAD(disp->port_table[port %
- DNS_DISPATCH_PORTTABLESIZE]);
- while (portentry != NULL) {
- if (portentry->port == port)
- return (portentry);
- portentry = ISC_LIST_NEXT(portentry, link);
- }
-
- return (NULL);
-}
-
-static dispportentry_t *
-new_portentry(dns_dispatch_t *disp, in_port_t port) {
- dispportentry_t *portentry;
-
- REQUIRE(disp->port_table != NULL);
-
- portentry = isc_mempool_get(disp->portpool);
- if (portentry == NULL)
- return (portentry);
-
- portentry->port = port;
- portentry->refs = 0;
- ISC_LINK_INIT(portentry, link);
- ISC_LIST_APPEND(disp->port_table[port % DNS_DISPATCH_PORTTABLESIZE],
- portentry, link);
-
- return (portentry);
-}
-
-/*%
- * The caller must not hold the qid->lock.
- */
-static void
-deref_portentry(dns_dispatch_t *disp, dispportentry_t **portentryp) {
- dispportentry_t *portentry = *portentryp;
- isc_boolean_t unlink = ISC_FALSE;
- dns_qid_t *qid;
-
- REQUIRE(disp->port_table != NULL);
- REQUIRE(portentry != NULL && portentry->refs > 0);
-
- qid = DNS_QID(disp);
- LOCK(&qid->lock);
- portentry->refs--;
- unlink = ISC_TF(portentry->refs == 0);
- UNLOCK(&qid->lock);
-
- if (unlink) {
- ISC_LIST_UNLINK(disp->port_table[portentry->port %
- DNS_DISPATCH_PORTTABLESIZE],
- portentry, link);
- isc_mempool_put(disp->portpool, portentry);
- }
-
- *portentryp = NULL;
-}
-
-/*%
- * Find a dispsocket for socket address 'dest', and port number 'port'.
- * Return NULL if no such entry exists.
- */
-static dispsocket_t *
-socket_search(dns_qid_t *qid, isc_sockaddr_t *dest, in_port_t port,
- unsigned int bucket)
-{
- dispsocket_t *dispsock;
-
- REQUIRE(bucket < qid->qid_nbuckets);
-
- dispsock = ISC_LIST_HEAD(qid->sock_table[bucket]);
-
- while (dispsock != NULL) {
- if (dispsock->portentry != NULL &&
- dispsock->portentry->port == port &&
- isc_sockaddr_equal(dest, &dispsock->host))
- return (dispsock);
- dispsock = ISC_LIST_NEXT(dispsock, blink);
- }
-
- return (NULL);
-}
-
-/*%
- * Make a new socket for a single dispatch with a random port number.
- * The caller must hold the disp->lock
- */
-static isc_result_t
-get_dispsocket(dns_dispatch_t *disp, isc_sockaddr_t *dest,
- isc_socketmgr_t *sockmgr, dispsocket_t **dispsockp,
- in_port_t *portp)
-{
- int i;
- isc_uint32_t r;
- dns_dispatchmgr_t *mgr = disp->mgr;
- isc_socket_t *sock = NULL;
- isc_result_t result = ISC_R_FAILURE;
- in_port_t port;
- isc_sockaddr_t localaddr;
- unsigned int bucket = 0;
- dispsocket_t *dispsock;
- unsigned int nports;
- in_port_t *ports;
- unsigned int bindoptions;
- dispportentry_t *portentry = NULL;
- dns_qid_t *qid;
-
- if (isc_sockaddr_pf(&disp->local) == AF_INET) {
- nports = disp->mgr->nv4ports;
- ports = disp->mgr->v4ports;
- } else {
- nports = disp->mgr->nv6ports;
- ports = disp->mgr->v6ports;
- }
- if (nports == 0)
- return (ISC_R_ADDRNOTAVAIL);
-
- dispsock = ISC_LIST_HEAD(disp->inactivesockets);
- if (dispsock != NULL) {
- ISC_LIST_UNLINK(disp->inactivesockets, dispsock, link);
- sock = dispsock->socket;
- dispsock->socket = NULL;
- } else {
- dispsock = isc_mempool_get(mgr->spool);
- if (dispsock == NULL)
- return (ISC_R_NOMEMORY);
-
- disp->nsockets++;
- dispsock->socket = NULL;
- dispsock->disp = disp;
- dispsock->resp = NULL;
- dispsock->portentry = NULL;
- isc_random_get(&r);
- dispsock->task = NULL;
- isc_task_attach(disp->task[r % disp->ntasks], &dispsock->task);
- ISC_LINK_INIT(dispsock, link);
- ISC_LINK_INIT(dispsock, blink);
- dispsock->magic = DISPSOCK_MAGIC;
- }
-
- /*
- * Pick up a random UDP port and open a new socket with it. Avoid
- * choosing ports that share the same destination because it will be
- * very likely to fail in bind(2) or connect(2).
- */
- localaddr = disp->local;
- qid = DNS_QID(disp);
-
- for (i = 0; i < 64; i++) {
- port = ports[dispatch_uniformrandom(DISP_ARC4CTX(disp),
- nports)];
- isc_sockaddr_setport(&localaddr, port);
-
- LOCK(&qid->lock);
- bucket = dns_hash(qid, dest, 0, port);
- if (socket_search(qid, dest, port, bucket) != NULL) {
- UNLOCK(&qid->lock);
- continue;
- }
- UNLOCK(&qid->lock);
- bindoptions = 0;
- portentry = port_search(disp, port);
-
- if (portentry != NULL)
- bindoptions |= ISC_SOCKET_REUSEADDRESS;
- result = open_socket(sockmgr, &localaddr, bindoptions, &sock,
- NULL);
- if (result == ISC_R_SUCCESS) {
- if (portentry == NULL) {
- portentry = new_portentry(disp, port);
- if (portentry == NULL) {
- result = ISC_R_NOMEMORY;
- break;
- }
- }
- portentry->refs++;
- break;
- } else if (result == ISC_R_NOPERM) {
- char buf[ISC_SOCKADDR_FORMATSIZE];
- isc_sockaddr_format(&localaddr, buf, sizeof(buf));
- dispatch_log(disp, ISC_LOG_WARNING,
- "open_socket(%s) -> %s: continuing",
- buf, isc_result_totext(result));
- } else if (result != ISC_R_ADDRINUSE)
- break;
- }
-
- if (result == ISC_R_SUCCESS) {
- dispsock->socket = sock;
- dispsock->host = *dest;
- dispsock->portentry = portentry;
- dispsock->bucket = bucket;
- LOCK(&qid->lock);
- ISC_LIST_APPEND(qid->sock_table[bucket], dispsock, blink);
- UNLOCK(&qid->lock);
- *dispsockp = dispsock;
- *portp = port;
- } else {
- /*
- * We could keep it in the inactive list, but since this should
- * be an exceptional case and might be resource shortage, we'd
- * rather destroy it.
- */
- if (sock != NULL)
- isc_socket_detach(&sock);
- destroy_dispsocket(disp, &dispsock);
- }
-
- return (result);
-}
-
-/*%
- * Destroy a dedicated dispatch socket.
- */
-static void
-destroy_dispsocket(dns_dispatch_t *disp, dispsocket_t **dispsockp) {
- dispsocket_t *dispsock;
- dns_qid_t *qid;
-
- /*
- * The dispatch must be locked.
- */
-
- REQUIRE(dispsockp != NULL && *dispsockp != NULL);
- dispsock = *dispsockp;
- REQUIRE(!ISC_LINK_LINKED(dispsock, link));
-
- disp->nsockets--;
- dispsock->magic = 0;
- if (dispsock->portentry != NULL)
- deref_portentry(disp, &dispsock->portentry);
- if (dispsock->socket != NULL)
- isc_socket_detach(&dispsock->socket);
- if (ISC_LINK_LINKED(dispsock, blink)) {
- qid = DNS_QID(disp);
- LOCK(&qid->lock);
- ISC_LIST_UNLINK(qid->sock_table[dispsock->bucket], dispsock,
- blink);
- UNLOCK(&qid->lock);
- }
- if (dispsock->task != NULL)
- isc_task_detach(&dispsock->task);
- isc_mempool_put(disp->mgr->spool, dispsock);
-
- *dispsockp = NULL;
-}
-
-/*%
- * Deactivate a dedicated dispatch socket. Move it to the inactive list for
- * future reuse unless the total number of sockets are exceeding the maximum.
- */
-static void
-deactivate_dispsocket(dns_dispatch_t *disp, dispsocket_t *dispsock) {
- isc_result_t result;
- dns_qid_t *qid;
-
- /*
- * The dispatch must be locked.
- */
- ISC_LIST_UNLINK(disp->activesockets, dispsock, link);
- if (dispsock->resp != NULL) {
- INSIST(dispsock->resp->dispsocket == dispsock);
- dispsock->resp->dispsocket = NULL;
- }
-
- INSIST(dispsock->portentry != NULL);
- deref_portentry(disp, &dispsock->portentry);
-
-#ifdef BIND9
- if (disp->nsockets > DNS_DISPATCH_POOLSOCKS)
- destroy_dispsocket(disp, &dispsock);
- else {
- result = isc_socket_close(dispsock->socket);
-
- qid = DNS_QID(disp);
- LOCK(&qid->lock);
- ISC_LIST_UNLINK(qid->sock_table[dispsock->bucket], dispsock,
- blink);
- UNLOCK(&qid->lock);
-
- if (result == ISC_R_SUCCESS)
- ISC_LIST_APPEND(disp->inactivesockets, dispsock, link);
- else {
- /*
- * If the underlying system does not allow this
- * optimization, destroy this temporary structure (and
- * create a new one for a new transaction).
- */
- INSIST(result == ISC_R_NOTIMPLEMENTED);
- destroy_dispsocket(disp, &dispsock);
- }
- }
-#else
- /* This kind of optimization isn't necessary for normal use */
- UNUSED(qid);
- UNUSED(result);
-
- destroy_dispsocket(disp, &dispsock);
-#endif
-}
-
-/*
- * Find an entry for query ID 'id', socket address 'dest', and port number
- * 'port'.
- * Return NULL if no such entry exists.
- */
-static dns_dispentry_t *
-entry_search(dns_qid_t *qid, isc_sockaddr_t *dest, dns_messageid_t id,
- in_port_t port, unsigned int bucket)
-{
- dns_dispentry_t *res;
-
- REQUIRE(bucket < qid->qid_nbuckets);
-
- res = ISC_LIST_HEAD(qid->qid_table[bucket]);
-
- while (res != NULL) {
- if (res->id == id && isc_sockaddr_equal(dest, &res->host) &&
- res->port == port) {
- return (res);
- }
- res = ISC_LIST_NEXT(res, link);
- }
-
- return (NULL);
-}
-
-static void
-free_buffer(dns_dispatch_t *disp, void *buf, unsigned int len) {
- isc_mempool_t *bpool;
- INSIST(buf != NULL && len != 0);
-
-
- switch (disp->socktype) {
- case isc_sockettype_tcp:
- INSIST(disp->tcpbuffers > 0);
- disp->tcpbuffers--;
- isc_mem_put(disp->mgr->mctx, buf, len);
- break;
- case isc_sockettype_udp:
- LOCK(&disp->mgr->buffer_lock);
- INSIST(disp->mgr->buffers > 0);
- INSIST(len == disp->mgr->buffersize);
- disp->mgr->buffers--;
- bpool = disp->mgr->bpool;
- UNLOCK(&disp->mgr->buffer_lock);
- isc_mempool_put(bpool, buf);
- break;
- default:
- INSIST(0);
- break;
- }
-}
-
-static void *
-allocate_udp_buffer(dns_dispatch_t *disp) {
- isc_mempool_t *bpool;
- void *temp;
-
- LOCK(&disp->mgr->buffer_lock);
- bpool = disp->mgr->bpool;
- disp->mgr->buffers++;
- UNLOCK(&disp->mgr->buffer_lock);
-
- temp = isc_mempool_get(bpool);
-
- if (temp == NULL) {
- LOCK(&disp->mgr->buffer_lock);
- disp->mgr->buffers--;
- UNLOCK(&disp->mgr->buffer_lock);
- }
-
- return (temp);
-}
-
-static inline void
-free_sevent(isc_event_t *ev) {
- isc_mempool_t *pool = ev->ev_destroy_arg;
- isc_socketevent_t *sev = (isc_socketevent_t *) ev;
- isc_mempool_put(pool, sev);
-}
-
-static inline isc_socketevent_t *
-allocate_sevent(dns_dispatch_t *disp, isc_socket_t *socket,
- isc_eventtype_t type, isc_taskaction_t action, const void *arg)
-{
- isc_socketevent_t *ev;
- void *deconst_arg;
-
- ev = isc_mempool_get(disp->sepool);
- if (ev == NULL)
- return (NULL);
- DE_CONST(arg, deconst_arg);
- ISC_EVENT_INIT(ev, sizeof(*ev), 0, NULL, type,
- action, deconst_arg, socket,
- free_sevent, disp->sepool);
- ev->result = ISC_R_UNSET;
- ISC_LINK_INIT(ev, ev_link);
- ISC_LIST_INIT(ev->bufferlist);
- ev->region.base = NULL;
- ev->n = 0;
- ev->offset = 0;
- ev->attributes = 0;
-
- return (ev);
-}
-
-
-static inline void
-free_devent(dns_dispatch_t *disp, dns_dispatchevent_t *ev) {
- if (disp->failsafe_ev == ev) {
- INSIST(disp->shutdown_out == 1);
- disp->shutdown_out = 0;
-
- return;
- }
-
- isc_mempool_put(disp->mgr->depool, ev);
-}
-
-static inline dns_dispatchevent_t *
-allocate_devent(dns_dispatch_t *disp) {
- dns_dispatchevent_t *ev;
-
- ev = isc_mempool_get(disp->mgr->depool);
- if (ev == NULL)
- return (NULL);
- ISC_EVENT_INIT(ev, sizeof(*ev), 0, NULL, 0,
- NULL, NULL, NULL, NULL, NULL);
-
- return (ev);
-}
-
-static void
-udp_exrecv(isc_task_t *task, isc_event_t *ev) {
- dispsocket_t *dispsock = ev->ev_arg;
-
- UNUSED(task);
-
- REQUIRE(VALID_DISPSOCK(dispsock));
- udp_recv(ev, dispsock->disp, dispsock);
-}
-
-static void
-udp_shrecv(isc_task_t *task, isc_event_t *ev) {
- dns_dispatch_t *disp = ev->ev_arg;
-
- UNUSED(task);
-
- REQUIRE(VALID_DISPATCH(disp));
- udp_recv(ev, disp, NULL);
-}
-
-/*
- * General flow:
- *
- * If I/O result == CANCELED or error, free the buffer.
- *
- * If query, free the buffer, restart.
- *
- * If response:
- * Allocate event, fill in details.
- * If cannot allocate, free buffer, restart.
- * find target. If not found, free buffer, restart.
- * if event queue is not empty, queue. else, send.
- * restart.
- */
-static void
-udp_recv(isc_event_t *ev_in, dns_dispatch_t *disp, dispsocket_t *dispsock) {
- isc_socketevent_t *ev = (isc_socketevent_t *)ev_in;
- dns_messageid_t id;
- isc_result_t dres;
- isc_buffer_t source;
- unsigned int flags;
- dns_dispentry_t *resp = NULL;
- dns_dispatchevent_t *rev;
- unsigned int bucket;
- isc_boolean_t killit;
- isc_boolean_t queue_response;
- dns_dispatchmgr_t *mgr;
- dns_qid_t *qid;
- isc_netaddr_t netaddr;
- int match;
- int result;
- isc_boolean_t qidlocked = ISC_FALSE;
-
- LOCK(&disp->lock);
-
- mgr = disp->mgr;
- qid = mgr->qid;
-
- dispatch_log(disp, LVL(90),
- "got packet: requests %d, buffers %d, recvs %d",
- disp->requests, disp->mgr->buffers, disp->recv_pending);
-
- if (dispsock == NULL && ev->ev_type == ISC_SOCKEVENT_RECVDONE) {
- /*
- * Unless the receive event was imported from a listening
- * interface, in which case the event type is
- * DNS_EVENT_IMPORTRECVDONE, receive operation must be pending.
- */
- INSIST(disp->recv_pending != 0);
- disp->recv_pending = 0;
- }
-
- if (dispsock != NULL &&
- (ev->result == ISC_R_CANCELED || dispsock->resp == NULL)) {
- /*
- * dispsock->resp can be NULL if this transaction was canceled
- * just after receiving a response. Since this socket is
- * exclusively used and there should be at most one receive
- * event the canceled event should have been no effect. So
- * we can (and should) deactivate the socket right now.
- */
- deactivate_dispsocket(disp, dispsock);
- dispsock = NULL;
- }
-
- if (disp->shutting_down) {
- /*
- * This dispatcher is shutting down.
- */
- free_buffer(disp, ev->region.base, ev->region.length);
-
- isc_event_free(&ev_in);
- ev = NULL;
-
- killit = destroy_disp_ok(disp);
- UNLOCK(&disp->lock);
- if (killit)
- isc_task_send(disp->task[0], &disp->ctlevent);
-
- return;
- }
-
- if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0) {
- if (dispsock != NULL) {
- resp = dispsock->resp;
- id = resp->id;
- if (ev->result != ISC_R_SUCCESS) {
- /*
- * This is most likely a network error on a
- * connected socket. It makes no sense to
- * check the address or parse the packet, but it
- * will help to return the error to the caller.
- */
- goto sendresponse;
- }
- } else {
- free_buffer(disp, ev->region.base, ev->region.length);
-
- UNLOCK(&disp->lock);
- isc_event_free(&ev_in);
- return;
- }
- } else if (ev->result != ISC_R_SUCCESS) {
- free_buffer(disp, ev->region.base, ev->region.length);
-
- if (ev->result != ISC_R_CANCELED)
- dispatch_log(disp, ISC_LOG_ERROR,
- "odd socket result in udp_recv(): %s",
- isc_result_totext(ev->result));
-
- UNLOCK(&disp->lock);
- isc_event_free(&ev_in);
- return;
- }
-
- /*
- * If this is from a blackholed address, drop it.
- */
- isc_netaddr_fromsockaddr(&netaddr, &ev->address);
- if (disp->mgr->blackhole != NULL &&
- dns_acl_match(&netaddr, NULL, disp->mgr->blackhole,
- NULL, &match, NULL) == ISC_R_SUCCESS &&
- match > 0)
- {
- if (isc_log_wouldlog(dns_lctx, LVL(10))) {
- char netaddrstr[ISC_NETADDR_FORMATSIZE];
- isc_netaddr_format(&netaddr, netaddrstr,
- sizeof(netaddrstr));
- dispatch_log(disp, LVL(10),
- "blackholed packet from %s",
- netaddrstr);
- }
- free_buffer(disp, ev->region.base, ev->region.length);
- goto restart;
- }
-
- /*
- * Peek into the buffer to see what we can see.
- */
- isc_buffer_init(&source, ev->region.base, ev->region.length);
- isc_buffer_add(&source, ev->n);
- dres = dns_message_peekheader(&source, &id, &flags);
- if (dres != ISC_R_SUCCESS) {
- free_buffer(disp, ev->region.base, ev->region.length);
- dispatch_log(disp, LVL(10), "got garbage packet");
- goto restart;
- }
-
- dispatch_log(disp, LVL(92),
- "got valid DNS message header, /QR %c, id %u",
- ((flags & DNS_MESSAGEFLAG_QR) ? '1' : '0'), id);
-
- /*
- * Look at flags. If query, drop it. If response,
- * look to see where it goes.
- */
- if ((flags & DNS_MESSAGEFLAG_QR) == 0) {
- /* query */
- free_buffer(disp, ev->region.base, ev->region.length);
- goto restart;
- }
-
- /*
- * Search for the corresponding response. If we are using an exclusive
- * socket, we've already identified it and we can skip the search; but
- * the ID and the address must match the expected ones.
- */
- if (resp == NULL) {
- bucket = dns_hash(qid, &ev->address, id, disp->localport);
- LOCK(&qid->lock);
- qidlocked = ISC_TRUE;
- resp = entry_search(qid, &ev->address, id, disp->localport,
- bucket);
- dispatch_log(disp, LVL(90),
- "search for response in bucket %d: %s",
- bucket, (resp == NULL ? "not found" : "found"));
-
- if (resp == NULL) {
- inc_stats(mgr, dns_resstatscounter_mismatch);
- free_buffer(disp, ev->region.base, ev->region.length);
- goto unlock;
- }
- } else if (resp->id != id || !isc_sockaddr_equal(&ev->address,
- &resp->host)) {
- dispatch_log(disp, LVL(90),
- "response to an exclusive socket doesn't match");
- inc_stats(mgr, dns_resstatscounter_mismatch);
- free_buffer(disp, ev->region.base, ev->region.length);
- goto unlock;
- }
-
- /*
- * Now that we have the original dispatch the query was sent
- * from check that the address and port the response was
- * sent to make sense.
- */
- if (disp != resp->disp) {
- isc_sockaddr_t a1;
- isc_sockaddr_t a2;
-
- /*
- * Check that the socket types and ports match.
- */
- if (disp->socktype != resp->disp->socktype ||
- isc_sockaddr_getport(&disp->local) !=
- isc_sockaddr_getport(&resp->disp->local)) {
- free_buffer(disp, ev->region.base, ev->region.length);
- goto unlock;
- }
-
- /*
- * If both dispatches are bound to an address then fail as
- * the addresses can't be equal (enforced by the IP stack).
- *
- * Note under Linux a packet can be sent out via IPv4 socket
- * and the response be received via a IPv6 socket.
- *
- * Requests sent out via IPv6 should always come back in
- * via IPv6.
- */
- if (isc_sockaddr_pf(&resp->disp->local) == PF_INET6 &&
- isc_sockaddr_pf(&disp->local) != PF_INET6) {
- free_buffer(disp, ev->region.base, ev->region.length);
- goto unlock;
- }
- isc_sockaddr_anyofpf(&a1, isc_sockaddr_pf(&resp->disp->local));
- isc_sockaddr_anyofpf(&a2, isc_sockaddr_pf(&disp->local));
- if (!isc_sockaddr_eqaddr(&a1, &resp->disp->local) &&
- !isc_sockaddr_eqaddr(&a2, &disp->local)) {
- free_buffer(disp, ev->region.base, ev->region.length);
- goto unlock;
- }
- }
-
- sendresponse:
- queue_response = resp->item_out;
- rev = allocate_devent(resp->disp);
- if (rev == NULL) {
- free_buffer(disp, ev->region.base, ev->region.length);
- goto unlock;
- }
-
- /*
- * At this point, rev contains the event we want to fill in, and
- * resp contains the information on the place to send it to.
- * Send the event off.
- */
- isc_buffer_init(&rev->buffer, ev->region.base, ev->region.length);
- isc_buffer_add(&rev->buffer, ev->n);
- rev->result = ev->result;
- rev->id = id;
- rev->addr = ev->address;
- rev->pktinfo = ev->pktinfo;
- rev->attributes = ev->attributes;
- if (queue_response) {
- ISC_LIST_APPEND(resp->items, rev, ev_link);
- } else {
- ISC_EVENT_INIT(rev, sizeof(*rev), 0, NULL,
- DNS_EVENT_DISPATCH,
- resp->action, resp->arg, resp, NULL, NULL);
- request_log(disp, resp, LVL(90),
- "[a] Sent event %p buffer %p len %d to task %p",
- rev, rev->buffer.base, rev->buffer.length,
- resp->task);
- resp->item_out = ISC_TRUE;
- isc_task_send(resp->task, ISC_EVENT_PTR(&rev));
- }
- unlock:
- if (qidlocked)
- UNLOCK(&qid->lock);
-
- /*
- * Restart recv() to get the next packet.
- */
- restart:
- result = startrecv(disp, dispsock);
- if (result != ISC_R_SUCCESS && dispsock != NULL) {
- /*
- * XXX: wired. There seems to be no recovery process other than
- * deactivate this socket anyway (since we cannot start
- * receiving, we won't be able to receive a cancel event
- * from the user).
- */
- deactivate_dispsocket(disp, dispsock);
- }
- UNLOCK(&disp->lock);
-
- isc_event_free(&ev_in);
-}
-
-/*
- * General flow:
- *
- * If I/O result == CANCELED, EOF, or error, notify everyone as the
- * various queues drain.
- *
- * If query, restart.
- *
- * If response:
- * Allocate event, fill in details.
- * If cannot allocate, restart.
- * find target. If not found, restart.
- * if event queue is not empty, queue. else, send.
- * restart.
- */
-static void
-tcp_recv(isc_task_t *task, isc_event_t *ev_in) {
- dns_dispatch_t *disp = ev_in->ev_arg;
- dns_tcpmsg_t *tcpmsg = &disp->tcpmsg;
- dns_messageid_t id;
- isc_result_t dres;
- unsigned int flags;
- dns_dispentry_t *resp;
- dns_dispatchevent_t *rev;
- unsigned int bucket;
- isc_boolean_t killit;
- isc_boolean_t queue_response;
- dns_qid_t *qid;
- int level;
- char buf[ISC_SOCKADDR_FORMATSIZE];
-
- UNUSED(task);
-
- REQUIRE(VALID_DISPATCH(disp));
-
- qid = disp->qid;
-
- dispatch_log(disp, LVL(90),
- "got TCP packet: requests %d, buffers %d, recvs %d",
- disp->requests, disp->tcpbuffers, disp->recv_pending);
-
- LOCK(&disp->lock);
-
- INSIST(disp->recv_pending != 0);
- disp->recv_pending = 0;
-
- if (disp->refcount == 0) {
- /*
- * This dispatcher is shutting down. Force cancelation.
- */
- tcpmsg->result = ISC_R_CANCELED;
- }
-
- if (tcpmsg->result != ISC_R_SUCCESS) {
- switch (tcpmsg->result) {
- case ISC_R_CANCELED:
- break;
-
- case ISC_R_EOF:
- dispatch_log(disp, LVL(90), "shutting down on EOF");
- do_cancel(disp);
- break;
-
- case ISC_R_CONNECTIONRESET:
- level = ISC_LOG_INFO;
- goto logit;
-
- default:
- level = ISC_LOG_ERROR;
- logit:
- isc_sockaddr_format(&tcpmsg->address, buf, sizeof(buf));
- dispatch_log(disp, level, "shutting down due to TCP "
- "receive error: %s: %s", buf,
- isc_result_totext(tcpmsg->result));
- do_cancel(disp);
- break;
- }
-
- /*
- * The event is statically allocated in the tcpmsg
- * structure, and destroy_disp() frees the tcpmsg, so we must
- * free the event *before* calling destroy_disp().
- */
- isc_event_free(&ev_in);
-
- disp->shutting_down = 1;
- disp->shutdown_why = tcpmsg->result;
-
- /*
- * If the recv() was canceled pass the word on.
- */
- killit = destroy_disp_ok(disp);
- UNLOCK(&disp->lock);
- if (killit)
- isc_task_send(disp->task[0], &disp->ctlevent);
- return;
- }
-
- dispatch_log(disp, LVL(90), "result %d, length == %d, addr = %p",
- tcpmsg->result,
- tcpmsg->buffer.length, tcpmsg->buffer.base);
-
- /*
- * Peek into the buffer to see what we can see.
- */
- dres = dns_message_peekheader(&tcpmsg->buffer, &id, &flags);
- if (dres != ISC_R_SUCCESS) {
- dispatch_log(disp, LVL(10), "got garbage packet");
- goto restart;
- }
-
- dispatch_log(disp, LVL(92),
- "got valid DNS message header, /QR %c, id %u",
- ((flags & DNS_MESSAGEFLAG_QR) ? '1' : '0'), id);
-
- /*
- * Allocate an event to send to the query or response client, and
- * allocate a new buffer for our use.
- */
-
- /*
- * Look at flags. If query, drop it. If response,
- * look to see where it goes.
- */
- if ((flags & DNS_MESSAGEFLAG_QR) == 0) {
- /*
- * Query.
- */
- goto restart;
- }
-
- /*
- * Response.
- */
- bucket = dns_hash(qid, &tcpmsg->address, id, disp->localport);
- LOCK(&qid->lock);
- resp = entry_search(qid, &tcpmsg->address, id, disp->localport, bucket);
- dispatch_log(disp, LVL(90),
- "search for response in bucket %d: %s",
- bucket, (resp == NULL ? "not found" : "found"));
-
- if (resp == NULL)
- goto unlock;
- queue_response = resp->item_out;
- rev = allocate_devent(disp);
- if (rev == NULL)
- goto unlock;
-
- /*
- * At this point, rev contains the event we want to fill in, and
- * resp contains the information on the place to send it to.
- * Send the event off.
- */
- dns_tcpmsg_keepbuffer(tcpmsg, &rev->buffer);
- disp->tcpbuffers++;
- rev->result = ISC_R_SUCCESS;
- rev->id = id;
- rev->addr = tcpmsg->address;
- if (queue_response) {
- ISC_LIST_APPEND(resp->items, rev, ev_link);
- } else {
- ISC_EVENT_INIT(rev, sizeof(*rev), 0, NULL, DNS_EVENT_DISPATCH,
- resp->action, resp->arg, resp, NULL, NULL);
- request_log(disp, resp, LVL(90),
- "[b] Sent event %p buffer %p len %d to task %p",
- rev, rev->buffer.base, rev->buffer.length,
- resp->task);
- resp->item_out = ISC_TRUE;
- isc_task_send(resp->task, ISC_EVENT_PTR(&rev));
- }
- unlock:
- UNLOCK(&qid->lock);
-
- /*
- * Restart recv() to get the next packet.
- */
- restart:
- (void)startrecv(disp, NULL);
-
- UNLOCK(&disp->lock);
-
- isc_event_free(&ev_in);
-}
-
-/*
- * disp must be locked.
- */
-static isc_result_t
-startrecv(dns_dispatch_t *disp, dispsocket_t *dispsock) {
- isc_result_t res;
- isc_region_t region;
- isc_socket_t *socket;
-
- if (disp->shutting_down == 1)
- return (ISC_R_SUCCESS);
-
- if ((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) != 0)
- return (ISC_R_SUCCESS);
-
- if (disp->recv_pending != 0 && dispsock == NULL)
- return (ISC_R_SUCCESS);
-
- if (disp->mgr->buffers >= disp->mgr->maxbuffers)
- return (ISC_R_NOMEMORY);
-
- if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0 &&
- dispsock == NULL)
- return (ISC_R_SUCCESS);
-
- if (dispsock != NULL)
- socket = dispsock->socket;
- else
- socket = disp->socket;
- INSIST(socket != NULL);
-
- switch (disp->socktype) {
- /*
- * UDP reads are always maximal.
- */
- case isc_sockettype_udp:
- region.length = disp->mgr->buffersize;
- region.base = allocate_udp_buffer(disp);
- if (region.base == NULL)
- return (ISC_R_NOMEMORY);
- if (dispsock != NULL) {
- isc_task_t *dt = dispsock->task;
- isc_socketevent_t *sev =
- allocate_sevent(disp, socket,
- ISC_SOCKEVENT_RECVDONE,
- udp_exrecv, dispsock);
- if (sev == NULL) {
- free_buffer(disp, region.base, region.length);
- return (ISC_R_NOMEMORY);
- }
-
- res = isc_socket_recv2(socket, &region, 1, dt, sev, 0);
- if (res != ISC_R_SUCCESS) {
- free_buffer(disp, region.base, region.length);
- return (res);
- }
- } else {
- isc_task_t *dt = disp->task[0];
- isc_socketevent_t *sev =
- allocate_sevent(disp, socket,
- ISC_SOCKEVENT_RECVDONE,
- udp_shrecv, disp);
- if (sev == NULL) {
- free_buffer(disp, region.base, region.length);
- return (ISC_R_NOMEMORY);
- }
-
- res = isc_socket_recv2(socket, &region, 1, dt, sev, 0);
- if (res != ISC_R_SUCCESS) {
- free_buffer(disp, region.base, region.length);
- disp->shutdown_why = res;
- disp->shutting_down = 1;
- do_cancel(disp);
- return (ISC_R_SUCCESS); /* recover by cancel */
- }
- INSIST(disp->recv_pending == 0);
- disp->recv_pending = 1;
- }
- break;
-
- case isc_sockettype_tcp:
- res = dns_tcpmsg_readmessage(&disp->tcpmsg, disp->task[0],
- tcp_recv, disp);
- if (res != ISC_R_SUCCESS) {
- disp->shutdown_why = res;
- disp->shutting_down = 1;
- do_cancel(disp);
- return (ISC_R_SUCCESS); /* recover by cancel */
- }
- INSIST(disp->recv_pending == 0);
- disp->recv_pending = 1;
- break;
- default:
- INSIST(0);
- break;
- }
-
- return (ISC_R_SUCCESS);
-}
-
-/*
- * Mgr must be locked when calling this function.
- */
-static isc_boolean_t
-destroy_mgr_ok(dns_dispatchmgr_t *mgr) {
- mgr_log(mgr, LVL(90),
- "destroy_mgr_ok: shuttingdown=%d, listnonempty=%d, "
- "depool=%d, rpool=%d, dpool=%d",
- MGR_IS_SHUTTINGDOWN(mgr), !ISC_LIST_EMPTY(mgr->list),
- isc_mempool_getallocated(mgr->depool),
- isc_mempool_getallocated(mgr->rpool),
- isc_mempool_getallocated(mgr->dpool));
- if (!MGR_IS_SHUTTINGDOWN(mgr))
- return (ISC_FALSE);
- if (!ISC_LIST_EMPTY(mgr->list))
- return (ISC_FALSE);
- if (isc_mempool_getallocated(mgr->depool) != 0)
- return (ISC_FALSE);
- if (isc_mempool_getallocated(mgr->rpool) != 0)
- return (ISC_FALSE);
- if (isc_mempool_getallocated(mgr->dpool) != 0)
- return (ISC_FALSE);
-
- return (ISC_TRUE);
-}
-
-/*
- * Mgr must be unlocked when calling this function.
- */
-static void
-destroy_mgr(dns_dispatchmgr_t **mgrp) {
- isc_mem_t *mctx;
- dns_dispatchmgr_t *mgr;
-
- mgr = *mgrp;
- *mgrp = NULL;
-
- mctx = mgr->mctx;
-
- mgr->magic = 0;
- mgr->mctx = NULL;
- DESTROYLOCK(&mgr->lock);
- mgr->state = 0;
-
- DESTROYLOCK(&mgr->arc4_lock);
-
- isc_mempool_destroy(&mgr->depool);
- isc_mempool_destroy(&mgr->rpool);
- isc_mempool_destroy(&mgr->dpool);
- if (mgr->bpool != NULL)
- isc_mempool_destroy(&mgr->bpool);
- if (mgr->spool != NULL)
- isc_mempool_destroy(&mgr->spool);
-
- DESTROYLOCK(&mgr->spool_lock);
- DESTROYLOCK(&mgr->bpool_lock);
- DESTROYLOCK(&mgr->dpool_lock);
- DESTROYLOCK(&mgr->rpool_lock);
- DESTROYLOCK(&mgr->depool_lock);
-
-#ifdef BIND9
- if (mgr->entropy != NULL)
- isc_entropy_detach(&mgr->entropy);
-#endif /* BIND9 */
- if (mgr->qid != NULL)
- qid_destroy(mctx, &mgr->qid);
-
- DESTROYLOCK(&mgr->buffer_lock);
-
- if (mgr->blackhole != NULL)
- dns_acl_detach(&mgr->blackhole);
-
- if (mgr->stats != NULL)
- isc_stats_detach(&mgr->stats);
-
- if (mgr->v4ports != NULL) {
- isc_mem_put(mctx, mgr->v4ports,
- mgr->nv4ports * sizeof(in_port_t));
- }
- if (mgr->v6ports != NULL) {
- isc_mem_put(mctx, mgr->v6ports,
- mgr->nv6ports * sizeof(in_port_t));
- }
- isc_mem_put(mctx, mgr, sizeof(dns_dispatchmgr_t));
- isc_mem_detach(&mctx);
-}
-
-static isc_result_t
-open_socket(isc_socketmgr_t *mgr, isc_sockaddr_t *local,
- unsigned int options, isc_socket_t **sockp,
- isc_socket_t *dup_socket)
-{
- isc_socket_t *sock;
- isc_result_t result;
-
- sock = *sockp;
- if (sock != NULL) {
-#ifdef BIND9
- result = isc_socket_open(sock);
- if (result != ISC_R_SUCCESS)
- return (result);
-#else
- INSIST(0);
-#endif
- } else if (dup_socket != NULL) {
- result = isc_socket_dup(dup_socket, &sock);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- isc_socket_setname(sock, "dispatcher", NULL);
- *sockp = sock;
- return (ISC_R_SUCCESS);
- } else {
- result = isc_socket_create(mgr, isc_sockaddr_pf(local),
- isc_sockettype_udp, &sock);
- if (result != ISC_R_SUCCESS)
- return (result);
- }
-
- isc_socket_setname(sock, "dispatcher", NULL);
-
-#ifndef ISC_ALLOW_MAPPED
- isc_socket_ipv6only(sock, ISC_TRUE);
-#endif
- result = isc_socket_bind(sock, local, options);
- if (result != ISC_R_SUCCESS) {
- if (*sockp == NULL)
- isc_socket_detach(&sock);
- else {
-#ifdef BIND9
- isc_socket_close(sock);
-#else
- INSIST(0);
-#endif
- }
- return (result);
- }
-
- *sockp = sock;
- return (ISC_R_SUCCESS);
-}
-
-/*%
- * Create a temporary port list to set the initial default set of dispatch
- * ports: [1024, 65535]. This is almost meaningless as the application will
- * normally set the ports explicitly, but is provided to fill some minor corner
- * cases.
- */
-static isc_result_t
-create_default_portset(isc_mem_t *mctx, isc_portset_t **portsetp) {
- isc_result_t result;
-
- result = isc_portset_create(mctx, portsetp);
- if (result != ISC_R_SUCCESS)
- return (result);
- isc_portset_addrange(*portsetp, 1024, 65535);
-
- return (ISC_R_SUCCESS);
-}
-
-/*
- * Publics.
- */
-
-isc_result_t
-dns_dispatchmgr_create(isc_mem_t *mctx, isc_entropy_t *entropy,
- dns_dispatchmgr_t **mgrp)
-{
- dns_dispatchmgr_t *mgr;
- isc_result_t result;
- isc_portset_t *v4portset = NULL;
- isc_portset_t *v6portset = NULL;
-
- REQUIRE(mctx != NULL);
- REQUIRE(mgrp != NULL && *mgrp == NULL);
-
- mgr = isc_mem_get(mctx, sizeof(dns_dispatchmgr_t));
- if (mgr == NULL)
- return (ISC_R_NOMEMORY);
-
- mgr->mctx = NULL;
- isc_mem_attach(mctx, &mgr->mctx);
-
- mgr->blackhole = NULL;
- mgr->stats = NULL;
-
- result = isc_mutex_init(&mgr->lock);
- if (result != ISC_R_SUCCESS)
- goto deallocate;
-
- result = isc_mutex_init(&mgr->arc4_lock);
- if (result != ISC_R_SUCCESS)
- goto kill_lock;
-
- result = isc_mutex_init(&mgr->buffer_lock);
- if (result != ISC_R_SUCCESS)
- goto kill_arc4_lock;
-
- result = isc_mutex_init(&mgr->depool_lock);
- if (result != ISC_R_SUCCESS)
- goto kill_buffer_lock;
-
- result = isc_mutex_init(&mgr->rpool_lock);
- if (result != ISC_R_SUCCESS)
- goto kill_depool_lock;
-
- result = isc_mutex_init(&mgr->dpool_lock);
- if (result != ISC_R_SUCCESS)
- goto kill_rpool_lock;
-
- result = isc_mutex_init(&mgr->bpool_lock);
- if (result != ISC_R_SUCCESS)
- goto kill_dpool_lock;
-
- result = isc_mutex_init(&mgr->spool_lock);
- if (result != ISC_R_SUCCESS)
- goto kill_bpool_lock;
-
- mgr->depool = NULL;
- if (isc_mempool_create(mgr->mctx, sizeof(dns_dispatchevent_t),
- &mgr->depool) != ISC_R_SUCCESS) {
- result = ISC_R_NOMEMORY;
- goto kill_spool_lock;
- }
-
- mgr->rpool = NULL;
- if (isc_mempool_create(mgr->mctx, sizeof(dns_dispentry_t),
- &mgr->rpool) != ISC_R_SUCCESS) {
- result = ISC_R_NOMEMORY;
- goto kill_depool;
- }
-
- mgr->dpool = NULL;
- if (isc_mempool_create(mgr->mctx, sizeof(dns_dispatch_t),
- &mgr->dpool) != ISC_R_SUCCESS) {
- result = ISC_R_NOMEMORY;
- goto kill_rpool;
- }
-
- isc_mempool_setname(mgr->depool, "dispmgr_depool");
- isc_mempool_setmaxalloc(mgr->depool, 32768);
- isc_mempool_setfreemax(mgr->depool, 32768);
- isc_mempool_associatelock(mgr->depool, &mgr->depool_lock);
- isc_mempool_setfillcount(mgr->depool, 256);
-
- isc_mempool_setname(mgr->rpool, "dispmgr_rpool");
- isc_mempool_setmaxalloc(mgr->rpool, 32768);
- isc_mempool_setfreemax(mgr->rpool, 32768);
- isc_mempool_associatelock(mgr->rpool, &mgr->rpool_lock);
- isc_mempool_setfillcount(mgr->rpool, 256);
-
- isc_mempool_setname(mgr->dpool, "dispmgr_dpool");
- isc_mempool_setmaxalloc(mgr->dpool, 32768);
- isc_mempool_setfreemax(mgr->dpool, 32768);
- isc_mempool_associatelock(mgr->dpool, &mgr->dpool_lock);
- isc_mempool_setfillcount(mgr->dpool, 256);
-
- mgr->buffers = 0;
- mgr->buffersize = 0;
- mgr->maxbuffers = 0;
- mgr->bpool = NULL;
- mgr->spool = NULL;
- mgr->entropy = NULL;
- mgr->qid = NULL;
- mgr->state = 0;
- ISC_LIST_INIT(mgr->list);
- mgr->v4ports = NULL;
- mgr->v6ports = NULL;
- mgr->nv4ports = 0;
- mgr->nv6ports = 0;
- mgr->magic = DNS_DISPATCHMGR_MAGIC;
-
- result = create_default_portset(mctx, &v4portset);
- if (result == ISC_R_SUCCESS) {
- result = create_default_portset(mctx, &v6portset);
- if (result == ISC_R_SUCCESS) {
- result = dns_dispatchmgr_setavailports(mgr,
- v4portset,
- v6portset);
- }
- }
- if (v4portset != NULL)
- isc_portset_destroy(mctx, &v4portset);
- if (v6portset != NULL)
- isc_portset_destroy(mctx, &v6portset);
- if (result != ISC_R_SUCCESS)
- goto kill_dpool;
-
-#ifdef BIND9
- if (entropy != NULL)
- isc_entropy_attach(entropy, &mgr->entropy);
-#else
- UNUSED(entropy);
-#endif
-
- dispatch_initrandom(&mgr->arc4ctx, mgr->entropy, &mgr->arc4_lock);
-
- *mgrp = mgr;
- return (ISC_R_SUCCESS);
-
- kill_dpool:
- isc_mempool_destroy(&mgr->dpool);
- kill_rpool:
- isc_mempool_destroy(&mgr->rpool);
- kill_depool:
- isc_mempool_destroy(&mgr->depool);
- kill_spool_lock:
- DESTROYLOCK(&mgr->spool_lock);
- kill_bpool_lock:
- DESTROYLOCK(&mgr->bpool_lock);
- kill_dpool_lock:
- DESTROYLOCK(&mgr->dpool_lock);
- kill_rpool_lock:
- DESTROYLOCK(&mgr->rpool_lock);
- kill_depool_lock:
- DESTROYLOCK(&mgr->depool_lock);
- kill_buffer_lock:
- DESTROYLOCK(&mgr->buffer_lock);
- kill_arc4_lock:
- DESTROYLOCK(&mgr->arc4_lock);
- kill_lock:
- DESTROYLOCK(&mgr->lock);
- deallocate:
- isc_mem_put(mctx, mgr, sizeof(dns_dispatchmgr_t));
- isc_mem_detach(&mctx);
-
- return (result);
-}
-
-void
-dns_dispatchmgr_setblackhole(dns_dispatchmgr_t *mgr, dns_acl_t *blackhole) {
- REQUIRE(VALID_DISPATCHMGR(mgr));
- if (mgr->blackhole != NULL)
- dns_acl_detach(&mgr->blackhole);
- dns_acl_attach(blackhole, &mgr->blackhole);
-}
-
-dns_acl_t *
-dns_dispatchmgr_getblackhole(dns_dispatchmgr_t *mgr) {
- REQUIRE(VALID_DISPATCHMGR(mgr));
- return (mgr->blackhole);
-}
-
-void
-dns_dispatchmgr_setblackportlist(dns_dispatchmgr_t *mgr,
- dns_portlist_t *portlist)
-{
- REQUIRE(VALID_DISPATCHMGR(mgr));
- UNUSED(portlist);
-
- /* This function is deprecated: use dns_dispatchmgr_setavailports(). */
- return;
-}
-
-dns_portlist_t *
-dns_dispatchmgr_getblackportlist(dns_dispatchmgr_t *mgr) {
- REQUIRE(VALID_DISPATCHMGR(mgr));
- return (NULL); /* this function is deprecated */
-}
-
-isc_result_t
-dns_dispatchmgr_setavailports(dns_dispatchmgr_t *mgr, isc_portset_t *v4portset,
- isc_portset_t *v6portset)
-{
- in_port_t *v4ports, *v6ports, p;
- unsigned int nv4ports, nv6ports, i4, i6;
-
- REQUIRE(VALID_DISPATCHMGR(mgr));
-
- nv4ports = isc_portset_nports(v4portset);
- nv6ports = isc_portset_nports(v6portset);
-
- v4ports = NULL;
- if (nv4ports != 0) {
- v4ports = isc_mem_get(mgr->mctx, sizeof(in_port_t) * nv4ports);
- if (v4ports == NULL)
- return (ISC_R_NOMEMORY);
- }
- v6ports = NULL;
- if (nv6ports != 0) {
- v6ports = isc_mem_get(mgr->mctx, sizeof(in_port_t) * nv6ports);
- if (v6ports == NULL) {
- if (v4ports != NULL) {
- isc_mem_put(mgr->mctx, v4ports,
- sizeof(in_port_t) *
- isc_portset_nports(v4portset));
- }
- return (ISC_R_NOMEMORY);
- }
- }
-
- p = 0;
- i4 = 0;
- i6 = 0;
- do {
- if (isc_portset_isset(v4portset, p)) {
- INSIST(i4 < nv4ports);
- v4ports[i4++] = p;
- }
- if (isc_portset_isset(v6portset, p)) {
- INSIST(i6 < nv6ports);
- v6ports[i6++] = p;
- }
- } while (p++ < 65535);
- INSIST(i4 == nv4ports && i6 == nv6ports);
-
- PORTBUFLOCK(mgr);
- if (mgr->v4ports != NULL) {
- isc_mem_put(mgr->mctx, mgr->v4ports,
- mgr->nv4ports * sizeof(in_port_t));
- }
- mgr->v4ports = v4ports;
- mgr->nv4ports = nv4ports;
-
- if (mgr->v6ports != NULL) {
- isc_mem_put(mgr->mctx, mgr->v6ports,
- mgr->nv6ports * sizeof(in_port_t));
- }
- mgr->v6ports = v6ports;
- mgr->nv6ports = nv6ports;
- PORTBUFUNLOCK(mgr);
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-dns_dispatchmgr_setudp(dns_dispatchmgr_t *mgr,
- unsigned int buffersize, unsigned int maxbuffers,
- unsigned int maxrequests, unsigned int buckets,
- unsigned int increment)
-{
- isc_result_t result;
-
- REQUIRE(VALID_DISPATCHMGR(mgr));
- REQUIRE(buffersize >= 512 && buffersize < (64 * 1024));
- REQUIRE(maxbuffers > 0);
- REQUIRE(buckets < 2097169); /* next prime > 65536 * 32 */
- REQUIRE(increment > buckets);
-
- /*
- * Keep some number of items around. This should be a config
- * option. For now, keep 8, but later keep at least two even
- * if the caller wants less. This allows us to ensure certain
- * things, like an event can be "freed" and the next allocation
- * will always succeed.
- *
- * Note that if limits are placed on anything here, we use one
- * event internally, so the actual limit should be "wanted + 1."
- *
- * XXXMLG
- */
-
- if (maxbuffers < 8)
- maxbuffers = 8;
-
- LOCK(&mgr->buffer_lock);
-
- /* Create or adjust buffer pool */
- if (mgr->bpool != NULL) {
- /*
- * We only increase the maxbuffers to avoid accidental buffer
- * shortage. Ideally we'd separate the manager-wide maximum
- * from per-dispatch limits and respect the latter within the
- * global limit. But at this moment that's deemed to be
- * overkilling and isn't worth additional implementation
- * complexity.
- */
- if (maxbuffers > mgr->maxbuffers) {
- isc_mempool_setmaxalloc(mgr->bpool, maxbuffers);
- isc_mempool_setfreemax(mgr->bpool, maxbuffers);
- mgr->maxbuffers = maxbuffers;
- }
- } else {
- result = isc_mempool_create(mgr->mctx, buffersize, &mgr->bpool);
- if (result != ISC_R_SUCCESS) {
- UNLOCK(&mgr->buffer_lock);
- return (result);
- }
- isc_mempool_setname(mgr->bpool, "dispmgr_bpool");
- isc_mempool_setmaxalloc(mgr->bpool, maxbuffers);
- isc_mempool_setfreemax(mgr->bpool, maxbuffers);
- isc_mempool_associatelock(mgr->bpool, &mgr->bpool_lock);
- isc_mempool_setfillcount(mgr->bpool, 256);
- }
-
- /* Create or adjust socket pool */
- if (mgr->spool != NULL) {
- if (maxrequests < DNS_DISPATCH_POOLSOCKS * 2)
- isc_mempool_setmaxalloc(mgr->spool, DNS_DISPATCH_POOLSOCKS * 2);
- isc_mempool_setfreemax(mgr->spool, DNS_DISPATCH_POOLSOCKS * 2);
- UNLOCK(&mgr->buffer_lock);
- return (ISC_R_SUCCESS);
- }
- result = isc_mempool_create(mgr->mctx, sizeof(dispsocket_t),
- &mgr->spool);
- if (result != ISC_R_SUCCESS) {
- UNLOCK(&mgr->buffer_lock);
- goto cleanup;
- }
- isc_mempool_setname(mgr->spool, "dispmgr_spool");
- isc_mempool_setmaxalloc(mgr->spool, maxrequests);
- isc_mempool_setfreemax(mgr->spool, maxrequests);
- isc_mempool_associatelock(mgr->spool, &mgr->spool_lock);
- isc_mempool_setfillcount(mgr->spool, 256);
-
- result = qid_allocate(mgr, buckets, increment, &mgr->qid, ISC_TRUE);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- mgr->buffersize = buffersize;
- mgr->maxbuffers = maxbuffers;
- UNLOCK(&mgr->buffer_lock);
- return (ISC_R_SUCCESS);
-
- cleanup:
- isc_mempool_destroy(&mgr->bpool);
- if (mgr->spool != NULL)
- isc_mempool_destroy(&mgr->spool);
- UNLOCK(&mgr->buffer_lock);
- return (result);
-}
-
-void
-dns_dispatchmgr_destroy(dns_dispatchmgr_t **mgrp) {
- dns_dispatchmgr_t *mgr;
- isc_boolean_t killit;
-
- REQUIRE(mgrp != NULL);
- REQUIRE(VALID_DISPATCHMGR(*mgrp));
-
- mgr = *mgrp;
- *mgrp = NULL;
-
- LOCK(&mgr->lock);
- mgr->state |= MGR_SHUTTINGDOWN;
-
- killit = destroy_mgr_ok(mgr);
- UNLOCK(&mgr->lock);
-
- mgr_log(mgr, LVL(90), "destroy: killit=%d", killit);
-
- if (killit)
- destroy_mgr(&mgr);
-}
-
-void
-dns_dispatchmgr_setstats(dns_dispatchmgr_t *mgr, isc_stats_t *stats) {
- REQUIRE(VALID_DISPATCHMGR(mgr));
- REQUIRE(ISC_LIST_EMPTY(mgr->list));
- REQUIRE(mgr->stats == NULL);
-
- isc_stats_attach(stats, &mgr->stats);
-}
-
-static int
-port_cmp(const void *key, const void *ent) {
- in_port_t p1 = *(const in_port_t *)key;
- in_port_t p2 = *(const in_port_t *)ent;
-
- if (p1 < p2)
- return (-1);
- else if (p1 == p2)
- return (0);
- else
- return (1);
-}
-
-static isc_boolean_t
-portavailable(dns_dispatchmgr_t *mgr, isc_socket_t *sock,
- isc_sockaddr_t *sockaddrp)
-{
- isc_sockaddr_t sockaddr;
- isc_result_t result;
- in_port_t *ports, port;
- unsigned int nports;
- isc_boolean_t available = ISC_FALSE;
-
- REQUIRE(sock != NULL || sockaddrp != NULL);
-
- PORTBUFLOCK(mgr);
- if (sock != NULL) {
- sockaddrp = &sockaddr;
- result = isc_socket_getsockname(sock, sockaddrp);
- if (result != ISC_R_SUCCESS)
- goto unlock;
- }
-
- if (isc_sockaddr_pf(sockaddrp) == AF_INET) {
- ports = mgr->v4ports;
- nports = mgr->nv4ports;
- } else {
- ports = mgr->v6ports;
- nports = mgr->nv6ports;
- }
- if (ports == NULL)
- goto unlock;
-
- port = isc_sockaddr_getport(sockaddrp);
- if (bsearch(&port, ports, nports, sizeof(in_port_t), port_cmp) != NULL)
- available = ISC_TRUE;
-
-unlock:
- PORTBUFUNLOCK(mgr);
- return (available);
-}
-
-#define ATTRMATCH(_a1, _a2, _mask) (((_a1) & (_mask)) == ((_a2) & (_mask)))
-
-static isc_boolean_t
-local_addr_match(dns_dispatch_t *disp, isc_sockaddr_t *addr) {
- isc_sockaddr_t sockaddr;
- isc_result_t result;
-
- REQUIRE(disp->socket != NULL);
-
- if (addr == NULL)
- return (ISC_TRUE);
-
- /*
- * Don't match wildcard ports unless the port is available in the
- * current configuration.
- */
- if (isc_sockaddr_getport(addr) == 0 &&
- isc_sockaddr_getport(&disp->local) == 0 &&
- !portavailable(disp->mgr, disp->socket, NULL)) {
- return (ISC_FALSE);
- }
-
- /*
- * Check if we match the binding <address,port>.
- * Wildcard ports match/fail here.
- */
- if (isc_sockaddr_equal(&disp->local, addr))
- return (ISC_TRUE);
- if (isc_sockaddr_getport(addr) == 0)
- return (ISC_FALSE);
-
- /*
- * Check if we match a bound wildcard port <address,port>.
- */
- if (!isc_sockaddr_eqaddr(&disp->local, addr))
- return (ISC_FALSE);
- result = isc_socket_getsockname(disp->socket, &sockaddr);
- if (result != ISC_R_SUCCESS)
- return (ISC_FALSE);
-
- return (isc_sockaddr_equal(&sockaddr, addr));
-}
-
-/*
- * Requires mgr be locked.
- *
- * No dispatcher can be locked by this thread when calling this function.
- *
- *
- * NOTE:
- * If a matching dispatcher is found, it is locked after this function
- * returns, and must be unlocked by the caller.
- */
-static isc_result_t
-dispatch_find(dns_dispatchmgr_t *mgr, isc_sockaddr_t *local,
- unsigned int attributes, unsigned int mask,
- dns_dispatch_t **dispp)
-{
- dns_dispatch_t *disp;
- isc_result_t result;
-
- /*
- * Make certain that we will not match a private or exclusive dispatch.
- */
- attributes &= ~(DNS_DISPATCHATTR_PRIVATE|DNS_DISPATCHATTR_EXCLUSIVE);
- mask |= (DNS_DISPATCHATTR_PRIVATE|DNS_DISPATCHATTR_EXCLUSIVE);
-
- disp = ISC_LIST_HEAD(mgr->list);
- while (disp != NULL) {
- LOCK(&disp->lock);
- if ((disp->shutting_down == 0)
- && ATTRMATCH(disp->attributes, attributes, mask)
- && local_addr_match(disp, local))
- break;
- UNLOCK(&disp->lock);
- disp = ISC_LIST_NEXT(disp, link);
- }
-
- if (disp == NULL) {
- result = ISC_R_NOTFOUND;
- goto out;
- }
-
- *dispp = disp;
- result = ISC_R_SUCCESS;
- out:
-
- return (result);
-}
-
-static isc_result_t
-qid_allocate(dns_dispatchmgr_t *mgr, unsigned int buckets,
- unsigned int increment, dns_qid_t **qidp,
- isc_boolean_t needsocktable)
-{
- dns_qid_t *qid;
- unsigned int i;
- isc_result_t result;
-
- REQUIRE(VALID_DISPATCHMGR(mgr));
- REQUIRE(buckets < 2097169); /* next prime > 65536 * 32 */
- REQUIRE(increment > buckets);
- REQUIRE(qidp != NULL && *qidp == NULL);
-
- qid = isc_mem_get(mgr->mctx, sizeof(*qid));
- if (qid == NULL)
- return (ISC_R_NOMEMORY);
-
- qid->qid_table = isc_mem_get(mgr->mctx,
- buckets * sizeof(dns_displist_t));
- if (qid->qid_table == NULL) {
- isc_mem_put(mgr->mctx, qid, sizeof(*qid));
- return (ISC_R_NOMEMORY);
- }
-
- qid->sock_table = NULL;
- if (needsocktable) {
- qid->sock_table = isc_mem_get(mgr->mctx, buckets *
- sizeof(dispsocketlist_t));
- if (qid->sock_table == NULL) {
- isc_mem_put(mgr->mctx, qid->qid_table,
- buckets * sizeof(dns_displist_t));
- isc_mem_put(mgr->mctx, qid, sizeof(*qid));
- return (ISC_R_NOMEMORY);
- }
- }
-
- result = isc_mutex_init(&qid->lock);
- if (result != ISC_R_SUCCESS) {
- if (qid->sock_table != NULL) {
- isc_mem_put(mgr->mctx, qid->sock_table,
- buckets * sizeof(dispsocketlist_t));
- }
- isc_mem_put(mgr->mctx, qid->qid_table,
- buckets * sizeof(dns_displist_t));
- isc_mem_put(mgr->mctx, qid, sizeof(*qid));
- return (result);
- }
-
- for (i = 0; i < buckets; i++) {
- ISC_LIST_INIT(qid->qid_table[i]);
- if (qid->sock_table != NULL)
- ISC_LIST_INIT(qid->sock_table[i]);
- }
-
- qid->qid_nbuckets = buckets;
- qid->qid_increment = increment;
- qid->magic = QID_MAGIC;
- *qidp = qid;
- return (ISC_R_SUCCESS);
-}
-
-static void
-qid_destroy(isc_mem_t *mctx, dns_qid_t **qidp) {
- dns_qid_t *qid;
-
- REQUIRE(qidp != NULL);
- qid = *qidp;
-
- REQUIRE(VALID_QID(qid));
-
- *qidp = NULL;
- qid->magic = 0;
- isc_mem_put(mctx, qid->qid_table,
- qid->qid_nbuckets * sizeof(dns_displist_t));
- if (qid->sock_table != NULL) {
- isc_mem_put(mctx, qid->sock_table,
- qid->qid_nbuckets * sizeof(dispsocketlist_t));
- }
- DESTROYLOCK(&qid->lock);
- isc_mem_put(mctx, qid, sizeof(*qid));
-}
-
-/*
- * Allocate and set important limits.
- */
-static isc_result_t
-dispatch_allocate(dns_dispatchmgr_t *mgr, unsigned int maxrequests,
- dns_dispatch_t **dispp)
-{
- dns_dispatch_t *disp;
- isc_result_t result;
-
- REQUIRE(VALID_DISPATCHMGR(mgr));
- REQUIRE(dispp != NULL && *dispp == NULL);
-
- /*
- * Set up the dispatcher, mostly. Don't bother setting some of
- * the options that are controlled by tcp vs. udp, etc.
- */
-
- disp = isc_mempool_get(mgr->dpool);
- if (disp == NULL)
- return (ISC_R_NOMEMORY);
-
- disp->magic = 0;
- disp->mgr = mgr;
- disp->maxrequests = maxrequests;
- disp->attributes = 0;
- ISC_LINK_INIT(disp, link);
- disp->refcount = 1;
- disp->recv_pending = 0;
- memset(&disp->local, 0, sizeof(disp->local));
- disp->localport = 0;
- disp->shutting_down = 0;
- disp->shutdown_out = 0;
- disp->connected = 0;
- disp->tcpmsg_valid = 0;
- disp->shutdown_why = ISC_R_UNEXPECTED;
- disp->requests = 0;
- disp->tcpbuffers = 0;
- disp->qid = NULL;
- ISC_LIST_INIT(disp->activesockets);
- ISC_LIST_INIT(disp->inactivesockets);
- disp->nsockets = 0;
- dispatch_initrandom(&disp->arc4ctx, mgr->entropy, NULL);
- disp->port_table = NULL;
- disp->portpool = NULL;
-
- result = isc_mutex_init(&disp->lock);
- if (result != ISC_R_SUCCESS)
- goto deallocate;
-
- disp->failsafe_ev = allocate_devent(disp);
- if (disp->failsafe_ev == NULL) {
- result = ISC_R_NOMEMORY;
- goto kill_lock;
- }
-
- disp->magic = DISPATCH_MAGIC;
-
- *dispp = disp;
- return (ISC_R_SUCCESS);
-
- /*
- * error returns
- */
- kill_lock:
- DESTROYLOCK(&disp->lock);
- deallocate:
- isc_mempool_put(mgr->dpool, disp);
-
- return (result);
-}
-
-
-/*
- * MUST be unlocked, and not used by anything.
- */
-static void
-dispatch_free(dns_dispatch_t **dispp)
-{
- dns_dispatch_t *disp;
- dns_dispatchmgr_t *mgr;
- int i;
-
- REQUIRE(VALID_DISPATCH(*dispp));
- disp = *dispp;
- *dispp = NULL;
-
- mgr = disp->mgr;
- REQUIRE(VALID_DISPATCHMGR(mgr));
-
- if (disp->tcpmsg_valid) {
- dns_tcpmsg_invalidate(&disp->tcpmsg);
- disp->tcpmsg_valid = 0;
- }
-
- INSIST(disp->tcpbuffers == 0);
- INSIST(disp->requests == 0);
- INSIST(disp->recv_pending == 0);
- INSIST(ISC_LIST_EMPTY(disp->activesockets));
- INSIST(ISC_LIST_EMPTY(disp->inactivesockets));
-
- isc_mempool_put(mgr->depool, disp->failsafe_ev);
- disp->failsafe_ev = NULL;
-
- if (disp->qid != NULL)
- qid_destroy(mgr->mctx, &disp->qid);
-
- if (disp->port_table != NULL) {
- for (i = 0; i < DNS_DISPATCH_PORTTABLESIZE; i++)
- INSIST(ISC_LIST_EMPTY(disp->port_table[i]));
- isc_mem_put(mgr->mctx, disp->port_table,
- sizeof(disp->port_table[0]) *
- DNS_DISPATCH_PORTTABLESIZE);
- }
-
- if (disp->portpool != NULL)
- isc_mempool_destroy(&disp->portpool);
-
- disp->mgr = NULL;
- DESTROYLOCK(&disp->lock);
- disp->magic = 0;
- isc_mempool_put(mgr->dpool, disp);
-}
-
-isc_result_t
-dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock,
- isc_taskmgr_t *taskmgr, unsigned int buffersize,
- unsigned int maxbuffers, unsigned int maxrequests,
- unsigned int buckets, unsigned int increment,
- unsigned int attributes, dns_dispatch_t **dispp)
-{
- isc_result_t result;
- dns_dispatch_t *disp;
-
- UNUSED(maxbuffers);
- UNUSED(buffersize);
-
- REQUIRE(VALID_DISPATCHMGR(mgr));
- REQUIRE(isc_socket_gettype(sock) == isc_sockettype_tcp);
- REQUIRE((attributes & DNS_DISPATCHATTR_TCP) != 0);
- REQUIRE((attributes & DNS_DISPATCHATTR_UDP) == 0);
-
- attributes |= DNS_DISPATCHATTR_PRIVATE; /* XXXMLG */
-
- LOCK(&mgr->lock);
-
- /*
- * dispatch_allocate() checks mgr for us.
- * qid_allocate() checks buckets and increment for us.
- */
- disp = NULL;
- result = dispatch_allocate(mgr, maxrequests, &disp);
- if (result != ISC_R_SUCCESS) {
- UNLOCK(&mgr->lock);
- return (result);
- }
-
- result = qid_allocate(mgr, buckets, increment, &disp->qid, ISC_FALSE);
- if (result != ISC_R_SUCCESS)
- goto deallocate_dispatch;
-
- disp->socktype = isc_sockettype_tcp;
- disp->socket = NULL;
- isc_socket_attach(sock, &disp->socket);
-
- disp->sepool = NULL;
-
- disp->ntasks = 1;
- disp->task[0] = NULL;
- result = isc_task_create(taskmgr, 0, &disp->task[0]);
- if (result != ISC_R_SUCCESS)
- goto kill_socket;
-
- disp->ctlevent = isc_event_allocate(mgr->mctx, disp,
- DNS_EVENT_DISPATCHCONTROL,
- destroy_disp, disp,
- sizeof(isc_event_t));
- if (disp->ctlevent == NULL) {
- result = ISC_R_NOMEMORY;
- goto kill_task;
- }
-
- isc_task_setname(disp->task[0], "tcpdispatch", disp);
-
- dns_tcpmsg_init(mgr->mctx, disp->socket, &disp->tcpmsg);
- disp->tcpmsg_valid = 1;
-
- disp->attributes = attributes;
-
- /*
- * Append it to the dispatcher list.
- */
- ISC_LIST_APPEND(mgr->list, disp, link);
- UNLOCK(&mgr->lock);
-
- mgr_log(mgr, LVL(90), "created TCP dispatcher %p", disp);
- dispatch_log(disp, LVL(90), "created task %p", disp->task[0]);
-
- *dispp = disp;
-
- return (ISC_R_SUCCESS);
-
- /*
- * Error returns.
- */
- kill_task:
- isc_task_detach(&disp->task[0]);
- kill_socket:
- isc_socket_detach(&disp->socket);
- deallocate_dispatch:
- dispatch_free(&disp);
-
- UNLOCK(&mgr->lock);
-
- return (result);
-}
-
-isc_result_t
-dns_dispatch_getudp_dup(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
- isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr,
- unsigned int buffersize,
- unsigned int maxbuffers, unsigned int maxrequests,
- unsigned int buckets, unsigned int increment,
- unsigned int attributes, unsigned int mask,
- dns_dispatch_t **dispp, dns_dispatch_t *dup_dispatch)
-{
- isc_result_t result;
- dns_dispatch_t *disp = NULL;
-
- REQUIRE(VALID_DISPATCHMGR(mgr));
- REQUIRE(sockmgr != NULL);
- REQUIRE(localaddr != NULL);
- REQUIRE(taskmgr != NULL);
- REQUIRE(buffersize >= 512 && buffersize < (64 * 1024));
- REQUIRE(maxbuffers > 0);
- REQUIRE(buckets < 2097169); /* next prime > 65536 * 32 */
- REQUIRE(increment > buckets);
- REQUIRE(dispp != NULL && *dispp == NULL);
- REQUIRE((attributes & DNS_DISPATCHATTR_TCP) == 0);
-
- result = dns_dispatchmgr_setudp(mgr, buffersize, maxbuffers,
- maxrequests, buckets, increment);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- LOCK(&mgr->lock);
-
- if ((attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0) {
- REQUIRE(isc_sockaddr_getport(localaddr) == 0);
- goto createudp;
- }
-
- /*
- * See if we have a dispatcher that matches.
- */
- if (dup_dispatch == NULL) {
- result = dispatch_find(mgr, localaddr, attributes, mask, &disp);
- if (result == ISC_R_SUCCESS) {
- disp->refcount++;
-
- if (disp->maxrequests < maxrequests)
- disp->maxrequests = maxrequests;
-
- if ((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) == 0
- && (attributes & DNS_DISPATCHATTR_NOLISTEN) != 0)
- {
- disp->attributes |= DNS_DISPATCHATTR_NOLISTEN;
- if (disp->recv_pending != 0)
- isc_socket_cancel(disp->socket,
- disp->task[0],
- ISC_SOCKCANCEL_RECV);
- }
-
- UNLOCK(&disp->lock);
- UNLOCK(&mgr->lock);
-
- *dispp = disp;
-
- return (ISC_R_SUCCESS);
- }
- }
-
- createudp:
- /*
- * Nope, create one.
- */
- result = dispatch_createudp(mgr, sockmgr, taskmgr, localaddr,
- maxrequests, attributes, &disp,
- dup_dispatch == NULL
- ? NULL
- : dup_dispatch->socket);
-
- if (result != ISC_R_SUCCESS) {
- UNLOCK(&mgr->lock);
- return (result);
- }
-
- UNLOCK(&mgr->lock);
- *dispp = disp;
-
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_dispatch_getudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
- isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr,
- unsigned int buffersize,
- unsigned int maxbuffers, unsigned int maxrequests,
- unsigned int buckets, unsigned int increment,
- unsigned int attributes, unsigned int mask,
- dns_dispatch_t **dispp)
-{
- return (dns_dispatch_getudp_dup(mgr, sockmgr, taskmgr, localaddr,
- buffersize, maxbuffers, maxrequests,
- buckets, increment, attributes,
- mask, dispp, NULL));
-}
-
-/*
- * mgr should be locked.
- */
-
-#ifndef DNS_DISPATCH_HELD
-#define DNS_DISPATCH_HELD 20U
-#endif
-
-static isc_result_t
-get_udpsocket(dns_dispatchmgr_t *mgr, dns_dispatch_t *disp,
- isc_socketmgr_t *sockmgr, isc_sockaddr_t *localaddr,
- isc_socket_t **sockp, isc_socket_t *dup_socket)
-{
- unsigned int i, j;
- isc_socket_t *held[DNS_DISPATCH_HELD];
- isc_sockaddr_t localaddr_bound;
- isc_socket_t *sock = NULL;
- isc_result_t result = ISC_R_SUCCESS;
- isc_boolean_t anyport;
-
- INSIST(sockp != NULL && *sockp == NULL);
-
- localaddr_bound = *localaddr;
- anyport = ISC_TF(isc_sockaddr_getport(localaddr) == 0);
-
- if (anyport) {
- unsigned int nports;
- in_port_t *ports;
-
- /*
- * If no port is specified, we first try to pick up a random
- * port by ourselves.
- */
- if (isc_sockaddr_pf(localaddr) == AF_INET) {
- nports = disp->mgr->nv4ports;
- ports = disp->mgr->v4ports;
- } else {
- nports = disp->mgr->nv6ports;
- ports = disp->mgr->v6ports;
- }
- if (nports == 0)
- return (ISC_R_ADDRNOTAVAIL);
-
- for (i = 0; i < 1024; i++) {
- in_port_t prt;
-
- prt = ports[dispatch_uniformrandom(
- DISP_ARC4CTX(disp),
- nports)];
- isc_sockaddr_setport(&localaddr_bound, prt);
- result = open_socket(sockmgr, &localaddr_bound,
- 0, &sock, NULL);
- /*
- * Continue if the port choosen is already in use
- * or the OS has reserved it.
- */
- if (result == ISC_R_NOPERM ||
- result == ISC_R_ADDRINUSE)
- continue;
- disp->localport = prt;
- *sockp = sock;
- return (result);
- }
-
- /*
- * If this fails 1024 times, we then ask the kernel for
- * choosing one.
- */
- } else {
- /* Allow to reuse address for non-random ports. */
- result = open_socket(sockmgr, localaddr,
- ISC_SOCKET_REUSEADDRESS, &sock,
- dup_socket);
-
- if (result == ISC_R_SUCCESS)
- *sockp = sock;
-
- return (result);
- }
-
- memset(held, 0, sizeof(held));
- i = 0;
-
- for (j = 0; j < 0xffffU; j++) {
- result = open_socket(sockmgr, localaddr, 0, &sock, NULL);
- if (result != ISC_R_SUCCESS)
- goto end;
- else if (portavailable(mgr, sock, NULL))
- break;
- if (held[i] != NULL)
- isc_socket_detach(&held[i]);
- held[i++] = sock;
- sock = NULL;
- if (i == DNS_DISPATCH_HELD)
- i = 0;
- }
- if (j == 0xffffU) {
- mgr_log(mgr, ISC_LOG_ERROR,
- "avoid-v%s-udp-ports: unable to allocate "
- "an available port",
- isc_sockaddr_pf(localaddr) == AF_INET ? "4" : "6");
- result = ISC_R_FAILURE;
- goto end;
- }
- *sockp = sock;
-
-end:
- for (i = 0; i < DNS_DISPATCH_HELD; i++) {
- if (held[i] != NULL)
- isc_socket_detach(&held[i]);
- }
-
- return (result);
-}
-
-static isc_result_t
-dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
- isc_taskmgr_t *taskmgr,
- isc_sockaddr_t *localaddr,
- unsigned int maxrequests,
- unsigned int attributes,
- dns_dispatch_t **dispp,
- isc_socket_t *dup_socket)
-{
- isc_result_t result;
- dns_dispatch_t *disp;
- isc_socket_t *sock = NULL;
- int i = 0;
-
- /*
- * dispatch_allocate() checks mgr for us.
- */
- disp = NULL;
- result = dispatch_allocate(mgr, maxrequests, &disp);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- if ((attributes & DNS_DISPATCHATTR_EXCLUSIVE) == 0) {
- result = get_udpsocket(mgr, disp, sockmgr, localaddr, &sock,
- dup_socket);
- if (result != ISC_R_SUCCESS)
- goto deallocate_dispatch;
-
- if (isc_log_wouldlog(dns_lctx, 90)) {
- char addrbuf[ISC_SOCKADDR_FORMATSIZE];
-
- isc_sockaddr_format(localaddr, addrbuf,
- ISC_SOCKADDR_FORMATSIZE);
- mgr_log(mgr, LVL(90), "dns_dispatch_createudp: Created"
- " UDP dispatch for %s with socket fd %d\n",
- addrbuf, isc_socket_getfd(sock));
- }
-
- } else {
- isc_sockaddr_t sa_any;
-
- /*
- * For dispatches using exclusive sockets with a specific
- * source address, we only check if the specified address is
- * available on the system. Query sockets will be created later
- * on demand.
- */
- isc_sockaddr_anyofpf(&sa_any, isc_sockaddr_pf(localaddr));
- if (!isc_sockaddr_eqaddr(&sa_any, localaddr)) {
- result = open_socket(sockmgr, localaddr, 0, &sock, NULL);
- if (sock != NULL)
- isc_socket_detach(&sock);
- if (result != ISC_R_SUCCESS)
- goto deallocate_dispatch;
- }
-
- disp->port_table = isc_mem_get(mgr->mctx,
- sizeof(disp->port_table[0]) *
- DNS_DISPATCH_PORTTABLESIZE);
- if (disp->port_table == NULL)
- goto deallocate_dispatch;
- for (i = 0; i < DNS_DISPATCH_PORTTABLESIZE; i++)
- ISC_LIST_INIT(disp->port_table[i]);
-
- result = isc_mempool_create(mgr->mctx, sizeof(dispportentry_t),
- &disp->portpool);
- if (result != ISC_R_SUCCESS)
- goto deallocate_dispatch;
- isc_mempool_setname(disp->portpool, "disp_portpool");
- isc_mempool_setfreemax(disp->portpool, 128);
- }
- disp->socktype = isc_sockettype_udp;
- disp->socket = sock;
- disp->local = *localaddr;
-
- if ((attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0)
- disp->ntasks = MAX_INTERNAL_TASKS;
- else
- disp->ntasks = 1;
- for (i = 0; i < disp->ntasks; i++) {
- disp->task[i] = NULL;
- result = isc_task_create(taskmgr, 0, &disp->task[i]);
- if (result != ISC_R_SUCCESS) {
- 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);
- }
-
- disp->ctlevent = isc_event_allocate(mgr->mctx, disp,
- DNS_EVENT_DISPATCHCONTROL,
- destroy_disp, disp,
- sizeof(isc_event_t));
- if (disp->ctlevent == NULL) {
- result = ISC_R_NOMEMORY;
- goto kill_task;
- }
-
- disp->sepool = NULL;
- if (isc_mempool_create(mgr->mctx, sizeof(isc_socketevent_t),
- &disp->sepool) != ISC_R_SUCCESS)
- {
- result = ISC_R_NOMEMORY;
- goto kill_ctlevent;
- }
-
- result = isc_mutex_init(&disp->sepool_lock);
- if (result != ISC_R_SUCCESS)
- goto kill_sepool;
-
- isc_mempool_setname(disp->sepool, "disp_sepool");
- isc_mempool_setmaxalloc(disp->sepool, 32768);
- isc_mempool_setfreemax(disp->sepool, 32768);
- isc_mempool_associatelock(disp->sepool, &disp->sepool_lock);
- isc_mempool_setfillcount(disp->sepool, 16);
-
- attributes &= ~DNS_DISPATCHATTR_TCP;
- attributes |= DNS_DISPATCHATTR_UDP;
- disp->attributes = attributes;
-
- /*
- * Append it to the dispatcher list.
- */
- ISC_LIST_APPEND(mgr->list, disp, link);
-
- mgr_log(mgr, LVL(90), "created UDP dispatcher %p", disp);
- dispatch_log(disp, LVL(90), "created task %p", disp->task[0]); /* XXX */
- if (disp->socket != NULL)
- dispatch_log(disp, LVL(90), "created socket %p", disp->socket);
-
- *dispp = disp;
-
- return (result);
-
- /*
- * Error returns.
- */
- kill_sepool:
- isc_mempool_destroy(&disp->sepool);
- kill_ctlevent:
- isc_event_free(&disp->ctlevent);
- kill_task:
- for (i = 0; i < disp->ntasks; i++)
- isc_task_detach(&disp->task[i]);
- kill_socket:
- if (disp->socket != NULL)
- isc_socket_detach(&disp->socket);
- deallocate_dispatch:
- dispatch_free(&disp);
-
- return (result);
-}
-
-void
-dns_dispatch_attach(dns_dispatch_t *disp, dns_dispatch_t **dispp) {
- REQUIRE(VALID_DISPATCH(disp));
- REQUIRE(dispp != NULL && *dispp == NULL);
-
- LOCK(&disp->lock);
- disp->refcount++;
- UNLOCK(&disp->lock);
-
- *dispp = disp;
-}
-
-/*
- * It is important to lock the manager while we are deleting the dispatch,
- * since dns_dispatch_getudp will call dispatch_find, which returns to
- * the caller a dispatch but does not attach to it until later. _getudp
- * locks the manager, however, so locking it here will keep us from attaching
- * to a dispatcher that is in the process of going away.
- */
-void
-dns_dispatch_detach(dns_dispatch_t **dispp) {
- dns_dispatch_t *disp;
- dispsocket_t *dispsock;
- isc_boolean_t killit;
-
- REQUIRE(dispp != NULL && VALID_DISPATCH(*dispp));
-
- disp = *dispp;
- *dispp = NULL;
-
- LOCK(&disp->lock);
-
- INSIST(disp->refcount > 0);
- disp->refcount--;
- if (disp->refcount == 0) {
- if (disp->recv_pending > 0)
- isc_socket_cancel(disp->socket, disp->task[0],
- ISC_SOCKCANCEL_RECV);
- for (dispsock = ISC_LIST_HEAD(disp->activesockets);
- dispsock != NULL;
- dispsock = ISC_LIST_NEXT(dispsock, link)) {
- isc_socket_cancel(dispsock->socket, dispsock->task,
- ISC_SOCKCANCEL_RECV);
- }
- disp->shutting_down = 1;
- }
-
- dispatch_log(disp, LVL(90), "detach: refcount %d", disp->refcount);
-
- killit = destroy_disp_ok(disp);
- UNLOCK(&disp->lock);
- if (killit)
- isc_task_send(disp->task[0], &disp->ctlevent);
-}
-
-isc_result_t
-dns_dispatch_addresponse2(dns_dispatch_t *disp, isc_sockaddr_t *dest,
- isc_task_t *task, isc_taskaction_t action, void *arg,
- dns_messageid_t *idp, dns_dispentry_t **resp,
- isc_socketmgr_t *sockmgr)
-{
- dns_dispentry_t *res;
- unsigned int bucket;
- in_port_t localport = 0;
- dns_messageid_t id;
- int i;
- isc_boolean_t ok;
- dns_qid_t *qid;
- dispsocket_t *dispsocket = NULL;
- isc_result_t result;
-
- REQUIRE(VALID_DISPATCH(disp));
- REQUIRE(task != NULL);
- REQUIRE(dest != NULL);
- REQUIRE(resp != NULL && *resp == NULL);
- REQUIRE(idp != NULL);
- if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0)
- REQUIRE(sockmgr != NULL);
-
- LOCK(&disp->lock);
-
- if (disp->shutting_down == 1) {
- UNLOCK(&disp->lock);
- return (ISC_R_SHUTTINGDOWN);
- }
-
- if (disp->requests >= disp->maxrequests) {
- UNLOCK(&disp->lock);
- return (ISC_R_QUOTA);
- }
-
- if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0 &&
- disp->nsockets > DNS_DISPATCH_SOCKSQUOTA) {
- dispsocket_t *oldestsocket;
- dns_dispentry_t *oldestresp;
- dns_dispatchevent_t *rev;
-
- /*
- * Kill oldest outstanding query if the number of sockets
- * exceeds the quota to keep the room for new queries.
- */
- oldestsocket = ISC_LIST_HEAD(disp->activesockets);
- oldestresp = oldestsocket->resp;
- if (oldestresp != NULL && !oldestresp->item_out) {
- rev = allocate_devent(oldestresp->disp);
- if (rev != NULL) {
- rev->buffer.base = NULL;
- rev->result = ISC_R_CANCELED;
- rev->id = oldestresp->id;
- ISC_EVENT_INIT(rev, sizeof(*rev), 0,
- NULL, DNS_EVENT_DISPATCH,
- oldestresp->action,
- oldestresp->arg, oldestresp,
- NULL, NULL);
- oldestresp->item_out = ISC_TRUE;
- isc_task_send(oldestresp->task,
- ISC_EVENT_PTR(&rev));
- inc_stats(disp->mgr,
- dns_resstatscounter_dispabort);
- }
- }
-
- /*
- * Move this entry to the tail so that it won't (easily) be
- * examined before actually being canceled.
- */
- ISC_LIST_UNLINK(disp->activesockets, oldestsocket, link);
- ISC_LIST_APPEND(disp->activesockets, oldestsocket, link);
- }
-
- qid = DNS_QID(disp);
-
- if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0) {
- /*
- * Get a separate UDP socket with a random port number.
- */
- result = get_dispsocket(disp, dest, sockmgr, &dispsocket,
- &localport);
- if (result != ISC_R_SUCCESS) {
- UNLOCK(&disp->lock);
- inc_stats(disp->mgr, dns_resstatscounter_dispsockfail);
- return (result);
- }
- } else {
- localport = disp->localport;
- }
-
- /*
- * Try somewhat hard to find an unique ID.
- */
- LOCK(&qid->lock);
- id = (dns_messageid_t)dispatch_random(DISP_ARC4CTX(disp));
- bucket = dns_hash(qid, dest, id, localport);
- ok = ISC_FALSE;
- for (i = 0; i < 64; i++) {
- if (entry_search(qid, dest, id, localport, bucket) == NULL) {
- ok = ISC_TRUE;
- break;
- }
- id += qid->qid_increment;
- id &= 0x0000ffff;
- bucket = dns_hash(qid, dest, id, localport);
- }
- UNLOCK(&qid->lock);
-
- if (!ok) {
- UNLOCK(&disp->lock);
- return (ISC_R_NOMORE);
- }
-
- res = isc_mempool_get(disp->mgr->rpool);
- if (res == NULL) {
- UNLOCK(&disp->lock);
- if (dispsocket != NULL)
- destroy_dispsocket(disp, &dispsocket);
- return (ISC_R_NOMEMORY);
- }
-
- disp->refcount++;
- disp->requests++;
- res->task = NULL;
- isc_task_attach(task, &res->task);
- res->disp = disp;
- res->id = id;
- res->port = localport;
- res->bucket = bucket;
- res->host = *dest;
- res->action = action;
- res->arg = arg;
- res->dispsocket = dispsocket;
- if (dispsocket != NULL)
- dispsocket->resp = res;
- res->item_out = ISC_FALSE;
- ISC_LIST_INIT(res->items);
- ISC_LINK_INIT(res, link);
- res->magic = RESPONSE_MAGIC;
-
- LOCK(&qid->lock);
- ISC_LIST_APPEND(qid->qid_table[bucket], res, link);
- UNLOCK(&qid->lock);
-
- request_log(disp, res, LVL(90),
- "attached to task %p", res->task);
-
- if (((disp->attributes & DNS_DISPATCHATTR_UDP) != 0) ||
- ((disp->attributes & DNS_DISPATCHATTR_CONNECTED) != 0)) {
- result = startrecv(disp, dispsocket);
- if (result != ISC_R_SUCCESS) {
- LOCK(&qid->lock);
- ISC_LIST_UNLINK(qid->qid_table[bucket], res, link);
- UNLOCK(&qid->lock);
-
- if (dispsocket != NULL)
- destroy_dispsocket(disp, &dispsocket);
-
- disp->refcount--;
- disp->requests--;
-
- UNLOCK(&disp->lock);
- isc_task_detach(&res->task);
- isc_mempool_put(disp->mgr->rpool, res);
- return (result);
- }
- }
-
- if (dispsocket != NULL)
- ISC_LIST_APPEND(disp->activesockets, dispsocket, link);
-
- UNLOCK(&disp->lock);
-
- *idp = id;
- *resp = res;
-
- if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0)
- INSIST(res->dispsocket != NULL);
-
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_dispatch_addresponse(dns_dispatch_t *disp, isc_sockaddr_t *dest,
- isc_task_t *task, isc_taskaction_t action, void *arg,
- dns_messageid_t *idp, dns_dispentry_t **resp)
-{
- REQUIRE(VALID_DISPATCH(disp));
- REQUIRE((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) == 0);
-
- return (dns_dispatch_addresponse2(disp, dest, task, action, arg,
- idp, resp, NULL));
-}
-
-void
-dns_dispatch_starttcp(dns_dispatch_t *disp) {
-
- REQUIRE(VALID_DISPATCH(disp));
-
- dispatch_log(disp, LVL(90), "starttcp %p", disp->task[0]);
-
- LOCK(&disp->lock);
- disp->attributes |= DNS_DISPATCHATTR_CONNECTED;
- (void)startrecv(disp, NULL);
- UNLOCK(&disp->lock);
-}
-
-void
-dns_dispatch_removeresponse(dns_dispentry_t **resp,
- dns_dispatchevent_t **sockevent)
-{
- dns_dispatchmgr_t *mgr;
- dns_dispatch_t *disp;
- dns_dispentry_t *res;
- dispsocket_t *dispsock;
- dns_dispatchevent_t *ev;
- unsigned int bucket;
- isc_boolean_t killit;
- unsigned int n;
- isc_eventlist_t events;
- dns_qid_t *qid;
-
- REQUIRE(resp != NULL);
- REQUIRE(VALID_RESPONSE(*resp));
-
- res = *resp;
- *resp = NULL;
-
- disp = res->disp;
- REQUIRE(VALID_DISPATCH(disp));
- mgr = disp->mgr;
- REQUIRE(VALID_DISPATCHMGR(mgr));
-
- qid = DNS_QID(disp);
-
- if (sockevent != NULL) {
- REQUIRE(*sockevent != NULL);
- ev = *sockevent;
- *sockevent = NULL;
- } else {
- ev = NULL;
- }
-
- LOCK(&disp->lock);
-
- INSIST(disp->requests > 0);
- disp->requests--;
- INSIST(disp->refcount > 0);
- disp->refcount--;
- if (disp->refcount == 0) {
- if (disp->recv_pending > 0)
- isc_socket_cancel(disp->socket, disp->task[0],
- ISC_SOCKCANCEL_RECV);
- for (dispsock = ISC_LIST_HEAD(disp->activesockets);
- dispsock != NULL;
- dispsock = ISC_LIST_NEXT(dispsock, link)) {
- isc_socket_cancel(dispsock->socket, dispsock->task,
- ISC_SOCKCANCEL_RECV);
- }
- disp->shutting_down = 1;
- }
-
- bucket = res->bucket;
-
- LOCK(&qid->lock);
- ISC_LIST_UNLINK(qid->qid_table[bucket], res, link);
- UNLOCK(&qid->lock);
-
- if (ev == NULL && res->item_out) {
- /*
- * We've posted our event, but the caller hasn't gotten it
- * yet. Take it back.
- */
- ISC_LIST_INIT(events);
- n = isc_task_unsend(res->task, res, DNS_EVENT_DISPATCH,
- NULL, &events);
- /*
- * We had better have gotten it back.
- */
- INSIST(n == 1);
- ev = (dns_dispatchevent_t *)ISC_LIST_HEAD(events);
- }
-
- if (ev != NULL) {
- REQUIRE(res->item_out == ISC_TRUE);
- res->item_out = ISC_FALSE;
- if (ev->buffer.base != NULL)
- free_buffer(disp, ev->buffer.base, ev->buffer.length);
- free_devent(disp, ev);
- }
-
- request_log(disp, res, LVL(90), "detaching from task %p", res->task);
- isc_task_detach(&res->task);
-
- if (res->dispsocket != NULL) {
- isc_socket_cancel(res->dispsocket->socket,
- res->dispsocket->task, ISC_SOCKCANCEL_RECV);
- res->dispsocket->resp = NULL;
- }
-
- /*
- * Free any buffered requests as well
- */
- ev = ISC_LIST_HEAD(res->items);
- while (ev != NULL) {
- ISC_LIST_UNLINK(res->items, ev, ev_link);
- if (ev->buffer.base != NULL)
- free_buffer(disp, ev->buffer.base, ev->buffer.length);
- free_devent(disp, ev);
- ev = ISC_LIST_HEAD(res->items);
- }
- res->magic = 0;
- isc_mempool_put(disp->mgr->rpool, res);
- if (disp->shutting_down == 1)
- do_cancel(disp);
- else
- (void)startrecv(disp, NULL);
-
- killit = destroy_disp_ok(disp);
- UNLOCK(&disp->lock);
- if (killit)
- isc_task_send(disp->task[0], &disp->ctlevent);
-}
-
-static void
-do_cancel(dns_dispatch_t *disp) {
- dns_dispatchevent_t *ev;
- dns_dispentry_t *resp;
- dns_qid_t *qid;
-
- if (disp->shutdown_out == 1)
- return;
-
- qid = DNS_QID(disp);
-
- /*
- * Search for the first response handler without packets outstanding
- * unless a specific hander is given.
- */
- LOCK(&qid->lock);
- for (resp = linear_first(qid);
- resp != NULL && resp->item_out;
- /* Empty. */)
- resp = linear_next(qid, resp);
-
- /*
- * No one to send the cancel event to, so nothing to do.
- */
- if (resp == NULL)
- goto unlock;
-
- /*
- * Send the shutdown failsafe event to this resp.
- */
- ev = disp->failsafe_ev;
- ISC_EVENT_INIT(ev, sizeof(*ev), 0, NULL, DNS_EVENT_DISPATCH,
- resp->action, resp->arg, resp, NULL, NULL);
- ev->result = disp->shutdown_why;
- ev->buffer.base = NULL;
- ev->buffer.length = 0;
- disp->shutdown_out = 1;
- request_log(disp, resp, LVL(10),
- "cancel: failsafe event %p -> task %p",
- ev, resp->task);
- resp->item_out = ISC_TRUE;
- isc_task_send(resp->task, ISC_EVENT_PTR(&ev));
- unlock:
- UNLOCK(&qid->lock);
-}
-
-isc_socket_t *
-dns_dispatch_getsocket(dns_dispatch_t *disp) {
- REQUIRE(VALID_DISPATCH(disp));
-
- return (disp->socket);
-}
-
-isc_socket_t *
-dns_dispatch_getentrysocket(dns_dispentry_t *resp) {
- REQUIRE(VALID_RESPONSE(resp));
-
- if (resp->dispsocket != NULL)
- return (resp->dispsocket->socket);
- else
- return (NULL);
-}
-
-isc_result_t
-dns_dispatch_getlocaladdress(dns_dispatch_t *disp, isc_sockaddr_t *addrp) {
-
- REQUIRE(VALID_DISPATCH(disp));
- REQUIRE(addrp != NULL);
-
- if (disp->socktype == isc_sockettype_udp) {
- *addrp = disp->local;
- return (ISC_R_SUCCESS);
- }
- return (ISC_R_NOTIMPLEMENTED);
-}
-
-void
-dns_dispatch_cancel(dns_dispatch_t *disp) {
- REQUIRE(VALID_DISPATCH(disp));
-
- LOCK(&disp->lock);
-
- if (disp->shutting_down == 1) {
- UNLOCK(&disp->lock);
- return;
- }
-
- disp->shutdown_why = ISC_R_CANCELED;
- disp->shutting_down = 1;
- do_cancel(disp);
-
- UNLOCK(&disp->lock);
-
- return;
-}
-
-unsigned int
-dns_dispatch_getattributes(dns_dispatch_t *disp) {
- REQUIRE(VALID_DISPATCH(disp));
-
- /*
- * We don't bother locking disp here; it's the caller's responsibility
- * to use only non volatile flags.
- */
- return (disp->attributes);
-}
-
-void
-dns_dispatch_changeattributes(dns_dispatch_t *disp,
- unsigned int attributes, unsigned int mask)
-{
- REQUIRE(VALID_DISPATCH(disp));
- /* Exclusive attribute can only be set on creation */
- REQUIRE((attributes & DNS_DISPATCHATTR_EXCLUSIVE) == 0);
- /* Also, a dispatch with randomport specified cannot start listening */
- REQUIRE((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) == 0 ||
- (attributes & DNS_DISPATCHATTR_NOLISTEN) == 0);
-
- /* XXXMLG
- * Should check for valid attributes here!
- */
-
- LOCK(&disp->lock);
-
- if ((mask & DNS_DISPATCHATTR_NOLISTEN) != 0) {
- if ((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) != 0 &&
- (attributes & DNS_DISPATCHATTR_NOLISTEN) == 0) {
- disp->attributes &= ~DNS_DISPATCHATTR_NOLISTEN;
- (void)startrecv(disp, NULL);
- } else if ((disp->attributes & DNS_DISPATCHATTR_NOLISTEN)
- == 0 &&
- (attributes & DNS_DISPATCHATTR_NOLISTEN) != 0) {
- disp->attributes |= DNS_DISPATCHATTR_NOLISTEN;
- if (disp->recv_pending != 0)
- isc_socket_cancel(disp->socket, disp->task[0],
- ISC_SOCKCANCEL_RECV);
- }
- }
-
- disp->attributes &= ~mask;
- disp->attributes |= (attributes & mask);
- UNLOCK(&disp->lock);
-}
-
-void
-dns_dispatch_importrecv(dns_dispatch_t *disp, isc_event_t *event) {
- void *buf;
- isc_socketevent_t *sevent, *newsevent;
-
- REQUIRE(VALID_DISPATCH(disp));
- REQUIRE((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) != 0);
- REQUIRE(event != NULL);
-
- sevent = (isc_socketevent_t *)event;
-
- INSIST(sevent->n <= disp->mgr->buffersize);
- newsevent = (isc_socketevent_t *)
- isc_event_allocate(disp->mgr->mctx, NULL,
- DNS_EVENT_IMPORTRECVDONE, udp_shrecv,
- disp, sizeof(isc_socketevent_t));
- if (newsevent == NULL)
- return;
-
- buf = allocate_udp_buffer(disp);
- if (buf == NULL) {
- isc_event_free(ISC_EVENT_PTR(&newsevent));
- return;
- }
- memcpy(buf, sevent->region.base, sevent->n);
- newsevent->region.base = buf;
- newsevent->region.length = disp->mgr->buffersize;
- newsevent->n = sevent->n;
- newsevent->result = sevent->result;
- newsevent->address = sevent->address;
- newsevent->timestamp = sevent->timestamp;
- newsevent->pktinfo = sevent->pktinfo;
- newsevent->attributes = sevent->attributes;
-
- isc_task_send(disp->task[0], ISC_EVENT_PTR(&newsevent));
-}
-
-dns_dispatch_t *
-dns_dispatchset_get(dns_dispatchset_t *dset) {
- dns_dispatch_t *disp;
-
- /* check that dispatch set is configured */
- if (dset == NULL || dset->ndisp == 0)
- return (NULL);
-
- LOCK(&dset->lock);
- disp = dset->dispatches[dset->cur];
- dset->cur++;
- if (dset->cur == dset->ndisp)
- dset->cur = 0;
- UNLOCK(&dset->lock);
-
- return (disp);
-}
-
-isc_result_t
-dns_dispatchset_create(isc_mem_t *mctx, isc_socketmgr_t *sockmgr,
- isc_taskmgr_t *taskmgr, dns_dispatch_t *source,
- dns_dispatchset_t **dsetp, int n)
-{
- isc_result_t result;
- dns_dispatchset_t *dset;
- dns_dispatchmgr_t *mgr;
- int i, j;
-
- REQUIRE(VALID_DISPATCH(source));
- REQUIRE((source->attributes & DNS_DISPATCHATTR_UDP) != 0);
- REQUIRE(dsetp != NULL && *dsetp == NULL);
-
- mgr = source->mgr;
-
- dset = isc_mem_get(mctx, sizeof(dns_dispatchset_t));
- if (dset == NULL)
- return (ISC_R_NOMEMORY);
- memset(dset, 0, sizeof(*dset));
-
- result = isc_mutex_init(&dset->lock);
- if (result != ISC_R_SUCCESS)
- goto fail_alloc;
-
- dset->dispatches = isc_mem_get(mctx, sizeof(dns_dispatch_t *) * n);
- if (dset == NULL) {
- result = ISC_R_NOMEMORY;
- goto fail_lock;
- }
-
- isc_mem_attach(mctx, &dset->mctx);
- dset->ndisp = n;
- dset->cur = 0;
-
- dset->dispatches[0] = NULL;
- dns_dispatch_attach(source, &dset->dispatches[0]);
-
- LOCK(&mgr->lock);
- for (i = 1; i < n; i++) {
- dset->dispatches[i] = NULL;
- result = dispatch_createudp(mgr, sockmgr, taskmgr,
- &source->local,
- source->maxrequests,
- source->attributes,
- &dset->dispatches[i],
- source->socket);
- if (result != ISC_R_SUCCESS)
- goto fail;
- }
-
- UNLOCK(&mgr->lock);
- *dsetp = dset;
-
- return (ISC_R_SUCCESS);
-
- fail:
- UNLOCK(&mgr->lock);
-
- for (j = 0; j < i; j++)
- dns_dispatch_detach(&(dset->dispatches[j]));
- isc_mem_put(mctx, dset->dispatches, sizeof(dns_dispatch_t *) * n);
- if (dset->mctx == mctx)
- isc_mem_detach(&dset->mctx);
-
- fail_lock:
- DESTROYLOCK(&dset->lock);
-
- fail_alloc:
- isc_mem_put(mctx, dset, sizeof(dns_dispatchset_t));
- return (result);
-}
-
-void
-dns_dispatchset_cancelall(dns_dispatchset_t *dset, isc_task_t *task) {
- int i;
-
- REQUIRE(dset != NULL);
-
- for (i = 0; i < dset->ndisp; i++) {
- isc_socket_t *sock;
- sock = dns_dispatch_getsocket(dset->dispatches[i]);
- isc_socket_cancel(sock, task, ISC_SOCKCANCEL_ALL);
- }
-}
-
-void
-dns_dispatchset_destroy(dns_dispatchset_t **dsetp) {
- dns_dispatchset_t *dset;
- int i;
-
- REQUIRE(dsetp != NULL && *dsetp != NULL);
-
- dset = *dsetp;
- for (i = 0; i < dset->ndisp; i++)
- dns_dispatch_detach(&(dset->dispatches[i]));
- isc_mem_put(dset->mctx, dset->dispatches,
- sizeof(dns_dispatch_t *) * dset->ndisp);
- DESTROYLOCK(&dset->lock);
- isc_mem_putanddetach(&dset->mctx, dset, sizeof(dns_dispatchset_t));
-
- *dsetp = NULL;
-}
-
-#if 0
-void
-dns_dispatchmgr_dump(dns_dispatchmgr_t *mgr) {
- dns_dispatch_t *disp;
- char foo[1024];
-
- disp = ISC_LIST_HEAD(mgr->list);
- while (disp != NULL) {
- isc_sockaddr_format(&disp->local, foo, sizeof(foo));
- printf("\tdispatch %p, addr %s\n", disp, foo);
- disp = ISC_LIST_NEXT(disp, link);
- }
-}
-#endif
diff --git a/contrib/bind9/lib/dns/dlz.c b/contrib/bind9/lib/dns/dlz.c
deleted file mode 100644
index 19c600c94126..000000000000
--- a/contrib/bind9/lib/dns/dlz.c
+++ /dev/null
@@ -1,655 +0,0 @@
-/*
- * Portions Copyright (C) 2005, 2007, 2009-2013 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * Copyright (C) 2002 Stichting NLnet, Netherlands, stichting@nlnet.nl.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the
- * above copyright notice and this permission notice appear in all
- * copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND STICHTING NLNET
- * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
- * STICHTING NLNET BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
- * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
- * USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * The development of Dynamically Loadable Zones (DLZ) for Bind 9 was
- * conceived and contributed by Rob Butler.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the
- * above copyright notice and this permission notice appear in all
- * copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ROB BUTLER
- * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
- * ROB BUTLER BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
- * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
- * USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/*! \file */
-
-/***
- *** Imports
- ***/
-
-#include <config.h>
-
-#include <dns/fixedname.h>
-#include <dns/log.h>
-#include <dns/master.h>
-#include <dns/dlz.h>
-#include <dns/ssu.h>
-#include <dns/zone.h>
-
-
-#include <isc/buffer.h>
-#include <isc/magic.h>
-#include <isc/mem.h>
-#include <isc/once.h>
-#include <isc/rwlock.h>
-#include <isc/string.h>
-#include <isc/util.h>
-
-/***
- *** Supported DLZ DB Implementations Registry
- ***/
-
-static ISC_LIST(dns_dlzimplementation_t) dlz_implementations;
-static isc_rwlock_t dlz_implock;
-static isc_once_t once = ISC_ONCE_INIT;
-
-static void
-dlz_initialize(void) {
- RUNTIME_CHECK(isc_rwlock_init(&dlz_implock, 0, 0) == ISC_R_SUCCESS);
- ISC_LIST_INIT(dlz_implementations);
-}
-
-/*%
- * Searches the dlz_implementations list for a driver matching name.
- */
-static inline dns_dlzimplementation_t *
-dlz_impfind(const char *name) {
- dns_dlzimplementation_t *imp;
-
- for (imp = ISC_LIST_HEAD(dlz_implementations);
- imp != NULL;
- imp = ISC_LIST_NEXT(imp, link))
- if (strcasecmp(name, imp->name) == 0)
- return (imp);
- return (NULL);
-}
-
-/***
- *** Basic DLZ Methods
- ***/
-
-isc_result_t
-dns_dlzallowzonexfr(dns_view_t *view, dns_name_t *name,
- isc_sockaddr_t *clientaddr, dns_db_t **dbp)
-{
- isc_result_t result;
- dns_dlzallowzonexfr_t allowzonexfr;
- dns_dlzdb_t *dlzdatabase;
-
- /*
- * Performs checks to make sure data is as we expect it to be.
- */
- REQUIRE(DNS_DLZ_VALID(view->dlzdatabase));
- REQUIRE(name != NULL);
- REQUIRE(dbp != NULL && *dbp == NULL);
-
- /* ask driver if the zone is supported */
- dlzdatabase = view->dlzdatabase;
- allowzonexfr = dlzdatabase->implementation->methods->allowzonexfr;
- result = (*allowzonexfr)(dlzdatabase->implementation->driverarg,
- dlzdatabase->dbdata, dlzdatabase->mctx,
- view->rdclass, name, clientaddr, dbp);
-
- if (result == ISC_R_NOTIMPLEMENTED)
- return (ISC_R_NOTFOUND);
- return (result);
-}
-
-isc_result_t
-dns_dlzcreate(isc_mem_t *mctx, const char *dlzname, const char *drivername,
- unsigned int argc, char *argv[], dns_dlzdb_t **dbp)
-{
- dns_dlzimplementation_t *impinfo;
- isc_result_t result;
- dns_dlzdb_t *db = NULL;
-
- /*
- * initialize the dlz_implementations list, this is guaranteed
- * to only really happen once.
- */
- RUNTIME_CHECK(isc_once_do(&once, dlz_initialize) == ISC_R_SUCCESS);
-
- /*
- * Performs checks to make sure data is as we expect it to be.
- */
- REQUIRE(dbp != NULL && *dbp == NULL);
- REQUIRE(dlzname != NULL);
- REQUIRE(drivername != NULL);
- REQUIRE(mctx != NULL);
-
- /* write log message */
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_DLZ, ISC_LOG_INFO,
- "Loading '%s' using driver %s", dlzname, drivername);
-
- /* lock the dlz_implementations list so we can search it. */
- RWLOCK(&dlz_implock, isc_rwlocktype_read);
-
- /* search for the driver implementation */
- impinfo = dlz_impfind(drivername);
- if (impinfo == NULL) {
- RWUNLOCK(&dlz_implock, isc_rwlocktype_read);
-
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
- "unsupported DLZ database driver '%s'."
- " %s not loaded.",
- drivername, dlzname);
-
- return (ISC_R_NOTFOUND);
- }
-
- /* Allocate memory to hold the DLZ database driver */
- db = isc_mem_get(mctx, sizeof(dns_dlzdb_t));
- if (db == NULL) {
- RWUNLOCK(&dlz_implock, isc_rwlocktype_read);
- return (ISC_R_NOMEMORY);
- }
-
- /* Make sure memory region is set to all 0's */
- memset(db, 0, sizeof(dns_dlzdb_t));
-
- db->implementation = impinfo;
-
- /* Create a new database using implementation 'drivername'. */
- result = ((impinfo->methods->create)(mctx, dlzname, argc, argv,
- impinfo->driverarg,
- &db->dbdata));
-
- /* mark the DLZ driver as valid */
- if (result == ISC_R_SUCCESS) {
- RWUNLOCK(&dlz_implock, isc_rwlocktype_read);
- db->magic = DNS_DLZ_MAGIC;
- isc_mem_attach(mctx, &db->mctx);
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
- "DLZ driver loaded successfully.");
- *dbp = db;
- return (ISC_R_SUCCESS);
- } else {
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
- "DLZ driver failed to load.");
- }
-
- /* impinfo->methods->create failed. */
- RWUNLOCK(&dlz_implock, isc_rwlocktype_read);
- isc_mem_put(mctx, db, sizeof(dns_dlzdb_t));
- return (result);
-}
-
-void
-dns_dlzdestroy(dns_dlzdb_t **dbp) {
- isc_mem_t *mctx;
- dns_dlzdestroy_t destroy;
-
- /* Write debugging message to log */
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
- "Unloading DLZ driver.");
-
- /*
- * Perform checks to make sure data is as we expect it to be.
- */
- 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;
- destroy = (*dbp)->implementation->methods->destroy;
- (*destroy)((*dbp)->implementation->driverarg,(*dbp)->dbdata);
- /* return memory */
- isc_mem_put(mctx, (*dbp), sizeof(dns_dlzdb_t));
- isc_mem_detach(&mctx);
- }
-
- *dbp = NULL;
-}
-
-
-isc_result_t
-dns_dlzfindzone(dns_view_t *view, dns_name_t *name, unsigned int minlabels,
- dns_db_t **dbp)
-{
- dns_fixedname_t fname;
- dns_name_t *zonename;
- unsigned int namelabels;
- unsigned int i;
- isc_result_t result;
- dns_dlzfindzone_t findzone;
- dns_dlzdb_t *dlzdatabase;
-
- /*
- * Performs checks to make sure data is as we expect it to be.
- */
- REQUIRE(DNS_DLZ_VALID(view->dlzdatabase));
- REQUIRE(name != NULL);
- REQUIRE(dbp != NULL && *dbp == NULL);
-
- /* setup a "fixed" dns name */
- dns_fixedname_init(&fname);
- zonename = dns_fixedname_name(&fname);
-
- /* count the number of labels in the name */
- namelabels = dns_name_countlabels(name);
-
- /*
- * loop through starting with the longest domain name and
- * trying shorter names portions of the name until we find a
- * match, have an error, or are below the 'minlabels'
- * threshold. minlabels is 0, if the standard database didn't
- * have a zone name match. Otherwise minlabels is the number
- * of labels in that name. We need to beat that for a
- * "better" match for the DLZ database to be authoritative
- * instead of the standard database.
- */
- for (i = namelabels; i > minlabels && i > 1; i--) {
- if (i == namelabels) {
- result = dns_name_copy(name, zonename, NULL);
- if (result != ISC_R_SUCCESS)
- return (result);
- } else
- dns_name_split(name, i, NULL, zonename);
-
- /* ask SDLZ driver if the zone is supported */
- dlzdatabase = view->dlzdatabase;
- findzone = dlzdatabase->implementation->methods->findzone;
- result = (*findzone)(dlzdatabase->implementation->driverarg,
- dlzdatabase->dbdata, dlzdatabase->mctx,
- view->rdclass, zonename, dbp);
- if (result != ISC_R_NOTFOUND)
- return (result);
- }
- return (ISC_R_NOTFOUND);
-}
-
-/*%
- * Registers a DLZ driver. This basically just adds the dlz
- * driver to the list of available drivers in the dlz_implementations list.
- */
-isc_result_t
-dns_dlzregister(const char *drivername, const dns_dlzmethods_t *methods,
- void *driverarg, isc_mem_t *mctx,
- dns_dlzimplementation_t **dlzimp)
-{
-
- dns_dlzimplementation_t *dlz_imp;
-
- /* Write debugging message to log */
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
- "Registering DLZ driver '%s'", drivername);
-
- /*
- * Performs checks to make sure data is as we expect it to be.
- */
- REQUIRE(drivername != NULL);
- REQUIRE(methods != NULL);
- REQUIRE(methods->create != NULL);
- REQUIRE(methods->destroy != NULL);
- REQUIRE(methods->findzone != NULL);
- REQUIRE(mctx != NULL);
- REQUIRE(dlzimp != NULL && *dlzimp == NULL);
-
- /*
- * initialize the dlz_implementations list, this is guaranteed
- * to only really happen once.
- */
- RUNTIME_CHECK(isc_once_do(&once, dlz_initialize) == ISC_R_SUCCESS);
-
- /* lock the dlz_implementations list so we can modify it. */
- RWLOCK(&dlz_implock, isc_rwlocktype_write);
-
- /*
- * check that another already registered driver isn't using
- * the same name
- */
- dlz_imp = dlz_impfind(drivername);
- if (dlz_imp != NULL) {
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
- "DLZ Driver '%s' already registered",
- drivername);
- RWUNLOCK(&dlz_implock, isc_rwlocktype_write);
- return (ISC_R_EXISTS);
- }
-
- /*
- * Allocate memory for a dlz_implementation object. Error if
- * we cannot.
- */
- dlz_imp = isc_mem_get(mctx, sizeof(dns_dlzimplementation_t));
- if (dlz_imp == NULL) {
- RWUNLOCK(&dlz_implock, isc_rwlocktype_write);
- return (ISC_R_NOMEMORY);
- }
-
- /* Make sure memory region is set to all 0's */
- memset(dlz_imp, 0, sizeof(dns_dlzimplementation_t));
-
- /* Store the data passed into this method */
- dlz_imp->name = drivername;
- dlz_imp->methods = methods;
- dlz_imp->mctx = NULL;
- dlz_imp->driverarg = driverarg;
-
- /* attach the new dlz_implementation object to a memory context */
- isc_mem_attach(mctx, &dlz_imp->mctx);
-
- /*
- * prepare the dlz_implementation object to be put in a list,
- * and append it to the list
- */
- ISC_LINK_INIT(dlz_imp, link);
- ISC_LIST_APPEND(dlz_implementations, dlz_imp, link);
-
- /* Unlock the dlz_implementations list. */
- RWUNLOCK(&dlz_implock, isc_rwlocktype_write);
-
- /* Pass back the dlz_implementation that we created. */
- *dlzimp = dlz_imp;
-
- return (ISC_R_SUCCESS);
-}
-
-/*%
- * Helper function for dns_dlzstrtoargv().
- * Pardon the gratuitous recursion.
- */
-static isc_result_t
-dns_dlzstrtoargvsub(isc_mem_t *mctx, char *s, unsigned int *argcp,
- char ***argvp, unsigned int n)
-{
- isc_result_t result;
-
- restart:
- /* Discard leading whitespace. */
- while (*s == ' ' || *s == '\t')
- s++;
-
- if (*s == '\0') {
- /* We have reached the end of the string. */
- *argcp = n;
- *argvp = isc_mem_get(mctx, n * sizeof(char *));
- if (*argvp == NULL)
- return (ISC_R_NOMEMORY);
- } else {
- char *p = s;
- while (*p != ' ' && *p != '\t' && *p != '\0' && *p != '{') {
- if (*p == '\n') {
- *p = ' ';
- goto restart;
- }
- p++;
- }
-
- /* do "grouping", items between { and } are one arg */
- if (*p == '{') {
- char *t = p;
- /*
- * shift all characters to left by 1 to get rid of '{'
- */
- while (*t != '\0') {
- t++;
- *(t-1) = *t;
- }
- while (*p != '\0' && *p != '}') {
- p++;
- }
- /* get rid of '}' character */
- if (*p == '}') {
- *p = '\0';
- p++;
- }
- /* normal case, no "grouping" */
- } else if (*p != '\0')
- *p++ = '\0';
-
- result = dns_dlzstrtoargvsub(mctx, p, argcp, argvp, n + 1);
- if (result != ISC_R_SUCCESS)
- return (result);
- (*argvp)[n] = s;
- }
- return (ISC_R_SUCCESS);
-}
-
-/*%
- * Tokenize the string "s" into whitespace-separated words,
- * return the number of words in '*argcp' and an array
- * of pointers to the words in '*argvp'. The caller
- * must free the array using isc_mem_put(). The string
- * is modified in-place.
- */
-isc_result_t
-dns_dlzstrtoargv(isc_mem_t *mctx, char *s,
- unsigned int *argcp, char ***argvp)
-{
- return(dns_dlzstrtoargvsub(mctx, s, argcp, argvp, 0));
-}
-
-/*%
- * Unregisters a DLZ driver. This basically just removes the dlz
- * driver from the list of available drivers in the dlz_implementations list.
- */
-void
-dns_dlzunregister(dns_dlzimplementation_t **dlzimp) {
- dns_dlzimplementation_t *dlz_imp;
- 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 DLZ driver.");
-
- /*
- * Performs checks to make sure data is as we expect it to be.
- */
- REQUIRE(dlzimp != NULL && *dlzimp != NULL);
-
- /*
- * initialize the dlz_implementations list, this is guaranteed
- * to only really happen once.
- */
- RUNTIME_CHECK(isc_once_do(&once, dlz_initialize) == ISC_R_SUCCESS);
-
- dlz_imp = *dlzimp;
-
- /* lock the dlz_implementations list so we can modify it. */
- RWLOCK(&dlz_implock, isc_rwlocktype_write);
-
- /* remove the dlz_implementation object from the list */
- ISC_LIST_UNLINK(dlz_implementations, dlz_imp, link);
- mctx = dlz_imp->mctx;
-
- /*
- * 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));
- isc_mem_detach(&mctx);
-
- /* 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_dlzdb_t *dlzdatabase;
-
- REQUIRE(DNS_DLZ_VALID(view->dlzdatabase));
-
- dlzdatabase = view->dlzdatabase;
-
- REQUIRE(dlzdatabase->configure_callback != NULL);
-
- isc_buffer_constinit(&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);
-
- /* 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);
-
- 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/contrib/bind9/lib/dns/dns64.c b/contrib/bind9/lib/dns/dns64.c
deleted file mode 100644
index 78eff579a2ba..000000000000
--- a/contrib/bind9/lib/dns/dns64.c
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * 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: dns64.c,v 1.8 2011/03/12 04:59:47 tbox 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;
- if (aaaaok == NULL)
- goto done;
- 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/contrib/bind9/lib/dns/dnssec.c b/contrib/bind9/lib/dns/dnssec.c
deleted file mode 100644
index d00c99b4124c..000000000000
--- a/contrib/bind9/lib/dns/dnssec.c
+++ /dev/null
@@ -1,1884 +0,0 @@
-/*
- * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * $Id$
- */
-
-/*! \file */
-
-#include <config.h>
-
-#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>
-#include <dns/rdataset.h>
-#include <dns/rdatastruct.h>
-#include <dns/result.h>
-#include <dns/stats.h>
-#include <dns/tsig.h> /* for DNS_TSIG_FUDGE */
-
-#include <dst/result.h>
-
-LIBDNS_EXTERNAL_DATA isc_stats_t *dns_dnssec_stats;
-
-#define is_response(msg) (msg->flags & DNS_MESSAGEFLAG_QR)
-
-#define RETERR(x) do { \
- result = (x); \
- if (result != ISC_R_SUCCESS) \
- goto failure; \
- } while (0)
-
-
-#define TYPE_SIGN 0
-#define TYPE_VERIFY 1
-
-static isc_result_t
-digest_callback(void *arg, isc_region_t *data);
-
-static int
-rdata_compare_wrapper(const void *rdata1, const void *rdata2);
-
-static isc_result_t
-rdataset_to_sortedarray(dns_rdataset_t *set, isc_mem_t *mctx,
- dns_rdata_t **rdata, int *nrdata);
-
-static isc_result_t
-digest_callback(void *arg, isc_region_t *data) {
- dst_context_t *ctx = arg;
-
- return (dst_context_adddata(ctx, data));
-}
-
-static inline void
-inc_stat(isc_statscounter_t counter) {
- if (dns_dnssec_stats != NULL)
- isc_stats_increment(dns_dnssec_stats, counter);
-}
-
-/*
- * Make qsort happy.
- */
-static int
-rdata_compare_wrapper(const void *rdata1, const void *rdata2) {
- return (dns_rdata_compare((const dns_rdata_t *)rdata1,
- (const dns_rdata_t *)rdata2));
-}
-
-/*
- * Sort the rdataset into an array.
- */
-static isc_result_t
-rdataset_to_sortedarray(dns_rdataset_t *set, isc_mem_t *mctx,
- dns_rdata_t **rdata, int *nrdata)
-{
- isc_result_t ret;
- int i = 0, n;
- dns_rdata_t *data;
- dns_rdataset_t rdataset;
-
- n = dns_rdataset_count(set);
-
- data = isc_mem_get(mctx, n * sizeof(dns_rdata_t));
- if (data == NULL)
- return (ISC_R_NOMEMORY);
-
- dns_rdataset_init(&rdataset);
- dns_rdataset_clone(set, &rdataset);
- ret = dns_rdataset_first(&rdataset);
- if (ret != ISC_R_SUCCESS) {
- dns_rdataset_disassociate(&rdataset);
- isc_mem_put(mctx, data, n * sizeof(dns_rdata_t));
- return (ret);
- }
-
- /*
- * Put them in the array.
- */
- do {
- dns_rdata_init(&data[i]);
- dns_rdataset_current(&rdataset, &data[i++]);
- } while (dns_rdataset_next(&rdataset) == ISC_R_SUCCESS);
-
- /*
- * Sort the array.
- */
- qsort(data, n, sizeof(dns_rdata_t), rdata_compare_wrapper);
- *rdata = data;
- *nrdata = n;
- dns_rdataset_disassociate(&rdataset);
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_dnssec_keyfromrdata(dns_name_t *name, dns_rdata_t *rdata, isc_mem_t *mctx,
- dst_key_t **key)
-{
- isc_buffer_t b;
- isc_region_t r;
-
- INSIST(name != NULL);
- INSIST(rdata != NULL);
- INSIST(mctx != NULL);
- INSIST(key != NULL);
- INSIST(*key == NULL);
- REQUIRE(rdata->type == dns_rdatatype_key ||
- rdata->type == dns_rdatatype_dnskey);
-
- dns_rdata_toregion(rdata, &r);
- isc_buffer_init(&b, r.base, r.length);
- isc_buffer_add(&b, r.length);
- return (dst_key_fromdns(name, rdata->rdclass, &b, mctx, key));
-}
-
-static isc_result_t
-digest_sig(dst_context_t *ctx, isc_boolean_t downcase, dns_rdata_t *sigrdata,
- dns_rdata_rrsig_t *rrsig)
-{
- isc_region_t r;
- isc_result_t ret;
- dns_fixedname_t fname;
-
- dns_rdata_toregion(sigrdata, &r);
- INSIST(r.length >= 19);
-
- r.length = 18;
- ret = dst_context_adddata(ctx, &r);
- if (ret != ISC_R_SUCCESS)
- return (ret);
- if (downcase) {
- dns_fixedname_init(&fname);
-
- RUNTIME_CHECK(dns_name_downcase(&rrsig->signer,
- dns_fixedname_name(&fname),
- NULL) == ISC_R_SUCCESS);
- dns_name_toregion(dns_fixedname_name(&fname), &r);
- } else
- dns_name_toregion(&rrsig->signer, &r);
-
- return (dst_context_adddata(ctx, &r));
-}
-
-isc_result_t
-dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
- isc_stdtime_t *inception, isc_stdtime_t *expire,
- isc_mem_t *mctx, isc_buffer_t *buffer, dns_rdata_t *sigrdata)
-{
- dns_rdata_rrsig_t sig;
- dns_rdata_t tmpsigrdata;
- dns_rdata_t *rdatas;
- int nrdatas, i;
- isc_buffer_t sigbuf, envbuf;
- isc_region_t r;
- dst_context_t *ctx = NULL;
- isc_result_t ret;
- isc_buffer_t *databuf = NULL;
- char data[256 + 8];
- isc_uint32_t flags;
- unsigned int sigsize;
- dns_fixedname_t fnewname;
- dns_fixedname_t fsigner;
-
- REQUIRE(name != NULL);
- REQUIRE(dns_name_countlabels(name) <= 255);
- REQUIRE(set != NULL);
- REQUIRE(key != NULL);
- REQUIRE(inception != NULL);
- REQUIRE(expire != NULL);
- REQUIRE(mctx != NULL);
- REQUIRE(sigrdata != NULL);
-
- if (*inception >= *expire)
- return (DNS_R_INVALIDTIME);
-
- /*
- * Is the key allowed to sign data?
- */
- flags = dst_key_flags(key);
- if (flags & DNS_KEYTYPE_NOAUTH)
- return (DNS_R_KEYUNAUTHORIZED);
- if ((flags & DNS_KEYFLAG_OWNERMASK) != DNS_KEYOWNER_ZONE)
- return (DNS_R_KEYUNAUTHORIZED);
-
- sig.mctx = mctx;
- sig.common.rdclass = set->rdclass;
- sig.common.rdtype = dns_rdatatype_rrsig;
- ISC_LINK_INIT(&sig.common, link);
-
- /*
- * Downcase signer.
- */
- dns_name_init(&sig.signer, NULL);
- dns_fixedname_init(&fsigner);
- RUNTIME_CHECK(dns_name_downcase(dst_key_name(key),
- dns_fixedname_name(&fsigner), NULL) == ISC_R_SUCCESS);
- dns_name_clone(dns_fixedname_name(&fsigner), &sig.signer);
-
- sig.covered = set->type;
- sig.algorithm = dst_key_alg(key);
- sig.labels = dns_name_countlabels(name) - 1;
- if (dns_name_iswildcard(name))
- sig.labels--;
- sig.originalttl = set->ttl;
- sig.timesigned = *inception;
- sig.timeexpire = *expire;
- sig.keyid = dst_key_id(key);
- ret = dst_key_sigsize(key, &sigsize);
- if (ret != ISC_R_SUCCESS)
- return (ret);
- sig.siglen = sigsize;
- /*
- * The actual contents of sig.signature are not important yet, since
- * they're not used in digest_sig().
- */
- sig.signature = isc_mem_get(mctx, sig.siglen);
- if (sig.signature == NULL)
- return (ISC_R_NOMEMORY);
-
- ret = isc_buffer_allocate(mctx, &databuf, sigsize + 256 + 18);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_signature;
-
- dns_rdata_init(&tmpsigrdata);
- ret = dns_rdata_fromstruct(&tmpsigrdata, sig.common.rdclass,
- sig.common.rdtype, &sig, databuf);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_databuf;
-
- ret = dst_context_create2(key, mctx, DNS_LOGCATEGORY_DNSSEC, &ctx);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_databuf;
-
- /*
- * Digest the SIG rdata.
- */
- ret = digest_sig(ctx, ISC_FALSE, &tmpsigrdata, &sig);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_context;
-
- dns_fixedname_init(&fnewname);
- RUNTIME_CHECK(dns_name_downcase(name, dns_fixedname_name(&fnewname),
- NULL) == ISC_R_SUCCESS);
- dns_name_toregion(dns_fixedname_name(&fnewname), &r);
-
- /*
- * Create an envelope for each rdata: <name|type|class|ttl>.
- */
- isc_buffer_init(&envbuf, data, sizeof(data));
- memcpy(data, r.base, r.length);
- isc_buffer_add(&envbuf, r.length);
- isc_buffer_putuint16(&envbuf, set->type);
- isc_buffer_putuint16(&envbuf, set->rdclass);
- isc_buffer_putuint32(&envbuf, set->ttl);
-
- ret = rdataset_to_sortedarray(set, mctx, &rdatas, &nrdatas);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_context;
- isc_buffer_usedregion(&envbuf, &r);
-
- for (i = 0; i < nrdatas; i++) {
- isc_uint16_t len;
- isc_buffer_t lenbuf;
- isc_region_t lenr;
-
- /*
- * Skip duplicates.
- */
- if (i > 0 && dns_rdata_compare(&rdatas[i], &rdatas[i-1]) == 0)
- continue;
-
- /*
- * Digest the envelope.
- */
- ret = dst_context_adddata(ctx, &r);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_array;
-
- /*
- * Digest the length of the rdata.
- */
- isc_buffer_init(&lenbuf, &len, sizeof(len));
- INSIST(rdatas[i].length < 65536);
- isc_buffer_putuint16(&lenbuf, (isc_uint16_t)rdatas[i].length);
- isc_buffer_usedregion(&lenbuf, &lenr);
- ret = dst_context_adddata(ctx, &lenr);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_array;
-
- /*
- * Digest the rdata.
- */
- ret = dns_rdata_digest(&rdatas[i], digest_callback, ctx);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_array;
- }
-
- isc_buffer_init(&sigbuf, sig.signature, sig.siglen);
- ret = dst_context_sign(ctx, &sigbuf);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_array;
- isc_buffer_usedregion(&sigbuf, &r);
- if (r.length != sig.siglen) {
- ret = ISC_R_NOSPACE;
- goto cleanup_array;
- }
-
- ret = dns_rdata_fromstruct(sigrdata, sig.common.rdclass,
- sig.common.rdtype, &sig, buffer);
-
-cleanup_array:
- isc_mem_put(mctx, rdatas, nrdatas * sizeof(dns_rdata_t));
-cleanup_context:
- dst_context_destroy(&ctx);
-cleanup_databuf:
- isc_buffer_free(&databuf);
-cleanup_signature:
- isc_mem_put(mctx, sig.signature, sig.siglen);
-
- return (ret);
-}
-
-isc_result_t
-dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
- isc_boolean_t ignoretime, isc_mem_t *mctx,
- dns_rdata_t *sigrdata, dns_name_t *wild)
-{
- return (dns_dnssec_verify3(name, set, key, ignoretime, 0, mctx,
- sigrdata, wild));
-}
-
-isc_result_t
-dns_dnssec_verify3(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
- isc_boolean_t ignoretime, unsigned int maxbits,
- isc_mem_t *mctx, dns_rdata_t *sigrdata, dns_name_t *wild)
-{
- dns_rdata_rrsig_t sig;
- dns_fixedname_t fnewname;
- isc_region_t r;
- isc_buffer_t envbuf;
- dns_rdata_t *rdatas;
- int nrdatas, i;
- isc_stdtime_t now;
- isc_result_t ret;
- unsigned char data[300];
- dst_context_t *ctx = NULL;
- int labels = 0;
- isc_uint32_t flags;
- isc_boolean_t downcase = ISC_FALSE;
-
- REQUIRE(name != NULL);
- REQUIRE(set != NULL);
- REQUIRE(key != NULL);
- REQUIRE(mctx != NULL);
- REQUIRE(sigrdata != NULL && sigrdata->type == dns_rdatatype_rrsig);
-
- ret = dns_rdata_tostruct(sigrdata, &sig, NULL);
- if (ret != ISC_R_SUCCESS)
- return (ret);
-
- if (set->type != sig.covered)
- return (DNS_R_SIGINVALID);
-
- if (isc_serial_lt(sig.timeexpire, sig.timesigned)) {
- inc_stat(dns_dnssecstats_fail);
- return (DNS_R_SIGINVALID);
- }
-
- if (!ignoretime) {
- isc_stdtime_get(&now);
-
- /*
- * Is SIG temporally valid?
- */
- if (isc_serial_lt((isc_uint32_t)now, sig.timesigned)) {
- inc_stat(dns_dnssecstats_fail);
- return (DNS_R_SIGFUTURE);
- } else if (isc_serial_lt(sig.timeexpire, (isc_uint32_t)now)) {
- inc_stat(dns_dnssecstats_fail);
- return (DNS_R_SIGEXPIRED);
- }
- }
-
- /*
- * NS, SOA and DNSSKEY records are signed by their owner.
- * DS records are signed by the parent.
- */
- switch (set->type) {
- case dns_rdatatype_ns:
- case dns_rdatatype_soa:
- case dns_rdatatype_dnskey:
- if (!dns_name_equal(name, &sig.signer)) {
- inc_stat(dns_dnssecstats_fail);
- return (DNS_R_SIGINVALID);
- }
- break;
- case dns_rdatatype_ds:
- if (dns_name_equal(name, &sig.signer)) {
- inc_stat(dns_dnssecstats_fail);
- return (DNS_R_SIGINVALID);
- }
- /* FALLTHROUGH */
- default:
- if (!dns_name_issubdomain(name, &sig.signer)) {
- inc_stat(dns_dnssecstats_fail);
- return (DNS_R_SIGINVALID);
- }
- break;
- }
-
- /*
- * Is the key allowed to sign data?
- */
- flags = dst_key_flags(key);
- if (flags & DNS_KEYTYPE_NOAUTH) {
- inc_stat(dns_dnssecstats_fail);
- return (DNS_R_KEYUNAUTHORIZED);
- }
- if ((flags & DNS_KEYFLAG_OWNERMASK) != DNS_KEYOWNER_ZONE) {
- inc_stat(dns_dnssecstats_fail);
- return (DNS_R_KEYUNAUTHORIZED);
- }
-
- again:
- ret = dst_context_create2(key, mctx, DNS_LOGCATEGORY_DNSSEC, &ctx);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_struct;
-
- /*
- * Digest the SIG rdata (not including the signature).
- */
- ret = digest_sig(ctx, downcase, sigrdata, &sig);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_context;
-
- /*
- * If the name is an expanded wildcard, use the wildcard name.
- */
- dns_fixedname_init(&fnewname);
- labels = dns_name_countlabels(name) - 1;
- RUNTIME_CHECK(dns_name_downcase(name, dns_fixedname_name(&fnewname),
- NULL) == ISC_R_SUCCESS);
- if (labels - sig.labels > 0)
- dns_name_split(dns_fixedname_name(&fnewname), sig.labels + 1,
- NULL, dns_fixedname_name(&fnewname));
-
- dns_name_toregion(dns_fixedname_name(&fnewname), &r);
-
- /*
- * Create an envelope for each rdata: <name|type|class|ttl>.
- */
- isc_buffer_init(&envbuf, data, sizeof(data));
- if (labels - sig.labels > 0) {
- isc_buffer_putuint8(&envbuf, 1);
- isc_buffer_putuint8(&envbuf, '*');
- memcpy(data + 2, r.base, r.length);
- }
- else
- memcpy(data, r.base, r.length);
- isc_buffer_add(&envbuf, r.length);
- isc_buffer_putuint16(&envbuf, set->type);
- isc_buffer_putuint16(&envbuf, set->rdclass);
- isc_buffer_putuint32(&envbuf, sig.originalttl);
-
- ret = rdataset_to_sortedarray(set, mctx, &rdatas, &nrdatas);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_context;
-
- isc_buffer_usedregion(&envbuf, &r);
-
- for (i = 0; i < nrdatas; i++) {
- isc_uint16_t len;
- isc_buffer_t lenbuf;
- isc_region_t lenr;
-
- /*
- * Skip duplicates.
- */
- if (i > 0 && dns_rdata_compare(&rdatas[i], &rdatas[i-1]) == 0)
- continue;
-
- /*
- * Digest the envelope.
- */
- ret = dst_context_adddata(ctx, &r);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_array;
-
- /*
- * Digest the rdata length.
- */
- isc_buffer_init(&lenbuf, &len, sizeof(len));
- INSIST(rdatas[i].length < 65536);
- isc_buffer_putuint16(&lenbuf, (isc_uint16_t)rdatas[i].length);
- isc_buffer_usedregion(&lenbuf, &lenr);
-
- /*
- * Digest the rdata.
- */
- ret = dst_context_adddata(ctx, &lenr);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_array;
- ret = dns_rdata_digest(&rdatas[i], digest_callback, ctx);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_array;
- }
-
- r.base = sig.signature;
- r.length = sig.siglen;
- ret = dst_context_verify2(ctx, maxbits, &r);
- if (ret == ISC_R_SUCCESS && downcase) {
- char namebuf[DNS_NAME_FORMATSIZE];
- dns_name_format(&sig.signer, namebuf, sizeof(namebuf));
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC,
- DNS_LOGMODULE_DNSSEC, ISC_LOG_DEBUG(1),
- "successfully validated after lower casing "
- "signer '%s'", namebuf);
- inc_stat(dns_dnssecstats_downcase);
- } else if (ret == ISC_R_SUCCESS)
- inc_stat(dns_dnssecstats_asis);
-
-cleanup_array:
- isc_mem_put(mctx, rdatas, nrdatas * sizeof(dns_rdata_t));
-cleanup_context:
- dst_context_destroy(&ctx);
- if (ret == DST_R_VERIFYFAILURE && !downcase) {
- downcase = ISC_TRUE;
- goto again;
- }
-cleanup_struct:
- dns_rdata_freestruct(&sig);
-
- if (ret == DST_R_VERIFYFAILURE)
- ret = DNS_R_SIGINVALID;
-
- if (ret != ISC_R_SUCCESS)
- inc_stat(dns_dnssecstats_fail);
-
- if (ret == ISC_R_SUCCESS && labels - sig.labels > 0) {
- if (wild != NULL)
- RUNTIME_CHECK(dns_name_concatenate(dns_wildcardname,
- dns_fixedname_name(&fnewname),
- wild, NULL) == ISC_R_SUCCESS);
- inc_stat(dns_dnssecstats_wildcard);
- ret = DNS_R_FROMWILDCARD;
- }
- return (ret);
-}
-
-isc_result_t
-dns_dnssec_verify(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
- isc_boolean_t ignoretime, isc_mem_t *mctx,
- dns_rdata_t *sigrdata)
-{
- isc_result_t result;
-
- result = dns_dnssec_verify2(name, set, key, ignoretime, mctx,
- sigrdata, NULL);
- if (result == DNS_R_FROMWILDCARD)
- result = ISC_R_SUCCESS;
- return (result);
-}
-
-static isc_boolean_t
-key_active(dst_key_t *key, isc_stdtime_t now) {
- isc_result_t result;
- isc_stdtime_t 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);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
-
- /*
- * Smart signing started with key format 1.3; prior to that, all
- * keys are assumed active
- */
- if (major == 1 && minor <= 2)
- return (ISC_TRUE);
-
- 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)
-
-isc_result_t
-dns_dnssec_findzonekeys2(dns_db_t *db, dns_dbversion_t *ver,
- dns_dbnode_t *node, dns_name_t *name,
- const char *directory, isc_mem_t *mctx,
- unsigned int maxkeys, dst_key_t **keys,
- unsigned int *nkeys)
-{
- dns_rdataset_t rdataset;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- isc_result_t result;
- dst_key_t *pubkey = NULL;
- unsigned int count = 0;
- isc_stdtime_t now;
-
- REQUIRE(nkeys != NULL);
- REQUIRE(keys != NULL);
-
- isc_stdtime_get(&now);
-
- *nkeys = 0;
- dns_rdataset_init(&rdataset);
- RETERR(dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 0, 0,
- &rdataset, NULL));
- RETERR(dns_rdataset_first(&rdataset));
- while (result == ISC_R_SUCCESS && count < maxkeys) {
- pubkey = NULL;
- dns_rdataset_current(&rdataset, &rdata);
- RETERR(dns_dnssec_keyfromrdata(name, &rdata, mctx, &pubkey));
- dst_key_setttl(pubkey, rdataset.ttl);
-
- if (!is_zone_key(pubkey) ||
- (dst_key_flags(pubkey) & DNS_KEYTYPE_NOAUTH) != 0)
- goto next;
- /* Corrupted .key file? */
- if (!dns_name_equal(name, dst_key_name(pubkey)))
- goto next;
- keys[count] = NULL;
- 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 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], now)) {
- dst_key_free(&keys[count]);
- keys[count] = pubkey;
- pubkey = NULL;
- count++;
- goto next;
- }
-
- /*
- * Whatever the key's default TTL may have
- * been, the rdataset TTL takes priority.
- */
- dst_key_setttl(keys[count], rdataset.ttl);
-
- if ((dst_key_flags(keys[count]) & DNS_KEYTYPE_NOAUTH) != 0) {
- /* We should never get here. */
- dst_key_free(&keys[count]);
- goto next;
- }
- count++;
- next:
- if (pubkey != NULL)
- dst_key_free(&pubkey);
- dns_rdata_reset(&rdata);
- result = dns_rdataset_next(&rdataset);
- }
- if (result != ISC_R_NOMORE)
- goto failure;
- if (count == 0)
- result = ISC_R_NOTFOUND;
- else
- result = ISC_R_SUCCESS;
-
- failure:
- if (dns_rdataset_isassociated(&rdataset))
- dns_rdataset_disassociate(&rdataset);
- if (pubkey != NULL)
- dst_key_free(&pubkey);
- if (result != ISC_R_SUCCESS)
- while (count > 0)
- dst_key_free(&keys[--count]);
- *nkeys = count;
- return (result);
-}
-
-isc_result_t
-dns_dnssec_findzonekeys(dns_db_t *db, dns_dbversion_t *ver,
- dns_dbnode_t *node, dns_name_t *name, isc_mem_t *mctx,
- unsigned int maxkeys, dst_key_t **keys,
- unsigned int *nkeys)
-{
- return (dns_dnssec_findzonekeys2(db, ver, node, name, NULL, mctx,
- maxkeys, keys, nkeys));
-}
-
-isc_result_t
-dns_dnssec_signmessage(dns_message_t *msg, dst_key_t *key) {
- dns_rdata_sig_t sig; /* SIG(0) */
- unsigned char data[512];
- unsigned char header[DNS_MESSAGE_HEADERLEN];
- isc_buffer_t headerbuf, databuf, sigbuf;
- unsigned int sigsize;
- isc_buffer_t *dynbuf = NULL;
- dns_rdata_t *rdata;
- dns_rdatalist_t *datalist;
- dns_rdataset_t *dataset;
- isc_region_t r;
- isc_stdtime_t now;
- dst_context_t *ctx = NULL;
- isc_mem_t *mctx;
- isc_result_t result;
- isc_boolean_t signeedsfree = ISC_TRUE;
-
- REQUIRE(msg != NULL);
- REQUIRE(key != NULL);
-
- if (is_response(msg))
- REQUIRE(msg->query.base != NULL);
-
- mctx = msg->mctx;
-
- memset(&sig, 0, sizeof(sig));
-
- sig.mctx = mctx;
- sig.common.rdclass = dns_rdataclass_any;
- sig.common.rdtype = dns_rdatatype_sig; /* SIG(0) */
- ISC_LINK_INIT(&sig.common, link);
-
- sig.covered = 0;
- sig.algorithm = dst_key_alg(key);
- sig.labels = 0; /* the root name */
- sig.originalttl = 0;
-
- isc_stdtime_get(&now);
- sig.timesigned = now - DNS_TSIG_FUDGE;
- sig.timeexpire = now + DNS_TSIG_FUDGE;
-
- sig.keyid = dst_key_id(key);
-
- dns_name_init(&sig.signer, NULL);
- dns_name_clone(dst_key_name(key), &sig.signer);
-
- sig.siglen = 0;
- sig.signature = NULL;
-
- isc_buffer_init(&databuf, data, sizeof(data));
-
- RETERR(dst_context_create2(key, mctx, DNS_LOGCATEGORY_DNSSEC, &ctx));
-
- /*
- * Digest the fields of the SIG - we can cheat and use
- * dns_rdata_fromstruct. Since siglen is 0, the digested data
- * is identical to dns format.
- */
- RETERR(dns_rdata_fromstruct(NULL, dns_rdataclass_any,
- dns_rdatatype_sig /* SIG(0) */,
- &sig, &databuf));
- isc_buffer_usedregion(&databuf, &r);
- RETERR(dst_context_adddata(ctx, &r));
-
- /*
- * If this is a response, digest the query.
- */
- if (is_response(msg))
- RETERR(dst_context_adddata(ctx, &msg->query));
-
- /*
- * Digest the header.
- */
- isc_buffer_init(&headerbuf, header, sizeof(header));
- dns_message_renderheader(msg, &headerbuf);
- isc_buffer_usedregion(&headerbuf, &r);
- RETERR(dst_context_adddata(ctx, &r));
-
- /*
- * Digest the remainder of the message.
- */
- isc_buffer_usedregion(msg->buffer, &r);
- isc_region_consume(&r, DNS_MESSAGE_HEADERLEN);
- RETERR(dst_context_adddata(ctx, &r));
-
- RETERR(dst_key_sigsize(key, &sigsize));
- sig.siglen = sigsize;
- sig.signature = (unsigned char *) isc_mem_get(mctx, sig.siglen);
- if (sig.signature == NULL) {
- result = ISC_R_NOMEMORY;
- goto failure;
- }
-
- isc_buffer_init(&sigbuf, sig.signature, sig.siglen);
- RETERR(dst_context_sign(ctx, &sigbuf));
- dst_context_destroy(&ctx);
-
- rdata = NULL;
- RETERR(dns_message_gettemprdata(msg, &rdata));
- RETERR(isc_buffer_allocate(msg->mctx, &dynbuf, 1024));
- RETERR(dns_rdata_fromstruct(rdata, dns_rdataclass_any,
- dns_rdatatype_sig /* SIG(0) */,
- &sig, dynbuf));
-
- isc_mem_put(mctx, sig.signature, sig.siglen);
- signeedsfree = ISC_FALSE;
-
- dns_message_takebuffer(msg, &dynbuf);
-
- datalist = NULL;
- RETERR(dns_message_gettemprdatalist(msg, &datalist));
- datalist->rdclass = dns_rdataclass_any;
- datalist->type = dns_rdatatype_sig; /* SIG(0) */
- datalist->covers = 0;
- datalist->ttl = 0;
- ISC_LIST_INIT(datalist->rdata);
- ISC_LIST_APPEND(datalist->rdata, rdata, link);
- dataset = NULL;
- RETERR(dns_message_gettemprdataset(msg, &dataset));
- dns_rdataset_init(dataset);
- RUNTIME_CHECK(dns_rdatalist_tordataset(datalist, dataset) == ISC_R_SUCCESS);
- msg->sig0 = dataset;
-
- return (ISC_R_SUCCESS);
-
-failure:
- if (dynbuf != NULL)
- isc_buffer_free(&dynbuf);
- if (signeedsfree)
- isc_mem_put(mctx, sig.signature, sig.siglen);
- if (ctx != NULL)
- dst_context_destroy(&ctx);
-
- return (result);
-}
-
-isc_result_t
-dns_dnssec_verifymessage(isc_buffer_t *source, dns_message_t *msg,
- dst_key_t *key)
-{
- dns_rdata_sig_t sig; /* SIG(0) */
- unsigned char header[DNS_MESSAGE_HEADERLEN];
- dns_rdata_t rdata = DNS_RDATA_INIT;
- isc_region_t r, source_r, sig_r, header_r;
- isc_stdtime_t now;
- dst_context_t *ctx = NULL;
- isc_mem_t *mctx;
- isc_result_t result;
- isc_uint16_t addcount;
- isc_boolean_t signeedsfree = ISC_FALSE;
-
- REQUIRE(source != NULL);
- REQUIRE(msg != NULL);
- REQUIRE(key != NULL);
-
- mctx = msg->mctx;
-
- msg->verify_attempted = 1;
-
- if (is_response(msg)) {
- if (msg->query.base == NULL)
- return (DNS_R_UNEXPECTEDTSIG);
- }
-
- isc_buffer_usedregion(source, &source_r);
-
- RETERR(dns_rdataset_first(msg->sig0));
- dns_rdataset_current(msg->sig0, &rdata);
-
- RETERR(dns_rdata_tostruct(&rdata, &sig, NULL));
- signeedsfree = ISC_TRUE;
-
- if (sig.labels != 0) {
- result = DNS_R_SIGINVALID;
- goto failure;
- }
-
- if (isc_serial_lt(sig.timeexpire, sig.timesigned)) {
- result = DNS_R_SIGINVALID;
- msg->sig0status = dns_tsigerror_badtime;
- goto failure;
- }
-
- isc_stdtime_get(&now);
- if (isc_serial_lt((isc_uint32_t)now, sig.timesigned)) {
- result = DNS_R_SIGFUTURE;
- msg->sig0status = dns_tsigerror_badtime;
- goto failure;
- }
- else if (isc_serial_lt(sig.timeexpire, (isc_uint32_t)now)) {
- result = DNS_R_SIGEXPIRED;
- msg->sig0status = dns_tsigerror_badtime;
- goto failure;
- }
-
- if (!dns_name_equal(dst_key_name(key), &sig.signer)) {
- result = DNS_R_SIGINVALID;
- msg->sig0status = dns_tsigerror_badkey;
- goto failure;
- }
-
- RETERR(dst_context_create2(key, mctx, DNS_LOGCATEGORY_DNSSEC, &ctx));
-
- /*
- * Digest the SIG(0) record, except for the signature.
- */
- dns_rdata_toregion(&rdata, &r);
- r.length -= sig.siglen;
- RETERR(dst_context_adddata(ctx, &r));
-
- /*
- * If this is a response, digest the query.
- */
- if (is_response(msg))
- RETERR(dst_context_adddata(ctx, &msg->query));
-
- /*
- * Extract the header.
- */
- memcpy(header, source_r.base, DNS_MESSAGE_HEADERLEN);
-
- /*
- * Decrement the additional field counter.
- */
- memcpy(&addcount, &header[DNS_MESSAGE_HEADERLEN - 2], 2);
- addcount = htons((isc_uint16_t)(ntohs(addcount) - 1));
- memcpy(&header[DNS_MESSAGE_HEADERLEN - 2], &addcount, 2);
-
- /*
- * Digest the modified header.
- */
- header_r.base = (unsigned char *) header;
- header_r.length = DNS_MESSAGE_HEADERLEN;
- RETERR(dst_context_adddata(ctx, &header_r));
-
- /*
- * Digest all non-SIG(0) records.
- */
- r.base = source_r.base + DNS_MESSAGE_HEADERLEN;
- r.length = msg->sigstart - DNS_MESSAGE_HEADERLEN;
- RETERR(dst_context_adddata(ctx, &r));
-
- sig_r.base = sig.signature;
- sig_r.length = sig.siglen;
- result = dst_context_verify(ctx, &sig_r);
- if (result != ISC_R_SUCCESS) {
- msg->sig0status = dns_tsigerror_badsig;
- goto failure;
- }
-
- msg->verified_sig = 1;
-
- dst_context_destroy(&ctx);
- dns_rdata_freestruct(&sig);
-
- return (ISC_R_SUCCESS);
-
-failure:
- if (signeedsfree)
- dns_rdata_freestruct(&sig);
- if (ctx != NULL)
- dst_context_destroy(&ctx);
-
- return (result);
-}
-
-/*%
- * Does this key ('rdata') self sign the rrset ('rdataset')?
- */
-isc_boolean_t
-dns_dnssec_selfsigns(dns_rdata_t *rdata, dns_name_t *name,
- dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
- isc_boolean_t ignoretime, isc_mem_t *mctx)
-{
- INSIST(rdataset->type == dns_rdatatype_key ||
- rdataset->type == dns_rdatatype_dnskey);
- if (rdataset->type == dns_rdatatype_key) {
- INSIST(sigrdataset->type == dns_rdatatype_sig);
- INSIST(sigrdataset->covers == dns_rdatatype_key);
- } else {
- INSIST(sigrdataset->type == dns_rdatatype_rrsig);
- INSIST(sigrdataset->covers == dns_rdatatype_dnskey);
- }
-
- return (dns_dnssec_signs(rdata, name, rdataset, sigrdataset,
- ignoretime, mctx));
-
-}
-
-isc_boolean_t
-dns_dnssec_signs(dns_rdata_t *rdata, dns_name_t *name,
- dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
- isc_boolean_t ignoretime, isc_mem_t *mctx)
-{
- dst_key_t *dstkey = NULL;
- dns_keytag_t keytag;
- dns_rdata_dnskey_t key;
- dns_rdata_rrsig_t sig;
- dns_rdata_t sigrdata = DNS_RDATA_INIT;
- isc_result_t result;
-
- INSIST(sigrdataset->type == dns_rdatatype_rrsig);
- if (sigrdataset->covers != rdataset->type)
- return (ISC_FALSE);
-
- result = dns_dnssec_keyfromrdata(name, rdata, mctx, &dstkey);
- if (result != ISC_R_SUCCESS)
- return (ISC_FALSE);
- result = dns_rdata_tostruct(rdata, &key, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
-
- keytag = dst_key_id(dstkey);
- for (result = dns_rdataset_first(sigrdataset);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(sigrdataset))
- {
- dns_rdata_reset(&sigrdata);
- dns_rdataset_current(sigrdataset, &sigrdata);
- result = dns_rdata_tostruct(&sigrdata, &sig, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
-
- if (sig.algorithm == key.algorithm &&
- sig.keyid == keytag) {
- result = dns_dnssec_verify2(name, rdataset, dstkey,
- ignoretime, mctx,
- &sigrdata, NULL);
- if (result == ISC_R_SUCCESS) {
- dst_key_free(&dstkey);
- return (ISC_TRUE);
- }
- }
- }
- 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);
- INSIST(result == ISC_R_SUCCESS);
-
- /* 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_stdtime_t now) {
- isc_result_t result;
- isc_stdtime_t 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);
-
- 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;
- isc_stdtime_t now;
-
- REQUIRE(keylist != NULL);
- ISC_LIST_INIT(list);
- isc_dir_init(&dir);
-
- isc_buffer_init(&b, namebuf, sizeof(namebuf) - 1);
- RETERR(dns_name_tofilenametext(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;
-
- isc_stdtime_get(&now);
-
- 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, now);
-
- 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 isc_result_t
-addkey(dns_dnsseckeylist_t *keylist, dst_key_t **newkey,
- isc_boolean_t savekeys, isc_mem_t *mctx)
-{
- dns_dnsseckey_t *key;
- isc_result_t result;
-
- /* 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 (ISC_R_SUCCESS);
- }
-
- result = dns_dnsseckey_create(mctx, newkey, &key);
- if (result != ISC_R_SUCCESS)
- return (result);
- 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;
- return (ISC_R_SUCCESS);
-}
-
-
-/*%
- * 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));
- dst_key_setttl(pubkey, keys.ttl);
-
- 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) {
- RETERR(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) {
- RETERR(addkey(keylist, &pubkey, savekeys, mctx));
- goto skip;
- }
- RETERR(result);
-
- /* This should never happen. */
- if ((dst_key_flags(privkey) & DNS_KEYTYPE_NOAUTH) != 0)
- goto skip;
-
- /*
- * Whatever the key's default TTL may have
- * been, the rdataset TTL takes priority.
- */
- dst_key_setttl(privkey, dst_key_getttl(pubkey));
-
- RETERR(addkey(keylist, &privkey, savekeys, mctx));
- skip:
- if (pubkey != NULL)
- 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 hint_ttl, dns_diff_t *diff,
- isc_boolean_t allzsk, isc_mem_t *mctx,
- void (*report)(const char *, ...))
-{
- isc_result_t result;
- dns_dnsseckey_t *key, *key1, *key2, *next;
- isc_boolean_t found_ttl = ISC_FALSE;
- dns_ttl_t ttl = hint_ttl;
-
- /*
- * First, look through the existing key list to find keys
- * supplied from the command line which are not in the zone.
- * Update the zone to include them.
- *
- * Also, if there are keys published in the zone already,
- * use their TTL for all subsequent published keys.
- */
- for (key = ISC_LIST_HEAD(*keys);
- key != NULL;
- 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));
- }
- if (key->source == dns_keysource_zoneapex) {
- ttl = dst_key_getttl(key->key);
- found_ttl = ISC_TRUE;
- }
- }
-
- /*
- * If there were no existing keys, use the smallest nonzero
- * TTL of the keys found in the repository.
- */
- if (!found_ttl && !ISC_LIST_EMPTY(*newkeys)) {
- dns_ttl_t shortest = 0;
-
- for (key = ISC_LIST_HEAD(*newkeys);
- key != NULL;
- key = ISC_LIST_NEXT(key, link)) {
- dns_ttl_t thisttl = dst_key_getttl(key->key);
- if (thisttl != 0 &&
- (shortest == 0 || thisttl < shortest))
- shortest = thisttl;
- }
-
- if (shortest != 0)
- ttl = shortest;
- }
-
- /*
- * Second, scan the list of newly found keys looking for matches
- * with known keys, and update accordingly.
- */
- 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) {
- 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/contrib/bind9/lib/dns/ds.c b/contrib/bind9/lib/dns/ds.c
deleted file mode 100644
index e72ecbb6cc2c..000000000000
--- a/contrib/bind9/lib/dns/ds.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (C) 2004-2007, 2010, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2002, 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: ds.c,v 1.13 2010/12/23 23:47:08 tbox Exp $ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <string.h>
-
-#include <isc/buffer.h>
-#include <isc/region.h>
-#include <isc/sha1.h>
-#include <isc/sha2.h>
-#include <isc/util.h>
-
-#include <dns/ds.h>
-#include <dns/fixedname.h>
-#include <dns/name.h>
-#include <dns/rdata.h>
-#include <dns/rdatastruct.h>
-#include <dns/result.h>
-
-#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,
- dns_rdata_t *rdata)
-{
- dns_fixedname_t fname;
- dns_name_t *name;
- unsigned char digest[ISC_SHA384_DIGESTLENGTH];
- isc_region_t r;
- isc_buffer_t b;
- dns_rdata_ds_t ds;
- isc_sha1_t sha1;
- isc_sha256_t sha256;
- isc_sha384_t sha384;
-#ifdef HAVE_OPENSSL_GOST
- EVP_MD_CTX ctx;
- const EVP_MD *md;
-#endif
-
- REQUIRE(key != NULL);
- REQUIRE(key->type == dns_rdatatype_dnskey);
-
- if (!dns_ds_digest_supported(digest_type))
- return (ISC_R_NOTIMPLEMENTED);
-
- dns_fixedname_init(&fname);
- name = dns_fixedname_name(&fname);
- (void)dns_name_downcase(owner, name, NULL);
-
- memset(buffer, 0, DNS_DS_BUFFERSIZE);
- isc_buffer_init(&b, buffer, DNS_DS_BUFFERSIZE);
-
- switch (digest_type) {
- case DNS_DSDIGEST_SHA1:
- isc_sha1_init(&sha1);
- dns_name_toregion(name, &r);
- isc_sha1_update(&sha1, r.base, r.length);
- dns_rdata_toregion(key, &r);
- INSIST(r.length >= 4);
- isc_sha1_update(&sha1, r.base, r.length);
- isc_sha1_final(&sha1, digest);
- break;
-
-#ifdef HAVE_OPENSSL_GOST
-#define CHECK(x) \
- if ((x) != 1) { \
- EVP_MD_CTX_cleanup(&ctx); \
- return (DST_R_CRYPTOFAILURE); \
- }
-
- case DNS_DSDIGEST_GOST:
- md = EVP_gost();
- if (md == NULL)
- return (DST_R_CRYPTOFAILURE);
- 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
-
- case DNS_DSDIGEST_SHA384:
- isc_sha384_init(&sha384);
- dns_name_toregion(name, &r);
- isc_sha384_update(&sha384, r.base, r.length);
- dns_rdata_toregion(key, &r);
- INSIST(r.length >= 4);
- isc_sha384_update(&sha384, r.base, r.length);
- isc_sha384_final(digest, &sha384);
- break;
-
- case DNS_DSDIGEST_SHA256:
- default:
- isc_sha256_init(&sha256);
- dns_name_toregion(name, &r);
- isc_sha256_update(&sha256, r.base, r.length);
- dns_rdata_toregion(key, &r);
- INSIST(r.length >= 4);
- isc_sha256_update(&sha256, r.base, r.length);
- isc_sha256_final(digest, &sha256);
- break;
- }
-
- ds.mctx = NULL;
- ds.common.rdclass = key->rdclass;
- ds.common.rdtype = dns_rdatatype_ds;
- ds.algorithm = r.base[3];
- ds.key_tag = dst_region_computeid(&r, ds.algorithm);
- ds.digest_type = digest_type;
- 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
-
- case DNS_DSDIGEST_SHA384:
- ds.length = ISC_SHA384_DIGESTLENGTH;
- break;
-
- case DNS_DSDIGEST_SHA256:
- default:
- ds.length = ISC_SHA256_DIGESTLENGTH;
- break;
- }
- ds.digest = digest;
-
- return (dns_rdata_fromstruct(rdata, key->rdclass, dns_rdatatype_ds,
- &ds, &b));
-}
-
-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 ||
- digest_type == DNS_DSDIGEST_SHA384));
-#else
- return (ISC_TF(digest_type == DNS_DSDIGEST_SHA1 ||
- digest_type == DNS_DSDIGEST_SHA256 ||
- digest_type == DNS_DSDIGEST_SHA384));
-#endif
-}
diff --git a/contrib/bind9/lib/dns/dst_api.c b/contrib/bind9/lib/dns/dst_api.c
deleted file mode 100644
index 98607246effc..000000000000
--- a/contrib/bind9/lib/dns/dst_api.c
+++ /dev/null
@@ -1,1862 +0,0 @@
-/*
- * Portions Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
- * Portions Copyright (C) 1999-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
- * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
- * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
- * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Portions Copyright (C) 1995-2000 by Network Associates, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
- * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
- * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
- * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * Principal Author: Brian Wellington
- * $Id: dst_api.c,v 1.65 2011/10/20 21:20:02 marka Exp $
- */
-
-/*! \file */
-
-#include <config.h>
-
-#include <stdlib.h>
-#include <time.h>
-
-#include <isc/buffer.h>
-#include <isc/dir.h>
-#include <isc/entropy.h>
-#include <isc/fsaccess.h>
-#include <isc/hmacsha.h>
-#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>
-#include <isc/string.h>
-#include <isc/time.h>
-#include <isc/util.h>
-#include <isc/file.h>
-
-#define DST_KEY_INTERNAL
-
-#include <dns/fixedname.h>
-#include <dns/keyvalues.h>
-#include <dns/name.h>
-#include <dns/rdata.h>
-#include <dns/rdataclass.h>
-#include <dns/ttl.h>
-#include <dns/types.h>
-
-#include <dst/result.h>
-
-#include "dst_internal.h"
-
-#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;
-
-void gss_log(int level, const char *fmt, ...) ISC_FORMAT_PRINTF(2, 3);
-
-isc_mem_t *dst__memory_pool = NULL;
-
-/*
- * Static functions.
- */
-static dst_key_t * get_key_struct(dns_name_t *name,
- unsigned int alg,
- unsigned int flags,
- unsigned int protocol,
- unsigned int bits,
- dns_rdataclass_t rdclass,
- dns_ttl_t ttl,
- isc_mem_t *mctx);
-static isc_result_t write_public_key(const dst_key_t *key, int type,
- const char *directory);
-static isc_result_t buildfilename(dns_name_t *name,
- dns_keytag_t id,
- unsigned int alg,
- unsigned int type,
- const char *directory,
- isc_buffer_t *out);
-static isc_result_t computeid(dst_key_t *key);
-static isc_result_t frombuffer(dns_name_t *name,
- unsigned int alg,
- unsigned int flags,
- unsigned int protocol,
- dns_rdataclass_t rdclass,
- isc_buffer_t *source,
- isc_mem_t *mctx,
- dst_key_t **keyp);
-
-static isc_result_t algorithm_status(unsigned int alg);
-
-static isc_result_t addsuffix(char *filename, int len,
- const char *dirname, const char *ofilename,
- const char *suffix);
-
-#define RETERR(x) \
- do { \
- result = (x); \
- if (result != ISC_R_SUCCESS) \
- goto out; \
- } while (0)
-
-#define CHECKALG(alg) \
- do { \
- isc_result_t _r; \
- _r = algorithm_status(alg); \
- if (_r != ISC_R_SUCCESS) \
- return (_r); \
- } while (0); \
-
-#if defined(OPENSSL) && defined(BIND9)
-static void *
-default_memalloc(void *arg, size_t size) {
- UNUSED(arg);
- if (size == 0U)
- size = 1;
- return (malloc(size));
-}
-
-static void
-default_memfree(void *arg, void *ptr) {
- UNUSED(arg);
- free(ptr);
-}
-#endif
-
-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);
-#ifdef BIND9
- REQUIRE(ectx != NULL);
-#else
- UNUSED(ectx);
-#endif
- REQUIRE(dst_initialized == ISC_FALSE);
-
-#ifndef OPENSSL
- UNUSED(engine);
-#endif
-
- dst__memory_pool = NULL;
-
-#if defined(OPENSSL) && defined(BIND9)
- UNUSED(mctx);
- /*
- * When using --with-openssl, there seems to be no good way of not
- * leaking memory due to the openssl error handling mechanism.
- * Avoid assertions by using a local memory context and not checking
- * for leaks on exit. Note: as there are leaks we cannot use
- * ISC_MEMFLAG_INTERNAL as it will free up memory still being used
- * by libcrypto.
- */
- result = isc_mem_createx2(0, 0, default_memalloc, default_memfree,
- NULL, &dst__memory_pool, 0);
- 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();
-
- memset(dst_t_func, 0, sizeof(dst_t_func));
- RETERR(dst__hmacmd5_init(&dst_t_func[DST_ALG_HMACMD5]));
- RETERR(dst__hmacsha1_init(&dst_t_func[DST_ALG_HMACSHA1]));
- RETERR(dst__hmacsha224_init(&dst_t_func[DST_ALG_HMACSHA224]));
- RETERR(dst__hmacsha256_init(&dst_t_func[DST_ALG_HMACSHA256]));
- 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(engine));
- RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSAMD5],
- DST_ALG_RSAMD5));
- RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSASHA1],
- DST_ALG_RSASHA1));
- RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_NSEC3RSASHA1],
- DST_ALG_NSEC3RSASHA1));
- RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSASHA256],
- DST_ALG_RSASHA256));
- RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSASHA512],
- DST_ALG_RSASHA512));
-#ifdef HAVE_OPENSSL_DSA
- RETERR(dst__openssldsa_init(&dst_t_func[DST_ALG_DSA]));
- 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
-#ifdef HAVE_OPENSSL_ECDSA
- RETERR(dst__opensslecdsa_init(&dst_t_func[DST_ALG_ECDSA256]));
- RETERR(dst__opensslecdsa_init(&dst_t_func[DST_ALG_ECDSA384]));
-#endif
-#endif /* OPENSSL */
-#ifdef GSSAPI
- RETERR(dst__gssapi_init(&dst_t_func[DST_ALG_GSSAPI]));
-#endif
- dst_initialized = ISC_TRUE;
- return (ISC_R_SUCCESS);
-
- out:
- /* avoid immediate crash! */
- dst_initialized = ISC_TRUE;
- dst_lib_destroy();
- return (result);
-}
-
-void
-dst_lib_destroy(void) {
- int i;
- RUNTIME_CHECK(dst_initialized == ISC_TRUE);
- dst_initialized = ISC_FALSE;
-
- for (i = 0; i < DST_MAX_ALGS; i++)
- if (dst_t_func[i] != NULL && dst_t_func[i]->cleanup != NULL)
- dst_t_func[i]->cleanup();
-#ifdef OPENSSL
- dst__openssl_destroy();
-#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
-dst_algorithm_supported(unsigned int alg) {
- REQUIRE(dst_initialized == ISC_TRUE);
-
- if (alg >= DST_MAX_ALGS || dst_t_func[alg] == NULL)
- return (ISC_FALSE);
- return (ISC_TRUE);
-}
-
-isc_result_t
-dst_context_create(dst_key_t *key, isc_mem_t *mctx, dst_context_t **dctxp) {
- return (dst_context_create2(key, mctx,
- DNS_LOGCATEGORY_GENERAL, dctxp));
-}
-
-isc_result_t
-dst_context_create2(dst_key_t *key, isc_mem_t *mctx,
- isc_logcategory_t *category, dst_context_t **dctxp) {
- dst_context_t *dctx;
- isc_result_t result;
-
- REQUIRE(dst_initialized == ISC_TRUE);
- REQUIRE(VALID_KEY(key));
- REQUIRE(mctx != NULL);
- REQUIRE(dctxp != NULL && *dctxp == NULL);
-
- if (key->func->createctx == NULL)
- return (DST_R_UNSUPPORTEDALG);
- if (key->keydata.generic == NULL)
- return (DST_R_NULLKEY);
-
- dctx = isc_mem_get(mctx, sizeof(dst_context_t));
- if (dctx == NULL)
- return (ISC_R_NOMEMORY);
- dctx->key = key;
- dctx->mctx = mctx;
- dctx->category = category;
- result = key->func->createctx(key, dctx);
- if (result != ISC_R_SUCCESS) {
- isc_mem_put(mctx, dctx, sizeof(dst_context_t));
- return (result);
- }
- dctx->magic = CTX_MAGIC;
- *dctxp = dctx;
- return (ISC_R_SUCCESS);
-}
-
-void
-dst_context_destroy(dst_context_t **dctxp) {
- dst_context_t *dctx;
-
- REQUIRE(dctxp != NULL && VALID_CTX(*dctxp));
-
- dctx = *dctxp;
- INSIST(dctx->key->func->destroyctx != NULL);
- dctx->key->func->destroyctx(dctx);
- dctx->magic = 0;
- isc_mem_put(dctx->mctx, dctx, sizeof(dst_context_t));
- *dctxp = NULL;
-}
-
-isc_result_t
-dst_context_adddata(dst_context_t *dctx, const isc_region_t *data) {
- REQUIRE(VALID_CTX(dctx));
- REQUIRE(data != NULL);
- INSIST(dctx->key->func->adddata != NULL);
-
- return (dctx->key->func->adddata(dctx, data));
-}
-
-isc_result_t
-dst_context_sign(dst_context_t *dctx, isc_buffer_t *sig) {
- dst_key_t *key;
-
- REQUIRE(VALID_CTX(dctx));
- REQUIRE(sig != NULL);
-
- key = dctx->key;
- CHECKALG(key->key_alg);
- if (key->keydata.generic == NULL)
- return (DST_R_NULLKEY);
-
- if (key->func->sign == NULL)
- return (DST_R_NOTPRIVATEKEY);
- if (key->func->isprivate == NULL ||
- key->func->isprivate(key) == ISC_FALSE)
- return (DST_R_NOTPRIVATEKEY);
-
- return (key->func->sign(dctx, sig));
-}
-
-isc_result_t
-dst_context_verify(dst_context_t *dctx, isc_region_t *sig) {
- REQUIRE(VALID_CTX(dctx));
- REQUIRE(sig != NULL);
-
- CHECKALG(dctx->key->key_alg);
- if (dctx->key->keydata.generic == NULL)
- return (DST_R_NULLKEY);
- if (dctx->key->func->verify == NULL)
- return (DST_R_NOTPUBLICKEY);
-
- return (dctx->key->func->verify(dctx, sig));
-}
-
-isc_result_t
-dst_context_verify2(dst_context_t *dctx, unsigned int maxbits,
- isc_region_t *sig)
-{
- REQUIRE(VALID_CTX(dctx));
- REQUIRE(sig != NULL);
-
- CHECKALG(dctx->key->key_alg);
- if (dctx->key->keydata.generic == NULL)
- return (DST_R_NULLKEY);
- if (dctx->key->func->verify == NULL &&
- dctx->key->func->verify2 == NULL)
- return (DST_R_NOTPUBLICKEY);
-
- return (dctx->key->func->verify2 != NULL ?
- dctx->key->func->verify2(dctx, maxbits, sig) :
- dctx->key->func->verify(dctx, sig));
-}
-
-isc_result_t
-dst_key_computesecret(const dst_key_t *pub, const dst_key_t *priv,
- isc_buffer_t *secret)
-{
- REQUIRE(dst_initialized == ISC_TRUE);
- REQUIRE(VALID_KEY(pub) && VALID_KEY(priv));
- REQUIRE(secret != NULL);
-
- CHECKALG(pub->key_alg);
- CHECKALG(priv->key_alg);
-
- if (pub->keydata.generic == NULL || priv->keydata.generic == NULL)
- return (DST_R_NULLKEY);
-
- if (pub->key_alg != priv->key_alg ||
- pub->func->computesecret == NULL ||
- priv->func->computesecret == NULL)
- return (DST_R_KEYCANNOTCOMPUTESECRET);
-
- if (dst_key_isprivate(priv) == ISC_FALSE)
- return (DST_R_NOTPRIVATEKEY);
-
- return (pub->func->computesecret(pub, priv, secret));
-}
-
-isc_result_t
-dst_key_tofile(const dst_key_t *key, int type, const char *directory) {
- isc_result_t ret = ISC_R_SUCCESS;
-
- REQUIRE(dst_initialized == ISC_TRUE);
- REQUIRE(VALID_KEY(key));
- REQUIRE((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) != 0);
-
- CHECKALG(key->key_alg);
-
- if (key->func->tofile == NULL)
- return (DST_R_UNSUPPORTEDALG);
-
- if (type & DST_TYPE_PUBLIC) {
- ret = write_public_key(key, type, directory);
- if (ret != ISC_R_SUCCESS)
- return (ret);
- }
-
- if ((type & DST_TYPE_PRIVATE) &&
- (key->key_flags & DNS_KEYFLAG_TYPEMASK) != DNS_KEYTYPE_NOKEY)
- return (key->func->tofile(key, directory));
- else
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dst_key_fromfile(dns_name_t *name, dns_keytag_t id,
- unsigned int alg, int type, const char *directory,
- isc_mem_t *mctx, dst_key_t **keyp)
-{
- char filename[ISC_DIR_NAMEMAX];
- isc_buffer_t b;
- dst_key_t *key;
- isc_result_t result;
-
- REQUIRE(dst_initialized == ISC_TRUE);
- REQUIRE(dns_name_isabsolute(name));
- REQUIRE((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) != 0);
- REQUIRE(mctx != NULL);
- REQUIRE(keyp != NULL && *keyp == NULL);
-
- CHECKALG(alg);
-
- isc_buffer_init(&b, filename, sizeof(filename));
- result = buildfilename(name, id, alg, type, directory, &b);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- key = NULL;
- result = dst_key_fromnamedfile(filename, NULL, type, mctx, &key);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- result = computeid(key);
- if (result != ISC_R_SUCCESS) {
- dst_key_free(&key);
- return (result);
- }
-
- if (!dns_name_equal(name, key->key_name) || id != key->key_id ||
- alg != key->key_alg) {
- dst_key_free(&key);
- return (DST_R_INVALIDPRIVATEKEY);
- }
-
- *keyp = key;
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-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;
- char *newfilename = NULL;
- int newfilenamelen = 0;
- isc_lex_t *lex = NULL;
-
- REQUIRE(dst_initialized == ISC_TRUE);
- REQUIRE(filename != NULL);
- REQUIRE((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) != 0);
- 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,
- dirname, filename, ".key");
- INSIST(result == ISC_R_SUCCESS);
-
- result = dst_key_read_public(newfilename, type, mctx, &pubkey);
- isc_mem_put(mctx, newfilename, newfilenamelen);
- newfilename = NULL;
- RETERR(result);
-
- if ((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) == DST_TYPE_PUBLIC ||
- (pubkey->key_flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY) {
- result = computeid(pubkey);
- if (result != ISC_R_SUCCESS) {
- dst_key_free(&pubkey);
- return (result);
- }
-
- *keyp = pubkey;
- return (ISC_R_SUCCESS);
- }
-
- result = algorithm_status(pubkey->key_alg);
- if (result != ISC_R_SUCCESS) {
- dst_key_free(&pubkey);
- return (result);
- }
-
- key = get_key_struct(pubkey->key_name, pubkey->key_alg,
- pubkey->key_flags, pubkey->key_proto, 0,
- pubkey->key_class, pubkey->key_ttl, mctx);
- 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,
- 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, pubkey));
- isc_lex_destroy(&lex);
-
- RETERR(computeid(key));
-
- 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)
- isc_lex_destroy(&lex);
- if (key != NULL)
- dst_key_free(&key);
- return (result);
-}
-
-isc_result_t
-dst_key_todns(const dst_key_t *key, isc_buffer_t *target) {
- REQUIRE(dst_initialized == ISC_TRUE);
- REQUIRE(VALID_KEY(key));
- REQUIRE(target != NULL);
-
- CHECKALG(key->key_alg);
-
- if (key->func->todns == NULL)
- return (DST_R_UNSUPPORTEDALG);
-
- if (isc_buffer_availablelength(target) < 4)
- return (ISC_R_NOSPACE);
- isc_buffer_putuint16(target, (isc_uint16_t)(key->key_flags & 0xffff));
- isc_buffer_putuint8(target, (isc_uint8_t)key->key_proto);
- isc_buffer_putuint8(target, (isc_uint8_t)key->key_alg);
-
- if (key->key_flags & DNS_KEYFLAG_EXTENDED) {
- if (isc_buffer_availablelength(target) < 2)
- return (ISC_R_NOSPACE);
- isc_buffer_putuint16(target,
- (isc_uint16_t)((key->key_flags >> 16)
- & 0xffff));
- }
-
- if (key->keydata.generic == NULL) /*%< NULL KEY */
- return (ISC_R_SUCCESS);
-
- return (key->func->todns(key, target));
-}
-
-isc_result_t
-dst_key_fromdns(dns_name_t *name, dns_rdataclass_t rdclass,
- isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp)
-{
- isc_uint8_t alg, proto;
- isc_uint32_t flags, extflags;
- dst_key_t *key = NULL;
- dns_keytag_t id, rid;
- isc_region_t r;
- isc_result_t result;
-
- REQUIRE(dst_initialized);
-
- isc_buffer_remainingregion(source, &r);
-
- if (isc_buffer_remaininglength(source) < 4)
- return (DST_R_INVALIDPUBLICKEY);
- flags = isc_buffer_getuint16(source);
- proto = isc_buffer_getuint8(source);
- alg = isc_buffer_getuint8(source);
-
- id = dst_region_computeid(&r, alg);
- rid = dst_region_computerid(&r, alg);
-
- if (flags & DNS_KEYFLAG_EXTENDED) {
- if (isc_buffer_remaininglength(source) < 2)
- return (DST_R_INVALIDPUBLICKEY);
- extflags = isc_buffer_getuint16(source);
- flags |= (extflags << 16);
- }
-
- result = frombuffer(name, alg, flags, proto, rdclass, source,
- mctx, &key);
- if (result != ISC_R_SUCCESS)
- return (result);
- key->key_id = id;
- key->key_rid = rid;
-
- *keyp = key;
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dst_key_frombuffer(dns_name_t *name, unsigned int alg,
- unsigned int flags, unsigned int protocol,
- dns_rdataclass_t rdclass,
- isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp)
-{
- dst_key_t *key = NULL;
- isc_result_t result;
-
- REQUIRE(dst_initialized);
-
- result = frombuffer(name, alg, flags, protocol, rdclass, source,
- mctx, &key);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- result = computeid(key);
- if (result != ISC_R_SUCCESS) {
- dst_key_free(&key);
- return (result);
- }
-
- *keyp = key;
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dst_key_tobuffer(const dst_key_t *key, isc_buffer_t *target) {
- REQUIRE(dst_initialized == ISC_TRUE);
- REQUIRE(VALID_KEY(key));
- REQUIRE(target != NULL);
-
- CHECKALG(key->key_alg);
-
- if (key->func->todns == NULL)
- return (DST_R_UNSUPPORTEDALG);
-
- return (key->func->todns(key, target));
-}
-
-isc_result_t
-dst_key_privatefrombuffer(dst_key_t *key, isc_buffer_t *buffer) {
- isc_lex_t *lex = NULL;
- isc_result_t result = ISC_R_SUCCESS;
-
- REQUIRE(dst_initialized == ISC_TRUE);
- REQUIRE(VALID_KEY(key));
- REQUIRE(!dst_key_isprivate(key));
- REQUIRE(buffer != NULL);
-
- if (key->func->parse == NULL)
- RETERR(DST_R_UNSUPPORTEDALG);
-
- RETERR(isc_lex_create(key->mctx, 1500, &lex));
- RETERR(isc_lex_openbuffer(lex, buffer));
- RETERR(key->func->parse(key, lex, NULL));
- out:
- if (lex != NULL)
- isc_lex_destroy(&lex);
- return (result);
-}
-
-gss_ctx_id_t
-dst_key_getgssctx(const dst_key_t *key)
-{
- REQUIRE(key != NULL);
-
- return (key->keydata.gssctx);
-}
-
-isc_result_t
-dst_key_fromgssapi(dns_name_t *name, gss_ctx_id_t gssctx, isc_mem_t *mctx,
- dst_key_t **keyp, isc_region_t *intoken)
-{
- dst_key_t *key;
- isc_result_t result;
-
- REQUIRE(gssctx != NULL);
- REQUIRE(keyp != NULL && *keyp == NULL);
-
- key = get_key_struct(name, DST_ALG_GSSAPI, 0, DNS_KEYPROTO_DNSSEC,
- 0, dns_rdataclass_in, 0, 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;
- result = ISC_R_SUCCESS;
-out:
- return result;
-}
-
-isc_result_t
-dst_key_buildinternal(dns_name_t *name, unsigned int alg,
- unsigned int bits, unsigned int flags,
- unsigned int protocol, dns_rdataclass_t rdclass,
- void *data, isc_mem_t *mctx, dst_key_t **keyp)
-{
- dst_key_t *key;
- isc_result_t result;
-
- REQUIRE(dst_initialized == ISC_TRUE);
- REQUIRE(dns_name_isabsolute(name));
- REQUIRE(mctx != NULL);
- REQUIRE(keyp != NULL && *keyp == NULL);
- REQUIRE(data != NULL);
-
- CHECKALG(alg);
-
- key = get_key_struct(name, alg, flags, protocol, bits, rdclass,
- 0, mctx);
- if (key == NULL)
- return (ISC_R_NOMEMORY);
-
- key->keydata.generic = data;
-
- result = computeid(key);
- if (result != ISC_R_SUCCESS) {
- dst_key_free(&key);
- return (result);
- }
-
- *keyp = key;
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dst_key_fromlabel(dns_name_t *name, int alg, unsigned int flags,
- unsigned int protocol, dns_rdataclass_t rdclass,
- const char *engine, const char *label, const char *pin,
- isc_mem_t *mctx, dst_key_t **keyp)
-{
- dst_key_t *key;
- isc_result_t result;
-
- REQUIRE(dst_initialized == ISC_TRUE);
- REQUIRE(dns_name_isabsolute(name));
- REQUIRE(mctx != NULL);
- REQUIRE(keyp != NULL && *keyp == NULL);
- REQUIRE(label != NULL);
-
- CHECKALG(alg);
-
- key = get_key_struct(name, alg, flags, protocol, 0, rdclass, 0, mctx);
- if (key == NULL)
- return (ISC_R_NOMEMORY);
-
- if (key->func->fromlabel == NULL) {
- dst_key_free(&key);
- return (DST_R_UNSUPPORTEDALG);
- }
-
- result = key->func->fromlabel(key, engine, label, pin);
- if (result != ISC_R_SUCCESS) {
- dst_key_free(&key);
- return (result);
- }
-
- result = computeid(key);
- if (result != ISC_R_SUCCESS) {
- dst_key_free(&key);
- return (result);
- }
-
- *keyp = key;
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dst_key_generate(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)
-{
- 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;
-
- REQUIRE(dst_initialized == ISC_TRUE);
- REQUIRE(dns_name_isabsolute(name));
- REQUIRE(mctx != NULL);
- REQUIRE(keyp != NULL && *keyp == NULL);
-
- CHECKALG(alg);
-
- key = get_key_struct(name, alg, flags, protocol, bits,
- rdclass, 0, mctx);
- if (key == NULL)
- return (ISC_R_NOMEMORY);
-
- if (bits == 0) { /*%< NULL KEY */
- key->key_flags |= DNS_KEYTYPE_NOKEY;
- *keyp = key;
- return (ISC_R_SUCCESS);
- }
-
- if (key->func->generate == NULL) {
- dst_key_free(&key);
- return (DST_R_UNSUPPORTEDALG);
- }
-
- ret = key->func->generate(key, param, callback);
- if (ret != ISC_R_SUCCESS) {
- dst_key_free(&key);
- return (ret);
- }
-
- ret = computeid(key);
- if (ret != ISC_R_SUCCESS) {
- dst_key_free(&key);
- return (ret);
- }
-
- *keyp = key;
- return (ISC_R_SUCCESS);
-}
-
-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)
- return (ISC_FALSE);
-
- 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_id != key2->key_rid &&
- key1->key_rid != key2->key_id)
- 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);
- 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->func->paramcompare != NULL &&
- key1->func->paramcompare(key1, key2) == ISC_TRUE)
- return (ISC_TRUE);
- else
- return (ISC_FALSE);
-}
-
-void
-dst_key_attach(dst_key_t *source, dst_key_t **target) {
-
- REQUIRE(dst_initialized == ISC_TRUE);
- REQUIRE(target != NULL && *target == NULL);
- REQUIRE(VALID_KEY(source));
-
- isc_refcount_increment(&source->refs, NULL);
- *target = source;
-}
-
-void
-dst_key_free(dst_key_t **keyp) {
- isc_mem_t *mctx;
- dst_key_t *key;
- unsigned int refs;
-
- REQUIRE(dst_initialized == ISC_TRUE);
- REQUIRE(keyp != NULL && VALID_KEY(*keyp));
-
- key = *keyp;
- mctx = key->mctx;
-
- isc_refcount_decrement(&key->refs, &refs);
- if (refs != 0)
- return;
-
- isc_refcount_destroy(&key->refs);
- if (key->keydata.generic != NULL) {
- INSIST(key->func->destroy != NULL);
- key->func->destroy(key);
- }
- if (key->engine != NULL)
- isc_mem_free(mctx, key->engine);
- if (key->label != NULL)
- 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_putanddetach(&mctx, key, sizeof(dst_key_t));
- *keyp = NULL;
-}
-
-isc_boolean_t
-dst_key_isprivate(const dst_key_t *key) {
- REQUIRE(VALID_KEY(key));
- INSIST(key->func->isprivate != NULL);
- return (key->func->isprivate(key));
-}
-
-isc_result_t
-dst_key_buildfilename(const dst_key_t *key, int type,
- const char *directory, isc_buffer_t *out) {
-
- REQUIRE(VALID_KEY(key));
- REQUIRE(type == DST_TYPE_PRIVATE || type == DST_TYPE_PUBLIC ||
- type == 0);
-
- return (buildfilename(key->key_name, key->key_id, key->key_alg,
- type, directory, out));
-}
-
-isc_result_t
-dst_key_sigsize(const dst_key_t *key, unsigned int *n) {
- REQUIRE(dst_initialized == ISC_TRUE);
- REQUIRE(VALID_KEY(key));
- REQUIRE(n != NULL);
-
- /* XXXVIX this switch statement is too sparse to gen a jump table. */
- switch (key->key_alg) {
- case DST_ALG_RSAMD5:
- case DST_ALG_RSASHA1:
- case DST_ALG_NSEC3RSASHA1:
- case DST_ALG_RSASHA256:
- case DST_ALG_RSASHA512:
- *n = (key->key_size + 7) / 8;
- break;
- case DST_ALG_DSA:
- case DST_ALG_NSEC3DSA:
- *n = DNS_SIG_DSASIGSIZE;
- break;
- case DST_ALG_ECCGOST:
- *n = DNS_SIG_GOSTSIGSIZE;
- break;
- case DST_ALG_ECDSA256:
- *n = DNS_SIG_ECDSA256SIZE;
- break;
- case DST_ALG_ECDSA384:
- *n = DNS_SIG_ECDSA384SIZE;
- break;
- case DST_ALG_HMACMD5:
- *n = 16;
- break;
- case DST_ALG_HMACSHA1:
- *n = ISC_SHA1_DIGESTLENGTH;
- break;
- case DST_ALG_HMACSHA224:
- *n = ISC_SHA224_DIGESTLENGTH;
- break;
- case DST_ALG_HMACSHA256:
- *n = ISC_SHA256_DIGESTLENGTH;
- break;
- case DST_ALG_HMACSHA384:
- *n = ISC_SHA384_DIGESTLENGTH;
- break;
- case DST_ALG_HMACSHA512:
- *n = ISC_SHA512_DIGESTLENGTH;
- break;
- case DST_ALG_GSSAPI:
- *n = 128; /*%< XXX */
- break;
- case DST_ALG_DH:
- default:
- return (DST_R_UNSUPPORTEDALG);
- }
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dst_key_secretsize(const dst_key_t *key, unsigned int *n) {
- REQUIRE(dst_initialized == ISC_TRUE);
- REQUIRE(VALID_KEY(key));
- REQUIRE(n != NULL);
-
- if (key->key_alg == DST_ALG_DH)
- *n = (key->key_size + 7) / 8;
- else
- return (DST_R_UNSUPPORTEDALG);
- 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->dump == 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, 0, 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
- ***/
-
-/*%
- * Allocates a key structure and fills in some of the fields.
- */
-static dst_key_t *
-get_key_struct(dns_name_t *name, unsigned int alg,
- unsigned int flags, unsigned int protocol,
- unsigned int bits, dns_rdataclass_t rdclass,
- dns_ttl_t ttl, isc_mem_t *mctx)
-{
- 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)
- return (NULL);
-
- memset(key, 0, sizeof(dst_key_t));
-
- key->key_name = isc_mem_get(mctx, sizeof(dns_name_t));
- if (key->key_name == NULL) {
- isc_mem_put(mctx, key, sizeof(dst_key_t));
- return (NULL);
- }
-
- dns_name_init(key->key_name, NULL);
- result = dns_name_dup(name, mctx, key->key_name);
- if (result != ISC_R_SUCCESS) {
- isc_mem_put(mctx, key->key_name, sizeof(dns_name_t));
- isc_mem_put(mctx, key, sizeof(dst_key_t));
- return (NULL);
- }
-
- result = isc_refcount_init(&key->refs, 1);
- if (result != ISC_R_SUCCESS) {
- dns_name_free(key->key_name, mctx);
- isc_mem_put(mctx, key->key_name, sizeof(dns_name_t));
- isc_mem_put(mctx, key, sizeof(dst_key_t));
- return (NULL);
- }
- isc_mem_attach(mctx, &key->mctx);
- key->key_alg = alg;
- key->key_flags = flags;
- key->key_proto = protocol;
- key->keydata.generic = NULL;
- key->key_size = bits;
- key->key_class = rdclass;
- key->key_ttl = ttl;
- key->func = dst_t_func[alg];
- key->fmt_major = 0;
- key->fmt_minor = 0;
- for (i = 0; i < (DST_MAX_TIMES + 1); i++) {
- key->times[i] = 0;
- key->timeset[i] = ISC_FALSE;
- }
- key->magic = KEY_MAGIC;
- return (key);
-}
-
-/*%
- * Reads a public key from disk
- */
-isc_result_t
-dst_key_read_public(const char *filename, int type,
- isc_mem_t *mctx, dst_key_t **keyp)
-{
- u_char rdatabuf[DST_KEY_MAXSIZE];
- isc_buffer_t b;
- dns_fixedname_t name;
- isc_lex_t *lex = NULL;
- isc_token_t token;
- isc_result_t ret;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- unsigned int opt = ISC_LEXOPT_DNSMULTILINE;
- dns_rdataclass_t rdclass = dns_rdataclass_in;
- isc_lexspecials_t specials;
- isc_uint32_t ttl = 0;
- isc_result_t result;
- dns_rdatatype_t keytype;
-
- /*
- * Open the file and read its formatted contents
- * File format:
- * domain.name [ttl] [class] [KEY|DNSKEY] <flags> <protocol> <algorithm> <key>
- */
-
- /* 1500 should be large enough for any key */
- ret = isc_lex_create(mctx, 1500, &lex);
- if (ret != ISC_R_SUCCESS)
- goto cleanup;
-
- memset(specials, 0, sizeof(specials));
- specials['('] = 1;
- specials[')'] = 1;
- specials['"'] = 1;
- isc_lex_setspecials(lex, specials);
- isc_lex_setcomments(lex, ISC_LEXCOMMENT_DNSMASTERFILE);
-
- ret = isc_lex_openfile(lex, filename);
- if (ret != ISC_R_SUCCESS)
- goto cleanup;
-
-#define NEXTTOKEN(lex, opt, token) { \
- ret = isc_lex_gettoken(lex, opt, token); \
- if (ret != ISC_R_SUCCESS) \
- goto cleanup; \
- }
-
-#define BADTOKEN() { \
- ret = ISC_R_UNEXPECTEDTOKEN; \
- goto cleanup; \
- }
-
- /* Read the domain name */
- NEXTTOKEN(lex, opt, &token);
- if (token.type != isc_tokentype_string)
- BADTOKEN();
-
- /*
- * We don't support "@" in .key files.
- */
- if (!strcmp(DST_AS_STR(token), "@"))
- BADTOKEN();
-
- dns_fixedname_init(&name);
- 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,
- 0, NULL);
- if (ret != ISC_R_SUCCESS)
- goto cleanup;
-
- /* Read the next word: either TTL, class, or 'KEY' */
- NEXTTOKEN(lex, opt, &token);
-
- if (token.type != isc_tokentype_string)
- BADTOKEN();
-
- /* If it's a TTL, read the next one */
- result = dns_ttl_fromtext(&token.value.as_textregion, &ttl);
- if (result == ISC_R_SUCCESS)
- NEXTTOKEN(lex, opt, &token);
-
- if (token.type != isc_tokentype_string)
- BADTOKEN();
-
- ret = dns_rdataclass_fromtext(&rdclass, &token.value.as_textregion);
- if (ret == ISC_R_SUCCESS)
- NEXTTOKEN(lex, opt, &token);
-
- if (token.type != isc_tokentype_string)
- BADTOKEN();
-
- if (strcasecmp(DST_AS_STR(token), "DNSKEY") == 0)
- keytype = dns_rdatatype_dnskey;
- else if (strcasecmp(DST_AS_STR(token), "KEY") == 0)
- keytype = dns_rdatatype_key; /*%< SIG(0), TKEY */
- else
- BADTOKEN();
-
- if (((type & DST_TYPE_KEY) != 0 && keytype != dns_rdatatype_key) ||
- ((type & DST_TYPE_KEY) == 0 && keytype != dns_rdatatype_dnskey)) {
- ret = DST_R_BADKEYTYPE;
- goto cleanup;
- }
-
- isc_buffer_init(&b, rdatabuf, sizeof(rdatabuf));
- ret = dns_rdata_fromtext(&rdata, rdclass, keytype, lex, NULL,
- ISC_FALSE, mctx, &b, NULL);
- if (ret != ISC_R_SUCCESS)
- goto cleanup;
-
- ret = dst_key_fromdns(dns_fixedname_name(&name), rdclass, &b, mctx,
- keyp);
- if (ret != ISC_R_SUCCESS)
- goto cleanup;
-
- dst_key_setttl(*keyp, ttl);
-
- cleanup:
- if (lex != NULL)
- isc_lex_destroy(&lex);
- return (ret);
-}
-
-static isc_boolean_t
-issymmetric(const dst_key_t *key) {
- REQUIRE(dst_initialized == ISC_TRUE);
- REQUIRE(VALID_KEY(key));
-
- /* XXXVIX this switch statement is too sparse to gen a jump table. */
- switch (key->key_alg) {
- case DST_ALG_RSAMD5:
- case DST_ALG_RSASHA1:
- case DST_ALG_NSEC3RSASHA1:
- case DST_ALG_RSASHA256:
- case DST_ALG_RSASHA512:
- case DST_ALG_DSA:
- case DST_ALG_NSEC3DSA:
- case DST_ALG_DH:
- case DST_ALG_ECCGOST:
- case DST_ALG_ECDSA256:
- case DST_ALG_ECDSA384:
- return (ISC_FALSE);
- case DST_ALG_HMACMD5:
- case DST_ALG_GSSAPI:
- return (ISC_TRUE);
- default:
- return (ISC_FALSE);
- }
-}
-
-/*%
- * 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
-write_public_key(const dst_key_t *key, int type, const char *directory) {
- FILE *fp;
- isc_buffer_t keyb, textb, fileb, classb;
- isc_region_t r;
- char filename[ISC_DIR_NAMEMAX];
- unsigned char key_array[DST_KEY_MAXSIZE];
- char text_array[DST_KEY_MAXTEXTSIZE];
- char class_array[10];
- isc_result_t ret;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- isc_fsaccess_t access;
-
- REQUIRE(VALID_KEY(key));
-
- isc_buffer_init(&keyb, key_array, sizeof(key_array));
- isc_buffer_init(&textb, text_array, sizeof(text_array));
- isc_buffer_init(&classb, class_array, sizeof(class_array));
-
- ret = dst_key_todns(key, &keyb);
- if (ret != ISC_R_SUCCESS)
- return (ret);
-
- isc_buffer_usedregion(&keyb, &r);
- dns_rdata_fromregion(&rdata, key->key_class, dns_rdatatype_dnskey, &r);
-
- ret = dns_rdata_totext(&rdata, (dns_name_t *) NULL, &textb);
- if (ret != ISC_R_SUCCESS)
- return (DST_R_INVALIDPUBLICKEY);
-
- ret = dns_rdataclass_totext(key->key_class, &classb);
- if (ret != ISC_R_SUCCESS)
- return (DST_R_INVALIDPUBLICKEY);
-
- /*
- * Make the filename.
- */
- isc_buffer_init(&fileb, filename, sizeof(filename));
- ret = dst_key_buildfilename(key, DST_TYPE_PUBLIC, directory, &fileb);
- if (ret != ISC_R_SUCCESS)
- return (ret);
-
- /*
- * Create public key file.
- */
- if ((fp = fopen(filename, "w")) == NULL)
- return (DST_R_WRITEERROR);
-
- if (issymmetric(key)) {
- access = 0;
- isc_fsaccess_add(ISC_FSACCESS_OWNER,
- ISC_FSACCESS_READ | ISC_FSACCESS_WRITE,
- &access);
- (void)isc_fsaccess_set(filename, access);
- }
-
- /* 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, " ");
-
- if (key->key_ttl != 0)
- fprintf(fp, "%d ", key->key_ttl);
-
- isc_buffer_usedregion(&classb, &r);
- if ((unsigned) fwrite(r.base, 1, r.length, fp) != r.length)
- ret = DST_R_WRITEERROR;
-
- if ((type & DST_TYPE_KEY) != 0)
- fprintf(fp, " KEY ");
- else
- fprintf(fp, " DNSKEY ");
-
- isc_buffer_usedregion(&textb, &r);
- if ((unsigned) fwrite(r.base, 1, r.length, fp) != r.length)
- ret = DST_R_WRITEERROR;
-
- fputc('\n', fp);
- fflush(fp);
- if (ferror(fp))
- ret = DST_R_WRITEERROR;
- fclose(fp);
-
- return (ret);
-}
-
-static isc_result_t
-buildfilename(dns_name_t *name, dns_keytag_t id,
- unsigned int alg, unsigned int type,
- const char *directory, isc_buffer_t *out)
-{
- const char *suffix = "";
- unsigned int len;
- isc_result_t result;
-
- REQUIRE(out != NULL);
- if ((type & DST_TYPE_PRIVATE) != 0)
- suffix = ".private";
- else if (type == DST_TYPE_PUBLIC)
- suffix = ".key";
- if (directory != NULL) {
- if (isc_buffer_availablelength(out) < strlen(directory))
- return (ISC_R_NOSPACE);
- isc_buffer_putstr(out, directory);
- if (strlen(directory) > 0U &&
- directory[strlen(directory) - 1] != '/')
- isc_buffer_putstr(out, "/");
- }
- if (isc_buffer_availablelength(out) < 1)
- return (ISC_R_NOSPACE);
- isc_buffer_putstr(out, "K");
- result = dns_name_tofilenametext(name, ISC_FALSE, out);
- if (result != ISC_R_SUCCESS)
- return (result);
- len = 1 + 3 + 1 + 5 + strlen(suffix) + 1;
- if (isc_buffer_availablelength(out) < len)
- return (ISC_R_NOSPACE);
- sprintf((char *) isc_buffer_used(out), "+%03d+%05d%s", alg, id,
- suffix);
- isc_buffer_add(out, len);
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-computeid(dst_key_t *key) {
- isc_buffer_t dnsbuf;
- unsigned char dns_array[DST_KEY_MAXSIZE];
- isc_region_t r;
- isc_result_t ret;
-
- isc_buffer_init(&dnsbuf, dns_array, sizeof(dns_array));
- ret = dst_key_todns(key, &dnsbuf);
- if (ret != ISC_R_SUCCESS)
- return (ret);
-
- isc_buffer_usedregion(&dnsbuf, &r);
- key->key_id = dst_region_computeid(&r, key->key_alg);
- key->key_rid = dst_region_computerid(&r, key->key_alg);
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-frombuffer(dns_name_t *name, unsigned int alg, unsigned int flags,
- unsigned int protocol, dns_rdataclass_t rdclass,
- isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp)
-{
- dst_key_t *key;
- isc_result_t ret;
-
- REQUIRE(dns_name_isabsolute(name));
- REQUIRE(source != NULL);
- REQUIRE(mctx != NULL);
- REQUIRE(keyp != NULL && *keyp == NULL);
-
- key = get_key_struct(name, alg, flags, protocol, 0, rdclass, 0, mctx);
- if (key == NULL)
- return (ISC_R_NOMEMORY);
-
- if (isc_buffer_remaininglength(source) > 0) {
- ret = algorithm_status(alg);
- if (ret != ISC_R_SUCCESS) {
- dst_key_free(&key);
- return (ret);
- }
- if (key->func->fromdns == NULL) {
- dst_key_free(&key);
- return (DST_R_UNSUPPORTEDALG);
- }
-
- ret = key->func->fromdns(key, source);
- if (ret != ISC_R_SUCCESS) {
- dst_key_free(&key);
- return (ret);
- }
- }
-
- *keyp = key;
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-algorithm_status(unsigned int alg) {
- REQUIRE(dst_initialized == ISC_TRUE);
-
- if (dst_algorithm_supported(alg))
- return (ISC_R_SUCCESS);
-#ifndef OPENSSL
- if (alg == DST_ALG_RSAMD5 || alg == DST_ALG_RSASHA1 ||
- 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_ECCGOST ||
- alg == DST_ALG_ECDSA256 || alg == DST_ALG_ECDSA384)
- return (DST_R_NOCRYPTO);
-#endif
- return (DST_R_UNSUPPORTEDALG);
-}
-
-static isc_result_t
-addsuffix(char *filename, int len, const char *odirname,
- const char *ofilename, const char *suffix)
-{
- int olen = strlen(ofilename);
- int n;
-
- if (olen > 1 && ofilename[olen - 1] == '.')
- olen -= 1;
- else if (olen > 8 && strcmp(ofilename + olen - 8, ".private") == 0)
- olen -= 8;
- else if (olen > 4 && strcmp(ofilename + olen - 4, ".key") == 0)
- olen -= 4;
-
- 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 (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;
- unsigned char buf[32];
- static isc_boolean_t first = ISC_TRUE;
-
- if (first) {
- /* Someone believes RAND_status() initializes the PRNG */
- flags &= ~ISC_ENTROPY_GOODONLY;
- ret = isc_entropy_getdata(dst_entropy_pool, buf,
- sizeof(buf), NULL, flags);
- INSIST(ret == ISC_R_SUCCESS);
- isc_entropy_putdata(dst_entropy_pool, buf,
- sizeof(buf), 2 * sizeof(buf));
- first = ISC_FALSE;
- }
-#endif
- return (isc_entropy_status(dst_entropy_pool));
-#else
- return (0);
-#endif
-}
-
-isc_buffer_t *
-dst_key_tkeytoken(const dst_key_t *key) {
- REQUIRE(VALID_KEY(key));
- return (key->key_tkeytoken);
-}
diff --git a/contrib/bind9/lib/dns/dst_internal.h b/contrib/bind9/lib/dns/dst_internal.h
deleted file mode 100644
index c3e8e29a46e8..000000000000
--- a/contrib/bind9/lib/dns/dst_internal.h
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Portions Copyright (C) 2004-2012 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
- * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
- * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
- * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Portions Copyright (C) 1995-2000 by Network Associates, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
- * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
- * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
- * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: dst_internal.h,v 1.31 2011/10/20 21:20:02 marka Exp $ */
-
-#ifndef DST_DST_INTERNAL_H
-#define DST_DST_INTERNAL_H 1
-
-#include <isc/lang.h>
-#include <isc/buffer.h>
-#include <isc/int.h>
-#include <isc/magic.h>
-#include <isc/region.h>
-#include <isc/types.h>
-#include <isc/md5.h>
-#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
-#include <openssl/dh.h>
-#include <openssl/dsa.h>
-#include <openssl/err.h>
-#include <openssl/evp.h>
-#include <openssl/objects.h>
-#include <openssl/rsa.h>
-#endif
-
-ISC_LANG_BEGINDECLS
-
-#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)
-
-extern isc_mem_t *dst__memory_pool;
-
-/***
- *** Types
- ***/
-
-typedef struct dst_func dst_func_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;
-typedef struct dst_hmacsha384_key dst_hmacsha384_key_t;
-typedef struct dst_hmacsha512_key dst_hmacsha512_key_t;
-
-/*% DST Key Structure */
-struct dst_key {
- unsigned int magic;
- isc_refcount_t refs;
- dns_name_t * key_name; /*%< name of the key */
- unsigned int key_size; /*%< size of the key in bits */
- unsigned int key_proto; /*%< protocols this key is used for */
- unsigned int key_alg; /*%< algorithm of the key */
- isc_uint32_t key_flags; /*%< flags of the public key */
- isc_uint16_t key_id; /*%< identifier of the key */
- isc_uint16_t key_rid; /*%< identifier of the key when
- revoked */
- isc_uint16_t key_bits; /*%< hmac digest bits */
- dns_rdataclass_t key_class; /*%< class of the key record */
- dns_ttl_t key_ttl; /*%< default/initial dnskey ttl */
- isc_mem_t *mctx; /*%< memory context */
- char *engine; /*%< engine name (HSM) */
- char *label; /*%< engine label (HSM) */
- union {
- void *generic;
- gss_ctx_id_t gssctx;
-#ifdef OPENSSL
-#if !defined(USE_EVP) || !USE_EVP
- RSA *rsa;
-#endif
- DSA *dsa;
- DH *dh;
- EVP_PKEY *pkey;
-#endif
- dst_hmacmd5_key_t *hmacmd5;
- dst_hmacsha1_key_t *hmacsha1;
- dst_hmacsha224_key_t *hmacsha224;
- dst_hmacsha256_key_t *hmacsha256;
- dst_hmacsha384_key_t *hmacsha384;
- dst_hmacsha512_key_t *hmacsha512;
-
- } keydata; /*%< pointer to key in crypto pkg fmt */
-
- 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 {
- unsigned int magic;
- dst_key_t *key;
- isc_mem_t *mctx;
- isc_logcategory_t *category;
- union {
- void *generic;
- dst_gssapi_signverifyctx_t *gssctx;
- isc_md5_t *md5ctx;
- isc_sha1_t *sha1ctx;
- isc_sha256_t *sha256ctx;
- isc_sha512_t *sha512ctx;
- isc_hmacmd5_t *hmacmd5ctx;
- isc_hmacsha1_t *hmacsha1ctx;
- isc_hmacsha224_t *hmacsha224ctx;
- isc_hmacsha256_t *hmacsha256ctx;
- isc_hmacsha384_t *hmacsha384ctx;
- isc_hmacsha512_t *hmacsha512ctx;
-#ifdef OPENSSL
- EVP_MD_CTX *evp_md_ctx;
-#endif
- } ctxdata;
-};
-
-struct dst_func {
- /*
- * Context functions
- */
- isc_result_t (*createctx)(dst_key_t *key, dst_context_t *dctx);
- void (*destroyctx)(dst_context_t *dctx);
- isc_result_t (*adddata)(dst_context_t *dctx, const isc_region_t *data);
-
- /*
- * Key operations
- */
- isc_result_t (*sign)(dst_context_t *dctx, isc_buffer_t *sig);
- isc_result_t (*verify)(dst_context_t *dctx, const isc_region_t *sig);
- isc_result_t (*verify2)(dst_context_t *dctx, int maxbits,
- const isc_region_t *sig);
- isc_result_t (*computesecret)(const dst_key_t *pub,
- const dst_key_t *priv,
- isc_buffer_t *secret);
- 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,
- void (*callback)(int));
- isc_boolean_t (*isprivate)(const dst_key_t *key);
- void (*destroy)(dst_key_t *key);
-
- /* conversion functions */
- 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,
- 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(const char *engine);
-
-isc_result_t dst__hmacmd5_init(struct dst_func **funcp);
-isc_result_t dst__hmacsha1_init(struct dst_func **funcp);
-isc_result_t dst__hmacsha224_init(struct dst_func **funcp);
-isc_result_t dst__hmacsha256_init(struct dst_func **funcp);
-isc_result_t dst__hmacsha384_init(struct dst_func **funcp);
-isc_result_t dst__hmacsha512_init(struct dst_func **funcp);
-isc_result_t dst__opensslrsa_init(struct dst_func **funcp,
- unsigned char algorithm);
-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
-#ifdef HAVE_OPENSSL_ECDSA
-isc_result_t dst__opensslecdsa_init(struct dst_func **funcp);
-#endif
-
-/*%
- * Destructors
- */
-void dst__openssl_destroy(void);
-
-/*%
- * Memory allocators using the DST memory pool.
- */
-void * dst__mem_alloc(size_t size);
-void dst__mem_free(void *ptr);
-void * dst__mem_realloc(void *ptr, size_t size);
-
-/*%
- * Entropy retriever using the DST entropy pool.
- */
-isc_result_t dst__entropy_getdata(void *buf, unsigned int len,
- isc_boolean_t pseudo);
-
-/*
- * Entropy status hook.
- */
-unsigned int dst__entropy_status(void);
-
-ISC_LANG_ENDDECLS
-
-#endif /* DST_DST_INTERNAL_H */
-/*! \file */
diff --git a/contrib/bind9/lib/dns/dst_lib.c b/contrib/bind9/lib/dns/dst_lib.c
deleted file mode 100644
index f1021d338dee..000000000000
--- a/contrib/bind9/lib/dns/dst_lib.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * Principal Author: Brian Wellington
- * $Id: dst_lib.c,v 1.5 2007/06/19 23:47:16 tbox Exp $
- */
-
-/*! \file */
-
-#include <config.h>
-
-#include <stddef.h>
-
-#include <isc/once.h>
-#include <isc/msgcat.h>
-#include <isc/util.h>
-
-#include <dst/lib.h>
-
-/***
- *** Globals
- ***/
-
-LIBDNS_EXTERNAL_DATA isc_msgcat_t * dst_msgcat = NULL;
-
-
-/***
- *** Private
- ***/
-
-static isc_once_t msgcat_once = ISC_ONCE_INIT;
-
-
-/***
- *** Functions
- ***/
-
-static void
-open_msgcat(void) {
- isc_msgcat_open("libdst.cat", &dst_msgcat);
-}
-
-void
-dst_lib_initmsgcat(void) {
-
- /*
- * Initialize the DST library's message catalog, dst_msgcat, if it
- * has not already been initialized.
- */
-
- RUNTIME_CHECK(isc_once_do(&msgcat_once, open_msgcat) == ISC_R_SUCCESS);
-}
diff --git a/contrib/bind9/lib/dns/dst_openssl.h b/contrib/bind9/lib/dns/dst_openssl.h
deleted file mode 100644
index 99a43ef948ac..000000000000
--- a/contrib/bind9/lib/dns/dst_openssl.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2002 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: dst_openssl.h,v 1.11 2011/03/12 04:59:48 tbox Exp $ */
-
-#ifndef DST_OPENSSL_H
-#define DST_OPENSSL_H 1
-
-#include <isc/lang.h>
-#include <isc/log.h>
-#include <isc/result.h>
-
-#include <openssl/err.h>
-#include <openssl/rand.h>
-#include <openssl/evp.h>
-#include <openssl/conf.h>
-#include <openssl/crypto.h>
-
-#if !defined(OPENSSL_NO_ENGINE) && defined(CRYPTO_LOCK_ENGINE) && \
- (OPENSSL_VERSION_NUMBER >= 0x0090707f)
-#define USE_ENGINE 1
-#endif
-
-ISC_LANG_BEGINDECLS
-
-isc_result_t
-dst__openssl_toresult(isc_result_t fallback);
-
-isc_result_t
-dst__openssl_toresult2(const char *funcname, isc_result_t fallback);
-
-isc_result_t
-dst__openssl_toresult3(isc_logcategory_t *category,
- const char *funcname, isc_result_t fallback);
-
-#ifdef USE_ENGINE
-ENGINE *
-dst__openssl_getengine(const char *engine);
-#else
-#define dst__openssl_getengine(x) NULL
-#endif
-
-ISC_LANG_ENDDECLS
-
-#endif /* DST_OPENSSL_H */
-/*! \file */
diff --git a/contrib/bind9/lib/dns/dst_parse.c b/contrib/bind9/lib/dns/dst_parse.c
deleted file mode 100644
index ca43cb3d1241..000000000000
--- a/contrib/bind9/lib/dns/dst_parse.c
+++ /dev/null
@@ -1,727 +0,0 @@
-/*
- * Portions Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
- * Portions Copyright (C) 1999-2002 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
- * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
- * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
- * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Portions Copyright (C) 1995-2000 by Network Associates, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
- * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
- * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
- * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*%
- * Principal Author: Brian Wellington
- * $Id: dst_parse.c,v 1.29 2011/08/18 23:46:35 tbox Exp $
- */
-
-#include <config.h>
-
-#include <isc/base64.h>
-#include <isc/dir.h>
-#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 <isc/file.h>
-
-#include <dns/time.h>
-#include <dns/log.h>
-
-#include "dst_internal.h"
-#include "dst_parse.h"
-#include "dst/result.h"
-
-#define DST_AS_STR(t) ((t).value.as_textregion.base)
-
-#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;
-};
-
-static struct parse_map map[] = {
- {TAG_RSA_MODULUS, "Modulus:"},
- {TAG_RSA_PUBLICEXPONENT, "PublicExponent:"},
- {TAG_RSA_PRIVATEEXPONENT, "PrivateExponent:"},
- {TAG_RSA_PRIME1, "Prime1:"},
- {TAG_RSA_PRIME2, "Prime2:"},
- {TAG_RSA_EXPONENT1, "Exponent1:"},
- {TAG_RSA_EXPONENT2, "Exponent2:"},
- {TAG_RSA_COEFFICIENT, "Coefficient:"},
- {TAG_RSA_ENGINE, "Engine:" },
- {TAG_RSA_LABEL, "Label:" },
- {TAG_RSA_PIN, "PIN:" },
-
- {TAG_DH_PRIME, "Prime(p):"},
- {TAG_DH_GENERATOR, "Generator(g):"},
- {TAG_DH_PRIVATE, "Private_value(x):"},
- {TAG_DH_PUBLIC, "Public_value(y):"},
-
- {TAG_DSA_PRIME, "Prime(p):"},
- {TAG_DSA_SUBPRIME, "Subprime(q):"},
- {TAG_DSA_BASE, "Base(g):"},
- {TAG_DSA_PRIVATE, "Private_value(x):"},
- {TAG_DSA_PUBLIC, "Public_value(y):"},
-
- {TAG_GOST_PRIVASN1, "GostAsn1:"},
-
- {TAG_ECDSA_PRIVATEKEY, "PrivateKey:"},
-
- {TAG_HMACMD5_KEY, "Key:"},
- {TAG_HMACMD5_BITS, "Bits:"},
-
- {TAG_HMACSHA1_KEY, "Key:"},
- {TAG_HMACSHA1_BITS, "Bits:"},
-
- {TAG_HMACSHA224_KEY, "Key:"},
- {TAG_HMACSHA224_BITS, "Bits:"},
-
- {TAG_HMACSHA256_KEY, "Key:"},
- {TAG_HMACSHA256_BITS, "Bits:"},
-
- {TAG_HMACSHA384_KEY, "Key:"},
- {TAG_HMACSHA384_BITS, "Bits:"},
-
- {TAG_HMACSHA512_KEY, "Key:"},
- {TAG_HMACSHA512_BITS, "Bits:"},
-
- {0, NULL}
-};
-
-static int
-find_value(const char *s, const unsigned int alg) {
- int i;
-
- 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 *
-find_tag(const int value) {
- int i;
-
- for (i = 0; ; i++) {
- if (map[i].tag == NULL)
- return (NULL);
- else if (value == map[i].value)
- return (map[i].tag);
- }
-}
-
-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];
- isc_boolean_t ok;
- unsigned int mask;
-
- for (i = 0; i < RSA_NTAGS; i++)
- have[i] = ISC_FALSE;
- for (j = 0; j < priv->nelements; j++) {
- for (i = 0; i < RSA_NTAGS; i++)
- if (priv->elements[j].tag == TAG(DST_ALG_RSAMD5, i))
- break;
- if (i == RSA_NTAGS)
- return (-1);
- have[i] = ISC_TRUE;
- }
-
- mask = ~0;
- mask <<= sizeof(mask) * 8 - TAG_SHIFT;
- mask >>= sizeof(mask) * 8 - TAG_SHIFT;
-
- if (have[TAG_RSA_ENGINE & mask])
- ok = have[TAG_RSA_MODULUS & mask] &&
- have[TAG_RSA_PUBLICEXPONENT & mask] &&
- have[TAG_RSA_LABEL & mask];
- else
- ok = have[TAG_RSA_MODULUS & mask] &&
- have[TAG_RSA_PUBLICEXPONENT & mask] &&
- have[TAG_RSA_PRIVATEEXPONENT & mask] &&
- have[TAG_RSA_PRIME1 & mask] &&
- have[TAG_RSA_PRIME2 & mask] &&
- have[TAG_RSA_EXPONENT1 & mask] &&
- have[TAG_RSA_EXPONENT2 & mask] &&
- have[TAG_RSA_COEFFICIENT & mask];
- return (ok ? 0 : -1 );
-}
-
-static int
-check_dh(const dst_private_t *priv) {
- int i, j;
- if (priv->nelements != DH_NTAGS)
- return (-1);
- for (i = 0; i < DH_NTAGS; i++) {
- for (j = 0; j < priv->nelements; j++)
- if (priv->elements[j].tag == TAG(DST_ALG_DH, i))
- break;
- if (j == priv->nelements)
- return (-1);
- }
- return (0);
-}
-
-static int
-check_dsa(const dst_private_t *priv) {
- int i, j;
- if (priv->nelements != DSA_NTAGS)
- return (-1);
- for (i = 0; i < DSA_NTAGS; i++) {
- for (j = 0; j < priv->nelements; j++)
- if (priv->elements[j].tag == TAG(DST_ALG_DSA, i))
- break;
- if (j == priv->nelements)
- return (-1);
- }
- return (0);
-}
-
-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_ecdsa(const dst_private_t *priv) {
- if (priv->nelements != ECDSA_NTAGS)
- return (-1);
- if (priv->elements[0].tag != TAG(DST_ALG_ECDSA256, 0))
- return (-1);
- return (0);
-}
-
-static int
-check_hmac_md5(const dst_private_t *priv, isc_boolean_t old) {
- int i, j;
-
- if (priv->nelements != HMACMD5_NTAGS) {
- /*
- * If this is a good old format and we are accepting
- * the old format return success.
- */
- if (old && priv->nelements == OLD_HMACMD5_NTAGS &&
- priv->elements[0].tag == TAG_HMACMD5_KEY)
- return (0);
- return (-1);
- }
- /*
- * We must be new format at this point.
- */
- for (i = 0; i < HMACMD5_NTAGS; i++) {
- for (j = 0; j < priv->nelements; j++)
- if (priv->elements[j].tag == TAG(DST_ALG_HMACMD5, i))
- break;
- if (j == priv->nelements)
- return (-1);
- }
- return (0);
-}
-
-static int
-check_hmac_sha(const dst_private_t *priv, unsigned int ntags,
- unsigned int alg)
-{
- unsigned int i, j;
- if (priv->nelements != ntags)
- return (-1);
- for (i = 0; i < ntags; i++) {
- for (j = 0; j < priv->nelements; j++)
- if (priv->elements[j].tag == TAG(alg, i))
- break;
- if (j == priv->nelements)
- return (-1);
- }
- return (0);
-}
-
-static int
-check_data(const dst_private_t *priv, const unsigned int alg,
- isc_boolean_t old)
-{
- /* XXXVIX this switch statement is too sparse to gen a jump table. */
- switch (alg) {
- case DST_ALG_RSAMD5:
- case DST_ALG_RSASHA1:
- case DST_ALG_NSEC3RSASHA1:
- case DST_ALG_RSASHA256:
- case DST_ALG_RSASHA512:
- return (check_rsa(priv));
- case DST_ALG_DH:
- return (check_dh(priv));
- case DST_ALG_DSA:
- case DST_ALG_NSEC3DSA:
- return (check_dsa(priv));
- case DST_ALG_ECCGOST:
- return (check_gost(priv));
- case DST_ALG_ECDSA256:
- case DST_ALG_ECDSA384:
- return (check_ecdsa(priv));
- case DST_ALG_HMACMD5:
- return (check_hmac_md5(priv, old));
- case DST_ALG_HMACSHA1:
- return (check_hmac_sha(priv, HMACSHA1_NTAGS, alg));
- case DST_ALG_HMACSHA224:
- return (check_hmac_sha(priv, HMACSHA224_NTAGS, alg));
- case DST_ALG_HMACSHA256:
- return (check_hmac_sha(priv, HMACSHA256_NTAGS, alg));
- case DST_ALG_HMACSHA384:
- return (check_hmac_sha(priv, HMACSHA384_NTAGS, alg));
- case DST_ALG_HMACSHA512:
- return (check_hmac_sha(priv, HMACSHA512_NTAGS, alg));
- default:
- return (DST_R_UNSUPPORTEDALG);
- }
-}
-
-void
-dst__privstruct_free(dst_private_t *priv, isc_mem_t *mctx) {
- int i;
-
- if (priv == NULL)
- return;
- for (i = 0; i < priv->nelements; i++) {
- if (priv->elements[i].data == NULL)
- continue;
- memset(priv->elements[i].data, 0, MAXFIELDSIZE);
- isc_mem_put(mctx, priv->elements[i].data, MAXFIELDSIZE);
- }
- priv->nelements = 0;
-}
-
-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 n = 0, major, minor, check;
- isc_buffer_t b;
- 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);
-
- priv->nelements = 0;
- memset(priv->elements, 0, sizeof(priv->elements));
-
-#define NEXTTOKEN(lex, opt, token) \
- do { \
- ret = isc_lex_gettoken(lex, opt, token); \
- if (ret != ISC_R_SUCCESS) \
- goto fail; \
- } while (0)
-
-#define READLINE(lex, opt, token) \
- do { \
- ret = isc_lex_gettoken(lex, opt, token); \
- if (ret == ISC_R_EOF) \
- break; \
- else if (ret != ISC_R_SUCCESS) \
- goto fail; \
- } while ((*token).type != isc_tokentype_eol)
-
- /*
- * Read the description line.
- */
- NEXTTOKEN(lex, opt, &token);
- if (token.type != isc_tokentype_string ||
- strcmp(DST_AS_STR(token), PRIVATE_KEY_STR) != 0)
- {
- ret = DST_R_INVALIDPRIVATEKEY;
- goto fail;
- }
-
- NEXTTOKEN(lex, opt, &token);
- if (token.type != isc_tokentype_string ||
- (DST_AS_STR(token))[0] != 'v')
- {
- ret = DST_R_INVALIDPRIVATEKEY;
- goto fail;
- }
- if (sscanf(DST_AS_STR(token), "v%d.%d", &major, &minor) != 2)
- {
- ret = DST_R_INVALIDPRIVATEKEY;
- goto fail;
- }
-
- 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);
-
- /*
- * Read the algorithm line.
- */
- NEXTTOKEN(lex, opt, &token);
- if (token.type != isc_tokentype_string ||
- strcmp(DST_AS_STR(token), ALGORITHM_STR) != 0)
- {
- ret = DST_R_INVALIDPRIVATEKEY;
- goto fail;
- }
-
- NEXTTOKEN(lex, opt | ISC_LEXOPT_NUMBER, &token);
- if (token.type != isc_tokentype_number ||
- token.value.as_ulong != (unsigned long) dst_key_alg(key))
- {
- ret = DST_R_INVALIDPRIVATEKEY;
- goto fail;
- }
-
- READLINE(lex, opt, &token);
-
- /*
- * Read the key data.
- */
- 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)
- goto done;
- if (ret != ISC_R_SUCCESS)
- goto fail;
- } while (token.type == isc_tokentype_eol);
-
- if (token.type != isc_tokentype_string) {
- ret = DST_R_INVALIDPRIVATEKEY;
- 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 && 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);
- if (data == NULL)
- goto fail;
-
- isc_buffer_init(&b, data, MAXFIELDSIZE);
- 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:
- check = check_data(priv, alg, ISC_TRUE);
- if (check < 0) {
- ret = DST_R_INVALIDPRIVATEKEY;
- goto fail;
- } else if (check != ISC_R_SUCCESS) {
- ret = check;
- goto fail;
- }
-
- return (ISC_R_SUCCESS);
-
-fail:
- dst__privstruct_free(priv, mctx);
- if (data != NULL)
- isc_mem_put(mctx, data, MAXFIELDSIZE);
-
- return (ret);
-}
-
-isc_result_t
-dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv,
- const char *directory)
-{
- FILE *fp;
- isc_result_t result;
- char filename[ISC_DIR_NAMEMAX];
- char buffer[MAXFIELDSIZE * 2];
- isc_fsaccess_t access;
- isc_stdtime_t when;
- isc_uint32_t value;
- isc_buffer_t b;
- isc_region_t r;
- int major, minor;
- mode_t mode;
- int i, ret;
-
- REQUIRE(priv != NULL);
-
- ret = check_data(priv, dst_key_alg(key), ISC_FALSE);
- if (ret < 0)
- return (DST_R_INVALIDPRIVATEKEY);
- else if (ret != ISC_R_SUCCESS)
- return (ret);
-
- isc_buffer_init(&b, filename, sizeof(filename));
- result = dst_key_buildfilename(key, DST_TYPE_PRIVATE, directory, &b);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- result = isc_file_mode(filename, &mode);
- if (result == ISC_R_SUCCESS && mode != 0600) {
- /* File exists; warn that we are changing its permissions */
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
- DNS_LOGMODULE_DNSSEC, ISC_LOG_WARNING,
- "Permissions on the file %s "
- "have changed from 0%o to 0600 as "
- "a result of this operation.",
- filename, (unsigned int)mode);
- }
-
- if ((fp = fopen(filename, "w")) == NULL)
- return (DST_R_WRITEERROR);
-
- access = 0;
- isc_fsaccess_add(ISC_FSACCESS_OWNER,
- ISC_FSACCESS_READ | ISC_FSACCESS_WRITE,
- &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, 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:
- fprintf(fp, "(RSA)\n");
- break;
- case DST_ALG_DH:
- fprintf(fp, "(DH)\n");
- break;
- case DST_ALG_DSA:
- fprintf(fp, "(DSA)\n");
- break;
- case DST_ALG_RSASHA1:
- fprintf(fp, "(RSASHA1)\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_ECDSA256:
- fprintf(fp, "(ECDSAP256SHA256)\n");
- break;
- case DST_ALG_ECDSA384:
- fprintf(fp, "(ECDSAP384SHA384)\n");
- break;
- case DST_ALG_HMACMD5:
- fprintf(fp, "(HMAC_MD5)\n");
- break;
- case DST_ALG_HMACSHA1:
- fprintf(fp, "(HMAC_SHA1)\n");
- break;
- case DST_ALG_HMACSHA224:
- fprintf(fp, "(HMAC_SHA224)\n");
- break;
- case DST_ALG_HMACSHA256:
- fprintf(fp, "(HMAC_SHA256)\n");
- break;
- case DST_ALG_HMACSHA384:
- fprintf(fp, "(HMAC_SHA384)\n");
- break;
- case DST_ALG_HMACSHA512:
- fprintf(fp, "(HMAC_SHA512)\n");
- break;
- default:
- fprintf(fp, "(?)\n");
- break;
- }
-
- for (i = 0; i < priv->nelements; i++) {
- const char *s;
-
- s = find_tag(priv->elements[i].tag);
-
- r.base = priv->elements[i].data;
- r.length = priv->elements[i].length;
- isc_buffer_init(&b, buffer, sizeof(buffer));
- result = isc_base64_totext(&r, sizeof(buffer), "", &b);
- if (result != ISC_R_SUCCESS) {
- fclose(fp);
- return (DST_R_INVALIDPRIVATEKEY);
- }
- isc_buffer_usedregion(&b, &r);
-
- fprintf(fp, "%s %.*s\n", s, (int)r.length, r.base);
- }
-
- /* 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) {
- fclose(fp);
- return (DST_R_INVALIDPRIVATEKEY);
- }
-
- isc_buffer_usedregion(&b, &r);
-
- fprintf(fp, "%s %.*s\n", timetags[i], (int)r.length,
- r.base);
- }
- }
-
- fflush(fp);
- result = ferror(fp) ? DST_R_WRITEERROR : ISC_R_SUCCESS;
- fclose(fp);
- return (result);
-}
-
-/*! \file */
diff --git a/contrib/bind9/lib/dns/dst_parse.h b/contrib/bind9/lib/dns/dst_parse.h
deleted file mode 100644
index f048bf0c01ed..000000000000
--- a/contrib/bind9/lib/dns/dst_parse.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Portions Copyright (C) 2004-2010, 2012 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
- * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
- * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
- * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Portions Copyright (C) 1995-2000 by Network Associates, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
- * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
- * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
- * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: dst_parse.h,v 1.17 2010/12/23 23:47:08 tbox Exp $ */
-
-/*! \file */
-#ifndef DST_DST_PARSE_H
-#define DST_DST_PARSE_H 1
-
-#include <isc/lang.h>
-
-#include <dst/dst.h>
-
-#define MAXFIELDSIZE 512
-
-/*
- * 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)
-#define TAG(alg, off) (((alg) << TAG_SHIFT) + (off))
-
-/* These are used by both RSA-MD5 and RSA-SHA1 */
-#define RSA_NTAGS 11
-#define TAG_RSA_MODULUS ((DST_ALG_RSAMD5 << TAG_SHIFT) + 0)
-#define TAG_RSA_PUBLICEXPONENT ((DST_ALG_RSAMD5 << TAG_SHIFT) + 1)
-#define TAG_RSA_PRIVATEEXPONENT ((DST_ALG_RSAMD5 << TAG_SHIFT) + 2)
-#define TAG_RSA_PRIME1 ((DST_ALG_RSAMD5 << TAG_SHIFT) + 3)
-#define TAG_RSA_PRIME2 ((DST_ALG_RSAMD5 << TAG_SHIFT) + 4)
-#define TAG_RSA_EXPONENT1 ((DST_ALG_RSAMD5 << TAG_SHIFT) + 5)
-#define TAG_RSA_EXPONENT2 ((DST_ALG_RSAMD5 << TAG_SHIFT) + 6)
-#define TAG_RSA_COEFFICIENT ((DST_ALG_RSAMD5 << TAG_SHIFT) + 7)
-#define TAG_RSA_ENGINE ((DST_ALG_RSAMD5 << TAG_SHIFT) + 8)
-#define TAG_RSA_LABEL ((DST_ALG_RSAMD5 << TAG_SHIFT) + 9)
-#define TAG_RSA_PIN ((DST_ALG_RSAMD5 << TAG_SHIFT) + 10)
-
-#define DH_NTAGS 4
-#define TAG_DH_PRIME ((DST_ALG_DH << TAG_SHIFT) + 0)
-#define TAG_DH_GENERATOR ((DST_ALG_DH << TAG_SHIFT) + 1)
-#define TAG_DH_PRIVATE ((DST_ALG_DH << TAG_SHIFT) + 2)
-#define TAG_DH_PUBLIC ((DST_ALG_DH << TAG_SHIFT) + 3)
-
-#define DSA_NTAGS 5
-#define TAG_DSA_PRIME ((DST_ALG_DSA << TAG_SHIFT) + 0)
-#define TAG_DSA_SUBPRIME ((DST_ALG_DSA << TAG_SHIFT) + 1)
-#define TAG_DSA_BASE ((DST_ALG_DSA << TAG_SHIFT) + 2)
-#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 ECDSA_NTAGS 1
-#define TAG_ECDSA_PRIVATEKEY ((DST_ALG_ECDSA256 << TAG_SHIFT) + 0)
-
-#define OLD_HMACMD5_NTAGS 1
-#define HMACMD5_NTAGS 2
-#define TAG_HMACMD5_KEY ((DST_ALG_HMACMD5 << TAG_SHIFT) + 0)
-#define TAG_HMACMD5_BITS ((DST_ALG_HMACMD5 << TAG_SHIFT) + 1)
-
-#define HMACSHA1_NTAGS 2
-#define TAG_HMACSHA1_KEY ((DST_ALG_HMACSHA1 << TAG_SHIFT) + 0)
-#define TAG_HMACSHA1_BITS ((DST_ALG_HMACSHA1 << TAG_SHIFT) + 1)
-
-#define HMACSHA224_NTAGS 2
-#define TAG_HMACSHA224_KEY ((DST_ALG_HMACSHA224 << TAG_SHIFT) + 0)
-#define TAG_HMACSHA224_BITS ((DST_ALG_HMACSHA224 << TAG_SHIFT) + 1)
-
-#define HMACSHA256_NTAGS 2
-#define TAG_HMACSHA256_KEY ((DST_ALG_HMACSHA256 << TAG_SHIFT) + 0)
-#define TAG_HMACSHA256_BITS ((DST_ALG_HMACSHA256 << TAG_SHIFT) + 1)
-
-#define HMACSHA384_NTAGS 2
-#define TAG_HMACSHA384_KEY ((DST_ALG_HMACSHA384 << TAG_SHIFT) + 0)
-#define TAG_HMACSHA384_BITS ((DST_ALG_HMACSHA384 << TAG_SHIFT) + 1)
-
-#define HMACSHA512_NTAGS 2
-#define TAG_HMACSHA512_KEY ((DST_ALG_HMACSHA512 << TAG_SHIFT) + 0)
-#define TAG_HMACSHA512_BITS ((DST_ALG_HMACSHA512 << TAG_SHIFT) + 1)
-
-struct dst_private_element {
- unsigned short tag;
- unsigned short length;
- unsigned char *data;
-};
-
-typedef struct dst_private_element dst_private_element_t;
-
-struct dst_private {
- unsigned short nelements;
- dst_private_element_t elements[MAXFIELDS];
-};
-
-typedef struct dst_private dst_private_t;
-
-ISC_LANG_BEGINDECLS
-
-void
-dst__privstruct_free(dst_private_t *priv, isc_mem_t *mctx);
-
-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);
-
-isc_result_t
-dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv,
- const char *directory);
-
-ISC_LANG_ENDDECLS
-
-#endif /* DST_DST_PARSE_H */
diff --git a/contrib/bind9/lib/dns/dst_result.c b/contrib/bind9/lib/dns/dst_result.c
deleted file mode 100644
index 297e809cc945..000000000000
--- a/contrib/bind9/lib/dns/dst_result.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007, 2008, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*%
- * Principal Author: Brian Wellington
- * $Id: dst_result.c,v 1.7 2008/04/01 23:47:10 tbox Exp $
- */
-
-#include <config.h>
-
-#include <isc/once.h>
-#include <isc/util.h>
-
-#include <dst/result.h>
-#include <dst/lib.h>
-
-static const char *text[DST_R_NRESULTS] = {
- "algorithm is unsupported", /*%< 0 */
- "crypto failure", /*%< 1 */
- "built with no crypto support", /*%< 2 */
- "illegal operation for a null key", /*%< 3 */
- "public key is invalid", /*%< 4 */
- "private key is invalid", /*%< 5 */
- "UNUSED6", /*%< 6 */
- "error occurred writing key to disk", /*%< 7 */
- "invalid algorithm specific parameter", /*%< 8 */
- "UNUSED9", /*%< 9 */
- "UNUSED10", /*%< 10 */
- "sign failure", /*%< 11 */
- "UNUSED12", /*%< 12 */
- "UNUSED13", /*%< 13 */
- "verify failure", /*%< 14 */
- "not a public key", /*%< 15 */
- "not a private key", /*%< 16 */
- "not a key that can compute a secret", /*%< 17 */
- "failure computing a shared secret", /*%< 18 */
- "no randomness available", /*%< 19 */
- "bad key type", /*%< 20 */
- "no engine" /*%< 21 */
-};
-
-#define DST_RESULT_RESULTSET 2
-
-static isc_once_t once = ISC_ONCE_INIT;
-
-static void
-initialize_action(void) {
- isc_result_t result;
-
- result = isc_result_register(ISC_RESULTCLASS_DST, DST_R_NRESULTS,
- text, dst_msgcat, DST_RESULT_RESULTSET);
- if (result != ISC_R_SUCCESS)
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_result_register() failed: %u", result);
-}
-
-static void
-initialize(void) {
- dst_lib_initmsgcat();
- RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
-}
-
-const char *
-dst_result_totext(isc_result_t result) {
- initialize();
-
- return (isc_result_totext(result));
-}
-
-void
-dst_result_register(void) {
- initialize();
-}
-
-/*! \file */
diff --git a/contrib/bind9/lib/dns/ecdb.c b/contrib/bind9/lib/dns/ecdb.c
deleted file mode 100644
index 8b3f7740081b..000000000000
--- a/contrib/bind9/lib/dns/ecdb.c
+++ /dev/null
@@ -1,827 +0,0 @@
-/*
- * Copyright (C) 2009-2011, 2013 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN 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.10 2011/12/20 00:06:53 marka 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)
-
-/*%
- * 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 RDATASET_ATTR_NEGATIVE 0x0100
-#define NXDOMAIN(header) \
- (((header)->attributes & RDATASET_ATTR_NXDOMAIN) != 0)
-#define NEGATIVE(header) \
- (((header)->attributes & RDATASET_ATTR_NEGATIVE) != 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;
- if (NEGATIVE(header))
- rdataset->attributes |= DNS_RDATASETATTR_NEGATIVE;
-
- 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;
- if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0)
- header->attributes |= RDATASET_ATTR_NEGATIVE;
- 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 */
- NULL, /* findnodeext */
- NULL /* findext */
-};
-
-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);
- }
-#if DNS_RDATASET_FIXED
- raw += 2 + (4 * count);
-#else
- raw += 2;
-#endif
- /*
- * 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];
-#if DNS_RDATASET_FIXED
- raw += length + 4;
-#else
- raw += length + 2;
-#endif
- 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];
-#if DNS_RDATASET_FIXED
- raw += 4;
-#else
- raw += 2;
-#endif
- 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/contrib/bind9/lib/dns/forward.c b/contrib/bind9/lib/dns/forward.c
deleted file mode 100644
index 7ec4e5c9debb..000000000000
--- a/contrib/bind9/lib/dns/forward.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: forward.c,v 1.14 2009/09/02 23:48:02 tbox Exp $ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <isc/magic.h>
-#include <isc/mem.h>
-#include <isc/rwlock.h>
-#include <isc/sockaddr.h>
-#include <isc/util.h>
-
-#include <dns/forward.h>
-#include <dns/rbt.h>
-#include <dns/result.h>
-#include <dns/types.h>
-
-struct dns_fwdtable {
- /* Unlocked. */
- unsigned int magic;
- isc_mem_t *mctx;
- isc_rwlock_t rwlock;
- /* Locked by lock. */
- dns_rbt_t *table;
-};
-
-#define FWDTABLEMAGIC ISC_MAGIC('F', 'w', 'd', 'T')
-#define VALID_FWDTABLE(ft) ISC_MAGIC_VALID(ft, FWDTABLEMAGIC)
-
-static void
-auto_detach(void *, void *);
-
-isc_result_t
-dns_fwdtable_create(isc_mem_t *mctx, dns_fwdtable_t **fwdtablep) {
- dns_fwdtable_t *fwdtable;
- isc_result_t result;
-
- REQUIRE(fwdtablep != NULL && *fwdtablep == NULL);
-
- fwdtable = isc_mem_get(mctx, sizeof(dns_fwdtable_t));
- if (fwdtable == NULL)
- return (ISC_R_NOMEMORY);
-
- fwdtable->table = NULL;
- result = dns_rbt_create(mctx, auto_detach, fwdtable, &fwdtable->table);
- if (result != ISC_R_SUCCESS)
- goto cleanup_fwdtable;
-
- result = isc_rwlock_init(&fwdtable->rwlock, 0, 0);
- if (result != ISC_R_SUCCESS)
- goto cleanup_rbt;
-
- fwdtable->mctx = NULL;
- isc_mem_attach(mctx, &fwdtable->mctx);
- fwdtable->magic = FWDTABLEMAGIC;
- *fwdtablep = fwdtable;
-
- return (ISC_R_SUCCESS);
-
- cleanup_rbt:
- dns_rbt_destroy(&fwdtable->table);
-
- cleanup_fwdtable:
- isc_mem_put(mctx, fwdtable, sizeof(dns_fwdtable_t));
-
- return (result);
-}
-
-isc_result_t
-dns_fwdtable_add(dns_fwdtable_t *fwdtable, dns_name_t *name,
- isc_sockaddrlist_t *addrs, dns_fwdpolicy_t fwdpolicy)
-{
- isc_result_t result;
- dns_forwarders_t *forwarders;
- isc_sockaddr_t *sa, *nsa;
-
- REQUIRE(VALID_FWDTABLE(fwdtable));
-
- forwarders = isc_mem_get(fwdtable->mctx, sizeof(dns_forwarders_t));
- if (forwarders == NULL)
- return (ISC_R_NOMEMORY);
-
- ISC_LIST_INIT(forwarders->addrs);
- for (sa = ISC_LIST_HEAD(*addrs);
- sa != NULL;
- sa = ISC_LIST_NEXT(sa, link))
- {
- nsa = isc_mem_get(fwdtable->mctx, sizeof(isc_sockaddr_t));
- if (nsa == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup;
- }
- *nsa = *sa;
- ISC_LINK_INIT(nsa, link);
- ISC_LIST_APPEND(forwarders->addrs, nsa, link);
- }
- forwarders->fwdpolicy = fwdpolicy;
-
- RWLOCK(&fwdtable->rwlock, isc_rwlocktype_write);
- result = dns_rbt_addname(fwdtable->table, name, forwarders);
- RWUNLOCK(&fwdtable->rwlock, isc_rwlocktype_write);
-
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- return (ISC_R_SUCCESS);
-
- cleanup:
- while (!ISC_LIST_EMPTY(forwarders->addrs)) {
- sa = ISC_LIST_HEAD(forwarders->addrs);
- ISC_LIST_UNLINK(forwarders->addrs, sa, link);
- isc_mem_put(fwdtable->mctx, sa, sizeof(isc_sockaddr_t));
- }
- isc_mem_put(fwdtable->mctx, forwarders, sizeof(dns_forwarders_t));
- return (result);
-}
-
-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,
- dns_name_t *foundname, dns_forwarders_t **forwardersp)
-{
- isc_result_t result;
-
- REQUIRE(VALID_FWDTABLE(fwdtable));
-
- RWLOCK(&fwdtable->rwlock, isc_rwlocktype_read);
-
- result = dns_rbt_findname(fwdtable->table, name, 0, foundname,
- (void **)forwardersp);
- if (result == DNS_R_PARTIALMATCH)
- result = ISC_R_SUCCESS;
-
- RWUNLOCK(&fwdtable->rwlock, isc_rwlocktype_read);
-
- return (result);
-}
-
-void
-dns_fwdtable_destroy(dns_fwdtable_t **fwdtablep) {
- dns_fwdtable_t *fwdtable;
- isc_mem_t *mctx;
-
- REQUIRE(fwdtablep != NULL && VALID_FWDTABLE(*fwdtablep));
-
- fwdtable = *fwdtablep;
-
- dns_rbt_destroy(&fwdtable->table);
- isc_rwlock_destroy(&fwdtable->rwlock);
- fwdtable->magic = 0;
- mctx = fwdtable->mctx;
- isc_mem_put(mctx, fwdtable, sizeof(dns_fwdtable_t));
- isc_mem_detach(&mctx);
-
- *fwdtablep = NULL;
-}
-
-/***
- *** Private
- ***/
-
-static void
-auto_detach(void *data, void *arg) {
- dns_forwarders_t *forwarders = data;
- dns_fwdtable_t *fwdtable = arg;
- isc_sockaddr_t *sa;
-
- UNUSED(arg);
-
- while (!ISC_LIST_EMPTY(forwarders->addrs)) {
- sa = ISC_LIST_HEAD(forwarders->addrs);
- ISC_LIST_UNLINK(forwarders->addrs, sa, link);
- isc_mem_put(fwdtable->mctx, sa, sizeof(isc_sockaddr_t));
- }
- isc_mem_put(fwdtable->mctx, forwarders, sizeof(dns_forwarders_t));
-}
diff --git a/contrib/bind9/lib/dns/gen-unix.h b/contrib/bind9/lib/dns/gen-unix.h
deleted file mode 100644
index 87529d4edfa0..000000000000
--- a/contrib/bind9/lib/dns/gen-unix.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: gen-unix.h,v 1.21 2009/01/17 23:47:42 tbox Exp $ */
-
-/*! \file
- * \brief
- * This file is responsible for defining two operations that are not
- * directly portable between Unix-like systems and Windows NT, option
- * parsing and directory scanning. It is here because it was decided
- * that the "gen" build utility was not to depend on libisc.a, so
- * the functions declared in isc/commandline.h and isc/dir.h could not
- * be used.
- *
- * The commandline stuff is really just a wrapper around getopt().
- * The dir stuff was shrunk to fit the needs of gen.c.
- */
-
-#ifndef DNS_GEN_UNIX_H
-#define DNS_GEN_UNIX_H 1
-
-#include <sys/types.h> /* Required on some systems for dirent.h. */
-
-#include <dirent.h>
-#include <unistd.h> /* XXXDCL Required for ?. */
-
-#include <isc/boolean.h>
-#include <isc/lang.h>
-
-#ifdef NEED_OPTARG
-extern char *optarg;
-#endif
-
-#define isc_commandline_parse getopt
-#define isc_commandline_argument optarg
-
-typedef struct {
- DIR *handle;
- char *filename;
-} isc_dir_t;
-
-ISC_LANG_BEGINDECLS
-
-static isc_boolean_t
-start_directory(const char *path, isc_dir_t *dir) {
- dir->handle = opendir(path);
-
- if (dir->handle != NULL)
- return (ISC_TRUE);
- else
- return (ISC_FALSE);
-
-}
-
-static isc_boolean_t
-next_file(isc_dir_t *dir) {
- struct dirent *dirent;
-
- dir->filename = NULL;
-
- if (dir->handle != NULL) {
- dirent = readdir(dir->handle);
- if (dirent != NULL)
- dir->filename = dirent->d_name;
- }
-
- if (dir->filename != NULL)
- return (ISC_TRUE);
- else
- return (ISC_FALSE);
-}
-
-static void
-end_directory(isc_dir_t *dir) {
- if (dir->handle != NULL)
- (void)closedir(dir->handle);
-
- dir->handle = NULL;
-}
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_GEN_UNIX_H */
diff --git a/contrib/bind9/lib/dns/gen.c b/contrib/bind9/lib/dns/gen.c
deleted file mode 100644
index 6b533dd23f9c..000000000000
--- a/contrib/bind9/lib/dns/gen.c
+++ /dev/null
@@ -1,910 +0,0 @@
-/*
- * Copyright (C) 2004-2009, 2012, 2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*! \file */
-
-#ifdef WIN32
-/*
- * Silence compiler warnings about using strcpy and friends.
- */
-#define _CRT_SECURE_NO_DEPRECATE 1
-/*
- * We use snprintf.
- */
-#define snprintf _snprintf
-#endif
-
-#include <sys/types.h>
-
-#include <ctype.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#ifdef WIN32
-#include "gen-win32.h"
-#else
-#include "gen-unix.h"
-#endif
-
-#define INSIST(cond) \
- if (!(cond)) { \
- fprintf(stderr, "%s:%d: INSIST(%s)\n", \
- __FILE__, __LINE__, #cond); \
- abort(); \
- }
-
-#define FROMTEXTARGS "rdclass, type, lexer, origin, options, target, callbacks"
-#define FROMTEXTCLASS "rdclass"
-#define FROMTEXTTYPE "type"
-#define FROMTEXTDEF "result = DNS_R_UNKNOWN"
-
-#define TOTEXTARGS "rdata, tctx, target"
-#define TOTEXTCLASS "rdata->rdclass"
-#define TOTEXTTYPE "rdata->type"
-#define TOTEXTDEF "use_default = ISC_TRUE"
-
-#define FROMWIREARGS "rdclass, type, source, dctx, options, target"
-#define FROMWIRECLASS "rdclass"
-#define FROMWIRETYPE "type"
-#define FROMWIREDEF "use_default = ISC_TRUE"
-
-#define TOWIREARGS "rdata, cctx, target"
-#define TOWIRECLASS "rdata->rdclass"
-#define TOWIRETYPE "rdata->type"
-#define TOWIREDEF "use_default = ISC_TRUE"
-
-#define FROMSTRUCTARGS "rdclass, type, source, target"
-#define FROMSTRUCTCLASS "rdclass"
-#define FROMSTRUCTTYPE "type"
-#define FROMSTRUCTDEF "use_default = ISC_TRUE"
-
-#define TOSTRUCTARGS "rdata, target, mctx"
-#define TOSTRUCTCLASS "rdata->rdclass"
-#define TOSTRUCTTYPE "rdata->type"
-#define TOSTRUCTDEF "use_default = ISC_TRUE"
-
-#define FREESTRUCTARGS "source"
-#define FREESTRUCTCLASS "common->rdclass"
-#define FREESTRUCTTYPE "common->rdtype"
-#define FREESTRUCTDEF NULL
-
-#define COMPAREARGS "rdata1, rdata2"
-#define COMPARECLASS "rdata1->rdclass"
-#define COMPARETYPE "rdata1->type"
-#define COMPAREDEF "use_default = ISC_TRUE"
-
-#define ADDITIONALDATAARGS "rdata, add, arg"
-#define ADDITIONALDATACLASS "rdata->rdclass"
-#define ADDITIONALDATATYPE "rdata->type"
-#define ADDITIONALDATADEF "use_default = ISC_TRUE"
-
-#define DIGESTARGS "rdata, digest, arg"
-#define DIGESTCLASS "rdata->rdclass"
-#define DIGESTTYPE "rdata->type"
-#define DIGESTDEF "use_default = ISC_TRUE"
-
-#define CHECKOWNERARGS "name, rdclass, type, wildcard"
-#define CHECKOWNERCLASS "rdclass"
-#define CHECKOWNERTYPE "type"
-#define CHECKOWNERDEF "result = ISC_TRUE"
-
-#define CHECKNAMESARGS "rdata, owner, bad"
-#define CHECKNAMESCLASS "rdata->rdclass"
-#define CHECKNAMESTYPE "rdata->type"
-#define CHECKNAMESDEF "result = ISC_TRUE"
-
-static const char copyright[] =
-"/*\n"
-" * Copyright (C) 2004%s Internet Systems Consortium, Inc. (\"ISC\")\n"
-" * Copyright (C) 1998-2003 Internet Software Consortium.\n"
-" *\n"
-" * Permission to use, copy, modify, and distribute this software for any\n"
-" * purpose with or without fee is hereby granted, provided that the above\n"
-" * copyright notice and this permission notice appear in all copies.\n"
-" *\n"
-" * THE SOFTWARE IS PROVIDED \"AS IS\" AND ISC DISCLAIMS ALL WARRANTIES WITH\n"
-" * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\n"
-" * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,\n"
-" * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\n"
-" * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE\n"
-" * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\n"
-" * PERFORMANCE OF THIS SOFTWARE.\n"
-" */\n"
-"\n"
-"/***************\n"
-" ***************\n"
-" *************** THIS FILE IS AUTOMATICALLY GENERATED BY gen.c.\n"
-" *************** DO NOT EDIT!\n"
-" ***************\n"
-" ***************/\n"
-"\n"
-"/*! \\file */\n"
-"\n";
-
-#define STR_EXPAND(tok) #tok
-#define STR(tok) STR_EXPAND(tok)
-
-#define TYPENAMES 256
-#define TYPECLASSLEN 20 /* DNS mnemonic size. Must be less than 100. */
-#define TYPECLASSBUF (TYPECLASSLEN + 1)
-#define TYPECLASSFMT "%" STR(TYPECLASSLEN) "[-0-9a-z]_%d"
-#define ATTRIBUTESIZE 256
-#define DIRNAMESIZE 256
-
-static struct cc {
- struct cc *next;
- int rdclass;
- char classname[TYPECLASSBUF];
-} *classes;
-
-static struct tt {
- struct tt *next;
- int rdclass;
- int type;
- char classname[TYPECLASSBUF];
- char typename[TYPECLASSBUF];
- char dirname[DIRNAMESIZE]; /* XXX Should be max path length */
-} *types;
-
-static struct ttnam {
- char typename[TYPECLASSBUF];
- char macroname[TYPECLASSBUF];
- char attr[ATTRIBUTESIZE];
- unsigned int sorted;
- int type;
-} typenames[TYPENAMES];
-
-static int maxtype = -1;
-
-static char *
-upper(char *);
-static char *
-funname(const char *, char *);
-static void
-doswitch(const char *, const char *, const char *, const char *,
- const char *, const char *);
-static void
-add(int, const char *, int, const char *, const char *);
-static void
-sd(int, const char *, const char *, char);
-static void
-insert_into_typenames(int, const char *, const char *);
-
-/*%
- * If you use more than 10 of these in, say, a printf(), you'll have problems.
- */
-static char *
-upper(char *s) {
- static int buf_to_use = 0;
- static char buf[10][256];
- char *b;
- int c;
-
- buf_to_use++;
- if (buf_to_use > 9)
- buf_to_use = 0;
-
- b = buf[buf_to_use];
- memset(b, 0, 256);
-
- while ((c = (*s++) & 0xff))
- *b++ = islower(c) ? toupper(c) : c;
- *b = '\0';
- return (buf[buf_to_use]);
-}
-
-static char *
-funname(const char *s, char *buf) {
- char *b = buf;
- char c;
-
- INSIST(strlen(s) < TYPECLASSBUF);
- while ((c = *s++)) {
- *b++ = (c == '-') ? '_' : c;
- }
- *b = '\0';
- return (buf);
-}
-
-static void
-doswitch(const char *name, const char *function, const char *args,
- const char *tsw, const char *csw, const char *res)
-{
- struct tt *tt;
- int first = 1;
- int lasttype = 0;
- int subswitch = 0;
- char buf1[TYPECLASSBUF], buf2[TYPECLASSBUF];
- const char *result = " result =";
-
- if (res == NULL)
- result = "";
-
- for (tt = types; tt != NULL; tt = tt->next) {
- if (first) {
- fprintf(stdout, "\n#define %s \\\n", name);
- fprintf(stdout, "\tswitch (%s) { \\\n" /*}*/, tsw);
- first = 0;
- }
- if (tt->type != lasttype && subswitch) {
- if (res == NULL)
- fprintf(stdout, "\t\tdefault: break; \\\n");
- else
- fprintf(stdout,
- "\t\tdefault: %s; break; \\\n", res);
- fputs(/*{*/ "\t\t} \\\n", stdout);
- fputs("\t\tbreak; \\\n", stdout);
- subswitch = 0;
- }
- if (tt->rdclass && tt->type != lasttype) {
- fprintf(stdout, "\tcase %d: switch (%s) { \\\n" /*}*/,
- tt->type, csw);
- subswitch = 1;
- }
- if (tt->rdclass == 0)
- fprintf(stdout,
- "\tcase %d:%s %s_%s(%s); break;",
- tt->type, result, function,
- funname(tt->typename, buf1), args);
- else
- fprintf(stdout,
- "\t\tcase %d:%s %s_%s_%s(%s); break;",
- tt->rdclass, result, function,
- funname(tt->classname, buf1),
- funname(tt->typename, buf2), args);
- fputs(" \\\n", stdout);
- lasttype = tt->type;
- }
- if (subswitch) {
- if (res == NULL)
- fprintf(stdout, "\t\tdefault: break; \\\n");
- else
- fprintf(stdout, "\t\tdefault: %s; break; \\\n", res);
- fputs(/*{*/ "\t\t} \\\n", stdout);
- fputs("\t\tbreak; \\\n", stdout);
- }
- if (first) {
- if (res == NULL)
- fprintf(stdout, "\n#define %s\n", name);
- else
- fprintf(stdout, "\n#define %s %s;\n", name, res);
- } else {
- if (res == NULL)
- fprintf(stdout, "\tdefault: break; \\\n");
- else
- fprintf(stdout, "\tdefault: %s; break; \\\n", res);
- fputs(/*{*/ "\t}\n", stdout);
- }
-}
-
-static struct ttnam *
-find_typename(int type) {
- int i;
-
- for (i = 0; i < TYPENAMES; i++) {
- if (typenames[i].typename[0] != 0 &&
- typenames[i].type == type)
- return (&typenames[i]);
- }
- return (NULL);
-}
-
-static void
-insert_into_typenames(int type, const char *typename, const char *attr) {
- struct ttnam *ttn = NULL;
- int c, i, n;
- char tmp[256];
-
- INSIST(strlen(typename) < TYPECLASSBUF);
- for (i = 0; i < TYPENAMES; i++) {
- if (typenames[i].typename[0] != 0 &&
- typenames[i].type == type &&
- strcmp(typename, typenames[i].typename) != 0) {
- fprintf(stderr,
- "Error: type %d has two names: %s, %s\n",
- type, typenames[i].typename, typename);
- exit(1);
- }
- if (typenames[i].typename[0] == 0 && ttn == NULL)
- ttn = &typenames[i];
- }
- if (ttn == NULL) {
- fprintf(stderr, "Error: typenames array too small\n");
- exit(1);
- }
-
- if (strlen(typename) > sizeof(ttn->typename) - 1) {
- fprintf(stderr, "Error: type name %s is too long\n",
- typename);
- exit(1);
- }
- strncpy(ttn->typename, typename, sizeof(ttn->typename));
- ttn->type = type;
-
- strncpy(ttn->macroname, ttn->typename, sizeof(ttn->macroname));
- c = strlen(ttn->macroname);
- while (c > 0) {
- if (ttn->macroname[c - 1] == '-')
- ttn->macroname[c - 1] = '_';
- c--;
- }
-
- if (attr == NULL) {
- n = snprintf(tmp, sizeof(tmp),
- "RRTYPE_%s_ATTRIBUTES", upper(ttn->macroname));
- INSIST(n > 0 && (unsigned)n < sizeof(tmp));
- attr = tmp;
- }
-
- if (ttn->attr[0] != 0 && strcmp(attr, ttn->attr) != 0) {
- fprintf(stderr, "Error: type %d has different attributes: "
- "%s, %s\n", type, ttn->attr, attr);
- exit(1);
- }
-
- if (strlen(attr) > sizeof(ttn->attr) - 1) {
- fprintf(stderr, "Error: attr (%s) [name %s] is too long\n",
- attr, typename);
- exit(1);
- }
- strncpy(ttn->attr, attr, sizeof(ttn->attr));
- ttn->sorted = 0;
- if (maxtype < type)
- maxtype = type;
-}
-
-static void
-add(int rdclass, const char *classname, int type, const char *typename,
- const char *dirname)
-{
- struct tt *newtt = (struct tt *)malloc(sizeof(*newtt));
- struct tt *tt, *oldtt;
- struct cc *newcc;
- struct cc *cc, *oldcc;
-
- INSIST(strlen(typename) < TYPECLASSBUF);
- INSIST(strlen(classname) < TYPECLASSBUF);
- INSIST(strlen(dirname) < DIRNAMESIZE);
-
- insert_into_typenames(type, typename, NULL);
-
- if (newtt == NULL) {
- fprintf(stderr, "malloc() failed\n");
- exit(1);
- }
-
- newtt->next = NULL;
- newtt->rdclass = rdclass;
- newtt->type = type;
- strncpy(newtt->classname, classname, sizeof(newtt->classname));
- strncpy(newtt->typename, typename, sizeof(newtt->typename));
- if (strncmp(dirname, "./", 2) == 0)
- dirname += 2;
- strncpy(newtt->dirname, dirname, sizeof(newtt->dirname));
-
- tt = types;
- oldtt = NULL;
-
- while ((tt != NULL) && (tt->type < type)) {
- oldtt = tt;
- tt = tt->next;
- }
-
- while ((tt != NULL) && (tt->type == type) && (tt->rdclass < rdclass)) {
- if (strcmp(tt->typename, typename) != 0)
- exit(1);
- oldtt = tt;
- tt = tt->next;
- }
-
- if ((tt != NULL) && (tt->type == type) && (tt->rdclass == rdclass))
- exit(1);
-
- newtt->next = tt;
- if (oldtt != NULL)
- oldtt->next = newtt;
- else
- types = newtt;
-
- /*
- * Do a class switch for this type.
- */
- if (rdclass == 0)
- return;
-
- newcc = (struct cc *)malloc(sizeof(*newcc));
- if (newcc == NULL) {
- fprintf(stderr, "malloc() failed\n");
- exit(1);
- }
- newcc->rdclass = rdclass;
- strncpy(newcc->classname, classname, sizeof(newcc->classname));
- cc = classes;
- oldcc = NULL;
-
- while ((cc != NULL) && (cc->rdclass < rdclass)) {
- oldcc = cc;
- cc = cc->next;
- }
-
- if ((cc != NULL) && cc->rdclass == rdclass) {
- free((char *)newcc);
- return;
- }
-
- newcc->next = cc;
- if (oldcc != NULL)
- oldcc->next = newcc;
- else
- classes = newcc;
-}
-
-static void
-sd(int rdclass, const char *classname, const char *dirname, char filetype) {
- char buf[TYPECLASSLEN + sizeof("_65535.h")];
- char typename[TYPECLASSBUF];
- int type, n;
- isc_dir_t dir;
-
- if (!start_directory(dirname, &dir))
- return;
-
- while (next_file(&dir)) {
- if (sscanf(dir.filename, TYPECLASSFMT, typename, &type) != 2)
- continue;
- if ((type > 65535) || (type < 0))
- continue;
-
- n = snprintf(buf, sizeof(buf), "%s_%d.%c", typename,
- type, filetype);
- INSIST(n > 0 && (unsigned)n < sizeof(buf));
- if (strcmp(buf, dir.filename) != 0)
- continue;
- add(rdclass, classname, type, typename, dirname);
- }
-
- end_directory(&dir);
-}
-
-static unsigned int
-HASH(char *string) {
- unsigned int n;
- unsigned char a, b;
-
- n = strlen(string);
- if (n == 0) {
- fprintf(stderr, "n == 0?\n");
- exit(1);
- }
- a = tolower((unsigned char)string[0]);
- b = tolower((unsigned char)string[n - 1]);
-
- return ((a + n) * b) % 256;
-}
-
-int
-main(int argc, char **argv) {
- char buf[DIRNAMESIZE]; /* XXX Should be max path length */
- char srcdir[DIRNAMESIZE]; /* XXX Should be max path length */
- int rdclass;
- char classname[TYPECLASSBUF];
- struct tt *tt;
- struct cc *cc;
- struct ttnam *ttn, *ttn2;
- unsigned int hash;
- struct tm *tm;
- time_t now;
- char year[11];
- int lasttype;
- int code = 1;
- int class_enum = 0;
- int type_enum = 0;
- int structs = 0;
- int depend = 0;
- int c, i, j, n;
- char buf1[TYPECLASSBUF];
- char filetype = 'c';
- FILE *fd;
- char *prefix = NULL;
- char *suffix = NULL;
- char *file = NULL;
- isc_dir_t dir;
-
- for (i = 0; i < TYPENAMES; i++)
- memset(&typenames[i], 0, sizeof(typenames[i]));
-
- strcpy(srcdir, "");
- while ((c = isc_commandline_parse(argc, argv, "cdits:F:P:S:")) != -1)
- switch (c) {
- case 'c':
- code = 0;
- depend = 0;
- type_enum = 0;
- class_enum = 1;
- filetype = 'c';
- structs = 0;
- break;
- case 'd':
- code = 0;
- depend = 1;
- class_enum = 0;
- type_enum = 0;
- structs = 0;
- filetype = 'h';
- break;
- case 't':
- code = 0;
- depend = 0;
- class_enum = 0;
- type_enum = 1;
- filetype = 'c';
- structs = 0;
- break;
- case 'i':
- code = 0;
- depend = 0;
- class_enum = 0;
- type_enum = 0;
- structs = 1;
- filetype = 'h';
- break;
- case 's':
- if (strlen(isc_commandline_argument) >
- DIRNAMESIZE - 2 * TYPECLASSLEN -
- sizeof("/rdata/_65535_65535")) {
- fprintf(stderr, "\"%s\" too long\n",
- isc_commandline_argument);
- exit(1);
- }
- n = snprintf(srcdir, sizeof(srcdir), "%s/",
- isc_commandline_argument);
- INSIST(n > 0 && (unsigned)n < sizeof(srcdir));
- break;
- case 'F':
- file = isc_commandline_argument;
- break;
- case 'P':
- prefix = isc_commandline_argument;
- break;
- case 'S':
- suffix = isc_commandline_argument;
- break;
- case '?':
- exit(1);
- }
-
- n = snprintf(buf, sizeof(buf), "%srdata", srcdir);
- INSIST(n > 0 && (unsigned)n < sizeof(srcdir));
-
- if (!start_directory(buf, &dir))
- exit(1);
-
- while (next_file(&dir)) {
- if (sscanf(dir.filename, TYPECLASSFMT, classname,
- &rdclass) != 2)
- continue;
- if ((rdclass > 65535) || (rdclass < 0))
- continue;
-
- n = snprintf(buf, sizeof(buf), "%srdata/%s_%d",
- srcdir, classname, rdclass);
- INSIST(n > 0 && (unsigned)n < sizeof(buf));
- if (strcmp(buf + 6 + strlen(srcdir), dir.filename) != 0)
- continue;
- sd(rdclass, classname, buf, filetype);
- }
- end_directory(&dir);
- n = snprintf(buf, sizeof(buf), "%srdata/generic", srcdir);
- INSIST(n > 0 && (unsigned)n < sizeof(srcdir));
- sd(0, "", buf, filetype);
-
- if (time(&now) != -1) {
- if ((tm = localtime(&now)) != NULL && tm->tm_year > 104) {
- n = snprintf(year, sizeof(year), "-%d",
- tm->tm_year + 1900);
- INSIST(n > 0 && (unsigned)n < sizeof(year));
- } else
- year[0] = 0;
- } else
- year[0] = 0;
-
- if (!depend) fprintf(stdout, copyright, year);
-
- if (code) {
- fputs("#ifndef DNS_CODE_H\n", stdout);
- fputs("#define DNS_CODE_H 1\n\n", stdout);
-
- fputs("#include <isc/boolean.h>\n", stdout);
- fputs("#include <isc/result.h>\n\n", stdout);
- fputs("#include <dns/name.h>\n\n", stdout);
-
- for (tt = types; tt != NULL; tt = tt->next)
- fprintf(stdout, "#include \"%s/%s_%d.c\"\n",
- tt->dirname, tt->typename, tt->type);
-
- fputs("\n\n", stdout);
-
- doswitch("FROMTEXTSWITCH", "fromtext", FROMTEXTARGS,
- FROMTEXTTYPE, FROMTEXTCLASS, FROMTEXTDEF);
- doswitch("TOTEXTSWITCH", "totext", TOTEXTARGS,
- TOTEXTTYPE, TOTEXTCLASS, TOTEXTDEF);
- doswitch("FROMWIRESWITCH", "fromwire", FROMWIREARGS,
- FROMWIRETYPE, FROMWIRECLASS, FROMWIREDEF);
- doswitch("TOWIRESWITCH", "towire", TOWIREARGS,
- 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,
- TOSTRUCTTYPE, TOSTRUCTCLASS, TOSTRUCTDEF);
- doswitch("FREESTRUCTSWITCH", "freestruct", FREESTRUCTARGS,
- FREESTRUCTTYPE, FREESTRUCTCLASS, FREESTRUCTDEF);
- doswitch("ADDITIONALDATASWITCH", "additionaldata",
- ADDITIONALDATAARGS, ADDITIONALDATATYPE,
- ADDITIONALDATACLASS, ADDITIONALDATADEF);
- doswitch("DIGESTSWITCH", "digest",
- DIGESTARGS, DIGESTTYPE,
- DIGESTCLASS, DIGESTDEF);
- doswitch("CHECKOWNERSWITCH", "checkowner",
- CHECKOWNERARGS, CHECKOWNERTYPE,
- CHECKOWNERCLASS, CHECKOWNERDEF);
- doswitch("CHECKNAMESSWITCH", "checknames",
- CHECKNAMESARGS, CHECKNAMESTYPE,
- CHECKNAMESCLASS, CHECKNAMESDEF);
-
- /*
- * From here down, we are processing the rdata names and
- * attributes.
- */
-
-#define PRINT_COMMA(x) (x == maxtype ? "" : ",")
-
-#define METANOTQUESTION "DNS_RDATATYPEATTR_META | " \
- "DNS_RDATATYPEATTR_NOTQUESTION"
-#define METAQUESTIONONLY "DNS_RDATATYPEATTR_META | " \
- "DNS_RDATATYPEATTR_QUESTIONONLY"
-#define RESERVED "DNS_RDATATYPEATTR_RESERVED"
-
- /*
- * Add in reserved/special types. This will let us
- * sort them without special cases.
- */
- insert_into_typenames(0, "reserved0", RESERVED);
- insert_into_typenames(31, "eid", RESERVED);
- insert_into_typenames(32, "nimloc", RESERVED);
- insert_into_typenames(34, "atma", RESERVED);
- insert_into_typenames(100, "uinfo", RESERVED);
- insert_into_typenames(101, "uid", RESERVED);
- insert_into_typenames(102, "gid", RESERVED);
- insert_into_typenames(251, "ixfr", METAQUESTIONONLY);
- insert_into_typenames(252, "axfr", METAQUESTIONONLY);
- insert_into_typenames(253, "mailb", METAQUESTIONONLY);
- insert_into_typenames(254, "maila", METAQUESTIONONLY);
- insert_into_typenames(255, "any", METAQUESTIONONLY);
-
- /*
- * Spit out a quick and dirty hash function. Here,
- * we walk through the list of type names, and calculate
- * a hash. This isn't perfect, but it will generate "pretty
- * good" estimates. Lowercase the characters before
- * computing in all cases.
- *
- * Here, walk the list from top to bottom, calculating
- * the hash (mod 256) for each name.
- */
- fprintf(stdout, "#define RDATATYPE_COMPARE(_s, _d, _tn, _n, _tp) \\\n");
- fprintf(stdout, "\tdo { \\\n");
- fprintf(stdout, "\t\tif (sizeof(_s) - 1 == _n && \\\n"
- "\t\t strncasecmp(_s,(_tn),"
- "(sizeof(_s) - 1)) == 0) { \\\n");
- fprintf(stdout, "\t\t\tif ((dns_rdatatype_attributes(_d) & "
- "DNS_RDATATYPEATTR_RESERVED) != 0) \\\n");
- fprintf(stdout, "\t\t\t\treturn (ISC_R_NOTIMPLEMENTED); \\\n");
- fprintf(stdout, "\t\t\t*(_tp) = _d; \\\n");
- fprintf(stdout, "\t\t\treturn (ISC_R_SUCCESS); \\\n");
- fprintf(stdout, "\t\t} \\\n");
- fprintf(stdout, "\t} while (0)\n\n");
-
- fprintf(stdout, "#define RDATATYPE_FROMTEXT_SW(_hash,"
- "_typename,_length,_typep) \\\n");
- fprintf(stdout, "\tswitch (_hash) { \\\n");
- for (i = 0; i <= maxtype; i++) {
- ttn = find_typename(i);
- if (ttn == NULL)
- continue;
-
- /*
- * Skip entries we already processed.
- */
- if (ttn->sorted != 0)
- continue;
-
- hash = HASH(ttn->typename);
- fprintf(stdout, "\t\tcase %u: \\\n", hash);
-
- /*
- * Find all other entries that happen to match
- * this hash.
- */
- for (j = 0; j <= maxtype; j++) {
- ttn2 = find_typename(j);
- if (ttn2 == NULL)
- continue;
- if (hash == HASH(ttn2->typename)) {
- fprintf(stdout, "\t\t\tRDATATYPE_COMPARE"
- "(\"%s\", %u, "
- "_typename, _length, _typep); \\\n",
- ttn2->typename, ttn2->type);
- ttn2->sorted = 1;
- }
- }
- fprintf(stdout, "\t\t\tbreak; \\\n");
- }
- fprintf(stdout, "\t}\n");
-
- fprintf(stdout, "#define RDATATYPE_ATTRIBUTE_SW \\\n");
- fprintf(stdout, "\tswitch (type) { \\\n");
- for (i = 0; i <= maxtype; i++) {
- ttn = find_typename(i);
- if (ttn == NULL)
- continue;
- fprintf(stdout, "\tcase %u: return (%s); \\\n",
- i, upper(ttn->attr));
- }
- fprintf(stdout, "\t}\n");
-
- fprintf(stdout, "#define RDATATYPE_TOTEXT_SW \\\n");
- fprintf(stdout, "\tswitch (type) { \\\n");
- for (i = 0; i <= maxtype; i++) {
- ttn = find_typename(i);
- if (ttn == NULL)
- continue;
- fprintf(stdout, "\tcase %u: return "
- "(str_totext(\"%s\", target)); \\\n",
- i, upper(ttn->typename));
- }
- fprintf(stdout, "\t}\n");
-
- fputs("#endif /* DNS_CODE_H */\n", stdout);
- } else if (type_enum) {
- char *s;
-
- fprintf(stdout, "#ifndef DNS_ENUMTYPE_H\n");
- fprintf(stdout, "#define DNS_ENUMTYPE_H 1\n\n");
-
- fprintf(stdout, "enum {\n");
- fprintf(stdout, "\tdns_rdatatype_none = 0,\n");
-
- lasttype = 0;
- for (tt = types; tt != NULL; tt = tt->next)
- if (tt->type != lasttype)
- fprintf(stdout,
- "\tdns_rdatatype_%s = %d,\n",
- funname(tt->typename, buf1),
- lasttype = tt->type);
-
- fprintf(stdout, "\tdns_rdatatype_ixfr = 251,\n");
- fprintf(stdout, "\tdns_rdatatype_axfr = 252,\n");
- fprintf(stdout, "\tdns_rdatatype_mailb = 253,\n");
- fprintf(stdout, "\tdns_rdatatype_maila = 254,\n");
- fprintf(stdout, "\tdns_rdatatype_any = 255\n");
-
- fprintf(stdout, "};\n\n");
-
- fprintf(stdout, "#define dns_rdatatype_none\t"
- "((dns_rdatatype_t)dns_rdatatype_none)\n");
-
- for (tt = types; tt != NULL; tt = tt->next)
- if (tt->type != lasttype) {
- s = funname(tt->typename, buf1);
- fprintf(stdout,
- "#define dns_rdatatype_%s\t%s"
- "((dns_rdatatype_t)dns_rdatatype_%s)"
- "\n",
- s, strlen(s) < 2U ? "\t" : "", s);
- lasttype = tt->type;
- }
-
- fprintf(stdout, "#define dns_rdatatype_ixfr\t"
- "((dns_rdatatype_t)dns_rdatatype_ixfr)\n");
- fprintf(stdout, "#define dns_rdatatype_axfr\t"
- "((dns_rdatatype_t)dns_rdatatype_axfr)\n");
- fprintf(stdout, "#define dns_rdatatype_mailb\t"
- "((dns_rdatatype_t)dns_rdatatype_mailb)\n");
- fprintf(stdout, "#define dns_rdatatype_maila\t"
- "((dns_rdatatype_t)dns_rdatatype_maila)\n");
- fprintf(stdout, "#define dns_rdatatype_any\t"
- "((dns_rdatatype_t)dns_rdatatype_any)\n");
-
- fprintf(stdout, "\n#endif /* DNS_ENUMTYPE_H */\n");
-
- } else if (class_enum) {
- char *s;
- int classnum;
-
- fprintf(stdout, "#ifndef DNS_ENUMCLASS_H\n");
- fprintf(stdout, "#define DNS_ENUMCLASS_H 1\n\n");
-
- fprintf(stdout, "enum {\n");
-
- fprintf(stdout, "\tdns_rdataclass_reserved0 = 0,\n");
- fprintf(stdout, "#define dns_rdataclass_reserved0 \\\n\t\t\t\t"
- "((dns_rdataclass_t)dns_rdataclass_reserved0)\n");
-
-#define PRINTCLASS(name, num) \
- do { \
- s = funname(name, buf1); \
- classnum = num; \
- fprintf(stdout, "\tdns_rdataclass_%s = %d%s\n", s, classnum, \
- classnum != 255 ? "," : ""); \
- fprintf(stdout, "#define dns_rdataclass_%s\t" \
- "((dns_rdataclass_t)dns_rdataclass_%s)\n", s, s); \
- } while (0)
-
- for (cc = classes; cc != NULL; cc = cc->next) {
- if (cc->rdclass == 3)
- PRINTCLASS("chaos", 3);
- else if (cc->rdclass == 255)
- PRINTCLASS("none", 254);
- PRINTCLASS(cc->classname, cc->rdclass);
- }
-
-#undef PRINTCLASS
-
- fprintf(stdout, "};\n\n");
- fprintf(stdout, "#endif /* DNS_ENUMCLASS_H */\n");
- } else if (structs) {
- if (prefix != NULL) {
- if ((fd = fopen(prefix,"r")) != NULL) {
- while (fgets(buf, sizeof(buf), fd) != NULL)
- fputs(buf, stdout);
- fclose(fd);
- }
- }
- for (tt = types; tt != NULL; tt = tt->next) {
- snprintf(buf, sizeof(buf), "%s/%s_%d.h",
- tt->dirname, tt->typename, tt->type);
- if ((fd = fopen(buf,"r")) != NULL) {
- while (fgets(buf, sizeof(buf), fd) != NULL)
- fputs(buf, stdout);
- fclose(fd);
- }
- }
- if (suffix != NULL) {
- if ((fd = fopen(suffix,"r")) != NULL) {
- while (fgets(buf, sizeof(buf), fd) != NULL)
- fputs(buf, stdout);
- fclose(fd);
- }
- }
- } else if (depend) {
- for (tt = types; tt != NULL; tt = tt->next)
- fprintf(stdout, "%s:\t%s/%s_%d.h\n", file,
- tt->dirname, tt->typename, tt->type);
- }
-
- if (ferror(stdout) != 0)
- exit(1);
-
- return (0);
-}
diff --git a/contrib/bind9/lib/dns/gssapi_link.c b/contrib/bind9/lib/dns/gssapi_link.c
deleted file mode 100644
index 5ad81cd80ced..000000000000
--- a/contrib/bind9/lib/dns/gssapi_link.c
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- * Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2000-2002 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * $Id: gssapi_link.c,v 1.17 2011/03/28 05:32:16 marka Exp $
- */
-
-#include <config.h>
-
-#ifdef GSSAPI
-
-#include <isc/base64.h>
-#include <isc/buffer.h>
-#include <isc/mem.h>
-#include <isc/string.h>
-#include <isc/util.h>
-
-#include <dst/result.h>
-
-#include "dst_internal.h"
-#include "dst_parse.h"
-
-#include <dst/gssapi.h>
-
-#define INITIAL_BUFFER_SIZE 1024
-#define BUFFER_EXTRA 1024
-
-#define REGION_TO_GBUFFER(r, gb) \
- do { \
- (gb).length = (r).length; \
- (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;
-};
-
-/*%
- * Allocate a temporary "context" for use in gathering data for signing
- * or verifying.
- */
-static isc_result_t
-gssapi_create_signverify_ctx(dst_key_t *key, dst_context_t *dctx) {
- dst_gssapi_signverifyctx_t *ctx;
- isc_result_t result;
-
- UNUSED(key);
-
- ctx = isc_mem_get(dctx->mctx, sizeof(dst_gssapi_signverifyctx_t));
- if (ctx == NULL)
- return (ISC_R_NOMEMORY);
- ctx->buffer = NULL;
- result = isc_buffer_allocate(dctx->mctx, &ctx->buffer,
- INITIAL_BUFFER_SIZE);
- if (result != ISC_R_SUCCESS) {
- isc_mem_put(dctx->mctx, ctx, sizeof(dst_gssapi_signverifyctx_t));
- return (result);
- }
-
- dctx->ctxdata.gssctx = ctx;
-
- return (ISC_R_SUCCESS);
-}
-
-/*%
- * Destroy the temporary sign/verify context.
- */
-static void
-gssapi_destroy_signverify_ctx(dst_context_t *dctx) {
- dst_gssapi_signverifyctx_t *ctx = dctx->ctxdata.gssctx;
-
- if (ctx != NULL) {
- if (ctx->buffer != NULL)
- isc_buffer_free(&ctx->buffer);
- isc_mem_put(dctx->mctx, ctx, sizeof(dst_gssapi_signverifyctx_t));
- dctx->ctxdata.gssctx = NULL;
- }
-}
-
-/*%
- * Add data to our running buffer of data we will be signing or verifying.
- * This code will see if the new data will fit in our existing buffer, and
- * copy it in if it will. If not, it will attempt to allocate a larger
- * buffer and copy old+new into it, and free the old buffer.
- */
-static isc_result_t
-gssapi_adddata(dst_context_t *dctx, const isc_region_t *data) {
- dst_gssapi_signverifyctx_t *ctx = dctx->ctxdata.gssctx;
- isc_buffer_t *newbuffer = NULL;
- isc_region_t r;
- unsigned int length;
- isc_result_t result;
-
- result = isc_buffer_copyregion(ctx->buffer, data);
- if (result == ISC_R_SUCCESS)
- return (ISC_R_SUCCESS);
-
- length = isc_buffer_length(ctx->buffer) + data->length + BUFFER_EXTRA;
-
- result = isc_buffer_allocate(dctx->mctx, &newbuffer, length);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- isc_buffer_usedregion(ctx->buffer, &r);
- (void)isc_buffer_copyregion(newbuffer, &r);
- (void)isc_buffer_copyregion(newbuffer, data);
-
- isc_buffer_free(&ctx->buffer);
- ctx->buffer = newbuffer;
-
- return (ISC_R_SUCCESS);
-}
-
-/*%
- * Sign.
- */
-static isc_result_t
-gssapi_sign(dst_context_t *dctx, isc_buffer_t *sig) {
- dst_gssapi_signverifyctx_t *ctx = dctx->ctxdata.gssctx;
- isc_region_t message;
- gss_buffer_desc gmessage, gsig;
- OM_uint32 minor, gret;
- gss_ctx_id_t gssctx = dctx->key->keydata.gssctx;
- char buf[1024];
-
- /*
- * Convert the data we wish to sign into a structure gssapi can
- * understand.
- */
- isc_buffer_usedregion(ctx->buffer, &message);
- REGION_TO_GBUFFER(message, gmessage);
-
- /*
- * Generate the signature.
- */
- gret = gss_get_mic(&minor, gssctx, GSS_C_QOP_DEFAULT, &gmessage,
- &gsig);
-
- /*
- * If it did not complete, we log the result and return a generic
- * failure code.
- */
- if (gret != GSS_S_COMPLETE) {
- gss_log(3, "GSS sign error: %s",
- gss_error_tostring(gret, minor, buf, sizeof(buf)));
- return (ISC_R_FAILURE);
- }
-
- /*
- * If it will not fit in our allocated buffer, return that we need
- * more space.
- */
- if (gsig.length > isc_buffer_availablelength(sig)) {
- gss_release_buffer(&minor, &gsig);
- return (ISC_R_NOSPACE);
- }
-
- /*
- * Copy the output into our buffer space, and release the gssapi
- * allocated space.
- */
- isc_buffer_putmem(sig, gsig.value, gsig.length);
- if (gsig.length != 0U)
- gss_release_buffer(&minor, &gsig);
-
- return (ISC_R_SUCCESS);
-}
-
-/*%
- * Verify.
- */
-static isc_result_t
-gssapi_verify(dst_context_t *dctx, const isc_region_t *sig) {
- dst_gssapi_signverifyctx_t *ctx = dctx->ctxdata.gssctx;
- isc_region_t message, r;
- gss_buffer_desc gmessage, gsig;
- OM_uint32 minor, gret;
- gss_ctx_id_t gssctx = dctx->key->keydata.gssctx;
- unsigned char *buf;
- char err[1024];
-
- /*
- * Convert the data we wish to sign into a structure gssapi can
- * understand.
- */
- isc_buffer_usedregion(ctx->buffer, &message);
- REGION_TO_GBUFFER(message, gmessage);
-
- /*
- * XXXMLG
- * It seem that gss_verify_mic() modifies the signature buffer,
- * at least on Heimdal's implementation. Copy it here to an allocated
- * buffer.
- */
- buf = isc_mem_allocate(dst__memory_pool, sig->length);
- if (buf == NULL)
- return (ISC_R_FAILURE);
- memcpy(buf, sig->base, sig->length);
- r.base = buf;
- r.length = sig->length;
- REGION_TO_GBUFFER(r, gsig);
-
- /*
- * Verify the data.
- */
- gret = gss_verify_mic(&minor, gssctx, &gmessage, &gsig, NULL);
-
- isc_mem_free(dst__memory_pool, buf);
-
- /*
- * Convert return codes into something useful to us.
- */
- if (gret != GSS_S_COMPLETE) {
- gss_log(3, "GSS verify error: %s",
- gss_error_tostring(gret, minor, err, sizeof(err)));
- if (gret == GSS_S_DEFECTIVE_TOKEN ||
- gret == GSS_S_BAD_SIG ||
- gret == GSS_S_DUPLICATE_TOKEN ||
- gret == GSS_S_OLD_TOKEN ||
- gret == GSS_S_UNSEQ_TOKEN ||
- gret == GSS_S_GAP_TOKEN ||
- gret == GSS_S_CONTEXT_EXPIRED ||
- gret == GSS_S_NO_CONTEXT ||
- gret == GSS_S_FAILURE)
- return(DST_R_VERIFYFAILURE);
- else
- return (ISC_R_FAILURE);
- }
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_boolean_t
-gssapi_compare(const dst_key_t *key1, const dst_key_t *key2) {
- gss_ctx_id_t gsskey1 = key1->keydata.gssctx;
- gss_ctx_id_t gsskey2 = key2->keydata.gssctx;
-
- /* No idea */
- return (ISC_TF(gsskey1 == gsskey2));
-}
-
-static isc_result_t
-gssapi_generate(dst_key_t *key, int unused, void (*callback)(int)) {
- UNUSED(key);
- UNUSED(unused);
- UNUSED(callback);
-
- /* No idea */
- return (ISC_R_FAILURE);
-}
-
-static isc_boolean_t
-gssapi_isprivate(const dst_key_t *key) {
- UNUSED(key);
- return (ISC_TRUE);
-}
-
-static void
-gssapi_destroy(dst_key_t *key) {
- REQUIRE(key != NULL);
- dst_gssapi_deletectx(key->mctx, &key->keydata.gssctx);
- 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) != 0U)
- 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 == 0U)
- 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,
- gssapi_adddata,
- gssapi_sign,
- gssapi_verify,
- NULL, /*%< verify2 */
- NULL, /*%< computesecret */
- gssapi_compare,
- NULL, /*%< paramcompare */
- gssapi_generate,
- gssapi_isprivate,
- gssapi_destroy,
- NULL, /*%< todns */
- NULL, /*%< fromdns */
- NULL, /*%< tofile */
- NULL, /*%< parse */
- NULL, /*%< cleanup */
- NULL, /*%< fromlabel */
- gssapi_dump,
- gssapi_restore,
-};
-
-isc_result_t
-dst__gssapi_init(dst_func_t **funcp) {
- REQUIRE(funcp != NULL);
- if (*funcp == NULL)
- *funcp = &gssapi_functions;
- return (ISC_R_SUCCESS);
-}
-
-#else
-int gssapi_link_unneeded = 1;
-#endif
-
-/*! \file */
diff --git a/contrib/bind9/lib/dns/gssapictx.c b/contrib/bind9/lib/dns/gssapictx.c
deleted file mode 100644
index a8c5900e6d14..000000000000
--- a/contrib/bind9/lib/dns/gssapictx.c
+++ /dev/null
@@ -1,872 +0,0 @@
-/*
- * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2000, 2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: gssapictx.c,v 1.29 2011/08/29 06:33:25 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>
-#include <isc/print.h>
-#include <isc/platform.h>
-#include <isc/random.h>
-#include <isc/string.h>
-#include <isc/time.h>
-#include <isc/util.h>
-
-#include <dns/fixedname.h>
-#include <dns/name.h>
-#include <dns/rdata.h>
-#include <dns/rdataclass.h>
-#include <dns/result.h>
-#include <dns/types.h>
-#include <dns/keyvalues.h>
-#include <dns/log.h>
-
-#include <dst/gssapi.h>
-#include <dst/result.h>
-
-#include "dst_internal.h"
-
-/*
- * If we're using our own SPNEGO implementation (see configure.in),
- * pull it in now. Otherwise, we just use whatever GSSAPI supplies.
- */
-#if defined(GSSAPI) && defined(USE_ISC_SPNEGO)
-#include "spnego.h"
-#define gss_accept_sec_context gss_accept_sec_context_spnego
-#define gss_init_sec_context gss_init_sec_context_spnego
-#endif
-
-/*
- * Solaris8 apparently needs an explicit OID set, and Solaris10 needs
- * one for anything but Kerberos. Supplying an explicit OID set
- * doesn't appear to hurt anything in other implementations, so we
- * always use one. If we're not using our own SPNEGO implementation,
- * we include SPNEGO's OID.
- */
-#if defined(GSSAPI)
-#include ISC_PLATFORM_KRB5HEADER
-
-static unsigned char krb5_mech_oid_bytes[] = {
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02
-};
-
-#ifndef USE_ISC_SPNEGO
-static unsigned char spnego_mech_oid_bytes[] = {
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x02
-};
-#endif
-
-static gss_OID_desc mech_oid_set_array[] = {
- { sizeof(krb5_mech_oid_bytes), krb5_mech_oid_bytes },
-#ifndef USE_ISC_SPNEGO
- { sizeof(spnego_mech_oid_bytes), spnego_mech_oid_bytes },
-#endif
-};
-
-static gss_OID_set_desc mech_oid_set = {
- sizeof(mech_oid_set_array) / sizeof(*mech_oid_set_array),
- mech_oid_set_array
-};
-
-#endif
-
-#define REGION_TO_GBUFFER(r, gb) \
- do { \
- (gb).length = (r).length; \
- (gb).value = (r).base; \
- } while (0)
-
-#define GBUFFER_TO_REGION(gb, r) \
- do { \
- (r).length = (gb).length; \
- (r).base = (gb).value; \
- } while (0)
-
-
-#define RETERR(x) do { \
- result = (x); \
- if (result != ISC_R_SUCCESS) \
- goto out; \
- } while (0)
-
-#ifdef GSSAPI
-static inline void
-name_to_gbuffer(dns_name_t *name, isc_buffer_t *buffer,
- gss_buffer_desc *gbuffer)
-{
- dns_name_t tname, *namep;
- isc_region_t r;
- isc_result_t result;
-
- if (!dns_name_isabsolute(name))
- namep = name;
- else
- {
- unsigned int labels;
- dns_name_init(&tname, NULL);
- labels = dns_name_countlabels(name);
- dns_name_getlabelsequence(name, 0, labels - 1, &tname);
- namep = &tname;
- }
-
- result = dns_name_toprincipal(namep, buffer);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- isc_buffer_putuint8(buffer, 0);
- isc_buffer_usedregion(buffer, &r);
- REGION_TO_GBUFFER(r, *gbuffer);
-}
-
-static void
-log_cred(const gss_cred_id_t cred) {
- OM_uint32 gret, minor, lifetime;
- gss_name_t gname;
- gss_buffer_desc gbuffer;
- gss_cred_usage_t usage;
- const char *usage_text;
- char buf[1024];
-
- gret = gss_inquire_cred(&minor, cred, &gname, &lifetime, &usage, NULL);
- if (gret != GSS_S_COMPLETE) {
- gss_log(3, "failed gss_inquire_cred: %s",
- gss_error_tostring(gret, minor, buf, sizeof(buf)));
- return;
- }
-
- gret = gss_display_name(&minor, gname, &gbuffer, NULL);
- if (gret != GSS_S_COMPLETE)
- gss_log(3, "failed gss_display_name: %s",
- gss_error_tostring(gret, minor, buf, sizeof(buf)));
- else {
- switch (usage) {
- case GSS_C_BOTH:
- usage_text = "GSS_C_BOTH";
- break;
- case GSS_C_INITIATE:
- usage_text = "GSS_C_INITIATE";
- break;
- case GSS_C_ACCEPT:
- usage_text = "GSS_C_ACCEPT";
- break;
- default:
- usage_text = "???";
- }
- gss_log(3, "gss cred: \"%s\", %s, %lu", (char *)gbuffer.value,
- usage_text, (unsigned long)lifetime);
- }
-
- if (gret == GSS_S_COMPLETE) {
- if (gbuffer.length != 0U) {
- gret = gss_release_buffer(&minor, &gbuffer);
- if (gret != GSS_S_COMPLETE)
- gss_log(3, "failed gss_release_buffer: %s",
- gss_error_tostring(gret, minor, buf,
- sizeof(buf)));
- }
- }
-
- gret = gss_release_name(&minor, &gname);
- if (gret != GSS_S_COMPLETE)
- gss_log(3, "failed gss_release_name: %s",
- gss_error_tostring(gret, minor, buf, sizeof(buf)));
-}
-#endif
-
-#ifdef GSSAPI
-/*
- * check for the most common configuration errors.
- *
- * The errors checked for are:
- * - 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
-check_config(const char *gss_name) {
- const char *p;
- krb5_context krb5_ctx;
- char *krb5_realm = NULL;
-
- if (strncasecmp(gss_name, "DNS/", 4) != 0) {
- gss_log(ISC_LOG_ERROR, "tkey-gssapi-credential (%s) "
- "should start with 'DNS/'", gss_name);
- return;
- }
-
- if (krb5_init_context(&krb5_ctx) != 0) {
- gss_log(ISC_LOG_ERROR, "Unable to initialise krb5 context");
- return;
- }
- if (krb5_get_default_realm(krb5_ctx, &krb5_realm) != 0) {
- gss_log(ISC_LOG_ERROR, "Unable to get krb5 default realm");
- krb5_free_context(krb5_ctx);
- return;
- }
- p = strchr(gss_name, '/');
- if (p == NULL) {
- gss_log(ISC_LOG_ERROR, "badly formatted "
- "tkey-gssapi-credentials (%s)", gss_name);
- krb5_free_context(krb5_ctx);
- return;
- }
- if (strcasecmp(p + 1, krb5_realm) != 0) {
- gss_log(ISC_LOG_ERROR, "default realm from krb5.conf (%s) "
- "does not match tkey-gssapi-credential (%s)",
- krb5_realm, gss_name);
- krb5_free_context(krb5_ctx);
- return;
- }
- krb5_free_context(krb5_ctx);
-}
-#endif
-
-isc_result_t
-dst_gssapi_acquirecred(dns_name_t *name, isc_boolean_t initiate,
- gss_cred_id_t *cred)
-{
-#ifdef GSSAPI
- isc_buffer_t namebuf;
- gss_name_t gname;
- gss_buffer_desc gnamebuf;
- unsigned char array[DNS_NAME_MAXTEXT + 1];
- OM_uint32 gret, minor;
- gss_OID_set mechs;
- OM_uint32 lifetime;
- gss_cred_usage_t usage;
- char buf[1024];
-
- REQUIRE(cred != NULL && *cred == NULL);
-
- /*
- * XXXSRA In theory we could use GSS_C_NT_HOSTBASED_SERVICE
- * 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
- * dependency due to DNS-based realm lookup in at least one
- * GSSAPI implementation (Heimdal). Oh well.
- */
- if (name != NULL) {
- isc_buffer_init(&namebuf, array, sizeof(array));
- name_to_gbuffer(name, &namebuf, &gnamebuf);
- gret = gss_import_name(&minor, &gnamebuf,
- GSS_C_NO_OID, &gname);
- if (gret != GSS_S_COMPLETE) {
- check_config((char *)array);
-
- gss_log(3, "failed gss_import_name: %s",
- gss_error_tostring(gret, minor, buf,
- sizeof(buf)));
- return (ISC_R_FAILURE);
- }
- } else
- gname = NULL;
-
- /* Get the credentials. */
- if (gname != NULL)
- gss_log(3, "acquiring credentials for %s",
- (char *)gnamebuf.value);
- else {
- /* XXXDCL does this even make any sense? */
- gss_log(3, "acquiring credentials for ?");
- }
-
- if (initiate)
- usage = GSS_C_INITIATE;
- else
- usage = GSS_C_ACCEPT;
-
- gret = gss_acquire_cred(&minor, gname, GSS_C_INDEFINITE,
- &mech_oid_set,
- usage, cred, &mechs, &lifetime);
-
- if (gret != GSS_S_COMPLETE) {
- gss_log(3, "failed to acquire %s credentials for %s: %s",
- initiate ? "initiate" : "accept",
- (gname != NULL) ? (char *)gnamebuf.value : "?",
- gss_error_tostring(gret, minor, buf, sizeof(buf)));
- check_config((char *)array);
- return (ISC_R_FAILURE);
- }
-
- gss_log(4, "acquired %s credentials for %s",
- initiate ? "initiate" : "accept",
- (gname != NULL) ? (char *)gnamebuf.value : "?");
-
- log_cred(*cred);
-
- return (ISC_R_SUCCESS);
-#else
- REQUIRE(cred != NULL && *cred == NULL);
-
- UNUSED(name);
- UNUSED(initiate);
- UNUSED(cred);
-
- return (ISC_R_NOTIMPLEMENTED);
-#endif
-}
-
-isc_boolean_t
-dst_gssapi_identitymatchesrealmkrb5(dns_name_t *signer, dns_name_t *name,
- dns_name_t *realm)
-{
-#ifdef GSSAPI
- char sbuf[DNS_NAME_FORMATSIZE];
- char nbuf[DNS_NAME_FORMATSIZE];
- char rbuf[DNS_NAME_FORMATSIZE];
- char *sname;
- char *rname;
- isc_buffer_t buffer;
- isc_result_t result;
-
- /*
- * It is far, far easier to write the names we are looking at into
- * a string, and do string operations on them.
- */
- isc_buffer_init(&buffer, sbuf, sizeof(sbuf));
- result = dns_name_toprincipal(signer, &buffer);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- isc_buffer_putuint8(&buffer, 0);
- if (name != NULL)
- dns_name_format(name, nbuf, sizeof(nbuf));
- dns_name_format(realm, rbuf, sizeof(rbuf));
-
- /*
- * Find the realm portion. This is the part after the @. If it
- * does not exist, we don't have something we like, so we fail our
- * compare.
- */
- rname = strchr(sbuf, '@');
- if (rname == NULL)
- return (isc_boolean_false);
- *rname = '\0';
- rname++;
-
- /*
- * 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"
- *
- * This will work for
- * host/example.com@EXAMPLE.COM
- */
- sname = strchr(sbuf, '/');
- if (sname == NULL)
- return (isc_boolean_false);
- *sname = '\0';
- sname++;
- if (strcmp(sbuf, "host") != 0)
- return (isc_boolean_false);
-
- /*
- * Now, we do a simple comparison between the name and the realm.
- */
- if (name != NULL) {
- if ((strcasecmp(sname, nbuf) == 0)
- && (strcmp(rname, rbuf) == 0))
- return (isc_boolean_true);
- } else {
- if (strcmp(rname, rbuf) == 0)
- return (isc_boolean_true);
- }
-
- return (isc_boolean_false);
-#else
- UNUSED(signer);
- UNUSED(name);
- UNUSED(realm);
- return (isc_boolean_false);
-#endif
-}
-
-isc_boolean_t
-dst_gssapi_identitymatchesrealmms(dns_name_t *signer, dns_name_t *name,
- dns_name_t *realm)
-{
-#ifdef GSSAPI
- char sbuf[DNS_NAME_FORMATSIZE];
- char nbuf[DNS_NAME_FORMATSIZE];
- char rbuf[DNS_NAME_FORMATSIZE];
- char *sname;
- char *nname;
- char *rname;
- isc_buffer_t buffer;
- isc_result_t result;
-
- /*
- * It is far, far easier to write the names we are looking at into
- * a string, and do string operations on them.
- */
- isc_buffer_init(&buffer, sbuf, sizeof(sbuf));
- result = dns_name_toprincipal(signer, &buffer);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- isc_buffer_putuint8(&buffer, 0);
- if (name != NULL)
- dns_name_format(name, nbuf, sizeof(nbuf));
- dns_name_format(realm, rbuf, sizeof(rbuf));
-
- /*
- * Find the realm portion. This is the part after the @. If it
- * does not exist, we don't have something we like, so we fail our
- * compare.
- */
- rname = strchr(sbuf, '@');
- if (rname == NULL)
- return (isc_boolean_false);
- sname = strchr(sbuf, '$');
- if (sname == NULL)
- return (isc_boolean_false);
-
- /*
- * Verify that the $ and @ follow one another.
- */
- if (rname - sname != 1)
- return (isc_boolean_false);
-
- /*
- * 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.
- *
- * All service principals in Microsoft format seem to be in
- * machinename$@EXAMPLE.COM
- * format.
- */
- rname++;
- *sname = '\0';
- sname = sbuf;
-
- /*
- * 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.
- */
- if (name != NULL) {
- nname = strchr(nbuf, '.');
- if (nname == NULL)
- return (isc_boolean_false);
- *nname++ = '\0';
- }
-
- /*
- * Now, we do a simple comparison between the name and the realm.
- */
- if (name != NULL) {
- if ((strcasecmp(sname, nbuf) == 0)
- && (strcmp(rname, rbuf) == 0)
- && (strcasecmp(nname, rbuf) == 0))
- return (isc_boolean_true);
- } else {
- if (strcmp(rname, rbuf) == 0)
- return (isc_boolean_true);
- }
-
-
- return (isc_boolean_false);
-#else
- UNUSED(signer);
- UNUSED(name);
- UNUSED(realm);
- return (isc_boolean_false);
-#endif
-}
-
-isc_result_t
-dst_gssapi_releasecred(gss_cred_id_t *cred) {
-#ifdef GSSAPI
- OM_uint32 gret, minor;
- char buf[1024];
-
- REQUIRE(cred != NULL && *cred != NULL);
-
- gret = gss_release_cred(&minor, cred);
- if (gret != GSS_S_COMPLETE) {
- /* Log the error, but still free the credential's memory */
- gss_log(3, "failed releasing credential: %s",
- gss_error_tostring(gret, minor, buf, sizeof(buf)));
- }
- *cred = NULL;
-
- return(ISC_R_SUCCESS);
-#else
- UNUSED(cred);
-
- return (ISC_R_NOTIMPLEMENTED);
-#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 != NULL)
- (*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_mem_t *mctx, char **err_message)
-{
-#ifdef GSSAPI
- isc_region_t r;
- isc_buffer_t namebuf;
- gss_name_t gname;
- OM_uint32 gret, minor, ret_flags, flags;
- gss_buffer_desc gintoken, *gintokenp, gouttoken = GSS_C_EMPTY_BUFFER;
- isc_result_t result;
- gss_buffer_desc gnamebuf;
- unsigned char array[DNS_NAME_MAXTEXT + 1];
-
- /* 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);
-
- /* 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;
- }
-
- if (intoken != NULL) {
- /* Don't call gss_release_buffer for gintoken! */
- REGION_TO_GBUFFER(*intoken, gintoken);
- gintokenp = &gintoken;
- } else {
- gintokenp = NULL;
- }
-
- /*
- * 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_INTEG_FLAG;
-
- gret = gss_init_sec_context(&minor, GSS_C_NO_CREDENTIAL, gssctx,
- gname, GSS_SPNEGO_MECHANISM, flags,
- 0, NULL, gintokenp,
- NULL, &gouttoken, &ret_flags, NULL);
-
- if (gret != GSS_S_COMPLETE && gret != GSS_S_CONTINUE_NEEDED) {
- gss_err_message(mctx, gret, minor, err_message);
- if (err_message != NULL && *err_message != NULL)
- gss_log(3, "Failure initiating security context: %s",
- *err_message);
- else
- gss_log(3, "Failure initiating security context");
-
- result = ISC_R_FAILURE;
- goto out;
- }
-
- /*
- * XXXSRA Not handled yet: RFC 3645 3.1.1: check ret_flags
- * MUTUAL and INTEG flags, fail if either not set.
- */
-
- /*
- * RFC 2744 states the a valid output token has a non-zero length.
- */
- if (gouttoken.length != 0U) {
- GBUFFER_TO_REGION(gouttoken, r);
- RETERR(isc_buffer_copyregion(outtoken, &r));
- (void)gss_release_buffer(&minor, &gouttoken);
- }
- (void)gss_release_name(&minor, &gname);
-
- if (gret == GSS_S_COMPLETE)
- result = ISC_R_SUCCESS;
- else
- result = DNS_R_CONTINUE;
-
- out:
- return (result);
-#else
- UNUSED(name);
- UNUSED(intoken);
- UNUSED(outtoken);
- UNUSED(gssctx);
- UNUSED(mctx);
- UNUSED(err_message);
-
- return (ISC_R_NOTIMPLEMENTED);
-#endif
-}
-
-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)
-{
-#ifdef GSSAPI
- isc_region_t r;
- isc_buffer_t namebuf;
- gss_buffer_desc gnamebuf = GSS_C_EMPTY_BUFFER, gintoken,
- gouttoken = GSS_C_EMPTY_BUFFER;
- OM_uint32 gret, minor;
- gss_ctx_id_t context = GSS_C_NO_CONTEXT;
- gss_name_t gname = NULL;
- isc_result_t result;
- char buf[1024];
-
- REQUIRE(outtoken != NULL && *outtoken == NULL);
-
- REGION_TO_GBUFFER(*intoken, gintoken);
-
- if (*ctxout == NULL)
- context = GSS_C_NO_CONTEXT;
- 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, 0, 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
- }
-
- log_cred(cred);
-
- gret = gss_accept_sec_context(&minor, &context, cred, &gintoken,
- GSS_C_NO_CHANNEL_BINDINGS, &gname,
- NULL, &gouttoken, NULL, NULL, NULL);
-
- result = ISC_R_FAILURE;
-
- switch (gret) {
- case GSS_S_COMPLETE:
- result = ISC_R_SUCCESS;
- break;
- case GSS_S_CONTINUE_NEEDED:
- result = DNS_R_CONTINUE;
- break;
- case GSS_S_DEFECTIVE_TOKEN:
- case GSS_S_DEFECTIVE_CREDENTIAL:
- case GSS_S_BAD_SIG:
- case GSS_S_DUPLICATE_TOKEN:
- case GSS_S_OLD_TOKEN:
- case GSS_S_NO_CRED:
- case GSS_S_CREDENTIALS_EXPIRED:
- case GSS_S_BAD_BINDINGS:
- case GSS_S_NO_CONTEXT:
- case GSS_S_BAD_MECH:
- case GSS_S_FAILURE:
- result = DNS_R_INVALIDTKEY;
- /* fall through */
- default:
- gss_log(3, "failed gss_accept_sec_context: %s",
- gss_error_tostring(gret, minor, buf, sizeof(buf)));
- return (result);
- }
-
- if (gouttoken.length > 0U) {
- RETERR(isc_buffer_allocate(mctx, outtoken, gouttoken.length));
- GBUFFER_TO_REGION(gouttoken, r);
- RETERR(isc_buffer_copyregion(*outtoken, &r));
- (void)gss_release_buffer(&minor, &gouttoken);
- }
-
- if (gret == GSS_S_COMPLETE) {
- gret = gss_display_name(&minor, gname, &gnamebuf, NULL);
- if (gret != GSS_S_COMPLETE) {
- gss_log(3, "failed gss_display_name: %s",
- gss_error_tostring(gret, minor,
- buf, sizeof(buf)));
- RETERR(ISC_R_FAILURE);
- }
-
- /*
- * Compensate for a bug in Solaris8's implementation
- * of gss_display_name(). Should be harmless in any
- * case, since principal names really should not
- * contain null characters.
- */
- if (gnamebuf.length > 0U &&
- ((char *)gnamebuf.value)[gnamebuf.length - 1] == '\0')
- gnamebuf.length--;
-
- gss_log(3, "gss-api source name (accept) is %.*s",
- (int)gnamebuf.length, (char *)gnamebuf.value);
-
- GBUFFER_TO_REGION(gnamebuf, r);
- isc_buffer_init(&namebuf, r.base, r.length);
- isc_buffer_add(&namebuf, r.length);
-
- RETERR(dns_name_fromtext(principal, &namebuf, dns_rootname,
- 0, NULL));
-
- if (gnamebuf.length != 0U) {
- gret = gss_release_buffer(&minor, &gnamebuf);
- if (gret != GSS_S_COMPLETE)
- gss_log(3, "failed gss_release_buffer: %s",
- gss_error_tostring(gret, minor, buf,
- sizeof(buf)));
- }
- }
-
- *ctxout = context;
-
- out:
- if (gname != NULL) {
- gret = gss_release_name(&minor, &gname);
- if (gret != GSS_S_COMPLETE)
- gss_log(3, "failed gss_release_name: %s",
- gss_error_tostring(gret, minor, buf,
- sizeof(buf)));
- }
-
- return (result);
-#else
- UNUSED(cred);
- UNUSED(gssapi_keytab);
- UNUSED(intoken);
- UNUSED(outtoken);
- UNUSED(ctxout);
- UNUSED(principal);
- UNUSED(mctx);
-
- return (ISC_R_NOTIMPLEMENTED);
-#endif
-}
-
-isc_result_t
-dst_gssapi_deletectx(isc_mem_t *mctx, gss_ctx_id_t *gssctx)
-{
-#ifdef GSSAPI
- OM_uint32 gret, minor;
- char buf[1024];
-
- UNUSED(mctx);
-
- REQUIRE(gssctx != NULL && *gssctx != NULL);
-
- /* Delete the context from the GSS provider */
- gret = gss_delete_sec_context(&minor, gssctx, GSS_C_NO_BUFFER);
- if (gret != GSS_S_COMPLETE) {
- /* Log the error, but still free the context's memory */
- gss_log(3, "Failure deleting security context %s",
- gss_error_tostring(gret, minor, buf, sizeof(buf)));
- }
- return(ISC_R_SUCCESS);
-#else
- UNUSED(mctx);
- UNUSED(gssctx);
- return (ISC_R_NOTIMPLEMENTED);
-#endif
-}
-
-char *
-gss_error_tostring(isc_uint32_t major, isc_uint32_t minor,
- char *buf, size_t buflen) {
-#ifdef GSSAPI
- gss_buffer_desc msg_minor = GSS_C_EMPTY_BUFFER,
- msg_major = GSS_C_EMPTY_BUFFER;
- OM_uint32 msg_ctx, minor_stat;
-
- /* Handle major status */
- msg_ctx = 0;
- (void)gss_display_status(&minor_stat, major, GSS_C_GSS_CODE,
- GSS_C_NULL_OID, &msg_ctx, &msg_major);
-
- /* Handle minor status */
- msg_ctx = 0;
- (void)gss_display_status(&minor_stat, minor, GSS_C_MECH_CODE,
- GSS_C_NULL_OID, &msg_ctx, &msg_minor);
-
- snprintf(buf, buflen, "GSSAPI error: Major = %s, Minor = %s.",
- (char *)msg_major.value, (char *)msg_minor.value);
-
- if (msg_major.length != 0U)
- (void)gss_release_buffer(&minor_stat, &msg_major);
- if (msg_minor.length != 0U)
- (void)gss_release_buffer(&minor_stat, &msg_minor);
- return(buf);
-#else
- snprintf(buf, buflen, "GSSAPI error: Major = %u, Minor = %u.",
- major, minor);
-
- return (buf);
-#endif
-}
-
-void
-gss_log(int level, const char *fmt, ...) {
- va_list ap;
-
- va_start(ap, fmt);
- isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL,
- DNS_LOGMODULE_TKEY, ISC_LOG_DEBUG(level), fmt, ap);
- va_end(ap);
-}
-
-/*! \file */
diff --git a/contrib/bind9/lib/dns/hmac_link.c b/contrib/bind9/lib/dns/hmac_link.c
deleted file mode 100644
index 256abb6eb475..000000000000
--- a/contrib/bind9/lib/dns/hmac_link.c
+++ /dev/null
@@ -1,1734 +0,0 @@
-/*
- * Portions Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
- * Portions Copyright (C) 1999-2002 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
- * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
- * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
- * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Portions Copyright (C) 1995-2000 by Network Associates, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
- * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
- * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
- * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * Principal Author: Brian Wellington
- * $Id: hmac_link.c,v 1.19 2011/01/11 23:47:13 tbox Exp $
- */
-
-#include <config.h>
-
-#include <isc/buffer.h>
-#include <isc/hmacmd5.h>
-#include <isc/hmacsha.h>
-#include <isc/md5.h>
-#include <isc/sha1.h>
-#include <isc/mem.h>
-#include <isc/string.h>
-#include <isc/util.h>
-
-#include <dst/result.h>
-
-#include "dst_internal.h"
-#include "dst_parse.h"
-
-static isc_result_t hmacmd5_fromdns(dst_key_t *key, isc_buffer_t *data);
-
-struct dst_hmacmd5_key {
- unsigned char key[ISC_MD5_BLOCK_LENGTH];
-};
-
-static isc_result_t
-getkeybits(dst_key_t *key, struct dst_private_element *element) {
-
- if (element->length != 2)
- return (DST_R_INVALIDPRIVATEKEY);
-
- key->key_bits = (element->data[0] << 8) + element->data[1];
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacmd5_createctx(dst_key_t *key, dst_context_t *dctx) {
- isc_hmacmd5_t *hmacmd5ctx;
- dst_hmacmd5_key_t *hkey = key->keydata.hmacmd5;
-
- hmacmd5ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacmd5_t));
- if (hmacmd5ctx == NULL)
- return (ISC_R_NOMEMORY);
- isc_hmacmd5_init(hmacmd5ctx, hkey->key, ISC_SHA1_BLOCK_LENGTH);
- dctx->ctxdata.hmacmd5ctx = hmacmd5ctx;
- return (ISC_R_SUCCESS);
-}
-
-static void
-hmacmd5_destroyctx(dst_context_t *dctx) {
- isc_hmacmd5_t *hmacmd5ctx = dctx->ctxdata.hmacmd5ctx;
-
- if (hmacmd5ctx != NULL) {
- isc_hmacmd5_invalidate(hmacmd5ctx);
- isc_mem_put(dctx->mctx, hmacmd5ctx, sizeof(isc_hmacmd5_t));
- dctx->ctxdata.hmacmd5ctx = NULL;
- }
-}
-
-static isc_result_t
-hmacmd5_adddata(dst_context_t *dctx, const isc_region_t *data) {
- isc_hmacmd5_t *hmacmd5ctx = dctx->ctxdata.hmacmd5ctx;
-
- isc_hmacmd5_update(hmacmd5ctx, data->base, data->length);
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacmd5_sign(dst_context_t *dctx, isc_buffer_t *sig) {
- isc_hmacmd5_t *hmacmd5ctx = dctx->ctxdata.hmacmd5ctx;
- unsigned char *digest;
-
- if (isc_buffer_availablelength(sig) < ISC_MD5_DIGESTLENGTH)
- return (ISC_R_NOSPACE);
- digest = isc_buffer_used(sig);
- isc_hmacmd5_sign(hmacmd5ctx, digest);
- isc_buffer_add(sig, ISC_MD5_DIGESTLENGTH);
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacmd5_verify(dst_context_t *dctx, const isc_region_t *sig) {
- isc_hmacmd5_t *hmacmd5ctx = dctx->ctxdata.hmacmd5ctx;
-
- if (sig->length > ISC_MD5_DIGESTLENGTH)
- return (DST_R_VERIFYFAILURE);
-
- if (isc_hmacmd5_verify2(hmacmd5ctx, sig->base, sig->length))
- return (ISC_R_SUCCESS);
- else
- return (DST_R_VERIFYFAILURE);
-}
-
-static isc_boolean_t
-hmacmd5_compare(const dst_key_t *key1, const dst_key_t *key2) {
- dst_hmacmd5_key_t *hkey1, *hkey2;
-
- hkey1 = key1->keydata.hmacmd5;
- hkey2 = key2->keydata.hmacmd5;
-
- if (hkey1 == NULL && hkey2 == NULL)
- return (ISC_TRUE);
- else if (hkey1 == NULL || hkey2 == NULL)
- return (ISC_FALSE);
-
- 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, void (*callback)(int)) {
- isc_buffer_t b;
- isc_result_t ret;
- unsigned int bytes;
- unsigned char data[ISC_SHA1_BLOCK_LENGTH];
-
- UNUSED(callback);
-
- bytes = (key->key_size + 7) / 8;
- if (bytes > ISC_SHA1_BLOCK_LENGTH) {
- bytes = ISC_SHA1_BLOCK_LENGTH;
- key->key_size = ISC_SHA1_BLOCK_LENGTH * 8;
- }
-
- memset(data, 0, ISC_SHA1_BLOCK_LENGTH);
- ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
-
- if (ret != ISC_R_SUCCESS)
- return (ret);
-
- isc_buffer_init(&b, data, bytes);
- isc_buffer_add(&b, bytes);
- ret = hmacmd5_fromdns(key, &b);
- memset(data, 0, ISC_SHA1_BLOCK_LENGTH);
-
- return (ret);
-}
-
-static isc_boolean_t
-hmacmd5_isprivate(const dst_key_t *key) {
- UNUSED(key);
- return (ISC_TRUE);
-}
-
-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;
-}
-
-static isc_result_t
-hmacmd5_todns(const dst_key_t *key, isc_buffer_t *data) {
- dst_hmacmd5_key_t *hkey;
- unsigned int bytes;
-
- REQUIRE(key->keydata.hmacmd5 != NULL);
-
- hkey = key->keydata.hmacmd5;
-
- bytes = (key->key_size + 7) / 8;
- if (isc_buffer_availablelength(data) < bytes)
- return (ISC_R_NOSPACE);
- isc_buffer_putmem(data, hkey->key, bytes);
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacmd5_fromdns(dst_key_t *key, isc_buffer_t *data) {
- dst_hmacmd5_key_t *hkey;
- int keylen;
- isc_region_t r;
- isc_md5_t md5ctx;
-
- isc_buffer_remainingregion(data, &r);
- if (r.length == 0)
- return (ISC_R_SUCCESS);
-
- hkey = isc_mem_get(key->mctx, sizeof(dst_hmacmd5_key_t));
- if (hkey == NULL)
- return (ISC_R_NOMEMORY);
-
- memset(hkey->key, 0, sizeof(hkey->key));
-
- 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);
- keylen = ISC_MD5_DIGESTLENGTH;
- }
- else {
- memcpy(hkey->key, r.base, r.length);
- keylen = r.length;
- }
-
- key->key_size = keylen * 8;
- key->keydata.hmacmd5 = hkey;
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacmd5_tofile(const dst_key_t *key, const char *directory) {
- int cnt = 0;
- dst_hmacmd5_key_t *hkey;
- dst_private_t priv;
- int bytes = (key->key_size + 7) / 8;
- unsigned char buf[2];
-
- if (key->keydata.hmacmd5 == NULL)
- return (DST_R_NULLKEY);
-
- hkey = key->keydata.hmacmd5;
-
- priv.elements[cnt].tag = TAG_HMACMD5_KEY;
- priv.elements[cnt].length = bytes;
- priv.elements[cnt++].data = hkey->key;
-
- buf[0] = (key->key_bits >> 8) & 0xffU;
- buf[1] = key->key_bits & 0xffU;
- priv.elements[cnt].tag = TAG_HMACMD5_BITS;
- priv.elements[cnt].data = buf;
- priv.elements[cnt++].length = 2;
-
- priv.nelements = cnt;
- return (dst__privstruct_writefile(key, &priv, directory));
-}
-
-static isc_result_t
-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);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- key->key_bits = 0;
- for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) {
- switch (priv.elements[i].tag) {
- case TAG_HMACMD5_KEY:
- isc_buffer_init(&b, priv.elements[i].data,
- priv.elements[i].length);
- isc_buffer_add(&b, priv.elements[i].length);
- tresult = hmacmd5_fromdns(key, &b);
- if (tresult != ISC_R_SUCCESS)
- result = tresult;
- break;
- case TAG_HMACMD5_BITS:
- tresult = getkeybits(key, &priv.elements[i]);
- if (tresult != ISC_R_SUCCESS)
- result = tresult;
- break;
- default:
- result = DST_R_INVALIDPRIVATEKEY;
- break;
- }
- }
- dst__privstruct_free(&priv, mctx);
- memset(&priv, 0, sizeof(priv));
- return (result);
-}
-
-static dst_func_t hmacmd5_functions = {
- hmacmd5_createctx,
- hmacmd5_destroyctx,
- hmacmd5_adddata,
- hmacmd5_sign,
- hmacmd5_verify,
- NULL, /*%< verify2 */
- NULL, /*%< computesecret */
- hmacmd5_compare,
- NULL, /*%< paramcompare */
- hmacmd5_generate,
- hmacmd5_isprivate,
- hmacmd5_destroy,
- hmacmd5_todns,
- hmacmd5_fromdns,
- hmacmd5_tofile,
- hmacmd5_parse,
- NULL, /*%< cleanup */
- NULL, /*%< fromlabel */
- NULL, /*%< dump */
- NULL, /*%< restore */
-};
-
-isc_result_t
-dst__hmacmd5_init(dst_func_t **funcp) {
- REQUIRE(funcp != NULL);
- if (*funcp == NULL)
- *funcp = &hmacmd5_functions;
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t hmacsha1_fromdns(dst_key_t *key, isc_buffer_t *data);
-
-struct dst_hmacsha1_key {
- unsigned char key[ISC_SHA1_BLOCK_LENGTH];
-};
-
-static isc_result_t
-hmacsha1_createctx(dst_key_t *key, dst_context_t *dctx) {
- isc_hmacsha1_t *hmacsha1ctx;
- dst_hmacsha1_key_t *hkey = key->keydata.hmacsha1;
-
- 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_BLOCK_LENGTH);
- dctx->ctxdata.hmacsha1ctx = hmacsha1ctx;
- return (ISC_R_SUCCESS);
-}
-
-static void
-hmacsha1_destroyctx(dst_context_t *dctx) {
- isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx;
-
- if (hmacsha1ctx != NULL) {
- isc_hmacsha1_invalidate(hmacsha1ctx);
- isc_mem_put(dctx->mctx, hmacsha1ctx, sizeof(isc_hmacsha1_t));
- dctx->ctxdata.hmacsha1ctx = NULL;
- }
-}
-
-static isc_result_t
-hmacsha1_adddata(dst_context_t *dctx, const isc_region_t *data) {
- isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx;
-
- isc_hmacsha1_update(hmacsha1ctx, data->base, data->length);
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha1_sign(dst_context_t *dctx, isc_buffer_t *sig) {
- isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx;
- unsigned char *digest;
-
- if (isc_buffer_availablelength(sig) < ISC_SHA1_DIGESTLENGTH)
- return (ISC_R_NOSPACE);
- digest = isc_buffer_used(sig);
- isc_hmacsha1_sign(hmacsha1ctx, digest, ISC_SHA1_DIGESTLENGTH);
- isc_buffer_add(sig, ISC_SHA1_DIGESTLENGTH);
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha1_verify(dst_context_t *dctx, const isc_region_t *sig) {
- isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx;
-
- if (sig->length > ISC_SHA1_DIGESTLENGTH || sig->length == 0)
- return (DST_R_VERIFYFAILURE);
-
- if (isc_hmacsha1_verify(hmacsha1ctx, sig->base, sig->length))
- return (ISC_R_SUCCESS);
- else
- return (DST_R_VERIFYFAILURE);
-}
-
-static isc_boolean_t
-hmacsha1_compare(const dst_key_t *key1, const dst_key_t *key2) {
- dst_hmacsha1_key_t *hkey1, *hkey2;
-
- hkey1 = key1->keydata.hmacsha1;
- hkey2 = key2->keydata.hmacsha1;
-
- if (hkey1 == NULL && hkey2 == NULL)
- return (ISC_TRUE);
- else if (hkey1 == NULL || hkey2 == NULL)
- return (ISC_FALSE);
-
- 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, void (*callback)(int)) {
- isc_buffer_t b;
- isc_result_t ret;
- unsigned int bytes;
- unsigned char data[ISC_SHA1_BLOCK_LENGTH];
-
- UNUSED(callback);
-
- bytes = (key->key_size + 7) / 8;
- if (bytes > ISC_SHA1_BLOCK_LENGTH) {
- bytes = ISC_SHA1_BLOCK_LENGTH;
- key->key_size = ISC_SHA1_BLOCK_LENGTH * 8;
- }
-
- memset(data, 0, ISC_SHA1_BLOCK_LENGTH);
- ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
-
- if (ret != ISC_R_SUCCESS)
- return (ret);
-
- isc_buffer_init(&b, data, bytes);
- isc_buffer_add(&b, bytes);
- ret = hmacsha1_fromdns(key, &b);
- memset(data, 0, ISC_SHA1_BLOCK_LENGTH);
-
- return (ret);
-}
-
-static isc_boolean_t
-hmacsha1_isprivate(const dst_key_t *key) {
- UNUSED(key);
- return (ISC_TRUE);
-}
-
-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;
-}
-
-static isc_result_t
-hmacsha1_todns(const dst_key_t *key, isc_buffer_t *data) {
- dst_hmacsha1_key_t *hkey;
- unsigned int bytes;
-
- REQUIRE(key->keydata.hmacsha1 != NULL);
-
- hkey = key->keydata.hmacsha1;
-
- bytes = (key->key_size + 7) / 8;
- if (isc_buffer_availablelength(data) < bytes)
- return (ISC_R_NOSPACE);
- isc_buffer_putmem(data, hkey->key, bytes);
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha1_fromdns(dst_key_t *key, isc_buffer_t *data) {
- dst_hmacsha1_key_t *hkey;
- int keylen;
- isc_region_t r;
- isc_sha1_t sha1ctx;
-
- isc_buffer_remainingregion(data, &r);
- if (r.length == 0)
- return (ISC_R_SUCCESS);
-
- hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha1_key_t));
- if (hkey == NULL)
- return (ISC_R_NOMEMORY);
-
- memset(hkey->key, 0, sizeof(hkey->key));
-
- 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);
- keylen = ISC_SHA1_DIGESTLENGTH;
- }
- else {
- memcpy(hkey->key, r.base, r.length);
- keylen = r.length;
- }
-
- key->key_size = keylen * 8;
- key->keydata.hmacsha1 = hkey;
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha1_tofile(const dst_key_t *key, const char *directory) {
- int cnt = 0;
- dst_hmacsha1_key_t *hkey;
- dst_private_t priv;
- int bytes = (key->key_size + 7) / 8;
- unsigned char buf[2];
-
- if (key->keydata.hmacsha1 == NULL)
- return (DST_R_NULLKEY);
-
- hkey = key->keydata.hmacsha1;
-
- priv.elements[cnt].tag = TAG_HMACSHA1_KEY;
- priv.elements[cnt].length = bytes;
- priv.elements[cnt++].data = hkey->key;
-
- buf[0] = (key->key_bits >> 8) & 0xffU;
- buf[1] = key->key_bits & 0xffU;
- priv.elements[cnt].tag = TAG_HMACSHA1_BITS;
- priv.elements[cnt].data = buf;
- priv.elements[cnt++].length = 2;
-
- priv.nelements = cnt;
- return (dst__privstruct_writefile(key, &priv, directory));
-}
-
-static isc_result_t
-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);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- key->key_bits = 0;
- for (i = 0; i < priv.nelements; i++) {
- switch (priv.elements[i].tag) {
- case TAG_HMACSHA1_KEY:
- isc_buffer_init(&b, priv.elements[i].data,
- priv.elements[i].length);
- isc_buffer_add(&b, priv.elements[i].length);
- tresult = hmacsha1_fromdns(key, &b);
- if (tresult != ISC_R_SUCCESS)
- result = tresult;
- break;
- case TAG_HMACSHA1_BITS:
- tresult = getkeybits(key, &priv.elements[i]);
- if (tresult != ISC_R_SUCCESS)
- result = tresult;
- break;
- default:
- result = DST_R_INVALIDPRIVATEKEY;
- break;
- }
- }
- dst__privstruct_free(&priv, mctx);
- memset(&priv, 0, sizeof(priv));
- return (result);
-}
-
-static dst_func_t hmacsha1_functions = {
- hmacsha1_createctx,
- hmacsha1_destroyctx,
- hmacsha1_adddata,
- hmacsha1_sign,
- hmacsha1_verify,
- NULL, /* verify2 */
- NULL, /* computesecret */
- hmacsha1_compare,
- NULL, /* paramcompare */
- hmacsha1_generate,
- hmacsha1_isprivate,
- hmacsha1_destroy,
- hmacsha1_todns,
- hmacsha1_fromdns,
- hmacsha1_tofile,
- hmacsha1_parse,
- NULL, /* cleanup */
- NULL, /* fromlabel */
- NULL, /* dump */
- NULL, /* restore */
-};
-
-isc_result_t
-dst__hmacsha1_init(dst_func_t **funcp) {
- REQUIRE(funcp != NULL);
- if (*funcp == NULL)
- *funcp = &hmacsha1_functions;
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t hmacsha224_fromdns(dst_key_t *key, isc_buffer_t *data);
-
-struct dst_hmacsha224_key {
- unsigned char key[ISC_SHA224_BLOCK_LENGTH];
-};
-
-static isc_result_t
-hmacsha224_createctx(dst_key_t *key, dst_context_t *dctx) {
- isc_hmacsha224_t *hmacsha224ctx;
- dst_hmacsha224_key_t *hkey = key->keydata.hmacsha224;
-
- 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_BLOCK_LENGTH);
- dctx->ctxdata.hmacsha224ctx = hmacsha224ctx;
- return (ISC_R_SUCCESS);
-}
-
-static void
-hmacsha224_destroyctx(dst_context_t *dctx) {
- isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx;
-
- if (hmacsha224ctx != NULL) {
- isc_hmacsha224_invalidate(hmacsha224ctx);
- isc_mem_put(dctx->mctx, hmacsha224ctx, sizeof(isc_hmacsha224_t));
- dctx->ctxdata.hmacsha224ctx = NULL;
- }
-}
-
-static isc_result_t
-hmacsha224_adddata(dst_context_t *dctx, const isc_region_t *data) {
- isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx;
-
- isc_hmacsha224_update(hmacsha224ctx, data->base, data->length);
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha224_sign(dst_context_t *dctx, isc_buffer_t *sig) {
- isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx;
- unsigned char *digest;
-
- if (isc_buffer_availablelength(sig) < ISC_SHA224_DIGESTLENGTH)
- return (ISC_R_NOSPACE);
- digest = isc_buffer_used(sig);
- isc_hmacsha224_sign(hmacsha224ctx, digest, ISC_SHA224_DIGESTLENGTH);
- isc_buffer_add(sig, ISC_SHA224_DIGESTLENGTH);
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha224_verify(dst_context_t *dctx, const isc_region_t *sig) {
- isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx;
-
- if (sig->length > ISC_SHA224_DIGESTLENGTH || sig->length == 0)
- return (DST_R_VERIFYFAILURE);
-
- if (isc_hmacsha224_verify(hmacsha224ctx, sig->base, sig->length))
- return (ISC_R_SUCCESS);
- else
- return (DST_R_VERIFYFAILURE);
-}
-
-static isc_boolean_t
-hmacsha224_compare(const dst_key_t *key1, const dst_key_t *key2) {
- dst_hmacsha224_key_t *hkey1, *hkey2;
-
- hkey1 = key1->keydata.hmacsha224;
- hkey2 = key2->keydata.hmacsha224;
-
- if (hkey1 == NULL && hkey2 == NULL)
- return (ISC_TRUE);
- else if (hkey1 == NULL || hkey2 == NULL)
- return (ISC_FALSE);
-
- 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,
- void (*callback)(int))
-{
- isc_buffer_t b;
- isc_result_t ret;
- unsigned int bytes;
- unsigned char data[ISC_SHA224_BLOCK_LENGTH];
-
- UNUSED(callback);
-
- bytes = (key->key_size + 7) / 8;
- if (bytes > ISC_SHA224_BLOCK_LENGTH) {
- bytes = ISC_SHA224_BLOCK_LENGTH;
- key->key_size = ISC_SHA224_BLOCK_LENGTH * 8;
- }
-
- memset(data, 0, ISC_SHA224_BLOCK_LENGTH);
- ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
-
- if (ret != ISC_R_SUCCESS)
- return (ret);
-
- isc_buffer_init(&b, data, bytes);
- isc_buffer_add(&b, bytes);
- ret = hmacsha224_fromdns(key, &b);
- memset(data, 0, ISC_SHA224_BLOCK_LENGTH);
-
- return (ret);
-}
-
-static isc_boolean_t
-hmacsha224_isprivate(const dst_key_t *key) {
- UNUSED(key);
- return (ISC_TRUE);
-}
-
-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;
-}
-
-static isc_result_t
-hmacsha224_todns(const dst_key_t *key, isc_buffer_t *data) {
- dst_hmacsha224_key_t *hkey;
- unsigned int bytes;
-
- REQUIRE(key->keydata.hmacsha224 != NULL);
-
- hkey = key->keydata.hmacsha224;
-
- bytes = (key->key_size + 7) / 8;
- if (isc_buffer_availablelength(data) < bytes)
- return (ISC_R_NOSPACE);
- isc_buffer_putmem(data, hkey->key, bytes);
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha224_fromdns(dst_key_t *key, isc_buffer_t *data) {
- dst_hmacsha224_key_t *hkey;
- int keylen;
- isc_region_t r;
- isc_sha224_t sha224ctx;
-
- isc_buffer_remainingregion(data, &r);
- if (r.length == 0)
- return (ISC_R_SUCCESS);
-
- hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha224_key_t));
- if (hkey == NULL)
- return (ISC_R_NOMEMORY);
-
- memset(hkey->key, 0, sizeof(hkey->key));
-
- 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);
- keylen = ISC_SHA224_DIGESTLENGTH;
- }
- else {
- memcpy(hkey->key, r.base, r.length);
- keylen = r.length;
- }
-
- key->key_size = keylen * 8;
- key->keydata.hmacsha224 = hkey;
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha224_tofile(const dst_key_t *key, const char *directory) {
- int cnt = 0;
- dst_hmacsha224_key_t *hkey;
- dst_private_t priv;
- int bytes = (key->key_size + 7) / 8;
- unsigned char buf[2];
-
- if (key->keydata.hmacsha224 == NULL)
- return (DST_R_NULLKEY);
-
- hkey = key->keydata.hmacsha224;
-
- priv.elements[cnt].tag = TAG_HMACSHA224_KEY;
- priv.elements[cnt].length = bytes;
- priv.elements[cnt++].data = hkey->key;
-
- buf[0] = (key->key_bits >> 8) & 0xffU;
- buf[1] = key->key_bits & 0xffU;
- priv.elements[cnt].tag = TAG_HMACSHA224_BITS;
- priv.elements[cnt].data = buf;
- priv.elements[cnt++].length = 2;
-
- priv.nelements = cnt;
- return (dst__privstruct_writefile(key, &priv, directory));
-}
-
-static isc_result_t
-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);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- key->key_bits = 0;
- for (i = 0; i < priv.nelements; i++) {
- switch (priv.elements[i].tag) {
- case TAG_HMACSHA224_KEY:
- isc_buffer_init(&b, priv.elements[i].data,
- priv.elements[i].length);
- isc_buffer_add(&b, priv.elements[i].length);
- tresult = hmacsha224_fromdns(key, &b);
- if (tresult != ISC_R_SUCCESS)
- result = tresult;
- break;
- case TAG_HMACSHA224_BITS:
- tresult = getkeybits(key, &priv.elements[i]);
- if (tresult != ISC_R_SUCCESS)
- result = tresult;
- break;
- default:
- result = DST_R_INVALIDPRIVATEKEY;
- break;
- }
- }
- dst__privstruct_free(&priv, mctx);
- memset(&priv, 0, sizeof(priv));
- return (result);
-}
-
-static dst_func_t hmacsha224_functions = {
- hmacsha224_createctx,
- hmacsha224_destroyctx,
- hmacsha224_adddata,
- hmacsha224_sign,
- hmacsha224_verify,
- NULL, /* verify2 */
- NULL, /* computesecret */
- hmacsha224_compare,
- NULL, /* paramcompare */
- hmacsha224_generate,
- hmacsha224_isprivate,
- hmacsha224_destroy,
- hmacsha224_todns,
- hmacsha224_fromdns,
- hmacsha224_tofile,
- hmacsha224_parse,
- NULL, /* cleanup */
- NULL, /* fromlabel */
- NULL, /* dump */
- NULL, /* restore */
-};
-
-isc_result_t
-dst__hmacsha224_init(dst_func_t **funcp) {
- REQUIRE(funcp != NULL);
- if (*funcp == NULL)
- *funcp = &hmacsha224_functions;
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t hmacsha256_fromdns(dst_key_t *key, isc_buffer_t *data);
-
-struct dst_hmacsha256_key {
- unsigned char key[ISC_SHA256_BLOCK_LENGTH];
-};
-
-static isc_result_t
-hmacsha256_createctx(dst_key_t *key, dst_context_t *dctx) {
- isc_hmacsha256_t *hmacsha256ctx;
- dst_hmacsha256_key_t *hkey = key->keydata.hmacsha256;
-
- 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_BLOCK_LENGTH);
- dctx->ctxdata.hmacsha256ctx = hmacsha256ctx;
- return (ISC_R_SUCCESS);
-}
-
-static void
-hmacsha256_destroyctx(dst_context_t *dctx) {
- isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx;
-
- if (hmacsha256ctx != NULL) {
- isc_hmacsha256_invalidate(hmacsha256ctx);
- isc_mem_put(dctx->mctx, hmacsha256ctx, sizeof(isc_hmacsha256_t));
- dctx->ctxdata.hmacsha256ctx = NULL;
- }
-}
-
-static isc_result_t
-hmacsha256_adddata(dst_context_t *dctx, const isc_region_t *data) {
- isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx;
-
- isc_hmacsha256_update(hmacsha256ctx, data->base, data->length);
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha256_sign(dst_context_t *dctx, isc_buffer_t *sig) {
- isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx;
- unsigned char *digest;
-
- if (isc_buffer_availablelength(sig) < ISC_SHA256_DIGESTLENGTH)
- return (ISC_R_NOSPACE);
- digest = isc_buffer_used(sig);
- isc_hmacsha256_sign(hmacsha256ctx, digest, ISC_SHA256_DIGESTLENGTH);
- isc_buffer_add(sig, ISC_SHA256_DIGESTLENGTH);
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha256_verify(dst_context_t *dctx, const isc_region_t *sig) {
- isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx;
-
- if (sig->length > ISC_SHA256_DIGESTLENGTH || sig->length == 0)
- return (DST_R_VERIFYFAILURE);
-
- if (isc_hmacsha256_verify(hmacsha256ctx, sig->base, sig->length))
- return (ISC_R_SUCCESS);
- else
- return (DST_R_VERIFYFAILURE);
-}
-
-static isc_boolean_t
-hmacsha256_compare(const dst_key_t *key1, const dst_key_t *key2) {
- dst_hmacsha256_key_t *hkey1, *hkey2;
-
- hkey1 = key1->keydata.hmacsha256;
- hkey2 = key2->keydata.hmacsha256;
-
- if (hkey1 == NULL && hkey2 == NULL)
- return (ISC_TRUE);
- else if (hkey1 == NULL || hkey2 == NULL)
- return (ISC_FALSE);
-
- 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,
- void (*callback)(int))
-{
- isc_buffer_t b;
- isc_result_t ret;
- unsigned int bytes;
- unsigned char data[ISC_SHA256_BLOCK_LENGTH];
-
- UNUSED(callback);
-
- bytes = (key->key_size + 7) / 8;
- if (bytes > ISC_SHA256_BLOCK_LENGTH) {
- bytes = ISC_SHA256_BLOCK_LENGTH;
- key->key_size = ISC_SHA256_BLOCK_LENGTH * 8;
- }
-
- memset(data, 0, ISC_SHA256_BLOCK_LENGTH);
- ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
-
- if (ret != ISC_R_SUCCESS)
- return (ret);
-
- isc_buffer_init(&b, data, bytes);
- isc_buffer_add(&b, bytes);
- ret = hmacsha256_fromdns(key, &b);
- memset(data, 0, ISC_SHA256_BLOCK_LENGTH);
-
- return (ret);
-}
-
-static isc_boolean_t
-hmacsha256_isprivate(const dst_key_t *key) {
- UNUSED(key);
- return (ISC_TRUE);
-}
-
-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;
-}
-
-static isc_result_t
-hmacsha256_todns(const dst_key_t *key, isc_buffer_t *data) {
- dst_hmacsha256_key_t *hkey;
- unsigned int bytes;
-
- REQUIRE(key->keydata.hmacsha256 != NULL);
-
- hkey = key->keydata.hmacsha256;
-
- bytes = (key->key_size + 7) / 8;
- if (isc_buffer_availablelength(data) < bytes)
- return (ISC_R_NOSPACE);
- isc_buffer_putmem(data, hkey->key, bytes);
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha256_fromdns(dst_key_t *key, isc_buffer_t *data) {
- dst_hmacsha256_key_t *hkey;
- int keylen;
- isc_region_t r;
- isc_sha256_t sha256ctx;
-
- isc_buffer_remainingregion(data, &r);
- if (r.length == 0)
- return (ISC_R_SUCCESS);
-
- hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha256_key_t));
- if (hkey == NULL)
- return (ISC_R_NOMEMORY);
-
- memset(hkey->key, 0, sizeof(hkey->key));
-
- 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);
- keylen = ISC_SHA256_DIGESTLENGTH;
- }
- else {
- memcpy(hkey->key, r.base, r.length);
- keylen = r.length;
- }
-
- key->key_size = keylen * 8;
- key->keydata.hmacsha256 = hkey;
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha256_tofile(const dst_key_t *key, const char *directory) {
- int cnt = 0;
- dst_hmacsha256_key_t *hkey;
- dst_private_t priv;
- int bytes = (key->key_size + 7) / 8;
- unsigned char buf[2];
-
- if (key->keydata.hmacsha256 == NULL)
- return (DST_R_NULLKEY);
-
- hkey = key->keydata.hmacsha256;
-
- priv.elements[cnt].tag = TAG_HMACSHA256_KEY;
- priv.elements[cnt].length = bytes;
- priv.elements[cnt++].data = hkey->key;
-
- buf[0] = (key->key_bits >> 8) & 0xffU;
- buf[1] = key->key_bits & 0xffU;
- priv.elements[cnt].tag = TAG_HMACSHA256_BITS;
- priv.elements[cnt].data = buf;
- priv.elements[cnt++].length = 2;
-
- priv.nelements = cnt;
- return (dst__privstruct_writefile(key, &priv, directory));
-}
-
-static isc_result_t
-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);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- key->key_bits = 0;
- for (i = 0; i < priv.nelements; i++) {
- switch (priv.elements[i].tag) {
- case TAG_HMACSHA256_KEY:
- isc_buffer_init(&b, priv.elements[i].data,
- priv.elements[i].length);
- isc_buffer_add(&b, priv.elements[i].length);
- tresult = hmacsha256_fromdns(key, &b);
- if (tresult != ISC_R_SUCCESS)
- result = tresult;
- break;
- case TAG_HMACSHA256_BITS:
- tresult = getkeybits(key, &priv.elements[i]);
- if (tresult != ISC_R_SUCCESS)
- result = tresult;
- break;
- default:
- result = DST_R_INVALIDPRIVATEKEY;
- break;
- }
- }
- dst__privstruct_free(&priv, mctx);
- memset(&priv, 0, sizeof(priv));
- return (result);
-}
-
-static dst_func_t hmacsha256_functions = {
- hmacsha256_createctx,
- hmacsha256_destroyctx,
- hmacsha256_adddata,
- hmacsha256_sign,
- hmacsha256_verify,
- NULL, /* verify2 */
- NULL, /* computesecret */
- hmacsha256_compare,
- NULL, /* paramcompare */
- hmacsha256_generate,
- hmacsha256_isprivate,
- hmacsha256_destroy,
- hmacsha256_todns,
- hmacsha256_fromdns,
- hmacsha256_tofile,
- hmacsha256_parse,
- NULL, /* cleanup */
- NULL, /* fromlabel */
- NULL, /* dump */
- NULL, /* restore */
-};
-
-isc_result_t
-dst__hmacsha256_init(dst_func_t **funcp) {
- REQUIRE(funcp != NULL);
- if (*funcp == NULL)
- *funcp = &hmacsha256_functions;
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t hmacsha384_fromdns(dst_key_t *key, isc_buffer_t *data);
-
-struct dst_hmacsha384_key {
- unsigned char key[ISC_SHA384_BLOCK_LENGTH];
-};
-
-static isc_result_t
-hmacsha384_createctx(dst_key_t *key, dst_context_t *dctx) {
- isc_hmacsha384_t *hmacsha384ctx;
- dst_hmacsha384_key_t *hkey = key->keydata.hmacsha384;
-
- 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_BLOCK_LENGTH);
- dctx->ctxdata.hmacsha384ctx = hmacsha384ctx;
- return (ISC_R_SUCCESS);
-}
-
-static void
-hmacsha384_destroyctx(dst_context_t *dctx) {
- isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx;
-
- if (hmacsha384ctx != NULL) {
- isc_hmacsha384_invalidate(hmacsha384ctx);
- isc_mem_put(dctx->mctx, hmacsha384ctx, sizeof(isc_hmacsha384_t));
- dctx->ctxdata.hmacsha384ctx = NULL;
- }
-}
-
-static isc_result_t
-hmacsha384_adddata(dst_context_t *dctx, const isc_region_t *data) {
- isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx;
-
- isc_hmacsha384_update(hmacsha384ctx, data->base, data->length);
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha384_sign(dst_context_t *dctx, isc_buffer_t *sig) {
- isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx;
- unsigned char *digest;
-
- if (isc_buffer_availablelength(sig) < ISC_SHA384_DIGESTLENGTH)
- return (ISC_R_NOSPACE);
- digest = isc_buffer_used(sig);
- isc_hmacsha384_sign(hmacsha384ctx, digest, ISC_SHA384_DIGESTLENGTH);
- isc_buffer_add(sig, ISC_SHA384_DIGESTLENGTH);
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha384_verify(dst_context_t *dctx, const isc_region_t *sig) {
- isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx;
-
- if (sig->length > ISC_SHA384_DIGESTLENGTH || sig->length == 0)
- return (DST_R_VERIFYFAILURE);
-
- if (isc_hmacsha384_verify(hmacsha384ctx, sig->base, sig->length))
- return (ISC_R_SUCCESS);
- else
- return (DST_R_VERIFYFAILURE);
-}
-
-static isc_boolean_t
-hmacsha384_compare(const dst_key_t *key1, const dst_key_t *key2) {
- dst_hmacsha384_key_t *hkey1, *hkey2;
-
- hkey1 = key1->keydata.hmacsha384;
- hkey2 = key2->keydata.hmacsha384;
-
- if (hkey1 == NULL && hkey2 == NULL)
- return (ISC_TRUE);
- else if (hkey1 == NULL || hkey2 == NULL)
- return (ISC_FALSE);
-
- 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,
- void (*callback)(int))
-{
- isc_buffer_t b;
- isc_result_t ret;
- unsigned int bytes;
- unsigned char data[ISC_SHA384_BLOCK_LENGTH];
-
- UNUSED(callback);
-
- bytes = (key->key_size + 7) / 8;
- if (bytes > ISC_SHA384_BLOCK_LENGTH) {
- bytes = ISC_SHA384_BLOCK_LENGTH;
- key->key_size = ISC_SHA384_BLOCK_LENGTH * 8;
- }
-
- memset(data, 0, ISC_SHA384_BLOCK_LENGTH);
- ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
-
- if (ret != ISC_R_SUCCESS)
- return (ret);
-
- isc_buffer_init(&b, data, bytes);
- isc_buffer_add(&b, bytes);
- ret = hmacsha384_fromdns(key, &b);
- memset(data, 0, ISC_SHA384_BLOCK_LENGTH);
-
- return (ret);
-}
-
-static isc_boolean_t
-hmacsha384_isprivate(const dst_key_t *key) {
- UNUSED(key);
- return (ISC_TRUE);
-}
-
-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;
-}
-
-static isc_result_t
-hmacsha384_todns(const dst_key_t *key, isc_buffer_t *data) {
- dst_hmacsha384_key_t *hkey;
- unsigned int bytes;
-
- REQUIRE(key->keydata.hmacsha384 != NULL);
-
- hkey = key->keydata.hmacsha384;
-
- bytes = (key->key_size + 7) / 8;
- if (isc_buffer_availablelength(data) < bytes)
- return (ISC_R_NOSPACE);
- isc_buffer_putmem(data, hkey->key, bytes);
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha384_fromdns(dst_key_t *key, isc_buffer_t *data) {
- dst_hmacsha384_key_t *hkey;
- int keylen;
- isc_region_t r;
- isc_sha384_t sha384ctx;
-
- isc_buffer_remainingregion(data, &r);
- if (r.length == 0)
- return (ISC_R_SUCCESS);
-
- hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha384_key_t));
- if (hkey == NULL)
- return (ISC_R_NOMEMORY);
-
- memset(hkey->key, 0, sizeof(hkey->key));
-
- 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);
- keylen = ISC_SHA384_DIGESTLENGTH;
- }
- else {
- memcpy(hkey->key, r.base, r.length);
- keylen = r.length;
- }
-
- key->key_size = keylen * 8;
- key->keydata.hmacsha384 = hkey;
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha384_tofile(const dst_key_t *key, const char *directory) {
- int cnt = 0;
- dst_hmacsha384_key_t *hkey;
- dst_private_t priv;
- int bytes = (key->key_size + 7) / 8;
- unsigned char buf[2];
-
- if (key->keydata.hmacsha384 == NULL)
- return (DST_R_NULLKEY);
-
- hkey = key->keydata.hmacsha384;
-
- priv.elements[cnt].tag = TAG_HMACSHA384_KEY;
- priv.elements[cnt].length = bytes;
- priv.elements[cnt++].data = hkey->key;
-
- buf[0] = (key->key_bits >> 8) & 0xffU;
- buf[1] = key->key_bits & 0xffU;
- priv.elements[cnt].tag = TAG_HMACSHA384_BITS;
- priv.elements[cnt].data = buf;
- priv.elements[cnt++].length = 2;
-
- priv.nelements = cnt;
- return (dst__privstruct_writefile(key, &priv, directory));
-}
-
-static isc_result_t
-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);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- key->key_bits = 0;
- for (i = 0; i < priv.nelements; i++) {
- switch (priv.elements[i].tag) {
- case TAG_HMACSHA384_KEY:
- isc_buffer_init(&b, priv.elements[i].data,
- priv.elements[i].length);
- isc_buffer_add(&b, priv.elements[i].length);
- tresult = hmacsha384_fromdns(key, &b);
- if (tresult != ISC_R_SUCCESS)
- result = tresult;
- break;
- case TAG_HMACSHA384_BITS:
- tresult = getkeybits(key, &priv.elements[i]);
- if (tresult != ISC_R_SUCCESS)
- result = tresult;
- break;
- default:
- result = DST_R_INVALIDPRIVATEKEY;
- break;
- }
- }
- dst__privstruct_free(&priv, mctx);
- memset(&priv, 0, sizeof(priv));
- return (result);
-}
-
-static dst_func_t hmacsha384_functions = {
- hmacsha384_createctx,
- hmacsha384_destroyctx,
- hmacsha384_adddata,
- hmacsha384_sign,
- hmacsha384_verify,
- NULL, /* verify2 */
- NULL, /* computesecret */
- hmacsha384_compare,
- NULL, /* paramcompare */
- hmacsha384_generate,
- hmacsha384_isprivate,
- hmacsha384_destroy,
- hmacsha384_todns,
- hmacsha384_fromdns,
- hmacsha384_tofile,
- hmacsha384_parse,
- NULL, /* cleanup */
- NULL, /* fromlabel */
- NULL, /* dump */
- NULL, /* restore */
-};
-
-isc_result_t
-dst__hmacsha384_init(dst_func_t **funcp) {
- REQUIRE(funcp != NULL);
- if (*funcp == NULL)
- *funcp = &hmacsha384_functions;
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t hmacsha512_fromdns(dst_key_t *key, isc_buffer_t *data);
-
-struct dst_hmacsha512_key {
- unsigned char key[ISC_SHA512_BLOCK_LENGTH];
-};
-
-static isc_result_t
-hmacsha512_createctx(dst_key_t *key, dst_context_t *dctx) {
- isc_hmacsha512_t *hmacsha512ctx;
- dst_hmacsha512_key_t *hkey = key->keydata.hmacsha512;
-
- 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_BLOCK_LENGTH);
- dctx->ctxdata.hmacsha512ctx = hmacsha512ctx;
- return (ISC_R_SUCCESS);
-}
-
-static void
-hmacsha512_destroyctx(dst_context_t *dctx) {
- isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx;
-
- if (hmacsha512ctx != NULL) {
- isc_hmacsha512_invalidate(hmacsha512ctx);
- isc_mem_put(dctx->mctx, hmacsha512ctx, sizeof(isc_hmacsha512_t));
- dctx->ctxdata.hmacsha512ctx = NULL;
- }
-}
-
-static isc_result_t
-hmacsha512_adddata(dst_context_t *dctx, const isc_region_t *data) {
- isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx;
-
- isc_hmacsha512_update(hmacsha512ctx, data->base, data->length);
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha512_sign(dst_context_t *dctx, isc_buffer_t *sig) {
- isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx;
- unsigned char *digest;
-
- if (isc_buffer_availablelength(sig) < ISC_SHA512_DIGESTLENGTH)
- return (ISC_R_NOSPACE);
- digest = isc_buffer_used(sig);
- isc_hmacsha512_sign(hmacsha512ctx, digest, ISC_SHA512_DIGESTLENGTH);
- isc_buffer_add(sig, ISC_SHA512_DIGESTLENGTH);
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha512_verify(dst_context_t *dctx, const isc_region_t *sig) {
- isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx;
-
- if (sig->length > ISC_SHA512_DIGESTLENGTH || sig->length == 0)
- return (DST_R_VERIFYFAILURE);
-
- if (isc_hmacsha512_verify(hmacsha512ctx, sig->base, sig->length))
- return (ISC_R_SUCCESS);
- else
- return (DST_R_VERIFYFAILURE);
-}
-
-static isc_boolean_t
-hmacsha512_compare(const dst_key_t *key1, const dst_key_t *key2) {
- dst_hmacsha512_key_t *hkey1, *hkey2;
-
- hkey1 = key1->keydata.hmacsha512;
- hkey2 = key2->keydata.hmacsha512;
-
- if (hkey1 == NULL && hkey2 == NULL)
- return (ISC_TRUE);
- else if (hkey1 == NULL || hkey2 == NULL)
- return (ISC_FALSE);
-
- 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,
- void (*callback)(int))
-{
- isc_buffer_t b;
- isc_result_t ret;
- unsigned int bytes;
- unsigned char data[ISC_SHA512_BLOCK_LENGTH];
-
- UNUSED(callback);
-
- bytes = (key->key_size + 7) / 8;
- if (bytes > ISC_SHA512_BLOCK_LENGTH) {
- bytes = ISC_SHA512_BLOCK_LENGTH;
- key->key_size = ISC_SHA512_BLOCK_LENGTH * 8;
- }
-
- memset(data, 0, ISC_SHA512_BLOCK_LENGTH);
- ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
-
- if (ret != ISC_R_SUCCESS)
- return (ret);
-
- isc_buffer_init(&b, data, bytes);
- isc_buffer_add(&b, bytes);
- ret = hmacsha512_fromdns(key, &b);
- memset(data, 0, ISC_SHA512_BLOCK_LENGTH);
-
- return (ret);
-}
-
-static isc_boolean_t
-hmacsha512_isprivate(const dst_key_t *key) {
- UNUSED(key);
- return (ISC_TRUE);
-}
-
-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;
-}
-
-static isc_result_t
-hmacsha512_todns(const dst_key_t *key, isc_buffer_t *data) {
- dst_hmacsha512_key_t *hkey;
- unsigned int bytes;
-
- REQUIRE(key->keydata.hmacsha512 != NULL);
-
- hkey = key->keydata.hmacsha512;
-
- bytes = (key->key_size + 7) / 8;
- if (isc_buffer_availablelength(data) < bytes)
- return (ISC_R_NOSPACE);
- isc_buffer_putmem(data, hkey->key, bytes);
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha512_fromdns(dst_key_t *key, isc_buffer_t *data) {
- dst_hmacsha512_key_t *hkey;
- int keylen;
- isc_region_t r;
- isc_sha512_t sha512ctx;
-
- isc_buffer_remainingregion(data, &r);
- if (r.length == 0)
- return (ISC_R_SUCCESS);
-
- hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha512_key_t));
- if (hkey == NULL)
- return (ISC_R_NOMEMORY);
-
- memset(hkey->key, 0, sizeof(hkey->key));
-
- 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);
- keylen = ISC_SHA512_DIGESTLENGTH;
- }
- else {
- memcpy(hkey->key, r.base, r.length);
- keylen = r.length;
- }
-
- key->key_size = keylen * 8;
- key->keydata.hmacsha512 = hkey;
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-hmacsha512_tofile(const dst_key_t *key, const char *directory) {
- int cnt = 0;
- dst_hmacsha512_key_t *hkey;
- dst_private_t priv;
- int bytes = (key->key_size + 7) / 8;
- unsigned char buf[2];
-
- if (key->keydata.hmacsha512 == NULL)
- return (DST_R_NULLKEY);
-
- hkey = key->keydata.hmacsha512;
-
- priv.elements[cnt].tag = TAG_HMACSHA512_KEY;
- priv.elements[cnt].length = bytes;
- priv.elements[cnt++].data = hkey->key;
-
- buf[0] = (key->key_bits >> 8) & 0xffU;
- buf[1] = key->key_bits & 0xffU;
- priv.elements[cnt].tag = TAG_HMACSHA512_BITS;
- priv.elements[cnt].data = buf;
- priv.elements[cnt++].length = 2;
-
- priv.nelements = cnt;
- return (dst__privstruct_writefile(key, &priv, directory));
-}
-
-static isc_result_t
-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);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- key->key_bits = 0;
- for (i = 0; i < priv.nelements; i++) {
- switch (priv.elements[i].tag) {
- case TAG_HMACSHA512_KEY:
- isc_buffer_init(&b, priv.elements[i].data,
- priv.elements[i].length);
- isc_buffer_add(&b, priv.elements[i].length);
- tresult = hmacsha512_fromdns(key, &b);
- if (tresult != ISC_R_SUCCESS)
- result = tresult;
- break;
- case TAG_HMACSHA512_BITS:
- tresult = getkeybits(key, &priv.elements[i]);
- if (tresult != ISC_R_SUCCESS)
- result = tresult;
- break;
- default:
- result = DST_R_INVALIDPRIVATEKEY;
- break;
- }
- }
- dst__privstruct_free(&priv, mctx);
- memset(&priv, 0, sizeof(priv));
- return (result);
-}
-
-static dst_func_t hmacsha512_functions = {
- hmacsha512_createctx,
- hmacsha512_destroyctx,
- hmacsha512_adddata,
- hmacsha512_sign,
- hmacsha512_verify,
- NULL, /* verify2 */
- NULL, /* computesecret */
- hmacsha512_compare,
- NULL, /* paramcompare */
- hmacsha512_generate,
- hmacsha512_isprivate,
- hmacsha512_destroy,
- hmacsha512_todns,
- hmacsha512_fromdns,
- hmacsha512_tofile,
- hmacsha512_parse,
- NULL, /* cleanup */
- NULL, /* fromlabel */
- NULL, /* dump */
- NULL, /* restore */
-};
-
-isc_result_t
-dst__hmacsha512_init(dst_func_t **funcp) {
- REQUIRE(funcp != NULL);
- if (*funcp == NULL)
- *funcp = &hmacsha512_functions;
- return (ISC_R_SUCCESS);
-}
-
-/*! \file */
diff --git a/contrib/bind9/lib/dns/include/Makefile.in b/contrib/bind9/lib/dns/include/Makefile.in
deleted file mode 100644
index 10d798d9605f..000000000000
--- a/contrib/bind9/lib/dns/include/Makefile.in
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
-# Copyright (C) 1998-2001 Internet Software Consortium.
-#
-# Permission to use, copy, modify, and/or distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-# PERFORMANCE OF THIS SOFTWARE.
-
-# $Id: Makefile.in,v 1.15 2007/06/19 23:47:16 tbox Exp $
-
-srcdir = @srcdir@
-VPATH = @srcdir@
-top_srcdir = @top_srcdir@
-
-SUBDIRS = dns dst
-TARGETS =
-
-@BIND9_MAKE_RULES@
diff --git a/contrib/bind9/lib/dns/include/dns/Makefile.in b/contrib/bind9/lib/dns/include/dns/Makefile.in
deleted file mode 100644
index 1a69f2c814f4..000000000000
--- a/contrib/bind9/lib/dns/include/dns/Makefile.in
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright (C) 2004, 2007-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
-# Copyright (C) 1998-2003 Internet Software Consortium.
-#
-# Permission to use, copy, modify, and/or distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-# LOSS OF USE, DATA OR PROFITS, WHETHER IN 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.60 2011/11/14 18:32:34 each Exp $
-
-srcdir = @srcdir@
-VPATH = @srcdir@
-top_srcdir = @top_srcdir@
-
-@BIND9_VERSION@
-
-HEADERS = acl.h adb.h byaddr.h cache.h callbacks.h cert.h compress.h \
- clientinfo.h db.h dbiterator.h dbtable.h diff.h dispatch.h \
- dlz.h dnssec.h ds.h events.h fixedname.h iptable.h journal.h \
- keyflags.h keytable.h keyvalues.h lib.h log.h \
- master.h masterdump.h message.h name.h ncache.h nsec.h \
- peer.h portlist.h private.h rbt.h rcode.h \
- rdata.h rdataclass.h rdatalist.h rdataset.h rdatasetiter.h \
- rdataslab.h rdatatype.h request.h resolver.h result.h \
- rootns.h rpz.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
-
-GENHEADERS = enumclass.h enumtype.h rdatastruct.h
-
-SUBDIRS =
-TARGETS =
-
-@BIND9_MAKE_RULES@
-
-installdirs:
- $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/dns
-
-install:: installdirs
- for i in ${HEADERS}; do \
- ${INSTALL_DATA} ${srcdir}/$$i ${DESTDIR}${includedir}/dns ; \
- done
- for i in ${GENHEADERS}; do \
- ${INSTALL_DATA} $$i ${DESTDIR}${includedir}/dns ; \
- done
diff --git a/contrib/bind9/lib/dns/include/dns/acache.h b/contrib/bind9/lib/dns/include/dns/acache.h
deleted file mode 100644
index 304cba758ad3..000000000000
--- a/contrib/bind9/lib/dns/include/dns/acache.h
+++ /dev/null
@@ -1,448 +0,0 @@
-/*
- * Copyright (C) 2004, 2006, 2007, 2013 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: acache.h,v 1.8 2007/06/19 23:47:16 tbox Exp $ */
-
-#ifndef DNS_ACACHE_H
-#define DNS_ACACHE_H 1
-
-/*****
- ***** Module Info
- *****/
-
-/*
- * Acache
- *
- * The Additional Cache Object
- *
- * This module manages internal caching entries that correspond to
- * the additional section data of a DNS DB node (an RRset header, more
- * accurately). An additional cache entry is expected to be (somehow)
- * attached to a particular RR in a particular DB node, and contains a set
- * of information of an additional data for the DB node.
- *
- * An additional cache object is intended to be created as a per-view
- * object, and manages all cache entries within the view.
- *
- * The intended usage of the additional caching is to provide a short cut
- * to additional glue RRs of an NS RR. For each NS RR, it is often
- * necessary to look for glue RRs to make a proper response. Once the
- * glue RRs are known, the additional caching allows the client to
- * associate the information to the original NS RR so that further
- * expensive lookups can be avoided for the NS RR.
- *
- * Each additional cache entry contains information to identify a
- * particular DB node and (optionally) an associated RRset. The
- * information consists of its zone, database, the version of the
- * database, database node, and RRset.
- *
- * A "negative" information can also be cached. For example, if a glue
- * RR does not exist as an authoritative data in the same zone as that
- * of the NS RR, this fact can be cached by specifying a NULL pointer
- * for the database, version, and node. (See the description for
- * dns_acache_getentry() below for more details.)
- *
- * Since each member stored in an additional cache entry holds a reference
- * to a corresponding object, a stale cache entry may cause unnecessary
- * memory consumption. For instance, when a zone is reloaded, additional
- * cache entries that have a reference to the zone (and its DB and/or
- * DB nodes) can delay the cleanup of the referred objects. In order to
- * minimize such a bad effect, this module provides several cleanup
- * mechanisms.
- *
- * The first one is a shutdown procedure called when the associated view
- * is shut down. In this case, dns_acache_shutdown() will be called and
- * all cache entries will be purged. This mechanism will help the
- * situation when the configuration is reloaded or the main server is
- * stopped.
- *
- * Per-DB cleanup mechanism is also provided. Each additional cache entry
- * is associated with related DB, which is expected to have been
- * registered when the DB was created by dns_acache_setdb(). If a
- * particular DB is going to be destroyed, the primary holder of the DB,
- * a typical example of which is a zone, will call dns_acache_putdb().
- * Then this module will clean-up all cache entries associated with the
- * DB. This mechanism is effective when a secondary zone DB is going to
- * be stale after a zone transfer.
- *
- * Finally, this module supports for periodic clean-up of stale entries.
- * Each cache entry has a timestamp field, which is updated every time
- * the entry is referred. A periodically invoked cleaner checks the
- * timestamp of each entry, and purge entries that have not been referred
- * for a certain period. The cleaner interval can be specified by
- * dns_acache_setcleaninginterval(). If the periodic clean-up is not
- * enough, it is also possible to specify the upper limit of entries
- * in terms of the memory consumption. If the maximum value is
- * specified, the cleaner is invoked when the memory consumption reaches
- * the high watermark inferred from the maximum value. In this case,
- * the cleaner will use more aggressive algorithm to decide the "victim"
- * entries. The maximum value can be specified by
- * dns_acache_setcachesize().
- *
- * When a cache entry is going to be purged within this module, the
- * callback function specified at the creation time will be called.
- * The callback function is expected to release all internal resources
- * related to the entry, which will typically be specific to DB
- * implementation, and to call dns_acache_detachentry(). The callback
- * mechanism is very important, since the holder of an additional cache
- * entry may not be able to initiate the clean-up of the entry, due to
- * the reference ordering. For example, as long as an additional cache
- * entry has a reference to a DB object, the DB cannot be freed, in which
- * a DB node may have a reference to the cache entry.
- *
- * Credits:
- * The basic idea of this kind of short-cut for frequently used
- * information is similar to the "pre-compiled answer" approach adopted
- * in nsd by NLnet LABS with RIPE NCC. Our work here is an independent
- * effort, but the success of nsd encouraged us to pursue this path.
- *
- * The design and implementation of the periodic memory management and
- * the upper limitation of memory consumption was derived from the cache
- * DB implementation of BIND9.
- *
- * MP:
- * There are two main locks in this module. One is for each entry, and
- * the other is for the additional cache object.
- *
- * Reliability:
- * The callback function for a cache entry is called with holding the
- * entry lock. Thus, it implicitly assumes the callback function does not
- * call a function that can require the lock. Typically, the only
- * function that can be called from the callback function safely is
- * dns_acache_detachentry(). The breakage of this implicit assumption
- * may cause a deadlock.
- *
- * Resources:
- * In a 32-bit architecture (such as i386), the following additional
- * memory is required comparing to the case that disables this module.
- * - 76 bytes for each additional cache entry
- * - if the entry has a DNS name and associated RRset,
- * * 44 bytes + size of the name (1-255 bytes)
- * * 52 bytes x number_of_RRs
- * - 28 bytes for each DB related to this module
- *
- * Using the additional cache also requires extra memory consumption in
- * the DB implementation. In the current implementation for rbtdb, we
- * need:
- * - two additional pointers for each DB node (8 bytes for a 32-bit
- * architecture
- * - for each RR associated to an RR in a DB node, we also need
- * a pointer and management objects to support the additional cache
- * function. These are allocated on-demand. The total size is
- * 32 bytes for a 32-bit architecture.
- *
- * Security:
- * Since this module does not handle any low-level data directly,
- * no security issue specific to this module is anticipated.
- *
- * Standards:
- * None.
- */
-
-/***
- *** Imports
- ***/
-
-#include <isc/mutex.h>
-#include <isc/lang.h>
-#include <isc/refcount.h>
-#include <isc/stdtime.h>
-
-#include <dns/types.h>
-
-/***
- *** Functions
- ***/
-ISC_LANG_BEGINDECLS
-
-isc_result_t
-dns_acache_create(dns_acache_t **acachep, isc_mem_t *mctx,
- isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr);
-/*
- * Create a new DNS additional cache object.
- *
- * Requires:
- *
- * 'mctx' is a valid memory context
- *
- * 'taskmgr' is a valid task manager
- *
- * 'timermgr' is a valid timer or NULL. If NULL, no periodic cleaning of
- * the cache will take place.
- *
- * 'acachep' is a valid pointer, and *acachep == NULL
- *
- * Ensures:
- *
- * '*acachep' is attached to the newly created cache
- *
- * Returns:
- *
- * ISC_R_SUCCESS
- * ISC_R_NOMEMORY
- * ISC_R_UNEXPECTED
- */
-
-void
-dns_acache_attach(dns_acache_t *source, dns_acache_t **targetp);
-/*
- * Attach *targetp to cache.
- *
- * Requires:
- *
- * 'acache' is a valid additional cache.
- *
- * 'targetp' points to a NULL dns_acache_t *.
- *
- * Ensures:
- *
- * *targetp is attached to the 'source' additional cache.
- */
-
-void
-dns_acache_detach(dns_acache_t **acachep);
-/*
- * Detach *acachep from its cache.
- *
- * Requires:
- *
- * '*acachep' points to a valid additional cache.
- *
- * Ensures:
- *
- * *acachep is NULL.
- *
- * If '*acachep' is the last reference to the cache and the additional
- * cache does not have an outstanding task, all resources used by the
- * cache will be freed.
- */
-
-void
-dns_acache_setcleaninginterval(dns_acache_t *acache, unsigned int t);
-/*
- * Set the periodic cleaning interval of an additional cache to 'interval'
- * seconds.
- */
-
-void
-dns_acache_setcachesize(dns_acache_t *acache, size_t size);
-/*
- * Set the maximum additional cache size. 0 means unlimited.
- */
-
-isc_result_t
-dns_acache_setdb(dns_acache_t *acache, dns_db_t *db);
-/*
- * Set 'db' in 'acache' when the db can be referred from acache, in order
- * to provide a hint for resolving the back reference.
- *
- * Requires:
- * 'acache' is a valid acache pointer.
- * 'db' is a valid DNS DB pointer.
- *
- * Ensures:
- * 'acache' will have a reference to 'db'.
- *
- * Returns:
- * ISC_R_SUCCESS
- * ISC_R_EXISTS (which means the specified 'db' is already set)
- * ISC_R_NOMEMORY
- */
-
-isc_result_t
-dns_acache_putdb(dns_acache_t *acache, dns_db_t *db);
-/*
- * Release 'db' from 'acache' if it has been set by dns_acache_setdb().
- *
- * Requires:
- * 'acache' is a valid acache pointer.
- * 'db' is a valid DNS DB pointer.
- *
- * Ensures:
- * 'acache' will release the reference to 'db'. Additionally, the content
- * of each cache entry that is related to the 'db' will be released via
- * the callback function.
- *
- * Returns:
- * ISC_R_SUCCESS
- * ISC_R_NOTFOUND (which means the specified 'db' is not set in 'acache')
- * ISC_R_NOMEMORY
- */
-
-void
-dns_acache_shutdown(dns_acache_t *acache);
-/*
- * Shutdown 'acache'.
- *
- * Requires:
- *
- * '*acache' is a valid additional cache.
- */
-
-isc_result_t
-dns_acache_createentry(dns_acache_t *acache, dns_db_t *origdb,
- void (*callback)(dns_acacheentry_t *, void **),
- void *cbarg, dns_acacheentry_t **entryp);
-/*
- * Create an additional cache entry. A new entry is created and attached to
- * the given additional cache object. A callback function is also associated
- * with the created entry, which will be called when the cache entry is purged
- * for some reason.
- *
- * Requires:
- *
- * 'acache' is a valid additional cache.
- * 'entryp' is a valid pointer, and *entryp == NULL
- * 'origdb' is a valid DNS DB pointer.
- * 'callback' and 'cbarg' can be NULL. In this case, however, the entry
- * is meaningless (and will be cleaned-up in the next periodical
- * cleaning).
- *
- * Ensures:
- * '*entryp' will point to a new additional cache entry.
- *
- * Returns:
- * ISC_R_SUCCESS
- * ISC_R_NOMEMORY
- */
-
-isc_result_t
-dns_acache_getentry(dns_acacheentry_t *entry, dns_zone_t **zonep,
- dns_db_t **dbp, dns_dbversion_t **versionp,
- dns_dbnode_t **nodep, dns_name_t *fname,
- dns_message_t *msg, isc_stdtime_t now);
-/*
- * Get content from a particular additional cache entry.
- *
- * Requires:
- *
- * 'entry' is a valid additional cache entry.
- * 'zonep' is a NULL pointer or '*zonep' == NULL (this is the only
- * optional parameter.)
- * 'dbp' is a valid pointer, and '*dbp' == NULL
- * 'versionp' is a valid pointer, and '*versionp' == NULL
- * 'nodep' is a valid pointer, and '*nodep' == NULL
- * 'fname' is a valid DNS name.
- * 'msg' is a valid DNS message.
- *
- * Ensures:
- * Several possible cases can happen according to the content.
- * 1. For a positive cache entry,
- * '*zonep' will point to the corresponding zone (if zonep is a valid
- * pointer),
- * '*dbp' will point to a DB for the zone,
- * '*versionp' will point to its version, and
- * '*nodep' will point to the corresponding DB node.
- * 'fname' will have the DNS name of the DB node and contain a list of
- * rdataset for the node (which can be an empty list).
- *
- * 2. For a negative cache entry that means no corresponding zone exists,
- * '*zonep' == NULL (if zonep is a valid pointer)
- * '*dbp', '*versionp', and '*nodep' will be NULL.
- *
- * 3. For a negative cache entry that means no corresponding DB node
- * exists, '*zonep' will point to the corresponding zone (if zonep is a
- * valid pointer),
- * '*dbp' will point to a corresponding DB for zone,
- * '*versionp' will point to its version.
- * '*nodep' will be kept as NULL.
- * 'fname' will not change.
- *
- * On failure, no new references will be created.
- *
- * Returns:
- * ISC_R_SUCCESS
- * ISC_R_NOMEMORY
- */
-
-isc_result_t
-dns_acache_setentry(dns_acache_t *acache, dns_acacheentry_t *entry,
- dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
- dns_dbnode_t *node, dns_name_t *fname);
-/*
- * Set content to a particular additional cache entry.
- *
- * Requires:
- * 'acache' is a valid additional cache.
- * 'entry' is a valid additional cache entry.
- * All the others pointers are NULL or a valid pointer of the
- * corresponding type.
- *
- * Returns:
- * ISC_R_SUCCESS
- * ISC_R_NOMEMORY
- * ISC_R_NOTFOUND
- */
-
-isc_boolean_t
-dns_acache_cancelentry(dns_acacheentry_t *entry);
-/*
- * Cancel the use of the cache entry 'entry'. This function is supposed to
- * be called when the node that holds the entry finds the content is not
- * correct any more. This function will try to release as much dependency as
- * possible, and will be ready to be cleaned-up. The registered callback
- * function will be canceled and will never called.
- *
- * Requires:
- * 'entry' is a valid additional cache entry.
- *
- * Returns:
- * ISC_TRUE if the entry was active when canceled
- */
-
-void
-dns_acache_attachentry(dns_acacheentry_t *source, dns_acacheentry_t **targetp);
-/*
- * Attach *targetp to the cache entry 'source'.
- *
- * Requires:
- *
- * 'source' is a valid additional cache entry.
- *
- * 'targetp' points to a NULL dns_acacheentry_t *.
- *
- * Ensures:
- *
- * *targetp is attached to 'source'.
- */
-
-void
-dns_acache_detachentry(dns_acacheentry_t **entryp);
-/*
- * Detach *entryp from its cache.
- *
- * Requires:
- *
- * '*entryp' points to a valid additional cache entry.
- *
- * Ensures:
- *
- * *entryp is NULL.
- *
- * If '*entryp' is the last reference to the entry,
- * cache does not have an outstanding task, all resources used by the
- * entry (including the entry object itself) will be freed.
- */
-
-void
-dns_acache_countquerymiss(dns_acache_t *acache);
-/*
- * Count up a missed acache query. XXXMLG need more docs.
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_ACACHE_H */
diff --git a/contrib/bind9/lib/dns/include/dns/acl.h b/contrib/bind9/lib/dns/include/dns/acl.h
deleted file mode 100644
index f4fc4a3bf9e1..000000000000
--- a/contrib/bind9/lib/dns/include/dns/acl.h
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: acl.h,v 1.35 2011/06/17 23:47:49 tbox Exp $ */
-
-#ifndef DNS_ACL_H
-#define DNS_ACL_H 1
-
-/*****
- ***** Module Info
- *****/
-
-/*! \file dns/acl.h
- * \brief
- * Address match list handling.
- */
-
-/***
- *** Imports
- ***/
-
-#include <isc/lang.h>
-#include <isc/magic.h>
-#include <isc/netaddr.h>
-#include <isc/refcount.h>
-
-#include <dns/name.h>
-#include <dns/types.h>
-#include <dns/iptable.h>
-
-/***
- *** Types
- ***/
-
-typedef enum {
- dns_aclelementtype_ipprefix,
- dns_aclelementtype_keyname,
- dns_aclelementtype_nestedacl,
- dns_aclelementtype_localhost,
- dns_aclelementtype_localnets,
- dns_aclelementtype_any
-} dns_aclelemettype_t;
-
-typedef struct dns_aclipprefix dns_aclipprefix_t;
-
-struct dns_aclipprefix {
- isc_netaddr_t address; /* IP4/IP6 */
- unsigned int prefixlen;
-};
-
-struct dns_aclelement {
- dns_aclelemettype_t type;
- isc_boolean_t negative;
- dns_name_t keyname;
- dns_acl_t *nestedacl;
- int node_num;
-};
-
-struct dns_acl {
- unsigned int magic;
- isc_mem_t *mctx;
- isc_refcount_t refcount;
- dns_iptable_t *iptable;
-#define node_count iptable->radix->num_added_node
- dns_aclelement_t *elements;
- isc_boolean_t has_negatives;
- unsigned int alloc; /*%< Elements allocated */
- unsigned int length; /*%< Elements initialized */
- char *name; /*%< Temporary use only */
- ISC_LINK(dns_acl_t) nextincache; /*%< Ditto */
-};
-
-struct dns_aclenv {
- dns_acl_t *localhost;
- dns_acl_t *localnets;
- isc_boolean_t match_mapped;
-};
-
-#define DNS_ACL_MAGIC ISC_MAGIC('D','a','c','l')
-#define DNS_ACL_VALID(a) ISC_MAGIC_VALID(a, DNS_ACL_MAGIC)
-
-/***
- *** Functions
- ***/
-
-ISC_LANG_BEGINDECLS
-
-isc_result_t
-dns_acl_create(isc_mem_t *mctx, int n, dns_acl_t **target);
-/*%<
- * Create a new ACL, including an IP table and an array with room
- * for 'n' ACL elements. The elements are uninitialized and the
- * length is 0.
- */
-
-isc_result_t
-dns_acl_any(isc_mem_t *mctx, dns_acl_t **target);
-/*%<
- * Create a new ACL that matches everything.
- */
-
-isc_result_t
-dns_acl_none(isc_mem_t *mctx, dns_acl_t **target);
-/*%<
- * Create a new ACL that matches nothing.
- */
-
-isc_boolean_t
-dns_acl_isany(dns_acl_t *acl);
-/*%<
- * Test whether ACL is set to "{ any; }"
- */
-
-isc_boolean_t
-dns_acl_isnone(dns_acl_t *acl);
-/*%<
- * Test whether ACL is set to "{ none; }"
- */
-
-isc_result_t
-dns_acl_merge(dns_acl_t *dest, dns_acl_t *source, isc_boolean_t pos);
-/*%<
- * Merge the contents of one ACL into another. Call dns_iptable_merge()
- * for the IP tables, then concatenate the element arrays.
- *
- * If pos is set to false, then the nested ACL is to be negated. This
- * means reverse the sense of each *positive* element or IP table node,
- * but leave negatives alone, so as to prevent a double-negative causing
- * an unexpected positive match in the parent ACL.
- */
-
-void
-dns_acl_attach(dns_acl_t *source, dns_acl_t **target);
-/*%<
- * Attach to acl 'source'.
- *
- * Requires:
- *\li 'source' to be a valid acl.
- *\li 'target' to be non NULL and '*target' to be NULL.
- */
-
-void
-dns_acl_detach(dns_acl_t **aclp);
-/*%<
- * Detach the acl. On final detach the acl must not be linked on any
- * list.
- *
- * Requires:
- *\li '*aclp' to be a valid acl.
- *
- * Insists:
- *\li '*aclp' is not linked on final detach.
- */
-
-isc_boolean_t
-dns_acl_isinsecure(const dns_acl_t *a);
-/*%<
- * Return #ISC_TRUE iff the acl 'a' is considered insecure, that is,
- * if it contains IP addresses other than those of the local host.
- * This is intended for applications such as printing warning
- * messages for suspect ACLs; it is not intended for making access
- * control decisions. We make no guarantee that an ACL for which
- * this function returns #ISC_FALSE is safe.
- */
-
-isc_result_t
-dns_aclenv_init(isc_mem_t *mctx, dns_aclenv_t *env);
-/*%<
- * Initialize ACL environment, setting up localhost and localnets ACLs
- */
-
-void
-dns_aclenv_copy(dns_aclenv_t *t, dns_aclenv_t *s);
-
-void
-dns_aclenv_destroy(dns_aclenv_t *env);
-
-isc_result_t
-dns_acl_match(const isc_netaddr_t *reqaddr,
- const dns_name_t *reqsigner,
- const dns_acl_t *acl,
- const dns_aclenv_t *env,
- int *match,
- const dns_aclelement_t **matchelt);
-/*%<
- * General, low-level ACL matching. This is expected to
- * be useful even for weird stuff like the topology and sortlist statements.
- *
- * Match the address 'reqaddr', and optionally the key name 'reqsigner',
- * against 'acl'. 'reqsigner' may be NULL.
- *
- * If there is a match, '*match' will be set to an integer whose absolute
- * value corresponds to the order in which the matching value was inserted
- * into the ACL. For a positive match, this value will be positive; for a
- * negative match, it will be negative.
- *
- * If there is no match, *match will be set to zero.
- *
- * If there is a match in the element list (either positive or negative)
- * and 'matchelt' is non-NULL, *matchelt will be pointed to the matching
- * element.
- *
- * Returns:
- *\li #ISC_R_SUCCESS Always succeeds.
- */
-
-isc_boolean_t
-dns_aclelement_match(const isc_netaddr_t *reqaddr,
- const dns_name_t *reqsigner,
- const dns_aclelement_t *e,
- const dns_aclenv_t *env,
- const dns_aclelement_t **matchelt);
-/*%<
- * Like dns_acl_match, but matches against the single ACL element 'e'
- * rather than a complete ACL, and returns ISC_TRUE iff it matched.
- *
- * To determine whether the match was positive or negative, the
- * caller should examine e->negative. Since the element 'e' may be
- * a reference to a named ACL or a nested ACL, a matching element
- * returned through 'matchelt' is not necessarily 'e' itself.
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_ACL_H */
diff --git a/contrib/bind9/lib/dns/include/dns/adb.h b/contrib/bind9/lib/dns/include/dns/adb.h
deleted file mode 100644
index a5a312406aff..000000000000
--- a/contrib/bind9/lib/dns/include/dns/adb.h
+++ /dev/null
@@ -1,634 +0,0 @@
-/*
- * Copyright (C) 2004-2008, 2011, 2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: adb.h,v 1.88 2011/12/05 17:10:51 each Exp $ */
-
-#ifndef DNS_ADB_H
-#define DNS_ADB_H 1
-
-/*****
- ***** Module Info
- *****/
-
-/*! \file dns/adb.h
- *\brief
- * DNS Address Database
- *
- * This module implements an address database (ADB) for mapping a name
- * to an isc_sockaddr_t. It also provides statistical information on
- * how good that address might be.
- *
- * A client will pass in a dns_name_t, and the ADB will walk through
- * the rdataset looking up addresses associated with the name. If it
- * is found on the internal lists, a structure is filled in with the
- * address information and stats for found addresses.
- *
- * If the name cannot be found on the internal lists, a new entry will
- * be created for a name if all the information needed can be found
- * in the zone table or cache. This new address will then be returned.
- *
- * If a request must be made to remote servers to satisfy a name lookup,
- * this module will start fetches to try to complete these addresses. When
- * at least one more completes, an event is sent to the caller. If none of
- * them resolve before the fetch times out, an event indicating this is
- * sent instead.
- *
- * Records are stored internally until a timer expires. The timer is the
- * smaller of the TTL or signature validity period.
- *
- * Lameness is stored per <qname,qtype> tuple, and this data hangs off each
- * address field. When an address is marked lame for a given tuple the address
- * will not be returned to a caller.
- *
- *
- * MP:
- *
- *\li The ADB takes care of all necessary locking.
- *
- *\li Only the task which initiated the name lookup can cancel the lookup.
- *
- *
- * Security:
- *
- *\li None, since all data stored is required to be pre-filtered.
- * (Cache needs to be sane, fetches return bounds-checked and sanity-
- * checked data, caller passes a good dns_name_t for the zone, etc)
- */
-
-/***
- *** Imports
- ***/
-
-#include <isc/lang.h>
-#include <isc/magic.h>
-#include <isc/mem.h>
-#include <isc/sockaddr.h>
-
-#include <dns/types.h>
-#include <dns/view.h>
-
-ISC_LANG_BEGINDECLS
-
-/***
- *** Magic number checks
- ***/
-
-#define DNS_ADBFIND_MAGIC ISC_MAGIC('a','d','b','H')
-#define DNS_ADBFIND_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBFIND_MAGIC)
-#define DNS_ADBADDRINFO_MAGIC ISC_MAGIC('a','d','A','I')
-#define DNS_ADBADDRINFO_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBADDRINFO_MAGIC)
-
-
-/***
- *** TYPES
- ***/
-
-typedef struct dns_adbname dns_adbname_t;
-
-/*!
- *\brief
- * Represents a lookup for a single name.
- *
- * On return, the client can safely use "list", and can reorder the list.
- * Items may not be _deleted_ from this list, however, or added to it
- * other than by using the dns_adb_*() API.
- */
-struct dns_adbfind {
- /* Public */
- unsigned int magic; /*%< RO: magic */
- dns_adbaddrinfolist_t list; /*%< RO: list of addrs */
- unsigned int query_pending; /*%< RO: partial list */
- unsigned int partial_result; /*%< RO: addrs missing */
- unsigned int options; /*%< RO: options */
- isc_result_t result_v4; /*%< RO: v4 result */
- isc_result_t result_v6; /*%< RO: v6 result */
- ISC_LINK(dns_adbfind_t) publink; /*%< RW: client use */
-
- /* Private */
- isc_mutex_t lock; /* locks all below */
- in_port_t port;
- int name_bucket;
- unsigned int flags;
- dns_adbname_t *adbname;
- dns_adb_t *adb;
- isc_event_t event;
- ISC_LINK(dns_adbfind_t) plink;
-};
-
-/*
- * _INET:
- * _INET6:
- * return addresses of that type.
- *
- * _EMPTYEVENT:
- * Only schedule an event if no addresses are known.
- * Must set _WANTEVENT for this to be meaningful.
- *
- * _WANTEVENT:
- * An event is desired. Check this bit in the returned find to see
- * if one will actually be generated.
- *
- * _AVOIDFETCHES:
- * If set, fetches will not be generated unless no addresses are
- * available in any of the address families requested.
- *
- * _STARTATZONE:
- * Fetches will start using the closest zone data or use the root servers.
- * This is useful for reestablishing glue that has expired.
- *
- * _GLUEOK:
- * _HINTOK:
- * Glue or hints are ok. These are used when matching names already
- * in the adb, and when dns databases are searched.
- *
- * _RETURNLAME:
- * Return lame servers in a find, so that all addresses are returned.
- *
- * _LAMEPRUNED:
- * At least one address was omitted from the list because it was lame.
- * This bit will NEVER be set if _RETURNLAME is set in the createfind().
- */
-/*% Return addresses of type INET. */
-#define DNS_ADBFIND_INET 0x00000001
-/*% Return addresses of type INET6. */
-#define DNS_ADBFIND_INET6 0x00000002
-#define DNS_ADBFIND_ADDRESSMASK 0x00000003
-/*%
- * Only schedule an event if no addresses are known.
- * Must set _WANTEVENT for this to be meaningful.
- */
-#define DNS_ADBFIND_EMPTYEVENT 0x00000004
-/*%
- * An event is desired. Check this bit in the returned find to see
- * if one will actually be generated.
- */
-#define DNS_ADBFIND_WANTEVENT 0x00000008
-/*%
- * If set, fetches will not be generated unless no addresses are
- * available in any of the address families requested.
- */
-#define DNS_ADBFIND_AVOIDFETCHES 0x00000010
-/*%
- * Fetches will start using the closest zone data or use the root servers.
- * This is useful for reestablishing glue that has expired.
- */
-#define DNS_ADBFIND_STARTATZONE 0x00000020
-/*%
- * Glue or hints are ok. These are used when matching names already
- * in the adb, and when dns databases are searched.
- */
-#define DNS_ADBFIND_GLUEOK 0x00000040
-/*%
- * Glue or hints are ok. These are used when matching names already
- * in the adb, and when dns databases are searched.
- */
-#define DNS_ADBFIND_HINTOK 0x00000080
-/*%
- * Return lame servers in a find, so that all addresses are returned.
- */
-#define DNS_ADBFIND_RETURNLAME 0x00000100
-/*%
- * Only schedule an event if no addresses are known.
- * Must set _WANTEVENT for this to be meaningful.
- */
-#define DNS_ADBFIND_LAMEPRUNED 0x00000200
-
-/*%
- * The answers to queries come back as a list of these.
- */
-struct dns_adbaddrinfo {
- unsigned int magic; /*%< private */
-
- isc_sockaddr_t sockaddr; /*%< [rw] */
- unsigned int srtt; /*%< [rw] microseconds */
- unsigned int flags; /*%< [rw] */
- dns_adbentry_t *entry; /*%< private */
- ISC_LINK(dns_adbaddrinfo_t) publink;
-};
-
-/*!<
- * The event sent to the caller task is just a plain old isc_event_t. It
- * contains no data other than a simple status, passed in the "type" field
- * to indicate that another address resolved, or all partially resolved
- * addresses have failed to resolve.
- *
- * "sender" is the dns_adbfind_t used to issue this query.
- *
- * This is simply a standard event, with the "type" set to:
- *
- *\li #DNS_EVENT_ADBMOREADDRESSES -- another address resolved.
- *\li #DNS_EVENT_ADBNOMOREADDRESSES -- all pending addresses failed,
- * were canceled, or otherwise will
- * not be usable.
- *\li #DNS_EVENT_ADBCANCELED -- The request was canceled by a
- * 3rd party.
- *\li #DNS_EVENT_ADBNAMEDELETED -- The name was deleted, so this request
- * was canceled.
- *
- * In each of these cases, the addresses returned by the initial call
- * to dns_adb_createfind() can still be used until they are no longer needed.
- */
-
-/****
- **** FUNCTIONS
- ****/
-
-
-isc_result_t
-dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *tmgr,
- isc_taskmgr_t *taskmgr, dns_adb_t **newadb);
-/*%<
- * Create a new ADB.
- *
- * Notes:
- *
- *\li Generally, applications should not create an ADB directly, but
- * should instead call dns_view_createresolver().
- *
- * Requires:
- *
- *\li 'mem' must be a valid memory context.
- *
- *\li 'view' be a pointer to a valid view.
- *
- *\li 'tmgr' be a pointer to a valid timer manager.
- *
- *\li 'taskmgr' be a pointer to a valid task manager.
- *
- *\li 'newadb' != NULL && '*newadb' == NULL.
- *
- * Returns:
- *
- *\li #ISC_R_SUCCESS after happiness.
- *\li #ISC_R_NOMEMORY after resource allocation failure.
- */
-
-void
-dns_adb_attach(dns_adb_t *adb, dns_adb_t **adbp);
-/*%
- * Attach to an 'adb' to 'adbp'.
- *
- * Requires:
- *\li 'adb' to be a valid dns_adb_t, created via dns_adb_create().
- *\li 'adbp' to be a valid pointer to a *dns_adb_t which is initialized
- * to NULL.
- */
-
-void
-dns_adb_detach(dns_adb_t **adb);
-/*%
- * Delete the ADB. Sets *ADB to NULL. Cancels any outstanding requests.
- *
- * Requires:
- *
- *\li 'adb' be non-NULL and '*adb' be a valid dns_adb_t, created via
- * dns_adb_create().
- */
-
-void
-dns_adb_whenshutdown(dns_adb_t *adb, isc_task_t *task, isc_event_t **eventp);
-/*%
- * Send '*eventp' to 'task' when 'adb' has shutdown.
- *
- * Requires:
- *
- *\li '*adb' is a valid dns_adb_t.
- *
- *\li eventp != NULL && *eventp is a valid event.
- *
- * Ensures:
- *
- *\li *eventp == NULL
- *
- *\li The event's sender field is set to the value of adb when the event
- * is sent.
- */
-
-void
-dns_adb_shutdown(dns_adb_t *adb);
-/*%<
- * Shutdown 'adb'.
- *
- * Requires:
- *
- * \li '*adb' is a valid dns_adb_t.
- */
-
-isc_result_t
-dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
- void *arg, dns_name_t *name, dns_name_t *qname,
- dns_rdatatype_t qtype, unsigned int options,
- isc_stdtime_t now, dns_name_t *target,
- in_port_t port, dns_adbfind_t **find);
-/*%<
- * Main interface for clients. The adb will look up the name given in
- * "name" and will build up a list of found addresses, and perhaps start
- * internal fetches to resolve names that are unknown currently.
- *
- * If other addresses resolve after this call completes, an event will
- * be sent to the <task, taskaction, arg> with the sender of that event
- * set to a pointer to the dns_adbfind_t returned by this function.
- *
- * If no events will be generated, the *find->result_v4 and/or result_v6
- * members may be examined for address lookup status. The usual #ISC_R_SUCCESS,
- * #ISC_R_FAILURE, #DNS_R_NXDOMAIN, and #DNS_R_NXRRSET are returned, along with
- * #ISC_R_NOTFOUND meaning the ADB has not _yet_ found the values. In this
- * latter case, retrying may produce more addresses.
- *
- * If events will be returned, the result_v[46] members are only valid
- * when that event is actually returned.
- *
- * The list of addresses returned is unordered. The caller must impose
- * any ordering required. The list will not contain "known bad" addresses,
- * however. For instance, it will not return hosts that are known to be
- * lame for the zone in question.
- *
- * The caller cannot (directly) modify the contents of the address list's
- * fields other than the "link" field. All values can be read at any
- * time, however.
- *
- * The "now" parameter is used only for determining which entries that
- * have a specific time to live or expire time should be removed from
- * the running database. If specified as zero, the current time will
- * be retrieved and used.
- *
- * If 'target' is not NULL and 'name' is an alias (i.e. the name is
- * CNAME'd or DNAME'd to another name), then 'target' will be updated with
- * the domain name that 'name' is aliased to.
- *
- * All addresses returned will have the sockaddr's port set to 'port.'
- * The caller may change them directly in the dns_adbaddrinfo_t since
- * they are copies of the internal address only.
- *
- * XXXMLG Document options, especially the flags which control how
- * events are sent.
- *
- * Requires:
- *
- *\li *adb be a valid isc_adb_t object.
- *
- *\li If events are to be sent, *task be a valid task,
- * and isc_taskaction_t != NULL.
- *
- *\li *name is a valid dns_name_t.
- *
- *\li qname != NULL and *qname be a valid dns_name_t.
- *
- *\li target == NULL or target is a valid name with a buffer.
- *
- *\li find != NULL && *find == NULL.
- *
- * Returns:
- *
- *\li #ISC_R_SUCCESS Addresses might have been returned, and events will be
- * delivered for unresolved addresses.
- *\li #ISC_R_NOMORE Addresses might have been returned, but no events
- * will ever be posted for this context. This is only
- * returned if task != NULL.
- *\li #ISC_R_NOMEMORY insufficient resources
- *\li #DNS_R_ALIAS 'name' is an alias for another name.
- *
- * Calls, and returns error codes from:
- *
- *\li isc_stdtime_get()
- *
- * Notes:
- *
- *\li No internal reference to "name" exists after this function
- * returns.
- */
-
-void
-dns_adb_cancelfind(dns_adbfind_t *find);
-/*%<
- * Cancels the find, and sends the event off to the caller.
- *
- * It is an error to call dns_adb_cancelfind() on a find where
- * no event is wanted, or will ever be sent.
- *
- * Note:
- *
- *\li It is possible that the real completion event was posted just
- * before the dns_adb_cancelfind() call was made. In this case,
- * dns_adb_cancelfind() will do nothing. The event callback needs
- * to be prepared to find this situation (i.e. result is valid but
- * the caller expects it to be canceled).
- *
- * Requires:
- *
- *\li 'find' be a valid dns_adbfind_t pointer.
- *
- *\li events would have been posted to the task. This can be checked
- * with (find->options & DNS_ADBFIND_WANTEVENT).
- *
- * Ensures:
- *
- *\li The event was posted to the task.
- */
-
-void
-dns_adb_destroyfind(dns_adbfind_t **find);
-/*%<
- * Destroys the find reference.
- *
- * Note:
- *
- *\li This can only be called after the event was delivered for a
- * find. Additionally, the event MUST have been freed via
- * isc_event_free() BEFORE this function is called.
- *
- * Requires:
- *
- *\li 'find' != NULL and *find be valid dns_adbfind_t pointer.
- *
- * Ensures:
- *
- *\li No "address found" events will be posted to the originating task
- * after this function returns.
- */
-
-void
-dns_adb_dump(dns_adb_t *adb, FILE *f);
-/*%<
- * This function is only used for debugging. It will dump as much of the
- * state of the running system as possible.
- *
- * Requires:
- *
- *\li adb be valid.
- *
- *\li f != NULL, and is a file open for writing.
- */
-
-void
-dns_adb_dumpfind(dns_adbfind_t *find, FILE *f);
-/*%<
- * This function is only used for debugging. Dump the data associated
- * with a find.
- *
- * Requires:
- *
- *\li find is valid.
- *
- * \li f != NULL, and is a file open for writing.
- */
-
-isc_result_t
-dns_adb_marklame(dns_adb_t *adb, dns_adbaddrinfo_t *addr, dns_name_t *qname,
- dns_rdatatype_t type, isc_stdtime_t expire_time);
-/*%<
- * Mark the given address as lame for the <qname,qtype>. expire_time should
- * be set to the time when the entry should expire. That is, if it is to
- * expire 10 minutes in the future, it should set it to (now + 10 * 60).
- *
- * Requires:
- *
- *\li adb be valid.
- *
- *\li addr be valid.
- *
- *\li qname be the qname used in the dns_adb_createfind() call.
- *
- * Returns:
- *
- *\li #ISC_R_SUCCESS -- all is well.
- *\li #ISC_R_NOMEMORY -- could not mark address as lame.
- */
-
-/*
- * A reasonable default for RTT adjustments
- */
-#define DNS_ADB_RTTADJDEFAULT 7 /*%< default scale */
-#define DNS_ADB_RTTADJREPLACE 0 /*%< replace with our rtt */
-#define DNS_ADB_RTTADJAGE 10 /*%< age this rtt */
-
-void
-dns_adb_adjustsrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
- unsigned int rtt, unsigned int factor);
-/*%<
- * Mix the round trip time into the existing smoothed rtt.
-
- * The formula used
- * (where srtt is the existing rtt value, and rtt and factor are arguments to
- * this function):
- *
- *\code
- * new_srtt = (old_srtt / 10 * factor) + (rtt / 10 * (10 - factor));
- *\endcode
- *
- * XXXRTH Do we want to publish the formula? What if we want to change how
- * this works later on? Recommend/require that the units are
- * microseconds?
- *
- * Requires:
- *
- *\li adb be valid.
- *
- *\li addr be valid.
- *
- *\li 0 <= factor <= 10
- *
- * Note:
- *
- *\li The srtt in addr will be updated to reflect the new global
- * srtt value. This may include changes made by others.
- */
-
-void
-dns_adb_changeflags(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
- unsigned int bits, unsigned int mask);
-/*%
- * Change Flags.
- *
- * Set the flags as given by:
- *
- *\li newflags = (oldflags & ~mask) | (bits & mask);
- *
- * Requires:
- *
- *\li adb be valid.
- *
- *\li addr be valid.
- */
-
-isc_result_t
-dns_adb_findaddrinfo(dns_adb_t *adb, isc_sockaddr_t *sa,
- dns_adbaddrinfo_t **addrp, isc_stdtime_t now);
-/*%<
- * Return a dns_adbaddrinfo_t that is associated with address 'sa'.
- *
- * Requires:
- *
- *\li adb is valid.
- *
- *\li sa is valid.
- *
- *\li addrp != NULL && *addrp == NULL
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMEMORY
- *\li #ISC_R_SHUTTINGDOWN
- */
-
-void
-dns_adb_freeaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **addrp);
-/*%<
- * Free a dns_adbaddrinfo_t allocated by dns_adb_findaddrinfo().
- *
- * Requires:
- *
- *\li adb is valid.
- *
- *\li *addrp is a valid dns_adbaddrinfo_t *.
- */
-
-void
-dns_adb_flush(dns_adb_t *adb);
-/*%<
- * Flushes all cached data from the adb.
- *
- * Requires:
- *\li adb is valid.
- */
-
-void
-dns_adb_setadbsize(dns_adb_t *adb, size_t size);
-/*%<
- * Set a target memory size. If memory usage exceeds the target
- * size entries will be removed before they would have expired on
- * a random basis.
- *
- * If 'size' is 0 then memory usage is unlimited.
- *
- * Requires:
- *\li 'adb' is valid.
- */
-
-void
-dns_adb_flushname(dns_adb_t *adb, dns_name_t *name);
-/*%<
- * Flush 'name' from the adb cache.
- *
- * Requires:
- *\li 'adb' is valid.
- *\li 'name' is valid.
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_ADB_H */
diff --git a/contrib/bind9/lib/dns/include/dns/bit.h b/contrib/bind9/lib/dns/include/dns/bit.h
deleted file mode 100644
index 28c733d486d9..000000000000
--- a/contrib/bind9/lib/dns/include/dns/bit.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2000, 2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: bit.h,v 1.14 2007/06/19 23:47:16 tbox Exp $ */
-
-#ifndef DNS_BIT_H
-#define DNS_BIT_H 1
-
-/*! \file dns/bit.h */
-
-#include <isc/int.h>
-#include <isc/boolean.h>
-
-typedef isc_uint64_t dns_bitset_t;
-
-#define DNS_BIT_SET(bit, bitset) \
- (*(bitset) |= ((dns_bitset_t)1 << (bit)))
-#define DNS_BIT_CLEAR(bit, bitset) \
- (*(bitset) &= ~((dns_bitset_t)1 << (bit)))
-#define DNS_BIT_CHECK(bit, bitset) \
- ISC_TF((*(bitset) & ((dns_bitset_t)1 << (bit))) \
- == ((dns_bitset_t)1 << (bit)))
-
-#endif /* DNS_BIT_H */
-
diff --git a/contrib/bind9/lib/dns/include/dns/byaddr.h b/contrib/bind9/lib/dns/include/dns/byaddr.h
deleted file mode 100644
index edf843083af5..000000000000
--- a/contrib/bind9/lib/dns/include/dns/byaddr.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2000-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: byaddr.h,v 1.22 2007/06/19 23:47:16 tbox Exp $ */
-
-#ifndef DNS_BYADDR_H
-#define DNS_BYADDR_H 1
-
-/*****
- ***** Module Info
- *****/
-
-/*! \file dns/byaddr.h
- * \brief
- * The byaddr module provides reverse lookup services for IPv4 and IPv6
- * addresses.
- *
- * MP:
- *\li The module ensures appropriate synchronization of data structures it
- * creates and manipulates.
- *
- * Reliability:
- *\li No anticipated impact.
- *
- * Resources:
- *\li TBS
- *
- * Security:
- *\li No anticipated impact.
- *
- * Standards:
- *\li RFCs: 1034, 1035, 2181, TBS
- *\li Drafts: TBS
- */
-
-#include <isc/lang.h>
-#include <isc/event.h>
-
-#include <dns/types.h>
-
-ISC_LANG_BEGINDECLS
-
-/*%
- * A 'dns_byaddrevent_t' is returned when a byaddr completes.
- * The sender field will be set to the byaddr that completed. If 'result'
- * is ISC_R_SUCCESS, then 'names' will contain a list of names associated
- * with the address. The recipient of the event must not change the list
- * and must not refer to any of the name data after the event is freed.
- */
-typedef struct dns_byaddrevent {
- ISC_EVENT_COMMON(struct dns_byaddrevent);
- isc_result_t result;
- dns_namelist_t names;
-} dns_byaddrevent_t;
-
-/*
- * This option is deprecated since we now only consider nibbles.
-#define DNS_BYADDROPT_IPV6NIBBLE 0x0001
- */
-/*% Note DNS_BYADDROPT_IPV6NIBBLE is now deprecated. */
-#define DNS_BYADDROPT_IPV6INT 0x0002
-
-isc_result_t
-dns_byaddr_create(isc_mem_t *mctx, isc_netaddr_t *address, dns_view_t *view,
- unsigned int options, isc_task_t *task,
- isc_taskaction_t action, void *arg, dns_byaddr_t **byaddrp);
-/*%<
- * Find the domain name of 'address'.
- *
- * Notes:
- *
- *\li There is a reverse lookup format for IPv6 addresses, 'nibble'
- *
- *\li The 'nibble' format for that address is
- *
- * \code
- * 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.e.f.ip6.arpa.
- * \endcode
- *
- *\li #DNS_BYADDROPT_IPV6INT can be used to get nibble lookups under ip6.int.
- *
- * Requires:
- *
- *\li 'mctx' is a valid mctx.
- *
- *\li 'address' is a valid IPv4 or IPv6 address.
- *
- *\li 'view' is a valid view which has a resolver.
- *
- *\li 'task' is a valid task.
- *
- *\li byaddrp != NULL && *byaddrp == NULL
- *
- * Returns:
- *
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMEMORY
- *
- *\li Any resolver-related error (e.g. #ISC_R_SHUTTINGDOWN) may also be
- * returned.
- */
-
-void
-dns_byaddr_cancel(dns_byaddr_t *byaddr);
-/*%<
- * Cancel 'byaddr'.
- *
- * Notes:
- *
- *\li If 'byaddr' has not completed, post its #DNS_EVENT_BYADDRDONE
- * event with a result code of #ISC_R_CANCELED.
- *
- * Requires:
- *
- *\li 'byaddr' is a valid byaddr.
- */
-
-void
-dns_byaddr_destroy(dns_byaddr_t **byaddrp);
-/*%<
- * Destroy 'byaddr'.
- *
- * Requires:
- *
- *\li '*byaddrp' is a valid byaddr.
- *
- *\li The caller has received the #DNS_EVENT_BYADDRDONE event (either because
- * the byaddr completed or because dns_byaddr_cancel() was called).
- *
- * Ensures:
- *
- *\li *byaddrp == NULL.
- */
-
-isc_result_t
-dns_byaddr_createptrname(isc_netaddr_t *address, isc_boolean_t nibble,
- dns_name_t *name);
-
-isc_result_t
-dns_byaddr_createptrname2(isc_netaddr_t *address, unsigned int options,
- dns_name_t *name);
-/*%<
- * Creates a name that would be used in a PTR query for this address. The
- * nibble flag indicates that the 'nibble' format is to be used if an IPv6
- * address is provided, instead of the 'bitstring' format. Since we dropped
- * the support of the bitstring labels, it is expected that the flag is always
- * set. 'options' are the same as for dns_byaddr_create().
- *
- * Requires:
- *
- * \li 'address' is a valid address.
- * \li 'name' is a valid name with a dedicated buffer.
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_BYADDR_H */
diff --git a/contrib/bind9/lib/dns/include/dns/cache.h b/contrib/bind9/lib/dns/include/dns/cache.h
deleted file mode 100644
index f7140aa7c6ce..000000000000
--- a/contrib/bind9/lib/dns/include/dns/cache.h
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * Copyright (C) 2004-2007, 2009, 2011, 2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: cache.h,v 1.32 2011/08/02 23:47:52 tbox Exp $ */
-
-#ifndef DNS_CACHE_H
-#define DNS_CACHE_H 1
-
-/*****
- ***** Module Info
- *****/
-
-/*! \file dns/cache.h
- * \brief
- * Defines dns_cache_t, the cache object.
- *
- * Notes:
- *\li A cache object contains DNS data of a single class.
- * Multiple classes will be handled by creating multiple
- * views, each with a different class and its own cache.
- *
- * MP:
- *\li See notes at the individual functions.
- *
- * Reliability:
- *
- * Resources:
- *
- * Security:
- *
- * Standards:
- */
-
-/***
- *** Imports
- ***/
-
-#include <isc/lang.h>
-#include <isc/stdtime.h>
-
-#include <dns/types.h>
-
-ISC_LANG_BEGINDECLS
-
-/***
- *** Functions
- ***/
-
-isc_result_t
-dns_cache_create(isc_mem_t *cmctx, 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 *cmctx, 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
-dns_cache_create3(isc_mem_t *cmctx, isc_mem_t *hmctx, 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.
- *
- * dns_cache_create2() will create a named cache.
- *
- * dns_cache_create3() will create a named cache using two separate memory
- * contexts, one for cache data which can be cleaned and a separate one for
- * memory allocated for the heap (which can grow without an upper limit and
- * has no mechanism for shrinking).
- *
- * dns_cache_create() is a backward compatible version that internally
- * specifies an empty cache name and a single memory context.
- *
- * Requires:
- *
- *\li 'cmctx' (and 'hmctx' if applicable) is a valid memory context.
- *
- *\li 'taskmgr' is a valid task manager and 'timermgr' is a valid timer
- * 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:
- *
- *\li '*cachep' is attached to the newly created cache
- *
- * Returns:
- *
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMEMORY
- */
-
-void
-dns_cache_attach(dns_cache_t *cache, dns_cache_t **targetp);
-/*%<
- * Attach *targetp to cache.
- *
- * Requires:
- *
- *\li 'cache' is a valid cache.
- *
- *\li 'targetp' points to a NULL dns_cache_t *.
- *
- * Ensures:
- *
- *\li *targetp is attached to cache.
- */
-
-void
-dns_cache_detach(dns_cache_t **cachep);
-/*%<
- * Detach *cachep from its cache.
- *
- * Requires:
- *
- *\li 'cachep' points to a valid cache.
- *
- * Ensures:
- *
- *\li *cachep is NULL.
- *
- *\li If '*cachep' is the last reference to the cache,
- * all resources used by the cache will be freed
- */
-
-void
-dns_cache_attachdb(dns_cache_t *cache, dns_db_t **dbp);
-/*%<
- * Attach *dbp to the cache's database.
- *
- * Notes:
- *
- *\li This may be used to get a reference to the database for
- * the purpose of cache lookups (XXX currently it is also
- * the way to add data to the cache, but having a
- * separate dns_cache_add() interface instead would allow
- * more control over memory usage).
- * The caller should call dns_db_detach() on the reference
- * when it is no longer needed.
- *
- * Requires:
- *
- *\li 'cache' is a valid cache.
- *
- *\li 'dbp' points to a NULL dns_db *.
- *
- * Ensures:
- *
- *\li *dbp is attached to the database.
- */
-
-
-isc_result_t
-dns_cache_setfilename(dns_cache_t *cache, const char *filename);
-/*%<
- * If 'filename' is non-NULL, make the cache persistent.
- * The cache's data will be stored in the given file.
- * If 'filename' is NULL, make the cache non-persistent.
- * Files that are no longer used are not unlinked automatically.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMEMORY
- *\li Various file-related failures
- */
-
-isc_result_t
-dns_cache_load(dns_cache_t *cache);
-/*%<
- * If the cache has a file name, load the cache contents from the file.
- * Previous cache contents are not discarded.
- * If no file name has been set, do nothing and return success.
- *
- * MT:
- *\li Multiple simultaneous attempts to load or dump the cache
- * will be serialized with respect to one another, but
- * the cache may be read and updated while the dump is
- * in progress. Updates performed during loading
- * may or may not be preserved, and reads may return
- * either the old or the newly loaded data.
- *
- * Returns:
- *
- *\li #ISC_R_SUCCESS
- * \li Various failures depending on the database implementation type
- */
-
-isc_result_t
-dns_cache_dump(dns_cache_t *cache);
-/*%<
- * If the cache has a file name, write the cache contents to disk,
- * overwriting any preexisting file. If no file name has been set,
- * do nothing and return success.
- *
- * MT:
- *\li Multiple simultaneous attempts to load or dump the cache
- * will be serialized with respect to one another, but
- * the cache may be read and updated while the dump is
- * in progress. Updates performed during the dump may
- * or may not be reflected in the dumped file.
- *
- * Returns:
- *
- *\li #ISC_R_SUCCESS
- * \li Various failures depending on the database implementation type
- */
-
-isc_result_t
-dns_cache_clean(dns_cache_t *cache, isc_stdtime_t now);
-/*%<
- * Force immediate cleaning of the cache, freeing all rdatasets
- * whose TTL has expired as of 'now' and that have no pending
- * references.
- */
-
-void
-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.
- */
-
-const char *
-dns_cache_getname(dns_cache_t *cache);
-/*%<
- * Get the cache name.
- */
-
-void
-dns_cache_setcachesize(dns_cache_t *cache, size_t size);
-/*%<
- * Set the maximum cache size. 0 means unlimited.
- */
-
-size_t
-dns_cache_getcachesize(dns_cache_t *cache);
-/*%<
- * Get the maximum cache size.
- */
-
-isc_result_t
-dns_cache_flush(dns_cache_t *cache);
-/*%<
- * Flushes all data from the cache.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMEMORY
- */
-
-isc_result_t
-dns_cache_flushnode(dns_cache_t *cache, dns_name_t *name,
- isc_boolean_t tree);
-/*
- * Flush a given name from the cache. If 'tree' is true, then
- * also flush all names under 'name'.
- *
- * Requires:
- *\li 'cache' to be valid.
- *\li 'name' to be valid.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMEMORY
- *\li other error returns.
- */
-
-isc_result_t
-dns_cache_flushname(dns_cache_t *cache, dns_name_t *name);
-/*
- * Flush a given name from the cache. Equivalent to
- * dns_cache_flushpartial(cache, name, ISC_FALSE).
- *
- * Requires:
- *\li 'cache' to be valid.
- *\li 'name' to be valid.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMEMORY
- *\li other error returns.
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_CACHE_H */
diff --git a/contrib/bind9/lib/dns/include/dns/callbacks.h b/contrib/bind9/lib/dns/include/dns/callbacks.h
deleted file mode 100644
index 5e9cb717f81e..000000000000
--- a/contrib/bind9/lib/dns/include/dns/callbacks.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2004-2007, 2011 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2002 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: callbacks.h,v 1.26 2011/12/09 23:47:05 tbox Exp $ */
-
-#ifndef DNS_CALLBACKS_H
-#define DNS_CALLBACKS_H 1
-
-/*! \file dns/callbacks.h */
-
-/***
- *** Imports
- ***/
-
-#include <isc/lang.h>
-
-#include <dns/types.h>
-
-ISC_LANG_BEGINDECLS
-
-/***
- *** Types
- ***/
-
-struct dns_rdatacallbacks {
- /*%
- * dns_load_master calls this when it has rdatasets to commit.
- */
- dns_addrdatasetfunc_t add;
-
- /*%
- * dns_master_load*() call this when loading a raw zonefile,
- * to pass back information obtained from the file header
- */
- dns_rawdatafunc_t rawdata;
- dns_zone_t *zone;
-
- /*%
- * dns_load_master / dns_rdata_fromtext call this to issue a error.
- */
- void (*error)(struct dns_rdatacallbacks *, const char *, ...);
- /*%
- * dns_load_master / dns_rdata_fromtext call this to issue a warning.
- */
- void (*warn)(struct dns_rdatacallbacks *, const char *, ...);
- /*%
- * Private data handles for use by the above callback functions.
- */
- void *add_private;
- void *error_private;
- void *warn_private;
-};
-
-/***
- *** Initialization
- ***/
-
-void
-dns_rdatacallbacks_init(dns_rdatacallbacks_t *callbacks);
-/*%<
- * Initialize 'callbacks'.
- *
- *
- * \li 'error' and 'warn' are set to default callbacks that print the
- * error message through the DNS library log context.
- *
- *\li All other elements are initialized to NULL.
- *
- * Requires:
- * \li 'callbacks' is a valid dns_rdatacallbacks_t,
- */
-
-void
-dns_rdatacallbacks_init_stdio(dns_rdatacallbacks_t *callbacks);
-/*%<
- * Like dns_rdatacallbacks_init, but logs to stdio.
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_CALLBACKS_H */
diff --git a/contrib/bind9/lib/dns/include/dns/cert.h b/contrib/bind9/lib/dns/include/dns/cert.h
deleted file mode 100644
index 1cda84875c38..000000000000
--- a/contrib/bind9/lib/dns/include/dns/cert.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: cert.h,v 1.19 2007/06/19 23:47:16 tbox Exp $ */
-
-#ifndef DNS_CERT_H
-#define DNS_CERT_H 1
-
-/*! \file dns/cert.h */
-
-#include <isc/lang.h>
-
-#include <dns/types.h>
-
-ISC_LANG_BEGINDECLS
-
-isc_result_t
-dns_cert_fromtext(dns_cert_t *certp, isc_textregion_t *source);
-/*%<
- * Convert the text 'source' refers to into a certificate type.
- * The text may contain either a mnemonic type name or a decimal type number.
- *
- * Requires:
- *\li 'certp' is a valid pointer.
- *
- *\li 'source' is a valid text region.
- *
- * Returns:
- *\li #ISC_R_SUCCESS on success
- *\li #ISC_R_RANGE numeric type is out of range
- *\li #DNS_R_UNKNOWN mnemonic type is unknown
- */
-
-isc_result_t
-dns_cert_totext(dns_cert_t cert, isc_buffer_t *target);
-/*%<
- * Put a textual representation of certificate type 'cert' into 'target'.
- *
- * Requires:
- *\li 'cert' is a valid cert.
- *
- *\li 'target' is a valid text buffer.
- *
- * Ensures:
- *\li If the result is success:
- * The used space in 'target' is updated.
- *
- * Returns:
- *\li #ISC_R_SUCCESS on success
- *\li #ISC_R_NOSPACE target buffer is too small
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_CERT_H */
diff --git a/contrib/bind9/lib/dns/include/dns/client.h b/contrib/bind9/lib/dns/include/dns/client.h
deleted file mode 100644
index d21dff788dde..000000000000
--- a/contrib/bind9/lib/dns/include/dns/client.h
+++ /dev/null
@@ -1,621 +0,0 @@
-/*
- * 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/contrib/bind9/lib/dns/include/dns/clientinfo.h b/contrib/bind9/lib/dns/include/dns/clientinfo.h
deleted file mode 100644
index 4f2b89cda43e..000000000000
--- a/contrib/bind9/lib/dns/include/dns/clientinfo.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * 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: clientinfo.h,v 1.3 2011/10/11 23:46:45 tbox Exp $ */
-
-#ifndef DNS_CLIENTINFO_H
-#define DNS_CLIENTINFO_H 1
-
-/*****
- ***** Module Info
- *****/
-
-/*! \file dns/clientinfo.h
- * \brief
- * The DNS clientinfo interface allows libdns to retrieve information
- * about the client from the caller.
- *
- * The clientinfo interface is used by the DNS DB and DLZ interfaces;
- * it allows databases to modify their answers on the basis of information
- * about the client, such as source IP address.
- *
- * dns_clientinfo_t contains a pointer to an opaque structure containing
- * client information in some form. dns_clientinfomethods_t contains a
- * list of methods which operate on that opaque structure to return
- * potentially useful data. Both structures also contain versioning
- * information.
- */
-
-/*****
- ***** Imports
- *****/
-
-#include <isc/sockaddr.h>
-#include <isc/types.h>
-
-ISC_LANG_BEGINDECLS
-
-/*****
- ***** Types
- *****/
-
-#define DNS_CLIENTINFO_VERSION 1
-typedef struct dns_clientinfo {
- isc_uint16_t version;
- void *data;
-} dns_clientinfo_t;
-
-typedef isc_result_t (*dns_clientinfo_sourceip_t)(dns_clientinfo_t *client,
- isc_sockaddr_t **addrp);
-
-#define DNS_CLIENTINFOMETHODS_VERSION 1
-#define DNS_CLIENTINFOMETHODS_AGE 0
-
-typedef struct dns_clientinfomethods {
- isc_uint16_t version;
- isc_uint16_t age;
- dns_clientinfo_sourceip_t sourceip;
-} dns_clientinfomethods_t;
-
-/*****
- ***** Methods
- *****/
-void
-dns_clientinfomethods_init(dns_clientinfomethods_t *methods,
- dns_clientinfo_sourceip_t sourceip);
-
-void
-dns_clientinfo_init(dns_clientinfo_t *ci, void *data);
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_CLIENTINFO_H */
diff --git a/contrib/bind9/lib/dns/include/dns/compress.h b/contrib/bind9/lib/dns/include/dns/compress.h
deleted file mode 100644
index a10f4d3930f0..000000000000
--- a/contrib/bind9/lib/dns/include/dns/compress.h
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: compress.h,v 1.42 2009/01/17 23:47:43 tbox Exp $ */
-
-#ifndef DNS_COMPRESS_H
-#define DNS_COMPRESS_H 1
-
-#include <isc/lang.h>
-#include <isc/region.h>
-
-#include <dns/types.h>
-
-ISC_LANG_BEGINDECLS
-
-#define DNS_COMPRESS_NONE 0x00 /*%< no compression */
-#define DNS_COMPRESS_GLOBAL14 0x01 /*%< "normal" compression. */
-#define DNS_COMPRESS_ALL 0x01 /*%< all compression. */
-#define DNS_COMPRESS_CASESENSITIVE 0x02 /*%< case sensitive compression. */
-
-/*! \file dns/compress.h
- * Direct manipulation of the structures is strongly discouraged.
- */
-
-#define DNS_COMPRESS_TABLESIZE 64
-#define DNS_COMPRESS_INITIALNODES 16
-
-typedef struct dns_compressnode dns_compressnode_t;
-
-struct dns_compressnode {
- isc_region_t r;
- isc_uint16_t offset;
- isc_uint16_t count;
- isc_uint8_t labels;
- dns_compressnode_t *next;
-};
-
-struct dns_compress {
- unsigned int magic; /*%< Magic number. */
- unsigned int allowed; /*%< Allowed methods. */
- int edns; /*%< Edns version or -1. */
- /*% Global compression table. */
- dns_compressnode_t *table[DNS_COMPRESS_TABLESIZE];
- /*% Preallocated nodes for the table. */
- dns_compressnode_t initialnodes[DNS_COMPRESS_INITIALNODES];
- isc_uint16_t count; /*%< Number of nodes. */
- isc_mem_t *mctx; /*%< Memory context. */
-};
-
-typedef enum {
- DNS_DECOMPRESS_ANY, /*%< Any compression */
- DNS_DECOMPRESS_STRICT, /*%< Allowed compression */
- DNS_DECOMPRESS_NONE /*%< No compression */
-} dns_decompresstype_t;
-
-struct dns_decompress {
- unsigned int magic; /*%< Magic number. */
- unsigned int allowed; /*%< Allowed methods. */
- int edns; /*%< Edns version or -1. */
- dns_decompresstype_t type; /*%< Strict checking */
-};
-
-isc_result_t
-dns_compress_init(dns_compress_t *cctx, int edns, isc_mem_t *mctx);
-/*%<
- * Initialise the compression context structure pointed to by 'cctx'.
- *
- * Requires:
- * \li 'cctx' is a valid dns_compress_t structure.
- * \li 'mctx' is an initialized memory context.
- * Ensures:
- * \li cctx->global is initialized.
- *
- * Returns:
- * \li #ISC_R_SUCCESS
- * \li failures from dns_rbt_create()
- */
-
-void
-dns_compress_invalidate(dns_compress_t *cctx);
-
-/*%<
- * Invalidate the compression structure pointed to by cctx.
- *
- * Requires:
- *\li 'cctx' to be initialized.
- */
-
-void
-dns_compress_setmethods(dns_compress_t *cctx, unsigned int allowed);
-
-/*%<
- * Sets allowed compression methods.
- *
- * Requires:
- *\li 'cctx' to be initialized.
- */
-
-unsigned int
-dns_compress_getmethods(dns_compress_t *cctx);
-
-/*%<
- * Gets allowed compression methods.
- *
- * Requires:
- *\li 'cctx' to be initialized.
- *
- * Returns:
- *\li allowed compression bitmap.
- */
-
-void
-dns_compress_setsensitive(dns_compress_t *cctx, isc_boolean_t sensitive);
-
-/*
- * Preserve the case of compressed domain names.
- *
- * Requires:
- * 'cctx' to be initialized.
- */
-
-isc_boolean_t
-dns_compress_getsensitive(dns_compress_t *cctx);
-/*
- * Return whether case is to be preserved when compressing
- * domain names.
- *
- * Requires:
- * 'cctx' to be initialized.
- */
-
-int
-dns_compress_getedns(dns_compress_t *cctx);
-
-/*%<
- * Gets edns value.
- *
- * Requires:
- *\li 'cctx' to be initialized.
- *
- * Returns:
- *\li -1 .. 255
- */
-
-isc_boolean_t
-dns_compress_findglobal(dns_compress_t *cctx, const dns_name_t *name,
- dns_name_t *prefix, isc_uint16_t *offset);
-/*%<
- * Finds longest possible match of 'name' in the global compression table.
- *
- * Requires:
- *\li 'cctx' to be initialized.
- *\li 'name' to be a absolute name.
- *\li 'prefix' to be initialized.
- *\li 'offset' to point to an isc_uint16_t.
- *
- * Ensures:
- *\li 'prefix' and 'offset' are valid if ISC_TRUE is returned.
- *
- * Returns:
- *\li #ISC_TRUE / #ISC_FALSE
- */
-
-void
-dns_compress_add(dns_compress_t *cctx, const dns_name_t *name,
- const dns_name_t *prefix, isc_uint16_t offset);
-/*%<
- * Add compression pointers for 'name' to the compression table,
- * not replacing existing pointers.
- *
- * Requires:
- *\li 'cctx' initialized
- *
- *\li 'name' must be initialized and absolute, and must remain
- * valid until the message compression is complete.
- *
- *\li 'prefix' must be a prefix returned by
- * dns_compress_findglobal(), or the same as 'name'.
- */
-
-void
-dns_compress_rollback(dns_compress_t *cctx, isc_uint16_t offset);
-
-/*%<
- * Remove any compression pointers from global table >= offset.
- *
- * Requires:
- *\li 'cctx' is initialized.
- */
-
-void
-dns_decompress_init(dns_decompress_t *dctx, int edns,
- dns_decompresstype_t type);
-
-/*%<
- * Initializes 'dctx'.
- * Records 'edns' and 'type' into the structure.
- *
- * Requires:
- *\li 'dctx' to be a valid pointer.
- */
-
-void
-dns_decompress_invalidate(dns_decompress_t *dctx);
-
-/*%<
- * Invalidates 'dctx'.
- *
- * Requires:
- *\li 'dctx' to be initialized
- */
-
-void
-dns_decompress_setmethods(dns_decompress_t *dctx, unsigned int allowed);
-
-/*%<
- * Sets 'dctx->allowed' to 'allowed'.
- *
- * Requires:
- *\li 'dctx' to be initialized
- */
-
-unsigned int
-dns_decompress_getmethods(dns_decompress_t *dctx);
-
-/*%<
- * Returns 'dctx->allowed'
- *
- * Requires:
- *\li 'dctx' to be initialized
- */
-
-int
-dns_decompress_edns(dns_decompress_t *dctx);
-
-/*%<
- * Returns 'dctx->edns'
- *
- * Requires:
- *\li 'dctx' to be initialized
- */
-
-dns_decompresstype_t
-dns_decompress_type(dns_decompress_t *dctx);
-
-/*%<
- * Returns 'dctx->type'
- *
- * Requires:
- *\li 'dctx' to be initialized
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_COMPRESS_H */
diff --git a/contrib/bind9/lib/dns/include/dns/db.h b/contrib/bind9/lib/dns/include/dns/db.h
deleted file mode 100644
index 66bc3e3481e1..000000000000
--- a/contrib/bind9/lib/dns/include/dns/db.h
+++ /dev/null
@@ -1,1573 +0,0 @@
-/*
- * Copyright (C) 2004-2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: db.h,v 1.107.4.1 2011/10/23 20:12:08 vjs Exp $ */
-
-#ifndef DNS_DB_H
-#define DNS_DB_H 1
-
-/*****
- ***** Module Info
- *****/
-
-/*! \file dns/db.h
- * \brief
- * The DNS DB interface allows named rdatasets to be stored and retrieved.
- *
- * The dns_db_t type is like a "virtual class". To actually use
- * DBs, an implementation of the class is required.
- *
- * XXX more XXX
- *
- * MP:
- * \li The module ensures appropriate synchronization of data structures it
- * creates and manipulates.
- *
- * Reliability:
- * \li No anticipated impact.
- *
- * Resources:
- * \li TBS
- *
- * Security:
- * \li No anticipated impact.
- *
- * Standards:
- * \li None.
- */
-
-/*****
- ***** Imports
- *****/
-
-#include <isc/lang.h>
-#include <isc/magic.h>
-#include <isc/ondestroy.h>
-#include <isc/stdtime.h>
-
-#include <dns/clientinfo.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
-
-/*****
- ***** Types
- *****/
-
-typedef struct dns_dbmethods {
- void (*attach)(dns_db_t *source, dns_db_t **targetp);
- void (*detach)(dns_db_t **dbp);
- isc_result_t (*beginload)(dns_db_t *db, dns_addrdatasetfunc_t *addp,
- dns_dbload_t **dbloadp);
- isc_result_t (*endload)(dns_db_t *db, dns_dbload_t **dbloadp);
- isc_result_t (*dump)(dns_db_t *db, dns_dbversion_t *version,
- const char *filename,
- dns_masterformat_t masterformat);
- void (*currentversion)(dns_db_t *db,
- dns_dbversion_t **versionp);
- isc_result_t (*newversion)(dns_db_t *db,
- dns_dbversion_t **versionp);
- void (*attachversion)(dns_db_t *db, dns_dbversion_t *source,
- dns_dbversion_t **targetp);
- void (*closeversion)(dns_db_t *db,
- dns_dbversion_t **versionp,
- isc_boolean_t commit);
- isc_result_t (*findnode)(dns_db_t *db, dns_name_t *name,
- isc_boolean_t create,
- dns_dbnode_t **nodep);
- 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);
- 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);
- void (*attachnode)(dns_db_t *db,
- dns_dbnode_t *source,
- dns_dbnode_t **targetp);
- void (*detachnode)(dns_db_t *db,
- dns_dbnode_t **targetp);
- isc_result_t (*expirenode)(dns_db_t *db, dns_dbnode_t *node,
- isc_stdtime_t now);
- void (*printnode)(dns_db_t *db, dns_dbnode_t *node,
- FILE *out);
- isc_result_t (*createiterator)(dns_db_t *db, unsigned int options,
- dns_dbiterator_t **iteratorp);
- isc_result_t (*findrdataset)(dns_db_t *db, dns_dbnode_t *node,
- dns_dbversion_t *version,
- dns_rdatatype_t type,
- dns_rdatatype_t covers,
- isc_stdtime_t now,
- dns_rdataset_t *rdataset,
- dns_rdataset_t *sigrdataset);
- isc_result_t (*allrdatasets)(dns_db_t *db, dns_dbnode_t *node,
- dns_dbversion_t *version,
- isc_stdtime_t now,
- dns_rdatasetiter_t **iteratorp);
- 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);
- 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);
- isc_result_t (*deleterdataset)(dns_db_t *db, dns_dbnode_t *node,
- dns_dbversion_t *version,
- dns_rdatatype_t type,
- dns_rdatatype_t covers);
- isc_boolean_t (*issecure)(dns_db_t *db);
- unsigned int (*nodecount)(dns_db_t *db);
- isc_boolean_t (*ispersistent)(dns_db_t *db);
- void (*overmem)(dns_db_t *db, isc_boolean_t overmem);
- void (*settask)(dns_db_t *db, isc_task_t *);
- isc_result_t (*getoriginnode)(dns_db_t *db, dns_dbnode_t **nodep);
- void (*transfernode)(dns_db_t *db, dns_dbnode_t **sourcep,
- dns_dbnode_t **targetp);
- isc_result_t (*getnsec3parameters)(dns_db_t *db,
- dns_dbversion_t *version,
- dns_hash_t *hash,
- isc_uint8_t *flags,
- isc_uint16_t *iterations,
- unsigned char *salt,
- size_t *salt_len);
- isc_result_t (*findnsec3node)(dns_db_t *db, dns_name_t *name,
- isc_boolean_t create,
- dns_dbnode_t **nodep);
- isc_result_t (*setsigningtime)(dns_db_t *db,
- dns_rdataset_t *rdataset,
- isc_stdtime_t resign);
- isc_result_t (*getsigningtime)(dns_db_t *db,
- dns_rdataset_t *rdataset,
- dns_name_t *name);
- void (*resigned)(dns_db_t *db, dns_rdataset_t *rdataset,
- dns_dbversion_t *version);
- isc_boolean_t (*isdnssec)(dns_db_t *db);
- dns_stats_t *(*getrrsetstats)(dns_db_t *db);
- isc_result_t (*rpz_enabled)(dns_db_t *db, dns_rpz_st_t *st);
- void (*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_name_t *query_qname);
- isc_result_t (*findnodeext)(dns_db_t *db, dns_name_t *name,
- isc_boolean_t create,
- dns_clientinfomethods_t *methods,
- dns_clientinfo_t *clientinfo,
- dns_dbnode_t **nodep);
- isc_result_t (*findext)(dns_db_t *db, dns_name_t *name,
- dns_dbversion_t *version,
- dns_rdatatype_t type, unsigned int options,
- isc_stdtime_t now,
- dns_dbnode_t **nodep, dns_name_t *foundname,
- dns_clientinfomethods_t *methods,
- dns_clientinfo_t *clientinfo,
- dns_rdataset_t *rdataset,
- dns_rdataset_t *sigrdataset);
-} dns_dbmethods_t;
-
-typedef isc_result_t
-(*dns_dbcreatefunc_t)(isc_mem_t *mctx, dns_name_t *name,
- dns_dbtype_t type, dns_rdataclass_t rdclass,
- unsigned int argc, char *argv[], void *driverarg,
- dns_db_t **dbp);
-
-#define DNS_DB_MAGIC ISC_MAGIC('D','N','S','D')
-#define DNS_DB_VALID(db) ISC_MAGIC_VALID(db, DNS_DB_MAGIC)
-
-/*%
- * This structure is actually just the common prefix of a DNS db
- * implementation's version of a dns_db_t.
- * \brief
- * Direct use of this structure by clients is forbidden. DB implementations
- * may change the structure. 'magic' must be DNS_DB_MAGIC for any of the
- * dns_db_ routines to work. DB implementations must maintain all DB
- * invariants.
- */
-struct dns_db {
- unsigned int magic;
- unsigned int impmagic;
- dns_dbmethods_t * methods;
- isc_uint16_t attributes;
- dns_rdataclass_t rdclass;
- dns_name_t origin;
- isc_ondestroy_t ondest;
- isc_mem_t * mctx;
-};
-
-#define DNS_DBATTR_CACHE 0x01
-#define DNS_DBATTR_STUB 0x02
-
-/*@{*/
-/*%
- * Options that can be specified for dns_db_find().
- */
-#define DNS_DBFIND_GLUEOK 0x0001
-#define DNS_DBFIND_VALIDATEGLUE 0x0002
-#define DNS_DBFIND_NOWILD 0x0004
-#define DNS_DBFIND_PENDINGOK 0x0008
-#define DNS_DBFIND_NOEXACT 0x0010
-#define DNS_DBFIND_FORCENSEC 0x0020
-#define DNS_DBFIND_COVERINGNSEC 0x0040
-#define DNS_DBFIND_FORCENSEC3 0x0080
-#define DNS_DBFIND_ADDITIONALOK 0x0100
-/*@}*/
-
-/*@{*/
-/*%
- * Options that can be specified for dns_db_addrdataset().
- */
-#define DNS_DBADD_MERGE 0x01
-#define DNS_DBADD_FORCE 0x02
-#define DNS_DBADD_EXACT 0x04
-#define DNS_DBADD_EXACTTTL 0x08
-/*@}*/
-
-/*%
- * Options that can be specified for dns_db_subtractrdataset().
- */
-#define DNS_DBSUB_EXACT 0x01
-
-/*@{*/
-/*%
- * Iterator options
- */
-#define DNS_DB_RELATIVENAMES 0x1
-#define DNS_DB_NSEC3ONLY 0x2
-#define DNS_DB_NONSEC3 0x4
-/*@}*/
-
-/*****
- ***** Methods
- *****/
-
-/***
- *** Basic DB Methods
- ***/
-
-isc_result_t
-dns_db_create(isc_mem_t *mctx, const char *db_type, dns_name_t *origin,
- dns_dbtype_t type, dns_rdataclass_t rdclass,
- unsigned int argc, char *argv[], dns_db_t **dbp);
-/*%<
- * Create a new database using implementation 'db_type'.
- *
- * Notes:
- * \li All names in the database must be subdomains of 'origin' and in class
- * 'rdclass'. The database makes its own copy of the origin, so the
- * caller may do whatever they like with 'origin' and its storage once the
- * call returns.
- *
- * \li DB implementation-specific parameters are passed using argc and argv.
- *
- * Requires:
- *
- * \li dbp != NULL and *dbp == NULL
- *
- * \li 'origin' is a valid absolute domain name.
- *
- * \li mctx is a valid memory context
- *
- * Ensures:
- *
- * \li A copy of 'origin' has been made for the databases use, and the
- * caller is free to do whatever they want with the name and storage
- * associated with 'origin'.
- *
- * Returns:
- *
- * \li #ISC_R_SUCCESS
- * \li #ISC_R_NOMEMORY
- * \li #ISC_R_NOTFOUND db_type not found
- *
- * \li Many other errors are possible, depending on what db_type was
- * specified.
- */
-
-void
-dns_db_attach(dns_db_t *source, dns_db_t **targetp);
-/*%<
- * Attach *targetp to source.
- *
- * Requires:
- *
- * \li 'source' is a valid database.
- *
- * \li 'targetp' points to a NULL dns_db_t *.
- *
- * Ensures:
- *
- * \li *targetp is attached to source.
- */
-
-void
-dns_db_detach(dns_db_t **dbp);
-/*%<
- * Detach *dbp from its database.
- *
- * Requires:
- *
- * \li 'dbp' points to a valid database.
- *
- * Ensures:
- *
- * \li *dbp is NULL.
- *
- * \li If '*dbp' is the last reference to the database,
- * all resources used by the database will be freed
- */
-
-isc_result_t
-dns_db_ondestroy(dns_db_t *db, isc_task_t *task, isc_event_t **eventp);
-/*%<
- * Causes 'eventp' to be sent to be sent to 'task' when the database is
- * destroyed.
- *
- * Note; ownership of the eventp is taken from the caller (and *eventp is
- * set to NULL). The sender field of the event is set to 'db' before it is
- * sent to the task.
- */
-
-isc_boolean_t
-dns_db_iscache(dns_db_t *db);
-/*%<
- * Does 'db' have cache semantics?
- *
- * Requires:
- *
- * \li 'db' is a valid database.
- *
- * Returns:
- * \li #ISC_TRUE 'db' has cache semantics
- * \li #ISC_FALSE otherwise
- */
-
-isc_boolean_t
-dns_db_iszone(dns_db_t *db);
-/*%<
- * Does 'db' have zone semantics?
- *
- * Requires:
- *
- * \li 'db' is a valid database.
- *
- * Returns:
- * \li #ISC_TRUE 'db' has zone semantics
- * \li #ISC_FALSE otherwise
- */
-
-isc_boolean_t
-dns_db_isstub(dns_db_t *db);
-/*%<
- * Does 'db' have stub semantics?
- *
- * Requires:
- *
- * \li 'db' is a valid database.
- *
- * Returns:
- * \li #ISC_TRUE 'db' has zone semantics
- * \li #ISC_FALSE otherwise
- */
-
-isc_boolean_t
-dns_db_issecure(dns_db_t *db);
-/*%<
- * Is 'db' secure?
- *
- * Requires:
- *
- * \li 'db' is a valid database with zone semantics.
- *
- * Returns:
- * \li #ISC_TRUE 'db' is secure.
- * \li #ISC_FALSE 'db' is not secure.
- */
-
-isc_boolean_t
-dns_db_isdnssec(dns_db_t *db);
-/*%<
- * Is 'db' secure or partially secure?
- *
- * Requires:
- *
- * \li 'db' is a valid database with zone semantics.
- *
- * Returns:
- * \li #ISC_TRUE 'db' is secure or is partially.
- * \li #ISC_FALSE 'db' is not secure.
- */
-
-dns_name_t *
-dns_db_origin(dns_db_t *db);
-/*%<
- * The origin of the database.
- *
- * Note: caller must not try to change this name.
- *
- * Requires:
- *
- * \li 'db' is a valid database.
- *
- * Returns:
- *
- * \li The origin of the database.
- */
-
-dns_rdataclass_t
-dns_db_class(dns_db_t *db);
-/*%<
- * The class of the database.
- *
- * Requires:
- *
- * \li 'db' is a valid database.
- *
- * Returns:
- *
- * \li The class of the database.
- */
-
-isc_result_t
-dns_db_beginload(dns_db_t *db, dns_addrdatasetfunc_t *addp,
- dns_dbload_t **dbloadp);
-/*%<
- * Begin loading 'db'.
- *
- * Requires:
- *
- * \li 'db' is a valid database.
- *
- * \li This is the first attempt to load 'db'.
- *
- * \li addp != NULL && *addp == NULL
- *
- * \li dbloadp != NULL && *dbloadp == NULL
- *
- * Ensures:
- *
- * \li On success, *addp will be a valid dns_addrdatasetfunc_t suitable
- * for loading 'db'. *dbloadp will be a valid DB load context which
- * should be used as 'arg' when *addp is called.
- *
- * Returns:
- *
- * \li #ISC_R_SUCCESS
- * \li #ISC_R_NOMEMORY
- *
- * \li Other results are possible, depending upon the database
- * implementation used, syntax errors in the master file, etc.
- */
-
-isc_result_t
-dns_db_endload(dns_db_t *db, dns_dbload_t **dbloadp);
-/*%<
- * Finish loading 'db'.
- *
- * Requires:
- *
- * \li 'db' is a valid database that is being loaded.
- *
- * \li dbloadp != NULL and *dbloadp is a valid database load context.
- *
- * Ensures:
- *
- * \li *dbloadp == NULL
- *
- * Returns:
- *
- * \li #ISC_R_SUCCESS
- * \li #ISC_R_NOMEMORY
- *
- * \li Other results are possible, depending upon the database
- * implementation used, syntax errors in the master file, etc.
- */
-
-isc_result_t
-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'.
- *
- * Notes:
- * \li This routine is equivalent to calling
- *
- *\code
- * dns_db_beginload();
- * dns_master_loadfile();
- * dns_db_endload();
- *\endcode
- *
- * Requires:
- *
- * \li 'db' is a valid database.
- *
- * \li This is the first attempt to load 'db'.
- *
- * Returns:
- *
- * \li #ISC_R_SUCCESS
- * \li #ISC_R_NOMEMORY
- *
- * \li Other results are possible, depending upon the database
- * implementation used, syntax errors in the master file, etc.
- */
-
-isc_result_t
-dns_db_dump(dns_db_t *db, dns_dbversion_t *version, const char *filename);
-
-isc_result_t
-dns_db_dump2(dns_db_t *db, dns_dbversion_t *version, const char *filename,
- dns_masterformat_t masterformat);
-/*%<
- * Dump version 'version' of 'db' to master file 'filename'.
- *
- * Requires:
- *
- * \li 'db' is a valid database.
- *
- * \li 'version' is a valid version.
- *
- * Returns:
- *
- * \li #ISC_R_SUCCESS
- * \li #ISC_R_NOMEMORY
- *
- * \li Other results are possible, depending upon the database
- * implementation used, OS file errors, etc.
- */
-
-/***
- *** Version Methods
- ***/
-
-void
-dns_db_currentversion(dns_db_t *db, dns_dbversion_t **versionp);
-/*%<
- * Open the current version for reading.
- *
- * Requires:
- *
- * \li 'db' is a valid database with zone semantics.
- *
- * \li versionp != NULL && *verisonp == NULL
- *
- * Ensures:
- *
- * \li On success, '*versionp' is attached to the current version.
- *
- */
-
-isc_result_t
-dns_db_newversion(dns_db_t *db, dns_dbversion_t **versionp);
-/*%<
- * Open a new version for reading and writing.
- *
- * Requires:
- *
- * \li 'db' is a valid database with zone semantics.
- *
- * \li versionp != NULL && *verisonp == NULL
- *
- * Ensures:
- *
- * \li On success, '*versionp' is attached to the current version.
- *
- * Returns:
- *
- * \li #ISC_R_SUCCESS
- * \li #ISC_R_NOMEMORY
- *
- * \li Other results are possible, depending upon the database
- * implementation used.
- */
-
-void
-dns_db_attachversion(dns_db_t *db, dns_dbversion_t *source,
- dns_dbversion_t **targetp);
-/*%<
- * Attach '*targetp' to 'source'.
- *
- * Requires:
- *
- * \li 'db' is a valid database with zone semantics.
- *
- * \li source is a valid open version
- *
- * \li targetp != NULL && *targetp == NULL
- *
- * Ensures:
- *
- * \li '*targetp' is attached to source.
- */
-
-void
-dns_db_closeversion(dns_db_t *db, dns_dbversion_t **versionp,
- isc_boolean_t commit);
-/*%<
- * Close version '*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 of 'commit' is ignored for read-only
- * versions.
- *
- * Requires:
- *
- * \li 'db' is a valid database with zone semantics.
- *
- * \li '*versionp' refers to a valid version.
- *
- * \li If committing a writable version, then there must be no other
- * outstanding references to the version (e.g. an active rdataset
- * iterator).
- *
- * Ensures:
- *
- * \li *versionp == NULL
- *
- * \li If *versionp is a read-write version, and commit is ISC_TRUE, then
- * the version will become the current version. If !commit, then all
- * changes made in the version will be undone, and the version will
- * not become the current version.
- */
-
-/***
- *** Node Methods
- ***/
-
-isc_result_t
-dns_db_findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
- dns_dbnode_t **nodep);
-
-isc_result_t
-dns_db_findnodeext(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
- dns_clientinfomethods_t *methods,
- dns_clientinfo_t *clientinfo, dns_dbnode_t **nodep);
-/*%<
- * Find the node with name 'name'.
- *
- * dns_db_findnodeext() (findnode extended) also accepts parameters
- * 'methods' and 'clientinfo', which, when provided, enable the database to
- * retreive information about the client from the caller, and modify its
- * response on the basis of that information.
- *
- * Notes:
- * \li If 'create' is ISC_TRUE and no node with name 'name' exists, then
- * such a node will be created.
- *
- * \li This routine is for finding or creating a node with the specified
- * name. There are no partial matches. It is not suitable for use
- * in building responses to ordinary DNS queries; clients which wish
- * to do that should use dns_db_find() instead.
- *
- * Requires:
- *
- * \li 'db' is a valid database.
- *
- * \li 'name' is a valid, non-empty, absolute name.
- *
- * \li nodep != NULL && *nodep == NULL
- *
- * Ensures:
- *
- * \li On success, *nodep is attached to the node with name 'name'.
- *
- * Returns:
- *
- * \li #ISC_R_SUCCESS
- * \li #ISC_R_NOTFOUND If !create and name not found.
- * \li #ISC_R_NOMEMORY Can only happen if create is ISC_TRUE.
- *
- * \li Other results are possible, depending upon the database
- * implementation used.
- */
-
-isc_result_t
-dns_db_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);
-
-isc_result_t
-dns_db_findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
- dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
- dns_dbnode_t **nodep, dns_name_t *foundname,
- dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo,
- dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset);
-/*%<
- * Find the best match for 'name' and 'type' in version 'version' of 'db'.
- *
- * dns_db_findext() (find extended) also accepts parameters 'methods'
- * and 'clientinfo', which when provided enable the database to retreive
- * information about the client from the caller, and modify its response
- * on the basis of this information.
- *
- * Notes:
- *
- * \li If type == dns_rdataset_any, then rdataset will not be bound.
- *
- * \li If 'options' does not have #DNS_DBFIND_GLUEOK set, then no glue will
- * be returned. For zone databases, glue is as defined in RFC2181.
- * For cache databases, glue is any rdataset with a trust of
- * dns_trust_glue.
- *
- * \li If 'options' does not have #DNS_DBFIND_ADDITIONALOK set, then no
- * additional records will be returned. Only caches can have
- * rdataset with trust dns_trust_additional.
- *
- * \li If 'options' does not have #DNS_DBFIND_PENDINGOK set, then no
- * pending data will be returned. This option is only meaningful for
- * cache databases.
- *
- * \li If the #DNS_DBFIND_NOWILD option is set, then wildcard matching will
- * be disabled. This option is only meaningful for zone databases.
- *
- * \li If the #DNS_DBFIND_FORCENSEC option is set, the database is assumed to
- * have NSEC records, and these will be returned when appropriate. This
- * is only necessary when querying a database that was not secure
- * when created.
- *
- * \li If the DNS_DBFIND_COVERINGNSEC option is set, then look for a
- * NSEC record that potentially covers 'name' if a answer cannot
- * be found. Note the returned NSEC needs to be checked to ensure
- * that it is correct. This only affects answers returned from the
- * cache.
- *
- * \li In the #DNS_DBFIND_FORCENSEC3 option is set, then we are looking
- * in the NSEC3 tree and not the main tree. Without this option being
- * set NSEC3 records will not be found.
- *
- * \li To respond to a query for SIG records, the caller should create a
- * rdataset iterator and extract the signatures from each rdataset.
- *
- * \li Making queries of type ANY with #DNS_DBFIND_GLUEOK is not recommended,
- * because the burden of determining whether a given rdataset is valid
- * glue or not falls upon the caller.
- *
- * \li The 'now' field is ignored if 'db' is a zone database. If 'db' is a
- * cache database, an rdataset will not be found unless it expires after
- * 'now'. Any ANY query will not match unless at least one rdataset at
- * the node expires after 'now'. If 'now' is zero, then the current time
- * will be used.
- *
- * Requires:
- *
- * \li 'db' is a valid database.
- *
- * \li 'type' is not SIG, or a meta-RR type other than 'ANY' (e.g. 'OPT').
- *
- * \li 'nodep' is NULL, or nodep is a valid pointer and *nodep == NULL.
- *
- * \li 'foundname' is a valid name with a dedicated buffer.
- *
- * \li 'rdataset' is NULL, or is a valid unassociated rdataset.
- *
- * Ensures,
- * on a non-error completion:
- *
- * \li If nodep != NULL, then it is bound to the found node.
- *
- * \li If foundname != NULL, then it contains the full name of the
- * found node.
- *
- * \li If rdataset != NULL and type != dns_rdatatype_any, then
- * rdataset is bound to the found rdataset.
- *
- * Non-error results are:
- *
- * \li #ISC_R_SUCCESS The desired node and type were
- * found.
- *
- * \li #DNS_R_WILDCARD The desired node and type were
- * found after performing
- * wildcard matching. This is
- * only returned if the
- * #DNS_DBFIND_INDICATEWILD
- * option is set; otherwise
- * #ISC_R_SUCCESS is returned.
- *
- * \li #DNS_R_GLUE The desired node and type were
- * found, but are glue. This
- * result can only occur if
- * the DNS_DBFIND_GLUEOK option
- * is set. This result can only
- * occur if 'db' is a zone
- * database. If type ==
- * dns_rdatatype_any, then the
- * node returned may contain, or
- * consist entirely of invalid
- * glue (i.e. data occluded by a
- * zone cut). The caller must
- * take care not to return invalid
- * glue to a client.
- *
- * \li #DNS_R_DELEGATION The data requested is beneath
- * a zone cut. node, foundname,
- * and rdataset reference the
- * NS RRset of the zone cut.
- * If 'db' is a cache database,
- * then this is the deepest known
- * delegation.
- *
- * \li #DNS_R_ZONECUT type == dns_rdatatype_any, and
- * the desired node is a zonecut.
- * The caller must take care not
- * to return inappropriate glue
- * to a client. This result can
- * only occur if 'db' is a zone
- * database and DNS_DBFIND_GLUEOK
- * is set.
- *
- * \li #DNS_R_DNAME The data requested is beneath
- * a DNAME. node, foundname,
- * and rdataset reference the
- * DNAME RRset.
- *
- * \li #DNS_R_CNAME The rdataset requested was not
- * found, but there is a CNAME
- * at the desired name. node,
- * foundname, and rdataset
- * reference the CNAME RRset.
- *
- * \li #DNS_R_NXDOMAIN The desired name does not
- * exist.
- *
- * \li #DNS_R_NXRRSET The desired name exists, but
- * the desired type does not.
- *
- * \li #ISC_R_NOTFOUND The desired name does not
- * exist, and no delegation could
- * be found. This result can only
- * occur if 'db' is a cache
- * database. The caller should
- * use its nameserver(s) of last
- * resort (e.g. root hints).
- *
- * \li #DNS_R_NCACHENXDOMAIN The desired name does not
- * exist. 'node' is bound to the
- * cache node with the desired
- * name, and 'rdataset' contains
- * the negative caching proof.
- *
- * \li #DNS_R_NCACHENXRRSET The desired type does not
- * exist. 'node' is bound to the
- * cache node with the desired
- * name, and 'rdataset' contains
- * the negative caching proof.
- *
- * \li #DNS_R_EMPTYNAME The name exists but there is
- * no data at the name.
- *
- * \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
- *
- * \li #DNS_R_BADDB Data that is required to be
- * present in the DB, e.g. an NSEC
- * record in a secure zone, is not
- * present.
- *
- * \li Other results are possible, and should all be treated as
- * errors.
- */
-
-isc_result_t
-dns_db_findzonecut(dns_db_t *db, dns_name_t *name,
- unsigned int options, isc_stdtime_t now,
- dns_dbnode_t **nodep, dns_name_t *foundname,
- dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset);
-/*%<
- * Find the deepest known zonecut which encloses 'name' in 'db'.
- *
- * Notes:
- *
- * \li If the #DNS_DBFIND_NOEXACT option is set, then the zonecut returned
- * (if any) will be the deepest known ancestor of 'name'.
- *
- * \li If 'now' is zero, then the current time will be used.
- *
- * Requires:
- *
- * \li 'db' is a valid database with cache semantics.
- *
- * \li 'nodep' is NULL, or nodep is a valid pointer and *nodep == NULL.
- *
- * \li 'foundname' is a valid name with a dedicated buffer.
- *
- * \li 'rdataset' is NULL, or is a valid unassociated rdataset.
- *
- * Ensures, on a non-error completion:
- *
- * \li If nodep != NULL, then it is bound to the found node.
- *
- * \li If foundname != NULL, then it contains the full name of the
- * found node.
- *
- * \li If rdataset != NULL and type != dns_rdatatype_any, then
- * rdataset is bound to the found rdataset.
- *
- * Non-error results are:
- *
- * \li #ISC_R_SUCCESS
- *
- * \li #ISC_R_NOTFOUND
- *
- * \li Other results are possible, and should all be treated as
- * errors.
- */
-
-void
-dns_db_attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp);
-/*%<
- * Attach *targetp to source.
- *
- * Requires:
- *
- * \li 'db' is a valid database.
- *
- * \li 'source' is a valid node.
- *
- * \li 'targetp' points to a NULL dns_dbnode_t *.
- *
- * Ensures:
- *
- * \li *targetp is attached to source.
- */
-
-void
-dns_db_detachnode(dns_db_t *db, dns_dbnode_t **nodep);
-/*%<
- * Detach *nodep from its node.
- *
- * Requires:
- *
- * \li 'db' is a valid database.
- *
- * \li 'nodep' points to a valid node.
- *
- * Ensures:
- *
- * \li *nodep is NULL.
- */
-
-void
-dns_db_transfernode(dns_db_t *db, dns_dbnode_t **sourcep,
- dns_dbnode_t **targetp);
-/*%<
- * Transfer a node between pointer.
- *
- * This is equivalent to calling dns_db_attachnode() then dns_db_detachnode().
- *
- * Requires:
- *
- * \li 'db' is a valid database.
- *
- * \li '*sourcep' is a valid node.
- *
- * \li 'targetp' points to a NULL dns_dbnode_t *.
- *
- * Ensures:
- *
- * \li '*sourcep' is NULL.
- */
-
-isc_result_t
-dns_db_expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now);
-/*%<
- * Mark as stale all records at 'node' which expire at or before 'now'.
- *
- * Note: if 'now' is zero, then the current time will be used.
- *
- * Requires:
- *
- * \li 'db' is a valid cache database.
- *
- * \li 'node' is a valid node.
- */
-
-void
-dns_db_printnode(dns_db_t *db, dns_dbnode_t *node, FILE *out);
-/*%<
- * Print a textual representation of the contents of the node to
- * 'out'.
- *
- * Note: this function is intended for debugging, not general use.
- *
- * Requires:
- *
- * \li 'db' is a valid database.
- *
- * \li 'node' is a valid node.
- */
-
-/***
- *** DB Iterator Creation
- ***/
-
-isc_result_t
-dns_db_createiterator(dns_db_t *db, unsigned int options,
- dns_dbiterator_t **iteratorp);
-/*%<
- * Create an iterator for version 'version' of 'db'.
- *
- * Notes:
- *
- * \li One or more of the following options can be set.
- * #DNS_DB_RELATIVENAMES
- * #DNS_DB_NSEC3ONLY
- * #DNS_DB_NONSEC3
- *
- * Requires:
- *
- * \li 'db' is a valid database.
- *
- * \li iteratorp != NULL && *iteratorp == NULL
- *
- * Ensures:
- *
- * \li On success, *iteratorp will be a valid database iterator.
- *
- * Returns:
- *
- * \li #ISC_R_SUCCESS
- * \li #ISC_R_NOMEMORY
- */
-
-/***
- *** Rdataset Methods
- ***/
-
-/*
- * XXXRTH Should we check for glue and pending data in dns_db_findrdataset()?
- */
-
-isc_result_t
-dns_db_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
- dns_rdatatype_t type, dns_rdatatype_t covers,
- isc_stdtime_t now, dns_rdataset_t *rdataset,
- dns_rdataset_t *sigrdataset);
-
-/*%<
- * Search for an rdataset of type 'type' at 'node' that are in version
- * 'version' of 'db'. If found, make 'rdataset' refer to it.
- *
- * Notes:
- *
- * \li If 'version' is NULL, then the current version will be used.
- *
- * \li Care must be used when using this routine to build a DNS response:
- * 'node' should have been found with dns_db_find(), not
- * dns_db_findnode(). No glue checking is done. No checking for
- * pending data is done.
- *
- * \li The 'now' field is ignored if 'db' is a zone database. If 'db' is a
- * cache database, an rdataset will not be found unless it expires after
- * 'now'. If 'now' is zero, then the current time will be used.
- *
- * Requires:
- *
- * \li 'db' is a valid database.
- *
- * \li 'node' is a valid node.
- *
- * \li 'rdataset' is a valid, disassociated rdataset.
- *
- * \li 'sigrdataset' is a valid, disassociated rdataset, or it is NULL.
- *
- * \li If 'covers' != 0, 'type' must be SIG.
- *
- * \li 'type' is not a meta-RR type such as 'ANY' or 'OPT'.
- *
- * Ensures:
- *
- * \li On success, 'rdataset' is associated with the found rdataset.
- *
- * Returns:
- *
- * \li #ISC_R_SUCCESS
- * \li #ISC_R_NOTFOUND
- *
- * \li Other results are possible, depending upon the database
- * implementation used.
- */
-
-isc_result_t
-dns_db_allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
- isc_stdtime_t now, dns_rdatasetiter_t **iteratorp);
-/*%<
- * Make '*iteratorp' an rdataset iterator for all rdatasets at 'node' in
- * version 'version' of 'db'.
- *
- * Notes:
- *
- * \li If 'version' is NULL, then the current version will be used.
- *
- * \li The 'now' field is ignored if 'db' is a zone database. If 'db' is a
- * cache database, an rdataset will not be found unless it expires after
- * 'now'. Any ANY query will not match unless at least one rdataset at
- * the node expires after 'now'. If 'now' is zero, then the current time
- * will be used.
- *
- * Requires:
- *
- * \li 'db' is a valid database.
- *
- * \li 'node' is a valid node.
- *
- * \li iteratorp != NULL && *iteratorp == NULL
- *
- * Ensures:
- *
- * \li On success, '*iteratorp' is a valid rdataset iterator.
- *
- * Returns:
- *
- * \li #ISC_R_SUCCESS
- * \li #ISC_R_NOTFOUND
- *
- * \li Other results are possible, depending upon the database
- * implementation used.
- */
-
-isc_result_t
-dns_db_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);
-/*%<
- * Add 'rdataset' to 'node' in version 'version' of 'db'.
- *
- * Notes:
- *
- * \li If the database has zone semantics, the #DNS_DBADD_MERGE option is set,
- * and an rdataset of the same type as 'rdataset' already exists at
- * 'node' then the contents of 'rdataset' will be merged with the existing
- * rdataset. If the option is not set, then rdataset will replace any
- * existing rdataset of the same type. If not merging and the
- * #DNS_DBADD_FORCE option is set, then the data will update the database
- * without regard to trust levels. If not forcing the data, then the
- * rdataset will only be added if its trust level is >= the trust level of
- * any existing rdataset. Forcing is only meaningful for cache databases.
- * If #DNS_DBADD_EXACT is set then there must be no rdata in common between
- * the old and new rdata sets. If #DNS_DBADD_EXACTTTL is set then both
- * the old and new rdata sets must have the same ttl.
- *
- * \li The 'now' field is ignored if 'db' is a zone database. If 'db' is
- * a cache database, then the added rdataset will expire no later than
- * now + rdataset->ttl.
- *
- * \li If 'addedrdataset' is not NULL, then it will be attached to the
- * resulting new rdataset in the database, or to the existing data if
- * the existing data was better.
- *
- * Requires:
- *
- * \li 'db' is a valid database.
- *
- * \li 'node' is a valid node.
- *
- * \li 'rdataset' is a valid, associated rdataset with the same class
- * as 'db'.
- *
- * \li 'addedrdataset' is NULL, or a valid, unassociated rdataset.
- *
- * \li The database has zone semantics and 'version' is a valid
- * read-write version, or the database has cache semantics
- * and version is NULL.
- *
- * \li If the database has cache semantics, the #DNS_DBADD_MERGE option must
- * not be set.
- *
- * Returns:
- *
- * \li #ISC_R_SUCCESS
- * \li #DNS_R_UNCHANGED The operation did not change anything.
- * \li #ISC_R_NOMEMORY
- * \li #DNS_R_NOTEXACT
- *
- * \li Other results are possible, depending upon the database
- * implementation used.
- */
-
-isc_result_t
-dns_db_subtractrdataset(dns_db_t *db, dns_dbnode_t *node,
- dns_dbversion_t *version, dns_rdataset_t *rdataset,
- unsigned int options, dns_rdataset_t *newrdataset);
-/*%<
- * Remove any rdata in 'rdataset' from 'node' in version 'version' of
- * 'db'.
- *
- * Notes:
- *
- * \li If 'newrdataset' is not NULL, then it will be attached to the
- * resulting new rdataset in the database, unless the rdataset has
- * become nonexistent. If DNS_DBSUB_EXACT is set then all elements
- * of 'rdataset' must exist at 'node'.
- *
- * Requires:
- *
- * \li 'db' is a valid database.
- *
- * \li 'node' is a valid node.
- *
- * \li 'rdataset' is a valid, associated rdataset with the same class
- * as 'db'.
- *
- * \li 'newrdataset' is NULL, or a valid, unassociated rdataset.
- *
- * \li The database has zone semantics and 'version' is a valid
- * read-write version.
- *
- * Returns:
- *
- * \li #ISC_R_SUCCESS
- * \li #DNS_R_UNCHANGED The operation did not change anything.
- * \li #DNS_R_NXRRSET All rdata of the same type as those
- * in 'rdataset' have been deleted.
- * \li #DNS_R_NOTEXACT Some part of 'rdataset' did not
- * exist and DNS_DBSUB_EXACT was set.
- *
- * \li Other results are possible, depending upon the database
- * implementation used.
- */
-
-isc_result_t
-dns_db_deleterdataset(dns_db_t *db, dns_dbnode_t *node,
- dns_dbversion_t *version, dns_rdatatype_t type,
- dns_rdatatype_t covers);
-/*%<
- * Make it so that no rdataset of type 'type' exists at 'node' in version
- * version 'version' of 'db'.
- *
- * Notes:
- *
- * \li If 'type' is dns_rdatatype_any, then no rdatasets will exist in
- * 'version' (provided that the dns_db_deleterdataset() isn't followed
- * by one or more dns_db_addrdataset() calls).
- *
- * Requires:
- *
- * \li 'db' is a valid database.
- *
- * \li 'node' is a valid node.
- *
- * \li The database has zone semantics and 'version' is a valid
- * read-write version, or the database has cache semantics
- * and version is NULL.
- *
- * \li 'type' is not a meta-RR type, except for dns_rdatatype_any, which is
- * allowed.
- *
- * \li If 'covers' != 0, 'type' must be SIG.
- *
- * Returns:
- *
- * \li #ISC_R_SUCCESS
- * \li #DNS_R_UNCHANGED No rdatasets of 'type' existed before
- * the operation was attempted.
- *
- * \li Other results are possible, depending upon the database
- * implementation used.
- */
-
-isc_result_t
-dns_db_getsoaserial(dns_db_t *db, dns_dbversion_t *ver, isc_uint32_t *serialp);
-/*%<
- * Get the current SOA serial number from a zone database.
- *
- * Requires:
- * \li 'db' is a valid database with zone semantics.
- * \li 'ver' is a valid version.
- */
-
-void
-dns_db_overmem(dns_db_t *db, isc_boolean_t overmem);
-/*%<
- * Enable / disable aggressive cache cleaning.
- */
-
-unsigned int
-dns_db_nodecount(dns_db_t *db);
-/*%<
- * Count the number of nodes in 'db'.
- *
- * Requires:
- *
- * \li 'db' is a valid database.
- *
- * Returns:
- * \li The number of nodes in the database
- */
-
-void
-dns_db_settask(dns_db_t *db, isc_task_t *task);
-/*%<
- * If task is set then the final detach maybe performed asynchronously.
- *
- * Requires:
- * \li 'db' is a valid database.
- * \li 'task' to be valid or NULL.
- */
-
-isc_boolean_t
-dns_db_ispersistent(dns_db_t *db);
-/*%<
- * Is 'db' persistent? A persistent database does not need to be loaded
- * from disk or written to disk.
- *
- * Requires:
- *
- * \li 'db' is a valid database.
- *
- * Returns:
- * \li #ISC_TRUE 'db' is persistent.
- * \li #ISC_FALSE 'db' is not persistent.
- */
-
-isc_result_t
-dns_db_register(const char *name, dns_dbcreatefunc_t create, void *driverarg,
- isc_mem_t *mctx, dns_dbimplementation_t **dbimp);
-
-/*%<
- * Register a new database implementation and add it to the list of
- * supported implementations.
- *
- * Requires:
- *
- * \li 'name' is not NULL
- * \li 'order' is a valid function pointer
- * \li 'mctx' is a valid memory context
- * \li dbimp != NULL && *dbimp == NULL
- *
- * Returns:
- * \li #ISC_R_SUCCESS The registration succeeded
- * \li #ISC_R_NOMEMORY Out of memory
- * \li #ISC_R_EXISTS A database implementation with the same name exists
- *
- * Ensures:
- *
- * \li *dbimp points to an opaque structure which must be passed to
- * dns_db_unregister().
- */
-
-void
-dns_db_unregister(dns_dbimplementation_t **dbimp);
-/*%<
- * Remove a database implementation from the list of supported
- * implementations. No databases of this type can be active when this
- * is called.
- *
- * Requires:
- * \li dbimp != NULL && *dbimp == NULL
- *
- * Ensures:
- *
- * \li Any memory allocated in *dbimp will be freed.
- */
-
-isc_result_t
-dns_db_getoriginnode(dns_db_t *db, dns_dbnode_t **nodep);
-/*%<
- * Get the origin DB node corresponding to the DB's zone. This function
- * should typically succeed unless the underlying DB implementation doesn't
- * support the feature.
- *
- * Requires:
- *
- * \li 'db' is a valid zone database.
- * \li 'nodep' != NULL && '*nodep' == NULL
- *
- * Ensures:
- * \li On success, '*nodep' will point to the DB node of the zone's origin.
- *
- * Returns:
- * \li #ISC_R_SUCCESS
- * \li #ISC_R_NOTFOUND - the DB implementation does not support this feature.
- */
-
-isc_result_t
-dns_db_getnsec3parameters(dns_db_t *db, dns_dbversion_t *version,
- dns_hash_t *hash, isc_uint8_t *flags,
- isc_uint16_t *interations,
- unsigned char *salt, size_t *salt_length);
-/*%<
- * Get the NSEC3 parameters that are associated with this zone.
- *
- * Requires:
- * \li 'db' is a valid zone database.
- *
- * Returns:
- * \li #ISC_R_SUCCESS
- * \li #ISC_R_NOTFOUND - the DB implementation does not support this feature
- * or this zone does not have NSEC3 records.
- */
-
-isc_result_t
-dns_db_findnsec3node(dns_db_t *db, dns_name_t *name,
- isc_boolean_t create, dns_dbnode_t **nodep);
-/*%<
- * Find the NSEC3 node with name 'name'.
- *
- * Notes:
- * \li If 'create' is ISC_TRUE and no node with name 'name' exists, then
- * such a node will be created.
- *
- * Requires:
- *
- * \li 'db' is a valid database.
- *
- * \li 'name' is a valid, non-empty, absolute name.
- *
- * \li nodep != NULL && *nodep == NULL
- *
- * Ensures:
- *
- * \li On success, *nodep is attached to the node with name 'name'.
- *
- * Returns:
- *
- * \li #ISC_R_SUCCESS
- * \li #ISC_R_NOTFOUND If !create and name not found.
- * \li #ISC_R_NOMEMORY Can only happen if create is ISC_TRUE.
- *
- * \li Other results are possible, depending upon the database
- * implementation used.
- */
-
-isc_result_t
-dns_db_setsigningtime(dns_db_t *db, dns_rdataset_t *rdataset,
- isc_stdtime_t resign);
-/*%<
- * Sets the re-signing time associated with 'rdataset' to 'resign'.
- *
- * Requires:
- * \li 'db' is a valid zone database.
- * \li 'rdataset' is or is to be associated with 'db'.
- * \li 'rdataset' is not pending removed from the heap via an
- * uncommitted call to dns_db_resigned().
- *
- * Returns:
- * \li #ISC_R_SUCCESS
- * \li #ISC_R_NOMEMORY
- * \li #ISC_R_NOTIMPLEMENTED - Not supported by this DB implementation.
- */
-
-isc_result_t
-dns_db_getsigningtime(dns_db_t *db, dns_rdataset_t *rdataset, dns_name_t *name);
-/*%<
- * Return the rdataset with the earliest signing time in the zone.
- * Note: the rdataset is version agnostic.
- *
- * Requires:
- * \li 'db' is a valid zone database.
- * \li 'rdataset' to be initialized but not associated.
- * \li 'name' to be NULL or have a buffer associated with it.
- *
- * Returns:
- * \li #ISC_R_SUCCESS
- * \li #ISC_R_NOTFOUND - No dataset exists.
- */
-
-void
-dns_db_resigned(dns_db_t *db, dns_rdataset_t *rdataset,
- dns_dbversion_t *version);
-/*%<
- * Mark 'rdataset' as not being available to be returned by
- * dns_db_getsigningtime(). If the changes associated with 'version'
- * are committed this will be permanent. If the version is not committed
- * this change will be rolled back when the version is closed. Until
- * 'version' is either committed or rolled back, 'rdataset' can no longer
- * be acted upon by dns_db_setsigningtime().
- *
- * Requires:
- * \li 'db' is a valid zone database.
- * \li 'rdataset' to be associated with 'db'.
- * \li 'version' to be open for writing.
- */
-
-dns_stats_t *
-dns_db_getrrsetstats(dns_db_t *db);
-/*%<
- * Get statistics information counting RRsets stored in the DB, when available.
- * The statistics may not be available depending on the DB implementation.
- *
- * Requires:
- *
- * \li 'db' is a valid database (zone or cache).
- *
- * Returns:
- * \li when available, a pointer to a statistics object created by
- * dns_rdatasetstats_create(); otherwise NULL.
- */
-
-isc_result_t
-dns_db_rpz_enabled(dns_db_t *db, dns_rpz_st_t *st);
-/*%<
- * Mark a database for response policy rewriting
- * or find which RPZ data is available.
- */
-
-void
-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,
- dns_name_t *query_qname);
-/*%<
- * 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/contrib/bind9/lib/dns/include/dns/dbiterator.h b/contrib/bind9/lib/dns/include/dns/dbiterator.h
deleted file mode 100644
index 366d6767a79f..000000000000
--- a/contrib/bind9/lib/dns/include/dns/dbiterator.h
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: dbiterator.h,v 1.25 2007/06/19 23:47:16 tbox Exp $ */
-
-#ifndef DNS_DBITERATOR_H
-#define DNS_DBITERATOR_H 1
-
-/*****
- ***** Module Info
- *****/
-
-/*! \file dns/dbiterator.h
- * \brief
- * The DNS DB Iterator interface allows iteration of all of the nodes in a
- * database.
- *
- * The dns_dbiterator_t type is like a "virtual class". To actually use
- * it, an implementation of the class is required. This implementation is
- * supplied by the database.
- *
- * It is the client's responsibility to call dns_db_detachnode() on all
- * nodes returned.
- *
- * XXX &lt;more&gt; XXX
- *
- * MP:
- *\li The iterator itself is not locked. The caller must ensure
- * synchronization.
- *
- *\li The iterator methods ensure appropriate database locking.
- *
- * Reliability:
- *\li No anticipated impact.
- *
- * Resources:
- *\li TBS
- *
- * Security:
- *\li No anticipated impact.
- *
- * Standards:
- *\li None.
- */
-
-/*****
- ***** Imports
- *****/
-
-#include <isc/lang.h>
-#include <isc/magic.h>
-
-#include <dns/types.h>
-
-ISC_LANG_BEGINDECLS
-
-/*****
- ***** Types
- *****/
-
-typedef struct dns_dbiteratormethods {
- void (*destroy)(dns_dbiterator_t **iteratorp);
- isc_result_t (*first)(dns_dbiterator_t *iterator);
- isc_result_t (*last)(dns_dbiterator_t *iterator);
- isc_result_t (*seek)(dns_dbiterator_t *iterator, dns_name_t *name);
- isc_result_t (*prev)(dns_dbiterator_t *iterator);
- isc_result_t (*next)(dns_dbiterator_t *iterator);
- isc_result_t (*current)(dns_dbiterator_t *iterator,
- dns_dbnode_t **nodep, dns_name_t *name);
- isc_result_t (*pause)(dns_dbiterator_t *iterator);
- isc_result_t (*origin)(dns_dbiterator_t *iterator,
- dns_name_t *name);
-} dns_dbiteratormethods_t;
-
-#define DNS_DBITERATOR_MAGIC ISC_MAGIC('D','N','S','I')
-#define DNS_DBITERATOR_VALID(dbi) ISC_MAGIC_VALID(dbi, DNS_DBITERATOR_MAGIC)
-/*%
- * This structure is actually just the common prefix of a DNS db
- * implementation's version of a dns_dbiterator_t.
- *
- * Clients may use the 'db' field of this structure. Except for that field,
- * direct use of this structure by clients is forbidden. DB implementations
- * may change the structure. 'magic' must be DNS_DBITERATOR_MAGIC for any of
- * the dns_dbiterator routines to work. DB iterator implementations must
- * maintain all DB iterator invariants.
- */
-struct dns_dbiterator {
- /* Unlocked. */
- unsigned int magic;
- dns_dbiteratormethods_t * methods;
- dns_db_t * db;
- isc_boolean_t relative_names;
- isc_boolean_t cleaning;
-};
-
-void
-dns_dbiterator_destroy(dns_dbiterator_t **iteratorp);
-/*%<
- * Destroy '*iteratorp'.
- *
- * Requires:
- *
- *\li '*iteratorp' is a valid iterator.
- *
- * Ensures:
- *
- *\li All resources used by the iterator are freed.
- *
- *\li *iteratorp == NULL.
- */
-
-isc_result_t
-dns_dbiterator_first(dns_dbiterator_t *iterator);
-/*%<
- * Move the node cursor to the first node in the database (if any).
- *
- * Requires:
- *\li 'iterator' is a valid iterator.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMORE There are no nodes in the database.
- *
- *\li Other results are possible, depending on the DB implementation.
- */
-
-isc_result_t
-dns_dbiterator_last(dns_dbiterator_t *iterator);
-/*%<
- * Move the node cursor to the last node in the database (if any).
- *
- * Requires:
- *\li 'iterator' is a valid iterator.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMORE There are no nodes in the database.
- *
- *\li Other results are possible, depending on the DB implementation.
- */
-
-isc_result_t
-dns_dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name);
-/*%<
- * Move the node cursor to the node with name 'name'.
- *
- * Requires:
- *\li 'iterator' is a valid iterator.
- *
- *\li 'name' is a valid name.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOTFOUND
- *
- *\li Other results are possible, depending on the DB implementation.
- */
-
-isc_result_t
-dns_dbiterator_prev(dns_dbiterator_t *iterator);
-/*%<
- * Move the node cursor to the previous node in the database (if any).
- *
- * Requires:
- *\li 'iterator' is a valid iterator.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMORE There are no more nodes in the
- * database.
- *
- *\li Other results are possible, depending on the DB implementation.
- */
-
-isc_result_t
-dns_dbiterator_next(dns_dbiterator_t *iterator);
-/*%<
- * Move the node cursor to the next node in the database (if any).
- *
- * Requires:
- *\li 'iterator' is a valid iterator.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMORE There are no more nodes in the
- * database.
- *
- *\li Other results are possible, depending on the DB implementation.
- */
-
-isc_result_t
-dns_dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep,
- dns_name_t *name);
-/*%<
- * Return the current node.
- *
- * Notes:
- *\li If 'name' is not NULL, it will be set to the name of the node.
- *
- * Requires:
- *\li 'iterator' is a valid iterator.
- *
- *\li nodep != NULL && *nodep == NULL
- *
- *\li The node cursor of 'iterator' is at a valid location (i.e. the
- * result of last call to a cursor movement command was ISC_R_SUCCESS).
- *
- *\li 'name' is NULL, or is a valid name with a dedicated buffer.
- *
- * Returns:
- *
- *\li #ISC_R_SUCCESS
- *\li #DNS_R_NEWORIGIN If this iterator was created with
- * 'relative_names' set to ISC_TRUE,
- * then #DNS_R_NEWORIGIN will be returned
- * when the origin the names are
- * relative to changes. This result
- * can occur only when 'name' is not
- * NULL. This is also a successful
- * result.
- *
- *\li Other results are possible, depending on the DB implementation.
- */
-
-isc_result_t
-dns_dbiterator_pause(dns_dbiterator_t *iterator);
-/*%<
- * Pause iteration.
- *
- * Calling a cursor movement method or dns_dbiterator_current() may cause
- * database locks to be acquired. Rather than reacquire these locks every
- * time one of these routines is called, the locks may simply be held.
- * Calling dns_dbiterator_pause() releases any such locks. Iterator clients
- * should call this routine any time they are not going to execute another
- * iterator method in the immediate future.
- *
- * Requires:
- *\li 'iterator' is a valid iterator.
- *
- * Ensures:
- *\li Any database locks being held for efficiency of iterator access are
- * released.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *
- *\li Other results are possible, depending on the DB implementation.
- */
-
-isc_result_t
-dns_dbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name);
-/*%<
- * Return the origin to which returned node names are relative.
- *
- * Requires:
- *
- *\li 'iterator' is a valid relative_names iterator.
- *
- *\li 'name' is a valid name with a dedicated buffer.
- *
- * Returns:
- *
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOSPACE
- *
- *\li Other results are possible, depending on the DB implementation.
- */
-
-void
-dns_dbiterator_setcleanmode(dns_dbiterator_t *iterator, isc_boolean_t mode);
-/*%<
- * Indicate that the given iterator is/is not cleaning the DB.
- *
- * Notes:
- *\li When 'mode' is ISC_TRUE,
- *
- * Requires:
- *\li 'iterator' is a valid iterator.
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_DBITERATOR_H */
diff --git a/contrib/bind9/lib/dns/include/dns/dbtable.h b/contrib/bind9/lib/dns/include/dns/dbtable.h
deleted file mode 100644
index 503de95107a9..000000000000
--- a/contrib/bind9/lib/dns/include/dns/dbtable.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: dbtable.h,v 1.23 2007/06/19 23:47:16 tbox Exp $ */
-
-#ifndef DNS_DBTABLE_H
-#define DNS_DBTABLE_H 1
-
-/*****
- ***** Module Info
- *****/
-
-/*! \file dns/dbtable.h
- * \brief
- * DNS DB Tables
- *
- * XXX TBS XXX
- *
- * MP:
- *\li The module ensures appropriate synchronization of data structures it
- * creates and manipulates.
- *
- * Reliability:
- *\li No anticipated impact.
- *
- * Resources:
- *\li None.
- *
- * Security:
- *\li No anticipated impact.
- *
- * Standards:
- *\li None.
- */
-
-#include <isc/lang.h>
-
-#include <dns/types.h>
-
-#define DNS_DBTABLEFIND_NOEXACT 0x01
-
-ISC_LANG_BEGINDECLS
-
-isc_result_t
-dns_dbtable_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
- dns_dbtable_t **dbtablep);
-/*%<
- * Make a new dbtable of class 'rdclass'
- *
- * Requires:
- *\li mctx != NULL
- * \li dbtablep != NULL && *dptablep == NULL
- *\li 'rdclass' is a valid class
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMEMORY
- *\li #ISC_R_UNEXPECTED
- */
-
-void
-dns_dbtable_attach(dns_dbtable_t *source, dns_dbtable_t **targetp);
-/*%<
- * Attach '*targetp' to 'source'.
- *
- * Requires:
- *
- *\li 'source' is a valid dbtable.
- *
- *\li 'targetp' points to a NULL dns_dbtable_t *.
- *
- * Ensures:
- *
- *\li *targetp is attached to source.
- */
-
-void
-dns_dbtable_detach(dns_dbtable_t **dbtablep);
-/*%<
- * Detach *dbtablep from its dbtable.
- *
- * Requires:
- *
- *\li '*dbtablep' points to a valid dbtable.
- *
- * Ensures:
- *
- *\li *dbtablep is NULL.
- *
- *\li If '*dbtablep' is the last reference to the dbtable,
- * all resources used by the dbtable will be freed
- */
-
-isc_result_t
-dns_dbtable_add(dns_dbtable_t *dbtable, dns_db_t *db);
-/*%<
- * Add 'db' to 'dbtable'.
- *
- * Requires:
- *\li 'dbtable' is a valid dbtable.
- *
- *\li 'db' is a valid database with the same class as 'dbtable'
- */
-
-void
-dns_dbtable_remove(dns_dbtable_t *dbtable, dns_db_t *db);
-/*%<
- * Remove 'db' from 'dbtable'.
- *
- * Requires:
- *\li 'db' was previously added to 'dbtable'.
- */
-
-void
-dns_dbtable_adddefault(dns_dbtable_t *dbtable, dns_db_t *db);
-/*%<
- * Use 'db' as the result of a dns_dbtable_find() if no better match is
- * available.
- */
-
-void
-dns_dbtable_getdefault(dns_dbtable_t *dbtable, dns_db_t **db);
-/*%<
- * Get the 'db' used as the result of a dns_dbtable_find()
- * if no better match is available.
- */
-
-void
-dns_dbtable_removedefault(dns_dbtable_t *dbtable);
-/*%<
- * Remove the default db from 'dbtable'.
- */
-
-isc_result_t
-dns_dbtable_find(dns_dbtable_t *dbtable, dns_name_t *name,
- unsigned int options, dns_db_t **dbp);
-/*%<
- * Find the deepest match to 'name' in the dbtable, and return it
- *
- * Notes:
- *\li If the DNS_DBTABLEFIND_NOEXACT option is set, the best partial
- * match (if any) to 'name' will be returned.
- *
- * Returns:
- * \li #ISC_R_SUCCESS on success
- *\li something else: no default and match
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_DBTABLE_H */
diff --git a/contrib/bind9/lib/dns/include/dns/diff.h b/contrib/bind9/lib/dns/include/dns/diff.h
deleted file mode 100644
index d522feb6f9cf..000000000000
--- a/contrib/bind9/lib/dns/include/dns/diff.h
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * Copyright (C) 2004-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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: diff.h,v 1.19 2010/06/04 23:51:14 tbox Exp $ */
-
-#ifndef DNS_DIFF_H
-#define DNS_DIFF_H 1
-
-/*****
- ***** Module Info
- *****/
-
-/*! \file dns/diff.h
- * \brief
- * A diff is a convenience type representing a list of changes to be
- * made to a database.
- */
-
-/***
- *** Imports
- ***/
-
-#include <isc/lang.h>
-#include <isc/magic.h>
-
-#include <dns/name.h>
-#include <dns/rdata.h>
-#include <dns/types.h>
-
-/***
- *** Types
- ***/
-
-/*%
- * A dns_difftuple_t represents a single RR being added or deleted.
- * The RR type and class are in the 'rdata' member; the class is always
- * the real one, not a DynDNS meta-class, so that the rdatas can be
- * compared using dns_rdata_compare(). The TTL is significant
- * even for deletions, because a deletion/addition pair cannot
- * be canceled out if the TTL differs (it might be an explicit
- * TTL update).
- *
- * Tuples are also used to represent complete RRs with owner
- * names for a couple of other purposes, such as the
- * individual RRs of a "RRset exists (value dependent)"
- * prerequisite set. In this case, op==DNS_DIFFOP_EXISTS,
- * and the TTL is ignored.
- *
- * DNS_DIFFOP_*RESIGN will cause the 'resign' attribute of the resulting
- * RRset to be recomputed to be 'resign' seconds before the earliest RRSIG
- * timeexpire.
- */
-
-typedef enum {
- DNS_DIFFOP_ADD = 0, /*%< Add an RR. */
- DNS_DIFFOP_DEL = 1, /*%< Delete an RR. */
- DNS_DIFFOP_EXISTS = 2, /*%< Assert RR existence. */
- DNS_DIFFOP_ADDRESIGN = 4, /*%< ADD + RESIGN. */
- DNS_DIFFOP_DELRESIGN = 5 /*%< DEL + RESIGN. */
-} dns_diffop_t;
-
-typedef struct dns_difftuple dns_difftuple_t;
-
-#define DNS_DIFFTUPLE_MAGIC ISC_MAGIC('D','I','F','T')
-#define DNS_DIFFTUPLE_VALID(t) ISC_MAGIC_VALID(t, DNS_DIFFTUPLE_MAGIC)
-
-struct dns_difftuple {
- unsigned int magic;
- isc_mem_t *mctx;
- dns_diffop_t op;
- dns_name_t name;
- dns_ttl_t ttl;
- dns_rdata_t rdata;
- ISC_LINK(dns_difftuple_t) link;
- /* Variable-size name data and rdata follows. */
-};
-
-/*%
- * A dns_diff_t represents a set of changes being applied to
- * a zone. Diffs are also used to represent "RRset exists
- * (value dependent)" prerequisites.
- */
-typedef struct dns_diff dns_diff_t;
-
-#define DNS_DIFF_MAGIC ISC_MAGIC('D','I','F','F')
-#define DNS_DIFF_VALID(t) ISC_MAGIC_VALID(t, DNS_DIFF_MAGIC)
-
-struct dns_diff {
- unsigned int magic;
- isc_mem_t * mctx;
- /*
- * Set the 'resign' attribute to this many second before the
- * earliest RRSIG timeexpire.
- */
- isc_uint32_t resign;
- ISC_LIST(dns_difftuple_t) tuples;
-};
-
-/* Type of comparison function for sorting diffs. */
-typedef int dns_diff_compare_func(const void *, const void *);
-
-/***
- *** Functions
- ***/
-
-ISC_LANG_BEGINDECLS
-
-/**************************************************************************/
-/*
- * Manipulation of diffs and tuples.
- */
-
-isc_result_t
-dns_difftuple_create(isc_mem_t *mctx,
- dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
- dns_rdata_t *rdata, dns_difftuple_t **tp);
-/*%<
- * Create a tuple. Deep copies are made of the name and rdata, so
- * they need not remain valid after the call.
- *
- * Requires:
- *\li *tp != NULL && *tp == NULL.
- *
- * Returns:
- *\li ISC_R_SUCCESS
- * \li ISC_R_NOMEMORY
- */
-
-void
-dns_difftuple_free(dns_difftuple_t **tp);
-/*%<
- * Free a tuple.
- *
- * Requires:
- * \li **tp is a valid tuple.
- *
- * Ensures:
- * \li *tp == NULL
- * \li All memory used by the tuple is freed.
- */
-
-isc_result_t
-dns_difftuple_copy(dns_difftuple_t *orig, dns_difftuple_t **copyp);
-/*%<
- * Copy a tuple.
- *
- * Requires:
- * \li 'orig' points to a valid tuple
- *\li copyp != NULL && *copyp == NULL
- */
-
-void
-dns_diff_init(isc_mem_t *mctx, dns_diff_t *diff);
-/*%<
- * Initialize a diff.
- *
- * Requires:
- * \li 'diff' points to an uninitialized dns_diff_t
- * \li allocated by the caller.
- *
- * Ensures:
- * \li '*diff' is a valid, empty diff.
- */
-
-void
-dns_diff_clear(dns_diff_t *diff);
-/*%<
- * Clear a diff, destroying all its tuples.
- *
- * Requires:
- * \li 'diff' points to a valid dns_diff_t.
- *
- * Ensures:
- * \li Any tuples in the diff are destroyed.
- * The diff now empty, but it is still valid
- * and may be reused without calling dns_diff_init
- * again. The only memory used is that of the
- * dns_diff_t structure itself.
- *
- * Notes:
- * \li Managing the memory of the dns_diff_t structure itself
- * is the caller's responsibility.
- */
-
-void
-dns_diff_append(dns_diff_t *diff, dns_difftuple_t **tuple);
-/*%<
- * Append a single tuple to a diff.
- *
- *\li 'diff' is a valid diff.
- * \li '*tuple' is a valid tuple.
- *
- * Ensures:
- *\li *tuple is NULL.
- *\li The tuple has been freed, or will be freed when the diff is cleared.
- */
-
-void
-dns_diff_appendminimal(dns_diff_t *diff, dns_difftuple_t **tuple);
-/*%<
- * Append 'tuple' to 'diff', removing any duplicate
- * or conflicting updates as needed to create a minimal diff.
- *
- * Requires:
- *\li 'diff' is a minimal diff.
- *
- * Ensures:
- *\li 'diff' is still a minimal diff.
- * \li *tuple is NULL.
- * \li The tuple has been freed, or will be freed when the diff is cleared.
- *
- */
-
-isc_result_t
-dns_diff_sort(dns_diff_t *diff, dns_diff_compare_func *compare);
-/*%<
- * Sort 'diff' in-place according to the comparison function 'compare'.
- */
-
-isc_result_t
-dns_diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver);
-isc_result_t
-dns_diff_applysilently(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver);
-/*%<
- * Apply 'diff' to the database 'db'.
- *
- * dns_diff_apply() logs warnings about updates with no effect or
- * with inconsistent TTLs; dns_diff_applysilently() does not.
- *
- * For efficiency, the diff should be sorted by owner name.
- * If it is not sorted, operation will still be correct,
- * but less efficient.
- *
- * Requires:
- *\li *diff is a valid diff (possibly empty), containing
- * tuples of type #DNS_DIFFOP_ADD and/or
- * For #DNS_DIFFOP_DEL tuples, the TTL is ignored.
- *
- */
-
-isc_result_t
-dns_diff_load(dns_diff_t *diff, dns_addrdatasetfunc_t addfunc,
- void *add_private);
-/*%<
- * Like dns_diff_apply, but for use when loading a new database
- * instead of modifying an existing one. This bypasses the
- * database transaction mechanisms.
- *
- * Requires:
- *\li 'addfunc' is a valid dns_addradatasetfunc_t obtained from
- * dns_db_beginload()
- *
- *\li 'add_private' points to a corresponding dns_dbload_t *
- * (XXX why is it a void pointer, then?)
- */
-
-isc_result_t
-dns_diff_print(dns_diff_t *diff, FILE *file);
-
-/*%<
- * Print the differences to 'file' or if 'file' is NULL via the
- * logging system.
- *
- * Require:
- *\li 'diff' to be valid.
- *\li 'file' to refer to a open file or NULL.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMEMORY
- *\li #ISC_R_UNEXPECTED
- *\li any error from dns_rdataset_totext()
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_DIFF_H */
diff --git a/contrib/bind9/lib/dns/include/dns/dispatch.h b/contrib/bind9/lib/dns/include/dns/dispatch.h
deleted file mode 100644
index 1235f7ca40f3..000000000000
--- a/contrib/bind9/lib/dns/include/dns/dispatch.h
+++ /dev/null
@@ -1,563 +0,0 @@
-/*
- * Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: dispatch.h,v 1.64 2011/07/28 23:47:58 tbox Exp $ */
-
-#ifndef DNS_DISPATCH_H
-#define DNS_DISPATCH_H 1
-
-/*****
- ***** Module Info
- *****/
-
-/*! \file dns/dispatch.h
- * \brief
- * DNS Dispatch Management
- * Shared UDP and single-use TCP dispatches for queries and responses.
- *
- * MP:
- *
- *\li All locking is performed internally to each dispatch.
- * Restrictions apply to dns_dispatch_removeresponse().
- *
- * Reliability:
- *
- * Resources:
- *
- * Security:
- *
- *\li Depends on the isc_socket_t and dns_message_t for prevention of
- * buffer overruns.
- *
- * Standards:
- *
- *\li None.
- */
-
-/***
- *** Imports
- ***/
-
-#include <isc/buffer.h>
-#include <isc/lang.h>
-#include <isc/mutex.h>
-#include <isc/socket.h>
-#include <isc/types.h>
-
-#include <dns/types.h>
-
-ISC_LANG_BEGINDECLS
-
-/*%
- * This event is sent to a task when a response comes in.
- * No part of this structure should ever be modified by the caller,
- * other than parts of the buffer. The holy parts of the buffer are
- * the base and size of the buffer. All other parts of the buffer may
- * be used. On event delivery the used region contains the packet.
- *
- * "id" is the received message id,
- *
- * "addr" is the host that sent it to us,
- *
- * "buffer" holds state on the received data.
- *
- * The "free" routine for this event will clean up itself as well as
- * any buffer space allocated from common pools.
- */
-
-struct dns_dispatchevent {
- ISC_EVENT_COMMON(dns_dispatchevent_t); /*%< standard event common */
- isc_result_t result; /*%< result code */
- isc_int32_t id; /*%< message id */
- isc_sockaddr_t addr; /*%< address recv'd from */
- struct in6_pktinfo pktinfo; /*%< reply info for v6 */
- isc_buffer_t buffer; /*%< data buffer */
- isc_uint32_t attributes; /*%< mirrored from socket.h */
-};
-
-/*%
- * This is a set of one or more dispatches which can be retrieved
- * round-robin fashion.
- */
-struct dns_dispatchset {
- isc_mem_t *mctx;
- dns_dispatch_t **dispatches;
- int ndisp;
- int cur;
- isc_mutex_t lock;
-};
-
-/*@{*/
-/*%
- * Attributes for added dispatchers.
- *
- * Values with the mask 0xffff0000 are application defined.
- * Values with the mask 0x0000ffff are library defined.
- *
- * Insane values (like setting both TCP and UDP) are not caught. Don't
- * do that.
- *
- * _PRIVATE
- * The dispatcher cannot be shared.
- *
- * _TCP, _UDP
- * The dispatcher is a TCP or UDP socket.
- *
- * _IPV4, _IPV6
- * The dispatcher uses an IPv4 or IPv6 socket.
- *
- * _NOLISTEN
- * The dispatcher should not listen on the socket.
- *
- * _MAKEQUERY
- * The dispatcher can be used to issue queries to other servers, and
- * accept replies from them.
- *
- * _RANDOMPORT
- * Previously used to indicate that the port of a dispatch UDP must be
- * chosen randomly. This behavior now always applies and the attribute
- * is obsoleted.
- *
- * _EXCLUSIVE
- * A separate socket will be used on-demand for each transaction.
- */
-#define DNS_DISPATCHATTR_PRIVATE 0x00000001U
-#define DNS_DISPATCHATTR_TCP 0x00000002U
-#define DNS_DISPATCHATTR_UDP 0x00000004U
-#define DNS_DISPATCHATTR_IPV4 0x00000008U
-#define DNS_DISPATCHATTR_IPV6 0x00000010U
-#define DNS_DISPATCHATTR_NOLISTEN 0x00000020U
-#define DNS_DISPATCHATTR_MAKEQUERY 0x00000040U
-#define DNS_DISPATCHATTR_CONNECTED 0x00000080U
-/*#define DNS_DISPATCHATTR_RANDOMPORT 0x00000100U*/
-#define DNS_DISPATCHATTR_EXCLUSIVE 0x00000200U
-/*@}*/
-
-isc_result_t
-dns_dispatchmgr_create(isc_mem_t *mctx, isc_entropy_t *entropy,
- dns_dispatchmgr_t **mgrp);
-/*%<
- * Creates a new dispatchmgr object.
- *
- * Requires:
- *\li "mctx" be a valid memory context.
- *
- *\li mgrp != NULL && *mgrp == NULL
- *
- *\li "entropy" may be NULL, in which case an insecure random generator
- * will be used. If it is non-NULL, it must be a valid entropy
- * source.
- *
- * Returns:
- *\li ISC_R_SUCCESS -- all ok
- *
- *\li anything else -- failure
- */
-
-
-void
-dns_dispatchmgr_destroy(dns_dispatchmgr_t **mgrp);
-/*%<
- * Destroys the dispatchmgr when it becomes empty. This could be
- * immediately.
- *
- * Requires:
- *\li mgrp != NULL && *mgrp is a valid dispatchmgr.
- */
-
-
-void
-dns_dispatchmgr_setblackhole(dns_dispatchmgr_t *mgr, dns_acl_t *blackhole);
-/*%<
- * Sets the dispatcher's "blackhole list," a list of addresses that will
- * be ignored by all dispatchers created by the dispatchmgr.
- *
- * Requires:
- * \li mgrp is a valid dispatchmgr
- * \li blackhole is a valid acl
- */
-
-
-dns_acl_t *
-dns_dispatchmgr_getblackhole(dns_dispatchmgr_t *mgr);
-/*%<
- * Gets a pointer to the dispatcher's current blackhole list,
- * without incrementing its reference count.
- *
- * Requires:
- *\li mgr is a valid dispatchmgr
- * Returns:
- *\li A pointer to the current blackhole list, or NULL.
- */
-
-void
-dns_dispatchmgr_setblackportlist(dns_dispatchmgr_t *mgr,
- dns_portlist_t *portlist);
-/*%<
- * This function is deprecated. Use dns_dispatchmgr_setavailports() instead.
- *
- * Requires:
- *\li mgr is a valid dispatchmgr
- */
-
-dns_portlist_t *
-dns_dispatchmgr_getblackportlist(dns_dispatchmgr_t *mgr);
-/*%<
- * This function is deprecated and always returns NULL.
- *
- * Requires:
- *\li mgr is a valid dispatchmgr
- */
-
-isc_result_t
-dns_dispatchmgr_setavailports(dns_dispatchmgr_t *mgr, isc_portset_t *v4portset,
- isc_portset_t *v6portset);
-/*%<
- * Sets a list of UDP ports that can be used for outgoing UDP messages.
- *
- * Requires:
- *\li mgr is a valid dispatchmgr
- *\li v4portset is NULL or a valid port set
- *\li v6portset is NULL or a valid port set
- */
-
-void
-dns_dispatchmgr_setstats(dns_dispatchmgr_t *mgr, isc_stats_t *stats);
-/*%<
- * Sets statistics counter for the dispatchmgr. This function is expected to
- * be called only on zone creation (when necessary).
- * Once installed, it cannot be removed or replaced. Also, there is no
- * interface to get the installed stats from the zone; the caller must keep the
- * stats to reference (e.g. dump) it later.
- *
- * Requires:
- *\li mgr is a valid dispatchmgr with no managed dispatch.
- *\li stats is a valid statistics supporting resolver statistics counters
- * (see dns/stats.h).
- */
-
-isc_result_t
-dns_dispatch_getudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
- isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr,
- unsigned int buffersize,
- unsigned int maxbuffers, unsigned int maxrequests,
- unsigned int buckets, unsigned int increment,
- unsigned int attributes, unsigned int mask,
- dns_dispatch_t **dispp);
-
-isc_result_t
-dns_dispatch_getudp_dup(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
- isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr,
- unsigned int buffersize,
- unsigned int maxbuffers, unsigned int maxrequests,
- unsigned int buckets, unsigned int increment,
- unsigned int attributes, unsigned int mask,
- dns_dispatch_t **dispp, dns_dispatch_t *dup);
-/*%<
- * Attach to existing dns_dispatch_t if one is found with dns_dispatchmgr_find,
- * otherwise create a new UDP dispatch.
- *
- * Requires:
- *\li All pointer parameters be valid for their respective types.
- *
- *\li dispp != NULL && *disp == NULL
- *
- *\li 512 <= buffersize <= 64k
- *
- *\li maxbuffers > 0
- *
- *\li buckets < 2097169
- *
- *\li increment > buckets
- *
- *\li (attributes & DNS_DISPATCHATTR_TCP) == 0
- *
- * Returns:
- *\li ISC_R_SUCCESS -- success.
- *
- *\li Anything else -- failure.
- */
-
-isc_result_t
-dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock,
- isc_taskmgr_t *taskmgr, unsigned int buffersize,
- unsigned int maxbuffers, unsigned int maxrequests,
- unsigned int buckets, unsigned int increment,
- unsigned int attributes, dns_dispatch_t **dispp);
-/*%<
- * Create a new dns_dispatch and attach it to the provided isc_socket_t.
- *
- * For all dispatches, "buffersize" is the maximum packet size we will
- * accept.
- *
- * "maxbuffers" and "maxrequests" control the number of buffers in the
- * overall system and the number of buffers which can be allocated to
- * requests.
- *
- * "buckets" is the number of buckets to use, and should be prime.
- *
- * "increment" is used in a collision avoidance function, and needs to be
- * a prime > buckets, and not 2.
- *
- * Requires:
- *
- *\li mgr is a valid dispatch manager.
- *
- *\li sock is a valid.
- *
- *\li task is a valid task that can be used internally to this dispatcher.
- *
- * \li 512 <= buffersize <= 64k
- *
- *\li maxbuffers > 0.
- *
- *\li maxrequests <= maxbuffers.
- *
- *\li buckets < 2097169 (the next prime after 65536 * 32)
- *
- *\li increment > buckets (and prime).
- *
- *\li attributes includes #DNS_DISPATCHATTR_TCP and does not include
- * #DNS_DISPATCHATTR_UDP.
- *
- * Returns:
- *\li ISC_R_SUCCESS -- success.
- *
- *\li Anything else -- failure.
- */
-
-void
-dns_dispatch_attach(dns_dispatch_t *disp, dns_dispatch_t **dispp);
-/*%<
- * Attach to a dispatch handle.
- *
- * Requires:
- *\li disp is valid.
- *
- *\li dispp != NULL && *dispp == NULL
- */
-
-void
-dns_dispatch_detach(dns_dispatch_t **dispp);
-/*%<
- * Detaches from the dispatch.
- *
- * Requires:
- *\li dispp != NULL and *dispp be a valid dispatch.
- */
-
-void
-dns_dispatch_starttcp(dns_dispatch_t *disp);
-/*%<
- * Start processing of a TCP dispatch once the socket connects.
- *
- * Requires:
- *\li 'disp' is valid.
- */
-
-isc_result_t
-dns_dispatch_addresponse2(dns_dispatch_t *disp, isc_sockaddr_t *dest,
- isc_task_t *task, isc_taskaction_t action, void *arg,
- isc_uint16_t *idp, dns_dispentry_t **resp,
- isc_socketmgr_t *sockmgr);
-
-isc_result_t
-dns_dispatch_addresponse(dns_dispatch_t *disp, isc_sockaddr_t *dest,
- isc_task_t *task, isc_taskaction_t action, void *arg,
- isc_uint16_t *idp, dns_dispentry_t **resp);
-/*%<
- * Add a response entry for this dispatch.
- *
- * "*idp" is filled in with the assigned message ID, and *resp is filled in
- * to contain the magic token used to request event flow stop.
- *
- * Arranges for the given task to get a callback for response packets. When
- * the event is delivered, it must be returned using dns_dispatch_freeevent()
- * or through dns_dispatch_removeresponse() for another to be delivered.
- *
- * Requires:
- *\li "idp" be non-NULL.
- *
- *\li "task" "action" and "arg" be set as appropriate.
- *
- *\li "dest" be non-NULL and valid.
- *
- *\li "resp" be non-NULL and *resp be NULL
- *
- *\li "sockmgr" be NULL or a valid socket manager. If 'disp' has
- * the DNS_DISPATCHATTR_EXCLUSIVE attribute, this must not be NULL,
- * which also means dns_dispatch_addresponse() cannot be used.
- *
- * Ensures:
- *
- *\li &lt;id, dest> is a unique tuple. That means incoming messages
- * are identifiable.
- *
- * Returns:
- *
- *\li ISC_R_SUCCESS -- all is well.
- *\li ISC_R_NOMEMORY -- memory could not be allocated.
- *\li ISC_R_NOMORE -- no more message ids can be allocated
- * for this destination.
- */
-
-
-void
-dns_dispatch_removeresponse(dns_dispentry_t **resp,
- dns_dispatchevent_t **sockevent);
-/*%<
- * Stops the flow of responses for the provided id and destination.
- * If "sockevent" is non-NULL, the dispatch event and associated buffer is
- * also returned to the system.
- *
- * Requires:
- *\li "resp" != NULL and "*resp" contain a value previously allocated
- * by dns_dispatch_addresponse();
- *
- *\li May only be called from within the task given as the 'task'
- * argument to dns_dispatch_addresponse() when allocating '*resp'.
- */
-
-isc_socket_t *
-dns_dispatch_getentrysocket(dns_dispentry_t *resp);
-
-isc_socket_t *
-dns_dispatch_getsocket(dns_dispatch_t *disp);
-/*%<
- * Return the socket associated with this dispatcher.
- *
- * Requires:
- *\li disp is valid.
- *
- * Returns:
- *\li The socket the dispatcher is using.
- */
-
-isc_result_t
-dns_dispatch_getlocaladdress(dns_dispatch_t *disp, isc_sockaddr_t *addrp);
-/*%<
- * Return the local address for this dispatch.
- * This currently only works for dispatches using UDP sockets.
- *
- * Requires:
- *\li disp is valid.
- *\li addrp to be non null.
- *
- * Returns:
- *\li ISC_R_SUCCESS
- *\li ISC_R_NOTIMPLEMENTED
- */
-
-void
-dns_dispatch_cancel(dns_dispatch_t *disp);
-/*%<
- * cancel outstanding clients
- *
- * Requires:
- *\li disp is valid.
- */
-
-unsigned int
-dns_dispatch_getattributes(dns_dispatch_t *disp);
-/*%<
- * Return the attributes (DNS_DISPATCHATTR_xxx) of this dispatch. Only the
- * non-changeable attributes are expected to be referenced by the caller.
- *
- * Requires:
- *\li disp is valid.
- */
-
-void
-dns_dispatch_changeattributes(dns_dispatch_t *disp,
- unsigned int attributes, unsigned int mask);
-/*%<
- * Set the bits described by "mask" to the corresponding values in
- * "attributes".
- *
- * That is:
- *
- * \code
- * new = (old & ~mask) | (attributes & mask)
- * \endcode
- *
- * This function has a side effect when #DNS_DISPATCHATTR_NOLISTEN changes.
- * When the flag becomes off, the dispatch will start receiving on the
- * corresponding socket. When the flag becomes on, receive events on the
- * corresponding socket will be canceled.
- *
- * Requires:
- *\li disp is valid.
- *
- *\li attributes are reasonable for the dispatch. That is, setting the UDP
- * attribute on a TCP socket isn't reasonable.
- */
-
-void
-dns_dispatch_importrecv(dns_dispatch_t *disp, isc_event_t *event);
-/*%<
- * Inform the dispatcher of a socket receive. This is used for sockets
- * shared between dispatchers and clients. If the dispatcher fails to copy
- * or send the event, nothing happens.
- *
- * Requires:
- *\li disp is valid, and the attribute DNS_DISPATCHATTR_NOLISTEN is set.
- * event != NULL
- */
-
-dns_dispatch_t *
-dns_dispatchset_get(dns_dispatchset_t *dset);
-/*%<
- * Retrieve the next dispatch from dispatch set 'dset', and increment
- * the round-robin counter.
- *
- * Requires:
- *\li dset != NULL
- */
-
-isc_result_t
-dns_dispatchset_create(isc_mem_t *mctx, isc_socketmgr_t *sockmgr,
- isc_taskmgr_t *taskmgr, dns_dispatch_t *source,
- dns_dispatchset_t **dsetp, int n);
-/*%<
- * Given a valid dispatch 'source', create a dispatch set containing
- * 'n' UDP dispatches, with the remainder filled out by clones of the
- * source.
- *
- * Requires:
- *\li source is a valid UDP dispatcher
- *\li dsetp != NULL, *dsetp == NULL
- */
-
-void
-dns_dispatchset_cancelall(dns_dispatchset_t *dset, isc_task_t *task);
-/*%<
- * Cancel socket operations for the dispatches in 'dset'.
- */
-
-void
-dns_dispatchset_destroy(dns_dispatchset_t **dsetp);
-/*%<
- * Dereference all the dispatches in '*dsetp', free the dispatchset
- * memory, and set *dsetp to NULL.
- *
- * Requires:
- *\li dset is valid
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_DISPATCH_H */
diff --git a/contrib/bind9/lib/dns/include/dns/dlz.h b/contrib/bind9/lib/dns/include/dns/dlz.h
deleted file mode 100644
index 48dfb833f650..000000000000
--- a/contrib/bind9/lib/dns/include/dns/dlz.h
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * Portions Copyright (C) 2005-2007, 2009-2012 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * Copyright (C) 2002 Stichting NLnet, Netherlands, stichting@nlnet.nl.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the
- * above copyright notice and this permission notice appear in all
- * copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND STICHTING NLNET
- * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
- * STICHTING NLNET BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
- * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
- * USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * The development of Dynamically Loadable Zones (DLZ) for Bind 9 was
- * conceived and contributed by Rob Butler.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the
- * above copyright notice and this permission notice appear in all
- * copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ROB BUTLER
- * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
- * ROB BUTLER BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
- * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
- * USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/*! \file dns/dlz.h */
-
-#ifndef DLZ_H
-#define DLZ_H 1
-
-/*****
- ***** Module Info
- *****/
-
-/*
- * DLZ Interface
- *
- * The DLZ interface allows zones to be looked up using a driver instead of
- * Bind's default in memory zone table.
- *
- *
- * Reliability:
- * No anticipated impact.
- *
- * Resources:
- *
- * Security:
- * No anticipated impact.
- *
- * Standards:
- * None.
- */
-
-/*****
- ***** Imports
- *****/
-
-#include <dns/name.h>
-#include <dns/types.h>
-#include <dns/view.h>
-#include <dst/dst.h>
-
-#include <isc/lang.h>
-
-ISC_LANG_BEGINDECLS
-
-/***
- *** Types
- ***/
-
-#define DNS_DLZ_MAGIC ISC_MAGIC('D','L','Z','D')
-#define DNS_DLZ_VALID(dlz) ISC_MAGIC_VALID(dlz, DNS_DLZ_MAGIC)
-
-typedef isc_result_t
-(*dns_dlzallowzonexfr_t)(void *driverarg, void *dbdata, isc_mem_t *mctx,
- dns_rdataclass_t rdclass, dns_name_t *name,
- isc_sockaddr_t *clientaddr,
- dns_db_t **dbp);
-
-/*%<
- * Method prototype. Drivers implementing the DLZ interface MUST
- * supply an allow zone transfer method. This method is called when
- * the DNS server is performing a zone transfer query. The driver's
- * method should return ISC_R_SUCCESS and a database pointer to the
- * name server if the zone is supported by the database, and zone
- * transfer is allowed. Otherwise it will return ISC_R_NOTFOUND if
- * the zone is not supported by the database, or ISC_R_NOPERM if zone
- * transfers are not allowed. If an error occurs it should return a
- * result code indicating the type of error.
- */
-
-typedef isc_result_t
-(*dns_dlzcreate_t)(isc_mem_t *mctx, const char *dlzname, unsigned int argc,
- char *argv[], void *driverarg, void **dbdata);
-
-/*%<
- * Method prototype. Drivers implementing the DLZ interface MUST
- * supply a create method. This method is called when the DNS server
- * is starting up and creating drivers for use later.
- */
-
-typedef void
-(*dns_dlzdestroy_t)(void *driverarg, void **dbdata);
-
-/*%<
- * Method prototype. Drivers implementing the DLZ interface MUST
- * supply a destroy method. This method is called when the DNS server
- * is shutting down and no longer needs the driver.
- */
-
-typedef isc_result_t
-(*dns_dlzfindzone_t)(void *driverarg, void *dbdata, isc_mem_t *mctx,
- dns_rdataclass_t rdclass, dns_name_t *name,
- dns_db_t **dbp);
-
-/*%<
-
- * Method prototype. Drivers implementing the DLZ interface MUST
- * supply a find zone method. This method is called when the DNS
- * server is performing a query. The find zone method will be called
- * with the longest possible name first, and continue to be called
- * with successively shorter domain names, until any of the following
- * occur:
- *
- * \li 1) a match is found, and the function returns (ISC_R_SUCCESS)
- *
- * \li 2) a problem occurs, and the functions returns anything other
- * than (ISC_R_NOTFOUND)
- * \li 3) we run out of domain name labels. I.E. we have tried the
- * shortest domain name
- * \li 4) the number of labels in the domain name is less than
- * min_labels for dns_dlzfindzone
- *
- * The driver's find zone method should return ISC_R_SUCCESS and a
- * database pointer to the name server if the zone is supported by the
- * database. Otherwise it will return ISC_R_NOTFOUND, and a null
- * pointer if the zone is not supported. If an error occurs it should
- * 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 */
-struct dns_dlzimplementation {
- const char *name;
- const dns_dlzmethods_t *methods;
- isc_mem_t *mctx;
- void *driverarg;
- ISC_LINK(dns_dlzimplementation_t) link;
-};
-
-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
-};
-
-
-/***
- *** Method declarations
- ***/
-
-isc_result_t
-dns_dlzallowzonexfr(dns_view_t *view, dns_name_t *name,
- isc_sockaddr_t *clientaddr, dns_db_t **dbp);
-
-/*%<
- * This method is called when the DNS server is performing a zone
- * transfer query. It will call the DLZ driver's allow zone transfer
- * method.
- */
-
-isc_result_t
-dns_dlzcreate(isc_mem_t *mctx, const char *dlzname,
- const char *drivername, unsigned int argc,
- char *argv[], dns_dlzdb_t **dbp);
-
-/*%<
- * This method is called when the DNS server is starting up and
- * creating drivers for use later. It will search the DLZ driver list
- * for 'drivername' and return a DLZ driver via dbp if a match is
- * found. If the DLZ driver supplies a create method, this function
- * will call it.
- */
-
-void
-dns_dlzdestroy(dns_dlzdb_t **dbp);
-
-/*%<
- * This method is called when the DNS server is shutting down and no
- * longer needs the driver. If the DLZ driver supplies a destroy
- * methods, this function will call it.
- */
-
-isc_result_t
-dns_dlzfindzone(dns_view_t *view, dns_name_t *name,
- unsigned int minlabels, dns_db_t **dbp);
-
-/*%<
- * This method is called when the DNS server is performing a query.
- * It will call the DLZ driver's find zone method.
- */
-
-isc_result_t
-dns_dlzregister(const char *drivername, const dns_dlzmethods_t *methods,
- void *driverarg, isc_mem_t *mctx,
- dns_dlzimplementation_t **dlzimp);
-
-/*%<
- * Register a dynamically loadable zones (DLZ) driver for the database
- * type 'drivername', implemented by the functions in '*methods'.
- *
- * dlzimp must point to a NULL dlz_implementation_t pointer. That is,
- * dlzimp != NULL && *dlzimp == NULL. It will be assigned a value that
- * will later be used to identify the driver when deregistering it.
- */
-
-isc_result_t
-dns_dlzstrtoargv(isc_mem_t *mctx, char *s, unsigned int *argcp, char ***argvp);
-
-/*%<
- * This method is called when the name server is starting up to parse
- * the DLZ driver command line from named.conf. Basically it splits
- * up a string into and argc / argv. The primary difference of this
- * method is items between braces { } are considered only 1 word. for
- * example the command line "this is { one grouped phrase } and this
- * isn't" would be parsed into:
- *
- * \li argv[0]: "this"
- * \li argv[1]: "is"
- * \li argv{2]: " one grouped phrase "
- * \li argv[3]: "and"
- * \li argv[4]: "this"
- * \li argv{5}: "isn't"
- *
- * braces should NOT be nested, more than one grouping in the command
- * line is allowed. Notice, argv[2] has an extra space at the
- * beginning and end. Extra spaces are not stripped between a
- * grouping. You can do so in your driver if needed, or be sure not
- * to put extra spaces before / after the braces.
- */
-
-void
-dns_dlzunregister(dns_dlzimplementation_t **dlzimp);
-
-/*%<
- * Removes the dlz driver from the list of registered dlz drivers.
- * There must be no active dlz drivers of this type when this function
- * is called.
- */
-
-
-typedef isc_result_t dns_dlz_writeablezone_t(dns_view_t *view,
- const char *zone_name);
-dns_dlz_writeablezone_t dns_dlz_writeablezone;
-/*%<
- * 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/contrib/bind9/lib/dns/include/dns/dlz_dlopen.h b/contrib/bind9/lib/dns/include/dns/dlz_dlopen.h
deleted file mode 100644
index f87722c3db8e..000000000000
--- a/contrib/bind9/lib/dns/include/dns/dlz_dlopen.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/*! \file dns/dlz_open.h */
-
-#ifndef DLZ_DLOPEN_H
-#define DLZ_DLOPEN_H
-
-#include <dns/sdlz.h>
-
-ISC_LANG_BEGINDECLS
-
-/*
- * This header provides a minimal set of defines and typedefs needed
- * for the entry points of an external DLZ module for bind9.
- */
-
-#define DLZ_DLOPEN_VERSION 2
-
-/*
- * dlz_dlopen_version() is required for all DLZ external drivers. It
- * should return DLZ_DLOPEN_VERSION
- */
-typedef int dlz_dlopen_version_t (unsigned int *flags);
-
-/*
- * dlz_dlopen_create() is required for all DLZ external drivers.
- */
-typedef isc_result_t dlz_dlopen_create_t (const char *dlzname,
- unsigned int argc,
- char *argv[],
- void **dbdata,
- ...);
-
-/*
- * dlz_dlopen_destroy() is optional, and will be called when the
- * driver is unloaded if supplied
- */
-typedef void dlz_dlopen_destroy_t (void *dbdata);
-
-/*
- * dlz_dlopen_findzonedb() is required for all DLZ external drivers
- */
-typedef isc_result_t dlz_dlopen_findzonedb_t (void *dbdata,
- const char *name);
-
-/*
- * dlz_dlopen_lookup() is required for all DLZ external drivers
- */
-typedef isc_result_t dlz_dlopen_lookup_t (const char *zone,
- const char *name,
- void *dbdata,
- dns_sdlzlookup_t *lookup,
- dns_clientinfomethods_t *methods,
- dns_clientinfo_t *clientinfo);
-
-/*
- * dlz_dlopen_authority is optional() if dlz_dlopen_lookup()
- * supplies authority information for the dns record
- */
-typedef isc_result_t dlz_dlopen_authority_t (const char *zone,
- void *dbdata,
- dns_sdlzlookup_t *lookup);
-
-/*
- * dlz_dlopen_allowzonexfr() is optional, and should be supplied if
- * you want to support zone transfers
- */
-typedef isc_result_t dlz_dlopen_allowzonexfr_t (void *dbdata,
- const char *name,
- const char *client);
-
-/*
- * dlz_dlopen_allnodes() is optional, but must be supplied if supply a
- * dlz_dlopen_allowzonexfr() function
- */
-typedef isc_result_t dlz_dlopen_allnodes_t (const char *zone,
- void *dbdata,
- dns_sdlzallnodes_t *allnodes);
-
-/*
- * dlz_dlopen_newversion() is optional. It should be supplied if you
- * want to support dynamic updates.
- */
-typedef isc_result_t dlz_dlopen_newversion_t (const char *zone,
- void *dbdata,
- void **versionp);
-
-/*
- * dlz_closeversion() is optional, but must be supplied if you supply
- * a dlz_newversion() function
- */
-typedef void dlz_dlopen_closeversion_t (const char *zone,
- isc_boolean_t commit,
- void *dbdata,
- void **versionp);
-
-/*
- * dlz_dlopen_configure() is optional, but must be supplied if you
- * want to support dynamic updates
- */
-typedef isc_result_t dlz_dlopen_configure_t (dns_view_t *view,
- void *dbdata);
-
-/*
- * dlz_dlopen_setclientcallback() is optional, but must be supplied if you
- * want to retrieve information about the client (e.g., source address)
- * before sending a replay.
- */
-typedef isc_result_t dlz_dlopen_setclientcallback_t (dns_view_t *view,
- void *dbdata);
-
-
-/*
- * dlz_dlopen_ssumatch() is optional, but must be supplied if you want
- * to support dynamic updates
- */
-typedef isc_boolean_t dlz_dlopen_ssumatch_t (const char *signer,
- const char *name,
- const char *tcpaddr,
- const char *type,
- const char *key,
- isc_uint32_t keydatalen,
- unsigned char *keydata,
- void *dbdata);
-
-/*
- * dlz_dlopen_addrdataset() is optional, but must be supplied if you
- * want to support dynamic updates
- */
-typedef isc_result_t dlz_dlopen_addrdataset_t (const char *name,
- const char *rdatastr,
- void *dbdata,
- void *version);
-
-/*
- * dlz_dlopen_subrdataset() is optional, but must be supplied if you
- * want to support dynamic updates
- */
-typedef isc_result_t dlz_dlopen_subrdataset_t (const char *name,
- const char *rdatastr,
- void *dbdata,
- void *version);
-
-/*
- * dlz_dlopen_delrdataset() is optional, but must be supplied if you
- * want to support dynamic updates
- */
-typedef isc_result_t dlz_dlopen_delrdataset_t (const char *name,
- const char *type,
- void *dbdata,
- void *version);
-
-ISC_LANG_ENDDECLS
-
-#endif
diff --git a/contrib/bind9/lib/dns/include/dns/dns64.h b/contrib/bind9/lib/dns/include/dns/dns64.h
deleted file mode 100644
index eb8f8d6436a6..000000000000
--- a/contrib/bind9/lib/dns/include/dns/dns64.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * 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/contrib/bind9/lib/dns/include/dns/dnssec.h b/contrib/bind9/lib/dns/include/dns/dnssec.h
deleted file mode 100644
index e443f91b635b..000000000000
--- a/contrib/bind9/lib/dns/include/dns/dnssec.h
+++ /dev/null
@@ -1,350 +0,0 @@
-/*
- * Copyright (C) 2004-2007, 2009-2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2002 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-#ifndef DNS_DNSSEC_H
-#define DNS_DNSSEC_H 1
-
-/*! \file dns/dnssec.h */
-
-#include <isc/lang.h>
-#include <isc/stdtime.h>
-#include <isc/stats.h>
-
-#include <dns/diff.h>
-#include <dns/types.h>
-
-#include <dst/dst.h>
-
-ISC_LANG_BEGINDECLS
-
-LIBDNS_EXTERNAL_DATA extern isc_stats_t *dns_dnssec_stats;
-
-/*%< Maximum number of keys supported in a zone. */
-#define DNS_MAXZONEKEYS 32
-
-/*
- * 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);
-/*%<
- * Creates a DST key from a DNS record. Basically a wrapper around
- * dst_key_fromdns().
- *
- * Requires:
- *\li 'name' is not NULL
- *\li 'rdata' is not NULL
- *\li 'mctx' is not NULL
- *\li 'key' is not NULL
- *\li '*key' is NULL
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMEMORY
- *\li DST_R_INVALIDPUBLICKEY
- *\li various errors from dns_name_totext
- */
-
-isc_result_t
-dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
- isc_stdtime_t *inception, isc_stdtime_t *expire,
- isc_mem_t *mctx, isc_buffer_t *buffer, dns_rdata_t *sigrdata);
-/*%<
- * Generates a RRSIG record covering this rdataset. This has no effect
- * on existing RRSIG records.
- *
- * Requires:
- *\li 'name' (the owner name of the record) is a valid name
- *\li 'set' is a valid rdataset
- *\li 'key' is a valid key
- *\li 'inception' is not NULL
- *\li 'expire' is not NULL
- *\li 'mctx' is not NULL
- *\li 'buffer' is not NULL
- *\li 'sigrdata' is not NULL
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMEMORY
- *\li #ISC_R_NOSPACE
- *\li #DNS_R_INVALIDTIME - the expiration is before the inception
- *\li #DNS_R_KEYUNAUTHORIZED - the key cannot sign this data (either
- * it is not a zone key or its flags prevent
- * authentication)
- *\li DST_R_*
- */
-
-isc_result_t
-dns_dnssec_verify(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
- isc_boolean_t ignoretime, isc_mem_t *mctx,
- dns_rdata_t *sigrdata);
-
-isc_result_t
-dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
- isc_boolean_t ignoretime, isc_mem_t *mctx,
- dns_rdata_t *sigrdata, dns_name_t *wild);
-
-isc_result_t
-dns_dnssec_verify3(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
- isc_boolean_t ignoretime, unsigned int maxbits,
- isc_mem_t *mctx, dns_rdata_t *sigrdata, dns_name_t *wild);
-/*%<
- * Verifies the RRSIG record covering this rdataset signed by a specific
- * key. This does not determine if the key's owner is authorized to sign
- * this record, as this requires a resolver or database.
- * If 'ignoretime' is ISC_TRUE, temporal validity will not be checked.
- *
- * 'maxbits' specifies the maximum number of rsa exponent bits accepted.
- *
- * Requires:
- *\li 'name' (the owner name of the record) is a valid name
- *\li 'set' is a valid rdataset
- *\li 'key' is a valid key
- *\li 'mctx' is not NULL
- *\li 'sigrdata' is a valid rdata containing a SIG record
- *\li 'wild' if non-NULL then is a valid and has a buffer.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMEMORY
- *\li #DNS_R_FROMWILDCARD - the signature is valid and is from
- * a wildcard expansion. dns_dnssec_verify2() only.
- * 'wild' contains the name of the wildcard if non-NULL.
- *\li #DNS_R_SIGINVALID - the signature fails to verify
- *\li #DNS_R_SIGEXPIRED - the signature has expired
- *\li #DNS_R_SIGFUTURE - the signature's validity period has not begun
- *\li #DNS_R_KEYUNAUTHORIZED - the key cannot sign this data (either
- * it is not a zone key or its flags prevent
- * authentication)
- *\li DST_R_*
- */
-
-/*@{*/
-isc_result_t
-dns_dnssec_findzonekeys(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
- dns_name_t *name, isc_mem_t *mctx,
- unsigned int maxkeys, dst_key_t **keys,
- unsigned int *nkeys);
-isc_result_t
-dns_dnssec_findzonekeys2(dns_db_t *db, dns_dbversion_t *ver,
- dns_dbnode_t *node, dns_name_t *name,
- const char *directory, isc_mem_t *mctx,
- unsigned int maxkeys, dst_key_t **keys,
- unsigned int *nkeys);
-/*%<
- * Finds a set of zone keys.
- * XXX temporary - this should be handled in dns_zone_t.
- */
-/*@}*/
-
-isc_result_t
-dns_dnssec_signmessage(dns_message_t *msg, dst_key_t *key);
-/*%<
- * Signs a message with a SIG(0) record. This is implicitly called by
- * dns_message_renderend() if msg->sig0key is not NULL.
- *
- * Requires:
- *\li 'msg' is a valid message
- *\li 'key' is a valid key that can be used for signing
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMEMORY
- *\li DST_R_*
- */
-
-isc_result_t
-dns_dnssec_verifymessage(isc_buffer_t *source, dns_message_t *msg,
- dst_key_t *key);
-/*%<
- * Verifies a message signed by a SIG(0) record. This is not
- * called implicitly by dns_message_parse(). If dns_message_signer()
- * is called before dns_dnssec_verifymessage(), it will return
- * #DNS_R_NOTVERIFIEDYET. dns_dnssec_verifymessage() will set
- * the verified_sig0 flag in msg if the verify succeeds, and
- * the sig0status field otherwise.
- *
- * Requires:
- *\li 'source' is a valid buffer containing the unparsed message
- *\li 'msg' is a valid message
- *\li 'key' is a valid key
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMEMORY
- *\li #ISC_R_NOTFOUND - no SIG(0) was found
- *\li #DNS_R_SIGINVALID - the SIG record is not well-formed or
- * was not generated by the key.
- *\li DST_R_*
- */
-
-isc_boolean_t
-dns_dnssec_selfsigns(dns_rdata_t *rdata, dns_name_t *name,
- dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
- isc_boolean_t ignoretime, isc_mem_t *mctx);
-
-
-isc_boolean_t
-dns_dnssec_signs(dns_rdata_t *rdata, dns_name_t *name,
- dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
- isc_boolean_t ignoretime, isc_mem_t *mctx);
-/*%<
- * Verify that 'rdataset' is validly signed in 'sigrdataset' by
- * the key in 'rdata'.
- *
- * dns_dnssec_selfsigns() requires that rdataset be a DNSKEY or KEY
- * rrset. dns_dnssec_signs() works on any rrset.
- */
-
-
-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 hint_ttl, dns_diff_t *diff, isc_boolean_t allzsk,
- isc_mem_t *mctx, void (*report)(const char *, ...));
-/*%<
- * Update the list of keys in 'keys' with new key information in 'newkeys'.
- *
- * 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.
- *
- * 'hint_ttl' is the TTL to use for the DNSKEY RRset if there is no
- * existing RRset, and if none of the keys to be added has a default TTL
- * (in which case we would use the shortest one). If the TTL is longer
- * than the time until a new key will be activated, then we have to delay
- * the key's activation.
- *
- * 'report' points to a function for reporting status.
- *
- * On completion, any remaining keys in 'newkeys' are freed.
- */
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_DNSSEC_H */
diff --git a/contrib/bind9/lib/dns/include/dns/ds.h b/contrib/bind9/lib/dns/include/dns/ds.h
deleted file mode 100644
index 03ab0ed09da6..000000000000
--- a/contrib/bind9/lib/dns/include/dns/ds.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2004-2007, 2010, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2002 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: ds.h,v 1.12 2010/12/23 23:47:08 tbox Exp $ */
-
-#ifndef DNS_DS_H
-#define DNS_DS_H 1
-
-#include <isc/lang.h>
-
-#include <dns/types.h>
-
-#define DNS_DSDIGEST_SHA1 (1)
-#define DNS_DSDIGEST_SHA256 (2)
-#define DNS_DSDIGEST_GOST (3)
-#define DNS_DSDIGEST_SHA384 (4)
-
-/* should not be here... */
-
-#define ISC_GOST_DIGESTLENGTH 32U
-
-/*
- * Assuming SHA-384 digest type.
- */
-#define DNS_DS_BUFFERSIZE (52)
-
-ISC_LANG_BEGINDECLS
-
-isc_result_t
-dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key,
- unsigned int digest_type, unsigned char *buffer,
- dns_rdata_t *rdata);
-/*%<
- * Build the rdata of a DS record.
- *
- * Requires:
- *\li key Points to a valid DNS KEY record.
- *\li buffer Points to a temporary buffer of at least
- * #DNS_DS_BUFFERSIZE bytes.
- *\li rdata Points to an initialized dns_rdata_t.
- *
- * Ensures:
- * \li *rdata Contains a valid DS rdata. The 'data' member refers
- * to 'buffer'.
- */
-
-isc_boolean_t
-dns_ds_digest_supported(unsigned int digest_type);
-/*%<
- * Is this digest algorithm supported by dns_ds_buildrdata()?
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_DS_H */
diff --git a/contrib/bind9/lib/dns/include/dns/ecdb.h b/contrib/bind9/lib/dns/include/dns/ecdb.h
deleted file mode 100644
index 246cc30a3826..000000000000
--- a/contrib/bind9/lib/dns/include/dns/ecdb.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN 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
- ***/
-
-ISC_LANG_BEGINDECLS
-
-/* 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/contrib/bind9/lib/dns/include/dns/events.h b/contrib/bind9/lib/dns/include/dns/events.h
deleted file mode 100644
index fd2144f64937..000000000000
--- a/contrib/bind9/lib/dns/include/dns/events.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: events.h,v 1.61 2011/10/28 06:20:06 each Exp $ */
-
-#ifndef DNS_EVENTS_H
-#define DNS_EVENTS_H 1
-
-#include <isc/eventclass.h>
-
-/*! \file dns/events.h
- * \brief
- * Registry of DNS event numbers.
- */
-
-#define DNS_EVENT_FETCHCONTROL (ISC_EVENTCLASS_DNS + 0)
-#define DNS_EVENT_FETCHDONE (ISC_EVENTCLASS_DNS + 1)
-#define DNS_EVENT_VIEWRESSHUTDOWN (ISC_EVENTCLASS_DNS + 2)
-#define DNS_EVENT_VIEWADBSHUTDOWN (ISC_EVENTCLASS_DNS + 3)
-#define DNS_EVENT_UPDATE (ISC_EVENTCLASS_DNS + 4)
-#define DNS_EVENT_UPDATEDONE (ISC_EVENTCLASS_DNS + 5)
-#define DNS_EVENT_DISPATCH (ISC_EVENTCLASS_DNS + 6)
-#define DNS_EVENT_TCPMSG (ISC_EVENTCLASS_DNS + 7)
-#define DNS_EVENT_ADBMOREADDRESSES (ISC_EVENTCLASS_DNS + 8)
-#define DNS_EVENT_ADBNOMOREADDRESSES (ISC_EVENTCLASS_DNS + 9)
-#define DNS_EVENT_ADBCANCELED (ISC_EVENTCLASS_DNS + 10)
-#define DNS_EVENT_ADBNAMEDELETED (ISC_EVENTCLASS_DNS + 11)
-#define DNS_EVENT_ADBSHUTDOWN (ISC_EVENTCLASS_DNS + 12)
-#define DNS_EVENT_ADBEXPIRED (ISC_EVENTCLASS_DNS + 13)
-#define DNS_EVENT_ADBCONTROL (ISC_EVENTCLASS_DNS + 14)
-#define DNS_EVENT_CACHECLEAN (ISC_EVENTCLASS_DNS + 15)
-#define DNS_EVENT_BYADDRDONE (ISC_EVENTCLASS_DNS + 16)
-#define DNS_EVENT_ZONECONTROL (ISC_EVENTCLASS_DNS + 17)
-#define DNS_EVENT_DBDESTROYED (ISC_EVENTCLASS_DNS + 18)
-#define DNS_EVENT_VALIDATORDONE (ISC_EVENTCLASS_DNS + 19)
-#define DNS_EVENT_REQUESTDONE (ISC_EVENTCLASS_DNS + 20)
-#define DNS_EVENT_VALIDATORSTART (ISC_EVENTCLASS_DNS + 21)
-#define DNS_EVENT_VIEWREQSHUTDOWN (ISC_EVENTCLASS_DNS + 22)
-#define DNS_EVENT_NOTIFYSENDTOADDR (ISC_EVENTCLASS_DNS + 23)
-#define DNS_EVENT_ZONE (ISC_EVENTCLASS_DNS + 24)
-#define DNS_EVENT_ZONESTARTXFRIN (ISC_EVENTCLASS_DNS + 25)
-#define DNS_EVENT_MASTERQUANTUM (ISC_EVENTCLASS_DNS + 26)
-#define DNS_EVENT_CACHEOVERMEM (ISC_EVENTCLASS_DNS + 27)
-#define DNS_EVENT_MASTERNEXTZONE (ISC_EVENTCLASS_DNS + 28)
-#define DNS_EVENT_IOREADY (ISC_EVENTCLASS_DNS + 29)
-#define DNS_EVENT_LOOKUPDONE (ISC_EVENTCLASS_DNS + 30)
-#define DNS_EVENT_RBTDEADNODES (ISC_EVENTCLASS_DNS + 31)
-#define DNS_EVENT_DISPATCHCONTROL (ISC_EVENTCLASS_DNS + 32)
-#define DNS_EVENT_REQUESTCONTROL (ISC_EVENTCLASS_DNS + 33)
-#define DNS_EVENT_DUMPQUANTUM (ISC_EVENTCLASS_DNS + 34)
-#define DNS_EVENT_IMPORTRECVDONE (ISC_EVENTCLASS_DNS + 35)
-#define DNS_EVENT_FREESTORAGE (ISC_EVENTCLASS_DNS + 36)
-#define DNS_EVENT_VIEWACACHESHUTDOWN (ISC_EVENTCLASS_DNS + 37)
-#define DNS_EVENT_ACACHECONTROL (ISC_EVENTCLASS_DNS + 38)
-#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_ZONESECURESERIAL (ISC_EVENTCLASS_DNS + 47)
-#define DNS_EVENT_ZONESECUREDB (ISC_EVENTCLASS_DNS + 48)
-#define DNS_EVENT_ZONELOAD (ISC_EVENTCLASS_DNS + 49)
-#define DNS_EVENT_KEYDONE (ISC_EVENTCLASS_DNS + 50)
-#define DNS_EVENT_SETNSEC3PARAM (ISC_EVENTCLASS_DNS + 51)
-
-#define DNS_EVENT_FIRSTEVENT (ISC_EVENTCLASS_DNS + 0)
-#define DNS_EVENT_LASTEVENT (ISC_EVENTCLASS_DNS + 65535)
-
-#endif /* DNS_EVENTS_H */
diff --git a/contrib/bind9/lib/dns/include/dns/fixedname.h b/contrib/bind9/lib/dns/include/dns/fixedname.h
deleted file mode 100644
index 5a2aaf333e48..000000000000
--- a/contrib/bind9/lib/dns/include/dns/fixedname.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: fixedname.h,v 1.19 2007/06/19 23:47:16 tbox Exp $ */
-
-#ifndef DNS_FIXEDNAME_H
-#define DNS_FIXEDNAME_H 1
-
-/*****
- ***** Module Info
- *****/
-
-/*! \file dns/fixedname.h
- * \brief
- * Fixed-size Names
- *
- * dns_fixedname_t is a convenience type containing a name, an offsets table,
- * and a dedicated buffer big enough for the longest possible name.
- *
- * MP:
- *\li The caller must ensure any required synchronization.
- *
- * Reliability:
- *\li No anticipated impact.
- *
- * Resources:
- *\li Per dns_fixedname_t:
- *\code
- * sizeof(dns_name_t) + sizeof(dns_offsets_t) +
- * sizeof(isc_buffer_t) + 255 bytes + structure padding
- *\endcode
- *
- * Security:
- *\li No anticipated impact.
- *
- * Standards:
- *\li None.
- */
-
-/*****
- ***** Imports
- *****/
-
-#include <isc/buffer.h>
-
-#include <dns/name.h>
-
-/*****
- ***** Types
- *****/
-
-struct dns_fixedname {
- dns_name_t name;
- dns_offsets_t offsets;
- isc_buffer_t buffer;
- unsigned char data[DNS_NAME_MAXWIRE];
-};
-
-#define dns_fixedname_init(fn) \
- do { \
- dns_name_init(&((fn)->name), (fn)->offsets); \
- isc_buffer_init(&((fn)->buffer), (fn)->data, \
- DNS_NAME_MAXWIRE); \
- dns_name_setbuffer(&((fn)->name), &((fn)->buffer)); \
- } while (0)
-
-#define dns_fixedname_invalidate(fn) \
- dns_name_invalidate(&((fn)->name))
-
-#define dns_fixedname_name(fn) (&((fn)->name))
-
-#endif /* DNS_FIXEDNAME_H */
diff --git a/contrib/bind9/lib/dns/include/dns/forward.h b/contrib/bind9/lib/dns/include/dns/forward.h
deleted file mode 100644
index 23e94be7894e..000000000000
--- a/contrib/bind9/lib/dns/include/dns/forward.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: forward.h,v 1.13 2009/09/02 23:48:02 tbox Exp $ */
-
-#ifndef DNS_FORWARD_H
-#define DNS_FORWARD_H 1
-
-/*! \file dns/forward.h */
-
-#include <isc/lang.h>
-#include <isc/result.h>
-
-#include <dns/types.h>
-
-ISC_LANG_BEGINDECLS
-
-struct dns_forwarders {
- isc_sockaddrlist_t addrs;
- dns_fwdpolicy_t fwdpolicy;
-};
-
-isc_result_t
-dns_fwdtable_create(isc_mem_t *mctx, dns_fwdtable_t **fwdtablep);
-/*%<
- * Creates a new forwarding table.
- *
- * Requires:
- * \li mctx is a valid memory context.
- * \li fwdtablep != NULL && *fwdtablep == NULL
- *
- * Returns:
- * \li #ISC_R_SUCCESS
- * \li #ISC_R_NOMEMORY
- */
-
-isc_result_t
-dns_fwdtable_add(dns_fwdtable_t *fwdtable, dns_name_t *name,
- isc_sockaddrlist_t *addrs, dns_fwdpolicy_t policy);
-/*%<
- * Adds an entry to the forwarding table. The entry associates
- * a domain with a list of forwarders and a forwarding policy. The
- * addrs list is copied if not empty, so the caller should free its copy.
- *
- * Requires:
- * \li fwdtable is a valid forwarding table.
- * \li name is a valid name
- * \li addrs is a valid list of sockaddrs, which may be empty.
- *
- * Returns:
- * \li #ISC_R_SUCCESS
- * \li #ISC_R_NOMEMORY
- */
-
-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);
-/*%<
- * Finds a domain in the forwarding table. The closest matching parent
- * domain is returned.
- *
- * Requires:
- * \li fwdtable is a valid forwarding table.
- * \li name is a valid name
- * \li forwardersp != NULL && *forwardersp == NULL
- *
- * Returns:
- * \li #ISC_R_SUCCESS
- * \li #ISC_R_NOTFOUND
- */
-
-isc_result_t
-dns_fwdtable_find2(dns_fwdtable_t *fwdtable, dns_name_t *name,
- dns_name_t *foundname, dns_forwarders_t **forwardersp);
-/*%<
- * Finds a domain in the forwarding table. The closest matching parent
- * domain is returned.
- *
- * Requires:
- * \li fwdtable is a valid forwarding table.
- * \li name is a valid name
- * \li forwardersp != NULL && *forwardersp == NULL
- * \li foundname to be NULL or a valid name with buffer.
- *
- * Returns:
- * \li #ISC_R_SUCCESS
- * \li #ISC_R_NOTFOUND
- */
-
-void
-dns_fwdtable_destroy(dns_fwdtable_t **fwdtablep);
-/*%<
- * Destroys a forwarding table.
- *
- * Requires:
- * \li fwtablep != NULL && *fwtablep != NULL
- *
- * Ensures:
- * \li all memory associated with the forwarding table is freed.
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_FORWARD_H */
diff --git a/contrib/bind9/lib/dns/include/dns/iptable.h b/contrib/bind9/lib/dns/include/dns/iptable.h
deleted file mode 100644
index 2ce8e18124b9..000000000000
--- a/contrib/bind9/lib/dns/include/dns/iptable.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: iptable.h,v 1.4 2007/09/14 01:46:05 marka Exp $ */
-
-#ifndef DNS_IPTABLE_H
-#define DNS_IPTABLE_H 1
-
-#include <isc/lang.h>
-#include <isc/magic.h>
-#include <isc/radix.h>
-
-#include <dns/types.h>
-
-struct dns_iptable {
- unsigned int magic;
- isc_mem_t *mctx;
- isc_refcount_t refcount;
- isc_radix_tree_t *radix;
- ISC_LINK(dns_iptable_t) nextincache;
-};
-
-#define DNS_IPTABLE_MAGIC ISC_MAGIC('T','a','b','l')
-#define DNS_IPTABLE_VALID(a) ISC_MAGIC_VALID(a, DNS_IPTABLE_MAGIC)
-
-/***
- *** Functions
- ***/
-
-ISC_LANG_BEGINDECLS
-
-isc_result_t
-dns_iptable_create(isc_mem_t *mctx, dns_iptable_t **target);
-/*
- * Create a new IP table and the underlying radix structure
- */
-
-isc_result_t
-dns_iptable_addprefix(dns_iptable_t *tab, isc_netaddr_t *addr,
- isc_uint16_t bitlen, isc_boolean_t pos);
-/*
- * Add an IP prefix to an existing IP table
- */
-
-isc_result_t
-dns_iptable_merge(dns_iptable_t *tab, dns_iptable_t *source, isc_boolean_t pos);
-/*
- * Merge one IP table into another one.
- */
-
-void
-dns_iptable_attach(dns_iptable_t *source, dns_iptable_t **target);
-
-void
-dns_iptable_detach(dns_iptable_t **tabp);
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_IPTABLE_H */
diff --git a/contrib/bind9/lib/dns/include/dns/journal.h b/contrib/bind9/lib/dns/include/dns/journal.h
deleted file mode 100644
index 68ba8b35ae91..000000000000
--- a/contrib/bind9/lib/dns/include/dns/journal.h
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * Copyright (C) 2004-2009, 2011 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: journal.h,v 1.43 2011/12/22 07:32:41 each Exp $ */
-
-#ifndef DNS_JOURNAL_H
-#define DNS_JOURNAL_H 1
-
-/*****
- ***** Module Info
- *****/
-
-/*! \file dns/journal.h
- * \brief
- * Database journaling.
- */
-
-/***
- *** Imports
- ***/
-
-#include <isc/lang.h>
-#include <isc/magic.h>
-
-#include <dns/name.h>
-#include <dns/diff.h>
-#include <dns/rdata.h>
-#include <dns/types.h>
-
-/***
- *** Defines.
- ***/
-#define DNS_JOURNALOPT_RESIGN 0x00000001
-
-#define DNS_JOURNAL_READ 0x00000000 /* ISC_FALSE */
-#define DNS_JOURNAL_CREATE 0x00000001 /* ISC_TRUE */
-#define DNS_JOURNAL_WRITE 0x00000002
-
-/***
- *** Types
- ***/
-
-/*%
- * A dns_journal_t represents an open journal file. This is an opaque type.
- *
- * A particular dns_journal_t object may be opened for writing, in which case
- * it can be used for writing transactions to a journal file, or it can be
- * opened for reading, in which case it can be used for reading transactions
- * from (iterating over) a journal file. A single dns_journal_t object may
- * not be used for both purposes.
- */
-typedef struct dns_journal dns_journal_t;
-
-
-/***
- *** Functions
- ***/
-
-ISC_LANG_BEGINDECLS
-
-/**************************************************************************/
-
-isc_result_t
-dns_db_createsoatuple(dns_db_t *db, dns_dbversion_t *ver, isc_mem_t *mctx,
- dns_diffop_t op, dns_difftuple_t **tp);
-/*!< brief
- * Create a diff tuple for the current database SOA.
- * XXX this probably belongs somewhere else.
- */
-
-
-/*@{*/
-#define DNS_SERIAL_GT(a, b) ((int)(((a) - (b)) & 0xFFFFFFFF) > 0)
-#define DNS_SERIAL_GE(a, b) ((int)(((a) - (b)) & 0xFFFFFFFF) >= 0)
-/*!< brief
- * Compare SOA serial numbers. DNS_SERIAL_GT(a, b) returns true iff
- * a is "greater than" b where "greater than" is as defined in RFC1982.
- * DNS_SERIAL_GE(a, b) returns true iff a is "greater than or equal to" b.
- */
-/*@}*/
-
-/**************************************************************************/
-/*
- * Journal object creation and destruction.
- */
-
-isc_result_t
-dns_journal_open(isc_mem_t *mctx, const char *filename, unsigned int mode,
- dns_journal_t **journalp);
-/*%<
- * Open the journal file 'filename' and create a dns_journal_t object for it.
- *
- * DNS_JOURNAL_CREATE open the journal for reading and writing and create
- * the journal if it does not exist.
- * DNS_JOURNAL_WRITE open the journal for reading and writing.
- * DNS_JOURNAL_READ open the journal for reading only.
- */
-
-void
-dns_journal_destroy(dns_journal_t **journalp);
-/*%<
- * Destroy a dns_journal_t, closing any open files and freeing its memory.
- */
-
-/**************************************************************************/
-/*
- * Writing transactions to journals.
- */
-
-isc_result_t
-dns_journal_begin_transaction(dns_journal_t *j);
-/*%<
- * Prepare to write a new transaction to the open journal file 'j'.
- *
- * Requires:
- * \li 'j' is open for writing.
- */
-
-isc_result_t
-dns_journal_writediff(dns_journal_t *j, dns_diff_t *diff);
-/*%<
- * Write 'diff' to the current transaction of journal file 'j'.
- *
- * Requires:
- * \li 'j' is open for writing and dns_journal_begin_transaction()
- * has been called.
- *
- *\li 'diff' is a full or partial, correctly ordered IXFR
- * difference sequence.
- */
-
-isc_result_t
-dns_journal_commit(dns_journal_t *j);
-/*%<
- * Commit the current transaction of journal file 'j'.
- *
- * Requires:
- * \li 'j' is open for writing and dns_journal_begin_transaction()
- * has been called.
- *
- * \li dns_journal_writediff() has been called one or more times
- * to form a complete, correctly ordered IXFR difference
- * sequence.
- */
-
-isc_result_t
-dns_journal_write_transaction(dns_journal_t *j, dns_diff_t *diff);
-/*%
- * Write a complete transaction at once to a journal file,
- * sorting it if necessary, and commit it. Equivalent to calling
- * dns_diff_sort(), dns_journal_begin_transaction(),
- * dns_journal_writediff(), and dns_journal_commit().
- *
- * Requires:
- *\li 'j' is open for writing.
- *
- * \li 'diff' contains exactly one SOA deletion, one SOA addition
- * with a greater serial number, and possibly other changes,
- * in arbitrary order.
- */
-
-/**************************************************************************/
-/*
- * Reading transactions from journals.
- */
-
-isc_uint32_t
-dns_journal_first_serial(dns_journal_t *j);
-isc_uint32_t
-dns_journal_last_serial(dns_journal_t *j);
-/*%<
- * Get the first and last addressable serial number in the journal.
- */
-
-isc_result_t
-dns_journal_iter_init(dns_journal_t *j,
- isc_uint32_t begin_serial, isc_uint32_t end_serial);
-/*%<
- * Prepare to iterate over the transactions that will bring the database
- * from SOA serial number 'begin_serial' to 'end_serial'.
- *
- * Returns:
- *\li ISC_R_SUCCESS
- *\li ISC_R_RANGE begin_serial is outside the addressable range.
- *\li ISC_R_NOTFOUND begin_serial is within the range of addressable
- * serial numbers covered by the journal, but
- * this particular serial number does not exist.
- */
-
-/*@{*/
-isc_result_t
-dns_journal_first_rr(dns_journal_t *j);
-isc_result_t
-dns_journal_next_rr(dns_journal_t *j);
-/*%<
- * Position the iterator at the first/next RR in a journal
- * transaction sequence established using dns_journal_iter_init().
- *
- * Requires:
- * \li dns_journal_iter_init() has been called.
- *
- */
-/*@}*/
-
-void
-dns_journal_current_rr(dns_journal_t *j, dns_name_t **name, isc_uint32_t *ttl,
- dns_rdata_t **rdata);
-/*%<
- * Get the name, ttl, and rdata of the current journal RR.
- *
- * Requires:
- * \li The last call to dns_journal_first_rr() or dns_journal_next_rr()
- * returned ISC_R_SUCCESS.
- */
-
-/**************************************************************************/
-/*
- * Database roll-forward.
- */
-
-isc_result_t
-dns_journal_rollforward(isc_mem_t *mctx, dns_db_t *db, unsigned int options,
- const char *filename);
-
-isc_result_t
-dns_journal_rollforward2(isc_mem_t *mctx, dns_db_t *db, unsigned int options,
- isc_uint32_t resign, const char *filename);
-/*%<
- * Roll forward (play back) the journal file "filename" into the
- * database "db". This should be called when the server starts
- * after a shutdown or crash. 'resign' is how many seconds before
- * a RRSIG is due to expire it should be scheduled to be regenerated.
- *
- * Requires:
- *\li dns_journal_rollforward() requires that DNS_JOURNALOPT_RESIGN
- * is not set.
- *\li 'mctx' is a valid memory context.
- *\li 'db' is a valid database which does not have a version
- * open for writing.
- *\li 'filename' is the name of the journal file belonging to 'db'.
- *
- * Returns:
- *\li DNS_R_NOJOURNAL when journal does not exist.
- *\li ISC_R_NOTFOUND when current serial in not in journal.
- *\li ISC_R_RANGE when current serial in not in journals range.
- *\li ISC_R_SUCCESS journal has been applied successfully to database.
- * others
- */
-
-isc_result_t
-dns_journal_print(isc_mem_t *mctx, const char *filename, FILE *file);
-/* For debugging not general use */
-
-isc_result_t
-dns_db_diff(isc_mem_t *mctx,
- dns_db_t *dba, dns_dbversion_t *dbvera,
- dns_db_t *dbb, dns_dbversion_t *dbverb,
- const char *journal_filename);
-
-isc_result_t
-dns_db_diffx(dns_diff_t *diff, dns_db_t *dba, dns_dbversion_t *dbvera,
- dns_db_t *dbb, dns_dbversion_t *dbverb,
- const char *journal_filename);
-/*%<
- * Compare the databases 'dba' and 'dbb' and generate a diff/journal
- * entry containing the changes to make 'dba' from 'dbb' (note
- * the order). This journal entry will consist of a single,
- * possibly very large transaction. Append the journal
- * entry to the journal file specified by 'journal_filename' if
- * non-NULL.
- */
-
-isc_result_t
-dns_journal_compact(isc_mem_t *mctx, char *filename, isc_uint32_t serial,
- isc_uint32_t target_size);
-/*%<
- * Attempt to compact the journal if it is greater that 'target_size'.
- * Changes from 'serial' onwards will be preserved. If the journal
- * exists and is non-empty 'serial' must exist in the journal.
- */
-
-isc_boolean_t
-dns_journal_get_sourceserial(dns_journal_t *j, isc_uint32_t *sourceserial);
-void
-dns_journal_set_sourceserial(dns_journal_t *j, isc_uint32_t sourceserial);
-/*%<
- * Get and set source serial.
- *
- * Returns:
- * ISC_TRUE if sourceserial has previously been set.
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_JOURNAL_H */
diff --git a/contrib/bind9/lib/dns/include/dns/keydata.h b/contrib/bind9/lib/dns/include/dns/keydata.h
deleted file mode 100644
index f24ca06e7c6b..000000000000
--- a/contrib/bind9/lib/dns/include/dns/keydata.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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/contrib/bind9/lib/dns/include/dns/keyflags.h b/contrib/bind9/lib/dns/include/dns/keyflags.h
deleted file mode 100644
index 74a1740bd1d7..000000000000
--- a/contrib/bind9/lib/dns/include/dns/keyflags.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: keyflags.h,v 1.16 2007/06/19 23:47:16 tbox Exp $ */
-
-#ifndef DNS_KEYFLAGS_H
-#define DNS_KEYFLAGS_H 1
-
-/*! \file dns/keyflags.h */
-
-#include <isc/lang.h>
-
-#include <dns/types.h>
-
-ISC_LANG_BEGINDECLS
-
-isc_result_t
-dns_keyflags_fromtext(dns_keyflags_t *flagsp, isc_textregion_t *source);
-/*%<
- * Convert the text 'source' refers to into a DNSSEC KEY flags value.
- * The text may contain either a set of flag mnemonics separated by
- * vertical bars or a decimal flags value. For compatibility with
- * older versions of BIND and the DNSSEC signer, octal values
- * prefixed with a zero and hexadecimal values prefixed with "0x"
- * are also accepted.
- *
- * Requires:
- *\li 'flagsp' is a valid pointer.
- *
- *\li 'source' is a valid text region.
- *
- * Returns:
- *\li ISC_R_SUCCESS on success
- *\li ISC_R_RANGE numeric flag value is out of range
- *\li DNS_R_UNKNOWN mnemonic flag is unknown
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_KEYFLAGS_H */
diff --git a/contrib/bind9/lib/dns/include/dns/keytable.h b/contrib/bind9/lib/dns/include/dns/keytable.h
deleted file mode 100644
index 3f4adaf6e398..000000000000
--- a/contrib/bind9/lib/dns/include/dns/keytable.h
+++ /dev/null
@@ -1,457 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: keytable.h,v 1.23 2010/06/25 03:24:05 marka Exp $ */
-
-#ifndef DNS_KEYTABLE_H
-#define DNS_KEYTABLE_H 1
-
-/*****
- ***** Module Info
- *****/
-
-/*! \file
- * \brief
- * The keytable module provides services for storing and retrieving DNSSEC
- * trusted keys, as well as the ability to find the deepest matching key
- * for a given domain name.
- *
- * MP:
- *\li The module ensures appropriate synchronization of data structures it
- * creates and manipulates.
- *
- * Resources:
- *\li TBS
- *
- * Security:
- *\li No anticipated impact.
- */
-
-#include <isc/lang.h>
-#include <isc/magic.h>
-#include <isc/refcount.h>
-#include <isc/rwlock.h>
-#include <isc/stdtime.h>
-
-#include <dns/types.h>
-
-#include <dst/dst.h>
-
-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);
-/*%<
- * Create a keytable.
- *
- * Requires:
- *
- *\li 'mctx' is a valid memory context.
- *
- *\li keytablep != NULL && *keytablep == NULL
- *
- * Ensures:
- *
- *\li On success, *keytablep is a valid, empty key table.
- *
- * Returns:
- *
- *\li ISC_R_SUCCESS
- *
- *\li Any other result indicates failure.
- */
-
-
-void
-dns_keytable_attach(dns_keytable_t *source, dns_keytable_t **targetp);
-/*%<
- * Attach *targetp to source.
- *
- * Requires:
- *
- *\li 'source' is a valid keytable.
- *
- *\li 'targetp' points to a NULL dns_keytable_t *.
- *
- * Ensures:
- *
- *\li *targetp is attached to source.
- */
-
-void
-dns_keytable_detach(dns_keytable_t **keytablep);
-/*%<
- * Detach *keytablep from its keytable.
- *
- * Requires:
- *
- *\li 'keytablep' points to a valid keytable.
- *
- * Ensures:
- *
- *\li *keytablep is NULL.
- *
- *\li If '*keytablep' is the last reference to the keytable,
- * all resources used by the keytable will be freed
- */
-
-isc_result_t
-dns_keytable_add(dns_keytable_t *keytable, isc_boolean_t managed,
- dst_key_t **keyp);
-/*%<
- * 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:
- *
- *\li On success, *keyp == NULL
- *
- * 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);
-/*%<
- * Search for a key named 'name', matching 'algorithm' and 'tag' in
- * 'keytable'. This finds the first instance which matches. Use
- * dns_keytable_findnextkeynode() to find other 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 DNS_R_PARTIALMATCH the name existed in the keytable.
- *\li ISC_R_NOTFOUND
- *
- *\li Any other result indicates an error.
- */
-
-isc_result_t
-dns_keytable_findnextkeynode(dns_keytable_t *keytable, dns_keynode_t *keynode,
- dns_keynode_t **nextnodep);
-/*%<
- * Search for the next key with the same properties as 'keynode' in
- * 'keytable' as found by dns_keytable_findkeynode().
- *
- * 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_finddeepestmatch(dns_keytable_t *keytable, dns_name_t *name,
- dns_name_t *foundname);
-/*%<
- * Search for the deepest match of 'name' in 'keytable'.
- *
- * Requires:
- *
- *\li 'keytable' is a valid keytable.
- *
- *\li 'name' is a valid absolute name.
- *
- *\li 'foundname' is a name with a dedicated buffer.
- *
- * Returns:
- *
- *\li ISC_R_SUCCESS
- *\li ISC_R_NOTFOUND
- *
- *\li Any other result indicates an error.
- */
-
-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);
-/*%<
- * Give back a keynode found via dns_keytable_findkeynode().
- *
- * Requires:
- *
- *\li 'keytable' is a valid keytable.
- *
- *\li *keynodep is a valid keynode returned by a call to
- * dns_keytable_findkeynode().
- *
- * Ensures:
- *
- *\li *keynodep == NULL
- */
-
-isc_result_t
-dns_keytable_issecuredomain(dns_keytable_t *keytable, dns_name_t *name,
- isc_boolean_t *wantdnssecp);
-/*%<
- * Is 'name' at or beneath a trusted key?
- *
- * Requires:
- *
- *\li 'keytable' is a valid keytable.
- *
- *\li 'name' is a valid absolute name.
- *
- *\li '*wantsdnssecp' is a valid isc_boolean_t.
- *
- * Ensures:
- *
- *\li On success, *wantsdnssecp will be ISC_TRUE if and only if 'name'
- * is at or beneath a trusted key.
- *
- * Returns:
- *
- *\li ISC_R_SUCCESS
- *
- *\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/contrib/bind9/lib/dns/include/dns/keyvalues.h b/contrib/bind9/lib/dns/include/dns/keyvalues.h
deleted file mode 100644
index 0c392ca14cff..000000000000
--- a/contrib/bind9/lib/dns/include/dns/keyvalues.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2004-2010, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001, 2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: keyvalues.h,v 1.29 2010/12/23 23:47:08 tbox Exp $ */
-
-#ifndef DNS_KEYVALUES_H
-#define DNS_KEYVALUES_H 1
-
-/*! \file dns/keyvalues.h */
-
-/*
- * Flags field of the KEY RR rdata
- */
-#define DNS_KEYFLAG_TYPEMASK 0xC000 /*%< Mask for "type" bits */
-#define DNS_KEYTYPE_AUTHCONF 0x0000 /*%< Key usable for both */
-#define DNS_KEYTYPE_CONFONLY 0x8000 /*%< Key usable for confidentiality */
-#define DNS_KEYTYPE_AUTHONLY 0x4000 /*%< Key usable for authentication */
-#define DNS_KEYTYPE_NOKEY 0xC000 /*%< No key usable for either; no key */
-#define DNS_KEYTYPE_NOAUTH DNS_KEYTYPE_CONFONLY
-#define DNS_KEYTYPE_NOCONF DNS_KEYTYPE_AUTHONLY
-
-#define DNS_KEYFLAG_RESERVED2 0x2000 /*%< reserved - must be zero */
-#define DNS_KEYFLAG_EXTENDED 0x1000 /*%< key has extended flags */
-#define DNS_KEYFLAG_RESERVED4 0x0800 /*%< reserved - must be zero */
-#define DNS_KEYFLAG_RESERVED5 0x0400 /*%< reserved - must be zero */
-#define DNS_KEYFLAG_OWNERMASK 0x0300 /*%< these bits determine the type */
-#define DNS_KEYOWNER_USER 0x0000 /*%< key is assoc. with user */
-#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 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 */
-#define DNS_KEYFLAG_SIGNATORYMASK 0x000F /*%< key can sign RR's of same name */
-
-#define DNS_KEYFLAG_RESERVEDMASK (DNS_KEYFLAG_RESERVED2 | \
- DNS_KEYFLAG_RESERVED4 | \
- DNS_KEYFLAG_RESERVED5 | \
- DNS_KEYFLAG_RESERVED9 | \
- DNS_KEYFLAG_RESERVED10 | \
- DNS_KEYFLAG_RESERVED11 )
-#define DNS_KEYFLAG_KSK 0x0001 /*%< key signing key */
-
-#define DNS_KEYFLAG_RESERVEDMASK2 0xFFFF /*%< no bits defined here */
-
-/* The Algorithm field of the KEY and SIG RR's is an integer, {1..254} */
-#define DNS_KEYALG_RSAMD5 1 /*%< RSA with MD5 */
-#define DNS_KEYALG_RSA DNS_KEYALG_RSAMD5
-#define DNS_KEYALG_DH 2 /*%< Diffie Hellman KEY */
-#define DNS_KEYALG_DSA 3 /*%< DSA KEY */
-#define DNS_KEYALG_NSEC3DSA 6
-#define DNS_KEYALG_DSS DNS_ALG_DSA
-#define DNS_KEYALG_ECC 4
-#define DNS_KEYALG_RSASHA1 5
-#define DNS_KEYALG_NSEC3RSASHA1 7
-#define DNS_KEYALG_RSASHA256 8
-#define DNS_KEYALG_RSASHA512 10
-#define DNS_KEYALG_ECCGOST 12
-#define DNS_KEYALG_ECDSA256 13
-#define DNS_KEYALG_ECDSA384 14
-#define DNS_KEYALG_INDIRECT 252
-#define DNS_KEYALG_PRIVATEDNS 253
-#define DNS_KEYALG_PRIVATEOID 254 /*%< Key begins with OID giving alg */
-
-/* Protocol values */
-#define DNS_KEYPROTO_RESERVED 0
-#define DNS_KEYPROTO_TLS 1
-#define DNS_KEYPROTO_EMAIL 2
-#define DNS_KEYPROTO_DNSSEC 3
-#define DNS_KEYPROTO_IPSEC 4
-#define DNS_KEYPROTO_ANY 255
-
-/* Signatures */
-#define DNS_SIG_RSAMINBITS 512 /*%< Size of a mod or exp in bits */
-#define DNS_SIG_RSAMAXBITS 2552
- /* Total of binary mod and exp */
-#define DNS_SIG_RSAMAXBYTES ((DNS_SIG_RSAMAXBITS+7/8)*2+3)
- /*%< Max length of text sig block */
-#define DNS_SIG_RSAMAXBASE64 (((DNS_SIG_RSAMAXBYTES+2)/3)*4)
-#define DNS_SIG_RSAMINSIZE ((DNS_SIG_RSAMINBITS+7)/8)
-#define DNS_SIG_RSAMAXSIZE ((DNS_SIG_RSAMAXBITS+7)/8)
-
-#define DNS_SIG_DSASIGSIZE 41
-#define DNS_SIG_DSAMINBITS 512
-#define DNS_SIG_DSAMAXBITS 1024
-#define DNS_SIG_DSAMINBYTES 213
-#define DNS_SIG_DSAMAXBYTES 405
-
-#define DNS_SIG_GOSTSIGSIZE 64
-
-#define DNS_SIG_ECDSA256SIZE 64
-#define DNS_SIG_ECDSA384SIZE 96
-
-#define DNS_KEY_ECDSA256SIZE 64
-#define DNS_KEY_ECDSA384SIZE 96
-
-#endif /* DNS_KEYVALUES_H */
diff --git a/contrib/bind9/lib/dns/include/dns/lib.h b/contrib/bind9/lib/dns/include/dns/lib.h
deleted file mode 100644
index a78562f910c0..000000000000
--- a/contrib/bind9/lib/dns/include/dns/lib.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: lib.h,v 1.18 2009/09/02 23:48:02 tbox Exp $ */
-
-#ifndef DNS_LIB_H
-#define DNS_LIB_H 1
-
-/*! \file dns/lib.h */
-
-#include <isc/types.h>
-#include <isc/lang.h>
-
-ISC_LANG_BEGINDECLS
-
-/*%
- * Tuning: external query load in packets per seconds.
- */
-LIBDNS_EXTERNAL_DATA extern unsigned int dns_pps;
-LIBDNS_EXTERNAL_DATA extern isc_msgcat_t *dns_msgcat;
-
-void
-dns_lib_initmsgcat(void);
-/*%<
- * Initialize the DNS library's message catalog, dns_msgcat, if it
- * 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/contrib/bind9/lib/dns/include/dns/log.h b/contrib/bind9/lib/dns/include/dns/log.h
deleted file mode 100644
index 3c4df8a45003..000000000000
--- a/contrib/bind9/lib/dns/include/dns/log.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2004-2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001, 2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: log.h,v 1.47 2011/10/13 22:48:24 tbox Exp $ */
-
-/*! \file dns/log.h
- * \author Principal Authors: DCL */
-
-#ifndef DNS_LOG_H
-#define DNS_LOG_H 1
-
-#include <isc/lang.h>
-#include <isc/log.h>
-
-LIBDNS_EXTERNAL_DATA extern isc_log_t *dns_lctx;
-LIBDNS_EXTERNAL_DATA extern isc_logcategory_t dns_categories[];
-LIBDNS_EXTERNAL_DATA extern isc_logmodule_t dns_modules[];
-
-#define DNS_LOGCATEGORY_NOTIFY (&dns_categories[0])
-#define DNS_LOGCATEGORY_DATABASE (&dns_categories[1])
-#define DNS_LOGCATEGORY_SECURITY (&dns_categories[2])
-/* DNS_LOGCATEGORY_CONFIG superseded by CFG_LOGCATEGORY_CONFIG */
-#define DNS_LOGCATEGORY_DNSSEC (&dns_categories[4])
-#define DNS_LOGCATEGORY_RESOLVER (&dns_categories[5])
-#define DNS_LOGCATEGORY_XFER_IN (&dns_categories[6])
-#define DNS_LOGCATEGORY_XFER_OUT (&dns_categories[7])
-#define DNS_LOGCATEGORY_DISPATCH (&dns_categories[8])
-#define DNS_LOGCATEGORY_LAME_SERVERS (&dns_categories[9])
-#define DNS_LOGCATEGORY_DELEGATION_ONLY (&dns_categories[10])
-#define DNS_LOGCATEGORY_EDNS_DISABLED (&dns_categories[11])
-#define DNS_LOGCATEGORY_RPZ (&dns_categories[12])
-
-/* Backwards compatibility. */
-#define DNS_LOGCATEGORY_GENERAL ISC_LOGCATEGORY_GENERAL
-
-#define DNS_LOGMODULE_DB (&dns_modules[0])
-#define DNS_LOGMODULE_RBTDB (&dns_modules[1])
-#define DNS_LOGMODULE_RBTDB64 (&dns_modules[2])
-#define DNS_LOGMODULE_RBT (&dns_modules[3])
-#define DNS_LOGMODULE_RDATA (&dns_modules[4])
-#define DNS_LOGMODULE_MASTER (&dns_modules[5])
-#define DNS_LOGMODULE_MESSAGE (&dns_modules[6])
-#define DNS_LOGMODULE_CACHE (&dns_modules[7])
-#define DNS_LOGMODULE_CONFIG (&dns_modules[8])
-#define DNS_LOGMODULE_RESOLVER (&dns_modules[9])
-#define DNS_LOGMODULE_ZONE (&dns_modules[10])
-#define DNS_LOGMODULE_JOURNAL (&dns_modules[11])
-#define DNS_LOGMODULE_ADB (&dns_modules[12])
-#define DNS_LOGMODULE_XFER_IN (&dns_modules[13])
-#define DNS_LOGMODULE_XFER_OUT (&dns_modules[14])
-#define DNS_LOGMODULE_ACL (&dns_modules[15])
-#define DNS_LOGMODULE_VALIDATOR (&dns_modules[16])
-#define DNS_LOGMODULE_DISPATCH (&dns_modules[17])
-#define DNS_LOGMODULE_REQUEST (&dns_modules[18])
-#define DNS_LOGMODULE_MASTERDUMP (&dns_modules[19])
-#define DNS_LOGMODULE_TSIG (&dns_modules[20])
-#define DNS_LOGMODULE_TKEY (&dns_modules[21])
-#define DNS_LOGMODULE_SDB (&dns_modules[22])
-#define DNS_LOGMODULE_DIFF (&dns_modules[23])
-#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])
-#define DNS_LOGMODULE_CRYPTO (&dns_modules[28])
-
-ISC_LANG_BEGINDECLS
-
-void
-dns_log_init(isc_log_t *lctx);
-/*%
- * Make the libdns categories and modules available for use with the
- * ISC logging library.
- *
- * Requires:
- *\li lctx is a valid logging context.
- *
- *\li dns_log_init() is called only once.
- *
- * Ensures:
- * \li The categories and modules defined above are available for
- * use by isc_log_usechannnel() and isc_log_write().
- */
-
-void
-dns_log_setcontext(isc_log_t *lctx);
-/*%
- * Make the libdns library use the provided context for logging internal
- * messages.
- *
- * Requires:
- *\li lctx is a valid logging context.
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_LOG_H */
diff --git a/contrib/bind9/lib/dns/include/dns/lookup.h b/contrib/bind9/lib/dns/include/dns/lookup.h
deleted file mode 100644
index e825e00ba4e5..000000000000
--- a/contrib/bind9/lib/dns/include/dns/lookup.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: lookup.h,v 1.14 2009/01/17 23:47:43 tbox Exp $ */
-
-#ifndef DNS_LOOKUP_H
-#define DNS_LOOKUP_H 1
-
-/*****
- ***** Module Info
- *****/
-
-/*! \file dns/lookup.h
- * \brief
- * The lookup module performs simple DNS lookups. It implements
- * the full resolver algorithm, both looking for local data and
- * resolving external names as necessary.
- *
- * MP:
- *\li The module ensures appropriate synchronization of data structures it
- * creates and manipulates.
- *
- * Reliability:
- *\li No anticipated impact.
- *
- * Resources:
- *\li TBS
- *
- * Security:
- *\li No anticipated impact.
- *
- * Standards:
- *\li RFCs: 1034, 1035, 2181, TBS
- *\li Drafts: TBS
- */
-
-#include <isc/lang.h>
-#include <isc/event.h>
-
-#include <dns/types.h>
-
-ISC_LANG_BEGINDECLS
-
-/*%
- * A 'dns_lookupevent_t' is returned when a lookup completes.
- * The sender field will be set to the lookup that completed. If 'result'
- * is ISC_R_SUCCESS, then 'names' will contain a list of names associated
- * with the address. The recipient of the event must not change the list
- * and must not refer to any of the name data after the event is freed.
- */
-typedef struct dns_lookupevent {
- ISC_EVENT_COMMON(struct dns_lookupevent);
- isc_result_t result;
- dns_name_t *name;
- dns_rdataset_t *rdataset;
- dns_rdataset_t *sigrdataset;
- dns_db_t *db;
- dns_dbnode_t *node;
-} dns_lookupevent_t;
-
-isc_result_t
-dns_lookup_create(isc_mem_t *mctx, dns_name_t *name, dns_rdatatype_t type,
- dns_view_t *view, unsigned int options, isc_task_t *task,
- isc_taskaction_t action, void *arg, dns_lookup_t **lookupp);
-/*%<
- * Finds the rrsets matching 'name' and 'type'.
- *
- * Requires:
- *
- *\li 'mctx' is a valid mctx.
- *
- *\li 'name' is a valid name.
- *
- *\li 'view' is a valid view which has a resolver.
- *
- *\li 'task' is a valid task.
- *
- *\li lookupp != NULL && *lookupp == NULL
- *
- * Returns:
- *
- *\li ISC_R_SUCCESS
- *\li ISC_R_NOMEMORY
- *
- *\li Any resolver-related error (e.g. ISC_R_SHUTTINGDOWN) may also be
- * returned.
- */
-
-void
-dns_lookup_cancel(dns_lookup_t *lookup);
-/*%<
- * Cancel 'lookup'.
- *
- * Notes:
- *
- *\li If 'lookup' has not completed, post its LOOKUPDONE event with a
- * result code of ISC_R_CANCELED.
- *
- * Requires:
- *
- *\li 'lookup' is a valid lookup.
- */
-
-void
-dns_lookup_destroy(dns_lookup_t **lookupp);
-/*%<
- * Destroy 'lookup'.
- *
- * Requires:
- *
- *\li '*lookupp' is a valid lookup.
- *
- *\li The caller has received the LOOKUPDONE event (either because the
- * lookup completed or because dns_lookup_cancel() was called).
- *
- * Ensures:
- *
- *\li *lookupp == NULL.
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_LOOKUP_H */
diff --git a/contrib/bind9/lib/dns/include/dns/master.h b/contrib/bind9/lib/dns/include/dns/master.h
deleted file mode 100644
index 896c6e95ecd3..000000000000
--- a/contrib/bind9/lib/dns/include/dns/master.h
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2002 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-#ifndef DNS_MASTER_H
-#define DNS_MASTER_H 1
-
-/*! \file dns/master.h */
-
-/***
- *** Imports
- ***/
-
-#include <stdio.h>
-
-#include <isc/lang.h>
-
-#include <dns/types.h>
-
-/*
- * Flags to be passed in the 'options' argument in the functions below.
- */
-#define DNS_MASTER_AGETTL 0x00000001 /*%< Age the ttl based on $DATE. */
-#define DNS_MASTER_MANYERRORS 0x00000002 /*%< Continue processing on errors. */
-#define DNS_MASTER_NOINCLUDE 0x00000004 /*%< Disallow $INCLUDE directives. */
-#define DNS_MASTER_ZONE 0x00000008 /*%< Loading a zone master file. */
-#define DNS_MASTER_HINT 0x00000010 /*%< Loading a hint master file. */
-#define DNS_MASTER_SLAVE 0x00000020 /*%< Loading a slave master file. */
-#define DNS_MASTER_CHECKNS 0x00000040 /*%<
- * Check NS records to see
- * if they are an address
- */
-#define DNS_MASTER_FATALNS 0x00000080 /*%<
- * Treat DNS_MASTER_CHECKNS
- * matches as fatal
- */
-#define DNS_MASTER_CHECKNAMES 0x00000100
-#define DNS_MASTER_CHECKNAMESFAIL 0x00000200
-#define DNS_MASTER_CHECKWILDCARD 0x00000400 /* Check for internal wildcards. */
-#define DNS_MASTER_CHECKMX 0x00000800
-#define DNS_MASTER_CHECKMXFAIL 0x00001000
-
-#define DNS_MASTER_RESIGN 0x00002000
-#define DNS_MASTER_KEY 0x00004000 /*%< Loading a key zone master file. */
-
-ISC_LANG_BEGINDECLS
-
-/*
- * Structures that implement the "raw" format for master dump.
- * These are provided for a reference purpose only; in the actual
- * encoding, we directly read/write each field so that the encoded data
- * is always "packed", regardless of the hardware architecture.
- */
-#define DNS_RAWFORMAT_VERSION 1
-
-/*
- * Flags to indicate the status of the data in the raw file header
- */
-#define DNS_MASTERRAW_COMPAT 0x01
-#define DNS_MASTERRAW_SOURCESERIALSET 0x02
-#define DNS_MASTERRAW_LASTXFRINSET 0x04
-
-/* Common header */
-struct dns_masterrawheader {
- isc_uint32_t format; /* must be
- * dns_masterformat_raw */
- isc_uint32_t version; /* compatibility for future
- * extensions */
- isc_uint32_t dumptime; /* timestamp on creation
- * (currently unused) */
- isc_uint32_t flags; /* Flags */
- isc_uint32_t sourceserial; /* Source serial number (used
- * by inline-signing zones) */
- isc_uint32_t lastxfrin; /* timestamp of last transfer
- * (used by slave zones) */
-};
-
-/* The structure for each RRset */
-typedef struct {
- isc_uint32_t totallen; /* length of the data for this
- * RRset, including the
- * "header" part */
- dns_rdataclass_t rdclass; /* 16-bit class */
- dns_rdatatype_t type; /* 16-bit type */
- dns_rdatatype_t covers; /* same as type */
- dns_ttl_t ttl; /* 32-bit TTL */
- isc_uint32_t nrdata; /* number of RRs in this set */
- /* followed by encoded owner name, and then rdata */
-} dns_masterrawrdataset_t;
-
-/***
- *** Function
- ***/
-
-isc_result_t
-dns_master_loadfile(const char *master_file,
- dns_name_t *top,
- dns_name_t *origin,
- dns_rdataclass_t zclass,
- unsigned int options,
- dns_rdatacallbacks_t *callbacks,
- isc_mem_t *mctx);
-
-isc_result_t
-dns_master_loadfile2(const char *master_file,
- dns_name_t *top,
- dns_name_t *origin,
- dns_rdataclass_t zclass,
- unsigned int options,
- dns_rdatacallbacks_t *callbacks,
- isc_mem_t *mctx,
- dns_masterformat_t format);
-
-isc_result_t
-dns_master_loadfile3(const char *master_file,
- dns_name_t *top,
- dns_name_t *origin,
- dns_rdataclass_t zclass,
- unsigned int options,
- isc_uint32_t resign,
- dns_rdatacallbacks_t *callbacks,
- isc_mem_t *mctx,
- dns_masterformat_t format);
-
-isc_result_t
-dns_master_loadstream(FILE *stream,
- dns_name_t *top,
- dns_name_t *origin,
- dns_rdataclass_t zclass,
- unsigned int options,
- dns_rdatacallbacks_t *callbacks,
- isc_mem_t *mctx);
-
-isc_result_t
-dns_master_loadbuffer(isc_buffer_t *buffer,
- dns_name_t *top,
- dns_name_t *origin,
- dns_rdataclass_t zclass,
- unsigned int options,
- dns_rdatacallbacks_t *callbacks,
- isc_mem_t *mctx);
-
-isc_result_t
-dns_master_loadlexer(isc_lex_t *lex,
- dns_name_t *top,
- dns_name_t *origin,
- dns_rdataclass_t zclass,
- unsigned int options,
- dns_rdatacallbacks_t *callbacks,
- isc_mem_t *mctx);
-
-isc_result_t
-dns_master_loadfileinc(const char *master_file,
- dns_name_t *top,
- dns_name_t *origin,
- dns_rdataclass_t zclass,
- unsigned int options,
- dns_rdatacallbacks_t *callbacks,
- isc_task_t *task,
- dns_loaddonefunc_t done, void *done_arg,
- dns_loadctx_t **ctxp, isc_mem_t *mctx);
-
-isc_result_t
-dns_master_loadfileinc2(const char *master_file,
- dns_name_t *top,
- dns_name_t *origin,
- dns_rdataclass_t zclass,
- unsigned int options,
- dns_rdatacallbacks_t *callbacks,
- isc_task_t *task,
- dns_loaddonefunc_t done, void *done_arg,
- dns_loadctx_t **ctxp, isc_mem_t *mctx,
- dns_masterformat_t format);
-
-isc_result_t
-dns_master_loadfileinc3(const char *master_file,
- dns_name_t *top,
- dns_name_t *origin,
- dns_rdataclass_t zclass,
- unsigned int options,
- isc_uint32_t resign,
- dns_rdatacallbacks_t *callbacks,
- isc_task_t *task,
- dns_loaddonefunc_t done, void *done_arg,
- dns_loadctx_t **ctxp, isc_mem_t *mctx,
- dns_masterformat_t format);
-
-isc_result_t
-dns_master_loadstreaminc(FILE *stream,
- dns_name_t *top,
- dns_name_t *origin,
- dns_rdataclass_t zclass,
- unsigned int options,
- dns_rdatacallbacks_t *callbacks,
- isc_task_t *task,
- dns_loaddonefunc_t done, void *done_arg,
- dns_loadctx_t **ctxp, isc_mem_t *mctx);
-
-isc_result_t
-dns_master_loadbufferinc(isc_buffer_t *buffer,
- dns_name_t *top,
- dns_name_t *origin,
- dns_rdataclass_t zclass,
- unsigned int options,
- dns_rdatacallbacks_t *callbacks,
- isc_task_t *task,
- dns_loaddonefunc_t done, void *done_arg,
- dns_loadctx_t **ctxp, isc_mem_t *mctx);
-
-isc_result_t
-dns_master_loadlexerinc(isc_lex_t *lex,
- dns_name_t *top,
- dns_name_t *origin,
- dns_rdataclass_t zclass,
- unsigned int options,
- dns_rdatacallbacks_t *callbacks,
- isc_task_t *task,
- dns_loaddonefunc_t done, void *done_arg,
- dns_loadctx_t **ctxp, isc_mem_t *mctx);
-
-/*%<
- * Loads a RFC1305 master file from a file, stream, buffer, or existing
- * lexer into rdatasets and then calls 'callbacks->commit' to commit the
- * rdatasets. Rdata memory belongs to dns_master_load and will be
- * reused / released when the callback completes. dns_load_master will
- * abort if callbacks->commit returns any value other than ISC_R_SUCCESS.
- *
- * If 'DNS_MASTER_AGETTL' is set and the master file contains one or more
- * $DATE directives, the TTLs of the data will be aged accordingly.
- *
- * 'callbacks->commit' is assumed to call 'callbacks->error' or
- * 'callbacks->warn' to generate any error messages required.
- *
- * 'done' is called with 'done_arg' and a result code when the loading
- * is completed or has failed. If the initial setup fails 'done' is
- * not called.
- *
- * 'resign' the number of seconds before a RRSIG expires that it should
- * be re-signed. 0 is used if not provided.
- *
- * Requires:
- *\li 'master_file' points to a valid string.
- *\li 'lexer' points to a valid lexer.
- *\li 'top' points to a valid name.
- *\li 'origin' points to a valid name.
- *\li 'callbacks->commit' points to a valid function.
- *\li 'callbacks->error' points to a valid function.
- *\li 'callbacks->warn' points to a valid function.
- *\li 'mctx' points to a valid memory context.
- *\li 'task' and 'done' to be valid.
- *\li 'lmgr' to be valid.
- *\li 'ctxp != NULL && ctxp == NULL'.
- *
- * Returns:
- *\li ISC_R_SUCCESS upon successfully loading the master file.
- *\li ISC_R_SEENINCLUDE upon successfully loading the master file with
- * a $INCLUDE statement.
- *\li ISC_R_NOMEMORY out of memory.
- *\li ISC_R_UNEXPECTEDEND expected to be able to read a input token and
- * there was not one.
- *\li ISC_R_UNEXPECTED
- *\li DNS_R_NOOWNER failed to specify a ownername.
- *\li DNS_R_NOTTL failed to specify a ttl.
- *\li DNS_R_BADCLASS record class did not match zone class.
- *\li DNS_R_CONTINUE load still in progress (dns_master_load*inc() only).
- *\li Any dns_rdata_fromtext() error code.
- *\li Any error code from callbacks->commit().
- */
-
-void
-dns_loadctx_detach(dns_loadctx_t **ctxp);
-/*%<
- * Detach from the load context.
- *
- * Requires:
- *\li '*ctxp' to be valid.
- *
- * Ensures:
- *\li '*ctxp == NULL'
- */
-
-void
-dns_loadctx_attach(dns_loadctx_t *source, dns_loadctx_t **target);
-/*%<
- * Attach to the load context.
- *
- * Requires:
- *\li 'source' to be valid.
- *\li 'target != NULL && *target == NULL'.
- */
-
-void
-dns_loadctx_cancel(dns_loadctx_t *ctx);
-/*%<
- * Cancel loading the zone file associated with this load context.
- *
- * Requires:
- *\li 'ctx' to be valid
- */
-
-void
-dns_master_initrawheader(dns_masterrawheader_t *header);
-/*%<
- * Initializes the header for a raw master file, setting all
- * values to zero.
- */
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_MASTER_H */
diff --git a/contrib/bind9/lib/dns/include/dns/masterdump.h b/contrib/bind9/lib/dns/include/dns/masterdump.h
deleted file mode 100644
index 8631248cc2ee..000000000000
--- a/contrib/bind9/lib/dns/include/dns/masterdump.h
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
- * Copyright (C) 2004-2008, 2011 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2002 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: masterdump.h,v 1.47 2011/12/08 23:46:49 tbox Exp $ */
-
-#ifndef DNS_MASTERDUMP_H
-#define DNS_MASTERDUMP_H 1
-
-/*! \file dns/masterdump.h */
-
-/***
- *** Imports
- ***/
-
-#include <stdio.h>
-
-#include <isc/lang.h>
-
-#include <dns/types.h>
-
-/***
- *** Types
- ***/
-
-typedef struct dns_master_style dns_master_style_t;
-
-/***
- *** Definitions
- ***/
-
-/*
- * Flags affecting master file formatting. Flags 0x0000FFFF
- * define the formatting of the rdata part and are defined in
- * rdata.h.
- */
-
-/*% Omit the owner name when possible. */
-#define DNS_STYLEFLAG_OMIT_OWNER 0x00010000U
-
-/*%
- * Omit the TTL when possible. If DNS_STYLEFLAG_TTL is
- * also set, this means no TTLs are ever printed
- * because $TTL directives are generated before every
- * change in the TTL. In this case, no columns need to
- * be reserved for the TTL. Master files generated with
- * these options will be rejected by BIND 4.x because it
- * does not recognize the $TTL directive.
- *
- * If DNS_STYLEFLAG_TTL is not also set, the TTL will be
- * omitted when it is equal to the previous TTL.
- * This is correct according to RFC1035, but the
- * TTLs may be silently misinterpreted by older
- * versions of BIND which use the SOA MINTTL as a
- * default TTL value.
- */
-#define DNS_STYLEFLAG_OMIT_TTL 0x00020000U
-
-/*% Omit the class when possible. */
-#define DNS_STYLEFLAG_OMIT_CLASS 0x00040000U
-
-/*% Output $TTL directives. */
-#define DNS_STYLEFLAG_TTL 0x00080000U
-
-/*%
- * Output $ORIGIN directives and print owner names relative to
- * the origin when possible.
- */
-#define DNS_STYLEFLAG_REL_OWNER 0x00100000U
-
-/*% Print domain names in RR data in relative form when possible.
- For this to take effect, DNS_STYLEFLAG_REL_OWNER must also be set. */
-#define DNS_STYLEFLAG_REL_DATA 0x00200000U
-
-/*% Print the trust level of each rdataset. */
-#define DNS_STYLEFLAG_TRUST 0x00400000U
-
-/*% Print negative caching entries. */
-#define DNS_STYLEFLAG_NCACHE 0x00800000U
-
-/*% Never print the TTL. */
-#define DNS_STYLEFLAG_NO_TTL 0x01000000U
-
-/*% Never print the CLASS. */
-#define DNS_STYLEFLAG_NO_CLASS 0x02000000U
-
-/*% Report re-signing time. */
-#define DNS_STYLEFLAG_RESIGN 0x04000000U
-
-ISC_LANG_BEGINDECLS
-
-/***
- *** Constants
- ***/
-
-/*%
- * The default master file style.
- *
- * This uses $TTL directives to avoid the need to dedicate a
- * tab stop for the TTL. The class is only printed for the first
- * rrset in the file and shares a tab stop with the RR type.
- */
-LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_default;
-
-/*%
- * A master file style that dumps zones to a very generic format easily
- * imported/checked with external tools.
- */
-LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_full;
-
-/*%
- * A master file style that prints explicit TTL values on each
- * record line, never using $TTL statements. The TTL has a tab
- * stop of its own, but the class and type share one.
- */
-LIBDNS_EXTERNAL_DATA extern const dns_master_style_t
- dns_master_style_explicitttl;
-
-/*%
- * A master style format designed for cache files. It prints explicit TTL
- * values on each record line and never uses $ORIGIN or relative names.
- */
-LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_cache;
-
-/*%
- * A master style that prints name, ttl, class, type, and value on
- * every line. Similar to explicitttl above, but more verbose.
- * Intended for generating master files which can be easily parsed
- * by perl scripts and similar applications.
- */
-LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_simple;
-
-/*%
- * The style used for debugging, "dig" output, etc.
- */
-LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_debug;
-
-/***
- *** Functions
- ***/
-
-void
-dns_dumpctx_attach(dns_dumpctx_t *source, dns_dumpctx_t **target);
-/*%<
- * Attach to a dump context.
- *
- * Require:
- *\li 'source' to be valid.
- *\li 'target' to be non NULL and '*target' to be NULL.
- */
-
-void
-dns_dumpctx_detach(dns_dumpctx_t **dctxp);
-/*%<
- * Detach from a dump context.
- *
- * Require:
- *\li 'dctxp' to point to a valid dump context.
- *
- * Ensures:
- *\li '*dctxp' is NULL.
- */
-
-void
-dns_dumpctx_cancel(dns_dumpctx_t *dctx);
-/*%<
- * Cancel a in progress dump.
- *
- * Require:
- *\li 'dctx' to be valid.
- */
-
-dns_dbversion_t *
-dns_dumpctx_version(dns_dumpctx_t *dctx);
-/*%<
- * Return the version handle (if any) of the database being dumped.
- *
- * Require:
- *\li 'dctx' to be valid.
- */
-
-dns_db_t *
-dns_dumpctx_db(dns_dumpctx_t *dctx);
-/*%<
- * Return the database being dumped.
- *
- * Require:
- *\li 'dctx' to be valid.
- */
-
-
-/*@{*/
-isc_result_t
-dns_master_dumptostreaminc(isc_mem_t *mctx, dns_db_t *db,
- dns_dbversion_t *version,
- const dns_master_style_t *style, FILE *f,
- isc_task_t *task, dns_dumpdonefunc_t done,
- void *done_arg, dns_dumpctx_t **dctxp);
-
-isc_result_t
-dns_master_dumptostream(isc_mem_t *mctx, dns_db_t *db,
- dns_dbversion_t *version,
- const dns_master_style_t *style, FILE *f);
-
-isc_result_t
-dns_master_dumptostream2(isc_mem_t *mctx, dns_db_t *db,
- dns_dbversion_t *version,
- const dns_master_style_t *style,
- dns_masterformat_t format, FILE *f);
-
-isc_result_t
-dns_master_dumptostream3(isc_mem_t *mctx, dns_db_t *db,
- dns_dbversion_t *version,
- const dns_master_style_t *style,
- dns_masterformat_t format,
- dns_masterrawheader_t *header, FILE *f);
-/*%<
- * Dump the database 'db' to the steam 'f' in the specified format by
- * 'format'. If the format is dns_masterformat_text (the RFC1035 format),
- * 'style' specifies the file style (e.g., &dns_master_style_default).
- *
- * dns_master_dumptostream() is an old form of dns_master_dumptostream3(),
- * which always specifies the dns_masterformat_text format.
- * dns_master_dumptostream2() is an old form which always specifies
- * a NULL header.
- *
- * If 'format' is dns_masterformat_raw, then 'header' can contain
- * information to be written to the file header.
- *
- * Temporary dynamic memory may be allocated from 'mctx'.
- *
- * Require:
- *\li 'task' to be valid.
- *\li 'done' to be non NULL.
- *\li 'dctxp' to be non NULL && '*dctxp' to be NULL.
- *
- * Returns:
- *\li ISC_R_SUCCESS
- *\li ISC_R_CONTINUE dns_master_dumptostreaminc() only.
- *\li ISC_R_NOMEMORY
- *\li Any database or rrset iterator error.
- *\li Any dns_rdata_totext() error code.
- */
-/*@}*/
-
-/*@{*/
-isc_result_t
-dns_master_dumpinc(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
- const dns_master_style_t *style, const char *filename,
- isc_task_t *task, dns_dumpdonefunc_t done, void *done_arg,
- dns_dumpctx_t **dctxp);
-
-isc_result_t
-dns_master_dumpinc2(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
- const dns_master_style_t *style, const char *filename,
- isc_task_t *task, dns_dumpdonefunc_t done, void *done_arg, dns_dumpctx_t **dctxp, dns_masterformat_t format);
-
-isc_result_t
-dns_master_dumpinc3(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
- const dns_master_style_t *style, const char *filename,
- isc_task_t *task, dns_dumpdonefunc_t done, void
- *done_arg, dns_dumpctx_t **dctxp,
- dns_masterformat_t format, dns_masterrawheader_t *header);
-
-isc_result_t
-dns_master_dump(isc_mem_t *mctx, dns_db_t *db,
- dns_dbversion_t *version,
- const dns_master_style_t *style, const char *filename);
-
-isc_result_t
-dns_master_dump2(isc_mem_t *mctx, dns_db_t *db,
- dns_dbversion_t *version,
- const dns_master_style_t *style, const char *filename,
- dns_masterformat_t format);
-
-isc_result_t
-dns_master_dump3(isc_mem_t *mctx, dns_db_t *db,
- dns_dbversion_t *version,
- const dns_master_style_t *style, const char *filename,
- dns_masterformat_t format, dns_masterrawheader_t *header);
-
-/*%<
- * Dump the database 'db' to the file 'filename' in the specified format by
- * 'format'. If the format is dns_masterformat_text (the RFC1035 format),
- * 'style' specifies the file style (e.g., &dns_master_style_default).
- *
- * dns_master_dumpinc() and dns_master_dump() are old forms of _dumpinc3()
- * and _dump3(), respectively, which always specify the dns_masterformat_text
- * format. dns_master_dumpinc2() and dns_master_dump2() are old forms which
- * always specify a NULL header.
- *
- * If 'format' is dns_masterformat_raw, then 'header' can contain
- * information to be written to the file header.
- *
- * Temporary dynamic memory may be allocated from 'mctx'.
- *
- * Returns:
- *\li ISC_R_SUCCESS
- *\li ISC_R_CONTINUE dns_master_dumpinc() only.
- *\li ISC_R_NOMEMORY
- *\li Any database or rrset iterator error.
- *\li Any dns_rdata_totext() error code.
- */
-/*@}*/
-
-isc_result_t
-dns_master_rdatasettotext(dns_name_t *owner_name,
- dns_rdataset_t *rdataset,
- const dns_master_style_t *style,
- isc_buffer_t *target);
-/*%<
- * Convert 'rdataset' to text format, storing the result in 'target'.
- *
- * Notes:
- *\li The rdata cursor position will be changed.
- *
- * Requires:
- *\li 'rdataset' is a valid non-question rdataset.
- *
- *\li 'rdataset' is not empty.
- */
-
-isc_result_t
-dns_master_questiontotext(dns_name_t *owner_name,
- dns_rdataset_t *rdataset,
- const dns_master_style_t *style,
- isc_buffer_t *target);
-
-isc_result_t
-dns_master_dumpnodetostream(isc_mem_t *mctx, dns_db_t *db,
- dns_dbversion_t *version,
- dns_dbnode_t *node, dns_name_t *name,
- const dns_master_style_t *style,
- FILE *f);
-
-isc_result_t
-dns_master_dumpnode(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
- dns_dbnode_t *node, dns_name_t *name,
- const dns_master_style_t *style, const char *filename);
-
-isc_result_t
-dns_master_stylecreate(dns_master_style_t **style, unsigned int flags,
- unsigned int ttl_column, unsigned int class_column,
- unsigned int type_column, unsigned int rdata_column,
- unsigned int line_length, unsigned int tab_width,
- isc_mem_t *mctx);
-
-isc_result_t
-dns_master_stylecreate2(dns_master_style_t **style, unsigned int flags,
- unsigned int ttl_column, unsigned int class_column,
- unsigned int type_column, unsigned int rdata_column,
- unsigned int line_length, unsigned int tab_width,
- unsigned int split_width, isc_mem_t *mctx);
-void
-dns_master_styledestroy(dns_master_style_t **style, isc_mem_t *mctx);
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_MASTERDUMP_H */
diff --git a/contrib/bind9/lib/dns/include/dns/message.h b/contrib/bind9/lib/dns/include/dns/message.h
deleted file mode 100644
index a6862faab633..000000000000
--- a/contrib/bind9/lib/dns/include/dns/message.h
+++ /dev/null
@@ -1,1379 +0,0 @@
-/*
- * Copyright (C) 2004-2010, 2012, 2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-#ifndef DNS_MESSAGE_H
-#define DNS_MESSAGE_H 1
-
-/***
- *** Imports
- ***/
-
-#include <isc/lang.h>
-#include <isc/magic.h>
-
-#include <dns/compress.h>
-#include <dns/masterdump.h>
-#include <dns/types.h>
-
-#include <dst/dst.h>
-
-/*! \file dns/message.h
- * \brief Message Handling Module
- *
- * How this beast works:
- *
- * When a dns message is received in a buffer, dns_message_fromwire() is called
- * on the memory region. Various items are checked including the format
- * of the message (if counts are right, if counts consume the entire sections,
- * and if sections consume the entire message) and known pseudo-RRs in the
- * additional data section are analyzed and removed.
- *
- * TSIG checking is also done at this layer, and any DNSSEC transaction
- * signatures should also be checked here.
- *
- * Notes on using the gettemp*() and puttemp*() functions:
- *
- * These functions return items (names, rdatasets, etc) allocated from some
- * internal state of the dns_message_t.
- *
- * Names and rdatasets must be put back into the dns_message_t in
- * one of two ways. Assume a name was allocated via
- * dns_message_gettempname():
- *
- *\li (1) insert it into a section, using dns_message_addname().
- *
- *\li (2) return it to the message using dns_message_puttempname().
- *
- * The same applies to rdatasets.
- *
- * On the other hand, offsets, rdatalists and rdatas allocated using
- * dns_message_gettemp*() will always be freed automatically
- * when the message is reset or destroyed; calling dns_message_puttemp*()
- * on rdatalists and rdatas is optional and serves only to enable the item
- * to be reused multiple times during the lifetime of the message; offsets
- * cannot be reused.
- *
- * Buffers allocated using isc_buffer_allocate() can be automatically freed
- * as well by giving the buffer to the message using dns_message_takebuffer().
- * Doing this will cause the buffer to be freed using isc_buffer_free()
- * when the section lists are cleared, such as in a reset or in a destroy.
- * Since the buffer itself exists until the message is destroyed, this sort
- * of code can be written:
- *
- * \code
- * buffer = isc_buffer_allocate(mctx, 512);
- * name = NULL;
- * name = dns_message_gettempname(message, &name);
- * dns_name_init(name, NULL);
- * result = dns_name_fromtext(name, &source, dns_rootname, 0, buffer);
- * dns_message_takebuffer(message, &buffer);
- * \endcode
- *
- *
- * TODO:
- *
- * XXX Needed: ways to set and retrieve EDNS information, add rdata to a
- * section, move rdata from one section to another, remove rdata, etc.
- */
-
-#define DNS_MESSAGEFLAG_QR 0x8000U
-#define DNS_MESSAGEFLAG_AA 0x0400U
-#define DNS_MESSAGEFLAG_TC 0x0200U
-#define DNS_MESSAGEFLAG_RD 0x0100U
-#define DNS_MESSAGEFLAG_RA 0x0080U
-#define DNS_MESSAGEFLAG_AD 0x0020U
-#define DNS_MESSAGEFLAG_CD 0x0010U
-
-/*%< EDNS0 extended message flags */
-#define DNS_MESSAGEEXTFLAG_DO 0x8000U
-
-/*%< EDNS0 extended OPT codes */
-#define DNS_OPT_NSID 0x0003 /*%< NSID opt code */
-
-#define DNS_MESSAGE_REPLYPRESERVE (DNS_MESSAGEFLAG_RD|DNS_MESSAGEFLAG_CD)
-#define DNS_MESSAGEEXTFLAG_REPLYPRESERVE (DNS_MESSAGEEXTFLAG_DO)
-
-#define DNS_MESSAGE_HEADERLEN 12 /*%< 6 isc_uint16_t's */
-
-#define DNS_MESSAGE_MAGIC ISC_MAGIC('M','S','G','@')
-#define DNS_MESSAGE_VALID(msg) ISC_MAGIC_VALID(msg, DNS_MESSAGE_MAGIC)
-
-/*
- * Ordering here matters. DNS_SECTION_ANY must be the lowest and negative,
- * and DNS_SECTION_MAX must be one greater than the last used section.
- */
-typedef int dns_section_t;
-#define DNS_SECTION_ANY (-1)
-#define DNS_SECTION_QUESTION 0
-#define DNS_SECTION_ANSWER 1
-#define DNS_SECTION_AUTHORITY 2
-#define DNS_SECTION_ADDITIONAL 3
-#define DNS_SECTION_MAX 4
-
-typedef int dns_pseudosection_t;
-#define DNS_PSEUDOSECTION_ANY (-1)
-#define DNS_PSEUDOSECTION_OPT 0
-#define DNS_PSEUDOSECTION_TSIG 1
-#define DNS_PSEUDOSECTION_SIG0 2
-#define DNS_PSEUDOSECTION_MAX 3
-
-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.
- */
-#define DNS_SECTION_ZONE DNS_SECTION_QUESTION
-#define DNS_SECTION_PREREQUISITE DNS_SECTION_ANSWER
-#define DNS_SECTION_UPDATE DNS_SECTION_AUTHORITY
-
-/*
- * These tell the message library how the created dns_message_t will be used.
- */
-#define DNS_MESSAGE_INTENTUNKNOWN 0 /*%< internal use only */
-#define DNS_MESSAGE_INTENTPARSE 1 /*%< parsing messages */
-#define DNS_MESSAGE_INTENTRENDER 2 /*%< rendering */
-
-/*
- * Control behavior of parsing
- */
-#define DNS_MESSAGEPARSE_PRESERVEORDER 0x0001 /*%< preserve rdata order */
-#define DNS_MESSAGEPARSE_BESTEFFORT 0x0002 /*%< return a message if a
- recoverable parse error
- occurs */
-#define DNS_MESSAGEPARSE_CLONEBUFFER 0x0004 /*%< save a copy of the
- source buffer */
-#define DNS_MESSAGEPARSE_IGNORETRUNCATION 0x0008 /*%< truncation errors are
- * not fatal. */
-
-/*
- * Control behavior of rendering
- */
-#define DNS_MESSAGERENDER_ORDERED 0x0001 /*%< don't change order */
-#define DNS_MESSAGERENDER_PARTIAL 0x0002 /*%< allow a partial rdataset */
-#define DNS_MESSAGERENDER_OMITDNSSEC 0x0004 /*%< omit DNSSEC records */
-#define DNS_MESSAGERENDER_PREFER_A 0x0008 /*%< prefer A records in
- 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;
-
-struct dns_message {
- /* public from here down */
- unsigned int magic;
-
- dns_messageid_t id;
- unsigned int flags;
- dns_rcode_t rcode;
- unsigned int opcode;
- dns_rdataclass_t rdclass;
-
- /* 4 real, 1 pseudo */
- unsigned int counts[DNS_SECTION_MAX];
-
- /* private from here down */
- dns_namelist_t sections[DNS_SECTION_MAX];
- dns_name_t *cursors[DNS_SECTION_MAX];
- dns_rdataset_t *opt;
- dns_rdataset_t *sig0;
- dns_rdataset_t *tsig;
-
- int state;
- unsigned int from_to_wire : 2;
- unsigned int header_ok : 1;
- unsigned int question_ok : 1;
- unsigned int tcp_continuation : 1;
- unsigned int verified_sig : 1;
- unsigned int verify_attempted : 1;
- unsigned int free_query : 1;
- unsigned int free_saved : 1;
-
- unsigned int opt_reserved;
- unsigned int sig_reserved;
- unsigned int reserved; /* reserved space (render) */
-
- isc_buffer_t *buffer;
- dns_compress_t *cctx;
-
- isc_mem_t *mctx;
- isc_mempool_t *namepool;
- isc_mempool_t *rdspool;
-
- isc_bufferlist_t scratchpad;
- isc_bufferlist_t cleanup;
-
- ISC_LIST(dns_msgblock_t) rdatas;
- ISC_LIST(dns_msgblock_t) rdatalists;
- ISC_LIST(dns_msgblock_t) offsets;
-
- ISC_LIST(dns_rdata_t) freerdata;
- ISC_LIST(dns_rdatalist_t) freerdatalist;
-
- dns_rcode_t tsigstatus;
- dns_rcode_t querytsigstatus;
- dns_name_t *tsigname; /* Owner name of TSIG, if any */
- dns_rdataset_t *querytsig;
- dns_tsigkey_t *tsigkey;
- dst_context_t *tsigctx;
- int sigstart;
- int timeadjust;
-
- dns_name_t *sig0name; /* Owner name of SIG0, if any */
- dst_key_t *sig0key;
- dns_rcode_t sig0status;
- isc_region_t query;
- isc_region_t saved;
-
- dns_rdatasetorderfunc_t order;
- const void * order_arg;
-};
-
-struct dns_ednsopt {
- isc_uint16_t code;
- isc_uint16_t length;
- unsigned char *value;
-};
-
-/***
- *** Functions
- ***/
-
-ISC_LANG_BEGINDECLS
-
-isc_result_t
-dns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp);
-
-/*%<
- * Create msg structure.
- *
- * This function will allocate some internal blocks of memory that are
- * expected to be needed for parsing or rendering nearly any type of message.
- *
- * Requires:
- *\li 'mctx' be a valid memory context.
- *
- *\li 'msgp' be non-null and '*msg' be NULL.
- *
- *\li 'intent' must be one of DNS_MESSAGE_INTENTPARSE or
- * #DNS_MESSAGE_INTENTRENDER.
- *
- * Ensures:
- *\li The data in "*msg" is set to indicate an unused and empty msg
- * structure.
- *
- * Returns:
- *\li #ISC_R_NOMEMORY -- out of memory
- *\li #ISC_R_SUCCESS -- success
- */
-
-void
-dns_message_reset(dns_message_t *msg, unsigned int intent);
-/*%<
- * Reset a message structure to default state. All internal lists are freed
- * or reset to a default state as well. This is simply a more efficient
- * way to call dns_message_destroy() followed by dns_message_allocate(),
- * since it avoid many memory allocations.
- *
- * If any data loanouts (buffers, names, rdatas, etc) were requested,
- * the caller must no longer use them after this call.
- *
- * The intended next use of the message will be 'intent'.
- *
- * Requires:
- *
- *\li 'msg' be valid.
- *
- *\li 'intent' is DNS_MESSAGE_INTENTPARSE or DNS_MESSAGE_INTENTRENDER
- */
-
-void
-dns_message_destroy(dns_message_t **msgp);
-/*%<
- * Destroy all state in the message.
- *
- * Requires:
- *
- *\li 'msgp' be valid.
- *
- * Ensures:
- *\li '*msgp' == NULL
- */
-
-isc_result_t
-dns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
- const dns_master_style_t *style,
- dns_messagetextflag_t flags,
- isc_buffer_t *target);
-
-isc_result_t
-dns_message_pseudosectiontotext(dns_message_t *msg,
- dns_pseudosection_t section,
- const dns_master_style_t *style,
- dns_messagetextflag_t flags,
- isc_buffer_t *target);
-/*%<
- * Convert section 'section' or 'pseudosection' of message 'msg' to
- * a cleartext representation
- *
- * Notes:
- * \li See dns_message_totext for meanings of flags.
- *
- * Requires:
- *
- *\li 'msg' is a valid message.
- *
- *\li 'style' is a valid master dump style.
- *
- *\li 'target' is a valid buffer.
- *
- *\li 'section' is a valid section label.
- *
- * Ensures:
- *
- *\li If the result is success:
- * The used space in 'target' is updated.
- *
- * Returns:
- *
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOSPACE
- *\li #ISC_R_NOMORE
- *
- *\li Note: On error return, *target may be partially filled with data.
-*/
-
-isc_result_t
-dns_message_totext(dns_message_t *msg, const dns_master_style_t *style,
- dns_messagetextflag_t flags, isc_buffer_t *target);
-/*%<
- * Convert all sections of message 'msg' to a cleartext representation
- *
- * Notes:
- * \li In flags, If #DNS_MESSAGETEXTFLAG_OMITDOT is set, then the
- * final '.' in absolute names will not be emitted. If
- * #DNS_MESSAGETEXTFLAG_NOCOMMENTS is cleared, lines beginning
- * with ";;" will be emitted indicating section name. If
- * #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.
- *
- *\li 'style' is a valid master dump style.
- *
- *\li 'target' is a valid buffer.
- *
- * Ensures:
- *
- *\li If the result is success:
- * The used space in 'target' is updated.
- *
- * Returns:
- *
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOSPACE
- *\li #ISC_R_NOMORE
- *
- *\li Note: On error return, *target may be partially filled with data.
- */
-
-isc_result_t
-dns_message_parse(dns_message_t *msg, isc_buffer_t *source,
- unsigned int options);
-/*%<
- * Parse raw wire data in 'source' as a DNS message.
- *
- * OPT records are detected and stored in the pseudo-section "opt".
- * TSIGs are detected and stored in the pseudo-section "tsig".
- *
- * If #DNS_MESSAGEPARSE_PRESERVEORDER is set, or if the opcode of the message
- * is UPDATE, a separate dns_name_t object will be created for each RR in the
- * message. Each such dns_name_t will have a single rdataset containing the
- * single RR, and the order of the RRs in the message is preserved.
- * Otherwise, only one dns_name_t object will be created for each unique
- * owner name in the section, and each such dns_name_t will have a list
- * of rdatasets. To access the names and their data, use
- * dns_message_firstname() and dns_message_nextname().
- *
- * If #DNS_MESSAGEPARSE_BESTEFFORT is set, errors in message content will
- * not be considered FORMERRs. If the entire message can be parsed, it
- * will be returned and DNS_R_RECOVERABLE will be returned.
- *
- * If #DNS_MESSAGEPARSE_IGNORETRUNCATION is set then return as many complete
- * RR's as possible, DNS_R_RECOVERABLE will be returned.
- *
- * OPT and TSIG records are always handled specially, regardless of the
- * 'preserve_order' setting.
- *
- * Requires:
- *\li "msg" be valid.
- *
- *\li "buffer" be a wire format buffer.
- *
- * Ensures:
- *\li The buffer's data format is correct.
- *
- *\li The buffer's contents verify as correct regarding header bits, buffer
- * and rdata sizes, etc.
- *
- * Returns:
- *\li #ISC_R_SUCCESS -- all is well
- *\li #ISC_R_NOMEMORY -- no memory
- *\li #DNS_R_RECOVERABLE -- the message parsed properly, but contained
- * errors.
- *\li Many other errors possible XXXMLG
- */
-
-isc_result_t
-dns_message_renderbegin(dns_message_t *msg, dns_compress_t *cctx,
- isc_buffer_t *buffer);
-/*%<
- * Begin rendering on a message. Only one call can be made to this function
- * per message.
- *
- * The compression context is "owned" by the message library until
- * dns_message_renderend() is called. It must be invalidated by the caller.
- *
- * The buffer is "owned" by the message library until dns_message_renderend()
- * is called.
- *
- * Requires:
- *
- *\li 'msg' be valid.
- *
- *\li 'cctx' be valid.
- *
- *\li 'buffer' is a valid buffer.
- *
- * Side Effects:
- *
- *\li The buffer is cleared before it is used.
- *
- * Returns:
- *\li #ISC_R_SUCCESS -- all is well
- *\li #ISC_R_NOSPACE -- output buffer is too small
- */
-
-isc_result_t
-dns_message_renderchangebuffer(dns_message_t *msg, isc_buffer_t *buffer);
-/*%<
- * Reset the buffer. This can be used after growing the old buffer
- * on a ISC_R_NOSPACE return from most of the render functions.
- *
- * On successful completion, the old buffer is no longer used by the
- * library. The new buffer is owned by the library until
- * dns_message_renderend() is called.
- *
- * Requires:
- *
- *\li 'msg' be valid.
- *
- *\li dns_message_renderbegin() was called.
- *
- *\li buffer != NULL.
- *
- * Returns:
- *\li #ISC_R_NOSPACE -- new buffer is too small
- *\li #ISC_R_SUCCESS -- all is well.
- */
-
-isc_result_t
-dns_message_renderreserve(dns_message_t *msg, unsigned int space);
-/*%<
- * XXXMLG should use size_t rather than unsigned int once the buffer
- * API is cleaned up
- *
- * Reserve "space" bytes in the given buffer.
- *
- * Requires:
- *
- *\li 'msg' be valid.
- *
- *\li dns_message_renderbegin() was called.
- *
- * Returns:
- *\li #ISC_R_SUCCESS -- all is well.
- *\li #ISC_R_NOSPACE -- not enough free space in the buffer.
- */
-
-void
-dns_message_renderrelease(dns_message_t *msg, unsigned int space);
-/*%<
- * XXXMLG should use size_t rather than unsigned int once the buffer
- * API is cleaned up
- *
- * Release "space" bytes in the given buffer that was previously reserved.
- *
- * Requires:
- *
- *\li 'msg' be valid.
- *
- *\li 'space' is less than or equal to the total amount of space reserved
- * via prior calls to dns_message_renderreserve().
- *
- *\li dns_message_renderbegin() was called.
- */
-
-isc_result_t
-dns_message_rendersection(dns_message_t *msg, dns_section_t section,
- unsigned int options);
-/*%<
- * Render all names, rdatalists, etc from the given section at the
- * specified priority or higher.
- *
- * Requires:
- *\li 'msg' be valid.
- *
- *\li 'section' be a valid section.
- *
- *\li dns_message_renderbegin() was called.
- *
- * Returns:
- *\li #ISC_R_SUCCESS -- all records were written, and there are
- * no more records for this section.
- *\li #ISC_R_NOSPACE -- Not enough room in the buffer to write
- * all records requested.
- *\li #DNS_R_MOREDATA -- All requested records written, and there
- * are records remaining for this section.
- */
-
-void
-dns_message_renderheader(dns_message_t *msg, isc_buffer_t *target);
-/*%<
- * Render the message header. This is implicitly called by
- * dns_message_renderend().
- *
- * Requires:
- *
- *\li 'msg' be a valid message.
- *
- *\li dns_message_renderbegin() was called.
- *
- *\li 'target' is a valid buffer with enough space to hold a message header
- */
-
-isc_result_t
-dns_message_renderend(dns_message_t *msg);
-/*%<
- * Finish rendering to the buffer. Note that more data can be in the
- * 'msg' structure. Destroying the structure will free this, or in a multi-
- * part EDNS1 message this data can be rendered to another buffer later.
- *
- * Requires:
- *
- *\li 'msg' be a valid message.
- *
- *\li dns_message_renderbegin() was called.
- *
- * Returns:
- *\li #ISC_R_SUCCESS -- all is well.
- */
-
-void
-dns_message_renderreset(dns_message_t *msg);
-/*%<
- * Reset the message so that it may be rendered again.
- *
- * Notes:
- *
- *\li If dns_message_renderbegin() has been called, dns_message_renderend()
- * must be called before calling this function.
- *
- * Requires:
- *
- *\li 'msg' be a valid message with rendering intent.
- */
-
-isc_result_t
-dns_message_firstname(dns_message_t *msg, dns_section_t section);
-/*%<
- * Set internal per-section name pointer to the beginning of the section.
- *
- * The functions dns_message_firstname() and dns_message_nextname() may
- * be used for iterating over the owner names in a section.
- *
- * Requires:
- *
- *\li 'msg' be valid.
- *
- *\li 'section' be a valid section.
- *
- * Returns:
- *\li #ISC_R_SUCCESS -- All is well.
- *\li #ISC_R_NOMORE -- No names on given section.
- */
-
-isc_result_t
-dns_message_nextname(dns_message_t *msg, dns_section_t section);
-/*%<
- * Sets the internal per-section name pointer to point to the next name
- * in that section.
- *
- * Requires:
- *
- * \li 'msg' be valid.
- *
- *\li 'section' be a valid section.
- *
- *\li dns_message_firstname() must have been called on this section,
- * and the result was ISC_R_SUCCESS.
- *
- * Returns:
- *\li #ISC_R_SUCCESS -- All is well.
- *\li #ISC_R_NOMORE -- No more names in given section.
- */
-
-void
-dns_message_currentname(dns_message_t *msg, dns_section_t section,
- dns_name_t **name);
-/*%<
- * Sets 'name' to point to the name where the per-section internal name
- * pointer is currently set.
- *
- * This function returns the name in the database, so any data associated
- * with it (via the name's "list" member) contains the actual rdatasets.
- *
- * Requires:
- *
- *\li 'msg' be valid.
- *
- *\li 'name' be non-NULL, and *name be NULL.
- *
- *\li 'section' be a valid section.
- *
- *\li dns_message_firstname() must have been called on this section,
- * and the result of it and any dns_message_nextname() calls was
- * #ISC_R_SUCCESS.
- */
-
-isc_result_t
-dns_message_findname(dns_message_t *msg, dns_section_t section,
- dns_name_t *target, dns_rdatatype_t type,
- dns_rdatatype_t covers, dns_name_t **foundname,
- dns_rdataset_t **rdataset);
-/*%<
- * Search for a name in the specified section. If it is found, *name is
- * set to point to the name, and *rdataset is set to point to the found
- * rdataset (if type is specified as other than dns_rdatatype_any).
- *
- * Requires:
- *\li 'msg' be valid.
- *
- *\li 'section' be a valid section.
- *
- *\li If a pointer to the name is desired, 'foundname' should be non-NULL.
- * If it is non-NULL, '*foundname' MUST be NULL.
- *
- *\li If a type other than dns_datatype_any is searched for, 'rdataset'
- * may be non-NULL, '*rdataset' be NULL, and will point at the found
- * rdataset. If the type is dns_datatype_any, 'rdataset' must be NULL.
- *
- *\li 'target' be a valid name.
- *
- *\li 'type' be a valid type.
- *
- *\li If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type.
- * Otherwise it should be 0.
- *
- * Returns:
- *\li #ISC_R_SUCCESS -- all is well.
- *\li #DNS_R_NXDOMAIN -- name does not exist in that section.
- *\li #DNS_R_NXRRSET -- The name does exist, but the desired
- * type does not.
- */
-
-isc_result_t
-dns_message_findtype(dns_name_t *name, dns_rdatatype_t type,
- dns_rdatatype_t covers, dns_rdataset_t **rdataset);
-/*%<
- * Search the name for the specified type. If it is found, *rdataset is
- * filled in with a pointer to that rdataset.
- *
- * Requires:
- *\li if '**rdataset' is non-NULL, *rdataset needs to be NULL.
- *
- *\li 'type' be a valid type, and NOT dns_rdatatype_any.
- *
- *\li If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type.
- * Otherwise it should be 0.
- *
- * Returns:
- *\li #ISC_R_SUCCESS -- all is well.
- *\li #ISC_R_NOTFOUND -- the desired type does not exist.
- */
-
-isc_result_t
-dns_message_find(dns_name_t *name, dns_rdataclass_t rdclass,
- dns_rdatatype_t type, dns_rdatatype_t covers,
- dns_rdataset_t **rdataset);
-/*%<
- * Search the name for the specified rdclass and type. If it is found,
- * *rdataset is filled in with a pointer to that rdataset.
- *
- * Requires:
- *\li if '**rdataset' is non-NULL, *rdataset needs to be NULL.
- *
- *\li 'type' be a valid type, and NOT dns_rdatatype_any.
- *
- *\li If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type.
- * Otherwise it should be 0.
- *
- * Returns:
- *\li #ISC_R_SUCCESS -- all is well.
- *\li #ISC_R_NOTFOUND -- the desired type does not exist.
- */
-
-void
-dns_message_movename(dns_message_t *msg, dns_name_t *name,
- dns_section_t fromsection,
- dns_section_t tosection);
-/*%<
- * Move a name from one section to another.
- *
- * Requires:
- *
- *\li 'msg' be valid.
- *
- *\li 'name' must be a name already in 'fromsection'.
- *
- *\li 'fromsection' must be a valid section.
- *
- *\li 'tosection' must be a valid section.
- */
-
-void
-dns_message_addname(dns_message_t *msg, dns_name_t *name,
- dns_section_t section);
-/*%<
- * Adds the name to the given section.
- *
- * It is the caller's responsibility to enforce any unique name requirements
- * in a section.
- *
- * Requires:
- *
- *\li 'msg' be valid, and be a renderable message.
- *
- *\li 'name' be a valid absolute name.
- *
- *\li 'section' be a named section.
- */
-
-void
-dns_message_removename(dns_message_t *msg, dns_name_t *name,
- dns_section_t section);
-/*%<
- * Remove a existing name from a given section.
- *
- * It is the caller's responsibility to ensure the name is part of the
- * given section.
- *
- * Requires:
- *
- *\li 'msg' be valid, and be a renderable message.
- *
- *\li 'name' be a valid absolute name.
- *
- *\li 'section' be a named section.
- */
-
-
-/*
- * LOANOUT FUNCTIONS
- *
- * Each of these functions loan a particular type of data to the caller.
- * The storage for these will vanish when the message is destroyed or
- * reset, and must NOT be used after these operations.
- */
-
-isc_result_t
-dns_message_gettempname(dns_message_t *msg, dns_name_t **item);
-/*%<
- * Return a name that can be used for any temporary purpose, including
- * inserting into the message's linked lists. The name must be returned
- * to the message code using dns_message_puttempname() or inserted into
- * one of the message's sections before the message is destroyed.
- *
- * It is the caller's responsibility to initialize this name.
- *
- * Requires:
- *\li msg be a valid message
- *
- *\li item != NULL && *item == NULL
- *
- * Returns:
- *\li #ISC_R_SUCCESS -- All is well.
- *\li #ISC_R_NOMEMORY -- No item can be allocated.
- */
-
-isc_result_t
-dns_message_gettempoffsets(dns_message_t *msg, dns_offsets_t **item);
-/*%<
- * Return an offsets array that can be used for any temporary purpose,
- * such as attaching to a temporary name. The offsets will be freed
- * when the message is destroyed or reset.
- *
- * Requires:
- *\li msg be a valid message
- *
- *\li item != NULL && *item == NULL
- *
- * Returns:
- *\li #ISC_R_SUCCESS -- All is well.
- *\li #ISC_R_NOMEMORY -- No item can be allocated.
- */
-
-isc_result_t
-dns_message_gettemprdata(dns_message_t *msg, dns_rdata_t **item);
-/*%<
- * Return a rdata that can be used for any temporary purpose, including
- * inserting into the message's linked lists. The rdata will be freed
- * when the message is destroyed or reset.
- *
- * Requires:
- *\li msg be a valid message
- *
- *\li item != NULL && *item == NULL
- *
- * Returns:
- *\li #ISC_R_SUCCESS -- All is well.
- *\li #ISC_R_NOMEMORY -- No item can be allocated.
- */
-
-isc_result_t
-dns_message_gettemprdataset(dns_message_t *msg, dns_rdataset_t **item);
-/*%<
- * Return a rdataset that can be used for any temporary purpose, including
- * inserting into the message's linked lists. The name must be returned
- * to the message code using dns_message_puttempname() or inserted into
- * one of the message's sections before the message is destroyed.
- *
- * Requires:
- *\li msg be a valid message
- *
- *\li item != NULL && *item == NULL
- *
- * Returns:
- *\li #ISC_R_SUCCESS -- All is well.
- *\li #ISC_R_NOMEMORY -- No item can be allocated.
- */
-
-isc_result_t
-dns_message_gettemprdatalist(dns_message_t *msg, dns_rdatalist_t **item);
-/*%<
- * Return a rdatalist that can be used for any temporary purpose, including
- * inserting into the message's linked lists. The rdatalist will be
- * destroyed when the message is destroyed or reset.
- *
- * Requires:
- *\li msg be a valid message
- *
- *\li item != NULL && *item == NULL
- *
- * Returns:
- *\li #ISC_R_SUCCESS -- All is well.
- *\li #ISC_R_NOMEMORY -- No item can be allocated.
- */
-
-void
-dns_message_puttempname(dns_message_t *msg, dns_name_t **item);
-/*%<
- * Return a borrowed name to the message's name free list.
- *
- * Requires:
- *\li msg be a valid message
- *
- *\li item != NULL && *item point to a name returned by
- * dns_message_gettempname()
- *
- * Ensures:
- *\li *item == NULL
- */
-
-void
-dns_message_puttemprdata(dns_message_t *msg, dns_rdata_t **item);
-/*%<
- * Return a borrowed rdata to the message's rdata free list.
- *
- * Requires:
- *\li msg be a valid message
- *
- *\li item != NULL && *item point to a rdata returned by
- * dns_message_gettemprdata()
- *
- * Ensures:
- *\li *item == NULL
- */
-
-void
-dns_message_puttemprdataset(dns_message_t *msg, dns_rdataset_t **item);
-/*%<
- * Return a borrowed rdataset to the message's rdataset free list.
- *
- * Requires:
- *\li msg be a valid message
- *
- *\li item != NULL && *item point to a rdataset returned by
- * dns_message_gettemprdataset()
- *
- * Ensures:
- *\li *item == NULL
- */
-
-void
-dns_message_puttemprdatalist(dns_message_t *msg, dns_rdatalist_t **item);
-/*%<
- * Return a borrowed rdatalist to the message's rdatalist free list.
- *
- * Requires:
- *\li msg be a valid message
- *
- *\li item != NULL && *item point to a rdatalist returned by
- * dns_message_gettemprdatalist()
- *
- * Ensures:
- *\li *item == NULL
- */
-
-isc_result_t
-dns_message_peekheader(isc_buffer_t *source, dns_messageid_t *idp,
- unsigned int *flagsp);
-/*%<
- * Assume the remaining region of "source" is a DNS message. Peek into
- * it and fill in "*idp" with the message id, and "*flagsp" with the flags.
- *
- * Requires:
- *
- *\li source != NULL
- *
- * Ensures:
- *
- *\li if (idp != NULL) *idp == message id.
- *
- *\li if (flagsp != NULL) *flagsp == message flags.
- *
- * Returns:
- *
- *\li #ISC_R_SUCCESS -- all is well.
- *
- *\li #ISC_R_UNEXPECTEDEND -- buffer doesn't contain enough for a header.
- */
-
-isc_result_t
-dns_message_reply(dns_message_t *msg, isc_boolean_t want_question_section);
-/*%<
- * Start formatting a reply to the query in 'msg'.
- *
- * Requires:
- *
- *\li 'msg' is a valid message with parsing intent, and contains a query.
- *
- * Ensures:
- *
- *\li The message will have a rendering intent. If 'want_question_section'
- * is true, the message opcode is query or notify, and the question
- * section is present and properly formatted, then the question section
- * will be included in the reply. All other sections will be cleared.
- * The QR flag will be set, the RD flag will be preserved, and all other
- * flags will be cleared.
- *
- * Returns:
- *
- *\li #ISC_R_SUCCESS -- all is well.
- *
- *\li #DNS_R_FORMERR -- the header or question section of the
- * message is invalid, replying is impossible.
- * If DNS_R_FORMERR is returned when
- * want_question_section is ISC_FALSE, then
- * it's the header section that's bad;
- * otherwise either of the header or question
- * sections may be bad.
- */
-
-dns_rdataset_t *
-dns_message_getopt(dns_message_t *msg);
-/*%<
- * Get the OPT record for 'msg'.
- *
- * Requires:
- *
- *\li 'msg' is a valid message.
- *
- * Returns:
- *
- *\li The OPT rdataset of 'msg', or NULL if there isn't one.
- */
-
-isc_result_t
-dns_message_setopt(dns_message_t *msg, dns_rdataset_t *opt);
-/*%<
- * Set the OPT record for 'msg'.
- *
- * Requires:
- *
- *\li 'msg' is a valid message with rendering intent
- * and no sections have been rendered.
- *
- *\li 'opt' is a valid OPT record.
- *
- * Ensures:
- *
- *\li The OPT record has either been freed or ownership of it has
- * been transferred to the message.
- *
- *\li If ISC_R_SUCCESS was returned, the OPT record will be rendered
- * when dns_message_renderend() is called.
- *
- * Returns:
- *
- *\li #ISC_R_SUCCESS -- all is well.
- *
- *\li #ISC_R_NOSPACE -- there is no space for the OPT record.
- */
-
-dns_rdataset_t *
-dns_message_gettsig(dns_message_t *msg, dns_name_t **owner);
-/*%<
- * Get the TSIG record and owner for 'msg'.
- *
- * Requires:
- *
- *\li 'msg' is a valid message.
- *\li 'owner' is NULL or *owner is NULL.
- *
- * Returns:
- *
- *\li The TSIG rdataset of 'msg', or NULL if there isn't one.
- *
- * Ensures:
- *
- * \li If 'owner' is not NULL, it will point to the owner name.
- */
-
-isc_result_t
-dns_message_settsigkey(dns_message_t *msg, dns_tsigkey_t *key);
-/*%<
- * Set the tsig key for 'msg'. This is only necessary for when rendering a
- * query or parsing a response. The key (if non-NULL) is attached to, and
- * will be detached when the message is destroyed.
- *
- * Requires:
- *
- *\li 'msg' is a valid message with rendering intent,
- * dns_message_renderbegin() has been called, and no sections have been
- * rendered.
- *\li 'key' is a valid tsig key or NULL.
- *
- * Returns:
- *
- *\li #ISC_R_SUCCESS -- all is well.
- *
- *\li #ISC_R_NOSPACE -- there is no space for the TSIG record.
- */
-
-dns_tsigkey_t *
-dns_message_gettsigkey(dns_message_t *msg);
-/*%<
- * Gets the tsig key for 'msg'.
- *
- * Requires:
- *
- *\li 'msg' is a valid message
- */
-
-isc_result_t
-dns_message_setquerytsig(dns_message_t *msg, isc_buffer_t *querytsig);
-/*%<
- * Indicates that 'querytsig' is the TSIG from the signed query for which
- * 'msg' is the response. This is also used for chained TSIGs in TCP
- * responses.
- *
- * Requires:
- *
- *\li 'querytsig' is a valid buffer as returned by dns_message_getquerytsig()
- * or NULL
- *
- *\li 'msg' is a valid message
- *
- * Returns:
- *
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMEMORY
- */
-
-isc_result_t
-dns_message_getquerytsig(dns_message_t *msg, isc_mem_t *mctx,
- isc_buffer_t **querytsig);
-/*%<
- * Gets the tsig from the TSIG from the signed query 'msg'. This is also used
- * for chained TSIGs in TCP responses. Unlike dns_message_gettsig, this makes
- * a copy of the data, so can be used if the message is destroyed.
- *
- * Requires:
- *
- *\li 'msg' is a valid signed message
- *\li 'mctx' is a valid memory context
- *\li querytsig != NULL && *querytsig == NULL
- *
- * Returns:
- *
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMEMORY
- *
- * Ensures:
- *\li 'tsig' points to NULL or an allocated buffer which must be freed
- * by the caller.
- */
-
-dns_rdataset_t *
-dns_message_getsig0(dns_message_t *msg, dns_name_t **owner);
-/*%<
- * Get the SIG(0) record and owner for 'msg'.
- *
- * Requires:
- *
- *\li 'msg' is a valid message.
- *\li 'owner' is NULL or *owner is NULL.
- *
- * Returns:
- *
- *\li The SIG(0) rdataset of 'msg', or NULL if there isn't one.
- *
- * Ensures:
- *
- * \li If 'owner' is not NULL, it will point to the owner name.
- */
-
-isc_result_t
-dns_message_setsig0key(dns_message_t *msg, dst_key_t *key);
-/*%<
- * Set the SIG(0) key for 'msg'.
- *
- * Requires:
- *
- *\li 'msg' is a valid message with rendering intent,
- * dns_message_renderbegin() has been called, and no sections have been
- * rendered.
- *\li 'key' is a valid sig key or NULL.
- *
- * Returns:
- *
- *\li #ISC_R_SUCCESS -- all is well.
- *
- *\li #ISC_R_NOSPACE -- there is no space for the SIG(0) record.
- */
-
-dst_key_t *
-dns_message_getsig0key(dns_message_t *msg);
-/*%<
- * Gets the SIG(0) key for 'msg'.
- *
- * Requires:
- *
- *\li 'msg' is a valid message
- */
-
-void
-dns_message_takebuffer(dns_message_t *msg, isc_buffer_t **buffer);
-/*%<
- * Give the *buffer to the message code to clean up when it is no
- * longer needed. This is usually when the message is reset or
- * destroyed.
- *
- * Requires:
- *
- *\li msg be a valid message.
- *
- *\li buffer != NULL && *buffer is a valid isc_buffer_t, which was
- * dynamically allocated via isc_buffer_allocate().
- */
-
-isc_result_t
-dns_message_signer(dns_message_t *msg, dns_name_t *signer);
-/*%<
- * If this message was signed, return the identity of the signer.
- * Unless ISC_R_NOTFOUND is returned, signer will reflect the name of the
- * key that signed the message.
- *
- * Requires:
- *
- *\li msg is a valid parsed message.
- *\li signer is a valid name
- *
- * Returns:
- *
- *\li #ISC_R_SUCCESS - the message was signed, and *signer
- * contains the signing identity
- *
- *\li #ISC_R_NOTFOUND - no TSIG or SIG(0) record is present in the
- * message
- *
- *\li #DNS_R_TSIGVERIFYFAILURE - the message was signed by a TSIG, but the
- * signature failed to verify
- *
- *\li #DNS_R_TSIGERRORSET - the message was signed by a TSIG and
- * verified, but the query was rejected by
- * the server
- *
- *\li #DNS_R_NOIDENTITY - the message was signed by a TSIG and
- * verified, but the key has no identity since
- * it was generated by an unsigned TKEY process
- *
- *\li #DNS_R_SIGINVALID - the message was signed by a SIG(0), but
- * the signature failed to verify
- *
- *\li #DNS_R_NOTVERIFIEDYET - the message was signed by a TSIG or SIG(0),
- * but the signature has not been verified yet
- */
-
-isc_result_t
-dns_message_checksig(dns_message_t *msg, dns_view_t *view);
-/*%<
- * If this message was signed, verify the signature.
- *
- * Requires:
- *
- *\li msg is a valid parsed message.
- *\li view is a valid view or NULL
- *
- * Returns:
- *
- *\li #ISC_R_SUCCESS - the message was unsigned, or the message
- * was signed correctly.
- *
- *\li #DNS_R_EXPECTEDTSIG - A TSIG was expected, but not seen
- *\li #DNS_R_UNEXPECTEDTSIG - A TSIG was seen but not expected
- *\li #DNS_R_TSIGVERIFYFAILURE - The TSIG failed to verify
- */
-
-isc_result_t
-dns_message_rechecksig(dns_message_t *msg, dns_view_t *view);
-/*%<
- * Reset the signature state and then if the message was signed,
- * verify the message.
- *
- * Requires:
- *
- *\li msg is a valid parsed message.
- *\li view is a valid view or NULL
- *
- * Returns:
- *
- *\li #ISC_R_SUCCESS - the message was unsigned, or the message
- * was signed correctly.
- *
- *\li #DNS_R_EXPECTEDTSIG - A TSIG was expected, but not seen
- *\li #DNS_R_UNEXPECTEDTSIG - A TSIG was seen but not expected
- *\li #DNS_R_TSIGVERIFYFAILURE - The TSIG failed to verify
- */
-
-void
-dns_message_resetsig(dns_message_t *msg);
-/*%<
- * Reset the signature state.
- *
- * Requires:
- *\li 'msg' is a valid parsed message.
- */
-
-isc_region_t *
-dns_message_getrawmessage(dns_message_t *msg);
-/*%<
- * Retrieve the raw message in compressed wire format. The message must
- * have been successfully parsed for it to have been saved.
- *
- * Requires:
- *\li msg is a valid parsed message.
- *
- * Returns:
- *\li NULL if there is no saved message.
- * a pointer to a region which refers the dns message.
- */
-
-void
-dns_message_setsortorder(dns_message_t *msg, dns_rdatasetorderfunc_t order,
- const void *order_arg);
-/*%<
- * Define the order in which RR sets get rendered by
- * dns_message_rendersection() to be the ascending order
- * defined by the integer value returned by 'order' when
- * given each RR and 'arg' as arguments. If 'order' and
- * 'order_arg' are NULL, a default order is used.
- *
- * Requires:
- *\li msg be a valid message.
- *\li order_arg is NULL if and only if order is NULL.
- */
-
-void
-dns_message_settimeadjust(dns_message_t *msg, int timeadjust);
-/*%<
- * Adjust the time used to sign/verify a message by timeadjust.
- * Currently only TSIG.
- *
- * Requires:
- *\li msg be a valid message.
- */
-
-int
-dns_message_gettimeadjust(dns_message_t *msg);
-/*%<
- * Return the current time adjustment.
- *
- * Requires:
- *\li msg be a valid message.
- */
-
-isc_result_t
-dns_message_buildopt(dns_message_t *msg, dns_rdataset_t **opt,
- unsigned int version, isc_uint16_t udpsize,
- unsigned int flags, dns_ednsopt_t *ednsopts, size_t count);
-/*%<
- * Built a opt record.
- *
- * Requires:
- * \li msg be a valid message.
- * \li opt to be a non NULL and *opt to be NULL.
- *
- * Returns:
- * \li ISC_R_SUCCESS on success.
- * \li ISC_R_NOMEMORY
- * \li ISC_R_NOSPACE
- * \li other.
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_MESSAGE_H */
diff --git a/contrib/bind9/lib/dns/include/dns/name.h b/contrib/bind9/lib/dns/include/dns/name.h
deleted file mode 100644
index 1a88e53264b4..000000000000
--- a/contrib/bind9/lib/dns/include/dns/name.h
+++ /dev/null
@@ -1,1364 +0,0 @@
-/*
- * Copyright (C) 2004-2007, 2009-2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: name.h,v 1.137 2011/01/13 04:59:26 tbox Exp $ */
-
-#ifndef DNS_NAME_H
-#define DNS_NAME_H 1
-
-/*****
- ***** Module Info
- *****/
-
-/*! \file dns/name.h
- * \brief
- * Provides facilities for manipulating DNS names and labels, including
- * conversions to and from wire format and text format.
- *
- * Given the large number of names possible in a nameserver, and because
- * names occur in rdata, it was important to come up with a very efficient
- * way of storing name data, but at the same time allow names to be
- * manipulated. The decision was to store names in uncompressed wire format,
- * and not to make them fully abstracted objects; i.e. certain parts of the
- * server know names are stored that way. This saves a lot of memory, and
- * makes adding names to messages easy. Having much of the server know
- * the representation would be perilous, and we certainly don't want each
- * user of names to be manipulating such a low-level structure. This is
- * where the Names and Labels module comes in. The module allows name or
- * label handles to be created and attached to uncompressed wire format
- * regions. All name operations and conversions are done through these
- * handles.
- *
- * MP:
- *\li Clients of this module must impose any required synchronization.
- *
- * Reliability:
- *\li This module deals with low-level byte streams. Errors in any of
- * the functions are likely to crash the server or corrupt memory.
- *
- * Resources:
- *\li None.
- *
- * Security:
- *
- *\li *** WARNING ***
- *
- *\li dns_name_fromwire() deals with raw network data. An error in
- * this routine could result in the failure or hijacking of the server.
- *
- * Standards:
- *\li RFC1035
- *\li Draft EDNS0 (0)
- *\li Draft Binary Labels (2)
- *
- */
-
-/***
- *** Imports
- ***/
-
-#include <stdio.h>
-
-#include <isc/boolean.h>
-#include <isc/lang.h>
-#include <isc/magic.h>
-#include <isc/region.h> /* Required for storage size of dns_label_t. */
-
-#include <dns/types.h>
-
-ISC_LANG_BEGINDECLS
-
-/*****
- ***** Labels
- *****
- ***** A 'label' is basically a region. It contains one DNS wire format
- ***** label of type 00 (ordinary).
- *****/
-
-/*****
- ***** Names
- *****
- ***** A 'name' is a handle to a binary region. It contains a sequence of one
- ***** or more DNS wire format labels of type 00 (ordinary).
- ***** Note that all names are not required to end with the root label,
- ***** as they are in the actual DNS wire protocol.
- *****/
-
-/***
- *** Types
- ***/
-
-/*%
- * Clients are strongly discouraged from using this type directly, with
- * the exception of the 'link' and 'list' fields which may be used directly
- * for whatever purpose the client desires.
- */
-struct dns_name {
- unsigned int magic;
- unsigned char * ndata;
- unsigned int length;
- unsigned int labels;
- unsigned int attributes;
- unsigned char * offsets;
- isc_buffer_t * buffer;
- ISC_LINK(dns_name_t) link;
- ISC_LIST(dns_rdataset_t) list;
-};
-
-#define DNS_NAME_MAGIC ISC_MAGIC('D','N','S','n')
-
-#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 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. */
-#define DNS_NAME_CHECKREVERSE 0x0008 /*%< Used by rdata. */
-#define DNS_NAME_CHECKMX 0x0010 /*%< Used by rdata. */
-#define DNS_NAME_CHECKMXFAIL 0x0020 /*%< Used by rdata. */
-
-LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_rootname;
-LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_wildcardname;
-
-/*%
- * Standard size of a wire format name
- */
-#define DNS_NAME_MAXWIRE 255
-
-/*
- * Text output filter procedure.
- * 'target' is the buffer to be converted. The region to be converted
- * is from 'buffer'->base + 'used_org' to the end of the used region.
- */
-typedef isc_result_t (*dns_name_totextfilter_t)(isc_buffer_t *target,
- unsigned int used_org,
- isc_boolean_t absolute);
-
-/***
- *** Initialization
- ***/
-
-void
-dns_name_init(dns_name_t *name, unsigned char *offsets);
-/*%<
- * Initialize 'name'.
- *
- * Notes:
- * \li 'offsets' is never required to be non-NULL, but specifying a
- * dns_offsets_t for 'offsets' will improve the performance of most
- * name operations if the name is used more than once.
- *
- * Requires:
- * \li 'name' is not NULL and points to a struct dns_name.
- *
- * \li offsets == NULL or offsets is a dns_offsets_t.
- *
- * Ensures:
- * \li 'name' is a valid name.
- * \li dns_name_countlabels(name) == 0
- * \li dns_name_isabsolute(name) == ISC_FALSE
- */
-
-void
-dns_name_reset(dns_name_t *name);
-/*%<
- * Reinitialize 'name'.
- *
- * Notes:
- * \li This function distinguishes itself from dns_name_init() in two
- * key ways:
- *
- * \li + If any buffer is associated with 'name' (via dns_name_setbuffer()
- * or by being part of a dns_fixedname_t) the link to the buffer
- * is retained but the buffer itself is cleared.
- *
- * \li + Of the attributes associated with 'name', all are retained except
- * DNS_NAMEATTR_ABSOLUTE.
- *
- * Requires:
- * \li 'name' is a valid name.
- *
- * Ensures:
- * \li 'name' is a valid name.
- * \li dns_name_countlabels(name) == 0
- * \li dns_name_isabsolute(name) == ISC_FALSE
- */
-
-void
-dns_name_invalidate(dns_name_t *name);
-/*%<
- * Make 'name' invalid.
- *
- * Requires:
- * \li 'name' is a valid name.
- *
- * Ensures:
- * \li If assertion checking is enabled, future attempts to use 'name'
- * without initializing it will cause an assertion failure.
- *
- * \li If the name had a dedicated buffer, that association is ended.
- */
-
-
-/***
- *** Dedicated Buffers
- ***/
-
-void
-dns_name_setbuffer(dns_name_t *name, isc_buffer_t *buffer);
-/*%<
- * Dedicate a buffer for use with 'name'.
- *
- * Notes:
- * \li Specification of a target buffer in dns_name_fromwire(),
- * dns_name_fromtext(), and dns_name_concatenate() is optional if
- * 'name' has a dedicated buffer.
- *
- * \li The caller must not write to buffer until the name has been
- * invalidated or is otherwise known not to be in use.
- *
- * \li If buffer is NULL and the name previously had a dedicated buffer,
- * than that buffer is no longer dedicated to use with this name.
- * The caller is responsible for ensuring that the storage used by
- * the name remains valid.
- *
- * Requires:
- * \li 'name' is a valid name.
- *
- * \li 'buffer' is a valid binary buffer and 'name' doesn't have a
- * dedicated buffer already, or 'buffer' is NULL.
- */
-
-isc_boolean_t
-dns_name_hasbuffer(const dns_name_t *name);
-/*%<
- * Does 'name' have a dedicated buffer?
- *
- * Requires:
- * \li 'name' is a valid name.
- *
- * Returns:
- * \li ISC_TRUE 'name' has a dedicated buffer.
- * \li ISC_FALSE 'name' does not have a dedicated buffer.
- */
-
-/***
- *** Properties
- ***/
-
-isc_boolean_t
-dns_name_isabsolute(const dns_name_t *name);
-/*%<
- * Does 'name' end in the root label?
- *
- * Requires:
- * \li 'name' is a valid name
- *
- * Returns:
- * \li TRUE The last label in 'name' is the root label.
- * \li FALSE The last label in 'name' is not the root label.
- */
-
-isc_boolean_t
-dns_name_iswildcard(const dns_name_t *name);
-/*%<
- * Is 'name' a wildcard name?
- *
- * Requires:
- * \li 'name' is a valid name
- *
- * \li dns_name_countlabels(name) > 0
- *
- * Returns:
- * \li TRUE The least significant label of 'name' is '*'.
- * \li FALSE The least significant label of 'name' is not '*'.
- */
-
-unsigned int
-dns_name_hash(dns_name_t *name, isc_boolean_t case_sensitive);
-/*%<
- * Provide a hash value for 'name'.
- *
- * Note: if 'case_sensitive' is ISC_FALSE, then names which differ only in
- * case will have the same hash value.
- *
- * Requires:
- * \li 'name' is a valid name
- *
- * Returns:
- * \li A hash value
- */
-
-unsigned int
-dns_name_fullhash(dns_name_t *name, isc_boolean_t case_sensitive);
-/*%<
- * Provide a hash value for 'name'. Unlike dns_name_hash(), this function
- * always takes into account of the entire name to calculate the hash value.
- *
- * Note: if 'case_sensitive' is ISC_FALSE, then names which differ only in
- * case will have the same hash value.
- *
- * Requires:
- *\li 'name' is a valid name
- *
- * Returns:
- *\li A hash value
- */
-
-unsigned int
-dns_name_hashbylabel(dns_name_t *name, isc_boolean_t case_sensitive);
-/*%<
- * Provide a hash value for 'name', where the hash value is the sum
- * of the hash values of each label.
- *
- * Note: if 'case_sensitive' is ISC_FALSE, then names which differ only in
- * case will have the same hash value.
- *
- * Requires:
- *\li 'name' is a valid name
- *
- * Returns:
- *\li A hash value
- */
-
-/*
- *** Comparisons
- ***/
-
-dns_namereln_t
-dns_name_fullcompare(const dns_name_t *name1, const dns_name_t *name2,
- int *orderp, unsigned int *nlabelsp);
-/*%<
- * Determine the relative ordering under the DNSSEC order relation of
- * 'name1' and 'name2', and also determine the hierarchical
- * relationship of the names.
- *
- * Note: It makes no sense for one of the names to be relative and the
- * other absolute. If both names are relative, then to be meaningfully
- * compared the caller must ensure that they are both relative to the
- * same domain.
- *
- * Requires:
- *\li 'name1' is a valid name
- *
- *\li dns_name_countlabels(name1) > 0
- *
- *\li 'name2' is a valid name
- *
- *\li dns_name_countlabels(name2) > 0
- *
- *\li orderp and nlabelsp are valid pointers.
- *
- *\li Either name1 is absolute and name2 is absolute, or neither is.
- *
- * Ensures:
- *
- *\li *orderp is < 0 if name1 < name2, 0 if name1 = name2, > 0 if
- * name1 > name2.
- *
- *\li *nlabelsp is the number of common significant labels.
- *
- * Returns:
- *\li dns_namereln_none There's no hierarchical relationship
- * between name1 and name2.
- *\li dns_namereln_contains name1 properly contains name2; i.e.
- * name2 is a proper subdomain of name1.
- *\li dns_namereln_subdomain name1 is a proper subdomain of name2.
- *\li dns_namereln_equal name1 and name2 are equal.
- *\li dns_namereln_commonancestor name1 and name2 share a common
- * ancestor.
- */
-
-int
-dns_name_compare(const dns_name_t *name1, const dns_name_t *name2);
-/*%<
- * Determine the relative ordering under the DNSSEC order relation of
- * 'name1' and 'name2'.
- *
- * Note: It makes no sense for one of the names to be relative and the
- * other absolute. If both names are relative, then to be meaningfully
- * compared the caller must ensure that they are both relative to the
- * same domain.
- *
- * Requires:
- * \li 'name1' is a valid name
- *
- * \li 'name2' is a valid name
- *
- * \li Either name1 is absolute and name2 is absolute, or neither is.
- *
- * Returns:
- * \li < 0 'name1' is less than 'name2'
- * \li 0 'name1' is equal to 'name2'
- * \li > 0 'name1' is greater than 'name2'
- */
-
-isc_boolean_t
-dns_name_equal(const dns_name_t *name1, const dns_name_t *name2);
-/*%<
- * Are 'name1' and 'name2' equal?
- *
- * Notes:
- * \li Because it only needs to test for equality, dns_name_equal() can be
- * significantly faster than dns_name_fullcompare() or dns_name_compare().
- *
- * \li Offsets tables are not used in the comparision.
- *
- * \li It makes no sense for one of the names to be relative and the
- * other absolute. If both names are relative, then to be meaningfully
- * compared the caller must ensure that they are both relative to the
- * same domain.
- *
- * Requires:
- * \li 'name1' is a valid name
- *
- * \li 'name2' is a valid name
- *
- * \li Either name1 is absolute and name2 is absolute, or neither is.
- *
- * Returns:
- * \li ISC_TRUE 'name1' and 'name2' are equal
- * \li ISC_FALSE 'name1' and 'name2' are not equal
- */
-
-isc_boolean_t
-dns_name_caseequal(const dns_name_t *name1, const dns_name_t *name2);
-/*%<
- * Case sensitive version of dns_name_equal().
- */
-
-int
-dns_name_rdatacompare(const dns_name_t *name1, const dns_name_t *name2);
-/*%<
- * Compare two names as if they are part of rdata in DNSSEC canonical
- * form.
- *
- * Requires:
- * \li 'name1' is a valid absolute name
- *
- * \li dns_name_countlabels(name1) > 0
- *
- * \li 'name2' is a valid absolute name
- *
- * \li dns_name_countlabels(name2) > 0
- *
- * Returns:
- * \li < 0 'name1' is less than 'name2'
- * \li 0 'name1' is equal to 'name2'
- * \li > 0 'name1' is greater than 'name2'
- */
-
-isc_boolean_t
-dns_name_issubdomain(const dns_name_t *name1, const dns_name_t *name2);
-/*%<
- * Is 'name1' a subdomain of 'name2'?
- *
- * Notes:
- * \li name1 is a subdomain of name2 if name1 is contained in name2, or
- * name1 equals name2.
- *
- * \li It makes no sense for one of the names to be relative and the
- * other absolute. If both names are relative, then to be meaningfully
- * compared the caller must ensure that they are both relative to the
- * same domain.
- *
- * Requires:
- * \li 'name1' is a valid name
- *
- * \li 'name2' is a valid name
- *
- * \li Either name1 is absolute and name2 is absolute, or neither is.
- *
- * Returns:
- * \li TRUE 'name1' is a subdomain of 'name2'
- * \li FALSE 'name1' is not a subdomain of 'name2'
- */
-
-isc_boolean_t
-dns_name_matcheswildcard(const dns_name_t *name, const dns_name_t *wname);
-/*%<
- * Does 'name' match the wildcard specified in 'wname'?
- *
- * Notes:
- * \li name matches the wildcard specified in wname if all labels
- * following the wildcard in wname are identical to the same number
- * of labels at the end of name.
- *
- * \li It makes no sense for one of the names to be relative and the
- * other absolute. If both names are relative, then to be meaningfully
- * compared the caller must ensure that they are both relative to the
- * same domain.
- *
- * Requires:
- * \li 'name' is a valid name
- *
- * \li dns_name_countlabels(name) > 0
- *
- * \li 'wname' is a valid name
- *
- * \li dns_name_countlabels(wname) > 0
- *
- * \li dns_name_iswildcard(wname) is true
- *
- * \li Either name is absolute and wname is absolute, or neither is.
- *
- * Returns:
- * \li TRUE 'name' matches the wildcard specified in 'wname'
- * \li FALSE 'name' does not match the wildcard specified in 'wname'
- */
-
-/***
- *** Labels
- ***/
-
-unsigned int
-dns_name_countlabels(const dns_name_t *name);
-/*%<
- * How many labels does 'name' have?
- *
- * Notes:
- * \li In this case, as in other places, a 'label' is an ordinary label.
- *
- * Requires:
- * \li 'name' is a valid name
- *
- * Ensures:
- * \li The result is <= 128.
- *
- * Returns:
- * \li The number of labels in 'name'.
- */
-
-void
-dns_name_getlabel(const dns_name_t *name, unsigned int n, dns_label_t *label);
-/*%<
- * Make 'label' refer to the 'n'th least significant label of 'name'.
- *
- * Notes:
- * \li Numbering starts at 0.
- *
- * \li Given "rc.vix.com.", the label 0 is "rc", and label 3 is the
- * root label.
- *
- * \li 'label' refers to the same memory as 'name', so 'name' must not
- * be changed while 'label' is still in use.
- *
- * Requires:
- * \li n < dns_name_countlabels(name)
- */
-
-void
-dns_name_getlabelsequence(const dns_name_t *source, unsigned int first,
- unsigned int n, dns_name_t *target);
-/*%<
- * Make 'target' refer to the 'n' labels including and following 'first'
- * in 'source'.
- *
- * Notes:
- * \li Numbering starts at 0.
- *
- * \li Given "rc.vix.com.", the label 0 is "rc", and label 3 is the
- * root label.
- *
- * \li 'target' refers to the same memory as 'source', so 'source'
- * must not be changed while 'target' is still in use.
- *
- * Requires:
- * \li 'source' and 'target' are valid names.
- *
- * \li first < dns_name_countlabels(name)
- *
- * \li first + n <= dns_name_countlabels(name)
- */
-
-
-void
-dns_name_clone(const dns_name_t *source, dns_name_t *target);
-/*%<
- * Make 'target' refer to the same name as 'source'.
- *
- * Notes:
- *
- * \li 'target' refers to the same memory as 'source', so 'source'
- * must not be changed while 'target' is still in use.
- *
- * \li This call is functionally equivalent to:
- *
- * \code
- * dns_name_getlabelsequence(source, 0,
- * dns_name_countlabels(source),
- * target);
- * \endcode
- *
- * but is more efficient. Also, dns_name_clone() works even if 'source'
- * is empty.
- *
- * Requires:
- *
- * \li 'source' is a valid name.
- *
- * \li 'target' is a valid name that is not read-only.
- */
-
-/***
- *** Conversions
- ***/
-
-void
-dns_name_fromregion(dns_name_t *name, const isc_region_t *r);
-/*%<
- * Make 'name' refer to region 'r'.
- *
- * Note:
- * \li If the conversion encounters a root label before the end of the
- * region the conversion stops and the length is set to the length
- * so far converted. A maximum of 255 bytes is converted.
- *
- * Requires:
- * \li The data in 'r' is a sequence of one or more type 00 or type 01000001
- * labels.
- */
-
-void
-dns_name_toregion(dns_name_t *name, isc_region_t *r);
-/*%<
- * Make 'r' refer to 'name'.
- *
- * Requires:
- *
- * \li 'name' is a valid name.
- *
- * \li 'r' is a valid region.
- */
-
-isc_result_t
-dns_name_fromwire(dns_name_t *name, isc_buffer_t *source,
- dns_decompress_t *dctx, unsigned int options,
- isc_buffer_t *target);
-/*%<
- * Copy the possibly-compressed name at source (active region) into target,
- * decompressing it.
- *
- * Notes:
- * \li Decompression policy is controlled by 'dctx'.
- *
- * \li If DNS_NAME_DOWNCASE is set, any uppercase letters in 'source' will be
- * downcased when they are copied into 'target'.
- *
- * Security:
- *
- * \li *** WARNING ***
- *
- * \li This routine will often be used when 'source' contains raw network
- * data. A programming error in this routine could result in a denial
- * of service, or in the hijacking of the server.
- *
- * Requires:
- *
- * \li 'name' is a valid name.
- *
- * \li 'source' is a valid buffer and the first byte of the active
- * region should be the first byte of a DNS wire format domain name.
- *
- * \li 'target' is a valid buffer or 'target' is NULL and 'name' has
- * a dedicated buffer.
- *
- * \li 'dctx' is a valid decompression context.
- *
- * Ensures:
- *
- * If result is success:
- * \li If 'target' is not NULL, 'name' is attached to it.
- *
- * \li Uppercase letters are downcased in the copy iff
- * DNS_NAME_DOWNCASE is set in options.
- *
- * \li The current location in source is advanced, and the used space
- * in target is updated.
- *
- * Result:
- * \li Success
- * \li Bad Form: Label Length
- * \li Bad Form: Unknown Label Type
- * \li Bad Form: Name Length
- * \li Bad Form: Compression type not allowed
- * \li Bad Form: Bad compression pointer
- * \li Bad Form: Input too short
- * \li Resource Limit: Too many compression pointers
- * \li Resource Limit: Not enough space in buffer
- */
-
-isc_result_t
-dns_name_towire(const dns_name_t *name, dns_compress_t *cctx,
- isc_buffer_t *target);
-/*%<
- * Convert 'name' into wire format, compressing it as specified by the
- * compression context 'cctx', and storing the result in 'target'.
- *
- * Notes:
- * \li If the compression context allows global compression, then the
- * global compression table may be updated.
- *
- * Requires:
- * \li 'name' is a valid name
- *
- * \li dns_name_countlabels(name) > 0
- *
- * \li dns_name_isabsolute(name) == TRUE
- *
- * \li target is a valid buffer.
- *
- * \li Any offsets specified in a global compression table are valid
- * for buffer.
- *
- * Ensures:
- *
- * If the result is success:
- *
- * \li The used space in target is updated.
- *
- * Returns:
- * \li Success
- * \li Resource Limit: Not enough space in buffer
- */
-
-isc_result_t
-dns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
- const dns_name_t *origin, unsigned int options,
- isc_buffer_t *target);
-/*%<
- * Convert the textual representation of a DNS name at source
- * into uncompressed wire form stored in target.
- *
- * Notes:
- * \li Relative domain names will have 'origin' appended to them
- * unless 'origin' is NULL, in which case relative domain names
- * will remain relative.
- *
- * \li If DNS_NAME_DOWNCASE is set in 'options', any uppercase letters
- * in 'source' will be downcased when they are copied into 'target'.
- *
- * Requires:
- *
- * \li 'name' is a valid name.
- *
- * \li 'source' is a valid buffer.
- *
- * \li 'target' is a valid buffer or 'target' is NULL and 'name' has
- * a dedicated buffer.
- *
- * Ensures:
- *
- * If result is success:
- * \li If 'target' is not NULL, 'name' is attached to it.
- *
- * \li Uppercase letters are downcased in the copy iff
- * DNS_NAME_DOWNCASE is set in 'options'.
- *
- * \li The current location in source is advanced, and the used space
- * in target is updated.
- *
- * Result:
- *\li #ISC_R_SUCCESS
- *\li #DNS_R_EMPTYLABEL
- *\li #DNS_R_LABELTOOLONG
- *\li #DNS_R_BADESCAPE
- *\li (#DNS_R_BADBITSTRING: should not be returned)
- *\li (#DNS_R_BITSTRINGTOOLONG: should not be returned)
- *\li #DNS_R_BADDOTTEDQUAD
- *\li #ISC_R_NOSPACE
- *\li #ISC_R_UNEXPECTEDEND
- */
-
-#define DNS_NAME_OMITFINALDOT 0x01U
-#define DNS_NAME_MASTERFILE 0x02U /* escape $ and @ */
-
-isc_result_t
-dns_name_toprincipal(dns_name_t *name, isc_buffer_t *target);
-
-isc_result_t
-dns_name_totext(dns_name_t *name, isc_boolean_t omit_final_dot,
- isc_buffer_t *target);
-
-isc_result_t
-dns_name_totext2(dns_name_t *name, unsigned int options, isc_buffer_t *target);
-/*%<
- * Convert 'name' into text format, storing the result in 'target'.
- *
- * Notes:
- *\li If 'omit_final_dot' is true, then the final '.' in absolute
- * names other than the root name will be omitted.
- *
- *\li If DNS_NAME_OMITFINALDOT is set in options, then the final '.'
- * in absolute names other than the root name will be omitted.
- *
- *\li If DNS_NAME_MASTERFILE is set in options, '$' and '@' will also
- * be escaped.
- *
- *\li If dns_name_countlabels == 0, the name will be "@", representing the
- * current origin as described by RFC1035.
- *
- *\li The name is not NUL terminated.
- *
- * Requires:
- *
- *\li 'name' is a valid name
- *
- *\li 'target' is a valid buffer.
- *
- *\li if dns_name_isabsolute == FALSE, then omit_final_dot == FALSE
- *
- * Ensures:
- *
- *\li If the result is success:
- * the used space in target is updated.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOSPACE
- */
-
-#define DNS_NAME_MAXTEXT 1023
-/*%<
- * The maximum length of the text representation of a domain
- * name as generated by dns_name_totext(). This does not
- * include space for a terminating NULL.
- *
- * This definition is conservative - the actual maximum
- * is 1004, derived as follows:
- *
- * A backslash-decimal escaped character takes 4 bytes.
- * A wire-encoded name can be up to 255 bytes and each
- * label is one length byte + at most 63 bytes of data.
- * Maximizing the label lengths gives us a name of
- * three 63-octet labels, one 61-octet label, and the
- * root label:
- *
- * 1 + 63 + 1 + 63 + 1 + 63 + 1 + 61 + 1 = 255
- *
- * When printed, this is (3 * 63 + 61) * 4
- * bytes for the escaped label data + 4 bytes for the
- * dot terminating each label = 1004 bytes total.
- */
-
-isc_result_t
-dns_name_tofilenametext(dns_name_t *name, isc_boolean_t omit_final_dot,
- isc_buffer_t *target);
-/*%<
- * Convert 'name' into an alternate text format appropriate for filenames,
- * storing the result in 'target'. The name data is downcased, guaranteeing
- * that the filename does not depend on the case of the converted name.
- *
- * Notes:
- *\li If 'omit_final_dot' is true, then the final '.' in absolute
- * names other than the root name will be omitted.
- *
- *\li The name is not NUL terminated.
- *
- * Requires:
- *
- *\li 'name' is a valid absolute name
- *
- *\li 'target' is a valid buffer.
- *
- * Ensures:
- *
- *\li If the result is success:
- * the used space in target is updated.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOSPACE
- */
-
-isc_result_t
-dns_name_downcase(dns_name_t *source, dns_name_t *name,
- isc_buffer_t *target);
-/*%<
- * Downcase 'source'.
- *
- * Requires:
- *
- *\li 'source' and 'name' are valid names.
- *
- *\li If source == name, then
- * 'source' must not be read-only
- *
- *\li Otherwise,
- * 'target' is a valid buffer or 'target' is NULL and
- * 'name' has a dedicated buffer.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOSPACE
- *
- * Note: if source == name, then the result will always be ISC_R_SUCCESS.
- */
-
-isc_result_t
-dns_name_concatenate(dns_name_t *prefix, dns_name_t *suffix,
- dns_name_t *name, isc_buffer_t *target);
-/*%<
- * Concatenate 'prefix' and 'suffix'.
- *
- * Requires:
- *
- *\li 'prefix' is a valid name or NULL.
- *
- *\li 'suffix' is a valid name or NULL.
- *
- *\li 'name' is a valid name or NULL.
- *
- *\li 'target' is a valid buffer or 'target' is NULL and 'name' has
- * a dedicated buffer.
- *
- *\li If 'prefix' is absolute, 'suffix' must be NULL or the empty name.
- *
- * Ensures:
- *
- *\li On success,
- * If 'target' is not NULL and 'name' is not NULL, then 'name'
- * is attached to it.
- * The used space in target is updated.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOSPACE
- *\li #DNS_R_NAMETOOLONG
- */
-
-void
-dns_name_split(dns_name_t *name, unsigned int suffixlabels,
- dns_name_t *prefix, dns_name_t *suffix);
-/*%<
- *
- * Split 'name' into two pieces on a label boundary.
- *
- * Notes:
- * \li 'name' is split such that 'suffix' holds the most significant
- * 'suffixlabels' labels. All other labels are stored in 'prefix'.
- *
- *\li Copying name data is avoided as much as possible, so 'prefix'
- * and 'suffix' will end up pointing at the data for 'name'.
- *
- *\li It is legitimate to pass a 'prefix' or 'suffix' that has
- * its name data stored someplace other than the dedicated buffer.
- * This is useful to avoid name copying in the calling function.
- *
- *\li It is also legitimate to pass a 'prefix' or 'suffix' that is
- * the same dns_name_t as 'name'.
- *
- * Requires:
- *\li 'name' is a valid name.
- *
- *\li 'suffixlabels' cannot exceed the number of labels in 'name'.
- *
- * \li 'prefix' is a valid name or NULL, and cannot be read-only.
- *
- *\li 'suffix' is a valid name or NULL, and cannot be read-only.
- *
- *\li If non-NULL, 'prefix' and 'suffix' must have dedicated buffers.
- *
- *\li 'prefix' and 'suffix' cannot point to the same buffer.
- *
- * Ensures:
- *
- *\li On success:
- * If 'prefix' is not NULL it will contain the least significant
- * labels.
- * If 'suffix' is not NULL it will contain the most significant
- * labels. dns_name_countlabels(suffix) will be equal to
- * suffixlabels.
- *
- *\li On failure:
- * Either 'prefix' or 'suffix' is invalidated (depending
- * on which one the problem was encountered with).
- *
- * Returns:
- *\li #ISC_R_SUCCESS No worries. (This function should always success).
- */
-
-isc_result_t
-dns_name_dup(const dns_name_t *source, isc_mem_t *mctx,
- dns_name_t *target);
-/*%<
- * Make 'target' a dynamically allocated copy of 'source'.
- *
- * Requires:
- *
- *\li 'source' is a valid non-empty name.
- *
- *\li 'target' is a valid name that is not read-only.
- *
- *\li 'mctx' is a valid memory context.
- */
-
-isc_result_t
-dns_name_dupwithoffsets(dns_name_t *source, isc_mem_t *mctx,
- dns_name_t *target);
-/*%<
- * Make 'target' a read-only dynamically allocated copy of 'source'.
- * 'target' will also have a dynamically allocated offsets table.
- *
- * Requires:
- *
- *\li 'source' is a valid non-empty name.
- *
- *\li 'target' is a valid name that is not read-only.
- *
- *\li 'target' has no offsets table.
- *
- *\li 'mctx' is a valid memory context.
- */
-
-void
-dns_name_free(dns_name_t *name, isc_mem_t *mctx);
-/*%<
- * Free 'name'.
- *
- * Requires:
- *
- *\li 'name' is a valid name created previously in 'mctx' by dns_name_dup().
- *
- *\li 'mctx' is a valid memory context.
- *
- * Ensures:
- *
- *\li All dynamic resources used by 'name' are freed and the name is
- * invalidated.
- */
-
-isc_result_t
-dns_name_digest(dns_name_t *name, dns_digestfunc_t digest, void *arg);
-/*%<
- * Send 'name' in DNSSEC canonical form to 'digest'.
- *
- * Requires:
- *
- *\li 'name' is a valid name.
- *
- *\li 'digest' is a valid dns_digestfunc_t.
- *
- * Ensures:
- *
- *\li If successful, the DNSSEC canonical form of 'name' will have been
- * sent to 'digest'.
- *
- *\li If digest() returns something other than ISC_R_SUCCESS, that result
- * will be returned as the result of dns_name_digest().
- *
- * Returns:
- *
- *\li #ISC_R_SUCCESS
- *
- *\li Many other results are possible if not successful.
- *
- */
-
-isc_boolean_t
-dns_name_dynamic(dns_name_t *name);
-/*%<
- * Returns whether there is dynamic memory associated with this name.
- *
- * Requires:
- *
- *\li 'name' is a valid name.
- *
- * Returns:
- *
- *\li 'ISC_TRUE' if the name is dynamic otherwise 'ISC_FALSE'.
- */
-
-isc_result_t
-dns_name_print(dns_name_t *name, FILE *stream);
-/*%<
- * Print 'name' on 'stream'.
- *
- * Requires:
- *
- *\li 'name' is a valid name.
- *
- *\li 'stream' is a valid stream.
- *
- * Returns:
- *
- *\li #ISC_R_SUCCESS
- *
- *\li Any error that dns_name_totext() can return.
- */
-
-void
-dns_name_format(dns_name_t *name, char *cp, unsigned int size);
-/*%<
- * Format 'name' as text appropriate for use in log messages.
- *
- * Store the formatted name at 'cp', writing no more than
- * 'size' bytes. The resulting string is guaranteed to be
- * null terminated.
- *
- * The formatted name will have a terminating dot only if it is
- * the root.
- *
- * This function cannot fail, instead any errors are indicated
- * in the returned text.
- *
- * Requires:
- *
- *\li 'name' is a valid name.
- *
- *\li 'cp' points a valid character array of size 'size'.
- *
- *\li 'size' > 0.
- *
- */
-
-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
- * end of dns_name_totext().
- *
- * Note: Under Windows you need to call "dns_name_settotextfilter(NULL);"
- * prior to exiting the thread otherwise memory will be leaked.
- * For other platforms, which are pthreads based, this is still a good
- * idea but not required.
- *
- * Returns
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_UNEXPECTED
- */
-
-#define DNS_NAME_FORMATSIZE (DNS_NAME_MAXTEXT + 1)
-/*%<
- * Suggested size of buffer passed to dns_name_format().
- * Includes space for the terminating NULL.
- */
-
-isc_result_t
-dns_name_copy(dns_name_t *source, dns_name_t *dest, isc_buffer_t *target);
-/*%<
- * Makes 'dest' refer to a copy of the name in 'source'. The data are
- * either copied to 'target' or the dedicated buffer in 'dest'.
- *
- * Requires:
- * \li 'source' is a valid name.
- *
- * \li 'dest' is an initialized name with a dedicated buffer.
- *
- * \li 'target' is NULL or an initialized buffer.
- *
- * \li Either dest has a dedicated buffer or target != NULL.
- *
- * Ensures:
- *
- *\li On success, the used space in target is updated.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOSPACE
- */
-
-isc_boolean_t
-dns_name_ishostname(const dns_name_t *name, isc_boolean_t wildcard);
-/*%<
- * Return if 'name' is a valid hostname. RFC 952 / RFC 1123.
- * If 'wildcard' is ISC_TRUE then allow the first label of name to
- * be a wildcard.
- * The root is also accepted.
- *
- * Requires:
- * 'name' to be valid.
- */
-
-
-isc_boolean_t
-dns_name_ismailbox(const dns_name_t *name);
-/*%<
- * Return if 'name' is a valid mailbox. RFC 821.
- *
- * Requires:
- * \li 'name' to be valid.
- */
-
-isc_boolean_t
-dns_name_internalwildcard(const dns_name_t *name);
-/*%<
- * Return if 'name' contains a internal wildcard name.
- *
- * Requires:
- * \li 'name' to be valid.
- */
-
-void
-dns_name_destroy(void);
-/*%<
- * Cleanup dns_name_settotextfilter() / dns_name_totext() state.
- *
- * This should be called as part of the final cleanup process.
- *
- * Note: dns_name_settotextfilter(NULL); should be called for all
- * threads which have called dns_name_settotextfilter() with a
- * non-NULL argument prior to calling dns_name_destroy();
- */
-
-ISC_LANG_ENDDECLS
-
-/*
- *** High Performance Macros
- ***/
-
-/*
- * WARNING: Use of these macros by applications may require recompilation
- * of the application in some situations where calling the function
- * would not.
- *
- * WARNING: No assertion checking is done for these macros.
- */
-
-#define DNS_NAME_INIT(n, o) \
-do { \
- dns_name_t *_n = (n); \
- /* memset(_n, 0, sizeof(*_n)); */ \
- _n->magic = DNS_NAME_MAGIC; \
- _n->ndata = NULL; \
- _n->length = 0; \
- _n->labels = 0; \
- _n->attributes = 0; \
- _n->offsets = (o); \
- _n->buffer = NULL; \
- ISC_LINK_INIT(_n, link); \
- ISC_LIST_INIT(_n->list); \
-} while (0)
-
-#define DNS_NAME_RESET(n) \
-do { \
- (n)->ndata = NULL; \
- (n)->length = 0; \
- (n)->labels = 0; \
- (n)->attributes &= ~DNS_NAMEATTR_ABSOLUTE; \
- if ((n)->buffer != NULL) \
- isc_buffer_clear((n)->buffer); \
-} while (0)
-
-#define DNS_NAME_SETBUFFER(n, b) \
- (n)->buffer = (b)
-
-#define DNS_NAME_ISABSOLUTE(n) \
- (((n)->attributes & DNS_NAMEATTR_ABSOLUTE) != 0 ? ISC_TRUE : ISC_FALSE)
-
-#define DNS_NAME_COUNTLABELS(n) \
- ((n)->labels)
-
-#define DNS_NAME_TOREGION(n, r) \
-do { \
- (r)->base = (n)->ndata; \
- (r)->length = (n)->length; \
-} while (0)
-
-#define DNS_NAME_SPLIT(n, l, p, s) \
-do { \
- dns_name_t *_n = (n); \
- dns_name_t *_p = (p); \
- dns_name_t *_s = (s); \
- unsigned int _l = (l); \
- if (_p != NULL) \
- dns_name_getlabelsequence(_n, 0, _n->labels - _l, _p); \
- if (_s != NULL) \
- dns_name_getlabelsequence(_n, _n->labels - _l, _l, _s); \
-} while (0)
-
-#ifdef DNS_NAME_USEINLINE
-
-#define dns_name_init(n, o) DNS_NAME_INIT(n, o)
-#define dns_name_reset(n) DNS_NAME_RESET(n)
-#define dns_name_setbuffer(n, b) DNS_NAME_SETBUFFER(n, b)
-#define dns_name_countlabels(n) DNS_NAME_COUNTLABELS(n)
-#define dns_name_isabsolute(n) DNS_NAME_ISABSOLUTE(n)
-#define dns_name_toregion(n, r) DNS_NAME_TOREGION(n, r)
-#define dns_name_split(n, l, p, s) DNS_NAME_SPLIT(n, l, p, s)
-
-#endif /* DNS_NAME_USEINLINE */
-
-#endif /* DNS_NAME_H */
diff --git a/contrib/bind9/lib/dns/include/dns/ncache.h b/contrib/bind9/lib/dns/include/dns/ncache.h
deleted file mode 100644
index 337e8348c810..000000000000
--- a/contrib/bind9/lib/dns/include/dns/ncache.h
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (C) 2004-2010, 2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2002 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: ncache.h,v 1.29 2010/05/14 23:50:40 tbox Exp $ */
-
-#ifndef DNS_NCACHE_H
-#define DNS_NCACHE_H 1
-
-/*****
- ***** Module Info
- *****/
-
-/*! \file dns/ncache.h
- *\brief
- * DNS Ncache
- *
- * XXX TBS XXX
- *
- * MP:
- *\li The caller must ensure any required synchronization.
- *
- * Reliability:
- *\li No anticipated impact.
- *
- * Resources:
- *\li TBS
- *
- * Security:
- *\li No anticipated impact.
- *
- * Standards:
- *\li RFC2308
- */
-
-#include <isc/lang.h>
-#include <isc/stdtime.h>
-
-#include <dns/types.h>
-
-ISC_LANG_BEGINDECLS
-
-/*%
- * _OMITDNSSEC:
- * Omit DNSSEC records when rendering.
- */
-#define DNS_NCACHETOWIRE_OMITDNSSEC 0x0001
-
-isc_result_t
-dns_ncache_add(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
- dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl,
- dns_rdataset_t *addedrdataset);
-isc_result_t
-dns_ncache_addoptout(dns_message_t *message, dns_db_t *cache,
- dns_dbnode_t *node, dns_rdatatype_t covers,
- isc_stdtime_t now, dns_ttl_t maxttl,
- isc_boolean_t optout, dns_rdataset_t *addedrdataset);
-/*%<
- * Convert the authority data from 'message' into a negative cache
- * rdataset, and store it in 'cache' at 'node' with a TTL limited to
- * 'maxttl'.
- *
- * \li dns_ncache_add produces a negative cache entry with a trust of no
- * more than answer
- * \li dns_ncache_addoptout produces a negative cache entry which will have
- * a trust of secure if all the records that make up the entry are secure.
- *
- * The 'covers' argument is the RR type whose nonexistence we are caching,
- * or dns_rdatatype_any when caching a NXDOMAIN response.
- *
- * 'optout' indicates a DNS_RDATASETATTR_OPTOUT should be set.
- *
- * Note:
- *\li If 'addedrdataset' is not NULL, then it will be attached to the added
- * rdataset. See dns_db_addrdataset() for more details.
- *
- * Requires:
- *\li 'message' is a valid message with a properly formatting negative cache
- * authority section.
- *
- *\li The requirements of dns_db_addrdataset() apply to 'cache', 'node',
- * 'now', and 'addedrdataset'.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOSPACE
- *
- *\li Any result code of dns_db_addrdataset() is a possible result code
- * of dns_ncache_add().
- */
-
-isc_result_t
-dns_ncache_towire(dns_rdataset_t *rdataset, dns_compress_t *cctx,
- isc_buffer_t *target, unsigned int options,
- unsigned int *countp);
-/*%<
- * Convert the negative caching rdataset 'rdataset' to wire format,
- * compressing names as specified in 'cctx', and storing the result in
- * 'target'. If 'omit_dnssec' is set, DNSSEC records will not
- * be added to 'target'.
- *
- * Notes:
- *\li The number of RRs added to target will be added to *countp.
- *
- * Requires:
- *\li 'rdataset' is a valid negative caching rdataset.
- *
- *\li 'rdataset' is not empty.
- *
- *\li 'countp' is a valid pointer.
- *
- * Ensures:
- *\li On a return of ISC_R_SUCCESS, 'target' contains a wire format
- * for the data contained in 'rdataset'. Any error return leaves
- * the buffer unchanged.
- *
- *\li *countp has been incremented by the number of RRs added to
- * target.
- *
- * Returns:
- *\li #ISC_R_SUCCESS - all ok
- *\li #ISC_R_NOSPACE - 'target' doesn't have enough room
- *
- *\li Any error returned by dns_rdata_towire(), dns_rdataset_next(),
- * dns_name_towire().
- */
-
-isc_result_t
-dns_ncache_getrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name,
- dns_rdatatype_t type, dns_rdataset_t *rdataset);
-/*%<
- * Search the negative caching rdataset for an rdataset with the
- * specified name and type.
- *
- * Requires:
- *\li 'ncacherdataset' is a valid negative caching rdataset.
- *
- *\li 'ncacherdataset' is not empty.
- *
- *\li 'name' is a valid name.
- *
- *\li 'type' is not SIG, or a meta-RR type.
- *
- *\li 'rdataset' is a valid disassociated rdataset.
- *
- * Ensures:
- *\li On a return of ISC_R_SUCCESS, 'rdataset' is bound to the found
- * rdataset.
- *
- * Returns:
- *\li #ISC_R_SUCCESS - the rdataset was found.
- *\li #ISC_R_NOTFOUND - the rdataset was not found.
- *
- */
-
-isc_result_t
-dns_ncache_getsigrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name,
- dns_rdatatype_t covers, dns_rdataset_t *rdataset);
-/*%<
- * Similar to dns_ncache_getrdataset() but get the rrsig that matches.
- */
-
-void
-dns_ncache_current(dns_rdataset_t *ncacherdataset, dns_name_t *found,
- dns_rdataset_t *rdataset);
-
-/*%<
- * Extract the current rdataset and name from a ncache entry.
- *
- * Requires:
- * \li 'ncacherdataset' to be valid and to be a negative cache entry
- * \li 'found' to be valid.
- * \li 'rdataset' to be unassociated.
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_NCACHE_H */
diff --git a/contrib/bind9/lib/dns/include/dns/nsec.h b/contrib/bind9/lib/dns/include/dns/nsec.h
deleted file mode 100644
index 440ee4e01513..000000000000
--- a/contrib/bind9/lib/dns/include/dns/nsec.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2004-2008, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001, 2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: nsec.h,v 1.14 2011/06/10 23:47:32 tbox Exp $ */
-
-#ifndef DNS_NSEC_H
-#define DNS_NSEC_H 1
-
-/*! \file dns/nsec.h */
-
-#include <isc/lang.h>
-
-#include <dns/types.h>
-#include <dns/name.h>
-
-#define DNS_NSEC_BUFFERSIZE (DNS_NAME_MAXWIRE + 8192 + 512)
-
-ISC_LANG_BEGINDECLS
-
-isc_result_t
-dns_nsec_buildrdata(dns_db_t *db, dns_dbversion_t *version,
- dns_dbnode_t *node, dns_name_t *target,
- unsigned char *buffer, dns_rdata_t *rdata);
-/*%<
- * Build the rdata of a NSEC record.
- *
- * Requires:
- *\li buffer Points to a temporary buffer of at least
- * DNS_NSEC_BUFFERSIZE bytes.
- *\li rdata Points to an initialized dns_rdata_t.
- *
- * Ensures:
- * \li *rdata Contains a valid NSEC rdata. The 'data' member refers
- * to 'buffer'.
- */
-
-isc_result_t
-dns_nsec_build(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node,
- dns_name_t *target, dns_ttl_t ttl);
-/*%<
- * Build a NSEC record and add it to a database.
- */
-
-isc_boolean_t
-dns_nsec_typepresent(dns_rdata_t *nsec, dns_rdatatype_t type);
-/*%<
- * Determine if a type is marked as present in an NSEC record.
- *
- * Requires:
- *\li 'nsec' points to a valid rdataset of type NSEC
- */
-
-isc_result_t
-dns_nsec_nseconly(dns_db_t *db, dns_dbversion_t *version,
- isc_boolean_t *answer);
-/*
- * Report whether the DNSKEY RRset has a NSEC only algorithm. Unknown
- * algorithms are assumed to support NSEC3. If DNSKEY is not found,
- * *answer is set to ISC_FALSE, and ISC_R_NOTFOUND is returned.
- *
- * Requires:
- * 'answer' to be non NULL.
- */
-
-unsigned int
-dns_nsec_compressbitmap(unsigned char *map, const unsigned char *raw,
- unsigned int max_type);
-/*%<
- * Convert a raw bitmap into a compressed windowed bit map. 'map' and 'raw'
- * may overlap.
- *
- * Returns the length of the compressed windowed bit map.
- */
-
-void
-dns_nsec_setbit(unsigned char *array, unsigned int type, unsigned int bit);
-/*%<
- * Set type bit in raw 'array' to 'bit'.
- */
-
-isc_boolean_t
-dns_nsec_isset(const unsigned char *array, unsigned int type);
-/*%<
- * Test if the corresponding 'type' bit is set in 'array'.
- */
-
-isc_result_t
-dns_nsec_noexistnodata(dns_rdatatype_t type, dns_name_t *name,
- dns_name_t *nsecname, dns_rdataset_t *nsecset,
- isc_boolean_t *exists, isc_boolean_t *data,
- dns_name_t *wild, dns_nseclog_t log, void *arg);
-/*%
- * Return ISC_R_SUCCESS if we can determine that the name doesn't exist
- * or we can determine whether there is data or not at the name.
- * If the name does not exist return the wildcard name.
- *
- * Return ISC_R_IGNORE when the NSEC is not the appropriate one.
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_NSEC_H */
diff --git a/contrib/bind9/lib/dns/include/dns/nsec3.h b/contrib/bind9/lib/dns/include/dns/nsec3.h
deleted file mode 100644
index e4a22868a2db..000000000000
--- a/contrib/bind9/lib/dns/include/dns/nsec3.h
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Copyright (C) 2008-2012 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: nsec3.h,v 1.14 2011/10/28 12:20:31 tbox Exp $ */
-
-#ifndef DNS_NSEC3_H
-#define DNS_NSEC3_H 1
-
-#include <isc/lang.h>
-#include <isc/iterated_hash.h>
-
-#include <dns/db.h>
-#include <dns/diff.h>
-#include <dns/name.h>
-#include <dns/rdatastruct.h>
-#include <dns/types.h>
-
-#define DNS_NSEC3_SALTSIZE 255
-
-/*
- * hash = 1, flags =1, iterations = 2, salt length = 1, salt = 255 (max)
- * hash length = 1, hash = 255 (max), bitmap = 8192 + 512 (max)
- */
-#define DNS_NSEC3_BUFFERSIZE (6 + 255 + 255 + 8192 + 512)
-/*
- * hash = 1, flags = 1, iterations = 2, salt length = 1, salt = 255 (max)
- */
-#define DNS_NSEC3PARAM_BUFFERSIZE (5 + 255)
-
-/*
- * Test "unknown" algorithm. Is mapped to dns_hash_sha1.
- */
-#define DNS_NSEC3_UNKNOWNALG 245U
-
-ISC_LANG_BEGINDECLS
-
-isc_result_t
-dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version,
- dns_dbnode_t *node, unsigned int hashalg,
- unsigned int optin, unsigned int iterations,
- const unsigned char *salt, size_t salt_length,
- const unsigned char *nexthash, size_t hash_length,
- unsigned char *buffer, dns_rdata_t *rdata);
-/*%<
- * Build the rdata of a NSEC3 record for the data at 'node'.
- * Note: 'node' is not the node where the NSEC3 record will be stored.
- *
- * Requires:
- * buffer Points to a temporary buffer of at least
- * DNS_NSEC_BUFFERSIZE bytes.
- * rdata Points to an initialized dns_rdata_t.
- *
- * Ensures:
- * *rdata Contains a valid NSEC3 rdata. The 'data' member refers
- * to 'buffer'.
- */
-
-isc_boolean_t
-dns_nsec3_typepresent(dns_rdata_t *nsec, dns_rdatatype_t type);
-/*%<
- * Determine if a type is marked as present in an NSEC3 record.
- *
- * Requires:
- * 'nsec' points to a valid rdataset of type NSEC3
- */
-
-isc_result_t
-dns_nsec3_hashname(dns_fixedname_t *result,
- unsigned char rethash[NSEC3_MAX_HASH_LENGTH],
- size_t *hash_length, dns_name_t *name, dns_name_t *origin,
- dns_hash_t hashalg, unsigned int iterations,
- const unsigned char *salt, size_t saltlength);
-/*%<
- * Make a hashed domain name from an unhashed one. If rethash is not NULL
- * the raw hash is stored there.
- */
-
-unsigned int
-dns_nsec3_hashlength(dns_hash_t hash);
-/*%<
- * Return the length of the hash produced by the specified algorithm
- * or zero when unknown.
- */
-
-isc_boolean_t
-dns_nsec3_supportedhash(dns_hash_t hash);
-/*%<
- * Return whether we support this hash algorithm or not.
- */
-
-isc_result_t
-dns_nsec3_addnsec3(dns_db_t *db, dns_dbversion_t *version,
- dns_name_t *name, const dns_rdata_nsec3param_t *nsec3param,
- dns_ttl_t nsecttl, isc_boolean_t unsecure, dns_diff_t *diff);
-
-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.
- * The existing NSEC3 records are removed.
- *
- * dns_nsec3_addnsec3() will only add records to the chain identified by
- * 'nsec3param'.
- *
- * 'unsecure' should be set to reflect if this is a potentially
- * unsecure delegation (no DS record).
- *
- * dns_nsec3_addnsec3s() will examine the NSEC3PARAM RRset to determine which
- * chains to be updated. NSEC3PARAM records with the DNS_NSEC3FLAG_CREATE
- * will be preferentially chosen over NSEC3PARAM records without
- * DNS_NSEC3FLAG_CREATE set. NSEC3PARAM records with DNS_NSEC3FLAG_REMOVE
- * set will be ignored by dns_nsec3_addnsec3s(). If DNS_NSEC3FLAG_CREATE
- * is set then the new NSEC3 will have OPTOUT set to match the that in the
- * 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.
- * 'name' to be valid.
- * 'nsec3param' to be valid.
- * 'diff' to be valid.
- */
-
-isc_result_t
-dns_nsec3_delnsec3(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
- const dns_rdata_nsec3param_t *nsec3param, dns_diff_t *diff);
-
-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.
- *
- * dns_nsec3_delnsec3() performs the above for the chain identified by
- * 'nsec3param'.
- *
- * dns_nsec3_delnsec3s() examines the NSEC3PARAM RRset in a similar manner
- * 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.
- * 'name' to be valid.
- * 'nsec3param' to be valid.
- * 'diff' to be valid.
- */
-
-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.
- * 'answer' to be non NULL.
- */
-
-isc_result_t
-dns_nsec3_maxiterations(dns_db_t *db, dns_dbversion_t *version,
- isc_mem_t *mctx, unsigned int *iterationsp);
-/*%<
- * Find the maximum permissible number of iterations allowed based on
- * the key strength.
- *
- * Requires:
- * 'db' to be valid.
- * 'version' to be valid or NULL.
- * 'mctx' to be valid.
- * '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, isc_boolean_t nonsec,
- dns_diff_t *diff);
-
-/*%<
- * Mark NSEC3PARAM for deletion.
- */
-
-isc_result_t
-dns_nsec3_noexistnodata(dns_rdatatype_t type, dns_name_t* name,
- dns_name_t *nsec3name, dns_rdataset_t *nsec3set,
- dns_name_t *zonename, isc_boolean_t *exists,
- isc_boolean_t *data, isc_boolean_t *optout,
- isc_boolean_t *unknown, isc_boolean_t *setclosest,
- isc_boolean_t *setnearest, dns_name_t *closest,
- dns_name_t *nearest, dns_nseclog_t logit, void *arg);
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_NSEC3_H */
diff --git a/contrib/bind9/lib/dns/include/dns/opcode.h b/contrib/bind9/lib/dns/include/dns/opcode.h
deleted file mode 100644
index 368b2b2c24dc..000000000000
--- a/contrib/bind9/lib/dns/include/dns/opcode.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2002 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: opcode.h,v 1.8 2007/06/19 23:47:17 tbox Exp $ */
-
-#ifndef DNS_OPCODE_H
-#define DNS_OPCODE_H 1
-
-/*! \file dns/opcode.h */
-
-#include <isc/lang.h>
-
-#include <dns/types.h>
-
-ISC_LANG_BEGINDECLS
-
-isc_result_t dns_opcode_totext(dns_opcode_t opcode, isc_buffer_t *target);
-/*%<
- * Put a textual representation of error 'opcode' into 'target'.
- *
- * Requires:
- *\li 'opcode' is a valid opcode.
- *
- *\li 'target' is a valid text buffer.
- *
- * Ensures:
- *\li If the result is success:
- * The used space in 'target' is updated.
- *
- * Returns:
- *\li #ISC_R_SUCCESS on success
- *\li #ISC_R_NOSPACE target buffer is too small
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_OPCODE_H */
diff --git a/contrib/bind9/lib/dns/include/dns/order.h b/contrib/bind9/lib/dns/include/dns/order.h
deleted file mode 100644
index 85663c37cbb1..000000000000
--- a/contrib/bind9/lib/dns/include/dns/order.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2002 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: order.h,v 1.9 2007/06/19 23:47:17 tbox Exp $ */
-
-#ifndef DNS_ORDER_H
-#define DNS_ORDER_H 1
-
-/*! \file dns/order.h */
-
-#include <isc/lang.h>
-#include <isc/types.h>
-
-#include <dns/types.h>
-
-ISC_LANG_BEGINDECLS
-
-isc_result_t
-dns_order_create(isc_mem_t *mctx, dns_order_t **orderp);
-/*%<
- * Create a order object.
- *
- * Requires:
- * \li 'orderp' to be non NULL and '*orderp == NULL'.
- *\li 'mctx' to be valid.
- *
- * Returns:
- *\li ISC_R_SUCCESS
- *\li ISC_R_NOMEMORY
- */
-
-isc_result_t
-dns_order_add(dns_order_t *order, dns_name_t *name,
- dns_rdatatype_t rdtype, dns_rdataclass_t rdclass,
- unsigned int mode);
-/*%<
- * Add a entry to the end of the order list.
- *
- * Requires:
- * \li 'order' to be valid.
- *\li 'name' to be valid.
- *\li 'mode' to be one of #DNS_RDATASERATTR_RANDOMIZE,
- * #DNS_RDATASERATTR_RANDOMIZE or zero (#DNS_RDATASERATTR_CYCLIC).
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMEMORY
- */
-
-unsigned int
-dns_order_find(dns_order_t *order, dns_name_t *name,
- dns_rdatatype_t rdtype, dns_rdataclass_t rdclass);
-/*%<
- * Find the first matching entry on the list.
- *
- * Requires:
- *\li 'order' to be valid.
- *\li 'name' to be valid.
- *
- * Returns the mode set by dns_order_add() or zero.
- */
-
-void
-dns_order_attach(dns_order_t *source, dns_order_t **target);
-/*%<
- * Attach to the 'source' object.
- *
- * Requires:
- * \li 'source' to be valid.
- *\li 'target' to be non NULL and '*target == NULL'.
- */
-
-void
-dns_order_detach(dns_order_t **orderp);
-/*%<
- * Detach from the object. Clean up if last this was the last
- * reference.
- *
- * Requires:
- *\li '*orderp' to be valid.
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_ORDER_H */
diff --git a/contrib/bind9/lib/dns/include/dns/peer.h b/contrib/bind9/lib/dns/include/dns/peer.h
deleted file mode 100644
index 86324a3d7021..000000000000
--- a/contrib/bind9/lib/dns/include/dns/peer.h
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: peer.h,v 1.35 2009/01/17 23:47:43 tbox Exp $ */
-
-#ifndef DNS_PEER_H
-#define DNS_PEER_H 1
-
-/*****
- ***** Module Info
- *****/
-
-/*! \file dns/peer.h
- * \brief
- * Data structures for peers (e.g. a 'server' config file statement)
- */
-
-/***
- *** Imports
- ***/
-
-#include <isc/lang.h>
-#include <isc/magic.h>
-#include <isc/netaddr.h>
-
-#include <dns/types.h>
-
-#define DNS_PEERLIST_MAGIC ISC_MAGIC('s','e','R','L')
-#define DNS_PEER_MAGIC ISC_MAGIC('S','E','r','v')
-
-#define DNS_PEERLIST_VALID(ptr) ISC_MAGIC_VALID(ptr, DNS_PEERLIST_MAGIC)
-#define DNS_PEER_VALID(ptr) ISC_MAGIC_VALID(ptr, DNS_PEER_MAGIC)
-
-/***
- *** Types
- ***/
-
-struct dns_peerlist {
- unsigned int magic;
- isc_uint32_t refs;
-
- isc_mem_t *mem;
-
- ISC_LIST(dns_peer_t) elements;
-};
-
-struct dns_peer {
- unsigned int magic;
- isc_uint32_t refs;
-
- isc_mem_t *mem;
-
- isc_netaddr_t address;
- unsigned int prefixlen;
- isc_boolean_t bogus;
- dns_transfer_format_t transfer_format;
- isc_uint32_t transfers;
- isc_boolean_t support_ixfr;
- isc_boolean_t provide_ixfr;
- isc_boolean_t request_ixfr;
- isc_boolean_t support_edns;
- isc_boolean_t request_nsid;
- dns_name_t *key;
- isc_sockaddr_t *transfer_source;
- isc_sockaddr_t *notify_source;
- isc_sockaddr_t *query_source;
- isc_uint16_t udpsize; /* receive size */
- isc_uint16_t maxudp; /* transmit size */
-
- isc_uint32_t bitflags;
-
- ISC_LINK(dns_peer_t) next;
-};
-
-/***
- *** Functions
- ***/
-
-ISC_LANG_BEGINDECLS
-
-isc_result_t
-dns_peerlist_new(isc_mem_t *mem, dns_peerlist_t **list);
-
-void
-dns_peerlist_attach(dns_peerlist_t *source, dns_peerlist_t **target);
-
-void
-dns_peerlist_detach(dns_peerlist_t **list);
-
-/*
- * After return caller still holds a reference to peer.
- */
-void
-dns_peerlist_addpeer(dns_peerlist_t *peers, dns_peer_t *peer);
-
-/*
- * Ditto. */
-isc_result_t
-dns_peerlist_peerbyaddr(dns_peerlist_t *peers, isc_netaddr_t *addr,
- dns_peer_t **retval);
-
-/*
- * What he said.
- */
-isc_result_t
-dns_peerlist_currpeer(dns_peerlist_t *peers, dns_peer_t **retval);
-
-isc_result_t
-dns_peer_new(isc_mem_t *mem, isc_netaddr_t *ipaddr, dns_peer_t **peer);
-
-isc_result_t
-dns_peer_newprefix(isc_mem_t *mem, isc_netaddr_t *ipaddr,
- unsigned int prefixlen, dns_peer_t **peer);
-
-void
-dns_peer_attach(dns_peer_t *source, dns_peer_t **target);
-
-void
-dns_peer_detach(dns_peer_t **list);
-
-isc_result_t
-dns_peer_setbogus(dns_peer_t *peer, isc_boolean_t newval);
-
-isc_result_t
-dns_peer_getbogus(dns_peer_t *peer, isc_boolean_t *retval);
-
-isc_result_t
-dns_peer_setrequestixfr(dns_peer_t *peer, isc_boolean_t newval);
-
-isc_result_t
-dns_peer_getrequestixfr(dns_peer_t *peer, isc_boolean_t *retval);
-
-isc_result_t
-dns_peer_setprovideixfr(dns_peer_t *peer, isc_boolean_t newval);
-
-isc_result_t
-dns_peer_getprovideixfr(dns_peer_t *peer, isc_boolean_t *retval);
-
-isc_result_t
-dns_peer_setrequestnsid(dns_peer_t *peer, isc_boolean_t newval);
-
-isc_result_t
-dns_peer_getrequestnsid(dns_peer_t *peer, isc_boolean_t *retval);
-
-isc_result_t
-dns_peer_setsupportedns(dns_peer_t *peer, isc_boolean_t newval);
-
-isc_result_t
-dns_peer_getsupportedns(dns_peer_t *peer, isc_boolean_t *retval);
-
-isc_result_t
-dns_peer_settransfers(dns_peer_t *peer, isc_uint32_t newval);
-
-isc_result_t
-dns_peer_gettransfers(dns_peer_t *peer, isc_uint32_t *retval);
-
-isc_result_t
-dns_peer_settransferformat(dns_peer_t *peer, dns_transfer_format_t newval);
-
-isc_result_t
-dns_peer_gettransferformat(dns_peer_t *peer, dns_transfer_format_t *retval);
-
-isc_result_t
-dns_peer_setkeybycharp(dns_peer_t *peer, const char *keyval);
-
-isc_result_t
-dns_peer_getkey(dns_peer_t *peer, dns_name_t **retval);
-
-isc_result_t
-dns_peer_setkey(dns_peer_t *peer, dns_name_t **keyval);
-
-isc_result_t
-dns_peer_settransfersource(dns_peer_t *peer,
- const isc_sockaddr_t *transfer_source);
-
-isc_result_t
-dns_peer_gettransfersource(dns_peer_t *peer, isc_sockaddr_t *transfer_source);
-
-isc_result_t
-dns_peer_setudpsize(dns_peer_t *peer, isc_uint16_t udpsize);
-
-isc_result_t
-dns_peer_getudpsize(dns_peer_t *peer, isc_uint16_t *udpsize);
-
-isc_result_t
-dns_peer_setmaxudp(dns_peer_t *peer, isc_uint16_t maxudp);
-
-isc_result_t
-dns_peer_getmaxudp(dns_peer_t *peer, isc_uint16_t *maxudp);
-
-isc_result_t
-dns_peer_setnotifysource(dns_peer_t *peer, const isc_sockaddr_t *notify_source);
-
-isc_result_t
-dns_peer_getnotifysource(dns_peer_t *peer, isc_sockaddr_t *notify_source);
-
-isc_result_t
-dns_peer_setquerysource(dns_peer_t *peer, const isc_sockaddr_t *query_source);
-
-isc_result_t
-dns_peer_getquerysource(dns_peer_t *peer, isc_sockaddr_t *query_source);
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_PEER_H */
diff --git a/contrib/bind9/lib/dns/include/dns/portlist.h b/contrib/bind9/lib/dns/include/dns/portlist.h
deleted file mode 100644
index f76731aa7672..000000000000
--- a/contrib/bind9/lib/dns/include/dns/portlist.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 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: portlist.h,v 1.9 2007/06/19 23:47:17 tbox Exp $ */
-
-/*! \file dns/portlist.h */
-
-#include <isc/lang.h>
-#include <isc/net.h>
-#include <isc/types.h>
-
-#include <dns/types.h>
-
-ISC_LANG_BEGINDECLS
-
-isc_result_t
-dns_portlist_create(isc_mem_t *mctx, dns_portlist_t **portlistp);
-/*%<
- * Create a port list.
- *
- * Requires:
- *\li 'mctx' to be valid.
- *\li 'portlistp' to be non NULL and '*portlistp' to be NULL;
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMEMORY
- *\li #ISC_R_UNEXPECTED
- */
-
-isc_result_t
-dns_portlist_add(dns_portlist_t *portlist, int af, in_port_t port);
-/*%<
- * Add the given <port,af> tuple to the portlist.
- *
- * Requires:
- *\li 'portlist' to be valid.
- *\li 'af' to be AF_INET or AF_INET6
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMEMORY
- */
-
-void
-dns_portlist_remove(dns_portlist_t *portlist, int af, in_port_t port);
-/*%<
- * Remove the given <port,af> tuple to the portlist.
- *
- * Requires:
- *\li 'portlist' to be valid.
- *\li 'af' to be AF_INET or AF_INET6
- */
-
-isc_boolean_t
-dns_portlist_match(dns_portlist_t *portlist, int af, in_port_t port);
-/*%<
- * Find the given <port,af> tuple to the portlist.
- *
- * Requires:
- *\li 'portlist' to be valid.
- *\li 'af' to be AF_INET or AF_INET6
- *
- * Returns
- * \li #ISC_TRUE if the tuple is found, ISC_FALSE otherwise.
- */
-
-void
-dns_portlist_attach(dns_portlist_t *portlist, dns_portlist_t **portlistp);
-/*%<
- * Attach to a port list.
- *
- * Requires:
- *\li 'portlist' to be valid.
- *\li 'portlistp' to be non NULL and '*portlistp' to be NULL;
- */
-
-void
-dns_portlist_detach(dns_portlist_t **portlistp);
-/*%<
- * Detach from a port list.
- *
- * Requires:
- *\li '*portlistp' to be valid.
- */
-
-ISC_LANG_ENDDECLS
diff --git a/contrib/bind9/lib/dns/include/dns/private.h b/contrib/bind9/lib/dns/include/dns/private.h
deleted file mode 100644
index c4a2ae64f71b..000000000000
--- a/contrib/bind9/lib/dns/include/dns/private.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN 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.5 2011/10/28 12:20:31 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_result_t
-dns_private_totext(dns_rdata_t *privaterdata, isc_buffer_t *buffer);
-/*%<
- * Convert a private-type RR 'privaterdata' to human-readable form,
- * and place the result in 'buffer'. The text should indicate
- * which action the private-type record specifies and whether the
- * action has been completed.
- *
- * Requires:
- * \li 'privaterdata' is a valid rdata containing at least five bytes
- * \li 'buffer' is a valid buffer
- *
- * Returns:
- * \li ISC_R_SUCCESS
- * \li other on error
- */
-
-ISC_LANG_ENDDECLS
-
-#endif
diff --git a/contrib/bind9/lib/dns/include/dns/rbt.h b/contrib/bind9/lib/dns/include/dns/rbt.h
deleted file mode 100644
index 3e9dc886576f..000000000000
--- a/contrib/bind9/lib/dns/include/dns/rbt.h
+++ /dev/null
@@ -1,942 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: rbt.h,v 1.77 2009/11/04 01:18:19 marka Exp $ */
-
-#ifndef DNS_RBT_H
-#define DNS_RBT_H 1
-
-/*! \file dns/rbt.h */
-
-#include <isc/lang.h>
-#include <isc/magic.h>
-#include <isc/refcount.h>
-
-#include <dns/types.h>
-
-ISC_LANG_BEGINDECLS
-
-#define DNS_RBT_USEHASH 1
-
-/*@{*/
-/*%
- * Option values for dns_rbt_findnode() and dns_rbt_findname().
- * These are used to form a bitmask.
- */
-#define DNS_RBTFIND_NOOPTIONS 0x00
-#define DNS_RBTFIND_EMPTYDATA 0x01
-#define DNS_RBTFIND_NOEXACT 0x02
-#define DNS_RBTFIND_NOPREDECESSOR 0x04
-/*@}*/
-
-#ifndef DNS_RBT_USEISCREFCOUNT
-#ifdef ISC_REFCOUNT_HAVEATOMIC
-#define DNS_RBT_USEISCREFCOUNT 1
-#endif
-#endif
-
-/*
- * These should add up to 30.
- */
-#define DNS_RBT_LOCKLENGTH 10
-#define DNS_RBT_REFLENGTH 20
-
-#define DNS_RBTNODE_MAGIC ISC_MAGIC('R','B','N','O')
-#if DNS_RBT_USEMAGIC
-#define DNS_RBTNODE_VALID(n) ISC_MAGIC_VALID(n, DNS_RBTNODE_MAGIC)
-#else
-#define DNS_RBTNODE_VALID(n) ISC_TRUE
-#endif
-
-/*%
- * This is the structure that is used for each node in the red/black
- * tree of trees. NOTE WELL: the implementation manages this as a variable
- * length structure, with the actual wire-format name and other data
- * appended to this structure. Allocating a contiguous block of memory for
- * 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;
-#endif
- dns_rbtnode_t *parent;
- dns_rbtnode_t *left;
- dns_rbtnode_t *right;
- dns_rbtnode_t *down;
-#ifdef DNS_RBT_USEHASH
- dns_rbtnode_t *hashnext;
-#endif
-
- /*%
- * Used for LRU cache. This linked list is used to mark nodes which
- * have no data any longer, but we cannot unlink at that exact moment
- * because we did not or could not obtain a write lock on the tree.
- */
- ISC_LINK(dns_rbtnode_t) deadlink;
-
- /*@{*/
- /*!
- * 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.
- *
- * In each case below the "range" indicated is what's _necessary_ for
- * the bitfield to hold, not what it actually _can_ hold.
- */
- 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 : 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 */
- /*@}*/
-
-#ifdef DNS_RBT_USEHASH
- unsigned int hashval;
-#endif
-
- /*@{*/
- /*!
- * These values are used in the RBT DB implementation. The appropriate
- * node lock must be held before accessing them.
- */
- void *data;
- unsigned int dirty:1;
- unsigned int wild:1;
- unsigned int locknum:DNS_RBT_LOCKLENGTH;
-#ifndef DNS_RBT_USEISCREFCOUNT
- unsigned int references:DNS_RBT_REFLENGTH;
-#else
- isc_refcount_t references; /* note that this is not in the bitfield */
-#endif
- /*@}*/
-};
-
-typedef isc_result_t (*dns_rbtfindcallback_t)(dns_rbtnode_t *node,
- dns_name_t *name,
- void *callback_arg);
-
-/*****
- ***** Chain Info
- *****/
-
-/*!
- * A chain is used to keep track of the sequence of nodes to reach any given
- * node from the root of the tree. Originally nodes did not have parent
- * pointers in them (for memory usage reasons) so there was no way to find
- * the path back to the root from any given node. Now that nodes have parent
- * pointers, chains might be going away in a future release, though the
- * movement functionality would remain.
- *
- * In any event, parent information, whether via parent pointers or chains, is
- * necessary information for iterating through the tree or for basic internal
- * tree maintenance issues (ie, the rotations that are done to rebalance the
- * tree when a node is added). The obvious implication of this is that for a
- * chain to remain valid, the tree has to be locked down against writes for the
- * duration of the useful life of the chain, because additions or removals can
- * change the path from the root to the node the chain has targeted.
- *
- * The dns_rbtnodechain_ functions _first, _last, _prev and _next all take
- * dns_name_t parameters for the name and the origin, which can be NULL. If
- * non-NULL, 'name' will end up pointing to the name data and offsets that are
- * stored at the node (and thus it will be read-only), so it should be a
- * regular dns_name_t that has been initialized with dns_name_init. When
- * 'origin' is non-NULL, it will get the name of the origin stored in it, so it
- * needs to have its own buffer space and offsets, which is most easily
- * accomplished with a dns_fixedname_t. It is _not_ necessary to reinitialize
- * either 'name' or 'origin' between calls to the chain functions.
- *
- * NOTE WELL: even though the name data at the root of the tree of trees will
- * be absolute (typically just "."), it will will be made into a relative name
- * with an origin of "." -- an empty name when the node is ".". This is
- * because a common on operation on 'name' and 'origin' is to use
- * dns_name_concatenate() on them to generate the complete name. An empty name
- * can be detected when dns_name_countlabels == 0, and is printed by
- * dns_name_totext()/dns_name_format() as "@", consistent with RFC1035's
- * definition of "@" as the current origin.
- *
- * dns_rbtnodechain_current is similar to the _first, _last, _prev and _next
- * functions but additionally can provide the node to which the chain points.
- */
-
-/*%
- * The number of level blocks to allocate at a time. Currently the maximum
- * number of levels is allocated directly in the structure, but future
- * revisions of this code might have a static initial block with dynamic
- * growth. Allocating space for 256 levels when the tree is almost never that
- * deep is wasteful, but it's not clear that it matters, since the waste is
- * only 2MB for 1000 concurrently active chains on a system with 64-bit
- * pointers.
- */
-#define DNS_RBT_LEVELBLOCK 254
-
-typedef struct dns_rbtnodechain {
- unsigned int magic;
- isc_mem_t * mctx;
- /*%
- * The terminal node of the chain. It is not in levels[].
- * This is ostensibly private ... but in a pinch it could be
- * used tell that the chain points nowhere without needing to
- * call dns_rbtnodechain_current().
- */
- dns_rbtnode_t * end;
- /*%
- * The maximum number of labels in a name is 128; bitstrings mean
- * a conceptually very large number (which I have not bothered to
- * compute) of logical levels because splitting can potentially occur
- * at each bit. However, DNSSEC restricts the number of "logical"
- * labels in a name to 255, meaning only 254 pointers are needed
- * in the worst case.
- */
- dns_rbtnode_t * levels[DNS_RBT_LEVELBLOCK];
- /*%
- * level_count indicates how deep the chain points into the
- * tree of trees, and is the index into the levels[] array.
- * Thus, levels[level_count - 1] is the last level node stored.
- * A chain that points to the top level of the tree of trees has
- * a level_count of 0, the first level has a level_count of 1, and
- * so on.
- */
- unsigned int level_count;
- /*%
- * level_matches tells how many levels matched above the node
- * returned by dns_rbt_findnode(). A match (partial or exact) found
- * in the first level thus results in level_matches being set to 1.
- * This is used by the rbtdb to set the start point for a recursive
- * search of superdomains until the RR it is looking for is found.
- */
- unsigned int level_matches;
-} dns_rbtnodechain_t;
-
-/*****
- ***** Public interfaces.
- *****/
-isc_result_t
-dns_rbt_create(isc_mem_t *mctx, void (*deleter)(void *, void *),
- void *deleter_arg, dns_rbt_t **rbtp);
-/*%<
- * Initialize a red-black tree of trees.
- *
- * Notes:
- *\li The deleter argument, if non-null, points to a function that is
- * responsible for cleaning up any memory associated with the data
- * pointer of a node when the node is deleted. It is passed the
- * deleted node's data pointer as its first argument and deleter_arg
- * as its second argument.
- *
- * Requires:
- * \li mctx is a pointer to a valid memory context.
- *\li rbtp != NULL && *rbtp == NULL
- *\li arg == NULL iff deleter == NULL
- *
- * Ensures:
- *\li If result is ISC_R_SUCCESS:
- * *rbtp points to a valid red-black tree manager
- *
- *\li If result is failure:
- * *rbtp does not point to a valid red-black tree manager.
- *
- * Returns:
- *\li #ISC_R_SUCCESS Success
- *\li #ISC_R_NOMEMORY Resource limit: Out of Memory
- */
-
-isc_result_t
-dns_rbt_addname(dns_rbt_t *rbt, dns_name_t *name, void *data);
-/*%<
- * Add 'name' to the tree of trees, associated with 'data'.
- *
- * Notes:
- *\li 'data' is never required to be non-NULL, but specifying it
- * when the name is added is faster than searching for 'name'
- * again and then setting the data pointer. The lack of a data pointer
- * for a node also has other ramifications regarding whether
- * dns_rbt_findname considers a node to exist, or dns_rbt_deletename
- * joins nodes.
- *
- * Requires:
- *\li rbt is a valid rbt manager.
- *\li dns_name_isabsolute(name) == TRUE
- *
- * Ensures:
- *\li 'name' is not altered in any way.
- *
- *\li Any external references to nodes in the tree are unaffected by
- * node splits that are necessary to insert the new name.
- *
- *\li If result is #ISC_R_SUCCESS:
- * 'name' is findable in the red/black tree of trees in O(log N).
- * The data pointer of the node for 'name' is set to 'data'.
- *
- *\li If result is #ISC_R_EXISTS or #ISC_R_NOSPACE:
- * The tree of trees is unaltered.
- *
- *\li If result is #ISC_R_NOMEMORY:
- * No guarantees.
- *
- * Returns:
- *\li #ISC_R_SUCCESS Success
- *\li #ISC_R_EXISTS The name already exists with associated data.
- *\li #ISC_R_NOSPACE The name had more logical labels than are allowed.
- *\li #ISC_R_NOMEMORY Resource Limit: Out of Memory
- */
-
-isc_result_t
-dns_rbt_addnode(dns_rbt_t *rbt, dns_name_t *name, dns_rbtnode_t **nodep);
-
-/*%<
- * Just like dns_rbt_addname, but returns the address of the node.
- *
- * Requires:
- *\li rbt is a valid rbt structure.
- *\li dns_name_isabsolute(name) == TRUE
- *\li nodep != NULL && *nodep == NULL
- *
- * Ensures:
- *\li 'name' is not altered in any way.
- *
- *\li Any external references to nodes in the tree are unaffected by
- * node splits that are necessary to insert the new name.
- *
- *\li If result is ISC_R_SUCCESS:
- * 'name' is findable in the red/black tree of trees in O(log N).
- * *nodep is the node that was added for 'name'.
- *
- *\li If result is ISC_R_EXISTS:
- * The tree of trees is unaltered.
- * *nodep is the existing node for 'name'.
- *
- *\li If result is ISC_R_NOMEMORY:
- * No guarantees.
- *
- * Returns:
- *\li #ISC_R_SUCCESS Success
- *\li #ISC_R_EXISTS The name already exists, possibly without data.
- *\li #ISC_R_NOMEMORY Resource Limit: Out of Memory
- */
-
-isc_result_t
-dns_rbt_findname(dns_rbt_t *rbt, dns_name_t *name, unsigned int options,
- dns_name_t *foundname, void **data);
-/*%<
- * Get the data pointer associated with 'name'.
- *
- * Notes:
- *\li When #DNS_RBTFIND_NOEXACT is set, the closest matching superdomain is
- * returned (also subject to #DNS_RBTFIND_EMPTYDATA), even when there is
- * an exact match in the tree.
- *
- *\li A node that has no data is considered not to exist for this function,
- * unless the #DNS_RBTFIND_EMPTYDATA option is set.
- *
- * Requires:
- *\li rbt is a valid rbt manager.
- *\li dns_name_isabsolute(name) == TRUE
- *\li data != NULL && *data == NULL
- *
- * Ensures:
- *\li 'name' and the tree are not altered in any way.
- *
- *\li If result is ISC_R_SUCCESS:
- * *data is the data associated with 'name'.
- *
- *\li If result is DNS_R_PARTIALMATCH:
- * *data is the data associated with the deepest superdomain
- * of 'name' which has data.
- *
- *\li If result is ISC_R_NOTFOUND:
- * Neither the name nor a superdomain was found with data.
- *
- * Returns:
- *\li #ISC_R_SUCCESS Success
- *\li #DNS_R_PARTIALMATCH Superdomain found with data
- *\li #ISC_R_NOTFOUND No match
- *\li #ISC_R_NOSPACE Concatenating nodes to form foundname failed
- */
-
-isc_result_t
-dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name, dns_name_t *foundname,
- dns_rbtnode_t **node, dns_rbtnodechain_t *chain,
- unsigned int options, dns_rbtfindcallback_t callback,
- void *callback_arg);
-/*%<
- * Find the node for 'name'.
- *
- * Notes:
- *\li A node that has no data is considered not to exist for this function,
- * unless the DNS_RBTFIND_EMPTYDATA option is set. This applies to both
- * exact matches and partial matches.
- *
- *\li If the chain parameter is non-NULL, then the path through the tree
- * to the DNSSEC predecessor of the searched for name is maintained,
- * unless the DNS_RBTFIND_NOPREDECESSOR or DNS_RBTFIND_NOEXACT option
- * is used. (For more details on those options, see below.)
- *
- *\li If there is no predecessor, then the chain will point to nowhere, as
- * indicated by chain->end being NULL or dns_rbtnodechain_current
- * returning ISC_R_NOTFOUND. Note that in a normal Internet DNS RBT
- * there will always be a predecessor for all names except the root
- * name, because '.' will exist and '.' is the predecessor of
- * everything. But you can certainly construct a trivial tree and a
- * search for it that has no predecessor.
- *
- *\li Within the chain structure, the 'levels' member of the structure holds
- * the root node of each level except the first.
- *
- *\li The 'level_count' of the chain indicates how deep the chain to the
- * predecessor name is, as an index into the 'levels[]' array. It does
- * not count name elements, per se, but only levels of the tree of trees,
- * the distinction arising because multiple labels from a name can be
- * stored on only one level. It is also does not include the level
- * that has the node, since that level is not stored in levels[].
- *
- *\li The chain's 'level_matches' is not directly related to the predecessor.
- * It is the number of levels above the level of the found 'node',
- * regardless of whether it was a partial match or exact match. When
- * the node is found in the top level tree, or no node is found at all,
- * level_matches is 0.
- *
- *\li When DNS_RBTFIND_NOEXACT is set, the closest matching superdomain is
- * returned (also subject to DNS_RBTFIND_EMPTYDATA), even when
- * there is an exact match in the tree. In this case, the chain
- * will not point to the DNSSEC predecessor, but will instead point
- * to the exact match, if there was any. Thus the preceding paragraphs
- * should have "exact match" substituted for "predecessor" to describe
- * how the various elements of the chain are set. This was done to
- * ensure that the chain's state was sane, and to prevent problems that
- * occurred when running the predecessor location code under conditions
- * it was not designed for. It is not clear *where* the chain should
- * point when DNS_RBTFIND_NOEXACT is set, so if you end up using a chain
- * with this option because you want a particular node, let us know
- * where you want the chain pointed, so this can be made more firm.
- *
- * Requires:
- *\li rbt is a valid rbt manager.
- *\li dns_name_isabsolute(name) == TRUE.
- *\li node != NULL && *node == NULL.
- *\li #DNS_RBTFIND_NOEXACT and DNS_RBTFIND_NOPREDECESSOR are mutually
- * exclusive.
- *
- * Ensures:
- *\li 'name' and the tree are not altered in any way.
- *
- *\li If result is ISC_R_SUCCESS:
- *\verbatim
- * *node is the terminal node for 'name'.
-
- * 'foundname' and 'name' represent the same name (though not
- * the same memory).
-
- * 'chain' points to the DNSSEC predecessor, if any, of 'name'.
- *
- * chain->level_matches and chain->level_count are equal.
- *\endverbatim
- *
- * If result is DNS_R_PARTIALMATCH:
- *\verbatim
- * *node is the data associated with the deepest superdomain
- * of 'name' which has data.
- *
- * 'foundname' is the name of deepest superdomain (which has
- * data, unless the DNS_RBTFIND_EMPTYDATA option is set).
- *
- * 'chain' points to the DNSSEC predecessor, if any, of 'name'.
- *\endverbatim
- *
- *\li If result is ISC_R_NOTFOUND:
- *\verbatim
- * Neither the name nor a superdomain was found. *node is NULL.
- *
- * 'chain' points to the DNSSEC predecessor, if any, of 'name'.
- *
- * chain->level_matches is 0.
- *\endverbatim
- *
- * Returns:
- *\li #ISC_R_SUCCESS Success
- *\li #DNS_R_PARTIALMATCH Superdomain found with data
- *\li #ISC_R_NOTFOUND No match, or superdomain with no data
- *\li #ISC_R_NOSPACE Concatenating nodes to form foundname failed
- */
-
-isc_result_t
-dns_rbt_deletename(dns_rbt_t *rbt, dns_name_t *name, isc_boolean_t recurse);
-/*%<
- * Delete 'name' from the tree of trees.
- *
- * Notes:
- *\li When 'name' is removed, if recurse is ISC_TRUE then all of its
- * subnames are removed too.
- *
- * Requires:
- *\li rbt is a valid rbt manager.
- *\li dns_name_isabsolute(name) == TRUE
- *
- * Ensures:
- *\li 'name' is not altered in any way.
- *
- *\li Does NOT ensure that any external references to nodes in the tree
- * are unaffected by node joins.
- *
- *\li If result is ISC_R_SUCCESS:
- * 'name' does not appear in the tree with data; however,
- * the node for the name might still exist which can be
- * found with dns_rbt_findnode (but not dns_rbt_findname).
- *
- *\li If result is ISC_R_NOTFOUND:
- * 'name' does not appear in the tree with data, because
- * it did not appear in the tree before the function was called.
- *
- *\li If result is something else:
- * See result codes for dns_rbt_findnode (if it fails, the
- * node is not deleted) or dns_rbt_deletenode (if it fails,
- * the node is deleted, but the tree is not optimized when
- * it could have been).
- *
- * Returns:
- *\li #ISC_R_SUCCESS Success
- *\li #ISC_R_NOTFOUND No match
- *\li something_else Any return code from dns_rbt_findnode except
- * DNS_R_PARTIALMATCH (which causes ISC_R_NOTFOUND
- * to be returned instead), and any code from
- * dns_rbt_deletenode.
- */
-
-isc_result_t
-dns_rbt_deletenode(dns_rbt_t *rbt, dns_rbtnode_t *node, isc_boolean_t recurse);
-/*%<
- * Delete 'node' from the tree of trees.
- *
- * Notes:
- *\li When 'node' is removed, if recurse is ISC_TRUE then all nodes
- * in levels down from it are removed too.
- *
- * Requires:
- *\li rbt is a valid rbt manager.
- *\li node != NULL.
- *
- * Ensures:
- *\li Does NOT ensure that any external references to nodes in the tree
- * are unaffected by node joins.
- *
- *\li If result is ISC_R_SUCCESS:
- * 'node' does not appear in the tree with data; however,
- * the node might still exist if it serves as a pointer to
- * a lower tree level as long as 'recurse' was false, hence
- * the node could can be found with dns_rbt_findnode when
- * that function's empty_data_ok parameter is true.
- *
- *\li If result is ISC_R_NOMEMORY or ISC_R_NOSPACE:
- * The node was deleted, but the tree structure was not
- * optimized.
- *
- * Returns:
- *\li #ISC_R_SUCCESS Success
- *\li #ISC_R_NOMEMORY Resource Limit: Out of Memory when joining nodes.
- *\li #ISC_R_NOSPACE dns_name_concatenate failed when joining nodes.
- */
-
-void
-dns_rbt_namefromnode(dns_rbtnode_t *node, dns_name_t *name);
-/*%<
- * Convert the sequence of labels stored at 'node' into a 'name'.
- *
- * Notes:
- *\li This function does not return the full name, from the root, but
- * just the labels at the indicated node.
- *
- *\li The name data pointed to by 'name' is the information stored
- * in the node, not a copy. Altering the data at this pointer
- * will likely cause grief.
- *
- * Requires:
- * \li name->offsets == NULL
- *
- * Ensures:
- * \li 'name' is DNS_NAMEATTR_READONLY.
- *
- * \li 'name' will point directly to the labels stored after the
- * dns_rbtnode_t struct.
- *
- * \li 'name' will have offsets that also point to the information stored
- * as part of the node.
- */
-
-isc_result_t
-dns_rbt_fullnamefromnode(dns_rbtnode_t *node, dns_name_t *name);
-/*%<
- * Like dns_rbt_namefromnode, but returns the full name from the root.
- *
- * Notes:
- * \li Unlike dns_rbt_namefromnode, the name will not point directly
- * to node data. Rather, dns_name_concatenate will be used to copy
- * the name data from each node into the 'name' argument.
- *
- * Requires:
- * \li name != NULL
- * \li name has a dedicated buffer.
- *
- * Returns:
- * \li ISC_R_SUCCESS
- * \li ISC_R_NOSPACE (possible via dns_name_concatenate)
- * \li DNS_R_NAMETOOLONG (possible via dns_name_concatenate)
- */
-
-char *
-dns_rbt_formatnodename(dns_rbtnode_t *node, char *printname,
- unsigned int size);
-/*%<
- * Format the full name of a node for printing, using dns_name_format().
- *
- * Notes:
- * \li 'size' is the length of the printname buffer. This should be
- * DNS_NAME_FORMATSIZE or larger.
- *
- * Requires:
- * \li node and printname are not NULL.
- *
- * Returns:
- * \li The 'printname' pointer.
- */
-
-unsigned int
-dns_rbt_nodecount(dns_rbt_t *rbt);
-/*%<
- * Obtain the number of nodes in the tree of trees.
- *
- * Requires:
- * \li rbt is a valid rbt manager.
- */
-
-void
-dns_rbt_destroy(dns_rbt_t **rbtp);
-isc_result_t
-dns_rbt_destroy2(dns_rbt_t **rbtp, unsigned int quantum);
-/*%<
- * Stop working with a red-black tree of trees.
- * If 'quantum' is zero then the entire tree will be destroyed.
- * If 'quantum' is non zero then up to 'quantum' nodes will be destroyed
- * allowing the rbt to be incrementally destroyed by repeated calls to
- * dns_rbt_destroy2(). Once dns_rbt_destroy2() has been called no other
- * operations than dns_rbt_destroy()/dns_rbt_destroy2() should be
- * performed on the tree of trees.
- *
- * Requires:
- * \li *rbt is a valid rbt manager.
- *
- * Ensures on ISC_R_SUCCESS:
- * \li All space allocated by the RBT library has been returned.
- *
- * \li *rbt is invalidated as an rbt manager.
- *
- * Returns:
- * \li ISC_R_SUCCESS
- * \li ISC_R_QUOTA if 'quantum' nodes have been destroyed.
- */
-
-void
-dns_rbt_printall(dns_rbt_t *rbt);
-/*%<
- * Print an ASCII representation of the internal structure of the red-black
- * tree of trees.
- *
- * Notes:
- * \li The name stored at each node, along with the node's color, is printed.
- * Then the down pointer, left and right pointers are displayed
- * recursively in turn. NULL down pointers are silently omitted;
- * NULL left and right pointers are printed.
- */
-
-/*****
- ***** Chain Functions
- *****/
-
-void
-dns_rbtnodechain_init(dns_rbtnodechain_t *chain, isc_mem_t *mctx);
-/*%<
- * Initialize 'chain'.
- *
- * Requires:
- *\li 'chain' is a valid pointer.
- *
- *\li 'mctx' is a valid memory context.
- *
- * Ensures:
- *\li 'chain' is suitable for use.
- */
-
-void
-dns_rbtnodechain_reset(dns_rbtnodechain_t *chain);
-/*%<
- * Free any dynamic storage associated with 'chain', and then reinitialize
- * 'chain'.
- *
- * Requires:
- *\li 'chain' is a valid pointer.
- *
- * Ensures:
- *\li 'chain' is suitable for use, and uses no dynamic storage.
- */
-
-void
-dns_rbtnodechain_invalidate(dns_rbtnodechain_t *chain);
-/*%<
- * Free any dynamic storage associated with 'chain', and then invalidates it.
- *
- * Notes:
- *\li Future calls to any dns_rbtnodechain_ function will need to call
- * dns_rbtnodechain_init on the chain first (except, of course,
- * dns_rbtnodechain_init itself).
- *
- * Requires:
- *\li 'chain' is a valid chain.
- *
- * Ensures:
- *\li 'chain' is no longer suitable for use, and uses no dynamic storage.
- */
-
-isc_result_t
-dns_rbtnodechain_current(dns_rbtnodechain_t *chain, dns_name_t *name,
- dns_name_t *origin, dns_rbtnode_t **node);
-/*%<
- * Provide the name, origin and node to which the chain is currently pointed.
- *
- * Notes:
- *\li The tree need not have be locked against additions for the chain
- * to remain valid, however there are no guarantees if any deletion
- * has been made since the chain was established.
- *
- * Requires:
- *\li 'chain' is a valid chain.
- *
- * Ensures:
- *\li 'node', if non-NULL, is the node to which the chain was pointed
- * by dns_rbt_findnode, dns_rbtnodechain_first or dns_rbtnodechain_last.
- * If none were called for the chain since it was initialized or reset,
- * or if the was no predecessor to the name searched for with
- * dns_rbt_findnode, then '*node' is NULL and ISC_R_NOTFOUND is returned.
- *
- *\li 'name', if non-NULL, is the name stored at the terminal level of
- * the chain. This is typically a single label, like the "www" of
- * "www.isc.org", but need not be so. At the root of the tree of trees,
- * if the node is "." then 'name' is ".", otherwise it is relative to ".".
- * (Minimalist and atypical case: if the tree has just the name
- * "isc.org." then the root node's stored name is "isc.org." but 'name'
- * will be "isc.org".)
- *
- *\li 'origin', if non-NULL, is the sequence of labels in the levels
- * above the terminal level, such as "isc.org." in the above example.
- * 'origin' is always "." for the root node.
- *
- *
- * Returns:
- *\li #ISC_R_SUCCESS name, origin & node were successfully set.
- *\li #ISC_R_NOTFOUND The chain does not point to any node.
- *\li &lt;something_else> Any error return from dns_name_concatenate.
- */
-
-isc_result_t
-dns_rbtnodechain_first(dns_rbtnodechain_t *chain, dns_rbt_t *rbt,
- dns_name_t *name, dns_name_t *origin);
-/*%<
- * Set the chain to the lexically first node in the tree of trees.
- *
- * Notes:
- *\li By the definition of ordering for DNS names, the root of the tree of
- * trees is the very first node, since everything else in the megatree
- * uses it as a common suffix.
- *
- * Requires:
- *\li 'chain' is a valid chain.
- *\li 'rbt' is a valid rbt manager.
- *
- * Ensures:
- *\li The chain points to the very first node of the tree.
- *
- *\li 'name' and 'origin', if non-NULL, are set as described for
- * dns_rbtnodechain_current. Thus 'origin' will always be ".".
- *
- * Returns:
- *\li #DNS_R_NEWORIGIN The name & origin were successfully set.
- *\li &lt;something_else> Any error result from dns_rbtnodechain_current.
- */
-
-isc_result_t
-dns_rbtnodechain_last(dns_rbtnodechain_t *chain, dns_rbt_t *rbt,
- dns_name_t *name, dns_name_t *origin);
-/*%<
- * Set the chain to the lexically last node in the tree of trees.
- *
- * Requires:
- *\li 'chain' is a valid chain.
- *\li 'rbt' is a valid rbt manager.
- *
- * Ensures:
- *\li The chain points to the very last node of the tree.
- *
- *\li 'name' and 'origin', if non-NULL, are set as described for
- * dns_rbtnodechain_current.
- *
- * Returns:
- *\li #DNS_R_NEWORIGIN The name & origin were successfully set.
- *\li #ISC_R_NOMEMORY Resource Limit: Out of Memory building chain.
- *\li &lt;something_else> Any error result from dns_name_concatenate.
- */
-
-isc_result_t
-dns_rbtnodechain_prev(dns_rbtnodechain_t *chain, dns_name_t *name,
- dns_name_t *origin);
-/*%<
- * Adjusts chain to point the DNSSEC predecessor of the name to which it
- * is currently pointed.
- *
- * Requires:
- *\li 'chain' is a valid chain.
- *\li 'chain' has been pointed somewhere in the tree with dns_rbt_findnode,
- * dns_rbtnodechain_first or dns_rbtnodechain_last -- and remember that
- * dns_rbt_findnode is not guaranteed to point the chain somewhere,
- * since there may have been no predecessor to the searched for name.
- *
- * Ensures:
- *\li The chain is pointed to the predecessor of its current target.
- *
- *\li 'name' and 'origin', if non-NULL, are set as described for
- * dns_rbtnodechain_current.
- *
- *\li 'origin' is only if a new origin was found.
- *
- * Returns:
- *\li #ISC_R_SUCCESS The predecessor was found and 'name' was set.
- *\li #DNS_R_NEWORIGIN The predecessor was found with a different
- * origin and 'name' and 'origin' were set.
- *\li #ISC_R_NOMORE There was no predecessor.
- *\li &lt;something_else> Any error result from dns_rbtnodechain_current.
- */
-
-isc_result_t
-dns_rbtnodechain_next(dns_rbtnodechain_t *chain, dns_name_t *name,
- dns_name_t *origin);
-/*%<
- * Adjusts chain to point the DNSSEC successor of the name to which it
- * is currently pointed.
- *
- * Requires:
- *\li 'chain' is a valid chain.
- *\li 'chain' has been pointed somewhere in the tree with dns_rbt_findnode,
- * dns_rbtnodechain_first or dns_rbtnodechain_last -- and remember that
- * dns_rbt_findnode is not guaranteed to point the chain somewhere,
- * since there may have been no predecessor to the searched for name.
- *
- * Ensures:
- *\li The chain is pointed to the successor of its current target.
- *
- *\li 'name' and 'origin', if non-NULL, are set as described for
- * dns_rbtnodechain_current.
- *
- *\li 'origin' is only if a new origin was found.
- *
- * Returns:
- *\li #ISC_R_SUCCESS The successor was found and 'name' was set.
- *\li #DNS_R_NEWORIGIN The successor was found with a different
- * origin and 'name' and 'origin' were set.
- *\li #ISC_R_NOMORE There was no successor.
- *\li &lt;something_else> Any error result from dns_name_concatenate.
- */
-
-isc_result_t
-dns_rbtnodechain_down(dns_rbtnodechain_t *chain, dns_name_t *name,
- dns_name_t *origin);
-/*%<
- * Descend down if possible.
- */
-
-isc_result_t
-dns_rbtnodechain_nextflat(dns_rbtnodechain_t *chain, dns_name_t *name);
-/*%<
- * Find the next node at the current depth in DNSSEC order.
- */
-
-/*
- * Wrapper macros for manipulating the rbtnode reference counter:
- * Since we selectively use isc_refcount_t for the reference counter of
- * a rbtnode, operations on the counter depend on the actual type of it.
- * The following macros provide a common interface to these operations,
- * hiding the back-end. The usage is the same as that of isc_refcount_xxx().
- */
-#ifdef DNS_RBT_USEISCREFCOUNT
-#define dns_rbtnode_refinit(node, n) \
- do { \
- isc_refcount_init(&(node)->references, (n)); \
- } while (0)
-#define dns_rbtnode_refdestroy(node) \
- do { \
- isc_refcount_destroy(&(node)->references); \
- } while (0)
-#define dns_rbtnode_refcurrent(node) \
- isc_refcount_current(&(node)->references)
-#define dns_rbtnode_refincrement0(node, refs) \
- do { \
- isc_refcount_increment0(&(node)->references, (refs)); \
- } while (0)
-#define dns_rbtnode_refincrement(node, refs) \
- do { \
- isc_refcount_increment(&(node)->references, (refs)); \
- } while (0)
-#define dns_rbtnode_refdecrement(node, refs) \
- do { \
- isc_refcount_decrement(&(node)->references, (refs)); \
- } 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_refcurrent(node) ((node)->references)
-#define dns_rbtnode_refincrement0(node, refs) \
- do { \
- unsigned int *_tmp = (unsigned int *)(refs); \
- (node)->references++; \
- if ((_tmp) != NULL) \
- (*_tmp) = (node)->references; \
- } while (0)
-#define dns_rbtnode_refincrement(node, refs) \
- do { \
- REQUIRE((node)->references > 0); \
- (node)->references++; \
- if ((refs) != NULL) \
- (*refs) = (node)->references; \
- } while (0)
-#define dns_rbtnode_refdecrement(node, refs) \
- do { \
- REQUIRE((node)->references > 0); \
- (node)->references--; \
- if ((refs) != NULL) \
- (*refs) = (node)->references; \
- } while (0)
-#endif /* DNS_RBT_USEISCREFCOUNT */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_RBT_H */
diff --git a/contrib/bind9/lib/dns/include/dns/rcode.h b/contrib/bind9/lib/dns/include/dns/rcode.h
deleted file mode 100644
index 94e831bfd54e..000000000000
--- a/contrib/bind9/lib/dns/include/dns/rcode.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: rcode.h,v 1.21 2008/09/25 04:02:39 tbox Exp $ */
-
-#ifndef DNS_RCODE_H
-#define DNS_RCODE_H 1
-
-/*! \file dns/rcode.h */
-
-#include <isc/lang.h>
-
-#include <dns/types.h>
-
-ISC_LANG_BEGINDECLS
-
-isc_result_t dns_rcode_fromtext(dns_rcode_t *rcodep, isc_textregion_t *source);
-/*%<
- * Convert the text 'source' refers to into a DNS error value.
- *
- * Requires:
- *\li 'rcodep' is a valid pointer.
- *
- *\li 'source' is a valid text region.
- *
- * Returns:
- *\li #ISC_R_SUCCESS on success
- *\li #DNS_R_UNKNOWN type is unknown
- */
-
-isc_result_t dns_rcode_totext(dns_rcode_t rcode, isc_buffer_t *target);
-/*%<
- * Put a textual representation of error 'rcode' into 'target'.
- *
- * Requires:
- *\li 'rcode' is a valid rcode.
- *
- *\li 'target' is a valid text buffer.
- *
- * Ensures:
- *\li If the result is success:
- * The used space in 'target' is updated.
- *
- * Returns:
- *\li #ISC_R_SUCCESS on success
- *\li #ISC_R_NOSPACE target buffer is too small
- */
-
-isc_result_t dns_tsigrcode_fromtext(dns_rcode_t *rcodep,
- isc_textregion_t *source);
-/*%<
- * Convert the text 'source' refers to into a TSIG/TKEY error value.
- *
- * Requires:
- *\li 'rcodep' is a valid pointer.
- *
- *\li 'source' is a valid text region.
- *
- * Returns:
- *\li #ISC_R_SUCCESS on success
- *\li #DNS_R_UNKNOWN type is unknown
- */
-
-isc_result_t dns_tsigrcode_totext(dns_rcode_t rcode, isc_buffer_t *target);
-/*%<
- * Put a textual representation of TSIG/TKEY error 'rcode' into 'target'.
- *
- * Requires:
- *\li 'rcode' is a valid TSIG/TKEY error code.
- *
- *\li 'target' is a valid text buffer.
- *
- * Ensures:
- *\li If the result is success:
- * The used space in 'target' is updated.
- *
- * Returns:
- *\li #ISC_R_SUCCESS on success
- *\li #ISC_R_NOSPACE target buffer is too small
- */
-
-isc_result_t
-dns_hashalg_fromtext(unsigned char *hashalg, isc_textregion_t *source);
-/*%<
- * Convert the text 'source' refers to into a has algorithm value.
- *
- * Requires:
- *\li 'hashalg' is a valid pointer.
- *
- *\li 'source' is a valid text region.
- *
- * Returns:
- *\li #ISC_R_SUCCESS on success
- *\li #DNS_R_UNKNOWN type is unknown
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_RCODE_H */
diff --git a/contrib/bind9/lib/dns/include/dns/rdata.h b/contrib/bind9/lib/dns/include/dns/rdata.h
deleted file mode 100644
index 89ecaf800696..000000000000
--- a/contrib/bind9/lib/dns/include/dns/rdata.h
+++ /dev/null
@@ -1,774 +0,0 @@
-/*
- * Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: rdata.h,v 1.80 2011/03/20 02:31:53 marka Exp $ */
-
-#ifndef DNS_RDATA_H
-#define DNS_RDATA_H 1
-
-/*****
- ***** Module Info
- *****/
-
-/*! \file dns/rdata.h
- * \brief
- * Provides facilities for manipulating DNS rdata, including conversions to
- * and from wire format and text format.
- *
- * Given the large amount of rdata possible in a nameserver, it was important
- * to come up with a very efficient way of storing rdata, but at the same
- * time allow it to be manipulated.
- *
- * The decision was to store rdata in uncompressed wire format,
- * and not to make it a fully abstracted object; i.e. certain parts of the
- * server know rdata is stored that way. This saves a lot of memory, and
- * makes adding rdata to messages easy. Having much of the server know
- * the representation would be perilous, and we certainly don't want each
- * user of rdata to be manipulating such a low-level structure. This is
- * where the rdata module comes in. The module allows rdata handles to be
- * created and attached to uncompressed wire format regions. All rdata
- * operations and conversions are done through these handles.
- *
- * Implementation Notes:
- *
- *\li The routines in this module are expected to be synthesized by the
- * build process from a set of source files, one per rdata type. For
- * portability, it's probably best that the building be done by a C
- * program. Adding a new rdata type will be a simple matter of adding
- * a file to a directory and rebuilding the server. *All* knowledge of
- * the format of a particular rdata type is in this file.
- *
- * MP:
- *\li Clients of this module must impose any required synchronization.
- *
- * Reliability:
- *\li This module deals with low-level byte streams. Errors in any of
- * the functions are likely to crash the server or corrupt memory.
- *
- *\li Rdata is typed, and the caller must know what type of rdata it has.
- * A caller that gets this wrong could crash the server.
- *
- *\li The fromstruct() and tostruct() routines use a void * pointer to
- * represent the structure. The caller must ensure that it passes a
- * pointer to the appropriate type, or the server could crash or memory
- * could be corrupted.
- *
- * Resources:
- *\li None.
- *
- * Security:
- *
- *\li *** WARNING ***
- * dns_rdata_fromwire() deals with raw network data. An error in
- * this routine could result in the failure or hijacking of the server.
- *
- * Standards:
- *\li RFC1035
- *\li Draft EDNS0 (0)
- *\li Draft EDNS1 (0)
- *\li Draft Binary Labels (2)
- *\li Draft Local Compression (1)
- *\li Various RFCs for particular types; these will be documented in the
- * sources files of the types.
- *
- */
-
-/***
- *** Imports
- ***/
-
-#include <isc/lang.h>
-
-#include <dns/types.h>
-#include <dns/name.h>
-#include <dns/message.h>
-
-ISC_LANG_BEGINDECLS
-
-
-/***
- *** Types
- ***/
-
-/*%
- ***** An 'rdata' is a handle to a binary region. The handle has an RR
- ***** class and type, and the data in the binary region is in the format
- ***** of the given class and type.
- *****/
-/*%
- * Clients are strongly discouraged from using this type directly, with
- * the exception of the 'link' field which may be used directly for whatever
- * purpose the client desires.
- */
-struct dns_rdata {
- unsigned char * data;
- unsigned int length;
- dns_rdataclass_t rdclass;
- dns_rdatatype_t type;
- unsigned int flags;
- ISC_LINK(dns_rdata_t) link;
-};
-
-#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)
-
-/*
- * The maximum length of a RDATA that can be sent on the wire.
- * Max packet size (65535) less header (12), less name (1), type (2),
- * class (2), ttl(4), length (2).
- *
- * None of the defined types that support name compression can exceed
- * this and all new types are to be sent uncompressed.
- */
-
-#define DNS_RDATA_MAXLENGTH 65512U
-
-/*
- * Flags affecting rdata formatting style. Flags 0xFFFF0000
- * are used by masterfile-level formatting and defined elsewhere.
- * See additional comments at dns_rdata_tofmttext().
- */
-
-/*% Split the rdata into multiple lines to try to keep it
- within the "width". */
-#define DNS_STYLEFLAG_MULTILINE 0x00000001U
-
-/*% Output explanatory comments. */
-#define DNS_STYLEFLAG_COMMENT 0x00000002U
-#define DNS_STYLEFLAG_RRCOMMENT 0x00000004U
-
-#define DNS_RDATA_DOWNCASE DNS_NAME_DOWNCASE
-#define DNS_RDATA_CHECKNAMES DNS_NAME_CHECKNAMES
-#define DNS_RDATA_CHECKNAMESFAIL DNS_NAME_CHECKNAMESFAIL
-#define DNS_RDATA_CHECKREVERSE DNS_NAME_CHECKREVERSE
-#define DNS_RDATA_CHECKMX DNS_NAME_CHECKMX
-#define DNS_RDATA_CHECKMXFAIL DNS_NAME_CHECKMXFAIL
-#define DNS_RDATA_UNKNOWNESCAPE 0x80000000
-
-/***
- *** Initialization
- ***/
-
-void
-dns_rdata_init(dns_rdata_t *rdata);
-/*%<
- * Make 'rdata' empty.
- *
- * Requires:
- * 'rdata' is a valid rdata (i.e. not NULL, points to a struct dns_rdata)
- */
-
-void
-dns_rdata_reset(dns_rdata_t *rdata);
-/*%<
- * Make 'rdata' empty.
- *
- * Requires:
- *\li 'rdata' is a previously initialized rdata and is not linked.
- */
-
-void
-dns_rdata_clone(const dns_rdata_t *src, dns_rdata_t *target);
-/*%<
- * Clone 'target' from 'src'.
- *
- * Requires:
- *\li 'src' to be initialized.
- *\li 'target' to be initialized.
- */
-
-/***
- *** Comparisons
- ***/
-
-int
-dns_rdata_compare(const dns_rdata_t *rdata1, const dns_rdata_t *rdata2);
-/*%<
- * Determine the relative ordering under the DNSSEC order relation of
- * 'rdata1' and 'rdata2'.
- *
- * 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'
- */
-
-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
- ***/
-
-void
-dns_rdata_fromregion(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
- dns_rdatatype_t type, isc_region_t *r);
-/*%<
- * Make 'rdata' refer to region 'r'.
- *
- * Requires:
- *
- *\li The data in 'r' is properly formatted for whatever type it is.
- */
-
-void
-dns_rdata_toregion(const dns_rdata_t *rdata, isc_region_t *r);
-/*%<
- * Make 'r' refer to 'rdata'.
- */
-
-isc_result_t
-dns_rdata_fromwire(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
- dns_rdatatype_t type, isc_buffer_t *source,
- dns_decompress_t *dctx, unsigned int options,
- isc_buffer_t *target);
-/*%<
- * Copy the possibly-compressed rdata at source into the target region.
- *
- * Notes:
- *\li Name decompression policy is controlled by 'dctx'.
- *
- * 'options'
- *\li DNS_RDATA_DOWNCASE downcase domain names when they are copied
- * into target.
- *
- * Requires:
- *
- *\li 'rdclass' and 'type' are valid.
- *
- *\li 'source' is a valid buffer, and the active region of 'source'
- * references the rdata to be processed.
- *
- *\li 'target' is a valid buffer.
- *
- *\li 'dctx' is a valid decompression context.
- *
- * Ensures,
- * if result is success:
- * \li If 'rdata' is not NULL, it is attached to the target.
- * \li The conditions dns_name_fromwire() ensures for names hold
- * for all names in the rdata.
- * \li The current location in source is advanced, and the used space
- * in target is updated.
- *
- * Result:
- *\li Success
- *\li Any non-success status from dns_name_fromwire()
- *\li Various 'Bad Form' class failures depending on class and type
- *\li Bad Form: Input too short
- *\li Resource Limit: Not enough space
- */
-
-isc_result_t
-dns_rdata_towire(dns_rdata_t *rdata, dns_compress_t *cctx,
- isc_buffer_t *target);
-/*%<
- * Convert 'rdata' into wire format, compressing it as specified by the
- * compression context 'cctx', and storing the result in 'target'.
- *
- * Notes:
- *\li If the compression context allows global compression, then the
- * global compression table may be updated.
- *
- * Requires:
- *\li 'rdata' is a valid, non-empty rdata
- *
- *\li target is a valid buffer
- *
- *\li Any offsets specified in a global compression table are valid
- * for target.
- *
- * Ensures,
- * if the result is success:
- * \li The used space in target is updated.
- *
- * Returns:
- *\li Success
- *\li Any non-success status from dns_name_towire()
- *\li Resource Limit: Not enough space
- */
-
-isc_result_t
-dns_rdata_fromtext(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
- dns_rdatatype_t type, isc_lex_t *lexer, dns_name_t *origin,
- unsigned int options, isc_mem_t *mctx,
- isc_buffer_t *target, dns_rdatacallbacks_t *callbacks);
-/*%<
- * Convert the textual representation of a DNS rdata into uncompressed wire
- * form stored in the target region. Tokens constituting the text of the rdata
- * are taken from 'lexer'.
- *
- * Notes:
- *\li Relative domain names in the rdata will have 'origin' appended to them.
- * A NULL origin implies "origin == dns_rootname".
- *
- *
- * 'options'
- *\li DNS_RDATA_DOWNCASE downcase domain names when they are copied
- * into target.
- *\li DNS_RDATA_CHECKNAMES perform checknames checks.
- *\li DNS_RDATA_CHECKNAMESFAIL fail if the checknames check fail. If
- * not set a warning will be issued.
- *\li DNS_RDATA_CHECKREVERSE this should set if the owner name ends
- * in IP6.ARPA, IP6.INT or IN-ADDR.ARPA.
- *
- * Requires:
- *
- *\li 'rdclass' and 'type' are valid.
- *
- *\li 'lexer' is a valid isc_lex_t.
- *
- *\li 'mctx' is a valid isc_mem_t.
- *
- *\li 'target' is a valid region.
- *
- *\li 'origin' if non NULL it must be absolute.
- *
- *\li 'callbacks' to be NULL or callbacks->warn and callbacks->error be
- * initialized.
- *
- * Ensures,
- * if result is success:
- *\li If 'rdata' is not NULL, it is attached to the target.
-
- *\li The conditions dns_name_fromtext() ensures for names hold
- * for all names in the rdata.
-
- *\li The used space in target is updated.
- *
- * Result:
- *\li Success
- *\li Translated result codes from isc_lex_gettoken
- *\li Various 'Bad Form' class failures depending on class and type
- *\li Bad Form: Input too short
- *\li Resource Limit: Not enough space
- *\li Resource Limit: Not enough memory
- */
-
-isc_result_t
-dns_rdata_totext(dns_rdata_t *rdata, dns_name_t *origin, isc_buffer_t *target);
-/*%<
- * Convert 'rdata' into text format, storing the result in 'target'.
- * The text will consist of a single line, with fields separated by
- * single spaces.
- *
- * Notes:
- *\li If 'origin' is not NULL, then any names in the rdata that are
- * subdomains of 'origin' will be made relative it.
- *
- *\li XXX Do we *really* want to support 'origin'? I'm inclined towards "no"
- * at the moment.
- *
- * Requires:
- *
- *\li 'rdata' is a valid, non-empty rdata
- *
- *\li 'origin' is NULL, or is a valid name
- *
- *\li 'target' is a valid text buffer
- *
- * Ensures,
- * if the result is success:
- *
- * \li The used space in target is updated.
- *
- * Returns:
- *\li Success
- *\li Any non-success status from dns_name_totext()
- *\li Resource Limit: Not enough space
- */
-
-isc_result_t
-dns_rdata_tofmttext(dns_rdata_t *rdata, dns_name_t *origin, unsigned int flags,
- unsigned int width, unsigned int split_width,
- const char *linebreak, isc_buffer_t *target);
-/*%<
- * Like dns_rdata_totext, but do formatted output suitable for
- * database dumps. This is intended for use by dns_db_dump();
- * library users are discouraged from calling it directly.
- *
- * If (flags & #DNS_STYLEFLAG_MULTILINE) != 0, attempt to stay
- * within 'width' by breaking the text into multiple lines.
- * The string 'linebreak' is inserted between lines, and parentheses
- * are added when necessary. Because RRs contain unbreakable elements
- * such as domain names whose length is variable, unpredictable, and
- * potentially large, there is no guarantee that the lines will
- * not exceed 'width' anyway.
- *
- * If (flags & #DNS_STYLEFLAG_MULTILINE) == 0, the rdata is always
- * printed as a single line, and no parentheses are used.
- * The 'width' and 'linebreak' arguments are ignored.
- *
- * If (flags & #DNS_STYLEFLAG_COMMENT) != 0, output explanatory
- * comments next to things like the SOA timer fields. Some
- * comments (e.g., the SOA ones) are only printed when multiline
- * output is selected.
- *
- * base64 rdata text (e.g., DNSKEY records) will be split into chunks
- * of 'split_width' characters. If split_width == 0, the text will
- * not be split at all. If split_width == UINT_MAX (0xffffffff), then
- * it is undefined and falls back to the default value of 'width'
- */
-
-isc_result_t
-dns_rdata_fromstruct(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
- dns_rdatatype_t type, void *source, isc_buffer_t *target);
-/*%<
- * Convert the C structure representation of an rdata into uncompressed wire
- * format in 'target'.
- *
- * XXX Should we have a 'size' parameter as a sanity check on target?
- *
- * Requires:
- *
- *\li 'rdclass' and 'type' are valid.
- *
- *\li 'source' points to a valid C struct for the class and type.
- *
- *\li 'target' is a valid buffer.
- *
- *\li All structure pointers to memory blocks should be NULL if their
- * corresponding length values are zero.
- *
- * Ensures,
- * if result is success:
- * \li If 'rdata' is not NULL, it is attached to the target.
- *
- * \li The used space in 'target' is updated.
- *
- * Result:
- *\li Success
- *\li Various 'Bad Form' class failures depending on class and type
- *\li Resource Limit: Not enough space
- */
-
-isc_result_t
-dns_rdata_tostruct(dns_rdata_t *rdata, void *target, isc_mem_t *mctx);
-/*%<
- * Convert an rdata into its C structure representation.
- *
- * If 'mctx' is NULL then 'rdata' must persist while 'target' is being used.
- *
- * If 'mctx' is non NULL then memory will be allocated if required.
- *
- * Requires:
- *
- *\li 'rdata' is a valid, non-empty rdata.
- *
- *\li 'target' to point to a valid pointer for the type and class.
- *
- * Result:
- *\li Success
- *\li Resource Limit: Not enough memory
- */
-
-void
-dns_rdata_freestruct(void *source);
-/*%<
- * Free dynamic memory attached to 'source' (if any).
- *
- * Requires:
- *
- *\li 'source' to point to the structure previously filled in by
- * dns_rdata_tostruct().
- */
-
-isc_boolean_t
-dns_rdatatype_ismeta(dns_rdatatype_t type);
-/*%<
- * Return true iff the rdata type 'type' is a meta-type
- * like ANY or AXFR.
- */
-
-isc_boolean_t
-dns_rdatatype_issingleton(dns_rdatatype_t type);
-/*%<
- * Return true iff the rdata type 'type' is a singleton type,
- * like CNAME or SOA.
- *
- * Requires:
- * \li 'type' is a valid rdata type.
- *
- */
-
-isc_boolean_t
-dns_rdataclass_ismeta(dns_rdataclass_t rdclass);
-/*%<
- * Return true iff the rdata class 'rdclass' is a meta-class
- * like ANY or NONE.
- */
-
-isc_boolean_t
-dns_rdatatype_isdnssec(dns_rdatatype_t type);
-/*%<
- * Return true iff 'type' is one of the DNSSEC
- * rdata types that may exist alongside a CNAME record.
- *
- * Requires:
- * \li 'type' is a valid rdata type.
- */
-
-isc_boolean_t
-dns_rdatatype_iszonecutauth(dns_rdatatype_t type);
-/*%<
- * Return true iff rdata of type 'type' is considered authoritative
- * data (not glue) in the NSEC chain when it occurs in the parent zone
- * at a zone cut.
- *
- * Requires:
- * \li 'type' is a valid rdata type.
- *
- */
-
-isc_boolean_t
-dns_rdatatype_isknown(dns_rdatatype_t type);
-/*%<
- * Return true iff the rdata type 'type' is known.
- *
- * Requires:
- * \li 'type' is a valid rdata type.
- *
- */
-
-
-isc_result_t
-dns_rdata_additionaldata(dns_rdata_t *rdata, dns_additionaldatafunc_t add,
- void *arg);
-/*%<
- * Call 'add' for each name and type from 'rdata' which is subject to
- * additional section processing.
- *
- * Requires:
- *
- *\li 'rdata' is a valid, non-empty rdata.
- *
- *\li 'add' is a valid dns_additionalfunc_t.
- *
- * Ensures:
- *
- *\li If successful, then add() will have been called for each name
- * and type subject to additional section processing.
- *
- *\li If add() returns something other than #ISC_R_SUCCESS, that result
- * will be returned as the result of dns_rdata_additionaldata().
- *
- * Returns:
- *
- *\li ISC_R_SUCCESS
- *
- *\li Many other results are possible if not successful.
- */
-
-isc_result_t
-dns_rdata_digest(dns_rdata_t *rdata, dns_digestfunc_t digest, void *arg);
-/*%<
- * Send 'rdata' in DNSSEC canonical form to 'digest'.
- *
- * Note:
- *\li 'digest' may be called more than once by dns_rdata_digest(). The
- * concatenation of all the regions, in the order they were given
- * to 'digest', will be the DNSSEC canonical form of 'rdata'.
- *
- * Requires:
- *
- *\li 'rdata' is a valid, non-empty rdata.
- *
- *\li 'digest' is a valid dns_digestfunc_t.
- *
- * Ensures:
- *
- *\li If successful, then all of the rdata's data has been sent, in
- * DNSSEC canonical form, to 'digest'.
- *
- *\li If digest() returns something other than ISC_R_SUCCESS, that result
- * will be returned as the result of dns_rdata_digest().
- *
- * Returns:
- *
- *\li ISC_R_SUCCESS
- *
- *\li Many other results are possible if not successful.
- */
-
-isc_boolean_t
-dns_rdatatype_questiononly(dns_rdatatype_t type);
-/*%<
- * Return true iff rdata of type 'type' can only appear in the question
- * section of a properly formatted message.
- *
- * Requires:
- * \li 'type' is a valid rdata type.
- *
- */
-
-isc_boolean_t
-dns_rdatatype_notquestion(dns_rdatatype_t type);
-/*%<
- * Return true iff rdata of type 'type' can not appear in the question
- * section of a properly formatted message.
- *
- * Requires:
- * \li 'type' is a valid rdata type.
- *
- */
-
-isc_boolean_t
-dns_rdatatype_atparent(dns_rdatatype_t type);
-/*%<
- * Return true iff rdata of type 'type' should appear at the parent of
- * a zone cut.
- *
- * Requires:
- * \li 'type' is a valid rdata type.
- *
- */
-
-unsigned int
-dns_rdatatype_attributes(dns_rdatatype_t rdtype);
-/*%<
- * Return attributes for the given type.
- *
- * Requires:
- *\li 'rdtype' are known.
- *
- * Returns:
- *\li a bitmask consisting of the following flags.
- */
-
-/*% only one may exist for a name */
-#define DNS_RDATATYPEATTR_SINGLETON 0x00000001U
-/*% requires no other data be present */
-#define DNS_RDATATYPEATTR_EXCLUSIVE 0x00000002U
-/*% Is a meta type */
-#define DNS_RDATATYPEATTR_META 0x00000004U
-/*% Is a DNSSEC type, like RRSIG or NSEC */
-#define DNS_RDATATYPEATTR_DNSSEC 0x00000008U
-/*% Is a zone cut authority type */
-#define DNS_RDATATYPEATTR_ZONECUTAUTH 0x00000010U
-/*% Is reserved (unusable) */
-#define DNS_RDATATYPEATTR_RESERVED 0x00000020U
-/*% Is an unknown type */
-#define DNS_RDATATYPEATTR_UNKNOWN 0x00000040U
-/*% Is META, and can only be in a question section */
-#define DNS_RDATATYPEATTR_QUESTIONONLY 0x00000080U
-/*% is META, and can NOT be in a question section */
-#define DNS_RDATATYPEATTR_NOTQUESTION 0x00000100U
-/*% Is present at zone cuts in the parent, not the child */
-#define DNS_RDATATYPEATTR_ATPARENT 0x00000200U
-
-dns_rdatatype_t
-dns_rdata_covers(dns_rdata_t *rdata);
-/*%<
- * Return the rdatatype that this type covers.
- *
- * Requires:
- *\li 'rdata' is a valid, non-empty rdata.
- *
- *\li 'rdata' is a type that covers other rdata types.
- *
- * Returns:
- *\li The type covered.
- */
-
-isc_boolean_t
-dns_rdata_checkowner(dns_name_t* name, dns_rdataclass_t rdclass,
- dns_rdatatype_t type, isc_boolean_t wildcard);
-/*
- * Returns whether this is a valid ownername for this <type,class>.
- * If wildcard is true allow the first label to be a wildcard if
- * appropriate.
- *
- * Requires:
- * 'name' is a valid name.
- */
-
-isc_boolean_t
-dns_rdata_checknames(dns_rdata_t *rdata, dns_name_t *owner, dns_name_t *bad);
-/*
- * Returns whether 'rdata' contains valid domain names. The checks are
- * sensitive to the owner name.
- *
- * If 'bad' is non-NULL and a domain name fails the check the
- * the offending name will be return in 'bad' by cloning from
- * the 'rdata' contents.
- *
- * Requires:
- * 'rdata' to be valid.
- * 'owner' to be valid.
- * '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/contrib/bind9/lib/dns/include/dns/rdataclass.h b/contrib/bind9/lib/dns/include/dns/rdataclass.h
deleted file mode 100644
index 786eb6af73fa..000000000000
--- a/contrib/bind9/lib/dns/include/dns/rdataclass.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-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: rdataclass.h,v 1.24 2007/06/19 23:47:17 tbox Exp $ */
-
-#ifndef DNS_RDATACLASS_H
-#define DNS_RDATACLASS_H 1
-
-/*! \file dns/rdataclass.h */
-
-#include <isc/lang.h>
-
-#include <dns/types.h>
-
-ISC_LANG_BEGINDECLS
-
-isc_result_t
-dns_rdataclass_fromtext(dns_rdataclass_t *classp, isc_textregion_t *source);
-/*%<
- * Convert the text 'source' refers to into a DNS class.
- *
- * Requires:
- *\li 'classp' is a valid pointer.
- *
- *\li 'source' is a valid text region.
- *
- * Returns:
- *\li #ISC_R_SUCCESS on success
- *\li #DNS_R_UNKNOWN class is unknown
- */
-
-isc_result_t
-dns_rdataclass_totext(dns_rdataclass_t rdclass, isc_buffer_t *target);
-/*%<
- * Put a textual representation of class 'rdclass' into 'target'.
- *
- * Requires:
- *\li 'rdclass' is a valid class.
- *
- *\li 'target' is a valid text buffer.
- *
- * Ensures,
- * if the result is success:
- *\li The used space in 'target' is updated.
- *
- * Returns:
- *\li #ISC_R_SUCCESS on success
- *\li #ISC_R_NOSPACE target buffer is too small
- */
-
-void
-dns_rdataclass_format(dns_rdataclass_t rdclass,
- char *array, unsigned int size);
-/*%<
- * Format a human-readable representation of the class 'rdclass'
- * into the character array 'array', which is of size 'size'.
- * The resulting string is guaranteed to be null-terminated.
- */
-
-#define DNS_RDATACLASS_FORMATSIZE sizeof("CLASS65535")
-/*%<
- * Minimum size of array to pass to dns_rdataclass_format().
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_RDATACLASS_H */
diff --git a/contrib/bind9/lib/dns/include/dns/rdatalist.h b/contrib/bind9/lib/dns/include/dns/rdatalist.h
deleted file mode 100644
index 57debc3951c0..000000000000
--- a/contrib/bind9/lib/dns/include/dns/rdatalist.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: rdatalist.h,v 1.22 2008/04/03 06:09:05 tbox Exp $ */
-
-#ifndef DNS_RDATALIST_H
-#define DNS_RDATALIST_H 1
-
-/*****
- ***** Module Info
- *****/
-
-/*! \file dns/rdatalist.h
- * \brief
- * A DNS rdatalist is a list of rdata of a common type and class.
- *
- * MP:
- *\li Clients of this module must impose any required synchronization.
- *
- * Reliability:
- *\li No anticipated impact.
- *
- * Resources:
- *\li TBS
- *
- * Security:
- *\li No anticipated impact.
- *
- * Standards:
- *\li None.
- */
-
-#include <isc/lang.h>
-
-#include <dns/types.h>
-
-/*%
- * Clients may use this type directly.
- */
-struct dns_rdatalist {
- dns_rdataclass_t rdclass;
- dns_rdatatype_t type;
- dns_rdatatype_t covers;
- dns_ttl_t ttl;
- ISC_LIST(dns_rdata_t) rdata;
- ISC_LINK(dns_rdatalist_t) link;
-};
-
-ISC_LANG_BEGINDECLS
-
-void
-dns_rdatalist_init(dns_rdatalist_t *rdatalist);
-/*%<
- * Initialize rdatalist.
- *
- * Ensures:
- *\li All fields of rdatalist have been initialized to their default
- * values.
- */
-
-isc_result_t
-dns_rdatalist_tordataset(dns_rdatalist_t *rdatalist,
- dns_rdataset_t *rdataset);
-/*%<
- * Make 'rdataset' refer to the rdata in 'rdatalist'.
- *
- * Note:
- *\li The caller must ensure that 'rdatalist' remains valid and unchanged
- * while 'rdataset' is associated with it.
- *
- * Requires:
- *
- *\li 'rdatalist' is a valid rdatalist.
- *
- *\li 'rdataset' is a valid rdataset that is not currently associated with
- * any rdata.
- *
- * Ensures,
- * on success,
- *
- *\li 'rdataset' is associated with the rdata in rdatalist.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- */
-
-isc_result_t
-dns_rdatalist_fromrdataset(dns_rdataset_t *rdataset,
- dns_rdatalist_t **rdatalist);
-/*%<
- * Point 'rdatalist' to the rdatalist in 'rdataset'.
- *
- * Requires:
- *
- *\li 'rdatalist' is a pointer to a NULL dns_rdatalist_t pointer.
- *
- *\li 'rdataset' is a valid rdataset associated with an rdatalist.
- *
- * Ensures,
- * on success,
- *
- *\li 'rdatalist' is pointed to the rdatalist in rdataset.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_RDATALIST_H */
diff --git a/contrib/bind9/lib/dns/include/dns/rdataset.h b/contrib/bind9/lib/dns/include/dns/rdataset.h
deleted file mode 100644
index 31bcd15f1424..000000000000
--- a/contrib/bind9/lib/dns/include/dns/rdataset.h
+++ /dev/null
@@ -1,682 +0,0 @@
-/*
- * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: rdataset.h,v 1.72 2011/06/08 22:13:51 each Exp $ */
-
-#ifndef DNS_RDATASET_H
-#define DNS_RDATASET_H 1
-
-/*****
- ***** Module Info
- *****/
-
-/*! \file dns/rdataset.h
- * \brief
- * A DNS rdataset is a handle that can be associated with a collection of
- * rdata all having a common owner name, class, and type.
- *
- * The dns_rdataset_t type is like a "virtual class". To actually use
- * rdatasets, an implementation of the method suite (e.g. "slabbed rdata") is
- * required.
- *
- * XXX &lt;more&gt; XXX
- *
- * MP:
- *\li Clients of this module must impose any required synchronization.
- *
- * Reliability:
- *\li No anticipated impact.
- *
- * Resources:
- *\li TBS
- *
- * Security:
- *\li No anticipated impact.
- *
- * Standards:
- *\li None.
- */
-
-#include <isc/lang.h>
-#include <isc/magic.h>
-#include <isc/stdtime.h>
-
-#include <dns/types.h>
-#include <dns/rdatastruct.h>
-
-ISC_LANG_BEGINDECLS
-
-typedef enum {
- dns_rdatasetadditional_fromauth,
- dns_rdatasetadditional_fromcache,
- dns_rdatasetadditional_fromglue
-} dns_rdatasetadditional_t;
-
-typedef struct dns_rdatasetmethods {
- void (*disassociate)(dns_rdataset_t *rdataset);
- isc_result_t (*first)(dns_rdataset_t *rdataset);
- isc_result_t (*next)(dns_rdataset_t *rdataset);
- void (*current)(dns_rdataset_t *rdataset,
- dns_rdata_t *rdata);
- void (*clone)(dns_rdataset_t *source,
- dns_rdataset_t *target);
- unsigned int (*count)(dns_rdataset_t *rdataset);
- isc_result_t (*addnoqname)(dns_rdataset_t *rdataset,
- dns_name_t *name);
- isc_result_t (*getnoqname)(dns_rdataset_t *rdataset,
- dns_name_t *name,
- dns_rdataset_t *neg,
- dns_rdataset_t *negsig);
- isc_result_t (*addclosest)(dns_rdataset_t *rdataset,
- dns_name_t *name);
- isc_result_t (*getclosest)(dns_rdataset_t *rdataset,
- dns_name_t *name,
- dns_rdataset_t *neg,
- dns_rdataset_t *negsig);
- isc_result_t (*getadditional)(dns_rdataset_t *rdataset,
- dns_rdatasetadditional_t type,
- dns_rdatatype_t qtype,
- dns_acache_t *acache,
- dns_zone_t **zonep,
- dns_db_t **dbp,
- dns_dbversion_t **versionp,
- dns_dbnode_t **nodep,
- dns_name_t *fname,
- dns_message_t *msg,
- isc_stdtime_t now);
- isc_result_t (*setadditional)(dns_rdataset_t *rdataset,
- dns_rdatasetadditional_t type,
- dns_rdatatype_t qtype,
- dns_acache_t *acache,
- dns_zone_t *zone,
- dns_db_t *db,
- dns_dbversion_t *version,
- dns_dbnode_t *node,
- dns_name_t *fname);
- isc_result_t (*putadditional)(dns_acache_t *acache,
- dns_rdataset_t *rdataset,
- dns_rdatasetadditional_t type,
- dns_rdatatype_t qtype);
- void (*settrust)(dns_rdataset_t *rdataset,
- dns_trust_t trust);
- void (*expire)(dns_rdataset_t *rdataset);
-} dns_rdatasetmethods_t;
-
-#define DNS_RDATASET_MAGIC ISC_MAGIC('D','N','S','R')
-#define DNS_RDATASET_VALID(set) ISC_MAGIC_VALID(set, DNS_RDATASET_MAGIC)
-
-/*%
- * Direct use of this structure by clients is strongly discouraged, except
- * for the 'link' field which may be used however the client wishes. The
- * 'private', 'current', and 'index' fields MUST NOT be changed by clients.
- * rdataset implementations may change any of the fields.
- */
-struct dns_rdataset {
- unsigned int magic; /* XXX ? */
- dns_rdatasetmethods_t * methods;
- ISC_LINK(dns_rdataset_t) link;
- /*
- * XXX do we need these, or should they be retrieved by methods?
- * Leaning towards the latter, since they are not frequently required
- * once you have the rdataset.
- */
- dns_rdataclass_t rdclass;
- dns_rdatatype_t type;
- dns_ttl_t ttl;
- dns_trust_t trust;
- dns_rdatatype_t covers;
- /*
- * attributes
- */
- unsigned int attributes;
- /*%
- * the counter provides the starting point in the "cyclic" order.
- * The value ISC_UINT32_MAX has a special meaning of "picking up a
- * random value." in order to take care of databases that do not
- * increment the counter.
- */
- isc_uint32_t count;
- /*
- * This RRSIG RRset should be re-generated around this time.
- * Only valid if DNS_RDATASETATTR_RESIGN is set in attributes.
- */
- isc_stdtime_t resign;
- /*@{*/
- /*%
- * These are for use by the rdataset implementation, and MUST NOT
- * be changed by clients.
- */
- void * private1;
- void * private2;
- void * private3;
- unsigned int privateuint4;
- void * private5;
- void * private6;
- void * private7;
- /*@}*/
-
-};
-
-/*!
- * \def DNS_RDATASETATTR_RENDERED
- * Used by message.c to indicate that the rdataset was rendered.
- *
- * \def DNS_RDATASETATTR_TTLADJUSTED
- * Used by message.c to indicate that the rdataset's rdata had differing
- * TTL values, and the rdataset->ttl holds the smallest.
- *
- * \def DNS_RDATASETATTR_LOADORDER
- * Output the RRset in load order.
- */
-
-#define DNS_RDATASETATTR_QUESTION 0x00000001
-#define DNS_RDATASETATTR_RENDERED 0x00000002 /*%< Used by message.c */
-#define DNS_RDATASETATTR_ANSWERED 0x00000004 /*%< Used by server. */
-#define DNS_RDATASETATTR_CACHE 0x00000008 /*%< Used by resolver. */
-#define DNS_RDATASETATTR_ANSWER 0x00000010 /*%< Used by resolver. */
-#define DNS_RDATASETATTR_ANSWERSIG 0x00000020 /*%< Used by resolver. */
-#define DNS_RDATASETATTR_EXTERNAL 0x00000040 /*%< Used by resolver. */
-#define DNS_RDATASETATTR_NCACHE 0x00000080 /*%< Used by resolver. */
-#define DNS_RDATASETATTR_CHAINING 0x00000100 /*%< Used by resolver. */
-#define DNS_RDATASETATTR_TTLADJUSTED 0x00000200 /*%< Used by message.c */
-#define DNS_RDATASETATTR_FIXEDORDER 0x00000400
-#define DNS_RDATASETATTR_RANDOMIZE 0x00000800
-#define DNS_RDATASETATTR_CHASE 0x00001000 /*%< Used by resolver. */
-#define DNS_RDATASETATTR_NXDOMAIN 0x00002000
-#define DNS_RDATASETATTR_NOQNAME 0x00004000
-#define DNS_RDATASETATTR_CHECKNAMES 0x00008000 /*%< Used by resolver. */
-#define DNS_RDATASETATTR_REQUIREDGLUE 0x00010000
-#define DNS_RDATASETATTR_LOADORDER 0x00020000
-#define DNS_RDATASETATTR_RESIGN 0x00040000
-#define DNS_RDATASETATTR_CLOSEST 0x00080000
-#define DNS_RDATASETATTR_OPTOUT 0x00100000 /*%< OPTOUT proof */
-#define DNS_RDATASETATTR_NEGATIVE 0x00200000
-
-/*%
- * _OMITDNSSEC:
- * Omit DNSSEC records when rendering ncache records.
- */
-#define DNS_RDATASETTOWIRE_OMITDNSSEC 0x0001
-
-void
-dns_rdataset_init(dns_rdataset_t *rdataset);
-/*%<
- * Make 'rdataset' a valid, disassociated rdataset.
- *
- * Requires:
- *\li 'rdataset' is not NULL.
- *
- * Ensures:
- *\li 'rdataset' is a valid, disassociated rdataset.
- */
-
-void
-dns_rdataset_invalidate(dns_rdataset_t *rdataset);
-/*%<
- * Invalidate 'rdataset'.
- *
- * Requires:
- *\li 'rdataset' is a valid, disassociated rdataset.
- *
- * Ensures:
- *\li If assertion checking is enabled, future attempts to use 'rdataset'
- * without initializing it will cause an assertion failure.
- */
-
-void
-dns_rdataset_disassociate(dns_rdataset_t *rdataset);
-/*%<
- * Disassociate 'rdataset' from its rdata, allowing it to be reused.
- *
- * Notes:
- *\li The client must ensure it has no references to rdata in the rdataset
- * before disassociating.
- *
- * Requires:
- *\li 'rdataset' is a valid, associated rdataset.
- *
- * Ensures:
- *\li 'rdataset' is a valid, disassociated rdataset.
- */
-
-isc_boolean_t
-dns_rdataset_isassociated(dns_rdataset_t *rdataset);
-/*%<
- * Is 'rdataset' associated?
- *
- * Requires:
- *\li 'rdataset' is a valid rdataset.
- *
- * Returns:
- *\li #ISC_TRUE 'rdataset' is associated.
- *\li #ISC_FALSE 'rdataset' is not associated.
- */
-
-void
-dns_rdataset_makequestion(dns_rdataset_t *rdataset, dns_rdataclass_t rdclass,
- dns_rdatatype_t type);
-/*%<
- * Make 'rdataset' a valid, associated, question rdataset, with a
- * question class of 'rdclass' and type 'type'.
- *
- * Notes:
- *\li Question rdatasets have a class and type, but no rdata.
- *
- * Requires:
- *\li 'rdataset' is a valid, disassociated rdataset.
- *
- * Ensures:
- *\li 'rdataset' is a valid, associated, question rdataset.
- */
-
-void
-dns_rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target);
-/*%<
- * Make 'target' refer to the same rdataset as 'source'.
- *
- * Requires:
- *\li 'source' is a valid, associated rdataset.
- *
- *\li 'target' is a valid, dissociated rdataset.
- *
- * Ensures:
- *\li 'target' references the same rdataset as 'source'.
- */
-
-unsigned int
-dns_rdataset_count(dns_rdataset_t *rdataset);
-/*%<
- * Return the number of records in 'rdataset'.
- *
- * Requires:
- *\li 'rdataset' is a valid, associated rdataset.
- *
- * Returns:
- *\li The number of records in 'rdataset'.
- */
-
-isc_result_t
-dns_rdataset_first(dns_rdataset_t *rdataset);
-/*%<
- * Move the rdata cursor to the first rdata in the rdataset (if any).
- *
- * Requires:
- *\li 'rdataset' is a valid, associated rdataset.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMORE There are no rdata in the set.
- */
-
-isc_result_t
-dns_rdataset_next(dns_rdataset_t *rdataset);
-/*%<
- * Move the rdata cursor to the next rdata in the rdataset (if any).
- *
- * Requires:
- *\li 'rdataset' is a valid, associated rdataset.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMORE There are no more rdata in the set.
- */
-
-void
-dns_rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata);
-/*%<
- * Make 'rdata' refer to the current rdata.
- *
- * Notes:
- *
- *\li The data returned in 'rdata' is valid for the life of the
- * rdataset; in particular, subsequent changes in the cursor position
- * do not invalidate 'rdata'.
- *
- * Requires:
- *\li 'rdataset' is a valid, associated rdataset.
- *
- *\li The rdata cursor of 'rdataset' is at a valid location (i.e. the
- * result of last call to a cursor movement command was ISC_R_SUCCESS).
- *
- * Ensures:
- *\li 'rdata' refers to the rdata at the rdata cursor location of
- *\li 'rdataset'.
- */
-
-isc_result_t
-dns_rdataset_totext(dns_rdataset_t *rdataset,
- dns_name_t *owner_name,
- isc_boolean_t omit_final_dot,
- isc_boolean_t question,
- isc_buffer_t *target);
-/*%<
- * Convert 'rdataset' to text format, storing the result in 'target'.
- *
- * Notes:
- *\li The rdata cursor position will be changed.
- *
- *\li The 'question' flag should normally be #ISC_FALSE. If it is
- * #ISC_TRUE, the TTL and rdata fields are not printed. This is
- * for use when printing an rdata representing a question section.
- *
- *\li This interface is deprecated; use dns_master_rdatasettottext()
- * and/or dns_master_questiontotext() instead.
- *
- * Requires:
- *\li 'rdataset' is a valid rdataset.
- *
- *\li 'rdataset' is not empty.
- */
-
-isc_result_t
-dns_rdataset_towire(dns_rdataset_t *rdataset,
- dns_name_t *owner_name,
- dns_compress_t *cctx,
- isc_buffer_t *target,
- unsigned int options,
- unsigned int *countp);
-/*%<
- * Convert 'rdataset' to wire format, compressing names as specified
- * in 'cctx', and storing the result in 'target'.
- *
- * Notes:
- *\li The rdata cursor position will be changed.
- *
- *\li The number of RRs added to target will be added to *countp.
- *
- * Requires:
- *\li 'rdataset' is a valid rdataset.
- *
- *\li 'rdataset' is not empty.
- *
- *\li 'countp' is a valid pointer.
- *
- * Ensures:
- *\li On a return of ISC_R_SUCCESS, 'target' contains a wire format
- * for the data contained in 'rdataset'. Any error return leaves
- * the buffer unchanged.
- *
- *\li *countp has been incremented by the number of RRs added to
- * target.
- *
- * Returns:
- *\li #ISC_R_SUCCESS - all ok
- *\li #ISC_R_NOSPACE - 'target' doesn't have enough room
- *
- *\li Any error returned by dns_rdata_towire(), dns_rdataset_next(),
- * dns_name_towire().
- */
-
-isc_result_t
-dns_rdataset_towiresorted(dns_rdataset_t *rdataset,
- const dns_name_t *owner_name,
- dns_compress_t *cctx,
- isc_buffer_t *target,
- dns_rdatasetorderfunc_t order,
- const void *order_arg,
- unsigned int options,
- unsigned int *countp);
-/*%<
- * Like dns_rdataset_towire(), but sorting the rdatasets according to
- * the integer value returned by 'order' when called with the rdataset
- * and 'order_arg' as arguments.
- *
- * Requires:
- *\li All the requirements of dns_rdataset_towire(), and
- * that order_arg is NULL if and only if order is NULL.
- */
-
-isc_result_t
-dns_rdataset_towirepartial(dns_rdataset_t *rdataset,
- const dns_name_t *owner_name,
- dns_compress_t *cctx,
- isc_buffer_t *target,
- dns_rdatasetorderfunc_t order,
- const void *order_arg,
- unsigned int options,
- unsigned int *countp,
- void **state);
-/*%<
- * Like dns_rdataset_towiresorted() except that a partial rdataset
- * may be written.
- *
- * Requires:
- *\li All the requirements of dns_rdataset_towiresorted().
- * If 'state' is non NULL then the current position in the
- * rdataset will be remembered if the rdataset in not
- * completely written and should be passed on on subsequent
- * calls (NOT CURRENTLY IMPLEMENTED).
- *
- * Returns:
- *\li #ISC_R_SUCCESS if all of the records were written.
- *\li #ISC_R_NOSPACE if unable to fit in all of the records. *countp
- * will be updated to reflect the number of records
- * written.
- */
-
-isc_result_t
-dns_rdataset_additionaldata(dns_rdataset_t *rdataset,
- dns_additionaldatafunc_t add, void *arg);
-/*%<
- * For each rdata in rdataset, call 'add' for each name and type in the
- * rdata which is subject to additional section processing.
- *
- * Requires:
- *
- *\li 'rdataset' is a valid, non-question rdataset.
- *
- *\li 'add' is a valid dns_additionaldatafunc_t
- *
- * Ensures:
- *
- *\li If successful, dns_rdata_additionaldata() will have been called for
- * each rdata in 'rdataset'.
- *
- *\li If a call to dns_rdata_additionaldata() is not successful, the
- * result returned will be the result of dns_rdataset_additionaldata().
- *
- * Returns:
- *
- *\li #ISC_R_SUCCESS
- *
- *\li Any error that dns_rdata_additionaldata() can return.
- */
-
-isc_result_t
-dns_rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name,
- dns_rdataset_t *neg, dns_rdataset_t *negsig);
-/*%<
- * Return the noqname proof for this record.
- *
- * Requires:
- *\li 'rdataset' to be valid and #DNS_RDATASETATTR_NOQNAME to be set.
- *\li 'name' to be valid.
- *\li 'neg' and 'negsig' to be valid and not associated.
- */
-
-isc_result_t
-dns_rdataset_addnoqname(dns_rdataset_t *rdataset, dns_name_t *name);
-/*%<
- * Associate a noqname proof with this record.
- * Sets #DNS_RDATASETATTR_NOQNAME if successful.
- * Adjusts the 'rdataset->ttl' to minimum of the 'rdataset->ttl' and
- * the 'nsec'/'nsec3' and 'rrsig(nsec)'/'rrsig(nsec3)' ttl.
- *
- * Requires:
- *\li 'rdataset' to be valid and #DNS_RDATASETATTR_NOQNAME to be set.
- *\li 'name' to be valid and have NSEC or NSEC3 and associated RRSIG
- * rdatasets.
- */
-
-isc_result_t
-dns_rdataset_getclosest(dns_rdataset_t *rdataset, dns_name_t *name,
- dns_rdataset_t *nsec, dns_rdataset_t *nsecsig);
-/*%<
- * Return the closest encloser for this record.
- *
- * Requires:
- *\li 'rdataset' to be valid and #DNS_RDATASETATTR_CLOSEST to be set.
- *\li 'name' to be valid.
- *\li 'nsec' and 'nsecsig' to be valid and not associated.
- */
-
-isc_result_t
-dns_rdataset_addclosest(dns_rdataset_t *rdataset, dns_name_t *name);
-/*%<
- * Associate a closest encloset proof with this record.
- * Sets #DNS_RDATASETATTR_CLOSEST if successful.
- * Adjusts the 'rdataset->ttl' to minimum of the 'rdataset->ttl' and
- * the 'nsec' and 'rrsig(nsec)' ttl.
- *
- * Requires:
- *\li 'rdataset' to be valid and #DNS_RDATASETATTR_CLOSEST to be set.
- *\li 'name' to be valid and have NSEC3 and RRSIG(NSEC3) rdatasets.
- */
-
-isc_result_t
-dns_rdataset_getadditional(dns_rdataset_t *rdataset,
- dns_rdatasetadditional_t type,
- dns_rdatatype_t qtype,
- dns_acache_t *acache,
- dns_zone_t **zonep,
- dns_db_t **dbp,
- dns_dbversion_t **versionp,
- dns_dbnode_t **nodep,
- dns_name_t *fname,
- dns_message_t *msg,
- isc_stdtime_t now);
-/*%<
- * Get cached additional information from the DB node for a particular
- * 'rdataset.' 'type' is one of dns_rdatasetadditional_fromauth,
- * dns_rdatasetadditional_fromcache, and dns_rdatasetadditional_fromglue,
- * which specifies the origin of the information. 'qtype' is intended to
- * be used for specifying a particular rdata type in the cached information.
- *
- * Requires:
- * \li 'rdataset' is a valid rdataset.
- * \li 'acache' can be NULL, in which case this function will simply return
- * ISC_R_FAILURE.
- * \li For the other pointers, see dns_acache_getentry().
- *
- * Ensures:
- * \li See dns_acache_getentry().
- *
- * Returns:
- * \li #ISC_R_SUCCESS
- * \li #ISC_R_FAILURE - additional information caching is not supported.
- * \li #ISC_R_NOTFOUND - the corresponding DB node has not cached additional
- * information for 'rdataset.'
- * \li Any error that dns_acache_getentry() can return.
- */
-
-isc_result_t
-dns_rdataset_setadditional(dns_rdataset_t *rdataset,
- dns_rdatasetadditional_t type,
- dns_rdatatype_t qtype,
- dns_acache_t *acache,
- dns_zone_t *zone,
- dns_db_t *db,
- dns_dbversion_t *version,
- dns_dbnode_t *node,
- dns_name_t *fname);
-/*%<
- * Set cached additional information to the DB node for a particular
- * 'rdataset.' See dns_rdataset_getadditional for the semantics of 'type'
- * and 'qtype'.
- *
- * Requires:
- * \li 'rdataset' is a valid rdataset.
- * \li 'acache' can be NULL, in which case this function will simply return
- * ISC_R_FAILURE.
- * \li For the other pointers, see dns_acache_setentry().
- *
- * Ensures:
- * \li See dns_acache_setentry().
- *
- * Returns:
- * \li #ISC_R_SUCCESS
- * \li #ISC_R_FAILURE - additional information caching is not supported.
- * \li #ISC_R_NOMEMORY
- * \li Any error that dns_acache_setentry() can return.
- */
-
-isc_result_t
-dns_rdataset_putadditional(dns_acache_t *acache,
- dns_rdataset_t *rdataset,
- dns_rdatasetadditional_t type,
- dns_rdatatype_t qtype);
-/*%<
- * Discard cached additional information stored in the DB node for a particular
- * 'rdataset.' See dns_rdataset_getadditional for the semantics of 'type'
- * and 'qtype'.
- *
- * Requires:
- * \li 'rdataset' is a valid rdataset.
- * \li 'acache' can be NULL, in which case this function will simply return
- * ISC_R_FAILURE.
- *
- * Ensures:
- * \li See dns_acache_cancelentry().
- *
- * Returns:
- * \li #ISC_R_SUCCESS
- * \li #ISC_R_FAILURE - additional information caching is not supported.
- * \li #ISC_R_NOTFOUND - the corresponding DB node has not cached additional
- * information for 'rdataset.'
- */
-
-void
-dns_rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust);
-/*%<
- * Set the trust of the 'rdataset' to trust in any in the backing database.
- * The local trust level of 'rdataset' is also set.
- */
-
-void
-dns_rdataset_expire(dns_rdataset_t *rdataset);
-/*%<
- * Mark the rdataset to be expired in the backing database.
- */
-
-void
-dns_rdataset_trimttl(dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
- dns_rdata_rrsig_t *rrsig, isc_stdtime_t now,
- isc_boolean_t acceptexpired);
-/*%<
- * Trim the ttl of 'rdataset' and 'sigrdataset' so that they will expire
- * at or before 'rrsig->expiretime'. If 'acceptexpired' is true and the
- * signature has expired or will expire in the next 120 seconds, limit
- * the ttl to be no more than 120 seconds.
- *
- * The ttl is further limited by the original ttl as stored in 'rrsig'
- * and the original ttl values of 'rdataset' and 'sigrdataset'.
- *
- * Requires:
- * \li 'rdataset' is a valid rdataset.
- * \li 'sigrdataset' is a valid rdataset.
- * \li 'rrsig' is non NULL.
- */
-
-const char *
-dns_trust_totext(dns_trust_t trust);
-/*
- * Display trust in textual form.
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_RDATASET_H */
diff --git a/contrib/bind9/lib/dns/include/dns/rdatasetiter.h b/contrib/bind9/lib/dns/include/dns/rdatasetiter.h
deleted file mode 100644
index dcde367f1c85..000000000000
--- a/contrib/bind9/lib/dns/include/dns/rdatasetiter.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: rdatasetiter.h,v 1.21 2007/06/19 23:47:17 tbox Exp $ */
-
-#ifndef DNS_RDATASETITER_H
-#define DNS_RDATASETITER_H 1
-
-/*****
- ***** Module Info
- *****/
-
-/*! \file dns/rdatasetiter.h
- * \brief
- * The DNS Rdataset Iterator interface allows iteration of all of the
- * rdatasets at a node.
- *
- * The dns_rdatasetiter_t type is like a "virtual class". To actually use
- * it, an implementation of the class is required. This implementation is
- * supplied by the database.
- *
- * It is the client's responsibility to call dns_rdataset_disassociate()
- * on all rdatasets returned.
- *
- * XXX more XXX
- *
- * MP:
- *\li The iterator itself is not locked. The caller must ensure
- * synchronization.
- *
- *\li The iterator methods ensure appropriate database locking.
- *
- * Reliability:
- *\li No anticipated impact.
- *
- * Resources:
- *\li TBS
- *
- * Security:
- *\li No anticipated impact.
- *
- * Standards:
- *\li None.
- */
-
-/*****
- ***** Imports
- *****/
-
-#include <isc/lang.h>
-#include <isc/magic.h>
-#include <isc/stdtime.h>
-
-#include <dns/types.h>
-
-ISC_LANG_BEGINDECLS
-
-/*****
- ***** Types
- *****/
-
-typedef struct dns_rdatasetitermethods {
- void (*destroy)(dns_rdatasetiter_t **iteratorp);
- isc_result_t (*first)(dns_rdatasetiter_t *iterator);
- isc_result_t (*next)(dns_rdatasetiter_t *iterator);
- void (*current)(dns_rdatasetiter_t *iterator,
- dns_rdataset_t *rdataset);
-} dns_rdatasetitermethods_t;
-
-#define DNS_RDATASETITER_MAGIC ISC_MAGIC('D','N','S','i')
-#define DNS_RDATASETITER_VALID(i) ISC_MAGIC_VALID(i, DNS_RDATASETITER_MAGIC)
-
-/*%
- * This structure is actually just the common prefix of a DNS db
- * implementation's version of a dns_rdatasetiter_t.
- * \brief
- * Direct use of this structure by clients is forbidden. DB implementations
- * may change the structure. 'magic' must be #DNS_RDATASETITER_MAGIC for
- * any of the dns_rdatasetiter routines to work. DB implementations must
- * maintain all DB rdataset iterator invariants.
- */
-struct dns_rdatasetiter {
- /* Unlocked. */
- unsigned int magic;
- dns_rdatasetitermethods_t * methods;
- dns_db_t * db;
- dns_dbnode_t * node;
- dns_dbversion_t * version;
- isc_stdtime_t now;
-};
-
-void
-dns_rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp);
-/*%<
- * Destroy '*iteratorp'.
- *
- * Requires:
- *
- *\li '*iteratorp' is a valid iterator.
- *
- * Ensures:
- *
- *\li All resources used by the iterator are freed.
- *
- *\li *iteratorp == NULL.
- */
-
-isc_result_t
-dns_rdatasetiter_first(dns_rdatasetiter_t *iterator);
-/*%<
- * Move the rdataset cursor to the first rdataset at the node (if any).
- *
- * Requires:
- *\li 'iterator' is a valid iterator.
- *
- * Returns:
- *\li ISC_R_SUCCESS
- *\li ISC_R_NOMORE There are no rdatasets at the node.
- *
- *\li Other results are possible, depending on the DB implementation.
- */
-
-isc_result_t
-dns_rdatasetiter_next(dns_rdatasetiter_t *iterator);
-/*%<
- * Move the rdataset cursor to the next rdataset at the node (if any).
- *
- * Requires:
- *\li 'iterator' is a valid iterator.
- *
- * Returns:
- *\li ISC_R_SUCCESS
- *\li ISC_R_NOMORE There are no more rdatasets at the
- * node.
- *
- *\li Other results are possible, depending on the DB implementation.
- */
-
-void
-dns_rdatasetiter_current(dns_rdatasetiter_t *iterator,
- dns_rdataset_t *rdataset);
-/*%<
- * Return the current rdataset.
- *
- * Requires:
- *\li 'iterator' is a valid iterator.
- *
- *\li 'rdataset' is a valid, disassociated rdataset.
- *
- *\li The rdataset cursor of 'iterator' is at a valid location (i.e. the
- * result of last call to a cursor movement command was #ISC_R_SUCCESS).
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_RDATASETITER_H */
diff --git a/contrib/bind9/lib/dns/include/dns/rdataslab.h b/contrib/bind9/lib/dns/include/dns/rdataslab.h
deleted file mode 100644
index 3ac44b879e03..000000000000
--- a/contrib/bind9/lib/dns/include/dns/rdataslab.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2002 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: rdataslab.h,v 1.33 2008/04/01 23:47:10 tbox Exp $ */
-
-#ifndef DNS_RDATASLAB_H
-#define DNS_RDATASLAB_H 1
-
-/*! \file dns/rdataslab.h
- * \brief
- * Implements storage of rdatasets into slabs of memory.
- *
- * MP:
- *\li Clients of this module must impose any required synchronization.
- *
- * Reliability:
- *\li This module deals with low-level byte streams. Errors in any of
- * the functions are likely to crash the server or corrupt memory.
- *
- *\li If the caller passes invalid memory references, these functions are
- * likely to crash the server or corrupt memory.
- *
- * Resources:
- *\li None.
- *
- * Security:
- *\li None.
- *
- * Standards:
- *\li None.
- */
-
-/***
- *** Imports
- ***/
-
-#include <isc/lang.h>
-
-#include <dns/types.h>
-
-ISC_LANG_BEGINDECLS
-
-#define DNS_RDATASLAB_FORCE 0x1
-#define DNS_RDATASLAB_EXACT 0x2
-
-#define DNS_RDATASLAB_OFFLINE 0x01 /* RRSIG is for offline DNSKEY */
-#define DNS_RDATASLAB_WARNMASK 0x0E /*%< RRSIG(DNSKEY) expired
- * warnings number mask. */
-#define DNS_RDATASLAB_WARNSHIFT 1 /*%< How many bits to shift to find
- * remaining expired warning number. */
-
-
-/***
- *** Functions
- ***/
-
-isc_result_t
-dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
- isc_region_t *region, unsigned int reservelen);
-/*%<
- * Slabify a rdataset. The slab area will be allocated and returned
- * in 'region'.
- *
- * Requires:
- *\li 'rdataset' is valid.
- *
- * Ensures:
- *\li 'region' will have base pointing to the start of allocated memory,
- * with the slabified region beginning at region->base + reservelen.
- * region->length contains the total length allocated.
- *
- * Returns:
- *\li ISC_R_SUCCESS - successful completion
- *\li ISC_R_NOMEMORY - no memory.
- *\li XXX others
- */
-
-void
-dns_rdataslab_tordataset(unsigned char *slab, unsigned int reservelen,
- dns_rdataclass_t rdclass, dns_rdatatype_t rdtype,
- dns_rdatatype_t covers, dns_ttl_t ttl,
- dns_rdataset_t *rdataset);
-/*%<
- * Construct an rdataset from a slab.
- *
- * Requires:
- *\li 'slab' points to a slab.
- *\li 'rdataset' is disassociated.
- *
- * Ensures:
- *\li 'rdataset' is associated and points to a valid rdataest.
- */
-unsigned int
-dns_rdataslab_size(unsigned char *slab, unsigned int reservelen);
-/*%<
- * Return the total size of an rdataslab.
- *
- * Requires:
- *\li 'slab' points to a slab.
- *
- * Returns:
- *\li The number of bytes in the slab, including the reservelen.
- */
-
-isc_result_t
-dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
- unsigned int reservelen, isc_mem_t *mctx,
- dns_rdataclass_t rdclass, dns_rdatatype_t type,
- unsigned int flags, unsigned char **tslabp);
-/*%<
- * Merge 'oslab' and 'nslab'.
- */
-
-isc_result_t
-dns_rdataslab_subtract(unsigned char *mslab, unsigned char *sslab,
- unsigned int reservelen, isc_mem_t *mctx,
- dns_rdataclass_t rdclass, dns_rdatatype_t type,
- unsigned int flags, unsigned char **tslabp);
-/*%<
- * Subtract 'sslab' from 'mslab'. If 'exact' is true then all elements
- * of 'sslab' must exist in 'mslab'.
- *
- * XXX
- * valid flags are DNS_RDATASLAB_EXACT
- */
-
-isc_boolean_t
-dns_rdataslab_equal(unsigned char *slab1, unsigned char *slab2,
- unsigned int reservelen);
-/*%<
- * Compare two rdataslabs for equality. This does _not_ do a full
- * DNSSEC comparison.
- *
- * Requires:
- *\li 'slab1' and 'slab2' point to slabs.
- *
- * Returns:
- *\li ISC_TRUE if the slabs are equal, ISC_FALSE otherwise.
- */
-isc_boolean_t
-dns_rdataslab_equalx(unsigned char *slab1, unsigned char *slab2,
- unsigned int reservelen, dns_rdataclass_t rdclass,
- dns_rdatatype_t type);
-/*%<
- * Compare two rdataslabs for DNSSEC equality.
- *
- * Requires:
- *\li 'slab1' and 'slab2' point to slabs.
- *
- * Returns:
- *\li ISC_TRUE if the slabs are equal, #ISC_FALSE otherwise.
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_RDATASLAB_H */
diff --git a/contrib/bind9/lib/dns/include/dns/rdatatype.h b/contrib/bind9/lib/dns/include/dns/rdatatype.h
deleted file mode 100644
index ba9a92c13f02..000000000000
--- a/contrib/bind9/lib/dns/include/dns/rdatatype.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-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: rdatatype.h,v 1.26 2008/09/25 04:02:39 tbox Exp $ */
-
-#ifndef DNS_RDATATYPE_H
-#define DNS_RDATATYPE_H 1
-
-/*! \file dns/rdatatype.h */
-
-#include <isc/lang.h>
-
-#include <dns/types.h>
-
-ISC_LANG_BEGINDECLS
-
-isc_result_t
-dns_rdatatype_fromtext(dns_rdatatype_t *typep, isc_textregion_t *source);
-/*%<
- * Convert the text 'source' refers to into a DNS rdata type.
- *
- * Requires:
- *\li 'typep' is a valid pointer.
- *
- *\li 'source' is a valid text region.
- *
- * Returns:
- *\li ISC_R_SUCCESS on success
- *\li DNS_R_UNKNOWN type is unknown
- */
-
-isc_result_t
-dns_rdatatype_totext(dns_rdatatype_t type, isc_buffer_t *target);
-/*%<
- * Put a textual representation of type 'type' into 'target'.
- *
- * Requires:
- *\li 'type' is a valid type.
- *
- *\li 'target' is a valid text buffer.
- *
- * Ensures,
- * if the result is success:
- *\li The used space in 'target' is updated.
- *
- * Returns:
- *\li #ISC_R_SUCCESS on success
- *\li #ISC_R_NOSPACE target buffer is too small
- */
-
-void
-dns_rdatatype_format(dns_rdatatype_t rdtype,
- char *array, unsigned int size);
-/*%<
- * Format a human-readable representation of the type 'rdtype'
- * into the character array 'array', which is of size 'size'.
- * The resulting string is guaranteed to be null-terminated.
- */
-
-#define DNS_RDATATYPE_FORMATSIZE sizeof("NSEC3PARAM")
-
-/*%<
- * Minimum size of array to pass to dns_rdatatype_format().
- * May need to be adjusted if a new RR type with a very long
- * name is defined.
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_RDATATYPE_H */
diff --git a/contrib/bind9/lib/dns/include/dns/request.h b/contrib/bind9/lib/dns/include/dns/request.h
deleted file mode 100644
index 8c792ddd5774..000000000000
--- a/contrib/bind9/lib/dns/include/dns/request.h
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: request.h,v 1.31 2010/03/04 23:50:34 tbox Exp $ */
-
-#ifndef DNS_REQUEST_H
-#define DNS_REQUEST_H 1
-
-/*****
- ***** Module Info
- *****/
-
-/*! \file dns/request.h
- *
- * \brief
- * The request module provides simple request/response services useful for
- * sending SOA queries, DNS Notify messages, and dynamic update requests.
- *
- * MP:
- *\li The module ensures appropriate synchronization of data structures it
- * creates and manipulates.
- *
- * Resources:
- *\li TBS
- *
- * Security:
- *\li No anticipated impact.
- */
-
-#include <isc/lang.h>
-#include <isc/event.h>
-
-#include <dns/types.h>
-
-#define DNS_REQUESTOPT_TCP 0x00000001U
-#define DNS_REQUESTOPT_CASE 0x00000002U
-
-typedef struct dns_requestevent {
- ISC_EVENT_COMMON(struct dns_requestevent);
- isc_result_t result;
- dns_request_t *request;
-} dns_requestevent_t;
-
-ISC_LANG_BEGINDECLS
-
-isc_result_t
-dns_requestmgr_create(isc_mem_t *mctx, isc_timermgr_t *timermgr,
- isc_socketmgr_t *socketmgr, isc_taskmgr_t *taskmgr,
- dns_dispatchmgr_t *dispatchmgr,
- dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6,
- dns_requestmgr_t **requestmgrp);
-/*%<
- * Create a request manager.
- *
- * Requires:
- *
- *\li 'mctx' is a valid memory context.
- *
- *\li 'timermgr' is a valid timer manager.
- *
- *\li 'socketmgr' is a valid socket manager.
- *
- *\li 'taskmgr' is a valid task manager.
- *
- *\li 'dispatchv4' is a valid dispatcher with an IPv4 UDP socket, or is NULL.
- *
- *\li 'dispatchv6' is a valid dispatcher with an IPv6 UDP socket, or is NULL.
- *
- *\li requestmgrp != NULL && *requestmgrp == NULL
- *
- * Ensures:
- *
- *\li On success, *requestmgrp is a valid request manager.
- *
- * Returns:
- *
- *\li ISC_R_SUCCESS
- *
- *\li Any other result indicates failure.
- */
-
-void
-dns_requestmgr_whenshutdown(dns_requestmgr_t *requestmgr, isc_task_t *task,
- isc_event_t **eventp);
-/*%<
- * Send '*eventp' to 'task' when 'requestmgr' has completed shutdown.
- *
- * Notes:
- *
- *\li It is not safe to detach the last reference to 'requestmgr' until
- * shutdown is complete.
- *
- * Requires:
- *
- *\li 'requestmgr' is a valid request manager.
- *
- *\li 'task' is a valid task.
- *
- *\li *eventp is a valid event.
- *
- * Ensures:
- *
- *\li *eventp == NULL.
- */
-
-void
-dns_requestmgr_shutdown(dns_requestmgr_t *requestmgr);
-/*%<
- * Start the shutdown process for 'requestmgr'.
- *
- * Notes:
- *
- *\li This call has no effect if the request manager is already shutting
- * down.
- *
- * Requires:
- *
- *\li 'requestmgr' is a valid requestmgr.
- */
-
-void
-dns_requestmgr_attach(dns_requestmgr_t *source, dns_requestmgr_t **targetp);
-/*%<
- * Attach to the request manager. dns_requestmgr_shutdown() must not
- * have been called on 'source' prior to calling dns_requestmgr_attach().
- *
- * Requires:
- *
- *\li 'source' is a valid requestmgr.
- *
- *\li 'targetp' to be non NULL and '*targetp' to be NULL.
- */
-
-void
-dns_requestmgr_detach(dns_requestmgr_t **requestmgrp);
-/*%<
- * Detach from the given requestmgr. If this is the final detach
- * requestmgr will be destroyed. dns_requestmgr_shutdown() must
- * be called before the final detach.
- *
- * Requires:
- *
- *\li '*requestmgrp' is a valid requestmgr.
- *
- * Ensures:
- *\li '*requestmgrp' is NULL.
- */
-
-isc_result_t
-dns_request_create(dns_requestmgr_t *requestmgr, dns_message_t *message,
- isc_sockaddr_t *address, unsigned int options,
- dns_tsigkey_t *key,
- unsigned int timeout, isc_task_t *task,
- isc_taskaction_t action, void *arg,
- dns_request_t **requestp);
-/*%<
- * Create and send a request.
- *
- * Notes:
- *
- *\li 'message' will be rendered and sent to 'address'. If the
- * #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'.
- *
- * Requires:
- *
- *\li 'message' is a valid DNS message.
- *
- *\li 'address' is a valid sockaddr.
- *
- *\li 'timeout' > 0
- *
- *\li 'task' is a valid task.
- *
- *\li requestp != NULL && *requestp == NULL
- */
-
-/*% See dns_request_createvia3() */
-isc_result_t
-dns_request_createvia(dns_requestmgr_t *requestmgr, dns_message_t *message,
- isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
- unsigned int options, dns_tsigkey_t *key,
- unsigned int timeout, isc_task_t *task,
- isc_taskaction_t action, void *arg,
- dns_request_t **requestp);
-
-/*% See dns_request_createvia3() */
-isc_result_t
-dns_request_createvia2(dns_requestmgr_t *requestmgr, dns_message_t *message,
- isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
- unsigned int options, dns_tsigkey_t *key,
- unsigned int timeout, unsigned int udptimeout,
- isc_task_t *task, isc_taskaction_t action, void *arg,
- dns_request_t **requestp);
-
-isc_result_t
-dns_request_createvia3(dns_requestmgr_t *requestmgr, dns_message_t *message,
- isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
- unsigned int options, dns_tsigkey_t *key,
- unsigned int timeout, unsigned int udptimeout,
- unsigned int udpretries, isc_task_t *task,
- isc_taskaction_t action, void *arg,
- dns_request_t **requestp);
-/*%<
- * Create and send a request.
- *
- * Notes:
- *
- *\li 'message' will be rendered and sent to 'address'. If the
- * #DNS_REQUESTOPT_TCP option is set, TCP will be used. The request
- * 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'.
- *
- * Requires:
- *
- *\li 'message' is a valid DNS message.
- *
- *\li 'dstaddr' is a valid sockaddr.
- *
- *\li 'srcaddr' is a valid sockaddr or NULL.
- *
- *\li 'srcaddr' and 'dstaddr' are the same protocol family.
- *
- *\li 'timeout' > 0
- *
- *\li 'task' is a valid task.
- *
- *\li requestp != NULL && *requestp == NULL
- */
-
-/*% See dns_request_createraw3() */
-isc_result_t
-dns_request_createraw(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
- isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
- unsigned int options, unsigned int timeout,
- isc_task_t *task, isc_taskaction_t action, void *arg,
- dns_request_t **requestp);
-
-/*% See dns_request_createraw3() */
-isc_result_t
-dns_request_createraw2(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
- isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
- unsigned int options, unsigned int timeout,
- unsigned int udptimeout, isc_task_t *task,
- isc_taskaction_t action, void *arg,
- dns_request_t **requestp);
-
-isc_result_t
-dns_request_createraw3(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
- isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
- unsigned int options, unsigned int timeout,
- unsigned int udptimeout, unsigned int udpretries,
- isc_task_t *task, isc_taskaction_t action, void *arg,
- dns_request_t **requestp);
-/*!<
- * \brief Create and send a request.
- *
- * Notes:
- *
- *\li 'msgbuf' will be sent to 'destaddr' after setting the id. If the
- * #DNS_REQUESTOPT_TCP option is set, TCP will be used. The request
- * will timeout after 'timeout' seconds. UDP requests will be resent
- * at 'udptimeout' intervals if non-zero or if 'udpretries' is not zero.
- *
- *\li When the request completes, successfully, due to a timeout, or
- * because it was canceled, a completion event will be sent to 'task'.
- *
- * Requires:
- *
- *\li 'msgbuf' is a valid DNS message in compressed wire format.
- *
- *\li 'destaddr' is a valid sockaddr.
- *
- *\li 'srcaddr' is a valid sockaddr or NULL.
- *
- *\li 'srcaddr' and 'dstaddr' are the same protocol family.
- *
- *\li 'timeout' > 0
- *
- *\li 'task' is a valid task.
- *
- *\li requestp != NULL && *requestp == NULL
- */
-
-void
-dns_request_cancel(dns_request_t *request);
-/*%<
- * Cancel 'request'.
- *
- * Requires:
- *
- *\li 'request' is a valid request.
- *
- * Ensures:
- *
- *\li If the completion event for 'request' has not yet been sent, it
- * will be sent, and the result code will be ISC_R_CANCELED.
- */
-
-isc_result_t
-dns_request_getresponse(dns_request_t *request, dns_message_t *message,
- unsigned int options);
-/*%<
- * Get the response to 'request' by filling in 'message'.
- *
- * 'options' is passed to dns_message_parse(). See dns_message_parse()
- * for more details.
- *
- * Requires:
- *
- *\li 'request' is a valid request for which the caller has received the
- * completion event.
- *
- *\li The result code of the completion event was #ISC_R_SUCCESS.
- *
- * Returns:
- *
- *\li ISC_R_SUCCESS
- *
- *\li Any result that dns_message_parse() can return.
- */
-
-isc_boolean_t
-dns_request_usedtcp(dns_request_t *request);
-/*%<
- * Return whether this query used TCP or not. Setting #DNS_REQUESTOPT_TCP
- * in the call to dns_request_create() will cause the function to return
- * #ISC_TRUE, otherwise the result is based on the query message size.
- *
- * Requires:
- *\li 'request' is a valid request.
- *
- * Returns:
- *\li ISC_TRUE if TCP was used.
- *\li ISC_FALSE if UDP was used.
- */
-
-void
-dns_request_destroy(dns_request_t **requestp);
-/*%<
- * Destroy 'request'.
- *
- * Requires:
- *
- *\li 'request' is a valid request for which the caller has received the
- * completion event.
- *
- * Ensures:
- *
- *\li *requestp == NULL
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_REQUEST_H */
diff --git a/contrib/bind9/lib/dns/include/dns/resolver.h b/contrib/bind9/lib/dns/include/dns/resolver.h
deleted file mode 100644
index 095269ea2dd2..000000000000
--- a/contrib/bind9/lib/dns/include/dns/resolver.h
+++ /dev/null
@@ -1,580 +0,0 @@
-/*
- * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001, 2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: resolver.h,v 1.72 2011/12/05 17:10:51 each Exp $ */
-
-#ifndef DNS_RESOLVER_H
-#define DNS_RESOLVER_H 1
-
-/*****
- ***** Module Info
- *****/
-
-/*! \file dns/resolver.h
- *
- * \brief
- * This is the BIND 9 resolver, the module responsible for resolving DNS
- * requests by iteratively querying authoritative servers and following
- * referrals. This is a "full resolver", not to be confused with
- * the stub resolvers most people associate with the word "resolver".
- * The full resolver is part of the caching name server or resolver
- * daemon the stub resolver talks to.
- *
- * MP:
- *\li The module ensures appropriate synchronization of data structures it
- * creates and manipulates.
- *
- * Reliability:
- *\li No anticipated impact.
- *
- * Resources:
- *\li TBS
- *
- * Security:
- *\li No anticipated impact.
- *
- * Standards:
- *\li RFCs: 1034, 1035, 2181, TBS
- *\li Drafts: TBS
- */
-
-#include <isc/lang.h>
-#include <isc/socket.h>
-
-#include <dns/types.h>
-#include <dns/fixedname.h>
-
-ISC_LANG_BEGINDECLS
-
-/*%
- * A dns_fetchevent_t is sent when a 'fetch' completes. Any of 'db',
- * 'node', 'rdataset', and 'sigrdataset' may be bound. It is the
- * receiver's responsibility to detach before freeing the event.
- * \brief
- * 'rdataset', 'sigrdataset', 'client' and 'id' are the values that were
- * supplied when dns_resolver_createfetch() was called. They are returned
- * to the caller so that they may be freed.
- */
-typedef struct dns_fetchevent {
- ISC_EVENT_COMMON(struct dns_fetchevent);
- dns_fetch_t * fetch;
- isc_result_t result;
- dns_rdatatype_t qtype;
- dns_db_t * db;
- dns_dbnode_t * node;
- dns_rdataset_t * rdataset;
- dns_rdataset_t * sigrdataset;
- dns_fixedname_t foundname;
- isc_sockaddr_t * client;
- dns_messageid_t id;
- isc_result_t vresult;
-} dns_fetchevent_t;
-
-/*
- * Options that modify how a 'fetch' is done.
- */
-#define DNS_FETCHOPT_TCP 0x01 /*%< Use TCP. */
-#define DNS_FETCHOPT_UNSHARED 0x02 /*%< See below. */
-#define DNS_FETCHOPT_RECURSIVE 0x04 /*%< Set RD? */
-#define DNS_FETCHOPT_NOEDNS0 0x08 /*%< Do not use EDNS. */
-#define DNS_FETCHOPT_FORWARDONLY 0x10 /*%< Only use forwarders. */
-#define DNS_FETCHOPT_NOVALIDATE 0x20 /*%< Disable validation. */
-#define DNS_FETCHOPT_EDNS512 0x40 /*%< Advertise a 512 byte
- UDP buffer. */
-#define DNS_FETCHOPT_WANTNSID 0x80 /*%< Request NSID */
-
-#define DNS_FETCHOPT_EDNSVERSIONSET 0x00800000
-#define DNS_FETCHOPT_EDNSVERSIONMASK 0xff000000
-#define DNS_FETCHOPT_EDNSVERSIONSHIFT 24
-
-/*
- * Upper bounds of class of query RTT (ms). Corresponds to
- * dns_resstatscounter_queryrttX statistics counters.
- */
-#define DNS_RESOLVER_QRYRTTCLASS0 10
-#define DNS_RESOLVER_QRYRTTCLASS0STR "10"
-#define DNS_RESOLVER_QRYRTTCLASS1 100
-#define DNS_RESOLVER_QRYRTTCLASS1STR "100"
-#define DNS_RESOLVER_QRYRTTCLASS2 500
-#define DNS_RESOLVER_QRYRTTCLASS2STR "500"
-#define DNS_RESOLVER_QRYRTTCLASS3 800
-#define DNS_RESOLVER_QRYRTTCLASS3STR "800"
-#define DNS_RESOLVER_QRYRTTCLASS4 1600
-#define DNS_RESOLVER_QRYRTTCLASS4STR "1600"
-
-/*
- * XXXRTH Should this API be made semi-private? (I.e.
- * _dns_resolver_create()).
- */
-
-#define DNS_RESOLVER_CHECKNAMES 0x01
-#define DNS_RESOLVER_CHECKNAMESFAIL 0x02
-
-isc_result_t
-dns_resolver_create(dns_view_t *view,
- isc_taskmgr_t *taskmgr,
- unsigned int ntasks, unsigned int ndisp,
- isc_socketmgr_t *socketmgr,
- isc_timermgr_t *timermgr,
- unsigned int options,
- dns_dispatchmgr_t *dispatchmgr,
- dns_dispatch_t *dispatchv4,
- dns_dispatch_t *dispatchv6,
- dns_resolver_t **resp);
-
-/*%<
- * Create a resolver.
- *
- * Notes:
- *
- *\li Generally, applications should not create a resolver directly, but
- * should instead call dns_view_createresolver().
- *
- * Requires:
- *
- *\li 'view' is a valid view.
- *
- *\li 'taskmgr' is a valid task manager.
- *
- *\li 'ntasks' > 0.
- *
- *\li 'socketmgr' is a valid socket manager.
- *
- *\li 'timermgr' is a valid timer manager.
- *
- *\li 'dispatchv4' is a dispatch with an IPv4 UDP socket, or is NULL.
- * If not NULL, 'ndisp' clones of it will be created by the resolver.
- *
- *\li 'dispatchv6' is a dispatch with an IPv6 UDP socket, or is NULL.
- * If not NULL, 'ndisp' clones of it will be created by the resolver.
- *
- *\li resp != NULL && *resp == NULL.
- *
- * Returns:
- *
- *\li #ISC_R_SUCCESS On success.
- *
- *\li Anything else Failure.
- */
-
-void
-dns_resolver_freeze(dns_resolver_t *res);
-/*%<
- * Freeze resolver.
- *
- * Notes:
- *
- *\li Certain configuration changes cannot be made after the resolver
- * is frozen. Fetches cannot be created until the resolver is frozen.
- *
- * Requires:
- *
- *\li 'res' is a valid resolver.
- *
- * Ensures:
- *
- *\li 'res' is frozen.
- */
-
-void
-dns_resolver_prime(dns_resolver_t *res);
-/*%<
- * Prime resolver.
- *
- * Notes:
- *
- *\li Resolvers which have a forwarding policy other than dns_fwdpolicy_only
- * need to be primed with the root nameservers, otherwise the root
- * nameserver hints data may be used indefinitely. This function requests
- * that the resolver start a priming fetch, if it isn't already priming.
- *
- * Requires:
- *
- *\li 'res' is a valid, frozen resolver.
- */
-
-
-void
-dns_resolver_whenshutdown(dns_resolver_t *res, isc_task_t *task,
- isc_event_t **eventp);
-/*%<
- * Send '*eventp' to 'task' when 'res' has completed shutdown.
- *
- * Notes:
- *
- *\li It is not safe to detach the last reference to 'res' until
- * shutdown is complete.
- *
- * Requires:
- *
- *\li 'res' is a valid resolver.
- *
- *\li 'task' is a valid task.
- *
- *\li *eventp is a valid event.
- *
- * Ensures:
- *
- *\li *eventp == NULL.
- */
-
-void
-dns_resolver_shutdown(dns_resolver_t *res);
-/*%<
- * Start the shutdown process for 'res'.
- *
- * Notes:
- *
- *\li This call has no effect if the resolver is already shutting down.
- *
- * Requires:
- *
- *\li 'res' is a valid resolver.
- */
-
-void
-dns_resolver_attach(dns_resolver_t *source, dns_resolver_t **targetp);
-
-void
-dns_resolver_detach(dns_resolver_t **resp);
-
-isc_result_t
-dns_resolver_createfetch(dns_resolver_t *res, dns_name_t *name,
- dns_rdatatype_t type,
- dns_name_t *domain, dns_rdataset_t *nameservers,
- dns_forwarders_t *forwarders,
- unsigned int options, isc_task_t *task,
- isc_taskaction_t action, void *arg,
- dns_rdataset_t *rdataset,
- dns_rdataset_t *sigrdataset,
- dns_fetch_t **fetchp);
-
-isc_result_t
-dns_resolver_createfetch2(dns_resolver_t *res, dns_name_t *name,
- dns_rdatatype_t type,
- dns_name_t *domain, dns_rdataset_t *nameservers,
- dns_forwarders_t *forwarders,
- isc_sockaddr_t *client, isc_uint16_t id,
- unsigned int options, isc_task_t *task,
- isc_taskaction_t action, void *arg,
- dns_rdataset_t *rdataset,
- dns_rdataset_t *sigrdataset,
- dns_fetch_t **fetchp);
-/*%<
- * Recurse to answer a question.
- *
- * Notes:
- *
- *\li This call starts a query for 'name', type 'type'.
- *
- *\li The 'domain' is a parent domain of 'name' for which
- * a set of name servers 'nameservers' is known. If no
- * such name server information is available, set
- * 'domain' and 'nameservers' to NULL.
- *
- *\li 'forwarders' is unimplemented, and subject to change when
- * we figure out how selective forwarding will work.
- *
- *\li When the fetch completes (successfully or otherwise), a
- * #DNS_EVENT_FETCHDONE event with action 'action' and arg 'arg' will be
- * posted to 'task'.
- *
- *\li The values of 'rdataset' and 'sigrdataset' will be returned in
- * the FETCHDONE event.
- *
- *\li 'client' and 'id' are used for duplicate query detection. '*client'
- * must remain stable until after 'action' has been called or
- * dns_resolver_cancelfetch() is called.
- *
- * Requires:
- *
- *\li 'res' is a valid resolver that has been frozen.
- *
- *\li 'name' is a valid name.
- *
- *\li 'type' is not a meta type other than ANY.
- *
- *\li 'domain' is a valid name or NULL.
- *
- *\li 'nameservers' is a valid NS rdataset (whose owner name is 'domain')
- * iff. 'domain' is not NULL.
- *
- *\li 'forwarders' is NULL.
- *
- *\li 'client' is a valid sockaddr or NULL.
- *
- *\li 'options' contains valid options.
- *
- *\li 'rdataset' is a valid, disassociated rdataset.
- *
- *\li 'sigrdataset' is NULL, or is a valid, disassociated rdataset.
- *
- *\li fetchp != NULL && *fetchp == NULL.
- *
- * Returns:
- *
- *\li #ISC_R_SUCCESS Success
- *\li #DNS_R_DUPLICATE
- *\li #DNS_R_DROP
- *
- *\li Many other values are possible, all of which indicate failure.
- */
-
-void
-dns_resolver_cancelfetch(dns_fetch_t *fetch);
-/*%<
- * Cancel 'fetch'.
- *
- * Notes:
- *
- *\li If 'fetch' has not completed, post its FETCHDONE event with a
- * result code of #ISC_R_CANCELED.
- *
- * Requires:
- *
- *\li 'fetch' is a valid fetch.
- */
-
-void
-dns_resolver_destroyfetch(dns_fetch_t **fetchp);
-/*%<
- * Destroy 'fetch'.
- *
- * Requires:
- *
- *\li '*fetchp' is a valid fetch.
- *
- *\li The caller has received the FETCHDONE event (either because the
- * fetch completed or because dns_resolver_cancelfetch() was called).
- *
- * Ensures:
- *
- *\li *fetchp == NULL.
- */
-
-void
-dns_resolver_logfetch(dns_fetch_t *fetch, isc_log_t *lctx,
- isc_logcategory_t *category, isc_logmodule_t *module,
- int level, isc_boolean_t duplicateok);
-/*%<
- * Dump a log message on internal state at the completion of given 'fetch'.
- * 'lctx', 'category', 'module', and 'level' are used to write the log message.
- * By default, only one log message is written even if the corresponding fetch
- * context serves multiple clients; if 'duplicateok' is true the suppression
- * is disabled and the message can be written every time this function is
- * called.
- *
- * Requires:
- *
- *\li 'fetch' is a valid fetch, and has completed.
- */
-
-dns_dispatchmgr_t *
-dns_resolver_dispatchmgr(dns_resolver_t *resolver);
-
-dns_dispatch_t *
-dns_resolver_dispatchv4(dns_resolver_t *resolver);
-
-dns_dispatch_t *
-dns_resolver_dispatchv6(dns_resolver_t *resolver);
-
-isc_socketmgr_t *
-dns_resolver_socketmgr(dns_resolver_t *resolver);
-
-isc_taskmgr_t *
-dns_resolver_taskmgr(dns_resolver_t *resolver);
-
-isc_uint32_t
-dns_resolver_getlamettl(dns_resolver_t *resolver);
-/*%<
- * Get the resolver's lame-ttl. zero => no lame processing.
- *
- * Requires:
- *\li 'resolver' to be valid.
- */
-
-void
-dns_resolver_setlamettl(dns_resolver_t *resolver, isc_uint32_t lame_ttl);
-/*%<
- * Set the resolver's lame-ttl. zero => no lame processing.
- *
- * Requires:
- *\li 'resolver' to be valid.
- */
-
-unsigned int
-dns_resolver_nrunning(dns_resolver_t *resolver);
-/*%<
- * Return the number of currently running resolutions in this
- * resolver. This is may be less than the number of outstanding
- * fetches due to multiple identical fetches, or more than the
- * number of of outstanding fetches due to the fact that resolution
- * can continue even though a fetch has been canceled.
- */
-
-isc_result_t
-dns_resolver_addalternate(dns_resolver_t *resolver, isc_sockaddr_t *alt,
- dns_name_t *name, in_port_t port);
-/*%<
- * Add alternate addresses to be tried in the event that the nameservers
- * for a zone are not available in the address families supported by the
- * operating system.
- *
- * Require:
- * \li only one of 'name' or 'alt' to be valid.
- */
-
-void
-dns_resolver_setudpsize(dns_resolver_t *resolver, isc_uint16_t udpsize);
-/*%<
- * Set the EDNS UDP buffer size advertised by the server.
- */
-
-isc_uint16_t
-dns_resolver_getudpsize(dns_resolver_t *resolver);
-/*%<
- * Get the current EDNS UDP buffer size.
- */
-
-void
-dns_resolver_reset_algorithms(dns_resolver_t *resolver);
-/*%<
- * Clear the disabled DNSSEC algorithms.
- */
-
-isc_result_t
-dns_resolver_disable_algorithm(dns_resolver_t *resolver, dns_name_t *name,
- unsigned int alg);
-/*%<
- * Mark the give DNSSEC algorithm as disabled and below 'name'.
- * Valid algorithms are less than 256.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_RANGE
- *\li #ISC_R_NOMEMORY
- */
-
-isc_boolean_t
-dns_resolver_algorithm_supported(dns_resolver_t *resolver, dns_name_t *name,
- unsigned int alg);
-/*%<
- * Check if the given algorithm is supported by this resolver.
- * This checks if the algorithm has been disabled via
- * dns_resolver_disable_algorithm() then the underlying
- * crypto libraries if not specifically disabled.
- */
-
-isc_boolean_t
-dns_resolver_digest_supported(dns_resolver_t *resolver, unsigned int digest_type);
-/*%<
- * Is this digest type supported.
- */
-
-void
-dns_resolver_resetmustbesecure(dns_resolver_t *resolver);
-
-isc_result_t
-dns_resolver_setmustbesecure(dns_resolver_t *resolver, dns_name_t *name,
- isc_boolean_t value);
-
-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);
-
-void
-dns_resolver_getclientsperquery(dns_resolver_t *resolver, isc_uint32_t *cur,
- isc_uint32_t *min, isc_uint32_t *max);
-
-isc_boolean_t
-dns_resolver_getzeronosoattl(dns_resolver_t *resolver);
-
-void
-dns_resolver_setzeronosoattl(dns_resolver_t *resolver, isc_boolean_t state);
-
-unsigned int
-dns_resolver_getoptions(dns_resolver_t *resolver);
-
-void
-dns_resolver_addbadcache(dns_resolver_t *resolver, dns_name_t *name,
- dns_rdatatype_t type, isc_time_t *expire);
-/*%<
- * Add a entry to the bad cache for <name,type> that will expire at 'expire'.
- *
- * Requires:
- * \li resolver to be valid.
- * \li name to be valid.
- */
-
-isc_boolean_t
-dns_resolver_getbadcache(dns_resolver_t *resolver, dns_name_t *name,
- dns_rdatatype_t type, isc_time_t *now);
-/*%<
- * Check to see if there is a unexpired entry in the bad cache for
- * <name,type>.
- *
- * Requires:
- * \li resolver to be valid.
- * \li name to be valid.
- */
-
-void
-dns_resolver_flushbadcache(dns_resolver_t *resolver, dns_name_t *name);
-/*%<
- * Flush the bad cache of all entries at 'name' if 'name' is non NULL.
- * Flush the entire bad cache if 'name' is NULL.
- *
- * Requires:
- * \li resolver to be valid.
- */
-
-void
-dns_resolver_printbadcache(dns_resolver_t *resolver, FILE *fp);
-/*%
- * Print out the contents of the bad cache to 'fp'.
- *
- * Requires:
- * \li resolver to be valid.
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_RESOLVER_H */
diff --git a/contrib/bind9/lib/dns/include/dns/result.h b/contrib/bind9/lib/dns/include/dns/result.h
deleted file mode 100644
index 12aacf9ba78a..000000000000
--- a/contrib/bind9/lib/dns/include/dns/result.h
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: result.h,v 1.123 2011/03/21 07:22:14 each Exp $ */
-
-#ifndef DNS_RESULT_H
-#define DNS_RESULT_H 1
-
-/*! \file dns/result.h */
-
-#include <isc/lang.h>
-#include <isc/resultclass.h>
-
-#include <dns/types.h>
-
-/*
- * Nothing in this file truly depends on <isc/result.h>, but the
- * DNS result codes are considered to be publicly derived from
- * the ISC result codes, so including this file buys you the ISC_R_
- * namespace too.
- */
-#include <isc/result.h> /* Contractual promise. */
-
-/*
- * DNS library result codes
- */
-#define DNS_R_LABELTOOLONG (ISC_RESULTCLASS_DNS + 0)
-#define DNS_R_BADESCAPE (ISC_RESULTCLASS_DNS + 1)
-/*
- * Since we dropped the support of bitstring labels, deprecate the related
- * result codes too.
-
-#define DNS_R_BADBITSTRING (ISC_RESULTCLASS_DNS + 2)
-#define DNS_R_BITSTRINGTOOLONG (ISC_RESULTCLASS_DNS + 3)
-*/
-#define DNS_R_EMPTYLABEL (ISC_RESULTCLASS_DNS + 4)
-#define DNS_R_BADDOTTEDQUAD (ISC_RESULTCLASS_DNS + 5)
-#define DNS_R_INVALIDNS (ISC_RESULTCLASS_DNS + 6)
-#define DNS_R_UNKNOWN (ISC_RESULTCLASS_DNS + 7)
-#define DNS_R_BADLABELTYPE (ISC_RESULTCLASS_DNS + 8)
-#define DNS_R_BADPOINTER (ISC_RESULTCLASS_DNS + 9)
-#define DNS_R_TOOMANYHOPS (ISC_RESULTCLASS_DNS + 10)
-#define DNS_R_DISALLOWED (ISC_RESULTCLASS_DNS + 11)
-#define DNS_R_EXTRATOKEN (ISC_RESULTCLASS_DNS + 12)
-#define DNS_R_EXTRADATA (ISC_RESULTCLASS_DNS + 13)
-#define DNS_R_TEXTTOOLONG (ISC_RESULTCLASS_DNS + 14)
-#define DNS_R_NOTZONETOP (ISC_RESULTCLASS_DNS + 15)
-#define DNS_R_SYNTAX (ISC_RESULTCLASS_DNS + 16)
-#define DNS_R_BADCKSUM (ISC_RESULTCLASS_DNS + 17)
-#define DNS_R_BADAAAA (ISC_RESULTCLASS_DNS + 18)
-#define DNS_R_NOOWNER (ISC_RESULTCLASS_DNS + 19)
-#define DNS_R_NOTTL (ISC_RESULTCLASS_DNS + 20)
-#define DNS_R_BADCLASS (ISC_RESULTCLASS_DNS + 21)
-#define DNS_R_NAMETOOLONG (ISC_RESULTCLASS_DNS + 22)
-#define DNS_R_PARTIALMATCH (ISC_RESULTCLASS_DNS + 23)
-#define DNS_R_NEWORIGIN (ISC_RESULTCLASS_DNS + 24)
-#define DNS_R_UNCHANGED (ISC_RESULTCLASS_DNS + 25)
-#define DNS_R_BADTTL (ISC_RESULTCLASS_DNS + 26)
-#define DNS_R_NOREDATA (ISC_RESULTCLASS_DNS + 27)
-#define DNS_R_CONTINUE (ISC_RESULTCLASS_DNS + 28)
-#define DNS_R_DELEGATION (ISC_RESULTCLASS_DNS + 29)
-#define DNS_R_GLUE (ISC_RESULTCLASS_DNS + 30)
-#define DNS_R_DNAME (ISC_RESULTCLASS_DNS + 31)
-#define DNS_R_CNAME (ISC_RESULTCLASS_DNS + 32)
-#define DNS_R_BADDB (ISC_RESULTCLASS_DNS + 33)
-#define DNS_R_ZONECUT (ISC_RESULTCLASS_DNS + 34)
-#define DNS_R_BADZONE (ISC_RESULTCLASS_DNS + 35)
-#define DNS_R_MOREDATA (ISC_RESULTCLASS_DNS + 36)
-#define DNS_R_UPTODATE (ISC_RESULTCLASS_DNS + 37)
-#define DNS_R_TSIGVERIFYFAILURE (ISC_RESULTCLASS_DNS + 38)
-#define DNS_R_TSIGERRORSET (ISC_RESULTCLASS_DNS + 39)
-#define DNS_R_SIGINVALID (ISC_RESULTCLASS_DNS + 40)
-#define DNS_R_SIGEXPIRED (ISC_RESULTCLASS_DNS + 41)
-#define DNS_R_SIGFUTURE (ISC_RESULTCLASS_DNS + 42)
-#define DNS_R_KEYUNAUTHORIZED (ISC_RESULTCLASS_DNS + 43)
-#define DNS_R_INVALIDTIME (ISC_RESULTCLASS_DNS + 44)
-#define DNS_R_EXPECTEDTSIG (ISC_RESULTCLASS_DNS + 45)
-#define DNS_R_UNEXPECTEDTSIG (ISC_RESULTCLASS_DNS + 46)
-#define DNS_R_INVALIDTKEY (ISC_RESULTCLASS_DNS + 47)
-#define DNS_R_HINT (ISC_RESULTCLASS_DNS + 48)
-#define DNS_R_DROP (ISC_RESULTCLASS_DNS + 49)
-#define DNS_R_NOTLOADED (ISC_RESULTCLASS_DNS + 50)
-#define DNS_R_NCACHENXDOMAIN (ISC_RESULTCLASS_DNS + 51)
-#define DNS_R_NCACHENXRRSET (ISC_RESULTCLASS_DNS + 52)
-#define DNS_R_WAIT (ISC_RESULTCLASS_DNS + 53)
-#define DNS_R_NOTVERIFIEDYET (ISC_RESULTCLASS_DNS + 54)
-#define DNS_R_NOIDENTITY (ISC_RESULTCLASS_DNS + 55)
-#define DNS_R_NOJOURNAL (ISC_RESULTCLASS_DNS + 56)
-#define DNS_R_ALIAS (ISC_RESULTCLASS_DNS + 57)
-#define DNS_R_USETCP (ISC_RESULTCLASS_DNS + 58)
-#define DNS_R_NOVALIDSIG (ISC_RESULTCLASS_DNS + 59)
-#define DNS_R_NOVALIDNSEC (ISC_RESULTCLASS_DNS + 60)
-#define DNS_R_NOTINSECURE (ISC_RESULTCLASS_DNS + 61)
-#define DNS_R_UNKNOWNSERVICE (ISC_RESULTCLASS_DNS + 62)
-#define DNS_R_RECOVERABLE (ISC_RESULTCLASS_DNS + 63)
-#define DNS_R_UNKNOWNOPT (ISC_RESULTCLASS_DNS + 64)
-#define DNS_R_UNEXPECTEDID (ISC_RESULTCLASS_DNS + 65)
-#define DNS_R_SEENINCLUDE (ISC_RESULTCLASS_DNS + 66)
-#define DNS_R_NOTEXACT (ISC_RESULTCLASS_DNS + 67)
-#define DNS_R_BLACKHOLED (ISC_RESULTCLASS_DNS + 68)
-#define DNS_R_BADALG (ISC_RESULTCLASS_DNS + 69)
-#define DNS_R_METATYPE (ISC_RESULTCLASS_DNS + 70)
-#define DNS_R_CNAMEANDOTHER (ISC_RESULTCLASS_DNS + 71)
-#define DNS_R_SINGLETON (ISC_RESULTCLASS_DNS + 72)
-#define DNS_R_HINTNXRRSET (ISC_RESULTCLASS_DNS + 73)
-#define DNS_R_NOMASTERFILE (ISC_RESULTCLASS_DNS + 74)
-#define DNS_R_UNKNOWNPROTO (ISC_RESULTCLASS_DNS + 75)
-#define DNS_R_CLOCKSKEW (ISC_RESULTCLASS_DNS + 76)
-#define DNS_R_BADIXFR (ISC_RESULTCLASS_DNS + 77)
-#define DNS_R_NOTAUTHORITATIVE (ISC_RESULTCLASS_DNS + 78)
-#define DNS_R_NOVALIDKEY (ISC_RESULTCLASS_DNS + 79)
-#define DNS_R_OBSOLETE (ISC_RESULTCLASS_DNS + 80)
-#define DNS_R_FROZEN (ISC_RESULTCLASS_DNS + 81)
-#define DNS_R_UNKNOWNFLAG (ISC_RESULTCLASS_DNS + 82)
-#define DNS_R_EXPECTEDRESPONSE (ISC_RESULTCLASS_DNS + 83)
-#define DNS_R_NOVALIDDS (ISC_RESULTCLASS_DNS + 84)
-#define DNS_R_NSISADDRESS (ISC_RESULTCLASS_DNS + 85)
-#define DNS_R_REMOTEFORMERR (ISC_RESULTCLASS_DNS + 86)
-#define DNS_R_TRUNCATEDTCP (ISC_RESULTCLASS_DNS + 87)
-#define DNS_R_LAME (ISC_RESULTCLASS_DNS + 88)
-#define DNS_R_UNEXPECTEDRCODE (ISC_RESULTCLASS_DNS + 89)
-#define DNS_R_UNEXPECTEDOPCODE (ISC_RESULTCLASS_DNS + 90)
-#define DNS_R_CHASEDSSERVERS (ISC_RESULTCLASS_DNS + 91)
-#define DNS_R_EMPTYNAME (ISC_RESULTCLASS_DNS + 92)
-#define DNS_R_EMPTYWILD (ISC_RESULTCLASS_DNS + 93)
-#define DNS_R_BADBITMAP (ISC_RESULTCLASS_DNS + 94)
-#define DNS_R_FROMWILDCARD (ISC_RESULTCLASS_DNS + 95)
-#define DNS_R_BADOWNERNAME (ISC_RESULTCLASS_DNS + 96)
-#define DNS_R_BADNAME (ISC_RESULTCLASS_DNS + 97)
-#define DNS_R_DYNAMIC (ISC_RESULTCLASS_DNS + 98)
-#define DNS_R_UNKNOWNCOMMAND (ISC_RESULTCLASS_DNS + 99)
-#define DNS_R_MUSTBESECURE (ISC_RESULTCLASS_DNS + 100)
-#define DNS_R_COVERINGNSEC (ISC_RESULTCLASS_DNS + 101)
-#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_BROKENCHAIN (ISC_RESULTCLASS_DNS + 106)
-#define DNS_R_EXPIRED (ISC_RESULTCLASS_DNS + 107)
-#define DNS_R_NOTDYNAMIC (ISC_RESULTCLASS_DNS + 108)
-#define DNS_R_BADEUI (ISC_RESULTCLASS_DNS + 109)
-
-#define DNS_R_NRESULTS 110 /*%< Number of results */
-
-/*
- * DNS wire format rcodes.
- *
- * By making these their own class we can easily convert them into the
- * wire-format rcode value simply by masking off the resultclass.
- */
-#define DNS_R_NOERROR (ISC_RESULTCLASS_DNSRCODE + 0)
-#define DNS_R_FORMERR (ISC_RESULTCLASS_DNSRCODE + 1)
-#define DNS_R_SERVFAIL (ISC_RESULTCLASS_DNSRCODE + 2)
-#define DNS_R_NXDOMAIN (ISC_RESULTCLASS_DNSRCODE + 3)
-#define DNS_R_NOTIMP (ISC_RESULTCLASS_DNSRCODE + 4)
-#define DNS_R_REFUSED (ISC_RESULTCLASS_DNSRCODE + 5)
-#define DNS_R_YXDOMAIN (ISC_RESULTCLASS_DNSRCODE + 6)
-#define DNS_R_YXRRSET (ISC_RESULTCLASS_DNSRCODE + 7)
-#define DNS_R_NXRRSET (ISC_RESULTCLASS_DNSRCODE + 8)
-#define DNS_R_NOTAUTH (ISC_RESULTCLASS_DNSRCODE + 9)
-#define DNS_R_NOTZONE (ISC_RESULTCLASS_DNSRCODE + 10)
-#define DNS_R_BADVERS (ISC_RESULTCLASS_DNSRCODE + 16)
-
-#define DNS_R_NRCODERESULTS 17 /*%< Number of rcode results */
-
-#define DNS_RESULT_ISRCODE(result) \
- (ISC_RESULTCLASS_INCLASS(ISC_RESULTCLASS_DNSRCODE, (result)))
-
-ISC_LANG_BEGINDECLS
-
-const char *
-dns_result_totext(isc_result_t);
-
-void
-dns_result_register(void);
-
-dns_rcode_t
-dns_result_torcode(isc_result_t result);
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_RESULT_H */
diff --git a/contrib/bind9/lib/dns/include/dns/rootns.h b/contrib/bind9/lib/dns/include/dns/rootns.h
deleted file mode 100644
index 6da3f79d8b8b..000000000000
--- a/contrib/bind9/lib/dns/include/dns/rootns.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: rootns.h,v 1.16 2007/06/19 23:47:17 tbox Exp $ */
-
-#ifndef DNS_ROOTNS_H
-#define DNS_ROOTNS_H 1
-
-/*! \file dns/rootns.h */
-
-#include <isc/lang.h>
-
-#include <dns/types.h>
-
-ISC_LANG_BEGINDECLS
-
-isc_result_t
-dns_rootns_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
- const char *filename, dns_db_t **target);
-
-void
-dns_root_checkhints(dns_view_t *view, dns_db_t *hints, dns_db_t *db);
-/*
- * Reports differences between hints and the real roots.
- *
- * Requires view, hints and (cache) db to be valid.
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_ROOTNS_H */
diff --git a/contrib/bind9/lib/dns/include/dns/rpz.h b/contrib/bind9/lib/dns/include/dns/rpz.h
deleted file mode 100644
index e1d50a53b555..000000000000
--- a/contrib/bind9/lib/dns/include/dns/rpz.h
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-
-#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_PREFIX "rpz-"
-#define DNS_RPZ_IP_ZONE DNS_RPZ_PREFIX"ip"
-#define DNS_RPZ_NSIP_ZONE DNS_RPZ_PREFIX"nsip"
-#define DNS_RPZ_NSDNAME_ZONE DNS_RPZ_PREFIX"nsdname"
-#define DNS_RPZ_PASSTHRU_ZONE DNS_RPZ_PREFIX"passthru"
-
-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_NSDNAME,
- DNS_RPZ_TYPE_NSIP
-} dns_rpz_type_t;
-
-/*
- * Require DNS_RPZ_POLICY_PASSTHRU < DNS_RPZ_POLICY_NXDOMAIN <
- * DNS_RPZ_POLICY_NODATA < DNS_RPZ_POLICY_CNAME to choose among competing
- * policies.
- */
-typedef enum {
- DNS_RPZ_POLICY_GIVEN = 0, /* 'given': what policy record says */
- DNS_RPZ_POLICY_DISABLED = 1, /* 'cname x': answer with x's rrsets */
- DNS_RPZ_POLICY_PASSTHRU = 2, /* 'passthru': do not rewrite */
- DNS_RPZ_POLICY_NXDOMAIN = 3, /* 'nxdomain': answer with NXDOMAIN */
- DNS_RPZ_POLICY_NODATA = 4, /* 'nodata': answer with ANCOUNT=0 */
- DNS_RPZ_POLICY_CNAME = 5, /* 'cname x': answer with x's rrsets */
- DNS_RPZ_POLICY_RECORD,
- DNS_RPZ_POLICY_WILDCNAME,
- 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; /* ordinal in list of policy zones */
- dns_name_t origin; /* Policy zone name */
- dns_name_t nsdname; /* DNS_RPZ_NSDNAME_ZONE.origin */
- dns_name_t passthru;/* DNS_RPZ_PASSTHRU_ZONE. */
- dns_name_t cname; /* override value for ..._CNAME */
- dns_ttl_t max_policy_ttl;
- dns_rpz_policy_t policy; /* DNS_RPZ_POLICY_GIVEN or override */
- isc_boolean_t recursive_only;
- isc_boolean_t defined;
-};
-
-/*
- * 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 /* qname checked */
-# define DNS_RPZ_DONE_QNAME_IP 0x0004 /* IP addresses of qname checked */
-# define DNS_RPZ_DONE_NSDNAME 0x0008 /* NS name missed; checking addresses */
-# define DNS_RPZ_DONE_IPv4 0x0010
-# define DNS_RPZ_RECURSING 0x0020
-# define DNS_RPZ_HAVE_IP 0x0040 /* a policy zone has IP addresses */
-# define DNS_RPZ_HAVE_NSIPv4 0x0080 /* IPv4 NISP addresses */
-# define DNS_RPZ_HAVE_NSIPv6 0x0100 /* IPv6 NISP addresses */
-# define DNS_RPZ_HAVE_NSDNAME 0x0200 /* NS names */
- /*
- * 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_dbversion_t *version;
- dns_dbnode_t *node;
- dns_rdataset_t *rdataset;
- } m;
- /*
- * State for chasing IP addresses and NS names 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;
- } r;
- /*
- * 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
-#define DNS_RPZ_MAX_TTL_DEFAULT DNS_RPZ_TTL_DEFAULT
-
-/*
- * 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)
-#define DNS_RPZ_DEBUG_LEVEL3 ISC_LOG_DEBUG(3)
-#define DNS_RPZ_DEBUG_QUIET (DNS_RPZ_DEBUG_LEVEL3+1)
-
-const char *
-dns_rpz_type2str(dns_rpz_type_t type);
-
-dns_rpz_policy_t
-dns_rpz_str2policy(const char *str);
-
-const char *
-dns_rpz_policy2str(dns_rpz_policy_t policy);
-
-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_get(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_rpz_zone_t *rpz, dns_rdataset_t *rdataset,
- dns_name_t *selfname);
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_RPZ_H */
-
diff --git a/contrib/bind9/lib/dns/include/dns/rriterator.h b/contrib/bind9/lib/dns/include/dns/rriterator.h
deleted file mode 100644
index c979f2249992..000000000000
--- a/contrib/bind9/lib/dns/include/dns/rriterator.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * 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: rriterator.h,v 1.4 2011/11/01 23:47:00 tbox 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);
-/*%
- * Initialize an rriterator; sets the cursor to the origin node
- * of the database.
- *
- * Requires:
- *
- * \li 'db' is a valid database.
- *
- * Returns:
- *
- * \li #ISC_R_SUCCESS
- * \li #ISC_R_NOMEMORY
- */
-
-isc_result_t
-dns_rriterator_first(dns_rriterator_t *it);
-/*%<
- * Move the rriterator cursor to the first rdata in the database.
- *
- * Requires:
- *\li 'it' is a valid, initialized rriterator
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMORE There are no rdata in the set.
- */
-
-isc_result_t
-dns_rriterator_nextrrset(dns_rriterator_t *it);
-/*%<
- * Move the rriterator cursor to the next rrset in the database,
- * skipping over any remaining records that have the same rdatatype
- * as the current one.
- *
- * Requires:
- *\li 'it' is a valid, initialized rriterator
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMORE No more rrsets in the database
- */
-
-isc_result_t
-dns_rriterator_next(dns_rriterator_t *it);
-/*%<
- * Move the rriterator cursor to the next rrset in the database,
- * skipping over any remaining records that have the same rdatatype
- * as the current one.
- *
- * Requires:
- *\li 'it' is a valid, initialized rriterator
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMORE No more records in the database
- */
-
-void
-dns_rriterator_current(dns_rriterator_t *it, dns_name_t **name,
- isc_uint32_t *ttl, dns_rdataset_t **rdataset,
- dns_rdata_t **rdata);
-/*%<
- * Make '*name' refer to the current name. If 'rdataset' is not NULL,
- * make '*rdataset' refer to the current * rdataset. If '*rdata' is not
- * NULL, make '*rdata' refer to the current record.
- *
- * Requires:
- *\li '*name' is a valid name object
- *\li 'rdataset' is NULL or '*rdataset' is NULL
- *\li 'rdata' is NULL or '*rdata' is NULL
- *
- * Ensures:
- *\li 'rdata' refers to the rdata at the rdata cursor location of
- *\li 'rdataset'.
- */
-
-void
-dns_rriterator_pause(dns_rriterator_t *it);
-/*%<
- * Pause rriterator. Frees any locks held by the database iterator.
- * Callers should use this routine any time they are not going to
- * execute another rriterator method in the immediate future.
- *
- * Requires:
- *\li 'it' is a valid iterator.
- *
- * Ensures:
- *\li Any database locks being held for efficiency of iterator access are
- * released.
- */
-
-void
-dns_rriterator_destroy(dns_rriterator_t *it);
-/*%<
- * Shut down and free resources in rriterator 'it'.
- *
- * Requires:
- *
- *\li 'it' is a valid iterator.
- *
- * Ensures:
- *
- *\li All resources used by the rriterator are freed.
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_RRITERATOR_H */
diff --git a/contrib/bind9/lib/dns/include/dns/sdb.h b/contrib/bind9/lib/dns/include/dns/sdb.h
deleted file mode 100644
index 27519034f171..000000000000
--- a/contrib/bind9/lib/dns/include/dns/sdb.h
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (C) 2004-2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2000, 2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: sdb.h,v 1.25 2011/10/11 23:46:45 tbox Exp $ */
-
-#ifndef DNS_SDB_H
-#define DNS_SDB_H 1
-
-/*****
- ***** Module Info
- *****/
-
-/*! \file dns/sdb.h
- * \brief
- * Simple database API.
- */
-
-/***
- *** Imports
- ***/
-
-#include <isc/lang.h>
-
-#include <dns/clientinfo.h>
-#include <dns/types.h>
-
-/***
- *** Types
- ***/
-
-/*%
- * A simple database. This is an opaque type.
- */
-typedef struct dns_sdb dns_sdb_t;
-
-/*%
- * A simple database lookup in progress. This is an opaque type.
- */
-typedef struct dns_sdblookup dns_sdblookup_t;
-
-/*%
- * A simple database traversal in progress. This is an opaque type.
- */
-typedef struct dns_sdballnodes dns_sdballnodes_t;
-
-typedef isc_result_t
-(*dns_sdblookupfunc_t)(const char *zone, const char *name, void *dbdata,
- dns_sdblookup_t *lookup,
- dns_clientinfomethods_t *methods,
- dns_clientinfo_t *clientinfo);
-typedef isc_result_t
-(*dns_sdblookup2func_t)(const dns_name_t *zone, const dns_name_t *name,
- void *dbdata, dns_sdblookup_t *lookup,
- dns_clientinfomethods_t *methods,
- dns_clientinfo_t *clientinfo);
-
-typedef isc_result_t
-(*dns_sdbauthorityfunc_t)(const char *zone, void *dbdata, dns_sdblookup_t *);
-
-typedef isc_result_t
-(*dns_sdballnodesfunc_t)(const char *zone, void *dbdata,
- dns_sdballnodes_t *allnodes);
-
-typedef isc_result_t
-(*dns_sdbcreatefunc_t)(const char *zone, int argc, char **argv,
- void *driverdata, void **dbdata);
-
-typedef void
-(*dns_sdbdestroyfunc_t)(const char *zone, void *driverdata, void **dbdata);
-
-
-typedef struct dns_sdbmethods {
- dns_sdblookupfunc_t lookup;
- dns_sdbauthorityfunc_t authority;
- dns_sdballnodesfunc_t allnodes;
- dns_sdbcreatefunc_t create;
- dns_sdbdestroyfunc_t destroy;
- dns_sdblookup2func_t lookup2;
-} dns_sdbmethods_t;
-
-/***
- *** Functions
- ***/
-
-ISC_LANG_BEGINDECLS
-
-#define DNS_SDBFLAG_RELATIVEOWNER 0x00000001U
-#define DNS_SDBFLAG_RELATIVERDATA 0x00000002U
-#define DNS_SDBFLAG_THREADSAFE 0x00000004U
-#define DNS_SDBFLAG_DNS64 0x00000008U
-
-isc_result_t
-dns_sdb_register(const char *drivername, const dns_sdbmethods_t *methods,
- void *driverdata, unsigned int flags, isc_mem_t *mctx,
- dns_sdbimplementation_t **sdbimp);
-/*%<
- * Register a simple database driver for the database type 'drivername',
- * implemented by the functions in '*methods'.
- *
- * sdbimp must point to a NULL dns_sdbimplementation_t pointer. That is,
- * sdbimp != NULL && *sdbimp == NULL. It will be assigned a value that
- * will later be used to identify the driver when deregistering it.
- *
- * The name server will perform lookups in the database by calling the
- * function 'lookup', passing it a printable zone name 'zone', a printable
- * domain name 'name', and a copy of the argument 'dbdata' that
- * was potentially returned by the create function. The 'dns_sdblookup_t'
- * argument to 'lookup' and 'authority' is an opaque pointer to be passed to
- * ns_sdb_putrr().
- *
- * The lookup function returns the lookup results to the name server
- * by calling ns_sdb_putrr() once for each record found. On success,
- * the return value of the lookup function should be ISC_R_SUCCESS.
- * If the domain name 'name' does not exist, the lookup function should
- * ISC_R_NOTFOUND. Any other return value is treated as an error.
- *
- * Lookups at the zone apex will cause the server to also call the
- * function 'authority' (if non-NULL), which must provide an SOA record
- * and NS records for the zone by calling ns_sdb_putrr() once for each of
- * these records. The 'authority' function may be NULL if invoking
- * the 'lookup' function on the zone apex will return SOA and NS records.
- *
- * The allnodes function, if non-NULL, fills in an opaque structure to be
- * used by a database iterator. This allows the zone to be transferred.
- * This may use a considerable amount of memory for large zones, and the
- * zone transfer may not be fully RFC1035 compliant if the zone is
- * frequently changed.
- *
- * The create function will be called for each zone configured
- * into the name server using this database type. It can be used
- * to create a "database object" containing zone specific data,
- * which can make use of the database arguments specified in the
- * name server configuration.
- *
- * The destroy function will be called to free the database object
- * when its zone is destroyed.
- *
- * The create and destroy functions may be NULL.
- *
- * If flags includes DNS_SDBFLAG_RELATIVEOWNER, the lookup and authority
- * functions will be called with relative names rather than absolute names.
- * The string "@" represents the zone apex in this case.
- *
- * If flags includes DNS_SDBFLAG_RELATIVERDATA, the rdata strings may
- * include relative names. Otherwise, all names in the rdata string must
- * be absolute. Be aware that if relative names are allowed, any
- * absolute names must contain a trailing dot.
- *
- * If flags includes DNS_SDBFLAG_THREADSAFE, the driver must be able to
- * handle multiple lookups in parallel. Otherwise, calls into the driver
- * are serialized.
- */
-
-void
-dns_sdb_unregister(dns_sdbimplementation_t **sdbimp);
-/*%<
- * Removes the simple database driver from the list of registered database
- * types. There must be no active databases of this type when this function
- * is called.
- */
-
-/*% See dns_sdb_putradata() */
-isc_result_t
-dns_sdb_putrr(dns_sdblookup_t *lookup, const char *type, dns_ttl_t ttl,
- const char *data);
-isc_result_t
-dns_sdb_putrdata(dns_sdblookup_t *lookup, dns_rdatatype_t type, dns_ttl_t ttl,
- const unsigned char *rdata, unsigned int rdlen);
-/*%<
- * Add a single resource record to the lookup structure to be
- * returned in the query response. dns_sdb_putrr() takes the
- * resource record in master file text format as a null-terminated
- * string, and dns_sdb_putrdata() takes the raw RDATA in
- * uncompressed wire format.
- */
-
-/*% See dns_sdb_putnamerdata() */
-isc_result_t
-dns_sdb_putnamedrr(dns_sdballnodes_t *allnodes, const char *name,
- const char *type, dns_ttl_t ttl, const char *data);
-isc_result_t
-dns_sdb_putnamedrdata(dns_sdballnodes_t *allnodes, const char *name,
- dns_rdatatype_t type, dns_ttl_t ttl,
- const void *rdata, unsigned int rdlen);
-/*%<
- * Add a single resource record to the allnodes structure to be
- * included in a zone transfer response, in text or wire
- * format as above.
- */
-
-isc_result_t
-dns_sdb_putsoa(dns_sdblookup_t *lookup, const char *mname, const char *rname,
- isc_uint32_t serial);
-/*%<
- * This function may optionally be called from the 'authority' callback
- * to simplify construction of the SOA record for 'zone'. It will
- * provide a SOA listing 'mname' as as the master server and 'rname' as
- * the responsible person mailbox. It is the responsibility of the
- * driver to increment the serial number between responses if necessary.
- * All other SOA fields will have reasonable default values.
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_SDB_H */
diff --git a/contrib/bind9/lib/dns/include/dns/sdlz.h b/contrib/bind9/lib/dns/include/dns/sdlz.h
deleted file mode 100644
index fbc6b95e70d1..000000000000
--- a/contrib/bind9/lib/dns/include/dns/sdlz.h
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * Portions Copyright (C) 2005-2007, 2009-2012 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * Copyright (C) 2002 Stichting NLnet, Netherlands, stichting@nlnet.nl.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the
- * above copyright notice and this permission notice appear in all
- * copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND STICHTING NLNET
- * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
- * STICHTING NLNET BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
- * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
- * USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * The development of Dynamically Loadable Zones (DLZ) for Bind 9 was
- * conceived and contributed by Rob Butler.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the
- * above copyright notice and this permission notice appear in all
- * copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ROB BUTLER
- * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
- * ROB BUTLER BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
- * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
- * USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/*! \file dns/sdlz.h */
-
-#ifndef SDLZ_H
-#define SDLZ_H 1
-
-#include <dns/clientinfo.h>
-#include <dns/dlz.h>
-
-ISC_LANG_BEGINDECLS
-
-#define DNS_SDLZFLAG_THREADSAFE 0x00000001U
-#define DNS_SDLZFLAG_RELATIVEOWNER 0x00000002U
-#define DNS_SDLZFLAG_RELATIVERDATA 0x00000004U
-
- /* A simple DLZ database. */
-typedef struct dns_sdlz_db dns_sdlz_db_t;
-
- /* A simple DLZ database lookup in progress. */
-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);
-/*%<
- * Method prototype. Drivers implementing the SDLZ interface may
- * supply an all nodes method. This method is called when the DNS
- * server is performing a zone transfer query, after the allow zone
- * transfer method has been called. This method is only called if the
- * allow zone transfer method returned ISC_R_SUCCESS. This method and
- * the allow zone transfer method are both required for zone transfers
- * to be supported. If the driver generates data dynamically (instead
- * of searching in a database for it) it should not implement this
- * function as a zone transfer would be meaningless. A SDLZ driver
- * 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);
-
-/*%<
- * Method prototype. Drivers implementing the SDLZ interface may
- * supply an allow zone transfer method. This method is called when
- * the DNS server is performing a zone transfer query, before the all
- * nodes method can be called. This method and the all node method
- * are both required for zone transfers to be supported. If the
- * driver generates data dynamically (instead of searching in a
- * database for it) it should not implement this function as a zone
- * transfer would be meaningless. A SDLZ driver does not have to
- * implement an allow zone transfer method.
- *
- * This method should return ISC_R_SUCCESS if the zone is supported by
- * the database and a zone transfer is allowed for the specified
- * client. If the zone is supported by the database, but zone
- * transfers are not allowed for the specified client this method
- * should return ISC_R_NOPERM.. Lastly the method should return
- * ISC_R_NOTFOUND if the zone is not supported by the database. If an
- * error occurs it should return a result code indicating the type of
- * error.
- */
-
-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
- * supply an authority method. This method is called when the DNS
- * server is performing a query, after both the find zone and lookup
- * methods have been called. This method is required if the lookup
- * function does not supply authority information for the dns
- * record. A SDLZ driver does not have to implement an authority
- * method.
- */
-
-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
- * supply a create method. This method is called when the DNS server
- * is starting up and creating drivers for use later. A SDLZ driver
- * does not have to implement a create method.
- */
-
-typedef void (*dns_sdlzdestroy_t)(void *driverarg, void *dbdata);
-
-/*%<
- * Method prototype. Drivers implementing the SDLZ interface may
- * supply a destroy method. This method is called when the DNS server
- * is shutting down and no longer needs the driver. A SDLZ driver does
- * not have to implement a destroy method.
- */
-
-typedef isc_result_t
-(*dns_sdlzfindzone_t)(void *driverarg, void *dbdata, const char *name);
-
-/*%<
- * Method prototype. Drivers implementing the SDLZ interface MUST
- * supply a find zone method. This method is called when the DNS
- * server is performing a query to to determine if 'name' is a
- * supported dns zone. The find zone method will be called with the
- * longest possible name first, and continue to be called with
- * successively shorter domain names, until any of the following
- * occur:
- *
- * \li 1) the function returns (ISC_R_SUCCESS) indicating a zone name
- * match.
- *
- * \li 2) a problem occurs, and the functions returns anything other than
- * (ISC_R_NOTFOUND)
- *
- * \li 3) we run out of domain name labels. I.E. we have tried the
- * shortest domain name
- *
- * \li 4) the number of labels in the domain name is less than min_labels
- * for dns_dlzfindzone
- *
- * The driver's find zone method should return ISC_R_SUCCESS if the
- * zone is supported by the database. Otherwise it should return
- * ISC_R_NOTFOUND, if the zone is not supported. If an error occurs
- * it should return a result code indicating the type of error.
- */
-
-typedef isc_result_t
-(*dns_sdlzlookupfunc_t)(const char *zone, const char *name, void *driverarg,
- void *dbdata, dns_sdlzlookup_t *lookup,
- dns_clientinfomethods_t *methods,
- dns_clientinfo_t *clientinfo);
-
-/*%<
- * Method prototype. Drivers implementing the SDLZ interface MUST
- * supply a lookup method. This method is called when the
- * DNS server is performing a query, after the find zone and before any
- * other methods have been called. This function returns DNS record
- * information using the dns_sdlz_putrr and dns_sdlz_putsoa functions.
- * If this function supplies authority information for the DNS record
- * the authority method is not required. If it does not, the
- * authority function is required.
- *
- * The 'methods' and 'clientinfo' args allow an SDLZ driver to retrieve
- * information about the querying client (such as source IP address)
- * from the caller.
- */
-
-typedef isc_result_t (*dns_sdlznewversion_t)(const char *zone,
- 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;
- dns_sdlzfindzone_t findzone;
- dns_sdlzlookupfunc_t lookup;
- 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
-dns_sdlzregister(const char *drivername, const dns_sdlzmethods_t *methods,
- void *driverarg, unsigned int flags, isc_mem_t *mctx,
- dns_sdlzimplementation_t **sdlzimp);
-/*%<
- * Register a dynamically loadable zones (dlz) driver for the database
- * type 'drivername', implemented by the functions in '*methods'.
- *
- * sdlzimp must point to a NULL dns_sdlzimplementation_t pointer.
- * That is, sdlzimp != NULL && *sdlzimp == NULL. It will be assigned
- * a value that will later be used to identify the driver when
- * deregistering it.
- */
-
-void
-dns_sdlzunregister(dns_sdlzimplementation_t **sdlzimp);
-
-/*%<
- * Removes the sdlz driver from the list of registered sdlz drivers.
- * There must be no active sdlz drivers of this type when this
- * function is called.
- */
-
-typedef isc_result_t dns_sdlz_putnamedrr_t(dns_sdlzallnodes_t *allnodes,
- const char *name,
- const char *type,
- dns_ttl_t ttl,
- const char *data);
-dns_sdlz_putnamedrr_t dns_sdlz_putnamedrr;
-
-/*%<
- * Add a single resource record to the allnodes structure to be later
- * parsed into a zone transfer response.
- */
-
-typedef isc_result_t dns_sdlz_putrr_t(dns_sdlzlookup_t *lookup,
- const char *type,
- dns_ttl_t ttl,
- const char *data);
-dns_sdlz_putrr_t dns_sdlz_putrr;
-/*%<
- * Add a single resource record to the lookup structure to be later
- * parsed into a query response.
- */
-
-typedef isc_result_t dns_sdlz_putsoa_t(dns_sdlzlookup_t *lookup,
- const char *mname,
- const char *rname,
- isc_uint32_t serial);
-dns_sdlz_putsoa_t dns_sdlz_putsoa;
-/*%<
- * This function may optionally be called from the 'authority'
- * callback to simplify construction of the SOA record for 'zone'. It
- * will provide a SOA listing 'mname' as as the master server and
- * 'rname' as the responsible person mailbox. It is the
- * responsibility of the driver to increment the serial number between
- * responses if necessary. All other SOA fields will have reasonable
- * default values.
- */
-
-
-typedef isc_result_t dns_sdlz_setdb_t(dns_dlzdb_t *dlzdatabase,
- dns_rdataclass_t rdclass,
- dns_name_t *name,
- dns_db_t **dbp);
-dns_sdlz_setdb_t dns_sdlz_setdb;
-/*%<
- * Create the database pointers for a writeable SDLZ zone
- */
-
-
-ISC_LANG_ENDDECLS
-
-#endif /* SDLZ_H */
diff --git a/contrib/bind9/lib/dns/include/dns/secalg.h b/contrib/bind9/lib/dns/include/dns/secalg.h
deleted file mode 100644
index 43d9fb25e1d2..000000000000
--- a/contrib/bind9/lib/dns/include/dns/secalg.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: secalg.h,v 1.21 2009/10/12 23:48:02 tbox Exp $ */
-
-#ifndef DNS_SECALG_H
-#define DNS_SECALG_H 1
-
-/*! \file dns/secalg.h */
-
-#include <isc/lang.h>
-
-#include <dns/types.h>
-
-ISC_LANG_BEGINDECLS
-
-isc_result_t
-dns_secalg_fromtext(dns_secalg_t *secalgp, isc_textregion_t *source);
-/*%<
- * Convert the text 'source' refers to into a DNSSEC security algorithm value.
- * The text may contain either a mnemonic algorithm name or a decimal algorithm
- * number.
- *
- * Requires:
- *\li 'secalgp' is a valid pointer.
- *
- *\li 'source' is a valid text region.
- *
- * Returns:
- *\li ISC_R_SUCCESS on success
- *\li ISC_R_RANGE numeric type is out of range
- *\li DNS_R_UNKNOWN mnemonic type is unknown
- */
-
-isc_result_t
-dns_secalg_totext(dns_secalg_t secalg, isc_buffer_t *target);
-/*%<
- * Put a textual representation of the DNSSEC security algorithm 'secalg'
- * into 'target'.
- *
- * Requires:
- *\li 'secalg' is a valid secalg.
- *
- *\li 'target' is a valid text buffer.
- *
- * Ensures,
- * if the result is success:
- *\li The used space in 'target' is updated.
- *
- * Returns:
- *\li ISC_R_SUCCESS on success
- *\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/contrib/bind9/lib/dns/include/dns/secproto.h b/contrib/bind9/lib/dns/include/dns/secproto.h
deleted file mode 100644
index b9179c0509ad..000000000000
--- a/contrib/bind9/lib/dns/include/dns/secproto.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: secproto.h,v 1.16 2007/06/19 23:47:17 tbox Exp $ */
-
-#ifndef DNS_SECPROTO_H
-#define DNS_SECPROTO_H 1
-
-/*! \file dns/secproto.h */
-
-#include <isc/lang.h>
-
-#include <dns/types.h>
-
-ISC_LANG_BEGINDECLS
-
-isc_result_t
-dns_secproto_fromtext(dns_secproto_t *secprotop, isc_textregion_t *source);
-/*%<
- * Convert the text 'source' refers to into a DNSSEC security protocol value.
- * The text may contain either a mnemonic protocol name or a decimal protocol
- * number.
- *
- * Requires:
- *\li 'secprotop' is a valid pointer.
- *
- *\li 'source' is a valid text region.
- *
- * Returns:
- *\li ISC_R_SUCCESS on success
- *\li ISC_R_RANGE numeric type is out of range
- *\li DNS_R_UNKNOWN mnemonic type is unknown
- */
-
-isc_result_t
-dns_secproto_totext(dns_secproto_t secproto, isc_buffer_t *target);
-/*%<
- * Put a textual representation of the DNSSEC security protocol 'secproto'
- * into 'target'.
- *
- * Requires:
- *\li 'secproto' is a valid secproto.
- *
- *\li 'target' is a valid text buffer.
- *
- * Ensures,
- * if the result is success:
- * \li The used space in 'target' is updated.
- *
- * Returns:
- *\li ISC_R_SUCCESS on success
- *\li ISC_R_NOSPACE target buffer is too small
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_SECPROTO_H */
diff --git a/contrib/bind9/lib/dns/include/dns/soa.h b/contrib/bind9/lib/dns/include/dns/soa.h
deleted file mode 100644
index 696235eea87b..000000000000
--- a/contrib/bind9/lib/dns/include/dns/soa.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: soa.h,v 1.12 2009/09/10 01:47:09 each Exp $ */
-
-#ifndef DNS_SOA_H
-#define DNS_SOA_H 1
-
-/*****
- ***** Module Info
- *****/
-
-/*! \file dns/soa.h
- * \brief
- * SOA utilities.
- */
-
-/***
- *** Imports
- ***/
-
-#include <isc/lang.h>
-#include <isc/types.h>
-
-#include <dns/types.h>
-
-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
-dns_soa_getrefresh(dns_rdata_t *rdata);
-isc_uint32_t
-dns_soa_getretry(dns_rdata_t *rdata);
-isc_uint32_t
-dns_soa_getexpire(dns_rdata_t *rdata);
-isc_uint32_t
-dns_soa_getminimum(dns_rdata_t *rdata);
-/*
- * Extract an integer field from the rdata of a SOA record.
- *
- * Requires:
- * rdata refers to the rdata of a well-formed SOA record.
- */
-
-void
-dns_soa_setserial(isc_uint32_t val, dns_rdata_t *rdata);
-void
-dns_soa_setrefresh(isc_uint32_t val, dns_rdata_t *rdata);
-void
-dns_soa_setretry(isc_uint32_t val, dns_rdata_t *rdata);
-void
-dns_soa_setexpire(isc_uint32_t val, dns_rdata_t *rdata);
-void
-dns_soa_setminimum(isc_uint32_t val, dns_rdata_t *rdata);
-/*
- * Change an integer field of a SOA record by modifying the
- * rdata in-place.
- *
- * Requires:
- * rdata refers to the rdata of a well-formed SOA record.
- */
-
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_SOA_H */
diff --git a/contrib/bind9/lib/dns/include/dns/ssu.h b/contrib/bind9/lib/dns/include/dns/ssu.h
deleted file mode 100644
index fbe01c3d6641..000000000000
--- a/contrib/bind9/lib/dns/include/dns/ssu.h
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN 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.h,v 1.28 2011/01/06 23:47:00 tbox Exp $ */
-
-#ifndef DNS_SSU_H
-#define DNS_SSU_H 1
-
-/*! \file dns/ssu.h */
-
-#include <isc/lang.h>
-
-#include <dns/types.h>
-#include <dst/dst.h>
-
-ISC_LANG_BEGINDECLS
-
-#define DNS_SSUMATCHTYPE_NAME 0
-#define DNS_SSUMATCHTYPE_SUBDOMAIN 1
-#define DNS_SSUMATCHTYPE_WILDCARD 2
-#define DNS_SSUMATCHTYPE_SELF 3
-#define DNS_SSUMATCHTYPE_SELFSUB 4
-#define DNS_SSUMATCHTYPE_SELFWILD 5
-#define DNS_SSUMATCHTYPE_SELFKRB5 6
-#define DNS_SSUMATCHTYPE_SELFMS 7
-#define DNS_SSUMATCHTYPE_SUBDOMAINMS 8
-#define DNS_SSUMATCHTYPE_SUBDOMAINKRB5 9
-#define DNS_SSUMATCHTYPE_TCPSELF 10
-#define DNS_SSUMATCHTYPE_6TO4SELF 11
-#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);
-/*%<
- * Creates a table that will be used to store simple-secure-update rules.
- * Note: all locking must be provided by the client.
- *
- * Requires:
- *\li 'mctx' is a valid memory context
- *\li 'table' is not NULL, and '*table' is NULL
- *
- * Returns:
- *\li ISC_R_SUCCESS
- *\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);
-/*%<
- * Attach '*targetp' to 'source'.
- *
- * Requires:
- *\li 'source' is a valid SSU table
- *\li 'targetp' points to a NULL dns_ssutable_t *.
- *
- * Ensures:
- *\li *targetp is attached to source.
- */
-
-void
-dns_ssutable_detach(dns_ssutable_t **tablep);
-/*%<
- * Detach '*tablep' from its simple-secure-update rule table.
- *
- * Requires:
- *\li 'tablep' points to a valid dns_ssutable_t
- *
- * Ensures:
- *\li *tablep is NULL
- *\li If '*tablep' is the last reference to the SSU table, all
- * resources used by the table will be freed.
- */
-
-isc_result_t
-dns_ssutable_addrule(dns_ssutable_t *table, isc_boolean_t grant,
- dns_name_t *identity, unsigned int matchtype,
- dns_name_t *name, unsigned int ntypes,
- dns_rdatatype_t *types);
-/*%<
- * Adds a new rule to a simple-secure-update rule table. The rule
- * either grants or denies update privileges of an identity (or set of
- * identities) to modify a name (or set of names) or certain types present
- * at that name.
- *
- * Notes:
- *\li If 'matchtype' is of SELF type, this rule only matches if the
- * name to be updated matches the signing identity.
- *
- *\li If 'ntypes' is 0, this rule applies to all types except
- * NS, SOA, RRSIG, and NSEC.
- *
- *\li If 'types' includes ANY, this rule applies to all types
- * except NSEC.
- *
- * Requires:
- *\li 'table' is a valid SSU table
- *\li 'identity' is a valid absolute name
- *\li 'matchtype' must be one of the defined constants.
- *\li 'name' is a valid absolute name
- *\li If 'ntypes' > 0, 'types' must not be NULL
- *
- * Returns:
- *\li ISC_R_SUCCESS
- *\li ISC_R_NOMEMORY
- */
-
-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, 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
- * no rules are matched, access is denied.
- *
- * Notes:
- * 'tcpaddr' should only be set if the request received
- * via TCP. This provides a weak assurance that the
- * request was not spoofed. 'tcpaddr' is to to validate
- * DNS_SSUMATCHTYPE_TCPSELF and DNS_SSUMATCHTYPE_6TO4SELF
- * rules.
- *
- * For DNS_SSUMATCHTYPE_TCPSELF the addresses are mapped to
- * the standard reverse names under IN-ADDR.ARPA and IP6.ARPA.
- * RFC 1035, Section 3.5, "IN-ADDR.ARPA domain" and RFC 3596,
- * Section 2.5, "IP6.ARPA Domain".
- *
- * For DNS_SSUMATCHTYPE_6TO4SELF, IPv4 address are converted
- * to a 6to4 prefix (48 bits) per the rules in RFC 3056. Only
- * the top 48 bits of the IPv6 address are mapped to the reverse
- * name. This is independent of whether the most significant 16
- * bits match 2002::/16, assigned for 6to4 prefixes, or not.
- *
- * Requires:
- *\li 'table' is a valid SSU table
- *\li 'signer' is NULL or a valid absolute name
- *\li 'tcpaddr' is NULL or a valid network address.
- *\li 'name' is a valid absolute name
- */
-
-
-/*% Accessor functions to extract rule components */
-isc_boolean_t dns_ssurule_isgrant(const dns_ssurule_t *rule);
-/*% Accessor functions to extract rule components */
-dns_name_t * dns_ssurule_identity(const dns_ssurule_t *rule);
-/*% Accessor functions to extract rule components */
-unsigned int dns_ssurule_matchtype(const dns_ssurule_t *rule);
-/*% Accessor functions to extract rule components */
-dns_name_t * dns_ssurule_name(const dns_ssurule_t *rule);
-/*% Accessor functions to extract rule components */
-unsigned int dns_ssurule_types(const dns_ssurule_t *rule,
- dns_rdatatype_t **types);
-
-isc_result_t dns_ssutable_firstrule(const dns_ssutable_t *table,
- dns_ssurule_t **rule);
-/*%<
- * Initiates a rule iterator. There is no need to maintain any state.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMORE
- */
-
-isc_result_t dns_ssutable_nextrule(dns_ssurule_t *rule,
- dns_ssurule_t **nextrule);
-/*%<
- * Returns the next rule in the table.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\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/contrib/bind9/lib/dns/include/dns/stats.h b/contrib/bind9/lib/dns/include/dns/stats.h
deleted file mode 100644
index 5364267272a0..000000000000
--- a/contrib/bind9/lib/dns/include/dns/stats.h
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * Copyright (C) 2004-2009, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2000, 2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-#ifndef DNS_STATS_H
-#define DNS_STATS_H 1
-
-/*! \file dns/stats.h */
-
-#include <dns/types.h>
-
-/*%
- * Statistics counters. Used as isc_statscounter_t values.
- */
-enum {
- /*%
- * Resolver statistics counters.
- */
- dns_resstatscounter_queryv4 = 0,
- dns_resstatscounter_queryv6 = 1,
- dns_resstatscounter_responsev4 = 2,
- dns_resstatscounter_responsev6 = 3,
- dns_resstatscounter_nxdomain = 4,
- dns_resstatscounter_servfail = 5,
- dns_resstatscounter_formerr = 6,
- dns_resstatscounter_othererror = 7,
- dns_resstatscounter_edns0fail = 8,
- dns_resstatscounter_mismatch = 9,
- dns_resstatscounter_truncated = 10,
- dns_resstatscounter_lame = 11,
- dns_resstatscounter_retry = 12,
- dns_resstatscounter_gluefetchv4 = 13,
- dns_resstatscounter_gluefetchv6 = 14,
- dns_resstatscounter_gluefetchv4fail = 15,
- dns_resstatscounter_gluefetchv6fail = 16,
- dns_resstatscounter_val = 17,
- dns_resstatscounter_valsuccess = 18,
- dns_resstatscounter_valnegsuccess = 19,
- dns_resstatscounter_valfail = 20,
- dns_resstatscounter_dispabort = 21,
- dns_resstatscounter_dispsockfail = 22,
- dns_resstatscounter_querytimeout = 23,
- dns_resstatscounter_queryrtt0 = 24,
- dns_resstatscounter_queryrtt1 = 25,
- dns_resstatscounter_queryrtt2 = 26,
- dns_resstatscounter_queryrtt3 = 27,
- dns_resstatscounter_queryrtt4 = 28,
- dns_resstatscounter_queryrtt5 = 29,
-
- dns_resstatscounter_max = 30,
-
- /*
- * DNSSEC stats.
- */
- dns_dnssecstats_asis = 0,
- dns_dnssecstats_downcase = 1,
- dns_dnssecstats_wildcard = 2,
- dns_dnssecstats_fail = 3,
-
- dns_dnssecstats_max = 4,
-
- /*%
- * Zone statistics counters.
- */
- dns_zonestatscounter_notifyoutv4 = 0,
- dns_zonestatscounter_notifyoutv6 = 1,
- dns_zonestatscounter_notifyinv4 = 2,
- dns_zonestatscounter_notifyinv6 = 3,
- dns_zonestatscounter_notifyrej = 4,
- dns_zonestatscounter_soaoutv4 = 5,
- dns_zonestatscounter_soaoutv6 = 6,
- dns_zonestatscounter_axfrreqv4 = 7,
- dns_zonestatscounter_axfrreqv6 = 8,
- dns_zonestatscounter_ixfrreqv4 = 9,
- dns_zonestatscounter_ixfrreqv6 = 10,
- dns_zonestatscounter_xfrsuccess = 11,
- dns_zonestatscounter_xfrfail = 12,
-
- dns_zonestatscounter_max = 13,
-
- /*%
- * Query statistics counters (obsolete).
- */
- dns_statscounter_success = 0, /*%< Successful lookup */
- dns_statscounter_referral = 1, /*%< Referral result */
- dns_statscounter_nxrrset = 2, /*%< NXRRSET result */
- dns_statscounter_nxdomain = 3, /*%< NXDOMAIN result */
- dns_statscounter_recursion = 4, /*%< Recursion was used */
- dns_statscounter_failure = 5, /*%< Some other failure */
- dns_statscounter_duplicate = 6, /*%< Duplicate query */
- dns_statscounter_dropped = 7 /*%< Duplicate query (dropped) */
-};
-
-#define DNS_STATS_NCOUNTERS 8
-
-#if 0
-/*%<
- * Flag(s) for dns_xxxstats_dump(). DNS_STATSDUMP_VERBOSE is obsolete.
- * ISC_STATSDUMP_VERBOSE should be used instead. These two values are
- * intentionally defined to be the same value to ensure binary compatibility.
- */
-#define DNS_STATSDUMP_VERBOSE 0x00000001 /*%< dump 0-value counters */
-#endif
-
-/*%<
- * (Obsoleted)
- */
-LIBDNS_EXTERNAL_DATA extern const char *dns_statscounter_names[];
-
-/*%
- * Attributes for statistics counters of RRset and Rdatatype types.
- *
- * _OTHERTYPE
- * The rdata type is not explicitly supported and the corresponding counter
- * is counted for other such types, too. When this attribute is set,
- * the base type is of no use.
- *
- * _NXRRSET
- * RRset type counters only. Indicates the RRset is non existent.
- *
- * _NXDOMAIN
- * RRset type counters only. Indicates a non existent name. When this
- * attribute is set, the base type is of no use.
- */
-#define DNS_RDATASTATSTYPE_ATTR_OTHERTYPE 0x0001
-#define DNS_RDATASTATSTYPE_ATTR_NXRRSET 0x0002
-#define DNS_RDATASTATSTYPE_ATTR_NXDOMAIN 0x0004
-
-/*%<
- * Conversion macros among dns_rdatatype_t, attributes and isc_statscounter_t.
- */
-#define DNS_RDATASTATSTYPE_BASE(type) ((dns_rdatatype_t)((type) & 0xFFFF))
-#define DNS_RDATASTATSTYPE_ATTR(type) ((type) >> 16)
-#define DNS_RDATASTATSTYPE_VALUE(b, a) (((a) << 16) | (b))
-
-/*%<
- * Types of dump callbacks.
- */
-typedef void (*dns_generalstats_dumper_t)(isc_statscounter_t, isc_uint64_t,
- void *);
-typedef void (*dns_rdatatypestats_dumper_t)(dns_rdatastatstype_t, isc_uint64_t,
- void *);
-typedef void (*dns_opcodestats_dumper_t)(dns_opcode_t, isc_uint64_t, void *);
-
-ISC_LANG_BEGINDECLS
-
-isc_result_t
-dns_generalstats_create(isc_mem_t *mctx, dns_stats_t **statsp, int ncounters);
-/*%<
- * Create a statistics counter structure of general type. It counts a general
- * set of counters indexed by an ID between 0 and ncounters -1.
- * This function is obsolete. A more general function, isc_stats_create(),
- * should be used.
- *
- * Requires:
- *\li 'mctx' must be a valid memory context.
- *
- *\li 'statsp' != NULL && '*statsp' == NULL.
- *
- * Returns:
- *\li ISC_R_SUCCESS -- all ok
- *
- *\li anything else -- failure
- */
-
-isc_result_t
-dns_rdatatypestats_create(isc_mem_t *mctx, dns_stats_t **statsp);
-/*%<
- * Create a statistics counter structure per rdatatype.
- *
- * Requires:
- *\li 'mctx' must be a valid memory context.
- *
- *\li 'statsp' != NULL && '*statsp' == NULL.
- *
- * Returns:
- *\li ISC_R_SUCCESS -- all ok
- *
- *\li anything else -- failure
- */
-
-isc_result_t
-dns_rdatasetstats_create(isc_mem_t *mctx, dns_stats_t **statsp);
-/*%<
- * Create a statistics counter structure per RRset.
- *
- * Requires:
- *\li 'mctx' must be a valid memory context.
- *
- *\li 'statsp' != NULL && '*statsp' == NULL.
- *
- * Returns:
- *\li ISC_R_SUCCESS -- all ok
- *
- *\li anything else -- failure
- */
-
-isc_result_t
-dns_opcodestats_create(isc_mem_t *mctx, dns_stats_t **statsp);
-/*%<
- * Create a statistics counter structure per opcode.
- *
- * Requires:
- *\li 'mctx' must be a valid memory context.
- *
- *\li 'statsp' != NULL && '*statsp' == NULL.
- *
- * Returns:
- *\li ISC_R_SUCCESS -- all ok
- *
- *\li anything else -- failure
- */
-
-void
-dns_stats_attach(dns_stats_t *stats, dns_stats_t **statsp);
-/*%<
- * Attach to a statistics set.
- *
- * Requires:
- *\li 'stats' is a valid dns_stats_t.
- *
- *\li 'statsp' != NULL && '*statsp' == NULL
- */
-
-void
-dns_stats_detach(dns_stats_t **statsp);
-/*%<
- * Detaches from the statistics set.
- *
- * Requires:
- *\li 'statsp' != NULL and '*statsp' is a valid dns_stats_t.
- */
-
-void
-dns_generalstats_increment(dns_stats_t *stats, isc_statscounter_t counter);
-/*%<
- * Increment the counter-th counter of stats. This function is obsolete.
- * A more general function, isc_stats_increment(), should be used.
- *
- * Requires:
- *\li 'stats' is a valid dns_stats_t created by dns_generalstats_create().
- *
- *\li counter is less than the maximum available ID for the stats specified
- * on creation.
- */
-
-void
-dns_rdatatypestats_increment(dns_stats_t *stats, dns_rdatatype_t type);
-/*%<
- * Increment the statistics counter for 'type'.
- *
- * Requires:
- *\li 'stats' is a valid dns_stats_t created by dns_rdatatypestats_create().
- */
-
-void
-dns_rdatasetstats_increment(dns_stats_t *stats, dns_rdatastatstype_t rrsettype);
-/*%<
- * Increment the statistics counter for 'rrsettype'.
- *
- * Requires:
- *\li 'stats' is a valid dns_stats_t created by dns_rdatasetstats_create().
- */
-
-void
-dns_rdatasetstats_decrement(dns_stats_t *stats, dns_rdatastatstype_t rrsettype);
-/*%<
- * Decrement the statistics counter for 'rrsettype'.
- *
- * Requires:
- *\li 'stats' is a valid dns_stats_t created by dns_rdatasetstats_create().
- */
-
-void
-dns_opcodestats_increment(dns_stats_t *stats, dns_opcode_t code);
-/*%<
- * Increment the statistics counter for 'code'.
- *
- * Requires:
- *\li 'stats' is a valid dns_stats_t created by dns_opcodestats_create().
- */
-
-void
-dns_generalstats_dump(dns_stats_t *stats, dns_generalstats_dumper_t dump_fn,
- void *arg, unsigned int options);
-/*%<
- * Dump the current statistics counters in a specified way. For each counter
- * in stats, dump_fn is called with its current value and the given argument
- * arg. By default counters that have a value of 0 is skipped; if options has
- * the ISC_STATSDUMP_VERBOSE flag, even such counters are dumped.
- *
- * This function is obsolete. A more general function, isc_stats_dump(),
- * should be used.
- *
- * Requires:
- *\li 'stats' is a valid dns_stats_t created by dns_generalstats_create().
- */
-
-void
-dns_rdatatypestats_dump(dns_stats_t *stats, dns_rdatatypestats_dumper_t dump_fn,
- void *arg, unsigned int options);
-/*%<
- * Dump the current statistics counters in a specified way. For each counter
- * in stats, dump_fn is called with the corresponding type in the form of
- * dns_rdatastatstype_t, the current counter value and the given argument
- * arg. By default counters that have a value of 0 is skipped; if options has
- * the ISC_STATSDUMP_VERBOSE flag, even such counters are dumped.
- *
- * Requires:
- *\li 'stats' is a valid dns_stats_t created by dns_generalstats_create().
- */
-
-void
-dns_rdatasetstats_dump(dns_stats_t *stats, dns_rdatatypestats_dumper_t dump_fn,
- void *arg, unsigned int options);
-/*%<
- * Dump the current statistics counters in a specified way. For each counter
- * in stats, dump_fn is called with the corresponding type in the form of
- * dns_rdatastatstype_t, the current counter value and the given argument
- * arg. By default counters that have a value of 0 is skipped; if options has
- * the ISC_STATSDUMP_VERBOSE flag, even such counters are dumped.
- *
- * Requires:
- *\li 'stats' is a valid dns_stats_t created by dns_generalstats_create().
- */
-
-void
-dns_opcodestats_dump(dns_stats_t *stats, dns_opcodestats_dumper_t dump_fn,
- void *arg, unsigned int options);
-/*%<
- * Dump the current statistics counters in a specified way. For each counter
- * in stats, dump_fn is called with the corresponding opcode, the current
- * counter value and the given argument arg. By default counters that have a
- * value of 0 is skipped; if options has the ISC_STATSDUMP_VERBOSE flag, even
- * such counters are dumped.
- *
- * Requires:
- *\li 'stats' is a valid dns_stats_t created by dns_generalstats_create().
- */
-
-isc_result_t
-dns_stats_alloccounters(isc_mem_t *mctx, isc_uint64_t **ctrp);
-/*%<
- * Allocate an array of query statistics counters from the memory
- * context 'mctx'.
- *
- * This function is obsoleted. Use dns_xxxstats_create() instead.
- */
-
-void
-dns_stats_freecounters(isc_mem_t *mctx, isc_uint64_t **ctrp);
-/*%<
- * Free an array of query statistics counters allocated from the memory
- * context 'mctx'.
- *
- * This function is obsoleted. Use dns_stats_destroy() instead.
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_STATS_H */
diff --git a/contrib/bind9/lib/dns/include/dns/tcpmsg.h b/contrib/bind9/lib/dns/include/dns/tcpmsg.h
deleted file mode 100644
index fe83c532c8b1..000000000000
--- a/contrib/bind9/lib/dns/include/dns/tcpmsg.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: tcpmsg.h,v 1.22 2007/06/19 23:47:17 tbox Exp $ */
-
-#ifndef DNS_TCPMSG_H
-#define DNS_TCPMSG_H 1
-
-/*! \file dns/tcpmsg.h */
-
-#include <isc/buffer.h>
-#include <isc/lang.h>
-#include <isc/socket.h>
-
-typedef struct dns_tcpmsg {
- /* private (don't touch!) */
- unsigned int magic;
- isc_uint16_t size;
- isc_buffer_t buffer;
- unsigned int maxsize;
- isc_mem_t *mctx;
- isc_socket_t *sock;
- isc_task_t *task;
- isc_taskaction_t action;
- void *arg;
- isc_event_t event;
- /* public (read-only) */
- isc_result_t result;
- isc_sockaddr_t address;
-} dns_tcpmsg_t;
-
-ISC_LANG_BEGINDECLS
-
-void
-dns_tcpmsg_init(isc_mem_t *mctx, isc_socket_t *sock, dns_tcpmsg_t *tcpmsg);
-/*%<
- * Associate a tcp message state with a given memory context and
- * TCP socket.
- *
- * Requires:
- *
- *\li "mctx" and "sock" be non-NULL and valid types.
- *
- *\li "sock" be a read/write TCP socket.
- *
- *\li "tcpmsg" be non-NULL and an uninitialized or invalidated structure.
- *
- * Ensures:
- *
- *\li "tcpmsg" is a valid structure.
- */
-
-void
-dns_tcpmsg_setmaxsize(dns_tcpmsg_t *tcpmsg, unsigned int maxsize);
-/*%<
- * Set the maximum packet size to "maxsize"
- *
- * Requires:
- *
- *\li "tcpmsg" be valid.
- *
- *\li 512 <= "maxsize" <= 65536
- */
-
-isc_result_t
-dns_tcpmsg_readmessage(dns_tcpmsg_t *tcpmsg,
- isc_task_t *task, isc_taskaction_t action, void *arg);
-/*%<
- * Schedule an event to be delivered when a DNS message is readable, or
- * when an error occurs on the socket.
- *
- * Requires:
- *
- *\li "tcpmsg" be valid.
- *
- *\li "task", "taskaction", and "arg" be valid.
- *
- * Returns:
- *
- *\li ISC_R_SUCCESS -- no error
- *\li Anything that the isc_socket_recv() call can return. XXXMLG
- *
- * Notes:
- *
- *\li The event delivered is a fully generic event. It will contain no
- * actual data. The sender will be a pointer to the dns_tcpmsg_t.
- * The result code inside that structure should be checked to see
- * what the final result was.
- */
-
-void
-dns_tcpmsg_cancelread(dns_tcpmsg_t *tcpmsg);
-/*%<
- * Cancel a readmessage() call. The event will still be posted with a
- * CANCELED result code.
- *
- * Requires:
- *
- *\li "tcpmsg" be valid.
- */
-
-void
-dns_tcpmsg_keepbuffer(dns_tcpmsg_t *tcpmsg, isc_buffer_t *buffer);
-/*%<
- * If a dns buffer is to be kept between calls, this function marks the
- * internal state-machine buffer as invalid, and copies all the contents
- * of the state into "buffer".
- *
- * Requires:
- *
- *\li "tcpmsg" be valid.
- *
- *\li "buffer" be non-NULL.
- */
-
-void
-dns_tcpmsg_invalidate(dns_tcpmsg_t *tcpmsg);
-/*%<
- * Clean up all allocated state, and invalidate the structure.
- *
- * Requires:
- *
- *\li "tcpmsg" be valid.
- *
- * Ensures:
- *
- *\li "tcpmsg" is invalidated and disassociated with all memory contexts,
- * sockets, etc.
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_TCPMSG_H */
diff --git a/contrib/bind9/lib/dns/include/dns/time.h b/contrib/bind9/lib/dns/include/dns/time.h
deleted file mode 100644
index 6a59c8a056ee..000000000000
--- a/contrib/bind9/lib/dns/include/dns/time.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2004-2007, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: time.h,v 1.19 2012/01/27 23:46:58 tbox Exp $ */
-
-#ifndef DNS_TIME_H
-#define DNS_TIME_H 1
-
-/*! \file dns/time.h */
-
-/***
- *** Imports
- ***/
-
-#include <isc/buffer.h>
-#include <isc/lang.h>
-
-ISC_LANG_BEGINDECLS
-
-/***
- *** Functions
- ***/
-
-isc_result_t
-dns_time64_fromtext(const char *source, isc_int64_t *target);
-/*%<
- * Convert a date and time in YYYYMMDDHHMMSS text format at 'source'
- * into to a 64-bit count of seconds since Jan 1 1970 0:00 GMT.
- * Store the count at 'target'.
- */
-
-isc_result_t
-dns_time32_fromtext(const char *source, isc_uint32_t *target);
-/*%<
- * Like dns_time64_fromtext, but returns the second count modulo 2^32
- * as per RFC2535.
- */
-
-
-isc_result_t
-dns_time64_totext(isc_int64_t value, isc_buffer_t *target);
-/*%<
- * Convert a 64-bit count of seconds since Jan 1 1970 0:00 GMT into
- * a YYYYMMDDHHMMSS text representation and append it to 'target'.
- */
-
-isc_result_t
-dns_time32_totext(isc_uint32_t value, isc_buffer_t *target);
-/*%<
- * Like dns_time64_totext, but for a 32-bit cyclic time value.
- * Of those dates whose counts of seconds since Jan 1 1970 0:00 GMT
- * are congruent with 'value' modulo 2^32, the one closest to the
- * current date is chosen.
- */
-
-isc_int64_t
-dns_time64_from32(isc_uint32_t value);
-/*%<
- * Covert a 32-bit cyclic time value into a 64 bit time stamp.
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_TIME_H */
diff --git a/contrib/bind9/lib/dns/include/dns/timer.h b/contrib/bind9/lib/dns/include/dns/timer.h
deleted file mode 100644
index 48d6d569cbb8..000000000000
--- a/contrib/bind9/lib/dns/include/dns/timer.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2000, 2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN 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.h,v 1.9 2007/06/19 23:47:17 tbox Exp $ */
-
-#ifndef DNS_TIMER_H
-#define DNS_TIMER_H 1
-
-/*! \file dns/timer.h */
-
-/***
- *** Imports
- ***/
-
-#include <isc/buffer.h>
-#include <isc/lang.h>
-
-ISC_LANG_BEGINDECLS
-
-/***
- *** Functions
- ***/
-
-isc_result_t
-dns_timer_setidle(isc_timer_t *timer, unsigned int maxtime,
- unsigned int idletime, isc_boolean_t purge);
-/*%<
- * Convenience function for setting up simple, one-second-granularity
- * idle timers as used by zone transfers.
- * \brief
- * Set the timer 'timer' to go off after 'idletime' seconds of inactivity,
- * or after 'maxtime' at the very latest. Events are purged iff
- * 'purge' is ISC_TRUE.
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_TIMER_H */
diff --git a/contrib/bind9/lib/dns/include/dns/tkey.h b/contrib/bind9/lib/dns/include/dns/tkey.h
deleted file mode 100644
index 0dcec1ecb4c7..000000000000
--- a/contrib/bind9/lib/dns/include/dns/tkey.h
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: tkey.h,v 1.32 2011/01/08 23:47:01 tbox Exp $ */
-
-#ifndef DNS_TKEY_H
-#define DNS_TKEY_H 1
-
-/*! \file dns/tkey.h */
-
-#include <isc/lang.h>
-
-#include <dns/types.h>
-
-#include <dst/dst.h>
-#include <dst/gssapi.h>
-
-ISC_LANG_BEGINDECLS
-
-/* Key agreement modes */
-#define DNS_TKEYMODE_SERVERASSIGNED 1
-#define DNS_TKEYMODE_DIFFIEHELLMAN 2
-#define DNS_TKEYMODE_GSSAPI 3
-#define DNS_TKEYMODE_RESOLVERASSIGNED 4
-#define DNS_TKEYMODE_DELETE 5
-
-struct dns_tkeyctx {
- dst_key_t *dhkey;
- dns_name_t *domain;
- gss_cred_id_t gsscred;
- isc_mem_t *mctx;
- isc_entropy_t *ectx;
- char *gssapi_keytab;
-};
-
-isc_result_t
-dns_tkeyctx_create(isc_mem_t *mctx, isc_entropy_t *ectx,
- dns_tkeyctx_t **tctxp);
-/*%<
- * Create an empty TKEY context.
- *
- * Requires:
- *\li 'mctx' is not NULL
- *\li 'tctx' is not NULL
- *\li '*tctx' is NULL
- *
- * Returns
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMEMORY
- *\li return codes from dns_name_fromtext()
- */
-
-void
-dns_tkeyctx_destroy(dns_tkeyctx_t **tctxp);
-/*%<
- * Frees all data associated with the TKEY context
- *
- * Requires:
- *\li 'tctx' is not NULL
- *\li '*tctx' is not NULL
- */
-
-isc_result_t
-dns_tkey_processquery(dns_message_t *msg, dns_tkeyctx_t *tctx,
- dns_tsig_keyring_t *ring);
-/*%<
- * Processes a query containing a TKEY record, adding or deleting TSIG
- * keys if necessary, and modifies the message to contain the response.
- *
- * Requires:
- *\li 'msg' is a valid message
- *\li 'tctx' is a valid TKEY context
- *\li 'ring' is a valid TSIG keyring
- *
- * Returns
- *\li #ISC_R_SUCCESS msg was updated (the TKEY operation succeeded,
- * or msg now includes a TKEY with an error set)
- * DNS_R_FORMERR the packet was malformed (missing a TKEY
- * or KEY).
- *\li other An error occurred while processing the message
- */
-
-isc_result_t
-dns_tkey_builddhquery(dns_message_t *msg, dst_key_t *key, dns_name_t *name,
- dns_name_t *algorithm, isc_buffer_t *nonce,
- isc_uint32_t lifetime);
-/*%<
- * Builds a query containing a TKEY that will generate a shared
- * secret using a Diffie-Hellman key exchange. The shared key
- * will be of the specified algorithm (only DNS_TSIG_HMACMD5_NAME
- * is supported), and will be named either 'name',
- * 'name' + server chosen domain, or random data + server chosen domain
- * if 'name' == dns_rootname. If nonce is not NULL, it supplies
- * random data used in the shared secret computation. The key is
- * requested to have the specified lifetime (in seconds)
- *
- *
- * Requires:
- *\li 'msg' is a valid message
- *\li 'key' is a valid Diffie Hellman dst key
- *\li 'name' is a valid name
- *\li 'algorithm' is a valid name
- *
- * Returns:
- *\li #ISC_R_SUCCESS msg was successfully updated to include the
- * query to be sent
- *\li other an error occurred while building the message
- */
-
-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,
- 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).
- *
- * Requires:
- *\li 'msg' is a valid message
- *\li 'name' is a valid name
- *\li 'gname' is a valid name
- *\li 'context' is a pointer to a valid gss_ctx_id_t
- * (which may have the value GSS_C_NO_CONTEXT)
- *\li 'win2k' when true says to turn on some hacks to work
- * with the non-standard GSS-TSIG of Windows 2000
- *
- * Returns:
- *\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
- */
-
-
-isc_result_t
-dns_tkey_builddeletequery(dns_message_t *msg, dns_tsigkey_t *key);
-/*%<
- * Builds a query containing a TKEY record that will delete the
- * specified shared secret from the server.
- *
- * Requires:
- *\li 'msg' is a valid message
- *\li 'key' is a valid TSIG key
- *
- * Returns:
- *\li #ISC_R_SUCCESS msg was successfully updated to include the
- * query to be sent
- *\li other an error occurred while building the message
- */
-
-isc_result_t
-dns_tkey_processdhresponse(dns_message_t *qmsg, dns_message_t *rmsg,
- dst_key_t *key, isc_buffer_t *nonce,
- dns_tsigkey_t **outkey, dns_tsig_keyring_t *ring);
-/*%<
- * Processes a response to a query containing a TKEY that was
- * designed to generate a shared secret using a Diffie-Hellman key
- * exchange. If the query was successful, a new shared key
- * is created and added to the list of shared keys.
- *
- * Requires:
- *\li 'qmsg' is a valid message (the query)
- *\li 'rmsg' is a valid message (the response)
- *\li 'key' is a valid Diffie Hellman dst key
- *\li 'outkey' is either NULL or a pointer to NULL
- *\li 'ring' is a valid keyring or NULL
- *
- * Returns:
- *\li #ISC_R_SUCCESS the shared key was successfully added
- *\li #ISC_R_NOTFOUND an error occurred while looking for a
- * component of the query or response
- */
-
-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, char **err_message);
-/*%<
- * XXX
- */
-
-isc_result_t
-dns_tkey_processdeleteresponse(dns_message_t *qmsg, dns_message_t *rmsg,
- dns_tsig_keyring_t *ring);
-/*%<
- * Processes a response to a query containing a TKEY that was
- * designed to delete a shared secret. If the query was successful,
- * the shared key is deleted from the list of shared keys.
- *
- * Requires:
- *\li 'qmsg' is a valid message (the query)
- *\li 'rmsg' is a valid message (the response)
- *\li 'ring' is not NULL
- *
- * Returns:
- *\li #ISC_R_SUCCESS the shared key was successfully deleted
- *\li #ISC_R_NOTFOUND an error occurred while looking for a
- * 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, char **err_message);
-
-/*
- * Client side negotiation of GSS-TSIG. Process the response
- * to a TKEY, and establish a TSIG key if negotiation was successful.
- * Build a response to the input TKEY message. Can take multiple
- * calls to successfully establish the context.
- *
- * Requires:
- * 'qmsg' is a valid message, the original TKEY request;
- * it will be filled with the new message to send
- * 'rmsg' is a valid message, the incoming TKEY message
- * 'server' is the server name
- * 'context' is the input context handle
- * 'outkey' receives the established key, if non-NULL;
- * if non-NULL must point to NULL
- * 'ring' is the keyring in which to establish the key,
- * or NULL
- * 'win2k' when true says to turn on some hacks to work
- * with the non-standard GSS-TSIG of Windows 2000
- *
- * Returns:
- * ISC_R_SUCCESS context was successfully established
- * ISC_R_NOTFOUND couldn't find a needed part of the query
- * or response
- * DNS_R_CONTINUE additional context negotiation is required;
- * send the new qmsg to the server
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_TKEY_H */
diff --git a/contrib/bind9/lib/dns/include/dns/tsec.h b/contrib/bind9/lib/dns/include/dns/tsec.h
deleted file mode 100644
index 4f31c3e2949d..000000000000
--- a/contrib/bind9/lib/dns/include/dns/tsec.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2009, 2010, 2012 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN 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.
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_TSEC_H */
diff --git a/contrib/bind9/lib/dns/include/dns/tsig.h b/contrib/bind9/lib/dns/include/dns/tsig.h
deleted file mode 100644
index 0422414d6edc..000000000000
--- a/contrib/bind9/lib/dns/include/dns/tsig.h
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: tsig.h,v 1.59 2011/01/11 23:47:13 tbox Exp $ */
-
-#ifndef DNS_TSIG_H
-#define DNS_TSIG_H 1
-
-/*! \file dns/tsig.h */
-
-#include <isc/lang.h>
-#include <isc/refcount.h>
-#include <isc/rwlock.h>
-#include <isc/stdio.h>
-#include <isc/stdtime.h>
-
-#include <dns/types.h>
-#include <dns/name.h>
-
-#include <dst/dst.h>
-
-/*
- * Algorithms.
- */
-LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacmd5_name;
-#define DNS_TSIG_HMACMD5_NAME dns_tsig_hmacmd5_name
-LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_gssapi_name;
-#define DNS_TSIG_GSSAPI_NAME dns_tsig_gssapi_name
-LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_gssapims_name;
-#define DNS_TSIG_GSSAPIMS_NAME dns_tsig_gssapims_name
-LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacsha1_name;
-#define DNS_TSIG_HMACSHA1_NAME dns_tsig_hmacsha1_name
-LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacsha224_name;
-#define DNS_TSIG_HMACSHA224_NAME dns_tsig_hmacsha224_name
-LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacsha256_name;
-#define DNS_TSIG_HMACSHA256_NAME dns_tsig_hmacsha256_name
-LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacsha384_name;
-#define DNS_TSIG_HMACSHA384_NAME dns_tsig_hmacsha384_name
-LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacsha512_name;
-#define DNS_TSIG_HMACSHA512_NAME dns_tsig_hmacsha512_name
-
-/*%
- * Default fudge value.
- */
-#define DNS_TSIG_FUDGE 300
-
-struct dns_tsig_keyring {
- dns_rbt_t *keys;
- unsigned int writecount;
- isc_rwlock_t lock;
- isc_mem_t *mctx;
- /*
- * LRU list of generated key along with a count of the keys on the
- * list and a maximum size.
- */
- unsigned int generated;
- unsigned int maxgenerated;
- ISC_LIST(dns_tsigkey_t) lru;
- unsigned int references;
-};
-
-struct dns_tsigkey {
- /* Unlocked */
- unsigned int magic; /*%< Magic number. */
- isc_mem_t *mctx;
- dst_key_t *key; /*%< Key */
- dns_name_t name; /*%< Key name */
- dns_name_t *algorithm; /*%< Algorithm name */
- dns_name_t *creator; /*%< name that created secret */
- isc_boolean_t generated; /*%< was this generated? */
- isc_stdtime_t inception; /*%< start of validity period */
- isc_stdtime_t expire; /*%< end of validity period */
- dns_tsig_keyring_t *ring; /*%< the enclosing keyring */
- isc_refcount_t refs; /*%< reference counter */
- ISC_LINK(dns_tsigkey_t) link;
-};
-
-#define dns_tsigkey_identity(tsigkey) \
- ((tsigkey) == NULL ? NULL : \
- (tsigkey)->generated ? ((tsigkey)->creator) : \
- (&((tsigkey)->name)))
-
-ISC_LANG_BEGINDECLS
-
-isc_result_t
-dns_tsigkey_create(dns_name_t *name, dns_name_t *algorithm,
- unsigned char *secret, int length, isc_boolean_t generated,
- dns_name_t *creator, isc_stdtime_t inception,
- isc_stdtime_t expire, isc_mem_t *mctx,
- dns_tsig_keyring_t *ring, dns_tsigkey_t **key);
-
-isc_result_t
-dns_tsigkey_createfromkey(dns_name_t *name, dns_name_t *algorithm,
- dst_key_t *dstkey, isc_boolean_t generated,
- dns_name_t *creator, isc_stdtime_t inception,
- isc_stdtime_t expire, isc_mem_t *mctx,
- dns_tsig_keyring_t *ring, dns_tsigkey_t **key);
-/*%<
- * Creates a tsig key structure and saves it in the keyring. If key is
- * not NULL, *key will contain a copy of the key. The keys validity
- * period is specified by (inception, expire), and will not expire if
- * inception == expire. If the key was generated, the creating identity,
- * if there is one, should be in the creator parameter. Specifying an
- * unimplemented algorithm will cause failure only if dstkey != NULL; this
- * allows a transient key with an invalid algorithm to exist long enough
- * to generate a BADKEY response.
- *
- * If dns_tsigkey_createfromkey is successful a new reference to 'dstkey'
- * will have been made.
- *
- * Requires:
- *\li 'name' is a valid dns_name_t
- *\li 'algorithm' is a valid dns_name_t
- *\li 'secret' is a valid pointer
- *\li 'length' is an integer >= 0
- *\li 'dstkey' is a valid dst key or NULL
- *\li 'creator' points to a valid dns_name_t or is NULL
- *\li 'mctx' is a valid memory context
- *\li 'ring' is a valid TSIG keyring or NULL
- *\li 'key' or '*key' must be NULL
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_EXISTS - a key with this name already exists
- *\li #ISC_R_NOTIMPLEMENTED - algorithm is not implemented
- *\li #ISC_R_NOMEMORY
- */
-
-void
-dns_tsigkey_attach(dns_tsigkey_t *source, dns_tsigkey_t **targetp);
-/*%<
- * Attach '*targetp' to 'source'.
- *
- * Requires:
- *\li 'key' is a valid TSIG key
- *
- * Ensures:
- *\li *targetp is attached to source.
- */
-
-void
-dns_tsigkey_detach(dns_tsigkey_t **keyp);
-/*%<
- * Detaches from the tsig key structure pointed to by '*key'.
- *
- * Requires:
- *\li 'keyp' is not NULL and '*keyp' is a valid TSIG key
- *
- * Ensures:
- *\li 'keyp' points to NULL
- */
-
-void
-dns_tsigkey_setdeleted(dns_tsigkey_t *key);
-/*%<
- * Prevents this key from being used again. It will be deleted when
- * no references exist.
- *
- * Requires:
- *\li 'key' is a valid TSIG key on a keyring
- */
-
-isc_result_t
-dns_tsig_sign(dns_message_t *msg);
-/*%<
- * Generates a TSIG record for this message
- *
- * Requires:
- *\li 'msg' is a valid message
- *\li 'msg->tsigkey' is a valid TSIG key
- *\li 'msg->tsig' is NULL
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMEMORY
- *\li #ISC_R_NOSPACE
- *\li #DNS_R_EXPECTEDTSIG
- * - this is a response & msg->querytsig is NULL
- */
-
-isc_result_t
-dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
- dns_tsig_keyring_t *ring1, dns_tsig_keyring_t *ring2);
-/*%<
- * Verifies the TSIG record in this message
- *
- * Requires:
- *\li 'source' is a valid buffer containing the unparsed message
- *\li 'msg' is a valid message
- *\li 'msg->tsigkey' is a valid TSIG key if this is a response
- *\li 'msg->tsig' is NULL
- *\li 'msg->querytsig' is not NULL if this is a response
- *\li 'ring1' and 'ring2' are each either a valid keyring or NULL
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMEMORY
- *\li #DNS_R_EXPECTEDTSIG - A TSIG was expected but not seen
- *\li #DNS_R_UNEXPECTEDTSIG - A TSIG was seen but not expected
- *\li #DNS_R_TSIGERRORSET - the TSIG verified but ->error was set
- * and this is a query
- *\li #DNS_R_CLOCKSKEW - the TSIG failed to verify because of
- * the time was out of the allowed range.
- *\li #DNS_R_TSIGVERIFYFAILURE - the TSIG failed to verify
- *\li #DNS_R_EXPECTEDRESPONSE - the message was set over TCP and
- * should have been a response,
- * but was not.
- */
-
-isc_result_t
-dns_tsigkey_find(dns_tsigkey_t **tsigkey, dns_name_t *name,
- dns_name_t *algorithm, dns_tsig_keyring_t *ring);
-/*%<
- * Returns the TSIG key corresponding to this name and (possibly)
- * algorithm. Also increments the key's reference counter.
- *
- * Requires:
- *\li 'tsigkey' is not NULL
- *\li '*tsigkey' is NULL
- *\li 'name' is a valid dns_name_t
- *\li 'algorithm' is a valid dns_name_t or NULL
- *\li 'ring' is a valid keyring
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOTFOUND
- */
-
-
-isc_result_t
-dns_tsigkeyring_create(isc_mem_t *mctx, dns_tsig_keyring_t **ringp);
-/*%<
- * Create an empty TSIG key ring.
- *
- * Requires:
- *\li 'mctx' is not NULL
- *\li 'ringp' is not NULL, and '*ringp' is NULL
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\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_detach(dns_tsig_keyring_t **ringp);
-
-isc_result_t
-dns_tsigkeyring_dumpanddetach(dns_tsig_keyring_t **ringp, FILE *fp);
-
-/*%<
- * Destroy a TSIG key ring.
- *
- * Requires:
- *\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/contrib/bind9/lib/dns/include/dns/ttl.h b/contrib/bind9/lib/dns/include/dns/ttl.h
deleted file mode 100644
index c2525183b7ba..000000000000
--- a/contrib/bind9/lib/dns/include/dns/ttl.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: ttl.h,v 1.19 2007/06/19 23:47:17 tbox Exp $ */
-
-#ifndef DNS_TTL_H
-#define DNS_TTL_H 1
-
-/*! \file dns/ttl.h */
-
-/***
- *** Imports
- ***/
-
-#include <isc/lang.h>
-#include <isc/types.h>
-
-ISC_LANG_BEGINDECLS
-
-/***
- *** Functions
- ***/
-
-isc_result_t
-dns_ttl_totext(isc_uint32_t src, isc_boolean_t verbose,
- isc_buffer_t *target);
-/*%<
- * Output a TTL or other time interval in a human-readable form.
- * The time interval is given as a count of seconds in 'src'.
- * The text representation is appended to 'target'.
- *
- * If 'verbose' is ISC_FALSE, use the terse BIND 8 style, like "1w2d3h4m5s".
- *
- * If 'verbose' is ISC_TRUE, use a verbose style like the SOA comments
- * in "dig", like "1 week 2 days 3 hours 4 minutes 5 seconds".
- *
- * Returns:
- * \li ISC_R_SUCCESS
- * \li ISC_R_NOSPACE
- */
-
-isc_result_t
-dns_counter_fromtext(isc_textregion_t *source, isc_uint32_t *ttl);
-/*%<
- * Converts a counter from either a plain number or a BIND 8 style value.
- *
- * Returns:
- *\li ISC_R_SUCCESS
- *\li DNS_R_SYNTAX
- */
-
-isc_result_t
-dns_ttl_fromtext(isc_textregion_t *source, isc_uint32_t *ttl);
-/*%<
- * Converts a ttl from either a plain number or a BIND 8 style value.
- *
- * Returns:
- *\li ISC_R_SUCCESS
- *\li DNS_R_BADTTL
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_TTL_H */
diff --git a/contrib/bind9/lib/dns/include/dns/types.h b/contrib/bind9/lib/dns/include/dns/types.h
deleted file mode 100644
index 76167c2f88da..000000000000
--- a/contrib/bind9/lib/dns/include/dns/types.h
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-#ifndef DNS_TYPES_H
-#define DNS_TYPES_H 1
-
-/*! \file dns/types.h
- * \brief
- * Including this file gives you type declarations suitable for use in
- * .h files, which lets us avoid circular type reference problems.
- * \brief
- * To actually use a type or get declarations of its methods, you must
- * include the appropriate .h file too.
- */
-
-#include <isc/types.h>
-
-typedef struct dns_acache dns_acache_t;
-typedef struct dns_acacheentry dns_acacheentry_t;
-typedef struct dns_acachestats dns_acachestats_t;
-typedef struct dns_acl dns_acl_t;
-typedef struct dns_aclelement dns_aclelement_t;
-typedef struct dns_aclenv dns_aclenv_t;
-typedef struct dns_adb dns_adb_t;
-typedef struct dns_adbaddrinfo dns_adbaddrinfo_t;
-typedef ISC_LIST(dns_adbaddrinfo_t) dns_adbaddrinfolist_t;
-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;
-typedef struct dns_db dns_db_t;
-typedef struct dns_dbimplementation dns_dbimplementation_t;
-typedef struct dns_dbiterator dns_dbiterator_t;
-typedef void dns_dbload_t;
-typedef void dns_dbnode_t;
-typedef struct dns_dbtable dns_dbtable_t;
-typedef void dns_dbversion_t;
-typedef struct dns_dlzimplementation dns_dlzimplementation_t;
-typedef struct dns_dlzdb dns_dlzdb_t;
-typedef struct dns_sdlzimplementation dns_sdlzimplementation_t;
-typedef struct dns_decompress dns_decompress_t;
-typedef struct dns_dispatch dns_dispatch_t;
-typedef struct dns_dispatchevent dns_dispatchevent_t;
-typedef struct dns_dispatchlist dns_dispatchlist_t;
-typedef struct dns_dispatchset dns_dispatchset_t;
-typedef struct dns_dispatchmgr dns_dispatchmgr_t;
-typedef struct dns_dispentry dns_dispentry_t;
-typedef struct dns_dns64 dns_dns64_t;
-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_ednsopt dns_ednsopt_t;
-typedef struct dns_fetch dns_fetch_t;
-typedef struct dns_fixedname dns_fixedname_t;
-typedef struct dns_forwarders dns_forwarders_t;
-typedef struct dns_fwdtable dns_fwdtable_t;
-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;
-typedef struct dns_loadmgr dns_loadmgr_t;
-typedef struct dns_masterrawheader dns_masterrawheader_t;
-typedef struct dns_message dns_message_t;
-typedef isc_uint16_t dns_messageid_t;
-typedef isc_region_t dns_label_t;
-typedef struct dns_lookup dns_lookup_t;
-typedef struct dns_name dns_name_t;
-typedef ISC_LIST(dns_name_t) dns_namelist_t;
-typedef isc_uint16_t dns_opcode_t;
-typedef unsigned char dns_offsets_t[128];
-typedef struct dns_order dns_order_t;
-typedef struct dns_peer dns_peer_t;
-typedef struct dns_peerlist dns_peerlist_t;
-typedef struct dns_portlist dns_portlist_t;
-typedef struct dns_rbt dns_rbt_t;
-typedef isc_uint16_t dns_rcode_t;
-typedef struct dns_rdata dns_rdata_t;
-typedef struct dns_rdatacallbacks dns_rdatacallbacks_t;
-typedef isc_uint16_t dns_rdataclass_t;
-typedef struct dns_rdatalist dns_rdatalist_t;
-typedef struct dns_rdataset dns_rdataset_t;
-typedef ISC_LIST(dns_rdataset_t) dns_rdatasetlist_t;
-typedef struct dns_rdatasetiter dns_rdatasetiter_t;
-typedef isc_uint16_t dns_rdatatype_t;
-typedef struct dns_request dns_request_t;
-typedef struct dns_requestmgr dns_requestmgr_t;
-typedef struct dns_resolver dns_resolver_t;
-typedef struct dns_sdbimplementation dns_sdbimplementation_t;
-typedef isc_uint8_t dns_secalg_t;
-typedef isc_uint8_t dns_secproto_t;
-typedef struct dns_signature dns_signature_t;
-typedef struct dns_ssurule dns_ssurule_t;
-typedef struct dns_ssutable dns_ssutable_t;
-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;
-typedef struct dns_validator dns_validator_t;
-typedef struct dns_view dns_view_t;
-typedef ISC_LIST(dns_view_t) dns_viewlist_t;
-typedef struct dns_zone dns_zone_t;
-typedef ISC_LIST(dns_zone_t) dns_zonelist_t;
-typedef struct dns_zonemgr dns_zonemgr_t;
-typedef struct dns_zt dns_zt_t;
-
-/*
- * If we are not using GSSAPI, define the types we use as opaque types here.
- */
-#ifndef GSSAPI
-typedef struct not_defined_gss_cred_id *gss_cred_id_t;
-typedef struct not_defined_gss_ctx *gss_ctx_id_t;
-#endif
-typedef struct dst_gssapi_signverifyctx dst_gssapi_signverifyctx_t;
-
-typedef enum {
- dns_hash_sha1 = 1
-} dns_hash_t;
-
-typedef enum {
- dns_fwdpolicy_none = 0,
- dns_fwdpolicy_first = 1,
- dns_fwdpolicy_only = 2
-} dns_fwdpolicy_t;
-
-typedef enum {
- dns_namereln_none = 0,
- dns_namereln_contains = 1,
- dns_namereln_subdomain = 2,
- dns_namereln_equal = 3,
- dns_namereln_commonancestor = 4
-} dns_namereln_t;
-
-typedef enum {
- dns_one_answer, dns_many_answers
-} dns_transfer_format_t;
-
-typedef enum {
- dns_dbtype_zone = 0, dns_dbtype_cache = 1, dns_dbtype_stub = 3
-} dns_dbtype_t;
-
-typedef enum {
- dns_notifytype_no = 0,
- dns_notifytype_yes = 1,
- dns_notifytype_explicit = 2,
- dns_notifytype_masteronly = 3
-} dns_notifytype_t;
-
-typedef enum {
- dns_dialuptype_no = 0,
- dns_dialuptype_yes = 1,
- dns_dialuptype_notify = 2,
- dns_dialuptype_notifypassive = 3,
- dns_dialuptype_refresh = 4,
- dns_dialuptype_passive = 5
-} dns_dialuptype_t;
-
-typedef enum {
- dns_masterformat_none = 0,
- dns_masterformat_text = 1,
- 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.
- */
-#include <dns/enumtype.h> /* Provides dns_rdatatype_t. */
-#include <dns/enumclass.h> /* Provides dns_rdataclass_t. */
-
-/*%
- * rcodes.
- */
-enum {
- /*
- * Standard rcodes.
- */
- dns_rcode_noerror = 0,
-#define dns_rcode_noerror ((dns_rcode_t)dns_rcode_noerror)
- dns_rcode_formerr = 1,
-#define dns_rcode_formerr ((dns_rcode_t)dns_rcode_formerr)
- dns_rcode_servfail = 2,
-#define dns_rcode_servfail ((dns_rcode_t)dns_rcode_servfail)
- dns_rcode_nxdomain = 3,
-#define dns_rcode_nxdomain ((dns_rcode_t)dns_rcode_nxdomain)
- dns_rcode_notimp = 4,
-#define dns_rcode_notimp ((dns_rcode_t)dns_rcode_notimp)
- dns_rcode_refused = 5,
-#define dns_rcode_refused ((dns_rcode_t)dns_rcode_refused)
- dns_rcode_yxdomain = 6,
-#define dns_rcode_yxdomain ((dns_rcode_t)dns_rcode_yxdomain)
- dns_rcode_yxrrset = 7,
-#define dns_rcode_yxrrset ((dns_rcode_t)dns_rcode_yxrrset)
- dns_rcode_nxrrset = 8,
-#define dns_rcode_nxrrset ((dns_rcode_t)dns_rcode_nxrrset)
- dns_rcode_notauth = 9,
-#define dns_rcode_notauth ((dns_rcode_t)dns_rcode_notauth)
- dns_rcode_notzone = 10,
-#define dns_rcode_notzone ((dns_rcode_t)dns_rcode_notzone)
- /*
- * Extended rcodes.
- */
- dns_rcode_badvers = 16
-#define dns_rcode_badvers ((dns_rcode_t)dns_rcode_badvers)
-};
-
-/*%
- * TSIG errors.
- */
-enum {
- dns_tsigerror_badsig = 16,
- dns_tsigerror_badkey = 17,
- dns_tsigerror_badtime = 18,
- dns_tsigerror_badmode = 19,
- dns_tsigerror_badname = 20,
- dns_tsigerror_badalg = 21,
- dns_tsigerror_badtrunc = 22
-};
-
-/*%
- * Opcodes.
- */
-enum {
- dns_opcode_query = 0,
-#define dns_opcode_query ((dns_opcode_t)dns_opcode_query)
- dns_opcode_iquery = 1,
-#define dns_opcode_iquery ((dns_opcode_t)dns_opcode_iquery)
- dns_opcode_status = 2,
-#define dns_opcode_status ((dns_opcode_t)dns_opcode_status)
- dns_opcode_notify = 4,
-#define dns_opcode_notify ((dns_opcode_t)dns_opcode_notify)
- dns_opcode_update = 5 /* dynamic update */
-#define dns_opcode_update ((dns_opcode_t)dns_opcode_update)
-};
-
-/*%
- * Trust levels. Must be kept in sync with trustnames[] in masterdump.c.
- */
-enum {
- /* Sentinel value; no data should have this trust level. */
- dns_trust_none = 0,
-#define dns_trust_none ((dns_trust_t)dns_trust_none)
-
- /*%
- * Subject to DNSSEC validation but has not yet been validated
- * dns_trust_pending_additional (from the additional section).
- */
- dns_trust_pending_additional = 1,
-#define dns_trust_pending_additional \
- ((dns_trust_t)dns_trust_pending_additional)
-
- dns_trust_pending_answer = 2,
-#define dns_trust_pending_answer ((dns_trust_t)dns_trust_pending_answer)
-
- /*% Received in the additional section of a response. */
- dns_trust_additional = 3,
-#define dns_trust_additional ((dns_trust_t)dns_trust_additional)
-
- /* Received in a referral response. */
- dns_trust_glue = 4,
-#define dns_trust_glue ((dns_trust_t)dns_trust_glue)
-
- /* Answer from a non-authoritative server */
- dns_trust_answer = 5,
-#define dns_trust_answer ((dns_trust_t)dns_trust_answer)
-
- /* Received in the authority section as part of an
- authoritative response */
- dns_trust_authauthority = 6,
-#define dns_trust_authauthority ((dns_trust_t)dns_trust_authauthority)
-
- /* Answer from an authoritative server */
- dns_trust_authanswer = 7,
-#define dns_trust_authanswer ((dns_trust_t)dns_trust_authanswer)
-
- /* Successfully DNSSEC validated */
- dns_trust_secure = 8,
-#define dns_trust_secure ((dns_trust_t)dns_trust_secure)
-
- /* This server is authoritative */
- dns_trust_ultimate = 9
-#define dns_trust_ultimate ((dns_trust_t)dns_trust_ultimate)
-};
-
-#define DNS_TRUST_PENDING(x) ((x) == dns_trust_pending_answer || \
- (x) == dns_trust_pending_additional)
-#define DNS_TRUST_ADDITIONAL(x) ((x) == dns_trust_additional || \
- (x) == dns_trust_pending_additional)
-#define DNS_TRUST_GLUE(x) ((x) == dns_trust_glue)
-#define DNS_TRUST_ANSWER(x) ((x) == dns_trust_answer)
-
-
-/*%
- * Name checking severities.
- */
-typedef enum {
- dns_severity_ignore,
- dns_severity_warn,
- dns_severity_fail
-} dns_severity_t;
-
-/*%
- * DNS Serial Number Update Method.
- *
- * \li _increment: Add one to the current serial, skipping 0.
- * \li _unixtime: Set to the seconds since 00:00 Jan 1, 1970,
- * if possible.
- * \li _yyyymmvv: Set to Year, Month, Version, if possible.
- * (Not yet implemented)
- */
-typedef enum {
- dns_updatemethod_increment = 0,
- dns_updatemethod_unixtime
-} dns_updatemethod_t;
-
-/*
- * Functions.
- */
-typedef void
-(*dns_dumpdonefunc_t)(void *, isc_result_t);
-
-typedef void
-(*dns_loaddonefunc_t)(void *, isc_result_t);
-
-typedef void
-(*dns_rawdatafunc_t)(dns_zone_t *, dns_masterrawheader_t *);
-
-typedef isc_result_t
-(*dns_addrdatasetfunc_t)(void *, dns_name_t *, dns_rdataset_t *);
-
-typedef isc_result_t
-(*dns_additionaldatafunc_t)(void *, dns_name_t *, dns_rdatatype_t);
-
-typedef isc_result_t
-(*dns_digestfunc_t)(void *, isc_region_t *);
-
-typedef void
-(*dns_xfrindone_t)(dns_zone_t *, isc_result_t);
-
-typedef void
-(*dns_updatecallback_t)(void *, isc_result_t, dns_message_t *);
-
-typedef int
-(*dns_rdatasetorderfunc_t)(const dns_rdata_t *, const void *);
-
-typedef isc_boolean_t
-(*dns_checkmxfunc_t)(dns_zone_t *, dns_name_t *, dns_name_t *);
-
-typedef isc_boolean_t
-(*dns_checksrvfunc_t)(dns_zone_t *, dns_name_t *, dns_name_t *);
-
-typedef isc_boolean_t
-(*dns_checknsfunc_t)(dns_zone_t *, dns_name_t *, dns_name_t *,
- dns_rdataset_t *, dns_rdataset_t *);
-
-typedef isc_boolean_t
-(*dns_isselffunc_t)(dns_view_t *, dns_tsigkey_t *, isc_sockaddr_t *,
- isc_sockaddr_t *, dns_rdataclass_t, void *);
-
-typedef void
-(*dns_nseclog_t)(void *val, int , const char *, ...);
-
-#endif /* DNS_TYPES_H */
diff --git a/contrib/bind9/lib/dns/include/dns/update.h b/contrib/bind9/lib/dns/include/dns/update.h
deleted file mode 100644
index 2d2c491f38a3..000000000000
--- a/contrib/bind9/lib/dns/include/dns/update.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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: update.h,v 1.5 2011/08/30 23:46:53 tbox Exp $ */
-
-#ifndef DNS_UPDATE_H
-#define DNS_UPDATE_H 1
-
-/*! \file dns/update.h */
-
-/***
- *** Imports
- ***/
-
-#include <isc/lang.h>
-
-#include <dns/types.h>
-#include <dns/diff.h>
-
-typedef struct {
- void (*func)(void *arg, dns_zone_t *zone, int level,
- const char *message);
- void *arg;
-} dns_update_log_t;
-
-ISC_LANG_BEGINDECLS
-
-/***
- *** Functions
- ***/
-
-isc_uint32_t
-dns_update_soaserial(isc_uint32_t serial, dns_updatemethod_t method);
-/*%<
- * Return the next serial number after 'serial', depending on the
- * update method 'method':
- *
- *\li * dns_updatemethod_increment increments the serial number by one
- *\li * dns_updatemethod_unixtime sets the serial number to the current
- * time (seconds since UNIX epoch) if possible, or increments by one
- * if not.
- */
-
-isc_result_t
-dns_update_signatures(dns_update_log_t *log, 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_LANG_ENDDECLS
-
-#endif /* DNS_UPDATE_H */
diff --git a/contrib/bind9/lib/dns/include/dns/validator.h b/contrib/bind9/lib/dns/include/dns/validator.h
deleted file mode 100644
index b3cfe9992fd9..000000000000
--- a/contrib/bind9/lib/dns/include/dns/validator.h
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * Copyright (C) 2004-2010, 2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2000-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: validator.h,v 1.46 2010/02/25 05:08:01 tbox Exp $ */
-
-#ifndef DNS_VALIDATOR_H
-#define DNS_VALIDATOR_H 1
-
-/*****
- ***** Module Info
- *****/
-
-/*! \file dns/validator.h
- *
- * \brief
- * DNS Validator
- * This is the BIND 9 validator, the module responsible for validating the
- * rdatasets and negative responses (messages). It makes use of zones in
- * the view and may fetch RRset to complete trust chains. It implements
- * DNSSEC as specified in RFC 4033, 4034 and 4035.
- *
- * It can also optionally implement ISC's DNSSEC look-aside validation.
- *
- * Correct operation is critical to preventing spoofed answers from secure
- * zones being accepted.
- *
- * MP:
- *\li The module ensures appropriate synchronization of data structures it
- * creates and manipulates.
- *
- * Reliability:
- *\li No anticipated impact.
- *
- * Resources:
- *\li TBS
- *
- * Security:
- *\li No anticipated impact.
- *
- * Standards:
- *\li RFCs: 1034, 1035, 2181, 4033, 4034, 4035.
- */
-
-#include <isc/lang.h>
-#include <isc/event.h>
-#include <isc/mutex.h>
-
-#include <dns/fixedname.h>
-#include <dns/types.h>
-#include <dns/rdataset.h>
-#include <dns/rdatastruct.h> /* for dns_rdata_rrsig_t */
-
-#include <dst/dst.h>
-
-/*%
- * A dns_validatorevent_t is sent when a 'validation' completes.
- * \brief
- * 'name', 'rdataset', 'sigrdataset', and 'message' are the values that were
- * supplied when dns_validator_create() was called. They are returned to the
- * caller so that they may be freed.
- *
- * If the RESULT is ISC_R_SUCCESS and the answer is secure then
- * proofs[] will contain the names of the NSEC records that hold the
- * various proofs. Note the same name may appear multiple times.
- */
-typedef struct dns_validatorevent {
- ISC_EVENT_COMMON(struct dns_validatorevent);
- dns_validator_t * validator;
- isc_result_t result;
- /*
- * Name and type of the response to be validated.
- */
- dns_name_t * name;
- dns_rdatatype_t type;
- /*
- * Rdata and RRSIG (if any) for positive responses.
- */
- dns_rdataset_t * rdataset;
- dns_rdataset_t * sigrdataset;
- /*
- * The full response. Required for negative responses.
- * Also required for positive wildcard responses.
- */
- dns_message_t * message;
- /*
- * Proofs to be cached.
- */
- dns_name_t * proofs[4];
- /*
- * Optout proof seen.
- */
- isc_boolean_t optout;
- /*
- * Answer is secure.
- */
- isc_boolean_t secure;
-} dns_validatorevent_t;
-
-#define DNS_VALIDATOR_NOQNAMEPROOF 0
-#define DNS_VALIDATOR_NODATAPROOF 1
-#define DNS_VALIDATOR_NOWILDCARDPROOF 2
-#define DNS_VALIDATOR_CLOSESTENCLOSER 3
-
-/*%
- * A validator object represents a validation in progress.
- * \brief
- * Clients are strongly discouraged from using this type directly, with
- * the exception of the 'link' field, which may be used directly for
- * whatever purpose the client desires.
- */
-struct dns_validator {
- /* Unlocked. */
- unsigned int magic;
- isc_mutex_t lock;
- dns_view_t * view;
- /* Locked by lock. */
- unsigned int options;
- unsigned int attributes;
- dns_validatorevent_t * event;
- dns_fetch_t * fetch;
- dns_validator_t * subvalidator;
- dns_validator_t * parent;
- dns_keytable_t * keytable;
- dns_keynode_t * keynode;
- dst_key_t * key;
- dns_rdata_rrsig_t * siginfo;
- isc_task_t * task;
- isc_taskaction_t action;
- void * arg;
- unsigned int labels;
- dns_rdataset_t * currentset;
- isc_boolean_t seensig;
- dns_rdataset_t * keyset;
- dns_rdataset_t * dsset;
- dns_rdataset_t * soaset;
- dns_rdataset_t * nsecset;
- dns_rdataset_t * nsec3set;
- dns_name_t * soaname;
- dns_rdataset_t frdataset;
- dns_rdataset_t fsigrdataset;
- dns_fixedname_t fname;
- dns_fixedname_t wild;
- dns_fixedname_t nearest;
- dns_fixedname_t closest;
- ISC_LINK(dns_validator_t) link;
- dns_rdataset_t dlv;
- dns_fixedname_t dlvsep;
- isc_boolean_t havedlvsep;
- isc_boolean_t mustbesecure;
- unsigned int dlvlabels;
- unsigned int depth;
- unsigned int authcount;
- unsigned int authfail;
-};
-
-/*%
- * dns_validator_create() options.
- */
-#define DNS_VALIDATOR_DLV 1U
-#define DNS_VALIDATOR_DEFER 2U
-
-ISC_LANG_BEGINDECLS
-
-isc_result_t
-dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
- dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
- dns_message_t *message, unsigned int options,
- isc_task_t *task, isc_taskaction_t action, void *arg,
- dns_validator_t **validatorp);
-/*%<
- * Start a DNSSEC validation.
- *
- * This validates a response to the question given by
- * 'name' and 'type'.
- *
- * To validate a positive response, the response data is
- * given by 'rdataset' and 'sigrdataset'. If 'sigrdataset'
- * is NULL, the data is presumed insecure and an attempt
- * is made to prove its insecurity by finding the appropriate
- * null key.
- *
- * The complete response message may be given in 'message',
- * to make available any authority section NSECs that may be
- * needed for validation of a response resulting from a
- * wildcard expansion (though no such wildcard validation
- * is implemented yet). If the complete response message
- * is not available, 'message' is NULL.
- *
- * To validate a negative response, the complete negative response
- * message is given in 'message'. The 'rdataset', and
- * 'sigrdataset' arguments must be NULL, but the 'name' and 'type'
- * arguments must be provided.
- *
- * The validation is performed in the context of 'view'.
- *
- * When the validation finishes, a dns_validatorevent_t with
- * the given 'action' and 'arg' are sent to 'task'.
- * Its 'result' field will be ISC_R_SUCCESS iff the
- * response was successfully proven to be either secure or
- * part of a known insecure domain.
- *
- * options:
- * If DNS_VALIDATOR_DLV is set the caller knows there is not a
- * trusted key and the validator should immediately attempt to validate
- * the answer by looking for an appropriate DLV RRset.
- */
-
-void
-dns_validator_send(dns_validator_t *validator);
-/*%<
- * Send a deferred validation request
- *
- * Requires:
- * 'validator' to points to a valid DNSSEC validator.
- */
-
-void
-dns_validator_cancel(dns_validator_t *validator);
-/*%<
- * Cancel a DNSSEC validation in progress.
- *
- * Requires:
- *\li 'validator' points to a valid DNSSEC validator, which
- * may or may not already have completed.
- *
- * Ensures:
- *\li It the validator has not already sent its completion
- * event, it will send it with result code ISC_R_CANCELED.
- */
-
-void
-dns_validator_destroy(dns_validator_t **validatorp);
-/*%<
- * Destroy a DNSSEC validator.
- *
- * Requires:
- *\li '*validatorp' points to a valid DNSSEC validator.
- * \li The validator must have completed and sent its completion
- * event.
- *
- * Ensures:
- *\li All resources used by the validator are freed.
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_VALIDATOR_H */
diff --git a/contrib/bind9/lib/dns/include/dns/version.h b/contrib/bind9/lib/dns/include/dns/version.h
deleted file mode 100644
index 2a33dcf286ce..000000000000
--- a/contrib/bind9/lib/dns/include/dns/version.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: version.h,v 1.9 2007/06/19 23:47:17 tbox Exp $ */
-
-/*! \file dns/version.h */
-
-#include <isc/platform.h>
-
-LIBDNS_EXTERNAL_DATA extern const char dns_version[];
-
-LIBDNS_EXTERNAL_DATA extern const unsigned int dns_libinterface;
-LIBDNS_EXTERNAL_DATA extern const unsigned int dns_librevision;
-LIBDNS_EXTERNAL_DATA extern const unsigned int dns_libage;
diff --git a/contrib/bind9/lib/dns/include/dns/view.h b/contrib/bind9/lib/dns/include/dns/view.h
deleted file mode 100644
index d0c1931d27be..000000000000
--- a/contrib/bind9/lib/dns/include/dns/view.h
+++ /dev/null
@@ -1,1114 +0,0 @@
-/*
- * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-#ifndef DNS_VIEW_H
-#define DNS_VIEW_H 1
-
-/*****
- ***** Module Info
- *****/
-
-/*! \file dns/view.h
- * \brief
- * DNS View
- *
- * A "view" is a DNS namespace, together with an optional resolver and a
- * forwarding policy. A "DNS namespace" is a (possibly empty) set of
- * authoritative zones together with an optional cache and optional
- * "hints" information.
- *
- * Views start out "unfrozen". In this state, core attributes like
- * the cache, set of zones, and forwarding policy may be set. While
- * "unfrozen", the caller (e.g. nameserver configuration loading
- * code), must ensure exclusive access to the view. When the view is
- * "frozen", the core attributes become immutable, and the view module
- * will ensure synchronization. Freezing allows the view's core attributes
- * to be accessed without locking.
- *
- * MP:
- *\li Before the view is frozen, the caller must ensure synchronization.
- *
- *\li After the view is frozen, the module guarantees appropriate
- * synchronization of any data structures it creates and manipulates.
- *
- * Reliability:
- *\li No anticipated impact.
- *
- * Resources:
- *\li TBS
- *
- * Security:
- *\li No anticipated impact.
- *
- * Standards:
- *\li None.
- */
-
-#include <stdio.h>
-
-#include <isc/lang.h>
-#include <isc/magic.h>
-#include <isc/event.h>
-#include <isc/mutex.h>
-#include <isc/net.h>
-#include <isc/refcount.h>
-#include <isc/rwlock.h>
-#include <isc/stdtime.h>
-
-#include <dns/acl.h>
-#include <dns/fixedname.h>
-#include <dns/rdatastruct.h>
-#include <dns/rpz.h>
-#include <dns/types.h>
-#include <dns/zt.h>
-
-ISC_LANG_BEGINDECLS
-
-struct dns_view {
- /* Unlocked. */
- unsigned int magic;
- isc_mem_t * mctx;
- dns_rdataclass_t rdclass;
- char * name;
- dns_zt_t * zonetable;
- dns_dlzdb_t * dlzdatabase;
- dns_resolver_t * resolver;
- dns_adb_t * adb;
- dns_requestmgr_t * requestmgr;
- dns_acache_t * acache;
- dns_cache_t * cache;
- dns_db_t * cachedb;
- dns_db_t * hints;
-
- /*
- * 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;
- isc_event_t resevent;
- isc_event_t adbevent;
- isc_event_t reqevent;
- isc_stats_t * resstats;
- dns_stats_t * resquerystats;
- isc_boolean_t cacheshared;
-
- /* Configurable data. */
- dns_tsig_keyring_t * statickeys;
- dns_tsig_keyring_t * dynamickeys;
- dns_peerlist_t * peers;
- dns_order_t * order;
- dns_fwdtable_t * fwdtable;
- isc_boolean_t recursion;
- isc_boolean_t auth_nxdomain;
- isc_boolean_t additionalfromcache;
- isc_boolean_t additionalfromauth;
- isc_boolean_t minimalresponses;
- isc_boolean_t enablednssec;
- isc_boolean_t enablevalidation;
- isc_boolean_t acceptexpired;
- dns_transfer_format_t transfer_format;
- dns_acl_t * cacheacl;
- dns_acl_t * cacheonacl;
- dns_acl_t * queryacl;
- dns_acl_t * queryonacl;
- dns_acl_t * recursionacl;
- dns_acl_t * recursiononacl;
- dns_acl_t * sortlist;
- dns_acl_t * notifyacl;
- 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 provideixfr;
- isc_boolean_t requestnsid;
- dns_ttl_t maxcachettl;
- dns_ttl_t maxncachettl;
- in_port_t dstport;
- dns_aclenv_t aclenv;
- dns_rdatatype_t preferred_glue;
- isc_boolean_t flush;
- dns_namelist_t * delonly;
- isc_boolean_t rootdelonly;
- dns_namelist_t * rootexclude;
- isc_boolean_t checknames;
- dns_name_t * dlv;
- dns_fixedname_t dlv_fixed;
- isc_uint16_t maxudp;
- unsigned int maxbits;
- dns_v4_aaaa_t v4_aaaa;
- dns_acl_t * v4_aaaa_acl;
- dns_dns64list_t dns64;
- unsigned int dns64cnt;
- ISC_LIST(dns_rpz_zone_t) rpz_zones;
- isc_boolean_t rpz_recursive_only;
- isc_boolean_t rpz_break_dnssec;
- unsigned int rpz_min_ns_labels;
-
- /*
- * Configurable data for server use only,
- * locked by server configuration lock.
- */
- dns_acl_t * matchclients;
- dns_acl_t * matchdestinations;
- isc_boolean_t matchrecursiveonly;
-
- /* Locked by themselves. */
- isc_refcount_t references;
-
- /* Locked by lock. */
- unsigned int weakrefs;
- unsigned int attributes;
- /* Under owner's locking control. */
- ISC_LINK(struct dns_view) link;
- dns_viewlist_t * viewlist;
-
- dns_zone_t * managed_keys;
- dns_zone_t * redirect;
-
-#ifdef BIND9
- /* File in which to store configuration for newly added zones */
- char * new_zone_file;
-
- void * new_zone_config;
- void (*cfg_destroy)(void **);
-#endif
-};
-
-#define DNS_VIEW_MAGIC ISC_MAGIC('V','i','e','w')
-#define DNS_VIEW_VALID(view) ISC_MAGIC_VALID(view, DNS_VIEW_MAGIC)
-
-#define DNS_VIEWATTR_RESSHUTDOWN 0x01
-#define DNS_VIEWATTR_ADBSHUTDOWN 0x02
-#define DNS_VIEWATTR_REQSHUTDOWN 0x04
-
-isc_result_t
-dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
- const char *name, dns_view_t **viewp);
-/*%<
- * Create a view.
- *
- * Notes:
- *
- *\li The newly created view has no cache, no resolver, and an empty
- * zone table. The view is not frozen.
- *
- * Requires:
- *
- *\li 'mctx' is a valid memory context.
- *
- *\li 'rdclass' is a valid class.
- *
- *\li 'name' is a valid C string.
- *
- *\li viewp != NULL && *viewp == NULL
- *
- * Returns:
- *
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMEMORY
- *
- *\li Other errors are possible.
- */
-
-void
-dns_view_attach(dns_view_t *source, dns_view_t **targetp);
-/*%<
- * Attach '*targetp' to 'source'.
- *
- * Requires:
- *
- *\li 'source' is a valid, frozen view.
- *
- *\li 'targetp' points to a NULL dns_view_t *.
- *
- * Ensures:
- *
- *\li *targetp is attached to source.
- *
- *\li While *targetp is attached, the view will not shut down.
- */
-
-void
-dns_view_detach(dns_view_t **viewp);
-/*%<
- * Detach '*viewp' from its view.
- *
- * Requires:
- *
- *\li 'viewp' points to a valid dns_view_t *
- *
- * Ensures:
- *
- *\li *viewp is NULL.
- */
-
-void
-dns_view_flushanddetach(dns_view_t **viewp);
-/*%<
- * Detach '*viewp' from its view. If this was the last reference
- * uncommitted changed in zones will be flushed to disk.
- *
- * Requires:
- *
- *\li 'viewp' points to a valid dns_view_t *
- *
- * Ensures:
- *
- *\li *viewp is NULL.
- */
-
-void
-dns_view_weakattach(dns_view_t *source, dns_view_t **targetp);
-/*%<
- * Weakly attach '*targetp' to 'source'.
- *
- * Requires:
- *
- *\li 'source' is a valid, frozen view.
- *
- *\li 'targetp' points to a NULL dns_view_t *.
- *
- * Ensures:
- *
- *\li *targetp is attached to source.
- *
- * \li While *targetp is attached, the view will not be freed.
- */
-
-void
-dns_view_weakdetach(dns_view_t **targetp);
-/*%<
- * Detach '*viewp' from its view.
- *
- * Requires:
- *
- *\li 'viewp' points to a valid dns_view_t *.
- *
- * Ensures:
- *
- *\li *viewp is NULL.
- */
-
-isc_result_t
-dns_view_createresolver(dns_view_t *view,
- isc_taskmgr_t *taskmgr,
- unsigned int ntasks, unsigned int ndisp,
- isc_socketmgr_t *socketmgr,
- isc_timermgr_t *timermgr,
- unsigned int options,
- dns_dispatchmgr_t *dispatchmgr,
- dns_dispatch_t *dispatchv4,
- dns_dispatch_t *dispatchv6);
-/*%<
- * Create a resolver and address database for the view.
- *
- * Requires:
- *
- *\li 'view' is a valid, unfrozen view.
- *
- *\li 'view' does not have a resolver already.
- *
- *\li The requirements of dns_resolver_create() apply to 'taskmgr',
- * 'ntasks', 'socketmgr', 'timermgr', 'options', 'dispatchv4', and
- * 'dispatchv6'.
- *
- * Returns:
- *
- *\li #ISC_R_SUCCESS
- *
- *\li Any error that dns_resolver_create() can return.
- */
-
-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. 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:
- *
- *\li 'view' is a valid, unfrozen view.
- *
- *\li 'cache' is a valid cache.
- *
- * Ensures:
- *
- * \li The cache of 'view' is 'cached.
- *
- *\li If this is not the first call to dns_view_setcache() for this
- * view, then previously set cache is detached.
- */
-
-void
-dns_view_sethints(dns_view_t *view, dns_db_t *hints);
-/*%<
- * Set the view's hints database.
- *
- * Requires:
- *
- *\li 'view' is a valid, unfrozen view, whose hints database has not been
- * set.
- *
- *\li 'hints' is a valid zone database.
- *
- * Ensures:
- *
- * \li The hints database of 'view' is '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
- *
- * Requires:
- *
- * \li 'view' is a valid, unfrozen view, whose static TSIG keyring has not
- * been set.
- *
- *\li 'ring' is a valid TSIG keyring
- *
- * Ensures:
- *
- *\li The static TSIG keyring of 'view' is '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
- * which outgoing queries are sent. The default is 53,
- * the standard DNS port.
- *
- * Requires:
- *
- *\li 'view' is a valid view.
- *
- *\li 'dstport' is a valid TCP/UDP port number.
- *
- * Ensures:
- *\li External name servers will be assumed to be listening
- * on 'dstport'. For servers whose address has already
- * obtained obtained at the time of the call, the view may
- * continue to use the previously set port until the address
- * times out from the view's address database.
- */
-
-
-isc_result_t
-dns_view_addzone(dns_view_t *view, dns_zone_t *zone);
-/*%<
- * Add zone 'zone' to 'view'.
- *
- * Requires:
- *
- *\li 'view' is a valid, unfrozen view.
- *
- *\li 'zone' is a valid zone.
- */
-
-void
-dns_view_freeze(dns_view_t *view);
-/*%<
- * Freeze view. No changes can be made to view configuration while frozen.
- *
- * Requires:
- *
- *\li 'view' is a valid, unfrozen view.
- *
- * Ensures:
- *
- *\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:
- *
- *\li See the description of dns_db_find() for information about 'options'.
- * If the caller sets #DNS_DBFIND_GLUEOK, it must ensure that 'name'
- * and 'type' are appropriate for glue retrieval.
- *
- *\li If 'now' is zero, then the current time will be used.
- *
- *\li If 'use_hints' is ISC_TRUE, and the view has a hints database, then
- * it will be searched last. If the answer is found in the hints
- * database, the result code will be DNS_R_HINT. If the name is found
- * 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
- * covers 'type', then 'sigrdataset' will be bound to it.
- *
- * Requires:
- *
- *\li 'view' is a valid, frozen view.
- *
- *\li 'name' is valid name.
- *
- *\li 'type' is a valid dns_rdatatype_t, and is not a meta query type
- * except dns_rdatatype_any.
- *
- *\li dbp == NULL || *dbp == NULL
- *
- *\li nodep == NULL || *nodep == NULL. If nodep != NULL, dbp != NULL.
- *
- *\li 'foundname' is a valid name with a dedicated buffer or NULL.
- *
- *\li 'rdataset' is a valid, disassociated rdataset.
- *
- *\li 'sigrdataset' is NULL, or is a valid, disassociated rdataset.
- *
- * Ensures:
- *
- *\li In successful cases, 'rdataset', and possibly 'sigrdataset', are
- * bound to the found data.
- *
- *\li If dbp != NULL, it points to the database containing the data.
- *
- *\li If nodep != NULL, it points to the database node containing the data.
- *
- *\li If foundname != NULL, it contains the full name of the found data.
- *
- * Returns:
- *
- *\li Any result that dns_db_find() can return, with the exception of
- * #DNS_R_DELEGATION.
- */
-
-isc_result_t
-dns_view_simplefind(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_rdataset_t *rdataset, dns_rdataset_t *sigrdataset);
-/*%<
- * Find an rdataset whose owner name is 'name', and whose type is
- * 'type'.
- *
- * Notes:
- *
- *\li This routine is appropriate for simple, exact-match queries of the
- * view. 'name' must be a canonical name; there is no DNAME or CNAME
- * processing.
- *
- *\li See the description of dns_db_find() for information about 'options'.
- * If the caller sets DNS_DBFIND_GLUEOK, it must ensure that 'name'
- * and 'type' are appropriate for glue retrieval.
- *
- *\li If 'now' is zero, then the current time will be used.
- *
- *\li If 'use_hints' is ISC_TRUE, and the view has a hints database, then
- * it will be searched last. If the answer is found in the hints
- * database, the result code will be DNS_R_HINT. If the name is found
- * in the hints database but not the type, the result code will be
- * DNS_R_HINTNXRRSET.
- *
- *\li If 'sigrdataset' is not NULL, and there is a SIG rdataset which
- * covers 'type', then 'sigrdataset' will be bound to it.
- *
- * Requires:
- *
- *\li 'view' is a valid, frozen view.
- *
- *\li 'name' is valid name.
- *
- *\li 'type' is a valid dns_rdatatype_t, and is not a meta query type
- * (e.g. dns_rdatatype_any), or dns_rdatatype_rrsig.
- *
- *\li 'rdataset' is a valid, disassociated rdataset.
- *
- *\li 'sigrdataset' is NULL, or is a valid, disassociated rdataset.
- *
- * Ensures:
- *
- *\li In successful cases, 'rdataset', and possibly 'sigrdataset', are
- * bound to the found data.
- *
- * Returns:
- *
- *\li #ISC_R_SUCCESS Success; result is desired type.
- *\li DNS_R_GLUE Success; result is glue.
- *\li DNS_R_HINT Success; result is a hint.
- *\li DNS_R_NCACHENXDOMAIN Success; result is a ncache entry.
- *\li DNS_R_NCACHENXRRSET Success; result is a ncache entry.
- *\li DNS_R_NXDOMAIN The name does not exist.
- *\li DNS_R_NXRRSET The rrset does not exist.
- *\li #ISC_R_NOTFOUND No matching data found,
- * or an error occurred.
- */
-
-/*% See dns_view_findzonecut2() */
-isc_result_t
-dns_view_findzonecut(dns_view_t *view, dns_name_t *name, dns_name_t *fname,
- isc_stdtime_t now, unsigned int options,
- isc_boolean_t use_hints,
- dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset);
-
-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,
- dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset);
-/*%<
- * Find the best known zonecut containing 'name'.
- *
- * This uses local authority, cache, and optionally hints data.
- * No external queries are performed.
- *
- * Notes:
- *
- *\li If 'now' is zero, then the current time will be used.
- *
- *\li If 'use_hints' is ISC_TRUE, and the view has a hints database, then
- * it will be searched last.
- *
- *\li If 'use_cache' is ISC_TRUE, and the view has a cache, then it will be
- * searched.
- *
- *\li If 'sigrdataset' is not NULL, and there is a SIG rdataset which
- * covers 'type', then 'sigrdataset' will be bound to it.
- *
- *\li If the DNS_DBFIND_NOEXACT option is set, then the zonecut returned
- * (if any) will be the deepest known ancestor of 'name'.
- *
- * Requires:
- *
- *\li 'view' is a valid, frozen view.
- *
- *\li 'name' is valid name.
- *
- *\li 'rdataset' is a valid, disassociated rdataset.
- *
- *\li 'sigrdataset' is NULL, or is a valid, disassociated rdataset.
- *
- * Returns:
- *
- *\li #ISC_R_SUCCESS Success.
- *
- *\li Many other results are possible.
- */
-
-isc_result_t
-dns_viewlist_find(dns_viewlist_t *list, const char *name,
- dns_rdataclass_t rdclass, dns_view_t **viewp);
-/*%<
- * Search for a view with name 'name' and class 'rdclass' in 'list'.
- * If found, '*viewp' is (strongly) attached to it.
- *
- * Requires:
- *
- *\li 'viewp' points to a NULL dns_view_t *.
- *
- * Returns:
- *
- *\li #ISC_R_SUCCESS A matching view was found.
- *\li #ISC_R_NOTFOUND No matching view was found.
- */
-
-isc_result_t
-dns_viewlist_findzone(dns_viewlist_t *list, dns_name_t *name, isc_boolean_t allclasses,
- dns_rdataclass_t rdclass, dns_zone_t **zonep);
-
-/*%<
- * Search zone with 'name' in view with 'rdclass' in viewlist 'list'
- * If found, zone is returned in *zonep. If allclasses is set rdclass is ignored
- *
- * Returns:
- *\li #ISC_R_SUCCESS A matching zone was found.
- *\li #ISC_R_NOTFOUND No matching zone was found.
- */
-
-isc_result_t
-dns_view_findzone(dns_view_t *view, dns_name_t *name, dns_zone_t **zonep);
-/*%<
- * Search for the zone 'name' in the zone table of 'view'.
- * If found, 'zonep' is (strongly) attached to it. There
- * are no partial matches.
- *
- * Requires:
- *
- *\li 'zonep' points to a NULL dns_zone_t *.
- *
- * Returns:
- *\li #ISC_R_SUCCESS A matching zone was found.
- *\li #ISC_R_NOTFOUND No matching zone was found.
- *\li others An error occurred.
- */
-
-isc_result_t
-dns_view_load(dns_view_t *view, isc_boolean_t stop);
-
-isc_result_t
-dns_view_loadnew(dns_view_t *view, isc_boolean_t stop);
-
-isc_result_t
-dns_view_asyncload(dns_view_t *view, dns_zt_allloaded_t callback, void *arg);
-/*%<
- * Load zones attached to this view. dns_view_load() loads
- * all zones whose master file has changed since the last
- * load; dns_view_loadnew() loads only zones that have never
- * been loaded.
- *
- * dns_view_asyncload() loads zones asynchronously. When all zones
- * in the view have finished loading, 'callback' is called with argument
- * 'arg' to inform the caller.
- *
- * If 'stop' is ISC_TRUE, stop on the first error and return it.
- * If 'stop' is ISC_FALSE (or we are loading asynchronously), ignore errors.
- *
- * Requires:
- *
- *\li 'view' is valid.
- */
-
-isc_result_t
-dns_view_gettsig(dns_view_t *view, dns_name_t *keyname,
- dns_tsigkey_t **keyp);
-/*%<
- * Find the TSIG key configured in 'view' with name 'keyname',
- * if any.
- *
- * Requires:
- *\li keyp points to a NULL dns_tsigkey_t *.
- *
- * Returns:
- *\li #ISC_R_SUCCESS A key was found and '*keyp' now points to it.
- *\li #ISC_R_NOTFOUND No key was found.
- *\li others An error occurred.
- */
-
-isc_result_t
-dns_view_getpeertsig(dns_view_t *view, isc_netaddr_t *peeraddr,
- dns_tsigkey_t **keyp);
-/*%<
- * Find the TSIG key configured in 'view' for the server whose
- * address is 'peeraddr', if any.
- *
- * Requires:
- * keyp points to a NULL dns_tsigkey_t *.
- *
- * Returns:
- *\li #ISC_R_SUCCESS A key was found and '*keyp' now points to it.
- *\li #ISC_R_NOTFOUND No key was found.
- *\li others An error occurred.
- */
-
-isc_result_t
-dns_view_checksig(dns_view_t *view, isc_buffer_t *source, dns_message_t *msg);
-/*%<
- * Verifies the signature of a message.
- *
- * Requires:
- *
- *\li 'view' is a valid view.
- *\li 'source' is a valid buffer containing the message
- *\li 'msg' is a valid message
- *
- * Returns:
- *\li see dns_tsig_verify()
- */
-
-void
-dns_view_dialup(dns_view_t *view);
-/*%<
- * Perform dialup-time maintenance on the zones of 'view'.
- */
-
-isc_result_t
-dns_view_dumpdbtostream(dns_view_t *view, FILE *fp);
-/*%<
- * Dump the current state of the view 'view' to the stream 'fp'
- * for purposes of analysis or debugging.
- *
- * Currently the dumped state includes the view's cache; in the future
- * it may also include other state such as the address database.
- * It will not not include authoritative data since it is voluminous and
- * easily obtainable by other means.
- *
- * Requires:
- *
- *\li 'view' is valid.
- *
- *\li 'fp' refers to a file open for writing.
- *
- * Returns:
- * \li ISC_R_SUCCESS The cache was successfully dumped.
- * \li others An error occurred (see dns_master_dump)
- */
-
-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). 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.
- *
- * No other tasks are executing.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMEMORY
- */
-
-isc_result_t
-dns_view_flushnode(dns_view_t *view, dns_name_t *name, isc_boolean_t tree);
-/*%<
- * Flush the given name from the view's cache (and optionally ADB/badcache).
- *
- * If 'tree' is true, flush 'name' and all names below it
- * from the cache, but do not flush ADB.
- *
- * If 'tree' is false, flush 'name' frmo both the cache and ADB,
- * but do not touch any other nodes.
- *
- * Requires:
- *\li 'view' is valid.
- *\li 'name' is valid.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- * other returns are failures.
- */
-
-isc_result_t
-dns_view_flushname(dns_view_t *view, dns_name_t *name);
-/*%<
- * Flush the given name from the view's cache, ADB and badcache.
- * Equivalent to dns_view_flushnode(view, name, ISC_FALSE).
- *
- *
- * Requires:
- *\li 'view' is valid.
- *\li 'name' is valid.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- * other returns are failures.
- */
-
-isc_result_t
-dns_view_adddelegationonly(dns_view_t *view, dns_name_t *name);
-/*%<
- * Add the given name to the delegation only table.
- *
- * Requires:
- *\li 'view' is valid.
- *\li 'name' is valid.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMEMORY
- */
-
-isc_result_t
-dns_view_excludedelegationonly(dns_view_t *view, dns_name_t *name);
-/*%<
- * Add the given name to be excluded from the root-delegation-only.
- *
- *
- * Requires:
- *\li 'view' is valid.
- *\li 'name' is valid.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMEMORY
- */
-
-isc_boolean_t
-dns_view_isdelegationonly(dns_view_t *view, dns_name_t *name);
-/*%<
- * Check if 'name' is in the delegation only table or if
- * rootdelonly is set that name is not being excluded.
- *
- * Requires:
- *\li 'view' is valid.
- *\li 'name' is valid.
- *
- * Returns:
- *\li #ISC_TRUE if the name is the table.
- *\li #ISC_FALSE otherwise.
- */
-
-void
-dns_view_setrootdelonly(dns_view_t *view, isc_boolean_t value);
-/*%<
- * Set the root delegation only flag.
- *
- * Requires:
- *\li 'view' is valid.
- */
-
-isc_boolean_t
-dns_view_getrootdelonly(dns_view_t *view);
-/*%<
- * Get the root delegation only flag.
- *
- * Requires:
- *\li 'view' is valid.
- */
-
-isc_result_t
-dns_view_freezezones(dns_view_t *view, isc_boolean_t freeze);
-/*%<
- * Freeze/thaw updates to master zones.
- *
- * Requires:
- * \li 'view' is valid.
- */
-
-void
-dns_view_setresstats(dns_view_t *view, isc_stats_t *stats);
-/*%<
- * Set a general resolver statistics counter set 'stats' for 'view'.
- *
- * Requires:
- * \li 'view' is valid and is not frozen.
- *
- *\li stats is a valid statistics supporting resolver statistics counters
- * (see dns/stats.h).
- */
-
-void
-dns_view_getresstats(dns_view_t *view, isc_stats_t **statsp);
-/*%<
- * Get the general statistics counter set for 'view'. If a statistics set is
- * set '*statsp' will be attached to the set; otherwise, '*statsp' will be
- * untouched.
- *
- * Requires:
- * \li 'view' is valid and is not frozen.
- *
- *\li 'statsp' != NULL && '*statsp' != NULL
- */
-
-void
-dns_view_setresquerystats(dns_view_t *view, dns_stats_t *stats);
-/*%<
- * Set a statistics counter set of rdata type, 'stats', for 'view'. Once the
- * statistic set is installed, view's resolver will count outgoing queries
- * per rdata type.
- *
- * Requires:
- * \li 'view' is valid and is not frozen.
- *
- *\li stats is a valid statistics created by dns_rdatatypestats_create().
- */
-
-void
-dns_view_getresquerystats(dns_view_t *view, dns_stats_t **statsp);
-/*%<
- * Get the rdatatype statistics counter set for 'view'. If a statistics set is
- * set '*statsp' will be attached to the set; otherwise, '*statsp' will be
- * untouched.
- *
- * Requires:
- * \li 'view' is valid and is not frozen.
- *
- *\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);
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_VIEW_H */
diff --git a/contrib/bind9/lib/dns/include/dns/xfrin.h b/contrib/bind9/lib/dns/include/dns/xfrin.h
deleted file mode 100644
index 2f20c35f4d05..000000000000
--- a/contrib/bind9/lib/dns/include/dns/xfrin.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: xfrin.h,v 1.30 2009/01/17 23:47:43 tbox Exp $ */
-
-#ifndef DNS_XFRIN_H
-#define DNS_XFRIN_H 1
-
-/*****
- ***** Module Info
- *****/
-
-/*! \file dns/xfrin.h
- * \brief
- * Incoming zone transfers (AXFR + IXFR).
- */
-
-/***
- *** Imports
- ***/
-
-#include <isc/lang.h>
-
-#include <dns/types.h>
-
-/***
- *** Types
- ***/
-
-/*%
- * A transfer in progress. This is an opaque type.
- */
-typedef struct dns_xfrin_ctx dns_xfrin_ctx_t;
-
-/***
- *** Functions
- ***/
-
-ISC_LANG_BEGINDECLS
-
-/*% see dns_xfrin_create2() */
-isc_result_t
-dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype,
- isc_sockaddr_t *masteraddr, dns_tsigkey_t *tsigkey,
- isc_mem_t *mctx, isc_timermgr_t *timermgr,
- isc_socketmgr_t *socketmgr, isc_task_t *task,
- dns_xfrindone_t done, dns_xfrin_ctx_t **xfrp);
-
-isc_result_t
-dns_xfrin_create2(dns_zone_t *zone, dns_rdatatype_t xfrtype,
- isc_sockaddr_t *masteraddr, isc_sockaddr_t *sourceaddr,
- dns_tsigkey_t *tsigkey, isc_mem_t *mctx,
- isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
- isc_task_t *task, dns_xfrindone_t done,
- dns_xfrin_ctx_t **xfrp);
-/*%<
- * Attempt to start an incoming zone transfer of 'zone'
- * from 'masteraddr', creating a dns_xfrin_ctx_t object to
- * manage it. Attach '*xfrp' to the newly created object.
- *
- * Iff ISC_R_SUCCESS is returned, '*done' is guaranteed to be
- * called in the context of 'task', with 'zone' and a result
- * code as arguments when the transfer finishes.
- *
- * Requires:
- *\li 'xfrtype' is dns_rdatatype_axfr, dns_rdatatype_ixfr
- * or dns_rdatatype_soa (soa query followed by axfr if
- * serial is greater than current serial).
- *
- *\li If 'xfrtype' is dns_rdatatype_ixfr or dns_rdatatype_soa,
- * the zone has a database.
- */
-
-void
-dns_xfrin_shutdown(dns_xfrin_ctx_t *xfr);
-/*%<
- * If the zone transfer 'xfr' has already finished,
- * do nothing. Otherwise, abort it and cause it to call
- * its done callback with a status of ISC_R_CANCELED.
- */
-
-void
-dns_xfrin_detach(dns_xfrin_ctx_t **xfrp);
-/*%<
- * Detach a reference to a zone transfer object.
- * Caller to maintain external locking if required.
- */
-
-void
-dns_xfrin_attach(dns_xfrin_ctx_t *source, dns_xfrin_ctx_t **target);
-/*%<
- * Caller to maintain external locking if required.
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_XFRIN_H */
diff --git a/contrib/bind9/lib/dns/include/dns/zone.h b/contrib/bind9/lib/dns/include/dns/zone.h
deleted file mode 100644
index f91801f6fe3f..000000000000
--- a/contrib/bind9/lib/dns/include/dns/zone.h
+++ /dev/null
@@ -1,2104 +0,0 @@
-/*
- * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-#ifndef DNS_ZONE_H
-#define DNS_ZONE_H 1
-
-/*! \file dns/zone.h */
-
-/***
- *** Imports
- ***/
-
-#include <stdio.h>
-
-#include <isc/formatcheck.h>
-#include <isc/lang.h>
-#include <isc/rwlock.h>
-
-#include <dns/master.h>
-#include <dns/masterdump.h>
-#include <dns/rdatastruct.h>
-#include <dns/rpz.h>
-#include <dns/types.h>
-#include <dns/zt.h>
-
-typedef enum {
- dns_zone_none,
- dns_zone_master,
- dns_zone_slave,
- dns_zone_stub,
- dns_zone_staticstub,
- dns_zone_key,
- dns_zone_dlz,
- dns_zone_redirect
-} dns_zonetype_t;
-
-typedef enum {
- dns_zonestat_none = 0,
- dns_zonestat_terse,
- dns_zonestat_full
-} dns_zonestat_level_t;
-
-#define DNS_ZONEOPT_SERVERS 0x00000001U /*%< perform server checks */
-#define DNS_ZONEOPT_PARENTS 0x00000002U /*%< perform parent checks */
-#define DNS_ZONEOPT_CHILDREN 0x00000004U /*%< perform child checks */
-#define DNS_ZONEOPT_NOTIFY 0x00000008U /*%< perform NOTIFY */
-#define DNS_ZONEOPT_MANYERRORS 0x00000010U /*%< return many errors on load */
-#define DNS_ZONEOPT_IXFRFROMDIFFS 0x00000020U /*%< calculate differences */
-#define DNS_ZONEOPT_NOMERGE 0x00000040U /*%< don't merge journal */
-#define DNS_ZONEOPT_CHECKNS 0x00000080U /*%< check if NS's are addresses */
-#define DNS_ZONEOPT_FATALNS 0x00000100U /*%< DNS_ZONEOPT_CHECKNS is fatal */
-#define DNS_ZONEOPT_MULTIMASTER 0x00000200U /*%< this zone has multiple masters */
-#define DNS_ZONEOPT_USEALTXFRSRC 0x00000400U /*%< use alternate transfer sources */
-#define DNS_ZONEOPT_CHECKNAMES 0x00000800U /*%< check-names */
-#define DNS_ZONEOPT_CHECKNAMESFAIL 0x00001000U /*%< fatal check-name failures */
-#define DNS_ZONEOPT_CHECKWILDCARD 0x00002000U /*%< check for internal wildcards */
-#define DNS_ZONEOPT_CHECKMX 0x00004000U /*%< check-mx */
-#define DNS_ZONEOPT_CHECKMXFAIL 0x00008000U /*%< fatal check-mx failures */
-#define DNS_ZONEOPT_CHECKINTEGRITY 0x00010000U /*%< perform integrity checks */
-#define DNS_ZONEOPT_CHECKSIBLING 0x00020000U /*%< perform sibling glue checks */
-#define DNS_ZONEOPT_NOCHECKNS 0x00040000U /*%< disable IN NS address checks */
-#define DNS_ZONEOPT_WARNMXCNAME 0x00080000U /*%< warn on MX CNAME check */
-#define DNS_ZONEOPT_IGNOREMXCNAME 0x00100000U /*%< ignore MX CNAME check */
-#define DNS_ZONEOPT_WARNSRVCNAME 0x00200000U /*%< warn on SRV CNAME check */
-#define DNS_ZONEOPT_IGNORESRVCNAME 0x00400000U /*%< ignore SRV CNAME check */
-#define DNS_ZONEOPT_UPDATECHECKKSK 0x00800000U /*%< check dnskey KSK flag */
-#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 */
-#define DNS_ZONEOPT_CHECKSPF 0x80000000U /*%< check SPF records */
-
-#ifndef NOMINUM_PUBLIC
-/*
- * Nominum specific options build down.
- */
-#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 */
-#define DNS_ZONEKEY_NORESIGN 0x00000010U /*%< no automatic resigning */
-
-#ifndef DNS_ZONE_MINREFRESH
-#define DNS_ZONE_MINREFRESH 300 /*%< 5 minutes */
-#endif
-#ifndef DNS_ZONE_MAXREFRESH
-#define DNS_ZONE_MAXREFRESH 2419200 /*%< 4 weeks */
-#endif
-#ifndef DNS_ZONE_DEFAULTREFRESH
-#define DNS_ZONE_DEFAULTREFRESH 3600 /*%< 1 hour */
-#endif
-#ifndef DNS_ZONE_MINRETRY
-#define DNS_ZONE_MINRETRY 300 /*%< 5 minutes */
-#endif
-#ifndef DNS_ZONE_MAXRETRY
-#define DNS_ZONE_MAXRETRY 1209600 /*%< 2 weeks */
-#endif
-#ifndef DNS_ZONE_DEFAULTRETRY
-#define DNS_ZONE_DEFAULTRETRY 60 /*%< 1 minute, subject to
- exponential backoff */
-#endif
-
-#define DNS_ZONESTATE_XFERRUNNING 1
-#define DNS_ZONESTATE_XFERDEFERRED 2
-#define DNS_ZONESTATE_SOAQUERY 3
-#define DNS_ZONESTATE_ANY 4
-
-ISC_LANG_BEGINDECLS
-
-/***
- *** Functions
- ***/
-
-isc_result_t
-dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx);
-/*%<
- * Creates a new empty zone and attach '*zonep' to it.
- *
- * Requires:
- *\li 'zonep' to point to a NULL pointer.
- *\li 'mctx' to be a valid memory context.
- *
- * Ensures:
- *\li '*zonep' refers to a valid zone.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMEMORY
- *\li #ISC_R_UNEXPECTED
- */
-
-void
-dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass);
-/*%<
- * Sets the class of a zone. This operation can only be performed
- * once on a zone.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- *\li dns_zone_setclass() not to have been called since the zone was
- * created.
- *\li 'rdclass' != dns_rdataclass_none.
- */
-
-dns_rdataclass_t
-dns_zone_getclass(dns_zone_t *zone);
-/*%<
- * Returns the current zone class.
- *
- * Requires:
- *\li 'zone' to be a valid zone.
- */
-
-isc_result_t
-dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp);
-
-isc_uint32_t
-dns_zone_getserial(dns_zone_t *zone);
-/*%<
- * Returns the current serial number of the zone. On success, the SOA
- * serial of the zone will be copied into '*serialp'.
- * dns_zone_getserial() cannot catch failure cases and is deprecated by
- * dns_zone_getserial2().
- *
- * Requires:
- *\li 'zone' to be a valid zone.
- *\li 'serialp' to be non NULL
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #DNS_R_NOTLOADED zone DB is not loaded
- */
-
-void
-dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type);
-/*%<
- * Sets the zone type. This operation can only be performed once on
- * a zone.
- *
- * Requires:
- *\li 'zone' to be a valid zone.
- *\li dns_zone_settype() not to have been called since the zone was
- * created.
- *\li 'type' != dns_zone_none
- */
-
-void
-dns_zone_setview(dns_zone_t *zone, dns_view_t *view);
-/*%<
- * Associate the zone with a view.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- */
-
-dns_view_t *
-dns_zone_getview(dns_zone_t *zone);
-/*%<
- * Returns the zone's associated view.
- *
- * Requires:
- *\li 'zone' to be a valid zone.
- */
-
-isc_result_t
-dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin);
-/*%<
- * Sets the zones origin to 'origin'.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- *\li 'origin' to be non NULL.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMEMORY
- */
-
-dns_name_t *
-dns_zone_getorigin(dns_zone_t *zone);
-/*%<
- * Returns the value of the origin.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- */
-
-isc_result_t
-dns_zone_setfile(dns_zone_t *zone, const char *file);
-
-isc_result_t
-dns_zone_setfile2(dns_zone_t *zone, const char *file,
- dns_masterformat_t format);
-/*%<
- * Sets the name of the master file in the format of 'format' from which
- * the zone loads its database to 'file'.
- *
- * For zones that have no associated master file, 'file' will be NULL.
- *
- * For zones with persistent databases, the file name
- * setting is ignored.
- *
- * dns_zone_setfile() is a backward-compatible form of
- * dns_zone_setfile2(), which always specifies the
- * dns_masterformat_text (RFC1035) format.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- *
- * Returns:
- *\li #ISC_R_NOMEMORY
- *\li #ISC_R_SUCCESS
- */
-
-const char *
-dns_zone_getfile(dns_zone_t *zone);
-/*%<
- * Gets the name of the zone's master file, if any.
- *
- * Requires:
- *\li 'zone' to be valid initialised zone.
- *
- * Returns:
- *\li Pointer to null-terminated file name, or NULL.
- */
-
-isc_result_t
-dns_zone_load(dns_zone_t *zone);
-
-isc_result_t
-dns_zone_loadnew(dns_zone_t *zone);
-
-isc_result_t
-dns_zone_loadandthaw(dns_zone_t *zone);
-
-/*%<
- * Cause the database to be loaded from its backing store.
- * Confirm that the minimum requirements for the zone type are
- * met, otherwise DNS_R_BADZONE is returned.
- *
- * dns_zone_loadnew() only loads zones that are not yet loaded.
- * dns_zone_load() also loads zones that are already loaded and
- * and whose master file has changed since the last load.
- * dns_zone_loadandthaw() is similar to dns_zone_load() but will
- * also re-enable DNS UPDATEs when the load completes.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- *
- * Returns:
- *\li #ISC_R_UNEXPECTED
- *\li #ISC_R_SUCCESS
- *\li DNS_R_CONTINUE Incremental load has been queued.
- *\li DNS_R_UPTODATE The zone has already been loaded based on
- * file system timestamps.
- *\li DNS_R_BADZONE
- *\li Any result value from dns_db_load().
- */
-
-isc_result_t
-dns_zone_asyncload(dns_zone_t *zone, dns_zt_zoneloaded_t done, void *arg);
-/*%<
- * Cause the database to be loaded from its backing store asynchronously.
- * Other zone maintenance functions are suspended until this is complete.
- * When finished, 'done' is called to inform the caller, with 'arg' as
- * its first argument and 'zone' as its second. (Normally, 'arg' is
- * expected to point to the zone table but is left undefined for testing
- * purposes.)
- */
-
-isc_boolean_t
-dns__zone_loadpending(dns_zone_t *zone);
-/*%<
- * Indicates whether the zone is waiting to be loaded asynchronously.
- * (Not currently intended for use outside of this module and associated
- * tests.)
- */
-
-void
-dns_zone_attach(dns_zone_t *source, dns_zone_t **target);
-/*%<
- * Attach '*target' to 'source' incrementing its external
- * reference count.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- *\li 'target' to be non NULL and '*target' to be NULL.
- */
-
-void
-dns_zone_detach(dns_zone_t **zonep);
-/*%<
- * Detach from a zone decrementing its external reference count.
- * If this was the last external reference to the zone it will be
- * shut down and eventually freed.
- *
- * Require:
- *\li 'zonep' to point to a valid zone.
- */
-
-void
-dns_zone_iattach(dns_zone_t *source, dns_zone_t **target);
-/*%<
- * Attach '*target' to 'source' incrementing its internal
- * reference count. This is intended for use by operations
- * such as zone transfers that need to prevent the zone
- * object from being freed but not from shutting down.
- *
- * Require:
- *\li The caller is running in the context of the zone's task.
- *\li 'zone' to be a valid zone.
- *\li 'target' to be non NULL and '*target' to be NULL.
- */
-
-void
-dns_zone_idetach(dns_zone_t **zonep);
-/*%<
- * Detach from a zone decrementing its internal reference count.
- * If there are no more internal or external references to the
- * zone, it will be freed.
- *
- * Require:
- *\li The caller is running in the context of the zone's task.
- *\li 'zonep' to point to a valid zone.
- */
-
-void
-dns_zone_setflag(dns_zone_t *zone, unsigned int flags, isc_boolean_t value);
-/*%<
- * Sets ('value' == 'ISC_TRUE') / clears ('value' == 'IS_FALSE')
- * zone flags. Valid flag bits are DNS_ZONE_F_*.
- *
- * Requires
- *\li 'zone' to be a valid zone.
- */
-
-isc_result_t
-dns_zone_getdb(dns_zone_t *zone, dns_db_t **dbp);
-/*%<
- * Attach '*dbp' to the database to if it exists otherwise
- * return DNS_R_NOTLOADED.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- *\li 'dbp' to be != NULL && '*dbp' == NULL.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\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);
-/*%<
- * Sets the database type to dbargv[0] and database arguments
- * to subsequent dbargv elements.
- * 'db_type' is not checked to see if it is a valid database type.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- *\li 'database' to be non NULL.
- *\li 'dbargc' to be >= 1
- *\li 'dbargv' to point to dbargc NULL-terminated strings
- *
- * Returns:
- *\li #ISC_R_NOMEMORY
- *\li #ISC_R_SUCCESS
- */
-
-isc_result_t
-dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx);
-/*%<
- * Returns the current dbtype. isc_mem_free() should be used
- * to free 'argv' after use.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- *\li 'argv' to be non NULL and *argv to be NULL.
- *\li 'mctx' to be valid.
- *
- * Returns:
- *\li #ISC_R_NOMEMORY
- *\li #ISC_R_SUCCESS
- */
-
-void
-dns_zone_markdirty(dns_zone_t *zone);
-/*%<
- * Mark a zone as 'dirty'.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- */
-
-void
-dns_zone_expire(dns_zone_t *zone);
-/*%<
- * Mark the zone as expired. If the zone requires dumping cause it to
- * be initiated. Set the refresh and retry intervals to there default
- * values and unload the zone.
- *
- * Require
- *\li 'zone' to be a valid zone.
- */
-
-void
-dns_zone_refresh(dns_zone_t *zone);
-/*%<
- * Initiate zone up to date checks. The zone must already be being
- * managed.
- *
- * Require
- *\li 'zone' to be a valid zone.
- */
-
-isc_result_t
-dns_zone_flush(dns_zone_t *zone);
-/*%<
- * Write the zone to database if there are uncommitted changes.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- */
-
-isc_result_t
-dns_zone_dump(dns_zone_t *zone);
-/*%<
- * Write the zone to database.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- */
-
-isc_result_t
-dns_zone_dumptostream(dns_zone_t *zone, FILE *fd);
-
-isc_result_t
-dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
- const dns_master_style_t *style);
-isc_result_t
-dns_zone_dumptostream3(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
- const dns_master_style_t *style,
- const isc_uint32_t rawversion);
-/*%<
- * Write the zone to stream 'fd' in the specified 'format'.
- * If the 'format' is dns_masterformat_text (RFC1035), 'style' also
- * specifies the file style (e.g., &dns_master_style_default).
- *
- * dns_zone_dumptostream() is a backward-compatible form of
- * dns_zone_dumptostream2(), which always uses the dns_masterformat_text
- * format and the dns_master_style_default style.
- *
- * dns_zone_dumptostream2() is a backward-compatible form of
- * dns_zone_dumptostream3(), which always uses the current
- * default raw file format version.
- *
- * Note that dns_zone_dumptostream3() is the most flexible form. It
- * can also provide the functionality of dns_zone_fulldumptostream().
- *
- * Require:
- *\li 'zone' to be a valid zone.
- *\li 'fd' to be a stream open for writing.
- */
-
-isc_result_t
-dns_zone_fulldumptostream(dns_zone_t *zone, FILE *fd);
-/*%<
- * The same as dns_zone_dumptostream, but dumps the zone with
- * different dump settings (dns_master_style_full).
- *
- * Require:
- *\li 'zone' to be a valid zone.
- *\li 'fd' to be a stream open for writing.
- */
-
-void
-dns_zone_maintenance(dns_zone_t *zone);
-/*%<
- * Perform regular maintenance on the zone. This is called as a
- * result of a zone being managed.
- *
- * Require
- *\li 'zone' to be a valid zone.
- */
-
-isc_result_t
-dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters,
- isc_uint32_t count);
-isc_result_t
-dns_zone_setmasterswithkeys(dns_zone_t *zone,
- const isc_sockaddr_t *masters,
- dns_name_t **keynames,
- isc_uint32_t count);
-/*%<
- * Set the list of master servers for the zone.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- *\li 'masters' array of isc_sockaddr_t with port set or NULL.
- *\li 'count' the number of masters.
- *\li 'keynames' array of dns_name_t's for tsig keys or NULL.
- *
- * \li dns_zone_setmasters() is just a wrapper to setmasterswithkeys(),
- * passing NULL in the keynames field.
- *
- * \li If 'masters' is NULL then 'count' must be zero.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMEMORY
- *\li Any result dns_name_dup() can return, if keynames!=NULL
- */
-
-isc_result_t
-dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
- isc_uint32_t count);
-isc_result_t
-dns_zone_setalsonotifywithkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
- dns_name_t **keynames, isc_uint32_t count);
-/*%<
- * Set the list of additional servers to be notified when
- * a zone changes. To clear the list use 'count = 0'.
- *
- * dns_zone_alsonotifywithkeys() allows each notify address to
- * be associated with a TSIG key.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- *\li 'notify' to be non-NULL if count != 0.
- *\li 'count' to be the number of notifiees.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMEMORY
- */
-
-void
-dns_zone_unload(dns_zone_t *zone);
-/*%<
- * detach the database from the zone structure.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- */
-
-void
-dns_zone_setoption(dns_zone_t *zone, unsigned int option, isc_boolean_t value);
-/*%<
- * Set given options on ('value' == ISC_TRUE) or off ('value' ==
- * #ISC_FALSE).
- *
- * Require:
- *\li 'zone' to be a valid zone.
- */
-
-unsigned int
-dns_zone_getoptions(dns_zone_t *zone);
-/*%<
- * Returns the current zone options.
- *
- * Require:
- *\li 'zone' to be a valid 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.
- *
- * Requires:
- *\li 'zone' is valid.
- *\li val > 0.
- */
-
-void
-dns_zone_setmaxrefreshtime(dns_zone_t *zone, isc_uint32_t val);
-/*%<
- * Set the maximum refresh time.
- *
- * Requires:
- *\li 'zone' is valid.
- *\li val > 0.
- */
-
-void
-dns_zone_setminretrytime(dns_zone_t *zone, isc_uint32_t val);
-/*%<
- * Set the minimum retry time.
- *
- * Requires:
- *\li 'zone' is valid.
- *\li val > 0.
- */
-
-void
-dns_zone_setmaxretrytime(dns_zone_t *zone, isc_uint32_t val);
-/*%<
- * Set the maximum retry time.
- *
- * Requires:
- *\li 'zone' is valid.
- * val > 0.
- */
-
-isc_result_t
-dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource);
-isc_result_t
-dns_zone_setaltxfrsource4(dns_zone_t *zone,
- const isc_sockaddr_t *xfrsource);
-/*%<
- * Set the source address to be used in IPv4 zone transfers.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- *\li 'xfrsource' to contain the address.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- */
-
-isc_sockaddr_t *
-dns_zone_getxfrsource4(dns_zone_t *zone);
-isc_sockaddr_t *
-dns_zone_getaltxfrsource4(dns_zone_t *zone);
-/*%<
- * Returns the source address set by a previous dns_zone_setxfrsource4
- * call, or the default of inaddr_any, port 0.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- */
-
-isc_result_t
-dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource);
-isc_result_t
-dns_zone_setaltxfrsource6(dns_zone_t *zone,
- const isc_sockaddr_t *xfrsource);
-/*%<
- * Set the source address to be used in IPv6 zone transfers.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- *\li 'xfrsource' to contain the address.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- */
-
-isc_sockaddr_t *
-dns_zone_getxfrsource6(dns_zone_t *zone);
-isc_sockaddr_t *
-dns_zone_getaltxfrsource6(dns_zone_t *zone);
-/*%<
- * Returns the source address set by a previous dns_zone_setxfrsource6
- * call, or the default of in6addr_any, port 0.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- */
-
-isc_result_t
-dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc);
-/*%<
- * Set the source address to be used with IPv4 NOTIFY messages.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- *\li 'notifysrc' to contain the address.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- */
-
-isc_sockaddr_t *
-dns_zone_getnotifysrc4(dns_zone_t *zone);
-/*%<
- * Returns the source address set by a previous dns_zone_setnotifysrc4
- * call, or the default of inaddr_any, port 0.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- */
-
-isc_result_t
-dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc);
-/*%<
- * Set the source address to be used with IPv6 NOTIFY messages.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- *\li 'notifysrc' to contain the address.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- */
-
-isc_sockaddr_t *
-dns_zone_getnotifysrc6(dns_zone_t *zone);
-/*%<
- * Returns the source address set by a previous dns_zone_setnotifysrc6
- * call, or the default of in6addr_any, port 0.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- */
-
-void
-dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl);
-/*%<
- * Sets the notify acl list for the zone.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- *\li 'acl' to be a valid acl.
- */
-
-void
-dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl);
-/*%<
- * Sets the query acl list for the zone.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- *\li 'acl' to be a valid acl.
- */
-
-void
-dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl);
-/*%<
- * Sets the query-on acl list for the zone.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- *\li 'acl' to be a valid acl.
- */
-
-void
-dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl);
-/*%<
- * Sets the update acl list for the zone.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- *\li 'acl' to be valid acl.
- */
-
-void
-dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl);
-/*%<
- * Sets the forward unsigned updates acl list for the zone.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- *\li 'acl' to be valid acl.
- */
-
-void
-dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl);
-/*%<
- * Sets the transfer acl list for the zone.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- *\li 'acl' to be valid acl.
- */
-
-dns_acl_t *
-dns_zone_getnotifyacl(dns_zone_t *zone);
-/*%<
- * Returns the current notify acl or NULL.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- *
- * Returns:
- *\li acl a pointer to the acl.
- *\li NULL
- */
-
-dns_acl_t *
-dns_zone_getqueryacl(dns_zone_t *zone);
-/*%<
- * Returns the current query acl or NULL.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- *
- * Returns:
- *\li acl a pointer to the acl.
- *\li NULL
- */
-
-dns_acl_t *
-dns_zone_getqueryonacl(dns_zone_t *zone);
-/*%<
- * Returns the current query-on acl or NULL.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- *
- * Returns:
- *\li acl a pointer to the acl.
- *\li NULL
- */
-
-dns_acl_t *
-dns_zone_getupdateacl(dns_zone_t *zone);
-/*%<
- * Returns the current update acl or NULL.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- *
- * Returns:
- *\li acl a pointer to the acl.
- *\li NULL
- */
-
-dns_acl_t *
-dns_zone_getforwardacl(dns_zone_t *zone);
-/*%<
- * Returns the current forward unsigned updates acl or NULL.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- *
- * Returns:
- *\li acl a pointer to the acl.
- *\li NULL
- */
-
-dns_acl_t *
-dns_zone_getxfracl(dns_zone_t *zone);
-/*%<
- * Returns the current transfer acl or NULL.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- *
- * Returns:
- *\li acl a pointer to the acl.
- *\li NULL
- */
-
-void
-dns_zone_clearupdateacl(dns_zone_t *zone);
-/*%<
- * Clear the current update acl.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- */
-
-void
-dns_zone_clearforwardacl(dns_zone_t *zone);
-/*%<
- * Clear the current forward unsigned updates acl.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- */
-
-void
-dns_zone_clearnotifyacl(dns_zone_t *zone);
-/*%<
- * Clear the current notify acl.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- */
-
-void
-dns_zone_clearqueryacl(dns_zone_t *zone);
-/*%<
- * Clear the current query acl.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- */
-
-void
-dns_zone_clearqueryonacl(dns_zone_t *zone);
-/*%<
- * Clear the current query-on acl.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- */
-
-void
-dns_zone_clearxfracl(dns_zone_t *zone);
-/*%<
- * Clear the current transfer acl.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- */
-
-isc_boolean_t
-dns_zone_getupdatedisabled(dns_zone_t *zone);
-/*%<
- * Return update disabled.
- * Transient unless called when running in isc_task_exclusive() mode.
- */
-
-void
-dns_zone_setupdatedisabled(dns_zone_t *zone, isc_boolean_t state);
-/*%<
- * Set update disabled.
- * Should only be called only when running in isc_task_exclusive() mode.
- * Failure to do so may result in updates being committed after the
- * call has been made.
- */
-
-isc_boolean_t
-dns_zone_getzeronosoattl(dns_zone_t *zone);
-/*%<
- * Return zero-no-soa-ttl status.
- */
-
-void
-dns_zone_setzeronosoattl(dns_zone_t *zone, isc_boolean_t state);
-/*%<
- * Set zero-no-soa-ttl status.
- */
-
-void
-dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity);
-/*%<
- * Set the severity of name checking when loading a zone.
- *
- * Require:
- * \li 'zone' to be a valid zone.
- */
-
-dns_severity_t
-dns_zone_getchecknames(dns_zone_t *zone);
-/*%<
- * Return the current severity of name checking.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- */
-
-void
-dns_zone_setjournalsize(dns_zone_t *zone, isc_int32_t size);
-/*%<
- * Sets the journal size for the zone.
- *
- * Requires:
- *\li 'zone' to be a valid zone.
- */
-
-isc_int32_t
-dns_zone_getjournalsize(dns_zone_t *zone);
-/*%<
- * Return the journal size as set with a previous call to
- * dns_zone_setjournalsize().
- *
- * Requires:
- *\li 'zone' to be a valid zone.
- */
-
-isc_result_t
-dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
- dns_message_t *msg);
-/*%<
- * Tell the zone that it has received a NOTIFY message from another
- * server. This may cause some zone maintenance activity to occur.
- *
- * Requires:
- *\li 'zone' to be a valid zone.
- *\li '*from' to contain the address of the server from which 'msg'
- * was received.
- *\li 'msg' a message with opcode NOTIFY and qr clear.
- *
- * Returns:
- *\li DNS_R_REFUSED
- *\li DNS_R_NOTIMP
- *\li DNS_R_FORMERR
- *\li DNS_R_SUCCESS
- */
-
-void
-dns_zone_setmaxxfrin(dns_zone_t *zone, isc_uint32_t maxxfrin);
-/*%<
- * Set the maximum time (in seconds) that a zone transfer in (AXFR/IXFR)
- * of this zone will use before being aborted.
- *
- * Requires:
- * \li 'zone' to be valid initialised zone.
- */
-
-isc_uint32_t
-dns_zone_getmaxxfrin(dns_zone_t *zone);
-/*%<
- * Returns the maximum transfer time for this zone. This will be
- * either the value set by the last call to dns_zone_setmaxxfrin() or
- * the default value of 1 hour.
- *
- * Requires:
- *\li 'zone' to be valid initialised zone.
- */
-
-void
-dns_zone_setmaxxfrout(dns_zone_t *zone, isc_uint32_t maxxfrout);
-/*%<
- * Set the maximum time (in seconds) that a zone transfer out (AXFR/IXFR)
- * of this zone will use before being aborted.
- *
- * Requires:
- * \li 'zone' to be valid initialised zone.
- */
-
-isc_uint32_t
-dns_zone_getmaxxfrout(dns_zone_t *zone);
-/*%<
- * Returns the maximum transfer time for this zone. This will be
- * either the value set by the last call to dns_zone_setmaxxfrout() or
- * the default value of 1 hour.
- *
- * Requires:
- *\li 'zone' to be valid initialised zone.
- */
-
-isc_result_t
-dns_zone_setjournal(dns_zone_t *zone, const char *journal);
-/*%<
- * Sets the filename used for journaling updates / IXFR transfers.
- * The default journal name is set by dns_zone_setfile() to be
- * "file.jnl". If 'journal' is NULL, the zone will have no
- * journal name.
- *
- * Requires:
- *\li 'zone' to be a valid zone.
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li #ISC_R_NOMEMORY
- */
-
-char *
-dns_zone_getjournal(dns_zone_t *zone);
-/*%<
- * Returns the journal name associated with this zone.
- * If no journal has been set this will be NULL.
- *
- * Requires:
- *\li 'zone' to be valid initialised zone.
- */
-
-dns_zonetype_t
-dns_zone_gettype(dns_zone_t *zone);
-/*%<
- * Returns the type of the zone (master/slave/etc.)
- *
- * Requires:
- *\li 'zone' to be valid initialised zone.
- */
-
-void
-dns_zone_settask(dns_zone_t *zone, isc_task_t *task);
-/*%<
- * Give a zone a task to work with. Any current task will be detached.
- *
- * Requires:
- *\li 'zone' to be valid.
- *\li 'task' to be valid.
- */
-
-void
-dns_zone_gettask(dns_zone_t *zone, isc_task_t **target);
-/*%<
- * Attach '*target' to the zone's task.
- *
- * Requires:
- *\li 'zone' to be valid initialised zone.
- *\li 'zone' to have a task.
- *\li 'target' to be != NULL && '*target' == NULL.
- */
-
-void
-dns_zone_notify(dns_zone_t *zone);
-/*%<
- * Generate notify events for this zone.
- *
- * Requires:
- *\li 'zone' to be a valid zone.
- */
-
-isc_result_t
-dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump);
-/*%<
- * Replace the database of "zone" with a new database "db".
- *
- * If "dump" is ISC_TRUE, then the new zone contents are dumped
- * into to the zone's master file for persistence. When replacing
- * a zone database by one just loaded from a master file, set
- * "dump" to ISC_FALSE to avoid a redundant redump of the data just
- * loaded. Otherwise, it should be set to ISC_TRUE.
- *
- * If the "diff-on-reload" option is enabled in the configuration file,
- * the differences between the old and the new database are added to the
- * journal file, and the master file dump is postponed.
- *
- * Requires:
- * \li 'zone' to be a valid zone.
- *
- * Returns:
- * \li DNS_R_SUCCESS
- * \li DNS_R_BADZONE zone failed basic consistency checks:
- * * a single SOA must exist
- * * some NS records must exist.
- * Others
- */
-
-isc_uint32_t
-dns_zone_getidlein(dns_zone_t *zone);
-/*%<
- * Requires:
- * \li 'zone' to be a valid zone.
- *
- * Returns:
- * \li number of seconds of idle time before we abort the transfer in.
- */
-
-void
-dns_zone_setidlein(dns_zone_t *zone, isc_uint32_t idlein);
-/*%<
- * \li Set the idle timeout for transfer the.
- * \li Zero set the default value, 1 hour.
- *
- * Requires:
- * \li 'zone' to be a valid zone.
- */
-
-isc_uint32_t
-dns_zone_getidleout(dns_zone_t *zone);
-/*%<
- *
- * Requires:
- * \li 'zone' to be a valid zone.
- *
- * Returns:
- * \li number of seconds of idle time before we abort a transfer out.
- */
-
-void
-dns_zone_setidleout(dns_zone_t *zone, isc_uint32_t idleout);
-/*%<
- * \li Set the idle timeout for transfers out.
- * \li Zero set the default value, 1 hour.
- *
- * Requires:
- * \li 'zone' to be a valid zone.
- */
-
-void
-dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table);
-/*%<
- * Get the simple-secure-update policy table.
- *
- * Requires:
- * \li 'zone' to be a valid zone.
- */
-
-void
-dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table);
-/*%<
- * Set / clear the simple-secure-update policy table.
- *
- * Requires:
- * \li 'zone' to be a valid zone.
- */
-
-isc_mem_t *
-dns_zone_getmctx(dns_zone_t *zone);
-/*%<
- * Get the memory context of a zone.
- *
- * Requires:
- * \li 'zone' to be a valid zone.
- */
-
-dns_zonemgr_t *
-dns_zone_getmgr(dns_zone_t *zone);
-/*%<
- * If 'zone' is managed return the zone manager otherwise NULL.
- *
- * Requires:
- * \li 'zone' to be a valid zone.
- */
-
-void
-dns_zone_setsigvalidityinterval(dns_zone_t *zone, isc_uint32_t interval);
-/*%<
- * Set the zone's RRSIG validity interval. This is the length of time
- * for which DNSSEC signatures created as a result of dynamic updates
- * to secure zones will remain valid, in seconds.
- *
- * Requires:
- * \li 'zone' to be a valid zone.
- */
-
-isc_uint32_t
-dns_zone_getsigvalidityinterval(dns_zone_t *zone);
-/*%<
- * Get the zone's RRSIG validity interval.
- *
- * Requires:
- * \li 'zone' to be a valid zone.
- */
-
-void
-dns_zone_setsigresigninginterval(dns_zone_t *zone, isc_uint32_t interval);
-/*%<
- * Set the zone's RRSIG re-signing interval. A dynamic zone's RRSIG's
- * will be re-signed 'interval' amount of time before they expire.
- *
- * Requires:
- * \li 'zone' to be a valid zone.
- */
-
-isc_uint32_t
-dns_zone_getsigresigninginterval(dns_zone_t *zone);
-/*%<
- * Get the zone's RRSIG re-signing interval.
- *
- * Requires:
- * \li 'zone' to be a valid zone.
- */
-
-void
-dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype);
-/*%<
- * Sets zone notify method to "notifytype"
- */
-
-isc_result_t
-dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg,
- dns_updatecallback_t callback, void *callback_arg);
-/*%<
- * Forward 'msg' to each master in turn until we get an answer or we
- * have exhausted the list of masters. 'callback' will be called with
- * ISC_R_SUCCESS if we get an answer and the returned message will be
- * passed as 'answer_message', otherwise a non ISC_R_SUCCESS result code
- * will be passed and answer_message will be NULL. The callback function
- * is responsible for destroying 'answer_message'.
- * (callback)(callback_arg, result, answer_message);
- *
- * Require:
- *\li 'zone' to be valid
- *\li 'msg' to be valid.
- *\li 'callback' to be non NULL.
- * Returns:
- *\li #ISC_R_SUCCESS if the message has been forwarded,
- *\li #ISC_R_NOMEMORY
- *\li Others
- */
-
-isc_result_t
-dns_zone_next(dns_zone_t *zone, dns_zone_t **next);
-/*%<
- * Find the next zone in the list of managed zones.
- *
- * Requires:
- *\li 'zone' to be valid
- *\li The zone manager for the indicated zone MUST be locked
- * by the caller. This is not checked.
- *\li 'next' be non-NULL, and '*next' be NULL.
- *
- * Ensures:
- *\li 'next' points to a valid zone (result ISC_R_SUCCESS) or to NULL
- * (result ISC_R_NOMORE).
- */
-
-
-
-isc_result_t
-dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first);
-/*%<
- * Find the first zone in the list of managed zones.
- *
- * Requires:
- *\li 'zonemgr' to be valid
- *\li The zone manager for the indicated zone MUST be locked
- * by the caller. This is not checked.
- *\li 'first' be non-NULL, and '*first' be NULL
- *
- * Ensures:
- *\li 'first' points to a valid zone (result ISC_R_SUCCESS) or to NULL
- * (result ISC_R_NOMORE).
- */
-
-isc_result_t
-dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory);
-/*%<
- * Sets the name of the directory where private keys used for
- * online signing of dynamic zones are found.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- *
- * Returns:
- *\li #ISC_R_NOMEMORY
- *\li #ISC_R_SUCCESS
- */
-
-const char *
-dns_zone_getkeydirectory(dns_zone_t *zone);
-/*%<
- * Gets the name of the directory where private keys used for
- * online signing of dynamic zones are found.
- *
- * Requires:
- *\li 'zone' to be valid initialised zone.
- *
- * Returns:
- * Pointer to null-terminated file name, or NULL.
- */
-
-
-isc_result_t
-dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
- isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
- dns_zonemgr_t **zmgrp);
-/*%<
- * Create a zone manager. Note: the zone manager will not be able to
- * manage any zones until dns_zonemgr_setsize() has been run.
- *
- * Requires:
- *\li 'mctx' to be a valid memory context.
- *\li 'taskmgr' to be a valid task manager.
- *\li 'timermgr' to be a valid timer manager.
- *\li 'zmgrp' to point to a NULL pointer.
- */
-
-isc_result_t
-dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones);
-/*%<
- * Set the size of the zone manager task pool. This must be run
- * before zmgr can be used for managing zones. Currently, it can only
- * be run once; the task pool cannot be resized.
- *
- * Requires:
- *\li zmgr is a valid zone manager.
- *\li zmgr->zonetasks has been initialized.
- */
-
-isc_result_t
-dns_zonemgr_createzone(dns_zonemgr_t *zmgr, dns_zone_t **zonep);
-/*%<
- * Allocate a new zone using a memory context from the
- * zone manager's memory context pool.
- *
- * Require:
- *\li 'zmgr' to be a valid zone manager.
- *\li 'zonep' != NULL and '*zonep' == NULL.
- */
-
-
-isc_result_t
-dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone);
-/*%<
- * Bring the zone under control of a zone manager.
- *
- * Require:
- *\li 'zmgr' to be a valid zone manager.
- *\li 'zone' to be a valid zone.
- */
-
-isc_result_t
-dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr);
-/*%<
- * Force zone maintenance of all zones managed by 'zmgr' at its
- * earliest convenience.
- */
-
-void
-dns__zonemgr_run(isc_task_t *task, isc_event_t *event);
-/*%<
- * Event handler to call dns_zonemgr_forcemaint(); used to start
- * zone operations from a unit test. Not intended for use outside
- * libdns or related tests.
- */
-
-void
-dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr);
-/*%<
- * Attempt to start any stalled zone transfers.
- */
-
-void
-dns_zonemgr_shutdown(dns_zonemgr_t *zmgr);
-/*%<
- * Shut down the zone manager.
- *
- * Requires:
- *\li 'zmgr' to be a valid zone manager.
- */
-
-void
-dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target);
-/*%<
- * Attach '*target' to 'source' incrementing its external
- * reference count.
- *
- * Require:
- *\li 'zone' to be a valid zone.
- *\li 'target' to be non NULL and '*target' to be NULL.
- */
-
-void
-dns_zonemgr_detach(dns_zonemgr_t **zmgrp);
-/*%<
- * Detach from a zone manager.
- *
- * Requires:
- *\li '*zmgrp' is a valid, non-NULL zone manager pointer.
- *
- * Ensures:
- *\li '*zmgrp' is NULL.
- */
-
-void
-dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone);
-/*%<
- * Release 'zone' from the managed by 'zmgr'. 'zmgr' is implicitly
- * detached from 'zone'.
- *
- * Requires:
- *\li 'zmgr' to be a valid zone manager.
- *\li 'zone' to be a valid zone.
- *\li 'zmgr' == 'zone->zmgr'
- *
- * Ensures:
- *\li 'zone->zmgr' == NULL;
- */
-
-void
-dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, isc_uint32_t value);
-/*%<
- * Set the maximum number of simultaneous transfers in allowed by
- * the zone manager.
- *
- * Requires:
- *\li 'zmgr' to be a valid zone manager.
- */
-
-isc_uint32_t
-dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr);
-/*%<
- * Return the maximum number of simultaneous transfers in allowed.
- *
- * Requires:
- *\li 'zmgr' to be a valid zone manager.
- */
-
-void
-dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, isc_uint32_t value);
-/*%<
- * Set the number of zone transfers allowed per nameserver.
- *
- * Requires:
- *\li 'zmgr' to be a valid zone manager
- */
-
-isc_uint32_t
-dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr);
-/*%<
- * Return the number of transfers allowed per nameserver.
- *
- * Requires:
- *\li 'zmgr' to be a valid zone manager.
- */
-
-void
-dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, isc_uint32_t iolimit);
-/*%<
- * Set the number of simultaneous file descriptors available for
- * reading and writing masterfiles.
- *
- * Requires:
- *\li 'zmgr' to be a valid zone manager.
- *\li 'iolimit' to be positive.
- */
-
-isc_uint32_t
-dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr);
-/*%<
- * Get the number of simultaneous file descriptors available for
- * reading and writing masterfiles.
- *
- * Requires:
- *\li 'zmgr' to be a valid zone manager.
- */
-
-void
-dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value);
-/*%<
- * Set the number of SOA queries sent per second.
- *
- * Requires:
- *\li 'zmgr' to be a valid zone manager
- */
-
-unsigned int
-dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr);
-/*%<
- * Return the number of SOA queries sent per second.
- *
- * Requires:
- *\li 'zmgr' to be a valid zone manager.
- */
-
-unsigned int
-dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state);
-/*%<
- * Returns the number of zones in the specified state.
- *
- * Requires:
- *\li 'zmgr' to be a valid zone manager.
- *\li 'state' to be a valid DNS_ZONESTATE_ constant.
- */
-
-void
-dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
- isc_sockaddr_t *local, isc_time_t *now);
-/*%<
- * Add the pair of addresses to the unreachable cache.
- *
- * Requires:
- *\li 'zmgr' to be a valid zone manager.
- *\li 'remote' to be a valid sockaddr.
- *\li 'local' to be a valid sockaddr.
- */
-
-isc_boolean_t
-dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
- isc_sockaddr_t *local, isc_time_t *now);
-/*%<
- * Returns ISC_TRUE if the given local/remote address pair
- * is found in the zone maanger's unreachable cache.
- *
- * Requires:
- *\li 'zmgr' to be a valid zone manager.
- *\li 'remote' to be a valid sockaddr.
- *\li 'local' to be a valid sockaddr.
- *\li 'now' != NULL
- */
-
-void
-dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
- isc_sockaddr_t *local);
-/*%<
- * Remove the pair of addresses from the unreachable cache.
- *
- * Requires:
- *\li 'zmgr' to be a valid zone manager.
- *\li 'remote' to be a valid sockaddr.
- *\li 'local' to be a valid sockaddr.
- */
-
-void
-dns_zone_forcereload(dns_zone_t *zone);
-/*%<
- * Force a reload of specified zone.
- *
- * Requires:
- *\li 'zone' to be a valid zone.
- */
-
-isc_boolean_t
-dns_zone_isforced(dns_zone_t *zone);
-/*%<
- * Check if the zone is waiting a forced reload.
- *
- * Requires:
- * \li 'zone' to be a valid zone.
- */
-
-isc_result_t
-dns_zone_setstatistics(dns_zone_t *zone, isc_boolean_t on);
-/*%<
- * This function is obsoleted by dns_zone_setrequeststats().
- */
-
-isc_uint64_t *
-dns_zone_getstatscounters(dns_zone_t *zone);
-/*%<
- * This function is obsoleted by dns_zone_getrequeststats().
- */
-
-void
-dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats);
-/*%<
- * Set a general zone-maintenance statistics set 'stats' for 'zone'. This
- * function is expected to be called only on zone creation (when necessary).
- * Once installed, it cannot be removed or replaced. Also, there is no
- * interface to get the installed stats from the zone; the caller must keep the
- * stats to reference (e.g. dump) it later.
- *
- * Requires:
- * \li 'zone' to be a valid zone and does not have a statistics set already
- * installed.
- *
- *\li stats is a valid statistics supporting zone statistics counters
- * (see dns/stats.h).
- */
-
-void
-dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats);
-
-void
-dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats);
-/*%<
- * Set additional statistics sets to zone. These are attached to the zone
- * but are not counted in the zone module; only the caller updates the
- * counters.
- *
- * Requires:
- * \li 'zone' to be a valid zone.
- *
- *\li stats is a valid statistics.
- */
-
-#ifdef NEWSTATS
-void
-dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats);
-#endif
-
-isc_stats_t *
-dns_zone_getrequeststats(dns_zone_t *zone);
-
-#ifdef NEWSTATS
-dns_stats_t *
-dns_zone_getrcvquerystats(dns_zone_t *zone);
-#endif
-
-/*%<
- * Get the additional statistics for zone, if one is installed.
- *
- * Requires:
- * \li 'zone' to be a valid zone.
- *
- * Returns:
- * \li when available, a pointer to the statistics set installed in zone;
- * otherwise NULL.
- */
-
-void
-dns_zone_dialup(dns_zone_t *zone);
-/*%<
- * Perform dialup-time maintenance on 'zone'.
- */
-
-void
-dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup);
-/*%<
- * Set the dialup type of 'zone' to 'dialup'.
- *
- * Requires:
- * \li 'zone' to be valid initialised zone.
- *\li 'dialup' to be a valid dialup type.
- */
-
-void
-dns_zone_log(dns_zone_t *zone, int level, const char *msg, ...)
- ISC_FORMAT_PRINTF(3, 4);
-/*%<
- * Log the message 'msg...' at 'level', including text that identifies
- * the message as applying to 'zone'.
- */
-
-void
-dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category, int level,
- const char *msg, ...) ISC_FORMAT_PRINTF(4, 5);
-/*%<
- * Log the message 'msg...' at 'level', including text that identifies
- * the message as applying to 'zone'.
- */
-
-void
-dns_zone_name(dns_zone_t *zone, char *buf, size_t len);
-/*%<
- * Return the name of the zone with class and view.
- *
- * Requires:
- *\li 'zone' to be valid.
- *\li 'buf' to be non NULL.
- */
-
-isc_result_t
-dns_zone_checknames(dns_zone_t *zone, dns_name_t *name, dns_rdata_t *rdata);
-/*%<
- * Check if this record meets the check-names policy.
- *
- * Requires:
- * 'zone' to be valid.
- * 'name' to be valid.
- * 'rdata' to be valid.
- *
- * Returns:
- * DNS_R_SUCCESS passed checks.
- * DNS_R_BADOWNERNAME failed ownername checks.
- * DNS_R_BADNAME failed rdata checks.
- */
-
-void
-dns_zone_setacache(dns_zone_t *zone, dns_acache_t *acache);
-/*%<
- * Associate the zone with an additional cache.
- *
- * Require:
- * 'zone' to be a valid zone.
- * 'acache' to be a non NULL pointer.
- *
- * Ensures:
- * 'zone' will have a reference to 'acache'
- */
-
-void
-dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx);
-/*%<
- * Set the post load integrity callback function 'checkmx'.
- * 'checkmx' will be called if the MX TARGET is not within the zone.
- *
- * Require:
- * 'zone' to be a valid zone.
- */
-
-void
-dns_zone_setchecksrv(dns_zone_t *zone, dns_checkmxfunc_t checksrv);
-/*%<
- * Set the post load integrity callback function 'checksrv'.
- * 'checksrv' will be called if the SRV TARGET is not within the zone.
- *
- * Require:
- * 'zone' to be a valid zone.
- */
-
-void
-dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns);
-/*%<
- * Set the post load integrity callback function 'checkns'.
- * 'checkns' will be called if the NS TARGET is not within the zone.
- *
- * Require:
- * 'zone' to be a valid zone.
- */
-
-void
-dns_zone_setnotifydelay(dns_zone_t *zone, isc_uint32_t delay);
-/*%<
- * Set the minimum delay between sets of notify messages.
- *
- * Requires:
- * 'zone' to be valid.
- */
-
-isc_uint32_t
-dns_zone_getnotifydelay(dns_zone_t *zone);
-/*%<
- * Get the minimum delay between sets of notify messages.
- *
- * Requires:
- * 'zone' to be valid.
- */
-
-void
-dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg);
-/*%<
- * Set the isself callback function and argument.
- *
- * isc_boolean_t
- * isself(dns_view_t *myview, dns_tsigkey_t *mykey, isc_netaddr_t *srcaddr,
- * isc_netaddr_t *destaddr, dns_rdataclass_t rdclass, void *arg);
- *
- * 'isself' returns ISC_TRUE if a non-recursive query from 'srcaddr' to
- * 'destaddr' with optional key 'mykey' for class 'rdclass' would be
- * delivered to 'myview'.
- */
-
-void
-dns_zone_setnodes(dns_zone_t *zone, isc_uint32_t nodes);
-/*%<
- * Set the number of nodes that will be checked per quantum.
- */
-
-void
-dns_zone_setsignatures(dns_zone_t *zone, isc_uint32_t signatures);
-/*%<
- * Set the number of signatures that will be generated per quantum.
- */
-
-isc_result_t
-dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
- isc_uint16_t keyid, isc_boolean_t deleteit);
-/*%<
- * Initiate/resume signing of the entire zone with the zone DNSKEY(s)
- * that match the given algorithm and keyid.
- */
-
-isc_result_t
-dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param);
-/*%<
- * Incrementally add a NSEC3 chain that corresponds to 'nsec3param'.
- */
-
-void
-dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type);
-dns_rdatatype_t
-dns_zone_getprivatetype(dns_zone_t *zone);
-/*
- * Get/Set the private record type. It is expected that these interfaces
- * 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_boolean_t
-dns_zone_isdynamic(dns_zone_t *zone, isc_boolean_t ignore_freeze);
-/*%
- * Return true iff the zone is "dynamic", in the sense that the zone's
- * master file (if any) is written by the server, rather than being
- * updated manually and read by the server.
- *
- * This is true for slave zones, stub zones, key zones, and zones that
- * allow dynamic updates either by having an update policy ("ssutable")
- * or an "allow-update" ACL with a value other than exactly "{ none; }".
- *
- * If 'ignore_freeze' is true, then the zone which has had updates disabled
- * will still report itself to be dynamic.
- *
- * Requires:
- * \li 'zone' to be valid.
- */
-
-isc_result_t
-dns_zone_setrefreshkeyinterval(dns_zone_t *zone, isc_uint32_t interval);
-/*%
- * Sets the frequency, in minutes, with which the key repository will be
- * checked to see if the keys for this zone have been updated. Any value
- * higher than 1440 minutes (24 hours) will be silently reduced. A
- * value of zero will return an out-of-range error.
- *
- * Requires:
- * \li 'zone' to be valid.
- */
-
-isc_boolean_t
-dns_zone_getrequestixfr(dns_zone_t *zone);
-/*%
- * Returns the true/false value of the request-ixfr option in the zone.
- *
- * Requires:
- * \li 'zone' to be valid.
- */
-
-void
-dns_zone_setrequestixfr(dns_zone_t *zone, isc_boolean_t flag);
-/*%
- * Sets the request-ixfr option for the zone. Either true or false. The
- * default value is determined by the setting of this option in the view.
- *
- * Requires:
- * \li 'zone' to be valid.
- */
-
-void
-dns_zone_setserialupdatemethod(dns_zone_t *zone, dns_updatemethod_t method);
-/*%
- * Sets the update method to use when incrementing the zone serial number
- * due to a DDNS update. Valid options are dns_updatemethod_increment
- * and dns_updatemethod_unixtime.
- *
- * Requires:
- * \li 'zone' to be valid.
- */
-
-dns_updatemethod_t
-dns_zone_getserialupdatemethod(dns_zone_t *zone);
-/*%
- * Returns the update method to be used when incrementing the zone serial
- * number due to a DDNS update.
- *
- * Requires:
- * \li 'zone' to be valid.
- */
-
-isc_result_t
-dns_zone_link(dns_zone_t *zone, dns_zone_t *raw);
-
-void
-dns_zone_getraw(dns_zone_t *zone, dns_zone_t **raw);
-
-isc_result_t
-dns_zone_keydone(dns_zone_t *zone, const char *data);
-
-isc_result_t
-dns_zone_setnsec3param(dns_zone_t *zone, isc_uint8_t hash, isc_uint8_t flags,
- isc_uint16_t iter, isc_uint8_t saltlen,
- unsigned char *salt, isc_boolean_t replace);
-/*%
- * Set the NSEC3 parameters for the zone.
- *
- * If 'replace' is ISC_TRUE, then the existing NSEC3 chain, if any, will
- * be replaced with the new one. If 'hash' is zero, then the replacement
- * chain will be NSEC rather than NSEC3.
- *
- * Requires:
- * \li 'zone' to be valid.
- */
-
-void
-dns_zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header);
-/*%
- * Set the data to be included in the header when the zone is dumped in
- * binary format.
- */
-
-isc_result_t
-dns_zone_synckeyzone(dns_zone_t *zone);
-/*%
- * Force the managed key zone to synchronize, and start the key
- * maintenance timer.
- */
-
-isc_result_t
-dns_zone_rpz_enable(dns_zone_t *zone);
-/*%
- * Set the response policy associated with a zone.
- */
-
-isc_boolean_t
-dns_zone_get_rpz(dns_zone_t *zone);
-
-void
-dns_zone_setstatlevel(dns_zone_t *zone, dns_zonestat_level_t level);
-
-dns_zonestat_level_t
-dns_zone_getstatlevel(dns_zone_t *zone);
-/*%
- * Set and get the statistics reporting level for the zone;
- * full, terse, or none.
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_ZONE_H */
diff --git a/contrib/bind9/lib/dns/include/dns/zonekey.h b/contrib/bind9/lib/dns/include/dns/zonekey.h
deleted file mode 100644
index d9ba86259fbd..000000000000
--- a/contrib/bind9/lib/dns/include/dns/zonekey.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: zonekey.h,v 1.10 2007/06/19 23:47:17 tbox Exp $ */
-
-#ifndef DNS_ZONEKEY_H
-#define DNS_ZONEKEY_H 1
-
-/*! \file dns/zonekey.h */
-
-#include <isc/lang.h>
-
-#include <dns/types.h>
-
-ISC_LANG_BEGINDECLS
-
-isc_boolean_t
-dns_zonekey_iszonekey(dns_rdata_t *keyrdata);
-/*%<
- * Determines if the key record contained in the rdata is a zone key.
- *
- * Requires:
- * 'keyrdata' is not NULL.
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_ZONEKEY_H */
diff --git a/contrib/bind9/lib/dns/include/dns/zt.h b/contrib/bind9/lib/dns/include/dns/zt.h
deleted file mode 100644
index f91d7e8dbe0f..000000000000
--- a/contrib/bind9/lib/dns/include/dns/zt.h
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright (C) 2004-2007, 2011 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2002 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: zt.h,v 1.40 2011/09/02 23:46:32 tbox Exp $ */
-
-#ifndef DNS_ZT_H
-#define DNS_ZT_H 1
-
-/*! \file dns/zt.h */
-
-#include <isc/lang.h>
-
-#include <dns/types.h>
-
-#define DNS_ZTFIND_NOEXACT 0x01
-
-ISC_LANG_BEGINDECLS
-
-typedef isc_result_t
-(*dns_zt_allloaded_t)(void *arg);
-/*%<
- * Method prototype: when all pending zone loads are complete,
- * the zone table can inform the caller via a callback function with
- * this signature.
- */
-
-typedef isc_result_t
-(*dns_zt_zoneloaded_t)(dns_zt_t *zt, dns_zone_t *zone, isc_task_t *task);
-/*%<
- * Method prototype: when a zone finishes loading, the zt object
- * can be informed via a callback function with this signature.
- */
-
-isc_result_t
-dns_zt_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_zt_t **zt);
-/*%<
- * Creates a new zone table.
- *
- * Requires:
- * \li 'mctx' to be initialized.
- *
- * Returns:
- * \li #ISC_R_SUCCESS on success.
- * \li #ISC_R_NOMEMORY
- */
-
-isc_result_t
-dns_zt_mount(dns_zt_t *zt, dns_zone_t *zone);
-/*%<
- * Mounts the zone on the zone table.
- *
- * Requires:
- * \li 'zt' to be valid
- * \li 'zone' to be valid
- *
- * Returns:
- * \li #ISC_R_SUCCESS
- * \li #ISC_R_EXISTS
- * \li #ISC_R_NOSPACE
- * \li #ISC_R_NOMEMORY
- */
-
-isc_result_t
-dns_zt_unmount(dns_zt_t *zt, dns_zone_t *zone);
-/*%<
- * Unmount the given zone from the table.
- *
- * Requires:
- * 'zt' to be valid
- * \li 'zone' to be valid
- *
- * Returns:
- * \li #ISC_R_SUCCESS
- * \li #ISC_R_NOTFOUND
- * \li #ISC_R_NOMEMORY
- */
-
-isc_result_t
-dns_zt_find(dns_zt_t *zt, dns_name_t *name, unsigned int options,
- dns_name_t *foundname, dns_zone_t **zone);
-/*%<
- * Find the best match for 'name' in 'zt'. If foundname is non NULL
- * then the name of the zone found is returned.
- *
- * Notes:
- * \li If the DNS_ZTFIND_NOEXACT is set, the best partial match (if any)
- * to 'name' will be returned.
- *
- * Requires:
- * \li 'zt' to be valid
- * \li 'name' to be valid
- * \li 'foundname' to be initialized and associated with a fixedname or NULL
- * \li 'zone' to be non NULL and '*zone' to be NULL
- *
- * Returns:
- * \li #ISC_R_SUCCESS
- * \li #DNS_R_PARTIALMATCH
- * \li #ISC_R_NOTFOUND
- * \li #ISC_R_NOSPACE
- */
-
-void
-dns_zt_detach(dns_zt_t **ztp);
-/*%<
- * Detach the given zonetable, if the reference count goes to zero the
- * zonetable will be freed. In either case 'ztp' is set to NULL.
- *
- * Requires:
- * \li '*ztp' to be valid
- */
-
-void
-dns_zt_flushanddetach(dns_zt_t **ztp);
-/*%<
- * Detach the given zonetable, if the reference count goes to zero the
- * zonetable will be flushed and then freed. In either case 'ztp' is
- * set to NULL.
- *
- * Requires:
- * \li '*ztp' to be valid
- */
-
-void
-dns_zt_attach(dns_zt_t *zt, dns_zt_t **ztp);
-/*%<
- * Attach 'zt' to '*ztp'.
- *
- * Requires:
- * \li 'zt' to be valid
- * \li '*ztp' to be NULL
- */
-
-isc_result_t
-dns_zt_load(dns_zt_t *zt, isc_boolean_t stop);
-
-isc_result_t
-dns_zt_loadnew(dns_zt_t *zt, isc_boolean_t stop);
-
-isc_result_t
-dns_zt_asyncload(dns_zt_t *zt, dns_zt_allloaded_t alldone, void *arg);
-/*%<
- * Load all zones in the table. If 'stop' is ISC_TRUE,
- * stop on the first error and return it. If 'stop'
- * is ISC_FALSE, ignore errors.
- *
- * dns_zt_loadnew() only loads zones that are not yet loaded.
- * dns_zt_load() also loads zones that are already loaded and
- * and whose master file has changed since the last load.
- * dns_zt_asyncload() loads zones asynchronously; when all
- * zones in the zone table have finished loaded (or failed due
- * to errors), the caller is informed by calling 'alldone'
- * with an argument of 'arg'.
- *
- * Requires:
- * \li 'zt' to be valid
- */
-
-isc_result_t
-dns_zt_freezezones(dns_zt_t *zt, isc_boolean_t freeze);
-/*%<
- * Freeze/thaw updates to master zones.
- * Any pending updates will be flushed.
- * Zones will be reloaded on thaw.
- */
-
-isc_result_t
-dns_zt_apply(dns_zt_t *zt, isc_boolean_t stop,
- isc_result_t (*action)(dns_zone_t *, void *), void *uap);
-
-isc_result_t
-dns_zt_apply2(dns_zt_t *zt, isc_boolean_t stop, isc_result_t *sub,
- isc_result_t (*action)(dns_zone_t *, void *), void *uap);
-/*%<
- * Apply a given 'action' to all zone zones in the table.
- * If 'stop' is 'ISC_TRUE' then walking the zone tree will stop if
- * 'action' does not return ISC_R_SUCCESS.
- *
- * Requires:
- * \li 'zt' to be valid.
- * \li 'action' to be non NULL.
- *
- * Returns:
- * \li ISC_R_SUCCESS if action was applied to all nodes. If 'stop' is
- * ISC_FALSE and 'sub' is non NULL then the first error (if any)
- * reported by 'action' is returned in '*sub';
- * any error code from 'action'.
- */
-
-isc_boolean_t
-dns_zt_loadspending(dns_zt_t *zt);
-/*%<
- * Returns ISC_TRUE if and only if there are zones still waiting to
- * be loaded in zone table 'zt'.
- *
- * Requires:
- * \li 'zt' to be valid.
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_ZT_H */
diff --git a/contrib/bind9/lib/dns/include/dst/Makefile.in b/contrib/bind9/lib/dns/include/dst/Makefile.in
deleted file mode 100644
index cece67dd33a0..000000000000
--- a/contrib/bind9/lib/dns/include/dst/Makefile.in
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
-# Copyright (C) 1998-2001 Internet Software Consortium.
-#
-# Permission to use, copy, modify, and/or distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-# PERFORMANCE OF THIS SOFTWARE.
-
-# $Id: Makefile.in,v 1.4 2007/12/11 20:28:55 marka Exp $
-
-srcdir = @srcdir@
-VPATH = @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}${includedir}/dst
-
-install:: installdirs
- for i in ${HEADERS}; do \
- ${INSTALL_DATA} ${srcdir}/$$i ${DESTDIR}${includedir}/dst ; \
- done
diff --git a/contrib/bind9/lib/dns/include/dst/dst.h b/contrib/bind9/lib/dns/include/dst/dst.h
deleted file mode 100644
index 4724fc64c95e..000000000000
--- a/contrib/bind9/lib/dns/include/dst/dst.h
+++ /dev/null
@@ -1,929 +0,0 @@
-/*
- * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2000-2002 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: dst.h,v 1.34 2011/10/20 21:20:02 marka Exp $ */
-
-#ifndef DST_DST_H
-#define DST_DST_H 1
-
-/*! \file dst/dst.h */
-
-#include <isc/lang.h>
-#include <isc/stdtime.h>
-
-#include <dns/types.h>
-#include <dns/log.h>
-#include <dns/name.h>
-#include <dns/secalg.h>
-
-#include <dst/gssapi.h>
-
-ISC_LANG_BEGINDECLS
-
-/***
- *** Types
- ***/
-
-/*%
- * The dst_key structure is opaque. Applications should use the accessor
- * functions provided to retrieve key attributes. If an application needs
- * to set attributes, new accessor functions will be written.
- */
-
-typedef struct dst_key dst_key_t;
-typedef struct dst_context dst_context_t;
-
-/* DST algorithm codes */
-#define DST_ALG_UNKNOWN 0
-#define DST_ALG_RSAMD5 1
-#define DST_ALG_RSA DST_ALG_RSAMD5 /*%< backwards compatibility */
-#define DST_ALG_DH 2
-#define DST_ALG_DSA 3
-#define DST_ALG_ECC 4
-#define DST_ALG_RSASHA1 5
-#define DST_ALG_NSEC3DSA 6
-#define DST_ALG_NSEC3RSASHA1 7
-#define DST_ALG_RSASHA256 8
-#define DST_ALG_RSASHA512 10
-#define DST_ALG_ECCGOST 12
-#define DST_ALG_ECDSA256 13
-#define DST_ALG_ECDSA384 14
-#define DST_ALG_HMACMD5 157
-#define DST_ALG_GSSAPI 160
-#define DST_ALG_HMACSHA1 161 /* XXXMPA */
-#define DST_ALG_HMACSHA224 162 /* XXXMPA */
-#define DST_ALG_HMACSHA256 163 /* XXXMPA */
-#define DST_ALG_HMACSHA384 164 /* XXXMPA */
-#define DST_ALG_HMACSHA512 165 /* XXXMPA */
-#define DST_ALG_PRIVATE 254
-#define DST_ALG_EXPAND 255
-#define DST_MAX_ALGS 255
-
-/*% A buffer of this size is large enough to hold any key */
-#define DST_KEY_MAXSIZE 1280
-
-/*%
- * A buffer of this size is large enough to hold the textual representation
- * of any key
- */
-#define DST_KEY_MAXTEXTSIZE 2048
-
-/*% 'Type' for dst_read_key() */
-#define DST_TYPE_KEY 0x1000000 /* KEY key */
-#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.
- *
- * Requires:
- * \li "mctx" is a valid memory context
- * \li "ectx" is a valid entropy context
- *
- * Returns:
- * \li ISC_R_SUCCESS
- * \li ISC_R_NOMEMORY
- * \li DST_R_NOENGINE
- *
- * Ensures:
- * \li DST is properly initialized.
- */
-
-void
-dst_lib_destroy(void);
-/*%<
- * Releases all resources allocated by DST.
- */
-
-isc_boolean_t
-dst_algorithm_supported(unsigned int alg);
-/*%<
- * Checks that a given algorithm is supported by DST.
- *
- * Returns:
- * \li ISC_TRUE
- * \li ISC_FALSE
- */
-
-isc_result_t
-dst_context_create(dst_key_t *key, isc_mem_t *mctx, dst_context_t **dctxp);
-
-isc_result_t
-dst_context_create2(dst_key_t *key, isc_mem_t *mctx,
- isc_logcategory_t *category, dst_context_t **dctxp);
-
-/*%<
- * Creates a context to be used for a sign or verify operation.
- *
- * Requires:
- * \li "key" is a valid key.
- * \li "mctx" is a valid memory context.
- * \li dctxp != NULL && *dctxp == NULL
- *
- * Returns:
- * \li ISC_R_SUCCESS
- * \li ISC_R_NOMEMORY
- *
- * Ensures:
- * \li *dctxp will contain a usable context.
- */
-
-void
-dst_context_destroy(dst_context_t **dctxp);
-/*%<
- * Destroys all memory associated with a context.
- *
- * Requires:
- * \li *dctxp != NULL && *dctxp == NULL
- *
- * Ensures:
- * \li *dctxp == NULL
- */
-
-isc_result_t
-dst_context_adddata(dst_context_t *dctx, const isc_region_t *data);
-/*%<
- * Incrementally adds data to the context to be used in a sign or verify
- * operation.
- *
- * Requires:
- * \li "dctx" is a valid context
- * \li "data" is a valid region
- *
- * Returns:
- * \li ISC_R_SUCCESS
- * \li DST_R_SIGNFAILURE
- * \li all other errors indicate failure
- */
-
-isc_result_t
-dst_context_sign(dst_context_t *dctx, isc_buffer_t *sig);
-/*%<
- * Computes a signature using the data and key stored in the context.
- *
- * Requires:
- * \li "dctx" is a valid context.
- * \li "sig" is a valid buffer.
- *
- * Returns:
- * \li ISC_R_SUCCESS
- * \li DST_R_VERIFYFAILURE
- * \li all other errors indicate failure
- *
- * Ensures:
- * \li "sig" will contain the signature
- */
-
-isc_result_t
-dst_context_verify(dst_context_t *dctx, isc_region_t *sig);
-
-isc_result_t
-dst_context_verify2(dst_context_t *dctx, unsigned int maxbits,
- isc_region_t *sig);
-/*%<
- * Verifies the signature using the data and key stored in the context.
- *
- * 'maxbits' specifies the maximum number of bits permitted in the RSA
- * exponent.
- *
- * Requires:
- * \li "dctx" is a valid context.
- * \li "sig" is a valid region.
- *
- * Returns:
- * \li ISC_R_SUCCESS
- * \li all other errors indicate failure
- *
- * Ensures:
- * \li "sig" will contain the signature
- */
-
-isc_result_t
-dst_key_computesecret(const dst_key_t *pub, const dst_key_t *priv,
- isc_buffer_t *secret);
-/*%<
- * Computes a shared secret from two (Diffie-Hellman) keys.
- *
- * Requires:
- * \li "pub" is a valid key that can be used to derive a shared secret
- * \li "priv" is a valid private key that can be used to derive a shared secret
- * \li "secret" is a valid buffer
- *
- * Returns:
- * \li ISC_R_SUCCESS
- * \li any other result indicates failure
- *
- * Ensures:
- * \li If successful, secret will contain the derived shared secret.
- */
-
-isc_result_t
-dst_key_fromfile(dns_name_t *name, dns_keytag_t id, unsigned int alg, int type,
- const char *directory, isc_mem_t *mctx, dst_key_t **keyp);
-/*%<
- * Reads a key from permanent storage. The key can either be a public or
- * private key, and is specified by name, algorithm, and id. If a private key
- * is specified, the public key must also be present. If directory is NULL,
- * the current directory is assumed.
- *
- * Requires:
- * \li "name" is a valid absolute dns name.
- * \li "id" is a valid key tag identifier.
- * \li "alg" is a supported key algorithm.
- * \li "type" is DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or the bitwise union.
- * DST_TYPE_KEY look for a KEY record otherwise DNSKEY
- * \li "mctx" is a valid memory context.
- * \li "keyp" is not NULL and "*keyp" is NULL.
- *
- * Returns:
- * \li ISC_R_SUCCESS
- * \li any other result indicates failure
- *
- * Ensures:
- * \li If successful, *keyp will contain a valid key.
- */
-
-isc_result_t
-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
- * DST_TYPE_KEY look for a KEY record otherwise DNSKEY
- * \li "mctx" is a valid memory context
- * \li "keyp" is not NULL and "*keyp" is NULL.
- *
- * Returns:
- * \li ISC_R_SUCCESS
- * \li any other result indicates failure
- *
- * Ensures:
- * \li If successful, *keyp will contain a valid key.
- */
-
-
-isc_result_t
-dst_key_read_public(const char *filename, int type,
- isc_mem_t *mctx, dst_key_t **keyp);
-/*%<
- * Reads a public key from permanent storage. The key must be a public key.
- *
- * Requires:
- * \li "filename" is not NULL
- * \li "type" is DST_TYPE_KEY look for a KEY record otherwise DNSKEY
- * \li "mctx" is a valid memory context
- * \li "keyp" is not NULL and "*keyp" is NULL.
- *
- * Returns:
- * \li ISC_R_SUCCESS
- * \li DST_R_BADKEYTYPE if the key type is not the expected one
- * \li ISC_R_UNEXPECTEDTOKEN if the file can not be parsed as a public key
- * \li any other result indicates failure
- *
- * Ensures:
- * \li If successful, *keyp will contain a valid key.
- */
-
-isc_result_t
-dst_key_tofile(const dst_key_t *key, int type, const char *directory);
-/*%<
- * Writes a key to permanent storage. The key can either be a public or
- * private key. Public keys are written in DNS format and private keys
- * are written as a set of base64 encoded values. If directory is NULL,
- * the current directory is assumed.
- *
- * Requires:
- * \li "key" is a valid key.
- * \li "type" is DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or the bitwise union
- *
- * Returns:
- * \li ISC_R_SUCCESS
- * \li any other result indicates failure
- */
-
-isc_result_t
-dst_key_fromdns(dns_name_t *name, dns_rdataclass_t rdclass,
- isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp);
-/*%<
- * Converts a DNS KEY record into a DST key.
- *
- * Requires:
- * \li "name" is a valid absolute dns name.
- * \li "source" is a valid buffer. There must be at least 4 bytes available.
- * \li "mctx" is a valid memory context.
- * \li "keyp" is not NULL and "*keyp" is NULL.
- *
- * Returns:
- * \li ISC_R_SUCCESS
- * \li any other result indicates failure
- *
- * Ensures:
- * \li If successful, *keyp will contain a valid key, and the consumed
- * pointer in data will be advanced.
- */
-
-isc_result_t
-dst_key_todns(const dst_key_t *key, isc_buffer_t *target);
-/*%<
- * Converts a DST key into a DNS KEY record.
- *
- * Requires:
- * \li "key" is a valid key.
- * \li "target" is a valid buffer. There must be at least 4 bytes unused.
- *
- * Returns:
- * \li ISC_R_SUCCESS
- * \li any other result indicates failure
- *
- * Ensures:
- * \li If successful, the used pointer in 'target' is advanced by at least 4.
- */
-
-isc_result_t
-dst_key_frombuffer(dns_name_t *name, unsigned int alg,
- unsigned int flags, unsigned int protocol,
- dns_rdataclass_t rdclass,
- isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp);
-/*%<
- * Converts a buffer containing DNS KEY RDATA into a DST key.
- *
- * Requires:
- *\li "name" is a valid absolute dns name.
- *\li "alg" is a supported key algorithm.
- *\li "source" is a valid buffer.
- *\li "mctx" is a valid memory context.
- *\li "keyp" is not NULL and "*keyp" is NULL.
- *
- * Returns:
- *\li ISC_R_SUCCESS
- * \li any other result indicates failure
- *
- * Ensures:
- *\li If successful, *keyp will contain a valid key, and the consumed
- * pointer in source will be advanced.
- */
-
-isc_result_t
-dst_key_tobuffer(const dst_key_t *key, isc_buffer_t *target);
-/*%<
- * Converts a DST key into DNS KEY RDATA format.
- *
- * Requires:
- *\li "key" is a valid key.
- *\li "target" is a valid buffer.
- *
- * Returns:
- *\li ISC_R_SUCCESS
- * \li any other result indicates failure
- *
- * Ensures:
- *\li If successful, the used pointer in 'target' is advanced.
- */
-
-isc_result_t
-dst_key_privatefrombuffer(dst_key_t *key, isc_buffer_t *buffer);
-/*%<
- * Converts a public key into a private key, reading the private key
- * information from the buffer. The buffer should contain the same data
- * as the .private key file would.
- *
- * Requires:
- *\li "key" is a valid public key.
- *\li "buffer" is not NULL.
- *
- * Returns:
- *\li ISC_R_SUCCESS
- * \li any other result indicates failure
- *
- * Ensures:
- *\li If successful, key will contain a valid private key.
- */
-
-gss_ctx_id_t
-dst_key_getgssctx(const dst_key_t *key);
-/*%<
- * Returns the opaque key data.
- * Be cautions when using this value unless you know what you are doing.
- *
- * Requires:
- *\li "key" is not NULL.
- *
- * Returns:
- *\li gssctx key data, possibly NULL.
- */
-
-isc_result_t
-dst_key_fromgssapi(dns_name_t *name, gss_ctx_id_t gssctx, isc_mem_t *mctx,
- dst_key_t **keyp, isc_region_t *intoken);
-/*%<
- * Converts a GSSAPI opaque context id into a DST key.
- *
- * Requires:
- *\li "name" is a valid absolute dns name.
- *\li "gssctx" is a GSSAPI context id.
- *\li "mctx" is a valid memory context.
- *\li "keyp" is not NULL and "*keyp" is NULL.
- *
- * Returns:
- *\li ISC_R_SUCCESS
- * \li any other result indicates failure
- *
- * Ensures:
- *\li If successful, *keyp will contain a valid key and be responsible for
- * the context id.
- */
-
-#ifdef DST_KEY_INTERNAL
-isc_result_t
-dst_key_buildinternal(dns_name_t *name, unsigned int alg,
- unsigned int bits, unsigned int flags,
- unsigned int protocol, dns_rdataclass_t rdclass,
- void *data, isc_mem_t *mctx, dst_key_t **keyp);
-#endif
-
-isc_result_t
-dst_key_fromlabel(dns_name_t *name, int alg, unsigned int flags,
- unsigned int protocol, dns_rdataclass_t rdclass,
- const char *engine, const char *label, const char *pin,
- isc_mem_t *mctx, dst_key_t **keyp);
-
-isc_result_t
-dst_key_generate(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);
-
-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:
- * \code
- * RSA: exponent
- * 0 use exponent 3
- * !0 use Fermat4 (2^16 + 1)
- * DH: generator
- * 0 default - use well known prime if bits == 768 or 1024,
- * otherwise use 2 as the generator.
- * !0 use this value as the generator.
- * DSA: unused
- * HMACMD5: entropy
- * 0 default - require good entropy
- * !0 lack of good entropy is ok
- *\endcode
- *
- * Requires:
- *\li "name" is a valid absolute dns name.
- *\li "keyp" is not NULL and "*keyp" is NULL.
- *
- * Returns:
- *\li ISC_R_SUCCESS
- * \li any other result indicates failure
- *
- * Ensures:
- *\li If successful, *keyp will contain a valid key.
- */
-
-isc_boolean_t
-dst_key_compare(const dst_key_t *key1, const dst_key_t *key2);
-/*%<
- * 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.
- *\li "key2" is a valid key.
- *
- * Returns:
- *\li ISC_TRUE
- * \li ISC_FALSE
- */
-
-isc_boolean_t
-dst_key_paramcompare(const dst_key_t *key1, const dst_key_t *key2);
-/*%<
- * Compares the parameters of two DST keys. This is used to determine if
- * two (Diffie-Hellman) keys can be used to derive a shared secret.
- *
- * Requires:
- *\li "key1" is a valid key.
- *\li "key2" is a valid key.
- *
- * Returns:
- *\li ISC_TRUE
- * \li ISC_FALSE
- */
-
-void
-dst_key_attach(dst_key_t *source, dst_key_t **target);
-/*
- * Attach to a existing key increasing the reference count.
- *
- * Requires:
- *\li 'source' to be a valid key.
- *\li 'target' to be non-NULL and '*target' to be NULL.
- */
-
-void
-dst_key_free(dst_key_t **keyp);
-/*%<
- * 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.
- *\li *keyp == NULL
- */
-
-/*%<
- * Accessor functions to obtain key fields.
- *
- * Require:
- *\li "key" is a valid key.
- */
-dns_name_t *
-dst_key_name(const dst_key_t *key);
-
-unsigned int
-dst_key_size(const dst_key_t *key);
-
-unsigned int
-dst_key_proto(const dst_key_t *key);
-
-unsigned int
-dst_key_alg(const dst_key_t *key);
-
-isc_uint32_t
-dst_key_flags(const dst_key_t *key);
-
-dns_keytag_t
-dst_key_id(const dst_key_t *key);
-
-dns_keytag_t
-dst_key_rid(const dst_key_t *key);
-
-dns_rdataclass_t
-dst_key_class(const dst_key_t *key);
-
-isc_boolean_t
-dst_key_isprivate(const dst_key_t *key);
-
-isc_boolean_t
-dst_key_iszonekey(const dst_key_t *key);
-
-isc_boolean_t
-dst_key_isnullkey(const dst_key_t *key);
-
-isc_result_t
-dst_key_buildfilename(const dst_key_t *key, int type,
- const char *directory, isc_buffer_t *out);
-/*%<
- * Generates the filename used by dst to store the specified key.
- * If directory is NULL, the current directory is assumed.
- *
- * Requires:
- *\li "key" is a valid key
- *\li "type" is either DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or 0 for no suffix.
- *\li "out" is a valid buffer
- *
- * Ensures:
- *\li the file name will be written to "out", and the used pointer will
- * be advanced.
- */
-
-isc_result_t
-dst_key_sigsize(const dst_key_t *key, unsigned int *n);
-/*%<
- * Computes the size of a signature generated by the given key.
- *
- * Requires:
- *\li "key" is a valid key.
- *\li "n" is not NULL
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li DST_R_UNSUPPORTEDALG
- *
- * Ensures:
- *\li "n" stores the size of a generated signature
- */
-
-isc_result_t
-dst_key_secretsize(const dst_key_t *key, unsigned int *n);
-/*%<
- * Computes the size of a shared secret generated by the given key.
- *
- * Requires:
- *\li "key" is a valid key.
- *\li "n" is not NULL
- *
- * Returns:
- *\li #ISC_R_SUCCESS
- *\li DST_R_UNSUPPORTEDALG
- *
- * Ensures:
- *\li "n" stores the size of a generated shared secret
- */
-
-isc_uint16_t
-dst_region_computeid(const isc_region_t *source, unsigned int alg);
-isc_uint16_t
-dst_region_computerid(const isc_region_t *source, unsigned int alg);
-/*%<
- * Computes the (revoked) key id of the key stored in the provided
- * region with the given algorithm.
- *
- * Requires:
- *\li "source" contains a valid, non-NULL region.
- *
- * Returns:
- *\li the key id
- */
-
-isc_uint16_t
-dst_key_getbits(const dst_key_t *key);
-/*%<
- * Get the number of digest bits required (0 == MAX).
- *
- * Requires:
- * "key" is a valid 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.
- */
-
-void
-dst_key_setttl(dst_key_t *key, dns_ttl_t ttl);
-/*%<
- * Set the default TTL to use when converting the key
- * to a KEY or DNSKEY RR.
- *
- * Requires:
- * "key" is a valid key.
- */
-
-dns_ttl_t
-dst_key_getttl(const dst_key_t *key);
-/*%<
- * Get the default TTL to use when converting the key
- * to a KEY or DNSKEY RR.
- *
- * Requires:
- * "key" is a valid key.
- */
-
-isc_result_t
-dst_key_setflags(dst_key_t *key, isc_uint32_t flags);
-/*
- * 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.
- *
- * Requires:
- * "key" is a valid key.
- */
-
-
-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/contrib/bind9/lib/dns/include/dst/gssapi.h b/contrib/bind9/lib/dns/include/dst/gssapi.h
deleted file mode 100644
index 1e81a55b9718..000000000000
--- a/contrib/bind9/lib/dns/include/dst/gssapi.h
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: gssapi.h,v 1.16 2011/01/08 23:47:01 tbox Exp $ */
-
-#ifndef DST_GSSAPI_H
-#define DST_GSSAPI_H 1
-
-/*! \file dst/gssapi.h */
-
-#include <isc/formatcheck.h>
-#include <isc/lang.h>
-#include <isc/platform.h>
-#include <isc/types.h>
-#include <dns/types.h>
-
-#ifdef GSSAPI
-#ifdef _WINDOWS
-/*
- * 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)
-#endif
-#endif
-
-ISC_LANG_BEGINDECLS
-
-/***
- *** Types
- ***/
-
-/***
- *** Functions
- ***/
-
-isc_result_t
-dst_gssapi_acquirecred(dns_name_t *name, isc_boolean_t initiate,
- gss_cred_id_t *cred);
-/*
- * Acquires GSS credentials.
- *
- * Requires:
- * 'name' is a valid name, preferably one known by the GSS provider
- * 'initiate' indicates whether the credentials are for initiating or
- * accepting contexts
- * 'cred' is a pointer to NULL, which will be allocated with the
- * credential handle. Call dst_gssapi_releasecred to free
- * the memory.
- *
- * Returns:
- * ISC_R_SUCCESS msg was successfully updated to include the
- * query to be sent
- * other an error occurred while building the message
- */
-
-isc_result_t
-dst_gssapi_releasecred(gss_cred_id_t *cred);
-/*
- * Releases GSS credentials. Calling this function does release the
- * memory allocated for the credential in dst_gssapi_acquirecred()
- *
- * Requires:
- * 'mctx' is a valid memory context
- * 'cred' is a pointer to the credential to be released
- *
- * Returns:
- * ISC_R_SUCCESS credential was released successfully
- * other an error occurred while releaseing
- * the credential
- */
-
-isc_result_t
-dst_gssapi_initctx(dns_name_t *name, isc_buffer_t *intoken,
- isc_buffer_t *outtoken, gss_ctx_id_t *gssctx,
- isc_mem_t *mctx, char **err_message);
-/*
- * Initiates a GSS context.
- *
- * Requires:
- * 'name' is a valid name, preferably one known by the GSS
- * provider
- * 'intoken' is a token received from the acceptor, or NULL if
- * there isn't one
- * 'outtoken' is a buffer to receive the token generated by
- * gss_init_sec_context() to be sent to the acceptor
- * 'context' is a pointer to a valid gss_ctx_id_t
- * (which may have the value GSS_C_NO_CONTEXT)
- *
- * Returns:
- * 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);
-/*
- * Accepts a GSS context.
- *
- * Requires:
- * 'mctx' is a valid memory context
- * 'cred' is the acceptor's valid GSS credential handle
- * 'intoken' is a token received from the initiator
- * 'outtoken' is a pointer a buffer pointer used to return the token
- * generated by gss_accept_sec_context() to be sent to the
- * initiator
- * 'context' is a valid pointer to receive the generated context handle.
- * On the initial call, it should be a pointer to NULL, which
- * will be allocated as a gss_ctx_id_t. Subsequent calls
- * should pass in the handle generated on the first call.
- * Call dst_gssapi_releasecred to delete the context and free
- * the memory.
- *
- * Requires:
- * 'outtoken' to != NULL && *outtoken == NULL.
- *
- * Returns:
- * ISC_R_SUCCESS msg was successfully updated to include the
- * query to be sent
- * other an error occurred while building the message
- */
-
-isc_result_t
-dst_gssapi_deletectx(isc_mem_t *mctx, gss_ctx_id_t *gssctx);
-/*
- * Destroys a GSS context. This function deletes the context from the GSS
- * provider and then frees the memory used by the context pointer.
- *
- * Requires:
- * 'mctx' is a valid memory context
- * 'context' is a valid GSS context
- *
- * Returns:
- * ISC_R_SUCCESS
- */
-
-
-void
-gss_log(int level, const char *fmt, ...)
-ISC_FORMAT_PRINTF(2, 3);
-/*
- * Logging function for GSS.
- *
- * Requires
- * 'level' is the log level to be used, as an integer
- * 'fmt' is a printf format specifier
- */
-
-char *
-gss_error_tostring(isc_uint32_t major, isc_uint32_t minor,
- char *buf, size_t buflen);
-/*
- * Render a GSS major status/minor status pair into a string
- *
- * Requires:
- * 'major' is a GSS major status code
- * 'minor' is a GSS minor status code
- *
- * Returns:
- * A string containing the text representation of the error codes.
- * Users should copy the string if they wish to keep it.
- */
-
-isc_boolean_t
-dst_gssapi_identitymatchesrealmkrb5(dns_name_t *signer, dns_name_t *name,
- dns_name_t *realm);
-/*
- * Compare a "signer" (in the format of a Kerberos-format Kerberos5
- * principal: host/example.com@EXAMPLE.COM) to the realm name stored
- * in "name" (which represents the realm name).
- *
- */
-
-isc_boolean_t
-dst_gssapi_identitymatchesrealmms(dns_name_t *signer, dns_name_t *name,
- dns_name_t *realm);
-/*
- * Compare a "signer" (in the format of a Kerberos-format Kerberos5
- * principal: host/example.com@EXAMPLE.COM) to the realm name stored
- * in "name" (which represents the realm name).
- *
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DST_GSSAPI_H */
diff --git a/contrib/bind9/lib/dns/include/dst/lib.h b/contrib/bind9/lib/dns/include/dst/lib.h
deleted file mode 100644
index 886575e9cb4e..000000000000
--- a/contrib/bind9/lib/dns/include/dst/lib.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: lib.h,v 1.7 2007/06/19 23:47:17 tbox Exp $ */
-
-#ifndef DST_LIB_H
-#define DST_LIB_H 1
-
-/*! \file dst/lib.h */
-
-#include <isc/types.h>
-#include <isc/lang.h>
-
-ISC_LANG_BEGINDECLS
-
-LIBDNS_EXTERNAL_DATA extern isc_msgcat_t *dst_msgcat;
-
-void
-dst_lib_initmsgcat(void);
-/*
- * Initialize the DST library's message catalog, dst_msgcat, if it
- * has not already been initialized.
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DST_LIB_H */
diff --git a/contrib/bind9/lib/dns/include/dst/result.h b/contrib/bind9/lib/dns/include/dst/result.h
deleted file mode 100644
index 00640a1b1c82..000000000000
--- a/contrib/bind9/lib/dns/include/dst/result.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2004-2008, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: result.h,v 1.9 2008/04/01 23:47:10 tbox Exp $ */
-
-#ifndef DST_RESULT_H
-#define DST_RESULT_H 1
-
-/*! \file dst/result.h */
-
-#include <isc/lang.h>
-#include <isc/resultclass.h>
-
-/*
- * Nothing in this file truly depends on <isc/result.h>, but the
- * DST result codes are considered to be publicly derived from
- * the ISC result codes, so including this file buys you the ISC_R_
- * namespace too.
- */
-#include <isc/result.h> /* Contractual promise. */
-
-#define DST_R_UNSUPPORTEDALG (ISC_RESULTCLASS_DST + 0)
-#define DST_R_CRYPTOFAILURE (ISC_RESULTCLASS_DST + 1)
-/* compat */
-#define DST_R_OPENSSLFAILURE DST_R_CRYPTOFAILURE
-#define DST_R_NOCRYPTO (ISC_RESULTCLASS_DST + 2)
-#define DST_R_NULLKEY (ISC_RESULTCLASS_DST + 3)
-#define DST_R_INVALIDPUBLICKEY (ISC_RESULTCLASS_DST + 4)
-#define DST_R_INVALIDPRIVATEKEY (ISC_RESULTCLASS_DST + 5)
-/* 6 is unused */
-#define DST_R_WRITEERROR (ISC_RESULTCLASS_DST + 7)
-#define DST_R_INVALIDPARAM (ISC_RESULTCLASS_DST + 8)
-/* 9 is unused */
-/* 10 is unused */
-#define DST_R_SIGNFAILURE (ISC_RESULTCLASS_DST + 11)
-/* 12 is unused */
-/* 13 is unused */
-#define DST_R_VERIFYFAILURE (ISC_RESULTCLASS_DST + 14)
-#define DST_R_NOTPUBLICKEY (ISC_RESULTCLASS_DST + 15)
-#define DST_R_NOTPRIVATEKEY (ISC_RESULTCLASS_DST + 16)
-#define DST_R_KEYCANNOTCOMPUTESECRET (ISC_RESULTCLASS_DST + 17)
-#define DST_R_COMPUTESECRETFAILURE (ISC_RESULTCLASS_DST + 18)
-#define DST_R_NORANDOMNESS (ISC_RESULTCLASS_DST + 19)
-#define DST_R_BADKEYTYPE (ISC_RESULTCLASS_DST + 20)
-#define DST_R_NOENGINE (ISC_RESULTCLASS_DST + 21)
-
-#define DST_R_NRESULTS 22 /* Number of results */
-
-ISC_LANG_BEGINDECLS
-
-const char *
-dst_result_totext(isc_result_t);
-
-void
-dst_result_register(void);
-
-ISC_LANG_ENDDECLS
-
-#endif /* DST_RESULT_H */
diff --git a/contrib/bind9/lib/dns/iptable.c b/contrib/bind9/lib/dns/iptable.c
deleted file mode 100644
index 701950533c9e..000000000000
--- a/contrib/bind9/lib/dns/iptable.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2007-2009, 2013 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: iptable.c,v 1.15 2009/02/18 23:47:48 tbox Exp $ */
-
-#include <config.h>
-
-#include <isc/mem.h>
-#include <isc/radix.h>
-
-#include <dns/acl.h>
-
-static void destroy_iptable(dns_iptable_t *dtab);
-
-/*
- * Create a new IP table and the underlying radix structure
- */
-isc_result_t
-dns_iptable_create(isc_mem_t *mctx, dns_iptable_t **target) {
- isc_result_t result;
- dns_iptable_t *tab;
-
- tab = isc_mem_get(mctx, sizeof(*tab));
- if (tab == NULL)
- return (ISC_R_NOMEMORY);
- tab->mctx = NULL;
- isc_mem_attach(mctx, &tab->mctx);
- isc_refcount_init(&tab->refcount, 1);
- tab->radix = NULL;
- tab->magic = DNS_IPTABLE_MAGIC;
-
- result = isc_radix_create(mctx, &tab->radix, RADIX_MAXBITS);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- *target = tab;
- return (ISC_R_SUCCESS);
-
- cleanup:
- dns_iptable_detach(&tab);
- return (result);
-}
-
-isc_boolean_t dns_iptable_neg = ISC_FALSE;
-isc_boolean_t dns_iptable_pos = ISC_TRUE;
-
-/*
- * Add an IP prefix to an existing IP table
- */
-isc_result_t
-dns_iptable_addprefix(dns_iptable_t *tab, isc_netaddr_t *addr,
- isc_uint16_t bitlen, isc_boolean_t pos)
-{
- isc_result_t result;
- isc_prefix_t pfx;
- isc_radix_node_t *node = NULL;
- int family;
-
- INSIST(DNS_IPTABLE_VALID(tab));
- INSIST(tab->radix);
-
- NETADDR_TO_PREFIX_T(addr, pfx, bitlen);
-
- result = isc_radix_insert(tab->radix, &node, NULL, &pfx);
- if (result != ISC_R_SUCCESS) {
- isc_refcount_destroy(&pfx.refcount);
- return(result);
- }
-
- /* If a node already contains data, don't overwrite it */
- family = pfx.family;
- if (family == AF_UNSPEC) {
- /* "any" or "none" */
- INSIST(pfx.bitlen == 0);
- if (pos) {
- if (node->data[0] == NULL)
- node->data[0] = &dns_iptable_pos;
- if (node->data[1] == NULL)
- node->data[1] = &dns_iptable_pos;
- } else {
- if (node->data[0] == NULL)
- node->data[0] = &dns_iptable_neg;
- if (node->data[1] == NULL)
- node->data[1] = &dns_iptable_neg;
- }
- } else {
- /* any other prefix */
- if (node->data[ISC_IS6(family)] == NULL) {
- if (pos)
- node->data[ISC_IS6(family)] = &dns_iptable_pos;
- else
- node->data[ISC_IS6(family)] = &dns_iptable_neg;
- }
- }
-
- isc_refcount_destroy(&pfx.refcount);
- return (ISC_R_SUCCESS);
-}
-
-/*
- * Merge one IP table into another one.
- */
-isc_result_t
-dns_iptable_merge(dns_iptable_t *tab, dns_iptable_t *source, isc_boolean_t pos)
-{
- isc_result_t result;
- isc_radix_node_t *node, *new_node;
- int max_node = 0;
-
- RADIX_WALK (source->radix->head, node) {
- new_node = NULL;
- result = isc_radix_insert (tab->radix, &new_node, node, NULL);
-
- if (result != ISC_R_SUCCESS)
- return(result);
-
- /*
- * If we're negating a nested ACL, then we should
- * reverse the sense of every node. However, this
- * could lead to a negative node in a nested ACL
- * becoming a positive match in the parent, which
- * could be a security risk. To prevent this, we
- * just leave the negative nodes negative.
- */
- if (!pos) {
- if (node->data[0] &&
- *(isc_boolean_t *) node->data[0] == ISC_TRUE)
- new_node->data[0] = &dns_iptable_neg;
-
- if (node->data[1] &&
- *(isc_boolean_t *) node->data[1] == ISC_TRUE)
- new_node->data[1] = &dns_iptable_neg;
- }
-
- if (node->node_num[0] > max_node)
- max_node = node->node_num[0];
- if (node->node_num[1] > max_node)
- max_node = node->node_num[1];
- } RADIX_WALK_END;
-
- tab->radix->num_added_node += max_node;
- return (ISC_R_SUCCESS);
-}
-
-void
-dns_iptable_attach(dns_iptable_t *source, dns_iptable_t **target) {
- REQUIRE(DNS_IPTABLE_VALID(source));
- isc_refcount_increment(&source->refcount, NULL);
- *target = source;
-}
-
-void
-dns_iptable_detach(dns_iptable_t **tabp) {
- dns_iptable_t *tab = *tabp;
- unsigned int refs;
- REQUIRE(DNS_IPTABLE_VALID(tab));
- isc_refcount_decrement(&tab->refcount, &refs);
- if (refs == 0)
- destroy_iptable(tab);
- *tabp = NULL;
-}
-
-static void
-destroy_iptable(dns_iptable_t *dtab) {
-
- REQUIRE(DNS_IPTABLE_VALID(dtab));
-
- if (dtab->radix != NULL) {
- isc_radix_destroy(dtab->radix, NULL);
- dtab->radix = NULL;
- }
-
- isc_refcount_destroy(&dtab->refcount);
- dtab->magic = 0;
- isc_mem_putanddetach(&dtab->mctx, dtab, sizeof(*dtab));
-}
diff --git a/contrib/bind9/lib/dns/journal.c b/contrib/bind9/lib/dns/journal.c
deleted file mode 100644
index 022a3e280f83..000000000000
--- a/contrib/bind9/lib/dns/journal.c
+++ /dev/null
@@ -1,2337 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007-2011, 2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2002 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: journal.c,v 1.120 2011/12/22 07:32:41 each Exp $ */
-
-#include <config.h>
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include <isc/file.h>
-#include <isc/mem.h>
-#include <isc/stdio.h>
-#include <isc/string.h>
-#include <isc/util.h>
-
-#include <dns/compress.h>
-#include <dns/db.h>
-#include <dns/dbiterator.h>
-#include <dns/diff.h>
-#include <dns/fixedname.h>
-#include <dns/journal.h>
-#include <dns/log.h>
-#include <dns/rdataset.h>
-#include <dns/rdatasetiter.h>
-#include <dns/result.h>
-#include <dns/soa.h>
-
-/*! \file
- * \brief Journaling.
- *
- * A journal file consists of
- *
- * \li A fixed-size header of type journal_rawheader_t.
- *
- * \li The index. This is an unordered array of index entries
- * of type journal_rawpos_t giving the locations
- * of some arbitrary subset of the journal's addressable
- * transactions. The index entries are used as hints to
- * speed up the process of locating a transaction with a given
- * serial number. Unused index entries have an "offset"
- * field of zero. The size of the index can vary between
- * journal files, but does not change during the lifetime
- * of a file. The size can be zero.
- *
- * \li The journal data. This consists of one or more transactions.
- * Each transaction begins with a transaction header of type
- * journal_rawxhdr_t. The transaction header is followed by a
- * sequence of RRs, similar in structure to an IXFR difference
- * sequence (RFC1995). That is, the pre-transaction SOA,
- * zero or more other deleted RRs, the post-transaction SOA,
- * and zero or more other added RRs. Unlike in IXFR, each RR
- * is prefixed with a 32-bit length.
- *
- * The journal data part grows as new transactions are
- * appended to the file. Only those transactions
- * whose serial number is current-(2^31-1) to current
- * are considered "addressable" and may be pointed
- * to from the header or index. They may be preceded
- * by old transactions that are no longer addressable,
- * and they may be followed by transactions that were
- * appended to the journal but never committed by updating
- * the "end" position in the header. The latter will
- * be overwritten when new transactions are added.
- */
-/*%
- * When true, accept IXFR difference sequences where the
- * SOA serial number does not change (BIND 8 sends such
- * sequences).
- */
-static isc_boolean_t bind8_compat = ISC_TRUE; /* XXX config */
-
-/**************************************************************************/
-/*
- * Miscellaneous utilities.
- */
-
-#define JOURNAL_COMMON_LOGARGS \
- dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_JOURNAL
-
-#define JOURNAL_DEBUG_LOGARGS(n) \
- JOURNAL_COMMON_LOGARGS, ISC_LOG_DEBUG(n)
-
-/*%
- * It would be non-sensical (or at least obtuse) to use FAIL() with an
- * ISC_R_SUCCESS code, but the test is there to keep the Solaris compiler
- * from complaining about "end-of-loop code not reached".
- */
-#define FAIL(code) \
- do { result = (code); \
- if (result != ISC_R_SUCCESS) goto failure; \
- } while (0)
-
-#define CHECK(op) \
- do { result = (op); \
- if (result != ISC_R_SUCCESS) goto failure; \
- } while (0)
-
-#define JOURNAL_SERIALSET 0x01U
-
-static isc_result_t index_to_disk(dns_journal_t *);
-
-static inline isc_uint32_t
-decode_uint32(unsigned char *p) {
- return ((p[0] << 24) +
- (p[1] << 16) +
- (p[2] << 8) +
- (p[3] << 0));
-}
-
-static inline void
-encode_uint32(isc_uint32_t val, unsigned char *p) {
- p[0] = (isc_uint8_t)(val >> 24);
- p[1] = (isc_uint8_t)(val >> 16);
- p[2] = (isc_uint8_t)(val >> 8);
- p[3] = (isc_uint8_t)(val >> 0);
-}
-
-isc_result_t
-dns_db_createsoatuple(dns_db_t *db, dns_dbversion_t *ver, isc_mem_t *mctx,
- dns_diffop_t op, dns_difftuple_t **tp)
-{
- isc_result_t result;
- dns_dbnode_t *node;
- dns_rdataset_t rdataset;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_name_t *zonename;
-
- zonename = dns_db_origin(db);
-
- node = NULL;
- result = dns_db_findnode(db, zonename, ISC_FALSE, &node);
- if (result != ISC_R_SUCCESS)
- goto nonode;
-
- dns_rdataset_init(&rdataset);
- result = dns_db_findrdataset(db, node, ver, dns_rdatatype_soa, 0,
- (isc_stdtime_t)0, &rdataset, NULL);
- if (result != ISC_R_SUCCESS)
- goto freenode;
-
- result = dns_rdataset_first(&rdataset);
- if (result != ISC_R_SUCCESS)
- goto freenode;
-
- dns_rdataset_current(&rdataset, &rdata);
-
- result = dns_difftuple_create(mctx, op, zonename, rdataset.ttl,
- &rdata, tp);
-
- dns_rdataset_disassociate(&rdataset);
- dns_db_detachnode(db, &node);
- return (result);
-
- freenode:
- dns_db_detachnode(db, &node);
- nonode:
- UNEXPECTED_ERROR(__FILE__, __LINE__, "missing SOA");
- return (result);
-}
-
-/* Journaling */
-
-/*%
- * On-disk representation of a "pointer" to a journal entry.
- * These are used in the journal header to locate the beginning
- * and end of the journal, and in the journal index to locate
- * other transactions.
- */
-typedef struct {
- unsigned char serial[4]; /*%< SOA serial before update. */
- /*
- * XXXRTH Should offset be 8 bytes?
- * XXXDCL ... probably, since isc_offset_t is 8 bytes on many OSs.
- * XXXAG ... but we will not be able to seek >2G anyway on many
- * platforms as long as we are using fseek() rather
- * than lseek().
- */
- unsigned char offset[4]; /*%< Offset from beginning of file. */
-} journal_rawpos_t;
-
-
-/*%
- * The header is of a fixed size, with some spare room for future
- * extensions.
- */
-#define JOURNAL_HEADER_SIZE 64 /* Bytes. */
-
-/*%
- * The on-disk representation of the journal header.
- * All numbers are stored in big-endian order.
- */
-typedef union {
- struct {
- /*% File format version ID. */
- unsigned char format[16];
- /*% Position of the first addressable transaction */
- journal_rawpos_t begin;
- /*% Position of the next (yet nonexistent) transaction. */
- journal_rawpos_t end;
- /*% Number of index entries following the header. */
- unsigned char index_size[4];
- /*% Source serial number. */
- unsigned char sourceserial[4];
- unsigned char flags;
- } h;
- /* Pad the header to a fixed size. */
- unsigned char pad[JOURNAL_HEADER_SIZE];
-} journal_rawheader_t;
-
-/*%
- * The on-disk representation of the transaction header.
- * There is one of these at the beginning of each transaction.
- */
-typedef struct {
- unsigned char size[4]; /*%< In bytes, excluding header. */
- unsigned char serial0[4]; /*%< SOA serial before update. */
- unsigned char serial1[4]; /*%< SOA serial after update. */
-} journal_rawxhdr_t;
-
-/*%
- * The on-disk representation of the RR header.
- * There is one of these at the beginning of each RR.
- */
-typedef struct {
- unsigned char size[4]; /*%< In bytes, excluding header. */
-} journal_rawrrhdr_t;
-
-/*%
- * The in-core representation of the journal header.
- */
-typedef struct {
- isc_uint32_t serial;
- isc_offset_t offset;
-} journal_pos_t;
-
-#define POS_VALID(pos) ((pos).offset != 0)
-#define POS_INVALIDATE(pos) ((pos).offset = 0, (pos).serial = 0)
-
-typedef struct {
- unsigned char format[16];
- journal_pos_t begin;
- journal_pos_t end;
- isc_uint32_t index_size;
- isc_uint32_t sourceserial;
- isc_boolean_t serialset;
-} journal_header_t;
-
-/*%
- * The in-core representation of the transaction header.
- */
-
-typedef struct {
- isc_uint32_t size;
- isc_uint32_t serial0;
- isc_uint32_t serial1;
-} journal_xhdr_t;
-
-/*%
- * The in-core representation of the RR header.
- */
-typedef struct {
- isc_uint32_t size;
-} journal_rrhdr_t;
-
-
-/*%
- * Initial contents to store in the header of a newly created
- * journal file.
- *
- * The header starts with the magic string ";BIND LOG V9\n"
- * to identify the file as a BIND 9 journal file. An ASCII
- * identification string is used rather than a binary magic
- * number to be consistent with BIND 8 (BIND 8 journal files
- * are ASCII text files).
- */
-
-static journal_header_t
-initial_journal_header = { ";BIND LOG V9\n", { 0, 0 }, { 0, 0 }, 0, 0, 0 };
-
-#define JOURNAL_EMPTY(h) ((h)->begin.offset == (h)->end.offset)
-
-typedef enum {
- JOURNAL_STATE_INVALID,
- JOURNAL_STATE_READ,
- JOURNAL_STATE_WRITE,
- JOURNAL_STATE_TRANSACTION,
- JOURNAL_STATE_INLINE
-} journal_state_t;
-
-struct dns_journal {
- unsigned int magic; /*%< JOUR */
- isc_mem_t *mctx; /*%< Memory context */
- journal_state_t state;
- const char *filename; /*%< Journal file name */
- FILE * fp; /*%< File handle */
- isc_offset_t offset; /*%< Current file offset */
- journal_header_t header; /*%< In-core journal header */
- unsigned char *rawindex; /*%< In-core buffer for journal index in on-disk format */
- journal_pos_t *index; /*%< In-core journal index */
-
- /*% Current transaction state (when writing). */
- struct {
- unsigned int n_soa; /*%< Number of SOAs seen */
- journal_pos_t pos[2]; /*%< Begin/end position */
- } x;
-
- /*% Iteration state (when reading). */
- struct {
- /* These define the part of the journal we iterate over. */
- journal_pos_t bpos; /*%< Position before first, */
- journal_pos_t epos; /*%< and after last transaction */
- /* The rest is iterator state. */
- isc_uint32_t current_serial; /*%< Current SOA serial */
- isc_buffer_t source; /*%< Data from disk */
- isc_buffer_t target; /*%< Data from _fromwire check */
- dns_decompress_t dctx; /*%< Dummy decompression ctx */
- dns_name_t name; /*%< Current domain name */
- dns_rdata_t rdata; /*%< Current rdata */
- isc_uint32_t ttl; /*%< Current TTL */
- unsigned int xsize; /*%< Size of transaction data */
- unsigned int xpos; /*%< Current position in it */
- isc_result_t result; /*%< Result of last call */
- } it;
-};
-
-#define DNS_JOURNAL_MAGIC ISC_MAGIC('J', 'O', 'U', 'R')
-#define DNS_JOURNAL_VALID(t) ISC_MAGIC_VALID(t, DNS_JOURNAL_MAGIC)
-
-static void
-journal_pos_decode(journal_rawpos_t *raw, journal_pos_t *cooked) {
- cooked->serial = decode_uint32(raw->serial);
- cooked->offset = decode_uint32(raw->offset);
-}
-
-static void
-journal_pos_encode(journal_rawpos_t *raw, journal_pos_t *cooked) {
- encode_uint32(cooked->serial, raw->serial);
- encode_uint32(cooked->offset, raw->offset);
-}
-
-static void
-journal_header_decode(journal_rawheader_t *raw, journal_header_t *cooked) {
- INSIST(sizeof(cooked->format) == sizeof(raw->h.format));
- memcpy(cooked->format, raw->h.format, sizeof(cooked->format));
- journal_pos_decode(&raw->h.begin, &cooked->begin);
- journal_pos_decode(&raw->h.end, &cooked->end);
- cooked->index_size = decode_uint32(raw->h.index_size);
- cooked->sourceserial = decode_uint32(raw->h.sourceserial);
- cooked->serialset = ISC_TF(raw->h.flags & JOURNAL_SERIALSET);
-}
-
-static void
-journal_header_encode(journal_header_t *cooked, journal_rawheader_t *raw) {
- unsigned char flags = 0;
-
- INSIST(sizeof(cooked->format) == sizeof(raw->h.format));
- memset(raw->pad, 0, sizeof(raw->pad));
- memcpy(raw->h.format, cooked->format, sizeof(raw->h.format));
- journal_pos_encode(&raw->h.begin, &cooked->begin);
- journal_pos_encode(&raw->h.end, &cooked->end);
- encode_uint32(cooked->index_size, raw->h.index_size);
- encode_uint32(cooked->sourceserial, raw->h.sourceserial);
- if (cooked->serialset)
- flags |= JOURNAL_SERIALSET;
- raw->h.flags = flags;
-}
-
-/*
- * Journal file I/O subroutines, with error checking and reporting.
- */
-static isc_result_t
-journal_seek(dns_journal_t *j, isc_uint32_t offset) {
- isc_result_t result;
- result = isc_stdio_seek(j->fp, (long)offset, SEEK_SET);
- if (result != ISC_R_SUCCESS) {
- isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,
- "%s: seek: %s", j->filename,
- isc_result_totext(result));
- return (ISC_R_UNEXPECTED);
- }
- j->offset = offset;
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-journal_read(dns_journal_t *j, void *mem, size_t nbytes) {
- isc_result_t result;
-
- result = isc_stdio_read(mem, 1, nbytes, j->fp, NULL);
- if (result != ISC_R_SUCCESS) {
- if (result == ISC_R_EOF)
- return (ISC_R_NOMORE);
- isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,
- "%s: read: %s",
- j->filename, isc_result_totext(result));
- return (ISC_R_UNEXPECTED);
- }
- j->offset += nbytes;
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-journal_write(dns_journal_t *j, void *mem, size_t nbytes) {
- isc_result_t result;
-
- result = isc_stdio_write(mem, 1, nbytes, j->fp, NULL);
- if (result != ISC_R_SUCCESS) {
- isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,
- "%s: write: %s",
- j->filename, isc_result_totext(result));
- return (ISC_R_UNEXPECTED);
- }
- j->offset += nbytes;
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-journal_fsync(dns_journal_t *j) {
- isc_result_t result;
- result = isc_stdio_flush(j->fp);
- if (result != ISC_R_SUCCESS) {
- isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,
- "%s: flush: %s",
- j->filename, isc_result_totext(result));
- return (ISC_R_UNEXPECTED);
- }
- result = isc_stdio_sync(j->fp);
- if (result != ISC_R_SUCCESS) {
- isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,
- "%s: fsync: %s",
- j->filename, isc_result_totext(result));
- return (ISC_R_UNEXPECTED);
- }
- return (ISC_R_SUCCESS);
-}
-
-/*
- * Read/write a transaction header at the current file position.
- */
-
-static isc_result_t
-journal_read_xhdr(dns_journal_t *j, journal_xhdr_t *xhdr) {
- journal_rawxhdr_t raw;
- isc_result_t result;
- result = journal_read(j, &raw, sizeof(raw));
- if (result != ISC_R_SUCCESS)
- return (result);
- xhdr->size = decode_uint32(raw.size);
- xhdr->serial0 = decode_uint32(raw.serial0);
- xhdr->serial1 = decode_uint32(raw.serial1);
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-journal_write_xhdr(dns_journal_t *j, isc_uint32_t size,
- isc_uint32_t serial0, isc_uint32_t serial1)
-{
- journal_rawxhdr_t raw;
- encode_uint32(size, raw.size);
- encode_uint32(serial0, raw.serial0);
- encode_uint32(serial1, raw.serial1);
- return (journal_write(j, &raw, sizeof(raw)));
-}
-
-
-/*
- * Read an RR header at the current file position.
- */
-
-static isc_result_t
-journal_read_rrhdr(dns_journal_t *j, journal_rrhdr_t *rrhdr) {
- journal_rawrrhdr_t raw;
- isc_result_t result;
- result = journal_read(j, &raw, sizeof(raw));
- if (result != ISC_R_SUCCESS)
- return (result);
- rrhdr->size = decode_uint32(raw.size);
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-journal_file_create(isc_mem_t *mctx, const char *filename) {
- FILE *fp = NULL;
- isc_result_t result;
- journal_header_t header;
- journal_rawheader_t rawheader;
- int index_size = 56; /* XXX configurable */
- int size;
- void *mem; /* Memory for temporary index image. */
-
- INSIST(sizeof(journal_rawheader_t) == JOURNAL_HEADER_SIZE);
-
- result = isc_stdio_open(filename, "wb", &fp);
- if (result != ISC_R_SUCCESS) {
- isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,
- "%s: create: %s",
- filename, isc_result_totext(result));
- return (ISC_R_UNEXPECTED);
- }
-
- header = initial_journal_header;
- header.index_size = index_size;
- journal_header_encode(&header, &rawheader);
-
- size = sizeof(journal_rawheader_t) +
- index_size * sizeof(journal_rawpos_t);
-
- mem = isc_mem_get(mctx, size);
- if (mem == NULL) {
- (void)isc_stdio_close(fp);
- (void)isc_file_remove(filename);
- return (ISC_R_NOMEMORY);
- }
- memset(mem, 0, size);
- memcpy(mem, &rawheader, sizeof(rawheader));
-
- result = isc_stdio_write(mem, 1, (size_t) size, fp, NULL);
- if (result != ISC_R_SUCCESS) {
- isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,
- "%s: write: %s",
- filename, isc_result_totext(result));
- (void)isc_stdio_close(fp);
- (void)isc_file_remove(filename);
- isc_mem_put(mctx, mem, size);
- return (ISC_R_UNEXPECTED);
- }
- isc_mem_put(mctx, mem, size);
-
- result = isc_stdio_close(fp);
- if (result != ISC_R_SUCCESS) {
- isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,
- "%s: close: %s",
- filename, isc_result_totext(result));
- (void)isc_file_remove(filename);
- return (ISC_R_UNEXPECTED);
- }
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-journal_open(isc_mem_t *mctx, const char *filename, isc_boolean_t write,
- isc_boolean_t create, dns_journal_t **journalp)
-{
- FILE *fp = NULL;
- isc_result_t result;
- journal_rawheader_t rawheader;
- dns_journal_t *j;
-
- INSIST(journalp != NULL && *journalp == NULL);
- j = isc_mem_get(mctx, sizeof(*j));
- if (j == NULL)
- return (ISC_R_NOMEMORY);
-
- j->mctx = NULL;
- isc_mem_attach(mctx, &j->mctx);
- j->state = JOURNAL_STATE_INVALID;
- j->fp = NULL;
- j->filename = filename;
- j->index = NULL;
- j->rawindex = NULL;
-
- result = isc_stdio_open(j->filename, write ? "rb+" : "rb", &fp);
-
- if (result == ISC_R_FILENOTFOUND) {
- if (create) {
- isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_DEBUG(1),
- "journal file %s does not exist, "
- "creating it", j->filename);
- CHECK(journal_file_create(mctx, filename));
- /*
- * Retry.
- */
- result = isc_stdio_open(j->filename, "rb+", &fp);
- } else {
- FAIL(ISC_R_NOTFOUND);
- }
- }
- if (result != ISC_R_SUCCESS) {
- isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,
- "%s: open: %s",
- j->filename, isc_result_totext(result));
- FAIL(ISC_R_UNEXPECTED);
- }
-
- j->fp = fp;
-
- /*
- * Set magic early so that seek/read can succeed.
- */
- j->magic = DNS_JOURNAL_MAGIC;
-
- CHECK(journal_seek(j, 0));
- CHECK(journal_read(j, &rawheader, sizeof(rawheader)));
-
- if (memcmp(rawheader.h.format, initial_journal_header.format,
- sizeof(initial_journal_header.format)) != 0) {
- isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,
- "%s: journal format not recognized",
- j->filename);
- FAIL(ISC_R_UNEXPECTED);
- }
- journal_header_decode(&rawheader, &j->header);
-
- /*
- * If there is an index, read the raw index into a dynamically
- * allocated buffer and then convert it into a cooked index.
- */
- if (j->header.index_size != 0) {
- unsigned int i;
- unsigned int rawbytes;
- unsigned char *p;
-
- rawbytes = j->header.index_size * sizeof(journal_rawpos_t);
- j->rawindex = isc_mem_get(mctx, rawbytes);
- if (j->rawindex == NULL)
- FAIL(ISC_R_NOMEMORY);
-
- CHECK(journal_read(j, j->rawindex, rawbytes));
-
- j->index = isc_mem_get(mctx, j->header.index_size *
- sizeof(journal_pos_t));
- if (j->index == NULL)
- FAIL(ISC_R_NOMEMORY);
-
- p = j->rawindex;
- for (i = 0; i < j->header.index_size; i++) {
- j->index[i].serial = decode_uint32(p);
- p += 4;
- j->index[i].offset = decode_uint32(p);
- p += 4;
- }
- INSIST(p == j->rawindex + rawbytes);
- }
- j->offset = -1; /* Invalid, must seek explicitly. */
-
- /*
- * Initialize the iterator.
- */
- dns_name_init(&j->it.name, NULL);
- dns_rdata_init(&j->it.rdata);
-
- /*
- * Set up empty initial buffers for unchecked and checked
- * wire format RR data. They will be reallocated
- * later.
- */
- isc_buffer_init(&j->it.source, NULL, 0);
- isc_buffer_init(&j->it.target, NULL, 0);
- dns_decompress_init(&j->it.dctx, -1, DNS_DECOMPRESS_NONE);
-
- j->state =
- write ? JOURNAL_STATE_WRITE : JOURNAL_STATE_READ;
-
- *journalp = j;
- return (ISC_R_SUCCESS);
-
- failure:
- j->magic = 0;
- if (j->index != NULL) {
- isc_mem_put(j->mctx, j->index, j->header.index_size *
- sizeof(journal_rawpos_t));
- j->index = NULL;
- }
- if (j->fp != NULL)
- (void)isc_stdio_close(j->fp);
- isc_mem_putanddetach(&j->mctx, j, sizeof(*j));
- return (result);
-}
-
-isc_result_t
-dns_journal_open(isc_mem_t *mctx, const char *filename, unsigned int mode,
- dns_journal_t **journalp)
-{
- isc_result_t result;
- int namelen;
- char backup[1024];
- isc_boolean_t write, create;
-
- create = ISC_TF(mode & DNS_JOURNAL_CREATE);
- write = ISC_TF(mode & (DNS_JOURNAL_WRITE|DNS_JOURNAL_CREATE));
-
- result = journal_open(mctx, filename, write, create, journalp);
- if (result == ISC_R_NOTFOUND) {
- namelen = strlen(filename);
- if (namelen > 4 && strcmp(filename + namelen - 4, ".jnl") == 0)
- namelen -= 4;
-
- result = isc_string_printf(backup, sizeof(backup), "%.*s.jbk",
- namelen, filename);
- if (result != ISC_R_SUCCESS)
- return (result);
- result = journal_open(mctx, backup, write, write, journalp);
- }
- return (result);
-}
-
-/*
- * A comparison function defining the sorting order for
- * entries in the IXFR-style journal file.
- *
- * The IXFR format requires that deletions are sorted before
- * additions, and within either one, SOA records are sorted
- * before others.
- *
- * Also sort the non-SOA records by type as a courtesy to the
- * server receiving the IXFR - it may help reduce the amount of
- * rdataset merging it has to do.
- */
-static int
-ixfr_order(const void *av, const void *bv) {
- dns_difftuple_t const * const *ap = av;
- dns_difftuple_t const * const *bp = bv;
- dns_difftuple_t const *a = *ap;
- dns_difftuple_t const *b = *bp;
- int r;
- int bop = 0, aop = 0;
-
- switch (a->op) {
- case DNS_DIFFOP_DEL:
- case DNS_DIFFOP_DELRESIGN:
- aop = 1;
- break;
- case DNS_DIFFOP_ADD:
- case DNS_DIFFOP_ADDRESIGN:
- aop = 0;
- break;
- default:
- INSIST(0);
- }
-
- switch (b->op) {
- case DNS_DIFFOP_DEL:
- case DNS_DIFFOP_DELRESIGN:
- bop = 1;
- break;
- case DNS_DIFFOP_ADD:
- case DNS_DIFFOP_ADDRESIGN:
- bop = 0;
- break;
- default:
- INSIST(0);
- }
-
- r = bop - aop;
- if (r != 0)
- return (r);
-
- r = (b->rdata.type == dns_rdatatype_soa) -
- (a->rdata.type == dns_rdatatype_soa);
- if (r != 0)
- return (r);
-
- r = (a->rdata.type - b->rdata.type);
- return (r);
-}
-
-/*
- * Advance '*pos' to the next journal transaction.
- *
- * Requires:
- * *pos refers to a valid journal transaction.
- *
- * Ensures:
- * When ISC_R_SUCCESS is returned,
- * *pos refers to the next journal transaction.
- *
- * Returns one of:
- *
- * ISC_R_SUCCESS
- * ISC_R_NOMORE *pos pointed at the last transaction
- * Other results due to file errors are possible.
- */
-static isc_result_t
-journal_next(dns_journal_t *j, journal_pos_t *pos) {
- isc_result_t result;
- journal_xhdr_t xhdr;
- REQUIRE(DNS_JOURNAL_VALID(j));
-
- result = journal_seek(j, pos->offset);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- if (pos->serial == j->header.end.serial)
- return (ISC_R_NOMORE);
- /*
- * Read the header of the current transaction.
- * This will return ISC_R_NOMORE if we are at EOF.
- */
- result = journal_read_xhdr(j, &xhdr);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- /*
- * Check serial number consistency.
- */
- if (xhdr.serial0 != pos->serial) {
- isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,
- "%s: journal file corrupt: "
- "expected serial %u, got %u",
- j->filename, pos->serial, xhdr.serial0);
- return (ISC_R_UNEXPECTED);
- }
-
- /*
- * Check for offset wraparound.
- */
- if ((isc_offset_t)(pos->offset + sizeof(journal_rawxhdr_t) + xhdr.size)
- < pos->offset) {
- isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,
- "%s: offset too large", j->filename);
- return (ISC_R_UNEXPECTED);
- }
-
- pos->offset += sizeof(journal_rawxhdr_t) + xhdr.size;
- pos->serial = xhdr.serial1;
- return (ISC_R_SUCCESS);
-}
-
-/*
- * If the index of the journal 'j' contains an entry "better"
- * than '*best_guess', replace '*best_guess' with it.
- *
- * "Better" means having a serial number closer to 'serial'
- * but not greater than 'serial'.
- */
-static void
-index_find(dns_journal_t *j, isc_uint32_t serial, journal_pos_t *best_guess) {
- unsigned int i;
- if (j->index == NULL)
- return;
- for (i = 0; i < j->header.index_size; i++) {
- if (POS_VALID(j->index[i]) &&
- DNS_SERIAL_GE(serial, j->index[i].serial) &&
- DNS_SERIAL_GT(j->index[i].serial, best_guess->serial))
- *best_guess = j->index[i];
- }
-}
-
-/*
- * Add a new index entry. If there is no room, make room by removing
- * the odd-numbered entries and compacting the others into the first
- * half of the index. This decimates old index entries exponentially
- * over time, so that the index always contains a much larger fraction
- * of recent serial numbers than of old ones. This is deliberate -
- * most index searches are for outgoing IXFR, and IXFR tends to request
- * recent versions more often than old ones.
- */
-static void
-index_add(dns_journal_t *j, journal_pos_t *pos) {
- unsigned int i;
- if (j->index == NULL)
- return;
- /*
- * Search for a vacant position.
- */
- for (i = 0; i < j->header.index_size; i++) {
- if (! POS_VALID(j->index[i]))
- break;
- }
- if (i == j->header.index_size) {
- unsigned int k = 0;
- /*
- * Found no vacant position. Make some room.
- */
- for (i = 0; i < j->header.index_size; i += 2) {
- j->index[k++] = j->index[i];
- }
- i = k; /* 'i' identifies the first vacant position. */
- while (k < j->header.index_size) {
- POS_INVALIDATE(j->index[k]);
- k++;
- }
- }
- INSIST(i < j->header.index_size);
- INSIST(! POS_VALID(j->index[i]));
-
- /*
- * Store the new index entry.
- */
- j->index[i] = *pos;
-}
-
-/*
- * Invalidate any existing index entries that could become
- * ambiguous when a new transaction with number 'serial' is added.
- */
-static void
-index_invalidate(dns_journal_t *j, isc_uint32_t serial) {
- unsigned int i;
- if (j->index == NULL)
- return;
- for (i = 0; i < j->header.index_size; i++) {
- if (! DNS_SERIAL_GT(serial, j->index[i].serial))
- POS_INVALIDATE(j->index[i]);
- }
-}
-
-/*
- * Try to find a transaction with initial serial number 'serial'
- * in the journal 'j'.
- *
- * If found, store its position at '*pos' and return ISC_R_SUCCESS.
- *
- * If 'serial' is current (= the ending serial number of the
- * last transaction in the journal), set '*pos' to
- * the position immediately following the last transaction and
- * return ISC_R_SUCCESS.
- *
- * If 'serial' is within the range of addressable serial numbers
- * covered by the journal but that particular serial number is missing
- * (from the journal, not just from the index), return ISC_R_NOTFOUND.
- *
- * If 'serial' is outside the range of addressable serial numbers
- * covered by the journal, return ISC_R_RANGE.
- *
- */
-static isc_result_t
-journal_find(dns_journal_t *j, isc_uint32_t serial, journal_pos_t *pos) {
- isc_result_t result;
- journal_pos_t current_pos;
- REQUIRE(DNS_JOURNAL_VALID(j));
-
- if (DNS_SERIAL_GT(j->header.begin.serial, serial))
- return (ISC_R_RANGE);
- if (DNS_SERIAL_GT(serial, j->header.end.serial))
- return (ISC_R_RANGE);
- if (serial == j->header.end.serial) {
- *pos = j->header.end;
- return (ISC_R_SUCCESS);
- }
-
- current_pos = j->header.begin;
- index_find(j, serial, &current_pos);
-
- while (current_pos.serial != serial) {
- if (DNS_SERIAL_GT(current_pos.serial, serial))
- return (ISC_R_NOTFOUND);
- result = journal_next(j, &current_pos);
- if (result != ISC_R_SUCCESS)
- return (result);
- }
- *pos = current_pos;
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_journal_begin_transaction(dns_journal_t *j) {
- isc_uint32_t offset;
- isc_result_t result;
- journal_rawxhdr_t hdr;
-
- REQUIRE(DNS_JOURNAL_VALID(j));
- REQUIRE(j->state == JOURNAL_STATE_WRITE ||
- j->state == JOURNAL_STATE_INLINE);
-
- /*
- * Find the file offset where the new transaction should
- * be written, and seek there.
- */
- if (JOURNAL_EMPTY(&j->header)) {
- offset = sizeof(journal_rawheader_t) +
- j->header.index_size * sizeof(journal_rawpos_t);
- } else {
- offset = j->header.end.offset;
- }
- j->x.pos[0].offset = offset;
- j->x.pos[1].offset = offset; /* Initial value, will be incremented. */
- j->x.n_soa = 0;
-
- CHECK(journal_seek(j, offset));
-
- /*
- * Write a dummy transaction header of all zeroes to reserve
- * space. It will be filled in when the transaction is
- * finished.
- */
- memset(&hdr, 0, sizeof(hdr));
- CHECK(journal_write(j, &hdr, sizeof(hdr)));
- j->x.pos[1].offset = j->offset;
-
- j->state = JOURNAL_STATE_TRANSACTION;
- result = ISC_R_SUCCESS;
- failure:
- return (result);
-}
-
-isc_result_t
-dns_journal_writediff(dns_journal_t *j, dns_diff_t *diff) {
- dns_difftuple_t *t;
- isc_buffer_t buffer;
- void *mem = NULL;
- unsigned int size;
- isc_result_t result;
- isc_region_t used;
-
- REQUIRE(DNS_DIFF_VALID(diff));
- REQUIRE(j->state == JOURNAL_STATE_TRANSACTION);
-
- isc_log_write(JOURNAL_DEBUG_LOGARGS(3), "writing to journal");
- (void)dns_diff_print(diff, NULL);
-
- /*
- * Pass 1: determine the buffer size needed, and
- * keep track of SOA serial numbers.
- */
- size = 0;
- for (t = ISC_LIST_HEAD(diff->tuples); t != NULL;
- t = ISC_LIST_NEXT(t, link))
- {
- if (t->rdata.type == dns_rdatatype_soa) {
- if (j->x.n_soa < 2)
- j->x.pos[j->x.n_soa].serial =
- dns_soa_getserial(&t->rdata);
- j->x.n_soa++;
- }
- size += sizeof(journal_rawrrhdr_t);
- size += t->name.length; /* XXX should have access macro? */
- size += 10;
- size += t->rdata.length;
- }
-
- mem = isc_mem_get(j->mctx, size);
- if (mem == NULL)
- return (ISC_R_NOMEMORY);
-
- isc_buffer_init(&buffer, mem, size);
-
- /*
- * Pass 2. Write RRs to buffer.
- */
- for (t = ISC_LIST_HEAD(diff->tuples); t != NULL;
- t = ISC_LIST_NEXT(t, link))
- {
- /*
- * Write the RR header.
- */
- isc_buffer_putuint32(&buffer, t->name.length + 10 +
- t->rdata.length);
- /*
- * Write the owner name, RR header, and RR data.
- */
- isc_buffer_putmem(&buffer, t->name.ndata, t->name.length);
- isc_buffer_putuint16(&buffer, t->rdata.type);
- isc_buffer_putuint16(&buffer, t->rdata.rdclass);
- isc_buffer_putuint32(&buffer, t->ttl);
- INSIST(t->rdata.length < 65536);
- isc_buffer_putuint16(&buffer, (isc_uint16_t)t->rdata.length);
- INSIST(isc_buffer_availablelength(&buffer) >= t->rdata.length);
- isc_buffer_putmem(&buffer, t->rdata.data, t->rdata.length);
- }
-
- isc_buffer_usedregion(&buffer, &used);
- INSIST(used.length == size);
-
- j->x.pos[1].offset += used.length;
-
- /*
- * Write the buffer contents to the journal file.
- */
- CHECK(journal_write(j, used.base, used.length));
-
- result = ISC_R_SUCCESS;
-
- failure:
- if (mem != NULL)
- isc_mem_put(j->mctx, mem, size);
- return (result);
-
-}
-
-isc_result_t
-dns_journal_commit(dns_journal_t *j) {
- isc_result_t result;
- journal_rawheader_t rawheader;
-
- REQUIRE(DNS_JOURNAL_VALID(j));
- REQUIRE(j->state == JOURNAL_STATE_TRANSACTION ||
- j->state == JOURNAL_STATE_INLINE);
-
- /*
- * Just write out a updated header.
- */
- if (j->state == JOURNAL_STATE_INLINE) {
- CHECK(journal_fsync(j));
- journal_header_encode(&j->header, &rawheader);
- CHECK(journal_seek(j, 0));
- CHECK(journal_write(j, &rawheader, sizeof(rawheader)));
- CHECK(journal_fsync(j));
- j->state = JOURNAL_STATE_WRITE;
- return (ISC_R_SUCCESS);
- }
-
- /*
- * Perform some basic consistency checks.
- */
- if (j->x.n_soa != 2) {
- isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,
- "%s: malformed transaction: %d SOAs",
- j->filename, j->x.n_soa);
- return (ISC_R_UNEXPECTED);
- }
- if (! (DNS_SERIAL_GT(j->x.pos[1].serial, j->x.pos[0].serial) ||
- (bind8_compat &&
- j->x.pos[1].serial == j->x.pos[0].serial)))
- {
- isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,
- "%s: malformed transaction: serial number "
- "would decrease", j->filename);
- return (ISC_R_UNEXPECTED);
- }
- if (! JOURNAL_EMPTY(&j->header)) {
- if (j->x.pos[0].serial != j->header.end.serial) {
- isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,
- "malformed transaction: "
- "%s last serial %u != "
- "transaction first serial %u",
- j->filename,
- j->header.end.serial,
- j->x.pos[0].serial);
- return (ISC_R_UNEXPECTED);
- }
- }
-
- /*
- * Some old journal entries may become non-addressable
- * when we increment the current serial number. Purge them
- * by stepping header.begin forward to the first addressable
- * transaction. Also purge them from the index.
- */
- if (! JOURNAL_EMPTY(&j->header)) {
- while (! DNS_SERIAL_GT(j->x.pos[1].serial,
- j->header.begin.serial)) {
- CHECK(journal_next(j, &j->header.begin));
- }
- index_invalidate(j, j->x.pos[1].serial);
- }
-#ifdef notyet
- if (DNS_SERIAL_GT(last_dumped_serial, j->x.pos[1].serial)) {
- force_dump(...);
- }
-#endif
-
- /*
- * Commit the transaction data to stable storage.
- */
- CHECK(journal_fsync(j));
-
- if (j->state == JOURNAL_STATE_TRANSACTION) {
- isc_offset_t offset;
- offset = (j->x.pos[1].offset - j->x.pos[0].offset) -
- sizeof(journal_rawxhdr_t);
- /*
- * Update the transaction header.
- */
- CHECK(journal_seek(j, j->x.pos[0].offset));
- CHECK(journal_write_xhdr(j, offset, j->x.pos[0].serial,
- j->x.pos[1].serial));
- }
-
- /*
- * Update the journal header.
- */
- if (JOURNAL_EMPTY(&j->header))
- j->header.begin = j->x.pos[0];
- j->header.end = j->x.pos[1];
- journal_header_encode(&j->header, &rawheader);
- CHECK(journal_seek(j, 0));
- CHECK(journal_write(j, &rawheader, sizeof(rawheader)));
-
- /*
- * Update the index.
- */
- index_add(j, &j->x.pos[0]);
-
- /*
- * Convert the index into on-disk format and write
- * it to disk.
- */
- CHECK(index_to_disk(j));
-
- /*
- * Commit the header to stable storage.
- */
- CHECK(journal_fsync(j));
-
- /*
- * We no longer have a transaction open.
- */
- j->state = JOURNAL_STATE_WRITE;
-
- result = ISC_R_SUCCESS;
-
- failure:
- return (result);
-}
-
-isc_result_t
-dns_journal_write_transaction(dns_journal_t *j, dns_diff_t *diff) {
- isc_result_t result;
- CHECK(dns_diff_sort(diff, ixfr_order));
- CHECK(dns_journal_begin_transaction(j));
- CHECK(dns_journal_writediff(j, diff));
- CHECK(dns_journal_commit(j));
- result = ISC_R_SUCCESS;
- failure:
- return (result);
-}
-
-void
-dns_journal_destroy(dns_journal_t **journalp) {
- dns_journal_t *j = *journalp;
- REQUIRE(DNS_JOURNAL_VALID(j));
-
- j->it.result = ISC_R_FAILURE;
- dns_name_invalidate(&j->it.name);
- dns_decompress_invalidate(&j->it.dctx);
- if (j->rawindex != NULL)
- isc_mem_put(j->mctx, j->rawindex, j->header.index_size *
- sizeof(journal_rawpos_t));
- if (j->index != NULL)
- isc_mem_put(j->mctx, j->index, j->header.index_size *
- sizeof(journal_pos_t));
- if (j->it.target.base != NULL)
- isc_mem_put(j->mctx, j->it.target.base, j->it.target.length);
- if (j->it.source.base != NULL)
- isc_mem_put(j->mctx, j->it.source.base, j->it.source.length);
-
- if (j->fp != NULL)
- (void)isc_stdio_close(j->fp);
- j->magic = 0;
- isc_mem_putanddetach(&j->mctx, j, sizeof(*j));
- *journalp = NULL;
-}
-
-/*
- * Roll the open journal 'j' into the database 'db'.
- * A new database version will be created.
- */
-
-/* XXX Share code with incoming IXFR? */
-
-static isc_result_t
-roll_forward(dns_journal_t *j, dns_db_t *db, unsigned int options,
- isc_uint32_t resign)
-{
- isc_buffer_t source; /* Transaction data from disk */
- isc_buffer_t target; /* Ditto after _fromwire check */
- isc_uint32_t db_serial; /* Database SOA serial */
- isc_uint32_t end_serial; /* Last journal SOA serial */
- isc_result_t result;
- dns_dbversion_t *ver = NULL;
- journal_pos_t pos;
- dns_diff_t diff;
- unsigned int n_soa = 0;
- unsigned int n_put = 0;
- dns_diffop_t op;
-
- REQUIRE(DNS_JOURNAL_VALID(j));
- REQUIRE(DNS_DB_VALID(db));
-
- dns_diff_init(j->mctx, &diff);
- diff.resign = resign;
-
- /*
- * Set up empty initial buffers for unchecked and checked
- * wire format transaction data. They will be reallocated
- * later.
- */
- isc_buffer_init(&source, NULL, 0);
- isc_buffer_init(&target, NULL, 0);
-
- /*
- * Create the new database version.
- */
- CHECK(dns_db_newversion(db, &ver));
-
- /*
- * Get the current database SOA serial number.
- */
- CHECK(dns_db_getsoaserial(db, ver, &db_serial));
-
- /*
- * Locate a journal entry for the current database serial.
- */
- CHECK(journal_find(j, db_serial, &pos));
- /*
- * XXX do more drastic things, like marking zone stale,
- * if this fails?
- */
- /*
- * XXXRTH The zone code should probably mark the zone as bad and
- * scream loudly into the log if this is a dynamic update
- * log reply that failed.
- */
-
- end_serial = dns_journal_last_serial(j);
- if (db_serial == end_serial)
- CHECK(DNS_R_UPTODATE);
-
- CHECK(dns_journal_iter_init(j, db_serial, end_serial));
-
- for (result = dns_journal_first_rr(j);
- result == ISC_R_SUCCESS;
- result = dns_journal_next_rr(j))
- {
- dns_name_t *name;
- isc_uint32_t ttl;
- dns_rdata_t *rdata;
- dns_difftuple_t *tuple = NULL;
-
- name = NULL;
- rdata = NULL;
- dns_journal_current_rr(j, &name, &ttl, &rdata);
-
- if (rdata->type == dns_rdatatype_soa) {
- n_soa++;
- if (n_soa == 2)
- db_serial = j->it.current_serial;
- }
-
- if (n_soa == 3)
- n_soa = 1;
- if (n_soa == 0) {
- isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,
- "%s: journal file corrupt: missing "
- "initial SOA", j->filename);
- FAIL(ISC_R_UNEXPECTED);
- }
- if ((options & DNS_JOURNALOPT_RESIGN) != 0)
- op = (n_soa == 1) ? DNS_DIFFOP_DELRESIGN :
- DNS_DIFFOP_ADDRESIGN;
- else
- op = (n_soa == 1) ? DNS_DIFFOP_DEL : DNS_DIFFOP_ADD;
-
- CHECK(dns_difftuple_create(diff.mctx, op, name, ttl, rdata,
- &tuple));
- dns_diff_append(&diff, &tuple);
-
- if (++n_put > 100) {
- isc_log_write(JOURNAL_DEBUG_LOGARGS(3),
- "%s: applying diff to database (%u)",
- j->filename, db_serial);
- (void)dns_diff_print(&diff, NULL);
- CHECK(dns_diff_apply(&diff, db, ver));
- dns_diff_clear(&diff);
- n_put = 0;
- }
- }
- if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
- CHECK(result);
-
- if (n_put != 0) {
- isc_log_write(JOURNAL_DEBUG_LOGARGS(3),
- "%s: applying final diff to database (%u)",
- j->filename, db_serial);
- (void)dns_diff_print(&diff, NULL);
- CHECK(dns_diff_apply(&diff, db, ver));
- dns_diff_clear(&diff);
- }
-
- failure:
- if (ver != NULL)
- dns_db_closeversion(db, &ver, result == ISC_R_SUCCESS ?
- ISC_TRUE : ISC_FALSE);
-
- if (source.base != NULL)
- isc_mem_put(j->mctx, source.base, source.length);
- if (target.base != NULL)
- isc_mem_put(j->mctx, target.base, target.length);
-
- dns_diff_clear(&diff);
-
- return (result);
-}
-
-isc_result_t
-dns_journal_rollforward(isc_mem_t *mctx, dns_db_t *db,
- unsigned int options, const char *filename)
-{
- REQUIRE((options & DNS_JOURNALOPT_RESIGN) == 0);
- return (dns_journal_rollforward2(mctx, db, options, 0, filename));
-}
-
-isc_result_t
-dns_journal_rollforward2(isc_mem_t *mctx, dns_db_t *db, unsigned int options,
- isc_uint32_t resign, const char *filename)
-{
- dns_journal_t *j;
- isc_result_t result;
-
- REQUIRE(DNS_DB_VALID(db));
- REQUIRE(filename != NULL);
-
- j = NULL;
- result = dns_journal_open(mctx, filename, DNS_JOURNAL_READ, &j);
- if (result == ISC_R_NOTFOUND) {
- isc_log_write(JOURNAL_DEBUG_LOGARGS(3),
- "no journal file, but that's OK");
- return (DNS_R_NOJOURNAL);
- }
- if (result != ISC_R_SUCCESS)
- return (result);
- if (JOURNAL_EMPTY(&j->header))
- result = DNS_R_UPTODATE;
- else
- result = roll_forward(j, db, options, resign);
-
- dns_journal_destroy(&j);
-
- return (result);
-}
-
-isc_result_t
-dns_journal_print(isc_mem_t *mctx, const char *filename, FILE *file) {
- dns_journal_t *j;
- isc_buffer_t source; /* Transaction data from disk */
- isc_buffer_t target; /* Ditto after _fromwire check */
- isc_uint32_t start_serial; /* Database SOA serial */
- isc_uint32_t end_serial; /* Last journal SOA serial */
- isc_result_t result;
- dns_diff_t diff;
- unsigned int n_soa = 0;
- unsigned int n_put = 0;
-
- REQUIRE(filename != NULL);
-
- j = NULL;
- result = dns_journal_open(mctx, filename, DNS_JOURNAL_READ, &j);
- if (result == ISC_R_NOTFOUND) {
- isc_log_write(JOURNAL_DEBUG_LOGARGS(3), "no journal file");
- return (DNS_R_NOJOURNAL);
- }
-
- if (result != ISC_R_SUCCESS) {
- isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,
- "journal open failure: %s: %s",
- isc_result_totext(result), filename);
- return (result);
- }
-
- if (j->header.serialset)
- fprintf(file, "Source serial = %u\n", j->header.sourceserial);
- dns_diff_init(j->mctx, &diff);
-
- /*
- * Set up empty initial buffers for unchecked and checked
- * wire format transaction data. They will be reallocated
- * later.
- */
- isc_buffer_init(&source, NULL, 0);
- isc_buffer_init(&target, NULL, 0);
-
- start_serial = dns_journal_first_serial(j);
- end_serial = dns_journal_last_serial(j);
-
- CHECK(dns_journal_iter_init(j, start_serial, end_serial));
-
- for (result = dns_journal_first_rr(j);
- result == ISC_R_SUCCESS;
- result = dns_journal_next_rr(j))
- {
- dns_name_t *name;
- isc_uint32_t ttl;
- dns_rdata_t *rdata;
- dns_difftuple_t *tuple = NULL;
-
- name = NULL;
- rdata = NULL;
- dns_journal_current_rr(j, &name, &ttl, &rdata);
-
- if (rdata->type == dns_rdatatype_soa)
- n_soa++;
-
- if (n_soa == 3)
- n_soa = 1;
- if (n_soa == 0) {
- isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,
- "%s: journal file corrupt: missing "
- "initial SOA", j->filename);
- FAIL(ISC_R_UNEXPECTED);
- }
- CHECK(dns_difftuple_create(diff.mctx, n_soa == 1 ?
- DNS_DIFFOP_DEL : DNS_DIFFOP_ADD,
- name, ttl, rdata, &tuple));
- dns_diff_append(&diff, &tuple);
-
- if (++n_put > 100) {
- result = dns_diff_print(&diff, file);
- dns_diff_clear(&diff);
- n_put = 0;
- if (result != ISC_R_SUCCESS)
- break;
- }
- }
- if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
- CHECK(result);
-
- if (n_put != 0) {
- result = dns_diff_print(&diff, file);
- dns_diff_clear(&diff);
- }
- goto cleanup;
-
- failure:
- isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,
- "%s: cannot print: journal file corrupt", j->filename);
-
- cleanup:
- if (source.base != NULL)
- isc_mem_put(j->mctx, source.base, source.length);
- if (target.base != NULL)
- isc_mem_put(j->mctx, target.base, target.length);
-
- dns_diff_clear(&diff);
- dns_journal_destroy(&j);
-
- return (result);
-}
-
-/**************************************************************************/
-/*
- * Miscellaneous accessors.
- */
-isc_uint32_t
-dns_journal_first_serial(dns_journal_t *j) {
- return (j->header.begin.serial);
-}
-
-isc_uint32_t
-dns_journal_last_serial(dns_journal_t *j) {
- return (j->header.end.serial);
-}
-
-void
-dns_journal_set_sourceserial(dns_journal_t *j, isc_uint32_t sourceserial) {
-
- REQUIRE(j->state == JOURNAL_STATE_WRITE ||
- j->state == JOURNAL_STATE_INLINE ||
- j->state == JOURNAL_STATE_TRANSACTION);
-
- j->header.sourceserial = sourceserial;
- j->header.serialset = ISC_TRUE;
- if (j->state == JOURNAL_STATE_WRITE)
- j->state = JOURNAL_STATE_INLINE;
-}
-
-isc_boolean_t
-dns_journal_get_sourceserial(dns_journal_t *j, isc_uint32_t *sourceserial) {
- REQUIRE(sourceserial != NULL);
-
- if (!j->header.serialset)
- return (ISC_FALSE);
- *sourceserial = j->header.sourceserial;
- return (ISC_TRUE);
-}
-
-/**************************************************************************/
-/*
- * Iteration support.
- *
- * When serving an outgoing IXFR, we transmit a part the journal starting
- * at the serial number in the IXFR request and ending at the serial
- * number that is current when the IXFR request arrives. The ending
- * serial number is not necessarily at the end of the journal:
- * the journal may grow while the IXFR is in progress, but we stop
- * when we reach the serial number that was current when the IXFR started.
- */
-
-static isc_result_t read_one_rr(dns_journal_t *j);
-
-/*
- * Make sure the buffer 'b' is has at least 'size' bytes
- * allocated, and clear it.
- *
- * Requires:
- * Either b->base is NULL, or it points to b->length bytes of memory
- * previously allocated by isc_mem_get().
- */
-
-static isc_result_t
-size_buffer(isc_mem_t *mctx, isc_buffer_t *b, unsigned size) {
- if (b->length < size) {
- void *mem = isc_mem_get(mctx, size);
- if (mem == NULL)
- return (ISC_R_NOMEMORY);
- if (b->base != NULL)
- isc_mem_put(mctx, b->base, b->length);
- b->base = mem;
- b->length = size;
- }
- isc_buffer_clear(b);
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_journal_iter_init(dns_journal_t *j,
- isc_uint32_t begin_serial, isc_uint32_t end_serial)
-{
- isc_result_t result;
-
- CHECK(journal_find(j, begin_serial, &j->it.bpos));
- INSIST(j->it.bpos.serial == begin_serial);
-
- CHECK(journal_find(j, end_serial, &j->it.epos));
- INSIST(j->it.epos.serial == end_serial);
-
- result = ISC_R_SUCCESS;
- failure:
- j->it.result = result;
- return (j->it.result);
-}
-
-
-isc_result_t
-dns_journal_first_rr(dns_journal_t *j) {
- isc_result_t result;
-
- /*
- * Seek to the beginning of the first transaction we are
- * interested in.
- */
- CHECK(journal_seek(j, j->it.bpos.offset));
- j->it.current_serial = j->it.bpos.serial;
-
- j->it.xsize = 0; /* We have no transaction data yet... */
- j->it.xpos = 0; /* ...and haven't used any of it. */
-
- return (read_one_rr(j));
-
- failure:
- return (result);
-}
-
-static isc_result_t
-read_one_rr(dns_journal_t *j) {
- isc_result_t result;
-
- dns_rdatatype_t rdtype;
- dns_rdataclass_t rdclass;
- unsigned int rdlen;
- isc_uint32_t ttl;
- journal_xhdr_t xhdr;
- journal_rrhdr_t rrhdr;
-
- INSIST(j->offset <= j->it.epos.offset);
- if (j->offset == j->it.epos.offset)
- return (ISC_R_NOMORE);
- if (j->it.xpos == j->it.xsize) {
- /*
- * We are at a transaction boundary.
- * Read another transaction header.
- */
- CHECK(journal_read_xhdr(j, &xhdr));
- if (xhdr.size == 0) {
- isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,
- "%s: journal corrupt: empty transaction",
- j->filename);
- FAIL(ISC_R_UNEXPECTED);
- }
- if (xhdr.serial0 != j->it.current_serial) {
- isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,
- "%s: journal file corrupt: "
- "expected serial %u, got %u",
- j->filename,
- j->it.current_serial, xhdr.serial0);
- FAIL(ISC_R_UNEXPECTED);
- }
- j->it.xsize = xhdr.size;
- j->it.xpos = 0;
- }
- /*
- * Read an RR.
- */
- CHECK(journal_read_rrhdr(j, &rrhdr));
- /*
- * Perform a sanity check on the journal RR size.
- * The smallest possible RR has a 1-byte owner name
- * and a 10-byte header. The largest possible
- * RR has 65535 bytes of data, a header, and a maximum-
- * size owner name, well below 70 k total.
- */
- if (rrhdr.size < 1+10 || rrhdr.size > 70000) {
- isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,
- "%s: journal corrupt: impossible RR size "
- "(%d bytes)", j->filename, rrhdr.size);
- FAIL(ISC_R_UNEXPECTED);
- }
-
- CHECK(size_buffer(j->mctx, &j->it.source, rrhdr.size));
- CHECK(journal_read(j, j->it.source.base, rrhdr.size));
- isc_buffer_add(&j->it.source, rrhdr.size);
-
- /*
- * The target buffer is made the same size
- * as the source buffer, with the assumption that when
- * no compression in present, the output of dns_*_fromwire()
- * is no larger than the input.
- */
- CHECK(size_buffer(j->mctx, &j->it.target, rrhdr.size));
-
- /*
- * Parse the owner name. We don't know where it
- * ends yet, so we make the entire "remaining"
- * part of the buffer "active".
- */
- isc_buffer_setactive(&j->it.source,
- j->it.source.used - j->it.source.current);
- CHECK(dns_name_fromwire(&j->it.name, &j->it.source,
- &j->it.dctx, 0, &j->it.target));
-
- /*
- * Check that the RR header is there, and parse it.
- */
- if (isc_buffer_remaininglength(&j->it.source) < 10)
- FAIL(DNS_R_FORMERR);
-
- rdtype = isc_buffer_getuint16(&j->it.source);
- rdclass = isc_buffer_getuint16(&j->it.source);
- ttl = isc_buffer_getuint32(&j->it.source);
- rdlen = isc_buffer_getuint16(&j->it.source);
-
- /*
- * Parse the rdata.
- */
- if (isc_buffer_remaininglength(&j->it.source) != rdlen)
- FAIL(DNS_R_FORMERR);
- isc_buffer_setactive(&j->it.source, rdlen);
- dns_rdata_reset(&j->it.rdata);
- CHECK(dns_rdata_fromwire(&j->it.rdata, rdclass,
- rdtype, &j->it.source, &j->it.dctx,
- 0, &j->it.target));
- j->it.ttl = ttl;
-
- j->it.xpos += sizeof(journal_rawrrhdr_t) + rrhdr.size;
- if (rdtype == dns_rdatatype_soa) {
- /* XXX could do additional consistency checks here */
- j->it.current_serial = dns_soa_getserial(&j->it.rdata);
- }
-
- result = ISC_R_SUCCESS;
-
- failure:
- j->it.result = result;
- return (result);
-}
-
-isc_result_t
-dns_journal_next_rr(dns_journal_t *j) {
- j->it.result = read_one_rr(j);
- return (j->it.result);
-}
-
-void
-dns_journal_current_rr(dns_journal_t *j, dns_name_t **name, isc_uint32_t *ttl,
- dns_rdata_t **rdata)
-{
- REQUIRE(j->it.result == ISC_R_SUCCESS);
- *name = &j->it.name;
- *ttl = j->it.ttl;
- *rdata = &j->it.rdata;
-}
-
-/**************************************************************************/
-/*
- * Generating diffs from databases
- */
-
-/*
- * Construct a diff containing all the RRs at the current name of the
- * database iterator 'dbit' in database 'db', version 'ver'.
- * Set '*name' to the current name, and append the diff to 'diff'.
- * All new tuples will have the operation 'op'.
- *
- * Requires: 'name' must have buffer large enough to hold the name.
- * Typically, a dns_fixedname_t would be used.
- */
-static isc_result_t
-get_name_diff(dns_db_t *db, dns_dbversion_t *ver, isc_stdtime_t now,
- dns_dbiterator_t *dbit, dns_name_t *name, dns_diffop_t op,
- dns_diff_t *diff)
-{
- isc_result_t result;
- dns_dbnode_t *node = NULL;
- dns_rdatasetiter_t *rdsiter = NULL;
- dns_difftuple_t *tuple = NULL;
-
- result = dns_dbiterator_current(dbit, &node, name);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- result = dns_db_allrdatasets(db, node, ver, now, &rdsiter);
- if (result != ISC_R_SUCCESS)
- goto cleanup_node;
-
- for (result = dns_rdatasetiter_first(rdsiter);
- result == ISC_R_SUCCESS;
- result = dns_rdatasetiter_next(rdsiter))
- {
- dns_rdataset_t rdataset;
-
- dns_rdataset_init(&rdataset);
- dns_rdatasetiter_current(rdsiter, &rdataset);
-
- 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_difftuple_create(diff->mctx, op, name,
- rdataset.ttl, &rdata,
- &tuple);
- if (result != ISC_R_SUCCESS) {
- dns_rdataset_disassociate(&rdataset);
- goto cleanup_iterator;
- }
- dns_diff_append(diff, &tuple);
- }
- dns_rdataset_disassociate(&rdataset);
- if (result != ISC_R_NOMORE)
- goto cleanup_iterator;
- }
- if (result != ISC_R_NOMORE)
- goto cleanup_iterator;
-
- result = ISC_R_SUCCESS;
-
- cleanup_iterator:
- dns_rdatasetiter_destroy(&rdsiter);
-
- cleanup_node:
- dns_db_detachnode(db, &node);
-
- return (result);
-}
-
-/*
- * Comparison function for use by dns_diff_subtract when sorting
- * the diffs to be subtracted. The sort keys are the rdata type
- * and the rdata itself. The owner name is ignored, because
- * it is known to be the same for all tuples.
- */
-static int
-rdata_order(const void *av, const void *bv) {
- dns_difftuple_t const * const *ap = av;
- dns_difftuple_t const * const *bp = bv;
- dns_difftuple_t const *a = *ap;
- dns_difftuple_t const *b = *bp;
- int r;
- r = (b->rdata.type - a->rdata.type);
- if (r != 0)
- return (r);
- r = dns_rdata_compare(&a->rdata, &b->rdata);
- return (r);
-}
-
-static isc_result_t
-dns_diff_subtract(dns_diff_t diff[2], dns_diff_t *r) {
- isc_result_t result;
- dns_difftuple_t *p[2];
- int i, t;
- isc_boolean_t append;
-
- CHECK(dns_diff_sort(&diff[0], rdata_order));
- CHECK(dns_diff_sort(&diff[1], rdata_order));
-
- for (;;) {
- p[0] = ISC_LIST_HEAD(diff[0].tuples);
- p[1] = ISC_LIST_HEAD(diff[1].tuples);
- if (p[0] == NULL && p[1] == NULL)
- break;
-
- for (i = 0; i < 2; i++)
- if (p[!i] == NULL) {
- ISC_LIST_UNLINK(diff[i].tuples, p[i], link);
- ISC_LIST_APPEND(r->tuples, p[i], link);
- goto next;
- }
- t = rdata_order(&p[0], &p[1]);
- if (t < 0) {
- ISC_LIST_UNLINK(diff[0].tuples, p[0], link);
- ISC_LIST_APPEND(r->tuples, p[0], link);
- goto next;
- }
- if (t > 0) {
- ISC_LIST_UNLINK(diff[1].tuples, p[1], link);
- ISC_LIST_APPEND(r->tuples, p[1], link);
- goto next;
- }
- INSIST(t == 0);
- /*
- * Identical RRs in both databases; skip them both
- * if the ttl differs.
- */
- append = ISC_TF(p[0]->ttl != p[1]->ttl);
- for (i = 0; i < 2; i++) {
- ISC_LIST_UNLINK(diff[i].tuples, p[i], link);
- if (append) {
- ISC_LIST_APPEND(r->tuples, p[i], link);
- } else {
- dns_difftuple_free(&p[i]);
- }
- }
- next: ;
- }
- result = ISC_R_SUCCESS;
- failure:
- return (result);
-}
-
-static isc_result_t
-diff_namespace(dns_db_t *dba, dns_dbversion_t *dbvera,
- dns_db_t *dbb, dns_dbversion_t *dbverb,
- unsigned int options, dns_diff_t *resultdiff)
-{
- dns_db_t *db[2];
- dns_dbversion_t *ver[2];
- dns_dbiterator_t *dbit[2] = { NULL, NULL };
- isc_boolean_t have[2] = { ISC_FALSE, ISC_FALSE };
- dns_fixedname_t fixname[2];
- isc_result_t result, itresult[2];
- dns_diff_t diff[2];
- int i, t;
-
- db[0] = dba, db[1] = dbb;
- ver[0] = dbvera, ver[1] = dbverb;
-
- dns_diff_init(resultdiff->mctx, &diff[0]);
- dns_diff_init(resultdiff->mctx, &diff[1]);
-
- dns_fixedname_init(&fixname[0]);
- dns_fixedname_init(&fixname[1]);
-
- result = dns_db_createiterator(db[0], options, &dbit[0]);
- if (result != ISC_R_SUCCESS)
- return (result);
- result = dns_db_createiterator(db[1], options, &dbit[1]);
- if (result != ISC_R_SUCCESS)
- goto cleanup_iterator;
-
- itresult[0] = dns_dbiterator_first(dbit[0]);
- itresult[1] = dns_dbiterator_first(dbit[1]);
-
- for (;;) {
- for (i = 0; i < 2; i++) {
- if (! have[i] && itresult[i] == ISC_R_SUCCESS) {
- CHECK(get_name_diff(db[i], ver[i], 0, dbit[i],
- dns_fixedname_name(&fixname[i]),
- i == 0 ?
- DNS_DIFFOP_ADD :
- DNS_DIFFOP_DEL,
- &diff[i]));
- itresult[i] = dns_dbiterator_next(dbit[i]);
- have[i] = ISC_TRUE;
- }
- }
-
- if (! have[0] && ! have[1]) {
- INSIST(ISC_LIST_EMPTY(diff[0].tuples));
- INSIST(ISC_LIST_EMPTY(diff[1].tuples));
- break;
- }
-
- for (i = 0; i < 2; i++) {
- if (! have[!i]) {
- ISC_LIST_APPENDLIST(resultdiff->tuples,
- diff[i].tuples, link);
- INSIST(ISC_LIST_EMPTY(diff[i].tuples));
- have[i] = ISC_FALSE;
- goto next;
- }
- }
-
- t = dns_name_compare(dns_fixedname_name(&fixname[0]),
- dns_fixedname_name(&fixname[1]));
- if (t < 0) {
- ISC_LIST_APPENDLIST(resultdiff->tuples,
- diff[0].tuples, link);
- INSIST(ISC_LIST_EMPTY(diff[0].tuples));
- have[0] = ISC_FALSE;
- continue;
- }
- if (t > 0) {
- ISC_LIST_APPENDLIST(resultdiff->tuples,
- diff[1].tuples, link);
- INSIST(ISC_LIST_EMPTY(diff[1].tuples));
- have[1] = ISC_FALSE;
- continue;
- }
- INSIST(t == 0);
- CHECK(dns_diff_subtract(diff, resultdiff));
- INSIST(ISC_LIST_EMPTY(diff[0].tuples));
- INSIST(ISC_LIST_EMPTY(diff[1].tuples));
- have[0] = have[1] = ISC_FALSE;
- next: ;
- }
- if (itresult[0] != ISC_R_NOMORE)
- FAIL(itresult[0]);
- if (itresult[1] != ISC_R_NOMORE)
- FAIL(itresult[1]);
-
- INSIST(ISC_LIST_EMPTY(diff[0].tuples));
- INSIST(ISC_LIST_EMPTY(diff[1].tuples));
-
- failure:
- dns_dbiterator_destroy(&dbit[1]);
-
- cleanup_iterator:
- dns_dbiterator_destroy(&dbit[0]);
- dns_diff_clear(&diff[0]);
- dns_diff_clear(&diff[1]);
- return (result);
-}
-
-/*
- * Compare the databases 'dba' and 'dbb' and generate a journal
- * entry containing the changes to make 'dba' from 'dbb' (note
- * the order). This journal entry will consist of a single,
- * possibly very large transaction.
- */
-isc_result_t
-dns_db_diff(isc_mem_t *mctx, dns_db_t *dba, dns_dbversion_t *dbvera,
- dns_db_t *dbb, dns_dbversion_t *dbverb, const char *filename)
-{
- isc_result_t result;
- dns_diff_t diff;
-
- dns_diff_init(mctx, &diff);
-
- result = dns_db_diffx(&diff, dba, dbvera, dbb, dbverb, filename);
-
- dns_diff_clear(&diff);
-
- return (result);
-}
-
-isc_result_t
-dns_db_diffx(dns_diff_t *diff, dns_db_t *dba, dns_dbversion_t *dbvera,
- dns_db_t *dbb, dns_dbversion_t *dbverb, const char *filename)
-{
- isc_result_t result;
- dns_journal_t *journal = NULL;
-
- if (filename != NULL) {
- result = dns_journal_open(diff->mctx, filename,
- DNS_JOURNAL_CREATE, &journal);
- if (result != ISC_R_SUCCESS)
- return (result);
- }
-
- CHECK(diff_namespace(dba, dbvera, dbb, dbverb, DNS_DB_NONSEC3, diff));
- CHECK(diff_namespace(dba, dbvera, dbb, dbverb, DNS_DB_NSEC3ONLY, diff));
-
- if (journal != NULL) {
- if (ISC_LIST_EMPTY(diff->tuples))
- isc_log_write(JOURNAL_DEBUG_LOGARGS(3), "no changes");
- else
- CHECK(dns_journal_write_transaction(journal, diff));
- }
-
- failure:
- if (journal != NULL)
- dns_journal_destroy(&journal);
- return (result);
-}
-
-isc_result_t
-dns_journal_compact(isc_mem_t *mctx, char *filename, isc_uint32_t serial,
- isc_uint32_t target_size)
-{
- unsigned int i;
- journal_pos_t best_guess;
- journal_pos_t current_pos;
- dns_journal_t *j = NULL;
- dns_journal_t *new = NULL;
- journal_rawheader_t rawheader;
- unsigned int copy_length;
- int namelen;
- char *buf = NULL;
- unsigned int size = 0;
- isc_result_t result;
- unsigned int indexend;
- char newname[1024];
- char backup[1024];
- isc_boolean_t is_backup = ISC_FALSE;
-
- namelen = strlen(filename);
- if (namelen > 4 && strcmp(filename + namelen - 4, ".jnl") == 0)
- namelen -= 4;
-
- result = isc_string_printf(newname, sizeof(newname), "%.*s.jnw",
- namelen, filename);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- result = isc_string_printf(backup, sizeof(backup), "%.*s.jbk",
- namelen, filename);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- result = journal_open(mctx, filename, ISC_FALSE, ISC_FALSE, &j);
- if (result == ISC_R_NOTFOUND) {
- is_backup = ISC_TRUE;
- result = journal_open(mctx, backup, ISC_FALSE, ISC_FALSE, &j);
- }
- if (result != ISC_R_SUCCESS)
- return (result);
-
- if (JOURNAL_EMPTY(&j->header)) {
- dns_journal_destroy(&j);
- return (ISC_R_SUCCESS);
- }
-
- if (DNS_SERIAL_GT(j->header.begin.serial, serial) ||
- DNS_SERIAL_GT(serial, j->header.end.serial)) {
- dns_journal_destroy(&j);
- return (ISC_R_RANGE);
- }
-
- /*
- * Cope with very small target sizes.
- */
- indexend = sizeof(journal_rawheader_t) +
- j->header.index_size * sizeof(journal_rawpos_t);
- if (target_size < indexend * 2)
- target_size = target_size/2 + indexend;
-
- /*
- * See if there is any work to do.
- */
- if ((isc_uint32_t) j->header.end.offset < target_size) {
- dns_journal_destroy(&j);
- return (ISC_R_SUCCESS);
- }
-
- CHECK(journal_open(mctx, newname, ISC_TRUE, ISC_TRUE, &new));
-
- /*
- * Remove overhead so space test below can succeed.
- */
- if (target_size >= indexend)
- target_size -= indexend;
-
- /*
- * Find if we can create enough free space.
- */
- best_guess = j->header.begin;
- for (i = 0; i < j->header.index_size; i++) {
- if (POS_VALID(j->index[i]) &&
- DNS_SERIAL_GE(serial, j->index[i].serial) &&
- ((isc_uint32_t)(j->header.end.offset - j->index[i].offset)
- >= target_size / 2) &&
- j->index[i].offset > best_guess.offset)
- best_guess = j->index[i];
- }
-
- current_pos = best_guess;
- while (current_pos.serial != serial) {
- CHECK(journal_next(j, &current_pos));
- if (current_pos.serial == j->header.end.serial)
- break;
-
- if (DNS_SERIAL_GE(serial, current_pos.serial) &&
- ((isc_uint32_t)(j->header.end.offset - current_pos.offset)
- >= (target_size / 2)) &&
- current_pos.offset > best_guess.offset)
- best_guess = current_pos;
- else
- break;
- }
-
- INSIST(best_guess.serial != j->header.end.serial);
- if (best_guess.serial != serial)
- CHECK(journal_next(j, &best_guess));
-
- /*
- * We should now be roughly half target_size provided
- * we did not reach 'serial'. If not we will just copy
- * all uncommitted deltas regardless of the size.
- */
- copy_length = j->header.end.offset - best_guess.offset;
-
- if (copy_length != 0) {
- /*
- * Copy best_guess to end into space just freed.
- */
- size = 64*1024;
- if (copy_length < size)
- size = copy_length;
- buf = isc_mem_get(mctx, size);
- if (buf == NULL) {
- result = ISC_R_NOMEMORY;
- goto failure;
- }
-
- CHECK(journal_seek(j, best_guess.offset));
- CHECK(journal_seek(new, indexend));
- for (i = 0; i < copy_length; i += size) {
- unsigned int len = (copy_length - i) > size ? size :
- (copy_length - i);
- CHECK(journal_read(j, buf, len));
- CHECK(journal_write(new, buf, len));
- }
-
- CHECK(journal_fsync(new));
-
- /*
- * Compute new header.
- */
- new->header.begin.serial = best_guess.serial;
- new->header.begin.offset = indexend;
- new->header.end.serial = j->header.end.serial;
- new->header.end.offset = indexend + copy_length;
- new->header.sourceserial = j->header.sourceserial;
- new->header.serialset = j->header.serialset;
-
- /*
- * Update the journal header.
- */
- journal_header_encode(&new->header, &rawheader);
- CHECK(journal_seek(new, 0));
- CHECK(journal_write(new, &rawheader, sizeof(rawheader)));
- CHECK(journal_fsync(new));
-
- /*
- * Build new index.
- */
- current_pos = new->header.begin;
- while (current_pos.serial != new->header.end.serial) {
- index_add(new, &current_pos);
- CHECK(journal_next(new, &current_pos));
- }
-
- /*
- * Write index.
- */
- CHECK(index_to_disk(new));
- CHECK(journal_fsync(new));
-
- indexend = new->header.end.offset;
- POST(indexend);
- }
-
- /*
- * Close both journals before trying to rename files (this is
- * necessary on WIN32).
- */
- dns_journal_destroy(&j);
- dns_journal_destroy(&new);
-
- /*
- * With a UFS file system this should just succeed and be atomic.
- * Any IXFR outs will just continue and the old journal will be
- * removed on final close.
- *
- * With MSDOS / NTFS we need to do a two stage rename, triggered
- * by EEXIST. (If any IXFR's are running in other threads, however,
- * this will fail, and the journal will not be compacted. But
- * if so, hopefully they'll be finished by the next time we
- * compact.)
- */
- if (rename(newname, filename) == -1) {
- if (errno == EEXIST && !is_backup) {
- result = isc_file_remove(backup);
- if (result != ISC_R_SUCCESS &&
- result != ISC_R_FILENOTFOUND)
- goto failure;
- if (rename(filename, backup) == -1)
- goto maperrno;
- if (rename(newname, filename) == -1)
- goto maperrno;
- (void)isc_file_remove(backup);
- } else {
- maperrno:
- result = ISC_R_FAILURE;
- goto failure;
- }
- }
-
- result = ISC_R_SUCCESS;
-
- failure:
- (void)isc_file_remove(newname);
- if (buf != NULL)
- isc_mem_put(mctx, buf, size);
- if (j != NULL)
- dns_journal_destroy(&j);
- if (new != NULL)
- dns_journal_destroy(&new);
- return (result);
-}
-
-static isc_result_t
-index_to_disk(dns_journal_t *j) {
- isc_result_t result = ISC_R_SUCCESS;
-
- if (j->header.index_size != 0) {
- unsigned int i;
- unsigned char *p;
- unsigned int rawbytes;
-
- rawbytes = j->header.index_size * sizeof(journal_rawpos_t);
-
- p = j->rawindex;
- for (i = 0; i < j->header.index_size; i++) {
- encode_uint32(j->index[i].serial, p);
- p += 4;
- encode_uint32(j->index[i].offset, p);
- p += 4;
- }
- INSIST(p == j->rawindex + rawbytes);
-
- CHECK(journal_seek(j, sizeof(journal_rawheader_t)));
- CHECK(journal_write(j, j->rawindex, rawbytes));
- }
-failure:
- return (result);
-}
diff --git a/contrib/bind9/lib/dns/key.c b/contrib/bind9/lib/dns/key.c
deleted file mode 100644
index ccac157c13f0..000000000000
--- a/contrib/bind9/lib/dns/key.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (C) 2004-2007, 2011 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: key.c,v 1.11 2011/10/20 21:20:02 marka Exp $ */
-
-#include <config.h>
-
-#include <stddef.h>
-#include <stdlib.h>
-
-#include <isc/region.h>
-#include <isc/util.h>
-
-#include <dns/keyvalues.h>
-
-#include <dst/dst.h>
-
-#include "dst_internal.h"
-
-isc_uint16_t
-dst_region_computeid(const isc_region_t *source, unsigned int alg) {
- isc_uint32_t ac;
- const unsigned char *p;
- int size;
-
- REQUIRE(source != NULL);
- REQUIRE(source->length >= 4);
-
- p = source->base;
- size = source->length;
-
- if (alg == DST_ALG_RSAMD5)
- return ((p[size - 3] << 8) + p[size - 2]);
-
- for (ac = 0; size > 1; size -= 2, p += 2)
- ac += ((*p) << 8) + *(p + 1);
-
- if (size > 0)
- ac += ((*p) << 8);
- ac += (ac >> 16) & 0xffff;
-
- return ((isc_uint16_t)(ac & 0xffff));
-}
-
-isc_uint16_t
-dst_region_computerid(const isc_region_t *source, unsigned int alg) {
- isc_uint32_t ac;
- const unsigned char *p;
- int size;
-
- REQUIRE(source != NULL);
- REQUIRE(source->length >= 4);
-
- p = source->base;
- size = source->length;
-
- if (alg == DST_ALG_RSAMD5)
- return ((p[size - 3] << 8) + p[size - 2]);
-
- ac = ((*p) << 8) + *(p + 1);
- ac |= DNS_KEYFLAG_REVOKE;
- for (size -= 2, p +=2; size > 1; size -= 2, p += 2)
- ac += ((*p) << 8) + *(p + 1);
-
- if (size > 0)
- ac += ((*p) << 8);
- ac += (ac >> 16) & 0xffff;
-
- return ((isc_uint16_t)(ac & 0xffff));
-}
-
-dns_name_t *
-dst_key_name(const dst_key_t *key) {
- REQUIRE(VALID_KEY(key));
- return (key->key_name);
-}
-
-unsigned int
-dst_key_size(const dst_key_t *key) {
- REQUIRE(VALID_KEY(key));
- return (key->key_size);
-}
-
-unsigned int
-dst_key_proto(const dst_key_t *key) {
- REQUIRE(VALID_KEY(key));
- return (key->key_proto);
-}
-
-unsigned int
-dst_key_alg(const dst_key_t *key) {
- REQUIRE(VALID_KEY(key));
- return (key->key_alg);
-}
-
-isc_uint32_t
-dst_key_flags(const dst_key_t *key) {
- REQUIRE(VALID_KEY(key));
- return (key->key_flags);
-}
-
-dns_keytag_t
-dst_key_id(const dst_key_t *key) {
- REQUIRE(VALID_KEY(key));
- return (key->key_id);
-}
-
-dns_keytag_t
-dst_key_rid(const dst_key_t *key) {
- REQUIRE(VALID_KEY(key));
- return (key->key_rid);
-}
-
-dns_rdataclass_t
-dst_key_class(const dst_key_t *key) {
- REQUIRE(VALID_KEY(key));
- return (key->key_class);
-}
-
-isc_boolean_t
-dst_key_iszonekey(const dst_key_t *key) {
- REQUIRE(VALID_KEY(key));
-
- if ((key->key_flags & DNS_KEYTYPE_NOAUTH) != 0)
- return (ISC_FALSE);
- if ((key->key_flags & DNS_KEYFLAG_OWNERMASK) != DNS_KEYOWNER_ZONE)
- return (ISC_FALSE);
- if (key->key_proto != DNS_KEYPROTO_DNSSEC &&
- key->key_proto != DNS_KEYPROTO_ANY)
- return (ISC_FALSE);
- return (ISC_TRUE);
-}
-
-isc_boolean_t
-dst_key_isnullkey(const dst_key_t *key) {
- REQUIRE(VALID_KEY(key));
-
- if ((key->key_flags & DNS_KEYFLAG_TYPEMASK) != DNS_KEYTYPE_NOKEY)
- return (ISC_FALSE);
- if ((key->key_flags & DNS_KEYFLAG_OWNERMASK) != DNS_KEYOWNER_ZONE)
- return (ISC_FALSE);
- if (key->key_proto != DNS_KEYPROTO_DNSSEC &&
- key->key_proto != DNS_KEYPROTO_ANY)
- return (ISC_FALSE);
- return (ISC_TRUE);
-}
-
-void
-dst_key_setbits(dst_key_t *key, isc_uint16_t bits) {
- unsigned int maxbits;
- REQUIRE(VALID_KEY(key));
- if (bits != 0) {
- RUNTIME_CHECK(dst_key_sigsize(key, &maxbits) == ISC_R_SUCCESS);
- maxbits *= 8;
- REQUIRE(bits <= maxbits);
- }
- key->key_bits = bits;
-}
-
-isc_uint16_t
-dst_key_getbits(const dst_key_t *key) {
- REQUIRE(VALID_KEY(key));
- return (key->key_bits);
-}
-
-void
-dst_key_setttl(dst_key_t *key, dns_ttl_t ttl) {
- REQUIRE(VALID_KEY(key));
- key->key_ttl = ttl;
-}
-
-dns_ttl_t
-dst_key_getttl(const dst_key_t *key) {
- REQUIRE(VALID_KEY(key));
- return (key->key_ttl);
-}
-
-/*! \file */
diff --git a/contrib/bind9/lib/dns/keydata.c b/contrib/bind9/lib/dns/keydata.c
deleted file mode 100644
index 822bd467dc55..000000000000
--- a/contrib/bind9/lib/dns/keydata.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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/contrib/bind9/lib/dns/keytable.c b/contrib/bind9/lib/dns/keytable.c
deleted file mode 100644
index c49847f326ad..000000000000
--- a/contrib/bind9/lib/dns/keytable.c
+++ /dev/null
@@ -1,674 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007, 2009, 2010, 2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2000, 2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: keytable.c,v 1.41 2010/06/25 23:46:51 tbox Exp $ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <isc/mem.h>
-#include <isc/rwlock.h>
-#include <isc/string.h> /* Required for HP/UX (and others?) */
-#include <isc/util.h>
-
-#include <dns/keytable.h>
-#include <dns/fixedname.h>
-#include <dns/rbt.h>
-#include <dns/result.h>
-
-static void
-free_keynode(void *node, void *arg) {
- dns_keynode_t *keynode = node;
- isc_mem_t *mctx = arg;
-
- dns_keynode_detachall(mctx, &keynode);
-}
-
-isc_result_t
-dns_keytable_create(isc_mem_t *mctx, dns_keytable_t **keytablep) {
- dns_keytable_t *keytable;
- isc_result_t result;
-
- /*
- * Create a keytable.
- */
-
- REQUIRE(keytablep != NULL && *keytablep == NULL);
-
- keytable = isc_mem_get(mctx, sizeof(*keytable));
- if (keytable == NULL)
- return (ISC_R_NOMEMORY);
-
- keytable->table = NULL;
- result = dns_rbt_create(mctx, free_keynode, mctx, &keytable->table);
- if (result != ISC_R_SUCCESS)
- goto cleanup_keytable;
-
- result = isc_mutex_init(&keytable->lock);
- if (result != ISC_R_SUCCESS)
- goto cleanup_rbt;
-
- result = isc_rwlock_init(&keytable->rwlock, 0, 0);
- if (result != ISC_R_SUCCESS)
- goto cleanup_lock;
-
- keytable->mctx = NULL;
- isc_mem_attach(mctx, &keytable->mctx);
- keytable->active_nodes = 0;
- keytable->references = 1;
- keytable->magic = KEYTABLE_MAGIC;
- *keytablep = keytable;
-
- return (ISC_R_SUCCESS);
-
- cleanup_lock:
- DESTROYLOCK(&keytable->lock);
-
- cleanup_rbt:
- dns_rbt_destroy(&keytable->table);
-
- cleanup_keytable:
- isc_mem_putanddetach(&mctx, keytable, sizeof(*keytable));
-
- return (result);
-}
-
-void
-dns_keytable_attach(dns_keytable_t *source, dns_keytable_t **targetp) {
-
- /*
- * Attach *targetp to source.
- */
-
- REQUIRE(VALID_KEYTABLE(source));
- REQUIRE(targetp != NULL && *targetp == NULL);
-
- RWLOCK(&source->rwlock, isc_rwlocktype_write);
-
- INSIST(source->references > 0);
- source->references++;
- INSIST(source->references != 0);
-
- RWUNLOCK(&source->rwlock, isc_rwlocktype_write);
-
- *targetp = source;
-}
-
-void
-dns_keytable_detach(dns_keytable_t **keytablep) {
- isc_boolean_t destroy = ISC_FALSE;
- dns_keytable_t *keytable;
-
- /*
- * Detach *keytablep from its keytable.
- */
-
- REQUIRE(keytablep != NULL && VALID_KEYTABLE(*keytablep));
-
- keytable = *keytablep;
-
- RWLOCK(&keytable->rwlock, isc_rwlocktype_write);
-
- INSIST(keytable->references > 0);
- keytable->references--;
- LOCK(&keytable->lock);
- if (keytable->references == 0 && keytable->active_nodes == 0)
- destroy = ISC_TRUE;
- UNLOCK(&keytable->lock);
-
- RWUNLOCK(&keytable->rwlock, isc_rwlocktype_write);
-
- if (destroy) {
- dns_rbt_destroy(&keytable->table);
- isc_rwlock_destroy(&keytable->rwlock);
- DESTROYLOCK(&keytable->lock);
- keytable->magic = 0;
- isc_mem_putanddetach(&keytable->mctx,
- keytable, sizeof(*keytable));
- }
-
- *keytablep = NULL;
-}
-
-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 = NULL;
- dns_rbtnode_t *node;
-
- REQUIRE(keyp == NULL || *keyp != NULL);
- REQUIRE(VALID_KEYTABLE(keytable));
-
- result = dns_keynode_create(keytable->mctx, &knode);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- knode->managed = managed;
-
- RWLOCK(&keytable->rwlock, isc_rwlocktype_write);
-
- node = NULL;
- result = dns_rbt_addnode(keytable->table, keyname, &node);
-
- 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;
- knode = NULL;
- }
-
- /* 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)
- 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)
-{
- isc_result_t result;
- dns_keynode_t *knode;
- void *data;
-
- /*
- * Search for a key named 'name', matching 'algorithm' and 'tag' in
- * 'keytable'.
- */
-
- REQUIRE(VALID_KEYTABLE(keytable));
- REQUIRE(dns_name_isabsolute(name));
- REQUIRE(keynodep != NULL && *keynodep == NULL);
-
- RWLOCK(&keytable->rwlock, isc_rwlocktype_read);
-
- /*
- * Note we don't want the DNS_R_PARTIALMATCH from dns_rbt_findname()
- * as that indicates that 'name' was not found.
- *
- * DNS_R_PARTIALMATCH indicates that the name was found but we
- * didn't get a match on algorithm and key id arguments.
- */
- knode = NULL;
- data = NULL;
- result = dns_rbt_findname(keytable->table, name, 0, NULL, &data);
-
- 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;
- }
- if (knode != NULL) {
- LOCK(&keytable->lock);
- keytable->active_nodes++;
- UNLOCK(&keytable->lock);
- dns_keynode_attach(knode, keynodep);
- } else
- result = DNS_R_PARTIALMATCH;
- } else if (result == DNS_R_PARTIALMATCH)
- result = ISC_R_NOTFOUND;
-
- RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read);
-
- return (result);
-}
-
-isc_result_t
-dns_keytable_findnextkeynode(dns_keytable_t *keytable, dns_keynode_t *keynode,
- dns_keynode_t **nextnodep)
-{
- isc_result_t result;
- dns_keynode_t *knode;
-
- /*
- * Search for the next key with the same properties as 'keynode' in
- * 'keytable'.
- */
-
- REQUIRE(VALID_KEYTABLE(keytable));
- REQUIRE(VALID_KEYNODE(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;
- }
- if (knode != NULL) {
- LOCK(&keytable->lock);
- keytable->active_nodes++;
- UNLOCK(&keytable->lock);
- result = ISC_R_SUCCESS;
- dns_keynode_attach(knode, nextnodep);
- } else
- result = ISC_R_NOTFOUND;
-
- return (result);
-}
-
-isc_result_t
-dns_keytable_finddeepestmatch(dns_keytable_t *keytable, dns_name_t *name,
- dns_name_t *foundname)
-{
- isc_result_t result;
- void *data;
-
- /*
- * Search for the deepest match in 'keytable'.
- */
-
- REQUIRE(VALID_KEYTABLE(keytable));
- REQUIRE(dns_name_isabsolute(name));
- REQUIRE(foundname != NULL);
-
- RWLOCK(&keytable->rwlock, isc_rwlocktype_read);
-
- data = NULL;
- result = dns_rbt_findname(keytable->table, name, 0, foundname, &data);
-
- if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH)
- result = ISC_R_SUCCESS;
-
- RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read);
-
- return (result);
-}
-
-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)
-{
- /*
- * Give back a keynode found via dns_keytable_findkeynode().
- */
-
- REQUIRE(VALID_KEYTABLE(keytable));
- REQUIRE(keynodep != NULL && VALID_KEYNODE(*keynodep));
-
- LOCK(&keytable->lock);
- INSIST(keytable->active_nodes > 0);
- keytable->active_nodes--;
- UNLOCK(&keytable->lock);
-
- dns_keynode_detach(keytable->mctx, keynodep);
-}
-
-isc_result_t
-dns_keytable_issecuredomain(dns_keytable_t *keytable, dns_name_t *name,
- isc_boolean_t *wantdnssecp)
-{
- isc_result_t result;
- void *data;
-
- /*
- * Is 'name' at or beneath a trusted key?
- */
-
- REQUIRE(VALID_KEYTABLE(keytable));
- REQUIRE(dns_name_isabsolute(name));
- REQUIRE(wantdnssecp != NULL);
-
- RWLOCK(&keytable->rwlock, isc_rwlocktype_read);
-
- data = NULL;
- result = dns_rbt_findname(keytable->table, name, 0, NULL, &data);
-
- if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
- INSIST(data != NULL);
- *wantdnssecp = ISC_TRUE;
- result = ISC_R_SUCCESS;
- } else if (result == ISC_R_NOTFOUND) {
- *wantdnssecp = ISC_FALSE;
- result = ISC_R_SUCCESS;
- }
-
- RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read);
-
- 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) {
-
- /*
- * Get the DST key associated with keynode.
- */
-
- REQUIRE(VALID_KEYNODE(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/contrib/bind9/lib/dns/lib.c b/contrib/bind9/lib/dns/lib.c
deleted file mode 100644
index df16fa22d0c1..000000000000
--- a/contrib/bind9/lib/dns/lib.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: lib.c,v 1.19 2009/09/03 00:12:23 each Exp $ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <stddef.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
- ***/
-
-LIBDNS_EXTERNAL_DATA unsigned int dns_pps = 0U;
-LIBDNS_EXTERNAL_DATA isc_msgcat_t * dns_msgcat = NULL;
-
-
-/***
- *** Private
- ***/
-
-static isc_once_t msgcat_once = ISC_ONCE_INIT;
-
-
-/***
- *** Functions
- ***/
-
-static void
-open_msgcat(void) {
- isc_msgcat_open("libdns.cat", &dns_msgcat);
-}
-
-void
-dns_lib_initmsgcat(void) {
-
- /*
- * Initialize the DNS library's message catalog, dns_msgcat, if it
- * has not already been initialized.
- */
-
- 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/contrib/bind9/lib/dns/log.c b/contrib/bind9/lib/dns/log.c
deleted file mode 100644
index c4d644e3899f..000000000000
--- a/contrib/bind9/lib/dns/log.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2004-2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001, 2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: log.c,v 1.49 2011/10/13 22:48:24 tbox Exp $ */
-
-/*! \file */
-
-/* Principal Authors: DCL */
-
-#include <config.h>
-
-#include <isc/util.h>
-
-#include <dns/log.h>
-
-/*%
- * When adding a new category, be sure to add the appropriate
- * \#define to <dns/log.h>.
- */
-LIBDNS_EXTERNAL_DATA isc_logcategory_t dns_categories[] = {
- { "notify", 0 },
- { "database", 0 },
- { "security", 0 },
- { "_placeholder", 0 },
- { "dnssec", 0 },
- { "resolver", 0 },
- { "xfer-in", 0 },
- { "xfer-out", 0 },
- { "dispatch", 0 },
- { "lame-servers", 0 },
- { "delegation-only", 0 },
- { "edns-disabled", 0 },
- { "rpz", 0 },
- { NULL, 0 }
-};
-
-/*%
- * When adding a new module, be sure to add the appropriate
- * \#define to <dns/log.h>.
- */
-LIBDNS_EXTERNAL_DATA isc_logmodule_t dns_modules[] = {
- { "dns/db", 0 },
- { "dns/rbtdb", 0 },
- { "dns/rbtdb64", 0 },
- { "dns/rbt", 0 },
- { "dns/rdata", 0 },
- { "dns/master", 0 },
- { "dns/message", 0 },
- { "dns/cache", 0 },
- { "dns/config", 0 },
- { "dns/resolver", 0 },
- { "dns/zone", 0 },
- { "dns/journal", 0 },
- { "dns/adb", 0 },
- { "dns/xfrin", 0 },
- { "dns/xfrout", 0 },
- { "dns/acl", 0 },
- { "dns/validator", 0 },
- { "dns/dispatch", 0 },
- { "dns/request", 0 },
- { "dns/masterdump", 0 },
- { "dns/tsig", 0 },
- { "dns/tkey", 0 },
- { "dns/sdb", 0 },
- { "dns/diff", 0 },
- { "dns/hints", 0 },
- { "dns/acache", 0 },
- { "dns/dlz", 0 },
- { "dns/dnssec", 0 },
- { "dns/crypto", 0 },
- { NULL, 0 }
-};
-
-LIBDNS_EXTERNAL_DATA isc_log_t *dns_lctx = NULL;
-
-void
-dns_log_init(isc_log_t *lctx) {
- REQUIRE(lctx != NULL);
-
- isc_log_registercategories(lctx, dns_categories);
- isc_log_registermodules(lctx, dns_modules);
-}
-
-void
-dns_log_setcontext(isc_log_t *lctx) {
- dns_lctx = lctx;
-}
diff --git a/contrib/bind9/lib/dns/lookup.c b/contrib/bind9/lib/dns/lookup.c
deleted file mode 100644
index 9387a955cd3f..000000000000
--- a/contrib/bind9/lib/dns/lookup.c
+++ /dev/null
@@ -1,498 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007, 2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: lookup.c,v 1.21 2007/06/18 23:47:40 tbox Exp $ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <isc/mem.h>
-#include <isc/netaddr.h>
-#include <isc/string.h> /* Required for HP/UX (and others?) */
-#include <isc/task.h>
-#include <isc/util.h>
-
-#include <dns/db.h>
-#include <dns/events.h>
-#include <dns/lookup.h>
-#include <dns/rdata.h>
-#include <dns/rdataset.h>
-#include <dns/rdatastruct.h>
-#include <dns/resolver.h>
-#include <dns/result.h>
-#include <dns/view.h>
-
-struct dns_lookup {
- /* Unlocked. */
- unsigned int magic;
- isc_mem_t * mctx;
- isc_mutex_t lock;
- dns_rdatatype_t type;
- dns_fixedname_t name;
- /* Locked by lock. */
- unsigned int options;
- isc_task_t * task;
- dns_view_t * view;
- dns_lookupevent_t * event;
- dns_fetch_t * fetch;
- unsigned int restarts;
- isc_boolean_t canceled;
- dns_rdataset_t rdataset;
- dns_rdataset_t sigrdataset;
-};
-
-#define LOOKUP_MAGIC ISC_MAGIC('l', 'o', 'o', 'k')
-#define VALID_LOOKUP(l) ISC_MAGIC_VALID((l), LOOKUP_MAGIC)
-
-#define MAX_RESTARTS 16
-
-static void lookup_find(dns_lookup_t *lookup, dns_fetchevent_t *event);
-
-static void
-fetch_done(isc_task_t *task, isc_event_t *event) {
- dns_lookup_t *lookup = event->ev_arg;
- dns_fetchevent_t *fevent;
-
- UNUSED(task);
- REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE);
- REQUIRE(VALID_LOOKUP(lookup));
- REQUIRE(lookup->task == task);
- fevent = (dns_fetchevent_t *)event;
- REQUIRE(fevent->fetch == lookup->fetch);
-
- lookup_find(lookup, fevent);
-}
-
-static inline isc_result_t
-start_fetch(dns_lookup_t *lookup) {
- isc_result_t result;
-
- /*
- * The caller must be holding the lookup's lock.
- */
-
- REQUIRE(lookup->fetch == NULL);
-
- result = dns_resolver_createfetch(lookup->view->resolver,
- dns_fixedname_name(&lookup->name),
- lookup->type,
- NULL, NULL, NULL, 0,
- lookup->task, fetch_done, lookup,
- &lookup->rdataset,
- &lookup->sigrdataset,
- &lookup->fetch);
-
- return (result);
-}
-
-static isc_result_t
-build_event(dns_lookup_t *lookup) {
- dns_name_t *name = NULL;
- dns_rdataset_t *rdataset = NULL;
- dns_rdataset_t *sigrdataset = NULL;
- isc_result_t result;
-
- name = isc_mem_get(lookup->mctx, sizeof(dns_name_t));
- if (name == NULL) {
- result = ISC_R_NOMEMORY;
- goto fail;
- }
- dns_name_init(name, NULL);
- result = dns_name_dup(dns_fixedname_name(&lookup->name),
- lookup->mctx, name);
- if (result != ISC_R_SUCCESS)
- goto fail;
-
- if (dns_rdataset_isassociated(&lookup->rdataset)) {
- rdataset = isc_mem_get(lookup->mctx, sizeof(dns_rdataset_t));
- if (rdataset == NULL) {
- result = ISC_R_NOMEMORY;
- goto fail;
- }
- dns_rdataset_init(rdataset);
- dns_rdataset_clone(&lookup->rdataset, rdataset);
- }
-
- if (dns_rdataset_isassociated(&lookup->sigrdataset)) {
- sigrdataset = isc_mem_get(lookup->mctx,
- sizeof(dns_rdataset_t));
- if (sigrdataset == NULL) {
- result = ISC_R_NOMEMORY;
- goto fail;
- }
- dns_rdataset_init(sigrdataset);
- dns_rdataset_clone(&lookup->sigrdataset, sigrdataset);
- }
-
- lookup->event->name = name;
- lookup->event->rdataset = rdataset;
- lookup->event->sigrdataset = sigrdataset;
-
- return (ISC_R_SUCCESS);
-
- fail:
- if (name != NULL) {
- if (dns_name_dynamic(name))
- dns_name_free(name, lookup->mctx);
- isc_mem_put(lookup->mctx, name, sizeof(dns_name_t));
- }
- if (rdataset != NULL) {
- if (dns_rdataset_isassociated(rdataset))
- dns_rdataset_disassociate(rdataset);
- isc_mem_put(lookup->mctx, rdataset, sizeof(dns_rdataset_t));
- }
- return (result);
-}
-
-static isc_result_t
-view_find(dns_lookup_t *lookup, dns_name_t *foundname) {
- isc_result_t result;
- dns_name_t *name = dns_fixedname_name(&lookup->name);
- dns_rdatatype_t type;
-
- if (lookup->type == dns_rdatatype_rrsig)
- type = dns_rdatatype_any;
- else
- type = lookup->type;
-
- result = dns_view_find(lookup->view, name, type, 0, 0, ISC_FALSE,
- &lookup->event->db, &lookup->event->node,
- foundname, &lookup->rdataset,
- &lookup->sigrdataset);
- return (result);
-}
-
-static void
-lookup_find(dns_lookup_t *lookup, dns_fetchevent_t *event) {
- isc_result_t result;
- isc_boolean_t want_restart;
- isc_boolean_t send_event;
- dns_name_t *name, *fname, *prefix;
- dns_fixedname_t foundname, fixed;
- 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(VALID_LOOKUP(lookup));
-
- LOCK(&lookup->lock);
-
- result = ISC_R_SUCCESS;
- name = dns_fixedname_name(&lookup->name);
-
- do {
- lookup->restarts++;
- want_restart = ISC_FALSE;
- send_event = ISC_TRUE;
-
- if (event == NULL && !lookup->canceled) {
- dns_fixedname_init(&foundname);
- fname = dns_fixedname_name(&foundname);
- INSIST(!dns_rdataset_isassociated(&lookup->rdataset));
- INSIST(!dns_rdataset_isassociated
- (&lookup->sigrdataset));
- /*
- * If we have restarted then clear the old node. */
- if (lookup->event->node != NULL) {
- INSIST(lookup->event->db != NULL);
- dns_db_detachnode(lookup->event->db,
- &lookup->event->node);
- }
- if (lookup->event->db != NULL)
- dns_db_detach(&lookup->event->db);
- result = view_find(lookup, fname);
- if (result == ISC_R_NOTFOUND) {
- /*
- * We don't know anything about the name.
- * Launch a fetch.
- */
- if (lookup->event->node != NULL) {
- INSIST(lookup->event->db != NULL);
- dns_db_detachnode(lookup->event->db,
- &lookup->event->node);
- }
- if (lookup->event->db != NULL)
- dns_db_detach(&lookup->event->db);
- result = start_fetch(lookup);
- if (result == ISC_R_SUCCESS)
- send_event = ISC_FALSE;
- goto done;
- }
- } else if (event != NULL) {
- result = event->result;
- fname = dns_fixedname_name(&event->foundname);
- dns_resolver_destroyfetch(&lookup->fetch);
- INSIST(event->rdataset == &lookup->rdataset);
- INSIST(event->sigrdataset == &lookup->sigrdataset);
- } else
- fname = NULL; /* Silence compiler warning. */
-
- /*
- * If we've been canceled, forget about the result.
- */
- if (lookup->canceled)
- result = ISC_R_CANCELED;
-
- switch (result) {
- case ISC_R_SUCCESS:
- result = build_event(lookup);
- if (event == NULL)
- break;
- if (event->db != NULL)
- dns_db_attach(event->db, &lookup->event->db);
- if (event->node != NULL)
- dns_db_attachnode(lookup->event->db,
- event->node,
- &lookup->event->node);
- break;
- case DNS_R_CNAME:
- /*
- * Copy the CNAME's target into the lookup's
- * query name and start over.
- */
- result = dns_rdataset_first(&lookup->rdataset);
- if (result != ISC_R_SUCCESS)
- break;
- dns_rdataset_current(&lookup->rdataset, &rdata);
- result = dns_rdata_tostruct(&rdata, &cname, NULL);
- dns_rdata_reset(&rdata);
- if (result != ISC_R_SUCCESS)
- break;
- result = dns_name_copy(&cname.cname, name, NULL);
- dns_rdata_freestruct(&cname);
- if (result == ISC_R_SUCCESS) {
- want_restart = ISC_TRUE;
- send_event = ISC_FALSE;
- }
- break;
- case DNS_R_DNAME:
- namereln = dns_name_fullcompare(name, fname, &order,
- &nlabels);
- INSIST(namereln == dns_namereln_subdomain);
- /*
- * Get the target name of the DNAME.
- */
- result = dns_rdataset_first(&lookup->rdataset);
- if (result != ISC_R_SUCCESS)
- break;
- dns_rdataset_current(&lookup->rdataset, &rdata);
- result = dns_rdata_tostruct(&rdata, &dname, NULL);
- dns_rdata_reset(&rdata);
- if (result != ISC_R_SUCCESS)
- break;
- /*
- * Construct the new query name and start over.
- */
- dns_fixedname_init(&fixed);
- prefix = dns_fixedname_name(&fixed);
- dns_name_split(name, nlabels, prefix, NULL);
- result = dns_name_concatenate(prefix, &dname.dname,
- name, NULL);
- dns_rdata_freestruct(&dname);
- if (result == ISC_R_SUCCESS) {
- want_restart = ISC_TRUE;
- send_event = ISC_FALSE;
- }
- break;
- default:
- send_event = ISC_TRUE;
- }
-
- if (dns_rdataset_isassociated(&lookup->rdataset))
- dns_rdataset_disassociate(&lookup->rdataset);
- if (dns_rdataset_isassociated(&lookup->sigrdataset))
- dns_rdataset_disassociate(&lookup->sigrdataset);
-
- done:
- if (event != NULL) {
- if (event->node != NULL)
- dns_db_detachnode(event->db, &event->node);
- if (event->db != NULL)
- dns_db_detach(&event->db);
- isc_event_free(ISC_EVENT_PTR(&event));
- }
-
- /*
- * Limit the number of restarts.
- */
- if (want_restart && lookup->restarts == MAX_RESTARTS) {
- want_restart = ISC_FALSE;
- result = ISC_R_QUOTA;
- send_event = ISC_TRUE;
- }
-
- } while (want_restart);
-
- if (send_event) {
- lookup->event->result = result;
- lookup->event->ev_sender = lookup;
- isc_task_sendanddetach(&lookup->task,
- (isc_event_t **)&lookup->event);
- dns_view_detach(&lookup->view);
- }
-
- UNLOCK(&lookup->lock);
-}
-
-static void
-levent_destroy(isc_event_t *event) {
- dns_lookupevent_t *levent;
- isc_mem_t *mctx;
-
- REQUIRE(event->ev_type == DNS_EVENT_LOOKUPDONE);
- mctx = event->ev_destroy_arg;
- levent = (dns_lookupevent_t *)event;
-
- if (levent->name != NULL) {
- if (dns_name_dynamic(levent->name))
- dns_name_free(levent->name, mctx);
- isc_mem_put(mctx, levent->name, sizeof(dns_name_t));
- }
- if (levent->rdataset != NULL) {
- dns_rdataset_disassociate(levent->rdataset);
- isc_mem_put(mctx, levent->rdataset, sizeof(dns_rdataset_t));
- }
- if (levent->sigrdataset != NULL) {
- dns_rdataset_disassociate(levent->sigrdataset);
- isc_mem_put(mctx, levent->sigrdataset, sizeof(dns_rdataset_t));
- }
- if (levent->node != NULL)
- dns_db_detachnode(levent->db, &levent->node);
- if (levent->db != NULL)
- dns_db_detach(&levent->db);
- isc_mem_put(mctx, event, event->ev_size);
-}
-
-isc_result_t
-dns_lookup_create(isc_mem_t *mctx, dns_name_t *name, dns_rdatatype_t type,
- dns_view_t *view, unsigned int options, isc_task_t *task,
- isc_taskaction_t action, void *arg, dns_lookup_t **lookupp)
-{
- isc_result_t result;
- dns_lookup_t *lookup;
- isc_event_t *ievent;
-
- lookup = isc_mem_get(mctx, sizeof(*lookup));
- if (lookup == NULL)
- return (ISC_R_NOMEMORY);
- lookup->mctx = NULL;
- isc_mem_attach(mctx, &lookup->mctx);
- lookup->options = options;
-
- ievent = isc_event_allocate(mctx, lookup, DNS_EVENT_LOOKUPDONE,
- action, arg, sizeof(*lookup->event));
- if (ievent == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup_lookup;
- }
- lookup->event = (dns_lookupevent_t *)ievent;
- lookup->event->ev_destroy = levent_destroy;
- lookup->event->ev_destroy_arg = mctx;
- lookup->event->result = ISC_R_FAILURE;
- lookup->event->name = NULL;
- lookup->event->rdataset = NULL;
- lookup->event->sigrdataset = NULL;
- lookup->event->db = NULL;
- lookup->event->node = NULL;
-
- lookup->task = NULL;
- isc_task_attach(task, &lookup->task);
-
- result = isc_mutex_init(&lookup->lock);
- if (result != ISC_R_SUCCESS)
- goto cleanup_event;
-
- dns_fixedname_init(&lookup->name);
-
- result = dns_name_copy(name, dns_fixedname_name(&lookup->name), NULL);
- if (result != ISC_R_SUCCESS)
- goto cleanup_lock;
-
- lookup->type = type;
- lookup->view = NULL;
- dns_view_attach(view, &lookup->view);
- lookup->fetch = NULL;
- lookup->restarts = 0;
- lookup->canceled = ISC_FALSE;
- dns_rdataset_init(&lookup->rdataset);
- dns_rdataset_init(&lookup->sigrdataset);
- lookup->magic = LOOKUP_MAGIC;
-
- *lookupp = lookup;
-
- lookup_find(lookup, NULL);
-
- return (ISC_R_SUCCESS);
-
- cleanup_lock:
- DESTROYLOCK(&lookup->lock);
-
- cleanup_event:
- ievent = (isc_event_t *)lookup->event;
- isc_event_free(&ievent);
- lookup->event = NULL;
-
- isc_task_detach(&lookup->task);
-
- cleanup_lookup:
- isc_mem_putanddetach(&mctx, lookup, sizeof(*lookup));
-
- return (result);
-}
-
-void
-dns_lookup_cancel(dns_lookup_t *lookup) {
- REQUIRE(VALID_LOOKUP(lookup));
-
- LOCK(&lookup->lock);
-
- if (!lookup->canceled) {
- lookup->canceled = ISC_TRUE;
- if (lookup->fetch != NULL) {
- INSIST(lookup->view != NULL);
- dns_resolver_cancelfetch(lookup->fetch);
- }
- }
-
- UNLOCK(&lookup->lock);
-}
-
-void
-dns_lookup_destroy(dns_lookup_t **lookupp) {
- dns_lookup_t *lookup;
-
- REQUIRE(lookupp != NULL);
- lookup = *lookupp;
- REQUIRE(VALID_LOOKUP(lookup));
- REQUIRE(lookup->event == NULL);
- REQUIRE(lookup->task == NULL);
- REQUIRE(lookup->view == NULL);
- if (dns_rdataset_isassociated(&lookup->rdataset))
- dns_rdataset_disassociate(&lookup->rdataset);
- if (dns_rdataset_isassociated(&lookup->sigrdataset))
- dns_rdataset_disassociate(&lookup->sigrdataset);
-
- DESTROYLOCK(&lookup->lock);
- lookup->magic = 0;
- isc_mem_putanddetach(&lookup->mctx, lookup, sizeof(*lookup));
-
- *lookupp = NULL;
-}
diff --git a/contrib/bind9/lib/dns/master.c b/contrib/bind9/lib/dns/master.c
deleted file mode 100644
index d0c175876f5c..000000000000
--- a/contrib/bind9/lib/dns/master.c
+++ /dev/null
@@ -1,3005 +0,0 @@
-/*
- * Copyright (C) 2004-2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <isc/event.h>
-#include <isc/lex.h>
-#include <isc/magic.h>
-#include <isc/mem.h>
-#include <isc/print.h>
-#include <isc/serial.h>
-#include <isc/stdio.h>
-#include <isc/stdtime.h>
-#include <isc/string.h>
-#include <isc/task.h>
-#include <isc/util.h>
-
-#include <dns/callbacks.h>
-#include <dns/events.h>
-#include <dns/fixedname.h>
-#include <dns/master.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/soa.h>
-#include <dns/time.h>
-#include <dns/ttl.h>
-
-/*!
- * Grow the number of dns_rdatalist_t (#RDLSZ) and dns_rdata_t (#RDSZ) structures
- * by these sizes when we need to.
- *
- */
-/*% RDLSZ reflects the number of different types with the same name expected. */
-#define RDLSZ 32
-/*%
- * RDSZ reflects the number of rdata expected at a give name that can fit into
- * 64k.
- */
-#define RDSZ 512
-
-#define NBUFS 4
-#define MAXWIRESZ 255
-
-/*%
- * Target buffer size and minimum target size.
- * MINTSIZ must be big enough to hold the largest rdata record.
- * \brief
- * TSIZ >= MINTSIZ
- */
-#define TSIZ (128*1024)
-/*%
- * max message size - header - root - type - class - ttl - rdlen
- */
-#define MINTSIZ DNS_RDATA_MAXLENGTH
-/*%
- * Size for tokens in the presentation format,
- * The largest tokens are the base64 blocks in KEY and CERT records,
- * Largest key allowed is about 1372 bytes but
- * there is no fixed upper bound on CERT records.
- * 2K is too small for some X.509s, 8K is overkill.
- */
-#define TOKENSIZ (8*1024)
-
-/*%
- * Buffers sizes for $GENERATE.
- */
-#define DNS_MASTER_LHS 2048
-#define DNS_MASTER_RHS MINTSIZ
-
-typedef ISC_LIST(dns_rdatalist_t) rdatalist_head_t;
-
-typedef struct dns_incctx dns_incctx_t;
-
-/*%
- * Master file load state.
- */
-
-struct dns_loadctx {
- unsigned int magic;
- isc_mem_t *mctx;
- dns_masterformat_t format;
-
- dns_rdatacallbacks_t *callbacks;
- isc_task_t *task;
- dns_loaddonefunc_t done;
- void *done_arg;
-
- /* Common methods */
- isc_result_t (*openfile)(dns_loadctx_t *lctx,
- const char *filename);
- isc_result_t (*load)(dns_loadctx_t *lctx);
-
- /* Members specific to the text format: */
- isc_lex_t *lex;
- isc_boolean_t keep_lex;
- unsigned int options;
- isc_boolean_t ttl_known;
- isc_boolean_t default_ttl_known;
- isc_boolean_t warn_1035;
- isc_boolean_t warn_tcr;
- isc_boolean_t warn_sigexpired;
- isc_boolean_t seen_include;
- isc_uint32_t ttl;
- isc_uint32_t default_ttl;
- dns_rdataclass_t zclass;
- dns_fixedname_t fixed_top;
- dns_name_t *top; /*%< top of zone */
-
- /* Members specific to the raw format: */
- FILE *f;
- isc_boolean_t first;
- dns_masterrawheader_t header;
-
- /* Which fixed buffers we are using? */
- unsigned int loop_cnt; /*% records per quantum,
- * 0 => all. */
- isc_boolean_t canceled;
- isc_mutex_t lock;
- isc_result_t result;
- /* locked by lock */
- isc_uint32_t references;
- dns_incctx_t *inc;
- isc_uint32_t resign;
-};
-
-struct dns_incctx {
- dns_incctx_t *parent;
- dns_name_t *origin;
- dns_name_t *current;
- dns_name_t *glue;
- dns_fixedname_t fixed[NBUFS]; /* working buffers */
- unsigned int in_use[NBUFS]; /* covert to bitmap? */
- int glue_in_use;
- int current_in_use;
- int origin_in_use;
- isc_boolean_t origin_changed;
- isc_boolean_t drop;
- unsigned int glue_line;
- unsigned int current_line;
-};
-
-#define DNS_LCTX_MAGIC ISC_MAGIC('L','c','t','x')
-#define DNS_LCTX_VALID(lctx) ISC_MAGIC_VALID(lctx, DNS_LCTX_MAGIC)
-
-#define DNS_AS_STR(t) ((t).value.as_textregion.base)
-
-static isc_result_t
-openfile_text(dns_loadctx_t *lctx, const char *master_file);
-
-static isc_result_t
-openfile_raw(dns_loadctx_t *lctx, const char *master_file);
-
-static isc_result_t
-load_text(dns_loadctx_t *lctx);
-
-static isc_result_t
-load_raw(dns_loadctx_t *lctx);
-
-static isc_result_t
-pushfile(const char *master_file, dns_name_t *origin, dns_loadctx_t *lctx);
-
-static isc_result_t
-commit(dns_rdatacallbacks_t *, dns_loadctx_t *, rdatalist_head_t *,
- dns_name_t *, const char *, unsigned int);
-
-static isc_boolean_t
-is_glue(rdatalist_head_t *, dns_name_t *);
-
-static dns_rdatalist_t *
-grow_rdatalist(int, dns_rdatalist_t *, int, rdatalist_head_t *,
- rdatalist_head_t *, isc_mem_t *mctx);
-
-static dns_rdata_t *
-grow_rdata(int, dns_rdata_t *, int, rdatalist_head_t *, rdatalist_head_t *,
- isc_mem_t *);
-
-static void
-load_quantum(isc_task_t *task, isc_event_t *event);
-
-static isc_result_t
-task_send(dns_loadctx_t *lctx);
-
-static void
-loadctx_destroy(dns_loadctx_t *lctx);
-
-#define GETTOKEN(lexer, options, token, eol) \
- do { \
- result = gettoken(lexer, options, token, eol, callbacks); \
- switch (result) { \
- case ISC_R_SUCCESS: \
- break; \
- case ISC_R_UNEXPECTED: \
- goto insist_and_cleanup; \
- default: \
- if (MANYERRS(lctx, result)) { \
- SETRESULT(lctx, result); \
- LOGIT(result); \
- read_till_eol = ISC_TRUE; \
- goto next_line; \
- } else \
- goto log_and_cleanup; \
- } \
- if ((token)->type == isc_tokentype_special) { \
- result = DNS_R_SYNTAX; \
- if (MANYERRS(lctx, result)) { \
- SETRESULT(lctx, result); \
- LOGIT(result); \
- read_till_eol = ISC_TRUE; \
- goto next_line; \
- } else \
- goto log_and_cleanup; \
- } \
- } while (0)
-
-#define COMMITALL \
- do { \
- result = commit(callbacks, lctx, &current_list, \
- ictx->current, source, ictx->current_line); \
- if (MANYERRS(lctx, result)) { \
- SETRESULT(lctx, result); \
- } else if (result != ISC_R_SUCCESS) \
- goto insist_and_cleanup; \
- result = commit(callbacks, lctx, &glue_list, \
- ictx->glue, source, ictx->glue_line); \
- if (MANYERRS(lctx, result)) { \
- SETRESULT(lctx, result); \
- } else if (result != ISC_R_SUCCESS) \
- goto insist_and_cleanup; \
- rdcount = 0; \
- rdlcount = 0; \
- isc_buffer_init(&target, target_mem, target_size); \
- rdcount_save = rdcount; \
- rdlcount_save = rdlcount; \
- } while (0)
-
-#define WARNUNEXPECTEDEOF(lexer) \
- do { \
- if (isc_lex_isfile(lexer)) \
- (*callbacks->warn)(callbacks, \
- "%s: file does not end with newline", \
- source); \
- } while (0)
-
-#define EXPECTEOL \
- do { \
- GETTOKEN(lctx->lex, 0, &token, ISC_TRUE); \
- if (token.type != isc_tokentype_eol) { \
- isc_lex_ungettoken(lctx->lex, &token); \
- result = DNS_R_EXTRATOKEN; \
- if (MANYERRS(lctx, result)) { \
- SETRESULT(lctx, result); \
- LOGIT(result); \
- read_till_eol = ISC_TRUE; \
- continue; \
- } else if (result != ISC_R_SUCCESS) \
- goto log_and_cleanup; \
- } \
- } while (0)
-
-#define MANYERRS(lctx, result) \
- ((result != ISC_R_SUCCESS) && \
- (result != ISC_R_IOERROR) && \
- ((lctx)->options & DNS_MASTER_MANYERRORS) != 0)
-
-#define SETRESULT(lctx, r) \
- do { \
- if ((lctx)->result == ISC_R_SUCCESS) \
- (lctx)->result = r; \
- } while (0)
-
-#define LOGITFILE(result, filename) \
- if (result == ISC_R_INVALIDFILE || result == ISC_R_FILENOTFOUND || \
- result == ISC_R_IOERROR || result == ISC_R_TOOMANYOPENFILES || \
- result == ISC_R_NOPERM) \
- (*callbacks->error)(callbacks, "%s: %s:%lu: %s: %s", \
- "dns_master_load", source, line, \
- filename, dns_result_totext(result)); \
- else LOGIT(result)
-
-#define LOGIT(result) \
- if (result == ISC_R_NOMEMORY) \
- (*callbacks->error)(callbacks, "dns_master_load: %s", \
- dns_result_totext(result)); \
- else \
- (*callbacks->error)(callbacks, "%s: %s:%lu: %s", \
- "dns_master_load", \
- source, line, dns_result_totext(result))
-
-
-static unsigned char in_addr_arpa_data[] = "\007IN-ADDR\004ARPA";
-static unsigned char in_addr_arpa_offsets[] = { 0, 8, 13 };
-static const dns_name_t in_addr_arpa =
-{
- DNS_NAME_MAGIC,
- in_addr_arpa_data, 14, 3,
- DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE,
- in_addr_arpa_offsets, NULL,
- {(void *)-1, (void *)-1},
- {NULL, NULL}
-};
-
-static unsigned char ip6_int_data[] = "\003IP6\003INT";
-static unsigned char ip6_int_offsets[] = { 0, 4, 8 };
-static const dns_name_t ip6_int =
-{
- DNS_NAME_MAGIC,
- ip6_int_data, 9, 3,
- DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE,
- ip6_int_offsets, NULL,
- {(void *)-1, (void *)-1},
- {NULL, NULL}
-};
-
-static unsigned char ip6_arpa_data[] = "\003IP6\004ARPA";
-static unsigned char ip6_arpa_offsets[] = { 0, 4, 9 };
-static const dns_name_t ip6_arpa =
-{
- DNS_NAME_MAGIC,
- ip6_arpa_data, 10, 3,
- DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE,
- ip6_arpa_offsets, NULL,
- {(void *)-1, (void *)-1},
- {NULL, NULL}
-};
-
-
-static inline isc_result_t
-gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *token,
- isc_boolean_t eol, dns_rdatacallbacks_t *callbacks)
-{
- isc_result_t result;
-
- options |= ISC_LEXOPT_EOL | ISC_LEXOPT_EOF | ISC_LEXOPT_DNSMULTILINE |
- ISC_LEXOPT_ESCAPE;
- result = isc_lex_gettoken(lex, options, token);
- if (result != ISC_R_SUCCESS) {
- switch (result) {
- case ISC_R_NOMEMORY:
- return (ISC_R_NOMEMORY);
- default:
- (*callbacks->error)(callbacks,
- "dns_master_load: %s:%lu:"
- " isc_lex_gettoken() failed: %s",
- isc_lex_getsourcename(lex),
- isc_lex_getsourceline(lex),
- isc_result_totext(result));
- return (result);
- }
- /*NOTREACHED*/
- }
- if (eol != ISC_TRUE)
- if (token->type == isc_tokentype_eol ||
- token->type == isc_tokentype_eof) {
- (*callbacks->error)(callbacks,
- "dns_master_load: %s:%lu: unexpected end of %s",
- isc_lex_getsourcename(lex),
- isc_lex_getsourceline(lex),
- (token->type ==
- isc_tokentype_eol) ?
- "line" : "file");
- return (ISC_R_UNEXPECTEDEND);
- }
- return (ISC_R_SUCCESS);
-}
-
-
-void
-dns_loadctx_attach(dns_loadctx_t *source, dns_loadctx_t **target) {
-
- REQUIRE(target != NULL && *target == NULL);
- REQUIRE(DNS_LCTX_VALID(source));
-
- LOCK(&source->lock);
- INSIST(source->references > 0);
- source->references++;
- INSIST(source->references != 0); /* Overflow? */
- UNLOCK(&source->lock);
-
- *target = source;
-}
-
-void
-dns_loadctx_detach(dns_loadctx_t **lctxp) {
- dns_loadctx_t *lctx;
- isc_boolean_t need_destroy = ISC_FALSE;
-
- REQUIRE(lctxp != NULL);
- lctx = *lctxp;
- REQUIRE(DNS_LCTX_VALID(lctx));
-
- LOCK(&lctx->lock);
- INSIST(lctx->references > 0);
- lctx->references--;
- if (lctx->references == 0)
- need_destroy = ISC_TRUE;
- UNLOCK(&lctx->lock);
-
- if (need_destroy)
- loadctx_destroy(lctx);
- *lctxp = NULL;
-}
-
-static void
-incctx_destroy(isc_mem_t *mctx, dns_incctx_t *ictx) {
- dns_incctx_t *parent;
-
- again:
- parent = ictx->parent;
- ictx->parent = NULL;
-
- isc_mem_put(mctx, ictx, sizeof(*ictx));
-
- if (parent != NULL) {
- ictx = parent;
- goto again;
- }
-}
-
-static void
-loadctx_destroy(dns_loadctx_t *lctx) {
- isc_mem_t *mctx;
- isc_result_t result;
-
- REQUIRE(DNS_LCTX_VALID(lctx));
-
- lctx->magic = 0;
- if (lctx->inc != NULL)
- incctx_destroy(lctx->mctx, lctx->inc);
-
- if (lctx->f != NULL) {
- result = isc_stdio_close(lctx->f);
- if (result != ISC_R_SUCCESS) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_stdio_close() failed: %s",
- isc_result_totext(result));
- }
- }
-
- /* isc_lex_destroy() will close all open streams */
- if (lctx->lex != NULL && !lctx->keep_lex)
- isc_lex_destroy(&lctx->lex);
-
- if (lctx->task != NULL)
- isc_task_detach(&lctx->task);
- DESTROYLOCK(&lctx->lock);
- mctx = NULL;
- isc_mem_attach(lctx->mctx, &mctx);
- isc_mem_detach(&lctx->mctx);
- isc_mem_put(mctx, lctx, sizeof(*lctx));
- isc_mem_detach(&mctx);
-}
-
-static isc_result_t
-incctx_create(isc_mem_t *mctx, dns_name_t *origin, dns_incctx_t **ictxp) {
- dns_incctx_t *ictx;
- isc_region_t r;
- int i;
-
- ictx = isc_mem_get(mctx, sizeof(*ictx));
- if (ictx == NULL)
- return (ISC_R_NOMEMORY);
-
- for (i = 0; i < NBUFS; i++) {
- dns_fixedname_init(&ictx->fixed[i]);
- ictx->in_use[i] = ISC_FALSE;
- }
-
- ictx->origin_in_use = 0;
- ictx->origin = dns_fixedname_name(&ictx->fixed[ictx->origin_in_use]);
- ictx->in_use[ictx->origin_in_use] = ISC_TRUE;
- dns_name_toregion(origin, &r);
- dns_name_fromregion(ictx->origin, &r);
-
- ictx->glue = NULL;
- ictx->current = NULL;
- ictx->glue_in_use = -1;
- ictx->current_in_use = -1;
- ictx->parent = NULL;
- ictx->drop = ISC_FALSE;
- ictx->glue_line = 0;
- ictx->current_line = 0;
-
- *ictxp = ictx;
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-loadctx_create(dns_masterformat_t format, isc_mem_t *mctx,
- unsigned int options, isc_uint32_t resign, dns_name_t *top,
- dns_rdataclass_t zclass, dns_name_t *origin,
- dns_rdatacallbacks_t *callbacks, isc_task_t *task,
- dns_loaddonefunc_t done, void *done_arg, isc_lex_t *lex,
- dns_loadctx_t **lctxp)
-{
- dns_loadctx_t *lctx;
- isc_result_t result;
- isc_region_t r;
- isc_lexspecials_t specials;
-
- REQUIRE(lctxp != NULL && *lctxp == NULL);
- REQUIRE(callbacks != NULL);
- REQUIRE(callbacks->add != NULL);
- REQUIRE(callbacks->error != NULL);
- REQUIRE(callbacks->warn != NULL);
- REQUIRE(mctx != NULL);
- REQUIRE(dns_name_isabsolute(top));
- REQUIRE(dns_name_isabsolute(origin));
- REQUIRE((task == NULL && done == NULL) ||
- (task != NULL && done != NULL));
-
- lctx = isc_mem_get(mctx, sizeof(*lctx));
- if (lctx == NULL)
- return (ISC_R_NOMEMORY);
- result = isc_mutex_init(&lctx->lock);
- if (result != ISC_R_SUCCESS) {
- isc_mem_put(mctx, lctx, sizeof(*lctx));
- return (result);
- }
-
- lctx->inc = NULL;
- result = incctx_create(mctx, origin, &lctx->inc);
- if (result != ISC_R_SUCCESS)
- goto cleanup_ctx;
-
- lctx->format = format;
- switch (format) {
- default:
- INSIST(0);
- case dns_masterformat_text:
- lctx->openfile = openfile_text;
- lctx->load = load_text;
- break;
- case dns_masterformat_raw:
- lctx->openfile = openfile_raw;
- lctx->load = load_raw;
- break;
- }
-
- if (lex != NULL) {
- lctx->lex = lex;
- lctx->keep_lex = ISC_TRUE;
- } else {
- lctx->lex = NULL;
- result = isc_lex_create(mctx, TOKENSIZ, &lctx->lex);
- if (result != ISC_R_SUCCESS)
- goto cleanup_inc;
- lctx->keep_lex = ISC_FALSE;
- memset(specials, 0, sizeof(specials));
- specials[0] = 1;
- specials['('] = 1;
- specials[')'] = 1;
- specials['"'] = 1;
- isc_lex_setspecials(lctx->lex, specials);
- isc_lex_setcomments(lctx->lex, ISC_LEXCOMMENT_DNSMASTERFILE);
- }
-
- lctx->ttl_known = ISC_FALSE;
- lctx->ttl = 0;
- lctx->default_ttl_known = ISC_FALSE;
- lctx->default_ttl = 0;
- lctx->warn_1035 = ISC_TRUE; /* XXX Argument? */
- lctx->warn_tcr = ISC_TRUE; /* XXX Argument? */
- lctx->warn_sigexpired = ISC_TRUE; /* XXX Argument? */
- lctx->options = options;
- lctx->seen_include = ISC_FALSE;
- lctx->zclass = zclass;
- lctx->resign = resign;
- lctx->result = ISC_R_SUCCESS;
-
- dns_fixedname_init(&lctx->fixed_top);
- lctx->top = dns_fixedname_name(&lctx->fixed_top);
- dns_name_toregion(top, &r);
- dns_name_fromregion(lctx->top, &r);
-
- lctx->f = NULL;
- lctx->first = ISC_TRUE;
- dns_master_initrawheader(&lctx->header);
-
- lctx->loop_cnt = (done != NULL) ? 100 : 0;
- lctx->callbacks = callbacks;
- lctx->task = NULL;
- if (task != NULL)
- isc_task_attach(task, &lctx->task);
- lctx->done = done;
- lctx->done_arg = done_arg;
- lctx->canceled = ISC_FALSE;
- lctx->mctx = NULL;
- isc_mem_attach(mctx, &lctx->mctx);
- lctx->references = 1; /* Implicit attach. */
- lctx->magic = DNS_LCTX_MAGIC;
- *lctxp = lctx;
- return (ISC_R_SUCCESS);
-
- cleanup_inc:
- incctx_destroy(mctx, lctx->inc);
- cleanup_ctx:
- isc_mem_put(mctx, lctx, sizeof(*lctx));
- 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")];
- char numbuf[128];
- char *cp;
- char mode[2];
- int delta = 0;
- isc_textregion_t r;
- unsigned int n;
- unsigned int width;
- isc_boolean_t nibblemode;
-
- r.base = buffer;
- r.length = length;
-
- while (*name != '\0') {
- if (*name == '$') {
- name++;
- if (*name == '$') {
- if (r.length == 0)
- return (ISC_R_NOSPACE);
- r.base[0] = *name++;
- isc_textregion_consume(&r, 1);
- continue;
- }
- nibblemode = ISC_FALSE;
- strcpy(fmt, "%d");
- /* Get format specifier. */
- if (*name == '{' ) {
- n = sscanf(name, "{%d,%u,%1[doxXnN]}",
- &delta, &width, mode);
- switch (n) {
- case 1:
- break;
- case 2:
- n = snprintf(fmt, sizeof(fmt),
- "%%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;
- default:
- return (DNS_R_SYNTAX);
- }
- if (n >= sizeof(fmt))
- return (ISC_R_NOSPACE);
- /* Skip past closing brace. */
- while (*name != '\0' && *name++ != '}')
- continue;
- }
- 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;
- while (*cp != '\0') {
- if (r.length == 0)
- return (ISC_R_NOSPACE);
- r.base[0] = *cp++;
- isc_textregion_consume(&r, 1);
- }
- } else if (*name == '\\') {
- if (r.length == 0)
- return (ISC_R_NOSPACE);
- r.base[0] = *name++;
- isc_textregion_consume(&r, 1);
- if (*name == '\0')
- continue;
- if (r.length == 0)
- return (ISC_R_NOSPACE);
- r.base[0] = *name++;
- isc_textregion_consume(&r, 1);
- } else {
- if (r.length == 0)
- return (ISC_R_NOSPACE);
- r.base[0] = *name++;
- isc_textregion_consume(&r, 1);
- }
- }
- if (r.length == 0)
- return (ISC_R_NOSPACE);
- r.base[0] = '\0';
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-openfile_text(dns_loadctx_t *lctx, const char *master_file) {
- return (isc_lex_openfile(lctx->lex, master_file));
-}
-
-static isc_result_t
-openfile_raw(dns_loadctx_t *lctx, const char *master_file) {
- isc_result_t result;
-
- result = isc_stdio_open(master_file, "rb", &lctx->f);
- if (result != ISC_R_SUCCESS && result != ISC_R_FILENOTFOUND) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_stdio_open() failed: %s",
- isc_result_totext(result));
- }
-
- return (result);
-}
-
-static isc_result_t
-generate(dns_loadctx_t *lctx, char *range, char *lhs, char *gtype, char *rhs,
- const char *source, unsigned int line)
-{
- char *target_mem = NULL;
- char *lhsbuf = NULL;
- char *rhsbuf = NULL;
- dns_fixedname_t ownerfixed;
- dns_name_t *owner;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdatacallbacks_t *callbacks;
- dns_rdatalist_t rdatalist;
- dns_rdatatype_t type;
- rdatalist_head_t head;
- int n;
- int target_size = MINTSIZ; /* only one rdata at a time */
- isc_buffer_t buffer;
- isc_buffer_t target;
- isc_result_t result;
- isc_textregion_t r;
- unsigned int start, stop, step, i;
- dns_incctx_t *ictx;
-
- ictx = lctx->inc;
- callbacks = lctx->callbacks;
- dns_fixedname_init(&ownerfixed);
- owner = dns_fixedname_name(&ownerfixed);
- ISC_LIST_INIT(head);
-
- target_mem = isc_mem_get(lctx->mctx, target_size);
- 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;
- }
- isc_buffer_init(&target, target_mem, target_size);
-
- n = sscanf(range, "%u-%u/%u", &start, &stop, &step);
- if (n < 2 || stop < start) {
- (*callbacks->error)(callbacks,
- "%s: %s:%lu: invalid range '%s'",
- "$GENERATE", source, line, range);
- result = DNS_R_SYNTAX;
- goto insist_cleanup;
- }
- if (n == 2)
- step = 1;
-
- /*
- * Get type.
- */
- r.base = gtype;
- r.length = strlen(gtype);
- result = dns_rdatatype_fromtext(&type, &r);
- if (result != ISC_R_SUCCESS) {
- (*callbacks->error)(callbacks,
- "%s: %s:%lu: unknown RR type '%s'",
- "$GENERATE", source, line, gtype);
- goto insist_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_LHS);
- if (result != ISC_R_SUCCESS)
- goto error_cleanup;
- result = genname(rhs, i, rhsbuf, DNS_MASTER_RHS);
- if (result != ISC_R_SUCCESS)
- goto error_cleanup;
-
- isc_buffer_init(&buffer, lhsbuf, strlen(lhsbuf));
- isc_buffer_add(&buffer, strlen(lhsbuf));
- isc_buffer_setactive(&buffer, strlen(lhsbuf));
- result = dns_name_fromtext(owner, &buffer, ictx->origin,
- 0, NULL);
- if (result != ISC_R_SUCCESS)
- goto error_cleanup;
-
- 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];
- dns_name_format(owner, namebuf, sizeof(namebuf));
- /*
- * Ignore out-of-zone data.
- */
- (*callbacks->warn)(callbacks,
- "%s:%lu: "
- "ignoring out-of-zone data (%s)",
- source, line, namebuf);
- continue;
- }
-
- isc_buffer_init(&buffer, rhsbuf, strlen(rhsbuf));
- isc_buffer_add(&buffer, strlen(rhsbuf));
- isc_buffer_setactive(&buffer, strlen(rhsbuf));
-
- result = isc_lex_openbuffer(lctx->lex, &buffer);
- if (result != ISC_R_SUCCESS)
- goto error_cleanup;
-
- isc_buffer_init(&target, target_mem, target_size);
- result = dns_rdata_fromtext(&rdata, lctx->zclass, type,
- lctx->lex, ictx->origin, 0,
- lctx->mctx, &target, callbacks);
- RUNTIME_CHECK(isc_lex_close(lctx->lex) == ISC_R_SUCCESS);
- if (result != ISC_R_SUCCESS)
- goto error_cleanup;
-
- rdatalist.type = type;
- rdatalist.covers = 0;
- rdatalist.rdclass = lctx->zclass;
- rdatalist.ttl = lctx->ttl;
- ISC_LIST_PREPEND(head, &rdatalist, link);
- ISC_LIST_APPEND(rdatalist.rdata, &rdata, link);
- result = commit(callbacks, lctx, &head, owner, source, line);
- ISC_LIST_UNLINK(rdatalist.rdata, &rdata, link);
- if (result != ISC_R_SUCCESS)
- goto error_cleanup;
- dns_rdata_reset(&rdata);
- }
- result = ISC_R_SUCCESS;
- goto cleanup;
-
- error_cleanup:
- if (result == ISC_R_NOMEMORY)
- (*callbacks->error)(callbacks, "$GENERATE: %s",
- dns_result_totext(result));
- else
- (*callbacks->error)(callbacks, "$GENERATE: %s:%lu: %s",
- source, line, dns_result_totext(result));
-
- insist_cleanup:
- INSIST(result != ISC_R_SUCCESS);
-
- cleanup:
- if (target_mem != NULL)
- isc_mem_put(lctx->mctx, target_mem, target_size);
- if (lhsbuf != NULL)
- isc_mem_put(lctx->mctx, lhsbuf, DNS_MASTER_LHS);
- if (rhsbuf != NULL)
- isc_mem_put(lctx->mctx, rhsbuf, DNS_MASTER_RHS);
- return (result);
-}
-
-static void
-limit_ttl(dns_rdatacallbacks_t *callbacks, const char *source, unsigned int line,
- isc_uint32_t *ttlp)
-{
- if (*ttlp > 0x7fffffffUL) {
- (callbacks->warn)(callbacks,
- "%s: %s:%lu: "
- "$TTL %lu > MAXTTL, "
- "setting $TTL to 0",
- "dns_master_load",
- source, line,
- *ttlp);
- *ttlp = 0;
- }
-}
-
-static isc_result_t
-check_ns(dns_loadctx_t *lctx, isc_token_t *token, const char *source,
- unsigned long line)
-{
- char *tmp = NULL;
- isc_result_t result = ISC_R_SUCCESS;
- void (*callback)(struct dns_rdatacallbacks *, const char *, ...);
-
- if ((lctx->options & DNS_MASTER_FATALNS) != 0)
- callback = lctx->callbacks->error;
- else
- callback = lctx->callbacks->warn;
-
- if (token->type == isc_tokentype_string) {
- struct in_addr addr;
- struct in6_addr addr6;
-
- tmp = isc_mem_strdup(lctx->mctx, DNS_AS_STR(*token));
- if (tmp == NULL)
- return (ISC_R_NOMEMORY);
- /*
- * Catch both "1.2.3.4" and "1.2.3.4."
- */
- if (tmp[strlen(tmp) - 1] == '.')
- tmp[strlen(tmp) - 1] = '\0';
- if (inet_aton(tmp, &addr) == 1 ||
- inet_pton(AF_INET6, tmp, &addr6) == 1)
- result = DNS_R_NSISADDRESS;
- }
- if (result != ISC_R_SUCCESS)
- (*callback)(lctx->callbacks, "%s:%lu: NS record '%s' "
- "appears to be an address",
- source, line, DNS_AS_STR(*token));
- if (tmp != NULL)
- isc_mem_free(lctx->mctx, tmp);
- return (result);
-}
-
-static void
-check_wildcard(dns_incctx_t *ictx, const char *source, unsigned long line,
- dns_rdatacallbacks_t *callbacks)
-{
- dns_name_t *name;
-
- name = (ictx->glue != NULL) ? ictx->glue : ictx->current;
- if (dns_name_internalwildcard(name)) {
- char namebuf[DNS_NAME_FORMATSIZE];
-
- dns_name_format(name, namebuf, sizeof(namebuf));
- (*callbacks->warn)(callbacks, "%s:%lu: warning: ownername "
- "'%s' contains an non-terminal wildcard",
- source, line, namebuf);
- }
-}
-
-static isc_result_t
-load_text(dns_loadctx_t *lctx) {
- dns_rdataclass_t rdclass;
- dns_rdatatype_t type, covers;
- isc_uint32_t ttl_offset = 0;
- dns_name_t *new_name;
- isc_boolean_t current_has_delegation = ISC_FALSE;
- isc_boolean_t done = ISC_FALSE;
- isc_boolean_t finish_origin = ISC_FALSE;
- isc_boolean_t finish_include = ISC_FALSE;
- isc_boolean_t read_till_eol = ISC_FALSE;
- isc_boolean_t initialws;
- char *include_file = NULL;
- isc_token_t token;
- isc_result_t result = ISC_R_UNEXPECTED;
- rdatalist_head_t glue_list;
- rdatalist_head_t current_list;
- dns_rdatalist_t *this;
- dns_rdatalist_t *rdatalist = NULL;
- dns_rdatalist_t *new_rdatalist;
- int rdlcount = 0;
- int rdlcount_save = 0;
- int rdatalist_size = 0;
- isc_buffer_t buffer;
- isc_buffer_t target;
- isc_buffer_t target_ft;
- isc_buffer_t target_save;
- dns_rdata_t *rdata = NULL;
- dns_rdata_t *new_rdata;
- int rdcount = 0;
- int rdcount_save = 0;
- int rdata_size = 0;
- unsigned char *target_mem = NULL;
- int target_size = TSIZ;
- int new_in_use;
- unsigned int loop_cnt = 0;
- isc_mem_t *mctx;
- dns_rdatacallbacks_t *callbacks;
- dns_incctx_t *ictx;
- char *range = NULL;
- char *lhs = NULL;
- char *gtype = NULL;
- char *rhs = NULL;
- const char *source = "";
- unsigned long line = 0;
- isc_boolean_t explicit_ttl;
- isc_stdtime_t now;
- char classname1[DNS_RDATACLASS_FORMATSIZE];
- char classname2[DNS_RDATACLASS_FORMATSIZE];
- unsigned int options = 0;
-
- REQUIRE(DNS_LCTX_VALID(lctx));
- callbacks = lctx->callbacks;
- mctx = lctx->mctx;
- ictx = lctx->inc;
-
- ISC_LIST_INIT(glue_list);
- ISC_LIST_INIT(current_list);
-
- isc_stdtime_get(&now);
-
- /*
- * Allocate target_size of buffer space. This is greater than twice
- * the maximum individual RR data size.
- */
- target_mem = isc_mem_get(mctx, target_size);
- if (target_mem == NULL) {
- result = ISC_R_NOMEMORY;
- goto log_and_cleanup;
- }
- isc_buffer_init(&target, target_mem, target_size);
- target_save = target;
-
- if ((lctx->options & DNS_MASTER_CHECKNAMES) != 0)
- options |= DNS_RDATA_CHECKNAMES;
- if ((lctx->options & DNS_MASTER_CHECKNAMESFAIL) != 0)
- options |= DNS_RDATA_CHECKNAMESFAIL;
- if ((lctx->options & DNS_MASTER_CHECKMX) != 0)
- options |= DNS_RDATA_CHECKMX;
- if ((lctx->options & DNS_MASTER_CHECKMXFAIL) != 0)
- options |= DNS_RDATA_CHECKMXFAIL;
- source = isc_lex_getsourcename(lctx->lex);
- do {
- initialws = ISC_FALSE;
- line = isc_lex_getsourceline(lctx->lex);
- GETTOKEN(lctx->lex, ISC_LEXOPT_INITIALWS | ISC_LEXOPT_QSTRING,
- &token, ISC_TRUE);
- line = isc_lex_getsourceline(lctx->lex);
-
- if (token.type == isc_tokentype_eof) {
- if (read_till_eol)
- WARNUNEXPECTEDEOF(lctx->lex);
- /* Pop the include stack? */
- if (ictx->parent != NULL) {
- COMMITALL;
- lctx->inc = ictx->parent;
- ictx->parent = NULL;
- incctx_destroy(lctx->mctx, ictx);
- RUNTIME_CHECK(isc_lex_close(lctx->lex) == ISC_R_SUCCESS);
- line = isc_lex_getsourceline(lctx->lex);
- source = isc_lex_getsourcename(lctx->lex);
- ictx = lctx->inc;
- EXPECTEOL;
- continue;
- }
- done = ISC_TRUE;
- continue;
- }
-
- if (token.type == isc_tokentype_eol) {
- read_till_eol = ISC_FALSE;
- continue; /* blank line */
- }
-
- if (read_till_eol)
- continue;
-
- if (token.type == isc_tokentype_initialws) {
- /*
- * Still working on the same name.
- */
- initialws = ISC_TRUE;
- } else if (token.type == isc_tokentype_string ||
- token.type == isc_tokentype_qstring) {
-
- /*
- * "$" Support.
- *
- * "$ORIGIN" and "$INCLUDE" can both take domain names.
- * The processing of "$ORIGIN" and "$INCLUDE" extends
- * across the normal domain name processing.
- */
-
- if (strcasecmp(DNS_AS_STR(token), "$ORIGIN") == 0) {
- GETTOKEN(lctx->lex, 0, &token, ISC_FALSE);
- finish_origin = ISC_TRUE;
- } else if (strcasecmp(DNS_AS_STR(token),
- "$TTL") == 0) {
- GETTOKEN(lctx->lex, 0, &token, ISC_FALSE);
- result =
- dns_ttl_fromtext(&token.value.as_textregion,
- &lctx->ttl);
- if (MANYERRS(lctx, result)) {
- SETRESULT(lctx, result);
- lctx->ttl = 0;
- } else if (result != ISC_R_SUCCESS)
- goto insist_and_cleanup;
- limit_ttl(callbacks, source, line, &lctx->ttl);
- lctx->default_ttl = lctx->ttl;
- lctx->default_ttl_known = ISC_TRUE;
- EXPECTEOL;
- continue;
- } else if (strcasecmp(DNS_AS_STR(token),
- "$INCLUDE") == 0) {
- COMMITALL;
- if ((lctx->options & DNS_MASTER_NOINCLUDE)
- != 0)
- {
- (callbacks->error)(callbacks,
- "%s: %s:%lu: $INCLUDE not allowed",
- "dns_master_load",
- source, line);
- result = DNS_R_REFUSED;
- goto insist_and_cleanup;
- }
- if (ttl_offset != 0) {
- (callbacks->error)(callbacks,
- "%s: %s:%lu: $INCLUDE "
- "may not be used with $DATE",
- "dns_master_load",
- source, line);
- result = DNS_R_SYNTAX;
- goto insist_and_cleanup;
- }
- GETTOKEN(lctx->lex, ISC_LEXOPT_QSTRING, &token,
- ISC_FALSE);
- if (include_file != NULL)
- isc_mem_free(mctx, include_file);
- include_file = isc_mem_strdup(mctx,
- DNS_AS_STR(token));
- if (include_file == NULL) {
- result = ISC_R_NOMEMORY;
- goto log_and_cleanup;
- }
- GETTOKEN(lctx->lex, 0, &token, ISC_TRUE);
-
- if (token.type == isc_tokentype_eol ||
- token.type == isc_tokentype_eof) {
- if (token.type == isc_tokentype_eof)
- WARNUNEXPECTEDEOF(lctx->lex);
- isc_lex_ungettoken(lctx->lex, &token);
- /*
- * No origin field.
- */
- result = pushfile(include_file,
- ictx->origin, lctx);
- if (MANYERRS(lctx, result)) {
- SETRESULT(lctx, result);
- LOGITFILE(result, include_file);
- continue;
- } else if (result != ISC_R_SUCCESS) {
- LOGITFILE(result, include_file);
- goto insist_and_cleanup;
- }
- ictx = lctx->inc;
- source =
- isc_lex_getsourcename(lctx->lex);
- line = isc_lex_getsourceline(lctx->lex);
- POST(line);
- continue;
- }
- /*
- * There is an origin field. Fall through
- * to domain name processing code and do
- * the actual inclusion later.
- */
- finish_include = ISC_TRUE;
- } else if (strcasecmp(DNS_AS_STR(token),
- "$DATE") == 0) {
- isc_int64_t dump_time64;
- isc_stdtime_t dump_time, current_time;
- GETTOKEN(lctx->lex, 0, &token, ISC_FALSE);
- isc_stdtime_get(&current_time);
- result = dns_time64_fromtext(DNS_AS_STR(token),
- &dump_time64);
- if (MANYERRS(lctx, result)) {
- SETRESULT(lctx, result);
- LOGIT(result);
- dump_time64 = 0;
- } else if (result != ISC_R_SUCCESS)
- goto log_and_cleanup;
- dump_time = (isc_stdtime_t)dump_time64;
- if (dump_time != dump_time64) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "%s: %s:%lu: $DATE outside epoch",
- "dns_master_load", source, line);
- result = ISC_R_UNEXPECTED;
- goto insist_and_cleanup;
- }
- if (dump_time > current_time) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "%s: %s:%lu: "
- "$DATE in future, using current date",
- "dns_master_load", source, line);
- dump_time = current_time;
- }
- ttl_offset = current_time - dump_time;
- EXPECTEOL;
- continue;
- } else if (strcasecmp(DNS_AS_STR(token),
- "$GENERATE") == 0) {
- /*
- * Lazy cleanup.
- */
- if (range != NULL)
- isc_mem_free(mctx, range);
- if (lhs != NULL)
- isc_mem_free(mctx, lhs);
- if (gtype != NULL)
- isc_mem_free(mctx, gtype);
- if (rhs != NULL)
- isc_mem_free(mctx, rhs);
- range = lhs = gtype = rhs = NULL;
- /* RANGE */
- GETTOKEN(lctx->lex, 0, &token, ISC_FALSE);
- range = isc_mem_strdup(mctx,
- DNS_AS_STR(token));
- if (range == NULL) {
- result = ISC_R_NOMEMORY;
- goto log_and_cleanup;
- }
- /* LHS */
- GETTOKEN(lctx->lex, 0, &token, ISC_FALSE);
- lhs = isc_mem_strdup(mctx, DNS_AS_STR(token));
- if (lhs == NULL) {
- result = ISC_R_NOMEMORY;
- goto log_and_cleanup;
- }
- rdclass = 0;
- explicit_ttl = ISC_FALSE;
- /* CLASS? */
- GETTOKEN(lctx->lex, 0, &token, ISC_FALSE);
- if (dns_rdataclass_fromtext(&rdclass,
- &token.value.as_textregion)
- == ISC_R_SUCCESS) {
- GETTOKEN(lctx->lex, 0, &token,
- ISC_FALSE);
- }
- /* TTL? */
- if (dns_ttl_fromtext(&token.value.as_textregion,
- &lctx->ttl)
- == ISC_R_SUCCESS) {
- limit_ttl(callbacks, source, line,
- &lctx->ttl);
- lctx->ttl_known = ISC_TRUE;
- explicit_ttl = ISC_TRUE;
- GETTOKEN(lctx->lex, 0, &token,
- ISC_FALSE);
- }
- /* CLASS? */
- if (rdclass == 0 &&
- dns_rdataclass_fromtext(&rdclass,
- &token.value.as_textregion)
- == ISC_R_SUCCESS)
- GETTOKEN(lctx->lex, 0, &token,
- ISC_FALSE);
- /* TYPE */
- gtype = isc_mem_strdup(mctx,
- DNS_AS_STR(token));
- if (gtype == NULL) {
- result = ISC_R_NOMEMORY;
- goto log_and_cleanup;
- }
- /* RHS */
- 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;
- goto log_and_cleanup;
- }
- if (!lctx->ttl_known &&
- !lctx->default_ttl_known) {
- (*callbacks->error)(callbacks,
- "%s: %s:%lu: no TTL specified",
- "dns_master_load", source, line);
- result = DNS_R_NOTTL;
- if (MANYERRS(lctx, result)) {
- SETRESULT(lctx, result);
- lctx->ttl = 0;
- } else if (result != ISC_R_SUCCESS)
- goto insist_and_cleanup;
- } else if (!explicit_ttl &&
- lctx->default_ttl_known) {
- lctx->ttl = lctx->default_ttl;
- }
- /*
- * If the class specified does not match the
- * zone's class print out a error message and
- * exit.
- */
- if (rdclass != 0 && rdclass != lctx->zclass) {
- goto bad_class;
- }
- result = generate(lctx, range, lhs, gtype, rhs,
- source, line);
- if (MANYERRS(lctx, result)) {
- SETRESULT(lctx, result);
- } else if (result != ISC_R_SUCCESS)
- goto insist_and_cleanup;
- EXPECTEOL;
- continue;
- } else if (strncasecmp(DNS_AS_STR(token),
- "$", 1) == 0) {
- (callbacks->error)(callbacks,
- "%s: %s:%lu: "
- "unknown $ directive '%s'",
- "dns_master_load", source, line,
- DNS_AS_STR(token));
- result = DNS_R_SYNTAX;
- if (MANYERRS(lctx, result)) {
- SETRESULT(lctx, result);
- } else if (result != ISC_R_SUCCESS)
- goto insist_and_cleanup;
- }
-
- /*
- * Normal processing resumes.
- *
- * Find a free name buffer.
- */
- for (new_in_use = 0; new_in_use < NBUFS; new_in_use++)
- if (!ictx->in_use[new_in_use])
- break;
- INSIST(new_in_use < NBUFS);
- dns_fixedname_init(&ictx->fixed[new_in_use]);
- new_name = dns_fixedname_name(&ictx->fixed[new_in_use]);
- isc_buffer_init(&buffer, token.value.as_region.base,
- token.value.as_region.length);
- isc_buffer_add(&buffer, token.value.as_region.length);
- isc_buffer_setactive(&buffer,
- token.value.as_region.length);
- result = dns_name_fromtext(new_name, &buffer,
- ictx->origin, 0, NULL);
- if (MANYERRS(lctx, result)) {
- SETRESULT(lctx, result);
- LOGIT(result);
- read_till_eol = ISC_TRUE;
- continue;
- } else if (result != ISC_R_SUCCESS)
- goto log_and_cleanup;
-
- /*
- * Finish $ORIGIN / $INCLUDE processing if required.
- */
- if (finish_origin) {
- if (ictx->origin_in_use != -1)
- ictx->in_use[ictx->origin_in_use] =
- ISC_FALSE;
- ictx->origin_in_use = new_in_use;
- ictx->in_use[ictx->origin_in_use] = ISC_TRUE;
- ictx->origin = new_name;
- ictx->origin_changed = ISC_TRUE;
- finish_origin = ISC_FALSE;
- EXPECTEOL;
- continue;
- }
- if (finish_include) {
- finish_include = ISC_FALSE;
- result = pushfile(include_file, new_name, lctx);
- if (MANYERRS(lctx, result)) {
- SETRESULT(lctx, result);
- LOGITFILE(result, include_file);
- continue;
- } else if (result != ISC_R_SUCCESS) {
- LOGITFILE(result, include_file);
- goto insist_and_cleanup;
- }
- ictx = lctx->inc;
- source = isc_lex_getsourcename(lctx->lex);
- line = isc_lex_getsourceline(lctx->lex);
- POST(line);
- continue;
- }
-
- /*
- * "$" Processing Finished
- */
-
- /*
- * If we are processing glue and the new name does
- * not match the current glue name, commit the glue
- * and pop stacks leaving us in 'normal' processing
- * state. Linked lists are undone by commit().
- */
- if (ictx->glue != NULL &&
- dns_name_compare(ictx->glue, new_name) != 0) {
- result = commit(callbacks, lctx, &glue_list,
- ictx->glue, source,
- ictx->glue_line);
- if (MANYERRS(lctx, result)) {
- SETRESULT(lctx, result);
- } else if (result != ISC_R_SUCCESS)
- goto insist_and_cleanup;
- if (ictx->glue_in_use != -1)
- ictx->in_use[ictx->glue_in_use] =
- ISC_FALSE;
- ictx->glue_in_use = -1;
- ictx->glue = NULL;
- rdcount = rdcount_save;
- rdlcount = rdlcount_save;
- target = target_save;
- }
-
- /*
- * If we are in 'normal' processing state and the new
- * name does not match the current name, see if the
- * new name is for glue and treat it as such,
- * otherwise we have a new name so commit what we
- * have.
- */
- if ((ictx->glue == NULL) && (ictx->current == NULL ||
- dns_name_compare(ictx->current, new_name) != 0)) {
- if (current_has_delegation &&
- is_glue(&current_list, new_name)) {
- rdcount_save = rdcount;
- rdlcount_save = rdlcount;
- target_save = target;
- ictx->glue = new_name;
- ictx->glue_in_use = new_in_use;
- ictx->in_use[ictx->glue_in_use] =
- ISC_TRUE;
- } else {
- result = commit(callbacks, lctx,
- &current_list,
- ictx->current,
- source,
- ictx->current_line);
- if (MANYERRS(lctx, result)) {
- SETRESULT(lctx, result);
- } else if (result != ISC_R_SUCCESS)
- goto insist_and_cleanup;
- rdcount = 0;
- rdlcount = 0;
- if (ictx->current_in_use != -1)
- ictx->in_use[ictx->current_in_use] =
- ISC_FALSE;
- ictx->current_in_use = new_in_use;
- ictx->in_use[ictx->current_in_use] =
- ISC_TRUE;
- ictx->current = new_name;
- current_has_delegation = ISC_FALSE;
- isc_buffer_init(&target, target_mem,
- target_size);
- }
- /*
- * Check for internal wildcards.
- */
- if ((lctx->options & DNS_MASTER_CHECKWILDCARD)
- != 0)
- check_wildcard(ictx, source, line,
- callbacks);
-
- }
- 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];
- dns_name_format(new_name, namebuf,
- sizeof(namebuf));
- /*
- * Ignore out-of-zone data.
- */
- (*callbacks->warn)(callbacks,
- "%s:%lu: "
- "ignoring out-of-zone data (%s)",
- source, line, namebuf);
- ictx->drop = ISC_TRUE;
- } else
- ictx->drop = ISC_FALSE;
- } else {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "%s:%lu: isc_lex_gettoken() returned "
- "unexpected token type (%d)",
- source, line, token.type);
- result = ISC_R_UNEXPECTED;
- if (MANYERRS(lctx, result)) {
- SETRESULT(lctx, result);
- LOGIT(result);
- continue;
- } else if (result != ISC_R_SUCCESS)
- goto insist_and_cleanup;
- }
-
- /*
- * Find TTL, class and type. Both TTL and class are optional
- * and may occur in any order if they exist. TTL and class
- * come before type which must exist.
- *
- * [<TTL>] [<class>] <type> <RDATA>
- * [<class>] [<TTL>] <type> <RDATA>
- */
-
- type = 0;
- rdclass = 0;
-
- GETTOKEN(lctx->lex, 0, &token, initialws);
-
- if (initialws) {
- if (token.type == isc_tokentype_eol) {
- read_till_eol = ISC_FALSE;
- continue; /* blank line */
- }
-
- if (token.type == isc_tokentype_eof) {
- WARNUNEXPECTEDEOF(lctx->lex);
- read_till_eol = ISC_FALSE;
- isc_lex_ungettoken(lctx->lex, &token);
- continue;
- }
-
- if (ictx->current == NULL) {
- (*callbacks->error)(callbacks,
- "%s:%lu: no current owner name",
- source, line);
- result = DNS_R_NOOWNER;
- if (MANYERRS(lctx, result)) {
- SETRESULT(lctx, result);
- read_till_eol = ISC_TRUE;
- continue;
- } else if (result != ISC_R_SUCCESS)
- goto insist_and_cleanup;
- }
-
- if (ictx->origin_changed) {
- char cbuf[DNS_NAME_FORMATSIZE];
- char obuf[DNS_NAME_FORMATSIZE];
- dns_name_format(ictx->current, cbuf,
- sizeof(cbuf));
- dns_name_format(ictx->origin, obuf,
- sizeof(obuf));
- (*callbacks->warn)(callbacks,
- "%s:%lu: record with inherited "
- "owner (%s) immediately after "
- "$ORIGIN (%s)", source, line,
- cbuf, obuf);
- }
- }
-
- ictx->origin_changed = ISC_FALSE;
-
- if (dns_rdataclass_fromtext(&rdclass,
- &token.value.as_textregion)
- == ISC_R_SUCCESS)
- GETTOKEN(lctx->lex, 0, &token, ISC_FALSE);
-
- explicit_ttl = ISC_FALSE;
- if (dns_ttl_fromtext(&token.value.as_textregion, &lctx->ttl)
- == ISC_R_SUCCESS) {
- limit_ttl(callbacks, source, line, &lctx->ttl);
- explicit_ttl = ISC_TRUE;
- lctx->ttl_known = ISC_TRUE;
- GETTOKEN(lctx->lex, 0, &token, ISC_FALSE);
- }
-
- if (token.type != isc_tokentype_string) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_lex_gettoken() returned unexpected token type");
- result = ISC_R_UNEXPECTED;
- if (MANYERRS(lctx, result)) {
- SETRESULT(lctx, result);
- read_till_eol = ISC_TRUE;
- continue;
- } else if (result != ISC_R_SUCCESS)
- goto insist_and_cleanup;
- }
-
- if (rdclass == 0 &&
- dns_rdataclass_fromtext(&rdclass,
- &token.value.as_textregion)
- == ISC_R_SUCCESS)
- GETTOKEN(lctx->lex, 0, &token, ISC_FALSE);
-
- if (token.type != isc_tokentype_string) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_lex_gettoken() returned unexpected token type");
- result = ISC_R_UNEXPECTED;
- if (MANYERRS(lctx, result)) {
- SETRESULT(lctx, result);
- read_till_eol = ISC_TRUE;
- continue;
- } else if (result != ISC_R_SUCCESS)
- goto insist_and_cleanup;
- }
-
- result = dns_rdatatype_fromtext(&type,
- &token.value.as_textregion);
- if (result != ISC_R_SUCCESS) {
- (*callbacks->warn)(callbacks,
- "%s:%lu: unknown RR type '%.*s'",
- source, line,
- token.value.as_textregion.length,
- token.value.as_textregion.base);
- if (MANYERRS(lctx, result)) {
- SETRESULT(lctx, result);
- read_till_eol = ISC_TRUE;
- continue;
- } else if (result != ISC_R_SUCCESS)
- goto insist_and_cleanup;
- }
-
- /*
- * If the class specified does not match the zone's class
- * print out a error message and exit.
- */
- if (rdclass != 0 && rdclass != lctx->zclass) {
- bad_class:
-
- dns_rdataclass_format(rdclass, classname1,
- sizeof(classname1));
- dns_rdataclass_format(lctx->zclass, classname2,
- sizeof(classname2));
- (*callbacks->error)(callbacks,
- "%s:%lu: class '%s' != "
- "zone class '%s'",
- source, line,
- classname1, classname2);
- result = DNS_R_BADCLASS;
- if (MANYERRS(lctx, result)) {
- SETRESULT(lctx, result);
- read_till_eol = ISC_TRUE;
- continue;
- } else if (result != ISC_R_SUCCESS)
- goto insist_and_cleanup;
- }
-
- if (type == dns_rdatatype_ns && ictx->glue == NULL)
- current_has_delegation = ISC_TRUE;
-
- /*
- * RFC1123: MD and MF are not allowed to be loaded from
- * master files.
- */
- if ((lctx->options & DNS_MASTER_ZONE) != 0 &&
- (lctx->options & DNS_MASTER_SLAVE) == 0 &&
- (type == dns_rdatatype_md || type == dns_rdatatype_mf)) {
- char typename[DNS_RDATATYPE_FORMATSIZE];
-
- result = DNS_R_OBSOLETE;
-
- dns_rdatatype_format(type, typename, sizeof(typename));
- (*callbacks->error)(callbacks,
- "%s:%lu: %s '%s': %s",
- source, line,
- "type", typename,
- dns_result_totext(result));
- if (MANYERRS(lctx, result)) {
- SETRESULT(lctx, result);
- } else
- goto insist_and_cleanup;
- }
-
- /*
- * Find a rdata structure.
- */
- if (rdcount == rdata_size) {
- new_rdata = grow_rdata(rdata_size + RDSZ, rdata,
- rdata_size, &current_list,
- &glue_list, mctx);
- if (new_rdata == NULL) {
- result = ISC_R_NOMEMORY;
- goto log_and_cleanup;
- }
- rdata_size += RDSZ;
- rdata = new_rdata;
- }
-
- /*
- * Peek at the NS record.
- */
- if (type == dns_rdatatype_ns &&
- lctx->zclass == dns_rdataclass_in &&
- (lctx->options & DNS_MASTER_CHECKNS) != 0) {
-
- GETTOKEN(lctx->lex, 0, &token, ISC_FALSE);
- result = check_ns(lctx, &token, source, line);
- isc_lex_ungettoken(lctx->lex, &token);
- if ((lctx->options & DNS_MASTER_FATALNS) != 0) {
- if (MANYERRS(lctx, result)) {
- SETRESULT(lctx, result);
- } else if (result != ISC_R_SUCCESS)
- goto insist_and_cleanup;
- }
- }
-
- /*
- * Check owner name.
- */
- options &= ~DNS_RDATA_CHECKREVERSE;
- if ((lctx->options & DNS_MASTER_CHECKNAMES) != 0) {
- isc_boolean_t ok;
- dns_name_t *name;
-
- name = (ictx->glue != NULL) ? ictx->glue :
- ictx->current;
- ok = dns_rdata_checkowner(name, lctx->zclass, type,
- ISC_TRUE);
- if (!ok) {
- char namebuf[DNS_NAME_FORMATSIZE];
- const char *desc;
- dns_name_format(name, namebuf, sizeof(namebuf));
- result = DNS_R_BADOWNERNAME;
- desc = dns_result_totext(result);
- if ((lctx->options & DNS_MASTER_CHECKNAMESFAIL) != 0) {
- (*callbacks->error)(callbacks,
- "%s:%lu: %s: %s",
- source, line,
- namebuf, desc);
- if (MANYERRS(lctx, result)) {
- SETRESULT(lctx, result);
- } else if (result != ISC_R_SUCCESS)
- goto cleanup;
- } else {
- (*callbacks->warn)(callbacks,
- "%s:%lu: %s: %s",
- source, line,
- namebuf, desc);
- }
- }
- if (type == dns_rdatatype_ptr &&
- (dns_name_issubdomain(name, &in_addr_arpa) ||
- dns_name_issubdomain(name, &ip6_arpa) ||
- dns_name_issubdomain(name, &ip6_int)))
- options |= DNS_RDATA_CHECKREVERSE;
- }
-
- /*
- * Read rdata contents.
- */
- dns_rdata_init(&rdata[rdcount]);
- target_ft = target;
- result = dns_rdata_fromtext(&rdata[rdcount], lctx->zclass,
- type, lctx->lex, ictx->origin,
- options, lctx->mctx, &target,
- callbacks);
- if (MANYERRS(lctx, result)) {
- SETRESULT(lctx, result);
- continue;
- } else if (result != ISC_R_SUCCESS)
- goto insist_and_cleanup;
-
- if (ictx->drop) {
- target = target_ft;
- continue;
- }
-
- if (type == dns_rdatatype_soa &&
- (lctx->options & DNS_MASTER_ZONE) != 0 &&
- dns_name_compare(ictx->current, lctx->top) != 0) {
- char namebuf[DNS_NAME_FORMATSIZE];
- dns_name_format(ictx->current, namebuf,
- sizeof(namebuf));
- (*callbacks->error)(callbacks, "%s:%lu: SOA "
- "record not at top of zone (%s)",
- source, line, namebuf);
- result = DNS_R_NOTZONETOP;
- if (MANYERRS(lctx, result)) {
- SETRESULT(lctx, result);
- read_till_eol = ISC_TRUE;
- target = target_ft;
- continue;
- } else if (result != ISC_R_SUCCESS)
- goto insist_and_cleanup;
- }
-
-
- if (type == dns_rdatatype_rrsig ||
- type == dns_rdatatype_sig)
- covers = dns_rdata_covers(&rdata[rdcount]);
- else
- covers = 0;
-
- if (!lctx->ttl_known && !lctx->default_ttl_known) {
- if (type == dns_rdatatype_soa) {
- (*callbacks->warn)(callbacks,
- "%s:%lu: no TTL specified; "
- "using SOA MINTTL instead",
- source, line);
- lctx->ttl = dns_soa_getminimum(&rdata[rdcount]);
- limit_ttl(callbacks, source, line, &lctx->ttl);
- lctx->default_ttl = lctx->ttl;
- lctx->default_ttl_known = ISC_TRUE;
- } else if ((lctx->options & DNS_MASTER_HINT) != 0) {
- /*
- * Zero TTL's are fine for hints.
- */
- lctx->ttl = 0;
- lctx->default_ttl = lctx->ttl;
- lctx->default_ttl_known = ISC_TRUE;
- } else {
- (*callbacks->warn)(callbacks,
- "%s:%lu: no TTL specified; "
- "zone rejected",
- source, line);
- result = DNS_R_NOTTL;
- if (MANYERRS(lctx, result)) {
- SETRESULT(lctx, result);
- lctx->ttl = 0;
- } else {
- goto insist_and_cleanup;
- }
- }
- } else if (!explicit_ttl && lctx->default_ttl_known) {
- lctx->ttl = lctx->default_ttl;
- } else if (!explicit_ttl && lctx->warn_1035) {
- (*callbacks->warn)(callbacks,
- "%s:%lu: "
- "using RFC1035 TTL semantics",
- source, line);
- lctx->warn_1035 = ISC_FALSE;
- }
-
- if (type == dns_rdatatype_rrsig && lctx->warn_sigexpired) {
- dns_rdata_rrsig_t sig;
- result = dns_rdata_tostruct(&rdata[rdcount], &sig,
- NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- if (isc_serial_lt(sig.timeexpire, now)) {
- (*callbacks->warn)(callbacks,
- "%s:%lu: "
- "signature has expired",
- source, line);
- lctx->warn_sigexpired = ISC_FALSE;
- }
- }
-
- if ((type == dns_rdatatype_sig || type == dns_rdatatype_nxt) &&
- lctx->warn_tcr && (lctx->options & DNS_MASTER_ZONE) != 0 &&
- (lctx->options & DNS_MASTER_SLAVE) == 0) {
- (*callbacks->warn)(callbacks, "%s:%lu: old style DNSSEC "
- " zone detected", source, line);
- lctx->warn_tcr = ISC_FALSE;
- }
-
- if ((lctx->options & DNS_MASTER_AGETTL) != 0) {
- /*
- * Adjust the TTL for $DATE. If the RR has already
- * expired, ignore it.
- */
- if (lctx->ttl < ttl_offset)
- continue;
- lctx->ttl -= ttl_offset;
- }
-
- /*
- * Find type in rdatalist.
- * If it does not exist create new one and prepend to list
- * as this will minimise list traversal.
- */
- if (ictx->glue != NULL)
- this = ISC_LIST_HEAD(glue_list);
- else
- this = ISC_LIST_HEAD(current_list);
-
- while (this != NULL) {
- if (this->type == type && this->covers == covers)
- break;
- this = ISC_LIST_NEXT(this, link);
- }
-
- if (this == NULL) {
- if (rdlcount == rdatalist_size) {
- new_rdatalist =
- grow_rdatalist(rdatalist_size + RDLSZ,
- rdatalist,
- rdatalist_size,
- &current_list,
- &glue_list,
- mctx);
- if (new_rdatalist == NULL) {
- result = ISC_R_NOMEMORY;
- goto log_and_cleanup;
- }
- rdatalist = new_rdatalist;
- rdatalist_size += RDLSZ;
- }
- this = &rdatalist[rdlcount++];
- this->type = type;
- this->covers = covers;
- this->rdclass = lctx->zclass;
- this->ttl = lctx->ttl;
- ISC_LIST_INIT(this->rdata);
- if (ictx->glue != NULL)
- ISC_LIST_INITANDPREPEND(glue_list, this, link);
- else
- ISC_LIST_INITANDPREPEND(current_list, this,
- link);
- } else if (this->ttl != lctx->ttl) {
- (*callbacks->warn)(callbacks,
- "%s:%lu: "
- "TTL set to prior TTL (%lu)",
- source, line, this->ttl);
- lctx->ttl = this->ttl;
- }
-
- ISC_LIST_APPEND(this->rdata, &rdata[rdcount], link);
- if (ictx->glue != NULL)
- ictx->glue_line = line;
- else
- ictx->current_line = line;
- rdcount++;
-
- /*
- * We must have at least 64k as rdlen is 16 bits.
- * If we don't commit everything we have so far.
- */
- if ((target.length - target.used) < MINTSIZ)
- COMMITALL;
- next_line:
- ;
- } while (!done && (lctx->loop_cnt == 0 || loop_cnt++ < lctx->loop_cnt));
-
- /*
- * Commit what has not yet been committed.
- */
- result = commit(callbacks, lctx, &current_list, ictx->current,
- source, ictx->current_line);
- if (MANYERRS(lctx, result)) {
- SETRESULT(lctx, result);
- } else if (result != ISC_R_SUCCESS)
- goto insist_and_cleanup;
- result = commit(callbacks, lctx, &glue_list, ictx->glue,
- source, ictx->glue_line);
- if (MANYERRS(lctx, result)) {
- SETRESULT(lctx, result);
- } else if (result != ISC_R_SUCCESS)
- goto insist_and_cleanup;
-
- if (!done) {
- INSIST(lctx->done != NULL && lctx->task != NULL);
- result = DNS_R_CONTINUE;
- } else if (result == ISC_R_SUCCESS && lctx->result != ISC_R_SUCCESS) {
- result = lctx->result;
- } else if (result == ISC_R_SUCCESS && lctx->seen_include)
- result = DNS_R_SEENINCLUDE;
- goto cleanup;
-
- log_and_cleanup:
- LOGIT(result);
-
- insist_and_cleanup:
- INSIST(result != ISC_R_SUCCESS);
-
- cleanup:
- while ((this = ISC_LIST_HEAD(current_list)) != NULL)
- ISC_LIST_UNLINK(current_list, this, link);
- while ((this = ISC_LIST_HEAD(glue_list)) != NULL)
- ISC_LIST_UNLINK(glue_list, this, link);
- if (rdatalist != NULL)
- isc_mem_put(mctx, rdatalist,
- rdatalist_size * sizeof(*rdatalist));
- if (rdata != NULL)
- isc_mem_put(mctx, rdata, rdata_size * sizeof(*rdata));
- if (target_mem != NULL)
- isc_mem_put(mctx, target_mem, target_size);
- if (include_file != NULL)
- isc_mem_free(mctx, include_file);
- if (range != NULL)
- isc_mem_free(mctx, range);
- if (lhs != NULL)
- isc_mem_free(mctx, lhs);
- if (gtype != NULL)
- isc_mem_free(mctx, gtype);
- if (rhs != NULL)
- isc_mem_free(mctx, rhs);
- return (result);
-}
-
-static isc_result_t
-pushfile(const char *master_file, dns_name_t *origin, dns_loadctx_t *lctx) {
- isc_result_t result;
- dns_incctx_t *ictx;
- dns_incctx_t *new = NULL;
- isc_region_t r;
- int new_in_use;
-
- REQUIRE(master_file != NULL);
- REQUIRE(DNS_LCTX_VALID(lctx));
-
- ictx = lctx->inc;
- lctx->seen_include = ISC_TRUE;
-
- result = incctx_create(lctx->mctx, origin, &new);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- /* Set current domain. */
- if (ictx->glue != NULL || ictx->current != NULL) {
- for (new_in_use = 0; new_in_use < NBUFS; new_in_use++)
- if (!new->in_use[new_in_use])
- break;
- INSIST(new_in_use < NBUFS);
- new->current_in_use = new_in_use;
- new->current =
- dns_fixedname_name(&new->fixed[new->current_in_use]);
- new->in_use[new->current_in_use] = ISC_TRUE;
- dns_name_toregion((ictx->glue != NULL) ?
- ictx->glue : ictx->current, &r);
- dns_name_fromregion(new->current, &r);
- new->drop = ictx->drop;
- }
-
- result = (lctx->openfile)(lctx, master_file);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- new->parent = ictx;
- lctx->inc = new;
- return (ISC_R_SUCCESS);
-
- cleanup:
- if (new != NULL)
- incctx_destroy(lctx->mctx, new);
- return (result);
-}
-
-static inline isc_result_t
-read_and_check(isc_boolean_t do_read, isc_buffer_t *buffer,
- size_t len, FILE *f)
-{
- isc_result_t result;
-
- if (do_read) {
- INSIST(isc_buffer_availablelength(buffer) >= len);
- result = isc_stdio_read(isc_buffer_used(buffer), 1, len,
- f, NULL);
- if (result != ISC_R_SUCCESS)
- return (result);
- isc_buffer_add(buffer, len);
- } else if (isc_buffer_remaininglength(buffer) < len)
- return (ISC_R_RANGE);
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-load_raw(dns_loadctx_t *lctx) {
- isc_result_t result = ISC_R_SUCCESS;
- isc_boolean_t done = ISC_FALSE;
- unsigned int loop_cnt = 0;
- dns_rdatacallbacks_t *callbacks;
- unsigned char namebuf[DNS_NAME_MAXWIRE];
- dns_fixedname_t fixed;
- dns_name_t *name;
- rdatalist_head_t head, dummy;
- dns_rdatalist_t rdatalist;
- isc_mem_t *mctx = lctx->mctx;
- dns_rdata_t *rdata = NULL;
- unsigned int rdata_size = 0;
- int target_size = TSIZ;
- isc_buffer_t target, buf;
- unsigned char *target_mem = NULL;
- dns_masterrawheader_t header;
- dns_decompress_t dctx;
-
- REQUIRE(DNS_LCTX_VALID(lctx));
- callbacks = lctx->callbacks;
- dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE);
-
- dns_master_initrawheader(&header);
-
- if (lctx->first) {
- unsigned char data[sizeof(header)];
- size_t commonlen =
- sizeof(header.format) + sizeof(header.version);
- size_t remainder;
-
- INSIST(commonlen <= sizeof(header));
- isc_buffer_init(&target, data, sizeof(data));
-
- result = isc_stdio_read(data, 1, commonlen, lctx->f, NULL);
- if (result != ISC_R_SUCCESS) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_stdio_read failed: %s",
- isc_result_totext(result));
- return (result);
- }
- isc_buffer_add(&target, commonlen);
- header.format = isc_buffer_getuint32(&target);
- if (header.format != dns_masterformat_raw) {
- (*callbacks->error)(callbacks,
- "dns_master_load: "
- "file format mismatch");
- return (ISC_R_NOTIMPLEMENTED);
- }
-
- header.version = isc_buffer_getuint32(&target);
- switch (header.version) {
- case 0:
- remainder = sizeof(header.dumptime);
- break;
- case DNS_RAWFORMAT_VERSION:
- remainder = sizeof(header) - commonlen;
- break;
- default:
- (*callbacks->error)(callbacks,
- "dns_master_load: "
- "unsupported file format version");
- return (ISC_R_NOTIMPLEMENTED);
- }
-
- result = isc_stdio_read(data + commonlen, 1, remainder,
- lctx->f, NULL);
- if (result != ISC_R_SUCCESS) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_stdio_read failed: %s",
- isc_result_totext(result));
- return (result);
- }
-
- isc_buffer_add(&target, remainder);
- header.dumptime = isc_buffer_getuint32(&target);
- if (header.version == DNS_RAWFORMAT_VERSION) {
- header.flags = isc_buffer_getuint32(&target);
- header.sourceserial = isc_buffer_getuint32(&target);
- header.lastxfrin = isc_buffer_getuint32(&target);
- }
-
- lctx->first = ISC_FALSE;
- lctx->header = header;
- }
-
- ISC_LIST_INIT(head);
- ISC_LIST_INIT(dummy);
- dns_rdatalist_init(&rdatalist);
-
- /*
- * Allocate target_size of buffer space. This is greater than twice
- * the maximum individual RR data size.
- */
- target_mem = isc_mem_get(mctx, target_size);
- if (target_mem == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup;
- }
- isc_buffer_init(&target, target_mem, target_size);
-
- dns_fixedname_init(&fixed);
- name = dns_fixedname_name(&fixed);
-
- /*
- * In the following loop, we regard any error fatal regardless of
- * whether "MANYERRORS" is set in the context option. This is because
- * normal errors should already have been checked at creation time.
- * Besides, it is very unlikely that we can recover from an error
- * in this format, and so trying to continue parsing erroneous data
- * does not really make sense.
- */
- for (loop_cnt = 0;
- (lctx->loop_cnt == 0 || loop_cnt < lctx->loop_cnt);
- loop_cnt++) {
- unsigned int i, rdcount;
- isc_uint16_t namelen;
- isc_uint32_t totallen;
- size_t minlen, readlen;
- isc_boolean_t sequential_read = ISC_FALSE;
-
- /* Read the data length */
- isc_buffer_clear(&target);
- INSIST(isc_buffer_availablelength(&target) >=
- sizeof(totallen));
- result = isc_stdio_read(target.base, 1, sizeof(totallen),
- lctx->f, NULL);
- if (result == ISC_R_EOF) {
- result = ISC_R_SUCCESS;
- done = ISC_TRUE;
- break;
- }
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- isc_buffer_add(&target, sizeof(totallen));
- totallen = isc_buffer_getuint32(&target);
- /*
- * Validation: the input data must at least contain the common
- * header.
- */
- minlen = sizeof(totallen) + sizeof(isc_uint16_t) +
- sizeof(isc_uint16_t) + sizeof(isc_uint16_t) +
- sizeof(isc_uint32_t) + sizeof(isc_uint32_t);
- if (totallen < minlen) {
- result = ISC_R_RANGE;
- goto cleanup;
- }
- totallen -= sizeof(totallen);
-
- isc_buffer_clear(&target);
- if (totallen > isc_buffer_availablelength(&target)) {
- /*
- * The default buffer size should typically be large
- * enough to store the entire RRset. We could try to
- * allocate enough space if this is not the case, but
- * it might cause a hazardous result when "totallen"
- * is forged. Thus, we'd rather take an inefficient
- * but robust approach in this atypical case: read
- * data step by step, and commit partial data when
- * necessary. Note that the buffer must be large
- * enough to store the "header part", owner name, and
- * at least one rdata (however large it is).
- */
- sequential_read = ISC_TRUE;
- readlen = minlen - sizeof(totallen);
- } else {
- /*
- * Typical case. We can read the whole RRset at once
- * with the default buffer.
- */
- readlen = totallen;
- }
- result = isc_stdio_read(target.base, 1, readlen,
- lctx->f, NULL);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- isc_buffer_add(&target, readlen);
-
- /* Construct RRset headers */
- rdatalist.rdclass = isc_buffer_getuint16(&target);
- rdatalist.type = isc_buffer_getuint16(&target);
- rdatalist.covers = isc_buffer_getuint16(&target);
- rdatalist.ttl = isc_buffer_getuint32(&target);
- rdcount = isc_buffer_getuint32(&target);
- if (rdcount == 0) {
- result = ISC_R_RANGE;
- goto cleanup;
- }
- INSIST(isc_buffer_consumedlength(&target) <= readlen);
-
- /* Owner name: length followed by name */
- result = read_and_check(sequential_read, &target,
- sizeof(namelen), lctx->f);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- namelen = isc_buffer_getuint16(&target);
- if (namelen > sizeof(namebuf)) {
- result = ISC_R_RANGE;
- goto cleanup;
- }
-
- result = read_and_check(sequential_read, &target, namelen,
- lctx->f);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- isc_buffer_setactive(&target, (unsigned int)namelen);
- result = dns_name_fromwire(name, &target, &dctx, 0, NULL);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- /* Rdata contents. */
- if (rdcount > rdata_size) {
- dns_rdata_t *new_rdata = NULL;
-
- new_rdata = grow_rdata(rdcount + RDSZ, rdata,
- rdata_size, &head,
- &dummy, mctx);
- if (new_rdata == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup;
- }
- rdata_size = rdcount + RDSZ;
- rdata = new_rdata;
- }
-
- continue_read:
- for (i = 0; i < rdcount; i++) {
- isc_uint16_t rdlen;
-
- dns_rdata_init(&rdata[i]);
-
- if (sequential_read &&
- isc_buffer_availablelength(&target) < MINTSIZ) {
- unsigned int j;
-
- INSIST(i > 0); /* detect an infinite loop */
-
- /* Partial Commit. */
- ISC_LIST_APPEND(head, &rdatalist, link);
- result = commit(callbacks, lctx, &head, name,
- NULL, 0);
- for (j = 0; j < i; j++) {
- ISC_LIST_UNLINK(rdatalist.rdata,
- &rdata[j], link);
- dns_rdata_reset(&rdata[j]);
- }
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- /* Rewind the buffer and continue */
- isc_buffer_clear(&target);
-
- rdcount -= i;
-
- goto continue_read;
- }
-
- /* rdata length */
- result = read_and_check(sequential_read, &target,
- sizeof(rdlen), lctx->f);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- rdlen = isc_buffer_getuint16(&target);
-
- /* rdata */
- result = read_and_check(sequential_read, &target,
- rdlen, lctx->f);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- isc_buffer_setactive(&target, (unsigned int)rdlen);
- /*
- * It is safe to have the source active region and
- * the target available region be the same if
- * decompression is disabled (see dctx above) and we
- * are not downcasing names (options == 0).
- */
- isc_buffer_init(&buf, isc_buffer_current(&target),
- (unsigned int)rdlen);
- result = dns_rdata_fromwire(&rdata[i],
- rdatalist.rdclass,
- rdatalist.type, &target,
- &dctx, 0, &buf);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- ISC_LIST_APPEND(rdatalist.rdata, &rdata[i], link);
- }
-
- /*
- * Sanity check. Still having remaining space is not
- * necessarily critical, but it very likely indicates broken
- * or malformed data.
- */
- if (isc_buffer_remaininglength(&target) != 0) {
- result = ISC_R_RANGE;
- goto cleanup;
- }
-
- ISC_LIST_APPEND(head, &rdatalist, link);
-
- /* Commit this RRset. rdatalist will be unlinked. */
- result = commit(callbacks, lctx, &head, name, NULL, 0);
-
- for (i = 0; i < rdcount; i++) {
- ISC_LIST_UNLINK(rdatalist.rdata, &rdata[i], link);
- dns_rdata_reset(&rdata[i]);
- }
-
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- }
-
- if (!done) {
- INSIST(lctx->done != NULL && lctx->task != NULL);
- result = DNS_R_CONTINUE;
- } else if (result == ISC_R_SUCCESS && lctx->result != ISC_R_SUCCESS)
- result = lctx->result;
-
- if (result == ISC_R_SUCCESS && callbacks->rawdata != NULL)
- (*callbacks->rawdata)(callbacks->zone, &header);
-
- cleanup:
- if (rdata != NULL)
- isc_mem_put(mctx, rdata, rdata_size * sizeof(*rdata));
- if (target_mem != NULL)
- isc_mem_put(mctx, target_mem, target_size);
- if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE) {
- (*callbacks->error)(callbacks, "dns_master_load: %s",
- dns_result_totext(result));
- }
-
- return (result);
-}
-
-isc_result_t
-dns_master_loadfile(const char *master_file, dns_name_t *top,
- dns_name_t *origin,
- dns_rdataclass_t zclass, unsigned int options,
- dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx)
-{
- return (dns_master_loadfile3(master_file, top, origin, zclass, options,
- 0, callbacks, mctx, dns_masterformat_text));
-}
-
-isc_result_t
-dns_master_loadfile2(const char *master_file, dns_name_t *top,
- dns_name_t *origin,
- dns_rdataclass_t zclass, unsigned int options,
- dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx,
- dns_masterformat_t format)
-{
- return (dns_master_loadfile3(master_file, top, origin, zclass, options,
- 0, callbacks, mctx, format));
-}
-
-isc_result_t
-dns_master_loadfile3(const char *master_file, dns_name_t *top,
- dns_name_t *origin, dns_rdataclass_t zclass,
- unsigned int options, isc_uint32_t resign,
- dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx,
- dns_masterformat_t format)
-{
- dns_loadctx_t *lctx = NULL;
- isc_result_t result;
-
- result = loadctx_create(format, mctx, options, resign, top, zclass,
- origin, callbacks, NULL, NULL, NULL, NULL,
- &lctx);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- result = (lctx->openfile)(lctx, master_file);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- result = (lctx->load)(lctx);
- INSIST(result != DNS_R_CONTINUE);
-
- cleanup:
- dns_loadctx_detach(&lctx);
- return (result);
-}
-
-isc_result_t
-dns_master_loadfileinc(const char *master_file, dns_name_t *top,
- dns_name_t *origin, dns_rdataclass_t zclass,
- unsigned int options, dns_rdatacallbacks_t *callbacks,
- isc_task_t *task, dns_loaddonefunc_t done,
- void *done_arg, dns_loadctx_t **lctxp, isc_mem_t *mctx)
-{
- return (dns_master_loadfileinc3(master_file, top, origin, zclass,
- options, 0, callbacks, task, done,
- done_arg, lctxp, mctx,
- dns_masterformat_text));
-}
-
-isc_result_t
-dns_master_loadfileinc2(const char *master_file, dns_name_t *top,
- dns_name_t *origin, dns_rdataclass_t zclass,
- unsigned int options, dns_rdatacallbacks_t *callbacks,
- isc_task_t *task, dns_loaddonefunc_t done,
- void *done_arg, dns_loadctx_t **lctxp, isc_mem_t *mctx,
- dns_masterformat_t format)
-{
- return (dns_master_loadfileinc3(master_file, top, origin, zclass,
- options, 0, callbacks, task, done,
- done_arg, lctxp, mctx, format));
-}
-
-isc_result_t
-dns_master_loadfileinc3(const char *master_file, dns_name_t *top,
- dns_name_t *origin, dns_rdataclass_t zclass,
- unsigned int options, isc_uint32_t resign,
- dns_rdatacallbacks_t *callbacks, isc_task_t *task,
- dns_loaddonefunc_t done, void *done_arg,
- dns_loadctx_t **lctxp, isc_mem_t *mctx,
- dns_masterformat_t format)
-{
- dns_loadctx_t *lctx = NULL;
- isc_result_t result;
-
- REQUIRE(task != NULL);
- REQUIRE(done != NULL);
-
- result = loadctx_create(format, mctx, options, resign, top, zclass,
- origin, callbacks, task, done, done_arg, NULL,
- &lctx);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- result = (lctx->openfile)(lctx, master_file);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- result = task_send(lctx);
- if (result == ISC_R_SUCCESS) {
- dns_loadctx_attach(lctx, lctxp);
- return (DNS_R_CONTINUE);
- }
-
- cleanup:
- dns_loadctx_detach(&lctx);
- return (result);
-}
-
-isc_result_t
-dns_master_loadstream(FILE *stream, dns_name_t *top, dns_name_t *origin,
- dns_rdataclass_t zclass, unsigned int options,
- dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx)
-{
- isc_result_t result;
- dns_loadctx_t *lctx = NULL;
-
- REQUIRE(stream != NULL);
-
- result = loadctx_create(dns_masterformat_text, mctx, options, 0, top,
- zclass, origin, callbacks, NULL, NULL, NULL,
- NULL, &lctx);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- result = isc_lex_openstream(lctx->lex, stream);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- result = (lctx->load)(lctx);
- INSIST(result != DNS_R_CONTINUE);
-
- cleanup:
- if (lctx != NULL)
- dns_loadctx_detach(&lctx);
- return (result);
-}
-
-isc_result_t
-dns_master_loadstreaminc(FILE *stream, dns_name_t *top, dns_name_t *origin,
- dns_rdataclass_t zclass, unsigned int options,
- dns_rdatacallbacks_t *callbacks, isc_task_t *task,
- dns_loaddonefunc_t done, void *done_arg,
- dns_loadctx_t **lctxp, isc_mem_t *mctx)
-{
- isc_result_t result;
- dns_loadctx_t *lctx = NULL;
-
- REQUIRE(stream != NULL);
- REQUIRE(task != NULL);
- REQUIRE(done != NULL);
-
- result = loadctx_create(dns_masterformat_text, mctx, options, 0, top,
- zclass, origin, callbacks, task, done,
- done_arg, NULL, &lctx);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- result = isc_lex_openstream(lctx->lex, stream);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- result = task_send(lctx);
- if (result == ISC_R_SUCCESS) {
- dns_loadctx_attach(lctx, lctxp);
- return (DNS_R_CONTINUE);
- }
-
- cleanup:
- if (lctx != NULL)
- dns_loadctx_detach(&lctx);
- return (result);
-}
-
-isc_result_t
-dns_master_loadbuffer(isc_buffer_t *buffer, dns_name_t *top,
- dns_name_t *origin, dns_rdataclass_t zclass,
- unsigned int options,
- dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx)
-{
- isc_result_t result;
- dns_loadctx_t *lctx = NULL;
-
- REQUIRE(buffer != NULL);
-
- result = loadctx_create(dns_masterformat_text, mctx, options, 0, top,
- zclass, origin, callbacks, NULL, NULL, NULL,
- NULL, &lctx);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- result = isc_lex_openbuffer(lctx->lex, buffer);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- result = (lctx->load)(lctx);
- INSIST(result != DNS_R_CONTINUE);
-
- cleanup:
- dns_loadctx_detach(&lctx);
- return (result);
-}
-
-isc_result_t
-dns_master_loadbufferinc(isc_buffer_t *buffer, dns_name_t *top,
- dns_name_t *origin, dns_rdataclass_t zclass,
- unsigned int options,
- dns_rdatacallbacks_t *callbacks, isc_task_t *task,
- dns_loaddonefunc_t done, void *done_arg,
- dns_loadctx_t **lctxp, isc_mem_t *mctx)
-{
- isc_result_t result;
- dns_loadctx_t *lctx = NULL;
-
- REQUIRE(buffer != NULL);
- REQUIRE(task != NULL);
- REQUIRE(done != NULL);
-
- result = loadctx_create(dns_masterformat_text, mctx, options, 0, top,
- zclass, origin, callbacks, task, done,
- done_arg, NULL, &lctx);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- result = isc_lex_openbuffer(lctx->lex, buffer);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- result = task_send(lctx);
- if (result == ISC_R_SUCCESS) {
- dns_loadctx_attach(lctx, lctxp);
- return (DNS_R_CONTINUE);
- }
-
- cleanup:
- dns_loadctx_detach(&lctx);
- return (result);
-}
-
-isc_result_t
-dns_master_loadlexer(isc_lex_t *lex, dns_name_t *top,
- dns_name_t *origin, dns_rdataclass_t zclass,
- unsigned int options,
- dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx)
-{
- isc_result_t result;
- dns_loadctx_t *lctx = NULL;
-
- REQUIRE(lex != NULL);
-
- result = loadctx_create(dns_masterformat_text, mctx, options, 0, top,
- zclass, origin, callbacks, NULL, NULL, NULL,
- lex, &lctx);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- result = (lctx->load)(lctx);
- INSIST(result != DNS_R_CONTINUE);
-
- dns_loadctx_detach(&lctx);
- return (result);
-}
-
-isc_result_t
-dns_master_loadlexerinc(isc_lex_t *lex, dns_name_t *top,
- dns_name_t *origin, dns_rdataclass_t zclass,
- unsigned int options,
- dns_rdatacallbacks_t *callbacks, isc_task_t *task,
- dns_loaddonefunc_t done, void *done_arg,
- dns_loadctx_t **lctxp, isc_mem_t *mctx)
-{
- isc_result_t result;
- dns_loadctx_t *lctx = NULL;
-
- REQUIRE(lex != NULL);
- REQUIRE(task != NULL);
- REQUIRE(done != NULL);
-
- result = loadctx_create(dns_masterformat_text, mctx, options, 0, top,
- zclass, origin, callbacks, task, done,
- done_arg, lex, &lctx);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- result = task_send(lctx);
- if (result == ISC_R_SUCCESS) {
- dns_loadctx_attach(lctx, lctxp);
- return (DNS_R_CONTINUE);
- }
-
- dns_loadctx_detach(&lctx);
- return (result);
-}
-
-/*
- * Grow the slab of dns_rdatalist_t structures.
- * Re-link glue and current list.
- */
-static dns_rdatalist_t *
-grow_rdatalist(int new_len, dns_rdatalist_t *old, int old_len,
- rdatalist_head_t *current, rdatalist_head_t *glue,
- isc_mem_t *mctx)
-{
- dns_rdatalist_t *new;
- int rdlcount = 0;
- ISC_LIST(dns_rdatalist_t) save;
- dns_rdatalist_t *this;
-
- new = isc_mem_get(mctx, new_len * sizeof(*new));
- if (new == NULL)
- return (NULL);
-
- ISC_LIST_INIT(save);
- while ((this = ISC_LIST_HEAD(*current)) != NULL) {
- ISC_LIST_UNLINK(*current, this, link);
- ISC_LIST_APPEND(save, this, link);
- }
- while ((this = ISC_LIST_HEAD(save)) != NULL) {
- ISC_LIST_UNLINK(save, this, link);
- INSIST(rdlcount < new_len);
- new[rdlcount] = *this;
- ISC_LIST_APPEND(*current, &new[rdlcount], link);
- rdlcount++;
- }
-
- ISC_LIST_INIT(save);
- while ((this = ISC_LIST_HEAD(*glue)) != NULL) {
- ISC_LIST_UNLINK(*glue, this, link);
- ISC_LIST_APPEND(save, this, link);
- }
- while ((this = ISC_LIST_HEAD(save)) != NULL) {
- ISC_LIST_UNLINK(save, this, link);
- INSIST(rdlcount < new_len);
- new[rdlcount] = *this;
- ISC_LIST_APPEND(*glue, &new[rdlcount], link);
- rdlcount++;
- }
-
- INSIST(rdlcount == old_len);
- if (old != NULL)
- isc_mem_put(mctx, old, old_len * sizeof(*old));
- return (new);
-}
-
-/*
- * Grow the slab of rdata structs.
- * Re-link the current and glue chains.
- */
-static dns_rdata_t *
-grow_rdata(int new_len, dns_rdata_t *old, int old_len,
- rdatalist_head_t *current, rdatalist_head_t *glue,
- isc_mem_t *mctx)
-{
- dns_rdata_t *new;
- int rdcount = 0;
- ISC_LIST(dns_rdata_t) save;
- dns_rdatalist_t *this;
- dns_rdata_t *rdata;
-
- new = isc_mem_get(mctx, new_len * sizeof(*new));
- if (new == NULL)
- return (NULL);
- memset(new, 0, new_len * sizeof(*new));
-
- /*
- * Copy current relinking.
- */
- this = ISC_LIST_HEAD(*current);
- while (this != NULL) {
- ISC_LIST_INIT(save);
- while ((rdata = ISC_LIST_HEAD(this->rdata)) != NULL) {
- ISC_LIST_UNLINK(this->rdata, rdata, link);
- ISC_LIST_APPEND(save, rdata, link);
- }
- while ((rdata = ISC_LIST_HEAD(save)) != NULL) {
- ISC_LIST_UNLINK(save, rdata, link);
- INSIST(rdcount < new_len);
- new[rdcount] = *rdata;
- ISC_LIST_APPEND(this->rdata, &new[rdcount], link);
- rdcount++;
- }
- this = ISC_LIST_NEXT(this, link);
- }
-
- /*
- * Copy glue relinking.
- */
- this = ISC_LIST_HEAD(*glue);
- while (this != NULL) {
- ISC_LIST_INIT(save);
- while ((rdata = ISC_LIST_HEAD(this->rdata)) != NULL) {
- ISC_LIST_UNLINK(this->rdata, rdata, link);
- ISC_LIST_APPEND(save, rdata, link);
- }
- while ((rdata = ISC_LIST_HEAD(save)) != NULL) {
- ISC_LIST_UNLINK(save, rdata, link);
- INSIST(rdcount < new_len);
- new[rdcount] = *rdata;
- ISC_LIST_APPEND(this->rdata, &new[rdcount], link);
- rdcount++;
- }
- this = ISC_LIST_NEXT(this, link);
- }
- INSIST(rdcount == old_len || rdcount == 0);
- if (old != NULL)
- isc_mem_put(mctx, old, old_len * sizeof(*old));
- return (new);
-}
-
-static isc_uint32_t
-resign_fromlist(dns_rdatalist_t *this, isc_uint32_t resign) {
- dns_rdata_t *rdata;
- dns_rdata_rrsig_t sig;
- isc_uint32_t when;
-
- rdata = ISC_LIST_HEAD(this->rdata);
- INSIST(rdata != NULL);
- (void)dns_rdata_tostruct(rdata, &sig, NULL);
- when = sig.timeexpire - resign;
-
- rdata = ISC_LIST_NEXT(rdata, link);
- while (rdata != NULL) {
- (void)dns_rdata_tostruct(rdata, &sig, NULL);
- if (sig.timeexpire - resign < when)
- when = sig.timeexpire - resign;
- rdata = ISC_LIST_NEXT(rdata, link);
- }
- return (when);
-}
-
-/*
- * Convert each element from a rdatalist_t to rdataset then call commit.
- * Unlink each element as we go.
- */
-
-static isc_result_t
-commit(dns_rdatacallbacks_t *callbacks, dns_loadctx_t *lctx,
- rdatalist_head_t *head, dns_name_t *owner,
- const char *source, unsigned int line)
-{
- dns_rdatalist_t *this;
- dns_rdataset_t dataset;
- isc_result_t result;
- char namebuf[DNS_NAME_FORMATSIZE];
- void (*error)(struct dns_rdatacallbacks *, const char *, ...);
-
- this = ISC_LIST_HEAD(*head);
- error = callbacks->error;
-
- if (this == NULL)
- return (ISC_R_SUCCESS);
- do {
- dns_rdataset_init(&dataset);
- RUNTIME_CHECK(dns_rdatalist_tordataset(this, &dataset)
- == ISC_R_SUCCESS);
- dataset.trust = dns_trust_ultimate;
- /*
- * If this is a secure dynamic zone set the re-signing time.
- */
- if (dataset.type == dns_rdatatype_rrsig &&
- (lctx->options & DNS_MASTER_RESIGN) != 0) {
- dataset.attributes |= DNS_RDATASETATTR_RESIGN;
- dns_name_format(owner, namebuf, sizeof(namebuf));
- dataset.resign = resign_fromlist(this, lctx->resign);
- }
- result = ((*callbacks->add)(callbacks->add_private, owner,
- &dataset));
- if (result == ISC_R_NOMEMORY) {
- (*error)(callbacks, "dns_master_load: %s",
- dns_result_totext(result));
- } else if (result != ISC_R_SUCCESS) {
- dns_name_format(owner, namebuf, sizeof(namebuf));
- if (source != NULL) {
- (*error)(callbacks, "%s: %s:%lu: %s: %s",
- "dns_master_load", source, line,
- namebuf, dns_result_totext(result));
- } else {
- (*error)(callbacks, "%s: %s: %s",
- "dns_master_load", namebuf,
- dns_result_totext(result));
- }
- }
- if (MANYERRS(lctx, result))
- SETRESULT(lctx, result);
- else if (result != ISC_R_SUCCESS)
- return (result);
- ISC_LIST_UNLINK(*head, this, link);
- this = ISC_LIST_HEAD(*head);
- } while (this != NULL);
- return (ISC_R_SUCCESS);
-}
-
-/*
- * Returns ISC_TRUE if one of the NS rdata's contains 'owner'.
- */
-
-static isc_boolean_t
-is_glue(rdatalist_head_t *head, dns_name_t *owner) {
- dns_rdatalist_t *this;
- dns_rdata_t *rdata;
- isc_region_t region;
- dns_name_t name;
-
- /*
- * Find NS rrset.
- */
- this = ISC_LIST_HEAD(*head);
- while (this != NULL) {
- if (this->type == dns_rdatatype_ns)
- break;
- this = ISC_LIST_NEXT(this, link);
- }
- if (this == NULL)
- return (ISC_FALSE);
-
- rdata = ISC_LIST_HEAD(this->rdata);
- while (rdata != NULL) {
- dns_name_init(&name, NULL);
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
- if (dns_name_compare(&name, owner) == 0)
- return (ISC_TRUE);
- rdata = ISC_LIST_NEXT(rdata, link);
- }
- return (ISC_FALSE);
-}
-
-static void
-load_quantum(isc_task_t *task, isc_event_t *event) {
- isc_result_t result;
- dns_loadctx_t *lctx;
-
- REQUIRE(event != NULL);
- lctx = event->ev_arg;
- REQUIRE(DNS_LCTX_VALID(lctx));
-
- if (lctx->canceled)
- result = ISC_R_CANCELED;
- else
- result = (lctx->load)(lctx);
- if (result == DNS_R_CONTINUE) {
- event->ev_arg = lctx;
- isc_task_send(task, &event);
- } else {
- (lctx->done)(lctx->done_arg, result);
- isc_event_free(&event);
- dns_loadctx_detach(&lctx);
- }
-}
-
-static isc_result_t
-task_send(dns_loadctx_t *lctx) {
- isc_event_t *event;
-
- event = isc_event_allocate(lctx->mctx, NULL,
- DNS_EVENT_MASTERQUANTUM,
- load_quantum, lctx, sizeof(*event));
- if (event == NULL)
- return (ISC_R_NOMEMORY);
- isc_task_send(lctx->task, &event);
- return (ISC_R_SUCCESS);
-}
-
-void
-dns_loadctx_cancel(dns_loadctx_t *lctx) {
- REQUIRE(DNS_LCTX_VALID(lctx));
-
- LOCK(&lctx->lock);
- lctx->canceled = ISC_TRUE;
- UNLOCK(&lctx->lock);
-}
-
-void
-dns_master_initrawheader(dns_masterrawheader_t *header) {
- memset(header, 0, sizeof(dns_masterrawheader_t));
-}
diff --git a/contrib/bind9/lib/dns/masterdump.c b/contrib/bind9/lib/dns/masterdump.c
deleted file mode 100644
index 2717658e691a..000000000000
--- a/contrib/bind9/lib/dns/masterdump.c
+++ /dev/null
@@ -1,1912 +0,0 @@
-/*
- * Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <stdlib.h>
-
-#include <isc/event.h>
-#include <isc/file.h>
-#include <isc/magic.h>
-#include <isc/mem.h>
-#include <isc/print.h>
-#include <isc/stdio.h>
-#include <isc/string.h>
-#include <isc/task.h>
-#include <isc/time.h>
-#include <isc/util.h>
-
-#include <dns/db.h>
-#include <dns/dbiterator.h>
-#include <dns/events.h>
-#include <dns/fixedname.h>
-#include <dns/lib.h>
-#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>
-#include <dns/rdatasetiter.h>
-#include <dns/rdatatype.h>
-#include <dns/result.h>
-#include <dns/time.h>
-#include <dns/ttl.h>
-
-#define DNS_DCTX_MAGIC ISC_MAGIC('D', 'c', 't', 'x')
-#define DNS_DCTX_VALID(d) ISC_MAGIC_VALID(d, DNS_DCTX_MAGIC)
-
-#define RETERR(x) do { \
- isc_result_t _r = (x); \
- if (_r != ISC_R_SUCCESS) \
- 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;
- unsigned int class_column;
- unsigned int type_column;
- unsigned int rdata_column;
- unsigned int line_length;
- unsigned int tab_width;
- unsigned int split_width;
-};
-
-/*%
- * The maximum length of the newline+indentation that is output
- * when inserting a line break in an RR. This effectively puts an
- * upper limits on the value of "rdata_column", because if it is
- * very large, the tabs and spaces needed to reach it will not fit.
- */
-#define DNS_TOTEXT_LINEBREAK_MAXLEN 100
-
-/*%
- * Context structure for a masterfile dump in progress.
- */
-typedef struct dns_totext_ctx {
- dns_master_style_t style;
- isc_boolean_t class_printed;
- char * linebreak;
- char linebreak_buf[DNS_TOTEXT_LINEBREAK_MAXLEN];
- dns_name_t * origin;
- dns_name_t * neworigin;
- dns_fixedname_t origin_fixname;
- isc_uint32_t current_ttl;
- isc_boolean_t current_ttl_valid;
-} dns_totext_ctx_t;
-
-LIBDNS_EXTERNAL_DATA const dns_master_style_t
-dns_master_style_default = {
- DNS_STYLEFLAG_OMIT_OWNER |
- DNS_STYLEFLAG_OMIT_CLASS |
- DNS_STYLEFLAG_REL_OWNER |
- DNS_STYLEFLAG_REL_DATA |
- DNS_STYLEFLAG_OMIT_TTL |
- DNS_STYLEFLAG_TTL |
- DNS_STYLEFLAG_COMMENT |
- DNS_STYLEFLAG_RRCOMMENT |
- DNS_STYLEFLAG_MULTILINE,
- 24, 24, 24, 32, 80, 8, UINT_MAX
-};
-
-LIBDNS_EXTERNAL_DATA const dns_master_style_t
-dns_master_style_full = {
- DNS_STYLEFLAG_COMMENT |
- DNS_STYLEFLAG_RESIGN,
- 46, 46, 46, 64, 120, 8, UINT_MAX
-};
-
-LIBDNS_EXTERNAL_DATA const dns_master_style_t
-dns_master_style_explicitttl = {
- DNS_STYLEFLAG_OMIT_OWNER |
- DNS_STYLEFLAG_OMIT_CLASS |
- DNS_STYLEFLAG_REL_OWNER |
- DNS_STYLEFLAG_REL_DATA |
- DNS_STYLEFLAG_COMMENT |
- DNS_STYLEFLAG_RRCOMMENT |
- DNS_STYLEFLAG_MULTILINE,
- 24, 32, 32, 40, 80, 8, UINT_MAX
-};
-
-LIBDNS_EXTERNAL_DATA const dns_master_style_t
-dns_master_style_cache = {
- DNS_STYLEFLAG_OMIT_OWNER |
- DNS_STYLEFLAG_OMIT_CLASS |
- DNS_STYLEFLAG_MULTILINE |
- DNS_STYLEFLAG_TRUST |
- DNS_STYLEFLAG_NCACHE,
- 24, 32, 32, 40, 80, 8, UINT_MAX
-};
-
-LIBDNS_EXTERNAL_DATA const dns_master_style_t
-dns_master_style_simple = {
- 0,
- 24, 32, 32, 40, 80, 8, UINT_MAX
-};
-
-/*%
- * A style suitable for dns_rdataset_totext().
- */
-LIBDNS_EXTERNAL_DATA const dns_master_style_t
-dns_master_style_debug = {
- DNS_STYLEFLAG_REL_OWNER,
- 24, 32, 40, 48, 80, 8, UINT_MAX
-};
-
-
-#define N_SPACES 10
-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;
- isc_mutex_t lock;
- unsigned int references;
- isc_boolean_t canceled;
- isc_boolean_t first;
- isc_boolean_t do_date;
- isc_stdtime_t now;
- FILE *f;
- dns_db_t *db;
- dns_dbversion_t *version;
- dns_dbiterator_t *dbiter;
- dns_totext_ctx_t tctx;
- isc_task_t *task;
- dns_dumpdonefunc_t done;
- void *done_arg;
- unsigned int nodes;
- /* dns_master_dumpinc() */
- char *file;
- char *tmpfile;
- dns_masterformat_t format;
- dns_masterrawheader_t header;
- isc_result_t (*dumpsets)(isc_mem_t *mctx, dns_name_t *name,
- dns_rdatasetiter_t *rdsiter,
- dns_totext_ctx_t *ctx,
- isc_buffer_t *buffer, FILE *f);
-};
-#endif /* BIND9 */
-
-#define NXDOMAIN(x) (((x)->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0)
-
-/*%
- * Output tabs and spaces to go from column '*current' to
- * column 'to', and update '*current' to reflect the new
- * current column.
- */
-static isc_result_t
-indent(unsigned int *current, unsigned int to, int tabwidth,
- isc_buffer_t *target)
-{
- isc_region_t r;
- unsigned char *p;
- unsigned int from;
- int ntabs, nspaces, t;
-
- from = *current;
-
- if (to < from + 1)
- to = from + 1;
-
- ntabs = to / tabwidth - from / tabwidth;
- if (ntabs < 0)
- ntabs = 0;
-
- if (ntabs > 0) {
- isc_buffer_availableregion(target, &r);
- if (r.length < (unsigned) ntabs)
- return (ISC_R_NOSPACE);
- p = r.base;
-
- t = ntabs;
- while (t) {
- int n = t;
- if (n > N_TABS)
- n = N_TABS;
- memcpy(p, tabs, n);
- p += n;
- t -= n;
- }
- isc_buffer_add(target, ntabs);
- from = (to / tabwidth) * tabwidth;
- }
-
- nspaces = to - from;
- INSIST(nspaces >= 0);
-
- isc_buffer_availableregion(target, &r);
- if (r.length < (unsigned) nspaces)
- return (ISC_R_NOSPACE);
- p = r.base;
-
- t = nspaces;
- while (t) {
- int n = t;
- if (n > N_SPACES)
- n = N_SPACES;
- memcpy(p, spaces, n);
- p += n;
- t -= n;
- }
- isc_buffer_add(target, nspaces);
-
- *current = to;
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-totext_ctx_init(const dns_master_style_t *style, dns_totext_ctx_t *ctx) {
- isc_result_t result;
-
- REQUIRE(style->tab_width != 0);
-
- ctx->style = *style;
- ctx->class_printed = ISC_FALSE;
-
- dns_fixedname_init(&ctx->origin_fixname);
-
- /*
- * Set up the line break string if needed.
- */
- if ((ctx->style.flags & DNS_STYLEFLAG_MULTILINE) != 0) {
- isc_buffer_t buf;
- isc_region_t r;
- unsigned int col = 0;
-
- isc_buffer_init(&buf, ctx->linebreak_buf,
- sizeof(ctx->linebreak_buf));
-
- isc_buffer_availableregion(&buf, &r);
- if (r.length < 1)
- return (DNS_R_TEXTTOOLONG);
- r.base[0] = '\n';
- isc_buffer_add(&buf, 1);
-
- result = indent(&col, ctx->style.rdata_column,
- ctx->style.tab_width, &buf);
- /*
- * Do not return ISC_R_NOSPACE if the line break string
- * buffer is too small, because that would just make
- * dump_rdataset() retry indefinitely with ever
- * bigger target buffers. That's a different buffer,
- * so it won't help. Use DNS_R_TEXTTOOLONG as a substitute.
- */
- if (result == ISC_R_NOSPACE)
- return (DNS_R_TEXTTOOLONG);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- isc_buffer_availableregion(&buf, &r);
- if (r.length < 1)
- return (DNS_R_TEXTTOOLONG);
- r.base[0] = '\0';
- isc_buffer_add(&buf, 1);
- ctx->linebreak = ctx->linebreak_buf;
- } else {
- ctx->linebreak = NULL;
- }
-
- ctx->origin = NULL;
- ctx->neworigin = NULL;
- ctx->current_ttl = 0;
- ctx->current_ttl_valid = ISC_FALSE;
-
- return (ISC_R_SUCCESS);
-}
-
-#define INDENT_TO(col) \
- do { \
- if ((result = indent(&column, ctx->style.col, \
- ctx->style.tab_width, target)) \
- != ISC_R_SUCCESS) \
- return (result); \
- } while (0)
-
-
-static isc_result_t
-str_totext(const char *source, isc_buffer_t *target) {
- unsigned int l;
- isc_region_t region;
-
- isc_buffer_availableregion(target, &region);
- l = strlen(source);
-
- if (l > region.length)
- return (ISC_R_NOSPACE);
-
- memcpy(region.base, source, l);
- isc_buffer_add(target, l);
- 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, 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
- * is omitted; otherwise 'owner_name' must be valid and have at least
- * one label.
- */
-
-static isc_result_t
-rdataset_totext(dns_rdataset_t *rdataset,
- dns_name_t *owner_name,
- dns_totext_ctx_t *ctx,
- isc_boolean_t omit_final_dot,
- isc_buffer_t *target)
-{
- isc_result_t result;
- unsigned int column;
- isc_boolean_t first = ISC_TRUE;
- isc_uint32_t current_ttl;
- isc_boolean_t current_ttl_valid;
- dns_rdatatype_t type;
- unsigned int type_start;
-
- REQUIRE(DNS_RDATASET_VALID(rdataset));
-
- rdataset->attributes |= DNS_RDATASETATTR_LOADORDER;
- result = dns_rdataset_first(rdataset);
-
- current_ttl = ctx->current_ttl;
- current_ttl_valid = ctx->current_ttl_valid;
-
- while (result == ISC_R_SUCCESS) {
- column = 0;
-
- /*
- * Owner name.
- */
- if (owner_name != NULL &&
- ! ((ctx->style.flags & DNS_STYLEFLAG_OMIT_OWNER) != 0 &&
- !first))
- {
- unsigned int name_start = target->used;
- RETERR(dns_name_totext(owner_name,
- omit_final_dot,
- target));
- column += target->used - name_start;
- }
-
- /*
- * TTL.
- */
- if ((ctx->style.flags & DNS_STYLEFLAG_NO_TTL) == 0 &&
- !((ctx->style.flags & DNS_STYLEFLAG_OMIT_TTL) != 0 &&
- current_ttl_valid &&
- rdataset->ttl == current_ttl))
- {
- char ttlbuf[64];
- isc_region_t r;
- unsigned int length;
-
- INDENT_TO(ttl_column);
- length = snprintf(ttlbuf, sizeof(ttlbuf), "%u",
- rdataset->ttl);
- INSIST(length <= sizeof(ttlbuf));
- isc_buffer_availableregion(target, &r);
- if (r.length < length)
- return (ISC_R_NOSPACE);
- memcpy(r.base, ttlbuf, length);
- isc_buffer_add(target, length);
- column += length;
-
- /*
- * If the $TTL directive is not in use, the TTL we
- * just printed becomes the default for subsequent RRs.
- */
- if ((ctx->style.flags & DNS_STYLEFLAG_TTL) == 0) {
- current_ttl = rdataset->ttl;
- current_ttl_valid = ISC_TRUE;
- }
- }
-
- /*
- * Class.
- */
- if ((ctx->style.flags & DNS_STYLEFLAG_NO_CLASS) == 0 &&
- ((ctx->style.flags & DNS_STYLEFLAG_OMIT_CLASS) == 0 ||
- ctx->class_printed == ISC_FALSE))
- {
- unsigned int class_start;
- INDENT_TO(class_column);
- class_start = target->used;
- result = dns_rdataclass_totext(rdataset->rdclass,
- target);
- if (result != ISC_R_SUCCESS)
- return (result);
- column += (target->used - class_start);
- }
-
- /*
- * Type.
- */
-
- if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) {
- type = rdataset->covers;
- } else {
- type = rdataset->type;
- }
-
- INDENT_TO(type_column);
- type_start = target->used;
- if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0)
- RETERR(str_totext("\\-", target));
- result = dns_rdatatype_totext(type, target);
- if (result != ISC_R_SUCCESS)
- return (result);
- column += (target->used - type_start);
-
- /*
- * Rdata.
- */
- INDENT_TO(rdata_column);
- if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) {
- if (NXDOMAIN(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;
-
- dns_rdataset_current(rdataset, &rdata);
-
- RETERR(dns_rdata_tofmttext(&rdata,
- ctx->origin,
- ctx->style.flags,
- ctx->style.line_length -
- ctx->style.rdata_column,
- ctx->style.split_width,
- ctx->linebreak,
- target));
-
- isc_buffer_availableregion(target, &r);
- if (r.length < 1)
- return (ISC_R_NOSPACE);
- r.base[0] = '\n';
- isc_buffer_add(target, 1);
- }
-
- first = ISC_FALSE;
- result = dns_rdataset_next(rdataset);
- }
-
- if (result != ISC_R_NOMORE)
- return (result);
-
- /*
- * Update the ctx state to reflect what we just printed.
- * This is done last, only when we are sure we will return
- * success, because this function may be called multiple
- * times with increasing buffer sizes until it succeeds,
- * and failed attempts must not update the state prematurely.
- */
- ctx->class_printed = ISC_TRUE;
- ctx->current_ttl= current_ttl;
- ctx->current_ttl_valid = current_ttl_valid;
-
- return (ISC_R_SUCCESS);
-}
-
-/*
- * Print the name, type, and class of an empty rdataset,
- * such as those used to represent the question section
- * of a DNS message.
- */
-static isc_result_t
-question_totext(dns_rdataset_t *rdataset,
- dns_name_t *owner_name,
- dns_totext_ctx_t *ctx,
- isc_boolean_t omit_final_dot,
- isc_buffer_t *target)
-{
- unsigned int column;
- isc_result_t result;
- isc_region_t r;
-
- REQUIRE(DNS_RDATASET_VALID(rdataset));
- result = dns_rdataset_first(rdataset);
- REQUIRE(result == ISC_R_NOMORE);
-
- column = 0;
-
- /* Owner name */
- {
- unsigned int name_start = target->used;
- RETERR(dns_name_totext(owner_name,
- omit_final_dot,
- target));
- column += target->used - name_start;
- }
-
- /* Class */
- {
- unsigned int class_start;
- INDENT_TO(class_column);
- class_start = target->used;
- result = dns_rdataclass_totext(rdataset->rdclass, target);
- if (result != ISC_R_SUCCESS)
- return (result);
- column += (target->used - class_start);
- }
-
- /* Type */
- {
- unsigned int type_start;
- INDENT_TO(type_column);
- type_start = target->used;
- result = dns_rdatatype_totext(rdataset->type, target);
- if (result != ISC_R_SUCCESS)
- return (result);
- column += (target->used - type_start);
- }
-
- isc_buffer_availableregion(target, &r);
- if (r.length < 1)
- return (ISC_R_NOSPACE);
- r.base[0] = '\n';
- isc_buffer_add(target, 1);
-
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_rdataset_totext(dns_rdataset_t *rdataset,
- dns_name_t *owner_name,
- isc_boolean_t omit_final_dot,
- isc_boolean_t question,
- isc_buffer_t *target)
-{
- dns_totext_ctx_t ctx;
- isc_result_t result;
- result = totext_ctx_init(&dns_master_style_debug, &ctx);
- if (result != ISC_R_SUCCESS) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "could not set master file style");
- return (ISC_R_UNEXPECTED);
- }
-
- /*
- * The caller might want to give us an empty owner
- * name (e.g. if they are outputting into a master
- * file and this rdataset has the same name as the
- * previous one.)
- */
- if (dns_name_countlabels(owner_name) == 0)
- owner_name = NULL;
-
- if (question)
- return (question_totext(rdataset, owner_name, &ctx,
- omit_final_dot, target));
- else
- return (rdataset_totext(rdataset, owner_name, &ctx,
- omit_final_dot, target));
-}
-
-isc_result_t
-dns_master_rdatasettotext(dns_name_t *owner_name,
- dns_rdataset_t *rdataset,
- const dns_master_style_t *style,
- isc_buffer_t *target)
-{
- dns_totext_ctx_t ctx;
- isc_result_t result;
- result = totext_ctx_init(style, &ctx);
- if (result != ISC_R_SUCCESS) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "could not set master file style");
- return (ISC_R_UNEXPECTED);
- }
-
- return (rdataset_totext(rdataset, owner_name, &ctx,
- ISC_FALSE, target));
-}
-
-isc_result_t
-dns_master_questiontotext(dns_name_t *owner_name,
- dns_rdataset_t *rdataset,
- const dns_master_style_t *style,
- isc_buffer_t *target)
-{
- dns_totext_ctx_t ctx;
- isc_result_t result;
- result = totext_ctx_init(style, &ctx);
- if (result != ISC_R_SUCCESS) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "could not set master file style");
- return (ISC_R_UNEXPECTED);
- }
-
- return (question_totext(rdataset, owner_name, &ctx,
- 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
- * hold the result from dns_ttl_totext(). If more than that is needed,
- * the buffer will be grown automatically.
- */
-
-static isc_result_t
-dump_rdataset(isc_mem_t *mctx, dns_name_t *name, dns_rdataset_t *rdataset,
- dns_totext_ctx_t *ctx,
- isc_buffer_t *buffer, FILE *f)
-{
- isc_region_t r;
- isc_result_t result;
-
- REQUIRE(buffer->length > 0);
-
- /*
- * Output a $TTL directive if needed.
- */
-
- if ((ctx->style.flags & DNS_STYLEFLAG_TTL) != 0) {
- if (ctx->current_ttl_valid == ISC_FALSE ||
- ctx->current_ttl != rdataset->ttl)
- {
- if ((ctx->style.flags & DNS_STYLEFLAG_COMMENT) != 0)
- {
- isc_buffer_clear(buffer);
- result = dns_ttl_totext(rdataset->ttl,
- ISC_TRUE, buffer);
- INSIST(result == ISC_R_SUCCESS);
- isc_buffer_usedregion(buffer, &r);
- fprintf(f, "$TTL %u\t; %.*s\n", rdataset->ttl,
- (int) r.length, (char *) r.base);
- } else {
- fprintf(f, "$TTL %u\n", rdataset->ttl);
- }
- ctx->current_ttl = rdataset->ttl;
- ctx->current_ttl_valid = ISC_TRUE;
- }
- }
-
- isc_buffer_clear(buffer);
-
- /*
- * Generate the text representation of the rdataset into
- * the buffer. If the buffer is too small, grow it.
- */
- for (;;) {
- int newlength;
- void *newmem;
- result = rdataset_totext(rdataset, name, ctx,
- ISC_FALSE, buffer);
- if (result != ISC_R_NOSPACE)
- break;
-
- newlength = buffer->length * 2;
- newmem = isc_mem_get(mctx, newlength);
- if (newmem == NULL)
- return (ISC_R_NOMEMORY);
- isc_mem_put(mctx, buffer->base, buffer->length);
- isc_buffer_init(buffer, newmem, newlength);
- }
- if (result != ISC_R_SUCCESS)
- return (result);
-
- /*
- * Write the buffer contents to the master file.
- */
- isc_buffer_usedregion(buffer, &r);
- result = isc_stdio_write(r.base, 1, (size_t)r.length, f, NULL);
-
- if (result != ISC_R_SUCCESS) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "master file write failed: %s",
- isc_result_totext(result));
- return (result);
- }
-
- return (ISC_R_SUCCESS);
-}
-
-/*
- * Define the order in which rdatasets should be printed in zone
- * files. We will print SOA and NS records before others, SIGs
- * immediately following the things they sign, and order everything
- * else by RR number. This is all just for aesthetics and
- * compatibility with buggy software that expects the SOA to be first;
- * the DNS specifications allow any order.
- */
-
-static int
-dump_order(const dns_rdataset_t *rds) {
- int t;
- int sig;
- if (rds->type == dns_rdatatype_rrsig) {
- t = rds->covers;
- sig = 1;
- } else {
- t = rds->type;
- sig = 0;
- }
- switch (t) {
- case dns_rdatatype_soa:
- t = 0;
- break;
- case dns_rdatatype_ns:
- t = 1;
- break;
- default:
- t += 2;
- break;
- }
- return (t << 1) + sig;
-}
-
-static int
-dump_order_compare(const void *a, const void *b) {
- return (dump_order(*((const dns_rdataset_t * const *) a)) -
- dump_order(*((const dns_rdataset_t * const *) b)));
-}
-
-/*
- * Dump all the rdatasets of a domain name to a master file. We make
- * a "best effort" attempt to sort the RRsets in a nice order, but if
- * there are more than MAXSORT RRsets, we punt and only sort them in
- * groups of MAXSORT. This is not expected to ever happen in practice
- * since much less than 64 RR types have been registered with the
- * IANA, so far, and the output will be correct (though not
- * aesthetically pleasing) even if it does happen.
- */
-
-#define MAXSORT 64
-
-static isc_result_t
-dump_rdatasets_text(isc_mem_t *mctx, dns_name_t *name,
- dns_rdatasetiter_t *rdsiter, dns_totext_ctx_t *ctx,
- isc_buffer_t *buffer, FILE *f)
-{
- isc_result_t itresult, dumpresult;
- isc_region_t r;
- dns_rdataset_t rdatasets[MAXSORT];
- dns_rdataset_t *sorted[MAXSORT];
- int i, n;
-
- itresult = dns_rdatasetiter_first(rdsiter);
- dumpresult = ISC_R_SUCCESS;
-
- if (itresult == ISC_R_SUCCESS && ctx->neworigin != NULL) {
- isc_buffer_clear(buffer);
- itresult = dns_name_totext(ctx->neworigin, ISC_FALSE, buffer);
- RUNTIME_CHECK(itresult == ISC_R_SUCCESS);
- isc_buffer_usedregion(buffer, &r);
- fprintf(f, "$ORIGIN %.*s\n", (int) r.length, (char *) r.base);
- ctx->neworigin = NULL;
- }
-
- again:
- for (i = 0;
- itresult == ISC_R_SUCCESS && i < MAXSORT;
- itresult = dns_rdatasetiter_next(rdsiter), i++) {
- dns_rdataset_init(&rdatasets[i]);
- dns_rdatasetiter_current(rdsiter, &rdatasets[i]);
- sorted[i] = &rdatasets[i];
- }
- n = i;
- INSIST(n <= MAXSORT);
-
- qsort(sorted, n, sizeof(sorted[0]), dump_order_compare);
-
- for (i = 0; i < n; i++) {
- dns_rdataset_t *rds = sorted[i];
- if (ctx->style.flags & DNS_STYLEFLAG_TRUST)
- fprintf(f, "; %s\n", dns_trust_totext(rds->trust));
- if (((rds->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) &&
- (ctx->style.flags & DNS_STYLEFLAG_NCACHE) == 0) {
- /* Omit negative cache entries */
- } else {
- isc_result_t result =
- dump_rdataset(mctx, name, rds, ctx,
- buffer, f);
- if (result != ISC_R_SUCCESS)
- dumpresult = result;
- if ((ctx->style.flags & DNS_STYLEFLAG_OMIT_OWNER) != 0)
- name = NULL;
- }
- if (ctx->style.flags & DNS_STYLEFLAG_RESIGN &&
- rds->attributes & DNS_RDATASETATTR_RESIGN) {
- isc_buffer_t b;
- char buf[sizeof("YYYYMMDDHHMMSS")];
- memset(buf, 0, sizeof(buf));
- isc_buffer_init(&b, buf, sizeof(buf) - 1);
- dns_time64_totext((isc_uint64_t)rds->resign, &b);
- fprintf(f, "; resign=%s\n", buf);
- }
- dns_rdataset_disassociate(rds);
- }
-
- if (dumpresult != ISC_R_SUCCESS)
- return (dumpresult);
-
- /*
- * If we got more data than could be sorted at once,
- * go handle the rest.
- */
- if (itresult == ISC_R_SUCCESS)
- goto again;
-
- if (itresult == ISC_R_NOMORE)
- itresult = ISC_R_SUCCESS;
-
- return (itresult);
-}
-
-/*
- * Dump given RRsets in the "raw" format.
- */
-static isc_result_t
-dump_rdataset_raw(isc_mem_t *mctx, dns_name_t *name, dns_rdataset_t *rdataset,
- isc_buffer_t *buffer, FILE *f)
-{
- isc_result_t result;
- isc_uint32_t totallen;
- isc_uint16_t dlen;
- isc_region_t r, r_hdr;
-
- REQUIRE(buffer->length > 0);
- REQUIRE(DNS_RDATASET_VALID(rdataset));
-
- rdataset->attributes |= DNS_RDATASETATTR_LOADORDER;
- restart:
- totallen = 0;
- result = dns_rdataset_first(rdataset);
- REQUIRE(result == ISC_R_SUCCESS);
-
- isc_buffer_clear(buffer);
-
- /*
- * Common header and owner name (length followed by name)
- * These fields should be in a moderate length, so we assume we
- * can store all of them in the initial buffer.
- */
- isc_buffer_availableregion(buffer, &r_hdr);
- INSIST(r_hdr.length >= sizeof(dns_masterrawrdataset_t));
- isc_buffer_putuint32(buffer, totallen); /* XXX: leave space */
- isc_buffer_putuint16(buffer, rdataset->rdclass); /* 16-bit class */
- isc_buffer_putuint16(buffer, rdataset->type); /* 16-bit type */
- isc_buffer_putuint16(buffer, rdataset->covers); /* same as type */
- isc_buffer_putuint32(buffer, rdataset->ttl); /* 32-bit TTL */
- isc_buffer_putuint32(buffer, dns_rdataset_count(rdataset));
- totallen = isc_buffer_usedlength(buffer);
- INSIST(totallen <= sizeof(dns_masterrawrdataset_t));
-
- dns_name_toregion(name, &r);
- INSIST(isc_buffer_availablelength(buffer) >=
- (sizeof(dlen) + r.length));
- dlen = (isc_uint16_t)r.length;
- isc_buffer_putuint16(buffer, dlen);
- isc_buffer_copyregion(buffer, &r);
- totallen += sizeof(dlen) + r.length;
-
- do {
- dns_rdata_t rdata = DNS_RDATA_INIT;
- isc_region_t r;
-
- dns_rdataset_current(rdataset, &rdata);
- dns_rdata_toregion(&rdata, &r);
- INSIST(r.length <= 0xffffU);
- dlen = (isc_uint16_t)r.length;
-
- /*
- * Copy the rdata into the buffer. If the buffer is too small,
- * grow it. This should be rare, so we'll simply restart the
- * entire procedure (or should we copy the old data and
- * continue?).
- */
- if (isc_buffer_availablelength(buffer) <
- sizeof(dlen) + r.length) {
- int newlength;
- void *newmem;
-
- newlength = buffer->length * 2;
- newmem = isc_mem_get(mctx, newlength);
- if (newmem == NULL)
- return (ISC_R_NOMEMORY);
- isc_mem_put(mctx, buffer->base, buffer->length);
- isc_buffer_init(buffer, newmem, newlength);
- goto restart;
- }
- isc_buffer_putuint16(buffer, dlen);
- isc_buffer_copyregion(buffer, &r);
- totallen += sizeof(dlen) + r.length;
-
- result = dns_rdataset_next(rdataset);
- } while (result == ISC_R_SUCCESS);
-
- if (result != ISC_R_NOMORE)
- return (result);
-
- /*
- * Fill in the total length field.
- * XXX: this is a bit tricky. Since we have already "used" the space
- * for the total length in the buffer, we first remember the entire
- * buffer length in the region, "rewind", and then write the value.
- */
- isc_buffer_usedregion(buffer, &r);
- isc_buffer_clear(buffer);
- isc_buffer_putuint32(buffer, totallen);
- INSIST(isc_buffer_usedlength(buffer) < totallen);
-
- /*
- * Write the buffer contents to the raw master file.
- */
- result = isc_stdio_write(r.base, 1, (size_t)r.length, f, NULL);
-
- if (result != ISC_R_SUCCESS) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "raw master file write failed: %s",
- isc_result_totext(result));
- return (result);
- }
-
- return (result);
-}
-
-static isc_result_t
-dump_rdatasets_raw(isc_mem_t *mctx, dns_name_t *name,
- dns_rdatasetiter_t *rdsiter, dns_totext_ctx_t *ctx,
- isc_buffer_t *buffer, FILE *f)
-{
- isc_result_t result;
- dns_rdataset_t rdataset;
-
- for (result = dns_rdatasetiter_first(rdsiter);
- result == ISC_R_SUCCESS;
- result = dns_rdatasetiter_next(rdsiter)) {
-
- dns_rdataset_init(&rdataset);
- dns_rdatasetiter_current(rdsiter, &rdataset);
-
- if (((rdataset.attributes & DNS_RDATASETATTR_NEGATIVE) != 0) &&
- (ctx->style.flags & DNS_STYLEFLAG_NCACHE) == 0) {
- /* Omit negative cache entries */
- } else {
- result = dump_rdataset_raw(mctx, name, &rdataset,
- buffer, f);
- }
- dns_rdataset_disassociate(&rdataset);
- if (result != ISC_R_SUCCESS)
- return (result);
- }
-
- if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
-
- return (result);
-}
-
-/*
- * Initial size of text conversion buffer. The buffer is used
- * for several purposes: converting origin names, rdatasets,
- * $DATE timestamps, and comment strings for $TTL directives.
- *
- * When converting rdatasets, it is dynamically resized, but
- * when converting origins, timestamps, etc it is not. Therefore,
- * the initial size must large enough to hold the longest possible
- * text representation of any domain name (for $ORIGIN).
- */
-static const int initial_buffer_length = 1200;
-
-static isc_result_t
-dumptostreaminc(dns_dumpctx_t *dctx);
-
-static void
-dumpctx_destroy(dns_dumpctx_t *dctx) {
-
- dctx->magic = 0;
- DESTROYLOCK(&dctx->lock);
- dns_dbiterator_destroy(&dctx->dbiter);
- if (dctx->version != NULL)
- dns_db_closeversion(dctx->db, &dctx->version, ISC_FALSE);
- dns_db_detach(&dctx->db);
- if (dctx->task != NULL)
- isc_task_detach(&dctx->task);
- if (dctx->file != NULL)
- isc_mem_free(dctx->mctx, dctx->file);
- if (dctx->tmpfile != NULL)
- isc_mem_free(dctx->mctx, dctx->tmpfile);
- isc_mem_putanddetach(&dctx->mctx, dctx, sizeof(*dctx));
-}
-
-void
-dns_dumpctx_attach(dns_dumpctx_t *source, dns_dumpctx_t **target) {
-
- REQUIRE(DNS_DCTX_VALID(source));
- REQUIRE(target != NULL && *target == NULL);
-
- LOCK(&source->lock);
- INSIST(source->references > 0);
- source->references++;
- INSIST(source->references != 0); /* Overflow? */
- UNLOCK(&source->lock);
-
- *target = source;
-}
-
-void
-dns_dumpctx_detach(dns_dumpctx_t **dctxp) {
- dns_dumpctx_t *dctx;
- isc_boolean_t need_destroy = ISC_FALSE;
-
- REQUIRE(dctxp != NULL);
- dctx = *dctxp;
- REQUIRE(DNS_DCTX_VALID(dctx));
-
- *dctxp = NULL;
-
- LOCK(&dctx->lock);
- INSIST(dctx->references != 0);
- dctx->references--;
- if (dctx->references == 0)
- need_destroy = ISC_TRUE;
- UNLOCK(&dctx->lock);
- if (need_destroy)
- dumpctx_destroy(dctx);
-}
-
-dns_dbversion_t *
-dns_dumpctx_version(dns_dumpctx_t *dctx) {
- REQUIRE(DNS_DCTX_VALID(dctx));
- return (dctx->version);
-}
-
-dns_db_t *
-dns_dumpctx_db(dns_dumpctx_t *dctx) {
- REQUIRE(DNS_DCTX_VALID(dctx));
- return (dctx->db);
-}
-
-void
-dns_dumpctx_cancel(dns_dumpctx_t *dctx) {
- REQUIRE(DNS_DCTX_VALID(dctx));
-
- LOCK(&dctx->lock);
- dctx->canceled = ISC_TRUE;
- UNLOCK(&dctx->lock);
-}
-
-static isc_result_t
-flushandsync(FILE *f, isc_result_t result, const char *temp) {
- isc_boolean_t logit = ISC_TF(result == ISC_R_SUCCESS);
-
- if (result == ISC_R_SUCCESS)
- result = isc_stdio_flush(f);
- if (result != ISC_R_SUCCESS && logit) {
- if (temp != NULL)
- isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL,
- DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR,
- "dumping to master file: %s: flush: %s",
- temp, isc_result_totext(result));
- else
- isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL,
- DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR,
- "dumping to stream: flush: %s",
- isc_result_totext(result));
- logit = ISC_FALSE;
- }
-
- if (result == ISC_R_SUCCESS)
- result = isc_stdio_sync(f);
- if (result != ISC_R_SUCCESS && logit) {
- if (temp != NULL)
- isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL,
- DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR,
- "dumping to master file: %s: fsync: %s",
- temp, isc_result_totext(result));
- else
- isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL,
- DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR,
- "dumping to stream: fsync: %s",
- isc_result_totext(result));
- }
- return (result);
-}
-
-static isc_result_t
-closeandrename(FILE *f, isc_result_t result, const char *temp, const char *file)
-{
- isc_result_t tresult;
- isc_boolean_t logit = ISC_TF(result == ISC_R_SUCCESS);
-
- result = flushandsync(f, result, temp);
- if (result != ISC_R_SUCCESS)
- logit = ISC_FALSE;
-
- tresult = isc_stdio_close(f);
- if (result == ISC_R_SUCCESS)
- result = tresult;
- if (result != ISC_R_SUCCESS && logit) {
- isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL,
- DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR,
- "dumping master file: %s: fclose: %s",
- temp, isc_result_totext(result));
- logit = ISC_FALSE;
- }
- if (result == ISC_R_SUCCESS)
- result = isc_file_rename(temp, file);
- else
- (void)isc_file_remove(temp);
- if (result != ISC_R_SUCCESS && logit) {
- isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL,
- DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR,
- "dumping master file: rename: %s: %s",
- file, isc_result_totext(result));
- }
- return (result);
-}
-
-static void
-dump_quantum(isc_task_t *task, isc_event_t *event) {
- isc_result_t result;
- isc_result_t tresult;
- dns_dumpctx_t *dctx;
-
- REQUIRE(event != NULL);
- dctx = event->ev_arg;
- REQUIRE(DNS_DCTX_VALID(dctx));
- if (dctx->canceled)
- result = ISC_R_CANCELED;
- else
- result = dumptostreaminc(dctx);
- if (result == DNS_R_CONTINUE) {
- event->ev_arg = dctx;
- isc_task_send(task, &event);
- return;
- }
-
- if (dctx->file != NULL) {
- tresult = closeandrename(dctx->f, result,
- dctx->tmpfile, dctx->file);
- if (tresult != ISC_R_SUCCESS && result == ISC_R_SUCCESS)
- result = tresult;
- } else
- result = flushandsync(dctx->f, result, NULL);
- (dctx->done)(dctx->done_arg, result);
- isc_event_free(&event);
- dns_dumpctx_detach(&dctx);
-}
-
-static isc_result_t
-task_send(dns_dumpctx_t *dctx) {
- isc_event_t *event;
-
- event = isc_event_allocate(dctx->mctx, NULL, DNS_EVENT_DUMPQUANTUM,
- dump_quantum, dctx, sizeof(*event));
- if (event == NULL)
- return (ISC_R_NOMEMORY);
- isc_task_send(dctx->task, &event);
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-dumpctx_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
- const dns_master_style_t *style, FILE *f, dns_dumpctx_t **dctxp,
- dns_masterformat_t format, dns_masterrawheader_t *header)
-{
- dns_dumpctx_t *dctx;
- isc_result_t result;
- unsigned int options;
-
- dctx = isc_mem_get(mctx, sizeof(*dctx));
- if (dctx == NULL)
- return (ISC_R_NOMEMORY);
-
- dctx->mctx = NULL;
- dctx->f = f;
- dctx->dbiter = NULL;
- dctx->db = NULL;
- dctx->version = NULL;
- dctx->done = NULL;
- dctx->done_arg = NULL;
- dctx->task = NULL;
- dctx->nodes = 0;
- dctx->first = ISC_TRUE;
- dctx->canceled = ISC_FALSE;
- dctx->file = NULL;
- dctx->tmpfile = NULL;
- dctx->format = format;
- if (header == NULL)
- dns_master_initrawheader(&dctx->header);
- else
- dctx->header = *header;
-
- switch (format) {
- case dns_masterformat_text:
- dctx->dumpsets = dump_rdatasets_text;
- break;
- case dns_masterformat_raw:
- dctx->dumpsets = dump_rdatasets_raw;
- break;
- default:
- INSIST(0);
- break;
- }
-
- result = totext_ctx_init(style, &dctx->tctx);
- if (result != ISC_R_SUCCESS) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "could not set master file style");
- goto cleanup;
- }
-
- isc_stdtime_get(&dctx->now);
- dns_db_attach(db, &dctx->db);
-
- dctx->do_date = dns_db_iscache(dctx->db);
-
- if (dctx->format == dns_masterformat_text &&
- (dctx->tctx.style.flags & DNS_STYLEFLAG_REL_OWNER) != 0) {
- options = DNS_DB_RELATIVENAMES;
- } else
- options = 0;
- result = dns_db_createiterator(dctx->db, options, &dctx->dbiter);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- result = isc_mutex_init(&dctx->lock);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- if (version != NULL)
- dns_db_attachversion(dctx->db, version, &dctx->version);
- else if (!dns_db_iscache(db))
- dns_db_currentversion(dctx->db, &dctx->version);
- isc_mem_attach(mctx, &dctx->mctx);
- dctx->references = 1;
- dctx->magic = DNS_DCTX_MAGIC;
- *dctxp = dctx;
- return (ISC_R_SUCCESS);
-
- cleanup:
- if (dctx->dbiter != NULL)
- dns_dbiterator_destroy(&dctx->dbiter);
- if (dctx->db != NULL)
- dns_db_detach(&dctx->db);
- if (dctx != NULL)
- isc_mem_put(mctx, dctx, sizeof(*dctx));
- return (result);
-}
-
-static isc_result_t
-dumptostreaminc(dns_dumpctx_t *dctx) {
- isc_result_t result;
- isc_buffer_t buffer;
- char *bufmem;
- isc_region_t r;
- dns_name_t *name;
- dns_fixedname_t fixname;
- unsigned int nodes;
- dns_masterrawheader_t rawheader;
- isc_uint32_t rawversion, now32;
- isc_time_t start;
-
- bufmem = isc_mem_get(dctx->mctx, initial_buffer_length);
- if (bufmem == NULL)
- return (ISC_R_NOMEMORY);
-
- isc_buffer_init(&buffer, bufmem, initial_buffer_length);
-
- dns_fixedname_init(&fixname);
- name = dns_fixedname_name(&fixname);
-
- if (dctx->first) {
- switch (dctx->format) {
- case dns_masterformat_text:
- /*
- * If the database has cache semantics, output an
- * RFC2540 $DATE directive so that the TTLs can be
- * adjusted when it is reloaded. For zones it is not
- * really needed, and it would make the file
- * incompatible with pre-RFC2540 software, so we omit
- * it in the zone case.
- */
- if (dctx->do_date) {
- result = dns_time32_totext(dctx->now, &buffer);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- isc_buffer_usedregion(&buffer, &r);
- fprintf(dctx->f, "$DATE %.*s\n",
- (int) r.length, (char *) r.base);
- }
- break;
- case dns_masterformat_raw:
- r.base = (unsigned char *)&rawheader;
- r.length = sizeof(rawheader);
- isc_buffer_region(&buffer, &r);
-#if !defined(STDTIME_ON_32BITS) || (STDTIME_ON_32BITS + 0) != 1
- /*
- * We assume isc_stdtime_t is a 32-bit integer,
- * which should be the case on most cases.
- * If it turns out to be uncommon, we'll need
- * to bump the version number and revise the
- * header format.
- */
- isc_log_write(dns_lctx,
- ISC_LOGCATEGORY_GENERAL,
- DNS_LOGMODULE_MASTERDUMP,
- ISC_LOG_INFO,
- "dumping master file in raw "
- "format: stdtime is not 32bits");
- now32 = 0;
-#else
- now32 = dctx->now;
-#endif
- rawversion = 1;
- if ((dctx->header.flags & DNS_MASTERRAW_COMPAT) != 0)
- rawversion = 0;
- isc_buffer_putuint32(&buffer, dns_masterformat_raw);
- isc_buffer_putuint32(&buffer, rawversion);
- isc_buffer_putuint32(&buffer, now32);
-
- if (rawversion == 1) {
- isc_buffer_putuint32(&buffer,
- dctx->header.flags);
- isc_buffer_putuint32(&buffer,
- dctx->header.sourceserial);
- isc_buffer_putuint32(&buffer,
- dctx->header.lastxfrin);
- }
-
- INSIST(isc_buffer_usedlength(&buffer) <=
- sizeof(rawheader));
- result = isc_stdio_write(buffer.base, 1,
- isc_buffer_usedlength(&buffer),
- dctx->f, NULL);
- if (result != ISC_R_SUCCESS)
- return (result);
- isc_buffer_clear(&buffer);
- break;
- default:
- INSIST(0);
- }
-
- result = dns_dbiterator_first(dctx->dbiter);
- dctx->first = ISC_FALSE;
- } else
- result = ISC_R_SUCCESS;
-
- nodes = dctx->nodes;
- isc_time_now(&start);
- while (result == ISC_R_SUCCESS && (dctx->nodes == 0 || nodes--)) {
- dns_rdatasetiter_t *rdsiter = NULL;
- dns_dbnode_t *node = NULL;
-
- result = dns_dbiterator_current(dctx->dbiter, &node, name);
- if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN)
- break;
- if (result == DNS_R_NEWORIGIN) {
- dns_name_t *origin =
- dns_fixedname_name(&dctx->tctx.origin_fixname);
- result = dns_dbiterator_origin(dctx->dbiter, origin);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- if ((dctx->tctx.style.flags & DNS_STYLEFLAG_REL_DATA) != 0)
- dctx->tctx.origin = origin;
- dctx->tctx.neworigin = origin;
- }
- result = dns_db_allrdatasets(dctx->db, node, dctx->version,
- dctx->now, &rdsiter);
- if (result != ISC_R_SUCCESS) {
- dns_db_detachnode(dctx->db, &node);
- goto fail;
- }
- result = (dctx->dumpsets)(dctx->mctx, name, rdsiter,
- &dctx->tctx, &buffer, dctx->f);
- dns_rdatasetiter_destroy(&rdsiter);
- if (result != ISC_R_SUCCESS) {
- dns_db_detachnode(dctx->db, &node);
- goto fail;
- }
- dns_db_detachnode(dctx->db, &node);
- result = dns_dbiterator_next(dctx->dbiter);
- }
-
- /*
- * Work out how many nodes can be written in the time between
- * two requests to the nameserver. Smooth the resulting number and
- * use it as a estimate for the number of nodes to be written in the
- * next iteration.
- */
- if (dctx->nodes != 0 && result == ISC_R_SUCCESS) {
- unsigned int pps = dns_pps; /* packets per second */
- unsigned int interval;
- isc_uint64_t usecs;
- isc_time_t end;
-
- isc_time_now(&end);
- if (pps < 100)
- pps = 100;
- interval = 1000000 / pps; /* interval in usecs */
- if (interval == 0)
- interval = 1;
- usecs = isc_time_microdiff(&end, &start);
- if (usecs == 0) {
- dctx->nodes = dctx->nodes * 2;
- if (dctx->nodes > 1000)
- dctx->nodes = 1000;
- } else {
- nodes = dctx->nodes * interval;
- nodes /= (unsigned int)usecs;
- if (nodes == 0)
- nodes = 1;
- else if (nodes > 1000)
- nodes = 1000;
-
- /* Smooth and assign. */
- dctx->nodes = (nodes + dctx->nodes * 7) / 8;
-
- isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL,
- DNS_LOGMODULE_MASTERDUMP,
- ISC_LOG_DEBUG(1),
- "dumptostreaminc(%p) new nodes -> %d\n",
- dctx, dctx->nodes);
- }
- result = DNS_R_CONTINUE;
- } else if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
- fail:
- RUNTIME_CHECK(dns_dbiterator_pause(dctx->dbiter) == ISC_R_SUCCESS);
- isc_mem_put(dctx->mctx, buffer.base, buffer.length);
- return (result);
-}
-
-isc_result_t
-dns_master_dumptostreaminc(isc_mem_t *mctx, dns_db_t *db,
- dns_dbversion_t *version,
- const dns_master_style_t *style,
- FILE *f, isc_task_t *task,
- dns_dumpdonefunc_t done, void *done_arg,
- dns_dumpctx_t **dctxp)
-{
- dns_dumpctx_t *dctx = NULL;
- isc_result_t result;
-
- REQUIRE(task != NULL);
- REQUIRE(f != NULL);
- REQUIRE(done != NULL);
-
- result = dumpctx_create(mctx, db, version, style, f, &dctx,
- dns_masterformat_text, NULL);
- if (result != ISC_R_SUCCESS)
- return (result);
- isc_task_attach(task, &dctx->task);
- dctx->done = done;
- dctx->done_arg = done_arg;
- dctx->nodes = 100;
-
- result = task_send(dctx);
- if (result == ISC_R_SUCCESS) {
- dns_dumpctx_attach(dctx, dctxp);
- return (DNS_R_CONTINUE);
- }
-
- dns_dumpctx_detach(&dctx);
- return (result);
-}
-
-/*
- * Dump an entire database into a master file.
- */
-isc_result_t
-dns_master_dumptostream(isc_mem_t *mctx, dns_db_t *db,
- dns_dbversion_t *version,
- const dns_master_style_t *style,
- FILE *f)
-{
- return (dns_master_dumptostream3(mctx, db, version, style,
- dns_masterformat_text, NULL, f));
-}
-
-isc_result_t
-dns_master_dumptostream2(isc_mem_t *mctx, dns_db_t *db,
- dns_dbversion_t *version,
- const dns_master_style_t *style,
- dns_masterformat_t format, FILE *f)
-{
- return (dns_master_dumptostream3(mctx, db, version, style,
- format, NULL, f));
-}
-
-isc_result_t
-dns_master_dumptostream3(isc_mem_t *mctx, dns_db_t *db,
- dns_dbversion_t *version,
- const dns_master_style_t *style,
- dns_masterformat_t format,
- dns_masterrawheader_t *header, FILE *f)
-{
- dns_dumpctx_t *dctx = NULL;
- isc_result_t result;
-
- result = dumpctx_create(mctx, db, version, style, f, &dctx,
- format, header);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- result = dumptostreaminc(dctx);
- INSIST(result != DNS_R_CONTINUE);
- dns_dumpctx_detach(&dctx);
-
- result = flushandsync(f, result, NULL);
- return (result);
-}
-
-static isc_result_t
-opentmp(isc_mem_t *mctx, dns_masterformat_t format, const char *file,
- char **tempp, FILE **fp) {
- FILE *f = NULL;
- isc_result_t result;
- char *tempname = NULL;
- int tempnamelen;
-
- tempnamelen = strlen(file) + 20;
- tempname = isc_mem_allocate(mctx, tempnamelen);
- if (tempname == NULL)
- return (ISC_R_NOMEMORY);
-
- result = isc_file_mktemplate(file, tempname, tempnamelen);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- if (format == dns_masterformat_text)
- result = isc_file_openunique(tempname, &f);
- else
- result = isc_file_bopenunique(tempname, &f);
- if (result != ISC_R_SUCCESS) {
- isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL,
- DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR,
- "dumping master file: %s: open: %s",
- tempname, isc_result_totext(result));
- goto cleanup;
- }
- *tempp = tempname;
- *fp = f;
- return (ISC_R_SUCCESS);
-
-cleanup:
- isc_mem_free(mctx, tempname);
- return (result);
-}
-
-isc_result_t
-dns_master_dumpinc(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
- const dns_master_style_t *style, const char *filename,
- isc_task_t *task, dns_dumpdonefunc_t done, void *done_arg,
- dns_dumpctx_t **dctxp)
-{
- return (dns_master_dumpinc3(mctx, db, version, style, filename, task,
- done, done_arg, dctxp,
- dns_masterformat_text, NULL));
-}
-
-isc_result_t
-dns_master_dumpinc2(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
- const dns_master_style_t *style, const char *filename,
- isc_task_t *task, dns_dumpdonefunc_t done, void *done_arg,
- dns_dumpctx_t **dctxp, dns_masterformat_t format)
-{
- return (dns_master_dumpinc3(mctx, db, version, style, filename, task,
- done, done_arg, dctxp, format, NULL));
-}
-
-isc_result_t
-dns_master_dumpinc3(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
- const dns_master_style_t *style, const char *filename,
- isc_task_t *task, dns_dumpdonefunc_t done, void *done_arg,
- dns_dumpctx_t **dctxp, dns_masterformat_t format,
- dns_masterrawheader_t *header)
-{
- FILE *f = NULL;
- isc_result_t result;
- char *tempname = NULL;
- char *file = NULL;
- dns_dumpctx_t *dctx = NULL;
-
- file = isc_mem_strdup(mctx, filename);
- if (file == NULL)
- return (ISC_R_NOMEMORY);
-
- result = opentmp(mctx, format, filename, &tempname, &f);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- result = dumpctx_create(mctx, db, version, style, f, &dctx,
- format, header);
- if (result != ISC_R_SUCCESS) {
- (void)isc_stdio_close(f);
- (void)isc_file_remove(tempname);
- goto cleanup;
- }
-
- isc_task_attach(task, &dctx->task);
- dctx->done = done;
- dctx->done_arg = done_arg;
- dctx->nodes = 100;
- dctx->file = file;
- file = NULL;
- dctx->tmpfile = tempname;
- tempname = NULL;
-
- result = task_send(dctx);
- if (result == ISC_R_SUCCESS) {
- dns_dumpctx_attach(dctx, dctxp);
- return (DNS_R_CONTINUE);
- }
-
- cleanup:
- if (dctx != NULL)
- dns_dumpctx_detach(&dctx);
- if (file != NULL)
- isc_mem_free(mctx, file);
- if (tempname != NULL)
- isc_mem_free(mctx, tempname);
- return (result);
-}
-
-isc_result_t
-dns_master_dump(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
- const dns_master_style_t *style, const char *filename)
-{
- return (dns_master_dump3(mctx, db, version, style, filename,
- dns_masterformat_text, NULL));
-}
-
-isc_result_t
-dns_master_dump2(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
- const dns_master_style_t *style, const char *filename,
- dns_masterformat_t format)
-{
- return (dns_master_dump3(mctx, db, version, style, filename,
- format, NULL));
-}
-
-isc_result_t
-dns_master_dump3(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
- const dns_master_style_t *style, const char *filename,
- dns_masterformat_t format, dns_masterrawheader_t *header)
-{
- FILE *f = NULL;
- isc_result_t result;
- char *tempname;
- dns_dumpctx_t *dctx = NULL;
-
- result = opentmp(mctx, format, filename, &tempname, &f);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- result = dumpctx_create(mctx, db, version, style, f, &dctx,
- format, header);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- result = dumptostreaminc(dctx);
- INSIST(result != DNS_R_CONTINUE);
- dns_dumpctx_detach(&dctx);
-
- result = closeandrename(f, result, tempname, filename);
-
- cleanup:
- isc_mem_free(mctx, tempname);
- return (result);
-}
-
-/*
- * Dump a database node into a master file.
- * XXX: this function assumes the text format.
- */
-isc_result_t
-dns_master_dumpnodetostream(isc_mem_t *mctx, dns_db_t *db,
- dns_dbversion_t *version,
- dns_dbnode_t *node, dns_name_t *name,
- const dns_master_style_t *style,
- FILE *f)
-{
- isc_result_t result;
- isc_buffer_t buffer;
- char *bufmem;
- isc_stdtime_t now;
- dns_totext_ctx_t ctx;
- dns_rdatasetiter_t *rdsiter = NULL;
-
- result = totext_ctx_init(style, &ctx);
- if (result != ISC_R_SUCCESS) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "could not set master file style");
- return (ISC_R_UNEXPECTED);
- }
-
- isc_stdtime_get(&now);
-
- bufmem = isc_mem_get(mctx, initial_buffer_length);
- if (bufmem == NULL)
- return (ISC_R_NOMEMORY);
-
- isc_buffer_init(&buffer, bufmem, initial_buffer_length);
-
- result = dns_db_allrdatasets(db, node, version, now, &rdsiter);
- if (result != ISC_R_SUCCESS)
- goto failure;
- result = dump_rdatasets_text(mctx, name, rdsiter, &ctx, &buffer, f);
- if (result != ISC_R_SUCCESS)
- goto failure;
- dns_rdatasetiter_destroy(&rdsiter);
-
- result = ISC_R_SUCCESS;
-
- failure:
- isc_mem_put(mctx, buffer.base, buffer.length);
- return (result);
-}
-
-isc_result_t
-dns_master_dumpnode(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
- dns_dbnode_t *node, dns_name_t *name,
- const dns_master_style_t *style, const char *filename)
-{
- FILE *f = NULL;
- isc_result_t result;
-
- result = isc_stdio_open(filename, "w", &f);
- if (result != ISC_R_SUCCESS) {
- isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL,
- DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR,
- "dumping node to file: %s: open: %s", filename,
- isc_result_totext(result));
- return (ISC_R_UNEXPECTED);
- }
-
- result = dns_master_dumpnodetostream(mctx, db, version, node, name,
- style, f);
- if (result != ISC_R_SUCCESS) {
- isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL,
- DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR,
- "dumping master file: %s: dump: %s", filename,
- isc_result_totext(result));
- (void)isc_stdio_close(f);
- return (ISC_R_UNEXPECTED);
- }
-
- result = isc_stdio_close(f);
- if (result != ISC_R_SUCCESS) {
- isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL,
- DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR,
- "dumping master file: %s: close: %s", filename,
- isc_result_totext(result));
- return (ISC_R_UNEXPECTED);
- }
-
- return (result);
-}
-#endif /* BIND9 */
-
-isc_result_t
-dns_master_stylecreate(dns_master_style_t **stylep, unsigned int flags,
- unsigned int ttl_column, unsigned int class_column,
- unsigned int type_column, unsigned int rdata_column,
- unsigned int line_length, unsigned int tab_width,
- isc_mem_t *mctx)
-{
- return (dns_master_stylecreate2(stylep, flags, ttl_column,
- class_column, type_column,
- rdata_column, line_length,
- tab_width, 0xffffffff, mctx));
-}
-
-isc_result_t
-dns_master_stylecreate2(dns_master_style_t **stylep, unsigned int flags,
- unsigned int ttl_column, unsigned int class_column,
- unsigned int type_column, unsigned int rdata_column,
- unsigned int line_length, unsigned int tab_width,
- unsigned int split_width, isc_mem_t *mctx)
-{
- dns_master_style_t *style;
-
- REQUIRE(stylep != NULL && *stylep == NULL);
- style = isc_mem_get(mctx, sizeof(*style));
- if (style == NULL)
- return (ISC_R_NOMEMORY);
-
- style->flags = flags;
- style->ttl_column = ttl_column;
- style->class_column = class_column;
- style->type_column = type_column;
- style->rdata_column = rdata_column;
- style->line_length = line_length;
- style->tab_width = tab_width;
- style->split_width = split_width;
-
- *stylep = style;
- return (ISC_R_SUCCESS);
-}
-
-void
-dns_master_styledestroy(dns_master_style_t **stylep, isc_mem_t *mctx) {
- dns_master_style_t *style;
-
- REQUIRE(stylep != NULL && *stylep != NULL);
- style = *stylep;
- *stylep = NULL;
- isc_mem_put(mctx, style, sizeof(*style));
-}
diff --git a/contrib/bind9/lib/dns/message.c b/contrib/bind9/lib/dns/message.c
deleted file mode 100644
index 53efc5a1beb5..000000000000
--- a/contrib/bind9/lib/dns/message.c
+++ /dev/null
@@ -1,3552 +0,0 @@
-/*
- * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/*! \file */
-
-/***
- *** Imports
- ***/
-
-#include <config.h>
-#include <ctype.h>
-
-#include <isc/buffer.h>
-#include <isc/mem.h>
-#include <isc/print.h>
-#include <isc/string.h> /* Required for HP/UX (and others?) */
-#include <isc/util.h>
-
-#include <dns/dnssec.h>
-#include <dns/keyvalues.h>
-#include <dns/log.h>
-#include <dns/masterdump.h>
-#include <dns/message.h>
-#include <dns/opcode.h>
-#include <dns/rdata.h>
-#include <dns/rdatalist.h>
-#include <dns/rdataset.h>
-#include <dns/rdatastruct.h>
-#include <dns/result.h>
-#include <dns/tsig.h>
-#include <dns/view.h>
-
-#ifdef SKAN_MSG_DEBUG
-static void
-hexdump(const char *msg, const char *msg2, void *base, size_t len) {
- unsigned char *p;
- unsigned int cnt;
-
- p = base;
- cnt = 0;
-
- printf("*** %s [%s] (%u bytes @ %p)\n", msg, msg2, len, base);
-
- while (cnt < len) {
- if (cnt % 16 == 0)
- printf("%p: ", p);
- else if (cnt % 8 == 0)
- printf(" |");
- printf(" %02x %c", *p, (isprint(*p) ? *p : ' '));
- p++;
- cnt++;
-
- if (cnt % 16 == 0)
- printf("\n");
- }
-
- if (cnt % 16 != 0)
- printf("\n");
-}
-#endif
-
-#define DNS_MESSAGE_OPCODE_MASK 0x7800U
-#define DNS_MESSAGE_OPCODE_SHIFT 11
-#define DNS_MESSAGE_RCODE_MASK 0x000fU
-#define DNS_MESSAGE_FLAG_MASK 0x8ff0U
-#define DNS_MESSAGE_EDNSRCODE_MASK 0xff000000U
-#define DNS_MESSAGE_EDNSRCODE_SHIFT 24
-#define DNS_MESSAGE_EDNSVERSION_MASK 0x00ff0000U
-#define DNS_MESSAGE_EDNSVERSION_SHIFT 16
-
-#define VALID_NAMED_SECTION(s) (((s) > DNS_SECTION_ANY) \
- && ((s) < DNS_SECTION_MAX))
-#define VALID_SECTION(s) (((s) >= DNS_SECTION_ANY) \
- && ((s) < DNS_SECTION_MAX))
-#define ADD_STRING(b, s) {if (strlen(s) >= \
- isc_buffer_availablelength(b)) \
- return(ISC_R_NOSPACE); else \
- isc_buffer_putstr(b, s);}
-#define VALID_PSEUDOSECTION(s) (((s) >= DNS_PSEUDOSECTION_ANY) \
- && ((s) < DNS_PSEUDOSECTION_MAX))
-
-#define OPTOUT(x) (((x)->attributes & DNS_RDATASETATTR_OPTOUT) != 0)
-
-/*%
- * This is the size of each individual scratchpad buffer, and the numbers
- * of various block allocations used within the server.
- * XXXMLG These should come from a config setting.
- */
-#define SCRATCHPAD_SIZE 512
-#define NAME_COUNT 8
-#define OFFSET_COUNT 4
-#define RDATA_COUNT 8
-#define RDATALIST_COUNT 8
-#define RDATASET_COUNT RDATALIST_COUNT
-
-/*%
- * Text representation of the different items, for message_totext
- * functions.
- */
-static const char *sectiontext[] = {
- "QUESTION",
- "ANSWER",
- "AUTHORITY",
- "ADDITIONAL"
-};
-
-static const char *updsectiontext[] = {
- "ZONE",
- "PREREQUISITE",
- "UPDATE",
- "ADDITIONAL"
-};
-
-static const char *opcodetext[] = {
- "QUERY",
- "IQUERY",
- "STATUS",
- "RESERVED3",
- "NOTIFY",
- "UPDATE",
- "RESERVED6",
- "RESERVED7",
- "RESERVED8",
- "RESERVED9",
- "RESERVED10",
- "RESERVED11",
- "RESERVED12",
- "RESERVED13",
- "RESERVED14",
- "RESERVED15"
-};
-
-static const char *rcodetext[] = {
- "NOERROR",
- "FORMERR",
- "SERVFAIL",
- "NXDOMAIN",
- "NOTIMP",
- "REFUSED",
- "YXDOMAIN",
- "YXRRSET",
- "NXRRSET",
- "NOTAUTH",
- "NOTZONE",
- "RESERVED11",
- "RESERVED12",
- "RESERVED13",
- "RESERVED14",
- "RESERVED15",
- "BADVERS"
-};
-
-
-/*%
- * "helper" type, which consists of a block of some type, and is linkable.
- * For it to work, sizeof(dns_msgblock_t) must be a multiple of the pointer
- * size, or the allocated elements will not be aligned correctly.
- */
-struct dns_msgblock {
- unsigned int count;
- unsigned int remaining;
- ISC_LINK(dns_msgblock_t) link;
-}; /* dynamically sized */
-
-static inline dns_msgblock_t *
-msgblock_allocate(isc_mem_t *, unsigned int, unsigned int);
-
-#define msgblock_get(block, type) \
- ((type *)msgblock_internalget(block, sizeof(type)))
-
-static inline void *
-msgblock_internalget(dns_msgblock_t *, unsigned int);
-
-static inline void
-msgblock_reset(dns_msgblock_t *);
-
-static inline void
-msgblock_free(isc_mem_t *, dns_msgblock_t *, unsigned int);
-
-/*
- * Allocate a new dns_msgblock_t, and return a pointer to it. If no memory
- * is free, return NULL.
- */
-static inline dns_msgblock_t *
-msgblock_allocate(isc_mem_t *mctx, unsigned int sizeof_type,
- unsigned int count)
-{
- dns_msgblock_t *block;
- unsigned int length;
-
- length = sizeof(dns_msgblock_t) + (sizeof_type * count);
-
- block = isc_mem_get(mctx, length);
- if (block == NULL)
- return (NULL);
-
- block->count = count;
- block->remaining = count;
-
- ISC_LINK_INIT(block, link);
-
- return (block);
-}
-
-/*
- * Return an element from the msgblock. If no more are available, return
- * NULL.
- */
-static inline void *
-msgblock_internalget(dns_msgblock_t *block, unsigned int sizeof_type) {
- void *ptr;
-
- if (block == NULL || block->remaining == 0)
- return (NULL);
-
- block->remaining--;
-
- ptr = (((unsigned char *)block)
- + sizeof(dns_msgblock_t)
- + (sizeof_type * block->remaining));
-
- return (ptr);
-}
-
-static inline void
-msgblock_reset(dns_msgblock_t *block) {
- block->remaining = block->count;
-}
-
-/*
- * Release memory associated with a message block.
- */
-static inline void
-msgblock_free(isc_mem_t *mctx, dns_msgblock_t *block, unsigned int sizeof_type)
-{
- unsigned int length;
-
- length = sizeof(dns_msgblock_t) + (sizeof_type * block->count);
-
- isc_mem_put(mctx, block, length);
-}
-
-/*
- * Allocate a new dynamic buffer, and attach it to this message as the
- * "current" buffer. (which is always the last on the list, for our
- * uses)
- */
-static inline isc_result_t
-newbuffer(dns_message_t *msg, unsigned int size) {
- isc_result_t result;
- isc_buffer_t *dynbuf;
-
- dynbuf = NULL;
- result = isc_buffer_allocate(msg->mctx, &dynbuf, size);
- if (result != ISC_R_SUCCESS)
- return (ISC_R_NOMEMORY);
-
- ISC_LIST_APPEND(msg->scratchpad, dynbuf, link);
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_buffer_t *
-currentbuffer(dns_message_t *msg) {
- isc_buffer_t *dynbuf;
-
- dynbuf = ISC_LIST_TAIL(msg->scratchpad);
- INSIST(dynbuf != NULL);
-
- return (dynbuf);
-}
-
-static inline void
-releaserdata(dns_message_t *msg, dns_rdata_t *rdata) {
- ISC_LIST_PREPEND(msg->freerdata, rdata, link);
-}
-
-static inline dns_rdata_t *
-newrdata(dns_message_t *msg) {
- dns_msgblock_t *msgblock;
- dns_rdata_t *rdata;
-
- rdata = ISC_LIST_HEAD(msg->freerdata);
- if (rdata != NULL) {
- ISC_LIST_UNLINK(msg->freerdata, rdata, link);
- return (rdata);
- }
-
- msgblock = ISC_LIST_TAIL(msg->rdatas);
- rdata = msgblock_get(msgblock, dns_rdata_t);
- if (rdata == NULL) {
- msgblock = msgblock_allocate(msg->mctx, sizeof(dns_rdata_t),
- RDATA_COUNT);
- if (msgblock == NULL)
- return (NULL);
-
- ISC_LIST_APPEND(msg->rdatas, msgblock, link);
-
- rdata = msgblock_get(msgblock, dns_rdata_t);
- }
-
- dns_rdata_init(rdata);
- return (rdata);
-}
-
-static inline void
-releaserdatalist(dns_message_t *msg, dns_rdatalist_t *rdatalist) {
- ISC_LIST_PREPEND(msg->freerdatalist, rdatalist, link);
-}
-
-static inline dns_rdatalist_t *
-newrdatalist(dns_message_t *msg) {
- dns_msgblock_t *msgblock;
- dns_rdatalist_t *rdatalist;
-
- rdatalist = ISC_LIST_HEAD(msg->freerdatalist);
- if (rdatalist != NULL) {
- ISC_LIST_UNLINK(msg->freerdatalist, rdatalist, link);
- return (rdatalist);
- }
-
- msgblock = ISC_LIST_TAIL(msg->rdatalists);
- rdatalist = msgblock_get(msgblock, dns_rdatalist_t);
- if (rdatalist == NULL) {
- msgblock = msgblock_allocate(msg->mctx,
- sizeof(dns_rdatalist_t),
- RDATALIST_COUNT);
- if (msgblock == NULL)
- return (NULL);
-
- ISC_LIST_APPEND(msg->rdatalists, msgblock, link);
-
- rdatalist = msgblock_get(msgblock, dns_rdatalist_t);
- }
-
- return (rdatalist);
-}
-
-static inline dns_offsets_t *
-newoffsets(dns_message_t *msg) {
- dns_msgblock_t *msgblock;
- dns_offsets_t *offsets;
-
- msgblock = ISC_LIST_TAIL(msg->offsets);
- offsets = msgblock_get(msgblock, dns_offsets_t);
- if (offsets == NULL) {
- msgblock = msgblock_allocate(msg->mctx,
- sizeof(dns_offsets_t),
- OFFSET_COUNT);
- if (msgblock == NULL)
- return (NULL);
-
- ISC_LIST_APPEND(msg->offsets, msgblock, link);
-
- offsets = msgblock_get(msgblock, dns_offsets_t);
- }
-
- return (offsets);
-}
-
-static inline void
-msginitheader(dns_message_t *m) {
- m->id = 0;
- m->flags = 0;
- m->rcode = 0;
- m->opcode = 0;
- m->rdclass = 0;
-}
-
-static inline void
-msginitprivate(dns_message_t *m) {
- unsigned int i;
-
- for (i = 0; i < DNS_SECTION_MAX; i++) {
- m->cursors[i] = NULL;
- m->counts[i] = 0;
- }
- m->opt = NULL;
- m->sig0 = NULL;
- m->sig0name = NULL;
- m->tsig = NULL;
- m->tsigname = NULL;
- m->state = DNS_SECTION_ANY; /* indicate nothing parsed or rendered */
- m->opt_reserved = 0;
- m->sig_reserved = 0;
- m->reserved = 0;
- m->buffer = NULL;
-}
-
-static inline void
-msginittsig(dns_message_t *m) {
- m->tsigstatus = dns_rcode_noerror;
- m->querytsigstatus = dns_rcode_noerror;
- m->tsigkey = NULL;
- m->tsigctx = NULL;
- m->sigstart = -1;
- m->sig0key = NULL;
- m->sig0status = dns_rcode_noerror;
- m->timeadjust = 0;
-}
-
-/*
- * Init elements to default state. Used both when allocating a new element
- * and when resetting one.
- */
-static inline void
-msginit(dns_message_t *m) {
- msginitheader(m);
- msginitprivate(m);
- msginittsig(m);
- m->header_ok = 0;
- m->question_ok = 0;
- m->tcp_continuation = 0;
- m->verified_sig = 0;
- m->verify_attempted = 0;
- m->order = NULL;
- m->order_arg = NULL;
- m->query.base = NULL;
- m->query.length = 0;
- m->free_query = 0;
- m->saved.base = NULL;
- m->saved.length = 0;
- m->free_saved = 0;
- m->querytsig = NULL;
-}
-
-static inline void
-msgresetnames(dns_message_t *msg, unsigned int first_section) {
- unsigned int i;
- dns_name_t *name, *next_name;
- dns_rdataset_t *rds, *next_rds;
-
- /*
- * Clean up name lists by calling the rdataset disassociate function.
- */
- for (i = first_section; i < DNS_SECTION_MAX; i++) {
- name = ISC_LIST_HEAD(msg->sections[i]);
- while (name != NULL) {
- next_name = ISC_LIST_NEXT(name, link);
- ISC_LIST_UNLINK(msg->sections[i], name, link);
-
- rds = ISC_LIST_HEAD(name->list);
- while (rds != NULL) {
- next_rds = ISC_LIST_NEXT(rds, link);
- ISC_LIST_UNLINK(name->list, rds, link);
-
- INSIST(dns_rdataset_isassociated(rds));
- dns_rdataset_disassociate(rds);
- isc_mempool_put(msg->rdspool, rds);
- rds = next_rds;
- }
- if (dns_name_dynamic(name))
- dns_name_free(name, msg->mctx);
- isc_mempool_put(msg->namepool, name);
- name = next_name;
- }
- }
-}
-
-static void
-msgresetopt(dns_message_t *msg)
-{
- if (msg->opt != NULL) {
- if (msg->opt_reserved > 0) {
- dns_message_renderrelease(msg, msg->opt_reserved);
- msg->opt_reserved = 0;
- }
- INSIST(dns_rdataset_isassociated(msg->opt));
- dns_rdataset_disassociate(msg->opt);
- isc_mempool_put(msg->rdspool, msg->opt);
- msg->opt = NULL;
- }
-}
-
-static void
-msgresetsigs(dns_message_t *msg, isc_boolean_t replying) {
- if (msg->sig_reserved > 0) {
- dns_message_renderrelease(msg, msg->sig_reserved);
- msg->sig_reserved = 0;
- }
- if (msg->tsig != NULL) {
- INSIST(dns_rdataset_isassociated(msg->tsig));
- INSIST(msg->namepool != NULL);
- if (replying) {
- INSIST(msg->querytsig == NULL);
- msg->querytsig = msg->tsig;
- } else {
- dns_rdataset_disassociate(msg->tsig);
- isc_mempool_put(msg->rdspool, msg->tsig);
- if (msg->querytsig != NULL) {
- dns_rdataset_disassociate(msg->querytsig);
- isc_mempool_put(msg->rdspool, msg->querytsig);
- }
- }
- if (dns_name_dynamic(msg->tsigname))
- dns_name_free(msg->tsigname, msg->mctx);
- isc_mempool_put(msg->namepool, msg->tsigname);
- msg->tsig = NULL;
- msg->tsigname = NULL;
- } else if (msg->querytsig != NULL && !replying) {
- dns_rdataset_disassociate(msg->querytsig);
- isc_mempool_put(msg->rdspool, msg->querytsig);
- msg->querytsig = NULL;
- }
- if (msg->sig0 != NULL) {
- INSIST(dns_rdataset_isassociated(msg->sig0));
- dns_rdataset_disassociate(msg->sig0);
- isc_mempool_put(msg->rdspool, msg->sig0);
- if (msg->sig0name != NULL) {
- if (dns_name_dynamic(msg->sig0name))
- dns_name_free(msg->sig0name, msg->mctx);
- isc_mempool_put(msg->namepool, msg->sig0name);
- }
- msg->sig0 = NULL;
- msg->sig0name = NULL;
- }
-}
-
-/*
- * Free all but one (or everything) for this message. This is used by
- * both dns_message_reset() and dns_message_destroy().
- */
-static void
-msgreset(dns_message_t *msg, isc_boolean_t everything) {
- dns_msgblock_t *msgblock, *next_msgblock;
- isc_buffer_t *dynbuf, *next_dynbuf;
- dns_rdata_t *rdata;
- dns_rdatalist_t *rdatalist;
-
- msgresetnames(msg, 0);
- msgresetopt(msg);
- msgresetsigs(msg, ISC_FALSE);
-
- /*
- * Clean up linked lists.
- */
-
- /*
- * Run through the free lists, and just unlink anything found there.
- * The memory isn't lost since these are part of message blocks we
- * have allocated.
- */
- rdata = ISC_LIST_HEAD(msg->freerdata);
- while (rdata != NULL) {
- ISC_LIST_UNLINK(msg->freerdata, rdata, link);
- rdata = ISC_LIST_HEAD(msg->freerdata);
- }
- rdatalist = ISC_LIST_HEAD(msg->freerdatalist);
- while (rdatalist != NULL) {
- ISC_LIST_UNLINK(msg->freerdatalist, rdatalist, link);
- rdatalist = ISC_LIST_HEAD(msg->freerdatalist);
- }
-
- dynbuf = ISC_LIST_HEAD(msg->scratchpad);
- INSIST(dynbuf != NULL);
- if (!everything) {
- isc_buffer_clear(dynbuf);
- dynbuf = ISC_LIST_NEXT(dynbuf, link);
- }
- while (dynbuf != NULL) {
- next_dynbuf = ISC_LIST_NEXT(dynbuf, link);
- ISC_LIST_UNLINK(msg->scratchpad, dynbuf, link);
- isc_buffer_free(&dynbuf);
- dynbuf = next_dynbuf;
- }
-
- msgblock = ISC_LIST_HEAD(msg->rdatas);
- if (!everything && msgblock != NULL) {
- msgblock_reset(msgblock);
- msgblock = ISC_LIST_NEXT(msgblock, link);
- }
- while (msgblock != NULL) {
- next_msgblock = ISC_LIST_NEXT(msgblock, link);
- ISC_LIST_UNLINK(msg->rdatas, msgblock, link);
- msgblock_free(msg->mctx, msgblock, sizeof(dns_rdata_t));
- msgblock = next_msgblock;
- }
-
- /*
- * rdatalists could be empty.
- */
-
- msgblock = ISC_LIST_HEAD(msg->rdatalists);
- if (!everything && msgblock != NULL) {
- msgblock_reset(msgblock);
- msgblock = ISC_LIST_NEXT(msgblock, link);
- }
- while (msgblock != NULL) {
- next_msgblock = ISC_LIST_NEXT(msgblock, link);
- ISC_LIST_UNLINK(msg->rdatalists, msgblock, link);
- msgblock_free(msg->mctx, msgblock, sizeof(dns_rdatalist_t));
- msgblock = next_msgblock;
- }
-
- msgblock = ISC_LIST_HEAD(msg->offsets);
- if (!everything && msgblock != NULL) {
- msgblock_reset(msgblock);
- msgblock = ISC_LIST_NEXT(msgblock, link);
- }
- while (msgblock != NULL) {
- next_msgblock = ISC_LIST_NEXT(msgblock, link);
- ISC_LIST_UNLINK(msg->offsets, msgblock, link);
- msgblock_free(msg->mctx, msgblock, sizeof(dns_offsets_t));
- msgblock = next_msgblock;
- }
-
- if (msg->tsigkey != NULL) {
- dns_tsigkey_detach(&msg->tsigkey);
- msg->tsigkey = NULL;
- }
-
- if (msg->tsigctx != NULL)
- dst_context_destroy(&msg->tsigctx);
-
- if (msg->query.base != NULL) {
- if (msg->free_query != 0)
- isc_mem_put(msg->mctx, msg->query.base,
- msg->query.length);
- msg->query.base = NULL;
- msg->query.length = 0;
- }
-
- if (msg->saved.base != NULL) {
- if (msg->free_saved != 0)
- isc_mem_put(msg->mctx, msg->saved.base,
- msg->saved.length);
- msg->saved.base = NULL;
- msg->saved.length = 0;
- }
-
- /*
- * cleanup the buffer cleanup list
- */
- dynbuf = ISC_LIST_HEAD(msg->cleanup);
- while (dynbuf != NULL) {
- next_dynbuf = ISC_LIST_NEXT(dynbuf, link);
- ISC_LIST_UNLINK(msg->cleanup, dynbuf, link);
- isc_buffer_free(&dynbuf);
- dynbuf = next_dynbuf;
- }
-
- /*
- * Set other bits to normal default values.
- */
- if (!everything)
- msginit(msg);
-
- ENSURE(isc_mempool_getallocated(msg->namepool) == 0);
- ENSURE(isc_mempool_getallocated(msg->rdspool) == 0);
-}
-
-static unsigned int
-spacefortsig(dns_tsigkey_t *key, int otherlen) {
- isc_region_t r1, r2;
- unsigned int x;
- isc_result_t result;
-
- /*
- * The space required for an TSIG record is:
- *
- * n1 bytes for the name
- * 2 bytes for the type
- * 2 bytes for the class
- * 4 bytes for the ttl
- * 2 bytes for the rdlength
- * n2 bytes for the algorithm name
- * 6 bytes for the time signed
- * 2 bytes for the fudge
- * 2 bytes for the MAC size
- * x bytes for the MAC
- * 2 bytes for the original id
- * 2 bytes for the error
- * 2 bytes for the other data length
- * y bytes for the other data (at most)
- * ---------------------------------
- * 26 + n1 + n2 + x + y bytes
- */
-
- dns_name_toregion(&key->name, &r1);
- dns_name_toregion(key->algorithm, &r2);
- if (key->key == NULL)
- x = 0;
- else {
- result = dst_key_sigsize(key->key, &x);
- if (result != ISC_R_SUCCESS)
- x = 0;
- }
- return (26 + r1.length + r2.length + x + otherlen);
-}
-
-isc_result_t
-dns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp)
-{
- dns_message_t *m;
- isc_result_t result;
- isc_buffer_t *dynbuf;
- unsigned int i;
-
- REQUIRE(mctx != NULL);
- REQUIRE(msgp != NULL);
- REQUIRE(*msgp == NULL);
- REQUIRE(intent == DNS_MESSAGE_INTENTPARSE
- || intent == DNS_MESSAGE_INTENTRENDER);
-
- m = isc_mem_get(mctx, sizeof(dns_message_t));
- if (m == NULL)
- return (ISC_R_NOMEMORY);
-
- /*
- * No allocations until further notice. Just initialize all lists
- * and other members that are freed in the cleanup phase here.
- */
-
- m->magic = DNS_MESSAGE_MAGIC;
- m->from_to_wire = intent;
- msginit(m);
-
- for (i = 0; i < DNS_SECTION_MAX; i++)
- ISC_LIST_INIT(m->sections[i]);
-
- m->mctx = NULL;
- isc_mem_attach(mctx, &m->mctx);
-
- ISC_LIST_INIT(m->scratchpad);
- ISC_LIST_INIT(m->cleanup);
- m->namepool = NULL;
- m->rdspool = NULL;
- ISC_LIST_INIT(m->rdatas);
- ISC_LIST_INIT(m->rdatalists);
- ISC_LIST_INIT(m->offsets);
- ISC_LIST_INIT(m->freerdata);
- ISC_LIST_INIT(m->freerdatalist);
-
- /*
- * Ok, it is safe to allocate (and then "goto cleanup" if failure)
- */
-
- result = isc_mempool_create(m->mctx, sizeof(dns_name_t), &m->namepool);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- isc_mempool_setfreemax(m->namepool, NAME_COUNT);
- isc_mempool_setname(m->namepool, "msg:names");
-
- result = isc_mempool_create(m->mctx, sizeof(dns_rdataset_t),
- &m->rdspool);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- isc_mempool_setfreemax(m->rdspool, NAME_COUNT);
- isc_mempool_setname(m->rdspool, "msg:rdataset");
-
- dynbuf = NULL;
- result = isc_buffer_allocate(mctx, &dynbuf, SCRATCHPAD_SIZE);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- ISC_LIST_APPEND(m->scratchpad, dynbuf, link);
-
- m->cctx = NULL;
-
- *msgp = m;
- return (ISC_R_SUCCESS);
-
- /*
- * Cleanup for error returns.
- */
- cleanup:
- dynbuf = ISC_LIST_HEAD(m->scratchpad);
- if (dynbuf != NULL) {
- ISC_LIST_UNLINK(m->scratchpad, dynbuf, link);
- isc_buffer_free(&dynbuf);
- }
- if (m->namepool != NULL)
- isc_mempool_destroy(&m->namepool);
- if (m->rdspool != NULL)
- isc_mempool_destroy(&m->rdspool);
- m->magic = 0;
- isc_mem_putanddetach(&mctx, m, sizeof(dns_message_t));
-
- return (ISC_R_NOMEMORY);
-}
-
-void
-dns_message_reset(dns_message_t *msg, unsigned int intent) {
- REQUIRE(DNS_MESSAGE_VALID(msg));
- REQUIRE(intent == DNS_MESSAGE_INTENTPARSE
- || intent == DNS_MESSAGE_INTENTRENDER);
-
- msgreset(msg, ISC_FALSE);
- msg->from_to_wire = intent;
-}
-
-void
-dns_message_destroy(dns_message_t **msgp) {
- dns_message_t *msg;
-
- REQUIRE(msgp != NULL);
- REQUIRE(DNS_MESSAGE_VALID(*msgp));
-
- msg = *msgp;
- *msgp = NULL;
-
- msgreset(msg, ISC_TRUE);
- isc_mempool_destroy(&msg->namepool);
- isc_mempool_destroy(&msg->rdspool);
- msg->magic = 0;
- isc_mem_putanddetach(&msg->mctx, msg, sizeof(dns_message_t));
-}
-
-static isc_result_t
-findname(dns_name_t **foundname, dns_name_t *target,
- dns_namelist_t *section)
-{
- dns_name_t *curr;
-
- for (curr = ISC_LIST_TAIL(*section);
- curr != NULL;
- curr = ISC_LIST_PREV(curr, link)) {
- if (dns_name_equal(curr, target)) {
- if (foundname != NULL)
- *foundname = curr;
- return (ISC_R_SUCCESS);
- }
- }
-
- return (ISC_R_NOTFOUND);
-}
-
-isc_result_t
-dns_message_find(dns_name_t *name, dns_rdataclass_t rdclass,
- dns_rdatatype_t type, dns_rdatatype_t covers,
- dns_rdataset_t **rdataset)
-{
- dns_rdataset_t *curr;
-
- if (rdataset != NULL) {
- REQUIRE(*rdataset == NULL);
- }
-
- for (curr = ISC_LIST_TAIL(name->list);
- curr != NULL;
- curr = ISC_LIST_PREV(curr, link)) {
- if (curr->rdclass == rdclass &&
- curr->type == type && curr->covers == covers) {
- if (rdataset != NULL)
- *rdataset = curr;
- return (ISC_R_SUCCESS);
- }
- }
-
- return (ISC_R_NOTFOUND);
-}
-
-isc_result_t
-dns_message_findtype(dns_name_t *name, dns_rdatatype_t type,
- dns_rdatatype_t covers, dns_rdataset_t **rdataset)
-{
- dns_rdataset_t *curr;
-
- REQUIRE(name != NULL);
- if (rdataset != NULL) {
- REQUIRE(*rdataset == NULL);
- }
-
- for (curr = ISC_LIST_TAIL(name->list);
- curr != NULL;
- curr = ISC_LIST_PREV(curr, link)) {
- if (curr->type == type && curr->covers == covers) {
- if (rdataset != NULL)
- *rdataset = curr;
- return (ISC_R_SUCCESS);
- }
- }
-
- return (ISC_R_NOTFOUND);
-}
-
-/*
- * Read a name from buffer "source".
- */
-static isc_result_t
-getname(dns_name_t *name, isc_buffer_t *source, dns_message_t *msg,
- dns_decompress_t *dctx)
-{
- isc_buffer_t *scratch;
- isc_result_t result;
- unsigned int tries;
-
- scratch = currentbuffer(msg);
-
- /*
- * First try: use current buffer.
- * Second try: allocate a new buffer and use that.
- */
- tries = 0;
- while (tries < 2) {
- result = dns_name_fromwire(name, source, dctx, ISC_FALSE,
- scratch);
-
- if (result == ISC_R_NOSPACE) {
- tries++;
-
- result = newbuffer(msg, SCRATCHPAD_SIZE);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- scratch = currentbuffer(msg);
- dns_name_reset(name);
- } else {
- return (result);
- }
- }
-
- INSIST(0); /* Cannot get here... */
- return (ISC_R_UNEXPECTED);
-}
-
-static isc_result_t
-getrdata(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
- dns_rdataclass_t rdclass, dns_rdatatype_t rdtype,
- unsigned int rdatalen, dns_rdata_t *rdata)
-{
- isc_buffer_t *scratch;
- isc_result_t result;
- unsigned int tries;
- unsigned int trysize;
-
- scratch = currentbuffer(msg);
-
- isc_buffer_setactive(source, rdatalen);
-
- /*
- * First try: use current buffer.
- * Second try: allocate a new buffer of size
- * max(SCRATCHPAD_SIZE, 2 * compressed_rdatalen)
- * (the data will fit if it was not more than 50% compressed)
- * Subsequent tries: double buffer size on each try.
- */
- tries = 0;
- trysize = 0;
- /* XXX possibly change this to a while (tries < 2) loop */
- for (;;) {
- result = dns_rdata_fromwire(rdata, rdclass, rdtype,
- source, dctx, 0,
- scratch);
-
- if (result == ISC_R_NOSPACE) {
- if (tries == 0) {
- trysize = 2 * rdatalen;
- if (trysize < SCRATCHPAD_SIZE)
- trysize = SCRATCHPAD_SIZE;
- } else {
- INSIST(trysize != 0);
- if (trysize >= 65535)
- return (ISC_R_NOSPACE);
- /* XXX DNS_R_RRTOOLONG? */
- trysize *= 2;
- }
- tries++;
- result = newbuffer(msg, trysize);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- scratch = currentbuffer(msg);
- } else {
- return (result);
- }
- }
-}
-
-#define DO_FORMERR \
- do { \
- if (best_effort) \
- seen_problem = ISC_TRUE; \
- else { \
- result = DNS_R_FORMERR; \
- goto cleanup; \
- } \
- } while (0)
-
-static isc_result_t
-getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
- unsigned int options)
-{
- isc_region_t r;
- unsigned int count;
- dns_name_t *name;
- dns_name_t *name2;
- dns_offsets_t *offsets;
- dns_rdataset_t *rdataset;
- dns_rdatalist_t *rdatalist;
- isc_result_t result;
- dns_rdatatype_t rdtype;
- dns_rdataclass_t rdclass;
- dns_namelist_t *section;
- isc_boolean_t free_name;
- isc_boolean_t best_effort;
- isc_boolean_t seen_problem;
-
- section = &msg->sections[DNS_SECTION_QUESTION];
-
- best_effort = ISC_TF(options & DNS_MESSAGEPARSE_BESTEFFORT);
- seen_problem = ISC_FALSE;
-
- name = NULL;
- rdataset = NULL;
- rdatalist = NULL;
-
- for (count = 0; count < msg->counts[DNS_SECTION_QUESTION]; count++) {
- name = isc_mempool_get(msg->namepool);
- if (name == NULL)
- return (ISC_R_NOMEMORY);
- free_name = ISC_TRUE;
-
- offsets = newoffsets(msg);
- if (offsets == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup;
- }
- dns_name_init(name, *offsets);
-
- /*
- * Parse the name out of this packet.
- */
- isc_buffer_remainingregion(source, &r);
- isc_buffer_setactive(source, r.length);
- result = getname(name, source, msg, dctx);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- /*
- * Run through the section, looking to see if this name
- * is already there. If it is found, put back the allocated
- * name since we no longer need it, and set our name pointer
- * to point to the name we found.
- */
- result = findname(&name2, name, section);
-
- /*
- * If it is the first name in the section, accept it.
- *
- * If it is not, but is not the same as the name already
- * in the question section, append to the section. Note that
- * here in the question section this is illegal, so return
- * FORMERR. In the future, check the opcode to see if
- * this should be legal or not. In either case we no longer
- * need this name pointer.
- */
- if (result != ISC_R_SUCCESS) {
- if (!ISC_LIST_EMPTY(*section))
- DO_FORMERR;
- ISC_LIST_APPEND(*section, name, link);
- free_name = ISC_FALSE;
- } else {
- isc_mempool_put(msg->namepool, name);
- name = name2;
- name2 = NULL;
- free_name = ISC_FALSE;
- }
-
- /*
- * Get type and class.
- */
- isc_buffer_remainingregion(source, &r);
- if (r.length < 4) {
- result = ISC_R_UNEXPECTEDEND;
- goto cleanup;
- }
- rdtype = isc_buffer_getuint16(source);
- rdclass = isc_buffer_getuint16(source);
-
- /*
- * If this class is different than the one we already read,
- * this is an error.
- */
- if (msg->state == DNS_SECTION_ANY) {
- msg->state = DNS_SECTION_QUESTION;
- msg->rdclass = rdclass;
- } else if (msg->rdclass != rdclass)
- DO_FORMERR;
-
- /*
- * Can't ask the same question twice.
- */
- result = dns_message_find(name, rdclass, rdtype, 0, NULL);
- if (result == ISC_R_SUCCESS)
- DO_FORMERR;
-
- /*
- * Allocate a new rdatalist.
- */
- rdatalist = newrdatalist(msg);
- if (rdatalist == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup;
- }
- rdataset = isc_mempool_get(msg->rdspool);
- if (rdataset == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup;
- }
-
- /*
- * Convert rdatalist to rdataset, and attach the latter to
- * the name.
- */
- rdatalist->type = rdtype;
- rdatalist->covers = 0;
- rdatalist->rdclass = rdclass;
- rdatalist->ttl = 0;
- ISC_LIST_INIT(rdatalist->rdata);
-
- dns_rdataset_init(rdataset);
- result = dns_rdatalist_tordataset(rdatalist, rdataset);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- rdataset->attributes |= DNS_RDATASETATTR_QUESTION;
-
- ISC_LIST_APPEND(name->list, rdataset, link);
- rdataset = NULL;
- }
-
- if (seen_problem)
- return (DNS_R_RECOVERABLE);
- return (ISC_R_SUCCESS);
-
- cleanup:
- if (rdataset != NULL) {
- INSIST(!dns_rdataset_isassociated(rdataset));
- isc_mempool_put(msg->rdspool, rdataset);
- }
-#if 0
- if (rdatalist != NULL)
- isc_mempool_put(msg->rdlpool, rdatalist);
-#endif
- if (free_name)
- isc_mempool_put(msg->namepool, name);
-
- return (result);
-}
-
-static isc_boolean_t
-update(dns_section_t section, dns_rdataclass_t rdclass) {
- if (section == DNS_SECTION_PREREQUISITE)
- return (ISC_TF(rdclass == dns_rdataclass_any ||
- rdclass == dns_rdataclass_none));
- if (section == DNS_SECTION_UPDATE)
- return (ISC_TF(rdclass == dns_rdataclass_any));
- return (ISC_FALSE);
-}
-
-static isc_result_t
-getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
- dns_section_t sectionid, unsigned int options)
-{
- isc_region_t r;
- unsigned int count, rdatalen;
- dns_name_t *name;
- dns_name_t *name2;
- dns_offsets_t *offsets;
- dns_rdataset_t *rdataset;
- dns_rdatalist_t *rdatalist;
- isc_result_t result;
- dns_rdatatype_t rdtype, covers;
- dns_rdataclass_t rdclass;
- dns_rdata_t *rdata;
- dns_ttl_t ttl;
- dns_namelist_t *section;
- isc_boolean_t free_name, free_rdataset;
- isc_boolean_t preserve_order, best_effort, seen_problem;
- isc_boolean_t issigzero;
-
- preserve_order = ISC_TF(options & DNS_MESSAGEPARSE_PRESERVEORDER);
- best_effort = ISC_TF(options & DNS_MESSAGEPARSE_BESTEFFORT);
- seen_problem = ISC_FALSE;
-
- for (count = 0; count < msg->counts[sectionid]; count++) {
- int recstart = source->current;
- isc_boolean_t skip_name_search, skip_type_search;
-
- section = &msg->sections[sectionid];
-
- skip_name_search = ISC_FALSE;
- skip_type_search = ISC_FALSE;
- free_rdataset = ISC_FALSE;
-
- name = isc_mempool_get(msg->namepool);
- if (name == NULL)
- return (ISC_R_NOMEMORY);
- free_name = ISC_TRUE;
-
- offsets = newoffsets(msg);
- if (offsets == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup;
- }
- dns_name_init(name, *offsets);
-
- /*
- * Parse the name out of this packet.
- */
- isc_buffer_remainingregion(source, &r);
- isc_buffer_setactive(source, r.length);
- result = getname(name, source, msg, dctx);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- /*
- * Get type, class, ttl, and rdatalen. Verify that at least
- * rdatalen bytes remain. (Some of this is deferred to
- * later.)
- */
- isc_buffer_remainingregion(source, &r);
- if (r.length < 2 + 2 + 4 + 2) {
- result = ISC_R_UNEXPECTEDEND;
- goto cleanup;
- }
- rdtype = isc_buffer_getuint16(source);
- rdclass = isc_buffer_getuint16(source);
-
- /*
- * If there was no question section, we may not yet have
- * established a class. Do so now.
- */
- if (msg->state == DNS_SECTION_ANY &&
- rdtype != dns_rdatatype_opt && /* class is UDP SIZE */
- rdtype != dns_rdatatype_tsig && /* class is ANY */
- rdtype != dns_rdatatype_tkey) { /* class is undefined */
- msg->rdclass = rdclass;
- msg->state = DNS_SECTION_QUESTION;
- }
-
- /*
- * If this class is different than the one in the question
- * section, bail.
- */
- if (msg->opcode != dns_opcode_update
- && rdtype != dns_rdatatype_tsig
- && rdtype != dns_rdatatype_opt
- && rdtype != dns_rdatatype_dnskey /* in a TKEY query */
- && rdtype != dns_rdatatype_sig /* SIG(0) */
- && rdtype != dns_rdatatype_tkey /* Win2000 TKEY */
- && msg->rdclass != dns_rdataclass_any
- && msg->rdclass != rdclass)
- DO_FORMERR;
-
- /*
- * Special type handling for TSIG, OPT, and TKEY.
- */
- if (rdtype == dns_rdatatype_tsig) {
- /*
- * If it is a tsig, verify that it is in the
- * additional data section.
- */
- if (sectionid != DNS_SECTION_ADDITIONAL ||
- rdclass != dns_rdataclass_any ||
- count != msg->counts[sectionid] - 1)
- DO_FORMERR;
- msg->sigstart = recstart;
- skip_name_search = ISC_TRUE;
- skip_type_search = ISC_TRUE;
- } else if (rdtype == dns_rdatatype_opt) {
- /*
- * The name of an OPT record must be ".", it
- * must be in the additional data section, and
- * it must be the first OPT we've seen.
- */
- if (!dns_name_equal(dns_rootname, name) ||
- msg->opt != NULL)
- DO_FORMERR;
- skip_name_search = ISC_TRUE;
- skip_type_search = ISC_TRUE;
- } else if (rdtype == dns_rdatatype_tkey) {
- /*
- * A TKEY must be in the additional section if this
- * is a query, and the answer section if this is a
- * response. Unless it's a Win2000 client.
- *
- * Its class is ignored.
- */
- dns_section_t tkeysection;
-
- if ((msg->flags & DNS_MESSAGEFLAG_QR) == 0)
- tkeysection = DNS_SECTION_ADDITIONAL;
- else
- tkeysection = DNS_SECTION_ANSWER;
- if (sectionid != tkeysection &&
- sectionid != DNS_SECTION_ANSWER)
- DO_FORMERR;
- }
-
- /*
- * ... now get ttl and rdatalen, and check buffer.
- */
- ttl = isc_buffer_getuint32(source);
- rdatalen = isc_buffer_getuint16(source);
- r.length -= (2 + 2 + 4 + 2);
- if (r.length < rdatalen) {
- result = ISC_R_UNEXPECTEDEND;
- goto cleanup;
- }
-
- /*
- * Read the rdata from the wire format. Interpret the
- * rdata according to its actual class, even if it had a
- * DynDNS meta-class in the packet (unless this is a TSIG).
- * Then put the meta-class back into the finished rdata.
- */
- rdata = newrdata(msg);
- if (rdata == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup;
- }
- if (msg->opcode == dns_opcode_update &&
- update(sectionid, rdclass)) {
- if (rdatalen != 0) {
- result = DNS_R_FORMERR;
- goto cleanup;
- }
- /*
- * When the rdata is empty, the data pointer is
- * never dereferenced, but it must still be non-NULL.
- * Casting 1 rather than "" avoids warnings about
- * discarding the const attribute of a string,
- * for compilers that would warn about such things.
- */
- rdata->data = (unsigned char *)1;
- rdata->length = 0;
- rdata->rdclass = rdclass;
- rdata->type = rdtype;
- rdata->flags = DNS_RDATA_UPDATE;
- result = ISC_R_SUCCESS;
- } else if (rdclass == dns_rdataclass_none &&
- msg->opcode == dns_opcode_update &&
- sectionid == DNS_SECTION_UPDATE) {
- result = getrdata(source, msg, dctx, msg->rdclass,
- rdtype, rdatalen, rdata);
- } else
- result = getrdata(source, msg, dctx, rdclass,
- rdtype, rdatalen, rdata);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- rdata->rdclass = rdclass;
- issigzero = ISC_FALSE;
- if (rdtype == dns_rdatatype_rrsig &&
- rdata->flags == 0) {
- covers = dns_rdata_covers(rdata);
- if (covers == 0)
- DO_FORMERR;
- } else if (rdtype == dns_rdatatype_sig /* SIG(0) */ &&
- rdata->flags == 0) {
- covers = dns_rdata_covers(rdata);
- if (covers == 0) {
- if (sectionid != DNS_SECTION_ADDITIONAL ||
- count != msg->counts[sectionid] - 1)
- DO_FORMERR;
- msg->sigstart = recstart;
- skip_name_search = ISC_TRUE;
- skip_type_search = ISC_TRUE;
- issigzero = ISC_TRUE;
- }
- } else
- covers = 0;
-
- /*
- * If we are doing a dynamic update or this is a meta-type,
- * don't bother searching for a name, just append this one
- * to the end of the message.
- */
- if (preserve_order || msg->opcode == dns_opcode_update ||
- skip_name_search) {
- if (rdtype != dns_rdatatype_opt &&
- rdtype != dns_rdatatype_tsig &&
- !issigzero)
- {
- ISC_LIST_APPEND(*section, name, link);
- free_name = ISC_FALSE;
- }
- } else {
- /*
- * Run through the section, looking to see if this name
- * is already there. If it is found, put back the
- * allocated name since we no longer need it, and set
- * our name pointer to point to the name we found.
- */
- result = findname(&name2, name, section);
-
- /*
- * If it is a new name, append to the section.
- */
- if (result == ISC_R_SUCCESS) {
- isc_mempool_put(msg->namepool, name);
- name = name2;
- } else {
- ISC_LIST_APPEND(*section, name, link);
- }
- free_name = ISC_FALSE;
- }
-
- /*
- * Search name for the particular type and class.
- * Skip this stage if in update mode or this is a meta-type.
- */
- if (preserve_order || msg->opcode == dns_opcode_update ||
- skip_type_search)
- result = ISC_R_NOTFOUND;
- else {
- /*
- * If this is a type that can only occur in
- * the question section, fail.
- */
- if (dns_rdatatype_questiononly(rdtype))
- DO_FORMERR;
-
- rdataset = NULL;
- result = dns_message_find(name, rdclass, rdtype,
- covers, &rdataset);
- }
-
- /*
- * If we found an rdataset that matches, we need to
- * append this rdata to that set. If we did not, we need
- * to create a new rdatalist, store the important bits there,
- * convert it to an rdataset, and link the latter to the name.
- * Yuck. When appending, make certain that the type isn't
- * a singleton type, such as SOA or CNAME.
- *
- * Note that this check will be bypassed when preserving order,
- * the opcode is an update, or the type search is skipped.
- */
- if (result == ISC_R_SUCCESS) {
- if (dns_rdatatype_issingleton(rdtype)) {
- dns_rdata_t *first;
- dns_rdatalist_fromrdataset(rdataset,
- &rdatalist);
- first = ISC_LIST_HEAD(rdatalist->rdata);
- INSIST(first != NULL);
- if (dns_rdata_compare(rdata, first) != 0)
- DO_FORMERR;
- }
- }
-
- if (result == ISC_R_NOTFOUND) {
- rdataset = isc_mempool_get(msg->rdspool);
- if (rdataset == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup;
- }
- free_rdataset = ISC_TRUE;
-
- rdatalist = newrdatalist(msg);
- if (rdatalist == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup;
- }
-
- rdatalist->type = rdtype;
- rdatalist->covers = covers;
- rdatalist->rdclass = rdclass;
- rdatalist->ttl = ttl;
- ISC_LIST_INIT(rdatalist->rdata);
-
- dns_rdataset_init(rdataset);
- RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist,
- rdataset)
- == ISC_R_SUCCESS);
-
- if (rdtype != dns_rdatatype_opt &&
- rdtype != dns_rdatatype_tsig &&
- !issigzero)
- {
- ISC_LIST_APPEND(name->list, rdataset, link);
- free_rdataset = ISC_FALSE;
- }
- }
-
- /*
- * Minimize TTLs.
- *
- * Section 5.2 of RFC2181 says we should drop
- * nonauthoritative rrsets where the TTLs differ, but we
- * currently treat them the as if they were authoritative and
- * minimize them.
- */
- if (ttl != rdataset->ttl) {
- rdataset->attributes |= DNS_RDATASETATTR_TTLADJUSTED;
- if (ttl < rdataset->ttl)
- rdataset->ttl = ttl;
- }
-
- /* Append this rdata to the rdataset. */
- dns_rdatalist_fromrdataset(rdataset, &rdatalist);
- ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
-
- /*
- * If this is an OPT record, remember it. Also, set
- * the extended rcode. Note that msg->opt will only be set
- * if best-effort parsing is enabled.
- */
- if (rdtype == dns_rdatatype_opt && msg->opt == NULL) {
- dns_rcode_t ercode;
-
- msg->opt = rdataset;
- rdataset = NULL;
- free_rdataset = ISC_FALSE;
- ercode = (dns_rcode_t)
- ((msg->opt->ttl & DNS_MESSAGE_EDNSRCODE_MASK)
- >> 20);
- msg->rcode |= ercode;
- isc_mempool_put(msg->namepool, name);
- free_name = ISC_FALSE;
- }
-
- /*
- * If this is an SIG(0) or TSIG record, remember it. Note
- * that msg->sig0 or msg->tsig will only be set if best-effort
- * parsing is enabled.
- */
- if (issigzero && msg->sig0 == NULL) {
- msg->sig0 = rdataset;
- msg->sig0name = name;
- rdataset = NULL;
- free_rdataset = ISC_FALSE;
- free_name = ISC_FALSE;
- } else if (rdtype == dns_rdatatype_tsig && msg->tsig == NULL) {
- msg->tsig = rdataset;
- msg->tsigname = name;
- /* Windows doesn't like TSIG names to be compressed. */
- msg->tsigname->attributes |= DNS_NAMEATTR_NOCOMPRESS;
- rdataset = NULL;
- free_rdataset = ISC_FALSE;
- free_name = ISC_FALSE;
- }
-
- if (seen_problem) {
- if (free_name)
- isc_mempool_put(msg->namepool, name);
- if (free_rdataset)
- isc_mempool_put(msg->rdspool, rdataset);
- free_name = free_rdataset = ISC_FALSE;
- }
- INSIST(free_name == ISC_FALSE);
- INSIST(free_rdataset == ISC_FALSE);
- }
-
- if (seen_problem)
- return (DNS_R_RECOVERABLE);
- return (ISC_R_SUCCESS);
-
- cleanup:
- if (free_name)
- isc_mempool_put(msg->namepool, name);
- if (free_rdataset)
- isc_mempool_put(msg->rdspool, rdataset);
-
- return (result);
-}
-
-isc_result_t
-dns_message_parse(dns_message_t *msg, isc_buffer_t *source,
- unsigned int options)
-{
- isc_region_t r;
- dns_decompress_t dctx;
- isc_result_t ret;
- isc_uint16_t tmpflags;
- isc_buffer_t origsource;
- isc_boolean_t seen_problem;
- isc_boolean_t ignore_tc;
-
- REQUIRE(DNS_MESSAGE_VALID(msg));
- REQUIRE(source != NULL);
- REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTPARSE);
-
- seen_problem = ISC_FALSE;
- ignore_tc = ISC_TF(options & DNS_MESSAGEPARSE_IGNORETRUNCATION);
-
- origsource = *source;
-
- msg->header_ok = 0;
- msg->question_ok = 0;
-
- isc_buffer_remainingregion(source, &r);
- if (r.length < DNS_MESSAGE_HEADERLEN)
- return (ISC_R_UNEXPECTEDEND);
-
- msg->id = isc_buffer_getuint16(source);
- tmpflags = isc_buffer_getuint16(source);
- msg->opcode = ((tmpflags & DNS_MESSAGE_OPCODE_MASK)
- >> DNS_MESSAGE_OPCODE_SHIFT);
- msg->rcode = (dns_rcode_t)(tmpflags & DNS_MESSAGE_RCODE_MASK);
- msg->flags = (tmpflags & DNS_MESSAGE_FLAG_MASK);
- msg->counts[DNS_SECTION_QUESTION] = isc_buffer_getuint16(source);
- msg->counts[DNS_SECTION_ANSWER] = isc_buffer_getuint16(source);
- msg->counts[DNS_SECTION_AUTHORITY] = isc_buffer_getuint16(source);
- msg->counts[DNS_SECTION_ADDITIONAL] = isc_buffer_getuint16(source);
-
- msg->header_ok = 1;
-
- /*
- * -1 means no EDNS.
- */
- dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_ANY);
-
- dns_decompress_setmethods(&dctx, DNS_COMPRESS_GLOBAL14);
-
- ret = getquestions(source, msg, &dctx, options);
- if (ret == ISC_R_UNEXPECTEDEND && ignore_tc)
- goto truncated;
- if (ret == DNS_R_RECOVERABLE) {
- seen_problem = ISC_TRUE;
- ret = ISC_R_SUCCESS;
- }
- if (ret != ISC_R_SUCCESS)
- return (ret);
- msg->question_ok = 1;
-
- ret = getsection(source, msg, &dctx, DNS_SECTION_ANSWER, options);
- if (ret == ISC_R_UNEXPECTEDEND && ignore_tc)
- goto truncated;
- if (ret == DNS_R_RECOVERABLE) {
- seen_problem = ISC_TRUE;
- ret = ISC_R_SUCCESS;
- }
- if (ret != ISC_R_SUCCESS)
- return (ret);
-
- ret = getsection(source, msg, &dctx, DNS_SECTION_AUTHORITY, options);
- if (ret == ISC_R_UNEXPECTEDEND && ignore_tc)
- goto truncated;
- if (ret == DNS_R_RECOVERABLE) {
- seen_problem = ISC_TRUE;
- ret = ISC_R_SUCCESS;
- }
- if (ret != ISC_R_SUCCESS)
- return (ret);
-
- ret = getsection(source, msg, &dctx, DNS_SECTION_ADDITIONAL, options);
- if (ret == ISC_R_UNEXPECTEDEND && ignore_tc)
- goto truncated;
- if (ret == DNS_R_RECOVERABLE) {
- seen_problem = ISC_TRUE;
- ret = ISC_R_SUCCESS;
- }
- if (ret != ISC_R_SUCCESS)
- return (ret);
-
- isc_buffer_remainingregion(source, &r);
- if (r.length != 0) {
- isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL,
- DNS_LOGMODULE_MESSAGE, ISC_LOG_DEBUG(3),
- "message has %u byte(s) of trailing garbage",
- r.length);
- }
-
- truncated:
- if ((options & DNS_MESSAGEPARSE_CLONEBUFFER) == 0)
- isc_buffer_usedregion(&origsource, &msg->saved);
- else {
- msg->saved.length = isc_buffer_usedlength(&origsource);
- msg->saved.base = isc_mem_get(msg->mctx, msg->saved.length);
- if (msg->saved.base == NULL)
- return (ISC_R_NOMEMORY);
- memcpy(msg->saved.base, isc_buffer_base(&origsource),
- msg->saved.length);
- msg->free_saved = 1;
- }
-
- if (ret == ISC_R_UNEXPECTEDEND && ignore_tc)
- return (DNS_R_RECOVERABLE);
- if (seen_problem == ISC_TRUE)
- return (DNS_R_RECOVERABLE);
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_message_renderbegin(dns_message_t *msg, dns_compress_t *cctx,
- isc_buffer_t *buffer)
-{
- isc_region_t r;
-
- REQUIRE(DNS_MESSAGE_VALID(msg));
- REQUIRE(buffer != NULL);
- REQUIRE(msg->buffer == NULL);
- REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
-
- msg->cctx = cctx;
-
- /*
- * Erase the contents of this buffer.
- */
- isc_buffer_clear(buffer);
-
- /*
- * Make certain there is enough for at least the header in this
- * buffer.
- */
- isc_buffer_availableregion(buffer, &r);
- if (r.length < DNS_MESSAGE_HEADERLEN)
- return (ISC_R_NOSPACE);
-
- if (r.length < msg->reserved)
- return (ISC_R_NOSPACE);
-
- /*
- * Reserve enough space for the header in this buffer.
- */
- isc_buffer_add(buffer, DNS_MESSAGE_HEADERLEN);
-
- msg->buffer = buffer;
-
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_message_renderchangebuffer(dns_message_t *msg, isc_buffer_t *buffer) {
- isc_region_t r, rn;
-
- REQUIRE(DNS_MESSAGE_VALID(msg));
- REQUIRE(buffer != NULL);
- REQUIRE(msg->buffer != NULL);
-
- /*
- * Ensure that the new buffer is empty, and has enough space to
- * hold the current contents.
- */
- isc_buffer_clear(buffer);
-
- isc_buffer_availableregion(buffer, &rn);
- isc_buffer_usedregion(msg->buffer, &r);
- REQUIRE(rn.length > r.length);
-
- /*
- * Copy the contents from the old to the new buffer.
- */
- isc_buffer_add(buffer, r.length);
- memcpy(rn.base, r.base, r.length);
-
- msg->buffer = buffer;
-
- return (ISC_R_SUCCESS);
-}
-
-void
-dns_message_renderrelease(dns_message_t *msg, unsigned int space) {
- REQUIRE(DNS_MESSAGE_VALID(msg));
- REQUIRE(space <= msg->reserved);
-
- msg->reserved -= space;
-}
-
-isc_result_t
-dns_message_renderreserve(dns_message_t *msg, unsigned int space) {
- isc_region_t r;
-
- REQUIRE(DNS_MESSAGE_VALID(msg));
-
- if (msg->buffer != NULL) {
- isc_buffer_availableregion(msg->buffer, &r);
- if (r.length < (space + msg->reserved))
- return (ISC_R_NOSPACE);
- }
-
- msg->reserved += space;
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_boolean_t
-wrong_priority(dns_rdataset_t *rds, int pass, dns_rdatatype_t preferred_glue) {
- int pass_needed;
-
- /*
- * If we are not rendering class IN, this ordering is bogus.
- */
- if (rds->rdclass != dns_rdataclass_in)
- return (ISC_FALSE);
-
- switch (rds->type) {
- case dns_rdatatype_a:
- case dns_rdatatype_aaaa:
- if (preferred_glue == rds->type)
- pass_needed = 4;
- else
- pass_needed = 3;
- break;
- case dns_rdatatype_rrsig:
- case dns_rdatatype_dnskey:
- pass_needed = 2;
- break;
- default:
- pass_needed = 1;
- }
-
- if (pass_needed >= pass)
- return (ISC_FALSE);
-
- 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)
-{
- dns_namelist_t *section;
- dns_name_t *name, *next_name;
- dns_rdataset_t *rdataset, *next_rdataset;
- unsigned int count, total;
- isc_result_t result;
- isc_buffer_t st; /* for rollbacks */
- int pass;
- isc_boolean_t partial = ISC_FALSE;
- unsigned int rd_options;
- dns_rdatatype_t preferred_glue = 0;
-
- REQUIRE(DNS_MESSAGE_VALID(msg));
- REQUIRE(msg->buffer != NULL);
- REQUIRE(VALID_NAMED_SECTION(sectionid));
-
- section = &msg->sections[sectionid];
-
- if ((sectionid == DNS_SECTION_ADDITIONAL)
- && (options & DNS_MESSAGERENDER_ORDERED) == 0) {
- if ((options & DNS_MESSAGERENDER_PREFER_A) != 0) {
- preferred_glue = dns_rdatatype_a;
- pass = 4;
- } else if ((options & DNS_MESSAGERENDER_PREFER_AAAA) != 0) {
- preferred_glue = dns_rdatatype_aaaa;
- pass = 4;
- } else
- pass = 3;
- } else
- pass = 1;
-
- if ((options & DNS_MESSAGERENDER_OMITDNSSEC) == 0)
- rd_options = 0;
- else
- rd_options = DNS_RDATASETTOWIRE_OMITDNSSEC;
-
- /*
- * Shrink the space in the buffer by the reserved amount.
- */
- msg->buffer->length -= msg->reserved;
-
- total = 0;
- if (msg->reserved == 0 && (options & DNS_MESSAGERENDER_PARTIAL) != 0)
- partial = ISC_TRUE;
-
- /*
- * Render required glue first. Set TC if it won't fit.
- */
- name = ISC_LIST_HEAD(*section);
- if (name != NULL) {
- rdataset = ISC_LIST_HEAD(name->list);
- if (rdataset != NULL &&
- (rdataset->attributes & DNS_RDATASETATTR_REQUIREDGLUE) != 0 &&
- (rdataset->attributes & DNS_RDATASETATTR_RENDERED) == 0) {
- const void *order_arg = msg->order_arg;
- st = *(msg->buffer);
- count = 0;
- if (partial)
- result = dns_rdataset_towirepartial(rdataset,
- name,
- msg->cctx,
- msg->buffer,
- msg->order,
- order_arg,
- rd_options,
- &count,
- NULL);
- else
- result = dns_rdataset_towiresorted(rdataset,
- name,
- msg->cctx,
- msg->buffer,
- msg->order,
- order_arg,
- rd_options,
- &count);
- total += count;
- if (partial && result == ISC_R_NOSPACE) {
- msg->flags |= DNS_MESSAGEFLAG_TC;
- msg->buffer->length += msg->reserved;
- msg->counts[sectionid] += total;
- return (result);
- }
- if (result == ISC_R_NOSPACE)
- msg->flags |= DNS_MESSAGEFLAG_TC;
- if (result != ISC_R_SUCCESS) {
- INSIST(st.used < 65536);
- dns_compress_rollback(msg->cctx,
- (isc_uint16_t)st.used);
- *(msg->buffer) = st; /* rollback */
- msg->buffer->length += msg->reserved;
- msg->counts[sectionid] += total;
- return (result);
- }
- rdataset->attributes |= DNS_RDATASETATTR_RENDERED;
- }
- }
-
- do {
- name = ISC_LIST_HEAD(*section);
- if (name == NULL) {
- msg->buffer->length += msg->reserved;
- msg->counts[sectionid] += total;
- return (ISC_R_SUCCESS);
- }
-
- while (name != NULL) {
- next_name = ISC_LIST_NEXT(name, link);
-
- rdataset = ISC_LIST_HEAD(name->list);
- while (rdataset != NULL) {
- next_rdataset = ISC_LIST_NEXT(rdataset, link);
-
- if ((rdataset->attributes &
- DNS_RDATASETATTR_RENDERED) != 0)
- goto next;
-
- if (((options & DNS_MESSAGERENDER_ORDERED)
- == 0)
- && (sectionid == DNS_SECTION_ADDITIONAL)
- && wrong_priority(rdataset, pass,
- 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;
- if (partial)
- result = dns_rdataset_towirepartial(
- rdataset,
- name,
- msg->cctx,
- msg->buffer,
- msg->order,
- msg->order_arg,
- rd_options,
- &count,
- NULL);
- else
- result = dns_rdataset_towiresorted(
- rdataset,
- name,
- msg->cctx,
- msg->buffer,
- msg->order,
- msg->order_arg,
- rd_options,
- &count);
-
- total += count;
-
- /*
- * If out of space, record stats on what we
- * rendered so far, and return that status.
- *
- * XXXMLG Need to change this when
- * dns_rdataset_towire() can render partial
- * sets starting at some arbitrary point in the
- * set. This will include setting a bit in the
- * rdataset to indicate that a partial
- * rendering was done, and some state saved
- * somewhere (probably in the message struct)
- * to indicate where to continue from.
- */
- if (partial && result == ISC_R_NOSPACE) {
- msg->buffer->length += msg->reserved;
- msg->counts[sectionid] += total;
- return (result);
- }
- if (result != ISC_R_SUCCESS) {
- INSIST(st.used < 65536);
- dns_compress_rollback(msg->cctx,
- (isc_uint16_t)st.used);
- *(msg->buffer) = st; /* rollback */
- msg->buffer->length += msg->reserved;
- msg->counts[sectionid] += total;
- return (result);
- }
-
- /*
- * If we have rendered non-validated data,
- * ensure that the AD bit is not set.
- */
- if (rdataset->trust != dns_trust_secure &&
- (sectionid == DNS_SECTION_ANSWER ||
- sectionid == DNS_SECTION_AUTHORITY))
- msg->flags &= ~DNS_MESSAGEFLAG_AD;
- if (OPTOUT(rdataset))
- msg->flags &= ~DNS_MESSAGEFLAG_AD;
-
- rdataset->attributes |=
- DNS_RDATASETATTR_RENDERED;
-
- next:
- rdataset = next_rdataset;
- }
-
- name = next_name;
- }
- } while (--pass != 0);
-
- msg->buffer->length += msg->reserved;
- msg->counts[sectionid] += total;
-
- return (ISC_R_SUCCESS);
-}
-
-void
-dns_message_renderheader(dns_message_t *msg, isc_buffer_t *target) {
- isc_uint16_t tmp;
- isc_region_t r;
-
- REQUIRE(DNS_MESSAGE_VALID(msg));
- REQUIRE(target != NULL);
-
- isc_buffer_availableregion(target, &r);
- REQUIRE(r.length >= DNS_MESSAGE_HEADERLEN);
-
- isc_buffer_putuint16(target, msg->id);
-
- tmp = ((msg->opcode << DNS_MESSAGE_OPCODE_SHIFT)
- & DNS_MESSAGE_OPCODE_MASK);
- tmp |= (msg->rcode & DNS_MESSAGE_RCODE_MASK);
- tmp |= (msg->flags & DNS_MESSAGE_FLAG_MASK);
-
- INSIST(msg->counts[DNS_SECTION_QUESTION] < 65536 &&
- msg->counts[DNS_SECTION_ANSWER] < 65536 &&
- msg->counts[DNS_SECTION_AUTHORITY] < 65536 &&
- msg->counts[DNS_SECTION_ADDITIONAL] < 65536);
-
- isc_buffer_putuint16(target, tmp);
- isc_buffer_putuint16(target,
- (isc_uint16_t)msg->counts[DNS_SECTION_QUESTION]);
- isc_buffer_putuint16(target,
- (isc_uint16_t)msg->counts[DNS_SECTION_ANSWER]);
- isc_buffer_putuint16(target,
- (isc_uint16_t)msg->counts[DNS_SECTION_AUTHORITY]);
- isc_buffer_putuint16(target,
- (isc_uint16_t)msg->counts[DNS_SECTION_ADDITIONAL]);
-}
-
-isc_result_t
-dns_message_renderend(dns_message_t *msg) {
- isc_buffer_t tmpbuf;
- isc_region_t r;
- int result;
- unsigned int count;
-
- REQUIRE(DNS_MESSAGE_VALID(msg));
- REQUIRE(msg->buffer != NULL);
-
- if ((msg->rcode & ~DNS_MESSAGE_RCODE_MASK) != 0 && msg->opt == NULL) {
- /*
- * We have an extended rcode but are not using EDNS.
- */
- return (DNS_R_FORMERR);
- }
-
- /*
- * If we're adding a OPT, TSIG or SIG(0) to a truncated message,
- * clear all rdatasets from the message except for the question
- * before adding the OPT, TSIG or SIG(0). If the question doesn't
- * fit, don't include it.
- */
- if ((msg->tsigkey != NULL || msg->sig0key != NULL || msg->opt) &&
- (msg->flags & DNS_MESSAGEFLAG_TC) != 0)
- {
- isc_buffer_t *buf;
-
- msgresetnames(msg, DNS_SECTION_ANSWER);
- buf = msg->buffer;
- dns_message_renderreset(msg);
- msg->buffer = buf;
- isc_buffer_clear(msg->buffer);
- isc_buffer_add(msg->buffer, DNS_MESSAGE_HEADERLEN);
- dns_compress_rollback(msg->cctx, 0);
- result = dns_message_rendersection(msg, DNS_SECTION_QUESTION,
- 0);
- if (result != ISC_R_SUCCESS && result != ISC_R_NOSPACE)
- return (result);
- }
-
- /*
- * If we've got an OPT record, render it.
- */
- if (msg->opt != NULL) {
- dns_message_renderrelease(msg, msg->opt_reserved);
- msg->opt_reserved = 0;
- /*
- * Set the extended rcode.
- */
- msg->opt->ttl &= ~DNS_MESSAGE_EDNSRCODE_MASK;
- msg->opt->ttl |= ((msg->rcode << 20) &
- DNS_MESSAGE_EDNSRCODE_MASK);
- /*
- * Render.
- */
- count = 0;
- result = dns_rdataset_towire(msg->opt, dns_rootname,
- msg->cctx, msg->buffer, 0,
- &count);
- msg->counts[DNS_SECTION_ADDITIONAL] += count;
- if (result != ISC_R_SUCCESS)
- return (result);
- }
-
- /*
- * If we're adding a TSIG record, generate and render it.
- */
- if (msg->tsigkey != NULL) {
- dns_message_renderrelease(msg, msg->sig_reserved);
- msg->sig_reserved = 0;
- result = dns_tsig_sign(msg);
- if (result != ISC_R_SUCCESS)
- return (result);
- count = 0;
- result = dns_rdataset_towire(msg->tsig, msg->tsigname,
- msg->cctx, msg->buffer, 0,
- &count);
- msg->counts[DNS_SECTION_ADDITIONAL] += count;
- if (result != ISC_R_SUCCESS)
- return (result);
- }
-
- /*
- * If we're adding a SIG(0) record, generate and render it.
- */
- if (msg->sig0key != NULL) {
- dns_message_renderrelease(msg, msg->sig_reserved);
- msg->sig_reserved = 0;
- result = dns_dnssec_signmessage(msg, msg->sig0key);
- if (result != ISC_R_SUCCESS)
- return (result);
- count = 0;
- /*
- * Note: dns_rootname is used here, not msg->sig0name, since
- * the owner name of a SIG(0) is irrelevant, and will not
- * be set in a message being rendered.
- */
- result = dns_rdataset_towire(msg->sig0, dns_rootname,
- msg->cctx, msg->buffer, 0,
- &count);
- msg->counts[DNS_SECTION_ADDITIONAL] += count;
- if (result != ISC_R_SUCCESS)
- return (result);
- }
-
- isc_buffer_usedregion(msg->buffer, &r);
- isc_buffer_init(&tmpbuf, r.base, r.length);
-
- dns_message_renderheader(msg, &tmpbuf);
-
- msg->buffer = NULL; /* forget about this buffer only on success XXX */
-
- return (ISC_R_SUCCESS);
-}
-
-void
-dns_message_renderreset(dns_message_t *msg) {
- unsigned int i;
- dns_name_t *name;
- dns_rdataset_t *rds;
-
- /*
- * Reset the message so that it may be rendered again.
- */
-
- REQUIRE(DNS_MESSAGE_VALID(msg));
- REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
-
- msg->buffer = NULL;
-
- for (i = 0; i < DNS_SECTION_MAX; i++) {
- msg->cursors[i] = NULL;
- msg->counts[i] = 0;
- for (name = ISC_LIST_HEAD(msg->sections[i]);
- name != NULL;
- name = ISC_LIST_NEXT(name, link)) {
- for (rds = ISC_LIST_HEAD(name->list);
- rds != NULL;
- rds = ISC_LIST_NEXT(rds, link)) {
- rds->attributes &= ~DNS_RDATASETATTR_RENDERED;
- }
- }
- }
- if (msg->tsigname != NULL)
- dns_message_puttempname(msg, &msg->tsigname);
- if (msg->tsig != NULL) {
- dns_rdataset_disassociate(msg->tsig);
- dns_message_puttemprdataset(msg, &msg->tsig);
- }
- if (msg->sig0 != NULL) {
- dns_rdataset_disassociate(msg->sig0);
- dns_message_puttemprdataset(msg, &msg->sig0);
- }
-}
-
-isc_result_t
-dns_message_firstname(dns_message_t *msg, dns_section_t section) {
- REQUIRE(DNS_MESSAGE_VALID(msg));
- REQUIRE(VALID_NAMED_SECTION(section));
-
- msg->cursors[section] = ISC_LIST_HEAD(msg->sections[section]);
-
- if (msg->cursors[section] == NULL)
- return (ISC_R_NOMORE);
-
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_message_nextname(dns_message_t *msg, dns_section_t section) {
- REQUIRE(DNS_MESSAGE_VALID(msg));
- REQUIRE(VALID_NAMED_SECTION(section));
- REQUIRE(msg->cursors[section] != NULL);
-
- msg->cursors[section] = ISC_LIST_NEXT(msg->cursors[section], link);
-
- if (msg->cursors[section] == NULL)
- return (ISC_R_NOMORE);
-
- return (ISC_R_SUCCESS);
-}
-
-void
-dns_message_currentname(dns_message_t *msg, dns_section_t section,
- dns_name_t **name)
-{
- REQUIRE(DNS_MESSAGE_VALID(msg));
- REQUIRE(VALID_NAMED_SECTION(section));
- REQUIRE(name != NULL && *name == NULL);
- REQUIRE(msg->cursors[section] != NULL);
-
- *name = msg->cursors[section];
-}
-
-isc_result_t
-dns_message_findname(dns_message_t *msg, dns_section_t section,
- dns_name_t *target, dns_rdatatype_t type,
- dns_rdatatype_t covers, dns_name_t **name,
- dns_rdataset_t **rdataset)
-{
- dns_name_t *foundname;
- isc_result_t result;
-
- /*
- * XXX These requirements are probably too intensive, especially
- * where things can be NULL, but as they are they ensure that if
- * something is NON-NULL, indicating that the caller expects it
- * to be filled in, that we can in fact fill it in.
- */
- REQUIRE(msg != NULL);
- REQUIRE(VALID_SECTION(section));
- REQUIRE(target != NULL);
- if (name != NULL)
- REQUIRE(*name == NULL);
- if (type == dns_rdatatype_any) {
- REQUIRE(rdataset == NULL);
- } else {
- if (rdataset != NULL)
- REQUIRE(*rdataset == NULL);
- }
-
- result = findname(&foundname, target,
- &msg->sections[section]);
-
- if (result == ISC_R_NOTFOUND)
- return (DNS_R_NXDOMAIN);
- else if (result != ISC_R_SUCCESS)
- return (result);
-
- if (name != NULL)
- *name = foundname;
-
- /*
- * And now look for the type.
- */
- if (type == dns_rdatatype_any)
- return (ISC_R_SUCCESS);
-
- result = dns_message_findtype(foundname, type, covers, rdataset);
- if (result == ISC_R_NOTFOUND)
- return (DNS_R_NXRRSET);
-
- return (result);
-}
-
-void
-dns_message_movename(dns_message_t *msg, dns_name_t *name,
- dns_section_t fromsection,
- dns_section_t tosection)
-{
- REQUIRE(msg != NULL);
- REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
- REQUIRE(name != NULL);
- REQUIRE(VALID_NAMED_SECTION(fromsection));
- REQUIRE(VALID_NAMED_SECTION(tosection));
-
- /*
- * Unlink the name from the old section
- */
- ISC_LIST_UNLINK(msg->sections[fromsection], name, link);
- ISC_LIST_APPEND(msg->sections[tosection], name, link);
-}
-
-void
-dns_message_addname(dns_message_t *msg, dns_name_t *name,
- dns_section_t section)
-{
- REQUIRE(msg != NULL);
- REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
- REQUIRE(name != NULL);
- REQUIRE(VALID_NAMED_SECTION(section));
-
- ISC_LIST_APPEND(msg->sections[section], name, link);
-}
-
-void
-dns_message_removename(dns_message_t *msg, dns_name_t *name,
- dns_section_t section)
-{
- REQUIRE(msg != NULL);
- REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
- REQUIRE(name != NULL);
- REQUIRE(VALID_NAMED_SECTION(section));
-
- ISC_LIST_UNLINK(msg->sections[section], name, link);
-}
-
-isc_result_t
-dns_message_gettempname(dns_message_t *msg, dns_name_t **item) {
- REQUIRE(DNS_MESSAGE_VALID(msg));
- REQUIRE(item != NULL && *item == NULL);
-
- *item = isc_mempool_get(msg->namepool);
- if (*item == NULL)
- return (ISC_R_NOMEMORY);
- dns_name_init(*item, NULL);
-
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_message_gettempoffsets(dns_message_t *msg, dns_offsets_t **item) {
- REQUIRE(DNS_MESSAGE_VALID(msg));
- REQUIRE(item != NULL && *item == NULL);
-
- *item = newoffsets(msg);
- if (*item == NULL)
- return (ISC_R_NOMEMORY);
-
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_message_gettemprdata(dns_message_t *msg, dns_rdata_t **item) {
- REQUIRE(DNS_MESSAGE_VALID(msg));
- REQUIRE(item != NULL && *item == NULL);
-
- *item = newrdata(msg);
- if (*item == NULL)
- return (ISC_R_NOMEMORY);
-
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_message_gettemprdataset(dns_message_t *msg, dns_rdataset_t **item) {
- REQUIRE(DNS_MESSAGE_VALID(msg));
- REQUIRE(item != NULL && *item == NULL);
-
- *item = isc_mempool_get(msg->rdspool);
- if (*item == NULL)
- return (ISC_R_NOMEMORY);
-
- dns_rdataset_init(*item);
-
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_message_gettemprdatalist(dns_message_t *msg, dns_rdatalist_t **item) {
- REQUIRE(DNS_MESSAGE_VALID(msg));
- REQUIRE(item != NULL && *item == NULL);
-
- *item = newrdatalist(msg);
- if (*item == NULL)
- return (ISC_R_NOMEMORY);
-
- return (ISC_R_SUCCESS);
-}
-
-void
-dns_message_puttempname(dns_message_t *msg, dns_name_t **item) {
- REQUIRE(DNS_MESSAGE_VALID(msg));
- REQUIRE(item != NULL && *item != NULL);
-
- if (dns_name_dynamic(*item))
- dns_name_free(*item, msg->mctx);
- isc_mempool_put(msg->namepool, *item);
- *item = NULL;
-}
-
-void
-dns_message_puttemprdata(dns_message_t *msg, dns_rdata_t **item) {
- REQUIRE(DNS_MESSAGE_VALID(msg));
- REQUIRE(item != NULL && *item != NULL);
-
- releaserdata(msg, *item);
- *item = NULL;
-}
-
-void
-dns_message_puttemprdataset(dns_message_t *msg, dns_rdataset_t **item) {
- REQUIRE(DNS_MESSAGE_VALID(msg));
- REQUIRE(item != NULL && *item != NULL);
-
- REQUIRE(!dns_rdataset_isassociated(*item));
- isc_mempool_put(msg->rdspool, *item);
- *item = NULL;
-}
-
-void
-dns_message_puttemprdatalist(dns_message_t *msg, dns_rdatalist_t **item) {
- REQUIRE(DNS_MESSAGE_VALID(msg));
- REQUIRE(item != NULL && *item != NULL);
-
- releaserdatalist(msg, *item);
- *item = NULL;
-}
-
-isc_result_t
-dns_message_peekheader(isc_buffer_t *source, dns_messageid_t *idp,
- unsigned int *flagsp)
-{
- isc_region_t r;
- isc_buffer_t buffer;
- dns_messageid_t id;
- unsigned int flags;
-
- REQUIRE(source != NULL);
-
- buffer = *source;
-
- isc_buffer_remainingregion(&buffer, &r);
- if (r.length < DNS_MESSAGE_HEADERLEN)
- return (ISC_R_UNEXPECTEDEND);
-
- id = isc_buffer_getuint16(&buffer);
- flags = isc_buffer_getuint16(&buffer);
- flags &= DNS_MESSAGE_FLAG_MASK;
-
- if (flagsp != NULL)
- *flagsp = flags;
- if (idp != NULL)
- *idp = id;
-
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_message_reply(dns_message_t *msg, isc_boolean_t want_question_section) {
- unsigned int clear_after;
- isc_result_t result;
-
- REQUIRE(DNS_MESSAGE_VALID(msg));
- REQUIRE((msg->flags & DNS_MESSAGEFLAG_QR) == 0);
-
- if (!msg->header_ok)
- return (DNS_R_FORMERR);
- if (msg->opcode != dns_opcode_query &&
- msg->opcode != dns_opcode_notify)
- want_question_section = ISC_FALSE;
- if (msg->opcode == dns_opcode_update)
- clear_after = DNS_SECTION_PREREQUISITE;
- else if (want_question_section) {
- if (!msg->question_ok)
- return (DNS_R_FORMERR);
- clear_after = DNS_SECTION_ANSWER;
- } else
- clear_after = DNS_SECTION_QUESTION;
- msg->from_to_wire = DNS_MESSAGE_INTENTRENDER;
- msgresetnames(msg, clear_after);
- msgresetopt(msg);
- msgresetsigs(msg, ISC_TRUE);
- msginitprivate(msg);
- /*
- * We now clear most flags and then set QR, ensuring that the
- * reply's flags will be in a reasonable state.
- */
- msg->flags &= DNS_MESSAGE_REPLYPRESERVE;
- msg->flags |= DNS_MESSAGEFLAG_QR;
-
- /*
- * This saves the query TSIG status, if the query was signed, and
- * reserves space in the reply for the TSIG.
- */
- if (msg->tsigkey != NULL) {
- unsigned int otherlen = 0;
- msg->querytsigstatus = msg->tsigstatus;
- msg->tsigstatus = dns_rcode_noerror;
- if (msg->querytsigstatus == dns_tsigerror_badtime)
- otherlen = 6;
- msg->sig_reserved = spacefortsig(msg->tsigkey, otherlen);
- result = dns_message_renderreserve(msg, msg->sig_reserved);
- if (result != ISC_R_SUCCESS) {
- msg->sig_reserved = 0;
- return (result);
- }
- }
- if (msg->saved.base != NULL) {
- msg->query.base = msg->saved.base;
- msg->query.length = msg->saved.length;
- msg->free_query = msg->free_saved;
- msg->saved.base = NULL;
- msg->saved.length = 0;
- msg->free_saved = 0;
- }
-
- return (ISC_R_SUCCESS);
-}
-
-dns_rdataset_t *
-dns_message_getopt(dns_message_t *msg) {
-
- /*
- * Get the OPT record for 'msg'.
- */
-
- REQUIRE(DNS_MESSAGE_VALID(msg));
-
- return (msg->opt);
-}
-
-isc_result_t
-dns_message_setopt(dns_message_t *msg, dns_rdataset_t *opt) {
- isc_result_t result;
- dns_rdata_t rdata = DNS_RDATA_INIT;
-
- /*
- * Set the OPT record for 'msg'.
- */
-
- /*
- * The space required for an OPT record is:
- *
- * 1 byte for the name
- * 2 bytes for the type
- * 2 bytes for the class
- * 4 bytes for the ttl
- * 2 bytes for the rdata length
- * ---------------------------------
- * 11 bytes
- *
- * plus the length of the rdata.
- */
-
- REQUIRE(DNS_MESSAGE_VALID(msg));
- REQUIRE(opt->type == dns_rdatatype_opt);
- REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
- REQUIRE(msg->state == DNS_SECTION_ANY);
-
- msgresetopt(msg);
-
- result = dns_rdataset_first(opt);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- dns_rdataset_current(opt, &rdata);
- msg->opt_reserved = 11 + rdata.length;
- result = dns_message_renderreserve(msg, msg->opt_reserved);
- if (result != ISC_R_SUCCESS) {
- msg->opt_reserved = 0;
- goto cleanup;
- }
-
- msg->opt = opt;
-
- return (ISC_R_SUCCESS);
-
- cleanup:
- dns_rdataset_disassociate(opt);
- dns_message_puttemprdataset(msg, &opt);
- return (result);
-}
-
-dns_rdataset_t *
-dns_message_gettsig(dns_message_t *msg, dns_name_t **owner) {
-
- /*
- * Get the TSIG record and owner for 'msg'.
- */
-
- REQUIRE(DNS_MESSAGE_VALID(msg));
- REQUIRE(owner == NULL || *owner == NULL);
-
- if (owner != NULL)
- *owner = msg->tsigname;
- return (msg->tsig);
-}
-
-isc_result_t
-dns_message_settsigkey(dns_message_t *msg, dns_tsigkey_t *key) {
- isc_result_t result;
-
- /*
- * Set the TSIG key for 'msg'
- */
-
- REQUIRE(DNS_MESSAGE_VALID(msg));
- REQUIRE(msg->state == DNS_SECTION_ANY);
-
- if (key == NULL && msg->tsigkey != NULL) {
- if (msg->sig_reserved != 0) {
- dns_message_renderrelease(msg, msg->sig_reserved);
- msg->sig_reserved = 0;
- }
- dns_tsigkey_detach(&msg->tsigkey);
- }
- if (key != NULL) {
- REQUIRE(msg->tsigkey == NULL && msg->sig0key == NULL);
- dns_tsigkey_attach(key, &msg->tsigkey);
- if (msg->from_to_wire == DNS_MESSAGE_INTENTRENDER) {
- msg->sig_reserved = spacefortsig(msg->tsigkey, 0);
- result = dns_message_renderreserve(msg,
- msg->sig_reserved);
- if (result != ISC_R_SUCCESS) {
- dns_tsigkey_detach(&msg->tsigkey);
- msg->sig_reserved = 0;
- return (result);
- }
- }
- }
- return (ISC_R_SUCCESS);
-}
-
-dns_tsigkey_t *
-dns_message_gettsigkey(dns_message_t *msg) {
-
- /*
- * Get the TSIG key for 'msg'
- */
-
- REQUIRE(DNS_MESSAGE_VALID(msg));
-
- return (msg->tsigkey);
-}
-
-isc_result_t
-dns_message_setquerytsig(dns_message_t *msg, isc_buffer_t *querytsig) {
- dns_rdata_t *rdata = NULL;
- dns_rdatalist_t *list = NULL;
- dns_rdataset_t *set = NULL;
- isc_buffer_t *buf = NULL;
- isc_region_t r;
- isc_result_t result;
-
- REQUIRE(DNS_MESSAGE_VALID(msg));
- REQUIRE(msg->querytsig == NULL);
-
- if (querytsig == NULL)
- return (ISC_R_SUCCESS);
-
- result = dns_message_gettemprdata(msg, &rdata);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- result = dns_message_gettemprdatalist(msg, &list);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- result = dns_message_gettemprdataset(msg, &set);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- isc_buffer_usedregion(querytsig, &r);
- result = isc_buffer_allocate(msg->mctx, &buf, r.length);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- isc_buffer_putmem(buf, r.base, r.length);
- isc_buffer_usedregion(buf, &r);
- dns_rdata_init(rdata);
- dns_rdata_fromregion(rdata, dns_rdataclass_any, dns_rdatatype_tsig, &r);
- dns_message_takebuffer(msg, &buf);
- ISC_LIST_INIT(list->rdata);
- ISC_LIST_APPEND(list->rdata, rdata, link);
- result = dns_rdatalist_tordataset(list, set);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- msg->querytsig = set;
-
- return (result);
-
- cleanup:
- if (rdata != NULL)
- dns_message_puttemprdata(msg, &rdata);
- if (list != NULL)
- dns_message_puttemprdatalist(msg, &list);
- if (set != NULL)
- dns_message_puttemprdataset(msg, &set);
- return (ISC_R_NOMEMORY);
-}
-
-isc_result_t
-dns_message_getquerytsig(dns_message_t *msg, isc_mem_t *mctx,
- isc_buffer_t **querytsig) {
- isc_result_t result;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- isc_region_t r;
-
- REQUIRE(DNS_MESSAGE_VALID(msg));
- REQUIRE(mctx != NULL);
- REQUIRE(querytsig != NULL && *querytsig == NULL);
-
- if (msg->tsig == NULL)
- return (ISC_R_SUCCESS);
-
- result = dns_rdataset_first(msg->tsig);
- if (result != ISC_R_SUCCESS)
- return (result);
- dns_rdataset_current(msg->tsig, &rdata);
- dns_rdata_toregion(&rdata, &r);
-
- result = isc_buffer_allocate(mctx, querytsig, r.length);
- if (result != ISC_R_SUCCESS)
- return (result);
- isc_buffer_putmem(*querytsig, r.base, r.length);
- return (ISC_R_SUCCESS);
-}
-
-dns_rdataset_t *
-dns_message_getsig0(dns_message_t *msg, dns_name_t **owner) {
-
- /*
- * Get the SIG(0) record for 'msg'.
- */
-
- REQUIRE(DNS_MESSAGE_VALID(msg));
- REQUIRE(owner == NULL || *owner == NULL);
-
- if (msg->sig0 != NULL && owner != NULL) {
- /* If dns_message_getsig0 is called on a rendered message
- * after the SIG(0) has been applied, we need to return the
- * root name, not NULL.
- */
- if (msg->sig0name == NULL)
- *owner = dns_rootname;
- else
- *owner = msg->sig0name;
- }
- return (msg->sig0);
-}
-
-isc_result_t
-dns_message_setsig0key(dns_message_t *msg, dst_key_t *key) {
- isc_region_t r;
- unsigned int x;
- isc_result_t result;
-
- /*
- * Set the SIG(0) key for 'msg'
- */
-
- /*
- * The space required for an SIG(0) record is:
- *
- * 1 byte for the name
- * 2 bytes for the type
- * 2 bytes for the class
- * 4 bytes for the ttl
- * 2 bytes for the type covered
- * 1 byte for the algorithm
- * 1 bytes for the labels
- * 4 bytes for the original ttl
- * 4 bytes for the signature expiration
- * 4 bytes for the signature inception
- * 2 bytes for the key tag
- * n bytes for the signer's name
- * x bytes for the signature
- * ---------------------------------
- * 27 + n + x bytes
- */
- REQUIRE(DNS_MESSAGE_VALID(msg));
- REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
- REQUIRE(msg->state == DNS_SECTION_ANY);
-
- if (key != NULL) {
- REQUIRE(msg->sig0key == NULL && msg->tsigkey == NULL);
- dns_name_toregion(dst_key_name(key), &r);
- result = dst_key_sigsize(key, &x);
- if (result != ISC_R_SUCCESS) {
- msg->sig_reserved = 0;
- return (result);
- }
- msg->sig_reserved = 27 + r.length + x;
- result = dns_message_renderreserve(msg, msg->sig_reserved);
- if (result != ISC_R_SUCCESS) {
- msg->sig_reserved = 0;
- return (result);
- }
- msg->sig0key = key;
- }
- return (ISC_R_SUCCESS);
-}
-
-dst_key_t *
-dns_message_getsig0key(dns_message_t *msg) {
-
- /*
- * Get the SIG(0) key for 'msg'
- */
-
- REQUIRE(DNS_MESSAGE_VALID(msg));
-
- return (msg->sig0key);
-}
-
-void
-dns_message_takebuffer(dns_message_t *msg, isc_buffer_t **buffer) {
- REQUIRE(DNS_MESSAGE_VALID(msg));
- REQUIRE(buffer != NULL);
- REQUIRE(ISC_BUFFER_VALID(*buffer));
-
- ISC_LIST_APPEND(msg->cleanup, *buffer, link);
- *buffer = NULL;
-}
-
-isc_result_t
-dns_message_signer(dns_message_t *msg, dns_name_t *signer) {
- isc_result_t result = ISC_R_SUCCESS;
- dns_rdata_t rdata = DNS_RDATA_INIT;
-
- REQUIRE(DNS_MESSAGE_VALID(msg));
- REQUIRE(signer != NULL);
- REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTPARSE);
-
- if (msg->tsig == NULL && msg->sig0 == NULL)
- return (ISC_R_NOTFOUND);
-
- if (msg->verify_attempted == 0)
- return (DNS_R_NOTVERIFIEDYET);
-
- if (!dns_name_hasbuffer(signer)) {
- isc_buffer_t *dynbuf = NULL;
- result = isc_buffer_allocate(msg->mctx, &dynbuf, 512);
- if (result != ISC_R_SUCCESS)
- return (result);
- dns_name_setbuffer(signer, dynbuf);
- dns_message_takebuffer(msg, &dynbuf);
- }
-
- if (msg->sig0 != NULL) {
- dns_rdata_sig_t sig;
-
- result = dns_rdataset_first(msg->sig0);
- INSIST(result == ISC_R_SUCCESS);
- dns_rdataset_current(msg->sig0, &rdata);
-
- result = dns_rdata_tostruct(&rdata, &sig, NULL);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- if (msg->verified_sig && msg->sig0status == dns_rcode_noerror)
- result = ISC_R_SUCCESS;
- else
- result = DNS_R_SIGINVALID;
- dns_name_clone(&sig.signer, signer);
- dns_rdata_freestruct(&sig);
- } else {
- dns_name_t *identity;
- dns_rdata_any_tsig_t tsig;
-
- result = dns_rdataset_first(msg->tsig);
- INSIST(result == ISC_R_SUCCESS);
- dns_rdataset_current(msg->tsig, &rdata);
-
- result = dns_rdata_tostruct(&rdata, &tsig, NULL);
- INSIST(result == ISC_R_SUCCESS);
- if (msg->tsigstatus != dns_rcode_noerror)
- result = DNS_R_TSIGVERIFYFAILURE;
- else if (tsig.error != dns_rcode_noerror)
- result = DNS_R_TSIGERRORSET;
- else
- result = ISC_R_SUCCESS;
- dns_rdata_freestruct(&tsig);
-
- if (msg->tsigkey == NULL) {
- /*
- * If msg->tsigstatus & tsig.error are both
- * dns_rcode_noerror, the message must have been
- * verified, which means msg->tsigkey will be
- * non-NULL.
- */
- INSIST(result != ISC_R_SUCCESS);
- } else {
- identity = dns_tsigkey_identity(msg->tsigkey);
- if (identity == NULL) {
- if (result == ISC_R_SUCCESS)
- result = DNS_R_NOIDENTITY;
- identity = &msg->tsigkey->name;
- }
- dns_name_clone(identity, signer);
- }
- }
-
- return (result);
-}
-
-void
-dns_message_resetsig(dns_message_t *msg) {
- REQUIRE(DNS_MESSAGE_VALID(msg));
- msg->verified_sig = 0;
- msg->verify_attempted = 0;
- msg->tsigstatus = dns_rcode_noerror;
- msg->sig0status = dns_rcode_noerror;
- msg->timeadjust = 0;
- if (msg->tsigkey != NULL) {
- dns_tsigkey_detach(&msg->tsigkey);
- msg->tsigkey = NULL;
- }
-}
-
-isc_result_t
-dns_message_rechecksig(dns_message_t *msg, dns_view_t *view) {
- dns_message_resetsig(msg);
- return (dns_message_checksig(msg, view));
-}
-
-#ifdef SKAN_MSG_DEBUG
-void
-dns_message_dumpsig(dns_message_t *msg, char *txt1) {
- dns_rdata_t querytsigrdata = DNS_RDATA_INIT;
- dns_rdata_any_tsig_t querytsig;
- isc_result_t result;
-
- if (msg->tsig != NULL) {
- result = dns_rdataset_first(msg->tsig);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- dns_rdataset_current(msg->tsig, &querytsigrdata);
- result = dns_rdata_tostruct(&querytsigrdata, &querytsig, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- hexdump(txt1, "TSIG", querytsig.signature,
- querytsig.siglen);
- }
-
- if (msg->querytsig != NULL) {
- result = dns_rdataset_first(msg->querytsig);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- dns_rdataset_current(msg->querytsig, &querytsigrdata);
- result = dns_rdata_tostruct(&querytsigrdata, &querytsig, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- hexdump(txt1, "QUERYTSIG", querytsig.signature,
- querytsig.siglen);
- }
-}
-#endif
-
-isc_result_t
-dns_message_checksig(dns_message_t *msg, dns_view_t *view) {
- isc_buffer_t b, msgb;
-
- REQUIRE(DNS_MESSAGE_VALID(msg));
-
- if (msg->tsigkey == NULL && msg->tsig == NULL && msg->sig0 == NULL)
- return (ISC_R_SUCCESS);
-
- INSIST(msg->saved.base != NULL);
- isc_buffer_init(&msgb, msg->saved.base, msg->saved.length);
- isc_buffer_add(&msgb, msg->saved.length);
- if (msg->tsigkey != NULL || msg->tsig != NULL) {
-#ifdef SKAN_MSG_DEBUG
- dns_message_dumpsig(msg, "dns_message_checksig#1");
-#endif
- if (view != NULL)
- return (dns_view_checksig(view, &msgb, msg));
- else
- return (dns_tsig_verify(&msgb, msg, NULL, NULL));
- } else {
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdata_sig_t sig;
- dns_rdataset_t keyset;
- isc_result_t result;
-
- result = dns_rdataset_first(msg->sig0);
- INSIST(result == ISC_R_SUCCESS);
- dns_rdataset_current(msg->sig0, &rdata);
-
- /*
- * This can occur when the message is a dynamic update, since
- * the rdata length checking is relaxed. This should not
- * happen in a well-formed message, since the SIG(0) is only
- * looked for in the additional section, and the dynamic update
- * meta-records are in the prerequisite and update sections.
- */
- if (rdata.length == 0)
- return (ISC_R_UNEXPECTEDEND);
-
- result = dns_rdata_tostruct(&rdata, &sig, msg->mctx);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- dns_rdataset_init(&keyset);
- if (view == NULL)
- return (DNS_R_KEYUNAUTHORIZED);
- result = dns_view_simplefind(view, &sig.signer,
- dns_rdatatype_key /* SIG(0) */,
- 0, 0, ISC_FALSE, &keyset, NULL);
-
- if (result != ISC_R_SUCCESS) {
- /* XXXBEW Should possibly create a fetch here */
- result = DNS_R_KEYUNAUTHORIZED;
- goto freesig;
- } else if (keyset.trust < dns_trust_secure) {
- /* XXXBEW Should call a validator here */
- result = DNS_R_KEYUNAUTHORIZED;
- goto freesig;
- }
- result = dns_rdataset_first(&keyset);
- INSIST(result == ISC_R_SUCCESS);
- for (;
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(&keyset))
- {
- dst_key_t *key = NULL;
-
- dns_rdata_reset(&rdata);
- dns_rdataset_current(&keyset, &rdata);
- isc_buffer_init(&b, rdata.data, rdata.length);
- isc_buffer_add(&b, rdata.length);
-
- result = dst_key_fromdns(&sig.signer, rdata.rdclass,
- &b, view->mctx, &key);
- if (result != ISC_R_SUCCESS)
- continue;
- if (dst_key_alg(key) != sig.algorithm ||
- dst_key_id(key) != sig.keyid ||
- !(dst_key_proto(key) == DNS_KEYPROTO_DNSSEC ||
- dst_key_proto(key) == DNS_KEYPROTO_ANY))
- {
- dst_key_free(&key);
- continue;
- }
- result = dns_dnssec_verifymessage(&msgb, msg, key);
- dst_key_free(&key);
- if (result == ISC_R_SUCCESS)
- break;
- }
- if (result == ISC_R_NOMORE)
- result = DNS_R_KEYUNAUTHORIZED;
-
- freesig:
- if (dns_rdataset_isassociated(&keyset))
- dns_rdataset_disassociate(&keyset);
- dns_rdata_freestruct(&sig);
- return (result);
- }
-}
-
-isc_result_t
-dns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
- const dns_master_style_t *style,
- dns_messagetextflag_t flags,
- isc_buffer_t *target) {
- 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);
- REQUIRE(VALID_SECTION(section));
-
- if (ISC_LIST_EMPTY(msg->sections[section]))
- return (ISC_R_SUCCESS);
-
- if ((flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0) {
- ADD_STRING(target, ";; ");
- if (msg->opcode != dns_opcode_update) {
- ADD_STRING(target, sectiontext[section]);
- } else {
- ADD_STRING(target, updsectiontext[section]);
- }
- ADD_STRING(target, " SECTION:\n");
- }
-
- dns_name_init(&empty_name, NULL);
- result = dns_message_firstname(msg, section);
- if (result != ISC_R_SUCCESS) {
- return (result);
- }
- do {
- name = NULL;
- dns_message_currentname(msg, section, &name);
- for (rdataset = ISC_LIST_HEAD(name->list);
- rdataset != NULL;
- rdataset = ISC_LIST_NEXT(rdataset, link)) {
- if (section == DNS_SECTION_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,
- rdataset,
- style,
- target);
- } else {
- result = dns_master_rdatasettotext(name,
- rdataset,
- style,
- target);
- }
- if (result != ISC_R_SUCCESS)
- return (result);
- }
- result = dns_message_nextname(msg, section);
- } while (result == ISC_R_SUCCESS);
- if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0 &&
- (flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0)
- ADD_STRING(target, "\n");
- if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
- return (result);
-}
-
-isc_result_t
-dns_message_pseudosectiontotext(dns_message_t *msg,
- dns_pseudosection_t section,
- const dns_master_style_t *style,
- dns_messagetextflag_t flags,
- isc_buffer_t *target) {
- dns_rdataset_t *ps = NULL;
- dns_name_t *name = NULL;
- isc_result_t result;
- char buf[sizeof("1234567890")];
- isc_uint32_t mbz;
- dns_rdata_t rdata;
- isc_buffer_t optbuf;
- isc_uint16_t optcode, optlen;
- unsigned char *optdata;
-
- REQUIRE(DNS_MESSAGE_VALID(msg));
- REQUIRE(target != NULL);
- REQUIRE(VALID_PSEUDOSECTION(section));
-
- switch (section) {
- case DNS_PSEUDOSECTION_OPT:
- ps = dns_message_getopt(msg);
- if (ps == NULL)
- return (ISC_R_SUCCESS);
- if ((flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0)
- ADD_STRING(target, ";; OPT PSEUDOSECTION:\n");
- ADD_STRING(target, "; EDNS: version: ");
- snprintf(buf, sizeof(buf), "%u",
- (unsigned int)((ps->ttl & 0x00ff0000) >> 16));
- ADD_STRING(target, buf);
- ADD_STRING(target, ", flags:");
- if ((ps->ttl & DNS_MESSAGEEXTFLAG_DO) != 0)
- ADD_STRING(target, " do");
- mbz = ps->ttl & 0xffff;
- mbz &= ~DNS_MESSAGEEXTFLAG_DO; /* Known Flags. */
- if (mbz != 0) {
- ADD_STRING(target, "; MBZ: ");
- snprintf(buf, sizeof(buf), "%.4x ", mbz);
- ADD_STRING(target, buf);
- ADD_STRING(target, ", udp: ");
- } else
- ADD_STRING(target, "; udp: ");
- snprintf(buf, sizeof(buf), "%u\n", (unsigned int)ps->rdclass);
- ADD_STRING(target, buf);
-
- result = dns_rdataset_first(ps);
- if (result != ISC_R_SUCCESS)
- return (ISC_R_SUCCESS);
-
- /* Print EDNS info, if any */
- dns_rdata_init(&rdata);
- dns_rdataset_current(ps, &rdata);
-
- isc_buffer_init(&optbuf, rdata.data, rdata.length);
- isc_buffer_add(&optbuf, rdata.length);
- while (isc_buffer_remaininglength(&optbuf) != 0) {
- INSIST(isc_buffer_remaininglength(&optbuf) >= 4U);
- optcode = isc_buffer_getuint16(&optbuf);
- optlen = isc_buffer_getuint16(&optbuf);
- INSIST(isc_buffer_remaininglength(&optbuf) >= optlen);
-
- if (optcode == DNS_OPT_NSID) {
- ADD_STRING(target, "; NSID");
- } else {
- ADD_STRING(target, "; OPT=");
- sprintf(buf, "%u", optcode);
- ADD_STRING(target, buf);
- }
-
- if (optlen != 0) {
- int i;
- ADD_STRING(target, ": ");
-
- optdata = isc_buffer_current(&optbuf);
- for (i = 0; i < optlen; i++) {
- sprintf(buf, "%02x ", optdata[i]);
- ADD_STRING(target, buf);
- }
- for (i = 0; i < optlen; i++) {
- ADD_STRING(target, " (");
- if (isprint(optdata[i]))
- isc_buffer_putmem(target,
- &optdata[i],
- 1);
- else
- isc_buffer_putstr(target, ".");
- ADD_STRING(target, ")");
- }
- isc_buffer_forward(&optbuf, optlen);
- }
- ADD_STRING(target, "\n");
- }
- return (ISC_R_SUCCESS);
- case DNS_PSEUDOSECTION_TSIG:
- ps = dns_message_gettsig(msg, &name);
- if (ps == NULL)
- return (ISC_R_SUCCESS);
- if ((flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0)
- ADD_STRING(target, ";; TSIG PSEUDOSECTION:\n");
- result = dns_master_rdatasettotext(name, ps, style, target);
- if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0 &&
- (flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0)
- ADD_STRING(target, "\n");
- return (result);
- case DNS_PSEUDOSECTION_SIG0:
- ps = dns_message_getsig0(msg, &name);
- if (ps == NULL)
- return (ISC_R_SUCCESS);
- if ((flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0)
- ADD_STRING(target, ";; SIG0 PSEUDOSECTION:\n");
- result = dns_master_rdatasettotext(name, ps, style, target);
- if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0 &&
- (flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0)
- ADD_STRING(target, "\n");
- return (result);
- }
- return (ISC_R_UNEXPECTED);
-}
-
-isc_result_t
-dns_message_totext(dns_message_t *msg, const dns_master_style_t *style,
- dns_messagetextflag_t flags, isc_buffer_t *target) {
- char buf[sizeof("1234567890")];
- isc_result_t result;
-
- REQUIRE(DNS_MESSAGE_VALID(msg));
- REQUIRE(target != NULL);
-
- if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0) {
- ADD_STRING(target, ";; ->>HEADER<<- opcode: ");
- ADD_STRING(target, opcodetext[msg->opcode]);
- ADD_STRING(target, ", status: ");
- if (msg->rcode < (sizeof(rcodetext)/sizeof(rcodetext[0]))) {
- ADD_STRING(target, rcodetext[msg->rcode]);
- } else {
- snprintf(buf, sizeof(buf), "%4u", msg->rcode);
- ADD_STRING(target, buf);
- }
- ADD_STRING(target, ", id: ");
- snprintf(buf, sizeof(buf), "%6u", msg->id);
- ADD_STRING(target, buf);
- ADD_STRING(target, "\n;; flags:");
- if ((msg->flags & DNS_MESSAGEFLAG_QR) != 0)
- ADD_STRING(target, " qr");
- if ((msg->flags & DNS_MESSAGEFLAG_AA) != 0)
- ADD_STRING(target, " aa");
- if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0)
- ADD_STRING(target, " tc");
- if ((msg->flags & DNS_MESSAGEFLAG_RD) != 0)
- ADD_STRING(target, " rd");
- if ((msg->flags & DNS_MESSAGEFLAG_RA) != 0)
- ADD_STRING(target, " ra");
- if ((msg->flags & DNS_MESSAGEFLAG_AD) != 0)
- ADD_STRING(target, " ad");
- if ((msg->flags & DNS_MESSAGEFLAG_CD) != 0)
- ADD_STRING(target, " cd");
- /*
- * The final unnamed flag must be zero.
- */
- if ((msg->flags & 0x0040U) != 0)
- ADD_STRING(target, "; MBZ: 0x4");
- if (msg->opcode != dns_opcode_update) {
- ADD_STRING(target, "; QUESTION: ");
- } else {
- ADD_STRING(target, "; ZONE: ");
- }
- snprintf(buf, sizeof(buf), "%1u",
- msg->counts[DNS_SECTION_QUESTION]);
- ADD_STRING(target, buf);
- if (msg->opcode != dns_opcode_update) {
- ADD_STRING(target, ", ANSWER: ");
- } else {
- ADD_STRING(target, ", PREREQ: ");
- }
- snprintf(buf, sizeof(buf), "%1u",
- msg->counts[DNS_SECTION_ANSWER]);
- ADD_STRING(target, buf);
- if (msg->opcode != dns_opcode_update) {
- ADD_STRING(target, ", AUTHORITY: ");
- } else {
- ADD_STRING(target, ", UPDATE: ");
- }
- snprintf(buf, sizeof(buf), "%1u",
- msg->counts[DNS_SECTION_AUTHORITY]);
- ADD_STRING(target, buf);
- ADD_STRING(target, ", ADDITIONAL: ");
- snprintf(buf, sizeof(buf), "%1u",
- msg->counts[DNS_SECTION_ADDITIONAL]);
- ADD_STRING(target, buf);
- ADD_STRING(target, "\n");
- }
- result = dns_message_pseudosectiontotext(msg,
- DNS_PSEUDOSECTION_OPT,
- style, flags, target);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- result = dns_message_sectiontotext(msg, DNS_SECTION_QUESTION,
- style, flags, target);
- if (result != ISC_R_SUCCESS)
- return (result);
- result = dns_message_sectiontotext(msg, DNS_SECTION_ANSWER,
- style, flags, target);
- if (result != ISC_R_SUCCESS)
- return (result);
- result = dns_message_sectiontotext(msg, DNS_SECTION_AUTHORITY,
- style, flags, target);
- if (result != ISC_R_SUCCESS)
- return (result);
- result = dns_message_sectiontotext(msg, DNS_SECTION_ADDITIONAL,
- style, flags, target);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- result = dns_message_pseudosectiontotext(msg,
- DNS_PSEUDOSECTION_TSIG,
- style, flags, target);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- result = dns_message_pseudosectiontotext(msg,
- DNS_PSEUDOSECTION_SIG0,
- style, flags, target);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- return (ISC_R_SUCCESS);
-}
-
-isc_region_t *
-dns_message_getrawmessage(dns_message_t *msg) {
- REQUIRE(DNS_MESSAGE_VALID(msg));
- return (&msg->saved);
-}
-
-void
-dns_message_setsortorder(dns_message_t *msg, dns_rdatasetorderfunc_t order,
- const void *order_arg)
-{
- REQUIRE(DNS_MESSAGE_VALID(msg));
- msg->order = order;
- msg->order_arg = order_arg;
-}
-
-void
-dns_message_settimeadjust(dns_message_t *msg, int timeadjust) {
- REQUIRE(DNS_MESSAGE_VALID(msg));
- msg->timeadjust = timeadjust;
-}
-
-int
-dns_message_gettimeadjust(dns_message_t *msg) {
- REQUIRE(DNS_MESSAGE_VALID(msg));
- return (msg->timeadjust);
-}
-
-isc_result_t
-dns_opcode_totext(dns_opcode_t opcode, isc_buffer_t *target) {
-
- REQUIRE(opcode < 16);
-
- if (isc_buffer_availablelength(target) < strlen(opcodetext[opcode]))
- return (ISC_R_NOSPACE);
- isc_buffer_putstr(target, opcodetext[opcode]);
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_message_buildopt(dns_message_t *message, dns_rdataset_t **rdatasetp,
- unsigned int version, isc_uint16_t udpsize,
- unsigned int flags, dns_ednsopt_t *ednsopts, size_t count)
-{
- dns_rdataset_t *rdataset = NULL;
- dns_rdatalist_t *rdatalist = NULL;
- dns_rdata_t *rdata = NULL;
- isc_result_t result;
- size_t len = 0, i;
-
- REQUIRE(DNS_MESSAGE_VALID(message));
- REQUIRE(rdatasetp != NULL && *rdatasetp == NULL);
-
- result = dns_message_gettemprdatalist(message, &rdatalist);
- if (result != ISC_R_SUCCESS)
- return (result);
- result = dns_message_gettemprdata(message, &rdata);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- result = dns_message_gettemprdataset(message, &rdataset);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- dns_rdataset_init(rdataset);
-
- rdatalist->type = dns_rdatatype_opt;
- rdatalist->covers = 0;
-
- /*
- * Set Maximum UDP buffer size.
- */
- rdatalist->rdclass = udpsize;
-
- /*
- * Set EXTENDED-RCODE and Z to 0.
- */
- rdatalist->ttl = (version << 16);
- rdatalist->ttl |= (flags & 0xffff);
-
- /*
- * Set EDNS options if applicable
- */
- if (count != 0U) {
- isc_buffer_t *buf = NULL;
- for (i = 0; i < count; i++)
- len += ednsopts[i].length + 4;
-
- if (len > 0xffffU) {
- result = ISC_R_NOSPACE;
- goto cleanup;
- }
-
- result = isc_buffer_allocate(message->mctx, &buf, len);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- for (i = 0; i < count; i++) {
- isc_buffer_putuint16(buf, ednsopts[i].code);
- isc_buffer_putuint16(buf, ednsopts[i].length);
- isc_buffer_putmem(buf, ednsopts[i].value,
- ednsopts[i].length);
- }
- rdata->data = isc_buffer_base(buf);
- rdata->length = len;
- dns_message_takebuffer(message, &buf);
- } else {
- rdata->data = NULL;
- rdata->length = 0;
- }
-
- rdata->rdclass = rdatalist->rdclass;
- rdata->type = rdatalist->type;
- rdata->flags = 0;
-
- ISC_LIST_INIT(rdatalist->rdata);
- ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
- result = dns_rdatalist_tordataset(rdatalist, rdataset);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
-
- *rdatasetp = rdataset;
- return (ISC_R_SUCCESS);
-
- cleanup:
- if (rdata != NULL)
- dns_message_puttemprdata(message, &rdata);
- if (rdataset != NULL)
- dns_message_puttemprdataset(message, &rdataset);
- if (rdatalist != NULL)
- dns_message_puttemprdatalist(message, &rdatalist);
- return (result);
-}
diff --git a/contrib/bind9/lib/dns/name.c b/contrib/bind9/lib/dns/name.c
deleted file mode 100644
index 7fb21e138c3c..000000000000
--- a/contrib/bind9/lib/dns/name.c
+++ /dev/null
@@ -1,2506 +0,0 @@
-/*
- * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <ctype.h>
-#include <stdlib.h>
-
-#include <isc/buffer.h>
-#include <isc/hash.h>
-#include <isc/mem.h>
-#include <isc/once.h>
-#include <isc/print.h>
-#include <isc/string.h>
-#include <isc/thread.h>
-#include <isc/util.h>
-
-#include <dns/compress.h>
-#include <dns/fixedname.h>
-#include <dns/name.h>
-#include <dns/result.h>
-
-#define VALID_NAME(n) ISC_MAGIC_VALID(n, DNS_NAME_MAGIC)
-
-typedef enum {
- ft_init = 0,
- ft_start,
- ft_ordinary,
- ft_initialescape,
- ft_escape,
- ft_escdecimal,
- ft_at
-} ft_state;
-
-typedef enum {
- fw_start = 0,
- fw_ordinary,
- fw_copy,
- fw_newcurrent
-} fw_state;
-
-static char digitvalue[256] = {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*16*/
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*32*/
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*48*/
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, /*64*/
- -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*80*/
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*96*/
- -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*112*/
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*128*/
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*256*/
-};
-
-static unsigned char maptolower[] = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
- 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
- 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
- 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
- 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
- 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
- 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
- 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
- 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
- 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
- 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
- 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
- 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
- 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
- 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
- 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
- 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
- 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
- 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
- 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
- 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
- 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
- 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
- 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
- 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
- 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
- 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
-};
-
-#define CONVERTTOASCII(c)
-#define CONVERTFROMASCII(c)
-
-#define INIT_OFFSETS(name, var, default) \
- if (name->offsets != NULL) \
- var = name->offsets; \
- else \
- var = default;
-
-#define SETUP_OFFSETS(name, var, default) \
- if (name->offsets != NULL) \
- var = name->offsets; \
- else { \
- var = default; \
- set_offsets(name, var, NULL); \
- }
-
-/*%
- * Note: If additional attributes are added that should not be set for
- * empty names, MAKE_EMPTY() must be changed so it clears them.
- */
-#define MAKE_EMPTY(name) \
-do { \
- name->ndata = NULL; \
- name->length = 0; \
- name->labels = 0; \
- name->attributes &= ~DNS_NAMEATTR_ABSOLUTE; \
-} while (0);
-
-/*%
- * A name is "bindable" if it can be set to point to a new value, i.e.
- * name->ndata and name->length may be changed.
- */
-#define BINDABLE(name) \
- ((name->attributes & (DNS_NAMEATTR_READONLY|DNS_NAMEATTR_DYNAMIC)) \
- == 0)
-
-/*%
- * Note that the name data must be a char array, not a string
- * literal, to avoid compiler warnings about discarding
- * the const attribute of a string.
- */
-static unsigned char root_ndata[] = { '\0' };
-static unsigned char root_offsets[] = { 0 };
-
-static dns_name_t root =
-{
- DNS_NAME_MAGIC,
- root_ndata, 1, 1,
- DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE,
- root_offsets, NULL,
- {(void *)-1, (void *)-1},
- {NULL, NULL}
-};
-
-/* XXXDCL make const? */
-LIBDNS_EXTERNAL_DATA dns_name_t *dns_rootname = &root;
-
-static unsigned char wild_ndata[] = { '\001', '*' };
-static unsigned char wild_offsets[] = { 0 };
-
-static dns_name_t wild =
-{
- DNS_NAME_MAGIC,
- wild_ndata, 2, 1,
- DNS_NAMEATTR_READONLY,
- wild_offsets, NULL,
- {(void *)-1, (void *)-1},
- {NULL, NULL}
-};
-
-/* XXXDCL make const? */
-LIBDNS_EXTERNAL_DATA dns_name_t *dns_wildcardname = &wild;
-
-unsigned int
-dns_fullname_hash(dns_name_t *name, isc_boolean_t case_sensitive);
-
-/*
- * dns_name_t to text post-conversion procedure.
- */
-#ifdef ISC_PLATFORM_USETHREADS
-static int thread_key_initialized = 0;
-static isc_mutex_t thread_key_mutex;
-static isc_mem_t *thread_key_mctx = NULL;
-static isc_thread_key_t totext_filter_proc_key;
-static isc_once_t once = ISC_ONCE_INIT;
-#else
-static dns_name_totextfilter_t totext_filter_proc = NULL;
-#endif
-
-static void
-set_offsets(const dns_name_t *name, unsigned char *offsets,
- dns_name_t *set_name);
-
-void
-dns_name_init(dns_name_t *name, unsigned char *offsets) {
- /*
- * Initialize 'name'.
- */
- DNS_NAME_INIT(name, offsets);
-}
-
-void
-dns_name_reset(dns_name_t *name) {
- REQUIRE(VALID_NAME(name));
- REQUIRE(BINDABLE(name));
-
- DNS_NAME_RESET(name);
-}
-
-void
-dns_name_invalidate(dns_name_t *name) {
- /*
- * Make 'name' invalid.
- */
-
- REQUIRE(VALID_NAME(name));
-
- name->magic = 0;
- name->ndata = NULL;
- name->length = 0;
- name->labels = 0;
- name->attributes = 0;
- name->offsets = NULL;
- name->buffer = NULL;
- ISC_LINK_INIT(name, link);
-}
-
-void
-dns_name_setbuffer(dns_name_t *name, isc_buffer_t *buffer) {
- /*
- * Dedicate a buffer for use with 'name'.
- */
-
- REQUIRE(VALID_NAME(name));
- REQUIRE((buffer != NULL && name->buffer == NULL) ||
- (buffer == NULL));
-
- name->buffer = buffer;
-}
-
-isc_boolean_t
-dns_name_hasbuffer(const dns_name_t *name) {
- /*
- * Does 'name' have a dedicated buffer?
- */
-
- REQUIRE(VALID_NAME(name));
-
- if (name->buffer != NULL)
- return (ISC_TRUE);
-
- return (ISC_FALSE);
-}
-
-isc_boolean_t
-dns_name_isabsolute(const dns_name_t *name) {
-
- /*
- * Does 'name' end in the root label?
- */
-
- REQUIRE(VALID_NAME(name));
-
- if ((name->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
- return (ISC_TRUE);
- return (ISC_FALSE);
-}
-
-#define hyphenchar(c) ((c) == 0x2d)
-#define asterchar(c) ((c) == 0x2a)
-#define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) \
- || ((c) >= 0x61 && (c) <= 0x7a))
-#define digitchar(c) ((c) >= 0x30 && (c) <= 0x39)
-#define borderchar(c) (alphachar(c) || digitchar(c))
-#define middlechar(c) (borderchar(c) || hyphenchar(c))
-#define domainchar(c) ((c) > 0x20 && (c) < 0x7f)
-
-isc_boolean_t
-dns_name_ismailbox(const dns_name_t *name) {
- unsigned char *ndata, ch;
- unsigned int n;
- isc_boolean_t first;
-
- REQUIRE(VALID_NAME(name));
- REQUIRE(name->labels > 0);
- REQUIRE(name->attributes & DNS_NAMEATTR_ABSOLUTE);
-
- /*
- * Root label.
- */
- if (name->length == 1)
- return (ISC_TRUE);
-
- ndata = name->ndata;
- n = *ndata++;
- INSIST(n <= 63);
- while (n--) {
- ch = *ndata++;
- if (!domainchar(ch))
- return (ISC_FALSE);
- }
-
- if (ndata == name->ndata + name->length)
- return (ISC_FALSE);
-
- /*
- * RFC292/RFC1123 hostname.
- */
- while (ndata < (name->ndata + name->length)) {
- n = *ndata++;
- INSIST(n <= 63);
- first = ISC_TRUE;
- while (n--) {
- ch = *ndata++;
- if (first || n == 0) {
- if (!borderchar(ch))
- return (ISC_FALSE);
- } else {
- if (!middlechar(ch))
- return (ISC_FALSE);
- }
- first = ISC_FALSE;
- }
- }
- return (ISC_TRUE);
-}
-
-isc_boolean_t
-dns_name_ishostname(const dns_name_t *name, isc_boolean_t wildcard) {
- unsigned char *ndata, ch;
- unsigned int n;
- isc_boolean_t first;
-
- REQUIRE(VALID_NAME(name));
- REQUIRE(name->labels > 0);
- REQUIRE(name->attributes & DNS_NAMEATTR_ABSOLUTE);
-
- /*
- * Root label.
- */
- if (name->length == 1)
- return (ISC_TRUE);
-
- /*
- * Skip wildcard if this is a ownername.
- */
- ndata = name->ndata;
- if (wildcard && ndata[0] == 1 && ndata[1] == '*')
- ndata += 2;
-
- /*
- * RFC292/RFC1123 hostname.
- */
- while (ndata < (name->ndata + name->length)) {
- n = *ndata++;
- INSIST(n <= 63);
- first = ISC_TRUE;
- while (n--) {
- ch = *ndata++;
- if (first || n == 0) {
- if (!borderchar(ch))
- return (ISC_FALSE);
- } else {
- if (!middlechar(ch))
- return (ISC_FALSE);
- }
- first = ISC_FALSE;
- }
- }
- return (ISC_TRUE);
-}
-
-isc_boolean_t
-dns_name_iswildcard(const dns_name_t *name) {
- unsigned char *ndata;
-
- /*
- * Is 'name' a wildcard name?
- */
-
- REQUIRE(VALID_NAME(name));
- REQUIRE(name->labels > 0);
-
- if (name->length >= 2) {
- ndata = name->ndata;
- if (ndata[0] == 1 && ndata[1] == '*')
- return (ISC_TRUE);
- }
-
- return (ISC_FALSE);
-}
-
-isc_boolean_t
-dns_name_internalwildcard(const dns_name_t *name) {
- unsigned char *ndata;
- unsigned int count;
- unsigned int label;
-
- /*
- * Does 'name' contain a internal wildcard?
- */
-
- REQUIRE(VALID_NAME(name));
- REQUIRE(name->labels > 0);
-
- /*
- * Skip first label.
- */
- ndata = name->ndata;
- count = *ndata++;
- INSIST(count <= 63);
- ndata += count;
- label = 1;
- /*
- * Check all but the last of the remaining labels.
- */
- while (label + 1 < name->labels) {
- count = *ndata++;
- INSIST(count <= 63);
- if (count == 1 && *ndata == '*')
- return (ISC_TRUE);
- ndata += count;
- label++;
- }
- return (ISC_FALSE);
-}
-
-static inline unsigned int
-name_hash(dns_name_t *name, isc_boolean_t case_sensitive) {
- unsigned int length;
- const unsigned char *s;
- unsigned int h = 0;
- unsigned char c;
-
- length = name->length;
- if (length > 16)
- length = 16;
-
- /*
- * This hash function is similar to the one Ousterhout
- * uses in Tcl.
- */
- s = name->ndata;
- if (case_sensitive) {
- while (length > 0) {
- h += ( h << 3 ) + *s;
- s++;
- length--;
- }
- } else {
- while (length > 0) {
- c = maptolower[*s];
- h += ( h << 3 ) + c;
- s++;
- length--;
- }
- }
-
- return (h);
-}
-
-unsigned int
-dns_name_hash(dns_name_t *name, isc_boolean_t case_sensitive) {
- /*
- * Provide a hash value for 'name'.
- */
- REQUIRE(VALID_NAME(name));
-
- if (name->labels == 0)
- return (0);
-
- return (name_hash(name, case_sensitive));
-}
-
-unsigned int
-dns_name_fullhash(dns_name_t *name, isc_boolean_t case_sensitive) {
- /*
- * Provide a hash value for 'name'.
- */
- REQUIRE(VALID_NAME(name));
-
- if (name->labels == 0)
- return (0);
-
- return (isc_hash_calc((const unsigned char *)name->ndata,
- name->length, case_sensitive));
-}
-
-unsigned int
-dns_fullname_hash(dns_name_t *name, isc_boolean_t case_sensitive) {
- /*
- * This function was deprecated due to the breakage of the name space
- * convention. We only keep this internally to provide binary backward
- * compatibility.
- */
- REQUIRE(VALID_NAME(name));
-
- return (dns_name_fullhash(name, case_sensitive));
-}
-
-unsigned int
-dns_name_hashbylabel(dns_name_t *name, isc_boolean_t case_sensitive) {
- unsigned char *offsets;
- dns_offsets_t odata;
- dns_name_t tname;
- unsigned int h = 0;
- unsigned int i;
-
- /*
- * Provide a hash value for 'name'.
- */
- REQUIRE(VALID_NAME(name));
-
- if (name->labels == 0)
- return (0);
- else if (name->labels == 1)
- return (name_hash(name, case_sensitive));
-
- SETUP_OFFSETS(name, offsets, odata);
- DNS_NAME_INIT(&tname, NULL);
- tname.labels = 1;
- h = 0;
- for (i = 0; i < name->labels; i++) {
- tname.ndata = name->ndata + offsets[i];
- if (i == name->labels - 1)
- tname.length = name->length - offsets[i];
- else
- tname.length = offsets[i + 1] - offsets[i];
- h += name_hash(&tname, case_sensitive);
- }
-
- return (h);
-}
-
-dns_namereln_t
-dns_name_fullcompare(const dns_name_t *name1, const dns_name_t *name2,
- int *orderp, unsigned int *nlabelsp)
-{
- unsigned int l1, l2, l, count1, count2, count, nlabels;
- int cdiff, ldiff, chdiff;
- unsigned char *label1, *label2;
- unsigned char *offsets1, *offsets2;
- dns_offsets_t odata1, odata2;
- dns_namereln_t namereln = dns_namereln_none;
-
- /*
- * Determine the relative ordering under the DNSSEC order relation of
- * 'name1' and 'name2', and also determine the hierarchical
- * relationship of the names.
- *
- * Note: It makes no sense for one of the names to be relative and the
- * other absolute. If both names are relative, then to be meaningfully
- * compared the caller must ensure that they are both relative to the
- * same domain.
- */
-
- REQUIRE(VALID_NAME(name1));
- REQUIRE(VALID_NAME(name2));
- REQUIRE(orderp != NULL);
- REQUIRE(nlabelsp != NULL);
- /*
- * Either name1 is absolute and name2 is absolute, or neither is.
- */
- REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) ==
- (name2->attributes & DNS_NAMEATTR_ABSOLUTE));
-
- SETUP_OFFSETS(name1, offsets1, odata1);
- SETUP_OFFSETS(name2, offsets2, odata2);
-
- nlabels = 0;
- l1 = name1->labels;
- l2 = name2->labels;
- if (l2 > l1) {
- l = l1;
- ldiff = 0 - (l2 - l1);
- } else {
- l = l2;
- ldiff = l1 - l2;
- }
-
- while (l > 0) {
- l--;
- l1--;
- l2--;
- label1 = &name1->ndata[offsets1[l1]];
- label2 = &name2->ndata[offsets2[l2]];
- count1 = *label1++;
- count2 = *label2++;
-
- /*
- * We dropped bitstring labels, and we don't support any
- * other extended label types.
- */
- INSIST(count1 <= 63 && count2 <= 63);
-
- cdiff = (int)count1 - (int)count2;
- if (cdiff < 0)
- count = count1;
- else
- count = count2;
-
- while (count > 0) {
- chdiff = (int)maptolower[*label1] -
- (int)maptolower[*label2];
- if (chdiff != 0) {
- *orderp = chdiff;
- goto done;
- }
- count--;
- label1++;
- label2++;
- }
- if (cdiff != 0) {
- *orderp = cdiff;
- goto done;
- }
- nlabels++;
- }
-
- *orderp = ldiff;
- if (ldiff < 0)
- namereln = dns_namereln_contains;
- else if (ldiff > 0)
- namereln = dns_namereln_subdomain;
- else
- namereln = dns_namereln_equal;
-
- done:
- *nlabelsp = nlabels;
-
- if (nlabels > 0 && namereln == dns_namereln_none)
- namereln = dns_namereln_commonancestor;
-
- return (namereln);
-}
-
-int
-dns_name_compare(const dns_name_t *name1, const dns_name_t *name2) {
- int order;
- unsigned int nlabels;
-
- /*
- * Determine the relative ordering under the DNSSEC order relation of
- * 'name1' and 'name2'.
- *
- * Note: It makes no sense for one of the names to be relative and the
- * other absolute. If both names are relative, then to be meaningfully
- * compared the caller must ensure that they are both relative to the
- * same domain.
- */
-
- (void)dns_name_fullcompare(name1, name2, &order, &nlabels);
-
- return (order);
-}
-
-isc_boolean_t
-dns_name_equal(const dns_name_t *name1, const dns_name_t *name2) {
- unsigned int l, count;
- unsigned char c;
- unsigned char *label1, *label2;
-
- /*
- * Are 'name1' and 'name2' equal?
- *
- * Note: It makes no sense for one of the names to be relative and the
- * other absolute. If both names are relative, then to be meaningfully
- * compared the caller must ensure that they are both relative to the
- * same domain.
- */
-
- REQUIRE(VALID_NAME(name1));
- REQUIRE(VALID_NAME(name2));
- /*
- * Either name1 is absolute and name2 is absolute, or neither is.
- */
- REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) ==
- (name2->attributes & DNS_NAMEATTR_ABSOLUTE));
-
- if (name1->length != name2->length)
- return (ISC_FALSE);
-
- l = name1->labels;
-
- if (l != name2->labels)
- return (ISC_FALSE);
-
- label1 = name1->ndata;
- label2 = name2->ndata;
- while (l > 0) {
- l--;
- count = *label1++;
- if (count != *label2++)
- return (ISC_FALSE);
-
- INSIST(count <= 63); /* no bitstring support */
-
- while (count > 0) {
- count--;
- c = maptolower[*label1++];
- if (c != maptolower[*label2++])
- return (ISC_FALSE);
- }
- }
-
- return (ISC_TRUE);
-}
-
-isc_boolean_t
-dns_name_caseequal(const dns_name_t *name1, const dns_name_t *name2) {
-
- /*
- * Are 'name1' and 'name2' equal?
- *
- * Note: It makes no sense for one of the names to be relative and the
- * other absolute. If both names are relative, then to be meaningfully
- * compared the caller must ensure that they are both relative to the
- * same domain.
- */
-
- REQUIRE(VALID_NAME(name1));
- REQUIRE(VALID_NAME(name2));
- /*
- * Either name1 is absolute and name2 is absolute, or neither is.
- */
- REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) ==
- (name2->attributes & DNS_NAMEATTR_ABSOLUTE));
-
- if (name1->length != name2->length)
- return (ISC_FALSE);
-
- if (memcmp(name1->ndata, name2->ndata, name1->length) != 0)
- return (ISC_FALSE);
-
- return (ISC_TRUE);
-}
-
-int
-dns_name_rdatacompare(const dns_name_t *name1, const dns_name_t *name2) {
- unsigned int l1, l2, l, count1, count2, count;
- unsigned char c1, c2;
- unsigned char *label1, *label2;
-
- /*
- * Compare two absolute names as rdata.
- */
-
- REQUIRE(VALID_NAME(name1));
- REQUIRE(name1->labels > 0);
- REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) != 0);
- REQUIRE(VALID_NAME(name2));
- REQUIRE(name2->labels > 0);
- REQUIRE((name2->attributes & DNS_NAMEATTR_ABSOLUTE) != 0);
-
- l1 = name1->labels;
- l2 = name2->labels;
-
- l = (l1 < l2) ? l1 : l2;
-
- label1 = name1->ndata;
- label2 = name2->ndata;
- while (l > 0) {
- l--;
- count1 = *label1++;
- count2 = *label2++;
-
- /* no bitstring support */
- INSIST(count1 <= 63 && count2 <= 63);
-
- if (count1 != count2)
- return ((count1 < count2) ? -1 : 1);
- count = count1;
- while (count > 0) {
- count--;
- c1 = maptolower[*label1++];
- c2 = maptolower[*label2++];
- if (c1 < c2)
- return (-1);
- else if (c1 > c2)
- return (1);
- }
- }
-
- /*
- * If one name had more labels than the other, their common
- * prefix must have been different because the shorter name
- * ended with the root label and the longer one can't have
- * a root label in the middle of it. Therefore, if we get
- * to this point, the lengths must be equal.
- */
- INSIST(l1 == l2);
-
- return (0);
-}
-
-isc_boolean_t
-dns_name_issubdomain(const dns_name_t *name1, const dns_name_t *name2) {
- int order;
- unsigned int nlabels;
- dns_namereln_t namereln;
-
- /*
- * Is 'name1' a subdomain of 'name2'?
- *
- * Note: It makes no sense for one of the names to be relative and the
- * other absolute. If both names are relative, then to be meaningfully
- * compared the caller must ensure that they are both relative to the
- * same domain.
- */
-
- namereln = dns_name_fullcompare(name1, name2, &order, &nlabels);
- if (namereln == dns_namereln_subdomain ||
- namereln == dns_namereln_equal)
- return (ISC_TRUE);
-
- return (ISC_FALSE);
-}
-
-isc_boolean_t
-dns_name_matcheswildcard(const dns_name_t *name, const dns_name_t *wname) {
- int order;
- unsigned int nlabels, labels;
- dns_name_t tname;
-
- REQUIRE(VALID_NAME(name));
- REQUIRE(name->labels > 0);
- REQUIRE(VALID_NAME(wname));
- labels = wname->labels;
- REQUIRE(labels > 0);
- REQUIRE(dns_name_iswildcard(wname));
-
-#if defined(__clang__) && \
- ( __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 2))
- memset(&tname, 0, sizeof(tname));
-#endif
- DNS_NAME_INIT(&tname, NULL);
- dns_name_getlabelsequence(wname, 1, labels - 1, &tname);
- if (dns_name_fullcompare(name, &tname, &order, &nlabels) ==
- dns_namereln_subdomain)
- return (ISC_TRUE);
- return (ISC_FALSE);
-}
-
-unsigned int
-dns_name_countlabels(const dns_name_t *name) {
- /*
- * How many labels does 'name' have?
- */
-
- REQUIRE(VALID_NAME(name));
-
- ENSURE(name->labels <= 128);
-
- return (name->labels);
-}
-
-void
-dns_name_getlabel(const dns_name_t *name, unsigned int n, dns_label_t *label) {
- unsigned char *offsets;
- dns_offsets_t odata;
-
- /*
- * Make 'label' refer to the 'n'th least significant label of 'name'.
- */
-
- REQUIRE(VALID_NAME(name));
- REQUIRE(name->labels > 0);
- REQUIRE(n < name->labels);
- REQUIRE(label != NULL);
-
- SETUP_OFFSETS(name, offsets, odata);
-
- label->base = &name->ndata[offsets[n]];
- if (n == name->labels - 1)
- label->length = name->length - offsets[n];
- else
- label->length = offsets[n + 1] - offsets[n];
-}
-
-void
-dns_name_getlabelsequence(const dns_name_t *source,
- unsigned int first, unsigned int n,
- dns_name_t *target)
-{
- unsigned char *offsets;
- dns_offsets_t odata;
- unsigned int firstoffset, endoffset;
-
- /*
- * Make 'target' refer to the 'n' labels including and following
- * 'first' in 'source'.
- */
-
- REQUIRE(VALID_NAME(source));
- REQUIRE(VALID_NAME(target));
- REQUIRE(first <= source->labels);
- REQUIRE(n <= source->labels - first); /* note first+n could overflow */
- REQUIRE(BINDABLE(target));
-
- SETUP_OFFSETS(source, offsets, odata);
-
- if (first == source->labels)
- firstoffset = source->length;
- else
- firstoffset = offsets[first];
-
- if (first + n == source->labels)
- endoffset = source->length;
- else
- endoffset = offsets[first + n];
-
- target->ndata = &source->ndata[firstoffset];
- target->length = endoffset - firstoffset;
-
- if (first + n == source->labels && n > 0 &&
- (source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
- target->attributes |= DNS_NAMEATTR_ABSOLUTE;
- else
- target->attributes &= ~DNS_NAMEATTR_ABSOLUTE;
-
- target->labels = n;
-
- /*
- * If source and target are the same, and we're making target
- * a prefix of source, the offsets table is correct already
- * so we don't need to call set_offsets().
- */
- if (target->offsets != NULL &&
- (target != source || first != 0))
- set_offsets(target, target->offsets, NULL);
-}
-
-void
-dns_name_clone(const dns_name_t *source, dns_name_t *target) {
-
- /*
- * Make 'target' refer to the same name as 'source'.
- */
-
- REQUIRE(VALID_NAME(source));
- REQUIRE(VALID_NAME(target));
- REQUIRE(BINDABLE(target));
-
- target->ndata = source->ndata;
- target->length = source->length;
- target->labels = source->labels;
- target->attributes = source->attributes &
- (unsigned int)~(DNS_NAMEATTR_READONLY | DNS_NAMEATTR_DYNAMIC |
- DNS_NAMEATTR_DYNOFFSETS);
- if (target->offsets != NULL && source->labels > 0) {
- if (source->offsets != NULL)
- memcpy(target->offsets, source->offsets,
- source->labels);
- else
- set_offsets(target, target->offsets, NULL);
- }
-}
-
-void
-dns_name_fromregion(dns_name_t *name, const isc_region_t *r) {
- unsigned char *offsets;
- dns_offsets_t odata;
- unsigned int len;
- isc_region_t r2;
-
- /*
- * Make 'name' refer to region 'r'.
- */
-
- REQUIRE(VALID_NAME(name));
- REQUIRE(r != NULL);
- REQUIRE(BINDABLE(name));
-
- INIT_OFFSETS(name, offsets, odata);
-
- if (name->buffer != NULL) {
- isc_buffer_clear(name->buffer);
- isc_buffer_availableregion(name->buffer, &r2);
- len = (r->length < r2.length) ? r->length : r2.length;
- if (len > DNS_NAME_MAXWIRE)
- len = DNS_NAME_MAXWIRE;
- memcpy(r2.base, r->base, len);
- name->ndata = r2.base;
- name->length = len;
- } else {
- name->ndata = r->base;
- name->length = (r->length <= DNS_NAME_MAXWIRE) ?
- r->length : DNS_NAME_MAXWIRE;
- }
-
- if (r->length > 0)
- set_offsets(name, offsets, name);
- else {
- name->labels = 0;
- name->attributes &= ~DNS_NAMEATTR_ABSOLUTE;
- }
-
- if (name->buffer != NULL)
- isc_buffer_add(name->buffer, name->length);
-}
-
-void
-dns_name_toregion(dns_name_t *name, isc_region_t *r) {
- /*
- * Make 'r' refer to 'name'.
- */
-
- REQUIRE(VALID_NAME(name));
- REQUIRE(r != NULL);
-
- DNS_NAME_TOREGION(name, r);
-}
-
-isc_result_t
-dns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
- const dns_name_t *origin, unsigned int options,
- isc_buffer_t *target)
-{
- unsigned char *ndata, *label = NULL;
- char *tdata;
- char c;
- ft_state state;
- unsigned int value = 0, count = 0;
- unsigned int n1 = 0, n2 = 0;
- unsigned int tlen, nrem, nused, digits = 0, labels, tused;
- isc_boolean_t done;
- unsigned char *offsets;
- dns_offsets_t odata;
- isc_boolean_t downcase;
-
- /*
- * Convert the textual representation of a DNS name at source
- * into uncompressed wire form stored in target.
- *
- * Notes:
- * Relative domain names will have 'origin' appended to them
- * unless 'origin' is NULL, in which case relative domain names
- * will remain relative.
- */
-
- REQUIRE(VALID_NAME(name));
- REQUIRE(ISC_BUFFER_VALID(source));
- REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) ||
- (target == NULL && ISC_BUFFER_VALID(name->buffer)));
-
- downcase = ISC_TF((options & DNS_NAME_DOWNCASE) != 0);
-
- if (target == NULL && name->buffer != NULL) {
- target = name->buffer;
- isc_buffer_clear(target);
- }
-
- REQUIRE(BINDABLE(name));
-
- INIT_OFFSETS(name, offsets, odata);
- offsets[0] = 0;
-
- /*
- * Make 'name' empty in case of failure.
- */
- MAKE_EMPTY(name);
-
- /*
- * Set up the state machine.
- */
- tdata = (char *)source->base + source->current;
- tlen = isc_buffer_remaininglength(source);
- tused = 0;
- ndata = isc_buffer_used(target);
- nrem = isc_buffer_availablelength(target);
- if (nrem > 255)
- nrem = 255;
- nused = 0;
- labels = 0;
- done = ISC_FALSE;
- state = ft_init;
-
- while (nrem > 0 && tlen > 0 && !done) {
- c = *tdata++;
- tlen--;
- tused++;
-
- switch (state) {
- case ft_init:
- /*
- * Is this the root name?
- */
- if (c == '.') {
- if (tlen != 0)
- return (DNS_R_EMPTYLABEL);
- labels++;
- *ndata++ = 0;
- nrem--;
- nused++;
- done = ISC_TRUE;
- break;
- }
- if (c == '@' && tlen == 0) {
- state = ft_at;
- break;
- }
-
- /* FALLTHROUGH */
- case ft_start:
- label = ndata;
- ndata++;
- nrem--;
- nused++;
- count = 0;
- if (c == '\\') {
- state = ft_initialescape;
- break;
- }
- state = ft_ordinary;
- if (nrem == 0)
- return (ISC_R_NOSPACE);
- /* FALLTHROUGH */
- case ft_ordinary:
- if (c == '.') {
- if (count == 0)
- return (DNS_R_EMPTYLABEL);
- *label = count;
- labels++;
- INSIST(labels <= 127);
- offsets[labels] = nused;
- if (tlen == 0) {
- labels++;
- *ndata++ = 0;
- nrem--;
- nused++;
- done = ISC_TRUE;
- }
- state = ft_start;
- } else if (c == '\\') {
- state = ft_escape;
- } else {
- if (count >= 63)
- return (DNS_R_LABELTOOLONG);
- count++;
- CONVERTTOASCII(c);
- if (downcase)
- c = maptolower[(int)c];
- *ndata++ = c;
- nrem--;
- nused++;
- }
- break;
- case ft_initialescape:
- if (c == '[') {
- /*
- * This looks like a bitstring label, which
- * was deprecated. Intentionally drop it.
- */
- return (DNS_R_BADLABELTYPE);
- }
- state = ft_escape;
- POST(state);
- /* FALLTHROUGH */
- case ft_escape:
- if (!isdigit(c & 0xff)) {
- if (count >= 63)
- return (DNS_R_LABELTOOLONG);
- count++;
- CONVERTTOASCII(c);
- if (downcase)
- c = maptolower[(int)c];
- *ndata++ = c;
- nrem--;
- nused++;
- state = ft_ordinary;
- break;
- }
- digits = 0;
- value = 0;
- state = ft_escdecimal;
- /* FALLTHROUGH */
- case ft_escdecimal:
- if (!isdigit(c & 0xff))
- return (DNS_R_BADESCAPE);
- value *= 10;
- value += digitvalue[(int)c];
- digits++;
- if (digits == 3) {
- if (value > 255)
- return (DNS_R_BADESCAPE);
- if (count >= 63)
- return (DNS_R_LABELTOOLONG);
- count++;
- if (downcase)
- value = maptolower[value];
- *ndata++ = value;
- nrem--;
- nused++;
- state = ft_ordinary;
- }
- break;
- default:
- FATAL_ERROR(__FILE__, __LINE__,
- "Unexpected state %d", state);
- /* Does not return. */
- }
- }
-
- if (!done) {
- if (nrem == 0)
- return (ISC_R_NOSPACE);
- INSIST(tlen == 0);
- if (state != ft_ordinary && state != ft_at)
- return (ISC_R_UNEXPECTEDEND);
- if (state == ft_ordinary) {
- INSIST(count != 0);
- *label = count;
- labels++;
- INSIST(labels <= 127);
- offsets[labels] = nused;
- }
- if (origin != NULL) {
- if (nrem < origin->length)
- return (ISC_R_NOSPACE);
- label = origin->ndata;
- n1 = origin->length;
- nrem -= n1;
- POST(nrem);
- while (n1 > 0) {
- n2 = *label++;
- INSIST(n2 <= 63); /* no bitstring support */
- *ndata++ = n2;
- n1 -= n2 + 1;
- nused += n2 + 1;
- while (n2 > 0) {
- c = *label++;
- if (downcase)
- c = maptolower[(int)c];
- *ndata++ = c;
- n2--;
- }
- labels++;
- if (n1 > 0) {
- INSIST(labels <= 127);
- offsets[labels] = nused;
- }
- }
- if ((origin->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
- name->attributes |= DNS_NAMEATTR_ABSOLUTE;
- }
- } else
- name->attributes |= DNS_NAMEATTR_ABSOLUTE;
-
- name->ndata = (unsigned char *)target->base + target->used;
- name->labels = labels;
- name->length = nused;
-
- isc_buffer_forward(source, tused);
- isc_buffer_add(target, name->length);
-
- return (ISC_R_SUCCESS);
-}
-
-#ifdef ISC_PLATFORM_USETHREADS
-static void
-free_specific(void *arg) {
- dns_name_totextfilter_t *mem = arg;
- isc_mem_put(thread_key_mctx, mem, sizeof(*mem));
- /* Stop use being called again. */
- (void)isc_thread_key_setspecific(totext_filter_proc_key, NULL);
-}
-
-static void
-thread_key_mutex_init(void) {
- RUNTIME_CHECK(isc_mutex_init(&thread_key_mutex) == ISC_R_SUCCESS);
-}
-
-static isc_result_t
-totext_filter_proc_key_init(void) {
- isc_result_t result;
-
- /*
- * We need the call to isc_once_do() to support profiled mutex
- * otherwise thread_key_mutex could be initialized at compile time.
- */
- 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_mctx == NULL)
- result = isc_mem_create2(0, 0, &thread_key_mctx, 0);
- if (result != ISC_R_SUCCESS)
- goto unlock;
- isc_mem_setname(thread_key_mctx, "threadkey", NULL);
- isc_mem_setdestroycheck(thread_key_mctx, ISC_FALSE);
-
- if (!thread_key_initialized &&
- isc_thread_key_create(&totext_filter_proc_key,
- free_specific) != 0) {
- result = ISC_R_FAILURE;
- isc_mem_detach(&thread_key_mctx);
- } else
- thread_key_initialized = 1;
- unlock:
- UNLOCK(&thread_key_mutex);
- }
- return (result);
-}
-#endif
-
-isc_result_t
-dns_name_totext(dns_name_t *name, isc_boolean_t omit_final_dot,
- isc_buffer_t *target)
-{
- unsigned int options = DNS_NAME_MASTERFILE;
-
- if (omit_final_dot)
- options |= DNS_NAME_OMITFINALDOT;
- return (dns_name_totext2(name, options, target));
-}
-
-isc_result_t
-dns_name_toprincipal(dns_name_t *name, isc_buffer_t *target) {
- return (dns_name_totext2(name, DNS_NAME_OMITFINALDOT, target));
-}
-
-isc_result_t
-dns_name_totext2(dns_name_t *name, unsigned int options, isc_buffer_t *target)
-{
- unsigned char *ndata;
- char *tdata;
- unsigned int nlen, tlen;
- unsigned char c;
- unsigned int trem, count;
- unsigned int labels;
- isc_boolean_t saw_root = ISC_FALSE;
- unsigned int oused = target->used;
-#ifdef ISC_PLATFORM_USETHREADS
- dns_name_totextfilter_t *mem;
- dns_name_totextfilter_t totext_filter_proc = NULL;
- isc_result_t result;
-#endif
- isc_boolean_t omit_final_dot =
- ISC_TF(options & DNS_NAME_OMITFINALDOT);
-
- /*
- * This function assumes the name is in proper uncompressed
- * wire format.
- */
- REQUIRE(VALID_NAME(name));
- REQUIRE(ISC_BUFFER_VALID(target));
-
-#ifdef ISC_PLATFORM_USETHREADS
- result = totext_filter_proc_key_init();
- if (result != ISC_R_SUCCESS)
- return (result);
-#endif
- ndata = name->ndata;
- nlen = name->length;
- labels = name->labels;
- tdata = isc_buffer_used(target);
- tlen = isc_buffer_availablelength(target);
-
- trem = tlen;
-
- if (labels == 0 && nlen == 0) {
- /*
- * Special handling for an empty name.
- */
- if (trem == 0)
- return (ISC_R_NOSPACE);
-
- /*
- * The names of these booleans are misleading in this case.
- * This empty name is not necessarily from the root node of
- * the DNS root zone, nor is a final dot going to be included.
- * They need to be set this way, though, to keep the "@"
- * from being trounced.
- */
- saw_root = ISC_TRUE;
- omit_final_dot = ISC_FALSE;
- *tdata++ = '@';
- trem--;
-
- /*
- * Skip the while() loop.
- */
- nlen = 0;
- } else if (nlen == 1 && labels == 1 && *ndata == '\0') {
- /*
- * Special handling for the root label.
- */
- if (trem == 0)
- return (ISC_R_NOSPACE);
-
- saw_root = ISC_TRUE;
- omit_final_dot = ISC_FALSE;
- *tdata++ = '.';
- trem--;
-
- /*
- * Skip the while() loop.
- */
- nlen = 0;
- }
-
- while (labels > 0 && nlen > 0 && trem > 0) {
- labels--;
- count = *ndata++;
- nlen--;
- if (count == 0) {
- saw_root = ISC_TRUE;
- break;
- }
- if (count < 64) {
- INSIST(nlen >= count);
- while (count > 0) {
- c = *ndata;
- switch (c) {
- /* Special modifiers in zone files. */
- case 0x40: /* '@' */
- case 0x24: /* '$' */
- if ((options & DNS_NAME_MASTERFILE) == 0)
- goto no_escape;
- /* FALLTHROUGH */
- case 0x22: /* '"' */
- case 0x28: /* '(' */
- case 0x29: /* ')' */
- case 0x2E: /* '.' */
- case 0x3B: /* ';' */
- case 0x5C: /* '\\' */
- if (trem < 2)
- return (ISC_R_NOSPACE);
- *tdata++ = '\\';
- CONVERTFROMASCII(c);
- *tdata++ = c;
- ndata++;
- trem -= 2;
- nlen--;
- break;
- no_escape:
- default:
- if (c > 0x20 && c < 0x7f) {
- if (trem == 0)
- return (ISC_R_NOSPACE);
- CONVERTFROMASCII(c);
- *tdata++ = c;
- ndata++;
- trem--;
- nlen--;
- } else {
- if (trem < 4)
- return (ISC_R_NOSPACE);
- *tdata++ = 0x5c;
- *tdata++ = 0x30 +
- ((c / 100) % 10);
- *tdata++ = 0x30 +
- ((c / 10) % 10);
- *tdata++ = 0x30 + (c % 10);
- trem -= 4;
- ndata++;
- nlen--;
- }
- }
- count--;
- }
- } else {
- FATAL_ERROR(__FILE__, __LINE__,
- "Unexpected label type %02x", count);
- /* NOTREACHED */
- }
-
- /*
- * The following assumes names are absolute. If not, we
- * fix things up later. Note that this means that in some
- * cases one more byte of text buffer is required than is
- * needed in the final output.
- */
- if (trem == 0)
- return (ISC_R_NOSPACE);
- *tdata++ = '.';
- trem--;
- }
-
- if (nlen != 0 && trem == 0)
- return (ISC_R_NOSPACE);
-
- if (!saw_root || omit_final_dot)
- trem++;
-
- isc_buffer_add(target, tlen - trem);
-
-#ifdef ISC_PLATFORM_USETHREADS
- mem = isc_thread_key_getspecific(totext_filter_proc_key);
- if (mem != NULL)
- totext_filter_proc = *mem;
-#endif
- if (totext_filter_proc != NULL)
- return ((*totext_filter_proc)(target, oused, saw_root));
-
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_name_tofilenametext(dns_name_t *name, isc_boolean_t omit_final_dot,
- isc_buffer_t *target)
-{
- unsigned char *ndata;
- char *tdata;
- unsigned int nlen, tlen;
- unsigned char c;
- unsigned int trem, count;
- unsigned int labels;
-
- /*
- * This function assumes the name is in proper uncompressed
- * wire format.
- */
- REQUIRE(VALID_NAME(name));
- REQUIRE((name->attributes & DNS_NAMEATTR_ABSOLUTE) != 0);
- REQUIRE(ISC_BUFFER_VALID(target));
-
- ndata = name->ndata;
- nlen = name->length;
- labels = name->labels;
- tdata = isc_buffer_used(target);
- tlen = isc_buffer_availablelength(target);
-
- trem = tlen;
-
- if (nlen == 1 && labels == 1 && *ndata == '\0') {
- /*
- * Special handling for the root label.
- */
- if (trem == 0)
- return (ISC_R_NOSPACE);
-
- omit_final_dot = ISC_FALSE;
- *tdata++ = '.';
- trem--;
-
- /*
- * Skip the while() loop.
- */
- nlen = 0;
- }
-
- while (labels > 0 && nlen > 0 && trem > 0) {
- labels--;
- count = *ndata++;
- nlen--;
- if (count == 0)
- break;
- if (count < 64) {
- INSIST(nlen >= count);
- while (count > 0) {
- c = *ndata;
- if ((c >= 0x30 && c <= 0x39) || /* digit */
- (c >= 0x41 && c <= 0x5A) || /* uppercase */
- (c >= 0x61 && c <= 0x7A) || /* lowercase */
- c == 0x2D || /* hyphen */
- c == 0x5F) /* underscore */
- {
- if (trem == 0)
- return (ISC_R_NOSPACE);
- /* downcase */
- if (c >= 0x41 && c <= 0x5A)
- c += 0x20;
- CONVERTFROMASCII(c);
- *tdata++ = c;
- ndata++;
- trem--;
- nlen--;
- } else {
- if (trem < 3)
- return (ISC_R_NOSPACE);
- sprintf(tdata, "%%%02X", c);
- tdata += 3;
- trem -= 3;
- ndata++;
- nlen--;
- }
- count--;
- }
- } else {
- FATAL_ERROR(__FILE__, __LINE__,
- "Unexpected label type %02x", count);
- /* NOTREACHED */
- }
-
- /*
- * The following assumes names are absolute. If not, we
- * fix things up later. Note that this means that in some
- * cases one more byte of text buffer is required than is
- * needed in the final output.
- */
- if (trem == 0)
- return (ISC_R_NOSPACE);
- *tdata++ = '.';
- trem--;
- }
-
- if (nlen != 0 && trem == 0)
- return (ISC_R_NOSPACE);
-
- if (omit_final_dot)
- trem++;
-
- isc_buffer_add(target, tlen - trem);
-
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_name_downcase(dns_name_t *source, dns_name_t *name, isc_buffer_t *target) {
- unsigned char *sndata, *ndata;
- unsigned int nlen, count, labels;
- isc_buffer_t buffer;
-
- /*
- * Downcase 'source'.
- */
-
- REQUIRE(VALID_NAME(source));
- REQUIRE(VALID_NAME(name));
- if (source == name) {
- REQUIRE((name->attributes & DNS_NAMEATTR_READONLY) == 0);
- isc_buffer_init(&buffer, source->ndata, source->length);
- target = &buffer;
- ndata = source->ndata;
- } else {
- REQUIRE(BINDABLE(name));
- REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) ||
- (target == NULL && ISC_BUFFER_VALID(name->buffer)));
- if (target == NULL) {
- target = name->buffer;
- isc_buffer_clear(name->buffer);
- }
- ndata = (unsigned char *)target->base + target->used;
- name->ndata = ndata;
- }
-
- sndata = source->ndata;
- nlen = source->length;
- labels = source->labels;
-
- if (nlen > (target->length - target->used)) {
- MAKE_EMPTY(name);
- return (ISC_R_NOSPACE);
- }
-
- while (labels > 0 && nlen > 0) {
- labels--;
- count = *sndata++;
- *ndata++ = count;
- nlen--;
- if (count < 64) {
- INSIST(nlen >= count);
- while (count > 0) {
- *ndata++ = maptolower[(*sndata++)];
- nlen--;
- count--;
- }
- } else {
- FATAL_ERROR(__FILE__, __LINE__,
- "Unexpected label type %02x", count);
- /* Does not return. */
- }
- }
-
- if (source != name) {
- name->labels = source->labels;
- name->length = source->length;
- if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
- name->attributes = DNS_NAMEATTR_ABSOLUTE;
- else
- name->attributes = 0;
- if (name->labels > 0 && name->offsets != NULL)
- set_offsets(name, name->offsets, NULL);
- }
-
- isc_buffer_add(target, name->length);
-
- return (ISC_R_SUCCESS);
-}
-
-static void
-set_offsets(const dns_name_t *name, unsigned char *offsets,
- dns_name_t *set_name)
-{
- unsigned int offset, count, length, nlabels;
- unsigned char *ndata;
- isc_boolean_t absolute;
-
- ndata = name->ndata;
- length = name->length;
- offset = 0;
- nlabels = 0;
- absolute = ISC_FALSE;
- while (offset != length) {
- INSIST(nlabels < 128);
- offsets[nlabels++] = offset;
- count = *ndata++;
- offset++;
- INSIST(count <= 63);
- offset += count;
- ndata += count;
- INSIST(offset <= length);
- if (count == 0) {
- absolute = ISC_TRUE;
- break;
- }
- }
- if (set_name != NULL) {
- INSIST(set_name == name);
-
- set_name->labels = nlabels;
- set_name->length = offset;
- if (absolute)
- set_name->attributes |= DNS_NAMEATTR_ABSOLUTE;
- else
- set_name->attributes &= ~DNS_NAMEATTR_ABSOLUTE;
- }
- INSIST(nlabels == name->labels);
- INSIST(offset == name->length);
-}
-
-isc_result_t
-dns_name_fromwire(dns_name_t *name, isc_buffer_t *source,
- dns_decompress_t *dctx, unsigned int options,
- isc_buffer_t *target)
-{
- unsigned char *cdata, *ndata;
- unsigned int cused; /* Bytes of compressed name data used */
- unsigned int nused, labels, n, nmax;
- unsigned int current, new_current, biggest_pointer;
- isc_boolean_t done;
- fw_state state = fw_start;
- unsigned int c;
- unsigned char *offsets;
- dns_offsets_t odata;
- isc_boolean_t downcase;
- isc_boolean_t seen_pointer;
-
- /*
- * Copy the possibly-compressed name at source into target,
- * decompressing it. Loop prevention is performed by checking
- * the new pointer against biggest_pointer.
- */
-
- REQUIRE(VALID_NAME(name));
- REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) ||
- (target == NULL && ISC_BUFFER_VALID(name->buffer)));
-
- downcase = ISC_TF((options & DNS_NAME_DOWNCASE) != 0);
-
- if (target == NULL && name->buffer != NULL) {
- target = name->buffer;
- isc_buffer_clear(target);
- }
-
- REQUIRE(dctx != NULL);
- REQUIRE(BINDABLE(name));
-
- INIT_OFFSETS(name, offsets, odata);
-
- /*
- * Make 'name' empty in case of failure.
- */
- MAKE_EMPTY(name);
-
- /*
- * Initialize things to make the compiler happy; they're not required.
- */
- n = 0;
- new_current = 0;
-
- /*
- * Set up.
- */
- labels = 0;
- done = ISC_FALSE;
-
- ndata = isc_buffer_used(target);
- nused = 0;
- seen_pointer = ISC_FALSE;
-
- /*
- * Find the maximum number of uncompressed target name
- * bytes we are willing to generate. This is the smaller
- * of the available target buffer length and the
- * maximum legal domain name length (255).
- */
- nmax = isc_buffer_availablelength(target);
- if (nmax > DNS_NAME_MAXWIRE)
- nmax = DNS_NAME_MAXWIRE;
-
- cdata = isc_buffer_current(source);
- cused = 0;
-
- current = source->current;
- biggest_pointer = current;
-
- /*
- * Note: The following code is not optimized for speed, but
- * rather for correctness. Speed will be addressed in the future.
- */
-
- while (current < source->active && !done) {
- c = *cdata++;
- current++;
- if (!seen_pointer)
- cused++;
-
- switch (state) {
- case fw_start:
- if (c < 64) {
- offsets[labels] = nused;
- labels++;
- if (nused + c + 1 > nmax)
- goto full;
- nused += c + 1;
- *ndata++ = c;
- if (c == 0)
- done = ISC_TRUE;
- n = c;
- state = fw_ordinary;
- } else if (c >= 128 && c < 192) {
- /*
- * 14 bit local compression pointer.
- * Local compression is no longer an
- * IETF draft.
- */
- return (DNS_R_BADLABELTYPE);
- } else if (c >= 192) {
- /*
- * Ordinary 14-bit pointer.
- */
- if ((dctx->allowed & DNS_COMPRESS_GLOBAL14) ==
- 0)
- return (DNS_R_DISALLOWED);
- new_current = c & 0x3F;
- n = 1;
- state = fw_newcurrent;
- } else
- return (DNS_R_BADLABELTYPE);
- break;
- case fw_ordinary:
- if (downcase)
- c = maptolower[c];
- /* FALLTHROUGH */
- case fw_copy:
- *ndata++ = c;
- n--;
- if (n == 0)
- state = fw_start;
- break;
- case fw_newcurrent:
- new_current *= 256;
- new_current += c;
- n--;
- if (n != 0)
- break;
- if (new_current >= biggest_pointer)
- return (DNS_R_BADPOINTER);
- biggest_pointer = new_current;
- current = new_current;
- cdata = (unsigned char *)source->base + current;
- seen_pointer = ISC_TRUE;
- state = fw_start;
- break;
- default:
- FATAL_ERROR(__FILE__, __LINE__,
- "Unknown state %d", state);
- /* Does not return. */
- }
- }
-
- if (!done)
- return (ISC_R_UNEXPECTEDEND);
-
- name->ndata = (unsigned char *)target->base + target->used;
- name->labels = labels;
- name->length = nused;
- name->attributes |= DNS_NAMEATTR_ABSOLUTE;
-
- isc_buffer_forward(source, cused);
- isc_buffer_add(target, name->length);
-
- return (ISC_R_SUCCESS);
-
- full:
- if (nmax == DNS_NAME_MAXWIRE)
- /*
- * The name did not fit even though we had a buffer
- * big enough to fit a maximum-length name.
- */
- return (DNS_R_NAMETOOLONG);
- else
- /*
- * The name might fit if only the caller could give us a
- * big enough buffer.
- */
- return (ISC_R_NOSPACE);
-}
-
-isc_result_t
-dns_name_towire(const dns_name_t *name, dns_compress_t *cctx,
- isc_buffer_t *target)
-{
- unsigned int methods;
- isc_uint16_t offset;
- dns_name_t gp; /* Global compression prefix */
- isc_boolean_t gf; /* Global compression target found */
- isc_uint16_t go; /* Global compression offset */
- dns_offsets_t clo;
- dns_name_t clname;
-
- /*
- * Convert 'name' into wire format, compressing it as specified by the
- * compression context 'cctx', and storing the result in 'target'.
- */
-
- REQUIRE(VALID_NAME(name));
- REQUIRE(cctx != NULL);
- REQUIRE(ISC_BUFFER_VALID(target));
-
- /*
- * If 'name' doesn't have an offsets table, make a clone which
- * has one.
- */
- if (name->offsets == NULL) {
-#if defined(__clang__) && \
- ( __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 2))
- memset(&clname, 0, sizeof(clname));
-#endif
- DNS_NAME_INIT(&clname, clo);
- dns_name_clone(name, &clname);
- name = &clname;
- }
- DNS_NAME_INIT(&gp, NULL);
-
- offset = target->used; /*XXX*/
-
- methods = dns_compress_getmethods(cctx);
-
- if ((name->attributes & DNS_NAMEATTR_NOCOMPRESS) == 0 &&
- (methods & DNS_COMPRESS_GLOBAL14) != 0)
- gf = dns_compress_findglobal(cctx, name, &gp, &go);
- else
- gf = ISC_FALSE;
-
- /*
- * If the offset is too high for 14 bit global compression, we're
- * out of luck.
- */
- if (gf && go >= 0x4000)
- gf = ISC_FALSE;
-
- /*
- * Will the compression pointer reduce the message size?
- */
- if (gf && (gp.length + 2) >= name->length)
- gf = ISC_FALSE;
-
- if (gf) {
- if (target->length - target->used < gp.length)
- return (ISC_R_NOSPACE);
- (void)memcpy((unsigned char *)target->base + target->used,
- gp.ndata, (size_t)gp.length);
- isc_buffer_add(target, gp.length);
- go |= 0xc000;
- if (target->length - target->used < 2)
- return (ISC_R_NOSPACE);
- isc_buffer_putuint16(target, go);
- if (gp.length != 0)
- dns_compress_add(cctx, name, &gp, offset);
- } else {
- if (target->length - target->used < name->length)
- return (ISC_R_NOSPACE);
- (void)memcpy((unsigned char *)target->base + target->used,
- name->ndata, (size_t)name->length);
- isc_buffer_add(target, name->length);
- dns_compress_add(cctx, name, name, offset);
- }
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_name_concatenate(dns_name_t *prefix, dns_name_t *suffix, dns_name_t *name,
- isc_buffer_t *target)
-{
- unsigned char *ndata, *offsets;
- unsigned int nrem, labels, prefix_length, length;
- isc_boolean_t copy_prefix = ISC_TRUE;
- isc_boolean_t copy_suffix = ISC_TRUE;
- isc_boolean_t absolute = ISC_FALSE;
- dns_name_t tmp_name;
- dns_offsets_t odata;
-
- /*
- * Concatenate 'prefix' and 'suffix'.
- */
-
- REQUIRE(prefix == NULL || VALID_NAME(prefix));
- REQUIRE(suffix == NULL || VALID_NAME(suffix));
- REQUIRE(name == NULL || VALID_NAME(name));
- REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) ||
- (target == NULL && name != NULL && ISC_BUFFER_VALID(name->buffer)));
- if (prefix == NULL || prefix->labels == 0)
- copy_prefix = ISC_FALSE;
- if (suffix == NULL || suffix->labels == 0)
- copy_suffix = ISC_FALSE;
- if (copy_prefix &&
- (prefix->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) {
- absolute = ISC_TRUE;
- REQUIRE(!copy_suffix);
- }
- if (name == NULL) {
- DNS_NAME_INIT(&tmp_name, odata);
- name = &tmp_name;
- }
- if (target == NULL) {
- INSIST(name->buffer != NULL);
- target = name->buffer;
- isc_buffer_clear(name->buffer);
- }
-
- REQUIRE(BINDABLE(name));
-
- /*
- * Set up.
- */
- nrem = target->length - target->used;
- ndata = (unsigned char *)target->base + target->used;
- if (nrem > DNS_NAME_MAXWIRE)
- nrem = DNS_NAME_MAXWIRE;
- length = 0;
- prefix_length = 0;
- labels = 0;
- if (copy_prefix) {
- prefix_length = prefix->length;
- length += prefix_length;
- labels += prefix->labels;
- }
- if (copy_suffix) {
- length += suffix->length;
- labels += suffix->labels;
- }
- if (length > DNS_NAME_MAXWIRE) {
- MAKE_EMPTY(name);
- return (DNS_R_NAMETOOLONG);
- }
- if (length > nrem) {
- MAKE_EMPTY(name);
- return (ISC_R_NOSPACE);
- }
-
- if (copy_suffix) {
- if ((suffix->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
- absolute = ISC_TRUE;
- if (suffix == name && suffix->buffer == target)
- memmove(ndata + prefix_length, suffix->ndata,
- suffix->length);
- else
- memcpy(ndata + prefix_length, suffix->ndata,
- suffix->length);
- }
-
- /*
- * If 'prefix' and 'name' are the same object, and the object has
- * a dedicated buffer, and we're using it, then we don't have to
- * copy anything.
- */
- if (copy_prefix && (prefix != name || prefix->buffer != target))
- memcpy(ndata, prefix->ndata, prefix_length);
-
- name->ndata = ndata;
- name->labels = labels;
- name->length = length;
- if (absolute)
- name->attributes = DNS_NAMEATTR_ABSOLUTE;
- else
- name->attributes = 0;
-
- if (name->labels > 0 && name->offsets != NULL) {
- INIT_OFFSETS(name, offsets, odata);
- set_offsets(name, offsets, NULL);
- }
-
- isc_buffer_add(target, name->length);
-
- return (ISC_R_SUCCESS);
-}
-
-void
-dns_name_split(dns_name_t *name, unsigned int suffixlabels,
- dns_name_t *prefix, dns_name_t *suffix)
-
-{
- unsigned int splitlabel;
-
- REQUIRE(VALID_NAME(name));
- REQUIRE(suffixlabels > 0);
- REQUIRE(suffixlabels < name->labels);
- REQUIRE(prefix != NULL || suffix != NULL);
- REQUIRE(prefix == NULL ||
- (VALID_NAME(prefix) &&
- prefix->buffer != NULL &&
- BINDABLE(prefix)));
- REQUIRE(suffix == NULL ||
- (VALID_NAME(suffix) &&
- suffix->buffer != NULL &&
- BINDABLE(suffix)));
-
- splitlabel = name->labels - suffixlabels;
-
- if (prefix != NULL)
- dns_name_getlabelsequence(name, 0, splitlabel, prefix);
-
- if (suffix != NULL)
- dns_name_getlabelsequence(name, splitlabel,
- suffixlabels, suffix);
-
- return;
-}
-
-isc_result_t
-dns_name_dup(const dns_name_t *source, isc_mem_t *mctx,
- dns_name_t *target)
-{
- /*
- * Make 'target' a dynamically allocated copy of 'source'.
- */
-
- REQUIRE(VALID_NAME(source));
- REQUIRE(source->length > 0);
- REQUIRE(VALID_NAME(target));
- REQUIRE(BINDABLE(target));
-
- /*
- * Make 'target' empty in case of failure.
- */
- MAKE_EMPTY(target);
-
- target->ndata = isc_mem_get(mctx, source->length);
- if (target->ndata == NULL)
- return (ISC_R_NOMEMORY);
-
- memcpy(target->ndata, source->ndata, source->length);
-
- target->length = source->length;
- target->labels = source->labels;
- target->attributes = DNS_NAMEATTR_DYNAMIC;
- if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
- target->attributes |= DNS_NAMEATTR_ABSOLUTE;
- if (target->offsets != NULL) {
- if (source->offsets != NULL)
- memcpy(target->offsets, source->offsets,
- source->labels);
- else
- set_offsets(target, target->offsets, NULL);
- }
-
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_name_dupwithoffsets(dns_name_t *source, isc_mem_t *mctx,
- dns_name_t *target)
-{
- /*
- * Make 'target' a read-only dynamically allocated copy of 'source'.
- * 'target' will also have a dynamically allocated offsets table.
- */
-
- REQUIRE(VALID_NAME(source));
- REQUIRE(source->length > 0);
- REQUIRE(VALID_NAME(target));
- REQUIRE(BINDABLE(target));
- REQUIRE(target->offsets == NULL);
-
- /*
- * Make 'target' empty in case of failure.
- */
- MAKE_EMPTY(target);
-
- target->ndata = isc_mem_get(mctx, source->length + source->labels);
- if (target->ndata == NULL)
- return (ISC_R_NOMEMORY);
-
- memcpy(target->ndata, source->ndata, source->length);
-
- target->length = source->length;
- target->labels = source->labels;
- target->attributes = DNS_NAMEATTR_DYNAMIC | DNS_NAMEATTR_DYNOFFSETS |
- DNS_NAMEATTR_READONLY;
- if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
- target->attributes |= DNS_NAMEATTR_ABSOLUTE;
- target->offsets = target->ndata + source->length;
- if (source->offsets != NULL)
- memcpy(target->offsets, source->offsets, source->labels);
- else
- set_offsets(target, target->offsets, NULL);
-
- return (ISC_R_SUCCESS);
-}
-
-void
-dns_name_free(dns_name_t *name, isc_mem_t *mctx) {
- size_t size;
-
- /*
- * Free 'name'.
- */
-
- REQUIRE(VALID_NAME(name));
- REQUIRE((name->attributes & DNS_NAMEATTR_DYNAMIC) != 0);
-
- size = name->length;
- if ((name->attributes & DNS_NAMEATTR_DYNOFFSETS) != 0)
- size += name->labels;
- isc_mem_put(mctx, name->ndata, size);
- dns_name_invalidate(name);
-}
-
-isc_result_t
-dns_name_digest(dns_name_t *name, dns_digestfunc_t digest, void *arg) {
- dns_name_t downname;
- unsigned char data[256];
- isc_buffer_t buffer;
- isc_result_t result;
- isc_region_t r;
-
- /*
- * Send 'name' in DNSSEC canonical form to 'digest'.
- */
-
- REQUIRE(VALID_NAME(name));
- REQUIRE(digest != NULL);
-
-#if defined(__clang__) && \
- ( __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 2))
- memset(&downname, 0, sizeof(downname));
-#endif
- DNS_NAME_INIT(&downname, NULL);
-
- isc_buffer_init(&buffer, data, sizeof(data));
-
- result = dns_name_downcase(name, &downname, &buffer);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- isc_buffer_usedregion(&buffer, &r);
-
- return ((digest)(arg, &r));
-}
-
-isc_boolean_t
-dns_name_dynamic(dns_name_t *name) {
- REQUIRE(VALID_NAME(name));
-
- /*
- * Returns whether there is dynamic memory associated with this name.
- */
-
- return ((name->attributes & DNS_NAMEATTR_DYNAMIC) != 0 ?
- ISC_TRUE : ISC_FALSE);
-}
-
-isc_result_t
-dns_name_print(dns_name_t *name, FILE *stream) {
- isc_result_t result;
- isc_buffer_t b;
- isc_region_t r;
- char t[1024];
-
- /*
- * Print 'name' on 'stream'.
- */
-
- REQUIRE(VALID_NAME(name));
-
- isc_buffer_init(&b, t, sizeof(t));
- result = dns_name_totext(name, ISC_FALSE, &b);
- if (result != ISC_R_SUCCESS)
- return (result);
- isc_buffer_usedregion(&b, &r);
- fprintf(stream, "%.*s", (int)r.length, (char *)r.base);
-
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_name_settotextfilter(dns_name_totextfilter_t proc) {
-#ifdef ISC_PLATFORM_USETHREADS
- isc_result_t result;
- dns_name_totextfilter_t *mem;
- int res;
-
- result = totext_filter_proc_key_init();
- if (result != ISC_R_SUCCESS)
- return (result);
-
- /*
- * If we already have been here set / clear as appropriate.
- * Otherwise allocate memory.
- */
- mem = isc_thread_key_getspecific(totext_filter_proc_key);
- if (mem != NULL && proc != NULL) {
- *mem = proc;
- return (ISC_R_SUCCESS);
- }
- if (proc == NULL) {
- isc_mem_put(thread_key_mctx, mem, sizeof(*mem));
- res = isc_thread_key_setspecific(totext_filter_proc_key, NULL);
- if (res != 0)
- result = ISC_R_UNEXPECTED;
- return (result);
- }
-
- mem = isc_mem_get(thread_key_mctx, sizeof(*mem));
- if (mem == NULL)
- return (ISC_R_NOMEMORY);
- *mem = proc;
- if (isc_thread_key_setspecific(totext_filter_proc_key, mem) != 0) {
- isc_mem_put(thread_key_mctx, mem, sizeof(*mem));
- result = ISC_R_UNEXPECTED;
- }
- return (result);
-#else
- totext_filter_proc = proc;
- return (ISC_R_SUCCESS);
-#endif
-}
-
-void
-dns_name_format(dns_name_t *name, char *cp, unsigned int size) {
- isc_result_t result;
- isc_buffer_t buf;
-
- REQUIRE(size > 0);
-
- /*
- * Leave room for null termination after buffer.
- */
- isc_buffer_init(&buf, cp, size - 1);
- result = dns_name_totext(name, ISC_TRUE, &buf);
- if (result == ISC_R_SUCCESS) {
- /*
- * Null terminate.
- */
- isc_region_t r;
- isc_buffer_usedregion(&buf, &r);
- ((char *) r.base)[r.length] = '\0';
-
- } else
- 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_constinit(&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;
-
- /*
- * Make dest a copy of source.
- */
-
- REQUIRE(VALID_NAME(source));
- REQUIRE(VALID_NAME(dest));
- REQUIRE(target != NULL || dest->buffer != NULL);
-
- if (target == NULL) {
- target = dest->buffer;
- isc_buffer_clear(dest->buffer);
- }
-
- REQUIRE(BINDABLE(dest));
-
- /*
- * Set up.
- */
- if (target->length - target->used < source->length)
- return (ISC_R_NOSPACE);
-
- ndata = (unsigned char *)target->base + target->used;
- dest->ndata = target->base;
-
- memcpy(ndata, source->ndata, source->length);
-
- dest->ndata = ndata;
- dest->labels = source->labels;
- dest->length = source->length;
- if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
- dest->attributes = DNS_NAMEATTR_ABSOLUTE;
- else
- dest->attributes = 0;
-
- if (dest->labels > 0 && dest->offsets != NULL) {
- if (source->offsets != NULL)
- memcpy(dest->offsets, source->offsets, source->labels);
- else
- set_offsets(dest, dest->offsets, NULL);
- }
-
- isc_buffer_add(target, dest->length);
-
- return (ISC_R_SUCCESS);
-}
-
-void
-dns_name_destroy(void) {
-#ifdef ISC_PLATFORM_USETHREADS
- RUNTIME_CHECK(isc_once_do(&once, thread_key_mutex_init)
- == ISC_R_SUCCESS);
-
- LOCK(&thread_key_mutex);
- if (thread_key_initialized) {
- isc_mem_detach(&thread_key_mctx);
- isc_thread_key_delete(totext_filter_proc_key);
- thread_key_initialized = 0;
- }
- UNLOCK(&thread_key_mutex);
-
-#endif
-}
diff --git a/contrib/bind9/lib/dns/ncache.c b/contrib/bind9/lib/dns/ncache.c
deleted file mode 100644
index bcb3d057898d..000000000000
--- a/contrib/bind9/lib/dns/ncache.c
+++ /dev/null
@@ -1,756 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007, 2008, 2010-2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <isc/buffer.h>
-#include <isc/util.h>
-
-#include <dns/db.h>
-#include <dns/message.h>
-#include <dns/ncache.h>
-#include <dns/rdata.h>
-#include <dns/rdatalist.h>
-#include <dns/rdataset.h>
-#include <dns/rdatastruct.h>
-
-#define DNS_NCACHE_RDATA 20U
-
-/*
- * The format of an ncache rdata is a sequence of zero or more records of
- * the following format:
- *
- * owner name
- * type
- * trust
- * rdata count
- * rdata length These two occur 'rdata count'
- * rdata times.
- *
- */
-
-static isc_result_t
-addoptout(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
- dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl,
- isc_boolean_t optout, isc_boolean_t secure,
- dns_rdataset_t *addedrdataset);
-
-static inline isc_result_t
-copy_rdataset(dns_rdataset_t *rdataset, isc_buffer_t *buffer) {
- isc_result_t result;
- unsigned int count;
- isc_region_t ar, r;
- dns_rdata_t rdata = DNS_RDATA_INIT;
-
- /*
- * Copy the rdataset count to the buffer.
- */
- isc_buffer_availableregion(buffer, &ar);
- if (ar.length < 2)
- return (ISC_R_NOSPACE);
- count = dns_rdataset_count(rdataset);
- INSIST(count <= 65535);
- isc_buffer_putuint16(buffer, (isc_uint16_t)count);
-
- result = dns_rdataset_first(rdataset);
- while (result == ISC_R_SUCCESS) {
- dns_rdataset_current(rdataset, &rdata);
- dns_rdata_toregion(&rdata, &r);
- INSIST(r.length <= 65535);
- isc_buffer_availableregion(buffer, &ar);
- if (ar.length < 2)
- return (ISC_R_NOSPACE);
- /*
- * Copy the rdata length to the buffer.
- */
- isc_buffer_putuint16(buffer, (isc_uint16_t)r.length);
- /*
- * Copy the rdata to the buffer.
- */
- result = isc_buffer_copyregion(buffer, &r);
- if (result != ISC_R_SUCCESS)
- return (result);
- dns_rdata_reset(&rdata);
- result = dns_rdataset_next(rdataset);
- }
- if (result != ISC_R_NOMORE)
- return (result);
-
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_ncache_add(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
- dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl,
- dns_rdataset_t *addedrdataset)
-{
- return (addoptout(message, cache, node, covers, now, maxttl,
- ISC_FALSE, ISC_FALSE, addedrdataset));
-}
-
-isc_result_t
-dns_ncache_addoptout(dns_message_t *message, dns_db_t *cache,
- dns_dbnode_t *node, dns_rdatatype_t covers,
- isc_stdtime_t now, dns_ttl_t maxttl,
- isc_boolean_t optout, dns_rdataset_t *addedrdataset)
-{
- return (addoptout(message, cache, node, covers, now, maxttl,
- optout, ISC_TRUE, addedrdataset));
-}
-
-static isc_result_t
-addoptout(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
- dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl,
- isc_boolean_t optout, isc_boolean_t secure,
- dns_rdataset_t *addedrdataset)
-{
- isc_result_t result;
- isc_buffer_t buffer;
- isc_region_t r;
- dns_rdataset_t *rdataset;
- dns_rdatatype_t type;
- dns_name_t *name;
- dns_ttl_t ttl;
- dns_trust_t trust;
- dns_rdata_t rdata[DNS_NCACHE_RDATA];
- dns_rdataset_t ncrdataset;
- dns_rdatalist_t ncrdatalist;
- unsigned char data[4096];
- unsigned int next = 0;
-
- /*
- * Convert the authority data from 'message' into a negative cache
- * rdataset, and store it in 'cache' at 'node'.
- */
-
- REQUIRE(message != NULL);
-
- /*
- * We assume that all data in the authority section has been
- * validated by the caller.
- */
-
- /*
- * Initialize the list.
- */
- ncrdatalist.rdclass = dns_db_class(cache);
- ncrdatalist.type = 0;
- ncrdatalist.covers = covers;
- ncrdatalist.ttl = maxttl;
- ISC_LIST_INIT(ncrdatalist.rdata);
- ISC_LINK_INIT(&ncrdatalist, link);
-
- /*
- * Build an ncache rdatas into buffer.
- */
- ttl = maxttl;
- trust = 0xffff;
- isc_buffer_init(&buffer, data, sizeof(data));
- if (message->counts[DNS_SECTION_AUTHORITY])
- result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
- else
- result = ISC_R_NOMORE;
- while (result == ISC_R_SUCCESS) {
- name = NULL;
- dns_message_currentname(message, DNS_SECTION_AUTHORITY,
- &name);
- if ((name->attributes & DNS_NAMEATTR_NCACHE) != 0) {
- for (rdataset = ISC_LIST_HEAD(name->list);
- rdataset != NULL;
- rdataset = ISC_LIST_NEXT(rdataset, link)) {
- if ((rdataset->attributes &
- DNS_RDATASETATTR_NCACHE) == 0)
- continue;
- type = rdataset->type;
- if (type == dns_rdatatype_rrsig)
- type = rdataset->covers;
- if (type == dns_rdatatype_soa ||
- type == dns_rdatatype_nsec ||
- type == dns_rdatatype_nsec3) {
- if (ttl > rdataset->ttl)
- ttl = rdataset->ttl;
- if (trust > rdataset->trust)
- trust = rdataset->trust;
- /*
- * Copy the owner name to the buffer.
- */
- dns_name_toregion(name, &r);
- result = isc_buffer_copyregion(&buffer,
- &r);
- if (result != ISC_R_SUCCESS)
- return (result);
- /*
- * Copy the type to the buffer.
- */
- isc_buffer_availableregion(&buffer,
- &r);
- if (r.length < 3)
- return (ISC_R_NOSPACE);
- isc_buffer_putuint16(&buffer,
- rdataset->type);
- isc_buffer_putuint8(&buffer,
- (unsigned char)rdataset->trust);
- /*
- * Copy the rdataset into the buffer.
- */
- result = copy_rdataset(rdataset,
- &buffer);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- 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);
- isc_buffer_forward(&buffer, r.length);
- next++;
- }
- }
- }
- result = dns_message_nextname(message, DNS_SECTION_AUTHORITY);
- }
- if (result != ISC_R_NOMORE)
- return (result);
-
- if (trust == 0xffff) {
- if ((message->flags & DNS_MESSAGEFLAG_AA) != 0 &&
- message->counts[DNS_SECTION_ANSWER] == 0) {
- /*
- * The response has aa set and we haven't followed
- * any CNAME or DNAME chains.
- */
- trust = dns_trust_authauthority;
- } else
- trust = dns_trust_additional;
- ttl = 0;
- }
-
- INSIST(trust != 0xffff);
-
- ncrdatalist.ttl = ttl;
-
- dns_rdataset_init(&ncrdataset);
- RUNTIME_CHECK(dns_rdatalist_tordataset(&ncrdatalist, &ncrdataset)
- == ISC_R_SUCCESS);
- if (!secure && trust > dns_trust_answer)
- trust = dns_trust_answer;
- ncrdataset.trust = trust;
- ncrdataset.attributes |= DNS_RDATASETATTR_NEGATIVE;
- if (message->rcode == dns_rcode_nxdomain)
- ncrdataset.attributes |= DNS_RDATASETATTR_NXDOMAIN;
- if (optout)
- ncrdataset.attributes |= DNS_RDATASETATTR_OPTOUT;
-
- return (dns_db_addrdataset(cache, node, NULL, now, &ncrdataset,
- 0, addedrdataset));
-}
-
-isc_result_t
-dns_ncache_towire(dns_rdataset_t *rdataset, dns_compress_t *cctx,
- isc_buffer_t *target, unsigned int options,
- unsigned int *countp)
-{
- dns_rdata_t rdata = DNS_RDATA_INIT;
- isc_result_t result;
- isc_region_t remaining, tavailable;
- isc_buffer_t source, savedbuffer, rdlen;
- dns_name_t name;
- dns_rdatatype_t type;
- unsigned int i, rcount, count;
-
- /*
- * Convert the negative caching rdataset 'rdataset' to wire format,
- * compressing names as specified in 'cctx', and storing the result in
- * 'target'.
- */
-
- REQUIRE(rdataset != NULL);
- REQUIRE(rdataset->type == 0);
- REQUIRE((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0);
-
- savedbuffer = *target;
- count = 0;
-
- result = dns_rdataset_first(rdataset);
- while (result == ISC_R_SUCCESS) {
- dns_rdataset_current(rdataset, &rdata);
- isc_buffer_init(&source, rdata.data, rdata.length);
- isc_buffer_add(&source, rdata.length);
- dns_name_init(&name, NULL);
- isc_buffer_remainingregion(&source, &remaining);
- dns_name_fromregion(&name, &remaining);
- INSIST(remaining.length >= name.length);
- isc_buffer_forward(&source, name.length);
- remaining.length -= name.length;
-
- INSIST(remaining.length >= 5);
- type = isc_buffer_getuint16(&source);
- isc_buffer_forward(&source, 1);
- rcount = isc_buffer_getuint16(&source);
-
- for (i = 0; i < rcount; i++) {
- /*
- * Get the length of this rdata and set up an
- * rdata structure for it.
- */
- isc_buffer_remainingregion(&source, &remaining);
- INSIST(remaining.length >= 2);
- dns_rdata_reset(&rdata);
- rdata.length = isc_buffer_getuint16(&source);
- isc_buffer_remainingregion(&source, &remaining);
- rdata.data = remaining.base;
- rdata.type = type;
- rdata.rdclass = rdataset->rdclass;
- INSIST(remaining.length >= rdata.length);
- isc_buffer_forward(&source, rdata.length);
-
- if ((options & DNS_NCACHETOWIRE_OMITDNSSEC) != 0 &&
- dns_rdatatype_isdnssec(type))
- continue;
-
- /*
- * Write the name.
- */
- dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
- result = dns_name_towire(&name, cctx, target);
- if (result != ISC_R_SUCCESS)
- goto rollback;
-
- /*
- * See if we have space for type, class, ttl, and
- * rdata length. Write the type, class, and ttl.
- */
- isc_buffer_availableregion(target, &tavailable);
- if (tavailable.length < 10) {
- result = ISC_R_NOSPACE;
- goto rollback;
- }
- isc_buffer_putuint16(target, type);
- isc_buffer_putuint16(target, rdataset->rdclass);
- isc_buffer_putuint32(target, rdataset->ttl);
-
- /*
- * Save space for rdata length.
- */
- rdlen = *target;
- isc_buffer_add(target, 2);
-
- /*
- * Write the rdata.
- */
- result = dns_rdata_towire(&rdata, cctx, target);
- if (result != ISC_R_SUCCESS)
- goto rollback;
-
- /*
- * Set the rdata length field to the compressed
- * length.
- */
- INSIST((target->used >= rdlen.used + 2) &&
- (target->used - rdlen.used - 2 < 65536));
- isc_buffer_putuint16(&rdlen,
- (isc_uint16_t)(target->used -
- rdlen.used - 2));
-
- count++;
- }
- INSIST(isc_buffer_remaininglength(&source) == 0);
- result = dns_rdataset_next(rdataset);
- dns_rdata_reset(&rdata);
- }
- if (result != ISC_R_NOMORE)
- goto rollback;
-
- *countp = count;
-
- return (ISC_R_SUCCESS);
-
- rollback:
- INSIST(savedbuffer.used < 65536);
- dns_compress_rollback(cctx, (isc_uint16_t)savedbuffer.used);
- *countp = 0;
- *target = savedbuffer;
-
- return (result);
-}
-
-static void
-rdataset_disassociate(dns_rdataset_t *rdataset) {
- UNUSED(rdataset);
-}
-
-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;
-
- REQUIRE(raw != NULL);
-
- r.length = raw[0] * 256 + raw[1];
- raw += 2;
- r.base = raw;
- dns_rdata_fromregion(rdata, rdataset->rdclass, rdataset->type, &r);
-}
-
-static void
-rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
- *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) {
- unsigned char *raw = rdataset->private3;
-
- raw[-1] = (unsigned char)trust;
-}
-
-static dns_rdatasetmethods_t rdataset_methods = {
- rdataset_disassociate,
- rdataset_first,
- rdataset_next,
- rdataset_current,
- rdataset_clone,
- rdataset_count,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- rdataset_settrust,
- NULL
-};
-
-isc_result_t
-dns_ncache_getrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name,
- dns_rdatatype_t type, dns_rdataset_t *rdataset)
-{
- isc_result_t result;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- isc_region_t remaining;
- isc_buffer_t source;
- dns_name_t tname;
- dns_rdatatype_t ttype;
- dns_trust_t trust = dns_trust_none;
- dns_rdataset_t clone;
-
- REQUIRE(ncacherdataset != NULL);
- REQUIRE(ncacherdataset->type == 0);
- REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0);
- REQUIRE(name != NULL);
- REQUIRE(!dns_rdataset_isassociated(rdataset));
- REQUIRE(type != dns_rdatatype_rrsig);
-
- dns_rdataset_init(&clone);
- dns_rdataset_clone(ncacherdataset, &clone);
- result = dns_rdataset_first(&clone);
- while (result == ISC_R_SUCCESS) {
- dns_rdataset_current(&clone, &rdata);
- isc_buffer_init(&source, rdata.data, rdata.length);
- isc_buffer_add(&source, rdata.length);
- dns_name_init(&tname, NULL);
- isc_buffer_remainingregion(&source, &remaining);
- dns_name_fromregion(&tname, &remaining);
- INSIST(remaining.length >= tname.length);
- isc_buffer_forward(&source, tname.length);
- remaining.length -= tname.length;
-
- INSIST(remaining.length >= 3);
- ttype = isc_buffer_getuint16(&source);
-
- if (ttype == type && dns_name_equal(&tname, name)) {
- trust = isc_buffer_getuint8(&source);
- INSIST(trust <= dns_trust_ultimate);
- isc_buffer_remainingregion(&source, &remaining);
- break;
- }
- result = dns_rdataset_next(&clone);
- dns_rdata_reset(&rdata);
- }
- dns_rdataset_disassociate(&clone);
- if (result == ISC_R_NOMORE)
- return (ISC_R_NOTFOUND);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- INSIST(remaining.length != 0);
-
- rdataset->methods = &rdataset_methods;
- rdataset->rdclass = ncacherdataset->rdclass;
- rdataset->type = type;
- rdataset->covers = 0;
- rdataset->ttl = ncacherdataset->ttl;
- rdataset->trust = trust;
- rdataset->private1 = NULL;
- rdataset->private2 = NULL;
-
- rdataset->private3 = remaining.base;
-
- /*
- * Reset iterator state.
- */
- rdataset->privateuint4 = 0;
- rdataset->private5 = NULL;
- rdataset->private6 = NULL;
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_ncache_getsigrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name,
- dns_rdatatype_t covers, dns_rdataset_t *rdataset)
-{
- dns_name_t tname;
- dns_rdata_rrsig_t rrsig;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdataset_t clone;
- dns_rdatatype_t type;
- dns_trust_t trust = dns_trust_none;
- isc_buffer_t source;
- isc_region_t remaining, sigregion;
- isc_result_t result;
- unsigned char *raw;
- unsigned int count;
-
- REQUIRE(ncacherdataset != NULL);
- REQUIRE(ncacherdataset->type == 0);
- REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0);
- REQUIRE(name != NULL);
- REQUIRE(!dns_rdataset_isassociated(rdataset));
-
- dns_rdataset_init(&clone);
- dns_rdataset_clone(ncacherdataset, &clone);
- result = dns_rdataset_first(&clone);
- while (result == ISC_R_SUCCESS) {
- dns_rdataset_current(&clone, &rdata);
- isc_buffer_init(&source, rdata.data, rdata.length);
- isc_buffer_add(&source, rdata.length);
- dns_name_init(&tname, NULL);
- isc_buffer_remainingregion(&source, &remaining);
- dns_name_fromregion(&tname, &remaining);
- INSIST(remaining.length >= tname.length);
- isc_buffer_forward(&source, tname.length);
- remaining.length -= tname.length;
- remaining.base += tname.length;
-
- INSIST(remaining.length >= 2);
- type = isc_buffer_getuint16(&source);
- remaining.length -= 2;
- remaining.base += 2;
-
- if (type != dns_rdatatype_rrsig ||
- !dns_name_equal(&tname, name)) {
- result = dns_rdataset_next(&clone);
- dns_rdata_reset(&rdata);
- continue;
- }
-
- INSIST(remaining.length >= 1);
- trust = isc_buffer_getuint8(&source);
- INSIST(trust <= dns_trust_ultimate);
- remaining.length -= 1;
- remaining.base += 1;
-
- raw = remaining.base;
- count = raw[0] * 256 + raw[1];
- INSIST(count > 0);
- raw += 2;
- sigregion.length = raw[0] * 256 + raw[1];
- raw += 2;
- sigregion.base = raw;
- dns_rdata_reset(&rdata);
- dns_rdata_fromregion(&rdata, rdataset->rdclass,
- dns_rdatatype_rrsig, &sigregion);
- (void)dns_rdata_tostruct(&rdata, &rrsig, NULL);
- if (rrsig.covered == covers) {
- isc_buffer_remainingregion(&source, &remaining);
- break;
- }
-
- result = dns_rdataset_next(&clone);
- dns_rdata_reset(&rdata);
- }
- dns_rdataset_disassociate(&clone);
- if (result == ISC_R_NOMORE)
- return (ISC_R_NOTFOUND);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- INSIST(remaining.length != 0);
-
- rdataset->methods = &rdataset_methods;
- rdataset->rdclass = ncacherdataset->rdclass;
- rdataset->type = dns_rdatatype_rrsig;
- rdataset->covers = covers;
- rdataset->ttl = ncacherdataset->ttl;
- rdataset->trust = trust;
- rdataset->private1 = NULL;
- rdataset->private2 = NULL;
-
- rdataset->private3 = remaining.base;
-
- /*
- * Reset iterator state.
- */
- rdataset->privateuint4 = 0;
- rdataset->private5 = NULL;
- rdataset->private6 = NULL;
- return (ISC_R_SUCCESS);
-}
-
-void
-dns_ncache_current(dns_rdataset_t *ncacherdataset, dns_name_t *found,
- dns_rdataset_t *rdataset)
-{
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_trust_t trust;
- isc_region_t remaining, sigregion;
- isc_buffer_t source;
- dns_name_t tname;
- dns_rdatatype_t type;
- unsigned int count;
- dns_rdata_rrsig_t rrsig;
- unsigned char *raw;
-
- REQUIRE(ncacherdataset != NULL);
- REQUIRE(ncacherdataset->type == 0);
- REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0);
- REQUIRE(found != NULL);
- REQUIRE(!dns_rdataset_isassociated(rdataset));
-
- dns_rdataset_current(ncacherdataset, &rdata);
- isc_buffer_init(&source, rdata.data, rdata.length);
- isc_buffer_add(&source, rdata.length);
-
- dns_name_init(&tname, NULL);
- isc_buffer_remainingregion(&source, &remaining);
- dns_name_fromregion(found, &remaining);
- INSIST(remaining.length >= found->length);
- isc_buffer_forward(&source, found->length);
- remaining.length -= found->length;
-
- INSIST(remaining.length >= 5);
- type = isc_buffer_getuint16(&source);
- trust = isc_buffer_getuint8(&source);
- INSIST(trust <= dns_trust_ultimate);
- isc_buffer_remainingregion(&source, &remaining);
-
- rdataset->methods = &rdataset_methods;
- rdataset->rdclass = ncacherdataset->rdclass;
- rdataset->type = type;
- if (type == dns_rdatatype_rrsig) {
- /*
- * Extract covers from RRSIG.
- */
- raw = remaining.base;
- count = raw[0] * 256 + raw[1];
- INSIST(count > 0);
- raw += 2;
- sigregion.length = raw[0] * 256 + raw[1];
- raw += 2;
- sigregion.base = raw;
- dns_rdata_reset(&rdata);
- dns_rdata_fromregion(&rdata, rdataset->rdclass,
- rdataset->type, &sigregion);
- (void)dns_rdata_tostruct(&rdata, &rrsig, NULL);
- rdataset->covers = rrsig.covered;
- } else
- rdataset->covers = 0;
- rdataset->ttl = ncacherdataset->ttl;
- rdataset->trust = trust;
- rdataset->private1 = NULL;
- rdataset->private2 = NULL;
-
- rdataset->private3 = remaining.base;
-
- /*
- * Reset iterator state.
- */
- rdataset->privateuint4 = 0;
- rdataset->private5 = NULL;
- rdataset->private6 = NULL;
-}
diff --git a/contrib/bind9/lib/dns/nsec.c b/contrib/bind9/lib/dns/nsec.c
deleted file mode 100644
index e446806b4e6a..000000000000
--- a/contrib/bind9/lib/dns/nsec.c
+++ /dev/null
@@ -1,451 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007-2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001, 2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <isc/log.h>
-#include <isc/string.h>
-#include <isc/util.h>
-
-#include <dns/db.h>
-#include <dns/nsec.h>
-#include <dns/rdata.h>
-#include <dns/rdatalist.h>
-#include <dns/rdataset.h>
-#include <dns/rdatasetiter.h>
-#include <dns/rdatastruct.h>
-#include <dns/result.h>
-
-#include <dst/dst.h>
-
-#define RETERR(x) do { \
- result = (x); \
- if (result != ISC_R_SUCCESS) \
- goto failure; \
- } while (0)
-
-void
-dns_nsec_setbit(unsigned char *array, unsigned int type, unsigned int bit) {
- unsigned int shift, mask;
-
- shift = 7 - (type % 8);
- mask = 1 << shift;
-
- if (bit != 0)
- array[type / 8] |= mask;
- else
- array[type / 8] &= (~mask & 0xFF);
-}
-
-isc_boolean_t
-dns_nsec_isset(const unsigned char *array, unsigned int type) {
- unsigned int byte, shift, mask;
-
- byte = array[type / 8];
- shift = 7 - (type % 8);
- mask = 1 << shift;
-
- return (ISC_TF(byte & mask));
-}
-
-unsigned int
-dns_nsec_compressbitmap(unsigned char *map, const unsigned char *raw,
- unsigned int max_type)
-{
- unsigned char *start = map;
- unsigned int window;
- int octet;
-
- if (raw == NULL)
- return (0);
-
- for (window = 0; window < 256; window++) {
- if (window * 256 > max_type)
- break;
- for (octet = 31; octet >= 0; octet--)
- if (*(raw + octet) != 0)
- break;
- if (octet < 0) {
- raw += 32;
- continue;
- }
- *map++ = window;
- *map++ = octet + 1;
- /*
- * Note: potential overlapping move.
- */
- memmove(map, raw, octet + 1);
- map += octet + 1;
- raw += 32;
- }
- return (map - start);
-}
-
-isc_result_t
-dns_nsec_buildrdata(dns_db_t *db, dns_dbversion_t *version,
- dns_dbnode_t *node, dns_name_t *target,
- unsigned char *buffer, dns_rdata_t *rdata)
-{
- isc_result_t result;
- dns_rdataset_t rdataset;
- isc_region_t r;
- unsigned int i;
-
- unsigned char *nsec_bits, *bm;
- unsigned int max_type;
- dns_rdatasetiter_t *rdsiter;
-
- memset(buffer, 0, DNS_NSEC_BUFFERSIZE);
- dns_name_toregion(target, &r);
- memcpy(buffer, r.base, r.length);
- r.base = buffer;
- /*
- * Use the end of the space for a raw bitmap leaving enough
- * space for the window identifiers and length octets.
- */
- bm = r.base + r.length + 512;
- nsec_bits = r.base + r.length;
- dns_nsec_setbit(bm, dns_rdatatype_rrsig, 1);
- dns_nsec_setbit(bm, dns_rdatatype_nsec, 1);
- max_type = dns_rdatatype_nsec;
- dns_rdataset_init(&rdataset);
- rdsiter = NULL;
- result = dns_db_allrdatasets(db, node, version, 0, &rdsiter);
- if (result != ISC_R_SUCCESS)
- return (result);
- 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_nsec &&
- rdataset.type != dns_rdatatype_nsec3 &&
- rdataset.type != dns_rdatatype_rrsig) {
- if (rdataset.type > max_type)
- max_type = rdataset.type;
- dns_nsec_setbit(bm, rdataset.type, 1);
- }
- dns_rdataset_disassociate(&rdataset);
- }
-
- /*
- * At zone cuts, deny the existence of glue in the parent zone.
- */
- if (dns_nsec_isset(bm, dns_rdatatype_ns) &&
- ! dns_nsec_isset(bm, dns_rdatatype_soa)) {
- for (i = 0; i <= max_type; i++) {
- if (dns_nsec_isset(bm, i) &&
- ! dns_rdatatype_iszonecutauth((dns_rdatatype_t)i))
- dns_nsec_setbit(bm, i, 0);
- }
- }
-
- dns_rdatasetiter_destroy(&rdsiter);
- if (result != ISC_R_NOMORE)
- return (result);
-
- nsec_bits += dns_nsec_compressbitmap(nsec_bits, bm, max_type);
-
- r.length = nsec_bits - r.base;
- INSIST(r.length <= DNS_NSEC_BUFFERSIZE);
- dns_rdata_fromregion(rdata,
- dns_db_class(db),
- dns_rdatatype_nsec,
- &r);
-
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_nsec_build(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node,
- dns_name_t *target, dns_ttl_t ttl)
-{
- isc_result_t result;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- unsigned char data[DNS_NSEC_BUFFERSIZE];
- dns_rdatalist_t rdatalist;
- dns_rdataset_t rdataset;
-
- dns_rdataset_init(&rdataset);
- dns_rdata_init(&rdata);
-
- RETERR(dns_nsec_buildrdata(db, version, node, target, data, &rdata));
-
- rdatalist.rdclass = dns_db_class(db);
- rdatalist.type = dns_rdatatype_nsec;
- rdatalist.covers = 0;
- rdatalist.ttl = ttl;
- ISC_LIST_INIT(rdatalist.rdata);
- ISC_LIST_APPEND(rdatalist.rdata, &rdata, link);
- RETERR(dns_rdatalist_tordataset(&rdatalist, &rdataset));
- result = dns_db_addrdataset(db, node, version, 0, &rdataset,
- 0, NULL);
- if (result == DNS_R_UNCHANGED)
- result = ISC_R_SUCCESS;
-
- failure:
- if (dns_rdataset_isassociated(&rdataset))
- dns_rdataset_disassociate(&rdataset);
- return (result);
-}
-
-isc_boolean_t
-dns_nsec_typepresent(dns_rdata_t *nsec, dns_rdatatype_t type) {
- dns_rdata_nsec_t nsecstruct;
- isc_result_t result;
- isc_boolean_t present;
- unsigned int i, len, window;
-
- REQUIRE(nsec != NULL);
- REQUIRE(nsec->type == dns_rdatatype_nsec);
-
- /* This should never fail */
- result = dns_rdata_tostruct(nsec, &nsecstruct, NULL);
- INSIST(result == ISC_R_SUCCESS);
-
- present = ISC_FALSE;
- for (i = 0; i < nsecstruct.len; i += len) {
- INSIST(i + 2 <= nsecstruct.len);
- window = nsecstruct.typebits[i];
- len = nsecstruct.typebits[i + 1];
- INSIST(len > 0 && len <= 32);
- i += 2;
- INSIST(i + len <= nsecstruct.len);
- if (window * 256 > type)
- break;
- if ((window + 1) * 256 <= type)
- continue;
- if (type < (window * 256) + len * 8)
- present = ISC_TF(dns_nsec_isset(&nsecstruct.typebits[i],
- type % 256));
- break;
- }
- dns_rdata_freestruct(&nsecstruct);
- return (present);
-}
-
-isc_result_t
-dns_nsec_nseconly(dns_db_t *db, dns_dbversion_t *version,
- isc_boolean_t *answer)
-{
- dns_dbnode_t *node = NULL;
- dns_rdataset_t rdataset;
- dns_rdata_dnskey_t dnskey;
- isc_result_t result;
-
- REQUIRE(answer != NULL);
-
- dns_rdataset_init(&rdataset);
-
- result = dns_db_getoriginnode(db, &node);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
- 0, 0, &rdataset, NULL);
- dns_db_detachnode(db, &node);
-
- if (result == ISC_R_NOTFOUND)
- *answer = ISC_FALSE;
- 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_rdataset_current(&rdataset, &rdata);
- result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
-
- if (dnskey.algorithm == DST_ALG_RSAMD5 ||
- dnskey.algorithm == DST_ALG_RSASHA1 ||
- dnskey.algorithm == DST_ALG_DSA ||
- dnskey.algorithm == DST_ALG_ECC)
- break;
- }
- dns_rdataset_disassociate(&rdataset);
- if (result == ISC_R_SUCCESS)
- *answer = ISC_TRUE;
- if (result == ISC_R_NOMORE) {
- *answer = ISC_FALSE;
- result = ISC_R_SUCCESS;
- }
- return (result);
-}
-
-/*%
- * Return ISC_R_SUCCESS if we can determine that the name doesn't exist
- * or we can determine whether there is data or not at the name.
- * If the name does not exist return the wildcard name.
- *
- * Return ISC_R_IGNORE when the NSEC is not the appropriate one.
- */
-isc_result_t
-dns_nsec_noexistnodata(dns_rdatatype_t type, dns_name_t *name,
- dns_name_t *nsecname, dns_rdataset_t *nsecset,
- isc_boolean_t *exists, isc_boolean_t *data,
- dns_name_t *wild, dns_nseclog_t logit, void *arg)
-{
- int order;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- isc_result_t result;
- dns_namereln_t relation;
- unsigned int olabels, nlabels, labels;
- dns_rdata_nsec_t nsec;
- isc_boolean_t atparent;
- isc_boolean_t ns;
- isc_boolean_t soa;
-
- REQUIRE(exists != NULL);
- REQUIRE(data != NULL);
- REQUIRE(nsecset != NULL &&
- nsecset->type == dns_rdatatype_nsec);
-
- result = dns_rdataset_first(nsecset);
- if (result != ISC_R_SUCCESS) {
- (*logit)(arg, ISC_LOG_DEBUG(3), "failure processing NSEC set");
- return (result);
- }
- dns_rdataset_current(nsecset, &rdata);
-
- (*logit)(arg, ISC_LOG_DEBUG(3), "looking for relevant NSEC");
- relation = dns_name_fullcompare(name, nsecname, &order, &olabels);
-
- if (order < 0) {
- /*
- * The name is not within the NSEC range.
- */
- (*logit)(arg, ISC_LOG_DEBUG(3),
- "NSEC does not cover name, before NSEC");
- return (ISC_R_IGNORE);
- }
-
- if (order == 0) {
- /*
- * The names are the same. If we are validating "."
- * then atparent should not be set as there is no parent.
- */
- atparent = (olabels != 1) && dns_rdatatype_atparent(type);
- ns = dns_nsec_typepresent(&rdata, dns_rdatatype_ns);
- soa = dns_nsec_typepresent(&rdata, dns_rdatatype_soa);
- if (ns && !soa) {
- if (!atparent) {
- /*
- * This NSEC record is from somewhere higher in
- * the DNS, and at the parent of a delegation.
- * It can not be legitimately used here.
- */
- (*logit)(arg, ISC_LOG_DEBUG(3),
- "ignoring parent nsec");
- return (ISC_R_IGNORE);
- }
- } else if (atparent && ns && soa) {
- /*
- * This NSEC record is from the child.
- * It can not be legitimately used here.
- */
- (*logit)(arg, ISC_LOG_DEBUG(3),
- "ignoring child nsec");
- return (ISC_R_IGNORE);
- }
- if (type == dns_rdatatype_cname || type == dns_rdatatype_nxt ||
- type == dns_rdatatype_nsec || type == dns_rdatatype_key ||
- !dns_nsec_typepresent(&rdata, dns_rdatatype_cname)) {
- *exists = ISC_TRUE;
- *data = dns_nsec_typepresent(&rdata, type);
- (*logit)(arg, ISC_LOG_DEBUG(3),
- "nsec proves name exists (owner) data=%d",
- *data);
- return (ISC_R_SUCCESS);
- }
- (*logit)(arg, ISC_LOG_DEBUG(3), "NSEC proves CNAME exists");
- return (ISC_R_IGNORE);
- }
-
- if (relation == dns_namereln_subdomain &&
- dns_nsec_typepresent(&rdata, dns_rdatatype_ns) &&
- !dns_nsec_typepresent(&rdata, dns_rdatatype_soa))
- {
- /*
- * This NSEC record is from somewhere higher in
- * the DNS, and at the parent of a delegation.
- * It can not be legitimately used here.
- */
- (*logit)(arg, ISC_LOG_DEBUG(3), "ignoring parent nsec");
- return (ISC_R_IGNORE);
- }
-
- result = dns_rdata_tostruct(&rdata, &nsec, NULL);
- if (result != ISC_R_SUCCESS)
- return (result);
- relation = dns_name_fullcompare(&nsec.next, name, &order, &nlabels);
- if (order == 0) {
- dns_rdata_freestruct(&nsec);
- (*logit)(arg, ISC_LOG_DEBUG(3),
- "ignoring nsec matches next name");
- return (ISC_R_IGNORE);
- }
-
- if (order < 0 && !dns_name_issubdomain(nsecname, &nsec.next)) {
- /*
- * The name is not within the NSEC range.
- */
- dns_rdata_freestruct(&nsec);
- (*logit)(arg, ISC_LOG_DEBUG(3),
- "ignoring nsec because name is past end of range");
- return (ISC_R_IGNORE);
- }
-
- if (order > 0 && relation == dns_namereln_subdomain) {
- (*logit)(arg, ISC_LOG_DEBUG(3),
- "nsec proves name exist (empty)");
- dns_rdata_freestruct(&nsec);
- *exists = ISC_TRUE;
- *data = ISC_FALSE;
- return (ISC_R_SUCCESS);
- }
- if (wild != NULL) {
- dns_name_t common;
- dns_name_init(&common, NULL);
- if (olabels > nlabels) {
- labels = dns_name_countlabels(nsecname);
- dns_name_getlabelsequence(nsecname, labels - olabels,
- olabels, &common);
- } else {
- labels = dns_name_countlabels(&nsec.next);
- dns_name_getlabelsequence(&nsec.next, labels - nlabels,
- nlabels, &common);
- }
- result = dns_name_concatenate(dns_wildcardname, &common,
- wild, NULL);
- if (result != ISC_R_SUCCESS) {
- dns_rdata_freestruct(&nsec);
- (*logit)(arg, ISC_LOG_DEBUG(3),
- "failure generating wildcard name");
- return (result);
- }
- }
- dns_rdata_freestruct(&nsec);
- (*logit)(arg, ISC_LOG_DEBUG(3), "nsec range ok");
- *exists = ISC_FALSE;
- return (ISC_R_SUCCESS);
-}
diff --git a/contrib/bind9/lib/dns/nsec3.c b/contrib/bind9/lib/dns/nsec3.c
deleted file mode 100644
index 935f515d23ed..000000000000
--- a/contrib/bind9/lib/dns/nsec3.c
+++ /dev/null
@@ -1,2087 +0,0 @@
-/*
- * Copyright (C) 2006, 2008-2012 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-#include <config.h>
-
-#include <isc/base32.h>
-#include <isc/buffer.h>
-#include <isc/hex.h>
-#include <isc/iterated_hash.h>
-#include <isc/log.h>
-#include <isc/string.h>
-#include <isc/util.h>
-
-#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>
-#include <dns/nsec.h>
-#include <dns/nsec3.h>
-#include <dns/rdata.h>
-#include <dns/rdatalist.h>
-#include <dns/rdataset.h>
-#include <dns/rdatasetiter.h>
-#include <dns/rdatastruct.h>
-#include <dns/result.h>
-
-#define CHECK(x) do { \
- result = (x); \
- if (result != ISC_R_SUCCESS) \
- goto failure; \
- } while (0)
-
-#define OPTOUT(x) (((x) & DNS_NSEC3FLAG_OPTOUT) != 0)
-#define CREATE(x) (((x) & DNS_NSEC3FLAG_CREATE) != 0)
-#define INITIAL(x) (((x) & DNS_NSEC3FLAG_INITIAL) != 0)
-#define REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
-
-isc_result_t
-dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version,
- dns_dbnode_t *node, unsigned int hashalg,
- unsigned int flags, unsigned int iterations,
- const unsigned char *salt, size_t salt_length,
- const unsigned char *nexthash, size_t hash_length,
- unsigned char *buffer, dns_rdata_t *rdata)
-{
- isc_result_t result;
- dns_rdataset_t rdataset;
- isc_region_t r;
- unsigned int i;
- isc_boolean_t found;
- isc_boolean_t found_ns;
- isc_boolean_t need_rrsig;
-
- unsigned char *nsec_bits, *bm;
- unsigned int max_type;
- dns_rdatasetiter_t *rdsiter;
- unsigned char *p;
-
- REQUIRE(salt_length < 256U);
- REQUIRE(hash_length < 256U);
- REQUIRE(flags <= 0xffU);
- REQUIRE(hashalg <= 0xffU);
- REQUIRE(iterations <= 0xffffU);
-
- switch (hashalg) {
- case dns_hash_sha1:
- REQUIRE(hash_length == ISC_SHA1_DIGESTLENGTH);
- break;
- }
-
- memset(buffer, 0, DNS_NSEC3_BUFFERSIZE);
-
- p = buffer;
-
- *p++ = hashalg;
- *p++ = flags;
-
- *p++ = iterations >> 8;
- *p++ = iterations;
-
- *p++ = salt_length;
- memcpy(p, salt, salt_length);
- p += salt_length;
-
- *p++ = hash_length;
- memcpy(p, nexthash, hash_length);
- p += hash_length;
-
- r.length = p - buffer;
- r.base = buffer;
-
- /*
- * Use the end of the space for a raw bitmap leaving enough
- * space for the window identifiers and length octets.
- */
- bm = r.base + r.length + 512;
- nsec_bits = r.base + r.length;
- max_type = 0;
- if (node == NULL)
- goto collapse_bitmap;
- dns_rdataset_init(&rdataset);
- rdsiter = NULL;
- result = dns_db_allrdatasets(db, node, version, 0, &rdsiter);
- if (result != ISC_R_SUCCESS)
- return (result);
- found = found_ns = need_rrsig = ISC_FALSE;
- 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_nsec &&
- rdataset.type != dns_rdatatype_nsec3 &&
- rdataset.type != dns_rdatatype_rrsig) {
- if (rdataset.type > max_type)
- max_type = rdataset.type;
- dns_nsec_setbit(bm, rdataset.type, 1);
- /*
- * Work out if we need to set the RRSIG bit for
- * this node. We set the RRSIG bit if either of
- * the following conditions are met:
- * 1) We have a SOA or DS then we need to set
- * the RRSIG bit as both always will be signed.
- * 2) We set the RRSIG bit if we don't have
- * a NS record but do have other data.
- */
- if (rdataset.type == dns_rdatatype_soa ||
- rdataset.type == dns_rdatatype_ds)
- need_rrsig = ISC_TRUE;
- else if (rdataset.type == dns_rdatatype_ns)
- found_ns = ISC_TRUE;
- else
- found = ISC_TRUE;
- }
- dns_rdataset_disassociate(&rdataset);
- }
- if ((found && !found_ns) || need_rrsig) {
- if (dns_rdatatype_rrsig > max_type)
- max_type = dns_rdatatype_rrsig;
- dns_nsec_setbit(bm, dns_rdatatype_rrsig, 1);
- }
-
- /*
- * At zone cuts, deny the existence of glue in the parent zone.
- */
- if (dns_nsec_isset(bm, dns_rdatatype_ns) &&
- ! dns_nsec_isset(bm, dns_rdatatype_soa)) {
- for (i = 0; i <= max_type; i++) {
- if (dns_nsec_isset(bm, i) &&
- ! dns_rdatatype_iszonecutauth((dns_rdatatype_t)i))
- dns_nsec_setbit(bm, i, 0);
- }
- }
-
- dns_rdatasetiter_destroy(&rdsiter);
- if (result != ISC_R_NOMORE)
- return (result);
-
- collapse_bitmap:
- nsec_bits += dns_nsec_compressbitmap(nsec_bits, bm, max_type);
- r.length = nsec_bits - r.base;
- INSIST(r.length <= DNS_NSEC3_BUFFERSIZE);
- dns_rdata_fromregion(rdata, dns_db_class(db), dns_rdatatype_nsec3, &r);
-
- return (ISC_R_SUCCESS);
-}
-
-isc_boolean_t
-dns_nsec3_typepresent(dns_rdata_t *rdata, dns_rdatatype_t type) {
- dns_rdata_nsec3_t nsec3;
- isc_result_t result;
- isc_boolean_t present;
- unsigned int i, len, window;
-
- REQUIRE(rdata != NULL);
- REQUIRE(rdata->type == dns_rdatatype_nsec3);
-
- /* This should never fail */
- result = dns_rdata_tostruct(rdata, &nsec3, NULL);
- INSIST(result == ISC_R_SUCCESS);
-
- present = ISC_FALSE;
- for (i = 0; i < nsec3.len; i += len) {
- INSIST(i + 2 <= nsec3.len);
- window = nsec3.typebits[i];
- len = nsec3.typebits[i + 1];
- INSIST(len > 0 && len <= 32);
- i += 2;
- INSIST(i + len <= nsec3.len);
- if (window * 256 > type)
- break;
- if ((window + 1) * 256 <= type)
- continue;
- if (type < (window * 256) + len * 8)
- present = ISC_TF(dns_nsec_isset(&nsec3.typebits[i],
- type % 256));
- break;
- }
- dns_rdata_freestruct(&nsec3);
- return (present);
-}
-
-isc_result_t
-dns_nsec3_hashname(dns_fixedname_t *result,
- unsigned char rethash[NSEC3_MAX_HASH_LENGTH],
- size_t *hash_length, dns_name_t *name, dns_name_t *origin,
- dns_hash_t hashalg, unsigned int iterations,
- const unsigned char *salt, size_t saltlength)
-{
- unsigned char hash[NSEC3_MAX_HASH_LENGTH];
- unsigned char nametext[DNS_NAME_FORMATSIZE];
- dns_fixedname_t fixed;
- dns_name_t *downcased;
- isc_buffer_t namebuffer;
- isc_region_t region;
- size_t len;
-
- if (rethash == NULL)
- rethash = hash;
-
- memset(rethash, 0, NSEC3_MAX_HASH_LENGTH);
-
- dns_fixedname_init(&fixed);
- downcased = dns_fixedname_name(&fixed);
- dns_name_downcase(name, downcased, NULL);
-
- /* hash the node name */
- len = isc_iterated_hash(rethash, hashalg, iterations, salt, saltlength,
- downcased->ndata, downcased->length);
- if (len == 0U)
- return (DNS_R_BADALG);
-
- if (hash_length != NULL)
- *hash_length = len;
-
- /* convert the hash to base32hex */
- region.base = rethash;
- region.length = len;
- isc_buffer_init(&namebuffer, nametext, sizeof nametext);
- isc_base32hex_totext(&region, 1, "", &namebuffer);
-
- /* convert the hex to a domain name */
- dns_fixedname_init(result);
- return (dns_name_fromtext(dns_fixedname_name(result), &namebuffer,
- origin, 0, NULL));
-}
-
-unsigned int
-dns_nsec3_hashlength(dns_hash_t hash) {
-
- switch (hash) {
- case dns_hash_sha1: return(ISC_SHA1_DIGESTLENGTH);
- }
- return (0);
-}
-
-isc_boolean_t
-dns_nsec3_supportedhash(dns_hash_t hash) {
- switch (hash) {
- case dns_hash_sha1: return (ISC_TRUE);
- }
- return (ISC_FALSE);
-}
-
-/*%
- * Update a single RR in version 'ver' of 'db' and log the
- * update in 'diff'.
- *
- * Ensures:
- * \li '*tuple' == NULL. Either the tuple is freed, or its
- * ownership has been transferred to the diff.
- */
-static isc_result_t
-do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
- dns_diff_t *diff)
-{
- dns_diff_t temp_diff;
- isc_result_t result;
-
- /*
- * Create a singleton diff.
- */
- dns_diff_init(diff->mctx, &temp_diff);
- 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);
-}
-
-/*%
- * Set '*exists' to true iff the given name exists, to false otherwise.
- */
-static isc_result_t
-name_exists(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
- isc_boolean_t *exists)
-{
- isc_result_t result;
- dns_dbnode_t *node = NULL;
- dns_rdatasetiter_t *iter = NULL;
-
- result = dns_db_findnode(db, name, ISC_FALSE, &node);
- if (result == ISC_R_NOTFOUND) {
- *exists = ISC_FALSE;
- return (ISC_R_SUCCESS);
- }
- if (result != ISC_R_SUCCESS)
- return (result);
-
- result = dns_db_allrdatasets(db, node, version,
- (isc_stdtime_t) 0, &iter);
- if (result != ISC_R_SUCCESS)
- goto cleanup_node;
-
- result = dns_rdatasetiter_first(iter);
- if (result == ISC_R_SUCCESS) {
- *exists = ISC_TRUE;
- } else if (result == ISC_R_NOMORE) {
- *exists = ISC_FALSE;
- result = ISC_R_SUCCESS;
- } else
- *exists = ISC_FALSE;
- dns_rdatasetiter_destroy(&iter);
-
- cleanup_node:
- dns_db_detachnode(db, &node);
- return (result);
-}
-
-static isc_boolean_t
-match_nsec3param(const dns_rdata_nsec3_t *nsec3,
- const dns_rdata_nsec3param_t *nsec3param)
-{
- if (nsec3->hash == nsec3param->hash &&
- nsec3->iterations == nsec3param->iterations &&
- nsec3->salt_length == nsec3param->salt_length &&
- !memcmp(nsec3->salt, nsec3param->salt, nsec3->salt_length))
- return (ISC_TRUE);
- return (ISC_FALSE);
-}
-
-/*%
- * Delete NSEC3 records at "name" which match "param", recording the
- * change in "diff".
- */
-static isc_result_t
-delete(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
- const dns_rdata_nsec3param_t *nsec3param, dns_diff_t *diff)
-{
- dns_dbnode_t *node = NULL ;
- dns_difftuple_t *tuple = NULL;
- dns_rdata_nsec3_t nsec3;
- dns_rdataset_t rdataset;
- isc_result_t result;
-
- result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
- if (result == ISC_R_NOTFOUND)
- return (ISC_R_SUCCESS);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- dns_rdataset_init(&rdataset);
- result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3, 0,
- (isc_stdtime_t) 0, &rdataset, NULL);
-
- if (result == ISC_R_NOTFOUND) {
- result = ISC_R_SUCCESS;
- goto cleanup_node;
- }
- if (result != ISC_R_SUCCESS)
- goto cleanup_node;
-
- for (result = dns_rdataset_first(&rdataset);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(&rdataset))
- {
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdataset_current(&rdataset, &rdata);
- CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL));
-
- if (!match_nsec3param(&nsec3, nsec3param))
- continue;
-
- result = dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, name,
- rdataset.ttl, &rdata, &tuple);
- if (result != ISC_R_SUCCESS)
- goto failure;
- result = do_one_tuple(&tuple, db, version, diff);
- if (result != ISC_R_SUCCESS)
- goto failure;
- }
- if (result != ISC_R_NOMORE)
- goto failure;
- result = ISC_R_SUCCESS;
-
- failure:
- dns_rdataset_disassociate(&rdataset);
- cleanup_node:
- dns_db_detachnode(db, &node);
-
- return (result);
-}
-
-static isc_boolean_t
-better_param(dns_rdataset_t *nsec3paramset, dns_rdata_t *param) {
- dns_rdataset_t rdataset;
- isc_result_t result;
-
- if (REMOVE(param->data[1]))
- return (ISC_TRUE);
-
- dns_rdataset_init(&rdataset);
- dns_rdataset_clone(nsec3paramset, &rdataset);
- for (result = dns_rdataset_first(&rdataset);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(&rdataset)) {
- dns_rdata_t rdata = DNS_RDATA_INIT;
- 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] ||
- REMOVE(rdata.data[1]) ||
- 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;
- if (CREATE(rdata.data[1]) && !CREATE(param->data[1])) {
- dns_rdataset_disassociate(&rdataset);
- return (ISC_TRUE);
- }
- }
- dns_rdataset_disassociate(&rdataset);
- return (ISC_FALSE);
-}
-
-static isc_result_t
-find_nsec3(dns_rdata_nsec3_t *nsec3, dns_rdataset_t *rdataset,
- const dns_rdata_nsec3param_t *nsec3param)
-{
- isc_result_t 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);
- CHECK(dns_rdata_tostruct(&rdata, nsec3, NULL));
- dns_rdata_reset(&rdata);
- if (match_nsec3param(nsec3, nsec3param))
- break;
- }
- failure:
- return (result);
-}
-
-isc_result_t
-dns_nsec3_addnsec3(dns_db_t *db, dns_dbversion_t *version,
- dns_name_t *name, const dns_rdata_nsec3param_t *nsec3param,
- dns_ttl_t nsecttl, isc_boolean_t unsecure, dns_diff_t *diff)
-{
- dns_dbiterator_t *dbit = NULL;
- dns_dbnode_t *node = NULL;
- dns_dbnode_t *newnode = NULL;
- dns_difftuple_t *tuple = NULL;
- dns_fixedname_t fixed;
- dns_fixedname_t fprev;
- dns_hash_t hash;
- dns_name_t *hashname;
- dns_name_t *origin;
- dns_name_t *prev;
- dns_name_t empty;
- dns_rdata_nsec3_t nsec3;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdataset_t rdataset;
- int pass;
- isc_boolean_t exists = ISC_FALSE;
- isc_boolean_t maybe_remove_unsecure = ISC_FALSE;
- isc_uint8_t flags;
- isc_buffer_t buffer;
- isc_result_t result;
- unsigned char *old_next;
- unsigned char *salt;
- unsigned char nexthash[NSEC3_MAX_HASH_LENGTH];
- unsigned char nsec3buf[DNS_NSEC3_BUFFERSIZE];
- unsigned int iterations;
- unsigned int labels;
- size_t next_length;
- unsigned int old_length;
- unsigned int salt_length;
-
- dns_fixedname_init(&fixed);
- hashname = dns_fixedname_name(&fixed);
- dns_fixedname_init(&fprev);
- prev = dns_fixedname_name(&fprev);
-
- dns_rdataset_init(&rdataset);
-
- origin = dns_db_origin(db);
-
- /*
- * Chain parameters.
- */
- hash = nsec3param->hash;
- iterations = nsec3param->iterations;
- salt_length = nsec3param->salt_length;
- salt = nsec3param->salt;
-
- /*
- * Default flags for a new chain.
- */
- flags = nsec3param->flags & DNS_NSEC3FLAG_OPTOUT;
-
- /*
- * If this is the first NSEC3 in the chain nexthash will
- * remain pointing to itself.
- */
- next_length = sizeof(nexthash);
- CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
- name, origin, hash, iterations,
- salt, salt_length));
-
- /*
- * Create the node if it doesn't exist and hold
- * a reference to it until we have added the NSEC3.
- */
- CHECK(dns_db_findnsec3node(db, hashname, ISC_TRUE, &newnode));
-
- /*
- * Seek the iterator to the 'newnode'.
- */
- CHECK(dns_db_createiterator(db, DNS_DB_NSEC3ONLY, &dbit));
- CHECK(dns_dbiterator_seek(dbit, hashname));
- CHECK(dns_dbiterator_pause(dbit));
- result = dns_db_findrdataset(db, newnode, version, dns_rdatatype_nsec3,
- 0, (isc_stdtime_t) 0, &rdataset, NULL);
- /*
- * If we updating a existing NSEC3 then find its
- * next field.
- */
- if (result == ISC_R_SUCCESS) {
- result = find_nsec3(&nsec3, &rdataset, nsec3param);
- if (result == ISC_R_SUCCESS) {
- if (!CREATE(nsec3param->flags))
- flags = nsec3.flags;
- next_length = nsec3.next_length;
- INSIST(next_length <= sizeof(nexthash));
- memcpy(nexthash, nsec3.next, next_length);
- dns_rdataset_disassociate(&rdataset);
- /*
- * If the NSEC3 is not for a unsecure delegation then
- * we are just updating it. If it is for a unsecure
- * delegation then we need find out if we need to
- * remove the NSEC3 record or not by examining the
- * previous NSEC3 record.
- */
- if (!unsecure)
- goto addnsec3;
- 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)
- goto failure;
- }
- }
-
- /*
- * Find the previous NSEC3 (if any) and update it if required.
- */
- pass = 0;
- do {
- result = dns_dbiterator_prev(dbit);
- if (result == ISC_R_NOMORE) {
- pass++;
- CHECK(dns_dbiterator_last(dbit));
- }
- CHECK(dns_dbiterator_current(dbit, &node, prev));
- CHECK(dns_dbiterator_pause(dbit));
- result = dns_db_findrdataset(db, node, version,
- dns_rdatatype_nsec3, 0,
- (isc_stdtime_t) 0, &rdataset,
- NULL);
- dns_db_detachnode(db, &node);
- if (result != ISC_R_SUCCESS)
- continue;
-
- result = find_nsec3(&nsec3, &rdataset, nsec3param);
- if (result == ISC_R_NOMORE) {
- dns_rdataset_disassociate(&rdataset);
- continue;
- }
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- if (maybe_remove_unsecure) {
- dns_rdataset_disassociate(&rdataset);
- /*
- * 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)) {
- result = dns_nsec3_delnsec3(db, version, name,
- nsec3param, diff);
- goto failure;
- }
- goto addnsec3;
- } else {
- /*
- * Is this is a unsecure delegation we are adding?
- * If so no change is required.
- */
- if (OPTOUT(nsec3.flags) && unsecure) {
- dns_rdataset_disassociate(&rdataset);
- goto failure;
- }
- }
-
- old_next = nsec3.next;
- old_length = nsec3.next_length;
-
- /*
- * Delete the old previous NSEC3.
- */
- CHECK(delete(db, version, prev, nsec3param, diff));
-
- /*
- * Fixup the previous NSEC3.
- */
- nsec3.next = nexthash;
- nsec3.next_length = next_length;
- isc_buffer_init(&buffer, nsec3buf, sizeof(nsec3buf));
- CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
- dns_rdatatype_nsec3, &nsec3,
- &buffer));
- CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, prev,
- rdataset.ttl, &rdata, &tuple));
- CHECK(do_one_tuple(&tuple, db, version, diff));
- INSIST(old_length <= sizeof(nexthash));
- memcpy(nexthash, old_next, old_length);
- if (!CREATE(nsec3param->flags))
- flags = nsec3.flags;
- dns_rdata_reset(&rdata);
- dns_rdataset_disassociate(&rdataset);
- break;
- } while (pass < 2);
-
- addnsec3:
- /*
- * Create the NSEC3 RDATA.
- */
- CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
- CHECK(dns_nsec3_buildrdata(db, version, node, hash, flags, iterations,
- salt, salt_length, nexthash, next_length,
- nsec3buf, &rdata));
- dns_db_detachnode(db, &node);
-
- /*
- * Delete the old NSEC3 and record the change.
- */
- CHECK(delete(db, version, hashname, nsec3param, diff));
- /*
- * Add the new NSEC3 and record the change.
- */
- CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
- hashname, nsecttl, &rdata, &tuple));
- CHECK(do_one_tuple(&tuple, db, version, diff));
- INSIST(tuple == NULL);
- dns_rdata_reset(&rdata);
- dns_db_detachnode(db, &newnode);
-
- /*
- * Add missing NSEC3 records for empty nodes
- */
- dns_name_init(&empty, NULL);
- dns_name_clone(name, &empty);
- do {
- labels = dns_name_countlabels(&empty) - 1;
- if (labels <= dns_name_countlabels(origin))
- break;
- dns_name_getlabelsequence(&empty, 1, labels, &empty);
- CHECK(name_exists(db, version, &empty, &exists));
- if (exists)
- break;
- CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
- &empty, origin, hash, iterations,
- salt, salt_length));
-
- /*
- * Create the node if it doesn't exist and hold
- * a reference to it until we have added the NSEC3
- * or we discover we don't need to add make a change.
- */
- CHECK(dns_db_findnsec3node(db, hashname, ISC_TRUE, &newnode));
- result = dns_db_findrdataset(db, newnode, version,
- dns_rdatatype_nsec3, 0,
- (isc_stdtime_t) 0, &rdataset,
- NULL);
- if (result == ISC_R_SUCCESS) {
- result = find_nsec3(&nsec3, &rdataset, nsec3param);
- dns_rdataset_disassociate(&rdataset);
- if (result == ISC_R_SUCCESS) {
- dns_db_detachnode(db, &newnode);
- break;
- }
- if (result != ISC_R_NOMORE)
- goto failure;
- }
-
- /*
- * Find the previous NSEC3 and update it.
- */
- CHECK(dns_dbiterator_seek(dbit, hashname));
- pass = 0;
- do {
- result = dns_dbiterator_prev(dbit);
- if (result == ISC_R_NOMORE) {
- pass++;
- CHECK(dns_dbiterator_last(dbit));
- }
- CHECK(dns_dbiterator_current(dbit, &node, prev));
- CHECK(dns_dbiterator_pause(dbit));
- result = dns_db_findrdataset(db, node, version,
- dns_rdatatype_nsec3, 0,
- (isc_stdtime_t) 0,
- &rdataset, NULL);
- dns_db_detachnode(db, &node);
- if (result != ISC_R_SUCCESS)
- continue;
- result = find_nsec3(&nsec3, &rdataset, nsec3param);
- if (result == ISC_R_NOMORE) {
- dns_rdataset_disassociate(&rdataset);
- continue;
- }
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- old_next = nsec3.next;
- old_length = nsec3.next_length;
-
- /*
- * Delete the old previous NSEC3.
- */
- CHECK(delete(db, version, prev, nsec3param, diff));
-
- /*
- * Fixup the previous NSEC3.
- */
- nsec3.next = nexthash;
- nsec3.next_length = next_length;
- isc_buffer_init(&buffer, nsec3buf,
- sizeof(nsec3buf));
- CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
- dns_rdatatype_nsec3, &nsec3,
- &buffer));
- CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
- prev, rdataset.ttl, &rdata,
- &tuple));
- CHECK(do_one_tuple(&tuple, db, version, diff));
- INSIST(old_length <= sizeof(nexthash));
- memcpy(nexthash, old_next, old_length);
- if (!CREATE(nsec3param->flags))
- flags = nsec3.flags;
- dns_rdata_reset(&rdata);
- dns_rdataset_disassociate(&rdataset);
- break;
- } while (pass < 2);
-
- INSIST(pass < 2);
-
- /*
- * Create the NSEC3 RDATA for the empty node.
- */
- CHECK(dns_nsec3_buildrdata(db, version, NULL, hash, flags,
- iterations, salt, salt_length,
- nexthash, next_length, nsec3buf,
- &rdata));
- /*
- * Delete the old NSEC3 and record the change.
- */
- CHECK(delete(db, version, hashname, nsec3param, diff));
-
- /*
- * Add the new NSEC3 and record the change.
- */
- CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
- hashname, nsecttl, &rdata, &tuple));
- CHECK(do_one_tuple(&tuple, db, version, diff));
- INSIST(tuple == NULL);
- dns_rdata_reset(&rdata);
- dns_db_detachnode(db, &newnode);
- } while (1);
-
- if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
-
- failure:
- if (dbit != NULL)
- dns_dbiterator_destroy(&dbit);
- if (dns_rdataset_isassociated(&rdataset))
- dns_rdataset_disassociate(&rdataset);
- if (node != NULL)
- dns_db_detachnode(db, &node);
- if (newnode != NULL)
- dns_db_detachnode(db, &newnode);
- return (result);
-}
-
-/*%
- * Add NSEC3 records for "name", recording the change in "diff".
- * The existing NSEC3 records are removed.
- */
-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)
-{
- dns_dbnode_t *node = NULL;
- dns_rdata_nsec3param_t nsec3param;
- dns_rdataset_t rdataset;
- isc_result_t result;
-
- dns_rdataset_init(&rdataset);
-
- /*
- * 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,
- dns_rdatatype_nsec3param, 0, 0,
- &rdataset, NULL);
- dns_db_detachnode(db, &node);
- if (result == ISC_R_NOTFOUND)
- return (ISC_R_SUCCESS);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- /*
- * 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));
-
- 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, isc_boolean_t nonsec,
- 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;
- if (nonsec)
- buf[2] |= 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_rdata_reset(&rdata);
- dns_rdataset_current(&rdataset, &rdata);
- INSIST(rdata.length <= sizeof(buf));
- memcpy(buf, rdata.data, rdata.length);
-
- /*
- * Private NSEC3 record length >= 6.
- * <0(1), hash(1), flags(1), iterations(2), saltlen(1)>
- */
- if (rdata.length < 6 || buf[0] != 0 ||
- (buf[2] & DNS_NSEC3FLAG_REMOVE) != 0 ||
- (nonsec && (buf[2] & DNS_NSEC3FLAG_NONSEC) != 0))
- continue;
-
- CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, origin,
- 0, &rdata, &tuple));
- CHECK(do_one_tuple(&tuple, db, ver, diff));
- INSIST(tuple == NULL);
-
- rdata.data = buf;
- buf[2] = DNS_NSEC3FLAG_REMOVE;
- if (nonsec)
- buf[2] |= 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);
- }
- }
- 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));
-
- 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)
- 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(&prdataset, &rdata2))
- continue;
-
- /*
- * We have a active chain. Update it.
- */
- CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param,
- 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);
-
- return (result);
-}
-
-/*%
- * Determine whether any NSEC3 records that were associated with
- * 'name' should be deleted or if they should continue to exist.
- * ISC_TRUE indicates they should be deleted.
- * ISC_FALSE indicates they should be retained.
- */
-static isc_result_t
-deleteit(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
- isc_boolean_t *yesno)
-{
- isc_result_t result;
- dns_fixedname_t foundname;
- dns_fixedname_init(&foundname);
-
- result = dns_db_find(db, name, ver, dns_rdatatype_any,
- DNS_DBFIND_GLUEOK | DNS_DBFIND_NOWILD,
- (isc_stdtime_t) 0, NULL,
- dns_fixedname_name(&foundname),
- NULL, NULL);
- if (result == DNS_R_EMPTYNAME || result == ISC_R_SUCCESS ||
- result == DNS_R_ZONECUT) {
- *yesno = ISC_FALSE;
- return (ISC_R_SUCCESS);
- }
- if (result == DNS_R_GLUE || result == DNS_R_DNAME ||
- result == DNS_R_DELEGATION || result == DNS_R_NXDOMAIN) {
- *yesno = ISC_TRUE;
- return (ISC_R_SUCCESS);
- }
- /*
- * Silence compiler.
- */
- *yesno = ISC_TRUE;
- return (result);
-}
-
-isc_result_t
-dns_nsec3_delnsec3(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
- const dns_rdata_nsec3param_t *nsec3param, dns_diff_t *diff)
-{
- dns_dbiterator_t *dbit = NULL;
- dns_dbnode_t *node = NULL;
- dns_difftuple_t *tuple = NULL;
- dns_fixedname_t fixed;
- dns_fixedname_t fprev;
- dns_hash_t hash;
- dns_name_t *hashname;
- dns_name_t *origin;
- dns_name_t *prev;
- dns_name_t empty;
- dns_rdata_nsec3_t nsec3;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdataset_t rdataset;
- int pass;
- isc_boolean_t yesno;
- isc_buffer_t buffer;
- isc_result_t result;
- unsigned char *salt;
- unsigned char nexthash[NSEC3_MAX_HASH_LENGTH];
- unsigned char nsec3buf[DNS_NSEC3_BUFFERSIZE];
- unsigned int iterations;
- unsigned int labels;
- size_t next_length;
- unsigned int salt_length;
-
- dns_fixedname_init(&fixed);
- hashname = dns_fixedname_name(&fixed);
- dns_fixedname_init(&fprev);
- prev = dns_fixedname_name(&fprev);
-
- dns_rdataset_init(&rdataset);
-
- origin = dns_db_origin(db);
-
- /*
- * Chain parameters.
- */
- hash = nsec3param->hash;
- iterations = nsec3param->iterations;
- salt_length = nsec3param->salt_length;
- salt = nsec3param->salt;
-
- /*
- * If this is the first NSEC3 in the chain nexthash will
- * remain pointing to itself.
- */
- next_length = sizeof(nexthash);
- CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
- name, origin, hash, iterations,
- salt, salt_length));
-
- CHECK(dns_db_createiterator(db, DNS_DB_NSEC3ONLY, &dbit));
-
- result = dns_dbiterator_seek(dbit, hashname);
- if (result == ISC_R_NOTFOUND)
- goto success;
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- CHECK(dns_dbiterator_current(dbit, &node, NULL));
- CHECK(dns_dbiterator_pause(dbit));
- result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3,
- 0, (isc_stdtime_t) 0, &rdataset, NULL);
- dns_db_detachnode(db, &node);
- if (result == ISC_R_NOTFOUND)
- goto success;
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- /*
- * If we find a existing NSEC3 for this chain then save the
- * next field.
- */
- result = find_nsec3(&nsec3, &rdataset, nsec3param);
- if (result == ISC_R_SUCCESS) {
- next_length = nsec3.next_length;
- INSIST(next_length <= sizeof(nexthash));
- memcpy(nexthash, nsec3.next, next_length);
- }
- dns_rdataset_disassociate(&rdataset);
- if (result == ISC_R_NOMORE)
- goto success;
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- /*
- * Find the previous NSEC3 and update it.
- */
- pass = 0;
- do {
- result = dns_dbiterator_prev(dbit);
- if (result == ISC_R_NOMORE) {
- pass++;
- CHECK(dns_dbiterator_last(dbit));
- }
- CHECK(dns_dbiterator_current(dbit, &node, prev));
- CHECK(dns_dbiterator_pause(dbit));
- result = dns_db_findrdataset(db, node, version,
- dns_rdatatype_nsec3, 0,
- (isc_stdtime_t) 0, &rdataset,
- NULL);
- dns_db_detachnode(db, &node);
- if (result != ISC_R_SUCCESS)
- continue;
- result = find_nsec3(&nsec3, &rdataset, nsec3param);
- if (result == ISC_R_NOMORE) {
- dns_rdataset_disassociate(&rdataset);
- continue;
- }
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- /*
- * Delete the old previous NSEC3.
- */
- CHECK(delete(db, version, prev, nsec3param, diff));
-
- /*
- * Fixup the previous NSEC3.
- */
- 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,
- &buffer));
- CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, prev,
- rdataset.ttl, &rdata, &tuple));
- CHECK(do_one_tuple(&tuple, db, version, diff));
- dns_rdata_reset(&rdata);
- dns_rdataset_disassociate(&rdataset);
- break;
- } while (pass < 2);
-
- /*
- * Delete the old NSEC3 and record the change.
- */
- CHECK(delete(db, version, hashname, nsec3param, diff));
-
- /*
- * Delete NSEC3 records for now non active nodes.
- */
- dns_name_init(&empty, NULL);
- dns_name_clone(name, &empty);
- do {
- labels = dns_name_countlabels(&empty) - 1;
- if (labels <= dns_name_countlabels(origin))
- break;
- dns_name_getlabelsequence(&empty, 1, labels, &empty);
- CHECK(deleteit(db, version, &empty, &yesno));
- if (!yesno)
- break;
-
- CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
- &empty, origin, hash, iterations,
- salt, salt_length));
- result = dns_dbiterator_seek(dbit, hashname);
- if (result == ISC_R_NOTFOUND)
- goto success;
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- CHECK(dns_dbiterator_current(dbit, &node, NULL));
- CHECK(dns_dbiterator_pause(dbit));
- result = dns_db_findrdataset(db, node, version,
- dns_rdatatype_nsec3, 0,
- (isc_stdtime_t) 0, &rdataset,
- NULL);
- dns_db_detachnode(db, &node);
- if (result == ISC_R_NOTFOUND)
- goto success;
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- result = find_nsec3(&nsec3, &rdataset, nsec3param);
- if (result == ISC_R_SUCCESS) {
- next_length = nsec3.next_length;
- INSIST(next_length <= sizeof(nexthash));
- memcpy(nexthash, nsec3.next, next_length);
- }
- dns_rdataset_disassociate(&rdataset);
- if (result == ISC_R_NOMORE)
- goto success;
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- pass = 0;
- do {
- result = dns_dbiterator_prev(dbit);
- if (result == ISC_R_NOMORE) {
- pass++;
- CHECK(dns_dbiterator_last(dbit));
- }
- CHECK(dns_dbiterator_current(dbit, &node, prev));
- CHECK(dns_dbiterator_pause(dbit));
- result = dns_db_findrdataset(db, node, version,
- dns_rdatatype_nsec3, 0,
- (isc_stdtime_t) 0,
- &rdataset, NULL);
- dns_db_detachnode(db, &node);
- if (result != ISC_R_SUCCESS)
- continue;
- result = find_nsec3(&nsec3, &rdataset, nsec3param);
- if (result == ISC_R_NOMORE) {
- dns_rdataset_disassociate(&rdataset);
- continue;
- }
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- /*
- * Delete the old previous NSEC3.
- */
- CHECK(delete(db, version, prev, nsec3param, diff));
-
- /*
- * Fixup the previous NSEC3.
- */
- nsec3.next = nexthash;
- nsec3.next_length = next_length;
- isc_buffer_init(&buffer, nsec3buf,
- sizeof(nsec3buf));
- CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
- dns_rdatatype_nsec3, &nsec3,
- &buffer));
- CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
- prev, rdataset.ttl, &rdata,
- &tuple));
- CHECK(do_one_tuple(&tuple, db, version, diff));
- dns_rdata_reset(&rdata);
- dns_rdataset_disassociate(&rdataset);
- break;
- } while (pass < 2);
-
- INSIST(pass < 2);
-
- /*
- * Delete the old NSEC3 and record the change.
- */
- CHECK(delete(db, version, hashname, nsec3param, diff));
- } while (1);
-
- success:
- result = ISC_R_SUCCESS;
-
- failure:
- if (dbit != NULL)
- dns_dbiterator_destroy(&dbit);
- if (dns_rdataset_isassociated(&rdataset))
- dns_rdataset_disassociate(&rdataset);
- if (node != NULL)
- dns_db_detachnode(db, &node);
- return (result);
-}
-
-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;
- isc_result_t result;
-
- dns_rdataset_init(&rdataset);
-
- /*
- * 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,
- 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));
-
- if (nsec3param.flags != 0)
- continue;
- /*
- * 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, &rdata2))
- continue;
-
- /*
- * We have a active chain. Update it.
- */
- CHECK(dns_nsec3_delnsec3(db, version, name, &nsec3param, diff));
- }
- if (result == ISC_R_NOMORE)
- success:
- 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_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;
- isc_result_t result;
-
- REQUIRE(answer != NULL);
-
- dns_rdataset_init(&rdataset);
-
- result = dns_db_getoriginnode(db, &node);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- 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) {
- 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 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;
- result = dns_rdata_tostruct(&rdata2, &nsec3param, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
-
- if (!complete && CREATE(nsec3param.flags))
- break;
- }
- dns_rdataset_disassociate(&rdataset);
- 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);
-}
-
-isc_result_t
-dns_nsec3_maxiterations(dns_db_t *db, dns_dbversion_t *version,
- isc_mem_t *mctx, unsigned int *iterationsp)
-{
- dns_dbnode_t *node = NULL;
- dns_rdataset_t rdataset;
- dst_key_t *key = NULL;
- isc_buffer_t buffer;
- isc_result_t result;
- unsigned int bits, minbits = 4096;
-
- result = dns_db_getoriginnode(db, &node);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- dns_rdataset_init(&rdataset);
- result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
- 0, 0, &rdataset, NULL);
- dns_db_detachnode(db, &node);
- if (result == ISC_R_NOTFOUND) {
- *iterationsp = 0;
- return (ISC_R_SUCCESS);
- }
- 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);
- isc_buffer_init(&buffer, rdata.data, rdata.length);
- isc_buffer_add(&buffer, rdata.length);
- CHECK(dst_key_fromdns(dns_db_origin(db), rdataset.rdclass,
- &buffer, mctx, &key));
- bits = dst_key_size(key);
- dst_key_free(&key);
- if (minbits > bits)
- minbits = bits;
- }
- if (result != ISC_R_NOMORE)
- goto failure;
-
- if (minbits <= 1024)
- *iterationsp = 150;
- else if (minbits <= 2048)
- *iterationsp = 500;
- else
- *iterationsp = 2500;
- result = ISC_R_SUCCESS;
-
- failure:
- if (dns_rdataset_isassociated(&rdataset))
- dns_rdataset_disassociate(&rdataset);
- return (result);
-}
-
-isc_result_t
-dns_nsec3_noexistnodata(dns_rdatatype_t type, dns_name_t* name,
- dns_name_t *nsec3name, dns_rdataset_t *nsec3set,
- dns_name_t *zonename, isc_boolean_t *exists,
- isc_boolean_t *data, isc_boolean_t *optout,
- isc_boolean_t *unknown, isc_boolean_t *setclosest,
- isc_boolean_t *setnearest, dns_name_t *closest,
- dns_name_t *nearest, dns_nseclog_t logit, void *arg)
-{
- char namebuf[DNS_NAME_FORMATSIZE];
- dns_fixedname_t fzone;
- dns_fixedname_t qfixed;
- dns_label_t hashlabel;
- dns_name_t *qname;
- dns_name_t *zone;
- dns_rdata_nsec3_t nsec3;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- int order;
- int scope;
- isc_boolean_t atparent;
- isc_boolean_t first;
- isc_boolean_t ns;
- isc_boolean_t soa;
- isc_buffer_t buffer;
- isc_result_t answer = ISC_R_IGNORE;
- isc_result_t result;
- unsigned char hash[NSEC3_MAX_HASH_LENGTH];
- unsigned char owner[NSEC3_MAX_HASH_LENGTH];
- unsigned int length;
- unsigned int qlabels;
- unsigned int zlabels;
-
- REQUIRE((exists == NULL && data == NULL) ||
- (exists != NULL && data != NULL));
- REQUIRE(nsec3set != NULL && nsec3set->type == dns_rdatatype_nsec3);
- REQUIRE((setclosest == NULL && closest == NULL) ||
- (setclosest != NULL && closest != NULL));
- REQUIRE((setnearest == NULL && nearest == NULL) ||
- (setnearest != NULL && nearest != NULL));
-
- result = dns_rdataset_first(nsec3set);
- if (result != ISC_R_SUCCESS) {
- (*logit)(arg, ISC_LOG_DEBUG(3), "failure processing NSEC3 set");
- return (result);
- }
-
- dns_rdataset_current(nsec3set, &rdata);
-
- result = dns_rdata_tostruct(&rdata, &nsec3, NULL);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- (*logit)(arg, ISC_LOG_DEBUG(3), "looking for relevant NSEC3");
-
- dns_fixedname_init(&fzone);
- zone = dns_fixedname_name(&fzone);
- zlabels = dns_name_countlabels(nsec3name);
-
- /*
- * NSEC3 records must have two or more labels to be valid.
- */
- if (zlabels < 2)
- return (ISC_R_IGNORE);
-
- /*
- * Strip off the NSEC3 hash to get the zone.
- */
- zlabels--;
- dns_name_split(nsec3name, zlabels, NULL, zone);
-
- /*
- * If not below the zone name we can ignore this record.
- */
- if (!dns_name_issubdomain(name, zone))
- return (ISC_R_IGNORE);
-
- /*
- * Is this zone the same or deeper than the current zone?
- */
- if (dns_name_countlabels(zonename) == 0 ||
- dns_name_issubdomain(zone, zonename))
- dns_name_copy(zone, zonename, NULL);
-
- if (!dns_name_equal(zone, zonename))
- return (ISC_R_IGNORE);
-
- /*
- * Are we only looking for the most enclosing zone?
- */
- if (exists == NULL || data == NULL)
- return (ISC_R_SUCCESS);
-
- /*
- * Only set unknown once we are sure that this NSEC3 is from
- * the deepest covering zone.
- */
- if (!dns_nsec3_supportedhash(nsec3.hash)) {
- if (unknown != NULL)
- *unknown = ISC_TRUE;
- return (ISC_R_IGNORE);
- }
-
- /*
- * Recover the hash from the first label.
- */
- dns_name_getlabel(nsec3name, 0, &hashlabel);
- isc_region_consume(&hashlabel, 1);
- isc_buffer_init(&buffer, owner, sizeof(owner));
- result = isc_base32hex_decoderegion(&hashlabel, &buffer);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- /*
- * The hash lengths should match. If not ignore the record.
- */
- if (isc_buffer_usedlength(&buffer) != nsec3.next_length)
- return (ISC_R_IGNORE);
-
- /*
- * Work out what this NSEC3 covers.
- * Inside (<0) or outside (>=0).
- */
- scope = memcmp(owner, nsec3.next, nsec3.next_length);
-
- /*
- * Prepare to compute all the hashes.
- */
- dns_fixedname_init(&qfixed);
- qname = dns_fixedname_name(&qfixed);
- dns_name_downcase(name, qname, NULL);
- qlabels = dns_name_countlabels(qname);
- first = ISC_TRUE;
-
- while (qlabels >= zlabels) {
- length = isc_iterated_hash(hash, nsec3.hash, nsec3.iterations,
- nsec3.salt, nsec3.salt_length,
- qname->ndata, qname->length);
- /*
- * The computed hash length should match.
- */
- if (length != nsec3.next_length) {
- (*logit)(arg, ISC_LOG_DEBUG(3),
- "ignoring NSEC bad length %u vs %u",
- length, nsec3.next_length);
- return (ISC_R_IGNORE);
- }
-
- order = memcmp(hash, owner, length);
- if (first && order == 0) {
- /*
- * The hashes are the same.
- */
- atparent = dns_rdatatype_atparent(type);
- ns = dns_nsec3_typepresent(&rdata, dns_rdatatype_ns);
- soa = dns_nsec3_typepresent(&rdata, dns_rdatatype_soa);
- if (ns && !soa) {
- if (!atparent) {
- /*
- * This NSEC3 record is from somewhere
- * higher in the DNS, and at the
- * parent of a delegation. It can not
- * be legitimately used here.
- */
- (*logit)(arg, ISC_LOG_DEBUG(3),
- "ignoring parent NSEC3");
- return (ISC_R_IGNORE);
- }
- } else if (atparent && ns && soa) {
- /*
- * This NSEC3 record is from the child.
- * It can not be legitimately used here.
- */
- (*logit)(arg, ISC_LOG_DEBUG(3),
- "ignoring child NSEC3");
- return (ISC_R_IGNORE);
- }
- if (type == dns_rdatatype_cname ||
- type == dns_rdatatype_nxt ||
- type == dns_rdatatype_nsec ||
- type == dns_rdatatype_key ||
- !dns_nsec3_typepresent(&rdata, dns_rdatatype_cname)) {
- *exists = ISC_TRUE;
- *data = dns_nsec3_typepresent(&rdata, type);
- (*logit)(arg, ISC_LOG_DEBUG(3),
- "NSEC3 proves name exists (owner) "
- "data=%d", *data);
- return (ISC_R_SUCCESS);
- }
- (*logit)(arg, ISC_LOG_DEBUG(3),
- "NSEC3 proves CNAME exists");
- return (ISC_R_IGNORE);
- }
-
- if (order == 0 &&
- dns_nsec3_typepresent(&rdata, dns_rdatatype_ns) &&
- !dns_nsec3_typepresent(&rdata, dns_rdatatype_soa))
- {
- /*
- * This NSEC3 record is from somewhere higher in
- * the DNS, and at the parent of a delegation.
- * It can not be legitimately used here.
- */
- (*logit)(arg, ISC_LOG_DEBUG(3),
- "ignoring parent NSEC3");
- return (ISC_R_IGNORE);
- }
-
- /*
- * Potential closest encloser.
- */
- if (order == 0) {
- if (closest != NULL &&
- (dns_name_countlabels(closest) == 0 ||
- dns_name_issubdomain(qname, closest)) &&
- !dns_nsec3_typepresent(&rdata, dns_rdatatype_ds) &&
- !dns_nsec3_typepresent(&rdata, dns_rdatatype_dname) &&
- (dns_nsec3_typepresent(&rdata, dns_rdatatype_soa) ||
- !dns_nsec3_typepresent(&rdata, dns_rdatatype_ns)))
- {
-
- dns_name_format(qname, namebuf,
- sizeof(namebuf));
- (*logit)(arg, ISC_LOG_DEBUG(3),
- "NSEC3 indicates potential closest "
- "encloser: '%s'", namebuf);
- dns_name_copy(qname, closest, NULL);
- *setclosest = ISC_TRUE;
- }
- dns_name_format(qname, namebuf, sizeof(namebuf));
- (*logit)(arg, ISC_LOG_DEBUG(3),
- "NSEC3 at super-domain %s", namebuf);
- return (answer);
- }
-
- /*
- * Find if the name does not exist.
- *
- * We continue as we need to find the name closest to the
- * closest encloser that doesn't exist.
- *
- * We also need to continue to ensure that we are not
- * proving the non-existence of a record in a sub-zone.
- * If that would be the case we will return ISC_R_IGNORE
- * above.
- */
- if ((scope < 0 && order > 0 &&
- memcmp(hash, nsec3.next, length) < 0) ||
- (scope >= 0 && (order > 0 ||
- memcmp(hash, nsec3.next, length) < 0)))
- {
- char namebuf[DNS_NAME_FORMATSIZE];
-
- dns_name_format(qname, namebuf, sizeof(namebuf));
- (*logit)(arg, ISC_LOG_DEBUG(3), "NSEC3 proves "
- "name does not exist: '%s'", namebuf);
- if (nearest != NULL &&
- (dns_name_countlabels(nearest) == 0 ||
- dns_name_issubdomain(nearest, qname))) {
- dns_name_copy(qname, nearest, NULL);
- *setnearest = ISC_TRUE;
- }
-
- *exists = ISC_FALSE;
- *data = ISC_FALSE;
- if (optout != NULL) {
- if ((nsec3.flags & DNS_NSEC3FLAG_OPTOUT) != 0)
- (*logit)(arg, ISC_LOG_DEBUG(3),
- "NSEC3 indicates optout");
- *optout =
- ISC_TF(nsec3.flags & DNS_NSEC3FLAG_OPTOUT);
- }
- answer = ISC_R_SUCCESS;
- }
-
- qlabels--;
- if (qlabels > 0)
- dns_name_split(qname, qlabels, NULL, qname);
- first = ISC_FALSE;
- }
- return (answer);
-}
diff --git a/contrib/bind9/lib/dns/openssl_link.c b/contrib/bind9/lib/dns/openssl_link.c
deleted file mode 100644
index 56465aa00645..000000000000
--- a/contrib/bind9/lib/dns/openssl_link.c
+++ /dev/null
@@ -1,392 +0,0 @@
-/*
- * Portions Copyright (C) 2004-2012 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
- * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
- * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
- * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Portions Copyright (C) 1995-2000 by Network Associates, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
- * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
- * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
- * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * Principal Author: Brian Wellington
- * $Id$
- */
-#ifdef OPENSSL
-
-#include <config.h>
-
-#include <isc/entropy.h>
-#include <isc/mem.h>
-#include <isc/mutex.h>
-#include <isc/mutexblock.h>
-#include <isc/string.h>
-#include <isc/thread.h>
-#include <isc/util.h>
-
-#include <dns/log.h>
-
-#include <dst/result.h>
-
-#include "dst_internal.h"
-#include "dst_openssl.h"
-
-#ifdef USE_ENGINE
-#include <openssl/engine.h>
-#endif
-
-static RAND_METHOD *rm = NULL;
-
-static isc_mutex_t *locks = NULL;
-static int nlocks;
-
-#ifdef USE_ENGINE
-static ENGINE *e = NULL;
-#endif
-
-static int
-entropy_get(unsigned char *buf, int num) {
- isc_result_t result;
- if (num < 0)
- return (-1);
- result = dst__entropy_getdata(buf, (unsigned int) num, ISC_FALSE);
- return (result == ISC_R_SUCCESS ? 1 : -1);
-}
-
-static int
-entropy_status(void) {
- return (dst__entropy_status() > 32);
-}
-
-static int
-entropy_getpseudo(unsigned char *buf, int num) {
- isc_result_t result;
- if (num < 0)
- return (-1);
- result = dst__entropy_getdata(buf, (unsigned int) num, ISC_TRUE);
- return (result == ISC_R_SUCCESS ? 1 : -1);
-}
-
-static void
-entropy_add(const void *buf, int num, double entropy) {
- /*
- * Do nothing. The only call to this provides no useful data anyway.
- */
- UNUSED(buf);
- UNUSED(num);
- UNUSED(entropy);
-}
-
-static void
-lock_callback(int mode, int type, const char *file, int line) {
- UNUSED(file);
- UNUSED(line);
- if ((mode & CRYPTO_LOCK) != 0)
- LOCK(&locks[type]);
- else
- UNLOCK(&locks[type]);
-}
-
-static unsigned long
-id_callback(void) {
- return ((unsigned long)isc_thread_self());
-}
-
-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
-mem_free(void *ptr) {
- INSIST(dst__memory_pool != NULL);
- if (ptr != NULL)
- isc_mem_free(dst__memory_pool, 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(const char *engine) {
- isc_result_t result;
-#ifdef USE_ENGINE
- ENGINE *re;
-#else
-
- UNUSED(engine);
-#endif
-
-#ifdef DNS_CRYPTO_LEAKS
- CRYPTO_malloc_debug_init();
- CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
- CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
-#endif
- CRYPTO_set_mem_functions(mem_alloc, mem_realloc, mem_free);
- nlocks = CRYPTO_num_locks();
- locks = mem_alloc(sizeof(isc_mutex_t) * nlocks);
- if (locks == NULL)
- return (ISC_R_NOMEMORY);
- result = isc_mutexblock_init(locks, nlocks);
- if (result != ISC_R_SUCCESS)
- goto cleanup_mutexalloc;
- CRYPTO_set_locking_callback(lock_callback);
- CRYPTO_set_id_callback(id_callback);
-
- ERR_load_crypto_strings();
-
- rm = mem_alloc(sizeof(RAND_METHOD));
- if (rm == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup_mutexinit;
- }
- rm->seed = NULL;
- rm->bytes = entropy_get;
- rm->cleanup = NULL;
- rm->add = entropy_add;
- rm->pseudorand = entropy_getpseudo;
- rm->status = entropy_status;
-
-#ifdef USE_ENGINE
- OPENSSL_config(NULL);
-
- if (engine != NULL && *engine == '\0')
- engine = NULL;
-
- if (engine != NULL) {
- e = ENGINE_by_id(engine);
- if (e == NULL) {
- result = DST_R_NOENGINE;
- goto cleanup_rm;
- }
- /* This will init the engine. */
- if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
- result = DST_R_NOENGINE;
- goto cleanup_rm;
- }
- }
-
- re = ENGINE_get_default_RAND();
- if (re == NULL) {
- re = ENGINE_new();
- if (re == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup_rm;
- }
- ENGINE_set_RAND(re, rm);
- ENGINE_set_default_RAND(re);
- ENGINE_free(re);
- } else
- ENGINE_finish(re);
-#else
- RAND_set_rand_method(rm);
-#endif /* USE_ENGINE */
- return (ISC_R_SUCCESS);
-
-#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);
-}
-
-void
-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_free();
-#endif
- OBJ_cleanup();
- EVP_cleanup();
-#if defined(USE_ENGINE)
- if (e != NULL)
- ENGINE_free(e);
- e = NULL;
-#if defined(USE_ENGINE) && OPENSSL_VERSION_NUMBER >= 0x00907000L
- ENGINE_cleanup();
-#endif
-#endif
-#if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
- CRYPTO_cleanup_all_ex_data();
-#endif
- ERR_clear_error();
- ERR_remove_state(0);
- ERR_free_strings();
-
-#ifdef DNS_CRYPTO_LEAKS
- CRYPTO_mem_leaks_fp(stderr);
-#endif
-
- if (locks != NULL) {
- CRYPTO_set_locking_callback(NULL);
- DESTROYMUTEXBLOCK(locks, nlocks);
- mem_free(locks);
- locks = NULL;
- }
-}
-
-static isc_result_t
-toresult(isc_result_t fallback) {
- isc_result_t result = fallback;
- unsigned long err = ERR_get_error();
-#ifdef HAVE_OPENSSL_ECDSA
- int lib = ERR_GET_LIB(err);
-#endif
- int reason = ERR_GET_REASON(err);
-
- switch (reason) {
- /*
- * ERR_* errors are globally unique; others
- * are unique per sublibrary
- */
- case ERR_R_MALLOC_FAILURE:
- result = ISC_R_NOMEMORY;
- break;
- default:
-#ifdef HAVE_OPENSSL_ECDSA
- if (lib == ERR_R_ECDSA_LIB &&
- reason == ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED) {
- result = ISC_R_NOENTROPY;
- break;
- }
-#endif
- break;
- }
-
- return (result);
-}
-
-isc_result_t
-dst__openssl_toresult(isc_result_t fallback) {
- isc_result_t result;
-
- result = toresult(fallback);
-
- ERR_clear_error();
- return (result);
-}
-
-isc_result_t
-dst__openssl_toresult2(const char *funcname, isc_result_t fallback) {
- return (dst__openssl_toresult3(DNS_LOGCATEGORY_GENERAL,
- funcname, fallback));
-}
-
-isc_result_t
-dst__openssl_toresult3(isc_logcategory_t *category,
- const char *funcname, isc_result_t fallback) {
- isc_result_t result;
- unsigned long err;
- const char *file, *data;
- int line, flags;
- char buf[256];
-
- result = toresult(fallback);
-
- isc_log_write(dns_lctx, category,
- DNS_LOGMODULE_CRYPTO, ISC_LOG_WARNING,
- "%s failed (%s)", funcname,
- isc_result_totext(result));
-
- if (result == ISC_R_NOMEMORY)
- goto done;
-
- for (;;) {
- err = ERR_get_error_line_data(&file, &line, &data, &flags);
- if (err == 0U)
- goto done;
- ERR_error_string_n(err, buf, sizeof(buf));
- isc_log_write(dns_lctx, category,
- DNS_LOGMODULE_CRYPTO, ISC_LOG_INFO,
- "%s:%s:%d:%s", buf, file, line,
- (flags & ERR_TXT_STRING) ? data : "");
- }
-
- done:
- ERR_clear_error();
- return (result);
-}
-
-#if defined(USE_ENGINE)
-ENGINE *
-dst__openssl_getengine(const char *engine) {
-
- if (engine == NULL)
- return (NULL);
- if (e == NULL)
- return (NULL);
- if (strcmp(engine, ENGINE_get_id(e)) == 0)
- return (e);
- return (NULL);
-}
-#endif
-
-#else /* OPENSSL */
-
-#include <isc/util.h>
-
-EMPTY_TRANSLATION_UNIT
-
-#endif /* OPENSSL */
-/*! \file */
diff --git a/contrib/bind9/lib/dns/openssldh_link.c b/contrib/bind9/lib/dns/openssldh_link.c
deleted file mode 100644
index 36b8a412a3ee..000000000000
--- a/contrib/bind9/lib/dns/openssldh_link.c
+++ /dev/null
@@ -1,678 +0,0 @@
-/*
- * Portions Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Portions Copyright (C) 1999-2002 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
- * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
- * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
- * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Portions Copyright (C) 1995-2000 by Network Associates, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
- * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
- * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
- * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * Principal Author: Brian Wellington
- * $Id: openssldh_link.c,v 1.20 2011/01/11 23:47:13 tbox Exp $
- */
-
-#ifdef OPENSSL
-
-#include <config.h>
-
-#include <ctype.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"
-
-#define PRIME768 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088" \
- "A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25" \
- "F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF"
-
-#define PRIME1024 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08" \
- "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF2" \
- "5F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406" \
- "B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF"
-
-#define PRIME1536 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \
- "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \
- "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \
- "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \
- "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \
- "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \
- "83655D23DCA3AD961C62F356208552BB9ED529077096966D" \
- "670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF"
-
-
-static isc_result_t openssldh_todns(const dst_key_t *key, isc_buffer_t *data);
-
-static BIGNUM bn2, bn768, bn1024, bn1536;
-
-static isc_result_t
-openssldh_computesecret(const dst_key_t *pub, const dst_key_t *priv,
- isc_buffer_t *secret)
-{
- DH *dhpub, *dhpriv;
- int ret;
- isc_region_t r;
- unsigned int len;
-
- REQUIRE(pub->keydata.dh != NULL);
- REQUIRE(priv->keydata.dh != NULL);
-
- dhpub = pub->keydata.dh;
- dhpriv = priv->keydata.dh;
-
- len = DH_size(dhpriv);
- isc_buffer_availableregion(secret, &r);
- if (r.length < len)
- return (ISC_R_NOSPACE);
- ret = DH_compute_key(r.base, dhpub->pub_key, dhpriv);
- if (ret == 0)
- return (dst__openssl_toresult2("DH_compute_key",
- DST_R_COMPUTESECRETFAILURE));
- isc_buffer_add(secret, len);
- return (ISC_R_SUCCESS);
-}
-
-static isc_boolean_t
-openssldh_compare(const dst_key_t *key1, const dst_key_t *key2) {
- int status;
- DH *dh1, *dh2;
-
- dh1 = key1->keydata.dh;
- dh2 = key2->keydata.dh;
-
- if (dh1 == NULL && dh2 == NULL)
- return (ISC_TRUE);
- else if (dh1 == NULL || dh2 == NULL)
- return (ISC_FALSE);
-
- status = BN_cmp(dh1->p, dh2->p) ||
- BN_cmp(dh1->g, dh2->g) ||
- BN_cmp(dh1->pub_key, dh2->pub_key);
-
- if (status != 0)
- return (ISC_FALSE);
-
- if (dh1->priv_key != NULL || dh2->priv_key != NULL) {
- if (dh1->priv_key == NULL || dh2->priv_key == NULL)
- return (ISC_FALSE);
- if (BN_cmp(dh1->priv_key, dh2->priv_key) != 0)
- return (ISC_FALSE);
- }
- return (ISC_TRUE);
-}
-
-static isc_boolean_t
-openssldh_paramcompare(const dst_key_t *key1, const dst_key_t *key2) {
- int status;
- DH *dh1, *dh2;
-
- dh1 = key1->keydata.dh;
- dh2 = key2->keydata.dh;
-
- if (dh1 == NULL && dh2 == NULL)
- return (ISC_TRUE);
- else if (dh1 == NULL || dh2 == NULL)
- return (ISC_FALSE);
-
- status = BN_cmp(dh1->p, dh2->p) ||
- BN_cmp(dh1->g, dh2->g);
-
- if (status != 0)
- return (ISC_FALSE);
- 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, 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
-
- if (generator == 0) {
- if (key->key_size == 768 ||
- key->key_size == 1024 ||
- key->key_size == 1536)
- {
- dh = DH_new();
- if (dh == NULL)
- return (dst__openssl_toresult(ISC_R_NOMEMORY));
- if (key->key_size == 768)
- dh->p = &bn768;
- else if (key->key_size == 1024)
- dh->p = &bn1024;
- else
- dh->p = &bn1536;
- dh->g = &bn2;
- } else
- generator = 2;
- }
-
- if (generator != 0) {
-#if OPENSSL_VERSION_NUMBER > 0x00908000L
- dh = DH_new();
- if (dh == NULL)
- return (dst__openssl_toresult(ISC_R_NOMEMORY));
-
- 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)) {
- DH_free(dh);
- return (dst__openssl_toresult2(
- "DH_generate_parameters_ex",
- DST_R_OPENSSLFAILURE));
- }
-#else
- dh = DH_generate_parameters(key->key_size, generator,
- NULL, NULL);
-#endif
- }
-
- if (dh == NULL)
- return (dst__openssl_toresult2("DH_generate_parameters",
- DST_R_OPENSSLFAILURE));
-
- if (DH_generate_key(dh) == 0) {
- DH_free(dh);
- return (dst__openssl_toresult2("DH_generate_key",
- DST_R_OPENSSLFAILURE));
- }
- dh->flags &= ~DH_FLAG_CACHE_MONT_P;
-
- key->keydata.dh = dh;
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_boolean_t
-openssldh_isprivate(const dst_key_t *key) {
- DH *dh = key->keydata.dh;
- return (ISC_TF(dh != NULL && dh->priv_key != NULL));
-}
-
-static void
-openssldh_destroy(dst_key_t *key) {
- DH *dh = key->keydata.dh;
-
- if (dh == NULL)
- return;
-
- if (dh->p == &bn768 || dh->p == &bn1024 || dh->p == &bn1536)
- dh->p = NULL;
- if (dh->g == &bn2)
- dh->g = NULL;
- DH_free(dh);
- key->keydata.dh = NULL;
-}
-
-static void
-uint16_toregion(isc_uint16_t val, isc_region_t *region) {
- *region->base++ = (val & 0xff00) >> 8;
- *region->base++ = (val & 0x00ff);
-}
-
-static isc_uint16_t
-uint16_fromregion(isc_region_t *region) {
- isc_uint16_t val;
- unsigned char *cp = region->base;
-
- val = ((unsigned int)(cp[0])) << 8;
- val |= ((unsigned int)(cp[1]));
-
- region->base += 2;
- return (val);
-}
-
-static isc_result_t
-openssldh_todns(const dst_key_t *key, isc_buffer_t *data) {
- DH *dh;
- isc_region_t r;
- isc_uint16_t dnslen, plen, glen, publen;
-
- REQUIRE(key->keydata.dh != NULL);
-
- dh = key->keydata.dh;
-
- isc_buffer_availableregion(data, &r);
-
- if (dh->g == &bn2 &&
- (dh->p == &bn768 || dh->p == &bn1024 || dh->p == &bn1536)) {
- plen = 1;
- glen = 0;
- }
- else {
- plen = BN_num_bytes(dh->p);
- glen = BN_num_bytes(dh->g);
- }
- publen = BN_num_bytes(dh->pub_key);
- dnslen = plen + glen + publen + 6;
- if (r.length < (unsigned int) dnslen)
- return (ISC_R_NOSPACE);
-
- uint16_toregion(plen, &r);
- if (plen == 1) {
- if (dh->p == &bn768)
- *r.base = 1;
- else if (dh->p == &bn1024)
- *r.base = 2;
- else
- *r.base = 3;
- }
- else
- BN_bn2bin(dh->p, r.base);
- r.base += plen;
-
- uint16_toregion(glen, &r);
- if (glen > 0)
- BN_bn2bin(dh->g, r.base);
- r.base += glen;
-
- uint16_toregion(publen, &r);
- BN_bn2bin(dh->pub_key, r.base);
- r.base += publen;
-
- isc_buffer_add(data, dnslen);
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-openssldh_fromdns(dst_key_t *key, isc_buffer_t *data) {
- DH *dh;
- isc_region_t r;
- isc_uint16_t plen, glen, publen;
- int special = 0;
-
- isc_buffer_remainingregion(data, &r);
- if (r.length == 0)
- return (ISC_R_SUCCESS);
-
- dh = DH_new();
- if (dh == NULL)
- return (dst__openssl_toresult(ISC_R_NOMEMORY));
- dh->flags &= ~DH_FLAG_CACHE_MONT_P;
-
- /*
- * Read the prime length. 1 & 2 are table entries, > 16 means a
- * prime follows, otherwise an error.
- */
- if (r.length < 2) {
- DH_free(dh);
- return (DST_R_INVALIDPUBLICKEY);
- }
- plen = uint16_fromregion(&r);
- if (plen < 16 && plen != 1 && plen != 2) {
- DH_free(dh);
- return (DST_R_INVALIDPUBLICKEY);
- }
- if (r.length < plen) {
- DH_free(dh);
- return (DST_R_INVALIDPUBLICKEY);
- }
- if (plen == 1 || plen == 2) {
- if (plen == 1)
- special = *r.base++;
- else
- special = uint16_fromregion(&r);
- switch (special) {
- case 1:
- dh->p = &bn768;
- break;
- case 2:
- dh->p = &bn1024;
- break;
- case 3:
- dh->p = &bn1536;
- break;
- default:
- DH_free(dh);
- return (DST_R_INVALIDPUBLICKEY);
- }
- }
- else {
- dh->p = BN_bin2bn(r.base, plen, NULL);
- r.base += plen;
- }
-
- /*
- * Read the generator length. This should be 0 if the prime was
- * special, but it might not be. If it's 0 and the prime is not
- * special, we have a problem.
- */
- if (r.length < 2) {
- DH_free(dh);
- return (DST_R_INVALIDPUBLICKEY);
- }
- glen = uint16_fromregion(&r);
- if (r.length < glen) {
- DH_free(dh);
- return (DST_R_INVALIDPUBLICKEY);
- }
- if (special != 0) {
- if (glen == 0)
- dh->g = &bn2;
- else {
- dh->g = BN_bin2bn(r.base, glen, NULL);
- if (BN_cmp(dh->g, &bn2) == 0) {
- BN_free(dh->g);
- dh->g = &bn2;
- }
- else {
- DH_free(dh);
- return (DST_R_INVALIDPUBLICKEY);
- }
- }
- }
- else {
- if (glen == 0) {
- DH_free(dh);
- return (DST_R_INVALIDPUBLICKEY);
- }
- dh->g = BN_bin2bn(r.base, glen, NULL);
- }
- r.base += glen;
-
- if (r.length < 2) {
- DH_free(dh);
- return (DST_R_INVALIDPUBLICKEY);
- }
- publen = uint16_fromregion(&r);
- if (r.length < publen) {
- DH_free(dh);
- return (DST_R_INVALIDPUBLICKEY);
- }
- dh->pub_key = BN_bin2bn(r.base, publen, NULL);
- r.base += publen;
-
- key->key_size = BN_num_bits(dh->p);
-
- isc_buffer_forward(data, plen + glen + publen + 6);
-
- key->keydata.dh = dh;
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-openssldh_tofile(const dst_key_t *key, const char *directory) {
- int i;
- DH *dh;
- dst_private_t priv;
- unsigned char *bufs[4];
- isc_result_t result;
-
- if (key->keydata.dh == NULL)
- return (DST_R_NULLKEY);
-
- dh = key->keydata.dh;
-
- memset(bufs, 0, sizeof(bufs));
- for (i = 0; i < 4; i++) {
- bufs[i] = isc_mem_get(key->mctx, BN_num_bytes(dh->p));
- if (bufs[i] == NULL) {
- result = ISC_R_NOMEMORY;
- goto fail;
- }
- }
-
- i = 0;
-
- priv.elements[i].tag = TAG_DH_PRIME;
- priv.elements[i].length = BN_num_bytes(dh->p);
- BN_bn2bin(dh->p, bufs[i]);
- priv.elements[i].data = bufs[i];
- i++;
-
- priv.elements[i].tag = TAG_DH_GENERATOR;
- priv.elements[i].length = BN_num_bytes(dh->g);
- BN_bn2bin(dh->g, bufs[i]);
- priv.elements[i].data = bufs[i];
- i++;
-
- priv.elements[i].tag = TAG_DH_PRIVATE;
- priv.elements[i].length = BN_num_bytes(dh->priv_key);
- BN_bn2bin(dh->priv_key, bufs[i]);
- priv.elements[i].data = bufs[i];
- i++;
-
- priv.elements[i].tag = TAG_DH_PUBLIC;
- priv.elements[i].length = BN_num_bytes(dh->pub_key);
- BN_bn2bin(dh->pub_key, bufs[i]);
- priv.elements[i].data = bufs[i];
- i++;
-
- priv.nelements = i;
- result = dst__privstruct_writefile(key, &priv, directory);
- fail:
- for (i = 0; i < 4; i++) {
- if (bufs[i] == NULL)
- break;
- isc_mem_put(key->mctx, bufs[i], BN_num_bytes(dh->p));
- }
- return (result);
-}
-
-static isc_result_t
-openssldh_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
- dst_private_t priv;
- isc_result_t ret;
- int i;
- DH *dh = NULL;
- isc_mem_t *mctx;
-#define DST_RET(a) {ret = a; goto err;}
-
- UNUSED(pub);
- mctx = key->mctx;
-
- /* read private key file */
- ret = dst__privstruct_parse(key, DST_ALG_DH, lexer, mctx, &priv);
- if (ret != ISC_R_SUCCESS)
- return (ret);
-
- dh = DH_new();
- if (dh == NULL)
- DST_RET(ISC_R_NOMEMORY);
- dh->flags &= ~DH_FLAG_CACHE_MONT_P;
- key->keydata.dh = dh;
-
- for (i = 0; i < priv.nelements; i++) {
- BIGNUM *bn;
- bn = BN_bin2bn(priv.elements[i].data,
- priv.elements[i].length, NULL);
- if (bn == NULL)
- DST_RET(ISC_R_NOMEMORY);
-
- switch (priv.elements[i].tag) {
- case TAG_DH_PRIME:
- dh->p = bn;
- break;
- case TAG_DH_GENERATOR:
- dh->g = bn;
- break;
- case TAG_DH_PRIVATE:
- dh->priv_key = bn;
- break;
- case TAG_DH_PUBLIC:
- dh->pub_key = bn;
- break;
- }
- }
- dst__privstruct_free(&priv, mctx);
-
- key->key_size = BN_num_bits(dh->p);
-
- if ((key->key_size == 768 ||
- key->key_size == 1024 ||
- key->key_size == 1536) &&
- BN_cmp(dh->g, &bn2) == 0)
- {
- if (key->key_size == 768 && BN_cmp(dh->p, &bn768) == 0) {
- BN_free(dh->p);
- BN_free(dh->g);
- dh->p = &bn768;
- dh->g = &bn2;
- } else if (key->key_size == 1024 &&
- BN_cmp(dh->p, &bn1024) == 0) {
- BN_free(dh->p);
- BN_free(dh->g);
- dh->p = &bn1024;
- dh->g = &bn2;
- } else if (key->key_size == 1536 &&
- BN_cmp(dh->p, &bn1536) == 0) {
- BN_free(dh->p);
- BN_free(dh->g);
- dh->p = &bn1536;
- dh->g = &bn2;
- }
- }
-
- return (ISC_R_SUCCESS);
-
- err:
- openssldh_destroy(key);
- dst__privstruct_free(&priv, mctx);
- memset(&priv, 0, sizeof(priv));
- return (ret);
-}
-
-static void
-BN_fromhex(BIGNUM *b, const char *str) {
- static const char hexdigits[] = "0123456789abcdef";
- unsigned char data[512];
- unsigned int i;
- BIGNUM *out;
-
- RUNTIME_CHECK(strlen(str) < 1024U && strlen(str) % 2 == 0U);
- for (i = 0; i < strlen(str); i += 2) {
- char *s;
- unsigned int high, low;
-
- s = strchr(hexdigits, tolower((unsigned char)str[i]));
- RUNTIME_CHECK(s != NULL);
- high = s - hexdigits;
-
- s = strchr(hexdigits, tolower((unsigned char)str[i + 1]));
- RUNTIME_CHECK(s != NULL);
- low = s - hexdigits;
-
- data[i/2] = (unsigned char)((high << 4) + low);
- }
- out = BN_bin2bn(data, strlen(str)/2, b);
- RUNTIME_CHECK(out != NULL);
-}
-
-static void
-openssldh_cleanup(void) {
- BN_free(&bn2);
- BN_free(&bn768);
- BN_free(&bn1024);
- BN_free(&bn1536);
-}
-
-static dst_func_t openssldh_functions = {
- NULL, /*%< createctx */
- NULL, /*%< destroyctx */
- NULL, /*%< adddata */
- NULL, /*%< openssldh_sign */
- NULL, /*%< openssldh_verify */
- NULL, /*%< openssldh_verify2 */
- openssldh_computesecret,
- openssldh_compare,
- openssldh_paramcompare,
- openssldh_generate,
- openssldh_isprivate,
- openssldh_destroy,
- openssldh_todns,
- openssldh_fromdns,
- openssldh_tofile,
- openssldh_parse,
- openssldh_cleanup,
- NULL, /*%< fromlabel */
- NULL, /*%< dump */
- NULL, /*%< restore */
-};
-
-isc_result_t
-dst__openssldh_init(dst_func_t **funcp) {
- REQUIRE(funcp != NULL);
- if (*funcp == NULL) {
- BN_init(&bn2);
- BN_init(&bn768);
- BN_init(&bn1024);
- BN_init(&bn1536);
- BN_set_word(&bn2, 2);
- BN_fromhex(&bn768, PRIME768);
- BN_fromhex(&bn1024, PRIME1024);
- BN_fromhex(&bn1536, PRIME1536);
- *funcp = &openssldh_functions;
- }
- return (ISC_R_SUCCESS);
-}
-
-#else /* OPENSSL */
-
-#include <isc/util.h>
-
-EMPTY_TRANSLATION_UNIT
-
-#endif /* OPENSSL */
-/*! \file */
diff --git a/contrib/bind9/lib/dns/openssldsa_link.c b/contrib/bind9/lib/dns/openssldsa_link.c
deleted file mode 100644
index 8bea1c09e05e..000000000000
--- a/contrib/bind9/lib/dns/openssldsa_link.c
+++ /dev/null
@@ -1,659 +0,0 @@
-/*
- * Portions Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Portions Copyright (C) 1999-2002 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
- * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
- * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
- * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Portions Copyright (C) 1995-2000 by Network Associates, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
- * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
- * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
- * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-#ifdef OPENSSL
-#ifndef USE_EVP
-#define USE_EVP 1
-#endif
-
-#include <config.h>
-
-#include <string.h>
-
-#include <isc/entropy.h>
-#include <isc/mem.h>
-#include <isc/sha1.h>
-#include <isc/util.h>
-
-#include <dst/result.h>
-
-#include "dst_internal.h"
-#include "dst_openssl.h"
-#include "dst_parse.h"
-
-#include <openssl/dsa.h>
-
-static isc_result_t openssldsa_todns(const dst_key_t *key, isc_buffer_t *data);
-
-static isc_result_t
-openssldsa_createctx(dst_key_t *key, dst_context_t *dctx) {
-#if USE_EVP
- EVP_MD_CTX *evp_md_ctx;
-
- UNUSED(key);
-
- evp_md_ctx = EVP_MD_CTX_create();
- if (evp_md_ctx == NULL)
- return (ISC_R_NOMEMORY);
-
- if (!EVP_DigestInit_ex(evp_md_ctx, EVP_dss1(), NULL)) {
- EVP_MD_CTX_destroy(evp_md_ctx);
- return (ISC_R_FAILURE);
- }
-
- dctx->ctxdata.evp_md_ctx = evp_md_ctx;
-
- return (ISC_R_SUCCESS);
-#else
- isc_sha1_t *sha1ctx;
-
- UNUSED(key);
-
- sha1ctx = isc_mem_get(dctx->mctx, sizeof(isc_sha1_t));
- isc_sha1_init(sha1ctx);
- dctx->ctxdata.sha1ctx = sha1ctx;
- return (ISC_R_SUCCESS);
-#endif
-}
-
-static void
-openssldsa_destroyctx(dst_context_t *dctx) {
-#if USE_EVP
- 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;
- }
-#else
- isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
-
- if (sha1ctx != NULL) {
- isc_sha1_invalidate(sha1ctx);
- isc_mem_put(dctx->mctx, sha1ctx, sizeof(isc_sha1_t));
- dctx->ctxdata.sha1ctx = NULL;
- }
-#endif
-}
-
-static isc_result_t
-openssldsa_adddata(dst_context_t *dctx, const isc_region_t *data) {
-#if USE_EVP
- 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);
- }
-#else
- isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
-
- isc_sha1_update(sha1ctx, data->base, data->length);
-#endif
- return (ISC_R_SUCCESS);
-}
-
-static int
-BN_bn2bin_fixed(BIGNUM *bn, unsigned char *buf, int size) {
- int bytes = size - BN_num_bytes(bn);
- while (bytes-- > 0)
- *buf++ = 0;
- BN_bn2bin(bn, buf);
- return (size);
-}
-
-static isc_result_t
-openssldsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
- dst_key_t *key = dctx->key;
- DSA *dsa = key->keydata.dsa;
- isc_region_t r;
- DSA_SIG *dsasig;
-#if USE_EVP
- EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
- EVP_PKEY *pkey;
- unsigned char *sigbuf;
- const unsigned char *sb;
- unsigned int siglen;
-#else
- isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
- unsigned char digest[ISC_SHA1_DIGESTLENGTH];
-#endif
-
- isc_buffer_availableregion(sig, &r);
- if (r.length < ISC_SHA1_DIGESTLENGTH * 2 + 1)
- return (ISC_R_NOSPACE);
-
-#if USE_EVP
- pkey = EVP_PKEY_new();
- if (pkey == NULL)
- return (ISC_R_NOMEMORY);
- if (!EVP_PKEY_set1_DSA(pkey, dsa)) {
- EVP_PKEY_free(pkey);
- return (ISC_R_FAILURE);
- }
- sigbuf = malloc(EVP_PKEY_size(pkey));
- if (sigbuf == NULL) {
- EVP_PKEY_free(pkey);
- return (ISC_R_NOMEMORY);
- }
- if (!EVP_SignFinal(evp_md_ctx, sigbuf, &siglen, pkey)) {
- EVP_PKEY_free(pkey);
- free(sigbuf);
- return (dst__openssl_toresult3(dctx->category,
- "EVP_SignFinal",
- ISC_R_FAILURE));
- }
- INSIST(EVP_PKEY_size(pkey) >= (int) siglen);
- EVP_PKEY_free(pkey);
- /* Convert from Dss-Sig-Value (RFC2459). */
- dsasig = DSA_SIG_new();
- if (dsasig == NULL) {
- free(sigbuf);
- return (ISC_R_NOMEMORY);
- }
- sb = sigbuf;
- if (d2i_DSA_SIG(&dsasig, &sb, (long) siglen) == NULL) {
- free(sigbuf);
- return (dst__openssl_toresult3(dctx->category,
- "d2i_DSA_SIG",
- ISC_R_FAILURE));
- }
- free(sigbuf);
-#elif 0
- /* Only use EVP for the Digest */
- if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &siglen)) {
- return (dst__openssl_toresult3(dctx->category,
- "EVP_DigestFinal_ex",
- ISC_R_FAILURE));
- }
- dsasig = DSA_do_sign(digest, ISC_SHA1_DIGESTLENGTH, dsa);
- if (dsasig == NULL)
- return (dst__openssl_toresult3(dctx->category,
- "DSA_do_sign",
- DST_R_SIGNFAILURE));
-#else
- isc_sha1_final(sha1ctx, digest);
-
- dsasig = DSA_do_sign(digest, ISC_SHA1_DIGESTLENGTH, dsa);
- if (dsasig == NULL)
- return (dst__openssl_toresult3(dctx->category,
- "DSA_do_sign",
- DST_R_SIGNFAILURE));
-#endif
- *r.base++ = (key->key_size - 512)/64;
- BN_bn2bin_fixed(dsasig->r, r.base, ISC_SHA1_DIGESTLENGTH);
- r.base += ISC_SHA1_DIGESTLENGTH;
- BN_bn2bin_fixed(dsasig->s, r.base, ISC_SHA1_DIGESTLENGTH);
- r.base += ISC_SHA1_DIGESTLENGTH;
- DSA_SIG_free(dsasig);
- isc_buffer_add(sig, ISC_SHA1_DIGESTLENGTH * 2 + 1);
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-openssldsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
- dst_key_t *key = dctx->key;
- DSA *dsa = key->keydata.dsa;
- int status = 0;
- unsigned char *cp = sig->base;
- DSA_SIG *dsasig;
-#if USE_EVP
- EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
-#if 0
- EVP_PKEY *pkey;
- unsigned char *sigbuf;
-#endif
- unsigned int siglen;
-#else
- isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
-#endif
- unsigned char digest[ISC_SHA1_DIGESTLENGTH];
-
-
-#if USE_EVP
-#if 1
- /* Only use EVP for the digest */
- if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &siglen)) {
- return (ISC_R_FAILURE);
- }
-#endif
-#else
- isc_sha1_final(sha1ctx, digest);
-#endif
-
- if (sig->length != 2 * ISC_SHA1_DIGESTLENGTH + 1) {
- return (DST_R_VERIFYFAILURE);
- }
-
- cp++; /*%< Skip T */
- dsasig = DSA_SIG_new();
- if (dsasig == NULL)
- return (ISC_R_NOMEMORY);
- dsasig->r = BN_bin2bn(cp, ISC_SHA1_DIGESTLENGTH, NULL);
- cp += ISC_SHA1_DIGESTLENGTH;
- dsasig->s = BN_bin2bn(cp, ISC_SHA1_DIGESTLENGTH, NULL);
-
-#if 0
- pkey = EVP_PKEY_new();
- if (pkey == NULL)
- return (ISC_R_NOMEMORY);
- if (!EVP_PKEY_set1_DSA(pkey, dsa)) {
- EVP_PKEY_free(pkey);
- return (ISC_R_FAILURE);
- }
- /* Convert to Dss-Sig-Value (RFC2459). */
- sigbuf = malloc(EVP_PKEY_size(pkey) + 50);
- if (sigbuf == NULL) {
- EVP_PKEY_free(pkey);
- return (ISC_R_NOMEMORY);
- }
- siglen = (unsigned) i2d_DSA_SIG(dsasig, &sigbuf);
- INSIST(EVP_PKEY_size(pkey) >= (int) siglen);
- status = EVP_VerifyFinal(evp_md_ctx, sigbuf, siglen, pkey);
- EVP_PKEY_free(pkey);
- free(sigbuf);
-#else
- status = DSA_do_verify(digest, ISC_SHA1_DIGESTLENGTH, dsasig, dsa);
-#endif
- DSA_SIG_free(dsasig);
- switch (status) {
- case 1:
- return (ISC_R_SUCCESS);
- case 0:
- return (dst__openssl_toresult(DST_R_VERIFYFAILURE));
- default:
- return (dst__openssl_toresult3(dctx->category,
- "DSA_do_verify",
- DST_R_VERIFYFAILURE));
- }
-}
-
-static isc_boolean_t
-openssldsa_compare(const dst_key_t *key1, const dst_key_t *key2) {
- int status;
- DSA *dsa1, *dsa2;
-
- dsa1 = key1->keydata.dsa;
- dsa2 = key2->keydata.dsa;
-
- if (dsa1 == NULL && dsa2 == NULL)
- return (ISC_TRUE);
- else if (dsa1 == NULL || dsa2 == NULL)
- return (ISC_FALSE);
-
- status = BN_cmp(dsa1->p, dsa2->p) ||
- BN_cmp(dsa1->q, dsa2->q) ||
- BN_cmp(dsa1->g, dsa2->g) ||
- BN_cmp(dsa1->pub_key, dsa2->pub_key);
-
- if (status != 0)
- return (ISC_FALSE);
-
- if (dsa1->priv_key != NULL || dsa2->priv_key != NULL) {
- if (dsa1->priv_key == NULL || dsa2->priv_key == NULL)
- return (ISC_FALSE);
- if (BN_cmp(dsa1->priv_key, dsa2->priv_key))
- return (ISC_FALSE);
- }
- 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
-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),
- ISC_FALSE);
- if (result != ISC_R_SUCCESS)
- return (result);
-
-#if OPENSSL_VERSION_NUMBER > 0x00908000L
- dsa = DSA_new();
- if (dsa == NULL)
- return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
-
- 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,
- &cb))
- {
- DSA_free(dsa);
- return (dst__openssl_toresult2("DSA_generate_parameters_ex",
- DST_R_OPENSSLFAILURE));
- }
-#else
- dsa = DSA_generate_parameters(key->key_size, rand_array,
- ISC_SHA1_DIGESTLENGTH, NULL, NULL,
- NULL, NULL);
- if (dsa == NULL)
- return (dst__openssl_toresult2("DSA_generate_parameters",
- DST_R_OPENSSLFAILURE));
-#endif
-
- if (DSA_generate_key(dsa) == 0) {
- DSA_free(dsa);
- return (dst__openssl_toresult2("DSA_generate_key",
- DST_R_OPENSSLFAILURE));
- }
- dsa->flags &= ~DSA_FLAG_CACHE_MONT_P;
-
- key->keydata.dsa = dsa;
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_boolean_t
-openssldsa_isprivate(const dst_key_t *key) {
- DSA *dsa = key->keydata.dsa;
- return (ISC_TF(dsa != NULL && dsa->priv_key != NULL));
-}
-
-static void
-openssldsa_destroy(dst_key_t *key) {
- DSA *dsa = key->keydata.dsa;
- DSA_free(dsa);
- key->keydata.dsa = NULL;
-}
-
-
-static isc_result_t
-openssldsa_todns(const dst_key_t *key, isc_buffer_t *data) {
- DSA *dsa;
- isc_region_t r;
- int dnslen;
- unsigned int t, p_bytes;
-
- REQUIRE(key->keydata.dsa != NULL);
-
- dsa = key->keydata.dsa;
-
- isc_buffer_availableregion(data, &r);
-
- t = (BN_num_bytes(dsa->p) - 64) / 8;
- if (t > 8)
- return (DST_R_INVALIDPUBLICKEY);
- p_bytes = 64 + 8 * t;
-
- dnslen = 1 + (key->key_size * 3)/8 + ISC_SHA1_DIGESTLENGTH;
- if (r.length < (unsigned int) dnslen)
- return (ISC_R_NOSPACE);
-
- *r.base++ = t;
- BN_bn2bin_fixed(dsa->q, r.base, ISC_SHA1_DIGESTLENGTH);
- r.base += ISC_SHA1_DIGESTLENGTH;
- BN_bn2bin_fixed(dsa->p, r.base, key->key_size/8);
- r.base += p_bytes;
- BN_bn2bin_fixed(dsa->g, r.base, key->key_size/8);
- r.base += p_bytes;
- BN_bn2bin_fixed(dsa->pub_key, r.base, key->key_size/8);
- r.base += p_bytes;
-
- isc_buffer_add(data, dnslen);
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-openssldsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
- DSA *dsa;
- isc_region_t r;
- unsigned int t, p_bytes;
- isc_mem_t *mctx = key->mctx;
-
- UNUSED(mctx);
-
- isc_buffer_remainingregion(data, &r);
- if (r.length == 0)
- return (ISC_R_SUCCESS);
-
- dsa = DSA_new();
- if (dsa == NULL)
- return (ISC_R_NOMEMORY);
- dsa->flags &= ~DSA_FLAG_CACHE_MONT_P;
-
- t = (unsigned int) *r.base++;
- if (t > 8) {
- DSA_free(dsa);
- return (DST_R_INVALIDPUBLICKEY);
- }
- p_bytes = 64 + 8 * t;
-
- if (r.length < 1 + ISC_SHA1_DIGESTLENGTH + 3 * p_bytes) {
- DSA_free(dsa);
- return (DST_R_INVALIDPUBLICKEY);
- }
-
- dsa->q = BN_bin2bn(r.base, ISC_SHA1_DIGESTLENGTH, NULL);
- r.base += ISC_SHA1_DIGESTLENGTH;
-
- dsa->p = BN_bin2bn(r.base, p_bytes, NULL);
- r.base += p_bytes;
-
- dsa->g = BN_bin2bn(r.base, p_bytes, NULL);
- r.base += p_bytes;
-
- dsa->pub_key = BN_bin2bn(r.base, p_bytes, NULL);
- r.base += p_bytes;
-
- key->key_size = p_bytes * 8;
-
- isc_buffer_forward(data, 1 + ISC_SHA1_DIGESTLENGTH + 3 * p_bytes);
-
- key->keydata.dsa = dsa;
-
- return (ISC_R_SUCCESS);
-}
-
-
-static isc_result_t
-openssldsa_tofile(const dst_key_t *key, const char *directory) {
- int cnt = 0;
- DSA *dsa;
- dst_private_t priv;
- unsigned char bufs[5][128];
-
- if (key->keydata.dsa == NULL)
- return (DST_R_NULLKEY);
-
- dsa = key->keydata.dsa;
-
- priv.elements[cnt].tag = TAG_DSA_PRIME;
- priv.elements[cnt].length = BN_num_bytes(dsa->p);
- BN_bn2bin(dsa->p, bufs[cnt]);
- priv.elements[cnt].data = bufs[cnt];
- cnt++;
-
- priv.elements[cnt].tag = TAG_DSA_SUBPRIME;
- priv.elements[cnt].length = BN_num_bytes(dsa->q);
- BN_bn2bin(dsa->q, bufs[cnt]);
- priv.elements[cnt].data = bufs[cnt];
- cnt++;
-
- priv.elements[cnt].tag = TAG_DSA_BASE;
- priv.elements[cnt].length = BN_num_bytes(dsa->g);
- BN_bn2bin(dsa->g, bufs[cnt]);
- priv.elements[cnt].data = bufs[cnt];
- cnt++;
-
- priv.elements[cnt].tag = TAG_DSA_PRIVATE;
- priv.elements[cnt].length = BN_num_bytes(dsa->priv_key);
- BN_bn2bin(dsa->priv_key, bufs[cnt]);
- priv.elements[cnt].data = bufs[cnt];
- cnt++;
-
- priv.elements[cnt].tag = TAG_DSA_PUBLIC;
- priv.elements[cnt].length = BN_num_bytes(dsa->pub_key);
- BN_bn2bin(dsa->pub_key, bufs[cnt]);
- priv.elements[cnt].data = bufs[cnt];
- cnt++;
-
- priv.nelements = cnt;
- return (dst__privstruct_writefile(key, &priv, directory));
-}
-
-static isc_result_t
-openssldsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
- dst_private_t priv;
- isc_result_t ret;
- int i;
- DSA *dsa = NULL;
- 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)
- return (ret);
-
- dsa = DSA_new();
- if (dsa == NULL)
- DST_RET(ISC_R_NOMEMORY);
- dsa->flags &= ~DSA_FLAG_CACHE_MONT_P;
- key->keydata.dsa = dsa;
-
- for (i=0; i < priv.nelements; i++) {
- BIGNUM *bn;
- bn = BN_bin2bn(priv.elements[i].data,
- priv.elements[i].length, NULL);
- if (bn == NULL)
- DST_RET(ISC_R_NOMEMORY);
-
- switch (priv.elements[i].tag) {
- case TAG_DSA_PRIME:
- dsa->p = bn;
- break;
- case TAG_DSA_SUBPRIME:
- dsa->q = bn;
- break;
- case TAG_DSA_BASE:
- dsa->g = bn;
- break;
- case TAG_DSA_PRIVATE:
- dsa->priv_key = bn;
- break;
- case TAG_DSA_PUBLIC:
- dsa->pub_key = bn;
- break;
- }
- }
- dst__privstruct_free(&priv, mctx);
-
- key->key_size = BN_num_bits(dsa->p);
-
- return (ISC_R_SUCCESS);
-
- err:
- openssldsa_destroy(key);
- dst__privstruct_free(&priv, mctx);
- memset(&priv, 0, sizeof(priv));
- return (ret);
-}
-
-static dst_func_t openssldsa_functions = {
- openssldsa_createctx,
- openssldsa_destroyctx,
- openssldsa_adddata,
- openssldsa_sign,
- openssldsa_verify,
- NULL, /*%< verify2 */
- NULL, /*%< computesecret */
- openssldsa_compare,
- NULL, /*%< paramcompare */
- openssldsa_generate,
- openssldsa_isprivate,
- openssldsa_destroy,
- openssldsa_todns,
- openssldsa_fromdns,
- openssldsa_tofile,
- openssldsa_parse,
- NULL, /*%< cleanup */
- NULL, /*%< fromlabel */
- NULL, /*%< dump */
- NULL, /*%< restore */
-};
-
-isc_result_t
-dst__openssldsa_init(dst_func_t **funcp) {
- REQUIRE(funcp != NULL);
- if (*funcp == NULL)
- *funcp = &openssldsa_functions;
- return (ISC_R_SUCCESS);
-}
-
-#else /* OPENSSL */
-
-#include <isc/util.h>
-
-EMPTY_TRANSLATION_UNIT
-
-#endif /* OPENSSL */
-/*! \file */
diff --git a/contrib/bind9/lib/dns/opensslecdsa_link.c b/contrib/bind9/lib/dns/opensslecdsa_link.c
deleted file mode 100644
index c3f5061b7546..000000000000
--- a/contrib/bind9/lib/dns/opensslecdsa_link.c
+++ /dev/null
@@ -1,607 +0,0 @@
-/*
- * Copyright (C) 2012, 2013 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-#include <config.h>
-
-#ifdef HAVE_OPENSSL_ECDSA
-
-#if !defined(HAVE_EVP_SHA256) || !defined(HAVE_EVP_SHA384)
-#error "ECDSA without EVP for SHA2?"
-#endif
-
-#include <isc/entropy.h>
-#include <isc/mem.h>
-#include <isc/sha2.h>
-#include <isc/string.h>
-#include <isc/util.h>
-
-#include <dns/keyvalues.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/ecdsa.h>
-#include <openssl/bn.h>
-
-#ifndef NID_X9_62_prime256v1
-#error "P-256 group is not known (NID_X9_62_prime256v1)"
-#endif
-#ifndef NID_secp384r1
-#error "P-384 group is not known (NID_secp384r1)"
-#endif
-
-#define DST_RET(a) {ret = a; goto err;}
-
-static isc_result_t opensslecdsa_todns(const dst_key_t *key,
- isc_buffer_t *data);
-
-static isc_result_t
-opensslecdsa_createctx(dst_key_t *key, dst_context_t *dctx) {
- EVP_MD_CTX *evp_md_ctx;
- const EVP_MD *type = NULL;
-
- UNUSED(key);
- REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 ||
- dctx->key->key_alg == DST_ALG_ECDSA384);
-
- evp_md_ctx = EVP_MD_CTX_create();
- if (evp_md_ctx == NULL)
- return (ISC_R_NOMEMORY);
- if (dctx->key->key_alg == DST_ALG_ECDSA256)
- type = EVP_sha256();
- else
- type = EVP_sha384();
-
- if (!EVP_DigestInit_ex(evp_md_ctx, type, NULL)) {
- EVP_MD_CTX_destroy(evp_md_ctx);
- return (dst__openssl_toresult3(dctx->category,
- "EVP_DigestInit_ex",
- ISC_R_FAILURE));
- }
-
- dctx->ctxdata.evp_md_ctx = evp_md_ctx;
-
- return (ISC_R_SUCCESS);
-}
-
-static void
-opensslecdsa_destroyctx(dst_context_t *dctx) {
- EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
-
- REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 ||
- dctx->key->key_alg == DST_ALG_ECDSA384);
-
- if (evp_md_ctx != NULL) {
- EVP_MD_CTX_destroy(evp_md_ctx);
- dctx->ctxdata.evp_md_ctx = NULL;
- }
-}
-
-static isc_result_t
-opensslecdsa_adddata(dst_context_t *dctx, const isc_region_t *data) {
- EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
-
- REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 ||
- dctx->key->key_alg == DST_ALG_ECDSA384);
-
- if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length))
- return (dst__openssl_toresult3(dctx->category,
- "EVP_DigestUpdate",
- ISC_R_FAILURE));
-
- return (ISC_R_SUCCESS);
-}
-
-static int
-BN_bn2bin_fixed(BIGNUM *bn, unsigned char *buf, int size) {
- int bytes = size - BN_num_bytes(bn);
-
- while (bytes-- > 0)
- *buf++ = 0;
- BN_bn2bin(bn, buf);
- return (size);
-}
-
-static isc_result_t
-opensslecdsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
- isc_result_t ret;
- dst_key_t *key = dctx->key;
- isc_region_t r;
- ECDSA_SIG *ecdsasig;
- EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
- EVP_PKEY *pkey = key->keydata.pkey;
- EC_KEY *eckey = EVP_PKEY_get1_EC_KEY(pkey);
- unsigned int dgstlen, siglen;
- unsigned char digest[EVP_MAX_MD_SIZE];
-
- REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
- key->key_alg == DST_ALG_ECDSA384);
-
- if (eckey == NULL)
- return (ISC_R_FAILURE);
-
- if (key->key_alg == DST_ALG_ECDSA256)
- siglen = DNS_SIG_ECDSA256SIZE;
- else
- siglen = DNS_SIG_ECDSA384SIZE;
-
- isc_buffer_availableregion(sig, &r);
- if (r.length < siglen)
- DST_RET(ISC_R_NOSPACE);
-
- if (!EVP_DigestFinal(evp_md_ctx, digest, &dgstlen))
- DST_RET(dst__openssl_toresult3(dctx->category,
- "EVP_DigestFinal",
- ISC_R_FAILURE));
-
- ecdsasig = ECDSA_do_sign(digest, dgstlen, eckey);
- if (ecdsasig == NULL)
- DST_RET(dst__openssl_toresult3(dctx->category,
- "ECDSA_do_sign",
- DST_R_SIGNFAILURE));
- BN_bn2bin_fixed(ecdsasig->r, r.base, siglen / 2);
- r.base += siglen / 2;
- BN_bn2bin_fixed(ecdsasig->s, r.base, siglen / 2);
- r.base += siglen / 2;
- ECDSA_SIG_free(ecdsasig);
- isc_buffer_add(sig, siglen);
- ret = ISC_R_SUCCESS;
-
- err:
- if (eckey != NULL)
- EC_KEY_free(eckey);
- return (ret);
-}
-
-static isc_result_t
-opensslecdsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
- isc_result_t ret;
- dst_key_t *key = dctx->key;
- int status;
- unsigned char *cp = sig->base;
- ECDSA_SIG *ecdsasig = NULL;
- EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
- EVP_PKEY *pkey = key->keydata.pkey;
- EC_KEY *eckey = EVP_PKEY_get1_EC_KEY(pkey);
- unsigned int dgstlen, siglen;
- unsigned char digest[EVP_MAX_MD_SIZE];
-
- REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
- key->key_alg == DST_ALG_ECDSA384);
-
- if (eckey == NULL)
- return (ISC_R_FAILURE);
-
- if (key->key_alg == DST_ALG_ECDSA256)
- siglen = DNS_SIG_ECDSA256SIZE;
- else
- siglen = DNS_SIG_ECDSA384SIZE;
-
- if (sig->length != siglen)
- return (DST_R_VERIFYFAILURE);
-
- if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &dgstlen))
- DST_RET (dst__openssl_toresult3(dctx->category,
- "EVP_DigestFinal_ex",
- ISC_R_FAILURE));
-
- ecdsasig = ECDSA_SIG_new();
- if (ecdsasig == NULL)
- DST_RET (ISC_R_NOMEMORY);
- if (ecdsasig->r != NULL)
- BN_free(ecdsasig->r);
- ecdsasig->r = BN_bin2bn(cp, siglen / 2, NULL);
- cp += siglen / 2;
- if (ecdsasig->s != NULL)
- BN_free(ecdsasig->s);
- ecdsasig->s = BN_bin2bn(cp, siglen / 2, NULL);
- /* cp += siglen / 2; */
-
- status = ECDSA_do_verify(digest, dgstlen, ecdsasig, eckey);
- switch (status) {
- case 1:
- ret = ISC_R_SUCCESS;
- break;
- case 0:
- ret = dst__openssl_toresult(DST_R_VERIFYFAILURE);
- break;
- default:
- ret = dst__openssl_toresult3(dctx->category,
- "ECDSA_do_verify",
- DST_R_VERIFYFAILURE);
- break;
- }
-
- err:
- if (ecdsasig != NULL)
- ECDSA_SIG_free(ecdsasig);
- if (eckey != NULL)
- EC_KEY_free(eckey);
- return (ret);
-}
-
-static isc_boolean_t
-opensslecdsa_compare(const dst_key_t *key1, const dst_key_t *key2) {
- isc_boolean_t ret;
- int status;
- EVP_PKEY *pkey1 = key1->keydata.pkey;
- EVP_PKEY *pkey2 = key2->keydata.pkey;
- EC_KEY *eckey1 = NULL;
- EC_KEY *eckey2 = NULL;
- const BIGNUM *priv1, *priv2;
-
- if (pkey1 == NULL && pkey2 == NULL)
- return (ISC_TRUE);
- else if (pkey1 == NULL || pkey2 == NULL)
- return (ISC_FALSE);
-
- eckey1 = EVP_PKEY_get1_EC_KEY(pkey1);
- eckey2 = EVP_PKEY_get1_EC_KEY(pkey2);
- if (eckey1 == NULL && eckey2 == NULL) {
- DST_RET (ISC_TRUE);
- } else if (eckey1 == NULL || eckey2 == NULL)
- DST_RET (ISC_FALSE);
-
- status = EVP_PKEY_cmp(pkey1, pkey2);
- if (status != 1)
- DST_RET (ISC_FALSE);
-
- priv1 = EC_KEY_get0_private_key(eckey1);
- priv2 = EC_KEY_get0_private_key(eckey2);
- if (priv1 != NULL || priv2 != NULL) {
- if (priv1 == NULL || priv2 == NULL)
- DST_RET (ISC_FALSE);
- if (BN_cmp(priv1, priv2) != 0)
- DST_RET (ISC_FALSE);
- }
- ret = ISC_TRUE;
-
- err:
- if (eckey1 != NULL)
- EC_KEY_free(eckey1);
- if (eckey2 != NULL)
- EC_KEY_free(eckey2);
- return (ret);
-}
-
-static isc_result_t
-opensslecdsa_generate(dst_key_t *key, int unused, void (*callback)(int)) {
- isc_result_t ret;
- EVP_PKEY *pkey;
- EC_KEY *eckey = NULL;
- int group_nid;
-
- REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
- key->key_alg == DST_ALG_ECDSA384);
- UNUSED(unused);
- UNUSED(callback);
-
- if (key->key_alg == DST_ALG_ECDSA256)
- group_nid = NID_X9_62_prime256v1;
- else
- group_nid = NID_secp384r1;
-
- eckey = EC_KEY_new_by_curve_name(group_nid);
- if (eckey == NULL)
- return (dst__openssl_toresult2("EC_KEY_new_by_curve_name",
- DST_R_OPENSSLFAILURE));
-
- if (EC_KEY_generate_key(eckey) != 1)
- DST_RET (dst__openssl_toresult2("EC_KEY_generate_key",
- DST_R_OPENSSLFAILURE));
-
- pkey = EVP_PKEY_new();
- if (pkey == NULL)
- DST_RET (ISC_R_NOMEMORY);
- if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) {
- EVP_PKEY_free(pkey);
- DST_RET (ISC_R_FAILURE);
- }
- key->keydata.pkey = pkey;
- ret = ISC_R_SUCCESS;
-
- err:
- if (eckey != NULL)
- EC_KEY_free(eckey);
- return (ret);
-}
-
-static isc_boolean_t
-opensslecdsa_isprivate(const dst_key_t *key) {
- isc_boolean_t ret;
- EVP_PKEY *pkey = key->keydata.pkey;
- EC_KEY *eckey = EVP_PKEY_get1_EC_KEY(pkey);
-
- ret = ISC_TF(eckey != NULL && EC_KEY_get0_private_key(eckey) != NULL);
- if (eckey != NULL)
- EC_KEY_free(eckey);
- return (ret);
-}
-
-static void
-opensslecdsa_destroy(dst_key_t *key) {
- EVP_PKEY *pkey = key->keydata.pkey;
-
- EVP_PKEY_free(pkey);
- key->keydata.pkey = NULL;
-}
-
-static isc_result_t
-opensslecdsa_todns(const dst_key_t *key, isc_buffer_t *data) {
- isc_result_t ret;
- EVP_PKEY *pkey;
- EC_KEY *eckey = NULL;
- isc_region_t r;
- int len;
- unsigned char *cp;
- unsigned char buf[DNS_KEY_ECDSA384SIZE + 1];
-
- REQUIRE(key->keydata.pkey != NULL);
-
- pkey = key->keydata.pkey;
- eckey = EVP_PKEY_get1_EC_KEY(pkey);
- if (eckey == NULL)
- return (dst__openssl_toresult(ISC_R_FAILURE));
- len = i2o_ECPublicKey(eckey, NULL);
- /* skip form */
- len--;
-
- isc_buffer_availableregion(data, &r);
- if (r.length < (unsigned int) len)
- DST_RET (ISC_R_NOSPACE);
- cp = buf;
- if (!i2o_ECPublicKey(eckey, &cp))
- DST_RET (dst__openssl_toresult(ISC_R_FAILURE));
- memcpy(r.base, buf + 1, len);
- isc_buffer_add(data, len);
- ret = ISC_R_SUCCESS;
-
- err:
- if (eckey != NULL)
- EC_KEY_free(eckey);
- return (ret);
-}
-
-static isc_result_t
-opensslecdsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
- isc_result_t ret;
- EVP_PKEY *pkey;
- EC_KEY *eckey = NULL;
- isc_region_t r;
- int group_nid;
- unsigned int len;
- const unsigned char *cp;
- unsigned char buf[DNS_KEY_ECDSA384SIZE + 1];
-
- REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
- key->key_alg == DST_ALG_ECDSA384);
-
- if (key->key_alg == DST_ALG_ECDSA256) {
- len = DNS_KEY_ECDSA256SIZE;
- group_nid = NID_X9_62_prime256v1;
- } else {
- len = DNS_KEY_ECDSA384SIZE;
- group_nid = NID_secp384r1;
- }
-
- isc_buffer_remainingregion(data, &r);
- if (r.length == 0)
- return (ISC_R_SUCCESS);
- if (r.length < len)
- return (DST_R_INVALIDPUBLICKEY);
-
- eckey = EC_KEY_new_by_curve_name(group_nid);
- if (eckey == NULL)
- return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
-
- buf[0] = POINT_CONVERSION_UNCOMPRESSED;
- memcpy(buf + 1, r.base, len);
- cp = buf;
- if (o2i_ECPublicKey(&eckey,
- (const unsigned char **) &cp,
- (long) len + 1) == NULL)
- DST_RET (dst__openssl_toresult(DST_R_INVALIDPUBLICKEY));
- if (EC_KEY_check_key(eckey) != 1)
- DST_RET (dst__openssl_toresult(DST_R_INVALIDPUBLICKEY));
-
- pkey = EVP_PKEY_new();
- if (pkey == NULL)
- DST_RET (ISC_R_NOMEMORY);
- if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) {
- EVP_PKEY_free(pkey);
- DST_RET (dst__openssl_toresult(ISC_R_FAILURE));
- }
-
- isc_buffer_forward(data, len);
- key->keydata.pkey = pkey;
- ret = ISC_R_SUCCESS;
-
- err:
- if (eckey != NULL)
- EC_KEY_free(eckey);
- return (ret);
-}
-
-static isc_result_t
-opensslecdsa_tofile(const dst_key_t *key, const char *directory) {
- isc_result_t ret;
- EVP_PKEY *pkey;
- EC_KEY *eckey = NULL;
- const BIGNUM *privkey;
- dst_private_t priv;
- unsigned char *buf = NULL;
-
- if (key->keydata.pkey == NULL)
- return (DST_R_NULLKEY);
-
- pkey = key->keydata.pkey;
- eckey = EVP_PKEY_get1_EC_KEY(pkey);
- if (eckey == NULL)
- return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
- privkey = EC_KEY_get0_private_key(eckey);
- if (privkey == NULL)
- DST_RET (ISC_R_FAILURE);
-
- buf = isc_mem_get(key->mctx, BN_num_bytes(privkey));
- if (buf == NULL)
- DST_RET (ISC_R_NOMEMORY);
-
- priv.elements[0].tag = TAG_ECDSA_PRIVATEKEY;
- priv.elements[0].length = BN_num_bytes(privkey);
- BN_bn2bin(privkey, buf);
- priv.elements[0].data = buf;
- priv.nelements = ECDSA_NTAGS;
- ret = dst__privstruct_writefile(key, &priv, directory);
-
- err:
- if (eckey != NULL)
- EC_KEY_free(eckey);
- if (buf != NULL)
- isc_mem_put(key->mctx, buf, BN_num_bytes(privkey));
- return (ret);
-}
-
-static isc_result_t
-ecdsa_check(EC_KEY *eckey, dst_key_t *pub)
-{
- isc_result_t ret = ISC_R_FAILURE;
- EVP_PKEY *pkey;
- EC_KEY *pubeckey = NULL;
- const EC_POINT *pubkey;
-
- if (pub == NULL)
- return (ISC_R_SUCCESS);
- pkey = pub->keydata.pkey;
- if (pkey == NULL)
- return (ISC_R_SUCCESS);
- pubeckey = EVP_PKEY_get1_EC_KEY(pkey);
- if (pubeckey == NULL)
- return (ISC_R_SUCCESS);
- pubkey = EC_KEY_get0_public_key(pubeckey);
- if (pubkey == NULL)
- DST_RET (ISC_R_SUCCESS);
- if (EC_KEY_set_public_key(eckey, pubkey) != 1)
- DST_RET (ISC_R_SUCCESS);
- if (EC_KEY_check_key(eckey) == 1)
- DST_RET (ISC_R_SUCCESS);
-
- err:
- if (pubeckey != NULL)
- EC_KEY_free(pubeckey);
- return (ret);
-}
-
-static isc_result_t
-opensslecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
- dst_private_t priv;
- isc_result_t ret;
- EVP_PKEY *pkey;
- EC_KEY *eckey = NULL;
- BIGNUM *privkey;
- int group_nid;
- isc_mem_t *mctx = key->mctx;
-
- REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
- key->key_alg == DST_ALG_ECDSA384);
-
- if (key->key_alg == DST_ALG_ECDSA256)
- group_nid = NID_X9_62_prime256v1;
- else
- group_nid = NID_secp384r1;
-
- eckey = EC_KEY_new_by_curve_name(group_nid);
- if (eckey == NULL)
- return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
-
- /* read private key file */
- ret = dst__privstruct_parse(key, DST_ALG_ECDSA256, lexer, mctx, &priv);
- if (ret != ISC_R_SUCCESS)
- goto err;
-
- privkey = BN_bin2bn(priv.elements[0].data,
- priv.elements[0].length, NULL);
- if (privkey == NULL)
- DST_RET(ISC_R_NOMEMORY);
- if (!EC_KEY_set_private_key(eckey, privkey))
- DST_RET(ISC_R_NOMEMORY);
- if (ecdsa_check(eckey, pub) != ISC_R_SUCCESS)
- DST_RET(DST_R_INVALIDPRIVATEKEY);
- dst__privstruct_free(&priv, mctx);
- memset(&priv, 0, sizeof(priv));
-
- pkey = EVP_PKEY_new();
- if (pkey == NULL)
- DST_RET (ISC_R_NOMEMORY);
- if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) {
- EVP_PKEY_free(pkey);
- DST_RET (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
- }
- key->keydata.pkey = pkey;
- ret = ISC_R_SUCCESS;
-
- err:
- if (eckey != NULL)
- EC_KEY_free(eckey);
- dst__privstruct_free(&priv, mctx);
- memset(&priv, 0, sizeof(priv));
- return (ret);
-}
-
-static dst_func_t opensslecdsa_functions = {
- opensslecdsa_createctx,
- opensslecdsa_destroyctx,
- opensslecdsa_adddata,
- opensslecdsa_sign,
- opensslecdsa_verify,
- NULL, /*%< verify2 */
- NULL, /*%< computesecret */
- opensslecdsa_compare,
- NULL, /*%< paramcompare */
- opensslecdsa_generate,
- opensslecdsa_isprivate,
- opensslecdsa_destroy,
- opensslecdsa_todns,
- opensslecdsa_fromdns,
- opensslecdsa_tofile,
- opensslecdsa_parse,
- NULL, /*%< cleanup */
- NULL, /*%< fromlabel */
- NULL, /*%< dump */
- NULL, /*%< restore */
-};
-
-isc_result_t
-dst__opensslecdsa_init(dst_func_t **funcp) {
- REQUIRE(funcp != NULL);
- if (*funcp == NULL)
- *funcp = &opensslecdsa_functions;
- return (ISC_R_SUCCESS);
-}
-
-#else /* HAVE_OPENSSL_ECDSA */
-
-#include <isc/util.h>
-
-EMPTY_TRANSLATION_UNIT
-
-#endif /* HAVE_OPENSSL_ECDSA */
-/*! \file */
diff --git a/contrib/bind9/lib/dns/opensslgost_link.c b/contrib/bind9/lib/dns/opensslgost_link.c
deleted file mode 100644
index 1ce4405eb21d..000000000000
--- a/contrib/bind9/lib/dns/opensslgost_link.c
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
- * Copyright (C) 2010-2012 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN 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);
- switch (status) {
- case 1:
- return (ISC_R_SUCCESS);
- case 0:
- return (dst__openssl_toresult(DST_R_VERIFYFAILURE));
- default:
- return (dst__openssl_toresult3(dctx->category,
- "EVP_VerifyFinal",
- DST_R_VERIFYFAILURE));
- }
-}
-
-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;
- isc_result_t ret;
-
- UNUSED(unused);
- ctx = EVP_PKEY_CTX_new_id(NID_id_GostR3410_2001, NULL);
- if (ctx == NULL)
- DST_RET(dst__openssl_toresult2("EVP_PKEY_CTX_new_id",
- DST_R_OPENSSLFAILURE));
- 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)
- DST_RET(dst__openssl_toresult2("EVP_PKEY_keygen_init",
- DST_R_OPENSSLFAILURE));
- if (EVP_PKEY_CTX_ctrl_str(ctx, "paramset", "A") <= 0)
- DST_RET(dst__openssl_toresult2("EVP_PKEY_CTX_ctrl_str",
- DST_R_OPENSSLFAILURE));
- if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
- DST_RET(dst__openssl_toresult2("EVP_PKEY_keygen",
- DST_R_OPENSSLFAILURE));
- 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 (ret);
-}
-
-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_toresult2("d2i_PUBKEY",
- 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_toresult2("i2d_PrivateKey",
- 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__openssl_toresult2("d2i_PrivateKey",
- 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, /*%< verify2 */
- 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) {
- isc_result_t ret;
-
- REQUIRE(funcp != NULL);
-
- /* check if the gost engine works properly */
- e = ENGINE_by_id("gost");
- if (e == NULL)
- return (dst__openssl_toresult2("ENGINE_by_id",
- DST_R_OPENSSLFAILURE));
- if (ENGINE_init(e) <= 0) {
- ENGINE_free(e);
- e = NULL;
- return (dst__openssl_toresult2("ENGINE_init",
- DST_R_OPENSSLFAILURE));
- }
- /* better than to rely on digest_gost symbol */
- opensslgost_digest = ENGINE_get_digest(e, NID_id_GostR3411_94);
- if (opensslgost_digest == NULL)
- DST_RET(dst__openssl_toresult2("ENGINE_get_digest",
- DST_R_OPENSSLFAILURE));
- /* from openssl.cnf */
- if (ENGINE_register_pkey_asn1_meths(e) <= 0)
- DST_RET(dst__openssl_toresult2(
- "ENGINE_register_pkey_asn1_meths",
- DST_R_OPENSSLFAILURE));
- if (ENGINE_ctrl_cmd_string(e,
- "CRYPT_PARAMS",
- "id-Gost28147-89-CryptoPro-A-ParamSet",
- 0) <= 0)
- DST_RET(dst__openssl_toresult2("ENGINE_ctrl_cmd_string",
- DST_R_OPENSSLFAILURE));
-
- if (*funcp == NULL)
- *funcp = &opensslgost_functions;
- return (ISC_R_SUCCESS);
-
- err:
- ENGINE_finish(e);
- ENGINE_free(e);
- e = NULL;
- return (ret);
-}
-
-#else /* HAVE_OPENSSL_GOST */
-
-#include <isc/util.h>
-
-EMPTY_TRANSLATION_UNIT
-
-#endif /* HAVE_OPENSSL_GOST */
-/*! \file */
diff --git a/contrib/bind9/lib/dns/opensslrsa_link.c b/contrib/bind9/lib/dns/opensslrsa_link.c
deleted file mode 100644
index fa7412cbddbd..000000000000
--- a/contrib/bind9/lib/dns/opensslrsa_link.c
+++ /dev/null
@@ -1,1491 +0,0 @@
-/*
- * Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2000-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * Principal Author: Brian Wellington
- * $Id$
- */
-#ifdef OPENSSL
-#include <config.h>
-
-#ifndef USE_EVP
-#if !defined(HAVE_EVP_SHA256) || !defined(HAVE_EVP_SHA512)
-#define USE_EVP 0
-#else
-#define USE_EVP 1
-#endif
-#endif
-
-
-#include <isc/entropy.h>
-#include <isc/md5.h>
-#include <isc/sha1.h>
-#include <isc/sha2.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>
-#if OPENSSL_VERSION_NUMBER > 0x00908000L
-#include <openssl/bn.h>
-#endif
-#ifdef USE_ENGINE
-#include <openssl/engine.h>
-#endif
-
-/*
- * Limit the size of public exponents.
- */
-#ifndef RSA_MAX_PUBEXP_BITS
-#define RSA_MAX_PUBEXP_BITS 35
-#endif
-
-/*
- * We don't use configure for windows so enforce the OpenSSL version
- * here. Unlike with configure we don't support overriding this test.
- */
-#ifdef WIN32
-#if !((OPENSSL_VERSION_NUMBER >= 0x009070cfL && \
- OPENSSL_VERSION_NUMBER < 0x00908000L) || \
- OPENSSL_VERSION_NUMBER >= 0x0090804fL)
-#error Please upgrade OpenSSL to 0.9.8d/0.9.7l or greater.
-#endif
-#endif
-
-
- /*
- * XXXMPA Temporarily disable RSA_BLINDING as it requires
- * good quality random data that cannot currently be guaranteed.
- * XXXMPA Find which versions of openssl use pseudo random data
- * and set RSA_FLAG_BLINDING for those.
- */
-
-#if 0
-#if OPENSSL_VERSION_NUMBER < 0x0090601fL
-#define SET_FLAGS(rsa) \
- do { \
- (rsa)->flags &= ~(RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE); \
- (rsa)->flags |= RSA_FLAG_BLINDING; \
- } while (0)
-#else
-#define SET_FLAGS(rsa) \
- do { \
- (rsa)->flags |= RSA_FLAG_BLINDING; \
- } while (0)
-#endif
-#endif
-
-#if OPENSSL_VERSION_NUMBER < 0x0090601fL
-#define SET_FLAGS(rsa) \
- do { \
- (rsa)->flags &= ~(RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE); \
- (rsa)->flags &= ~RSA_FLAG_BLINDING; \
- } while (0)
-#elif defined(RSA_FLAG_NO_BLINDING)
-#define SET_FLAGS(rsa) \
- do { \
- (rsa)->flags &= ~RSA_FLAG_BLINDING; \
- (rsa)->flags |= RSA_FLAG_NO_BLINDING; \
- } while (0)
-#else
-#define SET_FLAGS(rsa) \
- do { \
- (rsa)->flags &= ~RSA_FLAG_BLINDING; \
- } while (0)
-#endif
-
-#define DST_RET(a) {ret = a; goto err;}
-
-static isc_result_t opensslrsa_todns(const dst_key_t *key, isc_buffer_t *data);
-
-static isc_result_t
-opensslrsa_createctx(dst_key_t *key, dst_context_t *dctx) {
-#if USE_EVP
- EVP_MD_CTX *evp_md_ctx;
- const EVP_MD *type = NULL;
-#endif
-
- UNUSED(key);
- REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
- dctx->key->key_alg == DST_ALG_RSASHA1 ||
- dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 ||
- dctx->key->key_alg == DST_ALG_RSASHA256 ||
- dctx->key->key_alg == DST_ALG_RSASHA512);
-
-#if USE_EVP
- evp_md_ctx = EVP_MD_CTX_create();
- if (evp_md_ctx == NULL)
- return (ISC_R_NOMEMORY);
-
- switch (dctx->key->key_alg) {
- case DST_ALG_RSAMD5:
- type = EVP_md5(); /* MD5 + RSA */
- break;
- case DST_ALG_RSASHA1:
- case DST_ALG_NSEC3RSASHA1:
- type = EVP_sha1(); /* SHA1 + RSA */
- break;
-#ifdef HAVE_EVP_SHA256
- case DST_ALG_RSASHA256:
- type = EVP_sha256(); /* SHA256 + RSA */
- break;
-#endif
-#ifdef HAVE_EVP_SHA512
- case DST_ALG_RSASHA512:
- type = EVP_sha512();
- break;
-#endif
- default:
- INSIST(0);
- }
-
- if (!EVP_DigestInit_ex(evp_md_ctx, type, NULL)) {
- EVP_MD_CTX_destroy(evp_md_ctx);
- return (dst__openssl_toresult3(dctx->category,
- "EVP_DigestInit_ex",
- ISC_R_FAILURE));
- }
- dctx->ctxdata.evp_md_ctx = evp_md_ctx;
-#else
- switch (dctx->key->key_alg) {
- case DST_ALG_RSAMD5:
- {
- isc_md5_t *md5ctx;
-
- md5ctx = isc_mem_get(dctx->mctx, sizeof(isc_md5_t));
- if (md5ctx == NULL)
- return (ISC_R_NOMEMORY);
- isc_md5_init(md5ctx);
- dctx->ctxdata.md5ctx = md5ctx;
- }
- break;
- case DST_ALG_RSASHA1:
- case DST_ALG_NSEC3RSASHA1:
- {
- isc_sha1_t *sha1ctx;
-
- sha1ctx = isc_mem_get(dctx->mctx, sizeof(isc_sha1_t));
- if (sha1ctx == NULL)
- return (ISC_R_NOMEMORY);
- isc_sha1_init(sha1ctx);
- dctx->ctxdata.sha1ctx = sha1ctx;
- }
- break;
- case DST_ALG_RSASHA256:
- {
- isc_sha256_t *sha256ctx;
-
- sha256ctx = isc_mem_get(dctx->mctx,
- sizeof(isc_sha256_t));
- if (sha256ctx == NULL)
- return (ISC_R_NOMEMORY);
- isc_sha256_init(sha256ctx);
- dctx->ctxdata.sha256ctx = sha256ctx;
- }
- break;
- case DST_ALG_RSASHA512:
- {
- isc_sha512_t *sha512ctx;
-
- sha512ctx = isc_mem_get(dctx->mctx,
- sizeof(isc_sha512_t));
- if (sha512ctx == NULL)
- return (ISC_R_NOMEMORY);
- isc_sha512_init(sha512ctx);
- dctx->ctxdata.sha512ctx = sha512ctx;
- }
- break;
- default:
- INSIST(0);
- }
-#endif
-
- return (ISC_R_SUCCESS);
-}
-
-static void
-opensslrsa_destroyctx(dst_context_t *dctx) {
-#if USE_EVP
- EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
-#endif
-
- REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
- dctx->key->key_alg == DST_ALG_RSASHA1 ||
- dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 ||
- dctx->key->key_alg == DST_ALG_RSASHA256 ||
- dctx->key->key_alg == DST_ALG_RSASHA512);
-
-#if USE_EVP
- if (evp_md_ctx != NULL) {
- EVP_MD_CTX_destroy(evp_md_ctx);
- dctx->ctxdata.evp_md_ctx = NULL;
- }
-#else
- switch (dctx->key->key_alg) {
- case DST_ALG_RSAMD5:
- {
- isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
-
- if (md5ctx != NULL) {
- isc_md5_invalidate(md5ctx);
- isc_mem_put(dctx->mctx, md5ctx,
- sizeof(isc_md5_t));
- dctx->ctxdata.md5ctx = NULL;
- }
- }
- break;
- case DST_ALG_RSASHA1:
- case DST_ALG_NSEC3RSASHA1:
- {
- isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
-
- if (sha1ctx != NULL) {
- isc_sha1_invalidate(sha1ctx);
- isc_mem_put(dctx->mctx, sha1ctx,
- sizeof(isc_sha1_t));
- dctx->ctxdata.sha1ctx = NULL;
- }
- }
- break;
- case DST_ALG_RSASHA256:
- {
- isc_sha256_t *sha256ctx = dctx->ctxdata.sha256ctx;
-
- if (sha256ctx != NULL) {
- isc_sha256_invalidate(sha256ctx);
- isc_mem_put(dctx->mctx, sha256ctx,
- sizeof(isc_sha256_t));
- dctx->ctxdata.sha256ctx = NULL;
- }
- }
- break;
- case DST_ALG_RSASHA512:
- {
- isc_sha512_t *sha512ctx = dctx->ctxdata.sha512ctx;
-
- if (sha512ctx != NULL) {
- isc_sha512_invalidate(sha512ctx);
- isc_mem_put(dctx->mctx, sha512ctx,
- sizeof(isc_sha512_t));
- dctx->ctxdata.sha512ctx = NULL;
- }
- }
- break;
- default:
- INSIST(0);
- }
-#endif
-}
-
-static isc_result_t
-opensslrsa_adddata(dst_context_t *dctx, const isc_region_t *data) {
-#if USE_EVP
- EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
-#endif
-
- REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
- dctx->key->key_alg == DST_ALG_RSASHA1 ||
- dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 ||
- dctx->key->key_alg == DST_ALG_RSASHA256 ||
- dctx->key->key_alg == DST_ALG_RSASHA512);
-
-#if USE_EVP
- if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length)) {
- return (dst__openssl_toresult3(dctx->category,
- "EVP_DigestUpdate",
- ISC_R_FAILURE));
- }
-#else
- switch (dctx->key->key_alg) {
- case DST_ALG_RSAMD5:
- {
- isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
-
- isc_md5_update(md5ctx, data->base, data->length);
- }
- break;
- case DST_ALG_RSASHA1:
- case DST_ALG_NSEC3RSASHA1:
- {
- isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
-
- isc_sha1_update(sha1ctx, data->base, data->length);
- }
- break;
- case DST_ALG_RSASHA256:
- {
- isc_sha256_t *sha256ctx = dctx->ctxdata.sha256ctx;
-
- isc_sha256_update(sha256ctx, data->base, data->length);
- }
- break;
- case DST_ALG_RSASHA512:
- {
- isc_sha512_t *sha512ctx = dctx->ctxdata.sha512ctx;
-
- isc_sha512_update(sha512ctx, data->base, data->length);
- }
- break;
- default:
- INSIST(0);
- }
-#endif
- return (ISC_R_SUCCESS);
-}
-
-#if ! USE_EVP && OPENSSL_VERSION_NUMBER < 0x00908000L
-/*
- * Digest prefixes from RFC 5702.
- */
-static unsigned char sha256_prefix[] =
- { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
- 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20};
-static unsigned char sha512_prefix[] =
- { 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
- 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40};
-#define PREFIXLEN sizeof(sha512_prefix)
-#else
-#define PREFIXLEN 0
-#endif
-
-static isc_result_t
-opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
- dst_key_t *key = dctx->key;
- isc_region_t r;
- unsigned int siglen = 0;
-#if USE_EVP
- EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
- EVP_PKEY *pkey = key->keydata.pkey;
-#else
- RSA *rsa = key->keydata.rsa;
- /* note: ISC_SHA512_DIGESTLENGTH >= ISC_*_DIGESTLENGTH */
- unsigned char digest[PREFIXLEN + ISC_SHA512_DIGESTLENGTH];
- int status;
- int type = 0;
- unsigned int digestlen = 0;
-#if OPENSSL_VERSION_NUMBER < 0x00908000L
- unsigned int prefixlen = 0;
- const unsigned char *prefix = NULL;
-#endif
-#endif
-
- REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
- dctx->key->key_alg == DST_ALG_RSASHA1 ||
- dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 ||
- dctx->key->key_alg == DST_ALG_RSASHA256 ||
- dctx->key->key_alg == DST_ALG_RSASHA512);
-
- isc_buffer_availableregion(sig, &r);
-
-#if USE_EVP
- if (r.length < (unsigned int) EVP_PKEY_size(pkey))
- return (ISC_R_NOSPACE);
-
- if (!EVP_SignFinal(evp_md_ctx, r.base, &siglen, pkey)) {
- return (dst__openssl_toresult3(dctx->category,
- "EVP_SignFinal",
- ISC_R_FAILURE));
- }
-#else
- if (r.length < (unsigned int) RSA_size(rsa))
- return (ISC_R_NOSPACE);
-
- switch (dctx->key->key_alg) {
- case DST_ALG_RSAMD5:
- {
- isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
-
- isc_md5_final(md5ctx, digest);
- type = NID_md5;
- digestlen = ISC_MD5_DIGESTLENGTH;
- }
- break;
- case DST_ALG_RSASHA1:
- case DST_ALG_NSEC3RSASHA1:
- {
- isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
-
- isc_sha1_final(sha1ctx, digest);
- type = NID_sha1;
- digestlen = ISC_SHA1_DIGESTLENGTH;
- }
- break;
- case DST_ALG_RSASHA256:
- {
- isc_sha256_t *sha256ctx = dctx->ctxdata.sha256ctx;
-
- isc_sha256_final(digest, sha256ctx);
- digestlen = ISC_SHA256_DIGESTLENGTH;
-#if OPENSSL_VERSION_NUMBER < 0x00908000L
- prefix = sha256_prefix;
- prefixlen = sizeof(sha256_prefix);
-#else
- type = NID_sha256;
-#endif
- }
- break;
- case DST_ALG_RSASHA512:
- {
- isc_sha512_t *sha512ctx = dctx->ctxdata.sha512ctx;
-
- isc_sha512_final(digest, sha512ctx);
- digestlen = ISC_SHA512_DIGESTLENGTH;
-#if OPENSSL_VERSION_NUMBER < 0x00908000L
- prefix = sha512_prefix;
- prefixlen = sizeof(sha512_prefix);
-#else
- type = NID_sha512;
-#endif
- }
- break;
- default:
- INSIST(0);
- }
-
-#if OPENSSL_VERSION_NUMBER < 0x00908000L
- switch (dctx->key->key_alg) {
- case DST_ALG_RSAMD5:
- case DST_ALG_RSASHA1:
- case DST_ALG_NSEC3RSASHA1:
- INSIST(type != 0);
- status = RSA_sign(type, digest, digestlen, r.base,
- &siglen, rsa);
- break;
-
- case DST_ALG_RSASHA256:
- case DST_ALG_RSASHA512:
- INSIST(prefix != NULL);
- INSIST(prefixlen != 0);
- INSIST(prefixlen + digestlen <= sizeof(digest));
-
- memmove(digest + prefixlen, digest, digestlen);
- memcpy(digest, prefix, prefixlen);
- status = RSA_private_encrypt(digestlen + prefixlen,
- digest, r.base, rsa,
- RSA_PKCS1_PADDING);
- if (status < 0)
- status = 0;
- else
- siglen = status;
- break;
-
- default:
- INSIST(0);
- }
-#else
- INSIST(type != 0);
- status = RSA_sign(type, digest, digestlen, r.base, &siglen, rsa);
-#endif
- if (status == 0)
- return (dst__openssl_toresult3(dctx->category,
- "RSA_sign",
- DST_R_OPENSSLFAILURE));
-#endif
-
- isc_buffer_add(sig, siglen);
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-opensslrsa_verify2(dst_context_t *dctx, int maxbits, const isc_region_t *sig) {
- dst_key_t *key = dctx->key;
- int status = 0;
-#if USE_EVP
- EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
- EVP_PKEY *pkey = key->keydata.pkey;
- RSA *rsa;
- int bits;
-#else
- /* note: ISC_SHA512_DIGESTLENGTH >= ISC_*_DIGESTLENGTH */
- unsigned char digest[ISC_SHA512_DIGESTLENGTH];
- int type = 0;
- unsigned int digestlen = 0;
- RSA *rsa = key->keydata.rsa;
-#if OPENSSL_VERSION_NUMBER < 0x00908000L
- unsigned int prefixlen = 0;
- const unsigned char *prefix = NULL;
-#endif
-#endif
-
- REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
- dctx->key->key_alg == DST_ALG_RSASHA1 ||
- dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 ||
- dctx->key->key_alg == DST_ALG_RSASHA256 ||
- dctx->key->key_alg == DST_ALG_RSASHA512);
-
-#if USE_EVP
- rsa = EVP_PKEY_get1_RSA(pkey);
- if (rsa == NULL)
- return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
- bits = BN_num_bits(rsa->e);
- RSA_free(rsa);
- if (bits > maxbits && maxbits != 0)
- return (DST_R_VERIFYFAILURE);
-
- status = EVP_VerifyFinal(evp_md_ctx, sig->base, sig->length, pkey);
- switch (status) {
- case 1:
- return (ISC_R_SUCCESS);
- case 0:
- return (dst__openssl_toresult(DST_R_VERIFYFAILURE));
- default:
- return (dst__openssl_toresult3(dctx->category,
- "EVP_VerifyFinal",
- DST_R_VERIFYFAILURE));
- }
-#else
- if (BN_num_bits(rsa->e) > maxbits && maxbits != 0)
- return (DST_R_VERIFYFAILURE);
-
- switch (dctx->key->key_alg) {
- case DST_ALG_RSAMD5:
- {
- isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
-
- isc_md5_final(md5ctx, digest);
- type = NID_md5;
- digestlen = ISC_MD5_DIGESTLENGTH;
- }
- break;
- case DST_ALG_RSASHA1:
- case DST_ALG_NSEC3RSASHA1:
- {
- isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
-
- isc_sha1_final(sha1ctx, digest);
- type = NID_sha1;
- digestlen = ISC_SHA1_DIGESTLENGTH;
- }
- break;
- case DST_ALG_RSASHA256:
- {
- isc_sha256_t *sha256ctx = dctx->ctxdata.sha256ctx;
-
- isc_sha256_final(digest, sha256ctx);
- digestlen = ISC_SHA256_DIGESTLENGTH;
-#if OPENSSL_VERSION_NUMBER < 0x00908000L
- prefix = sha256_prefix;
- prefixlen = sizeof(sha256_prefix);
-#else
- type = NID_sha256;
-#endif
- }
- break;
- case DST_ALG_RSASHA512:
- {
- isc_sha512_t *sha512ctx = dctx->ctxdata.sha512ctx;
-
- isc_sha512_final(digest, sha512ctx);
- digestlen = ISC_SHA512_DIGESTLENGTH;
-#if OPENSSL_VERSION_NUMBER < 0x00908000L
- prefix = sha512_prefix;
- prefixlen = sizeof(sha512_prefix);
-#else
- type = NID_sha512;
-#endif
- }
- break;
- default:
- INSIST(0);
- }
-
- if (sig->length != (unsigned int) RSA_size(rsa))
- return (DST_R_VERIFYFAILURE);
-
-#if OPENSSL_VERSION_NUMBER < 0x00908000L
- switch (dctx->key->key_alg) {
- case DST_ALG_RSAMD5:
- case DST_ALG_RSASHA1:
- case DST_ALG_NSEC3RSASHA1:
- INSIST(type != 0);
- status = RSA_verify(type, digest, digestlen, sig->base,
- RSA_size(rsa), rsa);
- break;
-
- case DST_ALG_RSASHA256:
- case DST_ALG_RSASHA512:
- {
- /*
- * 1024 is big enough for all valid RSA bit sizes
- * for use with DNSSEC.
- */
- unsigned char original[PREFIXLEN + 1024];
-
- INSIST(prefix != NULL);
- INSIST(prefixlen != 0U);
-
- if (RSA_size(rsa) > (int)sizeof(original))
- return (DST_R_VERIFYFAILURE);
-
- status = RSA_public_decrypt(sig->length, sig->base,
- original, rsa,
- RSA_PKCS1_PADDING);
- if (status <= 0)
- return (dst__openssl_toresult3(
- dctx->category,
- "RSA_public_decrypt",
- DST_R_VERIFYFAILURE));
- if (status != (int)(prefixlen + digestlen))
- return (DST_R_VERIFYFAILURE);
- if (memcmp(original, prefix, prefixlen))
- return (DST_R_VERIFYFAILURE);
- if (memcmp(original + prefixlen, digest, digestlen))
- return (DST_R_VERIFYFAILURE);
- status = 1;
- }
- break;
-
- default:
- INSIST(0);
- }
-#else
- INSIST(type != 0);
- status = RSA_verify(type, digest, digestlen, sig->base,
- RSA_size(rsa), rsa);
-#endif
- if (status != 1)
- return (dst__openssl_toresult(DST_R_VERIFYFAILURE));
- return (ISC_R_SUCCESS);
-#endif
-}
-
-static isc_result_t
-opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
- return (opensslrsa_verify2(dctx, 0, sig));
-}
-
-static isc_boolean_t
-opensslrsa_compare(const dst_key_t *key1, const dst_key_t *key2) {
- int status;
- RSA *rsa1 = NULL, *rsa2 = NULL;
-#if USE_EVP
- EVP_PKEY *pkey1, *pkey2;
-#endif
-
-#if USE_EVP
- pkey1 = key1->keydata.pkey;
- pkey2 = key2->keydata.pkey;
- /*
- * The pkey reference will keep these around after
- * the RSA_free() call.
- */
- if (pkey1 != NULL) {
- rsa1 = EVP_PKEY_get1_RSA(pkey1);
- RSA_free(rsa1);
- }
- if (pkey2 != NULL) {
- rsa2 = EVP_PKEY_get1_RSA(pkey2);
- RSA_free(rsa2);
- }
-#else
- rsa1 = key1->keydata.rsa;
- rsa2 = key2->keydata.rsa;
-#endif
-
- if (rsa1 == NULL && rsa2 == NULL)
- return (ISC_TRUE);
- else if (rsa1 == NULL || rsa2 == NULL)
- return (ISC_FALSE);
-
- status = BN_cmp(rsa1->n, rsa2->n) ||
- BN_cmp(rsa1->e, rsa2->e);
-
- if (status != 0)
- return (ISC_FALSE);
-
-#if USE_EVP
- if ((rsa1->flags & RSA_FLAG_EXT_PKEY) != 0 ||
- (rsa2->flags & RSA_FLAG_EXT_PKEY) != 0) {
- if ((rsa1->flags & RSA_FLAG_EXT_PKEY) == 0 ||
- (rsa2->flags & RSA_FLAG_EXT_PKEY) == 0)
- return (ISC_FALSE);
- /*
- * Can't compare private parameters, BTW does it make sense?
- */
- return (ISC_TRUE);
- }
-#endif
-
- if (rsa1->d != NULL || rsa2->d != NULL) {
- if (rsa1->d == NULL || rsa2->d == NULL)
- return (ISC_FALSE);
- status = BN_cmp(rsa1->d, rsa2->d) ||
- BN_cmp(rsa1->p, rsa2->p) ||
- BN_cmp(rsa1->q, rsa2->q);
-
- if (status != 0)
- return (ISC_FALSE);
- }
- 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, void (*callback)(int)) {
-#if OPENSSL_VERSION_NUMBER > 0x00908000L
- isc_result_t ret = DST_R_OPENSSLFAILURE;
- BN_GENCB cb;
- union {
- void *dptr;
- void (*fptr)(int);
- } u;
- RSA *rsa = RSA_new();
- BIGNUM *e = BN_new();
-#if USE_EVP
- EVP_PKEY *pkey = EVP_PKEY_new();
-#endif
-
- if (rsa == NULL || e == NULL)
- goto err;
-#if USE_EVP
- if (pkey == NULL)
- goto err;
- if (!EVP_PKEY_set1_RSA(pkey, rsa))
- goto err;
-#endif
-
- if (exp == 0) {
- /* RSA_F4 0x10001 */
- BN_set_bit(e, 0);
- BN_set_bit(e, 16);
- } else {
- /* (phased-out) F5 0x100000001 */
- BN_set_bit(e, 0);
- BN_set_bit(e, 32);
- }
-
- 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);
- SET_FLAGS(rsa);
-#if USE_EVP
- key->keydata.pkey = pkey;
-
- RSA_free(rsa);
-#else
- key->keydata.rsa = rsa;
-#endif
- return (ISC_R_SUCCESS);
- }
- ret = dst__openssl_toresult2("RSA_generate_key_ex",
- DST_R_OPENSSLFAILURE);
-
-err:
-#if USE_EVP
- if (pkey != NULL)
- EVP_PKEY_free(pkey);
-#endif
- if (e != NULL)
- BN_free(e);
- if (rsa != NULL)
- RSA_free(rsa);
- return (dst__openssl_toresult(ret));
-#else
- RSA *rsa;
- unsigned long e;
-#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)
- e = RSA_F4;
- else
- e = 0x40000003;
- rsa = RSA_generate_key(key->key_size, e, NULL, NULL);
- if (rsa == NULL) {
-#if USE_EVP
- EVP_PKEY_free(pkey);
-#endif
- return (dst__openssl_toresult2("RSA_generate_key",
- DST_R_OPENSSLFAILURE));
- }
- SET_FLAGS(rsa);
-#if USE_EVP
- if (!EVP_PKEY_set1_RSA(pkey, rsa)) {
- EVP_PKEY_free(pkey);
- RSA_free(rsa);
- return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
- }
- key->keydata.pkey = pkey;
- RSA_free(rsa);
-#else
- key->keydata.rsa = rsa;
-#endif
-
- return (ISC_R_SUCCESS);
-#endif
-}
-
-static isc_boolean_t
-opensslrsa_isprivate(const dst_key_t *key) {
-#if USE_EVP
- RSA *rsa = EVP_PKEY_get1_RSA(key->keydata.pkey);
- INSIST(rsa != NULL);
- RSA_free(rsa);
- /* key->keydata.pkey still has a reference so rsa is still valid. */
-#else
- RSA *rsa = key->keydata.rsa;
-#endif
- if (rsa != NULL && (rsa->flags & RSA_FLAG_EXT_PKEY) != 0)
- return (ISC_TRUE);
- return (ISC_TF(rsa != NULL && rsa->d != NULL));
-}
-
-static void
-opensslrsa_destroy(dst_key_t *key) {
-#if USE_EVP
- EVP_PKEY *pkey = key->keydata.pkey;
- EVP_PKEY_free(pkey);
- key->keydata.pkey = NULL;
-#else
- RSA *rsa = key->keydata.rsa;
- RSA_free(rsa);
- key->keydata.rsa = NULL;
-#endif
-}
-
-
-static isc_result_t
-opensslrsa_todns(const dst_key_t *key, isc_buffer_t *data) {
- isc_region_t r;
- unsigned int e_bytes;
- unsigned int mod_bytes;
- isc_result_t ret;
- RSA *rsa;
-#if USE_EVP
- EVP_PKEY *pkey;
-#endif
-
-#if USE_EVP
- REQUIRE(key->keydata.pkey != NULL);
-#else
- REQUIRE(key->keydata.rsa != NULL);
-#endif
-
-#if USE_EVP
- pkey = key->keydata.pkey;
- rsa = EVP_PKEY_get1_RSA(pkey);
- if (rsa == NULL)
- return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
-#else
- rsa = key->keydata.rsa;
-#endif
-
- isc_buffer_availableregion(data, &r);
-
- e_bytes = BN_num_bytes(rsa->e);
- mod_bytes = BN_num_bytes(rsa->n);
-
- if (e_bytes < 256) { /*%< key exponent is <= 2040 bits */
- if (r.length < 1)
- DST_RET(ISC_R_NOSPACE);
- isc_buffer_putuint8(data, (isc_uint8_t) e_bytes);
- isc_region_consume(&r, 1);
- } else {
- if (r.length < 3)
- DST_RET(ISC_R_NOSPACE);
- isc_buffer_putuint8(data, 0);
- isc_buffer_putuint16(data, (isc_uint16_t) e_bytes);
- isc_region_consume(&r, 3);
- }
-
- if (r.length < e_bytes + mod_bytes)
- DST_RET(ISC_R_NOSPACE);
-
- BN_bn2bin(rsa->e, r.base);
- isc_region_consume(&r, e_bytes);
- BN_bn2bin(rsa->n, r.base);
-
- isc_buffer_add(data, e_bytes + mod_bytes);
-
- ret = ISC_R_SUCCESS;
- err:
-#if USE_EVP
- if (rsa != NULL)
- RSA_free(rsa);
-#endif
- return (ret);
-}
-
-static isc_result_t
-opensslrsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
- RSA *rsa;
- isc_region_t r;
- unsigned int e_bytes;
-#if USE_EVP
- EVP_PKEY *pkey;
-#endif
-
- isc_buffer_remainingregion(data, &r);
- if (r.length == 0)
- return (ISC_R_SUCCESS);
-
- rsa = RSA_new();
- if (rsa == NULL)
- return (dst__openssl_toresult(ISC_R_NOMEMORY));
- SET_FLAGS(rsa);
-
- if (r.length < 1) {
- RSA_free(rsa);
- return (DST_R_INVALIDPUBLICKEY);
- }
- e_bytes = *r.base++;
- r.length--;
-
- if (e_bytes == 0) {
- if (r.length < 2) {
- RSA_free(rsa);
- return (DST_R_INVALIDPUBLICKEY);
- }
- e_bytes = ((*r.base++) << 8);
- e_bytes += *r.base++;
- r.length -= 2;
- }
-
- if (r.length < e_bytes) {
- RSA_free(rsa);
- return (DST_R_INVALIDPUBLICKEY);
- }
- rsa->e = BN_bin2bn(r.base, e_bytes, NULL);
- r.base += e_bytes;
- r.length -= e_bytes;
-
- rsa->n = BN_bin2bn(r.base, r.length, NULL);
-
- key->key_size = BN_num_bits(rsa->n);
-
- isc_buffer_forward(data, r.length);
-
-#if USE_EVP
- pkey = EVP_PKEY_new();
- if (pkey == NULL) {
- RSA_free(rsa);
- return (ISC_R_NOMEMORY);
- }
- if (!EVP_PKEY_set1_RSA(pkey, rsa)) {
- EVP_PKEY_free(pkey);
- RSA_free(rsa);
- return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
- }
- key->keydata.pkey = pkey;
- RSA_free(rsa);
-#else
- key->keydata.rsa = rsa;
-#endif
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-opensslrsa_tofile(const dst_key_t *key, const char *directory) {
- int i;
- RSA *rsa;
- dst_private_t priv;
- unsigned char *bufs[8];
- isc_result_t result;
-
-#if USE_EVP
- if (key->keydata.pkey == NULL)
- return (DST_R_NULLKEY);
- rsa = EVP_PKEY_get1_RSA(key->keydata.pkey);
- if (rsa == NULL)
- return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
-#else
- if (key->keydata.rsa == NULL)
- return (DST_R_NULLKEY);
- rsa = key->keydata.rsa;
-#endif
-
- memset(bufs, 0, sizeof(bufs));
- for (i = 0; i < 8; i++) {
- bufs[i] = isc_mem_get(key->mctx, BN_num_bytes(rsa->n));
- if (bufs[i] == NULL) {
- result = ISC_R_NOMEMORY;
- goto fail;
- }
- }
-
- i = 0;
-
- priv.elements[i].tag = TAG_RSA_MODULUS;
- priv.elements[i].length = BN_num_bytes(rsa->n);
- BN_bn2bin(rsa->n, bufs[i]);
- priv.elements[i].data = bufs[i];
- i++;
-
- priv.elements[i].tag = TAG_RSA_PUBLICEXPONENT;
- priv.elements[i].length = BN_num_bytes(rsa->e);
- BN_bn2bin(rsa->e, bufs[i]);
- priv.elements[i].data = bufs[i];
- i++;
-
- if (rsa->d != NULL) {
- priv.elements[i].tag = TAG_RSA_PRIVATEEXPONENT;
- priv.elements[i].length = BN_num_bytes(rsa->d);
- BN_bn2bin(rsa->d, bufs[i]);
- priv.elements[i].data = bufs[i];
- i++;
- }
-
- if (rsa->p != NULL) {
- priv.elements[i].tag = TAG_RSA_PRIME1;
- priv.elements[i].length = BN_num_bytes(rsa->p);
- BN_bn2bin(rsa->p, bufs[i]);
- priv.elements[i].data = bufs[i];
- i++;
- }
-
- if (rsa->q != NULL) {
- priv.elements[i].tag = TAG_RSA_PRIME2;
- priv.elements[i].length = BN_num_bytes(rsa->q);
- BN_bn2bin(rsa->q, bufs[i]);
- priv.elements[i].data = bufs[i];
- i++;
- }
-
- if (rsa->dmp1 != NULL) {
- priv.elements[i].tag = TAG_RSA_EXPONENT1;
- priv.elements[i].length = BN_num_bytes(rsa->dmp1);
- BN_bn2bin(rsa->dmp1, bufs[i]);
- priv.elements[i].data = bufs[i];
- i++;
- }
-
- if (rsa->dmq1 != NULL) {
- priv.elements[i].tag = TAG_RSA_EXPONENT2;
- priv.elements[i].length = BN_num_bytes(rsa->dmq1);
- BN_bn2bin(rsa->dmq1, bufs[i]);
- priv.elements[i].data = bufs[i];
- i++;
- }
-
- if (rsa->iqmp != NULL) {
- priv.elements[i].tag = TAG_RSA_COEFFICIENT;
- priv.elements[i].length = BN_num_bytes(rsa->iqmp);
- BN_bn2bin(rsa->iqmp, bufs[i]);
- priv.elements[i].data = bufs[i];
- i++;
- }
-
- if (key->engine != NULL) {
- priv.elements[i].tag = TAG_RSA_ENGINE;
- priv.elements[i].length = strlen(key->engine) + 1;
- priv.elements[i].data = (unsigned char *)key->engine;
- i++;
- }
-
- if (key->label != NULL) {
- priv.elements[i].tag = TAG_RSA_LABEL;
- priv.elements[i].length = strlen(key->label) + 1;
- priv.elements[i].data = (unsigned char *)key->label;
- i++;
- }
-
-
- priv.nelements = i;
- result = dst__privstruct_writefile(key, &priv, directory);
- fail:
-#if USE_EVP
- RSA_free(rsa);
-#endif
- for (i = 0; i < 8; i++) {
- if (bufs[i] == NULL)
- break;
- isc_mem_put(key->mctx, bufs[i], BN_num_bytes(rsa->n));
- }
- return (result);
-}
-
-static isc_result_t
-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, *pubrsa = NULL;
-#ifdef USE_ENGINE
- ENGINE *e = NULL;
-#endif
- isc_mem_t *mctx = key->mctx;
- const char *engine = NULL, *label = NULL;
-#if defined(USE_ENGINE) || USE_EVP
- EVP_PKEY *pkey = NULL;
-#endif
-
-#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)
- goto err;
-
- for (i = 0; i < priv.nelements; i++) {
- switch (priv.elements[i].tag) {
- case TAG_RSA_ENGINE:
- engine = (char *)priv.elements[i].data;
- break;
- case TAG_RSA_LABEL:
- label = (char *)priv.elements[i].data;
- break;
- default:
- break;
- }
- }
- /*
- * Is this key is stored in a HSM?
- * See if we can fetch it.
- */
- if (label != NULL) {
-#ifdef USE_ENGINE
- 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);
- if (pkey == NULL)
- DST_RET(dst__openssl_toresult2(
- "ENGINE_load_private_key",
- ISC_R_NOTFOUND));
- 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 (BN_num_bits(rsa->e) > RSA_MAX_PUBEXP_BITS)
- DST_RET(ISC_R_RANGE);
- if (pubrsa != NULL)
- RSA_free(pubrsa);
- key->key_size = EVP_PKEY_bits(pkey);
-#if USE_EVP
- key->keydata.pkey = pkey;
- RSA_free(rsa);
-#else
- key->keydata.rsa = rsa;
- EVP_PKEY_free(pkey);
-#endif
- dst__privstruct_free(&priv, mctx);
- memset(&priv, 0, sizeof(priv));
- return (ISC_R_SUCCESS);
-#else
- DST_RET(DST_R_NOENGINE);
-#endif
- }
-
- rsa = RSA_new();
- if (rsa == NULL)
- DST_RET(ISC_R_NOMEMORY);
- SET_FLAGS(rsa);
-
-#if USE_EVP
- pkey = EVP_PKEY_new();
- if (pkey == NULL)
- DST_RET(ISC_R_NOMEMORY);
- if (!EVP_PKEY_set1_RSA(pkey, rsa))
- DST_RET(ISC_R_FAILURE);
- key->keydata.pkey = pkey;
-#else
- key->keydata.rsa = rsa;
-#endif
-
- for (i = 0; i < priv.nelements; i++) {
- BIGNUM *bn;
- switch (priv.elements[i].tag) {
- case TAG_RSA_ENGINE:
- continue;
- case TAG_RSA_LABEL:
- continue;
- case TAG_RSA_PIN:
- continue;
- default:
- bn = BN_bin2bn(priv.elements[i].data,
- priv.elements[i].length, NULL);
- if (bn == NULL)
- DST_RET(ISC_R_NOMEMORY);
- }
-
- switch (priv.elements[i].tag) {
- case TAG_RSA_MODULUS:
- rsa->n = bn;
- break;
- case TAG_RSA_PUBLICEXPONENT:
- rsa->e = bn;
- break;
- case TAG_RSA_PRIVATEEXPONENT:
- rsa->d = bn;
- break;
- case TAG_RSA_PRIME1:
- rsa->p = bn;
- break;
- case TAG_RSA_PRIME2:
- rsa->q = bn;
- break;
- case TAG_RSA_EXPONENT1:
- rsa->dmp1 = bn;
- break;
- case TAG_RSA_EXPONENT2:
- rsa->dmq1 = bn;
- break;
- case TAG_RSA_COEFFICIENT:
- rsa->iqmp = bn;
- break;
- }
- }
- dst__privstruct_free(&priv, mctx);
- memset(&priv, 0, sizeof(priv));
-
- if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS)
- DST_RET(DST_R_INVALIDPRIVATEKEY);
- if (BN_num_bits(rsa->e) > RSA_MAX_PUBEXP_BITS)
- DST_RET(ISC_R_RANGE);
- key->key_size = BN_num_bits(rsa->n);
- if (pubrsa != NULL)
- RSA_free(pubrsa);
-#if USE_EVP
- RSA_free(rsa);
-#endif
-
- return (ISC_R_SUCCESS);
-
- err:
-#if USE_EVP
- if (pkey != NULL)
- EVP_PKEY_free(pkey);
-#endif
- if (rsa != NULL)
- RSA_free(rsa);
- if (pubrsa != NULL)
- RSA_free(pubrsa);
- key->keydata.generic = NULL;
- dst__privstruct_free(&priv, mctx);
- memset(&priv, 0, sizeof(priv));
- return (ret);
-}
-
-static isc_result_t
-opensslrsa_fromlabel(dst_key_t *key, const char *engine, const char *label,
- const char *pin)
-{
-#ifdef USE_ENGINE
- 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(dst__openssl_toresult2("ENGINE_load_private_key",
- ISC_R_NOTFOUND));
- 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 (BN_num_bits(rsa->e) > RSA_MAX_PUBEXP_BITS)
- DST_RET(ISC_R_RANGE);
- if (pubrsa != NULL)
- RSA_free(pubrsa);
- key->key_size = EVP_PKEY_bits(pkey);
-#if USE_EVP
- key->keydata.pkey = pkey;
- RSA_free(rsa);
-#else
- key->keydata.rsa = rsa;
- EVP_PKEY_free(pkey);
-#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);
-#else
- UNUSED(key);
- UNUSED(engine);
- UNUSED(label);
- UNUSED(pin);
- return(DST_R_NOENGINE);
-#endif
-}
-
-static dst_func_t opensslrsa_functions = {
- opensslrsa_createctx,
- opensslrsa_destroyctx,
- opensslrsa_adddata,
- opensslrsa_sign,
- opensslrsa_verify,
- opensslrsa_verify2,
- NULL, /*%< computesecret */
- opensslrsa_compare,
- NULL, /*%< paramcompare */
- opensslrsa_generate,
- opensslrsa_isprivate,
- opensslrsa_destroy,
- opensslrsa_todns,
- opensslrsa_fromdns,
- opensslrsa_tofile,
- opensslrsa_parse,
- NULL, /*%< cleanup */
- opensslrsa_fromlabel,
- NULL, /*%< dump */
- NULL, /*%< restore */
-};
-
-isc_result_t
-dst__opensslrsa_init(dst_func_t **funcp, unsigned char algorithm) {
- REQUIRE(funcp != NULL);
-
- if (*funcp == NULL) {
- switch (algorithm) {
- case DST_ALG_RSASHA256:
-#if defined(HAVE_EVP_SHA256) || !USE_EVP
- *funcp = &opensslrsa_functions;
-#endif
- break;
- case DST_ALG_RSASHA512:
-#if defined(HAVE_EVP_SHA512) || !USE_EVP
- *funcp = &opensslrsa_functions;
-#endif
- break;
- default:
- *funcp = &opensslrsa_functions;
- break;
- }
- }
- return (ISC_R_SUCCESS);
-}
-
-#else /* OPENSSL */
-
-#include <isc/util.h>
-
-EMPTY_TRANSLATION_UNIT
-
-#endif /* OPENSSL */
-/*! \file */
diff --git a/contrib/bind9/lib/dns/order.c b/contrib/bind9/lib/dns/order.c
deleted file mode 100644
index 853b00196d21..000000000000
--- a/contrib/bind9/lib/dns/order.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2002 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: order.c,v 1.10 2007/06/19 23:47:16 tbox Exp $ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <isc/magic.h>
-#include <isc/mem.h>
-#include <isc/types.h>
-#include <isc/util.h>
-#include <isc/refcount.h>
-
-#include <dns/fixedname.h>
-#include <dns/name.h>
-#include <dns/order.h>
-#include <dns/rdataset.h>
-#include <dns/types.h>
-
-typedef struct dns_order_ent dns_order_ent_t;
-struct dns_order_ent {
- dns_fixedname_t name;
- dns_rdataclass_t rdclass;
- dns_rdatatype_t rdtype;
- unsigned int mode;
- ISC_LINK(dns_order_ent_t) link;
-};
-
-struct dns_order {
- unsigned int magic;
- isc_refcount_t references;
- ISC_LIST(dns_order_ent_t) ents;
- isc_mem_t *mctx;
-};
-
-#define DNS_ORDER_MAGIC ISC_MAGIC('O','r','d','r')
-#define DNS_ORDER_VALID(order) ISC_MAGIC_VALID(order, DNS_ORDER_MAGIC)
-
-isc_result_t
-dns_order_create(isc_mem_t *mctx, dns_order_t **orderp) {
- dns_order_t *order;
- isc_result_t result;
-
- REQUIRE(orderp != NULL && *orderp == NULL);
-
- order = isc_mem_get(mctx, sizeof(*order));
- if (order == NULL)
- return (ISC_R_NOMEMORY);
-
- ISC_LIST_INIT(order->ents);
-
- /* Implicit attach. */
- result = isc_refcount_init(&order->references, 1);
- if (result != ISC_R_SUCCESS) {
- isc_mem_put(mctx, order, sizeof(*order));
- return (result);
- }
-
- order->mctx = NULL;
- isc_mem_attach(mctx, &order->mctx);
- order->magic = DNS_ORDER_MAGIC;
- *orderp = order;
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_order_add(dns_order_t *order, dns_name_t *name,
- dns_rdatatype_t rdtype, dns_rdataclass_t rdclass,
- unsigned int mode)
-{
- dns_order_ent_t *ent;
-
- REQUIRE(DNS_ORDER_VALID(order));
- REQUIRE(mode == DNS_RDATASETATTR_RANDOMIZE ||
- mode == DNS_RDATASETATTR_FIXEDORDER ||
- mode == 0 /* DNS_RDATASETATTR_CYCLIC */ );
-
- ent = isc_mem_get(order->mctx, sizeof(*ent));
- if (ent == NULL)
- return (ISC_R_NOMEMORY);
-
- dns_fixedname_init(&ent->name);
- RUNTIME_CHECK(dns_name_copy(name, dns_fixedname_name(&ent->name), NULL)
- == ISC_R_SUCCESS);
- ent->rdtype = rdtype;
- ent->rdclass = rdclass;
- ent->mode = mode;
- ISC_LINK_INIT(ent, link);
- ISC_LIST_INITANDAPPEND(order->ents, ent, link);
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_boolean_t
-match(dns_name_t *name1, dns_name_t *name2) {
-
- if (dns_name_iswildcard(name2))
- return(dns_name_matcheswildcard(name1, name2));
- return (dns_name_equal(name1, name2));
-}
-
-unsigned int
-dns_order_find(dns_order_t *order, dns_name_t *name,
- dns_rdatatype_t rdtype, dns_rdataclass_t rdclass)
-{
- dns_order_ent_t *ent;
- REQUIRE(DNS_ORDER_VALID(order));
-
- for (ent = ISC_LIST_HEAD(order->ents);
- ent != NULL;
- ent = ISC_LIST_NEXT(ent, link)) {
- if (ent->rdtype != rdtype && ent->rdtype != dns_rdatatype_any)
- continue;
- if (ent->rdclass != rdclass &&
- ent->rdclass != dns_rdataclass_any)
- continue;
- if (match(name, dns_fixedname_name(&ent->name)))
- return (ent->mode);
- }
- return (0);
-}
-
-void
-dns_order_attach(dns_order_t *source, dns_order_t **target) {
- REQUIRE(DNS_ORDER_VALID(source));
- REQUIRE(target != NULL && *target == NULL);
- isc_refcount_increment(&source->references, NULL);
- *target = source;
-}
-
-void
-dns_order_detach(dns_order_t **orderp) {
- dns_order_t *order;
- dns_order_ent_t *ent;
- unsigned int references;
-
- REQUIRE(orderp != NULL);
- order = *orderp;
- REQUIRE(DNS_ORDER_VALID(order));
- isc_refcount_decrement(&order->references, &references);
- *orderp = NULL;
- if (references != 0)
- return;
-
- order->magic = 0;
- while ((ent = ISC_LIST_HEAD(order->ents)) != NULL) {
- ISC_LIST_UNLINK(order->ents, ent, link);
- isc_mem_put(order->mctx, ent, sizeof(*ent));
- }
- isc_refcount_destroy(&order->references);
- isc_mem_putanddetach(&order->mctx, order, sizeof(*order));
-}
diff --git a/contrib/bind9/lib/dns/peer.c b/contrib/bind9/lib/dns/peer.c
deleted file mode 100644
index ec9e08cb27b7..000000000000
--- a/contrib/bind9/lib/dns/peer.c
+++ /dev/null
@@ -1,712 +0,0 @@
-/*
- * Copyright (C) 2004-2009, 2012 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: peer.c,v 1.33 2009/09/02 23:48:02 tbox Exp $ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <isc/mem.h>
-#include <isc/string.h>
-#include <isc/util.h>
-#include <isc/sockaddr.h>
-
-#include <dns/bit.h>
-#include <dns/fixedname.h>
-#include <dns/name.h>
-#include <dns/peer.h>
-
-/*%
- * Bit positions in the dns_peer_t structure flags field
- */
-#define BOGUS_BIT 0
-#define SERVER_TRANSFER_FORMAT_BIT 1
-#define TRANSFERS_BIT 2
-#define PROVIDE_IXFR_BIT 3
-#define REQUEST_IXFR_BIT 4
-#define SUPPORT_EDNS_BIT 5
-#define SERVER_UDPSIZE_BIT 6
-#define SERVER_MAXUDP_BIT 7
-#define REQUEST_NSID_BIT 8
-
-static void
-peerlist_delete(dns_peerlist_t **list);
-
-static void
-peer_delete(dns_peer_t **peer);
-
-isc_result_t
-dns_peerlist_new(isc_mem_t *mem, dns_peerlist_t **list) {
- dns_peerlist_t *l;
-
- REQUIRE(list != NULL);
-
- l = isc_mem_get(mem, sizeof(*l));
- if (l == NULL)
- return (ISC_R_NOMEMORY);
-
- ISC_LIST_INIT(l->elements);
- l->mem = mem;
- l->refs = 1;
- l->magic = DNS_PEERLIST_MAGIC;
-
- *list = l;
-
- return (ISC_R_SUCCESS);
-}
-
-void
-dns_peerlist_attach(dns_peerlist_t *source, dns_peerlist_t **target) {
- REQUIRE(DNS_PEERLIST_VALID(source));
- REQUIRE(target != NULL);
- REQUIRE(*target == NULL);
-
- source->refs++;
-
- ENSURE(source->refs != 0xffffffffU);
-
- *target = source;
-}
-
-void
-dns_peerlist_detach(dns_peerlist_t **list) {
- dns_peerlist_t *plist;
-
- REQUIRE(list != NULL);
- REQUIRE(*list != NULL);
- REQUIRE(DNS_PEERLIST_VALID(*list));
-
- plist = *list;
- *list = NULL;
-
- REQUIRE(plist->refs > 0);
-
- plist->refs--;
-
- if (plist->refs == 0)
- peerlist_delete(&plist);
-}
-
-static void
-peerlist_delete(dns_peerlist_t **list) {
- dns_peerlist_t *l;
- dns_peer_t *server, *stmp;
-
- REQUIRE(list != NULL);
- REQUIRE(DNS_PEERLIST_VALID(*list));
-
- l = *list;
-
- REQUIRE(l->refs == 0);
-
- server = ISC_LIST_HEAD(l->elements);
- while (server != NULL) {
- stmp = ISC_LIST_NEXT(server, next);
- ISC_LIST_UNLINK(l->elements, server, next);
- dns_peer_detach(&server);
- server = stmp;
- }
-
- l->magic = 0;
- isc_mem_put(l->mem, l, sizeof(*l));
-
- *list = NULL;
-}
-
-void
-dns_peerlist_addpeer(dns_peerlist_t *peers, dns_peer_t *peer) {
- dns_peer_t *p = NULL;
-
- dns_peer_attach(peer, &p);
-
- /*
- * More specifics to front of list.
- */
- for (p = ISC_LIST_HEAD(peers->elements);
- p != NULL;
- p = ISC_LIST_NEXT(p, next))
- if (p->prefixlen < peer->prefixlen)
- break;
-
- if (p != NULL)
- ISC_LIST_INSERTBEFORE(peers->elements, p, peer, next);
- else
- ISC_LIST_APPEND(peers->elements, peer, next);
-
-}
-
-isc_result_t
-dns_peerlist_peerbyaddr(dns_peerlist_t *servers,
- isc_netaddr_t *addr, dns_peer_t **retval)
-{
- dns_peer_t *server;
- isc_result_t res;
-
- REQUIRE(retval != NULL);
- REQUIRE(DNS_PEERLIST_VALID(servers));
-
- server = ISC_LIST_HEAD(servers->elements);
- while (server != NULL) {
- if (isc_netaddr_eqprefix(addr, &server->address,
- server->prefixlen))
- break;
-
- server = ISC_LIST_NEXT(server, next);
- }
-
- if (server != NULL) {
- *retval = server;
- res = ISC_R_SUCCESS;
- } else {
- res = ISC_R_NOTFOUND;
- }
-
- return (res);
-}
-
-
-
-isc_result_t
-dns_peerlist_currpeer(dns_peerlist_t *peers, dns_peer_t **retval) {
- dns_peer_t *p = NULL;
-
- p = ISC_LIST_TAIL(peers->elements);
-
- dns_peer_attach(p, retval);
-
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_peer_new(isc_mem_t *mem, isc_netaddr_t *addr, dns_peer_t **peerptr) {
- unsigned int prefixlen = 0;
-
- REQUIRE(peerptr != NULL);
- switch(addr->family) {
- case AF_INET:
- prefixlen = 32;
- break;
- case AF_INET6:
- prefixlen = 128;
- break;
- default:
- INSIST(0);
- }
-
- return (dns_peer_newprefix(mem, addr, prefixlen, peerptr));
-}
-
-isc_result_t
-dns_peer_newprefix(isc_mem_t *mem, isc_netaddr_t *addr, unsigned int prefixlen,
- dns_peer_t **peerptr)
-{
- dns_peer_t *peer;
-
- REQUIRE(peerptr != NULL);
-
- peer = isc_mem_get(mem, sizeof(*peer));
- if (peer == NULL)
- return (ISC_R_NOMEMORY);
-
- peer->magic = DNS_PEER_MAGIC;
- peer->address = *addr;
- peer->prefixlen = prefixlen;
- peer->mem = mem;
- peer->bogus = ISC_FALSE;
- peer->transfer_format = dns_one_answer;
- peer->transfers = 0;
- peer->request_ixfr = ISC_FALSE;
- peer->provide_ixfr = ISC_FALSE;
- peer->key = NULL;
- peer->refs = 1;
- peer->transfer_source = NULL;
- peer->notify_source = NULL;
- peer->query_source = NULL;
-
- memset(&peer->bitflags, 0x0, sizeof(peer->bitflags));
-
- ISC_LINK_INIT(peer, next);
-
- *peerptr = peer;
-
- return (ISC_R_SUCCESS);
-}
-
-void
-dns_peer_attach(dns_peer_t *source, dns_peer_t **target) {
- REQUIRE(DNS_PEER_VALID(source));
- REQUIRE(target != NULL);
- REQUIRE(*target == NULL);
-
- source->refs++;
-
- ENSURE(source->refs != 0xffffffffU);
-
- *target = source;
-}
-
-void
-dns_peer_detach(dns_peer_t **peer) {
- dns_peer_t *p;
-
- REQUIRE(peer != NULL);
- REQUIRE(*peer != NULL);
- REQUIRE(DNS_PEER_VALID(*peer));
-
- p = *peer;
-
- REQUIRE(p->refs > 0);
-
- *peer = NULL;
- p->refs--;
-
- if (p->refs == 0)
- peer_delete(&p);
-}
-
-static void
-peer_delete(dns_peer_t **peer) {
- dns_peer_t *p;
- isc_mem_t *mem;
-
- REQUIRE(peer != NULL);
- REQUIRE(DNS_PEER_VALID(*peer));
-
- p = *peer;
-
- REQUIRE(p->refs == 0);
-
- mem = p->mem;
- p->mem = NULL;
- p->magic = 0;
-
- if (p->key != NULL) {
- dns_name_free(p->key, mem);
- isc_mem_put(mem, p->key, sizeof(dns_name_t));
- }
-
- if (p->transfer_source != NULL) {
- isc_mem_put(mem, p->transfer_source,
- sizeof(*p->transfer_source));
- }
-
- isc_mem_put(mem, p, sizeof(*p));
-
- *peer = NULL;
-}
-
-isc_result_t
-dns_peer_setbogus(dns_peer_t *peer, isc_boolean_t newval) {
- isc_boolean_t existed;
-
- REQUIRE(DNS_PEER_VALID(peer));
-
- existed = DNS_BIT_CHECK(BOGUS_BIT, &peer->bitflags);
-
- peer->bogus = newval;
- DNS_BIT_SET(BOGUS_BIT, &peer->bitflags);
-
- return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_peer_getbogus(dns_peer_t *peer, isc_boolean_t *retval) {
- REQUIRE(DNS_PEER_VALID(peer));
- REQUIRE(retval != NULL);
-
- if (DNS_BIT_CHECK(BOGUS_BIT, &peer->bitflags)) {
- *retval = peer->bogus;
- return (ISC_R_SUCCESS);
- } else
- return (ISC_R_NOTFOUND);
-}
-
-
-isc_result_t
-dns_peer_setprovideixfr(dns_peer_t *peer, isc_boolean_t newval) {
- isc_boolean_t existed;
-
- REQUIRE(DNS_PEER_VALID(peer));
-
- existed = DNS_BIT_CHECK(PROVIDE_IXFR_BIT, &peer->bitflags);
-
- peer->provide_ixfr = newval;
- DNS_BIT_SET(PROVIDE_IXFR_BIT, &peer->bitflags);
-
- return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_peer_getprovideixfr(dns_peer_t *peer, isc_boolean_t *retval) {
- REQUIRE(DNS_PEER_VALID(peer));
- REQUIRE(retval != NULL);
-
- if (DNS_BIT_CHECK(PROVIDE_IXFR_BIT, &peer->bitflags)) {
- *retval = peer->provide_ixfr;
- return (ISC_R_SUCCESS);
- } else {
- return (ISC_R_NOTFOUND);
- }
-}
-
-isc_result_t
-dns_peer_setrequestixfr(dns_peer_t *peer, isc_boolean_t newval) {
- isc_boolean_t existed;
-
- REQUIRE(DNS_PEER_VALID(peer));
-
- existed = DNS_BIT_CHECK(REQUEST_IXFR_BIT, &peer->bitflags);
-
- peer->request_ixfr = newval;
- DNS_BIT_SET(REQUEST_IXFR_BIT, &peer->bitflags);
-
- return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_peer_getrequestixfr(dns_peer_t *peer, isc_boolean_t *retval) {
- REQUIRE(DNS_PEER_VALID(peer));
- REQUIRE(retval != NULL);
-
- if (DNS_BIT_CHECK(REQUEST_IXFR_BIT, &peer->bitflags)) {
- *retval = peer->request_ixfr;
- return (ISC_R_SUCCESS);
- } else
- return (ISC_R_NOTFOUND);
-}
-
-isc_result_t
-dns_peer_setsupportedns(dns_peer_t *peer, isc_boolean_t newval) {
- isc_boolean_t existed;
-
- REQUIRE(DNS_PEER_VALID(peer));
-
- existed = DNS_BIT_CHECK(SUPPORT_EDNS_BIT, &peer->bitflags);
-
- peer->support_edns = newval;
- DNS_BIT_SET(SUPPORT_EDNS_BIT, &peer->bitflags);
-
- return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_peer_getsupportedns(dns_peer_t *peer, isc_boolean_t *retval) {
- REQUIRE(DNS_PEER_VALID(peer));
- REQUIRE(retval != NULL);
-
- if (DNS_BIT_CHECK(SUPPORT_EDNS_BIT, &peer->bitflags)) {
- *retval = peer->support_edns;
- return (ISC_R_SUCCESS);
- } else
- return (ISC_R_NOTFOUND);
-}
-
-isc_result_t
-dns_peer_setrequestnsid(dns_peer_t *peer, isc_boolean_t newval) {
- isc_boolean_t existed;
-
- REQUIRE(DNS_PEER_VALID(peer));
-
- existed = DNS_BIT_CHECK(REQUEST_NSID_BIT, &peer->bitflags);
-
- peer->request_nsid = newval;
- DNS_BIT_SET(REQUEST_NSID_BIT, &peer->bitflags);
-
- return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_peer_getrequestnsid(dns_peer_t *peer, isc_boolean_t *retval) {
- REQUIRE(DNS_PEER_VALID(peer));
- REQUIRE(retval != NULL);
-
- if (DNS_BIT_CHECK(REQUEST_NSID_BIT, &peer->bitflags)) {
- *retval = peer->request_nsid;
- return (ISC_R_SUCCESS);
- } else
- return (ISC_R_NOTFOUND);
-}
-
-isc_result_t
-dns_peer_settransfers(dns_peer_t *peer, isc_uint32_t newval) {
- isc_boolean_t existed;
-
- REQUIRE(DNS_PEER_VALID(peer));
-
- existed = DNS_BIT_CHECK(TRANSFERS_BIT, &peer->bitflags);
-
- peer->transfers = newval;
- DNS_BIT_SET(TRANSFERS_BIT, &peer->bitflags);
-
- return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_peer_gettransfers(dns_peer_t *peer, isc_uint32_t *retval) {
- REQUIRE(DNS_PEER_VALID(peer));
- REQUIRE(retval != NULL);
-
- if (DNS_BIT_CHECK(TRANSFERS_BIT, &peer->bitflags)) {
- *retval = peer->transfers;
- return (ISC_R_SUCCESS);
- } else {
- return (ISC_R_NOTFOUND);
- }
-}
-
-isc_result_t
-dns_peer_settransferformat(dns_peer_t *peer, dns_transfer_format_t newval) {
- isc_boolean_t existed;
-
- REQUIRE(DNS_PEER_VALID(peer));
-
- existed = DNS_BIT_CHECK(SERVER_TRANSFER_FORMAT_BIT,
- &peer->bitflags);
-
- peer->transfer_format = newval;
- DNS_BIT_SET(SERVER_TRANSFER_FORMAT_BIT, &peer->bitflags);
-
- return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_peer_gettransferformat(dns_peer_t *peer, dns_transfer_format_t *retval) {
- REQUIRE(DNS_PEER_VALID(peer));
- REQUIRE(retval != NULL);
-
- if (DNS_BIT_CHECK(SERVER_TRANSFER_FORMAT_BIT, &peer->bitflags)) {
- *retval = peer->transfer_format;
- return (ISC_R_SUCCESS);
- } else {
- return (ISC_R_NOTFOUND);
- }
-}
-
-isc_result_t
-dns_peer_getkey(dns_peer_t *peer, dns_name_t **retval) {
- REQUIRE(DNS_PEER_VALID(peer));
- REQUIRE(retval != NULL);
-
- if (peer->key != NULL) {
- *retval = peer->key;
- }
-
- return (peer->key == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_peer_setkey(dns_peer_t *peer, dns_name_t **keyval) {
- isc_boolean_t exists = ISC_FALSE;
-
- if (peer->key != NULL) {
- dns_name_free(peer->key, peer->mem);
- isc_mem_put(peer->mem, peer->key, sizeof(dns_name_t));
- exists = ISC_TRUE;
- }
-
- peer->key = *keyval;
- *keyval = NULL;
-
- return (exists ? ISC_R_EXISTS : ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_peer_setkeybycharp(dns_peer_t *peer, const char *keyval) {
- isc_buffer_t b;
- dns_fixedname_t fname;
- dns_name_t *name;
- isc_result_t result;
-
- dns_fixedname_init(&fname);
- isc_buffer_constinit(&b, keyval, strlen(keyval));
- isc_buffer_add(&b, strlen(keyval));
- result = dns_name_fromtext(dns_fixedname_name(&fname), &b,
- dns_rootname, 0, NULL);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- name = isc_mem_get(peer->mem, sizeof(dns_name_t));
- if (name == NULL)
- return (ISC_R_NOMEMORY);
-
- dns_name_init(name, NULL);
- result = dns_name_dup(dns_fixedname_name(&fname), peer->mem, name);
- if (result != ISC_R_SUCCESS) {
- isc_mem_put(peer->mem, name, sizeof(dns_name_t));
- return (result);
- }
-
- result = dns_peer_setkey(peer, &name);
- if (result != ISC_R_SUCCESS)
- isc_mem_put(peer->mem, name, sizeof(dns_name_t));
-
- return (result);
-}
-
-isc_result_t
-dns_peer_settransfersource(dns_peer_t *peer,
- const isc_sockaddr_t *transfer_source)
-{
- REQUIRE(DNS_PEER_VALID(peer));
-
- if (peer->transfer_source != NULL) {
- isc_mem_put(peer->mem, peer->transfer_source,
- sizeof(*peer->transfer_source));
- peer->transfer_source = NULL;
- }
- if (transfer_source != NULL) {
- peer->transfer_source = isc_mem_get(peer->mem,
- sizeof(*peer->transfer_source));
- if (peer->transfer_source == NULL)
- return (ISC_R_NOMEMORY);
-
- *peer->transfer_source = *transfer_source;
- }
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_peer_gettransfersource(dns_peer_t *peer, isc_sockaddr_t *transfer_source) {
- REQUIRE(DNS_PEER_VALID(peer));
- REQUIRE(transfer_source != NULL);
-
- if (peer->transfer_source == NULL)
- return (ISC_R_NOTFOUND);
- *transfer_source = *peer->transfer_source;
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_peer_setnotifysource(dns_peer_t *peer,
- const isc_sockaddr_t *notify_source)
-{
- REQUIRE(DNS_PEER_VALID(peer));
-
- if (peer->notify_source != NULL) {
- isc_mem_put(peer->mem, peer->notify_source,
- sizeof(*peer->notify_source));
- peer->notify_source = NULL;
- }
- if (notify_source != NULL) {
- peer->notify_source = isc_mem_get(peer->mem,
- sizeof(*peer->notify_source));
- if (peer->notify_source == NULL)
- return (ISC_R_NOMEMORY);
-
- *peer->notify_source = *notify_source;
- }
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_peer_getnotifysource(dns_peer_t *peer, isc_sockaddr_t *notify_source) {
- REQUIRE(DNS_PEER_VALID(peer));
- REQUIRE(notify_source != NULL);
-
- if (peer->notify_source == NULL)
- return (ISC_R_NOTFOUND);
- *notify_source = *peer->notify_source;
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_peer_setquerysource(dns_peer_t *peer, const isc_sockaddr_t *query_source) {
- REQUIRE(DNS_PEER_VALID(peer));
-
- if (peer->query_source != NULL) {
- isc_mem_put(peer->mem, peer->query_source,
- sizeof(*peer->query_source));
- peer->query_source = NULL;
- }
- if (query_source != NULL) {
- peer->query_source = isc_mem_get(peer->mem,
- sizeof(*peer->query_source));
- if (peer->query_source == NULL)
- return (ISC_R_NOMEMORY);
-
- *peer->query_source = *query_source;
- }
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_peer_getquerysource(dns_peer_t *peer, isc_sockaddr_t *query_source) {
- REQUIRE(DNS_PEER_VALID(peer));
- REQUIRE(query_source != NULL);
-
- if (peer->query_source == NULL)
- return (ISC_R_NOTFOUND);
- *query_source = *peer->query_source;
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_peer_setudpsize(dns_peer_t *peer, isc_uint16_t udpsize) {
- isc_boolean_t existed;
-
- REQUIRE(DNS_PEER_VALID(peer));
-
- existed = DNS_BIT_CHECK(SERVER_UDPSIZE_BIT, &peer->bitflags);
-
- peer->udpsize = udpsize;
- DNS_BIT_SET(SERVER_UDPSIZE_BIT, &peer->bitflags);
-
- return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_peer_getudpsize(dns_peer_t *peer, isc_uint16_t *udpsize) {
-
- REQUIRE(DNS_PEER_VALID(peer));
- REQUIRE(udpsize != NULL);
-
- if (DNS_BIT_CHECK(SERVER_UDPSIZE_BIT, &peer->bitflags)) {
- *udpsize = peer->udpsize;
- return (ISC_R_SUCCESS);
- } else {
- return (ISC_R_NOTFOUND);
- }
-}
-
-isc_result_t
-dns_peer_setmaxudp(dns_peer_t *peer, isc_uint16_t maxudp) {
- isc_boolean_t existed;
-
- REQUIRE(DNS_PEER_VALID(peer));
-
- existed = DNS_BIT_CHECK(SERVER_MAXUDP_BIT, &peer->bitflags);
-
- peer->maxudp = maxudp;
- DNS_BIT_SET(SERVER_MAXUDP_BIT, &peer->bitflags);
-
- return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_peer_getmaxudp(dns_peer_t *peer, isc_uint16_t *maxudp) {
-
- REQUIRE(DNS_PEER_VALID(peer));
- REQUIRE(maxudp != NULL);
-
- if (DNS_BIT_CHECK(SERVER_MAXUDP_BIT, &peer->bitflags)) {
- *maxudp = peer->maxudp;
- return (ISC_R_SUCCESS);
- } else {
- return (ISC_R_NOTFOUND);
- }
-}
diff --git a/contrib/bind9/lib/dns/portlist.c b/contrib/bind9/lib/dns/portlist.c
deleted file mode 100644
index 5bc89f482984..000000000000
--- a/contrib/bind9/lib/dns/portlist.c
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 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: portlist.c,v 1.13 2007/06/19 23:47:16 tbox Exp $ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <stdlib.h>
-
-#include <isc/magic.h>
-#include <isc/mem.h>
-#include <isc/mutex.h>
-#include <isc/net.h>
-#include <isc/refcount.h>
-#include <isc/result.h>
-#include <isc/string.h>
-#include <isc/types.h>
-#include <isc/util.h>
-
-#include <dns/types.h>
-#include <dns/portlist.h>
-
-#define DNS_PORTLIST_MAGIC ISC_MAGIC('P','L','S','T')
-#define DNS_VALID_PORTLIST(p) ISC_MAGIC_VALID(p, DNS_PORTLIST_MAGIC)
-
-typedef struct dns_element {
- in_port_t port;
- isc_uint16_t flags;
-} dns_element_t;
-
-struct dns_portlist {
- unsigned int magic;
- isc_mem_t *mctx;
- isc_refcount_t refcount;
- isc_mutex_t lock;
- dns_element_t *list;
- unsigned int allocated;
- unsigned int active;
-};
-
-#define DNS_PL_INET 0x0001
-#define DNS_PL_INET6 0x0002
-#define DNS_PL_ALLOCATE 16
-
-static int
-compare(const void *arg1, const void *arg2) {
- const dns_element_t *e1 = (const dns_element_t *)arg1;
- const dns_element_t *e2 = (const dns_element_t *)arg2;
-
- if (e1->port < e2->port)
- return (-1);
- if (e1->port > e2->port)
- return (1);
- return (0);
-}
-
-isc_result_t
-dns_portlist_create(isc_mem_t *mctx, dns_portlist_t **portlistp) {
- dns_portlist_t *portlist;
- isc_result_t result;
-
- REQUIRE(portlistp != NULL && *portlistp == NULL);
-
- portlist = isc_mem_get(mctx, sizeof(*portlist));
- if (portlist == NULL)
- return (ISC_R_NOMEMORY);
- result = isc_mutex_init(&portlist->lock);
- if (result != ISC_R_SUCCESS) {
- isc_mem_put(mctx, portlist, sizeof(*portlist));
- return (result);
- }
- result = isc_refcount_init(&portlist->refcount, 1);
- if (result != ISC_R_SUCCESS) {
- DESTROYLOCK(&portlist->lock);
- isc_mem_put(mctx, portlist, sizeof(*portlist));
- return (result);
- }
- portlist->list = NULL;
- portlist->allocated = 0;
- portlist->active = 0;
- portlist->mctx = NULL;
- isc_mem_attach(mctx, &portlist->mctx);
- portlist->magic = DNS_PORTLIST_MAGIC;
- *portlistp = portlist;
- return (ISC_R_SUCCESS);
-}
-
-static dns_element_t *
-find_port(dns_element_t *list, unsigned int len, in_port_t port) {
- unsigned int xtry = len / 2;
- unsigned int min = 0;
- unsigned int max = len - 1;
- unsigned int last = len;
-
- for (;;) {
- if (list[xtry].port == port)
- return (&list[xtry]);
- if (port > list[xtry].port) {
- if (xtry == max)
- break;
- min = xtry;
- xtry = xtry + (max - xtry + 1) / 2;
- INSIST(xtry <= max);
- if (xtry == last)
- break;
- last = min;
- } else {
- if (xtry == min)
- break;
- max = xtry;
- xtry = xtry - (xtry - min + 1) / 2;
- INSIST(xtry >= min);
- if (xtry == last)
- break;
- last = max;
- }
- }
- return (NULL);
-}
-
-isc_result_t
-dns_portlist_add(dns_portlist_t *portlist, int af, in_port_t port) {
- dns_element_t *el;
- isc_result_t result;
-
- REQUIRE(DNS_VALID_PORTLIST(portlist));
- REQUIRE(af == AF_INET || af == AF_INET6);
-
- LOCK(&portlist->lock);
- if (portlist->active != 0) {
- el = find_port(portlist->list, portlist->active, port);
- if (el != NULL) {
- if (af == AF_INET)
- el->flags |= DNS_PL_INET;
- else
- el->flags |= DNS_PL_INET6;
- result = ISC_R_SUCCESS;
- goto unlock;
- }
- }
-
- if (portlist->allocated <= portlist->active) {
- unsigned int allocated;
- allocated = portlist->allocated + DNS_PL_ALLOCATE;
- el = isc_mem_get(portlist->mctx, sizeof(*el) * allocated);
- if (el == NULL) {
- result = ISC_R_NOMEMORY;
- goto unlock;
- }
- if (portlist->list != NULL) {
- memcpy(el, portlist->list,
- portlist->allocated * sizeof(*el));
- isc_mem_put(portlist->mctx, portlist->list,
- portlist->allocated * sizeof(*el));
- }
- portlist->list = el;
- portlist->allocated = allocated;
- }
- portlist->list[portlist->active].port = port;
- if (af == AF_INET)
- portlist->list[portlist->active].flags = DNS_PL_INET;
- else
- portlist->list[portlist->active].flags = DNS_PL_INET6;
- portlist->active++;
- qsort(portlist->list, portlist->active, sizeof(*el), compare);
- result = ISC_R_SUCCESS;
- unlock:
- UNLOCK(&portlist->lock);
- return (result);
-}
-
-void
-dns_portlist_remove(dns_portlist_t *portlist, int af, in_port_t port) {
- dns_element_t *el;
-
- REQUIRE(DNS_VALID_PORTLIST(portlist));
- REQUIRE(af == AF_INET || af == AF_INET6);
-
- LOCK(&portlist->lock);
- if (portlist->active != 0) {
- el = find_port(portlist->list, portlist->active, port);
- if (el != NULL) {
- if (af == AF_INET)
- el->flags &= ~DNS_PL_INET;
- else
- el->flags &= ~DNS_PL_INET6;
- if (el->flags == 0) {
- *el = portlist->list[portlist->active];
- portlist->active--;
- qsort(portlist->list, portlist->active,
- sizeof(*el), compare);
- }
- }
- }
- UNLOCK(&portlist->lock);
-}
-
-isc_boolean_t
-dns_portlist_match(dns_portlist_t *portlist, int af, in_port_t port) {
- dns_element_t *el;
- isc_boolean_t result = ISC_FALSE;
-
- REQUIRE(DNS_VALID_PORTLIST(portlist));
- REQUIRE(af == AF_INET || af == AF_INET6);
- LOCK(&portlist->lock);
- if (portlist->active != 0) {
- el = find_port(portlist->list, portlist->active, port);
- if (el != NULL) {
- if (af == AF_INET && (el->flags & DNS_PL_INET) != 0)
- result = ISC_TRUE;
- if (af == AF_INET6 && (el->flags & DNS_PL_INET6) != 0)
- result = ISC_TRUE;
- }
- }
- UNLOCK(&portlist->lock);
- return (result);
-}
-
-void
-dns_portlist_attach(dns_portlist_t *portlist, dns_portlist_t **portlistp) {
-
- REQUIRE(DNS_VALID_PORTLIST(portlist));
- REQUIRE(portlistp != NULL && *portlistp == NULL);
-
- isc_refcount_increment(&portlist->refcount, NULL);
- *portlistp = portlist;
-}
-
-void
-dns_portlist_detach(dns_portlist_t **portlistp) {
- dns_portlist_t *portlist;
- unsigned int count;
-
- REQUIRE(portlistp != NULL);
- portlist = *portlistp;
- REQUIRE(DNS_VALID_PORTLIST(portlist));
- *portlistp = NULL;
- isc_refcount_decrement(&portlist->refcount, &count);
- if (count == 0) {
- portlist->magic = 0;
- isc_refcount_destroy(&portlist->refcount);
- if (portlist->list != NULL)
- isc_mem_put(portlist->mctx, portlist->list,
- portlist->allocated *
- sizeof(*portlist->list));
- DESTROYLOCK(&portlist->lock);
- isc_mem_putanddetach(&portlist->mctx, portlist,
- sizeof(*portlist));
- }
-}
diff --git a/contrib/bind9/lib/dns/private.c b/contrib/bind9/lib/dns/private.c
deleted file mode 100644
index 6521279f2d9b..000000000000
--- a/contrib/bind9/lib/dns/private.c
+++ /dev/null
@@ -1,371 +0,0 @@
-/*
- * Copyright (C) 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-#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 INITIAL(x) (((x) & DNS_NSEC3FLAG_INITIAL) != 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 chain.
- */
- 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);
-}
-
-isc_result_t
-dns_private_totext(dns_rdata_t *private, isc_buffer_t *buf) {
- isc_result_t result;
-
- if (private->length < 5)
- return (ISC_R_NOTFOUND);
-
- if (private->data[0] == 0) {
- unsigned char nsec3buf[DNS_NSEC3PARAM_BUFFERSIZE];
- unsigned char newbuf[DNS_NSEC3PARAM_BUFFERSIZE];
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdata_nsec3param_t nsec3param;
- isc_boolean_t remove, init, nonsec;
- isc_buffer_t b;
-
- if (!dns_nsec3param_fromprivate(private, &rdata, nsec3buf,
- sizeof(nsec3buf)))
- CHECK(ISC_R_FAILURE);
-
- CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
-
- remove = ISC_TF((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0);
- init = ISC_TF((nsec3param.flags & DNS_NSEC3FLAG_INITIAL) != 0);
- nonsec = ISC_TF((nsec3param.flags & DNS_NSEC3FLAG_NONSEC) != 0);
-
- nsec3param.flags &= ~(DNS_NSEC3FLAG_CREATE|
- DNS_NSEC3FLAG_REMOVE|
- DNS_NSEC3FLAG_INITIAL|
- DNS_NSEC3FLAG_NONSEC);
-
- if (init)
- isc_buffer_putstr(buf, "Pending NSEC3 chain ");
- else if (remove)
- isc_buffer_putstr(buf, "Removing NSEC3 chain ");
- else
- isc_buffer_putstr(buf, "Creating NSEC3 chain ");
-
- dns_rdata_reset(&rdata);
- isc_buffer_init(&b, newbuf, sizeof(newbuf));
- CHECK(dns_rdata_fromstruct(&rdata, dns_rdataclass_in,
- dns_rdatatype_nsec3param,
- &nsec3param, &b));
-
- CHECK(dns_rdata_totext(&rdata, NULL, buf));
-
- if (remove && !nonsec)
- isc_buffer_putstr(buf, " / creating NSEC chain");
- } else if (private->length == 5) {
- unsigned char alg = private->data[0];
- dns_keytag_t keyid = (private->data[2] | private->data[1] << 8);
- char keybuf[BUFSIZ], algbuf[DNS_SECALG_FORMATSIZE];
- isc_boolean_t remove = ISC_TF(private->data[3] != 0);
- isc_boolean_t complete = ISC_TF(private->data[4] != 0);
-
- if (remove && complete)
- isc_buffer_putstr(buf, "Done removing signatures for ");
- else if (remove)
- isc_buffer_putstr(buf, "Removing signatures for ");
- else if (complete)
- isc_buffer_putstr(buf, "Done signing with ");
- else
- isc_buffer_putstr(buf, "Signing with ");
-
- dns_secalg_format(alg, algbuf, sizeof(algbuf));
- sprintf(keybuf, "key %d/%s", keyid, algbuf);
- isc_buffer_putstr(buf, keybuf);
- } else
- return (ISC_R_NOTFOUND);
-
- isc_buffer_putuint8(buf, 0);
- result = ISC_R_SUCCESS;
- failure:
- return (result);
-}
diff --git a/contrib/bind9/lib/dns/rbt.c b/contrib/bind9/lib/dns/rbt.c
deleted file mode 100644
index 7381b4a325b3..000000000000
--- a/contrib/bind9/lib/dns/rbt.c
+++ /dev/null
@@ -1,2679 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007-2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/*! \file */
-
-/* Principal Authors: DCL */
-
-#include <config.h>
-
-#include <isc/mem.h>
-#include <isc/platform.h>
-#include <isc/print.h>
-#include <isc/refcount.h>
-#include <isc/string.h>
-#include <isc/util.h>
-
-/*%
- * This define is so dns/name.h (included by dns/fixedname.h) uses more
- * efficient macro calls instead of functions for a few operations.
- */
-#define DNS_NAME_USEINLINE 1
-
-#include <dns/fixedname.h>
-#include <dns/log.h>
-#include <dns/rbt.h>
-#include <dns/result.h>
-
-#define RBT_MAGIC ISC_MAGIC('R', 'B', 'T', '+')
-#define VALID_RBT(rbt) ISC_MAGIC_VALID(rbt, RBT_MAGIC)
-
-/*
- * XXXDCL Since parent pointers were added in again, I could remove all of the
- * chain junk, and replace with dns_rbt_firstnode, _previousnode, _nextnode,
- * _lastnode. This would involve pretty major change to the API.
- */
-#define CHAIN_MAGIC ISC_MAGIC('0', '-', '0', '-')
-#define VALID_CHAIN(chain) ISC_MAGIC_VALID(chain, CHAIN_MAGIC)
-
-#define RBT_HASH_SIZE 64
-
-#ifdef RBT_MEM_TEST
-#undef RBT_HASH_SIZE
-#define RBT_HASH_SIZE 2 /*%< To give the reallocation code a workout. */
-#endif
-
-struct dns_rbt {
- unsigned int magic;
- isc_mem_t * mctx;
- dns_rbtnode_t * root;
- void (*data_deleter)(void *, void *);
- void * deleter_arg;
- unsigned int nodecount;
- unsigned int hashsize;
- dns_rbtnode_t ** hashtable;
-};
-
-#define RED 0
-#define BLACK 1
-
-/*%
- * Elements of the rbtnode structure.
- */
-#define PARENT(node) ((node)->parent)
-#define LEFT(node) ((node)->left)
-#define RIGHT(node) ((node)->right)
-#define DOWN(node) ((node)->down)
-#define DATA(node) ((node)->data)
-#define HASHNEXT(node) ((node)->hashnext)
-#define HASHVAL(node) ((node)->hashval)
-#define COLOR(node) ((node)->color)
-#define NAMELEN(node) ((node)->namelen)
-#define OLDNAMELEN(node) ((node)->oldnamelen)
-#define OFFSETLEN(node) ((node)->offsetlen)
-#define ATTRS(node) ((node)->attributes)
-#define IS_ROOT(node) ISC_TF((node)->is_root == 1)
-#define FINDCALLBACK(node) ISC_TF((node)->find_callback == 1)
-
-/*%
- * Structure elements from the rbtdb.c, not
- * used as part of the rbt.c algorithms.
- */
-#define DIRTY(node) ((node)->dirty)
-#define WILD(node) ((node)->wild)
-#define LOCKNUM(node) ((node)->locknum)
-
-/*%
- * The variable length stuff stored after the node has the following
- * structure.
- *
- * <name_data>{1..255}<oldoffsetlen>{1}<offsets>{1..128}
- *
- * <name_data> contains the name of the node when it was created.
- * <oldoffsetlen> contains the length of <offsets> when the node was created.
- * <offsets> contains the offets into name for each label when the node was
- * created.
- */
-
-#define NAME(node) ((unsigned char *)((node) + 1))
-#define OFFSETS(node) (NAME(node) + OLDNAMELEN(node) + 1)
-#define OLDOFFSETLEN(node) (OFFSETS(node)[-1])
-
-#define NODE_SIZE(node) (sizeof(*node) + \
- OLDNAMELEN(node) + OLDOFFSETLEN(node) + 1)
-
-/*%
- * Color management.
- */
-#define IS_RED(node) ((node) != NULL && (node)->color == RED)
-#define IS_BLACK(node) ((node) == NULL || (node)->color == BLACK)
-#define MAKE_RED(node) ((node)->color = RED)
-#define MAKE_BLACK(node) ((node)->color = BLACK)
-
-/*%
- * Chain management.
- *
- * The "ancestors" member of chains were removed, with their job now
- * being wholly handled by parent pointers (which didn't exist, because
- * of memory concerns, when chains were first implemented).
- */
-#define ADD_LEVEL(chain, node) \
- (chain)->levels[(chain)->level_count++] = (node)
-
-/*%
- * The following macros directly access normally private name variables.
- * These macros are used to avoid a lot of function calls in the critical
- * path of the tree traversal code.
- */
-
-#define NODENAME(node, name) \
-do { \
- (name)->length = NAMELEN(node); \
- (name)->labels = OFFSETLEN(node); \
- (name)->ndata = NAME(node); \
- (name)->offsets = OFFSETS(node); \
- (name)->attributes = ATTRS(node); \
- (name)->attributes |= DNS_NAMEATTR_READONLY; \
-} while (0)
-
-#ifdef DNS_RBT_USEHASH
-static isc_result_t
-inithash(dns_rbt_t *rbt);
-#endif
-
-#ifdef DEBUG
-#define inline
-/*
- * A little something to help out in GDB.
- */
-dns_name_t Name(dns_rbtnode_t *node);
-dns_name_t
-Name(dns_rbtnode_t *node) {
- dns_name_t name;
-
- dns_name_init(&name, NULL);
- if (node != NULL)
- NODENAME(node, &name);
-
- return (name);
-}
-
-static void dns_rbt_printnodename(dns_rbtnode_t *node);
-#endif
-
-static inline dns_rbtnode_t *
-find_up(dns_rbtnode_t *node) {
- dns_rbtnode_t *root;
-
- /*
- * Return the node in the level above the argument node that points
- * to the level the argument node is in. If the argument node is in
- * the top level, the return value is NULL.
- */
- for (root = node; ! IS_ROOT(root); root = PARENT(root))
- ; /* Nothing. */
-
- return (PARENT(root));
-}
-
-/*
- * Forward declarations.
- */
-static isc_result_t
-create_node(isc_mem_t *mctx, dns_name_t *name, dns_rbtnode_t **nodep);
-
-#ifdef DNS_RBT_USEHASH
-static inline void
-hash_node(dns_rbt_t *rbt, dns_rbtnode_t *node, dns_name_t *name);
-static inline void
-unhash_node(dns_rbt_t *rbt, dns_rbtnode_t *node);
-#else
-#define hash_node(rbt, node, name) (ISC_R_SUCCESS)
-#define unhash_node(rbt, node)
-#endif
-
-static inline void
-rotate_left(dns_rbtnode_t *node, dns_rbtnode_t **rootp);
-static inline void
-rotate_right(dns_rbtnode_t *node, dns_rbtnode_t **rootp);
-
-static void
-dns_rbt_addonlevel(dns_rbtnode_t *node, dns_rbtnode_t *current, int order,
- dns_rbtnode_t **rootp);
-
-static void
-dns_rbt_deletefromlevel(dns_rbtnode_t *delete, dns_rbtnode_t **rootp);
-
-static isc_result_t
-dns_rbt_deletetree(dns_rbt_t *rbt, dns_rbtnode_t *node);
-
-static void
-dns_rbt_deletetreeflat(dns_rbt_t *rbt, unsigned int quantum,
- dns_rbtnode_t **nodep);
-
-/*
- * Initialize a red/black tree of trees.
- */
-isc_result_t
-dns_rbt_create(isc_mem_t *mctx, void (*deleter)(void *, void *),
- void *deleter_arg, dns_rbt_t **rbtp)
-{
-#ifdef DNS_RBT_USEHASH
- isc_result_t result;
-#endif
- dns_rbt_t *rbt;
-
-
- REQUIRE(mctx != NULL);
- REQUIRE(rbtp != NULL && *rbtp == NULL);
- REQUIRE(deleter == NULL ? deleter_arg == NULL : 1);
-
- rbt = (dns_rbt_t *)isc_mem_get(mctx, sizeof(*rbt));
- if (rbt == NULL)
- return (ISC_R_NOMEMORY);
-
- rbt->mctx = NULL;
- isc_mem_attach(mctx, &rbt->mctx);
- rbt->data_deleter = deleter;
- rbt->deleter_arg = deleter_arg;
- rbt->root = NULL;
- rbt->nodecount = 0;
- rbt->hashtable = NULL;
- rbt->hashsize = 0;
-
-#ifdef DNS_RBT_USEHASH
- result = inithash(rbt);
- if (result != ISC_R_SUCCESS) {
- isc_mem_putanddetach(&rbt->mctx, rbt, sizeof(*rbt));
- return (result);
- }
-#endif
-
- rbt->magic = RBT_MAGIC;
-
- *rbtp = rbt;
-
- return (ISC_R_SUCCESS);
-}
-
-/*
- * Deallocate a red/black tree of trees.
- */
-void
-dns_rbt_destroy(dns_rbt_t **rbtp) {
- RUNTIME_CHECK(dns_rbt_destroy2(rbtp, 0) == ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_rbt_destroy2(dns_rbt_t **rbtp, unsigned int quantum) {
- dns_rbt_t *rbt;
-
- REQUIRE(rbtp != NULL && VALID_RBT(*rbtp));
-
- rbt = *rbtp;
-
- dns_rbt_deletetreeflat(rbt, quantum, &rbt->root);
- if (rbt->root != NULL)
- return (ISC_R_QUOTA);
-
- INSIST(rbt->nodecount == 0);
-
- if (rbt->hashtable != NULL)
- isc_mem_put(rbt->mctx, rbt->hashtable,
- rbt->hashsize * sizeof(dns_rbtnode_t *));
-
- rbt->magic = 0;
-
- isc_mem_putanddetach(&rbt->mctx, rbt, sizeof(*rbt));
- *rbtp = NULL;
- return (ISC_R_SUCCESS);
-}
-
-unsigned int
-dns_rbt_nodecount(dns_rbt_t *rbt) {
- REQUIRE(VALID_RBT(rbt));
- return (rbt->nodecount);
-}
-
-static inline isc_result_t
-chain_name(dns_rbtnodechain_t *chain, dns_name_t *name,
- isc_boolean_t include_chain_end)
-{
- dns_name_t nodename;
- isc_result_t result = ISC_R_SUCCESS;
- int i;
-
- dns_name_init(&nodename, NULL);
-
- if (include_chain_end && chain->end != NULL) {
- NODENAME(chain->end, &nodename);
- result = dns_name_copy(&nodename, name, NULL);
- if (result != ISC_R_SUCCESS)
- return (result);
- } else
- dns_name_reset(name);
-
- for (i = (int)chain->level_count - 1; i >= 0; i--) {
- NODENAME(chain->levels[i], &nodename);
- result = dns_name_concatenate(name, &nodename, name, NULL);
-
- if (result != ISC_R_SUCCESS)
- return (result);
- }
- return (result);
-}
-
-static inline isc_result_t
-move_chain_to_last(dns_rbtnodechain_t *chain, dns_rbtnode_t *node) {
- do {
- /*
- * Go as far right and then down as much as possible,
- * as long as the rightmost node has a down pointer.
- */
- while (RIGHT(node) != NULL)
- node = RIGHT(node);
-
- if (DOWN(node) == NULL)
- break;
-
- ADD_LEVEL(chain, node);
- node = DOWN(node);
- } while (1);
-
- chain->end = node;
-
- return (ISC_R_SUCCESS);
-}
-
-/*
- * Add 'name' to tree, initializing its data pointer with 'data'.
- */
-
-isc_result_t
-dns_rbt_addnode(dns_rbt_t *rbt, dns_name_t *name, dns_rbtnode_t **nodep) {
- /*
- * Does this thing have too many variables or what?
- */
- dns_rbtnode_t **root, *parent, *child, *current, *new_current;
- dns_name_t *add_name, *new_name, current_name, *prefix, *suffix;
- dns_fixedname_t fixedcopy, fixedprefix, fixedsuffix, fnewname;
- dns_offsets_t current_offsets;
- dns_namereln_t compared;
- isc_result_t result = ISC_R_SUCCESS;
- dns_rbtnodechain_t chain;
- unsigned int common_labels;
- unsigned int nlabels, hlabels;
- int order;
-
- REQUIRE(VALID_RBT(rbt));
- REQUIRE(dns_name_isabsolute(name));
- REQUIRE(nodep != NULL && *nodep == NULL);
-
- /*
- * Create a copy of the name so the original name structure is
- * not modified.
- */
- dns_fixedname_init(&fixedcopy);
- add_name = dns_fixedname_name(&fixedcopy);
- dns_name_clone(name, add_name);
-
- if (rbt->root == NULL) {
- result = create_node(rbt->mctx, add_name, &new_current);
- if (result == ISC_R_SUCCESS) {
- rbt->nodecount++;
- new_current->is_root = 1;
- rbt->root = new_current;
- *nodep = new_current;
- hash_node(rbt, new_current, name);
- }
- return (result);
- }
-
- dns_rbtnodechain_init(&chain, rbt->mctx);
-
- dns_fixedname_init(&fixedprefix);
- dns_fixedname_init(&fixedsuffix);
- prefix = dns_fixedname_name(&fixedprefix);
- suffix = dns_fixedname_name(&fixedsuffix);
-
- root = &rbt->root;
- INSIST(IS_ROOT(*root));
- parent = NULL;
- current = NULL;
- child = *root;
- dns_name_init(&current_name, current_offsets);
- dns_fixedname_init(&fnewname);
- new_name = dns_fixedname_name(&fnewname);
- nlabels = dns_name_countlabels(name);
- hlabels = 0;
-
- do {
- current = child;
-
- NODENAME(current, &current_name);
- compared = dns_name_fullcompare(add_name, &current_name,
- &order, &common_labels);
-
- if (compared == dns_namereln_equal) {
- *nodep = current;
- result = ISC_R_EXISTS;
- break;
-
- }
-
- if (compared == dns_namereln_none) {
-
- if (order < 0) {
- parent = current;
- child = LEFT(current);
-
- } else if (order > 0) {
- parent = current;
- child = RIGHT(current);
-
- }
-
- } else {
- /*
- * This name has some suffix in common with the
- * name at the current node. If the name at
- * the current node is shorter, that means the
- * new name should be in a subtree. If the
- * name at the current node is longer, that means
- * the down pointer to this tree should point
- * to a new tree that has the common suffix, and
- * the non-common parts of these two names should
- * start a new tree.
- */
- hlabels += common_labels;
- if (compared == dns_namereln_subdomain) {
- /*
- * All of the existing labels are in common,
- * so the new name is in a subtree.
- * Whack off the common labels for the
- * not-in-common part to be searched for
- * in the next level.
- */
- dns_name_split(add_name, common_labels,
- add_name, NULL);
-
- /*
- * Follow the down pointer (possibly NULL).
- */
- root = &DOWN(current);
-
- INSIST(*root == NULL ||
- (IS_ROOT(*root) &&
- PARENT(*root) == current));
-
- parent = NULL;
- child = DOWN(current);
- ADD_LEVEL(&chain, current);
-
- } else {
- /*
- * The number of labels in common is fewer
- * than the number of labels at the current
- * node, so the current node must be adjusted
- * to have just the common suffix, and a down
- * pointer made to a new tree.
- */
-
- INSIST(compared == dns_namereln_commonancestor
- || compared == dns_namereln_contains);
-
- /*
- * Ensure the number of levels in the tree
- * does not exceed the number of logical
- * levels allowed by DNSSEC.
- *
- * XXXDCL need a better error result?
- *
- * XXXDCL Since chain ancestors were removed,
- * no longer used by dns_rbt_addonlevel(),
- * this is the only real use of chains in the
- * function. It could be done instead with
- * a simple integer variable, but I am pressed
- * for time.
- */
- if (chain.level_count ==
- (sizeof(chain.levels) /
- sizeof(*chain.levels))) {
- result = ISC_R_NOSPACE;
- break;
- }
-
- /*
- * Split the name into two parts, a prefix
- * which is the not-in-common parts of the
- * two names and a suffix that is the common
- * parts of them.
- */
- dns_name_split(&current_name, common_labels,
- prefix, suffix);
- result = create_node(rbt->mctx, suffix,
- &new_current);
-
- if (result != ISC_R_SUCCESS)
- break;
-
- /*
- * Reproduce the tree attributes of the
- * current node.
- */
- new_current->is_root = current->is_root;
- 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);
- COLOR(new_current) = COLOR(current);
-
- /*
- * Fix pointers that were to the current node.
- */
- if (parent != NULL) {
- if (LEFT(parent) == current)
- LEFT(parent) = new_current;
- else
- RIGHT(parent) = new_current;
- }
- if (LEFT(new_current) != NULL)
- PARENT(LEFT(new_current)) =
- new_current;
- if (RIGHT(new_current) != NULL)
- PARENT(RIGHT(new_current)) =
- new_current;
- if (*root == current)
- *root = new_current;
-
- NAMELEN(current) = prefix->length;
- OFFSETLEN(current) = prefix->labels;
-
- /*
- * Set up the new root of the next level.
- * By definition it will not be the top
- * level tree, so clear DNS_NAMEATTR_ABSOLUTE.
- */
- current->is_root = 1;
- PARENT(current) = new_current;
- DOWN(new_current) = current;
- root = &DOWN(new_current);
-
- ADD_LEVEL(&chain, new_current);
-
- LEFT(current) = NULL;
- RIGHT(current) = NULL;
-
- MAKE_BLACK(current);
- ATTRS(current) &= ~DNS_NAMEATTR_ABSOLUTE;
-
- rbt->nodecount++;
- dns_name_getlabelsequence(name,
- nlabels - hlabels,
- hlabels, new_name);
- hash_node(rbt, new_current, new_name);
-
- if (common_labels ==
- dns_name_countlabels(add_name)) {
- /*
- * The name has been added by pushing
- * the not-in-common parts down to
- * a new level.
- */
- *nodep = new_current;
- return (ISC_R_SUCCESS);
-
- } else {
- /*
- * The current node has no data,
- * because it is just a placeholder.
- * Its data pointer is already NULL
- * from create_node()), so there's
- * nothing more to do to it.
- */
-
- /*
- * The not-in-common parts of the new
- * name will be inserted into the new
- * level following this loop (unless
- * result != ISC_R_SUCCESS, which
- * is tested after the loop ends).
- */
- dns_name_split(add_name, common_labels,
- add_name, NULL);
-
- break;
- }
-
- }
-
- }
-
- } while (child != NULL);
-
- if (result == ISC_R_SUCCESS)
- result = create_node(rbt->mctx, add_name, &new_current);
-
- if (result == ISC_R_SUCCESS) {
- dns_rbt_addonlevel(new_current, current, order, root);
- rbt->nodecount++;
- *nodep = new_current;
- hash_node(rbt, new_current, name);
- }
-
- return (result);
-}
-
-/*
- * Add a name to the tree of trees, associating it with some data.
- */
-isc_result_t
-dns_rbt_addname(dns_rbt_t *rbt, dns_name_t *name, void *data) {
- isc_result_t result;
- dns_rbtnode_t *node;
-
- REQUIRE(VALID_RBT(rbt));
- REQUIRE(dns_name_isabsolute(name));
-
- node = NULL;
-
- result = dns_rbt_addnode(rbt, name, &node);
-
- /*
- * dns_rbt_addnode will report the node exists even when
- * it does not have data associated with it, but the
- * dns_rbt_*name functions all behave depending on whether
- * there is data associated with a node.
- */
- if (result == ISC_R_SUCCESS ||
- (result == ISC_R_EXISTS && DATA(node) == NULL)) {
- DATA(node) = data;
- result = ISC_R_SUCCESS;
- }
-
- return (result);
-}
-
-/*
- * Find the node for "name" in the tree of trees.
- */
-isc_result_t
-dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name, dns_name_t *foundname,
- dns_rbtnode_t **node, dns_rbtnodechain_t *chain,
- unsigned int options, dns_rbtfindcallback_t callback,
- void *callback_arg)
-{
- dns_rbtnode_t *current, *last_compared, *current_root;
- dns_rbtnodechain_t localchain;
- dns_name_t *search_name, current_name, *callback_name;
- dns_fixedname_t fixedcallbackname, fixedsearchname;
- dns_namereln_t compared;
- isc_result_t result, saved_result;
- unsigned int common_labels;
- unsigned int hlabels = 0;
- int order;
-
- REQUIRE(VALID_RBT(rbt));
- REQUIRE(dns_name_isabsolute(name));
- REQUIRE(node != NULL && *node == NULL);
- REQUIRE((options & (DNS_RBTFIND_NOEXACT | DNS_RBTFIND_NOPREDECESSOR))
- != (DNS_RBTFIND_NOEXACT | DNS_RBTFIND_NOPREDECESSOR));
-
- /*
- * If there is a chain it needs to appear to be in a sane state,
- * otherwise a chain is still needed to generate foundname and
- * callback_name.
- */
- if (chain == NULL) {
- options |= DNS_RBTFIND_NOPREDECESSOR;
- chain = &localchain;
- dns_rbtnodechain_init(chain, rbt->mctx);
- } else
- dns_rbtnodechain_reset(chain);
-
- if (rbt->root == NULL)
- return (ISC_R_NOTFOUND);
- else {
- /*
- * Appease GCC about variables it incorrectly thinks are
- * possibly used uninitialized.
- */
- compared = dns_namereln_none;
- last_compared = NULL;
- order = 0;
- }
-
- dns_fixedname_init(&fixedcallbackname);
- callback_name = dns_fixedname_name(&fixedcallbackname);
-
- /*
- * search_name is the name segment being sought in each tree level.
- * By using a fixedname, the search_name will definitely have offsets
- * for use by any splitting.
- * By using dns_name_clone, no name data should be copied thanks to
- * the lack of bitstring labels.
- */
- dns_fixedname_init(&fixedsearchname);
- search_name = dns_fixedname_name(&fixedsearchname);
- dns_name_clone(name, search_name);
-
- dns_name_init(&current_name, NULL);
-
- saved_result = ISC_R_SUCCESS;
- current = rbt->root;
- current_root = rbt->root;
-
- while (current != NULL) {
- NODENAME(current, &current_name);
- compared = dns_name_fullcompare(search_name, &current_name,
- &order, &common_labels);
- last_compared = current;
-
- if (compared == dns_namereln_equal)
- break;
-
- if (compared == dns_namereln_none) {
-#ifdef DNS_RBT_USEHASH
- dns_name_t hash_name;
- dns_rbtnode_t *hnode;
- dns_rbtnode_t *up_current;
- unsigned int nlabels;
- unsigned int tlabels = 1;
- unsigned int hash;
-
- /*
- * If there is no hash table, hashing can't be done.
- */
- if (rbt->hashtable == NULL)
- goto nohash;
-
- /*
- * The case of current != current_root, that
- * means a left or right pointer was followed,
- * only happens when the algorithm fell through to
- * the traditional binary search because of a
- * bitstring label. Since we dropped the bitstring
- * support, this should not happen.
- */
- INSIST(current == current_root);
-
- nlabels = dns_name_countlabels(search_name);
-
- /*
- * current_root is the root of the current level, so
- * it's parent is the same as it's "up" pointer.
- */
- up_current = PARENT(current_root);
- dns_name_init(&hash_name, NULL);
-
- hashagain:
- /*
- * Hash includes tail.
- */
- dns_name_getlabelsequence(name,
- nlabels - tlabels,
- hlabels + tlabels,
- &hash_name);
- hash = dns_name_fullhash(&hash_name, ISC_FALSE);
- dns_name_getlabelsequence(search_name,
- nlabels - tlabels,
- tlabels, &hash_name);
-
- for (hnode = rbt->hashtable[hash % rbt->hashsize];
- hnode != NULL;
- hnode = hnode->hashnext)
- {
- dns_name_t hnode_name;
-
- if (hash != HASHVAL(hnode))
- continue;
- if (find_up(hnode) != up_current)
- continue;
- dns_name_init(&hnode_name, NULL);
- NODENAME(hnode, &hnode_name);
- if (dns_name_equal(&hnode_name, &hash_name))
- break;
- }
-
- if (hnode != NULL) {
- current = hnode;
- /*
- * This is an optimization. If hashing found
- * the right node, the next call to
- * dns_name_fullcompare() would obviously
- * return _equal or _subdomain. Determine
- * which of those would be the case by
- * checking if the full name was hashed. Then
- * make it look like dns_name_fullcompare
- * was called and jump to the right place.
- */
- if (tlabels == nlabels) {
- compared = dns_namereln_equal;
- break;
- } else {
- common_labels = tlabels;
- compared = dns_namereln_subdomain;
- goto subdomain;
- }
- }
-
- if (tlabels++ < nlabels)
- goto hashagain;
-
- /*
- * All of the labels have been tried against the hash
- * table. Since we dropped the support of bitstring
- * labels, the name isn't in the table.
- */
- current = NULL;
- continue;
-
- nohash:
-#endif /* DNS_RBT_USEHASH */
- /*
- * Standard binary search tree movement.
- */
- if (order < 0)
- current = LEFT(current);
- else
- current = RIGHT(current);
-
- } else {
- /*
- * The names have some common suffix labels.
- *
- * If the number in common are equal in length to
- * the current node's name length, then follow the
- * down pointer and search in the new tree.
- */
- if (compared == dns_namereln_subdomain) {
- subdomain:
- /*
- * Whack off the current node's common parts
- * for the name to search in the next level.
- */
- dns_name_split(search_name, common_labels,
- search_name, NULL);
- hlabels += common_labels;
- /*
- * This might be the closest enclosing name.
- */
- if (DATA(current) != NULL ||
- (options & DNS_RBTFIND_EMPTYDATA) != 0)
- *node = current;
-
- /*
- * Point the chain to the next level. This
- * needs to be done before 'current' is pointed
- * there because the callback in the next
- * block of code needs the current 'current',
- * but in the event the callback requests that
- * the search be stopped then the
- * DNS_R_PARTIALMATCH code at the end of this
- * function needs the chain pointed to the
- * next level.
- */
- ADD_LEVEL(chain, current);
-
- /*
- * The caller may want to interrupt the
- * downward search when certain special nodes
- * are traversed. If this is a special node,
- * the callback is used to learn what the
- * caller wants to do.
- */
- if (callback != NULL &&
- FINDCALLBACK(current)) {
- result = chain_name(chain,
- callback_name,
- ISC_FALSE);
- if (result != ISC_R_SUCCESS) {
- dns_rbtnodechain_reset(chain);
- return (result);
- }
-
- result = (callback)(current,
- callback_name,
- callback_arg);
- if (result != DNS_R_CONTINUE) {
- saved_result = result;
- /*
- * Treat this node as if it
- * had no down pointer.
- */
- current = NULL;
- break;
- }
- }
-
- /*
- * Finally, head to the next tree level.
- */
- current = DOWN(current);
- current_root = current;
-
- } else {
- /*
- * Though there are labels in common, the
- * entire name at this node is not common
- * with the search name so the search
- * name does not exist in the tree.
- */
- INSIST(compared == dns_namereln_commonancestor
- || compared == dns_namereln_contains);
-
- current = NULL;
- }
- }
- }
-
- /*
- * If current is not NULL, NOEXACT is not disallowing exact matches,
- * and either the node has data or an empty node is ok, return
- * ISC_R_SUCCESS to indicate an exact match.
- */
- if (current != NULL && (options & DNS_RBTFIND_NOEXACT) == 0 &&
- (DATA(current) != NULL ||
- (options & DNS_RBTFIND_EMPTYDATA) != 0)) {
- /*
- * Found an exact match.
- */
- chain->end = current;
- chain->level_matches = chain->level_count;
-
- if (foundname != NULL)
- result = chain_name(chain, foundname, ISC_TRUE);
- else
- result = ISC_R_SUCCESS;
-
- if (result == ISC_R_SUCCESS) {
- *node = current;
- result = saved_result;
- } else
- *node = NULL;
- } else {
- /*
- * Did not find an exact match (or did not want one).
- */
- if (*node != NULL) {
- /*
- * ... but found a partially matching superdomain.
- * Unwind the chain to the partial match node
- * to set level_matches to the level above the node,
- * and then to derive the name.
- *
- * chain->level_count is guaranteed to be at least 1
- * here because by definition of finding a superdomain,
- * the chain is pointed to at least the first subtree.
- */
- chain->level_matches = chain->level_count - 1;
-
- while (chain->levels[chain->level_matches] != *node) {
- INSIST(chain->level_matches > 0);
- chain->level_matches--;
- }
-
- if (foundname != NULL) {
- unsigned int saved_count = chain->level_count;
-
- chain->level_count = chain->level_matches + 1;
-
- result = chain_name(chain, foundname,
- ISC_FALSE);
-
- chain->level_count = saved_count;
- } else
- result = ISC_R_SUCCESS;
-
- if (result == ISC_R_SUCCESS)
- result = DNS_R_PARTIALMATCH;
-
- } else
- result = ISC_R_NOTFOUND;
-
- if (current != NULL) {
- /*
- * There was an exact match but either
- * DNS_RBTFIND_NOEXACT was set, or
- * DNS_RBTFIND_EMPTYDATA was set and the node had no
- * data. A policy decision was made to set the
- * chain to the exact match, but this is subject
- * to change if it becomes apparent that something
- * else would be more useful. It is important that
- * this case is handled here, because the predecessor
- * setting code below assumes the match was not exact.
- */
- INSIST(((options & DNS_RBTFIND_NOEXACT) != 0) ||
- ((options & DNS_RBTFIND_EMPTYDATA) == 0 &&
- DATA(current) == NULL));
- chain->end = current;
-
- } else if ((options & DNS_RBTFIND_NOPREDECESSOR) != 0) {
- /*
- * Ensure the chain points nowhere.
- */
- chain->end = NULL;
-
- } else {
- /*
- * Since there was no exact match, the chain argument
- * needs to be pointed at the DNSSEC predecessor of
- * the search name.
- */
- if (compared == dns_namereln_subdomain) {
- /*
- * Attempted to follow a down pointer that was
- * NULL, which means the searched for name was
- * a subdomain of a terminal name in the tree.
- * Since there are no existing subdomains to
- * order against, the terminal name is the
- * predecessor.
- */
- INSIST(chain->level_count > 0);
- INSIST(chain->level_matches <
- chain->level_count);
- chain->end =
- chain->levels[--chain->level_count];
-
- } else {
- isc_result_t result2;
-
- /*
- * Point current to the node that stopped
- * the search.
- *
- * With the hashing modification that has been
- * added to the algorithm, the stop node of a
- * standard binary search is not known. So it
- * has to be found. There is probably a more
- * clever way of doing this.
- *
- * The assignment of current to NULL when
- * the relationship is *not* dns_namereln_none,
- * even though it later gets set to the same
- * last_compared anyway, is simply to not push
- * the while loop in one more level of
- * indentation.
- */
- if (compared == dns_namereln_none)
- current = last_compared;
- else
- current = NULL;
-
- while (current != NULL) {
- NODENAME(current, &current_name);
- compared = dns_name_fullcompare(
- search_name,
- &current_name,
- &order,
- &common_labels);
- POST(compared);
-
- last_compared = current;
-
- /*
- * Standard binary search movement.
- */
- if (order < 0)
- current = LEFT(current);
- else
- current = RIGHT(current);
-
- }
-
- current = last_compared;
-
- /*
- * Reached a point within a level tree that
- * positively indicates the name is not
- * present, but the stop node could be either
- * less than the desired name (order > 0) or
- * greater than the desired name (order < 0).
- *
- * If the stop node is less, it is not
- * necessarily the predecessor. If the stop
- * node has a down pointer, then the real
- * predecessor is at the end of a level below
- * (not necessarily the next level).
- * Move down levels until the rightmost node
- * does not have a down pointer.
- *
- * When the stop node is greater, it is
- * the successor. All the logic for finding
- * the predecessor is handily encapsulated
- * in dns_rbtnodechain_prev. In the event
- * that the search name is less than anything
- * else in the tree, the chain is reset.
- * XXX DCL What is the best way for the caller
- * to know that the search name has
- * no predecessor?
- */
-
-
- if (order > 0) {
- if (DOWN(current) != NULL) {
- ADD_LEVEL(chain, current);
-
- result2 =
- move_chain_to_last(chain,
- DOWN(current));
-
- if (result2 != ISC_R_SUCCESS)
- result = result2;
- } else
- /*
- * Ah, the pure and simple
- * case. The stop node is the
- * predecessor.
- */
- chain->end = current;
-
- } else {
- INSIST(order < 0);
-
- chain->end = current;
-
- result2 = dns_rbtnodechain_prev(chain,
- NULL,
- NULL);
- if (result2 == ISC_R_SUCCESS ||
- result2 == DNS_R_NEWORIGIN)
- ; /* Nothing. */
- else if (result2 == ISC_R_NOMORE)
- /*
- * There is no predecessor.
- */
- dns_rbtnodechain_reset(chain);
- else
- result = result2;
- }
-
- }
- }
- }
-
- ENSURE(*node == NULL || DNS_RBTNODE_VALID(*node));
-
- return (result);
-}
-
-/*
- * Get the data pointer associated with 'name'.
- */
-isc_result_t
-dns_rbt_findname(dns_rbt_t *rbt, dns_name_t *name, unsigned int options,
- dns_name_t *foundname, void **data) {
- dns_rbtnode_t *node = NULL;
- isc_result_t result;
-
- REQUIRE(data != NULL && *data == NULL);
-
- result = dns_rbt_findnode(rbt, name, foundname, &node, NULL,
- options, NULL, NULL);
-
- if (node != NULL &&
- (DATA(node) != NULL || (options & DNS_RBTFIND_EMPTYDATA) != 0))
- *data = DATA(node);
- else
- result = ISC_R_NOTFOUND;
-
- return (result);
-}
-
-/*
- * Delete a name from the tree of trees.
- */
-isc_result_t
-dns_rbt_deletename(dns_rbt_t *rbt, dns_name_t *name, isc_boolean_t recurse) {
- dns_rbtnode_t *node = NULL;
- isc_result_t result;
-
- REQUIRE(VALID_RBT(rbt));
- REQUIRE(dns_name_isabsolute(name));
-
- /*
- * First, find the node.
- *
- * When searching, the name might not have an exact match:
- * consider a.b.a.com, b.b.a.com and c.b.a.com as the only
- * elements of a tree, which would make layer 1 a single
- * node tree of "b.a.com" and layer 2 a three node tree of
- * a, b, and c. Deleting a.com would find only a partial depth
- * match in the first layer. Should it be a requirement that
- * that the name to be deleted have data? For now, it is.
- *
- * ->dirty, ->locknum and ->references are ignored; they are
- * solely the province of rbtdb.c.
- */
- result = dns_rbt_findnode(rbt, name, NULL, &node, NULL,
- DNS_RBTFIND_NOOPTIONS, NULL, NULL);
-
- if (result == ISC_R_SUCCESS) {
- if (DATA(node) != NULL)
- result = dns_rbt_deletenode(rbt, node, recurse);
- else
- result = ISC_R_NOTFOUND;
-
- } else if (result == DNS_R_PARTIALMATCH)
- result = ISC_R_NOTFOUND;
-
- return (result);
-}
-
-/*
- * Remove a node from the tree of trees.
- *
- * NOTE WELL: deletion is *not* symmetric with addition; that is, reversing
- * a sequence of additions to be deletions will not generally get the
- * tree back to the state it started in. For example, if the addition
- * of "b.c" caused the node "a.b.c" to be split, pushing "a" to its own level,
- * then the subsequent deletion of "b.c" will not cause "a" to be pulled up,
- * restoring "a.b.c". The RBT *used* to do this kind of rejoining, but it
- * turned out to be a bad idea because it could corrupt an active nodechain
- * that had "b.c" as one of its levels -- and the RBT has no idea what
- * nodechains are in use by callers, so it can't even *try* to helpfully
- * fix them up (which would probably be doomed to failure anyway).
- *
- * Similarly, it is possible to leave the tree in a state where a supposedly
- * deleted node still exists. The first case of this is obvious; take
- * the tree which has "b.c" on one level, pointing to "a". Now deleted "b.c".
- * It was just established in the previous paragraph why we can't pull "a"
- * back up to its parent level. But what happens when "a" then gets deleted?
- * "b.c" is left hanging around without data or children. This condition
- * is actually pretty easy to detect, but ... should it really be removed?
- * Is a chain pointing to it? An iterator? Who knows! (Note that the
- * references structure member cannot be looked at because it is private to
- * rbtdb.) This is ugly and makes me unhappy, but after hours of trying to
- * make it more aesthetically proper and getting nowhere, this is the way it
- * is going to stay until such time as it proves to be a *real* problem.
- *
- * Finally, for reference, note that the original routine that did node
- * joining was called join_nodes(). It has been excised, living now only
- * in the CVS history, but comments have been left behind that point to it just
- * in case someone wants to muck with this some more.
- *
- * The one positive aspect of all of this is that joining used to have a
- * case where it might fail. Without trying to join, now this function always
- * succeeds. It still returns isc_result_t, though, so the API wouldn't change.
- */
-isc_result_t
-dns_rbt_deletenode(dns_rbt_t *rbt, dns_rbtnode_t *node, isc_boolean_t recurse)
-{
- dns_rbtnode_t *parent;
-
- REQUIRE(VALID_RBT(rbt));
- REQUIRE(DNS_RBTNODE_VALID(node));
-
- if (DOWN(node) != NULL) {
- if (recurse)
- RUNTIME_CHECK(dns_rbt_deletetree(rbt, DOWN(node))
- == ISC_R_SUCCESS);
- else {
- if (DATA(node) != NULL && rbt->data_deleter != NULL)
- rbt->data_deleter(DATA(node), rbt->deleter_arg);
- DATA(node) = NULL;
-
- /*
- * Since there is at least one node below this one and
- * no recursion was requested, the deletion is
- * complete. The down node from this node might be all
- * by itself on a single level, so join_nodes() could
- * be used to collapse the tree (with all the caveats
- * of the comment at the start of this function).
- */
- return (ISC_R_SUCCESS);
- }
- }
-
- /*
- * Note the node that points to the level of the node that is being
- * deleted. If the deleted node is the top level, parent will be set
- * to NULL.
- */
- parent = find_up(node);
-
- /*
- * This node now has no down pointer (either because it didn't
- * have one to start, or because it was recursively removed).
- * So now the node needs to be removed from this level.
- */
- dns_rbt_deletefromlevel(node, parent == NULL ? &rbt->root :
- &DOWN(parent));
-
- if (DATA(node) != NULL && rbt->data_deleter != NULL)
- rbt->data_deleter(DATA(node), rbt->deleter_arg);
-
- unhash_node(rbt, node);
-#if DNS_RBT_USEMAGIC
- node->magic = 0;
-#endif
- dns_rbtnode_refdestroy(node);
- isc_mem_put(rbt->mctx, node, NODE_SIZE(node));
- rbt->nodecount--;
-
- /*
- * There are now two special cases that can exist that would
- * not have existed if the tree had been created using only
- * the names that now exist in it. (This is all related to
- * join_nodes() as described in this function's introductory comment.)
- * Both cases exist when the deleted node's parent (the node
- * that pointed to the deleted node's level) is not null but
- * it has no data: parent != NULL && DATA(parent) == NULL.
- *
- * The first case is that the deleted node was the last on its level:
- * DOWN(parent) == NULL. This case can only exist if the parent was
- * previously deleted -- and so now, apparently, the parent should go
- * away. That can't be done though because there might be external
- * references to it, such as through a nodechain.
- *
- * The other case also involves a parent with no data, but with the
- * deleted node being the next-to-last node instead of the last:
- * LEFT(DOWN(parent)) == NULL && RIGHT(DOWN(parent)) == NULL.
- * Presumably now the remaining node on the level should be joined
- * with the parent, but it's already been described why that can't be
- * done.
- */
-
- /*
- * This function never fails.
- */
- return (ISC_R_SUCCESS);
-}
-
-void
-dns_rbt_namefromnode(dns_rbtnode_t *node, dns_name_t *name) {
-
- REQUIRE(DNS_RBTNODE_VALID(node));
- REQUIRE(name != NULL);
- REQUIRE(name->offsets == NULL);
-
- NODENAME(node, name);
-}
-
-isc_result_t
-dns_rbt_fullnamefromnode(dns_rbtnode_t *node, dns_name_t *name) {
- dns_name_t current;
- isc_result_t result;
-
- REQUIRE(DNS_RBTNODE_VALID(node));
- REQUIRE(name != NULL);
- REQUIRE(name->buffer != NULL);
-
- dns_name_init(&current, NULL);
- dns_name_reset(name);
-
- do {
- INSIST(node != NULL);
-
- NODENAME(node, &current);
-
- result = dns_name_concatenate(name, &current, name, NULL);
- if (result != ISC_R_SUCCESS)
- break;
-
- node = find_up(node);
- } while (! dns_name_isabsolute(name));
-
- return (result);
-}
-
-char *
-dns_rbt_formatnodename(dns_rbtnode_t *node, char *printname, unsigned int size)
-{
- dns_fixedname_t fixedname;
- dns_name_t *name;
- isc_result_t result;
-
- REQUIRE(DNS_RBTNODE_VALID(node));
- REQUIRE(printname != NULL);
-
- dns_fixedname_init(&fixedname);
- name = dns_fixedname_name(&fixedname);
- result = dns_rbt_fullnamefromnode(node, name);
- if (result == ISC_R_SUCCESS)
- dns_name_format(name, printname, size);
- else
- snprintf(printname, size, "<error building name: %s>",
- dns_result_totext(result));
-
- return (printname);
-}
-
-static isc_result_t
-create_node(isc_mem_t *mctx, dns_name_t *name, dns_rbtnode_t **nodep) {
- dns_rbtnode_t *node;
- isc_region_t region;
- unsigned int labels;
-
- REQUIRE(name->offsets != NULL);
-
- dns_name_toregion(name, &region);
- labels = dns_name_countlabels(name);
- ENSURE(labels > 0);
-
- /*
- * Allocate space for the node structure, the name, and the offsets.
- */
- node = (dns_rbtnode_t *)isc_mem_get(mctx, sizeof(*node) +
- region.length + labels + 1);
-
- if (node == NULL)
- return (ISC_R_NOMEMORY);
-
- node->is_root = 0;
- PARENT(node) = NULL;
- RIGHT(node) = NULL;
- LEFT(node) = NULL;
- DOWN(node) = NULL;
- DATA(node) = NULL;
-#ifdef DNS_RBT_USEHASH
- HASHNEXT(node) = NULL;
- HASHVAL(node) = 0;
-#endif
-
- ISC_LINK_INIT(node, deadlink);
-
- LOCKNUM(node) = 0;
- WILD(node) = 0;
- DIRTY(node) = 0;
- dns_rbtnode_refinit(node, 0);
- node->find_callback = 0;
- node->nsec = DNS_RBT_NSEC_NORMAL;
-
- MAKE_BLACK(node);
-
- /*
- * The following is stored to make reconstructing a name from the
- * stored value in the node easy: the length of the name, the number
- * of labels, whether the name is absolute or not, the name itself,
- * and the name's offsets table.
- *
- * XXX RTH
- * The offsets table could be made smaller by eliminating the
- * first offset, which is always 0. This requires changes to
- * lib/dns/name.c.
- *
- * Note: OLDOFFSETLEN *must* be assigned *after* OLDNAMELEN is assigned
- * as it uses OLDNAMELEN.
- */
- OLDNAMELEN(node) = NAMELEN(node) = region.length;
- OLDOFFSETLEN(node) = OFFSETLEN(node) = labels;
- ATTRS(node) = name->attributes;
-
- memcpy(NAME(node), region.base, region.length);
- memcpy(OFFSETS(node), name->offsets, labels);
-
-#if DNS_RBT_USEMAGIC
- node->magic = DNS_RBTNODE_MAGIC;
-#endif
- *nodep = node;
-
- return (ISC_R_SUCCESS);
-}
-
-#ifdef DNS_RBT_USEHASH
-static inline void
-hash_add_node(dns_rbt_t *rbt, dns_rbtnode_t *node, dns_name_t *name) {
- unsigned int hash;
-
- HASHVAL(node) = dns_name_fullhash(name, ISC_FALSE);
-
- hash = HASHVAL(node) % rbt->hashsize;
- HASHNEXT(node) = rbt->hashtable[hash];
-
- rbt->hashtable[hash] = node;
-}
-
-static isc_result_t
-inithash(dns_rbt_t *rbt) {
- unsigned int bytes;
-
- rbt->hashsize = RBT_HASH_SIZE;
- bytes = rbt->hashsize * sizeof(dns_rbtnode_t *);
- rbt->hashtable = isc_mem_get(rbt->mctx, bytes);
-
- if (rbt->hashtable == NULL)
- return (ISC_R_NOMEMORY);
-
- memset(rbt->hashtable, 0, bytes);
-
- return (ISC_R_SUCCESS);
-}
-
-static void
-rehash(dns_rbt_t *rbt) {
- unsigned int oldsize;
- dns_rbtnode_t **oldtable;
- dns_rbtnode_t *node;
- unsigned int hash;
- unsigned int i;
-
- oldsize = rbt->hashsize;
- oldtable = rbt->hashtable;
- rbt->hashsize = rbt->hashsize * 2 + 1;
- rbt->hashtable = isc_mem_get(rbt->mctx,
- rbt->hashsize * sizeof(dns_rbtnode_t *));
- if (rbt->hashtable == NULL) {
- rbt->hashtable = oldtable;
- rbt->hashsize = oldsize;
- return;
- }
-
- INSIST(rbt->hashsize > 0);
-
- for (i = 0; i < rbt->hashsize; i++)
- rbt->hashtable[i] = NULL;
-
- for (i = 0; i < oldsize; i++) {
- node = oldtable[i];
- while (node != NULL) {
- hash = HASHVAL(node) % rbt->hashsize;
- oldtable[i] = HASHNEXT(node);
- HASHNEXT(node) = rbt->hashtable[hash];
- rbt->hashtable[hash] = node;
- node = oldtable[i];
- }
- }
-
- isc_mem_put(rbt->mctx, oldtable, oldsize * sizeof(dns_rbtnode_t *));
-}
-
-static inline void
-hash_node(dns_rbt_t *rbt, dns_rbtnode_t *node, dns_name_t *name) {
-
- REQUIRE(DNS_RBTNODE_VALID(node));
-
- if (rbt->nodecount >= (rbt->hashsize *3))
- rehash(rbt);
-
- hash_add_node(rbt, node, name);
-}
-
-static inline void
-unhash_node(dns_rbt_t *rbt, dns_rbtnode_t *node) {
- unsigned int bucket;
- dns_rbtnode_t *bucket_node;
-
- REQUIRE(DNS_RBTNODE_VALID(node));
-
- if (rbt->hashtable != NULL) {
- bucket = HASHVAL(node) % rbt->hashsize;
- bucket_node = rbt->hashtable[bucket];
-
- if (bucket_node == node)
- rbt->hashtable[bucket] = HASHNEXT(node);
- else {
- while (HASHNEXT(bucket_node) != node) {
- INSIST(HASHNEXT(bucket_node) != NULL);
- bucket_node = HASHNEXT(bucket_node);
- }
- HASHNEXT(bucket_node) = HASHNEXT(node);
- }
- }
-}
-#endif /* DNS_RBT_USEHASH */
-
-static inline void
-rotate_left(dns_rbtnode_t *node, dns_rbtnode_t **rootp) {
- dns_rbtnode_t *child;
-
- REQUIRE(DNS_RBTNODE_VALID(node));
- REQUIRE(rootp != NULL);
-
- child = RIGHT(node);
- INSIST(child != NULL);
-
- RIGHT(node) = LEFT(child);
- if (LEFT(child) != NULL)
- PARENT(LEFT(child)) = node;
- LEFT(child) = node;
-
- if (child != NULL)
- PARENT(child) = PARENT(node);
-
- if (IS_ROOT(node)) {
- *rootp = child;
- child->is_root = 1;
- node->is_root = 0;
-
- } else {
- if (LEFT(PARENT(node)) == node)
- LEFT(PARENT(node)) = child;
- else
- RIGHT(PARENT(node)) = child;
- }
-
- PARENT(node) = child;
-}
-
-static inline void
-rotate_right(dns_rbtnode_t *node, dns_rbtnode_t **rootp) {
- dns_rbtnode_t *child;
-
- REQUIRE(DNS_RBTNODE_VALID(node));
- REQUIRE(rootp != NULL);
-
- child = LEFT(node);
- INSIST(child != NULL);
-
- LEFT(node) = RIGHT(child);
- if (RIGHT(child) != NULL)
- PARENT(RIGHT(child)) = node;
- RIGHT(child) = node;
-
- if (child != NULL)
- PARENT(child) = PARENT(node);
-
- if (IS_ROOT(node)) {
- *rootp = child;
- child->is_root = 1;
- node->is_root = 0;
-
- } else {
- if (LEFT(PARENT(node)) == node)
- LEFT(PARENT(node)) = child;
- else
- RIGHT(PARENT(node)) = child;
- }
-
- PARENT(node) = child;
-}
-
-/*
- * This is the real workhorse of the insertion code, because it does the
- * true red/black tree on a single level.
- */
-static void
-dns_rbt_addonlevel(dns_rbtnode_t *node, dns_rbtnode_t *current, int order,
- dns_rbtnode_t **rootp)
-{
- dns_rbtnode_t *child, *root, *parent, *grandparent;
- dns_name_t add_name, current_name;
- dns_offsets_t add_offsets, current_offsets;
-
- REQUIRE(rootp != NULL);
- REQUIRE(DNS_RBTNODE_VALID(node) && LEFT(node) == NULL &&
- RIGHT(node) == NULL);
- REQUIRE(current != NULL);
-
- root = *rootp;
- if (root == NULL) {
- /*
- * First node of a level.
- */
- MAKE_BLACK(node);
- node->is_root = 1;
- PARENT(node) = current;
- *rootp = node;
- return;
- }
-
- child = root;
- POST(child);
-
- dns_name_init(&add_name, add_offsets);
- NODENAME(node, &add_name);
-
- dns_name_init(&current_name, current_offsets);
- NODENAME(current, &current_name);
-
- if (order < 0) {
- INSIST(LEFT(current) == NULL);
- LEFT(current) = node;
- } else {
- INSIST(RIGHT(current) == NULL);
- RIGHT(current) = node;
- }
-
- INSIST(PARENT(node) == NULL);
- PARENT(node) = current;
-
- MAKE_RED(node);
-
- while (node != root && IS_RED(PARENT(node))) {
- /*
- * XXXDCL could do away with separate parent and grandparent
- * variables. They are vestiges of the days before parent
- * pointers. However, they make the code a little clearer.
- */
-
- parent = PARENT(node);
- grandparent = PARENT(parent);
-
- if (parent == LEFT(grandparent)) {
- child = RIGHT(grandparent);
- if (child != NULL && IS_RED(child)) {
- MAKE_BLACK(parent);
- MAKE_BLACK(child);
- MAKE_RED(grandparent);
- node = grandparent;
- } else {
- if (node == RIGHT(parent)) {
- rotate_left(parent, &root);
- node = parent;
- parent = PARENT(node);
- grandparent = PARENT(parent);
- }
- MAKE_BLACK(parent);
- MAKE_RED(grandparent);
- rotate_right(grandparent, &root);
- }
- } else {
- child = LEFT(grandparent);
- if (child != NULL && IS_RED(child)) {
- MAKE_BLACK(parent);
- MAKE_BLACK(child);
- MAKE_RED(grandparent);
- node = grandparent;
- } else {
- if (node == LEFT(parent)) {
- rotate_right(parent, &root);
- node = parent;
- parent = PARENT(node);
- grandparent = PARENT(parent);
- }
- MAKE_BLACK(parent);
- MAKE_RED(grandparent);
- rotate_left(grandparent, &root);
- }
- }
- }
-
- MAKE_BLACK(root);
- ENSURE(IS_ROOT(root));
- *rootp = root;
-
- return;
-}
-
-/*
- * This is the real workhorse of the deletion code, because it does the
- * true red/black tree on a single level.
- */
-static void
-dns_rbt_deletefromlevel(dns_rbtnode_t *delete, dns_rbtnode_t **rootp) {
- dns_rbtnode_t *child, *sibling, *parent;
- dns_rbtnode_t *successor;
-
- REQUIRE(delete != NULL);
-
- /*
- * Verify that the parent history is (apparently) correct.
- */
- INSIST((IS_ROOT(delete) && *rootp == delete) ||
- (! IS_ROOT(delete) &&
- (LEFT(PARENT(delete)) == delete ||
- RIGHT(PARENT(delete)) == delete)));
-
- child = NULL;
-
- if (LEFT(delete) == NULL) {
- if (RIGHT(delete) == NULL) {
- if (IS_ROOT(delete)) {
- /*
- * This is the only item in the tree.
- */
- *rootp = NULL;
- return;
- }
- } else
- /*
- * This node has one child, on the right.
- */
- child = RIGHT(delete);
-
- } else if (RIGHT(delete) == NULL)
- /*
- * This node has one child, on the left.
- */
- child = LEFT(delete);
- else {
- dns_rbtnode_t holder, *tmp = &holder;
-
- /*
- * This node has two children, so it cannot be directly
- * deleted. Find its immediate in-order successor and
- * move it to this location, then do the deletion at the
- * old site of the successor.
- */
- successor = RIGHT(delete);
- while (LEFT(successor) != NULL)
- successor = LEFT(successor);
-
- /*
- * The successor cannot possibly have a left child;
- * if there is any child, it is on the right.
- */
- if (RIGHT(successor) != NULL)
- child = RIGHT(successor);
-
- /*
- * Swap the two nodes; it would be simpler to just replace
- * the value being deleted with that of the successor,
- * but this rigamarole is done so the caller has complete
- * control over the pointers (and memory allocation) of
- * all of nodes. If just the key value were removed from
- * the tree, the pointer to the node would be unchanged.
- */
-
- /*
- * First, put the successor in the tree location of the
- * node to be deleted. Save its existing tree pointer
- * information, which will be needed when linking up
- * delete to the successor's old location.
- */
- memcpy(tmp, successor, sizeof(dns_rbtnode_t));
-
- if (IS_ROOT(delete)) {
- *rootp = successor;
- successor->is_root = ISC_TRUE;
- delete->is_root = ISC_FALSE;
-
- } else
- if (LEFT(PARENT(delete)) == delete)
- LEFT(PARENT(delete)) = successor;
- else
- RIGHT(PARENT(delete)) = successor;
-
- PARENT(successor) = PARENT(delete);
- LEFT(successor) = LEFT(delete);
- RIGHT(successor) = RIGHT(delete);
- COLOR(successor) = COLOR(delete);
-
- if (LEFT(successor) != NULL)
- PARENT(LEFT(successor)) = successor;
- if (RIGHT(successor) != successor)
- PARENT(RIGHT(successor)) = successor;
-
- /*
- * Now relink the node to be deleted into the
- * successor's previous tree location. PARENT(tmp)
- * is the successor's original parent.
- */
- INSIST(! IS_ROOT(delete));
-
- if (PARENT(tmp) == delete) {
- /*
- * Node being deleted was successor's parent.
- */
- RIGHT(successor) = delete;
- PARENT(delete) = successor;
-
- } else {
- LEFT(PARENT(tmp)) = delete;
- PARENT(delete) = PARENT(tmp);
- }
-
- /*
- * Original location of successor node has no left.
- */
- LEFT(delete) = NULL;
- RIGHT(delete) = RIGHT(tmp);
- COLOR(delete) = COLOR(tmp);
- }
-
- /*
- * Remove the node by removing the links from its parent.
- */
- if (! IS_ROOT(delete)) {
- if (LEFT(PARENT(delete)) == delete)
- LEFT(PARENT(delete)) = child;
- else
- RIGHT(PARENT(delete)) = child;
-
- if (child != NULL)
- PARENT(child) = PARENT(delete);
-
- } else {
- /*
- * This is the root being deleted, and at this point
- * it is known to have just one child.
- */
- *rootp = child;
- child->is_root = 1;
- PARENT(child) = PARENT(delete);
- }
-
- /*
- * Fix color violations.
- */
- if (IS_BLACK(delete)) {
- parent = PARENT(delete);
-
- while (child != *rootp && IS_BLACK(child)) {
- INSIST(child == NULL || ! IS_ROOT(child));
-
- if (LEFT(parent) == child) {
- sibling = RIGHT(parent);
-
- if (IS_RED(sibling)) {
- MAKE_BLACK(sibling);
- MAKE_RED(parent);
- rotate_left(parent, rootp);
- sibling = RIGHT(parent);
- }
-
- INSIST(sibling != NULL);
-
- if (IS_BLACK(LEFT(sibling)) &&
- IS_BLACK(RIGHT(sibling))) {
- MAKE_RED(sibling);
- child = parent;
-
- } else {
-
- if (IS_BLACK(RIGHT(sibling))) {
- MAKE_BLACK(LEFT(sibling));
- MAKE_RED(sibling);
- rotate_right(sibling, rootp);
- sibling = RIGHT(parent);
- }
-
- COLOR(sibling) = COLOR(parent);
- MAKE_BLACK(parent);
- INSIST(RIGHT(sibling) != NULL);
- MAKE_BLACK(RIGHT(sibling));
- rotate_left(parent, rootp);
- child = *rootp;
- }
-
- } else {
- /*
- * Child is parent's right child.
- * Everything is done the same as above,
- * except mirrored.
- */
- sibling = LEFT(parent);
-
- if (IS_RED(sibling)) {
- MAKE_BLACK(sibling);
- MAKE_RED(parent);
- rotate_right(parent, rootp);
- sibling = LEFT(parent);
- }
-
- INSIST(sibling != NULL);
-
- if (IS_BLACK(LEFT(sibling)) &&
- IS_BLACK(RIGHT(sibling))) {
- MAKE_RED(sibling);
- child = parent;
-
- } else {
- if (IS_BLACK(LEFT(sibling))) {
- MAKE_BLACK(RIGHT(sibling));
- MAKE_RED(sibling);
- rotate_left(sibling, rootp);
- sibling = LEFT(parent);
- }
-
- COLOR(sibling) = COLOR(parent);
- MAKE_BLACK(parent);
- INSIST(LEFT(sibling) != NULL);
- MAKE_BLACK(LEFT(sibling));
- rotate_right(parent, rootp);
- child = *rootp;
- }
- }
-
- parent = PARENT(child);
- }
-
- if (IS_RED(child))
- MAKE_BLACK(child);
- }
-}
-
-/*
- * This should only be used on the root of a tree, because no color fixup
- * is done at all.
- *
- * NOTE: No root pointer maintenance is done, because the function is only
- * used for two cases:
- * + deleting everything DOWN from a node that is itself being deleted, and
- * + deleting the entire tree of trees from dns_rbt_destroy.
- * In each case, the root pointer is no longer relevant, so there
- * is no need for a root parameter to this function.
- *
- * If the function is ever intended to be used to delete something where
- * a pointer needs to be told that this tree no longer exists,
- * this function would need to adjusted accordingly.
- */
-static isc_result_t
-dns_rbt_deletetree(dns_rbt_t *rbt, dns_rbtnode_t *node) {
- isc_result_t result = ISC_R_SUCCESS;
- REQUIRE(VALID_RBT(rbt));
-
- if (node == NULL)
- return (result);
-
- if (LEFT(node) != NULL) {
- result = dns_rbt_deletetree(rbt, LEFT(node));
- if (result != ISC_R_SUCCESS)
- goto done;
- LEFT(node) = NULL;
- }
- if (RIGHT(node) != NULL) {
- result = dns_rbt_deletetree(rbt, RIGHT(node));
- if (result != ISC_R_SUCCESS)
- goto done;
- RIGHT(node) = NULL;
- }
- if (DOWN(node) != NULL) {
- result = dns_rbt_deletetree(rbt, DOWN(node));
- if (result != ISC_R_SUCCESS)
- goto done;
- DOWN(node) = NULL;
- }
- done:
- if (result != ISC_R_SUCCESS)
- return (result);
-
- if (DATA(node) != NULL && rbt->data_deleter != NULL)
- rbt->data_deleter(DATA(node), rbt->deleter_arg);
-
- unhash_node(rbt, node);
-#if DNS_RBT_USEMAGIC
- node->magic = 0;
-#endif
-
- isc_mem_put(rbt->mctx, node, NODE_SIZE(node));
- rbt->nodecount--;
- return (result);
-}
-
-static void
-dns_rbt_deletetreeflat(dns_rbt_t *rbt, unsigned int quantum,
- dns_rbtnode_t **nodep)
-{
- dns_rbtnode_t *parent;
- dns_rbtnode_t *node = *nodep;
- REQUIRE(VALID_RBT(rbt));
-
- again:
- if (node == NULL) {
- *nodep = NULL;
- return;
- }
-
- traverse:
- if (LEFT(node) != NULL) {
- node = LEFT(node);
- goto traverse;
- }
- if (DOWN(node) != NULL) {
- node = DOWN(node);
- goto traverse;
- }
-
- if (DATA(node) != NULL && rbt->data_deleter != NULL)
- rbt->data_deleter(DATA(node), rbt->deleter_arg);
-
- /*
- * Note: we don't call unhash_node() here as we are destroying
- * the complete rbt tree.
- */
-#if DNS_RBT_USEMAGIC
- node->magic = 0;
-#endif
- parent = PARENT(node);
- if (RIGHT(node) != NULL)
- PARENT(RIGHT(node)) = parent;
- if (parent != NULL) {
- if (LEFT(parent) == node)
- LEFT(parent) = RIGHT(node);
- else if (DOWN(parent) == node)
- DOWN(parent) = RIGHT(node);
- } else
- parent = RIGHT(node);
-
- isc_mem_put(rbt->mctx, node, NODE_SIZE(node));
- rbt->nodecount--;
- node = parent;
- if (quantum != 0 && --quantum == 0) {
- *nodep = node;
- return;
- }
- goto again;
-}
-
-static void
-dns_rbt_indent(int depth) {
- int i;
-
- for (i = 0; i < depth; i++)
- putchar('\t');
-}
-
-static void
-dns_rbt_printnodename(dns_rbtnode_t *node) {
- isc_region_t r;
- dns_name_t name;
- char buffer[DNS_NAME_FORMATSIZE];
- dns_offsets_t offsets;
-
- r.length = NAMELEN(node);
- r.base = NAME(node);
-
- dns_name_init(&name, offsets);
- dns_name_fromregion(&name, &r);
-
- dns_name_format(&name, buffer, sizeof(buffer));
-
- printf("%s", buffer);
-}
-
-static void
-dns_rbt_printtree(dns_rbtnode_t *root, dns_rbtnode_t *parent, int depth) {
- dns_rbt_indent(depth);
-
- if (root != NULL) {
- dns_rbt_printnodename(root);
- printf(" (%s", IS_RED(root) ? "RED" : "black");
- if (parent) {
- printf(" from ");
- dns_rbt_printnodename(parent);
- }
-
- if ((! IS_ROOT(root) && PARENT(root) != parent) ||
- ( IS_ROOT(root) && depth > 0 &&
- DOWN(PARENT(root)) != root)) {
-
- printf(" (BAD parent pointer! -> ");
- if (PARENT(root) != NULL)
- dns_rbt_printnodename(PARENT(root));
- else
- printf("NULL");
- printf(")");
- }
-
- printf(")\n");
-
-
- depth++;
-
- if (DOWN(root)) {
- dns_rbt_indent(depth);
- printf("++ BEG down from ");
- dns_rbt_printnodename(root);
- printf("\n");
- dns_rbt_printtree(DOWN(root), NULL, depth);
- dns_rbt_indent(depth);
- printf("-- END down from ");
- dns_rbt_printnodename(root);
- printf("\n");
- }
-
- if (IS_RED(root) && IS_RED(LEFT(root)))
- printf("** Red/Red color violation on left\n");
- dns_rbt_printtree(LEFT(root), root, depth);
-
- if (IS_RED(root) && IS_RED(RIGHT(root)))
- printf("** Red/Red color violation on right\n");
- dns_rbt_printtree(RIGHT(root), root, depth);
-
- } else
- printf("NULL\n");
-}
-
-void
-dns_rbt_printall(dns_rbt_t *rbt) {
- REQUIRE(VALID_RBT(rbt));
-
- dns_rbt_printtree(rbt->root, NULL, 0);
-}
-
-/*
- * Chain Functions
- */
-
-void
-dns_rbtnodechain_init(dns_rbtnodechain_t *chain, isc_mem_t *mctx) {
- /*
- * Initialize 'chain'.
- */
-
- REQUIRE(chain != NULL);
-
- chain->mctx = mctx;
- chain->end = NULL;
- chain->level_count = 0;
- chain->level_matches = 0;
- memset(chain->levels, 0, sizeof(chain->levels));
-
- chain->magic = CHAIN_MAGIC;
-}
-
-isc_result_t
-dns_rbtnodechain_current(dns_rbtnodechain_t *chain, dns_name_t *name,
- dns_name_t *origin, dns_rbtnode_t **node)
-{
- isc_result_t result = ISC_R_SUCCESS;
-
- REQUIRE(VALID_CHAIN(chain));
-
- if (node != NULL)
- *node = chain->end;
-
- if (chain->end == NULL)
- return (ISC_R_NOTFOUND);
-
- if (name != NULL) {
- NODENAME(chain->end, name);
-
- if (chain->level_count == 0) {
- /*
- * Names in the top level tree are all absolute.
- * Always make 'name' relative.
- */
- INSIST(dns_name_isabsolute(name));
-
- /*
- * This is cheaper than dns_name_getlabelsequence().
- */
- name->labels--;
- name->length--;
- name->attributes &= ~DNS_NAMEATTR_ABSOLUTE;
- }
- }
-
- if (origin != NULL) {
- if (chain->level_count > 0)
- result = chain_name(chain, origin, ISC_FALSE);
- else
- result = dns_name_copy(dns_rootname, origin, NULL);
- }
-
- return (result);
-}
-
-isc_result_t
-dns_rbtnodechain_prev(dns_rbtnodechain_t *chain, dns_name_t *name,
- dns_name_t *origin)
-{
- dns_rbtnode_t *current, *previous, *predecessor;
- isc_result_t result = ISC_R_SUCCESS;
- isc_boolean_t new_origin = ISC_FALSE;
-
- REQUIRE(VALID_CHAIN(chain) && chain->end != NULL);
-
- predecessor = NULL;
-
- current = chain->end;
-
- if (LEFT(current) != NULL) {
- /*
- * Moving left one then right as far as possible is the
- * previous node, at least for this level.
- */
- current = LEFT(current);
-
- while (RIGHT(current) != NULL)
- current = RIGHT(current);
-
- predecessor = current;
-
- } else {
- /*
- * No left links, so move toward the root. If at any point on
- * the way there the link from parent to child is a right
- * link, then the parent is the previous node, at least
- * for this level.
- */
- while (! IS_ROOT(current)) {
- previous = current;
- current = PARENT(current);
-
- if (RIGHT(current) == previous) {
- predecessor = current;
- break;
- }
- }
- }
-
- if (predecessor != NULL) {
- /*
- * Found a predecessor node in this level. It might not
- * really be the predecessor, however.
- */
- if (DOWN(predecessor) != NULL) {
- /*
- * The predecessor is really down at least one level.
- * Go down and as far right as possible, and repeat
- * as long as the rightmost node has a down pointer.
- */
- do {
- /*
- * XXX DCL Need to do something about origins
- * here. See whether to go down, and if so
- * whether it is truly what Bob calls a
- * new origin.
- */
- ADD_LEVEL(chain, predecessor);
- predecessor = DOWN(predecessor);
-
- /* XXX DCL duplicated from above; clever
- * way to unduplicate? */
-
- while (RIGHT(predecessor) != NULL)
- predecessor = RIGHT(predecessor);
- } while (DOWN(predecessor) != NULL);
-
- /* XXX DCL probably needs work on the concept */
- if (origin != NULL)
- new_origin = ISC_TRUE;
- }
-
- } else if (chain->level_count > 0) {
- /*
- * Dang, didn't find a predecessor in this level.
- * Got to the root of this level without having traversed
- * any right links. Ascend the tree one level; the
- * node that points to this tree is the predecessor.
- */
- INSIST(chain->level_count > 0 && IS_ROOT(current));
- predecessor = chain->levels[--chain->level_count];
-
- /* XXX DCL probably needs work on the concept */
- /*
- * Don't declare an origin change when the new origin is "."
- * at the top level tree, because "." is declared as the origin
- * for the second level tree.
- */
- if (origin != NULL &&
- (chain->level_count > 0 || OFFSETLEN(predecessor) > 1))
- new_origin = ISC_TRUE;
- }
-
- if (predecessor != NULL) {
- chain->end = predecessor;
-
- if (new_origin) {
- result = dns_rbtnodechain_current(chain, name, origin,
- NULL);
- if (result == ISC_R_SUCCESS)
- result = DNS_R_NEWORIGIN;
-
- } else
- result = dns_rbtnodechain_current(chain, name, NULL,
- NULL);
-
- } else
- result = ISC_R_NOMORE;
-
- return (result);
-}
-
-isc_result_t
-dns_rbtnodechain_down(dns_rbtnodechain_t *chain, dns_name_t *name,
- dns_name_t *origin)
-{
- dns_rbtnode_t *current, *successor;
- isc_result_t result = ISC_R_SUCCESS;
- isc_boolean_t new_origin = ISC_FALSE;
-
- REQUIRE(VALID_CHAIN(chain) && chain->end != NULL);
-
- successor = NULL;
-
- current = chain->end;
-
- if (DOWN(current) != NULL) {
- /*
- * Don't declare an origin change when the new origin is "."
- * at the second level tree, because "." is already declared
- * as the origin for the top level tree.
- */
- if (chain->level_count > 0 ||
- OFFSETLEN(current) > 1)
- new_origin = ISC_TRUE;
-
- ADD_LEVEL(chain, current);
- current = DOWN(current);
-
- while (LEFT(current) != NULL)
- current = LEFT(current);
-
- successor = current;
- }
-
- if (successor != NULL) {
- chain->end = successor;
-
- /*
- * It is not necessary to use dns_rbtnodechain_current like
- * the other functions because this function will never
- * find a node in the topmost level. This is because the
- * root level will never be more than one name, and everything
- * in the megatree is a successor to that node, down at
- * the second level or below.
- */
-
- if (name != NULL)
- NODENAME(chain->end, name);
-
- if (new_origin) {
- if (origin != NULL)
- result = chain_name(chain, origin, ISC_FALSE);
-
- if (result == ISC_R_SUCCESS)
- result = DNS_R_NEWORIGIN;
-
- } else
- result = ISC_R_SUCCESS;
-
- } else
- result = ISC_R_NOMORE;
-
- return (result);
-}
-
-isc_result_t
-dns_rbtnodechain_nextflat(dns_rbtnodechain_t *chain, dns_name_t *name) {
- dns_rbtnode_t *current, *previous, *successor;
- isc_result_t result = ISC_R_SUCCESS;
-
- REQUIRE(VALID_CHAIN(chain) && chain->end != NULL);
-
- successor = NULL;
-
- current = chain->end;
-
- if (RIGHT(current) == NULL) {
- while (! IS_ROOT(current)) {
- previous = current;
- current = PARENT(current);
-
- if (LEFT(current) == previous) {
- successor = current;
- break;
- }
- }
- } else {
- current = RIGHT(current);
-
- while (LEFT(current) != NULL)
- current = LEFT(current);
-
- successor = current;
- }
-
- if (successor != NULL) {
- chain->end = successor;
-
- if (name != NULL)
- NODENAME(chain->end, name);
-
- result = ISC_R_SUCCESS;
- } else
- result = ISC_R_NOMORE;
-
- return (result);
-}
-
-isc_result_t
-dns_rbtnodechain_next(dns_rbtnodechain_t *chain, dns_name_t *name,
- dns_name_t *origin)
-{
- dns_rbtnode_t *current, *previous, *successor;
- isc_result_t result = ISC_R_SUCCESS;
- isc_boolean_t new_origin = ISC_FALSE;
-
- REQUIRE(VALID_CHAIN(chain) && chain->end != NULL);
-
- successor = NULL;
-
- current = chain->end;
-
- /*
- * If there is a level below this node, the next node is the leftmost
- * node of the next level.
- */
- if (DOWN(current) != NULL) {
- /*
- * Don't declare an origin change when the new origin is "."
- * at the second level tree, because "." is already declared
- * as the origin for the top level tree.
- */
- if (chain->level_count > 0 ||
- OFFSETLEN(current) > 1)
- new_origin = ISC_TRUE;
-
- ADD_LEVEL(chain, current);
- current = DOWN(current);
-
- while (LEFT(current) != NULL)
- current = LEFT(current);
-
- successor = current;
-
- } else if (RIGHT(current) == NULL) {
- /*
- * The successor is up, either in this level or a previous one.
- * Head back toward the root of the tree, looking for any path
- * that was via a left link; the successor is the node that has
- * that left link. In the event the root of the level is
- * reached without having traversed any left links, ascend one
- * level and look for either a right link off the point of
- * ascent, or search for a left link upward again, repeating
- * ascends until either case is true.
- */
- do {
- while (! IS_ROOT(current)) {
- previous = current;
- current = PARENT(current);
-
- if (LEFT(current) == previous) {
- successor = current;
- break;
- }
- }
-
- if (successor == NULL) {
- /*
- * Reached the root without having traversed
- * any left pointers, so this level is done.
- */
- if (chain->level_count == 0)
- break;
-
- current = chain->levels[--chain->level_count];
- new_origin = ISC_TRUE;
-
- if (RIGHT(current) != NULL)
- break;
- }
- } while (successor == NULL);
- }
-
- if (successor == NULL && RIGHT(current) != NULL) {
- current = RIGHT(current);
-
- while (LEFT(current) != NULL)
- current = LEFT(current);
-
- successor = current;
- }
-
- if (successor != NULL) {
- chain->end = successor;
-
- /*
- * It is not necessary to use dns_rbtnodechain_current like
- * the other functions because this function will never
- * find a node in the topmost level. This is because the
- * root level will never be more than one name, and everything
- * in the megatree is a successor to that node, down at
- * the second level or below.
- */
-
- if (name != NULL)
- NODENAME(chain->end, name);
-
- if (new_origin) {
- if (origin != NULL)
- result = chain_name(chain, origin, ISC_FALSE);
-
- if (result == ISC_R_SUCCESS)
- result = DNS_R_NEWORIGIN;
-
- } else
- result = ISC_R_SUCCESS;
-
- } else
- result = ISC_R_NOMORE;
-
- return (result);
-}
-
-isc_result_t
-dns_rbtnodechain_first(dns_rbtnodechain_t *chain, dns_rbt_t *rbt,
- dns_name_t *name, dns_name_t *origin)
-
-{
- isc_result_t result;
-
- REQUIRE(VALID_RBT(rbt));
- REQUIRE(VALID_CHAIN(chain));
-
- dns_rbtnodechain_reset(chain);
-
- chain->end = rbt->root;
-
- result = dns_rbtnodechain_current(chain, name, origin, NULL);
-
- if (result == ISC_R_SUCCESS)
- result = DNS_R_NEWORIGIN;
-
- return (result);
-}
-
-isc_result_t
-dns_rbtnodechain_last(dns_rbtnodechain_t *chain, dns_rbt_t *rbt,
- dns_name_t *name, dns_name_t *origin)
-
-{
- isc_result_t result;
-
- REQUIRE(VALID_RBT(rbt));
- REQUIRE(VALID_CHAIN(chain));
-
- dns_rbtnodechain_reset(chain);
-
- result = move_chain_to_last(chain, rbt->root);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- result = dns_rbtnodechain_current(chain, name, origin, NULL);
-
- if (result == ISC_R_SUCCESS)
- result = DNS_R_NEWORIGIN;
-
- return (result);
-}
-
-
-void
-dns_rbtnodechain_reset(dns_rbtnodechain_t *chain) {
- /*
- * Free any dynamic storage associated with 'chain', and then
- * reinitialize 'chain'.
- */
-
- REQUIRE(VALID_CHAIN(chain));
-
- chain->end = NULL;
- chain->level_count = 0;
- chain->level_matches = 0;
-}
-
-void
-dns_rbtnodechain_invalidate(dns_rbtnodechain_t *chain) {
- /*
- * Free any dynamic storage associated with 'chain', and then
- * invalidate 'chain'.
- */
-
- dns_rbtnodechain_reset(chain);
-
- chain->magic = 0;
-}
diff --git a/contrib/bind9/lib/dns/rbtdb.c b/contrib/bind9/lib/dns/rbtdb.c
deleted file mode 100644
index bff52b87ef9d..000000000000
--- a/contrib/bind9/lib/dns/rbtdb.c
+++ /dev/null
@@ -1,9343 +0,0 @@
-/*
- * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/*! \file */
-
-/*
- * Principal Author: Bob Halley
- */
-
-#include <config.h>
-
-/* #define inline */
-
-#include <isc/event.h>
-#include <isc/heap.h>
-#include <isc/mem.h>
-#include <isc/mutex.h>
-#include <isc/platform.h>
-#include <isc/print.h>
-#include <isc/random.h>
-#include <isc/refcount.h>
-#include <isc/rwlock.h>
-#include <isc/serial.h>
-#include <isc/string.h>
-#include <isc/task.h>
-#include <isc/time.h>
-#include <isc/util.h>
-
-#include <dns/acache.h>
-#include <dns/db.h>
-#include <dns/dbiterator.h>
-#include <dns/events.h>
-#include <dns/fixedname.h>
-#include <dns/lib.h>
-#include <dns/log.h>
-#include <dns/masterdump.h>
-#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>
-#include <dns/rdataslab.h>
-#include <dns/rdatastruct.h>
-#include <dns/result.h>
-#include <dns/stats.h>
-#include <dns/view.h>
-#include <dns/zone.h>
-#include <dns/zonekey.h>
-
-#ifdef DNS_RBTDB_VERSION64
-#include "rbtdb64.h"
-#else
-#include "rbtdb.h"
-#endif
-
-#ifdef DNS_RBTDB_VERSION64
-#define RBTDB_MAGIC ISC_MAGIC('R', 'B', 'D', '8')
-#else
-#define RBTDB_MAGIC ISC_MAGIC('R', 'B', 'D', '4')
-#endif
-
-/*%
- * Note that "impmagic" is not the first four bytes of the struct, so
- * ISC_MAGIC_VALID cannot be used.
- */
-#define VALID_RBTDB(rbtdb) ((rbtdb) != NULL && \
- (rbtdb)->common.impmagic == RBTDB_MAGIC)
-
-#ifdef DNS_RBTDB_VERSION64
-typedef isc_uint64_t rbtdb_serial_t;
-/*%
- * Make casting easier in symbolic debuggers by using different names
- * for the 64 bit version.
- */
-#define dns_rbtdb_t dns_rbtdb64_t
-#define rdatasetheader_t rdatasetheader64_t
-#define rbtdb_version_t rbtdb_version64_t
-#else
-typedef isc_uint32_t rbtdb_serial_t;
-#endif
-
-typedef isc_uint32_t rbtdb_rdatatype_t;
-
-#define RBTDB_RDATATYPE_BASE(type) ((dns_rdatatype_t)((type) & 0xFFFF))
-#define RBTDB_RDATATYPE_EXT(type) ((dns_rdatatype_t)((type) >> 16))
-#define RBTDB_RDATATYPE_VALUE(b, e) ((rbtdb_rdatatype_t)((e) << 16) | (b))
-
-#define RBTDB_RDATATYPE_SIGNSEC \
- RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_nsec)
-#define RBTDB_RDATATYPE_SIGNSEC3 \
- RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_nsec3)
-#define RBTDB_RDATATYPE_SIGNS \
- RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_ns)
-#define RBTDB_RDATATYPE_SIGCNAME \
- RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_cname)
-#define RBTDB_RDATATYPE_SIGDNAME \
- RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_dname)
-#define RBTDB_RDATATYPE_SIGDDS \
- RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_ds)
-#define RBTDB_RDATATYPE_NCACHEANY \
- RBTDB_RDATATYPE_VALUE(0, dns_rdatatype_any)
-
-/*
- * We use rwlock for DB lock only when ISC_RWLOCK_USEATOMIC is non 0.
- * Using rwlock is effective with regard to lookup performance only when
- * it is implemented in an efficient way.
- * Otherwise, it is generally wise to stick to the simple locking since rwlock
- * would require more memory or can even make lookups slower due to its own
- * overhead (when it internally calls mutex locks).
- */
-#ifdef ISC_RWLOCK_USEATOMIC
-#define DNS_RBTDB_USERWLOCK 1
-#else
-#define DNS_RBTDB_USERWLOCK 0
-#endif
-
-#if DNS_RBTDB_USERWLOCK
-#define RBTDB_INITLOCK(l) isc_rwlock_init((l), 0, 0)
-#define RBTDB_DESTROYLOCK(l) isc_rwlock_destroy(l)
-#define RBTDB_LOCK(l, t) RWLOCK((l), (t))
-#define RBTDB_UNLOCK(l, t) RWUNLOCK((l), (t))
-#else
-#define RBTDB_INITLOCK(l) isc_mutex_init(l)
-#define RBTDB_DESTROYLOCK(l) DESTROYLOCK(l)
-#define RBTDB_LOCK(l, t) LOCK(l)
-#define RBTDB_UNLOCK(l, t) UNLOCK(l)
-#endif
-
-/*
- * Since node locking is sensitive to both performance and memory footprint,
- * we need some trick here. If we have both high-performance rwlock and
- * high performance and small-memory reference counters, we use rwlock for
- * node lock and isc_refcount for node references. In this case, we don't have
- * to protect the access to the counters by locks.
- * Otherwise, we simply use ordinary mutex lock for node locking, and use
- * simple integers as reference counters which is protected by the lock.
- * In most cases, we can simply use wrapper macros such as NODE_LOCK and
- * NODE_UNLOCK. In some other cases, however, we need to protect reference
- * counters first and then protect other parts of a node as read-only data.
- * Special additional macros, NODE_STRONGLOCK(), NODE_WEAKLOCK(), etc, are also
- * provided for these special cases. When we can use the efficient backend
- * routines, we should only protect the "other members" by NODE_WEAKLOCK(read).
- * Otherwise, we should use NODE_STRONGLOCK() to protect the entire critical
- * section including the access to the reference counter.
- * Note that we cannot use NODE_LOCK()/NODE_UNLOCK() wherever the protected
- * section is also protected by NODE_STRONGLOCK().
- */
-#if defined(ISC_RWLOCK_USEATOMIC) && defined(DNS_RBT_USEISCREFCOUNT)
-typedef isc_rwlock_t nodelock_t;
-
-#define NODE_INITLOCK(l) isc_rwlock_init((l), 0, 0)
-#define NODE_DESTROYLOCK(l) isc_rwlock_destroy(l)
-#define NODE_LOCK(l, t) RWLOCK((l), (t))
-#define NODE_UNLOCK(l, t) RWUNLOCK((l), (t))
-#define NODE_TRYUPGRADE(l) isc_rwlock_tryupgrade(l)
-
-#define NODE_STRONGLOCK(l) ((void)0)
-#define NODE_STRONGUNLOCK(l) ((void)0)
-#define NODE_WEAKLOCK(l, t) NODE_LOCK(l, t)
-#define NODE_WEAKUNLOCK(l, t) NODE_UNLOCK(l, t)
-#define NODE_WEAKDOWNGRADE(l) isc_rwlock_downgrade(l)
-#else
-typedef isc_mutex_t nodelock_t;
-
-#define NODE_INITLOCK(l) isc_mutex_init(l)
-#define NODE_DESTROYLOCK(l) DESTROYLOCK(l)
-#define NODE_LOCK(l, t) LOCK(l)
-#define NODE_UNLOCK(l, t) UNLOCK(l)
-#define NODE_TRYUPGRADE(l) ISC_R_SUCCESS
-
-#define NODE_STRONGLOCK(l) LOCK(l)
-#define NODE_STRONGUNLOCK(l) UNLOCK(l)
-#define NODE_WEAKLOCK(l, t) ((void)0)
-#define NODE_WEAKUNLOCK(l, t) ((void)0)
-#define NODE_WEAKDOWNGRADE(l) ((void)0)
-#endif
-
-/*%
- * Whether to rate-limit updating the LRU to avoid possible thread contention.
- * Our performance measurement has shown the cost is marginal, so it's defined
- * to be 0 by default either with or without threads.
- */
-#ifndef DNS_RBTDB_LIMITLRUUPDATE
-#define DNS_RBTDB_LIMITLRUUPDATE 0
-#endif
-
-/*
- * Allow clients with a virtual time of up to 5 minutes in the past to see
- * records that would have otherwise have expired.
- */
-#define RBTDB_VIRTUAL 300
-
-struct noqname {
- dns_name_t name;
- void * neg;
- void * negsig;
- dns_rdatatype_t type;
-};
-
-typedef struct acachectl acachectl_t;
-
-typedef struct rdatasetheader {
- /*%
- * Locked by the owning node's lock.
- */
- rbtdb_serial_t serial;
- dns_ttl_t rdh_ttl;
- rbtdb_rdatatype_t type;
- isc_uint16_t attributes;
- dns_trust_t trust;
- struct noqname *noqname;
- struct noqname *closest;
- /*%<
- * We don't use the LIST macros, because the LIST structure has
- * both head and tail pointers, and is doubly linked.
- */
-
- struct rdatasetheader *next;
- /*%<
- * If this is the top header for an rdataset, 'next' points
- * to the top header for the next rdataset (i.e., the next type).
- * Otherwise, it points up to the header whose down pointer points
- * at this header.
- */
-
- struct rdatasetheader *down;
- /*%<
- * Points to the header for the next older version of
- * this rdataset.
- */
-
- isc_uint32_t count;
- /*%<
- * Monotonously increased every time this rdataset is bound so that
- * it is used as the base of the starting point in DNS responses
- * when the "cyclic" rrset-order is required. Since the ordering
- * should not be so crucial, no lock is set for the counter for
- * performance reasons.
- */
-
- acachectl_t *additional_auth;
- acachectl_t *additional_glue;
-
- dns_rbtnode_t *node;
- isc_stdtime_t last_used;
- ISC_LINK(struct rdatasetheader) link;
-
- unsigned int heap_index;
- /*%<
- * Used for TTL-based cache cleaning.
- */
- isc_stdtime_t resign;
-} rdatasetheader_t;
-
-typedef ISC_LIST(rdatasetheader_t) rdatasetheaderlist_t;
-typedef ISC_LIST(dns_rbtnode_t) rbtnodelist_t;
-
-#define RDATASET_ATTR_NONEXISTENT 0x0001
-#define RDATASET_ATTR_STALE 0x0002
-#define RDATASET_ATTR_IGNORE 0x0004
-#define RDATASET_ATTR_RETAIN 0x0008
-#define RDATASET_ATTR_NXDOMAIN 0x0010
-#define RDATASET_ATTR_RESIGN 0x0020
-#define RDATASET_ATTR_STATCOUNT 0x0040
-#define RDATASET_ATTR_OPTOUT 0x0080
-#define RDATASET_ATTR_NEGATIVE 0x0100
-
-typedef struct acache_cbarg {
- dns_rdatasetadditional_t type;
- unsigned int count;
- dns_db_t *db;
- dns_dbnode_t *node;
- rdatasetheader_t *header;
-} acache_cbarg_t;
-
-struct acachectl {
- dns_acacheentry_t *entry;
- acache_cbarg_t *cbarg;
-};
-
-/*
- * XXX
- * When the cache will pre-expire data (due to memory low or other
- * situations) before the rdataset's TTL has expired, it MUST
- * respect the RETAIN bit and not expire the data until its TTL is
- * expired.
- */
-
-#undef IGNORE /* WIN32 winbase.h defines this. */
-
-#define EXISTS(header) \
- (((header)->attributes & RDATASET_ATTR_NONEXISTENT) == 0)
-#define NONEXISTENT(header) \
- (((header)->attributes & RDATASET_ATTR_NONEXISTENT) != 0)
-#define IGNORE(header) \
- (((header)->attributes & RDATASET_ATTR_IGNORE) != 0)
-#define RETAIN(header) \
- (((header)->attributes & RDATASET_ATTR_RETAIN) != 0)
-#define NXDOMAIN(header) \
- (((header)->attributes & RDATASET_ATTR_NXDOMAIN) != 0)
-#define RESIGN(header) \
- (((header)->attributes & RDATASET_ATTR_RESIGN) != 0)
-#define OPTOUT(header) \
- (((header)->attributes & RDATASET_ATTR_OPTOUT) != 0)
-#define NEGATIVE(header) \
- (((header)->attributes & RDATASET_ATTR_NEGATIVE) != 0)
-
-#define DEFAULT_NODE_LOCK_COUNT 7 /*%< Should be prime. */
-
-/*%
- * Number of buckets for cache DB entries (locks, LRU lists, TTL heaps).
- * There is a tradeoff issue about configuring this value: if this is too
- * small, it may cause heavier contention between threads; if this is too large,
- * LRU purge algorithm won't work well (entries tend to be purged prematurely).
- * The default value should work well for most environments, but this can
- * also be configurable at compilation time via the
- * DNS_RBTDB_CACHE_NODE_LOCK_COUNT variable. This value must be larger than
- * 1 due to the assumption of overmem_purge().
- */
-#ifdef DNS_RBTDB_CACHE_NODE_LOCK_COUNT
-#if DNS_RBTDB_CACHE_NODE_LOCK_COUNT <= 1
-#error "DNS_RBTDB_CACHE_NODE_LOCK_COUNT must be larger than 1"
-#else
-#define DEFAULT_CACHE_NODE_LOCK_COUNT DNS_RBTDB_CACHE_NODE_LOCK_COUNT
-#endif
-#else
-#define DEFAULT_CACHE_NODE_LOCK_COUNT 16
-#endif /* DNS_RBTDB_CACHE_NODE_LOCK_COUNT */
-
-typedef struct {
- nodelock_t lock;
- /* Protected in the refcount routines. */
- isc_refcount_t references;
- /* Locked by lock. */
- isc_boolean_t exiting;
-} rbtdb_nodelock_t;
-
-typedef struct rbtdb_changed {
- dns_rbtnode_t * node;
- isc_boolean_t dirty;
- ISC_LINK(struct rbtdb_changed) link;
-} rbtdb_changed_t;
-
-typedef ISC_LIST(rbtdb_changed_t) rbtdb_changedlist_t;
-
-typedef enum {
- dns_db_insecure,
- dns_db_partial,
- dns_db_secure
-} dns_db_secure_t;
-
-typedef struct dns_rbtdb dns_rbtdb_t;
-
-typedef struct rbtdb_version {
- /* Not locked */
- rbtdb_serial_t serial;
- dns_rbtdb_t * rbtdb;
- /*
- * Protected in the refcount routines.
- * XXXJT: should we change the lock policy based on the refcount
- * performance?
- */
- isc_refcount_t references;
- /* Locked by database lock. */
- isc_boolean_t writer;
- isc_boolean_t commit_ok;
- rbtdb_changedlist_t changed_list;
- rdatasetheaderlist_t resigned_list;
- ISC_LINK(struct rbtdb_version) link;
- dns_db_secure_t secure;
- isc_boolean_t havensec3;
- /* NSEC3 parameters */
- dns_hash_t hash;
- isc_uint8_t flags;
- isc_uint16_t iterations;
- isc_uint8_t salt_length;
- unsigned char salt[DNS_NSEC3_SALTSIZE];
-} rbtdb_version_t;
-
-typedef ISC_LIST(rbtdb_version_t) rbtdb_versionlist_t;
-
-struct dns_rbtdb {
- /* Unlocked. */
- dns_db_t common;
- /* Locks the data in this struct */
-#if DNS_RBTDB_USERWLOCK
- isc_rwlock_t lock;
-#else
- isc_mutex_t lock;
-#endif
- /* Locks the tree structure (prevents nodes appearing/disappearing) */
- isc_rwlock_t tree_lock;
- /* Locks for individual tree nodes */
- unsigned int node_lock_count;
- rbtdb_nodelock_t * node_locks;
- dns_rbtnode_t * origin_node;
- dns_stats_t * rrsetstats; /* cache DB only */
- /* Locked by lock. */
- unsigned int active;
- isc_refcount_t references;
- unsigned int attributes;
- rbtdb_serial_t current_serial;
- rbtdb_serial_t least_serial;
- rbtdb_serial_t next_serial;
- rbtdb_version_t * current_version;
- rbtdb_version_t * future_version;
- rbtdb_versionlist_t open_versions;
- isc_task_t * task;
- dns_dbnode_t *soanode;
- dns_dbnode_t *nsnode;
-
- /*
- * This is a linked list used to implement the LRU cache. There will
- * be node_lock_count linked lists here. Nodes in bucket 1 will be
- * placed on the linked list rdatasets[1].
- */
- rdatasetheaderlist_t *rdatasets;
-
- /*%
- * Temporary storage for stale cache nodes and dynamically deleted
- * nodes that await being cleaned up.
- */
- rbtnodelist_t *deadnodes;
-
- /*
- * Heaps. These are used for TTL based expiry in a cache,
- * or for zone resigning in a zone DB. hmctx is the memory
- * context to use for the heap (which differs from the main
- * database memory context in the case of a cache).
- */
- isc_mem_t * hmctx;
- isc_heap_t **heaps;
-
- /* 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;
-};
-
-#define RBTDB_ATTR_LOADED 0x01
-#define RBTDB_ATTR_LOADING 0x02
-
-/*%
- * Search Context
- */
-typedef struct {
- dns_rbtdb_t * rbtdb;
- rbtdb_version_t * rbtversion;
- rbtdb_serial_t serial;
- unsigned int options;
- dns_rbtnodechain_t chain;
- isc_boolean_t copy_name;
- isc_boolean_t need_cleanup;
- isc_boolean_t wild;
- dns_rbtnode_t * zonecut;
- rdatasetheader_t * zonecut_rdataset;
- rdatasetheader_t * zonecut_sigrdataset;
- dns_fixedname_t zonecut_name;
- isc_stdtime_t now;
-} rbtdb_search_t;
-
-/*%
- * Load Context
- */
-typedef struct {
- dns_rbtdb_t * rbtdb;
- isc_stdtime_t now;
-} rbtdb_load_t;
-
-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 isc_result_t rdataset_getnoqname(dns_rdataset_t *rdataset,
- dns_name_t *name,
- dns_rdataset_t *neg,
- dns_rdataset_t *negsig);
-static isc_result_t rdataset_getclosest(dns_rdataset_t *rdataset,
- dns_name_t *name,
- dns_rdataset_t *neg,
- dns_rdataset_t *negsig);
-static isc_result_t rdataset_getadditional(dns_rdataset_t *rdataset,
- dns_rdatasetadditional_t type,
- dns_rdatatype_t qtype,
- dns_acache_t *acache,
- dns_zone_t **zonep,
- dns_db_t **dbp,
- dns_dbversion_t **versionp,
- dns_dbnode_t **nodep,
- dns_name_t *fname,
- dns_message_t *msg,
- isc_stdtime_t now);
-static isc_result_t rdataset_setadditional(dns_rdataset_t *rdataset,
- dns_rdatasetadditional_t type,
- dns_rdatatype_t qtype,
- dns_acache_t *acache,
- dns_zone_t *zone,
- dns_db_t *db,
- dns_dbversion_t *version,
- dns_dbnode_t *node,
- dns_name_t *fname);
-static isc_result_t rdataset_putadditional(dns_acache_t *acache,
- dns_rdataset_t *rdataset,
- dns_rdatasetadditional_t type,
- dns_rdatatype_t qtype);
-static inline isc_boolean_t need_headerupdate(rdatasetheader_t *header,
- isc_stdtime_t now);
-static void update_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header,
- isc_stdtime_t now);
-static void expire_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header,
- isc_boolean_t tree_locked);
-static void overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start,
- isc_stdtime_t now, isc_boolean_t tree_locked);
-static isc_result_t resign_insert(dns_rbtdb_t *rbtdb, int idx,
- rdatasetheader_t *newheader);
-static void prune_tree(isc_task_t *task, isc_event_t *event);
-static void rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust);
-static void rdataset_expire(dns_rdataset_t *rdataset);
-
-static dns_rdatasetmethods_t rdataset_methods = {
- rdataset_disassociate,
- rdataset_first,
- rdataset_next,
- rdataset_current,
- rdataset_clone,
- rdataset_count,
- NULL,
- rdataset_getnoqname,
- NULL,
- rdataset_getclosest,
- rdataset_getadditional,
- rdataset_setadditional,
- rdataset_putadditional,
- rdataset_settrust,
- rdataset_expire
-};
-
-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
-};
-
-typedef struct rbtdb_rdatasetiter {
- dns_rdatasetiter_t common;
- rdatasetheader_t * current;
-} rbtdb_rdatasetiter_t;
-
-static void dbiterator_destroy(dns_dbiterator_t **iteratorp);
-static isc_result_t dbiterator_first(dns_dbiterator_t *iterator);
-static isc_result_t dbiterator_last(dns_dbiterator_t *iterator);
-static isc_result_t dbiterator_seek(dns_dbiterator_t *iterator,
- dns_name_t *name);
-static isc_result_t dbiterator_prev(dns_dbiterator_t *iterator);
-static isc_result_t dbiterator_next(dns_dbiterator_t *iterator);
-static isc_result_t dbiterator_current(dns_dbiterator_t *iterator,
- dns_dbnode_t **nodep,
- dns_name_t *name);
-static isc_result_t dbiterator_pause(dns_dbiterator_t *iterator);
-static isc_result_t dbiterator_origin(dns_dbiterator_t *iterator,
- dns_name_t *name);
-
-static dns_dbiteratormethods_t dbiterator_methods = {
- dbiterator_destroy,
- dbiterator_first,
- dbiterator_last,
- dbiterator_seek,
- dbiterator_prev,
- dbiterator_next,
- dbiterator_current,
- dbiterator_pause,
- dbiterator_origin
-};
-
-#define DELETION_BATCH_MAX 64
-
-/*
- * If 'paused' is ISC_TRUE, then the tree lock is not being held.
- */
-typedef struct rbtdb_dbiterator {
- dns_dbiterator_t common;
- isc_boolean_t paused;
- isc_boolean_t new_origin;
- isc_rwlocktype_t tree_locked;
- isc_result_t result;
- dns_fixedname_t name;
- dns_fixedname_t origin;
- dns_rbtnodechain_t chain;
- dns_rbtnodechain_t nsec3chain;
- dns_rbtnodechain_t *current;
- dns_rbtnode_t *node;
- dns_rbtnode_t *deletions[DELETION_BATCH_MAX];
- int delete;
- isc_boolean_t nsec3only;
- isc_boolean_t nonsec3;
-} rbtdb_dbiterator_t;
-
-
-#define IS_STUB(rbtdb) (((rbtdb)->common.attributes & DNS_DBATTR_STUB) != 0)
-#define IS_CACHE(rbtdb) (((rbtdb)->common.attributes & DNS_DBATTR_CACHE) != 0)
-
-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);
-#ifdef BIND9
-static void setnsec3parameters(dns_db_t *db, rbtdb_version_t *version);
-#endif
-
-/*%
- * 'init_count' is used to initialize 'newheader->count' which inturn
- * is used to determine where in the cycle rrset-order cyclic starts.
- * We don't lock this as we don't care about simultaneous updates.
- *
- * Note:
- * Both init_count and header->count can be ISC_UINT32_MAX.
- * The count on the returned rdataset however can't be as
- * that indicates that the database does not implement cyclic
- * processing.
- */
-static unsigned int init_count;
-
-/*
- * Locking
- *
- * If a routine is going to lock more than one lock in this module, then
- * the locking must be done in the following order:
- *
- * Tree Lock
- *
- * Node Lock (Only one from the set may be locked at one time by
- * any caller)
- *
- * Database Lock
- *
- * Failure to follow this hierarchy can result in deadlock.
- */
-
-/*
- * Deleting Nodes
- *
- * For zone databases the node for the origin of the zone MUST NOT be deleted.
- */
-
-
-/*
- * DB Routines
- */
-
-static void
-attach(dns_db_t *source, dns_db_t **targetp) {
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)source;
-
- REQUIRE(VALID_RBTDB(rbtdb));
-
- isc_refcount_increment(&rbtdb->references, NULL);
-
- *targetp = source;
-}
-
-static void
-free_rbtdb_callback(isc_task_t *task, isc_event_t *event) {
- dns_rbtdb_t *rbtdb = event->ev_arg;
-
- UNUSED(task);
-
- free_rbtdb(rbtdb, ISC_TRUE, event);
-}
-
-static void
-update_rrsetstats(dns_rbtdb_t *rbtdb, rdatasetheader_t *header,
- isc_boolean_t increment)
-{
- dns_rdatastatstype_t statattributes = 0;
- dns_rdatastatstype_t base = 0;
- dns_rdatastatstype_t type;
-
- /* At the moment we count statistics only for cache DB */
- INSIST(IS_CACHE(rbtdb));
-
- if (NEGATIVE(header)) {
- if (NXDOMAIN(header))
- statattributes = DNS_RDATASTATSTYPE_ATTR_NXDOMAIN;
- else {
- statattributes = DNS_RDATASTATSTYPE_ATTR_NXRRSET;
- base = RBTDB_RDATATYPE_EXT(header->type);
- }
- } else
- base = RBTDB_RDATATYPE_BASE(header->type);
-
- type = DNS_RDATASTATSTYPE_VALUE(base, statattributes);
- if (increment)
- dns_rdatasetstats_increment(rbtdb->rrsetstats, type);
- else
- dns_rdatasetstats_decrement(rbtdb->rrsetstats, type);
-}
-
-static void
-set_ttl(dns_rbtdb_t *rbtdb, rdatasetheader_t *header, dns_ttl_t newttl) {
- int idx;
- isc_heap_t *heap;
- dns_ttl_t oldttl;
-
- oldttl = header->rdh_ttl;
- header->rdh_ttl = newttl;
-
- if (!IS_CACHE(rbtdb))
- return;
-
- /*
- * It's possible the rbtdb is not a cache. If this is the case,
- * we will not have a heap, and we move on. If we do, though,
- * we might need to adjust things.
- */
- if (header->heap_index == 0 || newttl == oldttl)
- return;
- idx = header->node->locknum;
- if (rbtdb->heaps == NULL || rbtdb->heaps[idx] == NULL)
- return;
- heap = rbtdb->heaps[idx];
-
- if (newttl < oldttl)
- isc_heap_increased(heap, header->heap_index);
- else
- isc_heap_decreased(heap, header->heap_index);
-}
-
-/*%
- * These functions allow the heap code to rank the priority of each
- * element. It returns ISC_TRUE if v1 happens "sooner" than v2.
- */
-static isc_boolean_t
-ttl_sooner(void *v1, void *v2) {
- rdatasetheader_t *h1 = v1;
- rdatasetheader_t *h2 = v2;
-
- if (h1->rdh_ttl < h2->rdh_ttl)
- return (ISC_TRUE);
- return (ISC_FALSE);
-}
-
-static isc_boolean_t
-resign_sooner(void *v1, void *v2) {
- rdatasetheader_t *h1 = v1;
- rdatasetheader_t *h2 = v2;
-
- if (h1->resign < h2->resign)
- return (ISC_TRUE);
- return (ISC_FALSE);
-}
-
-/*%
- * This function sets the heap index into the header.
- */
-static void
-set_index(void *what, unsigned int index) {
- rdatasetheader_t *h = what;
-
- h->heap_index = index;
-}
-
-/*%
- * Work out how many nodes can be deleted in the time between two
- * requests to the nameserver. Smooth the resulting number and use it
- * as a estimate for the number of nodes to be deleted in the next
- * iteration.
- */
-static unsigned int
-adjust_quantum(unsigned int old, isc_time_t *start) {
- unsigned int pps = dns_pps; /* packets per second */
- unsigned int interval;
- isc_uint64_t usecs;
- isc_time_t end;
- unsigned int new;
-
- if (pps < 100)
- pps = 100;
- isc_time_now(&end);
-
- interval = 1000000 / pps; /* interval in usec */
- if (interval == 0)
- interval = 1;
- usecs = isc_time_microdiff(&end, start);
- if (usecs == 0) {
- /*
- * We were unable to measure the amount of time taken.
- * Double the nodes deleted next time.
- */
- old *= 2;
- if (old > 1000)
- old = 1000;
- return (old);
- }
- new = old * interval;
- new /= (unsigned int)usecs;
- if (new == 0)
- new = 1;
- else if (new > 1000)
- new = 1000;
-
- /* Smooth */
- new = (new + old * 3) / 4;
-
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE,
- ISC_LOG_DEBUG(1), "adjust_quantum -> %d", new);
-
- return (new);
-}
-
-static void
-free_rbtdb(dns_rbtdb_t *rbtdb, isc_boolean_t log, isc_event_t *event) {
- unsigned int i;
- 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)
- overmem((dns_db_t *)rbtdb, (isc_boolean_t)-1);
-
- REQUIRE(rbtdb->current_version != NULL || EMPTY(rbtdb->open_versions));
- REQUIRE(rbtdb->future_version == NULL);
-
- if (rbtdb->current_version != NULL) {
- unsigned int refs;
-
- isc_refcount_decrement(&rbtdb->current_version->references,
- &refs);
- INSIST(refs == 0);
- UNLINK(rbtdb->open_versions, rbtdb->current_version, link);
- isc_refcount_destroy(&rbtdb->current_version->references);
- isc_mem_put(rbtdb->common.mctx, rbtdb->current_version,
- sizeof(rbtdb_version_t));
- }
-
- /*
- * We assume the number of remaining dead nodes is reasonably small;
- * the overhead of unlinking all nodes here should be negligible.
- */
- for (i = 0; i < rbtdb->node_lock_count; i++) {
- dns_rbtnode_t *node;
-
- node = ISC_LIST_HEAD(rbtdb->deadnodes[i]);
- while (node != NULL) {
- ISC_LIST_UNLINK(rbtdb->deadnodes[i], node, deadlink);
- node = ISC_LIST_HEAD(rbtdb->deadnodes[i]);
- }
- }
-
- if (event == NULL)
- rbtdb->quantum = (rbtdb->task != NULL) ? 100 : 0;
-
- 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;
- }
- }
-
- isc_time_now(&start);
- result = dns_rbt_destroy2(treep, 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)
- continue;
- isc_task_send(rbtdb->task, &event);
- return;
- }
- INSIST(result == ISC_R_SUCCESS && *treep == NULL);
- }
-
- if (event != NULL)
- isc_event_free(&event);
- if (log) {
- if (dns_name_dynamic(&rbtdb->common.origin))
- dns_name_format(&rbtdb->common.origin, buf,
- sizeof(buf));
- else
- strcpy(buf, "<UNKNOWN>");
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_CACHE, ISC_LOG_DEBUG(1),
- "done free_rbtdb(%s)", buf);
- }
- if (dns_name_dynamic(&rbtdb->common.origin))
- dns_name_free(&rbtdb->common.origin, rbtdb->common.mctx);
- for (i = 0; i < rbtdb->node_lock_count; i++) {
- isc_refcount_destroy(&rbtdb->node_locks[i].references);
- NODE_DESTROYLOCK(&rbtdb->node_locks[i].lock);
- }
-
- /*
- * Clean up LRU / re-signing order lists.
- */
- if (rbtdb->rdatasets != NULL) {
- for (i = 0; i < rbtdb->node_lock_count; i++)
- INSIST(ISC_LIST_EMPTY(rbtdb->rdatasets[i]));
- isc_mem_put(rbtdb->common.mctx, rbtdb->rdatasets,
- rbtdb->node_lock_count *
- sizeof(rdatasetheaderlist_t));
- }
- /*
- * Clean up dead node buckets.
- */
- if (rbtdb->deadnodes != NULL) {
- for (i = 0; i < rbtdb->node_lock_count; i++)
- INSIST(ISC_LIST_EMPTY(rbtdb->deadnodes[i]));
- isc_mem_put(rbtdb->common.mctx, rbtdb->deadnodes,
- rbtdb->node_lock_count * sizeof(rbtnodelist_t));
- }
- /*
- * Clean up heap objects.
- */
- if (rbtdb->heaps != NULL) {
- for (i = 0; i < rbtdb->node_lock_count; i++)
- isc_heap_destroy(&rbtdb->heaps[i]);
- isc_mem_put(rbtdb->hmctx, rbtdb->heaps,
- rbtdb->node_lock_count * sizeof(isc_heap_t *));
- }
-
- 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);
- isc_refcount_destroy(&rbtdb->references);
- if (rbtdb->task != NULL)
- isc_task_detach(&rbtdb->task);
-
- RBTDB_DESTROYLOCK(&rbtdb->lock);
- rbtdb->common.magic = 0;
- rbtdb->common.impmagic = 0;
- ondest = rbtdb->common.ondest;
- isc_mem_detach(&rbtdb->hmctx);
- isc_mem_putanddetach(&rbtdb->common.mctx, rbtdb, sizeof(*rbtdb));
- isc_ondestroy_notify(&ondest, rbtdb);
-}
-
-static inline void
-maybe_free_rbtdb(dns_rbtdb_t *rbtdb) {
- isc_boolean_t want_free = ISC_FALSE;
- unsigned int i;
- unsigned int inactive = 0;
-
- /* XXX check for open versions here */
-
- if (rbtdb->soanode != NULL)
- dns_db_detachnode((dns_db_t *)rbtdb, &rbtdb->soanode);
- if (rbtdb->nsnode != NULL)
- dns_db_detachnode((dns_db_t *)rbtdb, &rbtdb->nsnode);
-
- /*
- * Even though there are no external direct references, there still
- * may be nodes in use.
- */
- for (i = 0; i < rbtdb->node_lock_count; i++) {
- NODE_LOCK(&rbtdb->node_locks[i].lock, isc_rwlocktype_write);
- rbtdb->node_locks[i].exiting = ISC_TRUE;
- NODE_UNLOCK(&rbtdb->node_locks[i].lock, isc_rwlocktype_write);
- if (isc_refcount_current(&rbtdb->node_locks[i].references)
- == 0) {
- inactive++;
- }
- }
-
- if (inactive != 0) {
- RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write);
- rbtdb->active -= inactive;
- if (rbtdb->active == 0)
- want_free = ISC_TRUE;
- RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write);
- if (want_free) {
- char buf[DNS_NAME_FORMATSIZE];
- if (dns_name_dynamic(&rbtdb->common.origin))
- dns_name_format(&rbtdb->common.origin, buf,
- sizeof(buf));
- else
- strcpy(buf, "<UNKNOWN>");
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_CACHE, ISC_LOG_DEBUG(1),
- "calling free_rbtdb(%s)", buf);
- free_rbtdb(rbtdb, ISC_TRUE, NULL);
- }
- }
-}
-
-static void
-detach(dns_db_t **dbp) {
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)(*dbp);
- unsigned int refs;
-
- REQUIRE(VALID_RBTDB(rbtdb));
-
- isc_refcount_decrement(&rbtdb->references, &refs);
-
- if (refs == 0)
- maybe_free_rbtdb(rbtdb);
-
- *dbp = NULL;
-}
-
-static void
-currentversion(dns_db_t *db, dns_dbversion_t **versionp) {
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
- rbtdb_version_t *version;
- unsigned int refs;
-
- REQUIRE(VALID_RBTDB(rbtdb));
-
- RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read);
- version = rbtdb->current_version;
- isc_refcount_increment(&version->references, &refs);
- RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_read);
-
- *versionp = (dns_dbversion_t *)version;
-}
-
-static inline rbtdb_version_t *
-allocate_version(isc_mem_t *mctx, rbtdb_serial_t serial,
- unsigned int references, isc_boolean_t writer)
-{
- isc_result_t result;
- rbtdb_version_t *version;
-
- version = isc_mem_get(mctx, sizeof(*version));
- if (version == NULL)
- return (NULL);
- version->serial = serial;
- result = isc_refcount_init(&version->references, references);
- if (result != ISC_R_SUCCESS) {
- isc_mem_put(mctx, version, sizeof(*version));
- return (NULL);
- }
- version->writer = writer;
- version->commit_ok = ISC_FALSE;
- ISC_LIST_INIT(version->changed_list);
- ISC_LIST_INIT(version->resigned_list);
- ISC_LINK_INIT(version, link);
-
- return (version);
-}
-
-static isc_result_t
-newversion(dns_db_t *db, dns_dbversion_t **versionp) {
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
- rbtdb_version_t *version;
-
- REQUIRE(VALID_RBTDB(rbtdb));
- REQUIRE(versionp != NULL && *versionp == NULL);
- REQUIRE(rbtdb->future_version == NULL);
-
- RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write);
- RUNTIME_CHECK(rbtdb->next_serial != 0); /* XXX Error? */
- version = allocate_version(rbtdb->common.mctx, rbtdb->next_serial, 1,
- ISC_TRUE);
- if (version != NULL) {
- version->rbtdb = rbtdb;
- version->commit_ok = ISC_TRUE;
- version->secure = rbtdb->current_version->secure;
- version->havensec3 = rbtdb->current_version->havensec3;
- if (version->havensec3) {
- version->flags = rbtdb->current_version->flags;
- version->iterations =
- rbtdb->current_version->iterations;
- version->hash = rbtdb->current_version->hash;
- version->salt_length =
- rbtdb->current_version->salt_length;
- memcpy(version->salt, rbtdb->current_version->salt,
- version->salt_length);
- } else {
- version->flags = 0;
- version->iterations = 0;
- version->hash = 0;
- version->salt_length = 0;
- memset(version->salt, 0, sizeof(version->salt));
- }
- rbtdb->next_serial++;
- rbtdb->future_version = version;
- }
- RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write);
-
- if (version == NULL)
- return (ISC_R_NOMEMORY);
-
- *versionp = version;
-
- return (ISC_R_SUCCESS);
-}
-
-static void
-attachversion(dns_db_t *db, dns_dbversion_t *source,
- dns_dbversion_t **targetp)
-{
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
- rbtdb_version_t *rbtversion = source;
- unsigned int refs;
-
- REQUIRE(VALID_RBTDB(rbtdb));
- INSIST(rbtversion != NULL && rbtversion->rbtdb == rbtdb);
-
- isc_refcount_increment(&rbtversion->references, &refs);
- INSIST(refs > 1);
-
- *targetp = rbtversion;
-}
-
-static rbtdb_changed_t *
-add_changed(dns_rbtdb_t *rbtdb, rbtdb_version_t *version,
- dns_rbtnode_t *node)
-{
- rbtdb_changed_t *changed;
- unsigned int refs;
-
- /*
- * Caller must be holding the node lock if its reference must be
- * protected by the lock.
- */
-
- changed = isc_mem_get(rbtdb->common.mctx, sizeof(*changed));
-
- RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write);
-
- REQUIRE(version->writer);
-
- if (changed != NULL) {
- dns_rbtnode_refincrement(node, &refs);
- INSIST(refs != 0);
- changed->node = node;
- changed->dirty = ISC_FALSE;
- ISC_LIST_INITANDAPPEND(version->changed_list, changed, link);
- } else
- version->commit_ok = ISC_FALSE;
-
- RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write);
-
- return (changed);
-}
-
-static void
-free_acachearray(isc_mem_t *mctx, rdatasetheader_t *header,
- acachectl_t *array)
-{
- unsigned int count;
- unsigned int i;
- unsigned char *raw; /* RDATASLAB */
-
- /*
- * The caller must be holding the corresponding node lock.
- */
-
- if (array == NULL)
- return;
-
- raw = (unsigned char *)header + sizeof(*header);
- count = raw[0] * 256 + raw[1];
-
- /*
- * Sanity check: since an additional cache entry has a reference to
- * the original DB node (in the callback arg), there should be no
- * acache entries when the node can be freed.
- */
- for (i = 0; i < count; i++)
- INSIST(array[i].entry == NULL && array[i].cbarg == NULL);
-
- isc_mem_put(mctx, array, count * sizeof(acachectl_t));
-}
-
-static inline void
-free_noqname(isc_mem_t *mctx, struct noqname **noqname) {
-
- if (dns_name_dynamic(&(*noqname)->name))
- dns_name_free(&(*noqname)->name, mctx);
- if ((*noqname)->neg != NULL)
- isc_mem_put(mctx, (*noqname)->neg,
- dns_rdataslab_size((*noqname)->neg, 0));
- if ((*noqname)->negsig != NULL)
- isc_mem_put(mctx, (*noqname)->negsig,
- dns_rdataslab_size((*noqname)->negsig, 0));
- isc_mem_put(mctx, *noqname, sizeof(**noqname));
- *noqname = NULL;
-}
-
-static inline void
-init_rdataset(dns_rbtdb_t *rbtdb, rdatasetheader_t *h)
-{
- ISC_LINK_INIT(h, link);
- h->heap_index = 0;
-
-#if TRACE_HEADER
- if (IS_CACHE(rbtdb) && rbtdb->common.rdclass == dns_rdataclass_in)
- fprintf(stderr, "initialized header: %p\n", h);
-#else
- UNUSED(rbtdb);
-#endif
-}
-
-static inline rdatasetheader_t *
-new_rdataset(dns_rbtdb_t *rbtdb, isc_mem_t *mctx)
-{
- rdatasetheader_t *h;
-
- h = isc_mem_get(mctx, sizeof(*h));
- if (h == NULL)
- return (NULL);
-
-#if TRACE_HEADER
- if (IS_CACHE(rbtdb) && rbtdb->common.rdclass == dns_rdataclass_in)
- fprintf(stderr, "allocated header: %p\n", h);
-#endif
- init_rdataset(rbtdb, h);
- return (h);
-}
-
-static inline void
-free_rdataset(dns_rbtdb_t *rbtdb, isc_mem_t *mctx, rdatasetheader_t *rdataset)
-{
- unsigned int size;
- int idx;
-
- if (EXISTS(rdataset) &&
- (rdataset->attributes & RDATASET_ATTR_STATCOUNT) != 0) {
- update_rrsetstats(rbtdb, rdataset, ISC_FALSE);
- }
-
- idx = rdataset->node->locknum;
- if (ISC_LINK_LINKED(rdataset, link)) {
- INSIST(IS_CACHE(rbtdb));
- ISC_LIST_UNLINK(rbtdb->rdatasets[idx], rdataset, link);
- }
- if (rdataset->heap_index != 0)
- isc_heap_delete(rbtdb->heaps[idx], rdataset->heap_index);
- rdataset->heap_index = 0;
-
- if (rdataset->noqname != NULL)
- free_noqname(mctx, &rdataset->noqname);
- if (rdataset->closest != NULL)
- free_noqname(mctx, &rdataset->closest);
-
- free_acachearray(mctx, rdataset, rdataset->additional_auth);
- free_acachearray(mctx, rdataset, rdataset->additional_glue);
-
- if ((rdataset->attributes & RDATASET_ATTR_NONEXISTENT) != 0)
- size = sizeof(*rdataset);
- else
- size = dns_rdataslab_size((unsigned char *)rdataset,
- sizeof(*rdataset));
- isc_mem_put(mctx, rdataset, size);
-}
-
-static inline void
-rollback_node(dns_rbtnode_t *node, rbtdb_serial_t serial) {
- rdatasetheader_t *header, *dcurrent;
- isc_boolean_t make_dirty = ISC_FALSE;
-
- /*
- * Caller must hold the node lock.
- */
-
- /*
- * We set the IGNORE attribute on rdatasets with serial number
- * 'serial'. When the reference count goes to zero, these rdatasets
- * will be cleaned up; until that time, they will be ignored.
- */
- for (header = node->data; header != NULL; header = header->next) {
- if (header->serial == serial) {
- header->attributes |= RDATASET_ATTR_IGNORE;
- make_dirty = ISC_TRUE;
- }
- for (dcurrent = header->down;
- dcurrent != NULL;
- dcurrent = dcurrent->down) {
- if (dcurrent->serial == serial) {
- dcurrent->attributes |= RDATASET_ATTR_IGNORE;
- make_dirty = ISC_TRUE;
- }
- }
- }
- if (make_dirty)
- node->dirty = 1;
-}
-
-static inline void
-clean_stale_headers(dns_rbtdb_t *rbtdb, isc_mem_t *mctx, rdatasetheader_t *top)
-{
- rdatasetheader_t *d, *down_next;
-
- for (d = top->down; d != NULL; d = down_next) {
- down_next = d->down;
- free_rdataset(rbtdb, mctx, d);
- }
- top->down = NULL;
-}
-
-static inline void
-clean_cache_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node) {
- rdatasetheader_t *current, *top_prev, *top_next;
- isc_mem_t *mctx = rbtdb->common.mctx;
-
- /*
- * Caller must be holding the node lock.
- */
-
- top_prev = NULL;
- for (current = node->data; current != NULL; current = top_next) {
- top_next = current->next;
- clean_stale_headers(rbtdb, mctx, current);
- /*
- * If current is nonexistent or stale, we can clean it up.
- */
- if ((current->attributes &
- (RDATASET_ATTR_NONEXISTENT|RDATASET_ATTR_STALE)) != 0) {
- if (top_prev != NULL)
- top_prev->next = current->next;
- else
- node->data = current->next;
- free_rdataset(rbtdb, mctx, current);
- } else
- top_prev = current;
- }
- node->dirty = 0;
-}
-
-static inline void
-clean_zone_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
- rbtdb_serial_t least_serial)
-{
- rdatasetheader_t *current, *dcurrent, *down_next, *dparent;
- rdatasetheader_t *top_prev, *top_next;
- isc_mem_t *mctx = rbtdb->common.mctx;
- isc_boolean_t still_dirty = ISC_FALSE;
-
- /*
- * Caller must be holding the node lock.
- */
- REQUIRE(least_serial != 0);
-
- top_prev = NULL;
- for (current = node->data; current != NULL; current = top_next) {
- top_next = current->next;
-
- /*
- * First, we clean up any instances of multiple rdatasets
- * with the same serial number, or that have the IGNORE
- * attribute.
- */
- dparent = current;
- for (dcurrent = current->down;
- dcurrent != NULL;
- dcurrent = down_next) {
- down_next = dcurrent->down;
- INSIST(dcurrent->serial <= dparent->serial);
- if (dcurrent->serial == dparent->serial ||
- IGNORE(dcurrent)) {
- if (down_next != NULL)
- down_next->next = dparent;
- dparent->down = down_next;
- free_rdataset(rbtdb, mctx, dcurrent);
- } else
- dparent = dcurrent;
- }
-
- /*
- * We've now eliminated all IGNORE datasets with the possible
- * exception of current, which we now check.
- */
- if (IGNORE(current)) {
- down_next = current->down;
- if (down_next == NULL) {
- if (top_prev != NULL)
- top_prev->next = current->next;
- else
- node->data = current->next;
- free_rdataset(rbtdb, mctx, current);
- /*
- * current no longer exists, so we can
- * just continue with the loop.
- */
- continue;
- } else {
- /*
- * Pull up current->down, making it the new
- * current.
- */
- if (top_prev != NULL)
- top_prev->next = down_next;
- else
- node->data = down_next;
- down_next->next = top_next;
- free_rdataset(rbtdb, mctx, current);
- current = down_next;
- }
- }
-
- /*
- * We now try to find the first down node less than the
- * least serial.
- */
- dparent = current;
- for (dcurrent = current->down;
- dcurrent != NULL;
- dcurrent = down_next) {
- down_next = dcurrent->down;
- if (dcurrent->serial < least_serial)
- break;
- dparent = dcurrent;
- }
-
- /*
- * If there is a such an rdataset, delete it and any older
- * versions.
- */
- if (dcurrent != NULL) {
- do {
- down_next = dcurrent->down;
- INSIST(dcurrent->serial <= least_serial);
- free_rdataset(rbtdb, mctx, dcurrent);
- dcurrent = down_next;
- } while (dcurrent != NULL);
- dparent->down = NULL;
- }
-
- /*
- * Note. The serial number of 'current' might be less than
- * least_serial too, but we cannot delete it because it is
- * the most recent version, unless it is a NONEXISTENT
- * rdataset.
- */
- if (current->down != NULL) {
- still_dirty = ISC_TRUE;
- top_prev = current;
- } else {
- /*
- * If this is a NONEXISTENT rdataset, we can delete it.
- */
- if (NONEXISTENT(current)) {
- if (top_prev != NULL)
- top_prev->next = current->next;
- else
- node->data = current->next;
- free_rdataset(rbtdb, mctx, current);
- } else
- top_prev = current;
- }
- }
- if (!still_dirty)
- 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_node(): "
- "dns_rbt_deletenode(nsecnode): %s",
- isc_result_totext(result));
- }
- }
-#ifdef BIND9
- if (rbtdb->rpz_cidr != NULL)
- dns_rpz_cidr_deleteip(rbtdb->rpz_cidr, name);
-#endif
- result = dns_rbt_deletenode(rbtdb->tree, node, ISC_FALSE);
- 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_cnode(): "
- "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
- * them when we deleted all the data at that node because we did not want
- * to wait for the tree write lock.
- *
- * The caller must hold a tree write lock and bucketnum'th node (write) lock.
- */
-static void
-cleanup_dead_nodes(dns_rbtdb_t *rbtdb, int bucketnum) {
- dns_rbtnode_t *node;
- int count = 10; /* XXXJT: should be adjustable */
-
- node = ISC_LIST_HEAD(rbtdb->deadnodes[bucketnum]);
- while (node != NULL && count > 0) {
- ISC_LIST_UNLINK(rbtdb->deadnodes[bucketnum], node, deadlink);
-
- /*
- * Since we're holding a tree write lock, it should be
- * impossible for this node to be referenced by others.
- */
- INSIST(dns_rbtnode_refcurrent(node) == 0 &&
- node->data == NULL);
-
- delete_node(rbtdb, node);
-
- node = ISC_LIST_HEAD(rbtdb->deadnodes[bucketnum]);
- count--;
- }
-}
-
-/*
- * Caller must be holding the node lock.
- */
-static inline void
-new_reference(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node) {
- unsigned int lockrefs, noderefs;
- isc_refcount_t *lockref;
-
- INSIST(!ISC_LINK_LINKED(node, deadlink));
- dns_rbtnode_refincrement0(node, &noderefs);
- if (noderefs == 1) { /* this is the first reference to the node */
- lockref = &rbtdb->node_locks[node->locknum].references;
- isc_refcount_increment0(lockref, &lockrefs);
- INSIST(lockrefs != 0);
- }
- INSIST(noderefs != 0);
-}
-
-/*
- * This function is assumed to be called when a node is newly referenced
- * and can be in the deadnode list. In that case the node must be retrieved
- * from the list because it is going to be used. In addition, if the caller
- * happens to hold a write lock on the tree, it's a good chance to purge dead
- * nodes.
- * Note: while a new reference is gained in multiple places, there are only very
- * few cases where the node can be in the deadnode list (only empty nodes can
- * have been added to the list).
- */
-static inline void
-reactivate_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
- isc_rwlocktype_t treelocktype)
-{
- isc_rwlocktype_t locktype = isc_rwlocktype_read;
- nodelock_t *nodelock = &rbtdb->node_locks[node->locknum].lock;
- isc_boolean_t maybe_cleanup = ISC_FALSE;
-
- POST(locktype);
-
- NODE_STRONGLOCK(nodelock);
- NODE_WEAKLOCK(nodelock, locktype);
-
- /*
- * Check if we can possibly cleanup the dead node. If so, upgrade
- * the node lock below to perform the cleanup.
- */
- if (!ISC_LIST_EMPTY(rbtdb->deadnodes[node->locknum]) &&
- treelocktype == isc_rwlocktype_write) {
- maybe_cleanup = ISC_TRUE;
- }
-
- if (ISC_LINK_LINKED(node, deadlink) || maybe_cleanup) {
- /*
- * Upgrade the lock and test if we still need to unlink.
- */
- NODE_WEAKUNLOCK(nodelock, locktype);
- locktype = isc_rwlocktype_write;
- POST(locktype);
- NODE_WEAKLOCK(nodelock, locktype);
- if (ISC_LINK_LINKED(node, deadlink))
- ISC_LIST_UNLINK(rbtdb->deadnodes[node->locknum],
- node, deadlink);
- if (maybe_cleanup)
- cleanup_dead_nodes(rbtdb, node->locknum);
- }
-
- new_reference(rbtdb, node);
-
- NODE_WEAKUNLOCK(nodelock, locktype);
- NODE_STRONGUNLOCK(nodelock);
-}
-
-/*
- * Caller must be holding the node lock; either the "strong", read or write
- * lock. Note that the lock must be held even when node references are
- * atomically modified; in that case the decrement operation itself does not
- * have to be protected, but we must avoid a race condition where multiple
- * threads are decreasing the reference to zero simultaneously and at least
- * one of them is going to free the node.
- * This function returns ISC_TRUE if and only if the node reference decreases
- * to zero.
- */
-static isc_boolean_t
-decrement_reference(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
- rbtdb_serial_t least_serial,
- isc_rwlocktype_t nlock, isc_rwlocktype_t tlock,
- isc_boolean_t pruning)
-{
- isc_result_t result;
- isc_boolean_t write_locked;
- rbtdb_nodelock_t *nodelock;
- unsigned int refs, nrefs;
- int bucket = node->locknum;
- isc_boolean_t no_reference = ISC_TRUE;
-
- nodelock = &rbtdb->node_locks[bucket];
-
- /* Handle easy and typical case first. */
- if (!node->dirty && (node->data != NULL || node->down != NULL)) {
- dns_rbtnode_refdecrement(node, &nrefs);
- INSIST((int)nrefs >= 0);
- if (nrefs == 0) {
- isc_refcount_decrement(&nodelock->references, &refs);
- INSIST((int)refs >= 0);
- }
- return ((nrefs == 0) ? ISC_TRUE : ISC_FALSE);
- }
-
- /* Upgrade the lock? */
- if (nlock == isc_rwlocktype_read) {
- NODE_WEAKUNLOCK(&nodelock->lock, isc_rwlocktype_read);
- NODE_WEAKLOCK(&nodelock->lock, isc_rwlocktype_write);
- }
-
- dns_rbtnode_refdecrement(node, &nrefs);
- INSIST((int)nrefs >= 0);
- if (nrefs > 0) {
- /* Restore the lock? */
- if (nlock == isc_rwlocktype_read)
- NODE_WEAKDOWNGRADE(&nodelock->lock);
- return (ISC_FALSE);
- }
-
- if (node->dirty) {
- if (IS_CACHE(rbtdb))
- clean_cache_node(rbtdb, node);
- else {
- if (least_serial == 0) {
- /*
- * Caller doesn't know the least serial.
- * Get it.
- */
- RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read);
- least_serial = rbtdb->least_serial;
- RBTDB_UNLOCK(&rbtdb->lock,
- isc_rwlocktype_read);
- }
- clean_zone_node(rbtdb, node, least_serial);
- }
- }
-
- /*
- * Attempt to switch to a write lock on the tree. If this fails,
- * we will add this node to a linked list of nodes in this locking
- * bucket which we will free later.
- */
- if (tlock != isc_rwlocktype_write) {
- /*
- * Locking hierarchy notwithstanding, we don't need to free
- * the node lock before acquiring the tree write lock because
- * we only do a trylock.
- */
- if (tlock == isc_rwlocktype_read)
- result = isc_rwlock_tryupgrade(&rbtdb->tree_lock);
- else
- result = isc_rwlock_trylock(&rbtdb->tree_lock,
- isc_rwlocktype_write);
- RUNTIME_CHECK(result == ISC_R_SUCCESS ||
- result == ISC_R_LOCKBUSY);
-
- write_locked = ISC_TF(result == ISC_R_SUCCESS);
- } else
- write_locked = ISC_TRUE;
-
- isc_refcount_decrement(&nodelock->references, &refs);
- INSIST((int)refs >= 0);
-
- /*
- * XXXDCL should this only be done for cache zones?
- */
- if (node->data != NULL || node->down != NULL)
- goto restore_locks;
-
- if (write_locked) {
- /*
- * We can now delete the node.
- */
-
- /*
- * If this node is the only one in the level it's in, deleting
- * this node may recursively make its parent the only node in
- * the parent level; if so, and if no one is currently using
- * the parent node, this is almost the only opportunity to
- * clean it up. But the recursive cleanup is not that trivial
- * since the child and parent may be in different lock buckets,
- * which would cause a lock order reversal problem. To avoid
- * the trouble, we'll dispatch a separate event for batch
- * cleaning. We need to check whether we're deleting the node
- * as a result of pruning to avoid infinite dispatching.
- * Note: pruning happens only when a task has been set for the
- * rbtdb. If the user of the rbtdb chooses not to set a task,
- * it's their responsibility to purge stale leaves (e.g. by
- * periodic walk-through).
- */
- if (!pruning && node->parent != NULL &&
- node->parent->down == node && node->left == NULL &&
- node->right == NULL && rbtdb->task != NULL) {
- isc_event_t *ev;
- dns_db_t *db;
-
- ev = isc_event_allocate(rbtdb->common.mctx, NULL,
- DNS_EVENT_RBTPRUNE,
- prune_tree, node,
- sizeof(isc_event_t));
- if (ev != NULL) {
- new_reference(rbtdb, node);
- db = NULL;
- attach((dns_db_t *)rbtdb, &db);
- ev->ev_sender = db;
- isc_task_send(rbtdb->task, &ev);
- no_reference = ISC_FALSE;
- } else {
- /*
- * XXX: this is a weird situation. We could
- * ignore this error case, but then the stale
- * node will unlikely be purged except via a
- * rare condition such as manual cleanup. So
- * we queue it in the deadnodes list, hoping
- * the memory shortage is temporary and the node
- * will be deleted later.
- */
- isc_log_write(dns_lctx,
- DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_CACHE,
- ISC_LOG_INFO,
- "decrement_reference: failed to "
- "allocate pruning event");
- INSIST(node->data == NULL);
- INSIST(!ISC_LINK_LINKED(node, deadlink));
- ISC_LIST_APPEND(rbtdb->deadnodes[bucket], node,
- deadlink);
- }
- } else {
- if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(1))) {
- char printname[DNS_NAME_FORMATSIZE];
-
- isc_log_write(dns_lctx,
- DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_CACHE,
- ISC_LOG_DEBUG(1),
- "decrement_reference: "
- "delete from rbt: %p %s",
- node,
- dns_rbt_formatnodename(node,
- printname,
- sizeof(printname)));
- }
-
- delete_node(rbtdb, node);
- }
- } else {
- INSIST(node->data == NULL);
- INSIST(!ISC_LINK_LINKED(node, deadlink));
- ISC_LIST_APPEND(rbtdb->deadnodes[bucket], node, deadlink);
- }
-
- restore_locks:
- /* Restore the lock? */
- if (nlock == isc_rwlocktype_read)
- NODE_WEAKDOWNGRADE(&nodelock->lock);
-
- /*
- * Relock a read lock, or unlock the write lock if no lock was held.
- */
- if (tlock == isc_rwlocktype_none)
- if (write_locked)
- RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
-
- if (tlock == isc_rwlocktype_read)
- if (write_locked)
- isc_rwlock_downgrade(&rbtdb->tree_lock);
-
- return (no_reference);
-}
-
-/*
- * Prune the tree by recursively cleaning-up single leaves. In the worst
- * case, the number of iteration is the number of tree levels, which is at
- * most the maximum number of domain name labels, i.e, 127. In practice, this
- * should be much smaller (only a few times), and even the worst case would be
- * acceptable for a single event.
- */
-static void
-prune_tree(isc_task_t *task, isc_event_t *event) {
- dns_rbtdb_t *rbtdb = event->ev_sender;
- dns_rbtnode_t *node = event->ev_arg;
- dns_rbtnode_t *parent;
- unsigned int locknum;
-
- UNUSED(task);
-
- isc_event_free(&event);
-
- RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
- locknum = node->locknum;
- NODE_LOCK(&rbtdb->node_locks[locknum].lock, isc_rwlocktype_write);
- do {
- parent = node->parent;
- decrement_reference(rbtdb, node, 0, isc_rwlocktype_write,
- isc_rwlocktype_write, ISC_TRUE);
-
- if (parent != NULL && parent->down == NULL) {
- /*
- * node was the only down child of the parent and has
- * just been removed. We'll then need to examine the
- * parent. Keep the lock if possible; otherwise,
- * release the old lock and acquire one for the parent.
- */
- if (parent->locknum != locknum) {
- NODE_UNLOCK(&rbtdb->node_locks[locknum].lock,
- isc_rwlocktype_write);
- locknum = parent->locknum;
- NODE_LOCK(&rbtdb->node_locks[locknum].lock,
- isc_rwlocktype_write);
- }
-
- /*
- * We need to gain a reference to the node before
- * decrementing it in the next iteration. In addition,
- * if the node is in the dead-nodes list, extract it
- * from the list beforehand as we do in
- * reactivate_node().
- */
- if (ISC_LINK_LINKED(parent, deadlink))
- ISC_LIST_UNLINK(rbtdb->deadnodes[locknum],
- parent, deadlink);
- new_reference(rbtdb, parent);
- } else
- parent = NULL;
-
- node = parent;
- } while (node != NULL);
- NODE_UNLOCK(&rbtdb->node_locks[locknum].lock, isc_rwlocktype_write);
- RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
-
- detach((dns_db_t **)&rbtdb);
-}
-
-static inline void
-make_least_version(dns_rbtdb_t *rbtdb, rbtdb_version_t *version,
- rbtdb_changedlist_t *cleanup_list)
-{
- /*
- * Caller must be holding the database lock.
- */
-
- rbtdb->least_serial = version->serial;
- *cleanup_list = version->changed_list;
- ISC_LIST_INIT(version->changed_list);
-}
-
-static inline void
-cleanup_nondirty(rbtdb_version_t *version, rbtdb_changedlist_t *cleanup_list) {
- rbtdb_changed_t *changed, *next_changed;
-
- /*
- * If the changed record is dirty, then
- * an update created multiple versions of
- * a given rdataset. We keep this list
- * until we're the least open version, at
- * which point it's safe to get rid of any
- * older versions.
- *
- * If the changed record isn't dirty, then
- * we don't need it anymore since we're
- * committing and not rolling back.
- *
- * The caller must be holding the database lock.
- */
- for (changed = HEAD(version->changed_list);
- changed != NULL;
- changed = next_changed) {
- next_changed = NEXT(changed, link);
- if (!changed->dirty) {
- UNLINK(version->changed_list,
- changed, link);
- APPEND(*cleanup_list,
- changed, link);
- }
- }
-}
-
-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;
- isc_boolean_t haszonekey = ISC_FALSE;
- isc_boolean_t hasnsec = ISC_FALSE;
- isc_result_t result;
-
- dns_rdataset_init(&keyset);
- result = dns_db_findrdataset(db, origin, version, dns_rdatatype_dnskey,
- 0, 0, &keyset, NULL);
- if (result == ISC_R_SUCCESS) {
- result = dns_rdataset_first(&keyset);
- while (result == ISC_R_SUCCESS) {
- dns_rdata_t keyrdata = DNS_RDATA_INIT;
- dns_rdataset_current(&keyset, &keyrdata);
- if (dns_zonekey_iszonekey(&keyrdata)) {
- haszonekey = ISC_TRUE;
- break;
- }
- result = dns_rdataset_next(&keyset);
- }
- dns_rdataset_disassociate(&keyset);
- }
- if (!haszonekey) {
- version->secure = dns_db_insecure;
- version->havensec3 = ISC_FALSE;
- return;
- }
-
- dns_rdataset_init(&nsecset);
- dns_rdataset_init(&signsecset);
- result = dns_db_findrdataset(db, origin, version, dns_rdatatype_nsec,
- 0, 0, &nsecset, &signsecset);
- if (result == ISC_R_SUCCESS) {
- if (dns_rdataset_isassociated(&signsecset)) {
- hasnsec = ISC_TRUE;
- dns_rdataset_disassociate(&signsecset);
- }
- dns_rdataset_disassociate(&nsecset);
- }
-
- setnsec3parameters(db, version);
-
- /*
- * Do we have a valid NSEC/NSEC3 chain?
- */
- if (version->havensec3 || hasnsec)
- version->secure = dns_db_secure;
- 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) {
- dns_rbtnode_t *node;
- dns_rdata_nsec3param_t nsec3param;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- isc_region_t region;
- isc_result_t result;
- rdatasetheader_t *header, *header_next;
- unsigned char *raw; /* RDATASLAB */
- unsigned int count, length;
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
-
- RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
- version->havensec3 = ISC_FALSE;
- node = rbtdb->origin_node;
- NODE_LOCK(&(rbtdb->node_locks[node->locknum].lock),
- isc_rwlocktype_read);
- for (header = node->data;
- header != NULL;
- header = header_next) {
- header_next = header->next;
- do {
- if (header->serial <= version->serial &&
- !IGNORE(header)) {
- if (NONEXISTENT(header))
- header = NULL;
- break;
- } else
- header = header->down;
- } while (header != NULL);
-
- if (header != NULL &&
- (header->type == dns_rdatatype_nsec3param)) {
- /*
- * Find A NSEC3PARAM with a supported algorithm.
- */
- raw = (unsigned char *)header + sizeof(*header);
- count = raw[0] * 256 + raw[1]; /* count */
-#if DNS_RDATASET_FIXED
- raw += count * 4 + 2;
-#else
- raw += 2;
-#endif
- while (count-- > 0U) {
- length = raw[0] * 256 + raw[1];
-#if DNS_RDATASET_FIXED
- raw += 4;
-#else
- raw += 2;
-#endif
- region.base = raw;
- region.length = length;
- raw += length;
- dns_rdata_fromregion(&rdata,
- rbtdb->common.rdclass,
- dns_rdatatype_nsec3param,
- &region);
- result = dns_rdata_tostruct(&rdata,
- &nsec3param,
- NULL);
- INSIST(result == ISC_R_SUCCESS);
- dns_rdata_reset(&rdata);
-
- if (nsec3param.hash != DNS_NSEC3_UNKNOWNALG &&
- !dns_nsec3_supportedhash(nsec3param.hash))
- continue;
-
- if (nsec3param.flags != 0)
- continue;
-
- memcpy(version->salt, nsec3param.salt,
- nsec3param.salt_length);
- version->hash = nsec3param.hash;
- version->salt_length = nsec3param.salt_length;
- version->iterations = nsec3param.iterations;
- version->flags = nsec3param.flags;
- version->havensec3 = ISC_TRUE;
- /*
- * Look for a better algorithm than the
- * unknown test algorithm.
- */
- if (nsec3param.hash != DNS_NSEC3_UNKNOWNALG)
- goto unlock;
- }
- }
- }
- unlock:
- NODE_UNLOCK(&(rbtdb->node_locks[node->locknum].lock),
- 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) {
- dns_rbtdb_t *rbtdb = event->ev_arg;
- isc_boolean_t again = ISC_FALSE;
- unsigned int locknum;
- unsigned int refs;
-
- RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
- for (locknum = 0; locknum < rbtdb->node_lock_count; locknum++) {
- NODE_LOCK(&rbtdb->node_locks[locknum].lock,
- isc_rwlocktype_write);
- cleanup_dead_nodes(rbtdb, locknum);
- if (ISC_LIST_HEAD(rbtdb->deadnodes[locknum]) != NULL)
- again = ISC_TRUE;
- NODE_UNLOCK(&rbtdb->node_locks[locknum].lock,
- isc_rwlocktype_write);
- }
- RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
- if (again)
- isc_task_send(task, &event);
- else {
- isc_event_free(&event);
- isc_refcount_decrement(&rbtdb->references, &refs);
- if (refs == 0)
- maybe_free_rbtdb(rbtdb);
- }
-}
-
-static void
-closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) {
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
- rbtdb_version_t *version, *cleanup_version, *least_greater;
- isc_boolean_t rollback = ISC_FALSE;
- rbtdb_changedlist_t cleanup_list;
- rdatasetheaderlist_t resigned_list;
- rbtdb_changed_t *changed, *next_changed;
- rbtdb_serial_t serial, least_serial;
- dns_rbtnode_t *rbtnode;
- unsigned int refs;
- rdatasetheader_t *header;
- isc_boolean_t writer;
-
- REQUIRE(VALID_RBTDB(rbtdb));
- version = (rbtdb_version_t *)*versionp;
- INSIST(version->rbtdb == rbtdb);
-
- cleanup_version = NULL;
- ISC_LIST_INIT(cleanup_list);
- ISC_LIST_INIT(resigned_list);
-
- isc_refcount_decrement(&version->references, &refs);
- if (refs > 0) { /* typical and easy case first */
- if (commit) {
- RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read);
- INSIST(!version->writer);
- RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_read);
- }
- goto end;
- }
-
- RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write);
- serial = version->serial;
- writer = version->writer;
- if (version->writer) {
- if (commit) {
- unsigned cur_ref;
- rbtdb_version_t *cur_version;
-
- INSIST(version->commit_ok);
- INSIST(version == rbtdb->future_version);
- /*
- * The current version is going to be replaced.
- * Release the (likely last) reference to it from the
- * DB itself and unlink it from the open list.
- */
- cur_version = rbtdb->current_version;
- isc_refcount_decrement(&cur_version->references,
- &cur_ref);
- if (cur_ref == 0) {
- if (cur_version->serial == rbtdb->least_serial)
- INSIST(EMPTY(cur_version->changed_list));
- UNLINK(rbtdb->open_versions,
- cur_version, link);
- }
- if (EMPTY(rbtdb->open_versions)) {
- /*
- * We're going to become the least open
- * version.
- */
- make_least_version(rbtdb, version,
- &cleanup_list);
- } else {
- /*
- * Some other open version is the
- * least version. We can't cleanup
- * records that were changed in this
- * version because the older versions
- * may still be in use by an open
- * version.
- *
- * We can, however, discard the
- * changed records for things that
- * we've added that didn't exist in
- * prior versions.
- */
- cleanup_nondirty(version, &cleanup_list);
- }
- /*
- * If the (soon to be former) current version
- * isn't being used by anyone, we can clean
- * it up.
- */
- if (cur_ref == 0) {
- cleanup_version = cur_version;
- APPENDLIST(version->changed_list,
- cleanup_version->changed_list,
- link);
- }
- /*
- * Become the current version.
- */
- version->writer = ISC_FALSE;
- rbtdb->current_version = version;
- rbtdb->current_serial = version->serial;
- rbtdb->future_version = NULL;
-
- /*
- * Keep the current version in the open list, and
- * gain a reference for the DB itself (see the DB
- * creation function below). This must be the only
- * case where we need to increment the counter from
- * zero and need to use isc_refcount_increment0().
- */
- isc_refcount_increment0(&version->references,
- &cur_ref);
- INSIST(cur_ref == 1);
- PREPEND(rbtdb->open_versions,
- rbtdb->current_version, link);
- resigned_list = version->resigned_list;
- ISC_LIST_INIT(version->resigned_list);
- } else {
- /*
- * We're rolling back this transaction.
- */
- cleanup_list = version->changed_list;
- ISC_LIST_INIT(version->changed_list);
- resigned_list = version->resigned_list;
- ISC_LIST_INIT(version->resigned_list);
- rollback = ISC_TRUE;
- cleanup_version = version;
- rbtdb->future_version = NULL;
- }
- } else {
- if (version != rbtdb->current_version) {
- /*
- * There are no external or internal references
- * to this version and it can be cleaned up.
- */
- cleanup_version = version;
-
- /*
- * Find the version with the least serial
- * number greater than ours.
- */
- least_greater = PREV(version, link);
- if (least_greater == NULL)
- least_greater = rbtdb->current_version;
-
- INSIST(version->serial < least_greater->serial);
- /*
- * Is this the least open version?
- */
- if (version->serial == rbtdb->least_serial) {
- /*
- * Yes. Install the new least open
- * version.
- */
- make_least_version(rbtdb,
- least_greater,
- &cleanup_list);
- } else {
- /*
- * Add any unexecuted cleanups to
- * those of the least greater version.
- */
- APPENDLIST(least_greater->changed_list,
- version->changed_list,
- link);
- }
- } else if (version->serial == rbtdb->least_serial)
- INSIST(EMPTY(version->changed_list));
- UNLINK(rbtdb->open_versions, version, link);
- }
- least_serial = rbtdb->least_serial;
- RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write);
-
- /*
- * Update the zone's secure status.
- */
- if (writer && commit && !IS_CACHE(rbtdb))
- iszonesecure(db, version, rbtdb->origin_node);
-
- if (cleanup_version != NULL) {
- INSIST(EMPTY(cleanup_version->changed_list));
- isc_mem_put(rbtdb->common.mctx, cleanup_version,
- sizeof(*cleanup_version));
- }
-
- /*
- * Commit/rollback re-signed headers.
- */
- for (header = HEAD(resigned_list);
- header != NULL;
- header = HEAD(resigned_list)) {
- nodelock_t *lock;
-
- ISC_LIST_UNLINK(resigned_list, header, link);
-
- lock = &rbtdb->node_locks[header->node->locknum].lock;
- NODE_LOCK(lock, isc_rwlocktype_write);
- if (rollback)
- resign_insert(rbtdb, header->node->locknum, header);
- decrement_reference(rbtdb, header->node, least_serial,
- isc_rwlocktype_write, isc_rwlocktype_none,
- ISC_FALSE);
- NODE_UNLOCK(lock, isc_rwlocktype_write);
- }
-
- if (!EMPTY(cleanup_list)) {
- isc_event_t *event = NULL;
- isc_rwlocktype_t tlock = isc_rwlocktype_none;
-
- if (rbtdb->task != NULL)
- event = isc_event_allocate(rbtdb->common.mctx, NULL,
- DNS_EVENT_RBTDEADNODES,
- cleanup_dead_nodes_callback,
- rbtdb, sizeof(isc_event_t));
- if (event == NULL) {
- /*
- * We acquire a tree write lock here in order to make
- * sure that stale nodes will be removed in
- * decrement_reference(). If we didn't have the lock,
- * those nodes could miss the chance to be removed
- * until the server stops. The write lock is
- * expensive, but this event should be rare enough
- * to justify the cost.
- */
- RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
- tlock = isc_rwlocktype_write;
- }
-
- for (changed = HEAD(cleanup_list);
- changed != NULL;
- changed = next_changed) {
- nodelock_t *lock;
-
- next_changed = NEXT(changed, link);
- rbtnode = changed->node;
- lock = &rbtdb->node_locks[rbtnode->locknum].lock;
-
- NODE_LOCK(lock, isc_rwlocktype_write);
- /*
- * This is a good opportunity to purge any dead nodes,
- * so use it.
- */
- if (event == NULL)
- cleanup_dead_nodes(rbtdb, rbtnode->locknum);
-
- if (rollback)
- rollback_node(rbtnode, serial);
- decrement_reference(rbtdb, rbtnode, least_serial,
- isc_rwlocktype_write, tlock,
- ISC_FALSE);
-
- NODE_UNLOCK(lock, isc_rwlocktype_write);
-
- isc_mem_put(rbtdb->common.mctx, changed,
- sizeof(*changed));
- }
- if (event != NULL) {
- isc_refcount_increment(&rbtdb->references, NULL);
- isc_task_send(rbtdb->task, &event);
- } else
- RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
- }
-
- end:
- *versionp = NULL;
-}
-
-/*
- * Add the necessary magic for the wildcard name 'name'
- * to be found in 'rbtdb'.
- *
- * In order for wildcard matching to work correctly in
- * zone_find(), we must ensure that a node for the wildcarding
- * level exists in the database, and has its 'find_callback'
- * and 'wild' bits set.
- *
- * E.g. if the wildcard name is "*.sub.example." then we
- * must ensure that "sub.example." exists and is marked as
- * a wildcard level.
- */
-static isc_result_t
-add_wildcard_magic(dns_rbtdb_t *rbtdb, dns_name_t *name) {
- isc_result_t result;
- dns_name_t foundname;
- dns_offsets_t offsets;
- unsigned int n;
- dns_rbtnode_t *node = NULL;
-
- dns_name_init(&foundname, offsets);
- n = dns_name_countlabels(name);
- INSIST(n >= 2);
- n--;
- dns_name_getlabelsequence(name, 1, n, &foundname);
- result = dns_rbt_addnode(rbtdb->tree, &foundname, &node);
- if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS)
- return (result);
- if (result == ISC_R_SUCCESS)
- node->nsec = DNS_RBT_NSEC_NORMAL;
- node->find_callback = 1;
- node->wild = 1;
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-add_empty_wildcards(dns_rbtdb_t *rbtdb, dns_name_t *name) {
- isc_result_t result;
- dns_name_t foundname;
- dns_offsets_t offsets;
- unsigned int n, l, i;
-
- dns_name_init(&foundname, offsets);
- n = dns_name_countlabels(name);
- l = dns_name_countlabels(&rbtdb->common.origin);
- i = l + 1;
- while (i < n) {
- dns_rbtnode_t *node = NULL; /* dummy */
- dns_name_getlabelsequence(name, n - i, i, &foundname);
- if (dns_name_iswildcard(&foundname)) {
- result = add_wildcard_magic(rbtdb, &foundname);
- if (result != ISC_R_SUCCESS)
- return (result);
- result = dns_rbt_addnode(rbtdb->tree, &foundname,
- &node);
- if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS)
- return (result);
- if (result == ISC_R_SUCCESS)
- node->nsec = DNS_RBT_NSEC_NORMAL;
- }
- i++;
- }
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-findnodeintree(dns_rbtdb_t *rbtdb, dns_rbt_t *tree, dns_name_t *name,
- isc_boolean_t create, dns_dbnode_t **nodep)
-{
- dns_rbtnode_t *node = NULL;
- dns_name_t nodename;
- isc_result_t result;
- isc_rwlocktype_t locktype = isc_rwlocktype_read;
-
- INSIST(tree == rbtdb->tree || tree == rbtdb->nsec3);
-
- dns_name_init(&nodename, NULL);
- RWLOCK(&rbtdb->tree_lock, locktype);
- result = dns_rbt_findnode(tree, name, NULL, &node, NULL,
- DNS_RBTFIND_EMPTYDATA, NULL, NULL);
- if (result != ISC_R_SUCCESS) {
- RWUNLOCK(&rbtdb->tree_lock, locktype);
- if (!create) {
- if (result == DNS_R_PARTIALMATCH)
- result = ISC_R_NOTFOUND;
- return (result);
- }
- /*
- * It would be nice to try to upgrade the lock instead of
- * unlocking then relocking.
- */
- locktype = isc_rwlocktype_write;
- RWLOCK(&rbtdb->tree_lock, locktype);
- node = NULL;
- result = dns_rbt_addnode(tree, name, &node);
- if (result == ISC_R_SUCCESS) {
-#ifdef BIND9
- if (tree == rbtdb->tree && 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;
-#else
- node->locknum = dns_name_hash(&nodename, ISC_TRUE) %
- rbtdb->node_lock_count;
-#endif
- if (tree == rbtdb->tree) {
- add_empty_wildcards(rbtdb, name);
-
- if (dns_name_iswildcard(name)) {
- result = add_wildcard_magic(rbtdb, name);
- if (result != ISC_R_SUCCESS) {
- RWUNLOCK(&rbtdb->tree_lock, locktype);
- return (result);
- }
- }
- }
- if (tree == rbtdb->nsec3)
- node->nsec = DNS_RBT_NSEC_NSEC3;
- } else if (result != ISC_R_EXISTS) {
- RWUNLOCK(&rbtdb->tree_lock, locktype);
- return (result);
- }
- }
-
- if (tree == rbtdb->nsec3)
- INSIST(node->nsec == DNS_RBT_NSEC_NSEC3);
-
- reactivate_node(rbtdb, node, locktype);
- RWUNLOCK(&rbtdb->tree_lock, locktype);
-
- *nodep = (dns_dbnode_t *)node;
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
- dns_dbnode_t **nodep)
-{
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
-
- REQUIRE(VALID_RBTDB(rbtdb));
-
- return (findnodeintree(rbtdb, rbtdb->tree, name, create, nodep));
-}
-
-static isc_result_t
-findnsec3node(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
- dns_dbnode_t **nodep)
-{
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
-
- REQUIRE(VALID_RBTDB(rbtdb));
-
- return (findnodeintree(rbtdb, rbtdb->nsec3, name, create, nodep));
-}
-
-static isc_result_t
-zone_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) {
- rbtdb_search_t *search = arg;
- rdatasetheader_t *header, *header_next;
- rdatasetheader_t *dname_header, *sigdname_header, *ns_header;
- rdatasetheader_t *found;
- isc_result_t result;
- dns_rbtnode_t *onode;
-
- /*
- * We only want to remember the topmost zone cut, since it's the one
- * that counts, so we'll just continue if we've already found a
- * zonecut.
- */
- if (search->zonecut != NULL)
- return (DNS_R_CONTINUE);
-
- found = NULL;
- result = DNS_R_CONTINUE;
- onode = search->rbtdb->origin_node;
-
- NODE_LOCK(&(search->rbtdb->node_locks[node->locknum].lock),
- isc_rwlocktype_read);
-
- /*
- * Look for an NS or DNAME rdataset active in our version.
- */
- ns_header = NULL;
- dname_header = NULL;
- sigdname_header = NULL;
- for (header = node->data; header != NULL; header = header_next) {
- header_next = header->next;
- if (header->type == dns_rdatatype_ns ||
- header->type == dns_rdatatype_dname ||
- header->type == RBTDB_RDATATYPE_SIGDNAME) {
- do {
- if (header->serial <= search->serial &&
- !IGNORE(header)) {
- /*
- * Is this a "this rdataset doesn't
- * exist" record?
- */
- if (NONEXISTENT(header))
- header = NULL;
- break;
- } else
- header = header->down;
- } while (header != NULL);
- if (header != NULL) {
- if (header->type == dns_rdatatype_dname)
- dname_header = header;
- else if (header->type ==
- RBTDB_RDATATYPE_SIGDNAME)
- sigdname_header = header;
- else if (node != onode ||
- IS_STUB(search->rbtdb)) {
- /*
- * We've found an NS rdataset that
- * isn't at the origin node. We check
- * that they're not at the origin node,
- * because otherwise we'd erroneously
- * treat the zone top as if it were
- * a delegation.
- */
- ns_header = header;
- }
- }
- }
- }
-
- /*
- * Did we find anything?
- */
- if (!IS_CACHE(search->rbtdb) && !IS_STUB(search->rbtdb) &&
- ns_header != NULL) {
- /*
- * Note that NS has precedence over DNAME if both exist
- * in a zone. Otherwise DNAME take precedence over NS.
- */
- found = ns_header;
- search->zonecut_sigrdataset = NULL;
- } else if (dname_header != NULL) {
- found = dname_header;
- search->zonecut_sigrdataset = sigdname_header;
- } else if (ns_header != NULL) {
- found = ns_header;
- search->zonecut_sigrdataset = NULL;
- }
-
- if (found != NULL) {
- /*
- * We increment the reference count on node to ensure that
- * search->zonecut_rdataset will still be valid later.
- */
- new_reference(search->rbtdb, node);
- search->zonecut = node;
- search->zonecut_rdataset = found;
- search->need_cleanup = ISC_TRUE;
- /*
- * Since we've found a zonecut, anything beneath it is
- * glue and is not subject to wildcard matching, so we
- * may clear search->wild.
- */
- search->wild = ISC_FALSE;
- if ((search->options & DNS_DBFIND_GLUEOK) == 0) {
- /*
- * If the caller does not want to find glue, then
- * this is the best answer and the search should
- * stop now.
- */
- result = DNS_R_PARTIALMATCH;
- } else {
- dns_name_t *zcname;
-
- /*
- * The search will continue beneath the zone cut.
- * This may or may not be the best match. In case it
- * is, we need to remember the node name.
- */
- zcname = dns_fixedname_name(&search->zonecut_name);
- RUNTIME_CHECK(dns_name_copy(name, zcname, NULL) ==
- ISC_R_SUCCESS);
- search->copy_name = ISC_TRUE;
- }
- } else {
- /*
- * There is no zonecut at this node which is active in this
- * version.
- *
- * If this is a "wild" node and the caller hasn't disabled
- * wildcard matching, remember that we've seen a wild node
- * in case we need to go searching for wildcard matches
- * later on.
- */
- if (node->wild && (search->options & DNS_DBFIND_NOWILD) == 0)
- search->wild = ISC_TRUE;
- }
-
- NODE_UNLOCK(&(search->rbtdb->node_locks[node->locknum].lock),
- isc_rwlocktype_read);
-
- return (result);
-}
-
-static inline void
-bind_rdataset(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
- rdatasetheader_t *header, isc_stdtime_t now,
- dns_rdataset_t *rdataset)
-{
- unsigned char *raw; /* RDATASLAB */
-
- /*
- * Caller must be holding the node reader lock.
- * XXXJT: technically, we need a writer lock, since we'll increment
- * the header count below. However, since the actual counter value
- * doesn't matter, we prioritize performance here. (We may want to
- * use atomic increment when available).
- */
-
- if (rdataset == NULL)
- return;
-
- new_reference(rbtdb, node);
-
- INSIST(rdataset->methods == NULL); /* We must be disassociated. */
-
- rdataset->methods = &rdataset_methods;
- rdataset->rdclass = rbtdb->common.rdclass;
- rdataset->type = RBTDB_RDATATYPE_BASE(header->type);
- rdataset->covers = RBTDB_RDATATYPE_EXT(header->type);
- rdataset->ttl = header->rdh_ttl - now;
- rdataset->trust = header->trust;
- if (NEGATIVE(header))
- rdataset->attributes |= DNS_RDATASETATTR_NEGATIVE;
- if (NXDOMAIN(header))
- rdataset->attributes |= DNS_RDATASETATTR_NXDOMAIN;
- if (OPTOUT(header))
- rdataset->attributes |= DNS_RDATASETATTR_OPTOUT;
- rdataset->private1 = rbtdb;
- rdataset->private2 = node;
- raw = (unsigned char *)header + sizeof(*header);
- rdataset->private3 = raw;
- rdataset->count = header->count++;
- if (rdataset->count == ISC_UINT32_MAX)
- rdataset->count = 0;
-
- /*
- * Reset iterator state.
- */
- rdataset->privateuint4 = 0;
- rdataset->private5 = NULL;
-
- /*
- * Add noqname proof.
- */
- rdataset->private6 = header->noqname;
- if (rdataset->private6 != NULL)
- rdataset->attributes |= DNS_RDATASETATTR_NOQNAME;
- rdataset->private7 = header->closest;
- if (rdataset->private7 != NULL)
- rdataset->attributes |= DNS_RDATASETATTR_CLOSEST;
-
- /*
- * Copy out re-signing information.
- */
- if (RESIGN(header)) {
- rdataset->attributes |= DNS_RDATASETATTR_RESIGN;
- rdataset->resign = header->resign;
- } else
- rdataset->resign = 0;
-}
-
-static inline isc_result_t
-setup_delegation(rbtdb_search_t *search, dns_dbnode_t **nodep,
- dns_name_t *foundname, dns_rdataset_t *rdataset,
- dns_rdataset_t *sigrdataset)
-{
- isc_result_t result;
- dns_name_t *zcname;
- rbtdb_rdatatype_t type;
- dns_rbtnode_t *node;
-
- /*
- * The caller MUST NOT be holding any node locks.
- */
-
- node = search->zonecut;
- type = search->zonecut_rdataset->type;
-
- /*
- * If we have to set foundname, we do it before anything else.
- * If we were to set foundname after we had set nodep or bound the
- * rdataset, then we'd have to undo that work if dns_name_copy()
- * failed. By setting foundname first, there's nothing to undo if
- * we have trouble.
- */
- if (foundname != NULL && search->copy_name) {
- zcname = dns_fixedname_name(&search->zonecut_name);
- result = dns_name_copy(zcname, foundname, NULL);
- if (result != ISC_R_SUCCESS)
- return (result);
- }
- if (nodep != NULL) {
- /*
- * Note that we don't have to increment the node's reference
- * count here because we're going to use the reference we
- * already have in the search block.
- */
- *nodep = node;
- search->need_cleanup = ISC_FALSE;
- }
- if (rdataset != NULL) {
- NODE_LOCK(&(search->rbtdb->node_locks[node->locknum].lock),
- isc_rwlocktype_read);
- bind_rdataset(search->rbtdb, node, search->zonecut_rdataset,
- search->now, rdataset);
- if (sigrdataset != NULL && search->zonecut_sigrdataset != NULL)
- bind_rdataset(search->rbtdb, node,
- search->zonecut_sigrdataset,
- search->now, sigrdataset);
- NODE_UNLOCK(&(search->rbtdb->node_locks[node->locknum].lock),
- isc_rwlocktype_read);
- }
-
- if (type == dns_rdatatype_dname)
- return (DNS_R_DNAME);
- return (DNS_R_DELEGATION);
-}
-
-static inline isc_boolean_t
-valid_glue(rbtdb_search_t *search, dns_name_t *name, rbtdb_rdatatype_t type,
- dns_rbtnode_t *node)
-{
- unsigned char *raw; /* RDATASLAB */
- unsigned int count, size;
- dns_name_t ns_name;
- isc_boolean_t valid = ISC_FALSE;
- dns_offsets_t offsets;
- isc_region_t region;
- rdatasetheader_t *header;
-
- /*
- * No additional locking is required.
- */
-
- /*
- * Valid glue types are A, AAAA, A6. NS is also a valid glue type
- * if it occurs at a zone cut, but is not valid below it.
- */
- if (type == dns_rdatatype_ns) {
- if (node != search->zonecut) {
- return (ISC_FALSE);
- }
- } else if (type != dns_rdatatype_a &&
- type != dns_rdatatype_aaaa &&
- type != dns_rdatatype_a6) {
- return (ISC_FALSE);
- }
-
- header = search->zonecut_rdataset;
- raw = (unsigned char *)header + sizeof(*header);
- count = raw[0] * 256 + raw[1];
-#if DNS_RDATASET_FIXED
- raw += 2 + (4 * count);
-#else
- raw += 2;
-#endif
-
- while (count > 0) {
- count--;
- size = raw[0] * 256 + raw[1];
-#if DNS_RDATASET_FIXED
- raw += 4;
-#else
- raw += 2;
-#endif
- region.base = raw;
- region.length = size;
- raw += size;
- /*
- * XXX Until we have rdata structures, we have no choice but
- * to directly access the rdata format.
- */
- dns_name_init(&ns_name, offsets);
- dns_name_fromregion(&ns_name, &region);
- if (dns_name_compare(&ns_name, name) == 0) {
- valid = ISC_TRUE;
- break;
- }
- }
-
- return (valid);
-}
-
-static inline isc_boolean_t
-activeempty(rbtdb_search_t *search, dns_rbtnodechain_t *chain,
- dns_name_t *name)
-{
- dns_fixedname_t fnext;
- dns_fixedname_t forigin;
- dns_name_t *next;
- dns_name_t *origin;
- dns_name_t prefix;
- dns_rbtdb_t *rbtdb;
- dns_rbtnode_t *node;
- isc_result_t result;
- isc_boolean_t answer = ISC_FALSE;
- rdatasetheader_t *header;
-
- rbtdb = search->rbtdb;
-
- dns_name_init(&prefix, NULL);
- dns_fixedname_init(&fnext);
- next = dns_fixedname_name(&fnext);
- dns_fixedname_init(&forigin);
- origin = dns_fixedname_name(&forigin);
-
- result = dns_rbtnodechain_next(chain, NULL, NULL);
- while (result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN) {
- node = NULL;
- result = dns_rbtnodechain_current(chain, &prefix,
- origin, &node);
- if (result != ISC_R_SUCCESS)
- break;
- NODE_LOCK(&(rbtdb->node_locks[node->locknum].lock),
- isc_rwlocktype_read);
- for (header = node->data;
- header != NULL;
- header = header->next) {
- if (header->serial <= search->serial &&
- !IGNORE(header) && EXISTS(header))
- break;
- }
- NODE_UNLOCK(&(rbtdb->node_locks[node->locknum].lock),
- isc_rwlocktype_read);
- if (header != NULL)
- break;
- result = dns_rbtnodechain_next(chain, NULL, NULL);
- }
- if (result == ISC_R_SUCCESS)
- result = dns_name_concatenate(&prefix, origin, next, NULL);
- if (result == ISC_R_SUCCESS && dns_name_issubdomain(next, name))
- answer = ISC_TRUE;
- return (answer);
-}
-
-static inline isc_boolean_t
-activeemtpynode(rbtdb_search_t *search, dns_name_t *qname, dns_name_t *wname) {
- dns_fixedname_t fnext;
- dns_fixedname_t forigin;
- dns_fixedname_t fprev;
- dns_name_t *next;
- dns_name_t *origin;
- dns_name_t *prev;
- dns_name_t name;
- dns_name_t rname;
- dns_name_t tname;
- dns_rbtdb_t *rbtdb;
- dns_rbtnode_t *node;
- dns_rbtnodechain_t chain;
- isc_boolean_t check_next = ISC_TRUE;
- isc_boolean_t check_prev = ISC_TRUE;
- isc_boolean_t answer = ISC_FALSE;
- isc_result_t result;
- rdatasetheader_t *header;
- unsigned int n;
-
- rbtdb = search->rbtdb;
-
- dns_name_init(&name, NULL);
- dns_name_init(&tname, NULL);
- dns_name_init(&rname, NULL);
- dns_fixedname_init(&fnext);
- next = dns_fixedname_name(&fnext);
- dns_fixedname_init(&fprev);
- prev = dns_fixedname_name(&fprev);
- dns_fixedname_init(&forigin);
- origin = dns_fixedname_name(&forigin);
-
- /*
- * Find if qname is at or below a empty node.
- * Use our own copy of the chain.
- */
-
- chain = search->chain;
- do {
- node = NULL;
- result = dns_rbtnodechain_current(&chain, &name,
- origin, &node);
- if (result != ISC_R_SUCCESS)
- break;
- NODE_LOCK(&(rbtdb->node_locks[node->locknum].lock),
- isc_rwlocktype_read);
- for (header = node->data;
- header != NULL;
- header = header->next) {
- if (header->serial <= search->serial &&
- !IGNORE(header) && EXISTS(header))
- break;
- }
- NODE_UNLOCK(&(rbtdb->node_locks[node->locknum].lock),
- isc_rwlocktype_read);
- if (header != NULL)
- break;
- result = dns_rbtnodechain_prev(&chain, NULL, NULL);
- } while (result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN);
- if (result == ISC_R_SUCCESS)
- result = dns_name_concatenate(&name, origin, prev, NULL);
- if (result != ISC_R_SUCCESS)
- check_prev = ISC_FALSE;
-
- result = dns_rbtnodechain_next(&chain, NULL, NULL);
- while (result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN) {
- node = NULL;
- result = dns_rbtnodechain_current(&chain, &name,
- origin, &node);
- if (result != ISC_R_SUCCESS)
- break;
- NODE_LOCK(&(rbtdb->node_locks[node->locknum].lock),
- isc_rwlocktype_read);
- for (header = node->data;
- header != NULL;
- header = header->next) {
- if (header->serial <= search->serial &&
- !IGNORE(header) && EXISTS(header))
- break;
- }
- NODE_UNLOCK(&(rbtdb->node_locks[node->locknum].lock),
- isc_rwlocktype_read);
- if (header != NULL)
- break;
- result = dns_rbtnodechain_next(&chain, NULL, NULL);
- }
- if (result == ISC_R_SUCCESS)
- result = dns_name_concatenate(&name, origin, next, NULL);
- if (result != ISC_R_SUCCESS)
- check_next = ISC_FALSE;
-
- dns_name_clone(qname, &rname);
-
- /*
- * Remove the wildcard label to find the terminal name.
- */
- n = dns_name_countlabels(wname);
- dns_name_getlabelsequence(wname, 1, n - 1, &tname);
-
- do {
- if ((check_prev && dns_name_issubdomain(prev, &rname)) ||
- (check_next && dns_name_issubdomain(next, &rname))) {
- answer = ISC_TRUE;
- break;
- }
- /*
- * Remove the left hand label.
- */
- n = dns_name_countlabels(&rname);
- dns_name_getlabelsequence(&rname, 1, n - 1, &rname);
- } while (!dns_name_equal(&rname, &tname));
- return (answer);
-}
-
-static inline isc_result_t
-find_wildcard(rbtdb_search_t *search, dns_rbtnode_t **nodep,
- dns_name_t *qname)
-{
- unsigned int i, j;
- dns_rbtnode_t *node, *level_node, *wnode;
- rdatasetheader_t *header;
- isc_result_t result = ISC_R_NOTFOUND;
- dns_name_t name;
- dns_name_t *wname;
- dns_fixedname_t fwname;
- dns_rbtdb_t *rbtdb;
- isc_boolean_t done, wild, active;
- dns_rbtnodechain_t wchain;
-
- /*
- * Caller must be holding the tree lock and MUST NOT be holding
- * any node locks.
- */
-
- /*
- * Examine each ancestor level. If the level's wild bit
- * is set, then construct the corresponding wildcard name and
- * search for it. If the wildcard node exists, and is active in
- * this version, we're done. If not, then we next check to see
- * if the ancestor is active in this version. If so, then there
- * can be no possible wildcard match and again we're done. If not,
- * continue the search.
- */
-
- rbtdb = search->rbtdb;
- i = search->chain.level_matches;
- done = ISC_FALSE;
- node = *nodep;
- do {
- NODE_LOCK(&(rbtdb->node_locks[node->locknum].lock),
- isc_rwlocktype_read);
-
- /*
- * First we try to figure out if this node is active in
- * the search's version. We do this now, even though we
- * may not need the information, because it simplifies the
- * locking and code flow.
- */
- for (header = node->data;
- header != NULL;
- header = header->next) {
- if (header->serial <= search->serial &&
- !IGNORE(header) && EXISTS(header))
- break;
- }
- if (header != NULL)
- active = ISC_TRUE;
- else
- active = ISC_FALSE;
-
- if (node->wild)
- wild = ISC_TRUE;
- else
- wild = ISC_FALSE;
-
- NODE_UNLOCK(&(rbtdb->node_locks[node->locknum].lock),
- isc_rwlocktype_read);
-
- if (wild) {
- /*
- * Construct the wildcard name for this level.
- */
- dns_name_init(&name, NULL);
- dns_rbt_namefromnode(node, &name);
- dns_fixedname_init(&fwname);
- wname = dns_fixedname_name(&fwname);
- result = dns_name_concatenate(dns_wildcardname, &name,
- wname, NULL);
- j = i;
- while (result == ISC_R_SUCCESS && j != 0) {
- j--;
- level_node = search->chain.levels[j];
- dns_name_init(&name, NULL);
- dns_rbt_namefromnode(level_node, &name);
- result = dns_name_concatenate(wname,
- &name,
- wname,
- NULL);
- }
- if (result != ISC_R_SUCCESS)
- break;
-
- wnode = NULL;
- dns_rbtnodechain_init(&wchain, NULL);
- result = dns_rbt_findnode(rbtdb->tree, wname,
- NULL, &wnode, &wchain,
- DNS_RBTFIND_EMPTYDATA,
- NULL, NULL);
- if (result == ISC_R_SUCCESS) {
- nodelock_t *lock;
-
- /*
- * We have found the wildcard node. If it
- * is active in the search's version, we're
- * done.
- */
- lock = &rbtdb->node_locks[wnode->locknum].lock;
- NODE_LOCK(lock, isc_rwlocktype_read);
- for (header = wnode->data;
- header != NULL;
- header = header->next) {
- if (header->serial <= search->serial &&
- !IGNORE(header) && EXISTS(header))
- break;
- }
- NODE_UNLOCK(lock, isc_rwlocktype_read);
- if (header != NULL ||
- activeempty(search, &wchain, wname)) {
- if (activeemtpynode(search, qname,
- wname)) {
- return (ISC_R_NOTFOUND);
- }
- /*
- * The wildcard node is active!
- *
- * Note: result is still ISC_R_SUCCESS
- * so we don't have to set it.
- */
- *nodep = wnode;
- break;
- }
- } else if (result != ISC_R_NOTFOUND &&
- result != DNS_R_PARTIALMATCH) {
- /*
- * An error has occurred. Bail out.
- */
- break;
- }
- }
-
- if (active) {
- /*
- * The level node is active. Any wildcarding
- * present at higher levels has no
- * effect and we're done.
- */
- result = ISC_R_NOTFOUND;
- break;
- }
-
- if (i > 0) {
- i--;
- node = search->chain.levels[i];
- } else
- done = ISC_TRUE;
- } while (!done);
-
- return (result);
-}
-
-static isc_boolean_t
-matchparams(rdatasetheader_t *header, rbtdb_search_t *search)
-{
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdata_nsec3_t nsec3;
- unsigned char *raw; /* RDATASLAB */
- unsigned int rdlen, count;
- isc_region_t region;
- isc_result_t result;
-
- REQUIRE(header->type == dns_rdatatype_nsec3);
-
- raw = (unsigned char *)header + sizeof(*header);
- count = raw[0] * 256 + raw[1]; /* count */
-#if DNS_RDATASET_FIXED
- raw += count * 4 + 2;
-#else
- raw += 2;
-#endif
- while (count-- > 0) {
- rdlen = raw[0] * 256 + raw[1];
-#if DNS_RDATASET_FIXED
- raw += 4;
-#else
- raw += 2;
-#endif
- region.base = raw;
- region.length = rdlen;
- dns_rdata_fromregion(&rdata, search->rbtdb->common.rdclass,
- dns_rdatatype_nsec3, &region);
- raw += rdlen;
- result = dns_rdata_tostruct(&rdata, &nsec3, NULL);
- INSIST(result == ISC_R_SUCCESS);
- if (nsec3.hash == search->rbtversion->hash &&
- nsec3.iterations == search->rbtversion->iterations &&
- nsec3.salt_length == search->rbtversion->salt_length &&
- memcmp(nsec3.salt, search->rbtversion->salt,
- nsec3.salt_length) == 0)
- return (ISC_TRUE);
- dns_rdata_reset(&rdata);
- }
- return (ISC_FALSE);
-}
-
-/*
- * 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, *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;
- dns_name_t *name, *origin;
- 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) {
- type = dns_rdatatype_nsec3;
- sigtype = RBTDB_RDATATYPE_SIGNSEC3;
- wraps = ISC_TRUE;
- } else {
- type = dns_rdatatype_nsec;
- sigtype = RBTDB_RDATATYPE_SIGNSEC;
- 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_LOCK(&(search->rbtdb->node_locks[node->locknum].lock),
- isc_rwlocktype_read);
- found = NULL;
- foundsig = NULL;
- empty_node = ISC_TRUE;
- for (header = node->data;
- header != NULL;
- header = header_next) {
- header_next = header->next;
- /*
- * Look for an active, extant NSEC or RRSIG NSEC.
- */
- do {
- if (header->serial <= search->serial &&
- !IGNORE(header)) {
- /*
- * Is this a "this rdataset doesn't
- * exist" record?
- */
- if (NONEXISTENT(header))
- header = NULL;
- break;
- } else
- header = header->down;
- } while (header != NULL);
- if (header != NULL) {
- /*
- * We now know that there is at least one
- * active rdataset at this node.
- */
- empty_node = ISC_FALSE;
- if (header->type == type) {
- found = header;
- if (foundsig != NULL)
- break;
- } else if (header->type == sigtype) {
- foundsig = header;
- if (found != NULL)
- break;
- }
- }
- }
- if (!empty_node) {
- if (found != NULL && search->rbtversion->havensec3 &&
- found->type == dns_rdatatype_nsec3 &&
- !matchparams(found, search)) {
- empty_node = ISC_TRUE;
- found = NULL;
- foundsig = NULL;
- result = previous_closest_nsec(type, search,
- name, origin,
- &prevnode, NULL,
- NULL);
- } else if (found != NULL &&
- (foundsig != NULL || !need_sig)) {
- /*
- * We've found the right NSEC/NSEC3 record.
- *
- * Note: for this to really be the right
- * NSEC record, it's essential that the NSEC
- * records of any nodes obscured by a zone
- * cut have been removed; we assume this is
- * the case.
- */
- result = dns_name_concatenate(name, origin,
- foundname, NULL);
- if (result == ISC_R_SUCCESS) {
- if (nodep != NULL) {
- new_reference(search->rbtdb,
- node);
- *nodep = node;
- }
- bind_rdataset(search->rbtdb, node,
- found, search->now,
- rdataset);
- if (foundsig != NULL)
- bind_rdataset(search->rbtdb,
- node,
- foundsig,
- search->now,
- sigrdataset);
- }
- } else if (found == NULL && foundsig == NULL) {
- /*
- * This node is active, but has no NSEC or
- * RRSIG NSEC. That means it's glue or
- * other obscured zone data that isn't
- * relevant for our search. Treat the
- * node as if it were empty and keep looking.
- */
- empty_node = ISC_TRUE;
- result = previous_closest_nsec(type, search,
- name, origin,
- &prevnode,
- &nsecchain,
- &first);
- } else {
- /*
- * We found an active node, but either the
- * NSEC or the RRSIG NSEC is missing. This
- * shouldn't happen.
- */
- result = DNS_R_BADDB;
- }
- } else {
- /*
- * This node isn't active. We've got to keep
- * looking.
- */
- 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);
- if (result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN) {
- wraps = ISC_FALSE;
- goto again;
- }
- }
-
- /*
- * If the result is ISC_R_NOMORE, then we got to the beginning of
- * the database and didn't find a NSEC record. This shouldn't
- * happen.
- */
- if (result == ISC_R_NOMORE)
- result = DNS_R_BADDB;
-
- return (result);
-}
-
-static isc_result_t
-zone_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_rbtnode_t *node = NULL;
- isc_result_t result;
- rbtdb_search_t search;
- isc_boolean_t cname_ok = ISC_TRUE;
- isc_boolean_t close_version = ISC_FALSE;
- isc_boolean_t maybe_zonecut = ISC_FALSE;
- isc_boolean_t at_zonecut = ISC_FALSE;
- isc_boolean_t wild;
- isc_boolean_t empty_node;
- rdatasetheader_t *header, *header_next, *found, *nsecheader;
- rdatasetheader_t *foundsig, *cnamesig, *nsecsig;
- rbtdb_rdatatype_t sigtype;
- isc_boolean_t active;
- dns_rbtnodechain_t chain;
- nodelock_t *lock;
- dns_rbt_t *tree;
-
- search.rbtdb = (dns_rbtdb_t *)db;
-
- REQUIRE(VALID_RBTDB(search.rbtdb));
- INSIST(version == NULL ||
- ((rbtdb_version_t *)version)->rbtdb == (dns_rbtdb_t *)db);
-
- /*
- * We don't care about 'now'.
- */
- UNUSED(now);
-
- /*
- * If the caller didn't supply a version, attach to the current
- * version.
- */
- if (version == NULL) {
- currentversion(db, &version);
- close_version = ISC_TRUE;
- }
-
- search.rbtversion = version;
- search.serial = search.rbtversion->serial;
- search.options = options;
- search.copy_name = ISC_FALSE;
- search.need_cleanup = ISC_FALSE;
- search.wild = ISC_FALSE;
- search.zonecut = NULL;
- dns_fixedname_init(&search.zonecut_name);
- dns_rbtnodechain_init(&search.chain, search.rbtdb->common.mctx);
- search.now = 0;
-
- /*
- * 'wild' will be true iff. we've matched a wildcard.
- */
- wild = ISC_FALSE;
-
- RWLOCK(&search.rbtdb->tree_lock, isc_rwlocktype_read);
-
- /*
- * Search down from the root of the tree. If, while going down, we
- * encounter a callback node, zone_zonecut_callback() will search the
- * rdatasets at the zone cut for active DNAME or NS rdatasets.
- */
- tree = (options & DNS_DBFIND_FORCENSEC3) != 0 ? search.rbtdb->nsec3 :
- search.rbtdb->tree;
- result = dns_rbt_findnode(tree, name, foundname, &node,
- &search.chain, DNS_RBTFIND_EMPTYDATA,
- zone_zonecut_callback, &search);
-
- if (result == DNS_R_PARTIALMATCH) {
- partial_match:
- if (search.zonecut != NULL) {
- result = setup_delegation(&search, nodep, foundname,
- rdataset, sigrdataset);
- goto tree_exit;
- }
-
- if (search.wild) {
- /*
- * At least one of the levels in the search chain
- * potentially has a wildcard. For each such level,
- * we must see if there's a matching wildcard active
- * in the current version.
- */
- result = find_wildcard(&search, &node, name);
- if (result == ISC_R_SUCCESS) {
- result = dns_name_copy(name, foundname, NULL);
- if (result != ISC_R_SUCCESS)
- goto tree_exit;
- wild = ISC_TRUE;
- goto found;
- }
- else if (result != ISC_R_NOTFOUND)
- goto tree_exit;
- }
-
- chain = search.chain;
- active = activeempty(&search, &chain, name);
-
- /*
- * If we're here, then the name does not exist, is not
- * beneath a zonecut, and there's no matching wildcard.
- */
- if ((search.rbtversion->secure == dns_db_secure &&
- !search.rbtversion->havensec3) ||
- (search.options & DNS_DBFIND_FORCENSEC) != 0 ||
- (search.options & DNS_DBFIND_FORCENSEC3) != 0)
- {
- result = find_closest_nsec(&search, nodep, foundname,
- rdataset, sigrdataset, tree,
- search.rbtversion->secure);
- if (result == ISC_R_SUCCESS)
- result = active ? DNS_R_EMPTYNAME :
- DNS_R_NXDOMAIN;
- } else
- result = active ? DNS_R_EMPTYNAME : DNS_R_NXDOMAIN;
- goto tree_exit;
- } else if (result != ISC_R_SUCCESS)
- goto tree_exit;
-
- found:
- /*
- * We have found a node whose name is the desired name, or we
- * have matched a wildcard.
- */
-
- if (search.zonecut != NULL) {
- /*
- * If we're beneath a zone cut, we don't want to look for
- * CNAMEs because they're not legitimate zone glue.
- */
- cname_ok = ISC_FALSE;
- } else {
- /*
- * The node may be a zone cut itself. If it might be one,
- * make sure we check for it later.
- *
- * DS records live above the zone cut in ordinary zone so
- * we want to ignore any referral.
- *
- * Stub zones don't have anything "above" the delgation so
- * we always return a referral.
- */
- if (node->find_callback &&
- ((node != search.rbtdb->origin_node &&
- !dns_rdatatype_atparent(type)) ||
- IS_STUB(search.rbtdb)))
- maybe_zonecut = ISC_TRUE;
- }
-
- /*
- * Certain DNSSEC types are not subject to CNAME matching
- * (RFC4035, section 2.5 and RFC3007).
- *
- * We don't check for RRSIG, because we don't store RRSIG records
- * directly.
- */
- if (type == dns_rdatatype_key || type == dns_rdatatype_nsec)
- cname_ok = ISC_FALSE;
-
- /*
- * We now go looking for rdata...
- */
-
- lock = &search.rbtdb->node_locks[node->locknum].lock;
- NODE_LOCK(lock, isc_rwlocktype_read);
-
- found = NULL;
- foundsig = NULL;
- sigtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, type);
- nsecheader = NULL;
- nsecsig = NULL;
- cnamesig = NULL;
- empty_node = ISC_TRUE;
- for (header = node->data; header != NULL; header = header_next) {
- header_next = header->next;
- /*
- * Look for an active, extant rdataset.
- */
- do {
- if (header->serial <= search.serial &&
- !IGNORE(header)) {
- /*
- * Is this a "this rdataset doesn't
- * exist" record?
- */
- if (NONEXISTENT(header))
- header = NULL;
- break;
- } else
- header = header->down;
- } while (header != NULL);
- if (header != NULL) {
- /*
- * We now know that there is at least one active
- * rdataset at this node.
- */
- empty_node = ISC_FALSE;
-
- /*
- * Do special zone cut handling, if requested.
- */
- if (maybe_zonecut &&
- header->type == dns_rdatatype_ns) {
- /*
- * We increment the reference count on node to
- * ensure that search->zonecut_rdataset will
- * still be valid later.
- */
- new_reference(search.rbtdb, node);
- search.zonecut = node;
- search.zonecut_rdataset = header;
- search.zonecut_sigrdataset = NULL;
- search.need_cleanup = ISC_TRUE;
- maybe_zonecut = ISC_FALSE;
- at_zonecut = ISC_TRUE;
- /*
- * It is not clear if KEY should still be
- * allowed at the parent side of the zone
- * cut or not. It is needed for RFC3007
- * validated updates.
- */
- if ((search.options & DNS_DBFIND_GLUEOK) == 0
- && type != dns_rdatatype_nsec
- && type != dns_rdatatype_key) {
- /*
- * Glue is not OK, but any answer we
- * could return would be glue. Return
- * the delegation.
- */
- found = NULL;
- break;
- }
- if (found != NULL && foundsig != NULL)
- break;
- }
-
-
- /*
- * If the NSEC3 record doesn't match the chain
- * we are using behave as if it isn't here.
- */
- if (header->type == dns_rdatatype_nsec3 &&
- !matchparams(header, &search)) {
- NODE_UNLOCK(lock, isc_rwlocktype_read);
- goto partial_match;
- }
- /*
- * If we found a type we were looking for,
- * remember it.
- */
- if (header->type == type ||
- type == dns_rdatatype_any ||
- (header->type == dns_rdatatype_cname &&
- cname_ok)) {
- /*
- * We've found the answer!
- */
- found = header;
- if (header->type == dns_rdatatype_cname &&
- cname_ok) {
- /*
- * We may be finding a CNAME instead
- * of the desired type.
- *
- * If we've already got the CNAME RRSIG,
- * use it, otherwise change sigtype
- * so that we find it.
- */
- if (cnamesig != NULL)
- foundsig = cnamesig;
- else
- sigtype =
- RBTDB_RDATATYPE_SIGCNAME;
- }
- /*
- * If we've got all we need, end the search.
- */
- if (!maybe_zonecut && foundsig != NULL)
- break;
- } else if (header->type == sigtype) {
- /*
- * We've found the RRSIG rdataset for our
- * target type. Remember it.
- */
- foundsig = header;
- /*
- * If we've got all we need, end the search.
- */
- if (!maybe_zonecut && found != NULL)
- break;
- } else if (header->type == dns_rdatatype_nsec &&
- !search.rbtversion->havensec3) {
- /*
- * Remember a NSEC rdataset even if we're
- * not specifically looking for it, because
- * we might need it later.
- */
- nsecheader = header;
- } else if (header->type == RBTDB_RDATATYPE_SIGNSEC &&
- !search.rbtversion->havensec3) {
- /*
- * If we need the NSEC rdataset, we'll also
- * need its signature.
- */
- nsecsig = header;
- } else if (cname_ok &&
- header->type == RBTDB_RDATATYPE_SIGCNAME) {
- /*
- * If we get a CNAME match, we'll also need
- * its signature.
- */
- cnamesig = header;
- }
- }
- }
-
- if (empty_node) {
- /*
- * We have an exact match for the name, but there are no
- * active rdatasets in the desired version. That means that
- * this node doesn't exist in the desired version, and that
- * we really have a partial match.
- */
- if (!wild) {
- NODE_UNLOCK(lock, isc_rwlocktype_read);
- goto partial_match;
- }
- }
-
- /*
- * If we didn't find what we were looking for...
- */
- if (found == NULL) {
- if (search.zonecut != NULL) {
- /*
- * We were trying to find glue at a node beneath a
- * zone cut, but didn't.
- *
- * Return the delegation.
- */
- NODE_UNLOCK(lock, isc_rwlocktype_read);
- result = setup_delegation(&search, nodep, foundname,
- rdataset, sigrdataset);
- goto tree_exit;
- }
- /*
- * The desired type doesn't exist.
- */
- result = DNS_R_NXRRSET;
- if (search.rbtversion->secure == dns_db_secure &&
- !search.rbtversion->havensec3 &&
- (nsecheader == NULL || nsecsig == NULL)) {
- /*
- * The zone is secure but there's no NSEC,
- * or the NSEC has no signature!
- */
- if (!wild) {
- result = DNS_R_BADDB;
- goto node_exit;
- }
-
- NODE_UNLOCK(lock, isc_rwlocktype_read);
- result = find_closest_nsec(&search, nodep, foundname,
- rdataset, sigrdataset,
- search.rbtdb->tree,
- search.rbtversion->secure);
- if (result == ISC_R_SUCCESS)
- result = DNS_R_EMPTYWILD;
- goto tree_exit;
- }
- if ((search.options & DNS_DBFIND_FORCENSEC) != 0 &&
- nsecheader == NULL)
- {
- /*
- * There's no NSEC record, and we were told
- * to find one.
- */
- result = DNS_R_BADDB;
- goto node_exit;
- }
- if (nodep != NULL) {
- new_reference(search.rbtdb, node);
- *nodep = node;
- }
- if ((search.rbtversion->secure == dns_db_secure &&
- !search.rbtversion->havensec3) ||
- (search.options & DNS_DBFIND_FORCENSEC) != 0)
- {
- bind_rdataset(search.rbtdb, node, nsecheader,
- 0, rdataset);
- if (nsecsig != NULL)
- bind_rdataset(search.rbtdb, node,
- nsecsig, 0, sigrdataset);
- }
- if (wild)
- foundname->attributes |= DNS_NAMEATTR_WILDCARD;
- goto node_exit;
- }
-
- /*
- * We found what we were looking for, or we found a CNAME.
- */
-
- if (type != found->type &&
- type != dns_rdatatype_any &&
- found->type == dns_rdatatype_cname) {
- /*
- * We weren't doing an ANY query and we found a CNAME instead
- * of the type we were looking for, so we need to indicate
- * that result to the caller.
- */
- result = DNS_R_CNAME;
- } else if (search.zonecut != NULL) {
- /*
- * If we're beneath a zone cut, we must indicate that the
- * result is glue, unless we're actually at the zone cut
- * and the type is NSEC or KEY.
- */
- if (search.zonecut == node) {
- /*
- * It is not clear if KEY should still be
- * allowed at the parent side of the zone
- * cut or not. It is needed for RFC3007
- * validated updates.
- */
- if (type == dns_rdatatype_nsec ||
- type == dns_rdatatype_nsec3 ||
- type == dns_rdatatype_key)
- result = ISC_R_SUCCESS;
- else if (type == dns_rdatatype_any)
- result = DNS_R_ZONECUT;
- else
- result = DNS_R_GLUE;
- } else
- result = DNS_R_GLUE;
- /*
- * We might have found data that isn't glue, but was occluded
- * by a dynamic update. If the caller cares about this, they
- * will have told us to validate glue.
- *
- * XXX We should cache the glue validity state!
- */
- if (result == DNS_R_GLUE &&
- (search.options & DNS_DBFIND_VALIDATEGLUE) != 0 &&
- !valid_glue(&search, foundname, type, node)) {
- NODE_UNLOCK(lock, isc_rwlocktype_read);
- result = setup_delegation(&search, nodep, foundname,
- rdataset, sigrdataset);
- goto tree_exit;
- }
- } else {
- /*
- * An ordinary successful query!
- */
- result = ISC_R_SUCCESS;
- }
-
- if (nodep != NULL) {
- if (!at_zonecut)
- new_reference(search.rbtdb, node);
- else
- search.need_cleanup = ISC_FALSE;
- *nodep = node;
- }
-
- if (type != dns_rdatatype_any) {
- bind_rdataset(search.rbtdb, node, found, 0, rdataset);
- if (foundsig != NULL)
- bind_rdataset(search.rbtdb, node, foundsig, 0,
- sigrdataset);
- }
-
- if (wild)
- foundname->attributes |= DNS_NAMEATTR_WILDCARD;
-
- node_exit:
- NODE_UNLOCK(lock, isc_rwlocktype_read);
-
- tree_exit:
- RWUNLOCK(&search.rbtdb->tree_lock, isc_rwlocktype_read);
-
- /*
- * If we found a zonecut but aren't going to use it, we have to
- * let go of it.
- */
- if (search.need_cleanup) {
- node = search.zonecut;
- INSIST(node != NULL);
- lock = &(search.rbtdb->node_locks[node->locknum].lock);
-
- NODE_LOCK(lock, isc_rwlocktype_read);
- decrement_reference(search.rbtdb, node, 0,
- isc_rwlocktype_read, isc_rwlocktype_none,
- ISC_FALSE);
- NODE_UNLOCK(lock, isc_rwlocktype_read);
- }
-
- if (close_version)
- closeversion(db, &version, ISC_FALSE);
-
- dns_rbtnodechain_reset(&search.chain);
-
- return (result);
-}
-
-static isc_result_t
-zone_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)
-{
- UNUSED(db);
- UNUSED(name);
- UNUSED(options);
- UNUSED(now);
- UNUSED(nodep);
- UNUSED(foundname);
- UNUSED(rdataset);
- UNUSED(sigrdataset);
-
- FATAL_ERROR(__FILE__, __LINE__, "zone_findzonecut() called!");
-
- /* NOTREACHED */
- return (ISC_R_NOTIMPLEMENTED);
-}
-
-static isc_result_t
-cache_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) {
- rbtdb_search_t *search = arg;
- rdatasetheader_t *header, *header_prev, *header_next;
- rdatasetheader_t *dname_header, *sigdname_header;
- isc_result_t result;
- nodelock_t *lock;
- isc_rwlocktype_t locktype;
-
- /* XXX comment */
-
- REQUIRE(search->zonecut == NULL);
-
- /*
- * Keep compiler silent.
- */
- UNUSED(name);
-
- lock = &(search->rbtdb->node_locks[node->locknum].lock);
- locktype = isc_rwlocktype_read;
- NODE_LOCK(lock, locktype);
-
- /*
- * Look for a DNAME or RRSIG DNAME rdataset.
- */
- dname_header = NULL;
- sigdname_header = NULL;
- header_prev = NULL;
- for (header = node->data; header != NULL; header = header_next) {
- header_next = header->next;
- if (header->rdh_ttl <= search->now) {
- /*
- * This rdataset is stale. If no one else is
- * using the node, we can clean it up right
- * now, otherwise we mark it as stale, and
- * the node as dirty, so it will get cleaned
- * up later.
- */
- if ((header->rdh_ttl <= search->now - RBTDB_VIRTUAL) &&
- (locktype == isc_rwlocktype_write ||
- NODE_TRYUPGRADE(lock) == ISC_R_SUCCESS)) {
- /*
- * We update the node's status only when we
- * can get write access; otherwise, we leave
- * others to this work. Periodical cleaning
- * will eventually take the job as the last
- * resort.
- * We won't downgrade the lock, since other
- * rdatasets are probably stale, too.
- */
- locktype = isc_rwlocktype_write;
-
- if (dns_rbtnode_refcurrent(node) == 0) {
- isc_mem_t *mctx;
-
- /*
- * header->down can be non-NULL if the
- * refcount has just decremented to 0
- * but decrement_reference() has not
- * performed clean_cache_node(), in
- * which case we need to purge the
- * stale headers first.
- */
- mctx = search->rbtdb->common.mctx;
- clean_stale_headers(search->rbtdb,
- mctx,
- header);
- if (header_prev != NULL)
- header_prev->next =
- header->next;
- else
- node->data = header->next;
- free_rdataset(search->rbtdb, mctx,
- header);
- } else {
- header->attributes |=
- RDATASET_ATTR_STALE;
- node->dirty = 1;
- header_prev = header;
- }
- } else
- header_prev = header;
- } else if (header->type == dns_rdatatype_dname &&
- EXISTS(header)) {
- dname_header = header;
- header_prev = header;
- } else if (header->type == RBTDB_RDATATYPE_SIGDNAME &&
- EXISTS(header)) {
- sigdname_header = header;
- header_prev = header;
- } else
- header_prev = header;
- }
-
- if (dname_header != NULL &&
- (!DNS_TRUST_PENDING(dname_header->trust) ||
- (search->options & DNS_DBFIND_PENDINGOK) != 0)) {
- /*
- * We increment the reference count on node to ensure that
- * search->zonecut_rdataset will still be valid later.
- */
- new_reference(search->rbtdb, node);
- INSIST(!ISC_LINK_LINKED(node, deadlink));
- search->zonecut = node;
- search->zonecut_rdataset = dname_header;
- search->zonecut_sigrdataset = sigdname_header;
- search->need_cleanup = ISC_TRUE;
- result = DNS_R_PARTIALMATCH;
- } else
- result = DNS_R_CONTINUE;
-
- NODE_UNLOCK(lock, locktype);
-
- return (result);
-}
-
-static inline isc_result_t
-find_deepest_zonecut(rbtdb_search_t *search, dns_rbtnode_t *node,
- dns_dbnode_t **nodep, dns_name_t *foundname,
- dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
-{
- unsigned int i;
- dns_rbtnode_t *level_node;
- rdatasetheader_t *header, *header_prev, *header_next;
- rdatasetheader_t *found, *foundsig;
- isc_result_t result = ISC_R_NOTFOUND;
- dns_name_t name;
- dns_rbtdb_t *rbtdb;
- isc_boolean_t done;
- nodelock_t *lock;
- isc_rwlocktype_t locktype;
-
- /*
- * Caller must be holding the tree lock.
- */
-
- rbtdb = search->rbtdb;
- i = search->chain.level_matches;
- done = ISC_FALSE;
- do {
- locktype = isc_rwlocktype_read;
- lock = &rbtdb->node_locks[node->locknum].lock;
- NODE_LOCK(lock, locktype);
-
- /*
- * Look for NS and RRSIG NS rdatasets.
- */
- found = NULL;
- foundsig = NULL;
- header_prev = NULL;
- for (header = node->data;
- header != NULL;
- header = header_next) {
- header_next = header->next;
- if (header->rdh_ttl <= search->now) {
- /*
- * This rdataset is stale. If no one else is
- * using the node, we can clean it up right
- * now, otherwise we mark it as stale, and
- * the node as dirty, so it will get cleaned
- * up later.
- */
- if ((header->rdh_ttl <= search->now -
- RBTDB_VIRTUAL) &&
- (locktype == isc_rwlocktype_write ||
- NODE_TRYUPGRADE(lock) == ISC_R_SUCCESS)) {
- /*
- * We update the node's status only
- * when we can get write access.
- */
- locktype = isc_rwlocktype_write;
-
- if (dns_rbtnode_refcurrent(node)
- == 0) {
- isc_mem_t *m;
-
- m = search->rbtdb->common.mctx;
- clean_stale_headers(
- search->rbtdb,
- m, header);
- if (header_prev != NULL)
- header_prev->next =
- header->next;
- else
- node->data =
- header->next;
- free_rdataset(rbtdb, m,
- header);
- } else {
- header->attributes |=
- RDATASET_ATTR_STALE;
- node->dirty = 1;
- header_prev = header;
- }
- } else
- header_prev = header;
- } else if (EXISTS(header)) {
- /*
- * We've found an extant rdataset. See if
- * we're interested in it.
- */
- if (header->type == dns_rdatatype_ns) {
- found = header;
- if (foundsig != NULL)
- break;
- } else if (header->type ==
- RBTDB_RDATATYPE_SIGNS) {
- foundsig = header;
- if (found != NULL)
- break;
- }
- header_prev = header;
- } else
- header_prev = header;
- }
-
- if (found != NULL) {
- /*
- * If we have to set foundname, we do it before
- * anything else. If we were to set foundname after
- * we had set nodep or bound the rdataset, then we'd
- * have to undo that work if dns_name_concatenate()
- * failed. By setting foundname first, there's
- * nothing to undo if we have trouble.
- */
- if (foundname != NULL) {
- dns_name_init(&name, NULL);
- dns_rbt_namefromnode(node, &name);
- result = dns_name_copy(&name, foundname, NULL);
- while (result == ISC_R_SUCCESS && i > 0) {
- i--;
- level_node = search->chain.levels[i];
- dns_name_init(&name, NULL);
- dns_rbt_namefromnode(level_node,
- &name);
- result =
- dns_name_concatenate(foundname,
- &name,
- foundname,
- NULL);
- }
- if (result != ISC_R_SUCCESS) {
- *nodep = NULL;
- goto node_exit;
- }
- }
- result = DNS_R_DELEGATION;
- if (nodep != NULL) {
- new_reference(search->rbtdb, node);
- *nodep = node;
- }
- bind_rdataset(search->rbtdb, node, found, search->now,
- rdataset);
- if (foundsig != NULL)
- bind_rdataset(search->rbtdb, node, foundsig,
- search->now, sigrdataset);
- if (need_headerupdate(found, search->now) ||
- (foundsig != NULL &&
- need_headerupdate(foundsig, search->now))) {
- if (locktype != isc_rwlocktype_write) {
- NODE_UNLOCK(lock, locktype);
- NODE_LOCK(lock, isc_rwlocktype_write);
- locktype = isc_rwlocktype_write;
- POST(locktype);
- }
- if (need_headerupdate(found, search->now))
- update_header(search->rbtdb, found,
- search->now);
- if (foundsig != NULL &&
- need_headerupdate(foundsig, search->now)) {
- update_header(search->rbtdb, foundsig,
- search->now);
- }
- }
- }
-
- node_exit:
- NODE_UNLOCK(lock, locktype);
-
- if (found == NULL && i > 0) {
- i--;
- node = search->chain.levels[i];
- } else
- done = ISC_TRUE;
-
- } while (!done);
-
- return (result);
-}
-
-static isc_result_t
-find_coveringnsec(rbtdb_search_t *search, dns_dbnode_t **nodep,
- isc_stdtime_t now, dns_name_t *foundname,
- dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
-{
- dns_rbtnode_t *node;
- rdatasetheader_t *header, *header_next, *header_prev;
- rdatasetheader_t *found, *foundsig;
- isc_boolean_t empty_node;
- isc_result_t result;
- dns_fixedname_t fname, forigin;
- dns_name_t *name, *origin;
- rbtdb_rdatatype_t matchtype, sigmatchtype;
- nodelock_t *lock;
- isc_rwlocktype_t locktype;
-
- matchtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_nsec, 0);
- sigmatchtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig,
- dns_rdatatype_nsec);
-
- 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);
- locktype = isc_rwlocktype_read;
- lock = &(search->rbtdb->node_locks[node->locknum].lock);
- NODE_LOCK(lock, locktype);
- found = NULL;
- foundsig = NULL;
- empty_node = ISC_TRUE;
- header_prev = NULL;
- for (header = node->data;
- header != NULL;
- header = header_next) {
- header_next = header->next;
- if (header->rdh_ttl <= now) {
- /*
- * This rdataset is stale. If no one else is
- * using the node, we can clean it up right
- * now, otherwise we mark it as stale, and the
- * node as dirty, so it will get cleaned up
- * later.
- */
- if ((header->rdh_ttl <= now - RBTDB_VIRTUAL) &&
- (locktype == isc_rwlocktype_write ||
- NODE_TRYUPGRADE(lock) == ISC_R_SUCCESS)) {
- /*
- * We update the node's status only
- * when we can get write access.
- */
- locktype = isc_rwlocktype_write;
-
- if (dns_rbtnode_refcurrent(node)
- == 0) {
- isc_mem_t *m;
-
- m = search->rbtdb->common.mctx;
- clean_stale_headers(
- search->rbtdb,
- m, header);
- if (header_prev != NULL)
- header_prev->next =
- header->next;
- else
- node->data = header->next;
- free_rdataset(search->rbtdb, m,
- header);
- } else {
- header->attributes |=
- RDATASET_ATTR_STALE;
- node->dirty = 1;
- header_prev = header;
- }
- } else
- header_prev = header;
- continue;
- }
- if (NONEXISTENT(header) ||
- RBTDB_RDATATYPE_BASE(header->type) == 0) {
- header_prev = header;
- continue;
- }
- empty_node = ISC_FALSE;
- if (header->type == matchtype)
- found = header;
- else if (header->type == sigmatchtype)
- foundsig = header;
- header_prev = header;
- }
- if (found != NULL) {
- result = dns_name_concatenate(name, origin,
- foundname, NULL);
- if (result != ISC_R_SUCCESS)
- goto unlock_node;
- bind_rdataset(search->rbtdb, node, found,
- now, rdataset);
- if (foundsig != NULL)
- bind_rdataset(search->rbtdb, node, foundsig,
- now, sigrdataset);
- new_reference(search->rbtdb, node);
- *nodep = node;
- result = DNS_R_COVERINGNSEC;
- } else if (!empty_node) {
- result = ISC_R_NOTFOUND;
- } else
- result = dns_rbtnodechain_prev(&search->chain, NULL,
- NULL);
- unlock_node:
- NODE_UNLOCK(lock, locktype);
- } while (empty_node && result == ISC_R_SUCCESS);
- return (result);
-}
-
-/*
- * Mark a database for response policy rewriting
- * or find which RPZ data is available.
- */
-#ifdef BIND9
-static isc_result_t
-rpz_enabled(dns_db_t *db, dns_rpz_st_t *st)
-{
- dns_rbtdb_t *rbtdb;
- isc_result_t result;
-
- result = ISC_R_SUCCESS;
- rbtdb = (dns_rbtdb_t *)db;
- REQUIRE(VALID_RBTDB(rbtdb));
- RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
- if (st != NULL) {
- dns_rpz_enabled_get(rbtdb->rpz_cidr, st);
- } else {
- result = dns_rpz_new_cidr(rbtdb->common.mctx,
- &rbtdb->common.origin,
- &rbtdb->rpz_cidr);
- }
- RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
- return (result);
-}
-
-/*
- * 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 earliest configured policy,
- * QNAME over IP over NSDNAME over NSIP,
- * the longest prefix,
- * the lexically smallest address.
- * The caller must have already checked that any existing policy was not
- * configured earlier than this policy zone and does not have a higher
- * precedence type.
- */
-static void
-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_name_t *query_qname)
-{
- 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);
- return;
- }
-
- 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;
-
- /*
- * If we already have a rule, discard this new rule if
- * is not better.
- * The caller has checked that st->m.rpz->num > rpz->num
- * or st->m.rpz->num == rpz->num and st->m.type >= rpz_type
- */
- if (st->m.policy != DNS_RPZ_POLICY_MISS &&
- st->m.rpz->num == rpz->num &&
- (st->m.type < rpz_type ||
- (st->m.type == rpz_type &&
- (st->m.prefix > prefix ||
- (st->m.prefix == prefix &&
- 0 > dns_name_rdatacompare(st->qname, qname))))))
- 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_RPZ,
- DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL,
- "rpz_findips findnode(%s) failed: %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(rpz,
- &zrdataset,
- selfname);
- if (rpz_policy == DNS_RPZ_POLICY_RECORD ||
- rpz_policy == DNS_RPZ_POLICY_WILDCNAME)
- 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) {
- /*
- * only log DNS_RPZ_POLICY_DISABLED hits
- */
- if (rpz->policy == DNS_RPZ_POLICY_DISABLED) {
- if (isc_log_wouldlog(dns_lctx,
- DNS_RPZ_INFO_LEVEL)) {
- char qname_buf[DNS_NAME_FORMATSIZE];
- char rpz_qname_buf[DNS_NAME_FORMATSIZE];
- dns_name_format(query_qname, qname_buf,
- sizeof(qname_buf));
- dns_name_format(qname, rpz_qname_buf,
- sizeof(rpz_qname_buf));
-
- isc_log_write(dns_lctx,
- DNS_LOGCATEGORY_RPZ,
- DNS_LOGMODULE_RBTDB,
- DNS_RPZ_INFO_LEVEL,
- "disabled rpz %s %s rewrite"
- " %s via %s",
- dns_rpz_type2str(rpz_type),
- dns_rpz_policy2str(rpz_policy),
- qname_buf, rpz_qname_buf);
- }
- continue;
- }
-
- rpz_policy = rpz->policy;
- }
-
- 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 = ISC_MIN(ttl, rpz->max_policy_ttl);
- st->m.result = result;
- dns_name_copy(qname, st->qname, NULL);
- if ((rpz_policy == DNS_RPZ_POLICY_RECORD ||
- rpz_policy == DNS_RPZ_POLICY_WILDCNAME) &&
- 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);
- st->m.version = version;
- dns_zone_attach(zone, &st->m.zone);
- if (dns_rdataset_isassociated(&zrdataset))
- dns_rdataset_disassociate(&zrdataset);
- }
-
- RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
-}
-#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,
- dns_dbnode_t **nodep, dns_name_t *foundname,
- dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
-{
- dns_rbtnode_t *node = NULL;
- isc_result_t result;
- rbtdb_search_t search;
- isc_boolean_t cname_ok = ISC_TRUE;
- isc_boolean_t empty_node;
- nodelock_t *lock;
- isc_rwlocktype_t locktype;
- rdatasetheader_t *header, *header_prev, *header_next;
- rdatasetheader_t *found, *nsheader;
- rdatasetheader_t *foundsig, *nssig, *cnamesig;
- rdatasetheader_t *update, *updatesig;
- rbtdb_rdatatype_t sigtype, negtype;
-
- UNUSED(version);
-
- search.rbtdb = (dns_rbtdb_t *)db;
-
- REQUIRE(VALID_RBTDB(search.rbtdb));
- REQUIRE(version == NULL);
-
- if (now == 0)
- isc_stdtime_get(&now);
-
- search.rbtversion = NULL;
- search.serial = 1;
- search.options = options;
- search.copy_name = ISC_FALSE;
- search.need_cleanup = ISC_FALSE;
- search.wild = ISC_FALSE;
- search.zonecut = NULL;
- dns_fixedname_init(&search.zonecut_name);
- dns_rbtnodechain_init(&search.chain, search.rbtdb->common.mctx);
- search.now = now;
- update = NULL;
- updatesig = NULL;
-
- RWLOCK(&search.rbtdb->tree_lock, isc_rwlocktype_read);
-
- /*
- * Search down from the root of the tree. If, while going down, we
- * encounter a callback node, cache_zonecut_callback() will search the
- * rdatasets at the zone cut for a DNAME rdataset.
- */
- result = dns_rbt_findnode(search.rbtdb->tree, name, foundname, &node,
- &search.chain, DNS_RBTFIND_EMPTYDATA,
- cache_zonecut_callback, &search);
-
- if (result == DNS_R_PARTIALMATCH) {
- if ((search.options & DNS_DBFIND_COVERINGNSEC) != 0) {
- result = find_coveringnsec(&search, nodep, now,
- foundname, rdataset,
- sigrdataset);
- if (result == DNS_R_COVERINGNSEC)
- goto tree_exit;
- }
- if (search.zonecut != NULL) {
- result = setup_delegation(&search, nodep, foundname,
- rdataset, sigrdataset);
- goto tree_exit;
- } else {
- find_ns:
- result = find_deepest_zonecut(&search, node, nodep,
- foundname, rdataset,
- sigrdataset);
- goto tree_exit;
- }
- } else if (result != ISC_R_SUCCESS)
- goto tree_exit;
-
- /*
- * Certain DNSSEC types are not subject to CNAME matching
- * (RFC4035, section 2.5 and RFC3007).
- *
- * We don't check for RRSIG, because we don't store RRSIG records
- * directly.
- */
- if (type == dns_rdatatype_key || type == dns_rdatatype_nsec)
- cname_ok = ISC_FALSE;
-
- /*
- * We now go looking for rdata...
- */
-
- lock = &(search.rbtdb->node_locks[node->locknum].lock);
- locktype = isc_rwlocktype_read;
- NODE_LOCK(lock, locktype);
-
- found = NULL;
- foundsig = NULL;
- sigtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, type);
- negtype = RBTDB_RDATATYPE_VALUE(0, type);
- nsheader = NULL;
- nssig = NULL;
- cnamesig = NULL;
- empty_node = ISC_TRUE;
- header_prev = NULL;
- for (header = node->data; header != NULL; header = header_next) {
- header_next = header->next;
- if (header->rdh_ttl <= now) {
- /*
- * This rdataset is stale. If no one else is using the
- * node, we can clean it up right now, otherwise we
- * mark it as stale, and the node as dirty, so it will
- * get cleaned up later.
- */
- if ((header->rdh_ttl <= now - RBTDB_VIRTUAL) &&
- (locktype == isc_rwlocktype_write ||
- NODE_TRYUPGRADE(lock) == ISC_R_SUCCESS)) {
- /*
- * We update the node's status only when we
- * can get write access.
- */
- locktype = isc_rwlocktype_write;
-
- if (dns_rbtnode_refcurrent(node) == 0) {
- isc_mem_t *mctx;
-
- mctx = search.rbtdb->common.mctx;
- clean_stale_headers(search.rbtdb, mctx,
- header);
- if (header_prev != NULL)
- header_prev->next =
- header->next;
- else
- node->data = header->next;
- free_rdataset(search.rbtdb, mctx,
- header);
- } else {
- header->attributes |=
- RDATASET_ATTR_STALE;
- node->dirty = 1;
- header_prev = header;
- }
- } else
- header_prev = header;
- } else if (EXISTS(header)) {
- /*
- * We now know that there is at least one active
- * non-stale rdataset at this node.
- */
- empty_node = ISC_FALSE;
-
- /*
- * If we found a type we were looking for, remember
- * it.
- */
- if (header->type == type ||
- (type == dns_rdatatype_any &&
- RBTDB_RDATATYPE_BASE(header->type) != 0) ||
- (cname_ok && header->type ==
- dns_rdatatype_cname)) {
- /*
- * We've found the answer.
- */
- found = header;
- if (header->type == dns_rdatatype_cname &&
- cname_ok &&
- cnamesig != NULL) {
- /*
- * If we've already got the
- * CNAME RRSIG, use it.
- */
- foundsig = cnamesig;
- }
- } else if (header->type == sigtype) {
- /*
- * We've found the RRSIG rdataset for our
- * target type. Remember it.
- */
- foundsig = header;
- } else if (header->type == RBTDB_RDATATYPE_NCACHEANY ||
- header->type == negtype) {
- /*
- * We've found a negative cache entry.
- */
- found = header;
- } else if (header->type == dns_rdatatype_ns) {
- /*
- * Remember a NS rdataset even if we're
- * not specifically looking for it, because
- * we might need it later.
- */
- nsheader = header;
- } else if (header->type == RBTDB_RDATATYPE_SIGNS) {
- /*
- * If we need the NS rdataset, we'll also
- * need its signature.
- */
- nssig = header;
- } else if (cname_ok &&
- header->type == RBTDB_RDATATYPE_SIGCNAME) {
- /*
- * If we get a CNAME match, we'll also need
- * its signature.
- */
- cnamesig = header;
- }
- header_prev = header;
- } else
- header_prev = header;
- }
-
- if (empty_node) {
- /*
- * We have an exact match for the name, but there are no
- * extant rdatasets. That means that this node doesn't
- * meaningfully exist, and that we really have a partial match.
- */
- NODE_UNLOCK(lock, locktype);
- goto find_ns;
- }
-
- /*
- * If we didn't find what we were looking for...
- */
- if (found == NULL ||
- (DNS_TRUST_ADDITIONAL(found->trust) &&
- ((options & DNS_DBFIND_ADDITIONALOK) == 0)) ||
- (found->trust == dns_trust_glue &&
- ((options & DNS_DBFIND_GLUEOK) == 0)) ||
- (DNS_TRUST_PENDING(found->trust) &&
- ((options & DNS_DBFIND_PENDINGOK) == 0))) {
- /*
- * If there is an NS rdataset at this node, then this is the
- * deepest zone cut.
- */
- if (nsheader != NULL) {
- if (nodep != NULL) {
- new_reference(search.rbtdb, node);
- INSIST(!ISC_LINK_LINKED(node, deadlink));
- *nodep = node;
- }
- bind_rdataset(search.rbtdb, node, nsheader, search.now,
- rdataset);
- if (need_headerupdate(nsheader, search.now))
- update = nsheader;
- if (nssig != NULL) {
- bind_rdataset(search.rbtdb, node, nssig,
- search.now, sigrdataset);
- if (need_headerupdate(nssig, search.now))
- updatesig = nssig;
- }
- result = DNS_R_DELEGATION;
- goto node_exit;
- }
-
- /*
- * Go find the deepest zone cut.
- */
- NODE_UNLOCK(lock, locktype);
- goto find_ns;
- }
-
- /*
- * We found what we were looking for, or we found a CNAME.
- */
-
- if (nodep != NULL) {
- new_reference(search.rbtdb, node);
- INSIST(!ISC_LINK_LINKED(node, deadlink));
- *nodep = node;
- }
-
- if (NEGATIVE(found)) {
- /*
- * We found a negative cache entry.
- */
- if (NXDOMAIN(found))
- result = DNS_R_NCACHENXDOMAIN;
- else
- result = DNS_R_NCACHENXRRSET;
- } else if (type != found->type &&
- type != dns_rdatatype_any &&
- found->type == dns_rdatatype_cname) {
- /*
- * We weren't doing an ANY query and we found a CNAME instead
- * of the type we were looking for, so we need to indicate
- * that result to the caller.
- */
- result = DNS_R_CNAME;
- } else {
- /*
- * An ordinary successful query!
- */
- result = ISC_R_SUCCESS;
- }
-
- if (type != dns_rdatatype_any || result == DNS_R_NCACHENXDOMAIN ||
- result == DNS_R_NCACHENXRRSET) {
- bind_rdataset(search.rbtdb, node, found, search.now,
- rdataset);
- if (need_headerupdate(found, search.now))
- update = found;
- if (!NEGATIVE(found) && foundsig != NULL) {
- bind_rdataset(search.rbtdb, node, foundsig, search.now,
- sigrdataset);
- if (need_headerupdate(foundsig, search.now))
- updatesig = foundsig;
- }
- }
-
- node_exit:
- if ((update != NULL || updatesig != NULL) &&
- locktype != isc_rwlocktype_write) {
- NODE_UNLOCK(lock, locktype);
- NODE_LOCK(lock, isc_rwlocktype_write);
- locktype = isc_rwlocktype_write;
- POST(locktype);
- }
- if (update != NULL && need_headerupdate(update, search.now))
- update_header(search.rbtdb, update, search.now);
- if (updatesig != NULL && need_headerupdate(updatesig, search.now))
- update_header(search.rbtdb, updatesig, search.now);
-
- NODE_UNLOCK(lock, locktype);
-
- tree_exit:
- RWUNLOCK(&search.rbtdb->tree_lock, isc_rwlocktype_read);
-
- /*
- * If we found a zonecut but aren't going to use it, we have to
- * let go of it.
- */
- if (search.need_cleanup) {
- node = search.zonecut;
- INSIST(node != NULL);
- lock = &(search.rbtdb->node_locks[node->locknum].lock);
-
- NODE_LOCK(lock, isc_rwlocktype_read);
- decrement_reference(search.rbtdb, node, 0,
- isc_rwlocktype_read, isc_rwlocktype_none,
- ISC_FALSE);
- NODE_UNLOCK(lock, isc_rwlocktype_read);
- }
-
- dns_rbtnodechain_reset(&search.chain);
-
- return (result);
-}
-
-static isc_result_t
-cache_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_rbtnode_t *node = NULL;
- nodelock_t *lock;
- isc_result_t result;
- rbtdb_search_t search;
- rdatasetheader_t *header, *header_prev, *header_next;
- rdatasetheader_t *found, *foundsig;
- unsigned int rbtoptions = DNS_RBTFIND_EMPTYDATA;
- isc_rwlocktype_t locktype;
-
- search.rbtdb = (dns_rbtdb_t *)db;
-
- REQUIRE(VALID_RBTDB(search.rbtdb));
-
- if (now == 0)
- isc_stdtime_get(&now);
-
- search.rbtversion = NULL;
- search.serial = 1;
- search.options = options;
- search.copy_name = ISC_FALSE;
- search.need_cleanup = ISC_FALSE;
- search.wild = ISC_FALSE;
- search.zonecut = NULL;
- dns_fixedname_init(&search.zonecut_name);
- dns_rbtnodechain_init(&search.chain, search.rbtdb->common.mctx);
- search.now = now;
-
- if ((options & DNS_DBFIND_NOEXACT) != 0)
- rbtoptions |= DNS_RBTFIND_NOEXACT;
-
- RWLOCK(&search.rbtdb->tree_lock, isc_rwlocktype_read);
-
- /*
- * Search down from the root of the tree.
- */
- result = dns_rbt_findnode(search.rbtdb->tree, name, foundname, &node,
- &search.chain, rbtoptions, NULL, &search);
-
- if (result == DNS_R_PARTIALMATCH) {
- find_ns:
- result = find_deepest_zonecut(&search, node, nodep, foundname,
- rdataset, sigrdataset);
- goto tree_exit;
- } else if (result != ISC_R_SUCCESS)
- goto tree_exit;
-
- /*
- * We now go looking for an NS rdataset at the node.
- */
-
- lock = &(search.rbtdb->node_locks[node->locknum].lock);
- locktype = isc_rwlocktype_read;
- NODE_LOCK(lock, locktype);
-
- found = NULL;
- foundsig = NULL;
- header_prev = NULL;
- for (header = node->data; header != NULL; header = header_next) {
- header_next = header->next;
- if (header->rdh_ttl <= now) {
- /*
- * This rdataset is stale. If no one else is using the
- * node, we can clean it up right now, otherwise we
- * mark it as stale, and the node as dirty, so it will
- * get cleaned up later.
- */
- if ((header->rdh_ttl <= now - RBTDB_VIRTUAL) &&
- (locktype == isc_rwlocktype_write ||
- NODE_TRYUPGRADE(lock) == ISC_R_SUCCESS)) {
- /*
- * We update the node's status only when we
- * can get write access.
- */
- locktype = isc_rwlocktype_write;
-
- if (dns_rbtnode_refcurrent(node) == 0) {
- isc_mem_t *mctx;
-
- mctx = search.rbtdb->common.mctx;
- clean_stale_headers(search.rbtdb, mctx,
- header);
- if (header_prev != NULL)
- header_prev->next =
- header->next;
- else
- node->data = header->next;
- free_rdataset(search.rbtdb, mctx,
- header);
- } else {
- header->attributes |=
- RDATASET_ATTR_STALE;
- node->dirty = 1;
- header_prev = header;
- }
- } else
- header_prev = header;
- } else if (EXISTS(header)) {
- /*
- * If we found a type we were looking for, remember
- * it.
- */
- if (header->type == dns_rdatatype_ns) {
- /*
- * Remember a NS rdataset even if we're
- * not specifically looking for it, because
- * we might need it later.
- */
- found = header;
- } else if (header->type == RBTDB_RDATATYPE_SIGNS) {
- /*
- * If we need the NS rdataset, we'll also
- * need its signature.
- */
- foundsig = header;
- }
- header_prev = header;
- } else
- header_prev = header;
- }
-
- if (found == NULL) {
- /*
- * No NS records here.
- */
- NODE_UNLOCK(lock, locktype);
- goto find_ns;
- }
-
- if (nodep != NULL) {
- new_reference(search.rbtdb, node);
- INSIST(!ISC_LINK_LINKED(node, deadlink));
- *nodep = node;
- }
-
- bind_rdataset(search.rbtdb, node, found, search.now, rdataset);
- if (foundsig != NULL)
- bind_rdataset(search.rbtdb, node, foundsig, search.now,
- sigrdataset);
-
- if (need_headerupdate(found, search.now) ||
- (foundsig != NULL && need_headerupdate(foundsig, search.now))) {
- if (locktype != isc_rwlocktype_write) {
- NODE_UNLOCK(lock, locktype);
- NODE_LOCK(lock, isc_rwlocktype_write);
- locktype = isc_rwlocktype_write;
- POST(locktype);
- }
- if (need_headerupdate(found, search.now))
- update_header(search.rbtdb, found, search.now);
- if (foundsig != NULL &&
- need_headerupdate(foundsig, search.now)) {
- update_header(search.rbtdb, foundsig, search.now);
- }
- }
-
- NODE_UNLOCK(lock, locktype);
-
- tree_exit:
- RWUNLOCK(&search.rbtdb->tree_lock, isc_rwlocktype_read);
-
- INSIST(!search.need_cleanup);
-
- dns_rbtnodechain_reset(&search.chain);
-
- if (result == DNS_R_DELEGATION)
- result = ISC_R_SUCCESS;
-
- return (result);
-}
-
-static void
-attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) {
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
- dns_rbtnode_t *node = (dns_rbtnode_t *)source;
- unsigned int refs;
-
- REQUIRE(VALID_RBTDB(rbtdb));
- REQUIRE(targetp != NULL && *targetp == NULL);
-
- NODE_STRONGLOCK(&rbtdb->node_locks[node->locknum].lock);
- dns_rbtnode_refincrement(node, &refs);
- INSIST(refs != 0);
- NODE_STRONGUNLOCK(&rbtdb->node_locks[node->locknum].lock);
-
- *targetp = source;
-}
-
-static void
-detachnode(dns_db_t *db, dns_dbnode_t **targetp) {
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
- dns_rbtnode_t *node;
- isc_boolean_t want_free = ISC_FALSE;
- isc_boolean_t inactive = ISC_FALSE;
- rbtdb_nodelock_t *nodelock;
-
- REQUIRE(VALID_RBTDB(rbtdb));
- REQUIRE(targetp != NULL && *targetp != NULL);
-
- node = (dns_rbtnode_t *)(*targetp);
- nodelock = &rbtdb->node_locks[node->locknum];
-
- NODE_LOCK(&nodelock->lock, isc_rwlocktype_read);
-
- if (decrement_reference(rbtdb, node, 0, isc_rwlocktype_read,
- isc_rwlocktype_none, ISC_FALSE)) {
- if (isc_refcount_current(&nodelock->references) == 0 &&
- nodelock->exiting) {
- inactive = ISC_TRUE;
- }
- }
-
- NODE_UNLOCK(&nodelock->lock, isc_rwlocktype_read);
-
- *targetp = NULL;
-
- if (inactive) {
- RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write);
- rbtdb->active--;
- if (rbtdb->active == 0)
- want_free = ISC_TRUE;
- RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write);
- if (want_free) {
- char buf[DNS_NAME_FORMATSIZE];
- if (dns_name_dynamic(&rbtdb->common.origin))
- dns_name_format(&rbtdb->common.origin, buf,
- sizeof(buf));
- else
- strcpy(buf, "<UNKNOWN>");
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_CACHE, ISC_LOG_DEBUG(1),
- "calling free_rbtdb(%s)", buf);
- free_rbtdb(rbtdb, ISC_TRUE, NULL);
- }
- }
-}
-
-static isc_result_t
-expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) {
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
- dns_rbtnode_t *rbtnode = node;
- rdatasetheader_t *header;
- isc_boolean_t force_expire = ISC_FALSE;
- /*
- * These are the category and module used by the cache cleaner.
- */
- isc_boolean_t log = ISC_FALSE;
- isc_logcategory_t *category = DNS_LOGCATEGORY_DATABASE;
- isc_logmodule_t *module = DNS_LOGMODULE_CACHE;
- int level = ISC_LOG_DEBUG(2);
- char printname[DNS_NAME_FORMATSIZE];
-
- REQUIRE(VALID_RBTDB(rbtdb));
-
- /*
- * Caller must hold a tree lock.
- */
-
- if (now == 0)
- isc_stdtime_get(&now);
-
- if (isc_mem_isovermem(rbtdb->common.mctx)) {
- isc_uint32_t val;
-
- isc_random_get(&val);
- /*
- * XXXDCL Could stand to have a better policy, like LRU.
- */
- force_expire = ISC_TF(rbtnode->down == NULL && val % 4 == 0);
-
- /*
- * Note that 'log' can be true IFF overmem is also true.
- * overmem can currently only be true for cache
- * databases -- hence all of the "overmem cache" log strings.
- */
- log = ISC_TF(isc_log_wouldlog(dns_lctx, level));
- if (log)
- isc_log_write(dns_lctx, category, module, level,
- "overmem cache: %s %s",
- force_expire ? "FORCE" : "check",
- dns_rbt_formatnodename(rbtnode,
- printname,
- sizeof(printname)));
- }
-
- /*
- * We may not need write access, but this code path is not performance
- * sensitive, so it should be okay to always lock as a writer.
- */
- NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_write);
-
- for (header = rbtnode->data; header != NULL; header = header->next)
- if (header->rdh_ttl <= now - RBTDB_VIRTUAL) {
- /*
- * We don't check if refcurrent(rbtnode) == 0 and try
- * to free like we do in cache_find(), because
- * refcurrent(rbtnode) must be non-zero. This is so
- * because 'node' is an argument to the function.
- */
- header->attributes |= RDATASET_ATTR_STALE;
- rbtnode->dirty = 1;
- if (log)
- isc_log_write(dns_lctx, category, module,
- level, "overmem cache: stale %s",
- printname);
- } else if (force_expire) {
- if (! RETAIN(header)) {
- set_ttl(rbtdb, header, 0);
- header->attributes |= RDATASET_ATTR_STALE;
- rbtnode->dirty = 1;
- } else if (log) {
- isc_log_write(dns_lctx, category, module,
- level, "overmem cache: "
- "reprieve by RETAIN() %s",
- printname);
- }
- } else if (isc_mem_isovermem(rbtdb->common.mctx) && log)
- isc_log_write(dns_lctx, category, module, level,
- "overmem cache: saved %s", printname);
-
- NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_write);
-
- return (ISC_R_SUCCESS);
-}
-
-static void
-overmem(dns_db_t *db, isc_boolean_t overmem) {
- /* This is an empty callback. See adb.c:water() */
-
- UNUSED(db);
- UNUSED(overmem);
-
- return;
-}
-
-static void
-printnode(dns_db_t *db, dns_dbnode_t *node, FILE *out) {
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
- dns_rbtnode_t *rbtnode = node;
- isc_boolean_t first;
-
- REQUIRE(VALID_RBTDB(rbtdb));
-
- NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_read);
-
- fprintf(out, "node %p, %u references, locknum = %u\n",
- rbtnode, dns_rbtnode_refcurrent(rbtnode),
- rbtnode->locknum);
- if (rbtnode->data != NULL) {
- rdatasetheader_t *current, *top_next;
-
- for (current = rbtnode->data; current != NULL;
- current = top_next) {
- top_next = current->next;
- first = ISC_TRUE;
- fprintf(out, "\ttype %u", current->type);
- do {
- if (!first)
- fprintf(out, "\t");
- first = ISC_FALSE;
- fprintf(out,
- "\tserial = %lu, ttl = %u, "
- "trust = %u, attributes = %u, "
- "resign = %u\n",
- (unsigned long)current->serial,
- current->rdh_ttl,
- current->trust,
- current->attributes,
- current->resign);
- current = current->down;
- } while (current != NULL);
- }
- } else
- fprintf(out, "(empty)\n");
-
- NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_read);
-}
-
-static isc_result_t
-createiterator(dns_db_t *db, unsigned int options, dns_dbiterator_t **iteratorp)
-{
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
- rbtdb_dbiterator_t *rbtdbiter;
-
- REQUIRE(VALID_RBTDB(rbtdb));
-
- rbtdbiter = isc_mem_get(rbtdb->common.mctx, sizeof(*rbtdbiter));
- if (rbtdbiter == NULL)
- return (ISC_R_NOMEMORY);
-
- rbtdbiter->common.methods = &dbiterator_methods;
- rbtdbiter->common.db = NULL;
- dns_db_attach(db, &rbtdbiter->common.db);
- rbtdbiter->common.relative_names =
- ISC_TF((options & DNS_DB_RELATIVENAMES) != 0);
- rbtdbiter->common.magic = DNS_DBITERATOR_MAGIC;
- rbtdbiter->common.cleaning = ISC_FALSE;
- rbtdbiter->paused = ISC_TRUE;
- rbtdbiter->tree_locked = isc_rwlocktype_none;
- rbtdbiter->result = ISC_R_SUCCESS;
- dns_fixedname_init(&rbtdbiter->name);
- dns_fixedname_init(&rbtdbiter->origin);
- rbtdbiter->node = NULL;
- rbtdbiter->delete = 0;
- rbtdbiter->nsec3only = ISC_TF((options & DNS_DB_NSEC3ONLY) != 0);
- rbtdbiter->nonsec3 = ISC_TF((options & DNS_DB_NONSEC3) != 0);
- memset(rbtdbiter->deletions, 0, sizeof(rbtdbiter->deletions));
- dns_rbtnodechain_init(&rbtdbiter->chain, db->mctx);
- dns_rbtnodechain_init(&rbtdbiter->nsec3chain, db->mctx);
- if (rbtdbiter->nsec3only)
- rbtdbiter->current = &rbtdbiter->nsec3chain;
- else
- rbtdbiter->current = &rbtdbiter->chain;
-
- *iteratorp = (dns_dbiterator_t *)rbtdbiter;
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-zone_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
- dns_rdatatype_t type, dns_rdatatype_t covers,
- isc_stdtime_t now, dns_rdataset_t *rdataset,
- dns_rdataset_t *sigrdataset)
-{
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
- dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node;
- rdatasetheader_t *header, *header_next, *found, *foundsig;
- rbtdb_serial_t serial;
- rbtdb_version_t *rbtversion = version;
- isc_boolean_t close_version = ISC_FALSE;
- rbtdb_rdatatype_t matchtype, sigmatchtype;
-
- REQUIRE(VALID_RBTDB(rbtdb));
- REQUIRE(type != dns_rdatatype_any);
- INSIST(rbtversion == NULL || rbtversion->rbtdb == rbtdb);
-
- if (rbtversion == NULL) {
- currentversion(db, (dns_dbversion_t **) (void *)(&rbtversion));
- close_version = ISC_TRUE;
- }
- serial = rbtversion->serial;
- now = 0;
-
- NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_read);
-
- found = NULL;
- foundsig = NULL;
- matchtype = RBTDB_RDATATYPE_VALUE(type, covers);
- if (covers == 0)
- sigmatchtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, type);
- else
- sigmatchtype = 0;
-
- for (header = rbtnode->data; header != NULL; header = header_next) {
- header_next = header->next;
- do {
- if (header->serial <= serial &&
- !IGNORE(header)) {
- /*
- * Is this a "this rdataset doesn't
- * exist" record?
- */
- if (NONEXISTENT(header))
- header = NULL;
- break;
- } else
- header = header->down;
- } while (header != NULL);
- if (header != NULL) {
- /*
- * We have an active, extant rdataset. If it's a
- * type we're looking for, remember it.
- */
- if (header->type == matchtype) {
- found = header;
- if (foundsig != NULL)
- break;
- } else if (header->type == sigmatchtype) {
- foundsig = header;
- if (found != NULL)
- break;
- }
- }
- }
- if (found != NULL) {
- bind_rdataset(rbtdb, rbtnode, found, now, rdataset);
- if (foundsig != NULL)
- bind_rdataset(rbtdb, rbtnode, foundsig, now,
- sigrdataset);
- }
-
- NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_read);
-
- if (close_version)
- closeversion(db, (dns_dbversion_t **) (void *)(&rbtversion),
- ISC_FALSE);
-
- if (found == NULL)
- return (ISC_R_NOTFOUND);
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
- dns_rdatatype_t type, dns_rdatatype_t covers,
- isc_stdtime_t now, dns_rdataset_t *rdataset,
- dns_rdataset_t *sigrdataset)
-{
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
- dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node;
- rdatasetheader_t *header, *header_next, *found, *foundsig;
- rbtdb_rdatatype_t matchtype, sigmatchtype, negtype;
- isc_result_t result;
- nodelock_t *lock;
- isc_rwlocktype_t locktype;
-
- REQUIRE(VALID_RBTDB(rbtdb));
- REQUIRE(type != dns_rdatatype_any);
-
- UNUSED(version);
-
- result = ISC_R_SUCCESS;
-
- if (now == 0)
- isc_stdtime_get(&now);
-
- lock = &rbtdb->node_locks[rbtnode->locknum].lock;
- locktype = isc_rwlocktype_read;
- NODE_LOCK(lock, locktype);
-
- found = NULL;
- foundsig = NULL;
- matchtype = RBTDB_RDATATYPE_VALUE(type, covers);
- negtype = RBTDB_RDATATYPE_VALUE(0, type);
- if (covers == 0)
- sigmatchtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, type);
- else
- sigmatchtype = 0;
-
- for (header = rbtnode->data; header != NULL; header = header_next) {
- header_next = header->next;
- if (header->rdh_ttl <= now) {
- if ((header->rdh_ttl <= now - RBTDB_VIRTUAL) &&
- (locktype == isc_rwlocktype_write ||
- NODE_TRYUPGRADE(lock) == ISC_R_SUCCESS)) {
- /*
- * We update the node's status only when we
- * can get write access.
- */
- locktype = isc_rwlocktype_write;
-
- /*
- * We don't check if refcurrent(rbtnode) == 0
- * and try to free like we do in cache_find(),
- * because refcurrent(rbtnode) must be
- * non-zero. This is so because 'node' is an
- * argument to the function.
- */
- header->attributes |= RDATASET_ATTR_STALE;
- rbtnode->dirty = 1;
- }
- } else if (EXISTS(header)) {
- if (header->type == matchtype)
- found = header;
- else if (header->type == RBTDB_RDATATYPE_NCACHEANY ||
- header->type == negtype)
- found = header;
- else if (header->type == sigmatchtype)
- foundsig = header;
- }
- }
- if (found != NULL) {
- bind_rdataset(rbtdb, rbtnode, found, now, rdataset);
- if (!NEGATIVE(found) && foundsig != NULL)
- bind_rdataset(rbtdb, rbtnode, foundsig, now,
- sigrdataset);
- }
-
- NODE_UNLOCK(lock, locktype);
-
- if (found == NULL)
- return (ISC_R_NOTFOUND);
-
- if (NEGATIVE(found)) {
- /*
- * We found a negative cache entry.
- */
- if (NXDOMAIN(found))
- result = DNS_R_NCACHENXDOMAIN;
- else
- result = DNS_R_NCACHENXRRSET;
- }
-
- return (result);
-}
-
-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_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
- dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node;
- rbtdb_version_t *rbtversion = version;
- rbtdb_rdatasetiter_t *iterator;
- unsigned int refs;
-
- REQUIRE(VALID_RBTDB(rbtdb));
-
- iterator = isc_mem_get(rbtdb->common.mctx, sizeof(*iterator));
- if (iterator == NULL)
- return (ISC_R_NOMEMORY);
-
- if ((db->attributes & DNS_DBATTR_CACHE) == 0) {
- now = 0;
- if (rbtversion == NULL)
- currentversion(db,
- (dns_dbversion_t **) (void *)(&rbtversion));
- else {
- unsigned int refs;
-
- INSIST(rbtversion->rbtdb == rbtdb);
-
- isc_refcount_increment(&rbtversion->references,
- &refs);
- INSIST(refs > 1);
- }
- } else {
- if (now == 0)
- isc_stdtime_get(&now);
- rbtversion = NULL;
- }
-
- iterator->common.magic = DNS_RDATASETITER_MAGIC;
- iterator->common.methods = &rdatasetiter_methods;
- iterator->common.db = db;
- iterator->common.node = node;
- iterator->common.version = (dns_dbversion_t *)rbtversion;
- iterator->common.now = now;
-
- NODE_STRONGLOCK(&rbtdb->node_locks[rbtnode->locknum].lock);
-
- dns_rbtnode_refincrement(rbtnode, &refs);
- INSIST(refs != 0);
-
- iterator->current = NULL;
-
- NODE_STRONGUNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock);
-
- *iteratorp = (dns_rdatasetiter_t *)iterator;
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_boolean_t
-cname_and_other_data(dns_rbtnode_t *node, rbtdb_serial_t serial) {
- rdatasetheader_t *header, *header_next;
- isc_boolean_t cname, other_data;
- dns_rdatatype_t rdtype;
-
- /*
- * The caller must hold the node lock.
- */
-
- /*
- * Look for CNAME and "other data" rdatasets active in our version.
- */
- cname = ISC_FALSE;
- other_data = ISC_FALSE;
- for (header = node->data; header != NULL; header = header_next) {
- header_next = header->next;
- if (header->type == dns_rdatatype_cname) {
- /*
- * Look for an active extant CNAME.
- */
- do {
- if (header->serial <= serial &&
- !IGNORE(header)) {
- /*
- * Is this a "this rdataset doesn't
- * exist" record?
- */
- if (NONEXISTENT(header))
- header = NULL;
- break;
- } else
- header = header->down;
- } while (header != NULL);
- if (header != NULL)
- cname = ISC_TRUE;
- } else {
- /*
- * Look for active extant "other data".
- *
- * "Other data" is any rdataset whose type is not
- * KEY, NSEC, SIG or RRSIG.
- */
- rdtype = RBTDB_RDATATYPE_BASE(header->type);
- if (rdtype != dns_rdatatype_key &&
- rdtype != dns_rdatatype_sig &&
- rdtype != dns_rdatatype_nsec &&
- rdtype != dns_rdatatype_rrsig) {
- /*
- * Is it active and extant?
- */
- do {
- if (header->serial <= serial &&
- !IGNORE(header)) {
- /*
- * Is this a "this rdataset
- * doesn't exist" record?
- */
- if (NONEXISTENT(header))
- header = NULL;
- break;
- } else
- header = header->down;
- } while (header != NULL);
- if (header != NULL)
- other_data = ISC_TRUE;
- }
- }
- }
-
- if (cname && other_data)
- return (ISC_TRUE);
-
- return (ISC_FALSE);
-}
-
-static isc_result_t
-resign_insert(dns_rbtdb_t *rbtdb, int idx, rdatasetheader_t *newheader) {
- isc_result_t result;
-
- INSIST(!IS_CACHE(rbtdb));
- INSIST(newheader->heap_index == 0);
- INSIST(!ISC_LINK_LINKED(newheader, link));
-
- result = isc_heap_insert(rbtdb->heaps[idx], newheader);
- return (result);
-}
-
-static isc_result_t
-add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
- rdatasetheader_t *newheader, unsigned int options, isc_boolean_t loading,
- dns_rdataset_t *addedrdataset, isc_stdtime_t now)
-{
- rbtdb_changed_t *changed = NULL;
- rdatasetheader_t *topheader, *topheader_prev, *header, *sigheader;
- unsigned char *merged;
- isc_result_t result;
- isc_boolean_t header_nx;
- isc_boolean_t newheader_nx;
- isc_boolean_t merge;
- dns_rdatatype_t rdtype, covers;
- rbtdb_rdatatype_t negtype, sigtype;
- dns_trust_t trust;
- int idx;
-
- /*
- * Add an rdatasetheader_t to a node.
- */
-
- /*
- * Caller must be holding the node lock.
- */
-
- if ((options & DNS_DBADD_MERGE) != 0) {
- REQUIRE(rbtversion != NULL);
- merge = ISC_TRUE;
- } else
- merge = ISC_FALSE;
-
- if ((options & DNS_DBADD_FORCE) != 0)
- trust = dns_trust_ultimate;
- else
- trust = newheader->trust;
-
- if (rbtversion != NULL && !loading) {
- /*
- * We always add a changed record, even if no changes end up
- * being made to this node, because it's harmless and
- * simplifies the code.
- */
- changed = add_changed(rbtdb, rbtversion, rbtnode);
- if (changed == NULL) {
- free_rdataset(rbtdb, rbtdb->common.mctx, newheader);
- return (ISC_R_NOMEMORY);
- }
- }
-
- newheader_nx = NONEXISTENT(newheader) ? ISC_TRUE : ISC_FALSE;
- topheader_prev = NULL;
- sigheader = NULL;
- negtype = 0;
- if (rbtversion == NULL && !newheader_nx) {
- rdtype = RBTDB_RDATATYPE_BASE(newheader->type);
- covers = RBTDB_RDATATYPE_EXT(newheader->type);
- sigtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, covers);
- if (NEGATIVE(newheader)) {
- /*
- * We're adding a negative cache entry.
- */
- for (topheader = rbtnode->data;
- topheader != NULL;
- topheader = topheader->next) {
- /*
- * If we're adding an negative cache entry
- * which covers all types (NXDOMAIN,
- * NODATA(QTYPE=ANY)).
- *
- * We make all other data stale so that the
- * only rdataset that can be found at this
- * node is the negative cache entry.
- *
- * Otherwise look for any RRSIGs of the
- * given type so they can be marked stale
- * later.
- */
- if (covers == dns_rdatatype_any) {
- set_ttl(rbtdb, topheader, 0);
- topheader->attributes |=
- RDATASET_ATTR_STALE;
- rbtnode->dirty = 1;
- } else if (topheader->type == sigtype)
- sigheader = topheader;
- }
- if (covers == dns_rdatatype_any)
- goto find_header;
- negtype = RBTDB_RDATATYPE_VALUE(covers, 0);
- } else {
- /*
- * We're adding something that isn't a
- * negative cache entry. Look for an extant
- * non-stale NXDOMAIN/NODATA(QTYPE=ANY) negative
- * cache entry. If we're adding an RRSIG, also
- * check for an extant non-stale NODATA ncache
- * entry which covers the same type as the RRSIG.
- */
- for (topheader = rbtnode->data;
- topheader != NULL;
- topheader = topheader->next) {
- if ((topheader->type ==
- RBTDB_RDATATYPE_NCACHEANY) ||
- (newheader->type == sigtype &&
- topheader->type ==
- RBTDB_RDATATYPE_VALUE(0, covers))) {
- break;
- }
- }
- if (topheader != NULL && EXISTS(topheader) &&
- topheader->rdh_ttl > now) {
- /*
- * Found one.
- */
- if (trust < topheader->trust) {
- /*
- * The NXDOMAIN/NODATA(QTYPE=ANY)
- * is more trusted.
- */
- free_rdataset(rbtdb,
- rbtdb->common.mctx,
- newheader);
- if (addedrdataset != NULL)
- bind_rdataset(rbtdb, rbtnode,
- topheader, now,
- addedrdataset);
- return (DNS_R_UNCHANGED);
- }
- /*
- * The new rdataset is better. Expire the
- * ncache entry.
- */
- set_ttl(rbtdb, topheader, 0);
- topheader->attributes |= RDATASET_ATTR_STALE;
- rbtnode->dirty = 1;
- topheader = NULL;
- goto find_header;
- }
- negtype = RBTDB_RDATATYPE_VALUE(0, rdtype);
- }
- }
-
- for (topheader = rbtnode->data;
- topheader != NULL;
- topheader = topheader->next) {
- if (topheader->type == newheader->type ||
- topheader->type == negtype)
- break;
- topheader_prev = topheader;
- }
-
- find_header:
- /*
- * If header isn't NULL, we've found the right type. There may be
- * IGNORE rdatasets between the top of the chain and the first real
- * data. We skip over them.
- */
- header = topheader;
- while (header != NULL && IGNORE(header))
- header = header->down;
- if (header != NULL) {
- header_nx = NONEXISTENT(header) ? ISC_TRUE : ISC_FALSE;
-
- /*
- * Deleting an already non-existent rdataset has no effect.
- */
- if (header_nx && newheader_nx) {
- free_rdataset(rbtdb, rbtdb->common.mctx, newheader);
- return (DNS_R_UNCHANGED);
- }
-
- /*
- * Trying to add an rdataset with lower trust to a cache DB
- * has no effect, provided that the cache data isn't stale.
- */
- if (rbtversion == NULL && trust < header->trust &&
- (header->rdh_ttl > now || header_nx)) {
- free_rdataset(rbtdb, rbtdb->common.mctx, newheader);
- if (addedrdataset != NULL)
- bind_rdataset(rbtdb, rbtnode, header, now,
- addedrdataset);
- return (DNS_R_UNCHANGED);
- }
-
- /*
- * Don't merge if a nonexistent rdataset is involved.
- */
- if (merge && (header_nx || newheader_nx))
- merge = ISC_FALSE;
-
- /*
- * If 'merge' is ISC_TRUE, we'll try to create a new rdataset
- * that is the union of 'newheader' and 'header'.
- */
- if (merge) {
- unsigned int flags = 0;
- INSIST(rbtversion->serial >= header->serial);
- merged = NULL;
- result = ISC_R_SUCCESS;
-
- if ((options & DNS_DBADD_EXACT) != 0)
- flags |= DNS_RDATASLAB_EXACT;
- if ((options & DNS_DBADD_EXACTTTL) != 0 &&
- newheader->rdh_ttl != header->rdh_ttl)
- result = DNS_R_NOTEXACT;
- else if (newheader->rdh_ttl != header->rdh_ttl)
- flags |= DNS_RDATASLAB_FORCE;
- if (result == ISC_R_SUCCESS)
- result = dns_rdataslab_merge(
- (unsigned char *)header,
- (unsigned char *)newheader,
- (unsigned int)(sizeof(*newheader)),
- rbtdb->common.mctx,
- rbtdb->common.rdclass,
- (dns_rdatatype_t)header->type,
- flags, &merged);
- if (result == ISC_R_SUCCESS) {
- /*
- * If 'header' has the same serial number as
- * we do, we could clean it up now if we knew
- * that our caller had no references to it.
- * We don't know this, however, so we leave it
- * alone. It will get cleaned up when
- * clean_zone_node() runs.
- */
- 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)
- newheader->resign = header->resign;
- } else {
- free_rdataset(rbtdb, rbtdb->common.mctx,
- newheader);
- return (result);
- }
- }
- /*
- * Don't replace existing NS, A and AAAA RRsets
- * in the cache if they are already exist. This
- * prevents named being locked to old servers.
- * Don't lower trust of existing record if the
- * update is forced.
- */
- if (IS_CACHE(rbtdb) && header->rdh_ttl > now &&
- header->type == dns_rdatatype_ns &&
- !header_nx && !newheader_nx &&
- header->trust >= newheader->trust &&
- dns_rdataslab_equalx((unsigned char *)header,
- (unsigned char *)newheader,
- (unsigned int)(sizeof(*newheader)),
- rbtdb->common.rdclass,
- (dns_rdatatype_t)header->type)) {
- /*
- * Honour the new ttl if it is less than the
- * older one.
- */
- if (header->rdh_ttl > newheader->rdh_ttl)
- set_ttl(rbtdb, header, newheader->rdh_ttl);
- if (header->noqname == NULL &&
- newheader->noqname != NULL) {
- header->noqname = newheader->noqname;
- newheader->noqname = NULL;
- }
- if (header->closest == NULL &&
- newheader->closest != NULL) {
- header->closest = newheader->closest;
- newheader->closest = NULL;
- }
- free_rdataset(rbtdb, rbtdb->common.mctx, newheader);
- if (addedrdataset != NULL)
- bind_rdataset(rbtdb, rbtnode, header, now,
- addedrdataset);
- return (ISC_R_SUCCESS);
- }
- /*
- * If we have will be replacing a NS RRset force its TTL
- * to be no more than the current NS RRset's TTL. This
- * ensures the delegations that are withdrawn are honoured.
- */
- if (IS_CACHE(rbtdb) && header->rdh_ttl > now &&
- header->type == dns_rdatatype_ns &&
- !header_nx && !newheader_nx &&
- header->trust <= newheader->trust) {
- if (newheader->rdh_ttl > header->rdh_ttl) {
- newheader->rdh_ttl = header->rdh_ttl;
- }
- }
- if (IS_CACHE(rbtdb) && header->rdh_ttl > now &&
- (header->type == dns_rdatatype_a ||
- header->type == dns_rdatatype_aaaa ||
- header->type == dns_rdatatype_ds ||
- header->type == RBTDB_RDATATYPE_SIGDDS) &&
- !header_nx && !newheader_nx &&
- header->trust >= newheader->trust &&
- dns_rdataslab_equal((unsigned char *)header,
- (unsigned char *)newheader,
- (unsigned int)(sizeof(*newheader)))) {
- /*
- * Honour the new ttl if it is less than the
- * older one.
- */
- if (header->rdh_ttl > newheader->rdh_ttl)
- set_ttl(rbtdb, header, newheader->rdh_ttl);
- if (header->noqname == NULL &&
- newheader->noqname != NULL) {
- header->noqname = newheader->noqname;
- newheader->noqname = NULL;
- }
- if (header->closest == NULL &&
- newheader->closest != NULL) {
- header->closest = newheader->closest;
- newheader->closest = NULL;
- }
- free_rdataset(rbtdb, rbtdb->common.mctx, newheader);
- if (addedrdataset != NULL)
- bind_rdataset(rbtdb, rbtnode, header, now,
- addedrdataset);
- return (ISC_R_SUCCESS);
- }
- INSIST(rbtversion == NULL ||
- rbtversion->serial >= topheader->serial);
- if (topheader_prev != NULL)
- topheader_prev->next = newheader;
- else
- rbtnode->data = newheader;
- newheader->next = topheader->next;
- if (loading) {
- /*
- * There are no other references to 'header' when
- * loading, so we MAY clean up 'header' now.
- * Since we don't generate changed records when
- * loading, we MUST clean up 'header' now.
- */
- newheader->down = NULL;
- free_rdataset(rbtdb, rbtdb->common.mctx, header);
- } else {
- newheader->down = topheader;
- topheader->next = newheader;
- rbtnode->dirty = 1;
- if (changed != NULL)
- changed->dirty = ISC_TRUE;
- if (rbtversion == NULL) {
- set_ttl(rbtdb, header, 0);
- header->attributes |= RDATASET_ATTR_STALE;
- if (sigheader != NULL) {
- set_ttl(rbtdb, sigheader, 0);
- sigheader->attributes |=
- RDATASET_ATTR_STALE;
- }
- }
- idx = newheader->node->locknum;
- if (IS_CACHE(rbtdb)) {
- ISC_LIST_PREPEND(rbtdb->rdatasets[idx],
- newheader, link);
- /*
- * XXXMLG We don't check the return value
- * here. If it fails, we will not do TTL
- * based expiry on this node. However, we
- * will do it on the LRU side, so memory
- * will not leak... for long.
- */
- INSIST(rbtdb->heaps != NULL);
- isc_heap_insert(rbtdb->heaps[idx], newheader);
- } else if (RESIGN(newheader))
- resign_insert(rbtdb, idx, newheader);
- }
- } else {
- /*
- * No non-IGNORED rdatasets of the given type exist at
- * this node.
- */
-
- /*
- * If we're trying to delete the type, don't bother.
- */
- if (newheader_nx) {
- free_rdataset(rbtdb, rbtdb->common.mctx, newheader);
- return (DNS_R_UNCHANGED);
- }
-
- if (topheader != NULL) {
- /*
- * We have an list of rdatasets of the given type,
- * but they're all marked IGNORE. We simply insert
- * the new rdataset at the head of the list.
- *
- * Ignored rdatasets cannot occur during loading, so
- * we INSIST on it.
- */
- INSIST(!loading);
- INSIST(rbtversion == NULL ||
- rbtversion->serial >= topheader->serial);
- if (topheader_prev != NULL)
- topheader_prev->next = newheader;
- else
- rbtnode->data = newheader;
- newheader->next = topheader->next;
- newheader->down = topheader;
- topheader->next = newheader;
- rbtnode->dirty = 1;
- if (changed != NULL)
- changed->dirty = ISC_TRUE;
- } else {
- /*
- * No rdatasets of the given type exist at the node.
- */
- newheader->next = rbtnode->data;
- newheader->down = NULL;
- rbtnode->data = newheader;
- }
- idx = newheader->node->locknum;
- if (IS_CACHE(rbtdb)) {
- ISC_LIST_PREPEND(rbtdb->rdatasets[idx],
- newheader, link);
- isc_heap_insert(rbtdb->heaps[idx], newheader);
- } else if (RESIGN(newheader)) {
- resign_insert(rbtdb, idx, newheader);
- }
- }
-
- /*
- * Check if the node now contains CNAME and other data.
- */
- if (rbtversion != NULL &&
- cname_and_other_data(rbtnode, rbtversion->serial))
- return (DNS_R_CNAMEANDOTHER);
-
- if (addedrdataset != NULL)
- bind_rdataset(rbtdb, rbtnode, newheader, now, addedrdataset);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_boolean_t
-delegating_type(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
- rbtdb_rdatatype_t type)
-{
- if (IS_CACHE(rbtdb)) {
- if (type == dns_rdatatype_dname)
- return (ISC_TRUE);
- else
- return (ISC_FALSE);
- } else if (type == dns_rdatatype_dname ||
- (type == dns_rdatatype_ns &&
- (node != rbtdb->origin_node || IS_STUB(rbtdb))))
- return (ISC_TRUE);
- return (ISC_FALSE);
-}
-
-static inline isc_result_t
-addnoqname(dns_rbtdb_t *rbtdb, rdatasetheader_t *newheader,
- dns_rdataset_t *rdataset)
-{
- struct noqname *noqname;
- isc_mem_t *mctx = rbtdb->common.mctx;
- dns_name_t name;
- dns_rdataset_t neg, negsig;
- isc_result_t result;
- isc_region_t r;
-
- dns_name_init(&name, NULL);
- dns_rdataset_init(&neg);
- dns_rdataset_init(&negsig);
-
- result = dns_rdataset_getnoqname(rdataset, &name, &neg, &negsig);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
-
- noqname = isc_mem_get(mctx, sizeof(*noqname));
- if (noqname == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup;
- }
- dns_name_init(&noqname->name, NULL);
- noqname->neg = NULL;
- noqname->negsig = NULL;
- noqname->type = neg.type;
- result = dns_name_dup(&name, mctx, &noqname->name);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- result = dns_rdataslab_fromrdataset(&neg, mctx, &r, 0);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- noqname->neg = r.base;
- result = dns_rdataslab_fromrdataset(&negsig, mctx, &r, 0);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- noqname->negsig = r.base;
- dns_rdataset_disassociate(&neg);
- dns_rdataset_disassociate(&negsig);
- newheader->noqname = noqname;
- return (ISC_R_SUCCESS);
-
-cleanup:
- dns_rdataset_disassociate(&neg);
- dns_rdataset_disassociate(&negsig);
- if (noqname != NULL)
- free_noqname(mctx, &noqname);
- return(result);
-}
-
-static inline isc_result_t
-addclosest(dns_rbtdb_t *rbtdb, rdatasetheader_t *newheader,
- dns_rdataset_t *rdataset)
-{
- struct noqname *closest;
- isc_mem_t *mctx = rbtdb->common.mctx;
- dns_name_t name;
- dns_rdataset_t neg, negsig;
- isc_result_t result;
- isc_region_t r;
-
- dns_name_init(&name, NULL);
- dns_rdataset_init(&neg);
- dns_rdataset_init(&negsig);
-
- result = dns_rdataset_getclosest(rdataset, &name, &neg, &negsig);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
-
- closest = isc_mem_get(mctx, sizeof(*closest));
- if (closest == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup;
- }
- dns_name_init(&closest->name, NULL);
- closest->neg = NULL;
- closest->negsig = NULL;
- closest->type = neg.type;
- result = dns_name_dup(&name, mctx, &closest->name);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- result = dns_rdataslab_fromrdataset(&neg, mctx, &r, 0);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- closest->neg = r.base;
- result = dns_rdataslab_fromrdataset(&negsig, mctx, &r, 0);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- closest->negsig = r.base;
- dns_rdataset_disassociate(&neg);
- dns_rdataset_disassociate(&negsig);
- newheader->closest = closest;
- return (ISC_R_SUCCESS);
-
- cleanup:
- dns_rdataset_disassociate(&neg);
- dns_rdataset_disassociate(&negsig);
- if (closest != NULL)
- free_noqname(mctx, &closest);
- return(result);
-}
-
-static dns_dbmethods_t zone_methods;
-
-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_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
- dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node;
- rbtdb_version_t *rbtversion = version;
- isc_region_t region;
- rdatasetheader_t *newheader;
- 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));
- INSIST(rbtversion == NULL || rbtversion->rbtdb == rbtdb);
-
- if (rbtdb->common.methods == &zone_methods)
- REQUIRE(((rbtnode->nsec == DNS_RBT_NSEC_NSEC3 &&
- (rdataset->type == dns_rdatatype_nsec3 ||
- rdataset->covers == dns_rdatatype_nsec3)) ||
- (rbtnode->nsec != DNS_RBT_NSEC_NSEC3 &&
- rdataset->type != dns_rdatatype_nsec3 &&
- rdataset->covers != dns_rdatatype_nsec3)));
-
- if (rbtversion == NULL) {
- if (now == 0)
- isc_stdtime_get(&now);
- } else
- now = 0;
-
- result = dns_rdataslab_fromrdataset(rdataset, rbtdb->common.mctx,
- &region, sizeof(rdatasetheader_t));
- if (result != ISC_R_SUCCESS)
- return (result);
-
- newheader = (rdatasetheader_t *)region.base;
- init_rdataset(rbtdb, newheader);
- set_ttl(rbtdb, newheader, rdataset->ttl + now);
- newheader->type = RBTDB_RDATATYPE_VALUE(rdataset->type,
- rdataset->covers);
- newheader->attributes = 0;
- newheader->noqname = NULL;
- newheader->closest = NULL;
- newheader->count = init_count++;
- newheader->trust = rdataset->trust;
- newheader->additional_auth = NULL;
- newheader->additional_glue = NULL;
- newheader->last_used = now;
- newheader->node = rbtnode;
- if (rbtversion != NULL) {
- newheader->serial = rbtversion->serial;
- now = 0;
-
- if ((rdataset->attributes & DNS_RDATASETATTR_RESIGN) != 0) {
- newheader->attributes |= RDATASET_ATTR_RESIGN;
- newheader->resign = rdataset->resign;
- } else
- newheader->resign = 0;
- } else {
- newheader->serial = 1;
- newheader->resign = 0;
- if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0)
- newheader->attributes |= RDATASET_ATTR_NEGATIVE;
- if ((rdataset->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0)
- newheader->attributes |= RDATASET_ATTR_NXDOMAIN;
- if ((rdataset->attributes & DNS_RDATASETATTR_OPTOUT) != 0)
- newheader->attributes |= RDATASET_ATTR_OPTOUT;
- if ((rdataset->attributes & DNS_RDATASETATTR_NOQNAME) != 0) {
- result = addnoqname(rbtdb, newheader, rdataset);
- if (result != ISC_R_SUCCESS) {
- free_rdataset(rbtdb, rbtdb->common.mctx,
- newheader);
- return (result);
- }
- }
- if ((rdataset->attributes & DNS_RDATASETATTR_CLOSEST) != 0) {
- result = addclosest(rbtdb, newheader, rdataset);
- if (result != ISC_R_SUCCESS) {
- free_rdataset(rbtdb, rbtdb->common.mctx,
- newheader);
- return (result);
- }
- }
- }
-
- /*
- * If we're adding a delegation type (e.g. NS or DNAME for a zone,
- * just DNAME for the cache), then we need to set the callback bit
- * on the node.
- */
- if (delegating_type(rbtdb, rbtnode, rdataset->type))
- delegating = ISC_TRUE;
- else
- delegating = ISC_FALSE;
-
- /*
- * 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 || newnsec || cache_is_overmem) {
- tree_locked = ISC_TRUE;
- RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
- }
-
- if (cache_is_overmem)
- overmem_purge(rbtdb, rbtnode->locknum, now, tree_locked);
-
- NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_write);
-
- if (rbtdb->rrsetstats != NULL) {
- newheader->attributes |= RDATASET_ATTR_STATCOUNT;
- update_rrsetstats(rbtdb, newheader, ISC_TRUE);
- }
-
- if (IS_CACHE(rbtdb)) {
- if (tree_locked)
- cleanup_dead_nodes(rbtdb, rbtnode->locknum);
-
- header = isc_heap_element(rbtdb->heaps[rbtnode->locknum], 1);
- if (header && header->rdh_ttl <= now - RBTDB_VIRTUAL)
- expire_header(rbtdb, header, tree_locked);
-
- /*
- * If we've been holding a write lock on the tree just for
- * cleaning, we can release it now. However, we still need the
- * node lock.
- */
- if (tree_locked && !delegating && !newnsec) {
- RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
- tree_locked = ISC_FALSE;
- }
- }
-
- 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;
-
- NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_write);
-
- if (tree_locked)
- RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
-
- /*
- * Update the zone's secure status. If version is non-NULL
- * this is deferred until closeversion() is called.
- */
- if (result == ISC_R_SUCCESS && version == NULL && !IS_CACHE(rbtdb))
- iszonesecure(db, version, rbtdb->origin_node);
-
- 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)
-{
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
- dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node;
- rbtdb_version_t *rbtversion = version;
- rdatasetheader_t *topheader, *topheader_prev, *header, *newheader;
- unsigned char *subresult;
- isc_region_t region;
- isc_result_t result;
- rbtdb_changed_t *changed;
-
- REQUIRE(VALID_RBTDB(rbtdb));
- REQUIRE(rbtversion != NULL && rbtversion->rbtdb == rbtdb);
-
- if (rbtdb->common.methods == &zone_methods)
- REQUIRE(((rbtnode->nsec == DNS_RBT_NSEC_NSEC3 &&
- (rdataset->type == dns_rdatatype_nsec3 ||
- rdataset->covers == dns_rdatatype_nsec3)) ||
- (rbtnode->nsec != DNS_RBT_NSEC_NSEC3 &&
- rdataset->type != dns_rdatatype_nsec3 &&
- rdataset->covers != dns_rdatatype_nsec3)));
-
- result = dns_rdataslab_fromrdataset(rdataset, rbtdb->common.mctx,
- &region,
- sizeof(rdatasetheader_t));
- if (result != ISC_R_SUCCESS)
- return (result);
- newheader = (rdatasetheader_t *)region.base;
- init_rdataset(rbtdb, newheader);
- set_ttl(rbtdb, newheader, rdataset->ttl);
- newheader->type = RBTDB_RDATATYPE_VALUE(rdataset->type,
- rdataset->covers);
- newheader->attributes = 0;
- newheader->serial = rbtversion->serial;
- newheader->trust = 0;
- newheader->noqname = NULL;
- newheader->closest = NULL;
- newheader->count = init_count++;
- newheader->additional_auth = NULL;
- newheader->additional_glue = NULL;
- newheader->last_used = 0;
- newheader->node = rbtnode;
- if ((rdataset->attributes & DNS_RDATASETATTR_RESIGN) != 0) {
- newheader->attributes |= RDATASET_ATTR_RESIGN;
- newheader->resign = rdataset->resign;
- } else
- newheader->resign = 0;
-
- NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_write);
-
- changed = add_changed(rbtdb, rbtversion, rbtnode);
- if (changed == NULL) {
- free_rdataset(rbtdb, rbtdb->common.mctx, newheader);
- NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_write);
- return (ISC_R_NOMEMORY);
- }
-
- topheader_prev = NULL;
- for (topheader = rbtnode->data;
- topheader != NULL;
- topheader = topheader->next) {
- if (topheader->type == newheader->type)
- break;
- topheader_prev = topheader;
- }
- /*
- * If header isn't NULL, we've found the right type. There may be
- * IGNORE rdatasets between the top of the chain and the first real
- * data. We skip over them.
- */
- header = topheader;
- while (header != NULL && IGNORE(header))
- header = header->down;
- if (header != NULL && EXISTS(header)) {
- unsigned int flags = 0;
- subresult = NULL;
- result = ISC_R_SUCCESS;
- if ((options & DNS_DBSUB_EXACT) != 0) {
- flags |= DNS_RDATASLAB_EXACT;
- if (newheader->rdh_ttl != header->rdh_ttl)
- result = DNS_R_NOTEXACT;
- }
- if (result == ISC_R_SUCCESS)
- result = dns_rdataslab_subtract(
- (unsigned char *)header,
- (unsigned char *)newheader,
- (unsigned int)(sizeof(*newheader)),
- rbtdb->common.mctx,
- rbtdb->common.rdclass,
- (dns_rdatatype_t)header->type,
- flags, &subresult);
- if (result == ISC_R_SUCCESS) {
- free_rdataset(rbtdb, rbtdb->common.mctx, newheader);
- newheader = (rdatasetheader_t *)subresult;
- init_rdataset(rbtdb, newheader);
- /*
- * We have to set the serial since the rdataslab
- * subtraction routine copies the reserved portion of
- * header, not newheader.
- */
- newheader->serial = rbtversion->serial;
- /*
- * XXXJT: dns_rdataslab_subtract() copied the pointers
- * to additional info. We need to clear these fields
- * to avoid having duplicated references.
- */
- newheader->additional_auth = NULL;
- newheader->additional_glue = NULL;
- } else if (result == DNS_R_NXRRSET) {
- /*
- * This subtraction would remove all of the rdata;
- * add a nonexistent header instead.
- */
- free_rdataset(rbtdb, rbtdb->common.mctx, newheader);
- newheader = new_rdataset(rbtdb, rbtdb->common.mctx);
- if (newheader == NULL) {
- result = ISC_R_NOMEMORY;
- goto unlock;
- }
- set_ttl(rbtdb, newheader, 0);
- newheader->type = topheader->type;
- newheader->attributes = RDATASET_ATTR_NONEXISTENT;
- newheader->trust = 0;
- newheader->serial = rbtversion->serial;
- newheader->noqname = NULL;
- newheader->closest = NULL;
- newheader->count = 0;
- newheader->additional_auth = NULL;
- newheader->additional_glue = NULL;
- newheader->node = rbtnode;
- newheader->resign = 0;
- newheader->last_used = 0;
- } else {
- free_rdataset(rbtdb, rbtdb->common.mctx, newheader);
- goto unlock;
- }
-
- /*
- * If we're here, we want to link newheader in front of
- * topheader.
- */
- INSIST(rbtversion->serial >= topheader->serial);
- if (topheader_prev != NULL)
- topheader_prev->next = newheader;
- else
- rbtnode->data = newheader;
- newheader->next = topheader->next;
- newheader->down = topheader;
- topheader->next = newheader;
- rbtnode->dirty = 1;
- changed->dirty = ISC_TRUE;
- } else {
- /*
- * The rdataset doesn't exist, so we don't need to do anything
- * to satisfy the deletion request.
- */
- free_rdataset(rbtdb, rbtdb->common.mctx, newheader);
- if ((options & DNS_DBSUB_EXACT) != 0)
- result = DNS_R_NOTEXACT;
- else
- result = DNS_R_UNCHANGED;
- }
-
- if (result == ISC_R_SUCCESS && newrdataset != NULL)
- bind_rdataset(rbtdb, rbtnode, newheader, 0, newrdataset);
-
- unlock:
- NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_write);
-
- /*
- * Update the zone's secure status. If version is non-NULL
- * this is deferred until closeversion() is called.
- */
- if (result == ISC_R_SUCCESS && version == NULL && !IS_CACHE(rbtdb))
- iszonesecure(db, rbtdb->current_version, rbtdb->origin_node);
-
- 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)
-{
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
- dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node;
- rbtdb_version_t *rbtversion = version;
- isc_result_t result;
- rdatasetheader_t *newheader;
-
- REQUIRE(VALID_RBTDB(rbtdb));
- INSIST(rbtversion == NULL || rbtversion->rbtdb == rbtdb);
-
- if (type == dns_rdatatype_any)
- return (ISC_R_NOTIMPLEMENTED);
- if (type == dns_rdatatype_rrsig && covers == 0)
- return (ISC_R_NOTIMPLEMENTED);
-
- newheader = new_rdataset(rbtdb, rbtdb->common.mctx);
- if (newheader == NULL)
- return (ISC_R_NOMEMORY);
- set_ttl(rbtdb, newheader, 0);
- newheader->type = RBTDB_RDATATYPE_VALUE(type, covers);
- newheader->attributes = RDATASET_ATTR_NONEXISTENT;
- newheader->trust = 0;
- newheader->noqname = NULL;
- newheader->closest = NULL;
- newheader->additional_auth = NULL;
- newheader->additional_glue = NULL;
- if (rbtversion != NULL)
- newheader->serial = rbtversion->serial;
- else
- newheader->serial = 0;
- newheader->count = 0;
- newheader->last_used = 0;
- newheader->node = rbtnode;
-
- NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_write);
-
- result = add(rbtdb, rbtnode, rbtversion, newheader, DNS_DBADD_FORCE,
- ISC_FALSE, NULL, 0);
-
- NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_write);
-
- /*
- * Update the zone's secure status. If version is non-NULL
- * this is deferred until closeversion() is called.
- */
- if (result == ISC_R_SUCCESS && version == NULL && !IS_CACHE(rbtdb))
- iszonesecure(db, rbtdb->current_version, rbtdb->origin_node);
-
- 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 && rbtdb->rpz_cidr != NULL)
- 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;
- dns_rbtdb_t *rbtdb = loadctx->rbtdb;
- dns_rbtnode_t *node;
- isc_result_t result;
- isc_region_t region;
- rdatasetheader_t *newheader;
-
- /*
- * This routine does no node locking. See comments in
- * 'load' below for more information on loading and
- * locking.
- */
-
-
- /*
- * SOA records are only allowed at top of zone.
- */
- if (rdataset->type == dns_rdatatype_soa &&
- !IS_CACHE(rbtdb) && !dns_name_equal(name, &rbtdb->common.origin))
- return (DNS_R_NOTZONETOP);
-
- if (rdataset->type != dns_rdatatype_nsec3 &&
- rdataset->covers != dns_rdatatype_nsec3)
- add_empty_wildcards(rbtdb, name);
-
- if (dns_name_iswildcard(name)) {
- /*
- * NS record owners cannot legally be wild cards.
- */
- if (rdataset->type == dns_rdatatype_ns)
- return (DNS_R_INVALIDNS);
- /*
- * NSEC3 record owners cannot legally be wild cards.
- */
- if (rdataset->type == dns_rdatatype_nsec3)
- return (DNS_R_INVALIDNSEC3);
- result = add_wildcard_magic(rbtdb, name);
- if (result != ISC_R_SUCCESS)
- return (result);
- }
-
- node = NULL;
- if (rdataset->type == dns_rdatatype_nsec3 ||
- rdataset->covers == dns_rdatatype_nsec3) {
- result = dns_rbt_addnode(rbtdb->nsec3, name, &node);
- if (result == ISC_R_SUCCESS)
- node->nsec = DNS_RBT_NSEC_NSEC3;
- } else if (rdataset->type == dns_rdatatype_nsec) {
- result = loadnode(rbtdb, name, &node, ISC_TRUE);
- } else {
- result = loadnode(rbtdb, name, &node, ISC_FALSE);
- }
- if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS)
- return (result);
- if (result == ISC_R_SUCCESS) {
- dns_name_t foundname;
- dns_name_init(&foundname, NULL);
- dns_rbt_namefromnode(node, &foundname);
-#ifdef DNS_RBT_USEHASH
- node->locknum = node->hashval % rbtdb->node_lock_count;
-#else
- node->locknum = dns_name_hash(&foundname, ISC_TRUE) %
- rbtdb->node_lock_count;
-#endif
- }
-
- result = dns_rdataslab_fromrdataset(rdataset, rbtdb->common.mctx,
- &region,
- sizeof(rdatasetheader_t));
- if (result != ISC_R_SUCCESS)
- return (result);
- newheader = (rdatasetheader_t *)region.base;
- init_rdataset(rbtdb, newheader);
- set_ttl(rbtdb, newheader,
- rdataset->ttl + loadctx->now); /* XXX overflow check */
- newheader->type = RBTDB_RDATATYPE_VALUE(rdataset->type,
- rdataset->covers);
- newheader->attributes = 0;
- newheader->trust = rdataset->trust;
- newheader->serial = 1;
- newheader->noqname = NULL;
- newheader->closest = NULL;
- newheader->count = init_count++;
- newheader->additional_auth = NULL;
- newheader->additional_glue = NULL;
- newheader->last_used = 0;
- newheader->node = node;
- if ((rdataset->attributes & DNS_RDATASETATTR_RESIGN) != 0) {
- newheader->attributes |= RDATASET_ATTR_RESIGN;
- newheader->resign = rdataset->resign;
- } else
- newheader->resign = 0;
-
- result = add(rbtdb, node, rbtdb->current_version, newheader,
- DNS_DBADD_MERGE, ISC_TRUE, NULL, 0);
- if (result == ISC_R_SUCCESS &&
- delegating_type(rbtdb, node, rdataset->type))
- node->find_callback = 1;
- else if (result == DNS_R_UNCHANGED)
- result = ISC_R_SUCCESS;
-
- return (result);
-}
-
-static isc_result_t
-beginload(dns_db_t *db, dns_addrdatasetfunc_t *addp, dns_dbload_t **dbloadp) {
- rbtdb_load_t *loadctx;
- dns_rbtdb_t *rbtdb;
-
- rbtdb = (dns_rbtdb_t *)db;
-
- REQUIRE(VALID_RBTDB(rbtdb));
-
- loadctx = isc_mem_get(rbtdb->common.mctx, sizeof(*loadctx));
- if (loadctx == NULL)
- return (ISC_R_NOMEMORY);
-
- loadctx->rbtdb = rbtdb;
- if (IS_CACHE(rbtdb))
- isc_stdtime_get(&loadctx->now);
- else
- loadctx->now = 0;
-
- RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write);
-
- REQUIRE((rbtdb->attributes & (RBTDB_ATTR_LOADED|RBTDB_ATTR_LOADING))
- == 0);
- rbtdb->attributes |= RBTDB_ATTR_LOADING;
-
- RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write);
-
- *addp = loading_addrdataset;
- *dbloadp = loadctx;
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-endload(dns_db_t *db, dns_dbload_t **dbloadp) {
- rbtdb_load_t *loadctx;
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
-
- REQUIRE(VALID_RBTDB(rbtdb));
- REQUIRE(dbloadp != NULL);
- loadctx = *dbloadp;
- REQUIRE(loadctx->rbtdb == rbtdb);
-
- RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write);
-
- REQUIRE((rbtdb->attributes & RBTDB_ATTR_LOADING) != 0);
- REQUIRE((rbtdb->attributes & RBTDB_ATTR_LOADED) == 0);
-
- rbtdb->attributes &= ~RBTDB_ATTR_LOADING;
- rbtdb->attributes |= RBTDB_ATTR_LOADED;
-
- RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write);
-
- /*
- * If there's a KEY rdataset at the zone origin containing a
- * zone key, we consider the zone secure.
- */
- if (! IS_CACHE(rbtdb))
- iszonesecure(db, rbtdb->current_version, rbtdb->origin_node);
-
- *dbloadp = NULL;
-
- isc_mem_put(rbtdb->common.mctx, loadctx, sizeof(*loadctx));
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-dump(dns_db_t *db, dns_dbversion_t *version, const char *filename,
- dns_masterformat_t masterformat) {
- dns_rbtdb_t *rbtdb;
- rbtdb_version_t *rbtversion = version;
-
- rbtdb = (dns_rbtdb_t *)db;
-
- REQUIRE(VALID_RBTDB(rbtdb));
- INSIST(rbtversion == NULL || rbtversion->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
-delete_callback(void *data, void *arg) {
- dns_rbtdb_t *rbtdb = arg;
- rdatasetheader_t *current, *next;
- unsigned int locknum;
-
- current = data;
- locknum = current->node->locknum;
- NODE_LOCK(&rbtdb->node_locks[locknum].lock, isc_rwlocktype_write);
- while (current != NULL) {
- next = current->next;
- free_rdataset(rbtdb, rbtdb->common.mctx, current);
- current = next;
- }
- NODE_UNLOCK(&rbtdb->node_locks[locknum].lock, isc_rwlocktype_write);
-}
-
-static isc_boolean_t
-issecure(dns_db_t *db) {
- dns_rbtdb_t *rbtdb;
- isc_boolean_t secure;
-
- rbtdb = (dns_rbtdb_t *)db;
-
- REQUIRE(VALID_RBTDB(rbtdb));
-
- RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
- secure = ISC_TF(rbtdb->current_version->secure == dns_db_secure);
- RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
-
- return (secure);
-}
-
-static isc_boolean_t
-isdnssec(dns_db_t *db) {
- dns_rbtdb_t *rbtdb;
- isc_boolean_t dnssec;
-
- rbtdb = (dns_rbtdb_t *)db;
-
- REQUIRE(VALID_RBTDB(rbtdb));
-
- RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
- dnssec = ISC_TF(rbtdb->current_version->secure != dns_db_insecure);
- RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
-
- return (dnssec);
-}
-
-static unsigned int
-nodecount(dns_db_t *db) {
- dns_rbtdb_t *rbtdb;
- unsigned int count;
-
- rbtdb = (dns_rbtdb_t *)db;
-
- REQUIRE(VALID_RBTDB(rbtdb));
-
- RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
- count = dns_rbt_nodecount(rbtdb->tree);
- RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
-
- return (count);
-}
-
-static void
-settask(dns_db_t *db, isc_task_t *task) {
- dns_rbtdb_t *rbtdb;
-
- rbtdb = (dns_rbtdb_t *)db;
-
- REQUIRE(VALID_RBTDB(rbtdb));
-
- RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write);
- if (rbtdb->task != NULL)
- isc_task_detach(&rbtdb->task);
- if (task != NULL)
- isc_task_attach(task, &rbtdb->task);
- RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write);
-}
-
-static isc_boolean_t
-ispersistent(dns_db_t *db) {
- UNUSED(db);
- return (ISC_FALSE);
-}
-
-static isc_result_t
-getoriginnode(dns_db_t *db, dns_dbnode_t **nodep) {
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
- dns_rbtnode_t *onode;
- isc_result_t result = ISC_R_SUCCESS;
-
- REQUIRE(VALID_RBTDB(rbtdb));
- REQUIRE(nodep != NULL && *nodep == NULL);
-
- /* Note that the access to origin_node doesn't require a DB lock */
- onode = (dns_rbtnode_t *)rbtdb->origin_node;
- if (onode != NULL) {
- NODE_STRONGLOCK(&rbtdb->node_locks[onode->locknum].lock);
- new_reference(rbtdb, onode);
- NODE_STRONGUNLOCK(&rbtdb->node_locks[onode->locknum].lock);
-
- *nodep = rbtdb->origin_node;
- } else {
- INSIST(IS_CACHE(rbtdb));
- result = ISC_R_NOTFOUND;
- }
-
- return (result);
-}
-
-static isc_result_t
-getnsec3parameters(dns_db_t *db, dns_dbversion_t *version, dns_hash_t *hash,
- isc_uint8_t *flags, isc_uint16_t *iterations,
- unsigned char *salt, size_t *salt_length)
-{
- dns_rbtdb_t *rbtdb;
- isc_result_t result = ISC_R_NOTFOUND;
- rbtdb_version_t *rbtversion = version;
-
- rbtdb = (dns_rbtdb_t *)db;
-
- REQUIRE(VALID_RBTDB(rbtdb));
- INSIST(rbtversion == NULL || rbtversion->rbtdb == rbtdb);
-
- RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
-
- if (rbtversion == NULL)
- rbtversion = rbtdb->current_version;
-
- if (rbtversion->havensec3) {
- if (hash != NULL)
- *hash = rbtversion->hash;
- if (salt != NULL && salt_length != NULL) {
- REQUIRE(*salt_length >= rbtversion->salt_length);
- memcpy(salt, rbtversion->salt, rbtversion->salt_length);
- }
- if (salt_length != NULL)
- *salt_length = rbtversion->salt_length;
- if (iterations != NULL)
- *iterations = rbtversion->iterations;
- if (flags != NULL)
- *flags = rbtversion->flags;
- result = ISC_R_SUCCESS;
- }
- RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
-
- return (result);
-}
-
-static isc_result_t
-setsigningtime(dns_db_t *db, dns_rdataset_t *rdataset, isc_stdtime_t resign) {
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
- isc_stdtime_t oldresign;
- isc_result_t result = ISC_R_SUCCESS;
- rdatasetheader_t *header;
-
- REQUIRE(VALID_RBTDB(rbtdb));
- REQUIRE(!IS_CACHE(rbtdb));
- REQUIRE(rdataset != NULL);
-
- header = rdataset->private3;
- header--;
-
- NODE_LOCK(&rbtdb->node_locks[header->node->locknum].lock,
- isc_rwlocktype_write);
-
- oldresign = header->resign;
- header->resign = resign;
- if (header->heap_index != 0) {
- INSIST(RESIGN(header));
- if (resign == 0) {
- isc_heap_delete(rbtdb->heaps[header->node->locknum],
- header->heap_index);
- header->heap_index = 0;
- } else if (resign < oldresign)
- isc_heap_increased(rbtdb->heaps[header->node->locknum],
- header->heap_index);
- else if (resign > oldresign)
- isc_heap_decreased(rbtdb->heaps[header->node->locknum],
- header->heap_index);
- } else if (resign && header->heap_index == 0) {
- header->attributes |= RDATASET_ATTR_RESIGN;
- result = resign_insert(rbtdb, header->node->locknum, header);
- }
- NODE_UNLOCK(&rbtdb->node_locks[header->node->locknum].lock,
- isc_rwlocktype_write);
- return (result);
-}
-
-static isc_result_t
-getsigningtime(dns_db_t *db, dns_rdataset_t *rdataset,
- dns_name_t *foundname)
-{
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
- rdatasetheader_t *header = NULL, *this;
- unsigned int i;
- isc_result_t result = ISC_R_NOTFOUND;
- unsigned int locknum;
-
- REQUIRE(VALID_RBTDB(rbtdb));
-
- RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
-
- for (i = 0; i < rbtdb->node_lock_count; i++) {
- NODE_LOCK(&rbtdb->node_locks[i].lock, isc_rwlocktype_read);
- this = isc_heap_element(rbtdb->heaps[i], 1);
- if (this == NULL) {
- NODE_UNLOCK(&rbtdb->node_locks[i].lock,
- isc_rwlocktype_read);
- continue;
- }
- if (header == NULL)
- header = this;
- else if (isc_serial_lt(this->resign, header->resign)) {
- locknum = header->node->locknum;
- NODE_UNLOCK(&rbtdb->node_locks[locknum].lock,
- isc_rwlocktype_read);
- header = this;
- } else
- NODE_UNLOCK(&rbtdb->node_locks[i].lock,
- isc_rwlocktype_read);
- }
-
- if (header == NULL)
- goto unlock;
-
- bind_rdataset(rbtdb, header->node, header, 0, rdataset);
-
- if (foundname != NULL)
- dns_rbt_fullnamefromnode(header->node, foundname);
-
- NODE_UNLOCK(&rbtdb->node_locks[header->node->locknum].lock,
- isc_rwlocktype_read);
-
- result = ISC_R_SUCCESS;
-
- unlock:
- RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
-
- return (result);
-}
-
-static void
-resigned(dns_db_t *db, dns_rdataset_t *rdataset, dns_dbversion_t *version)
-{
- rbtdb_version_t *rbtversion = (rbtdb_version_t *)version;
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
- dns_rbtnode_t *node;
- rdatasetheader_t *header;
-
- REQUIRE(VALID_RBTDB(rbtdb));
- REQUIRE(rdataset != NULL);
- REQUIRE(rdataset->methods == &rdataset_methods);
- REQUIRE(rbtdb->future_version == rbtversion);
- REQUIRE(rbtversion != NULL);
- REQUIRE(rbtversion->writer);
- REQUIRE(rbtversion->rbtdb == rbtdb);
-
- node = rdataset->private2;
- INSIST(node != NULL);
- header = rdataset->private3;
- INSIST(header != NULL);
- header--;
-
- RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
- NODE_LOCK(&rbtdb->node_locks[node->locknum].lock,
- isc_rwlocktype_write);
- /*
- * Delete from heap and save to re-signed list so that it can
- * be restored if we backout of this change.
- */
- new_reference(rbtdb, node);
- isc_heap_delete(rbtdb->heaps[node->locknum], header->heap_index);
- header->heap_index = 0;
- ISC_LIST_APPEND(rbtversion->resigned_list, header, link);
-
- NODE_UNLOCK(&rbtdb->node_locks[node->locknum].lock,
- isc_rwlocktype_write);
- RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
-}
-
-static dns_stats_t *
-getrrsetstats(dns_db_t *db) {
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
-
- REQUIRE(VALID_RBTDB(rbtdb));
- REQUIRE(IS_CACHE(rbtdb)); /* current restriction */
-
- return (rbtdb->rrsetstats);
-}
-
-static dns_dbmethods_t zone_methods = {
- attach,
- detach,
- beginload,
- endload,
- dump,
- currentversion,
- newversion,
- attachversion,
- closeversion,
- findnode,
- zone_find,
- zone_findzonecut,
- attachnode,
- detachnode,
- expirenode,
- printnode,
- createiterator,
- zone_findrdataset,
- allrdatasets,
- addrdataset,
- subtractrdataset,
- deleterdataset,
- issecure,
- nodecount,
- ispersistent,
- overmem,
- settask,
- getoriginnode,
- NULL,
- getnsec3parameters,
- findnsec3node,
- setsigningtime,
- getsigningtime,
- resigned,
- isdnssec,
- NULL,
-#ifdef BIND9
- rpz_enabled,
- rpz_findips,
-#else
- NULL,
- NULL,
-#endif
- NULL,
- NULL
-};
-
-static dns_dbmethods_t cache_methods = {
- attach,
- detach,
- beginload,
- endload,
- dump,
- currentversion,
- newversion,
- attachversion,
- closeversion,
- findnode,
- cache_find,
- cache_findzonecut,
- attachnode,
- detachnode,
- expirenode,
- printnode,
- createiterator,
- cache_findrdataset,
- allrdatasets,
- addrdataset,
- subtractrdataset,
- deleterdataset,
- issecure,
- nodecount,
- ispersistent,
- overmem,
- settask,
- getoriginnode,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- isdnssec,
- getrrsetstats,
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-isc_result_t
-#ifdef DNS_RBTDB_VERSION64
-dns_rbtdb64_create
-#else
-dns_rbtdb_create
-#endif
- (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_rbtdb_t *rbtdb;
- isc_result_t result;
- int i;
- dns_name_t name;
- isc_boolean_t (*sooner)(void *, void *);
- isc_mem_t *hmctx = mctx;
-
- /* Keep the compiler happy. */
- UNUSED(driverarg);
-
- rbtdb = isc_mem_get(mctx, sizeof(*rbtdb));
- if (rbtdb == NULL)
- return (ISC_R_NOMEMORY);
-
- /*
- * If argv[0] exists, it points to a memory context to use for heap
- */
- if (argc != 0)
- hmctx = (isc_mem_t *) argv[0];
-
- memset(rbtdb, '\0', sizeof(*rbtdb));
- dns_name_init(&rbtdb->common.origin, NULL);
- rbtdb->common.attributes = 0;
- if (type == dns_dbtype_cache) {
- rbtdb->common.methods = &cache_methods;
- rbtdb->common.attributes |= DNS_DBATTR_CACHE;
- } else if (type == dns_dbtype_stub) {
- rbtdb->common.methods = &zone_methods;
- rbtdb->common.attributes |= DNS_DBATTR_STUB;
- } else
- rbtdb->common.methods = &zone_methods;
- rbtdb->common.rdclass = rdclass;
- rbtdb->common.mctx = NULL;
-
- result = RBTDB_INITLOCK(&rbtdb->lock);
- if (result != ISC_R_SUCCESS)
- goto cleanup_rbtdb;
-
- result = isc_rwlock_init(&rbtdb->tree_lock, 0, 0);
- if (result != ISC_R_SUCCESS)
- goto cleanup_lock;
-
- /*
- * Initialize node_lock_count in a generic way to support future
- * extension which allows the user to specify this value on creation.
- * Note that when specified for a cache DB it must be larger than 1
- * as commented with the definition of DEFAULT_CACHE_NODE_LOCK_COUNT.
- */
- if (rbtdb->node_lock_count == 0) {
- if (IS_CACHE(rbtdb))
- rbtdb->node_lock_count = DEFAULT_CACHE_NODE_LOCK_COUNT;
- else
- rbtdb->node_lock_count = DEFAULT_NODE_LOCK_COUNT;
- } else if (rbtdb->node_lock_count < 2 && IS_CACHE(rbtdb)) {
- result = ISC_R_RANGE;
- goto cleanup_tree_lock;
- }
- INSIST(rbtdb->node_lock_count < (1 << DNS_RBT_LOCKLENGTH));
- rbtdb->node_locks = isc_mem_get(mctx, rbtdb->node_lock_count *
- sizeof(rbtdb_nodelock_t));
- if (rbtdb->node_locks == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup_tree_lock;
- }
-
- rbtdb->rrsetstats = NULL;
- if (IS_CACHE(rbtdb)) {
- result = dns_rdatasetstats_create(mctx, &rbtdb->rrsetstats);
- if (result != ISC_R_SUCCESS)
- goto cleanup_node_locks;
- rbtdb->rdatasets = isc_mem_get(mctx, rbtdb->node_lock_count *
- sizeof(rdatasetheaderlist_t));
- if (rbtdb->rdatasets == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup_rrsetstats;
- }
- for (i = 0; i < (int)rbtdb->node_lock_count; i++)
- ISC_LIST_INIT(rbtdb->rdatasets[i]);
- } else
- rbtdb->rdatasets = NULL;
-
- /*
- * Create the heaps.
- */
- rbtdb->heaps = isc_mem_get(hmctx, rbtdb->node_lock_count *
- sizeof(isc_heap_t *));
- if (rbtdb->heaps == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup_rdatasets;
- }
- for (i = 0; i < (int)rbtdb->node_lock_count; i++)
- rbtdb->heaps[i] = NULL;
- sooner = IS_CACHE(rbtdb) ? ttl_sooner : resign_sooner;
- for (i = 0; i < (int)rbtdb->node_lock_count; i++) {
- result = isc_heap_create(hmctx, sooner, set_index, 0,
- &rbtdb->heaps[i]);
- if (result != ISC_R_SUCCESS)
- goto cleanup_heaps;
- }
-
- /*
- * Create deadnode lists.
- */
- rbtdb->deadnodes = isc_mem_get(mctx, rbtdb->node_lock_count *
- sizeof(rbtnodelist_t));
- if (rbtdb->deadnodes == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup_heaps;
- }
- for (i = 0; i < (int)rbtdb->node_lock_count; i++)
- ISC_LIST_INIT(rbtdb->deadnodes[i]);
-
- rbtdb->active = rbtdb->node_lock_count;
-
- for (i = 0; i < (int)(rbtdb->node_lock_count); i++) {
- result = NODE_INITLOCK(&rbtdb->node_locks[i].lock);
- if (result == ISC_R_SUCCESS) {
- result = isc_refcount_init(&rbtdb->node_locks[i].references, 0);
- if (result != ISC_R_SUCCESS)
- NODE_DESTROYLOCK(&rbtdb->node_locks[i].lock);
- }
- if (result != ISC_R_SUCCESS) {
- while (i-- > 0) {
- NODE_DESTROYLOCK(&rbtdb->node_locks[i].lock);
- isc_refcount_decrement(&rbtdb->node_locks[i].references, NULL);
- isc_refcount_destroy(&rbtdb->node_locks[i].references);
- }
- goto cleanup_deadnodes;
- }
- rbtdb->node_locks[i].exiting = ISC_FALSE;
- }
-
- /*
- * Attach to the mctx. The database will persist so long as there
- * are references to it, and attaching to the mctx ensures that our
- * mctx won't disappear out from under us.
- */
- isc_mem_attach(mctx, &rbtdb->common.mctx);
- isc_mem_attach(hmctx, &rbtdb->hmctx);
-
- /*
- * Must be initialized before free_rbtdb() is called.
- */
- isc_ondestroy_init(&rbtdb->common.ondest);
-
- /*
- * Make a copy of the origin name.
- */
- result = dns_name_dupwithoffsets(origin, mctx, &rbtdb->common.origin);
- if (result != ISC_R_SUCCESS) {
- free_rbtdb(rbtdb, ISC_FALSE, NULL);
- return (result);
- }
-
- /*
- * Make the Red-Black Trees.
- */
- result = dns_rbt_create(mctx, delete_callback, rbtdb, &rbtdb->tree);
- if (result != ISC_R_SUCCESS) {
- free_rbtdb(rbtdb, ISC_FALSE, NULL);
- 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);
- }
-
- /*
- * 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.
- * In loading_addrdataset() we could simply compare the new name
- * to the origin name, but this is expensive. Also, we don't know the
- * node name in addrdataset(), so we need another way of knowing the
- * zone's top.
- *
- * We now explicitly create a node for the zone's origin, and then
- * we simply remember the node's address. This is safe, because
- * the top-of-zone node can never be deleted, nor can its address
- * change.
- */
- if (!IS_CACHE(rbtdb)) {
- dns_rbtnode_t *nsec3node;
-
- rbtdb->origin_node = NULL;
- result = dns_rbt_addnode(rbtdb->tree, &rbtdb->common.origin,
- &rbtdb->origin_node);
- if (result != ISC_R_SUCCESS) {
- INSIST(result != ISC_R_EXISTS);
- free_rbtdb(rbtdb, ISC_FALSE, NULL);
- return (result);
- }
- rbtdb->origin_node->nsec = DNS_RBT_NSEC_NORMAL;
- /*
- * We need to give the origin node the right locknum.
- */
- dns_name_init(&name, NULL);
- dns_rbt_namefromnode(rbtdb->origin_node, &name);
-#ifdef DNS_RBT_USEHASH
- rbtdb->origin_node->locknum =
- rbtdb->origin_node->hashval %
- rbtdb->node_lock_count;
-#else
- rbtdb->origin_node->locknum =
- dns_name_hash(&name, ISC_TRUE) %
- rbtdb->node_lock_count;
-#endif
- /*
- * Add an apex node to the NSEC3 tree so that NSEC3 searches
- * return partial matches when there is only a single NSEC3
- * record in the tree.
- */
- nsec3node = NULL;
- result = dns_rbt_addnode(rbtdb->nsec3, &rbtdb->common.origin,
- &nsec3node);
- if (result != ISC_R_SUCCESS) {
- INSIST(result != ISC_R_EXISTS);
- free_rbtdb(rbtdb, ISC_FALSE, NULL);
- return (result);
- }
- nsec3node->nsec = DNS_RBT_NSEC_NSEC3;
- /*
- * We need to give the nsec3 origin node the right locknum.
- */
- dns_name_init(&name, NULL);
- dns_rbt_namefromnode(nsec3node, &name);
-#ifdef DNS_RBT_USEHASH
- nsec3node->locknum = nsec3node->hashval %
- rbtdb->node_lock_count;
-#else
- nsec3node->locknum = dns_name_hash(&name, ISC_TRUE) %
- rbtdb->node_lock_count;
-#endif
- }
-
- /*
- * Misc. Initialization.
- */
- result = isc_refcount_init(&rbtdb->references, 1);
- if (result != ISC_R_SUCCESS) {
- free_rbtdb(rbtdb, ISC_FALSE, NULL);
- return (result);
- }
- rbtdb->attributes = 0;
- rbtdb->task = NULL;
-
- /*
- * Version Initialization.
- */
- rbtdb->current_serial = 1;
- rbtdb->least_serial = 1;
- rbtdb->next_serial = 2;
- rbtdb->current_version = allocate_version(mctx, 1, 1, ISC_FALSE);
- if (rbtdb->current_version == NULL) {
- isc_refcount_decrement(&rbtdb->references, NULL);
- isc_refcount_destroy(&rbtdb->references);
- free_rbtdb(rbtdb, ISC_FALSE, NULL);
- return (ISC_R_NOMEMORY);
- }
- rbtdb->current_version->rbtdb = rbtdb;
- rbtdb->current_version->secure = dns_db_insecure;
- rbtdb->current_version->havensec3 = ISC_FALSE;
- rbtdb->current_version->flags = 0;
- rbtdb->current_version->iterations = 0;
- rbtdb->current_version->hash = 0;
- rbtdb->current_version->salt_length = 0;
- memset(rbtdb->current_version->salt, 0,
- sizeof(rbtdb->current_version->salt));
- rbtdb->future_version = NULL;
- ISC_LIST_INIT(rbtdb->open_versions);
- /*
- * Keep the current version in the open list so that list operation
- * won't happen in normal lookup operations.
- */
- PREPEND(rbtdb->open_versions, rbtdb->current_version, link);
-
- rbtdb->common.magic = DNS_DB_MAGIC;
- rbtdb->common.impmagic = RBTDB_MAGIC;
-
- *dbp = (dns_db_t *)rbtdb;
-
- return (ISC_R_SUCCESS);
-
- cleanup_deadnodes:
- isc_mem_put(mctx, rbtdb->deadnodes,
- rbtdb->node_lock_count * sizeof(rbtnodelist_t));
-
- cleanup_heaps:
- if (rbtdb->heaps != NULL) {
- for (i = 0 ; i < (int)rbtdb->node_lock_count ; i++)
- if (rbtdb->heaps[i] != NULL)
- isc_heap_destroy(&rbtdb->heaps[i]);
- isc_mem_put(hmctx, rbtdb->heaps,
- rbtdb->node_lock_count * sizeof(isc_heap_t *));
- }
-
- cleanup_rdatasets:
- if (rbtdb->rdatasets != NULL)
- isc_mem_put(mctx, rbtdb->rdatasets, rbtdb->node_lock_count *
- sizeof(rdatasetheaderlist_t));
- cleanup_rrsetstats:
- if (rbtdb->rrsetstats != NULL)
- dns_stats_detach(&rbtdb->rrsetstats);
-
- cleanup_node_locks:
- isc_mem_put(mctx, rbtdb->node_locks,
- rbtdb->node_lock_count * sizeof(rbtdb_nodelock_t));
-
- cleanup_tree_lock:
- isc_rwlock_destroy(&rbtdb->tree_lock);
-
- cleanup_lock:
- RBTDB_DESTROYLOCK(&rbtdb->lock);
-
- cleanup_rbtdb:
- isc_mem_put(mctx, rbtdb, sizeof(*rbtdb));
- return (result);
-}
-
-
-/*
- * Slabbed Rdataset Methods
- */
-
-static void
-rdataset_disassociate(dns_rdataset_t *rdataset) {
- dns_db_t *db = rdataset->private1;
- dns_dbnode_t *node = rdataset->private2;
-
- detachnode(db, &node);
-}
-
-static isc_result_t
-rdataset_first(dns_rdataset_t *rdataset) {
- unsigned char *raw = rdataset->private3; /* RDATASLAB */
- unsigned int count;
-
- count = raw[0] * 256 + raw[1];
- if (count == 0) {
- rdataset->private5 = NULL;
- return (ISC_R_NOMORE);
- }
-
-#if DNS_RDATASET_FIXED
- if ((rdataset->attributes & DNS_RDATASETATTR_LOADORDER) == 0)
- raw += 2 + (4 * count);
- else
-#endif
- 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.
- *
- * If DNS_RDATASETATTR_LOADORDER is not set 'raw' points to the
- * first record. If DNS_RDATASETATTR_LOADORDER is set 'raw' points
- * to the first entry in the offset table.
- */
- 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; /* RDATASLAB */
-
- count = rdataset->privateuint4;
- if (count == 0)
- return (ISC_R_NOMORE);
- count--;
- rdataset->privateuint4 = count;
-
- /*
- * Skip forward one record (length + 4) or one offset (4).
- */
- raw = rdataset->private5;
-#if DNS_RDATASET_FIXED
- if ((rdataset->attributes & DNS_RDATASETATTR_LOADORDER) == 0) {
-#endif
- length = raw[0] * 256 + raw[1];
- raw += length;
-#if DNS_RDATASET_FIXED
- }
- rdataset->private5 = raw + 4; /* length(2) + order(2) */
-#else
- rdataset->private5 = raw + 2; /* length(2) */
-#endif
-
- return (ISC_R_SUCCESS);
-}
-
-static void
-rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
- unsigned char *raw = rdataset->private5; /* RDATASLAB */
-#if DNS_RDATASET_FIXED
- unsigned int offset;
-#endif
- unsigned int length;
- isc_region_t r;
- unsigned int flags = 0;
-
- REQUIRE(raw != NULL);
-
- /*
- * Find the start of the record if not already in private5
- * then skip the length and order fields.
- */
-#if DNS_RDATASET_FIXED
- if ((rdataset->attributes & DNS_RDATASETATTR_LOADORDER) != 0) {
- offset = (raw[0] << 24) + (raw[1] << 16) +
- (raw[2] << 8) + raw[3];
- raw = rdataset->private3;
- raw += offset;
- }
-#endif
- length = raw[0] * 256 + raw[1];
-#if DNS_RDATASET_FIXED
- raw += 4;
-#else
- raw += 2;
-#endif
- 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);
- INSIST(!ISC_LINK_LINKED(target, link));
- *target = *source;
- ISC_LINK_INIT(target, link);
-
- /*
- * Reset iterator state.
- */
- target->privateuint4 = 0;
- target->private5 = NULL;
-}
-
-static unsigned int
-rdataset_count(dns_rdataset_t *rdataset) {
- unsigned char *raw = rdataset->private3; /* RDATASLAB */
- unsigned int count;
-
- count = raw[0] * 256 + raw[1];
-
- return (count);
-}
-
-static isc_result_t
-rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name,
- dns_rdataset_t *nsec, dns_rdataset_t *nsecsig)
-{
- dns_db_t *db = rdataset->private1;
- dns_dbnode_t *node = rdataset->private2;
- dns_dbnode_t *cloned_node;
- struct noqname *noqname = rdataset->private6;
-
- cloned_node = NULL;
- attachnode(db, node, &cloned_node);
- nsec->methods = &rdataset_methods;
- nsec->rdclass = db->rdclass;
- nsec->type = noqname->type;
- nsec->covers = 0;
- nsec->ttl = rdataset->ttl;
- nsec->trust = rdataset->trust;
- nsec->private1 = rdataset->private1;
- nsec->private2 = rdataset->private2;
- nsec->private3 = noqname->neg;
- nsec->privateuint4 = 0;
- nsec->private5 = NULL;
- nsec->private6 = NULL;
- nsec->private7 = NULL;
-
- cloned_node = NULL;
- attachnode(db, node, &cloned_node);
- nsecsig->methods = &rdataset_methods;
- nsecsig->rdclass = db->rdclass;
- nsecsig->type = dns_rdatatype_rrsig;
- nsecsig->covers = noqname->type;
- nsecsig->ttl = rdataset->ttl;
- nsecsig->trust = rdataset->trust;
- nsecsig->private1 = rdataset->private1;
- nsecsig->private2 = rdataset->private2;
- nsecsig->private3 = noqname->negsig;
- nsecsig->privateuint4 = 0;
- nsecsig->private5 = NULL;
- nsec->private6 = NULL;
- nsec->private7 = NULL;
-
- dns_name_clone(&noqname->name, name);
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-rdataset_getclosest(dns_rdataset_t *rdataset, dns_name_t *name,
- dns_rdataset_t *nsec, dns_rdataset_t *nsecsig)
-{
- dns_db_t *db = rdataset->private1;
- dns_dbnode_t *node = rdataset->private2;
- dns_dbnode_t *cloned_node;
- struct noqname *closest = rdataset->private7;
-
- cloned_node = NULL;
- attachnode(db, node, &cloned_node);
- nsec->methods = &rdataset_methods;
- nsec->rdclass = db->rdclass;
- nsec->type = closest->type;
- nsec->covers = 0;
- nsec->ttl = rdataset->ttl;
- nsec->trust = rdataset->trust;
- nsec->private1 = rdataset->private1;
- nsec->private2 = rdataset->private2;
- nsec->private3 = closest->neg;
- nsec->privateuint4 = 0;
- nsec->private5 = NULL;
- nsec->private6 = NULL;
- nsec->private7 = NULL;
-
- cloned_node = NULL;
- attachnode(db, node, &cloned_node);
- nsecsig->methods = &rdataset_methods;
- nsecsig->rdclass = db->rdclass;
- nsecsig->type = dns_rdatatype_rrsig;
- nsecsig->covers = closest->type;
- nsecsig->ttl = rdataset->ttl;
- nsecsig->trust = rdataset->trust;
- nsecsig->private1 = rdataset->private1;
- nsecsig->private2 = rdataset->private2;
- nsecsig->private3 = closest->negsig;
- nsecsig->privateuint4 = 0;
- nsecsig->private5 = NULL;
- nsec->private6 = NULL;
- nsec->private7 = NULL;
-
- dns_name_clone(&closest->name, name);
-
- return (ISC_R_SUCCESS);
-}
-
-static void
-rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) {
- dns_rbtdb_t *rbtdb = rdataset->private1;
- dns_rbtnode_t *rbtnode = rdataset->private2;
- rdatasetheader_t *header = rdataset->private3;
-
- header--;
- NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_write);
- header->trust = rdataset->trust = trust;
- NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_write);
-}
-
-static void
-rdataset_expire(dns_rdataset_t *rdataset) {
- dns_rbtdb_t *rbtdb = rdataset->private1;
- dns_rbtnode_t *rbtnode = rdataset->private2;
- rdatasetheader_t *header = rdataset->private3;
-
- header--;
- NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_write);
- expire_header(rbtdb, header, ISC_FALSE);
- NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_write);
-}
-
-/*
- * Rdataset Iterator Methods
- */
-
-static void
-rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp) {
- rbtdb_rdatasetiter_t *rbtiterator;
-
- rbtiterator = (rbtdb_rdatasetiter_t *)(*iteratorp);
-
- if (rbtiterator->common.version != NULL)
- closeversion(rbtiterator->common.db,
- &rbtiterator->common.version, ISC_FALSE);
- detachnode(rbtiterator->common.db, &rbtiterator->common.node);
- isc_mem_put(rbtiterator->common.db->mctx, rbtiterator,
- sizeof(*rbtiterator));
-
- *iteratorp = NULL;
-}
-
-static isc_result_t
-rdatasetiter_first(dns_rdatasetiter_t *iterator) {
- rbtdb_rdatasetiter_t *rbtiterator = (rbtdb_rdatasetiter_t *)iterator;
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)(rbtiterator->common.db);
- dns_rbtnode_t *rbtnode = rbtiterator->common.node;
- rbtdb_version_t *rbtversion = rbtiterator->common.version;
- rdatasetheader_t *header, *top_next;
- rbtdb_serial_t serial;
- isc_stdtime_t now;
-
- if (IS_CACHE(rbtdb)) {
- serial = 1;
- now = rbtiterator->common.now;
- } else {
- serial = rbtversion->serial;
- now = 0;
- }
-
- NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_read);
-
- for (header = rbtnode->data; header != NULL; header = top_next) {
- top_next = header->next;
- do {
- if (header->serial <= serial && !IGNORE(header)) {
- /*
- * Is this a "this rdataset doesn't exist"
- * record? Or is it too old in the cache?
- *
- * Note: unlike everywhere else, we
- * check for now > header->rdh_ttl instead
- * of now >= header->rdh_ttl. This allows
- * ANY and RRSIG queries for 0 TTL
- * rdatasets to work.
- */
- if (NONEXISTENT(header) ||
- (now != 0 && now > header->rdh_ttl))
- header = NULL;
- break;
- } else
- header = header->down;
- } while (header != NULL);
- if (header != NULL)
- break;
- }
-
- NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_read);
-
- rbtiterator->current = header;
-
- if (header == NULL)
- return (ISC_R_NOMORE);
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-rdatasetiter_next(dns_rdatasetiter_t *iterator) {
- rbtdb_rdatasetiter_t *rbtiterator = (rbtdb_rdatasetiter_t *)iterator;
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)(rbtiterator->common.db);
- dns_rbtnode_t *rbtnode = rbtiterator->common.node;
- rbtdb_version_t *rbtversion = rbtiterator->common.version;
- rdatasetheader_t *header, *top_next;
- rbtdb_serial_t serial;
- isc_stdtime_t now;
- rbtdb_rdatatype_t type, negtype;
- dns_rdatatype_t rdtype, covers;
-
- header = rbtiterator->current;
- if (header == NULL)
- return (ISC_R_NOMORE);
-
- if (IS_CACHE(rbtdb)) {
- serial = 1;
- now = rbtiterator->common.now;
- } else {
- serial = rbtversion->serial;
- now = 0;
- }
-
- NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_read);
-
- type = header->type;
- rdtype = RBTDB_RDATATYPE_BASE(header->type);
- if (NEGATIVE(header)) {
- covers = RBTDB_RDATATYPE_EXT(header->type);
- negtype = RBTDB_RDATATYPE_VALUE(covers, 0);
- } else
- negtype = RBTDB_RDATATYPE_VALUE(0, rdtype);
- for (header = header->next; header != NULL; header = top_next) {
- top_next = header->next;
- /*
- * If not walking back up the down list.
- */
- if (header->type != type && header->type != negtype) {
- do {
- if (header->serial <= serial &&
- !IGNORE(header)) {
- /*
- * Is this a "this rdataset doesn't
- * exist" record?
- *
- * Note: unlike everywhere else, we
- * check for now > header->ttl instead
- * of now >= header->ttl. This allows
- * ANY and RRSIG queries for 0 TTL
- * rdatasets to work.
- */
- if ((header->attributes &
- RDATASET_ATTR_NONEXISTENT) != 0 ||
- (now != 0 && now > header->rdh_ttl))
- header = NULL;
- break;
- } else
- header = header->down;
- } while (header != NULL);
- if (header != NULL)
- break;
- }
- }
-
- NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_read);
-
- rbtiterator->current = header;
-
- if (header == NULL)
- return (ISC_R_NOMORE);
-
- return (ISC_R_SUCCESS);
-}
-
-static void
-rdatasetiter_current(dns_rdatasetiter_t *iterator, dns_rdataset_t *rdataset) {
- rbtdb_rdatasetiter_t *rbtiterator = (rbtdb_rdatasetiter_t *)iterator;
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)(rbtiterator->common.db);
- dns_rbtnode_t *rbtnode = rbtiterator->common.node;
- rdatasetheader_t *header;
-
- header = rbtiterator->current;
- REQUIRE(header != NULL);
-
- NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_read);
-
- bind_rdataset(rbtdb, rbtnode, header, rbtiterator->common.now,
- rdataset);
-
- NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_read);
-}
-
-
-/*
- * Database Iterator Methods
- */
-
-static inline void
-reference_iter_node(rbtdb_dbiterator_t *rbtdbiter) {
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)rbtdbiter->common.db;
- dns_rbtnode_t *node = rbtdbiter->node;
-
- if (node == NULL)
- return;
-
- INSIST(rbtdbiter->tree_locked != isc_rwlocktype_none);
- reactivate_node(rbtdb, node, rbtdbiter->tree_locked);
-}
-
-static inline void
-dereference_iter_node(rbtdb_dbiterator_t *rbtdbiter) {
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)rbtdbiter->common.db;
- dns_rbtnode_t *node = rbtdbiter->node;
- nodelock_t *lock;
-
- if (node == NULL)
- return;
-
- lock = &rbtdb->node_locks[node->locknum].lock;
- NODE_LOCK(lock, isc_rwlocktype_read);
- decrement_reference(rbtdb, node, 0, isc_rwlocktype_read,
- rbtdbiter->tree_locked, ISC_FALSE);
- NODE_UNLOCK(lock, isc_rwlocktype_read);
-
- rbtdbiter->node = NULL;
-}
-
-static void
-flush_deletions(rbtdb_dbiterator_t *rbtdbiter) {
- dns_rbtnode_t *node;
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)rbtdbiter->common.db;
- isc_boolean_t was_read_locked = ISC_FALSE;
- nodelock_t *lock;
- int i;
-
- if (rbtdbiter->delete != 0) {
- /*
- * Note that "%d node of %d in tree" can report things like
- * "flush_deletions: 59 nodes of 41 in tree". This means
- * That some nodes appear on the deletions list more than
- * once. Only the last occurence will actually be deleted.
- */
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_CACHE, ISC_LOG_DEBUG(1),
- "flush_deletions: %d nodes of %d in tree",
- rbtdbiter->delete,
- dns_rbt_nodecount(rbtdb->tree));
-
- if (rbtdbiter->tree_locked == isc_rwlocktype_read) {
- RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
- was_read_locked = ISC_TRUE;
- }
- RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
- rbtdbiter->tree_locked = isc_rwlocktype_write;
-
- for (i = 0; i < rbtdbiter->delete; i++) {
- node = rbtdbiter->deletions[i];
- lock = &rbtdb->node_locks[node->locknum].lock;
-
- NODE_LOCK(lock, isc_rwlocktype_read);
- decrement_reference(rbtdb, node, 0,
- isc_rwlocktype_read,
- rbtdbiter->tree_locked, ISC_FALSE);
- NODE_UNLOCK(lock, isc_rwlocktype_read);
- }
-
- rbtdbiter->delete = 0;
-
- RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
- if (was_read_locked) {
- RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
- rbtdbiter->tree_locked = isc_rwlocktype_read;
-
- } else {
- rbtdbiter->tree_locked = isc_rwlocktype_none;
- }
- }
-}
-
-static inline void
-resume_iteration(rbtdb_dbiterator_t *rbtdbiter) {
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)rbtdbiter->common.db;
-
- REQUIRE(rbtdbiter->paused);
- REQUIRE(rbtdbiter->tree_locked == isc_rwlocktype_none);
-
- RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
- rbtdbiter->tree_locked = isc_rwlocktype_read;
-
- rbtdbiter->paused = ISC_FALSE;
-}
-
-static void
-dbiterator_destroy(dns_dbiterator_t **iteratorp) {
- rbtdb_dbiterator_t *rbtdbiter = (rbtdb_dbiterator_t *)(*iteratorp);
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)rbtdbiter->common.db;
- dns_db_t *db = NULL;
-
- if (rbtdbiter->tree_locked == isc_rwlocktype_read) {
- RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
- rbtdbiter->tree_locked = isc_rwlocktype_none;
- } else
- INSIST(rbtdbiter->tree_locked == isc_rwlocktype_none);
-
- dereference_iter_node(rbtdbiter);
-
- flush_deletions(rbtdbiter);
-
- dns_db_attach(rbtdbiter->common.db, &db);
- dns_db_detach(&rbtdbiter->common.db);
-
- dns_rbtnodechain_reset(&rbtdbiter->chain);
- dns_rbtnodechain_reset(&rbtdbiter->nsec3chain);
- isc_mem_put(db->mctx, rbtdbiter, sizeof(*rbtdbiter));
- dns_db_detach(&db);
-
- *iteratorp = NULL;
-}
-
-static isc_result_t
-dbiterator_first(dns_dbiterator_t *iterator) {
- isc_result_t result;
- rbtdb_dbiterator_t *rbtdbiter = (rbtdb_dbiterator_t *)iterator;
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)iterator->db;
- dns_name_t *name, *origin;
-
- if (rbtdbiter->result != ISC_R_SUCCESS &&
- rbtdbiter->result != ISC_R_NOMORE)
- return (rbtdbiter->result);
-
- if (rbtdbiter->paused)
- resume_iteration(rbtdbiter);
-
- dereference_iter_node(rbtdbiter);
-
- name = dns_fixedname_name(&rbtdbiter->name);
- origin = dns_fixedname_name(&rbtdbiter->origin);
- dns_rbtnodechain_reset(&rbtdbiter->chain);
- dns_rbtnodechain_reset(&rbtdbiter->nsec3chain);
-
- if (rbtdbiter->nsec3only) {
- rbtdbiter->current = &rbtdbiter->nsec3chain;
- result = dns_rbtnodechain_first(rbtdbiter->current,
- rbtdb->nsec3, name, origin);
- } else {
- rbtdbiter->current = &rbtdbiter->chain;
- result = dns_rbtnodechain_first(rbtdbiter->current,
- rbtdb->tree, name, origin);
- if (!rbtdbiter->nonsec3 && result == ISC_R_NOTFOUND) {
- rbtdbiter->current = &rbtdbiter->nsec3chain;
- result = dns_rbtnodechain_first(rbtdbiter->current,
- rbtdb->nsec3, name,
- origin);
- }
- }
- if (result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN) {
- result = dns_rbtnodechain_current(rbtdbiter->current, NULL,
- NULL, &rbtdbiter->node);
- if (result == ISC_R_SUCCESS) {
- rbtdbiter->new_origin = ISC_TRUE;
- reference_iter_node(rbtdbiter);
- }
- } else {
- INSIST(result == ISC_R_NOTFOUND);
- result = ISC_R_NOMORE; /* The tree is empty. */
- }
-
- rbtdbiter->result = result;
-
- return (result);
-}
-
-static isc_result_t
-dbiterator_last(dns_dbiterator_t *iterator) {
- isc_result_t result;
- rbtdb_dbiterator_t *rbtdbiter = (rbtdb_dbiterator_t *)iterator;
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)iterator->db;
- dns_name_t *name, *origin;
-
- if (rbtdbiter->result != ISC_R_SUCCESS &&
- rbtdbiter->result != ISC_R_NOMORE)
- return (rbtdbiter->result);
-
- if (rbtdbiter->paused)
- resume_iteration(rbtdbiter);
-
- dereference_iter_node(rbtdbiter);
-
- name = dns_fixedname_name(&rbtdbiter->name);
- origin = dns_fixedname_name(&rbtdbiter->origin);
- dns_rbtnodechain_reset(&rbtdbiter->chain);
- dns_rbtnodechain_reset(&rbtdbiter->nsec3chain);
-
- result = ISC_R_NOTFOUND;
- if (rbtdbiter->nsec3only && !rbtdbiter->nonsec3) {
- rbtdbiter->current = &rbtdbiter->nsec3chain;
- result = dns_rbtnodechain_last(rbtdbiter->current,
- rbtdb->nsec3, name, origin);
- }
- if (!rbtdbiter->nsec3only && result == ISC_R_NOTFOUND) {
- rbtdbiter->current = &rbtdbiter->chain;
- result = dns_rbtnodechain_last(rbtdbiter->current, rbtdb->tree,
- name, origin);
- }
- if (result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN) {
- result = dns_rbtnodechain_current(rbtdbiter->current, NULL,
- NULL, &rbtdbiter->node);
- if (result == ISC_R_SUCCESS) {
- rbtdbiter->new_origin = ISC_TRUE;
- reference_iter_node(rbtdbiter);
- }
- } else {
- INSIST(result == ISC_R_NOTFOUND);
- result = ISC_R_NOMORE; /* The tree is empty. */
- }
-
- rbtdbiter->result = result;
-
- return (result);
-}
-
-static isc_result_t
-dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name) {
- isc_result_t result, tresult;
- rbtdb_dbiterator_t *rbtdbiter = (rbtdb_dbiterator_t *)iterator;
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)iterator->db;
- dns_name_t *iname, *origin;
-
- if (rbtdbiter->result != ISC_R_SUCCESS &&
- rbtdbiter->result != ISC_R_NOTFOUND &&
- rbtdbiter->result != ISC_R_NOMORE)
- return (rbtdbiter->result);
-
- if (rbtdbiter->paused)
- resume_iteration(rbtdbiter);
-
- dereference_iter_node(rbtdbiter);
-
- iname = dns_fixedname_name(&rbtdbiter->name);
- origin = dns_fixedname_name(&rbtdbiter->origin);
- dns_rbtnodechain_reset(&rbtdbiter->chain);
- dns_rbtnodechain_reset(&rbtdbiter->nsec3chain);
-
- if (rbtdbiter->nsec3only) {
- rbtdbiter->current = &rbtdbiter->nsec3chain;
- result = dns_rbt_findnode(rbtdb->nsec3, name, NULL,
- &rbtdbiter->node,
- rbtdbiter->current,
- DNS_RBTFIND_EMPTYDATA, NULL, NULL);
- } else if (rbtdbiter->nonsec3) {
- rbtdbiter->current = &rbtdbiter->chain;
- result = dns_rbt_findnode(rbtdb->tree, name, NULL,
- &rbtdbiter->node,
- rbtdbiter->current,
- DNS_RBTFIND_EMPTYDATA, NULL, NULL);
- } else {
- /*
- * Stay on main chain if not found on either chain.
- */
- rbtdbiter->current = &rbtdbiter->chain;
- result = dns_rbt_findnode(rbtdb->tree, name, NULL,
- &rbtdbiter->node,
- rbtdbiter->current,
- DNS_RBTFIND_EMPTYDATA, NULL, NULL);
- if (result == DNS_R_PARTIALMATCH) {
- dns_rbtnode_t *node = NULL;
- tresult = dns_rbt_findnode(rbtdb->nsec3, name, NULL,
- &node, &rbtdbiter->nsec3chain,
- DNS_RBTFIND_EMPTYDATA,
- NULL, NULL);
- if (tresult == ISC_R_SUCCESS) {
- rbtdbiter->node = node;
- rbtdbiter->current = &rbtdbiter->nsec3chain;
- result = tresult;
- }
- }
- }
-
-#if 1
- if (result == ISC_R_SUCCESS) {
- result = dns_rbtnodechain_current(rbtdbiter->current, iname,
- origin, NULL);
- if (result == ISC_R_SUCCESS) {
- rbtdbiter->new_origin = ISC_TRUE;
- reference_iter_node(rbtdbiter);
- }
- } else if (result == DNS_R_PARTIALMATCH) {
- result = ISC_R_NOTFOUND;
- rbtdbiter->node = NULL;
- }
-
- rbtdbiter->result = result;
-#else
- if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
- isc_result_t tresult;
- tresult = dns_rbtnodechain_current(rbtdbiter->current, iname,
- origin, NULL);
- if (tresult == ISC_R_SUCCESS) {
- rbtdbiter->new_origin = ISC_TRUE;
- reference_iter_node(rbtdbiter);
- } else {
- result = tresult;
- rbtdbiter->node = NULL;
- }
- } else
- rbtdbiter->node = NULL;
-
- rbtdbiter->result = (result == DNS_R_PARTIALMATCH) ?
- ISC_R_SUCCESS : result;
-#endif
-
- return (result);
-}
-
-static isc_result_t
-dbiterator_prev(dns_dbiterator_t *iterator) {
- isc_result_t result;
- rbtdb_dbiterator_t *rbtdbiter = (rbtdb_dbiterator_t *)iterator;
- dns_name_t *name, *origin;
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)iterator->db;
-
- REQUIRE(rbtdbiter->node != NULL);
-
- if (rbtdbiter->result != ISC_R_SUCCESS)
- return (rbtdbiter->result);
-
- if (rbtdbiter->paused)
- resume_iteration(rbtdbiter);
-
- name = dns_fixedname_name(&rbtdbiter->name);
- origin = dns_fixedname_name(&rbtdbiter->origin);
- result = dns_rbtnodechain_prev(rbtdbiter->current, name, origin);
- if (result == ISC_R_NOMORE && !rbtdbiter->nsec3only &&
- !rbtdbiter->nonsec3 &&
- &rbtdbiter->nsec3chain == rbtdbiter->current) {
- rbtdbiter->current = &rbtdbiter->chain;
- dns_rbtnodechain_reset(rbtdbiter->current);
- result = dns_rbtnodechain_last(rbtdbiter->current, rbtdb->tree,
- name, origin);
- if (result == ISC_R_NOTFOUND)
- result = ISC_R_NOMORE;
- }
-
- dereference_iter_node(rbtdbiter);
-
- if (result == DNS_R_NEWORIGIN || result == ISC_R_SUCCESS) {
- rbtdbiter->new_origin = ISC_TF(result == DNS_R_NEWORIGIN);
- result = dns_rbtnodechain_current(rbtdbiter->current, NULL,
- NULL, &rbtdbiter->node);
- }
-
- if (result == ISC_R_SUCCESS)
- reference_iter_node(rbtdbiter);
-
- rbtdbiter->result = result;
-
- return (result);
-}
-
-static isc_result_t
-dbiterator_next(dns_dbiterator_t *iterator) {
- isc_result_t result;
- rbtdb_dbiterator_t *rbtdbiter = (rbtdb_dbiterator_t *)iterator;
- dns_name_t *name, *origin;
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)iterator->db;
-
- REQUIRE(rbtdbiter->node != NULL);
-
- if (rbtdbiter->result != ISC_R_SUCCESS)
- return (rbtdbiter->result);
-
- if (rbtdbiter->paused)
- resume_iteration(rbtdbiter);
-
- name = dns_fixedname_name(&rbtdbiter->name);
- origin = dns_fixedname_name(&rbtdbiter->origin);
- result = dns_rbtnodechain_next(rbtdbiter->current, name, origin);
- if (result == ISC_R_NOMORE && !rbtdbiter->nsec3only &&
- !rbtdbiter->nonsec3 && &rbtdbiter->chain == rbtdbiter->current) {
- rbtdbiter->current = &rbtdbiter->nsec3chain;
- dns_rbtnodechain_reset(rbtdbiter->current);
- result = dns_rbtnodechain_first(rbtdbiter->current,
- rbtdb->nsec3, name, origin);
- if (result == ISC_R_NOTFOUND)
- result = ISC_R_NOMORE;
- }
-
- dereference_iter_node(rbtdbiter);
-
- if (result == DNS_R_NEWORIGIN || result == ISC_R_SUCCESS) {
- rbtdbiter->new_origin = ISC_TF(result == DNS_R_NEWORIGIN);
- result = dns_rbtnodechain_current(rbtdbiter->current, NULL,
- NULL, &rbtdbiter->node);
- }
- if (result == ISC_R_SUCCESS)
- reference_iter_node(rbtdbiter);
-
- rbtdbiter->result = result;
-
- return (result);
-}
-
-static isc_result_t
-dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep,
- dns_name_t *name)
-{
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)iterator->db;
- rbtdb_dbiterator_t *rbtdbiter = (rbtdb_dbiterator_t *)iterator;
- dns_rbtnode_t *node = rbtdbiter->node;
- isc_result_t result;
- dns_name_t *nodename = dns_fixedname_name(&rbtdbiter->name);
- dns_name_t *origin = dns_fixedname_name(&rbtdbiter->origin);
-
- REQUIRE(rbtdbiter->result == ISC_R_SUCCESS);
- REQUIRE(rbtdbiter->node != NULL);
-
- if (rbtdbiter->paused)
- resume_iteration(rbtdbiter);
-
- if (name != NULL) {
- if (rbtdbiter->common.relative_names)
- origin = NULL;
- result = dns_name_concatenate(nodename, origin, name, NULL);
- if (result != ISC_R_SUCCESS)
- return (result);
- if (rbtdbiter->common.relative_names && rbtdbiter->new_origin)
- result = DNS_R_NEWORIGIN;
- } else
- result = ISC_R_SUCCESS;
-
- NODE_STRONGLOCK(&rbtdb->node_locks[node->locknum].lock);
- new_reference(rbtdb, node);
- NODE_STRONGUNLOCK(&rbtdb->node_locks[node->locknum].lock);
-
- *nodep = rbtdbiter->node;
-
- if (iterator->cleaning && result == ISC_R_SUCCESS) {
- isc_result_t expire_result;
-
- /*
- * If the deletion array is full, flush it before trying
- * to expire the current node. The current node can't
- * fully deleted while the iteration cursor is still on it.
- */
- if (rbtdbiter->delete == DELETION_BATCH_MAX)
- flush_deletions(rbtdbiter);
-
- expire_result = expirenode(iterator->db, *nodep, 0);
-
- /*
- * expirenode() currently always returns success.
- */
- if (expire_result == ISC_R_SUCCESS && node->down == NULL) {
- unsigned int refs;
-
- rbtdbiter->deletions[rbtdbiter->delete++] = node;
- NODE_STRONGLOCK(&rbtdb->node_locks[node->locknum].lock);
- dns_rbtnode_refincrement(node, &refs);
- INSIST(refs != 0);
- NODE_STRONGUNLOCK(&rbtdb->node_locks[node->locknum].lock);
- }
- }
-
- return (result);
-}
-
-static isc_result_t
-dbiterator_pause(dns_dbiterator_t *iterator) {
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)iterator->db;
- rbtdb_dbiterator_t *rbtdbiter = (rbtdb_dbiterator_t *)iterator;
-
- if (rbtdbiter->result != ISC_R_SUCCESS &&
- rbtdbiter->result != ISC_R_NOMORE)
- return (rbtdbiter->result);
-
- if (rbtdbiter->paused)
- return (ISC_R_SUCCESS);
-
- rbtdbiter->paused = ISC_TRUE;
-
- if (rbtdbiter->tree_locked != isc_rwlocktype_none) {
- INSIST(rbtdbiter->tree_locked == isc_rwlocktype_read);
- RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
- rbtdbiter->tree_locked = isc_rwlocktype_none;
- }
-
- flush_deletions(rbtdbiter);
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-dbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name) {
- rbtdb_dbiterator_t *rbtdbiter = (rbtdb_dbiterator_t *)iterator;
- dns_name_t *origin = dns_fixedname_name(&rbtdbiter->origin);
-
- if (rbtdbiter->result != ISC_R_SUCCESS)
- return (rbtdbiter->result);
-
- return (dns_name_copy(origin, name, NULL));
-}
-
-/*%
- * Additional cache routines.
- */
-static isc_result_t
-rdataset_getadditional(dns_rdataset_t *rdataset, dns_rdatasetadditional_t type,
- dns_rdatatype_t qtype, dns_acache_t *acache,
- dns_zone_t **zonep, dns_db_t **dbp,
- dns_dbversion_t **versionp, dns_dbnode_t **nodep,
- 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 */
- unsigned int current_count = rdataset->privateuint4;
- unsigned int count;
- rdatasetheader_t *header;
- nodelock_t *nodelock;
- unsigned int total_count;
- acachectl_t *acarray;
- dns_acacheentry_t *entry;
- isc_result_t result;
-
- UNUSED(qtype); /* we do not use this value at least for now */
- UNUSED(acache);
-
- header = (struct rdatasetheader *)(raw - sizeof(*header));
-
- total_count = raw[0] * 256 + raw[1];
- INSIST(total_count > current_count);
- count = total_count - current_count - 1;
-
- acarray = NULL;
-
- nodelock = &rbtdb->node_locks[rbtnode->locknum].lock;
- NODE_LOCK(nodelock, isc_rwlocktype_read);
-
- switch (type) {
- case dns_rdatasetadditional_fromauth:
- acarray = header->additional_auth;
- break;
- case dns_rdatasetadditional_fromcache:
- acarray = NULL;
- break;
- case dns_rdatasetadditional_fromglue:
- acarray = header->additional_glue;
- break;
- default:
- INSIST(0);
- }
-
- if (acarray == NULL) {
- if (type != dns_rdatasetadditional_fromcache)
- dns_acache_countquerymiss(acache);
- NODE_UNLOCK(nodelock, isc_rwlocktype_read);
- return (ISC_R_NOTFOUND);
- }
-
- if (acarray[count].entry == NULL) {
- dns_acache_countquerymiss(acache);
- NODE_UNLOCK(nodelock, isc_rwlocktype_read);
- return (ISC_R_NOTFOUND);
- }
-
- entry = NULL;
- dns_acache_attachentry(acarray[count].entry, &entry);
-
- NODE_UNLOCK(nodelock, isc_rwlocktype_read);
-
- result = dns_acache_getentry(entry, zonep, dbp, versionp,
- nodep, fname, msg, now);
-
- dns_acache_detachentry(&entry);
-
- return (result);
-}
-
-static void
-acache_callback(dns_acacheentry_t *entry, void **arg) {
- dns_rbtdb_t *rbtdb;
- dns_rbtnode_t *rbtnode;
- nodelock_t *nodelock;
- acachectl_t *acarray = NULL;
- acache_cbarg_t *cbarg;
- unsigned int count;
-
- REQUIRE(arg != NULL);
- cbarg = *arg;
-
- /*
- * The caller must hold the entry lock.
- */
-
- rbtdb = (dns_rbtdb_t *)cbarg->db;
- rbtnode = (dns_rbtnode_t *)cbarg->node;
-
- nodelock = &rbtdb->node_locks[rbtnode->locknum].lock;
- NODE_LOCK(nodelock, isc_rwlocktype_write);
-
- switch (cbarg->type) {
- case dns_rdatasetadditional_fromauth:
- acarray = cbarg->header->additional_auth;
- break;
- case dns_rdatasetadditional_fromglue:
- acarray = cbarg->header->additional_glue;
- break;
- default:
- INSIST(0);
- }
-
- count = cbarg->count;
- if (acarray != NULL && acarray[count].entry == entry) {
- acarray[count].entry = NULL;
- INSIST(acarray[count].cbarg == cbarg);
- acarray[count].cbarg = NULL;
- isc_mem_put(rbtdb->common.mctx, cbarg, sizeof(acache_cbarg_t));
- dns_acache_detachentry(&entry);
- }
-
- NODE_UNLOCK(nodelock, isc_rwlocktype_write);
-
- dns_db_detachnode((dns_db_t *)rbtdb, (dns_dbnode_t **)(void*)&rbtnode);
- 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)
-{
- acache_cbarg_t *cbarg;
-
- REQUIRE(mctx != NULL);
- REQUIRE(entry != NULL);
- REQUIRE(cbargp != NULL && *cbargp != NULL);
-
- cbarg = *cbargp;
-
- if (dns_acache_cancelentry(entry)) {
- dns_db_detachnode(cbarg->db, &cbarg->node);
- dns_db_detach(&cbarg->db);
- }
-
- isc_mem_put(mctx, cbarg, sizeof(acache_cbarg_t));
-
- *cbargp = NULL;
-}
-#endif /* BIND9 */
-
-static isc_result_t
-rdataset_setadditional(dns_rdataset_t *rdataset, dns_rdatasetadditional_t type,
- dns_rdatatype_t qtype, dns_acache_t *acache,
- dns_zone_t *zone, dns_db_t *db,
- 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 */
- unsigned int current_count = rdataset->privateuint4;
- rdatasetheader_t *header;
- unsigned int total_count, count;
- nodelock_t *nodelock;
- isc_result_t result;
- acachectl_t *acarray;
- dns_acacheentry_t *newentry, *oldentry = NULL;
- acache_cbarg_t *newcbarg, *oldcbarg = NULL;
-
- UNUSED(qtype);
-
- if (type == dns_rdatasetadditional_fromcache)
- return (ISC_R_SUCCESS);
-
- header = (struct rdatasetheader *)(raw - sizeof(*header));
-
- total_count = raw[0] * 256 + raw[1];
- INSIST(total_count > current_count);
- count = total_count - current_count - 1; /* should be private data */
-
- newcbarg = isc_mem_get(rbtdb->common.mctx, sizeof(*newcbarg));
- if (newcbarg == NULL)
- return (ISC_R_NOMEMORY);
- newcbarg->type = type;
- newcbarg->count = count;
- newcbarg->header = header;
- newcbarg->db = NULL;
- dns_db_attach((dns_db_t *)rbtdb, &newcbarg->db);
- newcbarg->node = NULL;
- dns_db_attachnode((dns_db_t *)rbtdb, (dns_dbnode_t *)rbtnode,
- &newcbarg->node);
- newentry = NULL;
- result = dns_acache_createentry(acache, (dns_db_t *)rbtdb,
- acache_callback, newcbarg, &newentry);
- if (result != ISC_R_SUCCESS)
- goto fail;
-
- /* Set cache data in the new entry. */
- result = dns_acache_setentry(acache, newentry, zone, db,
- version, node, fname);
- if (result != ISC_R_SUCCESS)
- goto fail;
-
- nodelock = &rbtdb->node_locks[rbtnode->locknum].lock;
- NODE_LOCK(nodelock, isc_rwlocktype_write);
-
- acarray = NULL;
- switch (type) {
- case dns_rdatasetadditional_fromauth:
- acarray = header->additional_auth;
- break;
- case dns_rdatasetadditional_fromglue:
- acarray = header->additional_glue;
- break;
- default:
- INSIST(0);
- }
-
- if (acarray == NULL) {
- unsigned int i;
-
- acarray = isc_mem_get(rbtdb->common.mctx, total_count *
- sizeof(acachectl_t));
-
- if (acarray == NULL) {
- NODE_UNLOCK(nodelock, isc_rwlocktype_write);
- goto fail;
- }
-
- for (i = 0; i < total_count; i++) {
- acarray[i].entry = NULL;
- acarray[i].cbarg = NULL;
- }
- }
- switch (type) {
- case dns_rdatasetadditional_fromauth:
- header->additional_auth = acarray;
- break;
- case dns_rdatasetadditional_fromglue:
- header->additional_glue = acarray;
- break;
- default:
- INSIST(0);
- }
-
- if (acarray[count].entry != NULL) {
- /*
- * Swap the entry. Delay cleaning-up the old entry since
- * it would require a node lock.
- */
- oldentry = acarray[count].entry;
- INSIST(acarray[count].cbarg != NULL);
- oldcbarg = acarray[count].cbarg;
- }
- acarray[count].entry = newentry;
- acarray[count].cbarg = newcbarg;
-
- NODE_UNLOCK(nodelock, isc_rwlocktype_write);
-
- if (oldentry != NULL) {
- acache_cancelentry(rbtdb->common.mctx, oldentry, &oldcbarg);
- dns_acache_detachentry(&oldentry);
- }
-
- return (ISC_R_SUCCESS);
-
- fail:
- if (newcbarg != NULL) {
- if (newentry != NULL) {
- acache_cancelentry(rbtdb->common.mctx, newentry,
- &newcbarg);
- dns_acache_detachentry(&newentry);
- } else {
- dns_db_detachnode((dns_db_t *)rbtdb, &newcbarg->node);
- dns_db_detach(&newcbarg->db);
- isc_mem_put(rbtdb->common.mctx, newcbarg,
- sizeof(*newcbarg));
- }
- }
-
- 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 */
- unsigned int current_count = rdataset->privateuint4;
- rdatasetheader_t *header;
- nodelock_t *nodelock;
- unsigned int total_count, count;
- acachectl_t *acarray;
- dns_acacheentry_t *entry;
- acache_cbarg_t *cbarg;
-
- UNUSED(qtype); /* we do not use this value at least for now */
- UNUSED(acache);
-
- if (type == dns_rdatasetadditional_fromcache)
- return (ISC_R_SUCCESS);
-
- header = (struct rdatasetheader *)(raw - sizeof(*header));
-
- total_count = raw[0] * 256 + raw[1];
- INSIST(total_count > current_count);
- count = total_count - current_count - 1;
-
- acarray = NULL;
- entry = NULL;
-
- nodelock = &rbtdb->node_locks[rbtnode->locknum].lock;
- NODE_LOCK(nodelock, isc_rwlocktype_write);
-
- switch (type) {
- case dns_rdatasetadditional_fromauth:
- acarray = header->additional_auth;
- break;
- case dns_rdatasetadditional_fromglue:
- acarray = header->additional_glue;
- break;
- default:
- INSIST(0);
- }
-
- if (acarray == NULL) {
- NODE_UNLOCK(nodelock, isc_rwlocktype_write);
- return (ISC_R_NOTFOUND);
- }
-
- entry = acarray[count].entry;
- if (entry == NULL) {
- NODE_UNLOCK(nodelock, isc_rwlocktype_write);
- return (ISC_R_NOTFOUND);
- }
-
- acarray[count].entry = NULL;
- cbarg = acarray[count].cbarg;
- acarray[count].cbarg = NULL;
-
- NODE_UNLOCK(nodelock, isc_rwlocktype_write);
-
- if (entry != NULL) {
- if (cbarg != NULL)
- acache_cancelentry(rbtdb->common.mctx, entry, &cbarg);
- dns_acache_detachentry(&entry);
- }
-
- return (ISC_R_SUCCESS);
-#endif
-}
-
-/*%
- * Routines for LRU-based cache management.
- */
-
-/*%
- * See if a given cache entry that is being reused needs to be updated
- * in the LRU-list. From the LRU management point of view, this function is
- * expected to return true for almost all cases. When used with threads,
- * however, this may cause a non-negligible performance penalty because a
- * writer lock will have to be acquired before updating the list.
- * If DNS_RBTDB_LIMITLRUUPDATE is defined to be non 0 at compilation time, this
- * function returns true if the entry has not been updated for some period of
- * time. We differentiate the NS or glue address case and the others since
- * experiments have shown that the former tends to be accessed relatively
- * infrequently and the cost of cache miss is higher (e.g., a missing NS records
- * may cause external queries at a higher level zone, involving more
- * transactions).
- *
- * Caller must hold the node (read or write) lock.
- */
-static inline isc_boolean_t
-need_headerupdate(rdatasetheader_t *header, isc_stdtime_t now) {
- if ((header->attributes &
- (RDATASET_ATTR_NONEXISTENT|RDATASET_ATTR_STALE)) != 0)
- return (ISC_FALSE);
-
-#if DNS_RBTDB_LIMITLRUUPDATE
- if (header->type == dns_rdatatype_ns ||
- (header->trust == dns_trust_glue &&
- (header->type == dns_rdatatype_a ||
- header->type == dns_rdatatype_aaaa))) {
- /*
- * Glue records are updated if at least 60 seconds have passed
- * since the previous update time.
- */
- return (header->last_used + 60 <= now);
- }
-
- /* Other records are updated if 5 minutes have passed. */
- return (header->last_used + 300 <= now);
-#else
- UNUSED(now);
-
- return (ISC_TRUE);
-#endif
-}
-
-/*%
- * Update the timestamp of a given cache entry and move it to the head
- * of the corresponding LRU list.
- *
- * Caller must hold the node (write) lock.
- *
- * Note that the we do NOT touch the heap here, as the TTL has not changed.
- */
-static void
-update_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header,
- isc_stdtime_t now)
-{
- INSIST(IS_CACHE(rbtdb));
-
- /* To be checked: can we really assume this? XXXMLG */
- INSIST(ISC_LINK_LINKED(header, link));
-
- ISC_LIST_UNLINK(rbtdb->rdatasets[header->node->locknum], header, link);
- header->last_used = now;
- ISC_LIST_PREPEND(rbtdb->rdatasets[header->node->locknum], header, link);
-}
-
-/*%
- * Purge some expired and/or stale (i.e. unused for some period) cache entries
- * under an overmem condition. To recover from this condition quickly, up to
- * 2 entries will be purged. This process is triggered while adding a new
- * entry, and we specifically avoid purging entries in the same LRU bucket as
- * the one to which the new entry will belong. Otherwise, we might purge
- * entries of the same name of different RR types while adding RRsets from a
- * single response (consider the case where we're adding A and AAAA glue records
- * of the same NS name).
- */
-static void
-overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start,
- isc_stdtime_t now, isc_boolean_t tree_locked)
-{
- rdatasetheader_t *header, *header_prev;
- unsigned int locknum;
- int purgecount = 2;
-
- for (locknum = (locknum_start + 1) % rbtdb->node_lock_count;
- locknum != locknum_start && purgecount > 0;
- locknum = (locknum + 1) % rbtdb->node_lock_count) {
- NODE_LOCK(&rbtdb->node_locks[locknum].lock,
- isc_rwlocktype_write);
-
- header = isc_heap_element(rbtdb->heaps[locknum], 1);
- if (header && header->rdh_ttl <= now - RBTDB_VIRTUAL) {
- expire_header(rbtdb, header, tree_locked);
- purgecount--;
- }
-
- for (header = ISC_LIST_TAIL(rbtdb->rdatasets[locknum]);
- header != NULL && purgecount > 0;
- header = header_prev) {
- header_prev = ISC_LIST_PREV(header, link);
- /*
- * Unlink the entry at this point to avoid checking it
- * again even if it's currently used someone else and
- * cannot be purged at this moment. This entry won't be
- * referenced any more (so unlinking is safe) since the
- * TTL was reset to 0.
- */
- ISC_LIST_UNLINK(rbtdb->rdatasets[locknum], header,
- link);
- expire_header(rbtdb, header, tree_locked);
- purgecount--;
- }
-
- NODE_UNLOCK(&rbtdb->node_locks[locknum].lock,
- isc_rwlocktype_write);
- }
-}
-
-static void
-expire_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header,
- isc_boolean_t tree_locked)
-{
- set_ttl(rbtdb, header, 0);
- header->attributes |= RDATASET_ATTR_STALE;
- header->node->dirty = 1;
-
- /*
- * Caller must hold the node (write) lock.
- */
-
- if (dns_rbtnode_refcurrent(header->node) == 0) {
- /*
- * If no one else is using the node, we can clean it up now.
- * We first need to gain a new reference to the node to meet a
- * requirement of decrement_reference().
- */
- new_reference(rbtdb, header->node);
- decrement_reference(rbtdb, header->node, 0,
- isc_rwlocktype_write,
- tree_locked ? isc_rwlocktype_write :
- isc_rwlocktype_none, ISC_FALSE);
- }
-}
diff --git a/contrib/bind9/lib/dns/rbtdb.h b/contrib/bind9/lib/dns/rbtdb.h
deleted file mode 100644
index 9eb9c5c56f2a..000000000000
--- a/contrib/bind9/lib/dns/rbtdb.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-#ifndef DNS_RBTDB_H
-#define DNS_RBTDB_H 1
-
-#include <isc/lang.h>
-#include <dns/types.h>
-
-/*****
- ***** Module Info
- *****/
-
-/*! \file
- * \brief
- * DNS Red-Black Tree DB Implementation
- */
-
-ISC_LANG_BEGINDECLS
-
-isc_result_t
-dns_rbtdb_create(isc_mem_t *mctx, dns_name_t *base, dns_dbtype_t type,
- dns_rdataclass_t rdclass, unsigned int argc, char *argv[],
- void *driverarg, dns_db_t **dbp);
-
-/*%<
- * Create a new database of type "rbt" (or "rbt64"). Called via
- * dns_db_create(); see documentation for that function for more details.
- *
- * If argv[0] is set, it points to a valid memory context to be used for
- * allocation of heap memory. Generally this is used for cache databases
- * only.
- *
- * Requires:
- *
- * \li argc == 0 or argv[0] is a valid memory context.
- */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_RBTDB_H */
diff --git a/contrib/bind9/lib/dns/rbtdb64.c b/contrib/bind9/lib/dns/rbtdb64.c
deleted file mode 100644
index 5e325fac0ab0..000000000000
--- a/contrib/bind9/lib/dns/rbtdb64.c
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: rbtdb64.c,v 1.11 2007/06/19 23:47:16 tbox Exp $ */
-
-/*! \file */
-
-#define DNS_RBTDB_VERSION64 1
-#include "rbtdb.c"
diff --git a/contrib/bind9/lib/dns/rbtdb64.h b/contrib/bind9/lib/dns/rbtdb64.h
deleted file mode 100644
index fe11622f6740..000000000000
--- a/contrib/bind9/lib/dns/rbtdb64.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: rbtdb64.h,v 1.17 2007/06/19 23:47:16 tbox Exp $ */
-
-#ifndef DNS_RBTDB64_H
-#define DNS_RBTDB64_H 1
-
-#include <isc/lang.h>
-
-/*****
- ***** Module Info
- *****/
-
-/*! \file
- * \brief
- * DNS Red-Black Tree DB Implementation with 64-bit version numbers
- */
-
-#include <dns/db.h>
-
-ISC_LANG_BEGINDECLS
-
-isc_result_t
-dns_rbtdb64_create(isc_mem_t *mctx, dns_name_t *base, dns_dbtype_t type,
- dns_rdataclass_t rdclass, unsigned int argc, char *argv[],
- void *driverarg, dns_db_t **dbp);
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_RBTDB64_H */
diff --git a/contrib/bind9/lib/dns/rcode.c b/contrib/bind9/lib/dns/rcode.c
deleted file mode 100644
index 0b7fe8c28051..000000000000
--- a/contrib/bind9/lib/dns/rcode.c
+++ /dev/null
@@ -1,515 +0,0 @@
-/*
- * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-#include <config.h>
-#include <ctype.h>
-
-#include <isc/buffer.h>
-#include <isc/parseint.h>
-#include <isc/print.h>
-#include <isc/region.h>
-#include <isc/result.h>
-#include <isc/stdio.h>
-#include <isc/stdlib.h>
-#include <isc/string.h>
-#include <isc/types.h>
-#include <isc/util.h>
-
-#include <dns/cert.h>
-#include <dns/keyflags.h>
-#include <dns/keyvalues.h>
-#include <dns/rcode.h>
-#include <dns/rdataclass.h>
-#include <dns/result.h>
-#include <dns/secalg.h>
-#include <dns/secproto.h>
-
-#define RETERR(x) \
- do { \
- isc_result_t _r = (x); \
- if (_r != ISC_R_SUCCESS) \
- return (_r); \
- } while (0)
-
-#define NUMBERSIZE sizeof("037777777777") /* 2^32-1 octal + NUL */
-
-#define RCODENAMES \
- /* standard rcodes */ \
- { dns_rcode_noerror, "NOERROR", 0}, \
- { dns_rcode_formerr, "FORMERR", 0}, \
- { dns_rcode_servfail, "SERVFAIL", 0}, \
- { dns_rcode_nxdomain, "NXDOMAIN", 0}, \
- { dns_rcode_notimp, "NOTIMP", 0}, \
- { dns_rcode_refused, "REFUSED", 0}, \
- { dns_rcode_yxdomain, "YXDOMAIN", 0}, \
- { dns_rcode_yxrrset, "YXRRSET", 0}, \
- { dns_rcode_nxrrset, "NXRRSET", 0}, \
- { dns_rcode_notauth, "NOTAUTH", 0}, \
- { dns_rcode_notzone, "NOTZONE", 0},
-
-#define ERCODENAMES \
- /* extended rcodes */ \
- { dns_rcode_badvers, "BADVERS", 0}, \
- { 0, NULL, 0 }
-
-#define TSIGRCODENAMES \
- /* extended rcodes */ \
- { dns_tsigerror_badsig, "BADSIG", 0}, \
- { dns_tsigerror_badkey, "BADKEY", 0}, \
- { dns_tsigerror_badtime, "BADTIME", 0}, \
- { dns_tsigerror_badmode, "BADMODE", 0}, \
- { dns_tsigerror_badname, "BADNAME", 0}, \
- { dns_tsigerror_badalg, "BADALG", 0}, \
- { dns_tsigerror_badtrunc, "BADTRUNC", 0}, \
- { 0, NULL, 0 }
-
-/* 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}
-
-/* RFC2535 section 7, RFC3110 */
-
-#define SECALGNAMES \
- { DNS_KEYALG_RSAMD5, "RSAMD5", 0 }, \
- { DNS_KEYALG_RSAMD5, "RSA", 0 }, \
- { DNS_KEYALG_DH, "DH", 0 }, \
- { DNS_KEYALG_DSA, "DSA", 0 }, \
- { DNS_KEYALG_NSEC3DSA, "NSEC3DSA", 0 }, \
- { DNS_KEYALG_ECC, "ECC", 0 }, \
- { DNS_KEYALG_RSASHA1, "RSASHA1", 0 }, \
- { DNS_KEYALG_NSEC3RSASHA1, "NSEC3RSASHA1", 0 }, \
- { DNS_KEYALG_RSASHA256, "RSASHA256", 0 }, \
- { DNS_KEYALG_RSASHA512, "RSASHA512", 0 }, \
- { DNS_KEYALG_ECCGOST, "ECCGOST", 0 }, \
- { DNS_KEYALG_ECDSA256, "ECDSAP256SHA256", 0 }, \
- { DNS_KEYALG_ECDSA384, "ECDSAP384SHA384", 0 }, \
- { DNS_KEYALG_INDIRECT, "INDIRECT", 0 }, \
- { DNS_KEYALG_PRIVATEDNS, "PRIVATEDNS", 0 }, \
- { DNS_KEYALG_PRIVATEOID, "PRIVATEOID", 0 }, \
- { 0, NULL, 0}
-
-/* RFC2535 section 7.1 */
-
-#define SECPROTONAMES \
- { 0, "NONE", 0 }, \
- { 1, "TLS", 0 }, \
- { 2, "EMAIL", 0 }, \
- { 3, "DNSSEC", 0 }, \
- { 4, "IPSEC", 0 }, \
- { 255, "ALL", 0 }, \
- { 0, NULL, 0}
-
-#define HASHALGNAMES \
- { 1, "SHA-1", 0 }, \
- { 0, NULL, 0 }
-
-struct tbl {
- unsigned int value;
- const char *name;
- int flags;
-};
-
-static struct tbl rcodes[] = { RCODENAMES ERCODENAMES };
-static struct tbl tsigrcodes[] = { RCODENAMES TSIGRCODENAMES };
-static struct tbl certs[] = { CERTNAMES };
-static struct tbl secalgs[] = { SECALGNAMES };
-static struct tbl secprotos[] = { SECPROTONAMES };
-static struct tbl hashalgs[] = { HASHALGNAMES };
-
-static struct keyflag {
- const char *name;
- unsigned int value;
- unsigned int mask;
-} keyflags[] = {
- { "NOCONF", 0x4000, 0xC000 },
- { "NOAUTH", 0x8000, 0xC000 },
- { "NOKEY", 0xC000, 0xC000 },
- { "FLAG2", 0x2000, 0x2000 },
- { "EXTEND", 0x1000, 0x1000 },
- { "FLAG4", 0x0800, 0x0800 },
- { "FLAG5", 0x0400, 0x0400 },
- { "USER", 0x0000, 0x0300 },
- { "ZONE", 0x0100, 0x0300 },
- { "HOST", 0x0200, 0x0300 },
- { "NTYP3", 0x0300, 0x0300 },
- { "FLAG8", 0x0080, 0x0080 },
- { "FLAG9", 0x0040, 0x0040 },
- { "FLAG10", 0x0020, 0x0020 },
- { "FLAG11", 0x0010, 0x0010 },
- { "SIG0", 0x0000, 0x000F },
- { "SIG1", 0x0001, 0x000F },
- { "SIG2", 0x0002, 0x000F },
- { "SIG3", 0x0003, 0x000F },
- { "SIG4", 0x0004, 0x000F },
- { "SIG5", 0x0005, 0x000F },
- { "SIG6", 0x0006, 0x000F },
- { "SIG7", 0x0007, 0x000F },
- { "SIG8", 0x0008, 0x000F },
- { "SIG9", 0x0009, 0x000F },
- { "SIG10", 0x000A, 0x000F },
- { "SIG11", 0x000B, 0x000F },
- { "SIG12", 0x000C, 0x000F },
- { "SIG13", 0x000D, 0x000F },
- { "SIG14", 0x000E, 0x000F },
- { "SIG15", 0x000F, 0x000F },
- { "KSK", DNS_KEYFLAG_KSK, DNS_KEYFLAG_KSK },
- { NULL, 0, 0 }
-};
-
-static isc_result_t
-str_totext(const char *source, isc_buffer_t *target) {
- unsigned int l;
- isc_region_t region;
-
- isc_buffer_availableregion(target, &region);
- l = strlen(source);
-
- if (l > region.length)
- return (ISC_R_NOSPACE);
-
- memcpy(region.base, source, l);
- isc_buffer_add(target, l);
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-maybe_numeric(unsigned int *valuep, isc_textregion_t *source,
- unsigned int max, isc_boolean_t hex_allowed)
-{
- isc_result_t result;
- isc_uint32_t n;
- char buffer[NUMBERSIZE];
-
- if (! isdigit(source->base[0] & 0xff) ||
- source->length > NUMBERSIZE - 1)
- return (ISC_R_BADNUMBER);
-
- /*
- * We have a potential number. Try to parse it with
- * isc_parse_uint32(). isc_parse_uint32() requires
- * null termination, so we must make a copy.
- */
- strncpy(buffer, source->base, NUMBERSIZE);
- INSIST(buffer[source->length] == '\0');
-
- result = isc_parse_uint32(&n, buffer, 10);
- if (result == ISC_R_BADNUMBER && hex_allowed)
- result = isc_parse_uint32(&n, buffer, 16);
- if (result != ISC_R_SUCCESS)
- return (result);
- if (n > max)
- return (ISC_R_RANGE);
- *valuep = n;
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-dns_mnemonic_fromtext(unsigned int *valuep, isc_textregion_t *source,
- struct tbl *table, unsigned int max)
-{
- isc_result_t result;
- int i;
-
- result = maybe_numeric(valuep, source, max, ISC_FALSE);
- if (result != ISC_R_BADNUMBER)
- return (result);
-
- for (i = 0; table[i].name != NULL; i++) {
- unsigned int n;
- n = strlen(table[i].name);
- if (n == source->length &&
- strncasecmp(source->base, table[i].name, n) == 0) {
- *valuep = table[i].value;
- return (ISC_R_SUCCESS);
- }
- }
- return (DNS_R_UNKNOWN);
-}
-
-static isc_result_t
-dns_mnemonic_totext(unsigned int value, isc_buffer_t *target,
- struct tbl *table)
-{
- int i = 0;
- char buf[sizeof("4294967296")];
- while (table[i].name != NULL) {
- if (table[i].value == value) {
- return (str_totext(table[i].name, target));
- }
- i++;
- }
- snprintf(buf, sizeof(buf), "%u", value);
- return (str_totext(buf, target));
-}
-
-isc_result_t
-dns_rcode_fromtext(dns_rcode_t *rcodep, isc_textregion_t *source) {
- unsigned int value;
- RETERR(dns_mnemonic_fromtext(&value, source, rcodes, 0xffff));
- *rcodep = value;
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_rcode_totext(dns_rcode_t rcode, isc_buffer_t *target) {
- return (dns_mnemonic_totext(rcode, target, rcodes));
-}
-
-isc_result_t
-dns_tsigrcode_fromtext(dns_rcode_t *rcodep, isc_textregion_t *source) {
- unsigned int value;
- RETERR(dns_mnemonic_fromtext(&value, source, tsigrcodes, 0xffff));
- *rcodep = value;
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_tsigrcode_totext(dns_rcode_t rcode, isc_buffer_t *target) {
- return (dns_mnemonic_totext(rcode, target, tsigrcodes));
-}
-
-isc_result_t
-dns_cert_fromtext(dns_cert_t *certp, isc_textregion_t *source) {
- unsigned int value;
- RETERR(dns_mnemonic_fromtext(&value, source, certs, 0xffff));
- *certp = value;
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_cert_totext(dns_cert_t cert, isc_buffer_t *target) {
- return (dns_mnemonic_totext(cert, target, certs));
-}
-
-isc_result_t
-dns_secalg_fromtext(dns_secalg_t *secalgp, isc_textregion_t *source) {
- unsigned int value;
- RETERR(dns_mnemonic_fromtext(&value, source, secalgs, 0xff));
- *secalgp = value;
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-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;
- RETERR(dns_mnemonic_fromtext(&value, source, secprotos, 0xff));
- *secprotop = value;
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_secproto_totext(dns_secproto_t secproto, isc_buffer_t *target) {
- return (dns_mnemonic_totext(secproto, target, secprotos));
-}
-
-isc_result_t
-dns_hashalg_fromtext(unsigned char *hashalg, isc_textregion_t *source) {
- unsigned int value;
- RETERR(dns_mnemonic_fromtext(&value, source, hashalgs, 0xff));
- *hashalg = value;
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_keyflags_fromtext(dns_keyflags_t *flagsp, isc_textregion_t *source)
-{
- isc_result_t result;
- char *text, *end;
- unsigned int value, mask;
-
- result = maybe_numeric(&value, source, 0xffff, ISC_TRUE);
- if (result == ISC_R_SUCCESS) {
- *flagsp = value;
- return (ISC_R_SUCCESS);
- }
- if (result != ISC_R_BADNUMBER)
- return (result);
-
- text = source->base;
- end = source->base + source->length;
- value = mask = 0;
-
- while (text < end) {
- struct keyflag *p;
- unsigned int len;
- char *delim = memchr(text, '|', end - text);
- if (delim != NULL)
- len = delim - text;
- else
- len = end - text;
- for (p = keyflags; p->name != NULL; p++) {
- if (strncasecmp(p->name, text, len) == 0)
- break;
- }
- if (p->name == NULL)
- return (DNS_R_UNKNOWNFLAG);
- value |= p->value;
-#ifdef notyet
- if ((mask & p->mask) != 0)
- warn("overlapping key flags");
-#endif
- mask |= p->mask;
- text += len;
- if (delim != NULL)
- text++; /* Skip "|" */
- }
- *flagsp = value;
- return (ISC_R_SUCCESS);
-}
-
-/*
- * This uses lots of hard coded values, but how often do we actually
- * add classes?
- */
-isc_result_t
-dns_rdataclass_fromtext(dns_rdataclass_t *classp, isc_textregion_t *source) {
-#define COMPARE(string, rdclass) \
- if (((sizeof(string) - 1) == source->length) \
- && (strncasecmp(source->base, string, source->length) == 0)) { \
- *classp = rdclass; \
- return (ISC_R_SUCCESS); \
- }
-
- switch (tolower((unsigned char)source->base[0])) {
- case 'a':
- COMPARE("any", dns_rdataclass_any);
- break;
- case 'c':
- /*
- * RFC1035 says the mnemonic for the CHAOS class is CH,
- * but historical BIND practice is to call it CHAOS.
- * We will accept both forms, but only generate CH.
- */
- COMPARE("ch", dns_rdataclass_chaos);
- COMPARE("chaos", dns_rdataclass_chaos);
-
- if (source->length > 5 &&
- source->length < (5 + sizeof("65000")) &&
- strncasecmp("class", source->base, 5) == 0) {
- char buf[sizeof("65000")];
- char *endp;
- unsigned int val;
-
- strncpy(buf, source->base + 5, source->length - 5);
- buf[source->length - 5] = '\0';
- val = strtoul(buf, &endp, 10);
- if (*endp == '\0' && val <= 0xffff) {
- *classp = (dns_rdataclass_t)val;
- return (ISC_R_SUCCESS);
- }
- }
- break;
- case 'h':
- COMPARE("hs", dns_rdataclass_hs);
- COMPARE("hesiod", dns_rdataclass_hs);
- break;
- case 'i':
- COMPARE("in", dns_rdataclass_in);
- break;
- case 'n':
- COMPARE("none", dns_rdataclass_none);
- break;
- case 'r':
- COMPARE("reserved0", dns_rdataclass_reserved0);
- break;
- }
-
-#undef COMPARE
-
- return (DNS_R_UNKNOWN);
-}
-
-isc_result_t
-dns_rdataclass_totext(dns_rdataclass_t rdclass, isc_buffer_t *target) {
- char buf[sizeof("CLASS65535")];
-
- switch (rdclass) {
- case dns_rdataclass_any:
- return (str_totext("ANY", target));
- case dns_rdataclass_chaos:
- return (str_totext("CH", target));
- case dns_rdataclass_hs:
- return (str_totext("HS", target));
- case dns_rdataclass_in:
- return (str_totext("IN", target));
- case dns_rdataclass_none:
- return (str_totext("NONE", target));
- case dns_rdataclass_reserved0:
- return (str_totext("RESERVED0", target));
- default:
- snprintf(buf, sizeof(buf), "CLASS%u", rdclass);
- return (str_totext(buf, target));
- }
-}
-
-void
-dns_rdataclass_format(dns_rdataclass_t rdclass,
- char *array, unsigned int size)
-{
- isc_result_t result;
- isc_buffer_t buf;
-
- if (size == 0U)
- return;
-
- isc_buffer_init(&buf, array, size);
- result = dns_rdataclass_totext(rdclass, &buf);
- /*
- * Null terminate.
- */
- if (result == ISC_R_SUCCESS) {
- if (isc_buffer_availablelength(&buf) >= 1)
- isc_buffer_putuint8(&buf, 0);
- else
- result = ISC_R_NOSPACE;
- }
- if (result != ISC_R_SUCCESS)
- strlcpy(array, "<unknown>", size);
-}
diff --git a/contrib/bind9/lib/dns/rdata.c b/contrib/bind9/lib/dns/rdata.c
deleted file mode 100644
index a83dab462ce5..000000000000
--- a/contrib/bind9/lib/dns/rdata.c
+++ /dev/null
@@ -1,2175 +0,0 @@
-/*
- * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/*! \file */
-
-#include <config.h>
-#include <ctype.h>
-
-#include <isc/base64.h>
-#include <isc/hex.h>
-#include <isc/lex.h>
-#include <isc/mem.h>
-#include <isc/parseint.h>
-#include <isc/print.h>
-#include <isc/string.h>
-#include <isc/stdlib.h>
-#include <isc/util.h>
-
-#include <dns/callbacks.h>
-#include <dns/cert.h>
-#include <dns/compress.h>
-#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>
-#include <dns/rdatastruct.h>
-#include <dns/rdatatype.h>
-#include <dns/result.h>
-#include <dns/secalg.h>
-#include <dns/secproto.h>
-#include <dns/time.h>
-#include <dns/ttl.h>
-
-#define RETERR(x) \
- do { \
- isc_result_t _r = (x); \
- if (_r != ISC_R_SUCCESS) \
- return (_r); \
- } while (0)
-
-#define RETTOK(x) \
- do { \
- isc_result_t _r = (x); \
- if (_r != ISC_R_SUCCESS) { \
- isc_lex_ungettoken(lexer, &token); \
- return (_r); \
- } \
- } while (0)
-
-#define DNS_AS_STR(t) ((t).value.as_textregion.base)
-
-#define ARGS_FROMTEXT int rdclass, dns_rdatatype_t type, \
- isc_lex_t *lexer, dns_name_t *origin, \
- unsigned int options, isc_buffer_t *target, \
- dns_rdatacallbacks_t *callbacks
-
-#define ARGS_TOTEXT dns_rdata_t *rdata, dns_rdata_textctx_t *tctx, \
- isc_buffer_t *target
-
-#define ARGS_FROMWIRE int rdclass, dns_rdatatype_t type, \
- isc_buffer_t *source, dns_decompress_t *dctx, \
- unsigned int options, isc_buffer_t *target
-
-#define ARGS_TOWIRE dns_rdata_t *rdata, dns_compress_t *cctx, \
- isc_buffer_t *target
-
-#define ARGS_COMPARE const dns_rdata_t *rdata1, const dns_rdata_t *rdata2
-
-#define ARGS_FROMSTRUCT int rdclass, dns_rdatatype_t type, \
- void *source, isc_buffer_t *target
-
-#define ARGS_TOSTRUCT dns_rdata_t *rdata, void *target, isc_mem_t *mctx
-
-#define ARGS_FREESTRUCT void *source
-
-#define ARGS_ADDLDATA dns_rdata_t *rdata, dns_additionaldatafunc_t add, \
- void *arg
-
-#define ARGS_DIGEST dns_rdata_t *rdata, dns_digestfunc_t digest, void *arg
-
-#define ARGS_CHECKOWNER dns_name_t *name, dns_rdataclass_t rdclass, \
- dns_rdatatype_t type, isc_boolean_t wildcard
-
-#define ARGS_CHECKNAMES dns_rdata_t *rdata, dns_name_t *owner, dns_name_t *bad
-
-
-/*%
- * Context structure for the totext_ functions.
- * Contains formatting options for rdata-to-text
- * conversion.
- */
-typedef struct dns_rdata_textctx {
- dns_name_t *origin; /*%< Current origin, or NULL. */
- unsigned int flags; /*%< DNS_STYLEFLAG_* */
- unsigned int width; /*%< Width of rdata column. */
- const char *linebreak; /*%< Line break string. */
-} dns_rdata_textctx_t;
-
-static isc_result_t
-txt_totext(isc_region_t *source, isc_buffer_t *target);
-
-static isc_result_t
-txt_fromtext(isc_textregion_t *source, isc_buffer_t *target);
-
-static isc_result_t
-txt_fromwire(isc_buffer_t *source, isc_buffer_t *target);
-
-static isc_result_t
-multitxt_totext(isc_region_t *source, isc_buffer_t *target);
-
-static isc_result_t
-multitxt_fromtext(isc_textregion_t *source, isc_buffer_t *target);
-
-static isc_result_t
-multitxt_fromwire(isc_buffer_t *source, isc_buffer_t *target);
-
-static isc_boolean_t
-name_prefix(dns_name_t *name, dns_name_t *origin, dns_name_t *target);
-
-static unsigned int
-name_length(dns_name_t *name);
-
-static isc_result_t
-str_totext(const char *source, isc_buffer_t *target);
-
-static isc_result_t
-inet_totext(int af, isc_region_t *src, isc_buffer_t *target);
-
-static isc_boolean_t
-buffer_empty(isc_buffer_t *source);
-
-static void
-buffer_fromregion(isc_buffer_t *buffer, isc_region_t *region);
-
-static isc_result_t
-uint32_tobuffer(isc_uint32_t, isc_buffer_t *target);
-
-static isc_result_t
-uint16_tobuffer(isc_uint32_t, isc_buffer_t *target);
-
-static isc_result_t
-uint8_tobuffer(isc_uint32_t, isc_buffer_t *target);
-
-static isc_result_t
-name_tobuffer(dns_name_t *name, isc_buffer_t *target);
-
-static isc_uint32_t
-uint32_fromregion(isc_region_t *region);
-
-static isc_uint16_t
-uint16_fromregion(isc_region_t *region);
-
-static isc_uint8_t
-uint8_fromregion(isc_region_t *region);
-
-static isc_uint8_t
-uint8_consume_fromregion(isc_region_t *region);
-
-static isc_result_t
-mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length);
-
-static int
-hexvalue(char value);
-
-static int
-decvalue(char value);
-
-static isc_result_t
-btoa_totext(unsigned char *inbuf, int inbuflen, isc_buffer_t *target);
-
-static isc_result_t
-atob_tobuffer(isc_lex_t *lexer, isc_buffer_t *target);
-
-static void
-default_fromtext_callback(dns_rdatacallbacks_t *callbacks, const char *, ...)
- ISC_FORMAT_PRINTF(2, 3);
-
-static void
-fromtext_error(void (*callback)(dns_rdatacallbacks_t *, const char *, ...),
- dns_rdatacallbacks_t *callbacks, const char *name,
- unsigned long line, isc_token_t *token, isc_result_t result);
-
-static void
-fromtext_warneof(isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks);
-
-static isc_result_t
-rdata_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx,
- isc_buffer_t *target);
-
-static void
-warn_badname(dns_name_t *name, isc_lex_t *lexer,
- dns_rdatacallbacks_t *callbacks);
-
-static void
-warn_badmx(isc_token_t *token, isc_lex_t *lexer,
- dns_rdatacallbacks_t *callbacks);
-
-static isc_uint16_t
-uint16_consume_fromregion(isc_region_t *region);
-
-static isc_result_t
-unknown_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx,
- isc_buffer_t *target);
-
-/*% INT16 Size */
-#define NS_INT16SZ 2
-/*% IPv6 Address Size */
-#define NS_LOCATORSZ 8
-
-/*%
- * convert presentation level address to network order binary form.
- * \return
- * 1 if `src' is a valid [RFC1884 2.2] address, else 0.
- * \note
- * (1) does not touch `dst' unless it's returning 1.
- */
-static inline int
-locator_pton(const char *src, unsigned char *dst) {
- static const char xdigits_l[] = "0123456789abcdef",
- xdigits_u[] = "0123456789ABCDEF";
- unsigned char tmp[NS_LOCATORSZ];
- unsigned char *tp = tmp, *endp;
- const char *xdigits;
- int ch, seen_xdigits;
- unsigned int val;
-
- memset(tp, '\0', NS_LOCATORSZ);
- endp = tp + NS_LOCATORSZ;
- seen_xdigits = 0;
- val = 0;
- while ((ch = *src++) != '\0') {
- const char *pch;
-
- pch = strchr((xdigits = xdigits_l), ch);
- if (pch == NULL)
- pch = strchr((xdigits = xdigits_u), ch);
- if (pch != NULL) {
- val <<= 4;
- val |= (pch - xdigits);
- if (++seen_xdigits > 4)
- return (0);
- continue;
- }
- if (ch == ':') {
- if (!seen_xdigits)
- return (0);
- if (tp + NS_INT16SZ > endp)
- return (0);
- *tp++ = (unsigned char) (val >> 8) & 0xff;
- *tp++ = (unsigned char) val & 0xff;
- seen_xdigits = 0;
- val = 0;
- continue;
- }
- return (0);
- }
- if (seen_xdigits) {
- if (tp + NS_INT16SZ > endp)
- return (0);
- *tp++ = (unsigned char) (val >> 8) & 0xff;
- *tp++ = (unsigned char) val & 0xff;
- }
- if (tp != endp)
- return (0);
- memcpy(dst, tmp, NS_LOCATORSZ);
- return (1);
-}
-
-static inline int
-getquad(const void *src, struct in_addr *dst,
- isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks)
-{
- int result;
- struct in_addr *tmp;
-
- result = inet_aton(src, dst);
- if (result == 1 && callbacks != NULL &&
- inet_pton(AF_INET, src, &tmp) != 1) {
- const char *name = isc_lex_getsourcename(lexer);
- if (name == NULL)
- name = "UNKNOWN";
- (*callbacks->warn)(callbacks, "%s:%lu: \"%s\" "
- "is not a decimal dotted quad", name,
- isc_lex_getsourceline(lexer), src);
- }
- return (result);
-}
-
-static inline isc_result_t
-name_duporclone(dns_name_t *source, isc_mem_t *mctx, dns_name_t *target) {
-
- if (mctx != NULL)
- return (dns_name_dup(source, mctx, target));
- dns_name_clone(source, target);
- return (ISC_R_SUCCESS);
-}
-
-static inline void *
-mem_maybedup(isc_mem_t *mctx, void *source, size_t length) {
- void *new;
-
- if (mctx == NULL)
- return (source);
- new = isc_mem_allocate(mctx, length);
- if (new != NULL)
- memcpy(new, source, length);
-
- return (new);
-}
-
-static const char hexdigits[] = "0123456789abcdef";
-static const char decdigits[] = "0123456789";
-
-#include "code.h"
-
-#define META 0x0001
-#define RESERVED 0x0002
-
-/***
- *** Initialization
- ***/
-
-void
-dns_rdata_init(dns_rdata_t *rdata) {
-
- REQUIRE(rdata != NULL);
-
- rdata->data = NULL;
- rdata->length = 0;
- rdata->rdclass = 0;
- rdata->type = 0;
- rdata->flags = 0;
- ISC_LINK_INIT(rdata, link);
- /* ISC_LIST_INIT(rdata->list); */
-}
-
-void
-dns_rdata_reset(dns_rdata_t *rdata) {
-
- REQUIRE(rdata != NULL);
-
- REQUIRE(!ISC_LINK_LINKED(rdata, link));
- REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
-
- rdata->data = NULL;
- rdata->length = 0;
- rdata->rdclass = 0;
- rdata->type = 0;
- rdata->flags = 0;
-}
-
-/***
- ***
- ***/
-
-void
-dns_rdata_clone(const dns_rdata_t *src, dns_rdata_t *target) {
-
- REQUIRE(src != NULL);
- REQUIRE(target != NULL);
-
- REQUIRE(DNS_RDATA_INITIALIZED(target));
-
- REQUIRE(DNS_RDATA_VALIDFLAGS(src));
- REQUIRE(DNS_RDATA_VALIDFLAGS(target));
-
- target->data = src->data;
- target->length = src->length;
- target->rdclass = src->rdclass;
- target->type = src->type;
- target->flags = src->flags;
-}
-
-
-/***
- *** Comparisons
- ***/
-
-int
-dns_rdata_compare(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->length == 0 || rdata1->data != NULL);
- REQUIRE(rdata2->length == 0 || 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);
-
- COMPARESWITCH
-
- 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);
-}
-
-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->length == 0 || rdata1->data != NULL);
- REQUIRE(rdata2->length == 0 || 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
- ***/
-
-void
-dns_rdata_fromregion(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
- dns_rdatatype_t type, isc_region_t *r)
-{
-
- REQUIRE(rdata != NULL);
- REQUIRE(DNS_RDATA_INITIALIZED(rdata));
- REQUIRE(r != NULL);
-
- REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
-
- rdata->data = r->base;
- rdata->length = r->length;
- rdata->rdclass = rdclass;
- rdata->type = type;
- rdata->flags = 0;
-}
-
-void
-dns_rdata_toregion(const dns_rdata_t *rdata, isc_region_t *r) {
-
- REQUIRE(rdata != NULL);
- REQUIRE(r != NULL);
- REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
-
- r->base = rdata->data;
- r->length = rdata->length;
-}
-
-isc_result_t
-dns_rdata_fromwire(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
- dns_rdatatype_t type, isc_buffer_t *source,
- dns_decompress_t *dctx, unsigned int options,
- isc_buffer_t *target)
-{
- isc_result_t result = ISC_R_NOTIMPLEMENTED;
- isc_region_t region;
- isc_buffer_t ss;
- isc_buffer_t st;
- isc_boolean_t use_default = ISC_FALSE;
- isc_uint32_t activelength;
- size_t length;
-
- REQUIRE(dctx != NULL);
- if (rdata != NULL) {
- REQUIRE(DNS_RDATA_INITIALIZED(rdata));
- REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
- }
- REQUIRE(source != NULL);
- REQUIRE(target != NULL);
-
- if (type == 0)
- return (DNS_R_FORMERR);
-
- ss = *source;
- st = *target;
-
- activelength = isc_buffer_activelength(source);
- INSIST(activelength < 65536);
-
- FROMWIRESWITCH
-
- if (use_default) {
- if (activelength > isc_buffer_availablelength(target))
- result = ISC_R_NOSPACE;
- else {
- isc_buffer_putmem(target, isc_buffer_current(source),
- activelength);
- isc_buffer_forward(source, activelength);
- result = ISC_R_SUCCESS;
- }
- }
-
- /*
- * Reject any rdata that expands out to more than DNS_RDATA_MAXLENGTH
- * as we cannot transmit it.
- */
- length = isc_buffer_usedlength(target) - isc_buffer_usedlength(&st);
- if (result == ISC_R_SUCCESS && length > DNS_RDATA_MAXLENGTH)
- result = DNS_R_FORMERR;
-
- /*
- * We should have consumed all of our buffer.
- */
- if (result == ISC_R_SUCCESS && !buffer_empty(source))
- result = DNS_R_EXTRADATA;
-
- if (rdata != NULL && result == ISC_R_SUCCESS) {
- region.base = isc_buffer_used(&st);
- region.length = length;
- dns_rdata_fromregion(rdata, rdclass, type, &region);
- }
-
- if (result != ISC_R_SUCCESS) {
- *source = ss;
- *target = st;
- }
- return (result);
-}
-
-isc_result_t
-dns_rdata_towire(dns_rdata_t *rdata, dns_compress_t *cctx,
- isc_buffer_t *target)
-{
- isc_result_t result = ISC_R_NOTIMPLEMENTED;
- isc_boolean_t use_default = ISC_FALSE;
- isc_region_t tr;
- isc_buffer_t st;
-
- REQUIRE(rdata != NULL);
- REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
-
- /*
- * Some DynDNS meta-RRs have empty rdata.
- */
- if ((rdata->flags & DNS_RDATA_UPDATE) != 0) {
- INSIST(rdata->length == 0);
- return (ISC_R_SUCCESS);
- }
-
- st = *target;
-
- TOWIRESWITCH
-
- if (use_default) {
- isc_buffer_availableregion(target, &tr);
- if (tr.length < rdata->length)
- return (ISC_R_NOSPACE);
- memcpy(tr.base, rdata->data, rdata->length);
- isc_buffer_add(target, rdata->length);
- return (ISC_R_SUCCESS);
- }
- if (result != ISC_R_SUCCESS) {
- *target = st;
- INSIST(target->used < 65536);
- dns_compress_rollback(cctx, (isc_uint16_t)target->used);
- }
- return (result);
-}
-
-/*
- * If the binary data in 'src' is valid uncompressed wire format
- * rdata of class 'rdclass' and type 'type', return ISC_R_SUCCESS
- * and copy the validated rdata to 'dest'. Otherwise return an error.
- */
-static isc_result_t
-rdata_validate(isc_buffer_t *src, isc_buffer_t *dest, dns_rdataclass_t rdclass,
- dns_rdatatype_t type)
-{
- dns_decompress_t dctx;
- isc_result_t result;
-
- dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE);
- isc_buffer_setactive(src, isc_buffer_usedlength(src));
- result = dns_rdata_fromwire(NULL, rdclass, type, src, &dctx, 0, dest);
- dns_decompress_invalidate(&dctx);
-
- return (result);
-}
-
-static isc_result_t
-unknown_fromtext(dns_rdataclass_t rdclass, dns_rdatatype_t type,
- isc_lex_t *lexer, isc_mem_t *mctx, isc_buffer_t *target)
-{
- isc_result_t result;
- isc_buffer_t *buf = NULL;
- isc_token_t token;
-
- if (type == 0 || dns_rdatatype_ismeta(type))
- return (DNS_R_METATYPE);
-
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if (token.value.as_ulong > 65535U)
- return (ISC_R_RANGE);
- result = isc_buffer_allocate(mctx, &buf, token.value.as_ulong);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- result = isc_hex_tobuffer(lexer, buf,
- (unsigned int)token.value.as_ulong);
- if (result != ISC_R_SUCCESS)
- goto failure;
- if (isc_buffer_usedlength(buf) != token.value.as_ulong) {
- result = ISC_R_UNEXPECTEDEND;
- goto failure;
- }
-
- if (dns_rdatatype_isknown(type)) {
- result = rdata_validate(buf, target, rdclass, type);
- } else {
- isc_region_t r;
- isc_buffer_usedregion(buf, &r);
- result = isc_buffer_copyregion(target, &r);
- }
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- isc_buffer_free(&buf);
- return (ISC_R_SUCCESS);
-
- failure:
- isc_buffer_free(&buf);
- return (result);
-}
-
-isc_result_t
-dns_rdata_fromtext(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
- dns_rdatatype_t type, isc_lex_t *lexer,
- dns_name_t *origin, unsigned int options, isc_mem_t *mctx,
- isc_buffer_t *target, dns_rdatacallbacks_t *callbacks)
-{
- isc_result_t result = ISC_R_NOTIMPLEMENTED;
- isc_region_t region;
- isc_buffer_t st;
- isc_token_t token;
- unsigned int lexoptions = ISC_LEXOPT_EOL | ISC_LEXOPT_EOF |
- ISC_LEXOPT_DNSMULTILINE | ISC_LEXOPT_ESCAPE;
- char *name;
- unsigned long line;
- void (*callback)(dns_rdatacallbacks_t *, const char *, ...);
- isc_result_t tresult;
- size_t length;
- isc_boolean_t unknown;
-
- REQUIRE(origin == NULL || dns_name_isabsolute(origin) == ISC_TRUE);
- if (rdata != NULL) {
- REQUIRE(DNS_RDATA_INITIALIZED(rdata));
- REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
- }
- if (callbacks != NULL) {
- REQUIRE(callbacks->warn != NULL);
- REQUIRE(callbacks->error != NULL);
- }
-
- st = *target;
-
- if (callbacks != NULL)
- callback = callbacks->error;
- else
- callback = default_fromtext_callback;
-
- result = isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring,
- ISC_FALSE);
- if (result != ISC_R_SUCCESS) {
- name = isc_lex_getsourcename(lexer);
- line = isc_lex_getsourceline(lexer);
- fromtext_error(callback, callbacks, name, line, NULL, result);
- return (result);
- }
-
- unknown = ISC_FALSE;
- if (token.type == isc_tokentype_string &&
- strcmp(DNS_AS_STR(token), "\\#") == 0) {
- /*
- * If this is a TXT record '\#' could be a escaped '#'.
- * Look to see if the next token is a number and if so
- * treat it as a unknown record format.
- */
- if (type == dns_rdatatype_txt) {
- result = isc_lex_getmastertoken(lexer, &token,
- isc_tokentype_number,
- ISC_FALSE);
- if (result == ISC_R_SUCCESS)
- isc_lex_ungettoken(lexer, &token);
- }
-
- if (result == ISC_R_SUCCESS) {
- unknown = ISC_TRUE;
- result = unknown_fromtext(rdclass, type, lexer,
- mctx, target);
- } else
- options |= DNS_RDATA_UNKNOWNESCAPE;
- } else
- isc_lex_ungettoken(lexer, &token);
-
- if (!unknown)
- FROMTEXTSWITCH
-
- /*
- * Consume to end of line / file.
- * If not at end of line initially set error code.
- * Call callback via fromtext_error once if there was an error.
- */
- do {
- name = isc_lex_getsourcename(lexer);
- line = isc_lex_getsourceline(lexer);
- tresult = isc_lex_gettoken(lexer, lexoptions, &token);
- if (tresult != ISC_R_SUCCESS) {
- if (result == ISC_R_SUCCESS)
- result = tresult;
- if (callback != NULL)
- fromtext_error(callback, callbacks, name,
- line, NULL, result);
- break;
- } else if (token.type != isc_tokentype_eol &&
- token.type != isc_tokentype_eof) {
- if (result == ISC_R_SUCCESS)
- result = DNS_R_EXTRATOKEN;
- if (callback != NULL) {
- fromtext_error(callback, callbacks, name,
- line, &token, result);
- callback = NULL;
- }
- } else if (result != ISC_R_SUCCESS && callback != NULL) {
- fromtext_error(callback, callbacks, name, line,
- &token, result);
- break;
- } else {
- if (token.type == isc_tokentype_eof)
- fromtext_warneof(lexer, callbacks);
- break;
- }
- } while (1);
-
- length = isc_buffer_usedlength(target) - isc_buffer_usedlength(&st);
- if (result == ISC_R_SUCCESS && length > DNS_RDATA_MAXLENGTH)
- result = ISC_R_NOSPACE;
-
- if (rdata != NULL && result == ISC_R_SUCCESS) {
- region.base = isc_buffer_used(&st);
- region.length = length;
- dns_rdata_fromregion(rdata, rdclass, type, &region);
- }
- if (result != ISC_R_SUCCESS) {
- *target = st;
- }
- return (result);
-}
-
-static isc_result_t
-unknown_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx,
- isc_buffer_t *target)
-{
- isc_result_t result;
- char buf[sizeof("65535")];
- isc_region_t sr;
-
- strlcpy(buf, "\\# ", sizeof(buf));
- result = str_totext(buf, target);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- dns_rdata_toregion(rdata, &sr);
- INSIST(sr.length < 65536);
- snprintf(buf, sizeof(buf), "%u", sr.length);
- result = str_totext(buf, target);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- if (sr.length != 0U) {
- if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
- result = str_totext(" ( ", target);
- else
- result = str_totext(" ", target);
-
- if (result != ISC_R_SUCCESS)
- return (result);
-
- if (tctx->width == 0) /* No splitting */
- result = isc_hex_totext(&sr, 0, "", target);
- else
- result = isc_hex_totext(&sr, tctx->width - 2,
- tctx->linebreak,
- target);
- if (result == ISC_R_SUCCESS &&
- (tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
- result = str_totext(" )", target);
- }
- return (result);
-}
-
-static isc_result_t
-rdata_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx,
- isc_buffer_t *target)
-{
- isc_result_t result = ISC_R_NOTIMPLEMENTED;
- isc_boolean_t use_default = ISC_FALSE;
-
- REQUIRE(rdata != NULL);
- REQUIRE(tctx->origin == NULL ||
- dns_name_isabsolute(tctx->origin) == ISC_TRUE);
-
- /*
- * Some DynDNS meta-RRs have empty rdata.
- */
- if ((rdata->flags & DNS_RDATA_UPDATE) != 0) {
- INSIST(rdata->length == 0);
- return (ISC_R_SUCCESS);
- }
-
- TOTEXTSWITCH
-
- if (use_default)
- result = unknown_totext(rdata, tctx, target);
-
- return (result);
-}
-
-isc_result_t
-dns_rdata_totext(dns_rdata_t *rdata, dns_name_t *origin, isc_buffer_t *target)
-{
- dns_rdata_textctx_t tctx;
-
- REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
-
- /*
- * Set up formatting options for single-line output.
- */
- tctx.origin = origin;
- tctx.flags = 0;
- tctx.width = 60;
- tctx.linebreak = " ";
- return (rdata_totext(rdata, &tctx, target));
-}
-
-isc_result_t
-dns_rdata_tofmttext(dns_rdata_t *rdata, dns_name_t *origin,
- unsigned int flags, unsigned int width,
- unsigned int split_width, const char *linebreak,
- isc_buffer_t *target)
-{
- dns_rdata_textctx_t tctx;
-
- REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
-
- /*
- * Set up formatting options for formatted output.
- */
- tctx.origin = origin;
- tctx.flags = flags;
- if (split_width == 0xffffffff)
- tctx.width = width;
- else
- tctx.width = split_width;
-
- if ((flags & DNS_STYLEFLAG_MULTILINE) != 0)
- tctx.linebreak = linebreak;
- else {
- if (split_width == 0xffffffff)
- tctx.width = 60; /* Used for hex word length only. */
- tctx.linebreak = " ";
- }
- return (rdata_totext(rdata, &tctx, target));
-}
-
-isc_result_t
-dns_rdata_fromstruct(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
- dns_rdatatype_t type, void *source,
- isc_buffer_t *target)
-{
- isc_result_t result = ISC_R_NOTIMPLEMENTED;
- isc_buffer_t st;
- isc_region_t region;
- isc_boolean_t use_default = ISC_FALSE;
- size_t length;
-
- REQUIRE(source != NULL);
- if (rdata != NULL) {
- REQUIRE(DNS_RDATA_INITIALIZED(rdata));
- REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
- }
-
- st = *target;
-
- FROMSTRUCTSWITCH
-
- if (use_default)
- (void)NULL;
-
- length = isc_buffer_usedlength(target) - isc_buffer_usedlength(&st);
- if (result == ISC_R_SUCCESS && length > DNS_RDATA_MAXLENGTH)
- result = ISC_R_NOSPACE;
-
- if (rdata != NULL && result == ISC_R_SUCCESS) {
- region.base = isc_buffer_used(&st);
- region.length = length;
- dns_rdata_fromregion(rdata, rdclass, type, &region);
- }
- if (result != ISC_R_SUCCESS)
- *target = st;
- return (result);
-}
-
-isc_result_t
-dns_rdata_tostruct(dns_rdata_t *rdata, void *target, isc_mem_t *mctx) {
- isc_result_t result = ISC_R_NOTIMPLEMENTED;
- isc_boolean_t use_default = ISC_FALSE;
-
- REQUIRE(rdata != NULL);
- REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
-
- TOSTRUCTSWITCH
-
- if (use_default)
- (void)NULL;
-
- return (result);
-}
-
-void
-dns_rdata_freestruct(void *source) {
- dns_rdatacommon_t *common = source;
- REQUIRE(source != NULL);
-
- FREESTRUCTSWITCH
-}
-
-isc_result_t
-dns_rdata_additionaldata(dns_rdata_t *rdata, dns_additionaldatafunc_t add,
- void *arg)
-{
- isc_result_t result = ISC_R_NOTIMPLEMENTED;
- isc_boolean_t use_default = ISC_FALSE;
-
- /*
- * Call 'add' for each name and type from 'rdata' which is subject to
- * additional section processing.
- */
-
- REQUIRE(rdata != NULL);
- REQUIRE(add != NULL);
- REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
-
- ADDITIONALDATASWITCH
-
- /* No additional processing for unknown types */
- if (use_default)
- result = ISC_R_SUCCESS;
-
- return (result);
-}
-
-isc_result_t
-dns_rdata_digest(dns_rdata_t *rdata, dns_digestfunc_t digest, void *arg) {
- isc_result_t result = ISC_R_NOTIMPLEMENTED;
- isc_boolean_t use_default = ISC_FALSE;
- isc_region_t r;
-
- /*
- * Send 'rdata' in DNSSEC canonical form to 'digest'.
- */
-
- REQUIRE(rdata != NULL);
- REQUIRE(digest != NULL);
- REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
-
- DIGESTSWITCH
-
- if (use_default) {
- dns_rdata_toregion(rdata, &r);
- result = (digest)(arg, &r);
- }
-
- return (result);
-}
-
-isc_boolean_t
-dns_rdata_checkowner(dns_name_t *name, dns_rdataclass_t rdclass,
- dns_rdatatype_t type, isc_boolean_t wildcard)
-{
- isc_boolean_t result;
-
- CHECKOWNERSWITCH
- return (result);
-}
-
-isc_boolean_t
-dns_rdata_checknames(dns_rdata_t *rdata, dns_name_t *owner, dns_name_t *bad)
-{
- isc_boolean_t result;
-
- CHECKNAMESSWITCH
- return (result);
-}
-
-unsigned int
-dns_rdatatype_attributes(dns_rdatatype_t type)
-{
- RDATATYPE_ATTRIBUTE_SW
- if (type >= (dns_rdatatype_t)128 && type < (dns_rdatatype_t)255)
- return (DNS_RDATATYPEATTR_UNKNOWN | DNS_RDATATYPEATTR_META);
- return (DNS_RDATATYPEATTR_UNKNOWN);
-}
-
-isc_result_t
-dns_rdatatype_fromtext(dns_rdatatype_t *typep, isc_textregion_t *source) {
- unsigned int hash;
- unsigned int n;
- unsigned char a, b;
-
- n = source->length;
-
- if (n == 0)
- return (DNS_R_UNKNOWN);
-
- a = tolower((unsigned char)source->base[0]);
- b = tolower((unsigned char)source->base[n - 1]);
-
- hash = ((a + n) * b) % 256;
-
- /*
- * This switch block is inlined via \#define, and will use "return"
- * to return a result to the caller if it is a valid (known)
- * rdatatype name.
- */
- RDATATYPE_FROMTEXT_SW(hash, source->base, n, typep);
-
- if (source->length > 4 && source->length < (4 + sizeof("65000")) &&
- strncasecmp("type", source->base, 4) == 0) {
- char buf[sizeof("65000")];
- char *endp;
- unsigned int val;
-
- strncpy(buf, source->base + 4, source->length - 4);
- buf[source->length - 4] = '\0';
- val = strtoul(buf, &endp, 10);
- if (*endp == '\0' && val <= 0xffff) {
- *typep = (dns_rdatatype_t)val;
- return (ISC_R_SUCCESS);
- }
- }
-
- return (DNS_R_UNKNOWN);
-}
-
-isc_result_t
-dns_rdatatype_totext(dns_rdatatype_t type, isc_buffer_t *target) {
- char buf[sizeof("TYPE65535")];
-
- RDATATYPE_TOTEXT_SW
- snprintf(buf, sizeof(buf), "TYPE%u", type);
- return (str_totext(buf, target));
-}
-
-void
-dns_rdatatype_format(dns_rdatatype_t rdtype,
- char *array, unsigned int size)
-{
- isc_result_t result;
- isc_buffer_t buf;
-
- if (size == 0U)
- return;
-
- isc_buffer_init(&buf, array, size);
- result = dns_rdatatype_totext(rdtype, &buf);
- /*
- * Null terminate.
- */
- if (result == ISC_R_SUCCESS) {
- if (isc_buffer_availablelength(&buf) >= 1)
- isc_buffer_putuint8(&buf, 0);
- else
- result = ISC_R_NOSPACE;
- }
- if (result != ISC_R_SUCCESS)
- strlcpy(array, "<unknown>", size);
-}
-
-/*
- * Private function.
- */
-
-static unsigned int
-name_length(dns_name_t *name) {
- return (name->length);
-}
-
-static isc_result_t
-txt_totext(isc_region_t *source, isc_buffer_t *target) {
- unsigned int tl;
- unsigned int n;
- unsigned char *sp;
- char *tp;
- isc_region_t region;
-
- isc_buffer_availableregion(target, &region);
- sp = source->base;
- tp = (char *)region.base;
- tl = region.length;
-
- n = *sp++;
-
- REQUIRE(n + 1 <= source->length);
-
- if (tl < 1)
- return (ISC_R_NOSPACE);
- *tp++ = '"';
- tl--;
- while (n--) {
- if (*sp < 0x20 || *sp >= 0x7f) {
- if (tl < 4)
- return (ISC_R_NOSPACE);
- *tp++ = 0x5c;
- *tp++ = 0x30 + ((*sp / 100) % 10);
- *tp++ = 0x30 + ((*sp / 10) % 10);
- *tp++ = 0x30 + (*sp % 10);
- sp++;
- tl -= 4;
- continue;
- }
- /* double quote, semi-colon, backslash */
- if (*sp == 0x22 || *sp == 0x3b || *sp == 0x5c) {
- if (tl < 2)
- return (ISC_R_NOSPACE);
- *tp++ = '\\';
- tl--;
- }
- if (tl < 1)
- return (ISC_R_NOSPACE);
- *tp++ = *sp++;
- tl--;
- }
- if (tl < 1)
- return (ISC_R_NOSPACE);
- *tp++ = '"';
- tl--;
- isc_buffer_add(target, tp - (char *)region.base);
- isc_region_consume(source, *source->base + 1);
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-txt_fromtext(isc_textregion_t *source, isc_buffer_t *target) {
- isc_region_t tregion;
- isc_boolean_t escape;
- unsigned int n, nrem;
- char *s;
- unsigned char *t;
- int d;
- int c;
-
- isc_buffer_availableregion(target, &tregion);
- s = source->base;
- n = source->length;
- t = tregion.base;
- nrem = tregion.length;
- escape = ISC_FALSE;
- if (nrem < 1)
- return (ISC_R_NOSPACE);
- /*
- * Length byte.
- */
- nrem--;
- t++;
- /*
- * Maximum text string length.
- */
- if (nrem > 255)
- nrem = 255;
- while (n-- != 0) {
- c = (*s++) & 0xff;
- if (escape && (d = decvalue((char)c)) != -1) {
- c = d;
- if (n == 0)
- return (DNS_R_SYNTAX);
- n--;
- if ((d = decvalue(*s++)) != -1)
- c = c * 10 + d;
- else
- return (DNS_R_SYNTAX);
- if (n == 0)
- return (DNS_R_SYNTAX);
- n--;
- if ((d = decvalue(*s++)) != -1)
- c = c * 10 + d;
- else
- return (DNS_R_SYNTAX);
- if (c > 255)
- return (DNS_R_SYNTAX);
- } else if (!escape && c == '\\') {
- escape = ISC_TRUE;
- continue;
- }
- escape = ISC_FALSE;
- if (nrem == 0)
- return ((tregion.length <= 256U) ?
- ISC_R_NOSPACE : DNS_R_SYNTAX);
- *t++ = c;
- nrem--;
- }
- if (escape)
- return (DNS_R_SYNTAX);
- *tregion.base = t - tregion.base - 1;
- isc_buffer_add(target, *tregion.base + 1);
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-txt_fromwire(isc_buffer_t *source, isc_buffer_t *target) {
- unsigned int n;
- isc_region_t sregion;
- isc_region_t tregion;
-
- isc_buffer_activeregion(source, &sregion);
- if (sregion.length == 0)
- return(ISC_R_UNEXPECTEDEND);
- n = *sregion.base + 1;
- if (n > sregion.length)
- return (ISC_R_UNEXPECTEDEND);
-
- isc_buffer_availableregion(target, &tregion);
- if (n > tregion.length)
- return (ISC_R_NOSPACE);
-
- if (tregion.base != sregion.base)
- memcpy(tregion.base, sregion.base, n);
- isc_buffer_forward(source, n);
- isc_buffer_add(target, n);
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-multitxt_totext(isc_region_t *source, isc_buffer_t *target) {
- unsigned int tl;
- unsigned int n0, n;
- unsigned char *sp;
- char *tp;
- isc_region_t region;
-
- isc_buffer_availableregion(target, &region);
- sp = source->base;
- tp = (char *)region.base;
- tl = region.length;
-
- if (tl < 1)
- return (ISC_R_NOSPACE);
- *tp++ = '"';
- tl--;
- do {
- n0 = n = *sp++;
-
- REQUIRE(n0 + 1 <= source->length);
-
- while (n--) {
- if (*sp < 0x20 || *sp >= 0x7f) {
- if (tl < 4)
- return (ISC_R_NOSPACE);
- *tp++ = 0x5c;
- *tp++ = 0x30 + ((*sp / 100) % 10);
- *tp++ = 0x30 + ((*sp / 10) % 10);
- *tp++ = 0x30 + (*sp % 10);
- sp++;
- tl -= 4;
- continue;
- }
- /* double quote, semi-colon, backslash */
- if (*sp == 0x22 || *sp == 0x3b || *sp == 0x5c) {
- if (tl < 2)
- return (ISC_R_NOSPACE);
- *tp++ = '\\';
- tl--;
- }
- if (tl < 1)
- return (ISC_R_NOSPACE);
- *tp++ = *sp++;
- tl--;
- }
- isc_region_consume(source, n0 + 1);
- } while (source->length != 0);
- if (tl < 1)
- return (ISC_R_NOSPACE);
- *tp++ = '"';
- tl--;
- isc_buffer_add(target, tp - (char *)region.base);
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-multitxt_fromtext(isc_textregion_t *source, isc_buffer_t *target) {
- isc_region_t tregion;
- isc_boolean_t escape;
- unsigned int n, nrem;
- char *s;
- unsigned char *t0, *t;
- int d;
- int c;
-
- s = source->base;
- n = source->length;
- escape = ISC_FALSE;
-
- do {
- isc_buffer_availableregion(target, &tregion);
- t0 = tregion.base;
- nrem = tregion.length;
- if (nrem < 1)
- return (ISC_R_NOSPACE);
- /* length byte */
- t = t0;
- nrem--;
- t++;
- /* 255 byte character-string slice */
- if (nrem > 255)
- nrem = 255;
- while (n != 0) {
- --n;
- c = (*s++) & 0xff;
- if (escape && (d = decvalue((char)c)) != -1) {
- c = d;
- if (n == 0)
- return (DNS_R_SYNTAX);
- n--;
- if ((d = decvalue(*s++)) != -1)
- c = c * 10 + d;
- else
- return (DNS_R_SYNTAX);
- if (n == 0)
- return (DNS_R_SYNTAX);
- n--;
- if ((d = decvalue(*s++)) != -1)
- c = c * 10 + d;
- else
- return (DNS_R_SYNTAX);
- if (c > 255)
- return (DNS_R_SYNTAX);
- } else if (!escape && c == '\\') {
- escape = ISC_TRUE;
- continue;
- }
- escape = ISC_FALSE;
- *t++ = c;
- nrem--;
- if (nrem == 0)
- break;
- }
- if (escape)
- return (DNS_R_SYNTAX);
- *t0 = t - t0 - 1;
- isc_buffer_add(target, *t0 + 1);
- } while (n != 0);
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-multitxt_fromwire(isc_buffer_t *source, isc_buffer_t *target) {
- unsigned int n;
- isc_region_t sregion;
- isc_region_t tregion;
-
- isc_buffer_activeregion(source, &sregion);
- if (sregion.length == 0)
- return(ISC_R_UNEXPECTEDEND);
- n = 256U;
- do {
- if (n != 256U)
- return (DNS_R_SYNTAX);
- n = *sregion.base + 1;
- if (n > sregion.length)
- return (ISC_R_UNEXPECTEDEND);
-
- isc_buffer_availableregion(target, &tregion);
- if (n > tregion.length)
- return (ISC_R_NOSPACE);
-
- if (tregion.base != sregion.base)
- memcpy(tregion.base, sregion.base, n);
- isc_buffer_forward(source, n);
- isc_buffer_add(target, n);
- isc_buffer_activeregion(source, &sregion);
- } while (sregion.length != 0);
- return (ISC_R_SUCCESS);
-}
-
-static isc_boolean_t
-name_prefix(dns_name_t *name, dns_name_t *origin, dns_name_t *target) {
- int l1, l2;
-
- if (origin == NULL)
- goto return_false;
-
- if (dns_name_compare(origin, dns_rootname) == 0)
- goto return_false;
-
- if (!dns_name_issubdomain(name, origin))
- goto return_false;
-
- l1 = dns_name_countlabels(name);
- l2 = dns_name_countlabels(origin);
-
- if (l1 == l2)
- goto return_false;
-
- /* Master files should be case preserving. */
- dns_name_getlabelsequence(name, l1 - l2, l2, target);
- if (!dns_name_caseequal(origin, target))
- goto return_false;
-
- dns_name_getlabelsequence(name, 0, l1 - l2, target);
- return (ISC_TRUE);
-
-return_false:
- *target = *name;
- return (ISC_FALSE);
-}
-
-static isc_result_t
-str_totext(const char *source, isc_buffer_t *target) {
- unsigned int l;
- isc_region_t region;
-
- isc_buffer_availableregion(target, &region);
- l = strlen(source);
-
- if (l > region.length)
- return (ISC_R_NOSPACE);
-
- memcpy(region.base, source, l);
- isc_buffer_add(target, l);
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-inet_totext(int af, isc_region_t *src, isc_buffer_t *target) {
- char tmpbuf[64];
-
- /* Note - inet_ntop doesn't do size checking on its input. */
- if (inet_ntop(af, src->base, tmpbuf, sizeof(tmpbuf)) == NULL)
- return (ISC_R_NOSPACE);
- if (strlen(tmpbuf) > isc_buffer_availablelength(target))
- return (ISC_R_NOSPACE);
- isc_buffer_putstr(target, tmpbuf);
- return (ISC_R_SUCCESS);
-}
-
-static isc_boolean_t
-buffer_empty(isc_buffer_t *source) {
- return((source->current == source->active) ? ISC_TRUE : ISC_FALSE);
-}
-
-static void
-buffer_fromregion(isc_buffer_t *buffer, isc_region_t *region) {
- isc_buffer_init(buffer, region->base, region->length);
- isc_buffer_add(buffer, region->length);
- isc_buffer_setactive(buffer, region->length);
-}
-
-static isc_result_t
-uint32_tobuffer(isc_uint32_t value, isc_buffer_t *target) {
- isc_region_t region;
-
- isc_buffer_availableregion(target, &region);
- if (region.length < 4)
- return (ISC_R_NOSPACE);
- isc_buffer_putuint32(target, value);
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-uint16_tobuffer(isc_uint32_t value, isc_buffer_t *target) {
- isc_region_t region;
-
- if (value > 0xffff)
- return (ISC_R_RANGE);
- isc_buffer_availableregion(target, &region);
- if (region.length < 2)
- return (ISC_R_NOSPACE);
- isc_buffer_putuint16(target, (isc_uint16_t)value);
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-uint8_tobuffer(isc_uint32_t value, isc_buffer_t *target) {
- isc_region_t region;
-
- if (value > 0xff)
- return (ISC_R_RANGE);
- isc_buffer_availableregion(target, &region);
- if (region.length < 1)
- return (ISC_R_NOSPACE);
- isc_buffer_putuint8(target, (isc_uint8_t)value);
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-name_tobuffer(dns_name_t *name, isc_buffer_t *target) {
- isc_region_t r;
- dns_name_toregion(name, &r);
- return (isc_buffer_copyregion(target, &r));
-}
-
-static isc_uint32_t
-uint32_fromregion(isc_region_t *region) {
- isc_uint32_t value;
-
- REQUIRE(region->length >= 4);
- value = region->base[0] << 24;
- value |= region->base[1] << 16;
- value |= region->base[2] << 8;
- value |= region->base[3];
- return(value);
-}
-
-static isc_uint16_t
-uint16_consume_fromregion(isc_region_t *region) {
- isc_uint16_t r = uint16_fromregion(region);
-
- isc_region_consume(region, 2);
- return r;
-}
-
-static isc_uint16_t
-uint16_fromregion(isc_region_t *region) {
-
- REQUIRE(region->length >= 2);
-
- return ((region->base[0] << 8) | region->base[1]);
-}
-
-static isc_uint8_t
-uint8_fromregion(isc_region_t *region) {
-
- REQUIRE(region->length >= 1);
-
- return (region->base[0]);
-}
-
-static isc_uint8_t
-uint8_consume_fromregion(isc_region_t *region) {
- isc_uint8_t r = uint8_fromregion(region);
-
- isc_region_consume(region, 1);
- return r;
-}
-
-static isc_result_t
-mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length) {
- isc_region_t tr;
-
- isc_buffer_availableregion(target, &tr);
- if (length > tr.length)
- return (ISC_R_NOSPACE);
- if (tr.base != base)
- memcpy(tr.base, base, length);
- isc_buffer_add(target, length);
- return (ISC_R_SUCCESS);
-}
-
-static int
-hexvalue(char value) {
- char *s;
- unsigned char c;
-
- c = (unsigned char)value;
-
- if (!isascii(c))
- return (-1);
- if (isupper(c))
- c = tolower(c);
- if ((s = strchr(hexdigits, c)) == NULL)
- return (-1);
- return (s - hexdigits);
-}
-
-static int
-decvalue(char value) {
- char *s;
-
- /*
- * isascii() is valid for full range of int values, no need to
- * mask or cast.
- */
- if (!isascii(value))
- return (-1);
- if ((s = strchr(decdigits, value)) == NULL)
- return (-1);
- return (s - decdigits);
-}
-
-static const char atob_digits[86] =
- "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`" \
- "abcdefghijklmnopqrstu";
-/*
- * Subroutines to convert between 8 bit binary bytes and printable ASCII.
- * Computes the number of bytes, and three kinds of simple checksums.
- * Incoming bytes are collected into 32-bit words, then printed in base 85:
- * exp(85,5) > exp(2,32)
- * The ASCII characters used are between '!' and 'u';
- * 'z' encodes 32-bit zero; 'x' is used to mark the end of encoded data.
- *
- * Originally by Paul Rutter (philabs!per) and Joe Orost (petsd!joe) for
- * the atob/btoa programs, released with the compress program, in mod.sources.
- * Modified by Mike Schwartz 8/19/86 for use in BIND.
- * Modified to be re-entrant 3/2/99.
- */
-
-
-struct state {
- isc_int32_t Ceor;
- isc_int32_t Csum;
- isc_int32_t Crot;
- isc_int32_t word;
- isc_int32_t bcount;
-};
-
-#define Ceor state->Ceor
-#define Csum state->Csum
-#define Crot state->Crot
-#define word state->word
-#define bcount state->bcount
-
-#define times85(x) ((((((x<<2)+x)<<2)+x)<<2)+x)
-
-static isc_result_t byte_atob(int c, isc_buffer_t *target,
- struct state *state);
-static isc_result_t putbyte(int c, isc_buffer_t *, struct state *state);
-static isc_result_t byte_btoa(int c, isc_buffer_t *, struct state *state);
-
-/*
- * Decode ASCII-encoded byte c into binary representation and
- * place into *bufp, advancing bufp.
- */
-static isc_result_t
-byte_atob(int c, isc_buffer_t *target, struct state *state) {
- char *s;
- if (c == 'z') {
- if (bcount != 0)
- return(DNS_R_SYNTAX);
- else {
- RETERR(putbyte(0, target, state));
- RETERR(putbyte(0, target, state));
- RETERR(putbyte(0, target, state));
- RETERR(putbyte(0, target, state));
- }
- } else if ((s = strchr(atob_digits, c)) != NULL) {
- if (bcount == 0) {
- word = s - atob_digits;
- ++bcount;
- } else if (bcount < 4) {
- word = times85(word);
- word += s - atob_digits;
- ++bcount;
- } else {
- word = times85(word);
- word += s - atob_digits;
- RETERR(putbyte((word >> 24) & 0xff, target, state));
- RETERR(putbyte((word >> 16) & 0xff, target, state));
- RETERR(putbyte((word >> 8) & 0xff, target, state));
- RETERR(putbyte(word & 0xff, target, state));
- word = 0;
- bcount = 0;
- }
- } else
- return(DNS_R_SYNTAX);
- return(ISC_R_SUCCESS);
-}
-
-/*
- * Compute checksum info and place c into target.
- */
-static isc_result_t
-putbyte(int c, isc_buffer_t *target, struct state *state) {
- isc_region_t tr;
-
- Ceor ^= c;
- Csum += c;
- Csum += 1;
- if ((Crot & 0x80000000)) {
- Crot <<= 1;
- Crot += 1;
- } else {
- Crot <<= 1;
- }
- Crot += c;
- isc_buffer_availableregion(target, &tr);
- if (tr.length < 1)
- return (ISC_R_NOSPACE);
- tr.base[0] = c;
- isc_buffer_add(target, 1);
- return (ISC_R_SUCCESS);
-}
-
-/*
- * Read the ASCII-encoded data from inbuf, of length inbuflen, and convert
- * it into T_UNSPEC (binary data) in outbuf, not to exceed outbuflen bytes;
- * outbuflen must be divisible by 4. (Note: this is because outbuf is filled
- * in 4 bytes at a time. If the actual data doesn't end on an even 4-byte
- * boundary, there will be no problem...it will be padded with 0 bytes, and
- * numbytes will indicate the correct number of bytes. The main point is
- * that since the buffer is filled in 4 bytes at a time, even if there is
- * not a full 4 bytes of data at the end, there has to be room to 0-pad the
- * data, so the buffer must be of size divisible by 4). Place the number of
- * output bytes in numbytes, and return a failure/success status.
- */
-
-static isc_result_t
-atob_tobuffer(isc_lex_t *lexer, isc_buffer_t *target) {
- long oeor, osum, orot;
- struct state statebuf, *state= &statebuf;
- isc_token_t token;
- char c;
- char *e;
-
- Ceor = Csum = Crot = word = bcount = 0;
-
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- while (token.value.as_textregion.length != 0) {
- if ((c = token.value.as_textregion.base[0]) == 'x') {
- break;
- } else
- RETERR(byte_atob(c, target, state));
- isc_textregion_consume(&token.value.as_textregion, 1);
- }
-
- /*
- * Number of bytes.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if ((token.value.as_ulong % 4) != 0U)
- isc_buffer_subtract(target, 4 - (token.value.as_ulong % 4));
-
- /*
- * Checksum.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- oeor = strtol(DNS_AS_STR(token), &e, 16);
- if (*e != 0)
- return (DNS_R_SYNTAX);
-
- /*
- * Checksum.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- osum = strtol(DNS_AS_STR(token), &e, 16);
- if (*e != 0)
- return (DNS_R_SYNTAX);
-
- /*
- * Checksum.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- orot = strtol(DNS_AS_STR(token), &e, 16);
- if (*e != 0)
- return (DNS_R_SYNTAX);
-
- if ((oeor != Ceor) || (osum != Csum) || (orot != Crot))
- return(DNS_R_BADCKSUM);
- return (ISC_R_SUCCESS);
-}
-
-/*
- * Encode binary byte c into ASCII representation and place into *bufp,
- * advancing bufp.
- */
-static isc_result_t
-byte_btoa(int c, isc_buffer_t *target, struct state *state) {
- isc_region_t tr;
-
- isc_buffer_availableregion(target, &tr);
- Ceor ^= c;
- Csum += c;
- Csum += 1;
- if ((Crot & 0x80000000)) {
- Crot <<= 1;
- Crot += 1;
- } else {
- Crot <<= 1;
- }
- Crot += c;
-
- word <<= 8;
- word |= c;
- if (bcount == 3) {
- if (word == 0) {
- if (tr.length < 1)
- return (ISC_R_NOSPACE);
- tr.base[0] = 'z';
- isc_buffer_add(target, 1);
- } else {
- register int tmp = 0;
- register isc_int32_t tmpword = word;
-
- if (tmpword < 0) {
- /*
- * Because some don't support u_long.
- */
- tmp = 32;
- tmpword -= (isc_int32_t)(85 * 85 * 85 * 85 * 32);
- }
- if (tmpword < 0) {
- tmp = 64;
- tmpword -= (isc_int32_t)(85 * 85 * 85 * 85 * 32);
- }
- if (tr.length < 5)
- return (ISC_R_NOSPACE);
- tr.base[0] = atob_digits[(tmpword /
- (isc_int32_t)(85 * 85 * 85 * 85))
- + tmp];
- tmpword %= (isc_int32_t)(85 * 85 * 85 * 85);
- tr.base[1] = atob_digits[tmpword / (85 * 85 * 85)];
- tmpword %= (85 * 85 * 85);
- tr.base[2] = atob_digits[tmpword / (85 * 85)];
- tmpword %= (85 * 85);
- tr.base[3] = atob_digits[tmpword / 85];
- tmpword %= 85;
- tr.base[4] = atob_digits[tmpword];
- isc_buffer_add(target, 5);
- }
- bcount = 0;
- } else {
- bcount += 1;
- }
- return (ISC_R_SUCCESS);
-}
-
-
-/*
- * Encode the binary data from inbuf, of length inbuflen, into a
- * target. Return success/failure status
- */
-static isc_result_t
-btoa_totext(unsigned char *inbuf, int inbuflen, isc_buffer_t *target) {
- int inc;
- struct state statebuf, *state = &statebuf;
- char buf[sizeof("x 2000000000 ffffffff ffffffff ffffffff")];
-
- Ceor = Csum = Crot = word = bcount = 0;
- for (inc = 0; inc < inbuflen; inbuf++, inc++)
- RETERR(byte_btoa(*inbuf, target, state));
-
- while (bcount != 0)
- RETERR(byte_btoa(0, target, state));
-
- /*
- * Put byte count and checksum information at end of buffer,
- * delimited by 'x'
- */
- snprintf(buf, sizeof(buf), "x %d %x %x %x", inbuflen, Ceor, Csum, Crot);
- return (str_totext(buf, target));
-}
-
-
-static void
-default_fromtext_callback(dns_rdatacallbacks_t *callbacks, const char *fmt,
- ...)
-{
- va_list ap;
-
- UNUSED(callbacks);
-
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
- fprintf(stderr, "\n");
-}
-
-static void
-fromtext_warneof(isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks) {
- if (isc_lex_isfile(lexer) && callbacks != NULL) {
- const char *name = isc_lex_getsourcename(lexer);
- if (name == NULL)
- name = "UNKNOWN";
- (*callbacks->warn)(callbacks,
- "%s:%lu: file does not end with newline",
- name, isc_lex_getsourceline(lexer));
- }
-}
-
-static void
-warn_badmx(isc_token_t *token, isc_lex_t *lexer,
- dns_rdatacallbacks_t *callbacks)
-{
- const char *file;
- unsigned long line;
-
- if (lexer != NULL) {
- file = isc_lex_getsourcename(lexer);
- line = isc_lex_getsourceline(lexer);
- (*callbacks->warn)(callbacks, "%s:%u: warning: '%s': %s",
- file, line, DNS_AS_STR(*token),
- dns_result_totext(DNS_R_MXISADDRESS));
- }
-}
-
-static void
-warn_badname(dns_name_t *name, isc_lex_t *lexer,
- dns_rdatacallbacks_t *callbacks)
-{
- const char *file;
- unsigned long line;
- char namebuf[DNS_NAME_FORMATSIZE];
-
- if (lexer != NULL) {
- file = isc_lex_getsourcename(lexer);
- line = isc_lex_getsourceline(lexer);
- dns_name_format(name, namebuf, sizeof(namebuf));
- (*callbacks->warn)(callbacks, "%s:%u: warning: %s: %s",
- file, line, namebuf,
- dns_result_totext(DNS_R_BADNAME));
- }
-}
-
-static void
-fromtext_error(void (*callback)(dns_rdatacallbacks_t *, const char *, ...),
- dns_rdatacallbacks_t *callbacks, const char *name,
- unsigned long line, isc_token_t *token, isc_result_t result)
-{
- if (name == NULL)
- name = "UNKNOWN";
-
- if (token != NULL) {
- switch (token->type) {
- case isc_tokentype_eol:
- (*callback)(callbacks, "%s: %s:%lu: near eol: %s",
- "dns_rdata_fromtext", name, line,
- dns_result_totext(result));
- break;
- case isc_tokentype_eof:
- (*callback)(callbacks, "%s: %s:%lu: near eof: %s",
- "dns_rdata_fromtext", name, line,
- dns_result_totext(result));
- break;
- case isc_tokentype_number:
- (*callback)(callbacks, "%s: %s:%lu: near %lu: %s",
- "dns_rdata_fromtext", name, line,
- token->value.as_ulong,
- dns_result_totext(result));
- break;
- case isc_tokentype_string:
- case isc_tokentype_qstring:
- (*callback)(callbacks, "%s: %s:%lu: near '%s': %s",
- "dns_rdata_fromtext", name, line,
- DNS_AS_STR(*token),
- dns_result_totext(result));
- break;
- default:
- (*callback)(callbacks, "%s: %s:%lu: %s",
- "dns_rdata_fromtext", name, line,
- dns_result_totext(result));
- break;
- }
- } else {
- (*callback)(callbacks, "dns_rdata_fromtext: %s:%lu: %s",
- name, line, dns_result_totext(result));
- }
-}
-
-dns_rdatatype_t
-dns_rdata_covers(dns_rdata_t *rdata) {
- if (rdata->type == 46)
- return (covers_rrsig(rdata));
- return (covers_sig(rdata));
-}
-
-isc_boolean_t
-dns_rdatatype_ismeta(dns_rdatatype_t type) {
- if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_META) != 0)
- return (ISC_TRUE);
- return (ISC_FALSE);
-}
-
-isc_boolean_t
-dns_rdatatype_issingleton(dns_rdatatype_t type) {
- if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_SINGLETON)
- != 0)
- return (ISC_TRUE);
- return (ISC_FALSE);
-}
-
-isc_boolean_t
-dns_rdatatype_notquestion(dns_rdatatype_t type) {
- if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_NOTQUESTION)
- != 0)
- return (ISC_TRUE);
- return (ISC_FALSE);
-}
-
-isc_boolean_t
-dns_rdatatype_questiononly(dns_rdatatype_t type) {
- if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_QUESTIONONLY)
- != 0)
- return (ISC_TRUE);
- return (ISC_FALSE);
-}
-
-isc_boolean_t
-dns_rdatatype_atparent(dns_rdatatype_t type) {
- if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_ATPARENT) != 0)
- return (ISC_TRUE);
- return (ISC_FALSE);
-}
-
-isc_boolean_t
-dns_rdataclass_ismeta(dns_rdataclass_t rdclass) {
-
- if (rdclass == dns_rdataclass_reserved0
- || rdclass == dns_rdataclass_none
- || rdclass == dns_rdataclass_any)
- return (ISC_TRUE);
-
- return (ISC_FALSE); /* Assume it is not a meta class. */
-}
-
-isc_boolean_t
-dns_rdatatype_isdnssec(dns_rdatatype_t type) {
- if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_DNSSEC) != 0)
- return (ISC_TRUE);
- return (ISC_FALSE);
-}
-
-isc_boolean_t
-dns_rdatatype_iszonecutauth(dns_rdatatype_t type) {
- if ((dns_rdatatype_attributes(type)
- & (DNS_RDATATYPEATTR_DNSSEC | DNS_RDATATYPEATTR_ZONECUTAUTH))
- != 0)
- return (ISC_TRUE);
- return (ISC_FALSE);
-}
-
-isc_boolean_t
-dns_rdatatype_isknown(dns_rdatatype_t type) {
- if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_UNKNOWN)
- == 0)
- 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/contrib/bind9/lib/dns/rdata/any_255/tsig_250.c b/contrib/bind9/lib/dns/rdata/any_255/tsig_250.c
deleted file mode 100644
index 3f91f91c009a..000000000000
--- a/contrib/bind9/lib/dns/rdata/any_255/tsig_250.c
+++ /dev/null
@@ -1,603 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/* Reviewed: Thu Mar 16 13:39:43 PST 2000 by gson */
-
-#ifndef RDATA_ANY_255_TSIG_250_C
-#define RDATA_ANY_255_TSIG_250_C
-
-#define RRTYPE_TSIG_ATTRIBUTES \
- (DNS_RDATATYPEATTR_META | DNS_RDATATYPEATTR_NOTQUESTION)
-
-static inline isc_result_t
-fromtext_any_tsig(ARGS_FROMTEXT) {
- isc_token_t token;
- dns_name_t name;
- isc_uint64_t sigtime;
- isc_buffer_t buffer;
- dns_rcode_t rcode;
- long i;
- char *e;
-
- REQUIRE(type == 250);
- REQUIRE(rdclass == 255);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(callbacks);
-
- /*
- * Algorithm Name.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- dns_name_init(&name, NULL);
- buffer_fromregion(&buffer, &token.value.as_region);
- origin = (origin != NULL) ? origin : dns_rootname;
- RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
-
- /*
- * Time Signed: 48 bits.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- sigtime = isc_string_touint64(DNS_AS_STR(token), &e, 10);
- if (*e != 0)
- RETTOK(DNS_R_SYNTAX);
- if ((sigtime >> 48) != 0)
- RETTOK(ISC_R_RANGE);
- RETERR(uint16_tobuffer((isc_uint16_t)(sigtime >> 32), target));
- RETERR(uint32_tobuffer((isc_uint32_t)(sigtime & 0xffffffffU), target));
-
- /*
- * Fudge.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if (token.value.as_ulong > 0xffffU)
- RETTOK(ISC_R_RANGE);
- RETERR(uint16_tobuffer(token.value.as_ulong, target));
-
- /*
- * Signature Size.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if (token.value.as_ulong > 0xffffU)
- RETTOK(ISC_R_RANGE);
- RETERR(uint16_tobuffer(token.value.as_ulong, target));
-
- /*
- * Signature.
- */
- RETERR(isc_base64_tobuffer(lexer, target, (int)token.value.as_ulong));
-
- /*
- * Original ID.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if (token.value.as_ulong > 0xffffU)
- RETTOK(ISC_R_RANGE);
- RETERR(uint16_tobuffer(token.value.as_ulong, target));
-
- /*
- * Error.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- if (dns_tsigrcode_fromtext(&rcode, &token.value.as_textregion)
- != ISC_R_SUCCESS)
- {
- i = strtol(DNS_AS_STR(token), &e, 10);
- if (*e != 0)
- RETTOK(DNS_R_UNKNOWN);
- if (i < 0 || i > 0xffff)
- RETTOK(ISC_R_RANGE);
- rcode = (dns_rcode_t)i;
- }
- RETERR(uint16_tobuffer(rcode, target));
-
- /*
- * Other Len.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if (token.value.as_ulong > 0xffffU)
- RETTOK(ISC_R_RANGE);
- RETERR(uint16_tobuffer(token.value.as_ulong, target));
-
- /*
- * Other Data.
- */
- return (isc_base64_tobuffer(lexer, target, (int)token.value.as_ulong));
-}
-
-static inline isc_result_t
-totext_any_tsig(ARGS_TOTEXT) {
- isc_region_t sr;
- isc_region_t sigr;
- char buf[sizeof(" 281474976710655 ")];
- char *bufp;
- dns_name_t name;
- dns_name_t prefix;
- isc_boolean_t sub;
- isc_uint64_t sigtime;
- unsigned short n;
-
- REQUIRE(rdata->type == 250);
- REQUIRE(rdata->rdclass == 255);
- REQUIRE(rdata->length != 0);
-
- dns_rdata_toregion(rdata, &sr);
- /*
- * Algorithm Name.
- */
- dns_name_init(&name, NULL);
- dns_name_init(&prefix, NULL);
- dns_name_fromregion(&name, &sr);
- sub = name_prefix(&name, tctx->origin, &prefix);
- RETERR(dns_name_totext(&prefix, sub, target));
- RETERR(str_totext(" ", target));
- isc_region_consume(&sr, name_length(&name));
-
- /*
- * Time Signed.
- */
- sigtime = ((isc_uint64_t)sr.base[0] << 40) |
- ((isc_uint64_t)sr.base[1] << 32) |
- ((isc_uint64_t)sr.base[2] << 24) |
- ((isc_uint64_t)sr.base[3] << 16) |
- ((isc_uint64_t)sr.base[4] << 8) |
- (isc_uint64_t)sr.base[5];
- isc_region_consume(&sr, 6);
- bufp = &buf[sizeof(buf) - 1];
- *bufp-- = 0;
- *bufp-- = ' ';
- do {
- *bufp-- = decdigits[sigtime % 10];
- sigtime /= 10;
- } while (sigtime != 0);
- bufp++;
- RETERR(str_totext(bufp, target));
-
- /*
- * Fudge.
- */
- n = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
- sprintf(buf, "%u ", n);
- RETERR(str_totext(buf, target));
-
- /*
- * Signature Size.
- */
- n = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
- sprintf(buf, "%u", n);
- RETERR(str_totext(buf, target));
-
- /*
- * Signature.
- */
- REQUIRE(n <= sr.length);
- sigr = sr;
- sigr.length = n;
- if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
- RETERR(str_totext(" (", target));
- RETERR(str_totext(tctx->linebreak, target));
- if (tctx->width == 0) /* No splitting */
- RETERR(isc_base64_totext(&sigr, 60, "", target));
- else
- RETERR(isc_base64_totext(&sigr, tctx->width - 2,
- tctx->linebreak, target));
- if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
- RETERR(str_totext(" ) ", target));
- else
- RETERR(str_totext(" ", target));
- isc_region_consume(&sr, n);
-
- /*
- * Original ID.
- */
- n = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
- sprintf(buf, "%u ", n);
- RETERR(str_totext(buf, target));
-
- /*
- * Error.
- */
- n = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
- RETERR(dns_tsigrcode_totext((dns_rcode_t)n, target));
-
- /*
- * Other Size.
- */
- n = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
- sprintf(buf, " %u ", n);
- RETERR(str_totext(buf, target));
-
- /*
- * Other.
- */
- if (tctx->width == 0) /* No splitting */
- return (isc_base64_totext(&sr, 60, "", target));
- else
- return (isc_base64_totext(&sr, 60, " ", target));
-}
-
-static inline isc_result_t
-fromwire_any_tsig(ARGS_FROMWIRE) {
- isc_region_t sr;
- dns_name_t name;
- unsigned long n;
-
- REQUIRE(type == 250);
- REQUIRE(rdclass == 255);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
-
- /*
- * Algorithm Name.
- */
- dns_name_init(&name, NULL);
- RETERR(dns_name_fromwire(&name, source, dctx, options, target));
-
- isc_buffer_activeregion(source, &sr);
- /*
- * Time Signed + Fudge.
- */
- if (sr.length < 8)
- return (ISC_R_UNEXPECTEDEND);
- RETERR(mem_tobuffer(target, sr.base, 8));
- isc_region_consume(&sr, 8);
- isc_buffer_forward(source, 8);
-
- /*
- * Signature Length + Signature.
- */
- if (sr.length < 2)
- return (ISC_R_UNEXPECTEDEND);
- n = uint16_fromregion(&sr);
- if (sr.length < n + 2)
- return (ISC_R_UNEXPECTEDEND);
- RETERR(mem_tobuffer(target, sr.base, n + 2));
- isc_region_consume(&sr, n + 2);
- isc_buffer_forward(source, n + 2);
-
- /*
- * Original ID + Error.
- */
- if (sr.length < 4)
- return (ISC_R_UNEXPECTEDEND);
- RETERR(mem_tobuffer(target, sr.base, 4));
- isc_region_consume(&sr, 4);
- isc_buffer_forward(source, 4);
-
- /*
- * Other Length + Other.
- */
- if (sr.length < 2)
- return (ISC_R_UNEXPECTEDEND);
- n = uint16_fromregion(&sr);
- if (sr.length < n + 2)
- return (ISC_R_UNEXPECTEDEND);
- isc_buffer_forward(source, n + 2);
- return (mem_tobuffer(target, sr.base, n + 2));
-}
-
-static inline isc_result_t
-towire_any_tsig(ARGS_TOWIRE) {
- isc_region_t sr;
- dns_name_t name;
- dns_offsets_t offsets;
-
- REQUIRE(rdata->type == 250);
- REQUIRE(rdata->rdclass == 255);
- REQUIRE(rdata->length != 0);
-
- dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
- dns_rdata_toregion(rdata, &sr);
- dns_name_init(&name, offsets);
- dns_name_fromregion(&name, &sr);
- RETERR(dns_name_towire(&name, cctx, target));
- isc_region_consume(&sr, name_length(&name));
- return (mem_tobuffer(target, sr.base, sr.length));
-}
-
-static inline int
-compare_any_tsig(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 == 250);
- REQUIRE(rdata1->rdclass == 255);
- REQUIRE(rdata1->length != 0);
- REQUIRE(rdata2->length != 0);
-
- dns_rdata_toregion(rdata1, &r1);
- dns_rdata_toregion(rdata2, &r2);
- dns_name_init(&name1, NULL);
- dns_name_init(&name2, NULL);
- 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));
-}
-
-static inline isc_result_t
-fromstruct_any_tsig(ARGS_FROMSTRUCT) {
- dns_rdata_any_tsig_t *tsig = source;
- isc_region_t tr;
-
- REQUIRE(type == 250);
- REQUIRE(rdclass == 255);
- REQUIRE(source != NULL);
- REQUIRE(tsig->common.rdclass == rdclass);
- REQUIRE(tsig->common.rdtype == type);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- /*
- * Algorithm Name.
- */
- RETERR(name_tobuffer(&tsig->algorithm, target));
-
- isc_buffer_availableregion(target, &tr);
- if (tr.length < 6 + 2 + 2)
- return (ISC_R_NOSPACE);
-
- /*
- * Time Signed: 48 bits.
- */
- RETERR(uint16_tobuffer((isc_uint16_t)(tsig->timesigned >> 32),
- target));
- RETERR(uint32_tobuffer((isc_uint32_t)(tsig->timesigned & 0xffffffffU),
- target));
-
- /*
- * Fudge.
- */
- RETERR(uint16_tobuffer(tsig->fudge, target));
-
- /*
- * Signature Size.
- */
- RETERR(uint16_tobuffer(tsig->siglen, target));
-
- /*
- * Signature.
- */
- RETERR(mem_tobuffer(target, tsig->signature, tsig->siglen));
-
- isc_buffer_availableregion(target, &tr);
- if (tr.length < 2 + 2 + 2)
- return (ISC_R_NOSPACE);
-
- /*
- * Original ID.
- */
- RETERR(uint16_tobuffer(tsig->originalid, target));
-
- /*
- * Error.
- */
- RETERR(uint16_tobuffer(tsig->error, target));
-
- /*
- * Other Len.
- */
- RETERR(uint16_tobuffer(tsig->otherlen, target));
-
- /*
- * Other Data.
- */
- return (mem_tobuffer(target, tsig->other, tsig->otherlen));
-}
-
-static inline isc_result_t
-tostruct_any_tsig(ARGS_TOSTRUCT) {
- dns_rdata_any_tsig_t *tsig;
- dns_name_t alg;
- isc_region_t sr;
-
- REQUIRE(rdata->type == 250);
- REQUIRE(rdata->rdclass == 255);
- REQUIRE(rdata->length != 0);
-
- tsig = (dns_rdata_any_tsig_t *) target;
- tsig->common.rdclass = rdata->rdclass;
- tsig->common.rdtype = rdata->type;
- ISC_LINK_INIT(&tsig->common, link);
-
- dns_rdata_toregion(rdata, &sr);
-
- /*
- * Algorithm Name.
- */
- dns_name_init(&alg, NULL);
- dns_name_fromregion(&alg, &sr);
- dns_name_init(&tsig->algorithm, NULL);
- RETERR(name_duporclone(&alg, mctx, &tsig->algorithm));
-
- isc_region_consume(&sr, name_length(&tsig->algorithm));
-
- /*
- * Time Signed.
- */
- INSIST(sr.length >= 6);
- tsig->timesigned = ((isc_uint64_t)sr.base[0] << 40) |
- ((isc_uint64_t)sr.base[1] << 32) |
- ((isc_uint64_t)sr.base[2] << 24) |
- ((isc_uint64_t)sr.base[3] << 16) |
- ((isc_uint64_t)sr.base[4] << 8) |
- (isc_uint64_t)sr.base[5];
- isc_region_consume(&sr, 6);
-
- /*
- * Fudge.
- */
- tsig->fudge = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
-
- /*
- * Signature Size.
- */
- tsig->siglen = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
-
- /*
- * Signature.
- */
- INSIST(sr.length >= tsig->siglen);
- tsig->signature = mem_maybedup(mctx, sr.base, tsig->siglen);
- if (tsig->signature == NULL)
- goto cleanup;
- isc_region_consume(&sr, tsig->siglen);
-
- /*
- * Original ID.
- */
- tsig->originalid = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
-
- /*
- * Error.
- */
- tsig->error = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
-
- /*
- * Other Size.
- */
- tsig->otherlen = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
-
- /*
- * Other.
- */
- INSIST(sr.length == tsig->otherlen);
- tsig->other = mem_maybedup(mctx, sr.base, tsig->otherlen);
- if (tsig->other == NULL)
- goto cleanup;
-
- tsig->mctx = mctx;
- return (ISC_R_SUCCESS);
-
- cleanup:
- if (mctx != NULL)
- dns_name_free(&tsig->algorithm, tsig->mctx);
- if (mctx != NULL && tsig->signature != NULL)
- isc_mem_free(mctx, tsig->signature);
- return (ISC_R_NOMEMORY);
-}
-
-static inline void
-freestruct_any_tsig(ARGS_FREESTRUCT) {
- dns_rdata_any_tsig_t *tsig = (dns_rdata_any_tsig_t *) source;
-
- REQUIRE(source != NULL);
- REQUIRE(tsig->common.rdclass == 255);
- REQUIRE(tsig->common.rdtype == 250);
-
- if (tsig->mctx == NULL)
- return;
-
- dns_name_free(&tsig->algorithm, tsig->mctx);
- if (tsig->signature != NULL)
- isc_mem_free(tsig->mctx, tsig->signature);
- if (tsig->other != NULL)
- isc_mem_free(tsig->mctx, tsig->other);
- tsig->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_any_tsig(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 250);
- REQUIRE(rdata->rdclass == 255);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_any_tsig(ARGS_DIGEST) {
-
- REQUIRE(rdata->type == 250);
- REQUIRE(rdata->rdclass == 255);
-
- UNUSED(rdata);
- UNUSED(digest);
- UNUSED(arg);
-
- return (ISC_R_NOTIMPLEMENTED);
-}
-
-static inline isc_boolean_t
-checkowner_any_tsig(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 250);
- REQUIRE(rdclass == 255);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_any_tsig(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 250);
- REQUIRE(rdata->rdclass == 250);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- 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/contrib/bind9/lib/dns/rdata/any_255/tsig_250.h b/contrib/bind9/lib/dns/rdata/any_255/tsig_250.h
deleted file mode 100644
index 0c016676b065..000000000000
--- a/contrib/bind9/lib/dns/rdata/any_255/tsig_250.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: tsig_250.h,v 1.25 2007/06/19 23:47:17 tbox Exp $ */
-
-#ifndef ANY_255_TSIG_250_H
-#define ANY_255_TSIG_250_H 1
-
-/*% RFC2845 */
-typedef struct dns_rdata_any_tsig {
- dns_rdatacommon_t common;
- isc_mem_t * mctx;
- dns_name_t algorithm;
- isc_uint64_t timesigned;
- isc_uint16_t fudge;
- isc_uint16_t siglen;
- unsigned char * signature;
- isc_uint16_t originalid;
- isc_uint16_t error;
- isc_uint16_t otherlen;
- unsigned char * other;
-} dns_rdata_any_tsig_t;
-
-#endif /* ANY_255_TSIG_250_H */
diff --git a/contrib/bind9/lib/dns/rdata/ch_3/a_1.c b/contrib/bind9/lib/dns/rdata/ch_3/a_1.c
deleted file mode 100644
index e3f98106514d..000000000000
--- a/contrib/bind9/lib/dns/rdata/ch_3/a_1.c
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * 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
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $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 */
-
-#ifndef RDATA_CH_3_A_1_C
-#define RDATA_CH_3_A_1_C
-
-#include <isc/net.h>
-
-#define RRTYPE_A_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_ch_a(ARGS_FROMTEXT) {
- isc_token_t token;
- dns_name_t name;
- isc_buffer_t buffer;
-
- REQUIRE(type == 1);
- REQUIRE(rdclass == dns_rdataclass_ch); /* 3 */
-
- UNUSED(type);
- UNUSED(callbacks);
-
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
-
- /* get domain name */
- dns_name_init(&name, NULL);
- buffer_fromregion(&buffer, &token.value.as_region);
- origin = (origin != NULL) ? origin : dns_rootname;
- RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
- if ((options & DNS_RDATA_CHECKNAMES) != 0 &&
- (options & DNS_RDATA_CHECKREVERSE) != 0) {
- isc_boolean_t ok;
- ok = dns_name_ishostname(&name, ISC_FALSE);
- if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0)
- RETTOK(DNS_R_BADNAME);
- if (!ok && callbacks != NULL)
- warn_badname(&name, lexer, callbacks);
- }
-
- /* 16-bit octal address */
- RETERR(isc_lex_getoctaltoken(lexer, &token, ISC_FALSE));
- if (token.value.as_ulong > 0xffffU)
- RETTOK(ISC_R_RANGE);
- return (uint16_tobuffer(token.value.as_ulong, target));
-}
-
-static inline isc_result_t
-totext_ch_a(ARGS_TOTEXT) {
- isc_region_t region;
- dns_name_t name;
- dns_name_t prefix;
- isc_boolean_t sub;
- char buf[sizeof("0177777")];
- isc_uint16_t addr;
-
- REQUIRE(rdata->type == 1);
- REQUIRE(rdata->rdclass == dns_rdataclass_ch); /* 3 */
- REQUIRE(rdata->length != 0);
-
- dns_name_init(&name, NULL);
- dns_name_init(&prefix, NULL);
-
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
- isc_region_consume(&region, name_length(&name));
- addr = uint16_fromregion(&region);
-
- sub = name_prefix(&name, tctx->origin, &prefix);
- RETERR(dns_name_totext(&prefix, sub, target));
-
- sprintf(buf, "%o", addr); /* note octal */
- RETERR(str_totext(" ", target));
- return (str_totext(buf, target));
-}
-
-static inline isc_result_t
-fromwire_ch_a(ARGS_FROMWIRE) {
- isc_region_t sregion;
- isc_region_t tregion;
- dns_name_t name;
-
- REQUIRE(type == 1);
- REQUIRE(rdclass == dns_rdataclass_ch);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- 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);
- isc_buffer_availableregion(target, &tregion);
- if (sregion.length < 2)
- return (ISC_R_UNEXPECTEDEND);
- if (tregion.length < 2)
- return (ISC_R_NOSPACE);
-
- memcpy(tregion.base, sregion.base, 2);
- isc_buffer_forward(source, 2);
- isc_buffer_add(target, 2);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-towire_ch_a(ARGS_TOWIRE) {
- dns_name_t name;
- dns_offsets_t offsets;
- isc_region_t sregion;
- isc_region_t tregion;
-
- REQUIRE(rdata->type == 1);
- REQUIRE(rdata->rdclass == dns_rdataclass_ch);
- REQUIRE(rdata->length != 0);
-
- dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
-
- dns_name_init(&name, offsets);
-
- dns_rdata_toregion(rdata, &sregion);
-
- dns_name_fromregion(&name, &sregion);
- isc_region_consume(&sregion, name_length(&name));
- RETERR(dns_name_towire(&name, cctx, target));
-
- isc_buffer_availableregion(target, &tregion);
- if (tregion.length < 2)
- return (ISC_R_NOSPACE);
-
- memcpy(tregion.base, sregion.base, 2);
- isc_buffer_add(target, 2);
- return (ISC_R_SUCCESS);
-}
-
-static inline int
-compare_ch_a(ARGS_COMPARE) {
- dns_name_t name1;
- dns_name_t name2;
- isc_region_t region1;
- isc_region_t region2;
- int order;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 1);
- REQUIRE(rdata1->rdclass == dns_rdataclass_ch);
- 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);
- isc_region_consume(&region1, name_length(&name1));
- isc_region_consume(&region2, name_length(&name2));
-
- order = dns_name_rdatacompare(&name1, &name2);
- if (order != 0)
- return (order);
-
- order = memcmp(rdata1->data, rdata2->data, 2);
- if (order != 0)
- order = (order < 0) ? -1 : 1;
- return (order);
-}
-
-static inline isc_result_t
-fromstruct_ch_a(ARGS_FROMSTRUCT) {
- dns_rdata_ch_a_t *a = source;
- isc_region_t region;
-
- REQUIRE(type == 1);
- REQUIRE(source != NULL);
- REQUIRE(a->common.rdtype == type);
- REQUIRE(a->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_name_toregion(&a->ch_addr_dom, &region);
- RETERR(isc_buffer_copyregion(target, &region));
-
- return (uint16_tobuffer(ntohs(a->ch_addr), target));
-}
-
-static inline isc_result_t
-tostruct_ch_a(ARGS_TOSTRUCT) {
- dns_rdata_ch_a_t *a = target;
- isc_region_t region;
- dns_name_t name;
-
- REQUIRE(rdata->type == 1);
- REQUIRE(rdata->rdclass == dns_rdataclass_ch);
- REQUIRE(rdata->length != 0);
-
- a->common.rdclass = rdata->rdclass;
- a->common.rdtype = rdata->type;
- ISC_LINK_INIT(&a->common, link);
-
- dns_rdata_toregion(rdata, &region);
-
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &region);
- isc_region_consume(&region, name_length(&name));
-
- dns_name_init(&a->ch_addr_dom, NULL);
- RETERR(name_duporclone(&name, mctx, &a->ch_addr_dom));
- a->ch_addr = htons(uint16_fromregion(&region));
- a->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_ch_a(ARGS_FREESTRUCT) {
- dns_rdata_ch_a_t *a = source;
-
- REQUIRE(source != NULL);
- REQUIRE(a->common.rdtype == 1);
-
- if (a->mctx == NULL)
- return;
-
- dns_name_free(&a->ch_addr_dom, a->mctx);
- a->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_ch_a(ARGS_ADDLDATA) {
-
- REQUIRE(rdata->type == 1);
- REQUIRE(rdata->rdclass == dns_rdataclass_ch);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_ch_a(ARGS_DIGEST) {
- isc_region_t r;
-
- dns_name_t name;
-
- REQUIRE(rdata->type == 1);
- REQUIRE(rdata->rdclass == dns_rdataclass_ch);
-
- dns_rdata_toregion(rdata, &r);
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &r);
- isc_region_consume(&r, name_length(&name));
- RETERR(dns_name_digest(&name, digest, arg));
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_ch_a(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 1);
- REQUIRE(rdclass == dns_rdataclass_ch);
-
- UNUSED(type);
-
- return (dns_name_ishostname(name, wildcard));
-}
-
-static inline isc_boolean_t
-checknames_ch_a(ARGS_CHECKNAMES) {
- isc_region_t region;
- dns_name_t name;
-
- REQUIRE(rdata->type == 1);
- REQUIRE(rdata->rdclass == dns_rdataclass_ch);
-
- UNUSED(owner);
-
- dns_rdata_toregion(rdata, &region);
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &region);
- if (!dns_name_ishostname(&name, ISC_FALSE)) {
- if (bad != NULL)
- dns_name_clone(&name, bad);
- return (ISC_FALSE);
- }
-
- 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/contrib/bind9/lib/dns/rdata/ch_3/a_1.h b/contrib/bind9/lib/dns/rdata/ch_3/a_1.h
deleted file mode 100644
index a279d0e7fcd3..000000000000
--- a/contrib/bind9/lib/dns/rdata/ch_3/a_1.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2005, 2007 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: a_1.h,v 1.5 2007/06/19 23:47:17 tbox Exp $ */
-
-/* by Bjorn.Victor@it.uu.se, 2005-05-07 */
-/* Based on generic/mx_15.h */
-
-#ifndef CH_3_A_1_H
-#define CH_3_A_1_H 1
-
-typedef isc_uint16_t ch_addr_t;
-
-typedef struct dns_rdata_ch_a {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- dns_name_t ch_addr_dom; /* ch-addr domain for back mapping */
- ch_addr_t ch_addr; /* chaos address (16 bit) network order */
-} dns_rdata_ch_a_t;
-
-#endif /* CH_3_A_1_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/afsdb_18.c b/contrib/bind9/lib/dns/rdata/generic/afsdb_18.c
deleted file mode 100644
index 279f86c677d7..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/afsdb_18.c
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $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 */
-
-/* RFC1183 */
-
-#ifndef RDATA_GENERIC_AFSDB_18_C
-#define RDATA_GENERIC_AFSDB_18_C
-
-#define RRTYPE_AFSDB_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_afsdb(ARGS_FROMTEXT) {
- isc_token_t token;
- isc_buffer_t buffer;
- dns_name_t name;
- isc_boolean_t ok;
-
- REQUIRE(type == 18);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(callbacks);
-
- /*
- * Subtype.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if (token.value.as_ulong > 0xffffU)
- RETTOK(ISC_R_RANGE);
- RETERR(uint16_tobuffer(token.value.as_ulong, target));
-
- /*
- * Hostname.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- dns_name_init(&name, NULL);
- buffer_fromregion(&buffer, &token.value.as_region);
- origin = (origin != NULL) ? origin : dns_rootname;
- RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
- ok = ISC_TRUE;
- if ((options & DNS_RDATA_CHECKNAMES) != 0)
- ok = dns_name_ishostname(&name, ISC_FALSE);
- if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0)
- RETTOK(DNS_R_BADNAME);
- if (!ok && callbacks != NULL)
- warn_badname(&name, lexer, callbacks);
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_afsdb(ARGS_TOTEXT) {
- dns_name_t name;
- dns_name_t prefix;
- isc_region_t region;
- char buf[sizeof("64000 ")];
- isc_boolean_t sub;
- unsigned int num;
-
- REQUIRE(rdata->type == 18);
- REQUIRE(rdata->length != 0);
-
- dns_name_init(&name, NULL);
- dns_name_init(&prefix, NULL);
-
- dns_rdata_toregion(rdata, &region);
- num = uint16_fromregion(&region);
- isc_region_consume(&region, 2);
- sprintf(buf, "%u ", num);
- RETERR(str_totext(buf, target));
- dns_name_fromregion(&name, &region);
- sub = name_prefix(&name, tctx->origin, &prefix);
- return (dns_name_totext(&prefix, sub, target));
-}
-
-static inline isc_result_t
-fromwire_afsdb(ARGS_FROMWIRE) {
- dns_name_t name;
- isc_region_t sr;
- isc_region_t tr;
-
- REQUIRE(type == 18);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
-
- dns_name_init(&name, NULL);
-
- isc_buffer_activeregion(source, &sr);
- isc_buffer_availableregion(target, &tr);
- if (tr.length < 2)
- return (ISC_R_NOSPACE);
- if (sr.length < 2)
- return (ISC_R_UNEXPECTEDEND);
- memcpy(tr.base, sr.base, 2);
- isc_buffer_forward(source, 2);
- isc_buffer_add(target, 2);
- return (dns_name_fromwire(&name, source, dctx, options, target));
-}
-
-static inline isc_result_t
-towire_afsdb(ARGS_TOWIRE) {
- isc_region_t tr;
- isc_region_t sr;
- dns_name_t name;
- dns_offsets_t offsets;
-
- REQUIRE(rdata->type == 18);
- REQUIRE(rdata->length != 0);
-
- dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
- isc_buffer_availableregion(target, &tr);
- dns_rdata_toregion(rdata, &sr);
- if (tr.length < 2)
- return (ISC_R_NOSPACE);
- memcpy(tr.base, sr.base, 2);
- isc_region_consume(&sr, 2);
- isc_buffer_add(target, 2);
-
- dns_name_init(&name, offsets);
- dns_name_fromregion(&name, &sr);
-
- return (dns_name_towire(&name, cctx, target));
-}
-
-static inline int
-compare_afsdb(ARGS_COMPARE) {
- int result;
- dns_name_t name1;
- dns_name_t name2;
- isc_region_t region1;
- isc_region_t region2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 18);
- REQUIRE(rdata1->length != 0);
- REQUIRE(rdata2->length != 0);
-
- result = memcmp(rdata1->data, rdata2->data, 2);
- if (result != 0)
- return (result < 0 ? -1 : 1);
-
- dns_name_init(&name1, NULL);
- dns_name_init(&name2, NULL);
-
- dns_rdata_toregion(rdata1, &region1);
- dns_rdata_toregion(rdata2, &region2);
-
- isc_region_consume(&region1, 2);
- isc_region_consume(&region2, 2);
-
- dns_name_fromregion(&name1, &region1);
- dns_name_fromregion(&name2, &region2);
-
- return (dns_name_rdatacompare(&name1, &name2));
-}
-
-static inline isc_result_t
-fromstruct_afsdb(ARGS_FROMSTRUCT) {
- dns_rdata_afsdb_t *afsdb = source;
- isc_region_t region;
-
- REQUIRE(type == 18);
- REQUIRE(source != NULL);
- REQUIRE(afsdb->common.rdclass == rdclass);
- REQUIRE(afsdb->common.rdtype == type);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- RETERR(uint16_tobuffer(afsdb->subtype, target));
- dns_name_toregion(&afsdb->server, &region);
- return (isc_buffer_copyregion(target, &region));
-}
-
-static inline isc_result_t
-tostruct_afsdb(ARGS_TOSTRUCT) {
- isc_region_t region;
- dns_rdata_afsdb_t *afsdb = target;
- dns_name_t name;
-
- REQUIRE(rdata->type == 18);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- afsdb->common.rdclass = rdata->rdclass;
- afsdb->common.rdtype = rdata->type;
- ISC_LINK_INIT(&afsdb->common, link);
-
- dns_name_init(&afsdb->server, NULL);
-
- dns_rdata_toregion(rdata, &region);
-
- afsdb->subtype = uint16_fromregion(&region);
- isc_region_consume(&region, 2);
-
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &region);
-
- RETERR(name_duporclone(&name, mctx, &afsdb->server));
- afsdb->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_afsdb(ARGS_FREESTRUCT) {
- dns_rdata_afsdb_t *afsdb = source;
-
- REQUIRE(source != NULL);
- REQUIRE(afsdb->common.rdtype == 18);
-
- if (afsdb->mctx == NULL)
- return;
-
- dns_name_free(&afsdb->server, afsdb->mctx);
- afsdb->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_afsdb(ARGS_ADDLDATA) {
- dns_name_t name;
- dns_offsets_t offsets;
- isc_region_t region;
-
- REQUIRE(rdata->type == 18);
-
- dns_name_init(&name, offsets);
- dns_rdata_toregion(rdata, &region);
- isc_region_consume(&region, 2);
- dns_name_fromregion(&name, &region);
-
- return ((add)(arg, &name, dns_rdatatype_a));
-}
-
-static inline isc_result_t
-digest_afsdb(ARGS_DIGEST) {
- isc_region_t r1, r2;
- dns_name_t name;
-
- REQUIRE(rdata->type == 18);
-
- dns_rdata_toregion(rdata, &r1);
- r2 = r1;
- isc_region_consume(&r2, 2);
- r1.length = 2;
- RETERR((digest)(arg, &r1));
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &r2);
-
- return (dns_name_digest(&name, digest, arg));
-}
-
-static inline isc_boolean_t
-checkowner_afsdb(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 18);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_afsdb(ARGS_CHECKNAMES) {
- isc_region_t region;
- dns_name_t name;
-
- REQUIRE(rdata->type == 18);
-
- UNUSED(owner);
-
- dns_rdata_toregion(rdata, &region);
- isc_region_consume(&region, 2);
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &region);
- if (!dns_name_ishostname(&name, ISC_FALSE)) {
- if (bad != NULL)
- dns_name_clone(&name, bad);
- return (ISC_FALSE);
- }
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_afsdb(ARGS_COMPARE) {
- return (compare_afsdb(rdata1, rdata2));
-}
-#endif /* RDATA_GENERIC_AFSDB_18_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/afsdb_18.h b/contrib/bind9/lib/dns/rdata/generic/afsdb_18.h
deleted file mode 100644
index ccccc116f653..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/afsdb_18.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef GENERIC_AFSDB_18_H
-#define GENERIC_AFSDB_18_H 1
-
-/* $Id: afsdb_18.h,v 1.20 2007/06/19 23:47:17 tbox Exp $ */
-
-/*!
- * \brief Per RFC1183 */
-
-typedef struct dns_rdata_afsdb {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- isc_uint16_t subtype;
- dns_name_t server;
-} dns_rdata_afsdb_t;
-
-#endif /* GENERIC_AFSDB_18_H */
-
diff --git a/contrib/bind9/lib/dns/rdata/generic/cert_37.c b/contrib/bind9/lib/dns/rdata/generic/cert_37.c
deleted file mode 100644
index a03290a60a02..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/cert_37.c
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/* Reviewed: Wed Mar 15 21:14:32 EST 2000 by tale */
-
-/* RFC2538 */
-
-#ifndef RDATA_GENERIC_CERT_37_C
-#define RDATA_GENERIC_CERT_37_C
-
-#define RRTYPE_CERT_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_cert(ARGS_FROMTEXT) {
- isc_token_t token;
- dns_secalg_t secalg;
- dns_cert_t cert;
-
- REQUIRE(type == 37);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(origin);
- UNUSED(options);
- UNUSED(callbacks);
-
- /*
- * Cert type.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- RETTOK(dns_cert_fromtext(&cert, &token.value.as_textregion));
- RETERR(uint16_tobuffer(cert, target));
-
- /*
- * Key tag.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if (token.value.as_ulong > 0xffffU)
- RETTOK(ISC_R_RANGE);
- RETERR(uint16_tobuffer(token.value.as_ulong, target));
-
- /*
- * Algorithm.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- RETTOK(dns_secalg_fromtext(&secalg, &token.value.as_textregion));
- RETERR(mem_tobuffer(target, &secalg, 1));
-
- return (isc_base64_tobuffer(lexer, target, -1));
-}
-
-static inline isc_result_t
-totext_cert(ARGS_TOTEXT) {
- isc_region_t sr;
- char buf[sizeof("64000 ")];
- unsigned int n;
-
- REQUIRE(rdata->type == 37);
- REQUIRE(rdata->length != 0);
-
- UNUSED(tctx);
-
- dns_rdata_toregion(rdata, &sr);
-
- /*
- * Type.
- */
- n = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
- RETERR(dns_cert_totext((dns_cert_t)n, target));
- RETERR(str_totext(" ", target));
-
- /*
- * Key tag.
- */
- n = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
- sprintf(buf, "%u ", n);
- RETERR(str_totext(buf, target));
-
- /*
- * Algorithm.
- */
- RETERR(dns_secalg_totext(sr.base[0], target));
- isc_region_consume(&sr, 1);
-
- /*
- * Cert.
- */
- if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
- RETERR(str_totext(" (", target));
- RETERR(str_totext(tctx->linebreak, target));
- if (tctx->width == 0) /* No splitting */
- RETERR(isc_base64_totext(&sr, 60, "", target));
- else
- RETERR(isc_base64_totext(&sr, tctx->width - 2,
- tctx->linebreak, target));
- if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
- RETERR(str_totext(" )", target));
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-fromwire_cert(ARGS_FROMWIRE) {
- isc_region_t sr;
-
- REQUIRE(type == 37);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(dctx);
- UNUSED(options);
-
- isc_buffer_activeregion(source, &sr);
- if (sr.length < 5)
- return (ISC_R_UNEXPECTEDEND);
-
- isc_buffer_forward(source, sr.length);
- return (mem_tobuffer(target, sr.base, sr.length));
-}
-
-static inline isc_result_t
-towire_cert(ARGS_TOWIRE) {
- isc_region_t sr;
-
- REQUIRE(rdata->type == 37);
- REQUIRE(rdata->length != 0);
-
- UNUSED(cctx);
-
- dns_rdata_toregion(rdata, &sr);
- return (mem_tobuffer(target, sr.base, sr.length));
-}
-
-static inline int
-compare_cert(ARGS_COMPARE) {
- isc_region_t r1;
- isc_region_t r2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 37);
- 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_cert(ARGS_FROMSTRUCT) {
- dns_rdata_cert_t *cert = source;
-
- REQUIRE(type == 37);
- REQUIRE(source != NULL);
- REQUIRE(cert->common.rdtype == type);
- REQUIRE(cert->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- RETERR(uint16_tobuffer(cert->type, target));
- RETERR(uint16_tobuffer(cert->key_tag, target));
- RETERR(uint8_tobuffer(cert->algorithm, target));
-
- return (mem_tobuffer(target, cert->certificate, cert->length));
-}
-
-static inline isc_result_t
-tostruct_cert(ARGS_TOSTRUCT) {
- dns_rdata_cert_t *cert = target;
- isc_region_t region;
-
- REQUIRE(rdata->type == 37);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- cert->common.rdclass = rdata->rdclass;
- cert->common.rdtype = rdata->type;
- ISC_LINK_INIT(&cert->common, link);
-
- dns_rdata_toregion(rdata, &region);
-
- cert->type = uint16_fromregion(&region);
- isc_region_consume(&region, 2);
- cert->key_tag = uint16_fromregion(&region);
- isc_region_consume(&region, 2);
- cert->algorithm = uint8_fromregion(&region);
- isc_region_consume(&region, 1);
- cert->length = region.length;
-
- cert->certificate = mem_maybedup(mctx, region.base, region.length);
- if (cert->certificate == NULL)
- return (ISC_R_NOMEMORY);
-
- cert->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_cert(ARGS_FREESTRUCT) {
- dns_rdata_cert_t *cert = source;
-
- REQUIRE(cert != NULL);
- REQUIRE(cert->common.rdtype == 37);
-
- if (cert->mctx == NULL)
- return;
-
- if (cert->certificate != NULL)
- isc_mem_free(cert->mctx, cert->certificate);
- cert->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_cert(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 37);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_cert(ARGS_DIGEST) {
- isc_region_t r;
-
- REQUIRE(rdata->type == 37);
-
- dns_rdata_toregion(rdata, &r);
-
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_cert(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 37);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_cert(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 37);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- return (ISC_TRUE);
-}
-
-
-static inline int
-casecompare_cert(ARGS_COMPARE) {
- return (compare_cert(rdata1, rdata2));
-}
-#endif /* RDATA_GENERIC_CERT_37_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/cert_37.h b/contrib/bind9/lib/dns/rdata/generic/cert_37.h
deleted file mode 100644
index ddfaa4f6dab0..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/cert_37.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: cert_37.h,v 1.20 2007/06/19 23:47:17 tbox Exp $ */
-
-#ifndef GENERIC_CERT_37_H
-#define GENERIC_CERT_37_H 1
-
-/*% RFC2538 */
-typedef struct dns_rdata_cert {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- isc_uint16_t type;
- isc_uint16_t key_tag;
- isc_uint8_t algorithm;
- isc_uint16_t length;
- unsigned char *certificate;
-} dns_rdata_cert_t;
-
-#endif /* GENERIC_CERT_37_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/cname_5.c b/contrib/bind9/lib/dns/rdata/generic/cname_5.c
deleted file mode 100644
index 45a48a897fc0..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/cname_5.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $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 */
-
-#ifndef RDATA_GENERIC_CNAME_5_C
-#define RDATA_GENERIC_CNAME_5_C
-
-#define RRTYPE_CNAME_ATTRIBUTES \
- (DNS_RDATATYPEATTR_EXCLUSIVE | DNS_RDATATYPEATTR_SINGLETON)
-
-static inline isc_result_t
-fromtext_cname(ARGS_FROMTEXT) {
- isc_token_t token;
- dns_name_t name;
- isc_buffer_t buffer;
-
- REQUIRE(type == 5);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(callbacks);
-
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
-
- dns_name_init(&name, NULL);
- buffer_fromregion(&buffer, &token.value.as_region);
- origin = (origin != NULL) ? origin : dns_rootname;
- RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_cname(ARGS_TOTEXT) {
- isc_region_t region;
- dns_name_t name;
- dns_name_t prefix;
- isc_boolean_t sub;
-
- REQUIRE(rdata->type == 5);
- REQUIRE(rdata->length != 0);
-
- dns_name_init(&name, NULL);
- dns_name_init(&prefix, NULL);
-
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
-
- sub = name_prefix(&name, tctx->origin, &prefix);
-
- return (dns_name_totext(&prefix, sub, target));
-}
-
-static inline isc_result_t
-fromwire_cname(ARGS_FROMWIRE) {
- dns_name_t name;
-
- REQUIRE(type == 5);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14);
-
- dns_name_init(&name, NULL);
- return (dns_name_fromwire(&name, source, dctx, options, target));
-}
-
-static inline isc_result_t
-towire_cname(ARGS_TOWIRE) {
- dns_name_t name;
- dns_offsets_t offsets;
- isc_region_t region;
-
- REQUIRE(rdata->type == 5);
- REQUIRE(rdata->length != 0);
-
- dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
-
- dns_name_init(&name, offsets);
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
-
- return (dns_name_towire(&name, cctx, target));
-}
-
-static inline int
-compare_cname(ARGS_COMPARE) {
- dns_name_t name1;
- dns_name_t name2;
- isc_region_t region1;
- isc_region_t region2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 5);
- 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);
-
- return (dns_name_rdatacompare(&name1, &name2));
-}
-
-static inline isc_result_t
-fromstruct_cname(ARGS_FROMSTRUCT) {
- dns_rdata_cname_t *cname = source;
- isc_region_t region;
-
- REQUIRE(type == 5);
- REQUIRE(source != NULL);
- REQUIRE(cname->common.rdtype == type);
- REQUIRE(cname->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_name_toregion(&cname->cname, &region);
- return (isc_buffer_copyregion(target, &region));
-}
-
-static inline isc_result_t
-tostruct_cname(ARGS_TOSTRUCT) {
- isc_region_t region;
- dns_rdata_cname_t *cname = target;
- dns_name_t name;
-
- REQUIRE(rdata->type == 5);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- cname->common.rdclass = rdata->rdclass;
- cname->common.rdtype = rdata->type;
- ISC_LINK_INIT(&cname->common, link);
-
- dns_name_init(&name, NULL);
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
- dns_name_init(&cname->cname, NULL);
- RETERR(name_duporclone(&name, mctx, &cname->cname));
- cname->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_cname(ARGS_FREESTRUCT) {
- dns_rdata_cname_t *cname = source;
-
- REQUIRE(source != NULL);
-
- if (cname->mctx == NULL)
- return;
-
- dns_name_free(&cname->cname, cname->mctx);
- cname->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_cname(ARGS_ADDLDATA) {
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- REQUIRE(rdata->type == 5);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_cname(ARGS_DIGEST) {
- isc_region_t r;
- dns_name_t name;
-
- REQUIRE(rdata->type == 5);
-
- dns_rdata_toregion(rdata, &r);
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &r);
-
- return (dns_name_digest(&name, digest, arg));
-}
-
-static inline isc_boolean_t
-checkowner_cname(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 5);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_cname(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 5);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_cname(ARGS_COMPARE) {
- return (compare_cname(rdata1, rdata2));
-}
-
-#endif /* RDATA_GENERIC_CNAME_5_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/cname_5.h b/contrib/bind9/lib/dns/rdata/generic/cname_5.h
deleted file mode 100644
index 516f8d38abda..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/cname_5.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-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: cname_5.h,v 1.26 2007/06/19 23:47:17 tbox Exp $ */
-
-#ifndef GENERIC_CNAME_5_H
-#define GENERIC_CNAME_5_H 1
-
-typedef struct dns_rdata_cname {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- dns_name_t cname;
-} dns_rdata_cname_t;
-
-#endif /* GENERIC_CNAME_5_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/dlv_32769.c b/contrib/bind9/lib/dns/rdata/generic/dlv_32769.c
deleted file mode 100644
index 5751ad894527..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/dlv_32769.c
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Copyright (C) 2004, 2006, 2007, 2009-2013 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/* draft-ietf-dnsext-delegation-signer-05.txt */
-
-#ifndef RDATA_GENERIC_DLV_32769_C
-#define RDATA_GENERIC_DLV_32769_C
-
-#define RRTYPE_DLV_ATTRIBUTES 0
-
-#include <isc/sha1.h>
-#include <isc/sha2.h>
-
-#include <dns/ds.h>
-
-
-static inline isc_result_t
-fromtext_dlv(ARGS_FROMTEXT) {
- isc_token_t token;
- unsigned char c;
- int length;
-
- REQUIRE(type == 32769);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(origin);
- UNUSED(options);
- UNUSED(callbacks);
-
- /*
- * Key tag.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if (token.value.as_ulong > 0xffffU)
- RETTOK(ISC_R_RANGE);
- RETERR(uint16_tobuffer(token.value.as_ulong, target));
-
- /*
- * 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));
-
- /*
- * Digest type.
- */
- 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));
- c = (unsigned char) token.value.as_ulong;
-
- /*
- * Digest.
- */
- switch (c) {
- case DNS_DSDIGEST_SHA1:
- length = ISC_SHA1_DIGESTLENGTH;
- break;
- case DNS_DSDIGEST_SHA256:
- length = ISC_SHA256_DIGESTLENGTH;
- break;
- case DNS_DSDIGEST_GOST:
- length = ISC_GOST_DIGESTLENGTH;
- break;
- case DNS_DSDIGEST_SHA384:
- length = ISC_SHA384_DIGESTLENGTH;
- break;
- default:
- length = -1;
- break;
- }
- return (isc_hex_tobuffer(lexer, target, length));
-}
-
-static inline isc_result_t
-totext_dlv(ARGS_TOTEXT) {
- isc_region_t sr;
- char buf[sizeof("64000 ")];
- unsigned int n;
-
- REQUIRE(rdata->type == 32769);
- REQUIRE(rdata->length != 0);
-
- UNUSED(tctx);
-
- dns_rdata_toregion(rdata, &sr);
-
- /*
- * Key tag.
- */
- n = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
- sprintf(buf, "%u ", n);
- RETERR(str_totext(buf, target));
-
- /*
- * Algorithm.
- */
- n = uint8_fromregion(&sr);
- isc_region_consume(&sr, 1);
- sprintf(buf, "%u ", n);
- RETERR(str_totext(buf, target));
-
- /*
- * Digest type.
- */
- n = uint8_fromregion(&sr);
- isc_region_consume(&sr, 1);
- sprintf(buf, "%u", n);
- RETERR(str_totext(buf, target));
-
- /*
- * Digest.
- */
- if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
- RETERR(str_totext(" (", target));
- RETERR(str_totext(tctx->linebreak, target));
- if (tctx->width == 0) /* No splitting */
- RETERR(isc_hex_totext(&sr, 0, "", target));
- else
- RETERR(isc_hex_totext(&sr, tctx->width - 2,
- tctx->linebreak, target));
- if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
- RETERR(str_totext(" )", target));
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-fromwire_dlv(ARGS_FROMWIRE) {
- isc_region_t sr;
-
- REQUIRE(type == 32769);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(dctx);
- UNUSED(options);
-
- isc_buffer_activeregion(source, &sr);
-
- /*
- * Check digest lengths if we know them.
- */
- if (sr.length < 4 ||
- (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.base[3] == DNS_DSDIGEST_GOST &&
- sr.length < 4 + ISC_GOST_DIGESTLENGTH) ||
- (sr.base[3] == DNS_DSDIGEST_SHA384 &&
- sr.length < 4 + ISC_SHA384_DIGESTLENGTH))
- return (ISC_R_UNEXPECTEDEND);
-
- /*
- * Only copy digest lengths if we know them.
- * If there is extra data dns_rdata_fromwire() will
- * detect that.
- */
- if (sr.base[3] == DNS_DSDIGEST_SHA1)
- 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;
- else if (sr.base[3] == DNS_DSDIGEST_SHA384)
- sr.length = 4 + ISC_SHA384_DIGESTLENGTH;
-
- isc_buffer_forward(source, sr.length);
- return (mem_tobuffer(target, sr.base, sr.length));
-}
-
-static inline isc_result_t
-towire_dlv(ARGS_TOWIRE) {
- isc_region_t sr;
-
- REQUIRE(rdata->type == 32769);
- REQUIRE(rdata->length != 0);
-
- UNUSED(cctx);
-
- dns_rdata_toregion(rdata, &sr);
- return (mem_tobuffer(target, sr.base, sr.length));
-}
-
-static inline int
-compare_dlv(ARGS_COMPARE) {
- isc_region_t r1;
- isc_region_t r2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 32769);
- 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_dlv(ARGS_FROMSTRUCT) {
- dns_rdata_dlv_t *dlv = source;
-
- REQUIRE(type == 32769);
- REQUIRE(source != NULL);
- REQUIRE(dlv->common.rdtype == type);
- REQUIRE(dlv->common.rdclass == rdclass);
- switch (dlv->digest_type) {
- case DNS_DSDIGEST_SHA1:
- REQUIRE(dlv->length == ISC_SHA1_DIGESTLENGTH);
- break;
- case DNS_DSDIGEST_SHA256:
- REQUIRE(dlv->length == ISC_SHA256_DIGESTLENGTH);
- break;
- case DNS_DSDIGEST_GOST:
- REQUIRE(dlv->length == ISC_GOST_DIGESTLENGTH);
- break;
- case DNS_DSDIGEST_SHA384:
- REQUIRE(dlv->length == ISC_SHA384_DIGESTLENGTH);
- break;
- }
-
- UNUSED(type);
- UNUSED(rdclass);
-
- RETERR(uint16_tobuffer(dlv->key_tag, target));
- RETERR(uint8_tobuffer(dlv->algorithm, target));
- RETERR(uint8_tobuffer(dlv->digest_type, target));
-
- return (mem_tobuffer(target, dlv->digest, dlv->length));
-}
-
-static inline isc_result_t
-tostruct_dlv(ARGS_TOSTRUCT) {
- dns_rdata_dlv_t *dlv = target;
- isc_region_t region;
-
- REQUIRE(rdata->type == 32769);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- dlv->common.rdclass = rdata->rdclass;
- dlv->common.rdtype = rdata->type;
- ISC_LINK_INIT(&dlv->common, link);
-
- dns_rdata_toregion(rdata, &region);
-
- dlv->key_tag = uint16_fromregion(&region);
- isc_region_consume(&region, 2);
- dlv->algorithm = uint8_fromregion(&region);
- isc_region_consume(&region, 1);
- dlv->digest_type = uint8_fromregion(&region);
- isc_region_consume(&region, 1);
- dlv->length = region.length;
-
- dlv->digest = mem_maybedup(mctx, region.base, region.length);
- if (dlv->digest == NULL)
- return (ISC_R_NOMEMORY);
-
- dlv->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_dlv(ARGS_FREESTRUCT) {
- dns_rdata_dlv_t *dlv = source;
-
- REQUIRE(dlv != NULL);
- REQUIRE(dlv->common.rdtype == 32769);
-
- if (dlv->mctx == NULL)
- return;
-
- if (dlv->digest != NULL)
- isc_mem_free(dlv->mctx, dlv->digest);
- dlv->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_dlv(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 32769);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_dlv(ARGS_DIGEST) {
- isc_region_t r;
-
- REQUIRE(rdata->type == 32769);
-
- dns_rdata_toregion(rdata, &r);
-
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_dlv(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 32769);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_dlv(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 32769);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_dlv(ARGS_COMPARE) {
- return (compare_dlv(rdata1, rdata2));
-}
-
-#endif /* RDATA_GENERIC_DLV_32769_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/dlv_32769.h b/contrib/bind9/lib/dns/rdata/generic/dlv_32769.h
deleted file mode 100644
index 2313c57582d8..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/dlv_32769.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2004, 2006, 2007 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: dlv_32769.h,v 1.5 2007/06/19 23:47:17 tbox Exp $ */
-
-/* draft-ietf-dnsext-delegation-signer-05.txt */
-#ifndef GENERIC_DLV_32769_H
-#define GENERIC_DLV_32769_H 1
-
-typedef struct dns_rdata_dlv {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- isc_uint16_t key_tag;
- isc_uint8_t algorithm;
- isc_uint8_t digest_type;
- isc_uint16_t length;
- unsigned char *digest;
-} dns_rdata_dlv_t;
-
-#endif /* GENERIC_DLV_32769_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/dname_39.c b/contrib/bind9/lib/dns/rdata/generic/dname_39.c
deleted file mode 100644
index d899494f5368..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/dname_39.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $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 */
-
-/* RFC2672 */
-
-#ifndef RDATA_GENERIC_DNAME_39_C
-#define RDATA_GENERIC_DNAME_39_C
-
-#define RRTYPE_DNAME_ATTRIBUTES (DNS_RDATATYPEATTR_SINGLETON)
-
-static inline isc_result_t
-fromtext_dname(ARGS_FROMTEXT) {
- isc_token_t token;
- dns_name_t name;
- isc_buffer_t buffer;
-
- REQUIRE(type == 39);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(callbacks);
-
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
-
- dns_name_init(&name, NULL);
- buffer_fromregion(&buffer, &token.value.as_region);
- origin = (origin != NULL) ? origin : dns_rootname;
- RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_dname(ARGS_TOTEXT) {
- isc_region_t region;
- dns_name_t name;
- dns_name_t prefix;
- isc_boolean_t sub;
-
- REQUIRE(rdata->type == 39);
- REQUIRE(rdata->length != 0);
-
- dns_name_init(&name, NULL);
- dns_name_init(&prefix, NULL);
-
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
-
- sub = name_prefix(&name, tctx->origin, &prefix);
-
- return (dns_name_totext(&prefix, sub, target));
-}
-
-static inline isc_result_t
-fromwire_dname(ARGS_FROMWIRE) {
- dns_name_t name;
-
- REQUIRE(type == 39);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
-
- dns_name_init(&name, NULL);
- return(dns_name_fromwire(&name, source, dctx, options, target));
-}
-
-static inline isc_result_t
-towire_dname(ARGS_TOWIRE) {
- dns_name_t name;
- dns_offsets_t offsets;
- isc_region_t region;
-
- REQUIRE(rdata->type == 39);
- REQUIRE(rdata->length != 0);
-
- dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
- dns_name_init(&name, offsets);
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
-
- return (dns_name_towire(&name, cctx, target));
-}
-
-static inline int
-compare_dname(ARGS_COMPARE) {
- dns_name_t name1;
- dns_name_t name2;
- isc_region_t region1;
- isc_region_t region2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 39);
- 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);
-
- return (dns_name_rdatacompare(&name1, &name2));
-}
-
-static inline isc_result_t
-fromstruct_dname(ARGS_FROMSTRUCT) {
- dns_rdata_dname_t *dname = source;
- isc_region_t region;
-
- REQUIRE(type == 39);
- REQUIRE(source != NULL);
- REQUIRE(dname->common.rdtype == type);
- REQUIRE(dname->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_name_toregion(&dname->dname, &region);
- return (isc_buffer_copyregion(target, &region));
-}
-
-static inline isc_result_t
-tostruct_dname(ARGS_TOSTRUCT) {
- isc_region_t region;
- dns_rdata_dname_t *dname = target;
- dns_name_t name;
-
- REQUIRE(rdata->type == 39);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- dname->common.rdclass = rdata->rdclass;
- dname->common.rdtype = rdata->type;
- ISC_LINK_INIT(&dname->common, link);
-
- dns_name_init(&name, NULL);
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
- dns_name_init(&dname->dname, NULL);
- RETERR(name_duporclone(&name, mctx, &dname->dname));
- dname->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_dname(ARGS_FREESTRUCT) {
- dns_rdata_dname_t *dname = source;
-
- REQUIRE(source != NULL);
- REQUIRE(dname->common.rdtype == 39);
-
- if (dname->mctx == NULL)
- return;
-
- dns_name_free(&dname->dname, dname->mctx);
- dname->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_dname(ARGS_ADDLDATA) {
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- REQUIRE(rdata->type == 39);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_dname(ARGS_DIGEST) {
- isc_region_t r;
- dns_name_t name;
-
- REQUIRE(rdata->type == 39);
-
- dns_rdata_toregion(rdata, &r);
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &r);
-
- return (dns_name_digest(&name, digest, arg));
-}
-
-static inline isc_boolean_t
-checkowner_dname(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 39);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_dname(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 39);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_dname(ARGS_COMPARE) {
- return (compare_dname(rdata1, rdata2));
-}
-#endif /* RDATA_GENERIC_DNAME_39_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/dname_39.h b/contrib/bind9/lib/dns/rdata/generic/dname_39.h
deleted file mode 100644
index f8aca2756f83..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/dname_39.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef GENERIC_DNAME_39_H
-#define GENERIC_DNAME_39_H 1
-
-/* $Id: dname_39.h,v 1.21 2007/06/19 23:47:17 tbox Exp $ */
-
-/*!
- * \brief per RFC2672 */
-
-typedef struct dns_rdata_dname {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- dns_name_t dname;
-} dns_rdata_dname_t;
-
-#endif /* GENERIC_DNAME_39_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/dnskey_48.c b/contrib/bind9/lib/dns/rdata/generic/dnskey_48.c
deleted file mode 100644
index 688e7ac5e18f..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/dnskey_48.c
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/*
- * Reviewed: Wed Mar 15 16:47:10 PST 2000 by halley.
- */
-
-/* RFC2535 */
-
-#ifndef RDATA_GENERIC_DNSKEY_48_C
-#define RDATA_GENERIC_DNSKEY_48_C
-
-#include <dst/dst.h>
-
-#define RRTYPE_DNSKEY_ATTRIBUTES (DNS_RDATATYPEATTR_DNSSEC)
-
-static inline isc_result_t
-fromtext_dnskey(ARGS_FROMTEXT) {
- isc_token_t token;
- dns_secalg_t alg;
- dns_secproto_t proto;
- dns_keyflags_t flags;
-
- REQUIRE(type == 48);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(origin);
- UNUSED(options);
- UNUSED(callbacks);
-
- /* 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_dnskey(ARGS_TOTEXT) {
- isc_region_t sr;
- char buf[sizeof("64000")];
- unsigned int flags;
- unsigned char algorithm;
- char algbuf[DNS_NAME_FORMATSIZE];
- const char *keyinfo;
-
- REQUIRE(rdata->type == 48);
- REQUIRE(rdata->length != 0);
-
- dns_rdata_toregion(rdata, &sr);
-
- /* flags */
- flags = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
- sprintf(buf, "%u", flags);
- RETERR(str_totext(buf, target));
- RETERR(str_totext(" ", target));
- if ((flags & DNS_KEYFLAG_KSK) != 0) {
- if (flags & DNS_KEYFLAG_REVOKE)
- keyinfo = "revoked KSK";
- else
- keyinfo = "KSK";
- } else
- keyinfo = "ZSK";
-
- /* protocol */
- sprintf(buf, "%u", sr.base[0]);
- 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);
-
- if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0 &&
- algorithm == DNS_KEYALG_PRIVATEDNS) {
- dns_name_t name;
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &sr);
- dns_name_format(&name, algbuf, sizeof(algbuf));
- } else {
- dns_secalg_format((dns_secalg_t) algorithm, algbuf,
- sizeof(algbuf));
- }
-
- /* key */
- if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
- RETERR(str_totext(" (", target));
- RETERR(str_totext(tctx->linebreak, target));
- if (tctx->width == 0) /* No splitting */
- RETERR(isc_base64_totext(&sr, 0, "", target));
- else
- RETERR(isc_base64_totext(&sr, tctx->width - 2,
- tctx->linebreak, target));
-
- if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 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_RRCOMMENT) != 0) {
- isc_region_t tmpr;
-
- RETERR(str_totext(" ; ", target));
- RETERR(str_totext(keyinfo, target));
- RETERR(str_totext("; alg = ", target));
- RETERR(str_totext(algbuf, target));
- RETERR(str_totext("; key id = ", target));
- dns_rdata_toregion(rdata, &tmpr);
- sprintf(buf, "%u", dst_region_computeid(&tmpr, algorithm));
- RETERR(str_totext(buf, target));
- }
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-fromwire_dnskey(ARGS_FROMWIRE) {
- unsigned char algorithm;
- isc_region_t sr;
-
- REQUIRE(type == 48);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(dctx);
- UNUSED(options);
-
- isc_buffer_activeregion(source, &sr);
- 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));
-}
-
-static inline isc_result_t
-towire_dnskey(ARGS_TOWIRE) {
- isc_region_t sr;
-
- REQUIRE(rdata->type == 48);
- REQUIRE(rdata->length != 0);
-
- UNUSED(cctx);
-
- dns_rdata_toregion(rdata, &sr);
- return (mem_tobuffer(target, sr.base, sr.length));
-}
-
-static inline int
-compare_dnskey(ARGS_COMPARE) {
- isc_region_t r1;
- isc_region_t r2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 48);
- 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_dnskey(ARGS_FROMSTRUCT) {
- dns_rdata_dnskey_t *dnskey = source;
-
- REQUIRE(type == 48);
- REQUIRE(source != NULL);
- REQUIRE(dnskey->common.rdtype == type);
- REQUIRE(dnskey->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- /* Flags */
- RETERR(uint16_tobuffer(dnskey->flags, target));
-
- /* Protocol */
- RETERR(uint8_tobuffer(dnskey->protocol, target));
-
- /* Algorithm */
- RETERR(uint8_tobuffer(dnskey->algorithm, target));
-
- /* Data */
- return (mem_tobuffer(target, dnskey->data, dnskey->datalen));
-}
-
-static inline isc_result_t
-tostruct_dnskey(ARGS_TOSTRUCT) {
- dns_rdata_dnskey_t *dnskey = target;
- isc_region_t sr;
-
- REQUIRE(rdata->type == 48);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- dnskey->common.rdclass = rdata->rdclass;
- dnskey->common.rdtype = rdata->type;
- ISC_LINK_INIT(&dnskey->common, link);
-
- dns_rdata_toregion(rdata, &sr);
-
- /* Flags */
- if (sr.length < 2)
- return (ISC_R_UNEXPECTEDEND);
- dnskey->flags = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
-
- /* Protocol */
- if (sr.length < 1)
- return (ISC_R_UNEXPECTEDEND);
- dnskey->protocol = uint8_fromregion(&sr);
- isc_region_consume(&sr, 1);
-
- /* Algorithm */
- if (sr.length < 1)
- return (ISC_R_UNEXPECTEDEND);
- dnskey->algorithm = uint8_fromregion(&sr);
- isc_region_consume(&sr, 1);
-
- /* Data */
- dnskey->datalen = sr.length;
- dnskey->data = mem_maybedup(mctx, sr.base, dnskey->datalen);
- if (dnskey->data == NULL)
- return (ISC_R_NOMEMORY);
-
- dnskey->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_dnskey(ARGS_FREESTRUCT) {
- dns_rdata_dnskey_t *dnskey = (dns_rdata_dnskey_t *) source;
-
- REQUIRE(source != NULL);
- REQUIRE(dnskey->common.rdtype == 48);
-
- if (dnskey->mctx == NULL)
- return;
-
- if (dnskey->data != NULL)
- isc_mem_free(dnskey->mctx, dnskey->data);
- dnskey->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_dnskey(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 48);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_dnskey(ARGS_DIGEST) {
- isc_region_t r;
-
- REQUIRE(rdata->type == 48);
-
- dns_rdata_toregion(rdata, &r);
-
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_dnskey(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 48);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_dnskey(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 48);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- 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/contrib/bind9/lib/dns/rdata/generic/dnskey_48.h b/contrib/bind9/lib/dns/rdata/generic/dnskey_48.h
deleted file mode 100644
index ce88cd1bf37a..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/dnskey_48.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 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.
- */
-
-#ifndef GENERIC_DNSKEY_48_H
-#define GENERIC_DNSKEY_48_H 1
-
-/* $Id: dnskey_48.h,v 1.7 2007/06/19 23:47:17 tbox Exp $ */
-
-/*!
- * \brief per RFC2535 */
-
-typedef struct dns_rdata_dnskey {
- dns_rdatacommon_t common;
- isc_mem_t * mctx;
- isc_uint16_t flags;
- isc_uint8_t protocol;
- isc_uint8_t algorithm;
- isc_uint16_t datalen;
- unsigned char * data;
-} dns_rdata_dnskey_t;
-
-
-#endif /* GENERIC_DNSKEY_48_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/ds_43.c b/contrib/bind9/lib/dns/rdata/generic/ds_43.c
deleted file mode 100644
index dd47c8d5e83e..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/ds_43.c
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007, 2009-2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2002 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/* draft-ietf-dnsext-delegation-signer-05.txt */
-
-#ifndef RDATA_GENERIC_DS_43_C
-#define RDATA_GENERIC_DS_43_C
-
-#define RRTYPE_DS_ATTRIBUTES \
- (DNS_RDATATYPEATTR_DNSSEC|DNS_RDATATYPEATTR_ATPARENT)
-
-#include <isc/sha1.h>
-#include <isc/sha2.h>
-
-#include <dns/ds.h>
-
-static inline isc_result_t
-fromtext_ds(ARGS_FROMTEXT) {
- isc_token_t token;
- unsigned char c;
- int length;
-
- REQUIRE(type == 43);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(origin);
- UNUSED(options);
- UNUSED(callbacks);
-
- /*
- * Key tag.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if (token.value.as_ulong > 0xffffU)
- RETTOK(ISC_R_RANGE);
- RETERR(uint16_tobuffer(token.value.as_ulong, target));
-
- /*
- * Algorithm.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- RETTOK(dns_secalg_fromtext(&c, &token.value.as_textregion));
- RETERR(mem_tobuffer(target, &c, 1));
-
- /*
- * Digest type.
- */
- 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));
- c = (unsigned char) token.value.as_ulong;
-
- /*
- * Digest.
- */
- switch (c) {
- case DNS_DSDIGEST_SHA1:
- length = ISC_SHA1_DIGESTLENGTH;
- break;
- case DNS_DSDIGEST_SHA256:
- length = ISC_SHA256_DIGESTLENGTH;
- break;
- case DNS_DSDIGEST_GOST:
- length = ISC_GOST_DIGESTLENGTH;
- break;
- case DNS_DSDIGEST_SHA384:
- length = ISC_SHA384_DIGESTLENGTH;
- break;
- default:
- length = -1;
- break;
- }
- return (isc_hex_tobuffer(lexer, target, length));
-}
-
-static inline isc_result_t
-totext_ds(ARGS_TOTEXT) {
- isc_region_t sr;
- char buf[sizeof("64000 ")];
- unsigned int n;
-
- REQUIRE(rdata->type == 43);
- REQUIRE(rdata->length != 0);
-
- UNUSED(tctx);
-
- dns_rdata_toregion(rdata, &sr);
-
- /*
- * Key tag.
- */
- n = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
- sprintf(buf, "%u ", n);
- RETERR(str_totext(buf, target));
-
- /*
- * Algorithm.
- */
- n = uint8_fromregion(&sr);
- isc_region_consume(&sr, 1);
- sprintf(buf, "%u ", n);
- RETERR(str_totext(buf, target));
-
- /*
- * Digest type.
- */
- n = uint8_fromregion(&sr);
- isc_region_consume(&sr, 1);
- sprintf(buf, "%u", n);
- RETERR(str_totext(buf, target));
-
- /*
- * Digest.
- */
- if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
- RETERR(str_totext(" (", target));
- RETERR(str_totext(tctx->linebreak, target));
- if (tctx->width == 0) /* No splitting */
- RETERR(isc_hex_totext(&sr, 0, "", target));
- else
- RETERR(isc_hex_totext(&sr, tctx->width - 2,
- tctx->linebreak, target));
- if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
- RETERR(str_totext(" )", target));
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-fromwire_ds(ARGS_FROMWIRE) {
- isc_region_t sr;
-
- REQUIRE(type == 43);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(dctx);
- UNUSED(options);
-
- isc_buffer_activeregion(source, &sr);
-
- /*
- * Check digest lengths if we know them.
- */
- if (sr.length < 4 ||
- (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.base[3] == DNS_DSDIGEST_GOST &&
- sr.length < 4 + ISC_GOST_DIGESTLENGTH) ||
- (sr.base[3] == DNS_DSDIGEST_SHA384 &&
- sr.length < 4 + ISC_SHA384_DIGESTLENGTH))
- return (ISC_R_UNEXPECTEDEND);
-
- /*
- * Only copy digest lengths if we know them.
- * If there is extra data dns_rdata_fromwire() will
- * detect that.
- */
- if (sr.base[3] == DNS_DSDIGEST_SHA1)
- 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;
- else if (sr.base[3] == DNS_DSDIGEST_SHA384)
- sr.length = 4 + ISC_SHA384_DIGESTLENGTH;
-
- isc_buffer_forward(source, sr.length);
- return (mem_tobuffer(target, sr.base, sr.length));
-}
-
-static inline isc_result_t
-towire_ds(ARGS_TOWIRE) {
- isc_region_t sr;
-
- REQUIRE(rdata->type == 43);
- REQUIRE(rdata->length != 0);
-
- UNUSED(cctx);
-
- dns_rdata_toregion(rdata, &sr);
- return (mem_tobuffer(target, sr.base, sr.length));
-}
-
-static inline int
-compare_ds(ARGS_COMPARE) {
- isc_region_t r1;
- isc_region_t r2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 43);
- 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_ds(ARGS_FROMSTRUCT) {
- dns_rdata_ds_t *ds = source;
-
- REQUIRE(type == 43);
- REQUIRE(source != NULL);
- REQUIRE(ds->common.rdtype == type);
- REQUIRE(ds->common.rdclass == rdclass);
- switch (ds->digest_type) {
- case DNS_DSDIGEST_SHA1:
- REQUIRE(ds->length == ISC_SHA1_DIGESTLENGTH);
- break;
- case DNS_DSDIGEST_SHA256:
- REQUIRE(ds->length == ISC_SHA256_DIGESTLENGTH);
- break;
- case DNS_DSDIGEST_GOST:
- REQUIRE(ds->length == ISC_GOST_DIGESTLENGTH);
- break;
- case DNS_DSDIGEST_SHA384:
- REQUIRE(ds->length == ISC_SHA384_DIGESTLENGTH);
- break;
- }
-
- UNUSED(type);
- UNUSED(rdclass);
-
- RETERR(uint16_tobuffer(ds->key_tag, target));
- RETERR(uint8_tobuffer(ds->algorithm, target));
- RETERR(uint8_tobuffer(ds->digest_type, target));
-
- return (mem_tobuffer(target, ds->digest, ds->length));
-}
-
-static inline isc_result_t
-tostruct_ds(ARGS_TOSTRUCT) {
- dns_rdata_ds_t *ds = target;
- isc_region_t region;
-
- REQUIRE(rdata->type == 43);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- ds->common.rdclass = rdata->rdclass;
- ds->common.rdtype = rdata->type;
- ISC_LINK_INIT(&ds->common, link);
-
- dns_rdata_toregion(rdata, &region);
-
- ds->key_tag = uint16_fromregion(&region);
- isc_region_consume(&region, 2);
- ds->algorithm = uint8_fromregion(&region);
- isc_region_consume(&region, 1);
- ds->digest_type = uint8_fromregion(&region);
- isc_region_consume(&region, 1);
- ds->length = region.length;
-
- ds->digest = mem_maybedup(mctx, region.base, region.length);
- if (ds->digest == NULL)
- return (ISC_R_NOMEMORY);
-
- ds->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_ds(ARGS_FREESTRUCT) {
- dns_rdata_ds_t *ds = source;
-
- REQUIRE(ds != NULL);
- REQUIRE(ds->common.rdtype == 43);
-
- if (ds->mctx == NULL)
- return;
-
- if (ds->digest != NULL)
- isc_mem_free(ds->mctx, ds->digest);
- ds->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_ds(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 43);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_ds(ARGS_DIGEST) {
- isc_region_t r;
-
- REQUIRE(rdata->type == 43);
-
- dns_rdata_toregion(rdata, &r);
-
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_ds(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 43);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_ds(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 43);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_ds(ARGS_COMPARE) {
- return (compare_ds(rdata1, rdata2));
-}
-
-#endif /* RDATA_GENERIC_DS_43_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/ds_43.h b/contrib/bind9/lib/dns/rdata/generic/ds_43.h
deleted file mode 100644
index 3a409a15ee37..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/ds_43.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2002 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: ds_43.h,v 1.7 2007/06/19 23:47:17 tbox Exp $ */
-
-#ifndef GENERIC_DS_43_H
-#define GENERIC_DS_43_H 1
-
-/*!
- * \brief per draft-ietf-dnsext-delegation-signer-05.txt */
-typedef struct dns_rdata_ds {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- isc_uint16_t key_tag;
- isc_uint8_t algorithm;
- isc_uint8_t digest_type;
- isc_uint16_t length;
- unsigned char *digest;
-} dns_rdata_ds_t;
-
-#endif /* GENERIC_DS_43_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/eui48_108.c b/contrib/bind9/lib/dns/rdata/generic/eui48_108.c
deleted file mode 100644
index 3e52fec0ed4a..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/eui48_108.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER 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 RDATA_GENERIC_EUI48_108_C
-#define RDATA_GENERIC_EUI48_108_C
-
-#include <string.h>
-
-#define RRTYPE_EUI48_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_eui48(ARGS_FROMTEXT) {
- isc_token_t token;
- unsigned char eui48[6];
- unsigned int l0, l1, l2, l3, l4, l5;
- int n;
-
- REQUIRE(type == 108);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(origin);
- UNUSED(options);
- UNUSED(callbacks);
-
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- n = sscanf(DNS_AS_STR(token), "%2x-%2x-%2x-%2x-%2x-%2x",
- &l0, &l1, &l2, &l3, &l4, &l5);
- if (n != 6 || l0 > 255U || l1 > 255U || l2 > 255U || l3 > 255U ||
- l4 > 255U || l5 > 255U)
- return (DNS_R_BADEUI);
-
- eui48[0] = l0;
- eui48[1] = l1;
- eui48[2] = l2;
- eui48[3] = l3;
- eui48[4] = l4;
- eui48[5] = l5;
- return (mem_tobuffer(target, eui48, sizeof(eui48)));
-}
-
-static inline isc_result_t
-totext_eui48(ARGS_TOTEXT) {
- char buf[sizeof("xx-xx-xx-xx-xx-xx")];
-
- REQUIRE(rdata->type == 108);
- REQUIRE(rdata->length == 6);
-
- UNUSED(tctx);
-
- (void)snprintf(buf, sizeof(buf), "%02x-%02x-%02x-%02x-%02x-%02x",
- rdata->data[0], rdata->data[1], rdata->data[2],
- rdata->data[3], rdata->data[4], rdata->data[5]);
- return (str_totext(buf, target));
-}
-
-static inline isc_result_t
-fromwire_eui48(ARGS_FROMWIRE) {
- isc_region_t sregion;
-
- REQUIRE(type == 108);
-
- UNUSED(type);
- UNUSED(options);
- UNUSED(rdclass);
- UNUSED(dctx);
-
- isc_buffer_activeregion(source, &sregion);
- if (sregion.length != 6)
- return (DNS_R_FORMERR);
- isc_buffer_forward(source, sregion.length);
- return (mem_tobuffer(target, sregion.base, sregion.length));
-}
-
-static inline isc_result_t
-towire_eui48(ARGS_TOWIRE) {
-
- REQUIRE(rdata->type == 108);
- REQUIRE(rdata->length == 6);
-
- UNUSED(cctx);
-
- return (mem_tobuffer(target, rdata->data, rdata->length));
-}
-
-static inline int
-compare_eui48(ARGS_COMPARE) {
- isc_region_t region1;
- isc_region_t region2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 108);
- REQUIRE(rdata1->length == 6);
- REQUIRE(rdata2->length == 6);
-
- dns_rdata_toregion(rdata1, &region1);
- dns_rdata_toregion(rdata2, &region2);
- return (isc_region_compare(&region1, &region2));
-}
-
-static inline isc_result_t
-fromstruct_eui48(ARGS_FROMSTRUCT) {
- dns_rdata_eui48_t *eui48 = source;
-
- REQUIRE(type == 108);
- REQUIRE(source != NULL);
- REQUIRE(eui48->common.rdtype == type);
- REQUIRE(eui48->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- return (mem_tobuffer(target, eui48->eui48, sizeof(eui48->eui48)));
-}
-
-static inline isc_result_t
-tostruct_eui48(ARGS_TOSTRUCT) {
- dns_rdata_eui48_t *eui48 = target;
-
- REQUIRE(rdata->type == 108);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length == 6);
-
- UNUSED(mctx);
-
- eui48->common.rdclass = rdata->rdclass;
- eui48->common.rdtype = rdata->type;
- ISC_LINK_INIT(&eui48->common, link);
-
- memcpy(eui48->eui48, rdata->data, rdata->length);
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_eui48(ARGS_FREESTRUCT) {
- dns_rdata_eui48_t *eui48 = source;
-
- REQUIRE(source != NULL);
- REQUIRE(eui48->common.rdtype == 108);
-
- return;
-}
-
-static inline isc_result_t
-additionaldata_eui48(ARGS_ADDLDATA) {
-
- REQUIRE(rdata->type == 108);
- REQUIRE(rdata->length == 6);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_eui48(ARGS_DIGEST) {
- isc_region_t r;
-
- REQUIRE(rdata->type == 108);
- REQUIRE(rdata->length == 6);
-
- dns_rdata_toregion(rdata, &r);
-
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_eui48(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 108);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_eui48(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 108);
- REQUIRE(rdata->length == 6);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_eui48(ARGS_COMPARE) {
- return (compare_eui48(rdata1, rdata2));
-}
-
-#endif /* RDATA_GENERIC_EUI48_108_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/eui48_108.h b/contrib/bind9/lib/dns/rdata/generic/eui48_108.h
deleted file mode 100644
index 508c61fd6809..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/eui48_108.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER 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_EUI48_108_H
-#define GENERIC_EUI48_108_H 1
-
-typedef struct dns_rdata_eui48 {
- dns_rdatacommon_t common;
- unsigned char eui48[6];
-} dns_rdata_eui48_t;
-
-#endif /* GENERIC_EUI48_10k_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/eui64_109.c b/contrib/bind9/lib/dns/rdata/generic/eui64_109.c
deleted file mode 100644
index 245994fdf5c0..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/eui64_109.c
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER 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 RDATA_GENERIC_EUI64_109_C
-#define RDATA_GENERIC_EUI64_109_C
-
-#include <string.h>
-
-#define RRTYPE_EUI64_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_eui64(ARGS_FROMTEXT) {
- isc_token_t token;
- unsigned char eui64[8];
- unsigned int l0, l1, l2, l3, l4, l5, l6, l7;
- int n;
-
- REQUIRE(type == 109);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(origin);
- UNUSED(options);
- UNUSED(callbacks);
-
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- n = sscanf(DNS_AS_STR(token), "%2x-%2x-%2x-%2x-%2x-%2x-%2x-%2x",
- &l0, &l1, &l2, &l3, &l4, &l5, &l6, &l7);
- if (n != 8 || l0 > 255U || l1 > 255U || l2 > 255U || l3 > 255U ||
- l4 > 255U || l5 > 255U || l6 > 255U || l7 > 255U)
- return (DNS_R_BADEUI);
-
- eui64[0] = l0;
- eui64[1] = l1;
- eui64[2] = l2;
- eui64[3] = l3;
- eui64[4] = l4;
- eui64[5] = l5;
- eui64[6] = l6;
- eui64[7] = l7;
- return (mem_tobuffer(target, eui64, sizeof(eui64)));
-}
-
-static inline isc_result_t
-totext_eui64(ARGS_TOTEXT) {
- char buf[sizeof("xx-xx-xx-xx-xx-xx-xx-xx")];
-
- REQUIRE(rdata->type == 109);
- REQUIRE(rdata->length == 8);
-
- UNUSED(tctx);
-
- (void)snprintf(buf, sizeof(buf),
- "%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x",
- rdata->data[0], rdata->data[1],
- rdata->data[2], rdata->data[3],
- rdata->data[4], rdata->data[5],
- rdata->data[6], rdata->data[7]);
- return (str_totext(buf, target));
-}
-
-static inline isc_result_t
-fromwire_eui64(ARGS_FROMWIRE) {
- isc_region_t sregion;
-
- REQUIRE(type == 109);
-
- UNUSED(type);
- UNUSED(options);
- UNUSED(rdclass);
- UNUSED(dctx);
-
- isc_buffer_activeregion(source, &sregion);
- if (sregion.length != 8)
- return (DNS_R_FORMERR);
- isc_buffer_forward(source, sregion.length);
- return (mem_tobuffer(target, sregion.base, sregion.length));
-}
-
-static inline isc_result_t
-towire_eui64(ARGS_TOWIRE) {
-
- REQUIRE(rdata->type == 109);
- REQUIRE(rdata->length == 8);
-
- UNUSED(cctx);
-
- return (mem_tobuffer(target, rdata->data, rdata->length));
-}
-
-static inline int
-compare_eui64(ARGS_COMPARE) {
- isc_region_t region1;
- isc_region_t region2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 109);
- REQUIRE(rdata1->length == 8);
- REQUIRE(rdata2->length == 8);
-
- dns_rdata_toregion(rdata1, &region1);
- dns_rdata_toregion(rdata2, &region2);
- return (isc_region_compare(&region1, &region2));
-}
-
-static inline isc_result_t
-fromstruct_eui64(ARGS_FROMSTRUCT) {
- dns_rdata_eui64_t *eui64 = source;
-
- REQUIRE(type == 109);
- REQUIRE(source != NULL);
- REQUIRE(eui64->common.rdtype == type);
- REQUIRE(eui64->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- return (mem_tobuffer(target, eui64->eui64, sizeof(eui64->eui64)));
-}
-
-static inline isc_result_t
-tostruct_eui64(ARGS_TOSTRUCT) {
- dns_rdata_eui64_t *eui64 = target;
-
- REQUIRE(rdata->type == 109);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length == 8);
-
- UNUSED(mctx);
-
- eui64->common.rdclass = rdata->rdclass;
- eui64->common.rdtype = rdata->type;
- ISC_LINK_INIT(&eui64->common, link);
-
- memcpy(eui64->eui64, rdata->data, rdata->length);
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_eui64(ARGS_FREESTRUCT) {
- dns_rdata_eui64_t *eui64 = source;
-
- REQUIRE(source != NULL);
- REQUIRE(eui64->common.rdtype == 109);
-
- return;
-}
-
-static inline isc_result_t
-additionaldata_eui64(ARGS_ADDLDATA) {
-
- REQUIRE(rdata->type == 109);
- REQUIRE(rdata->length == 8);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_eui64(ARGS_DIGEST) {
- isc_region_t r;
-
- REQUIRE(rdata->type == 109);
- REQUIRE(rdata->length == 8);
-
- dns_rdata_toregion(rdata, &r);
-
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_eui64(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 109);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_eui64(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 109);
- REQUIRE(rdata->length == 8);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_eui64(ARGS_COMPARE) {
- return (compare_eui64(rdata1, rdata2));
-}
-
-#endif /* RDATA_GENERIC_EUI64_109_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/eui64_109.h b/contrib/bind9/lib/dns/rdata/generic/eui64_109.h
deleted file mode 100644
index 56996f8ff31b..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/eui64_109.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER 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_EUI64_109_H
-#define GENERIC_EUI64_109_H 1
-
-typedef struct dns_rdata_eui64 {
- dns_rdatacommon_t common;
- unsigned char eui64[8];
-} dns_rdata_eui64_t;
-
-#endif /* GENERIC_EUI64_10k_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/gpos_27.c b/contrib/bind9/lib/dns/rdata/generic/gpos_27.c
deleted file mode 100644
index ce71822b8237..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/gpos_27.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $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 */
-
-/* RFC1712 */
-
-#ifndef RDATA_GENERIC_GPOS_27_C
-#define RDATA_GENERIC_GPOS_27_C
-
-#define RRTYPE_GPOS_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_gpos(ARGS_FROMTEXT) {
- isc_token_t token;
- int i;
-
- REQUIRE(type == 27);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(origin);
- UNUSED(options);
- UNUSED(callbacks);
-
- for (i = 0; i < 3; i++) {
- RETERR(isc_lex_getmastertoken(lexer, &token,
- isc_tokentype_qstring,
- ISC_FALSE));
- RETTOK(txt_fromtext(&token.value.as_textregion, target));
- }
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_gpos(ARGS_TOTEXT) {
- isc_region_t region;
- int i;
-
- REQUIRE(rdata->type == 27);
- REQUIRE(rdata->length != 0);
-
- UNUSED(tctx);
-
- dns_rdata_toregion(rdata, &region);
-
- for (i = 0; i < 3; i++) {
- RETERR(txt_totext(&region, target));
- if (i != 2)
- RETERR(str_totext(" ", target));
- }
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-fromwire_gpos(ARGS_FROMWIRE) {
- int i;
-
- REQUIRE(type == 27);
-
- UNUSED(type);
- UNUSED(dctx);
- UNUSED(rdclass);
- UNUSED(options);
-
- for (i = 0; i < 3; i++)
- RETERR(txt_fromwire(source, target));
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-towire_gpos(ARGS_TOWIRE) {
-
- REQUIRE(rdata->type == 27);
- REQUIRE(rdata->length != 0);
-
- UNUSED(cctx);
-
- return (mem_tobuffer(target, rdata->data, rdata->length));
-}
-
-static inline int
-compare_gpos(ARGS_COMPARE) {
- isc_region_t r1;
- isc_region_t r2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 27);
- 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_gpos(ARGS_FROMSTRUCT) {
- dns_rdata_gpos_t *gpos = source;
-
- REQUIRE(type == 27);
- REQUIRE(source != NULL);
- REQUIRE(gpos->common.rdtype == type);
- REQUIRE(gpos->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- RETERR(uint8_tobuffer(gpos->long_len, target));
- RETERR(mem_tobuffer(target, gpos->longitude, gpos->long_len));
- RETERR(uint8_tobuffer(gpos->lat_len, target));
- RETERR(mem_tobuffer(target, gpos->latitude, gpos->lat_len));
- RETERR(uint8_tobuffer(gpos->alt_len, target));
- return (mem_tobuffer(target, gpos->altitude, gpos->alt_len));
-}
-
-static inline isc_result_t
-tostruct_gpos(ARGS_TOSTRUCT) {
- dns_rdata_gpos_t *gpos = target;
- isc_region_t region;
-
- REQUIRE(rdata->type == 27);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- gpos->common.rdclass = rdata->rdclass;
- gpos->common.rdtype = rdata->type;
- ISC_LINK_INIT(&gpos->common, link);
-
- dns_rdata_toregion(rdata, &region);
- gpos->long_len = uint8_fromregion(&region);
- isc_region_consume(&region, 1);
- gpos->longitude = mem_maybedup(mctx, region.base, gpos->long_len);
- if (gpos->longitude == NULL)
- return (ISC_R_NOMEMORY);
- isc_region_consume(&region, gpos->long_len);
-
- gpos->lat_len = uint8_fromregion(&region);
- isc_region_consume(&region, 1);
- gpos->latitude = mem_maybedup(mctx, region.base, gpos->lat_len);
- if (gpos->latitude == NULL)
- goto cleanup_longitude;
- isc_region_consume(&region, gpos->lat_len);
-
- gpos->alt_len = uint8_fromregion(&region);
- isc_region_consume(&region, 1);
- if (gpos->lat_len > 0) {
- gpos->altitude =
- mem_maybedup(mctx, region.base, gpos->alt_len);
- if (gpos->altitude == NULL)
- goto cleanup_latitude;
- } else
- gpos->altitude = NULL;
-
- gpos->mctx = mctx;
- return (ISC_R_SUCCESS);
-
- cleanup_latitude:
- if (mctx != NULL && gpos->longitude != NULL)
- isc_mem_free(mctx, gpos->longitude);
-
- cleanup_longitude:
- if (mctx != NULL && gpos->latitude != NULL)
- isc_mem_free(mctx, gpos->latitude);
- return (ISC_R_NOMEMORY);
-}
-
-static inline void
-freestruct_gpos(ARGS_FREESTRUCT) {
- dns_rdata_gpos_t *gpos = source;
-
- REQUIRE(source != NULL);
- REQUIRE(gpos->common.rdtype == 27);
-
- if (gpos->mctx == NULL)
- return;
-
- if (gpos->longitude != NULL)
- isc_mem_free(gpos->mctx, gpos->longitude);
- if (gpos->latitude != NULL)
- isc_mem_free(gpos->mctx, gpos->latitude);
- if (gpos->altitude != NULL)
- isc_mem_free(gpos->mctx, gpos->altitude);
- gpos->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_gpos(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 27);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_gpos(ARGS_DIGEST) {
- isc_region_t r;
-
- REQUIRE(rdata->type == 27);
-
- dns_rdata_toregion(rdata, &r);
-
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_gpos(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 27);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_gpos(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 27);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_gpos(ARGS_COMPARE) {
- return (compare_gpos(rdata1, rdata2));
-}
-
-#endif /* RDATA_GENERIC_GPOS_27_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/gpos_27.h b/contrib/bind9/lib/dns/rdata/generic/gpos_27.h
deleted file mode 100644
index f5df4fa18898..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/gpos_27.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef GENERIC_GPOS_27_H
-#define GENERIC_GPOS_27_H 1
-
-/* $Id: gpos_27.h,v 1.17 2007/06/19 23:47:17 tbox Exp $ */
-
-/*!
- * \brief per RFC1712 */
-
-typedef struct dns_rdata_gpos {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- char *longitude;
- char *latitude;
- char *altitude;
- isc_uint8_t long_len;
- isc_uint8_t lat_len;
- isc_uint8_t alt_len;
-} dns_rdata_gpos_t;
-
-#endif /* GENERIC_GPOS_27_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/hinfo_13.c b/contrib/bind9/lib/dns/rdata/generic/hinfo_13.c
deleted file mode 100644
index 10b4fec79dea..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/hinfo_13.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $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.
- */
-
-#ifndef RDATA_GENERIC_HINFO_13_C
-#define RDATA_GENERIC_HINFO_13_C
-
-#define RRTYPE_HINFO_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_hinfo(ARGS_FROMTEXT) {
- isc_token_t token;
- int i;
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(origin);
- UNUSED(options);
- UNUSED(callbacks);
-
- REQUIRE(type == 13);
-
- for (i = 0; i < 2; i++) {
- RETERR(isc_lex_getmastertoken(lexer, &token,
- isc_tokentype_qstring,
- ISC_FALSE));
- RETTOK(txt_fromtext(&token.value.as_textregion, target));
- }
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_hinfo(ARGS_TOTEXT) {
- isc_region_t region;
-
- UNUSED(tctx);
-
- REQUIRE(rdata->type == 13);
- REQUIRE(rdata->length != 0);
-
- dns_rdata_toregion(rdata, &region);
- RETERR(txt_totext(&region, target));
- RETERR(str_totext(" ", target));
- return (txt_totext(&region, target));
-}
-
-static inline isc_result_t
-fromwire_hinfo(ARGS_FROMWIRE) {
-
- REQUIRE(type == 13);
-
- UNUSED(type);
- UNUSED(dctx);
- UNUSED(rdclass);
- UNUSED(options);
-
- RETERR(txt_fromwire(source, target));
- return (txt_fromwire(source, target));
-}
-
-static inline isc_result_t
-towire_hinfo(ARGS_TOWIRE) {
-
- UNUSED(cctx);
-
- REQUIRE(rdata->type == 13);
- REQUIRE(rdata->length != 0);
-
- return (mem_tobuffer(target, rdata->data, rdata->length));
-}
-
-static inline int
-compare_hinfo(ARGS_COMPARE) {
- isc_region_t r1;
- isc_region_t r2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 13);
- 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_hinfo(ARGS_FROMSTRUCT) {
- dns_rdata_hinfo_t *hinfo = source;
-
- REQUIRE(type == 13);
- REQUIRE(source != NULL);
- REQUIRE(hinfo->common.rdtype == type);
- REQUIRE(hinfo->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- RETERR(uint8_tobuffer(hinfo->cpu_len, target));
- RETERR(mem_tobuffer(target, hinfo->cpu, hinfo->cpu_len));
- RETERR(uint8_tobuffer(hinfo->os_len, target));
- return (mem_tobuffer(target, hinfo->os, hinfo->os_len));
-}
-
-static inline isc_result_t
-tostruct_hinfo(ARGS_TOSTRUCT) {
- dns_rdata_hinfo_t *hinfo = target;
- isc_region_t region;
-
- REQUIRE(rdata->type == 13);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- hinfo->common.rdclass = rdata->rdclass;
- hinfo->common.rdtype = rdata->type;
- ISC_LINK_INIT(&hinfo->common, link);
-
- dns_rdata_toregion(rdata, &region);
- hinfo->cpu_len = uint8_fromregion(&region);
- isc_region_consume(&region, 1);
- hinfo->cpu = mem_maybedup(mctx, region.base, hinfo->cpu_len);
- if (hinfo->cpu == NULL)
- return (ISC_R_NOMEMORY);
- isc_region_consume(&region, hinfo->cpu_len);
-
- hinfo->os_len = uint8_fromregion(&region);
- isc_region_consume(&region, 1);
- hinfo->os = mem_maybedup(mctx, region.base, hinfo->os_len);
- if (hinfo->os == NULL)
- goto cleanup;
-
- hinfo->mctx = mctx;
- return (ISC_R_SUCCESS);
-
- cleanup:
- if (mctx != NULL && hinfo->cpu != NULL)
- isc_mem_free(mctx, hinfo->cpu);
- return (ISC_R_NOMEMORY);
-}
-
-static inline void
-freestruct_hinfo(ARGS_FREESTRUCT) {
- dns_rdata_hinfo_t *hinfo = source;
-
- REQUIRE(source != NULL);
-
- if (hinfo->mctx == NULL)
- return;
-
- if (hinfo->cpu != NULL)
- isc_mem_free(hinfo->mctx, hinfo->cpu);
- if (hinfo->os != NULL)
- isc_mem_free(hinfo->mctx, hinfo->os);
- hinfo->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_hinfo(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 13);
-
- UNUSED(add);
- UNUSED(arg);
- UNUSED(rdata);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_hinfo(ARGS_DIGEST) {
- isc_region_t r;
-
- REQUIRE(rdata->type == 13);
-
- dns_rdata_toregion(rdata, &r);
-
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_hinfo(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 13);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_hinfo(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 13);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_hinfo(ARGS_COMPARE) {
- return (compare_hinfo(rdata1, rdata2));
-}
-#endif /* RDATA_GENERIC_HINFO_13_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/hinfo_13.h b/contrib/bind9/lib/dns/rdata/generic/hinfo_13.h
deleted file mode 100644
index 66766dfe041b..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/hinfo_13.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef GENERIC_HINFO_13_H
-#define GENERIC_HINFO_13_H 1
-
-/* $Id: hinfo_13.h,v 1.25 2007/06/19 23:47:17 tbox Exp $ */
-
-typedef struct dns_rdata_hinfo {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- char *cpu;
- char *os;
- isc_uint8_t cpu_len;
- isc_uint8_t os_len;
-} dns_rdata_hinfo_t;
-
-#endif /* GENERIC_HINFO_13_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/hip_55.c b/contrib/bind9/lib/dns/rdata/generic/hip_55.c
deleted file mode 100644
index 5a5140f8ddd6..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/hip_55.c
+++ /dev/null
@@ -1,506 +0,0 @@
-/*
- * 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/contrib/bind9/lib/dns/rdata/generic/hip_55.h b/contrib/bind9/lib/dns/rdata/generic/hip_55.h
deleted file mode 100644
index 69f2eba88046..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/hip_55.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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/contrib/bind9/lib/dns/rdata/generic/ipseckey_45.c b/contrib/bind9/lib/dns/rdata/generic/ipseckey_45.c
deleted file mode 100644
index 1d2508c42e25..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/ipseckey_45.c
+++ /dev/null
@@ -1,501 +0,0 @@
-/*
- * Copyright (C) 2005, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-#ifndef RDATA_GENERIC_IPSECKEY_45_C
-#define RDATA_GENERIC_IPSECKEY_45_C
-
-#include <string.h>
-
-#include <isc/net.h>
-
-#define RRTYPE_IPSECKEY_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_ipseckey(ARGS_FROMTEXT) {
- isc_token_t token;
- dns_name_t name;
- isc_buffer_t buffer;
- unsigned int gateway;
- struct in_addr addr;
- unsigned char addr6[16];
- isc_region_t region;
-
- REQUIRE(type == 45);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(callbacks);
-
- /*
- * Precedence.
- */
- 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));
-
- /*
- * Gateway type.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if (token.value.as_ulong > 0x3U)
- RETTOK(ISC_R_RANGE);
- RETERR(uint8_tobuffer(token.value.as_ulong, target));
- gateway = token.value.as_ulong;
-
- /*
- * 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));
-
- /*
- * Gateway.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
-
- switch (gateway) {
- case 0:
- if (strcmp(DNS_AS_STR(token), ".") != 0)
- RETTOK(DNS_R_SYNTAX);
- break;
-
- case 1:
- if (getquad(DNS_AS_STR(token), &addr, lexer, callbacks) != 1)
- RETTOK(DNS_R_BADDOTTEDQUAD);
- isc_buffer_availableregion(target, &region);
- if (region.length < 4)
- return (ISC_R_NOSPACE);
- memcpy(region.base, &addr, 4);
- isc_buffer_add(target, 4);
- break;
-
- case 2:
- if (inet_pton(AF_INET6, DNS_AS_STR(token), addr6) != 1)
- RETTOK(DNS_R_BADAAAA);
- isc_buffer_availableregion(target, &region);
- if (region.length < 16)
- return (ISC_R_NOSPACE);
- memcpy(region.base, addr6, 16);
- isc_buffer_add(target, 16);
- break;
-
- case 3:
- dns_name_init(&name, NULL);
- buffer_fromregion(&buffer, &token.value.as_region);
- origin = (origin != NULL) ? origin : dns_rootname;
- RETTOK(dns_name_fromtext(&name, &buffer, origin,
- options, target));
- break;
- }
-
- /*
- * Public key.
- */
- return (isc_base64_tobuffer(lexer, target, -1));
-}
-
-static inline isc_result_t
-totext_ipseckey(ARGS_TOTEXT) {
- isc_region_t region;
- dns_name_t name;
- char buf[sizeof("255 ")];
- unsigned short num;
- unsigned short gateway;
-
- REQUIRE(rdata->type == 45);
- REQUIRE(rdata->length >= 3);
-
- dns_name_init(&name, NULL);
-
- if (rdata->data[1] > 3U)
- return (ISC_R_NOTIMPLEMENTED);
-
- if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
- RETERR(str_totext("( ", target));
-
- /*
- * Precedence.
- */
- dns_rdata_toregion(rdata, &region);
- num = uint8_fromregion(&region);
- isc_region_consume(&region, 1);
- sprintf(buf, "%u ", num);
- RETERR(str_totext(buf, target));
-
- /*
- * Gateway type.
- */
- gateway = uint8_fromregion(&region);
- isc_region_consume(&region, 1);
- sprintf(buf, "%u ", gateway);
- RETERR(str_totext(buf, target));
-
- /*
- * Algorithm.
- */
- num = uint8_fromregion(&region);
- isc_region_consume(&region, 1);
- sprintf(buf, "%u ", num);
- RETERR(str_totext(buf, target));
-
- /*
- * Gateway.
- */
- switch (gateway) {
- case 0:
- RETERR(str_totext(".", target));
- break;
-
- case 1:
- RETERR(inet_totext(AF_INET, &region, target));
- isc_region_consume(&region, 4);
- break;
-
- case 2:
- RETERR(inet_totext(AF_INET6, &region, target));
- isc_region_consume(&region, 16);
- break;
-
- case 3:
- dns_name_fromregion(&name, &region);
- RETERR(dns_name_totext(&name, ISC_FALSE, target));
- isc_region_consume(&region, name_length(&name));
- break;
- }
-
- /*
- * Key.
- */
- if (region.length > 0U) {
- RETERR(str_totext(tctx->linebreak, target));
- if (tctx->width == 0) /* No splitting */
- RETERR(isc_base64_totext(&region, 60, "", target));
- else
- RETERR(isc_base64_totext(&region, tctx->width - 2,
- tctx->linebreak, target));
- }
-
- if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
- RETERR(str_totext(" )", target));
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-fromwire_ipseckey(ARGS_FROMWIRE) {
- dns_name_t name;
- isc_region_t region;
-
- REQUIRE(type == 45);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
-
- dns_name_init(&name, NULL);
-
- isc_buffer_activeregion(source, &region);
- if (region.length < 3)
- return (ISC_R_UNEXPECTEDEND);
-
- switch (region.base[1]) {
- case 0:
- isc_buffer_forward(source, region.length);
- return (mem_tobuffer(target, region.base, region.length));
-
- case 1:
- if (region.length < 7)
- return (ISC_R_UNEXPECTEDEND);
- isc_buffer_forward(source, region.length);
- return (mem_tobuffer(target, region.base, region.length));
-
- case 2:
- if (region.length < 19)
- return (ISC_R_UNEXPECTEDEND);
- isc_buffer_forward(source, region.length);
- return (mem_tobuffer(target, region.base, region.length));
-
- case 3:
- RETERR(mem_tobuffer(target, region.base, 3));
- isc_buffer_forward(source, 3);
- RETERR(dns_name_fromwire(&name, source, dctx, options, target));
- isc_buffer_activeregion(source, &region);
- isc_buffer_forward(source, region.length);
- return(mem_tobuffer(target, region.base, region.length));
-
- default:
- return (ISC_R_NOTIMPLEMENTED);
- }
-}
-
-static inline isc_result_t
-towire_ipseckey(ARGS_TOWIRE) {
- isc_region_t region;
-
- REQUIRE(rdata->type == 45);
- REQUIRE(rdata->length != 0);
-
- UNUSED(cctx);
-
- dns_rdata_toregion(rdata, &region);
- return (mem_tobuffer(target, region.base, region.length));
-}
-
-static inline int
-compare_ipseckey(ARGS_COMPARE) {
- isc_region_t region1;
- isc_region_t region2;
-
- 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);
-
- return (isc_region_compare(&region1, &region2));
-}
-
-static inline isc_result_t
-fromstruct_ipseckey(ARGS_FROMSTRUCT) {
- dns_rdata_ipseckey_t *ipseckey = source;
- isc_region_t region;
- isc_uint32_t n;
-
- REQUIRE(type == 45);
- REQUIRE(source != NULL);
- REQUIRE(ipseckey->common.rdtype == type);
- REQUIRE(ipseckey->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- if (ipseckey->gateway_type > 3U)
- return (ISC_R_NOTIMPLEMENTED);
-
- RETERR(uint8_tobuffer(ipseckey->precedence, target));
- RETERR(uint8_tobuffer(ipseckey->gateway_type, target));
- RETERR(uint8_tobuffer(ipseckey->algorithm, target));
-
- switch (ipseckey->gateway_type) {
- case 0:
- break;
-
- case 1:
- n = ntohl(ipseckey->in_addr.s_addr);
- RETERR(uint32_tobuffer(n, target));
- break;
-
- case 2:
- RETERR(mem_tobuffer(target, ipseckey->in6_addr.s6_addr, 16));
- break;
-
- case 3:
- dns_name_toregion(&ipseckey->gateway, &region);
- RETERR(isc_buffer_copyregion(target, &region));
- break;
- }
-
- return (mem_tobuffer(target, ipseckey->key, ipseckey->keylength));
-}
-
-static inline isc_result_t
-tostruct_ipseckey(ARGS_TOSTRUCT) {
- isc_region_t region;
- dns_rdata_ipseckey_t *ipseckey = target;
- dns_name_t name;
- isc_uint32_t n;
-
- REQUIRE(rdata->type == 45);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length >= 3);
-
- if (rdata->data[1] > 3U)
- return (ISC_R_NOTIMPLEMENTED);
-
- ipseckey->common.rdclass = rdata->rdclass;
- ipseckey->common.rdtype = rdata->type;
- ISC_LINK_INIT(&ipseckey->common, link);
-
- dns_name_init(&name, NULL);
- dns_rdata_toregion(rdata, &region);
-
- ipseckey->precedence = uint8_fromregion(&region);
- isc_region_consume(&region, 1);
-
- ipseckey->gateway_type = uint8_fromregion(&region);
- isc_region_consume(&region, 1);
-
- ipseckey->algorithm = uint8_fromregion(&region);
- isc_region_consume(&region, 1);
-
- switch (ipseckey->gateway_type) {
- case 0:
- break;
-
- case 1:
- n = uint32_fromregion(&region);
- ipseckey->in_addr.s_addr = htonl(n);
- isc_region_consume(&region, 4);
- break;
-
- case 2:
- memcpy(ipseckey->in6_addr.s6_addr, region.base, 16);
- isc_region_consume(&region, 16);
- break;
-
- case 3:
- dns_name_init(&ipseckey->gateway, NULL);
- dns_name_fromregion(&name, &region);
- RETERR(name_duporclone(&name, mctx, &ipseckey->gateway));
- isc_region_consume(&region, name_length(&name));
- break;
- }
-
- ipseckey->keylength = region.length;
- if (ipseckey->keylength != 0U) {
- ipseckey->key = mem_maybedup(mctx, region.base,
- ipseckey->keylength);
- if (ipseckey->key == NULL) {
- if (ipseckey->gateway_type == 3)
- dns_name_free(&ipseckey->gateway,
- ipseckey->mctx);
- return (ISC_R_NOMEMORY);
- }
- } else
- ipseckey->key = NULL;
-
- ipseckey->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_ipseckey(ARGS_FREESTRUCT) {
- dns_rdata_ipseckey_t *ipseckey = source;
-
- REQUIRE(source != NULL);
- REQUIRE(ipseckey->common.rdtype == 45);
-
- if (ipseckey->mctx == NULL)
- return;
-
- if (ipseckey->gateway_type == 3)
- dns_name_free(&ipseckey->gateway, ipseckey->mctx);
-
- if (ipseckey->key != NULL)
- isc_mem_free(ipseckey->mctx, ipseckey->key);
-
- ipseckey->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_ipseckey(ARGS_ADDLDATA) {
-
- REQUIRE(rdata->type == 45);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_ipseckey(ARGS_DIGEST) {
- isc_region_t region;
-
- REQUIRE(rdata->type == 45);
-
- dns_rdata_toregion(rdata, &region);
- return ((digest)(arg, &region));
-}
-
-static inline isc_boolean_t
-checkowner_ipseckey(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 45);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_ipseckey(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 45);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- 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/contrib/bind9/lib/dns/rdata/generic/ipseckey_45.h b/contrib/bind9/lib/dns/rdata/generic/ipseckey_45.h
deleted file mode 100644
index 2a6201f0b716..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/ipseckey_45.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2005, 2007 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: ipseckey_45.h,v 1.4 2007/06/19 23:47:17 tbox Exp $ */
-
-#ifndef GENERIC_IPSECKEY_45_H
-#define GENERIC_IPSECKEY_45_H 1
-
-typedef struct dns_rdata_ipseckey {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- isc_uint8_t precedence;
- isc_uint8_t gateway_type;
- isc_uint8_t algorithm;
- struct in_addr in_addr; /* gateway type 1 */
- struct in6_addr in6_addr; /* gateway type 2 */
- dns_name_t gateway; /* gateway type 3 */
- unsigned char *key;
- isc_uint16_t keylength;
-} dns_rdata_ipseckey_t;
-
-#endif /* GENERIC_IPSECKEY_45_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/isdn_20.c b/contrib/bind9/lib/dns/rdata/generic/isdn_20.c
deleted file mode 100644
index 5aac73f3713f..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/isdn_20.c
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $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 */
-
-/* RFC1183 */
-
-#ifndef RDATA_GENERIC_ISDN_20_C
-#define RDATA_GENERIC_ISDN_20_C
-
-#define RRTYPE_ISDN_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_isdn(ARGS_FROMTEXT) {
- isc_token_t token;
-
- REQUIRE(type == 20);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(origin);
- UNUSED(options);
- UNUSED(callbacks);
-
- /* ISDN-address */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring,
- ISC_FALSE));
- RETTOK(txt_fromtext(&token.value.as_textregion, target));
-
- /* sa: optional */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring,
- ISC_TRUE));
- if (token.type != isc_tokentype_string &&
- token.type != isc_tokentype_qstring) {
- isc_lex_ungettoken(lexer, &token);
- return (ISC_R_SUCCESS);
- }
- RETTOK(txt_fromtext(&token.value.as_textregion, target));
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_isdn(ARGS_TOTEXT) {
- isc_region_t region;
-
- REQUIRE(rdata->type == 20);
- REQUIRE(rdata->length != 0);
-
- UNUSED(tctx);
-
- dns_rdata_toregion(rdata, &region);
- RETERR(txt_totext(&region, target));
- if (region.length == 0)
- return (ISC_R_SUCCESS);
- RETERR(str_totext(" ", target));
- return (txt_totext(&region, target));
-}
-
-static inline isc_result_t
-fromwire_isdn(ARGS_FROMWIRE) {
- REQUIRE(type == 20);
-
- UNUSED(type);
- UNUSED(dctx);
- UNUSED(rdclass);
- UNUSED(options);
-
- RETERR(txt_fromwire(source, target));
- if (buffer_empty(source))
- return (ISC_R_SUCCESS);
- return (txt_fromwire(source, target));
-}
-
-static inline isc_result_t
-towire_isdn(ARGS_TOWIRE) {
- UNUSED(cctx);
-
- REQUIRE(rdata->type == 20);
- REQUIRE(rdata->length != 0);
-
- return (mem_tobuffer(target, rdata->data, rdata->length));
-}
-
-static inline int
-compare_isdn(ARGS_COMPARE) {
- isc_region_t r1;
- isc_region_t r2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 20);
- 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_isdn(ARGS_FROMSTRUCT) {
- dns_rdata_isdn_t *isdn = source;
-
- REQUIRE(type == 20);
- REQUIRE(source != NULL);
- REQUIRE(isdn->common.rdtype == type);
- REQUIRE(isdn->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- RETERR(uint8_tobuffer(isdn->isdn_len, target));
- RETERR(mem_tobuffer(target, isdn->isdn, isdn->isdn_len));
- RETERR(uint8_tobuffer(isdn->subaddress_len, target));
- return (mem_tobuffer(target, isdn->subaddress, isdn->subaddress_len));
-}
-
-static inline isc_result_t
-tostruct_isdn(ARGS_TOSTRUCT) {
- dns_rdata_isdn_t *isdn = target;
- isc_region_t r;
-
- REQUIRE(rdata->type == 20);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- isdn->common.rdclass = rdata->rdclass;
- isdn->common.rdtype = rdata->type;
- ISC_LINK_INIT(&isdn->common, link);
-
- dns_rdata_toregion(rdata, &r);
-
- isdn->isdn_len = uint8_fromregion(&r);
- isc_region_consume(&r, 1);
- isdn->isdn = mem_maybedup(mctx, r.base, isdn->isdn_len);
- if (isdn->isdn == NULL)
- return (ISC_R_NOMEMORY);
- isc_region_consume(&r, isdn->isdn_len);
-
- isdn->subaddress_len = uint8_fromregion(&r);
- isc_region_consume(&r, 1);
- isdn->subaddress = mem_maybedup(mctx, r.base, isdn->subaddress_len);
- if (isdn->subaddress == NULL)
- goto cleanup;
-
- isdn->mctx = mctx;
- return (ISC_R_SUCCESS);
-
- cleanup:
- if (mctx != NULL && isdn->isdn != NULL)
- isc_mem_free(mctx, isdn->isdn);
- return (ISC_R_NOMEMORY);
-}
-
-static inline void
-freestruct_isdn(ARGS_FREESTRUCT) {
- dns_rdata_isdn_t *isdn = source;
-
- REQUIRE(source != NULL);
-
- if (isdn->mctx == NULL)
- return;
-
- if (isdn->isdn != NULL)
- isc_mem_free(isdn->mctx, isdn->isdn);
- if (isdn->subaddress != NULL)
- isc_mem_free(isdn->mctx, isdn->subaddress);
- isdn->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_isdn(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 20);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_isdn(ARGS_DIGEST) {
- isc_region_t r;
-
- REQUIRE(rdata->type == 20);
-
- dns_rdata_toregion(rdata, &r);
-
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_isdn(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 20);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_isdn(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 20);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_isdn(ARGS_COMPARE) {
- return (compare_isdn(rdata1, rdata2));
-}
-
-#endif /* RDATA_GENERIC_ISDN_20_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/isdn_20.h b/contrib/bind9/lib/dns/rdata/generic/isdn_20.h
deleted file mode 100644
index a1f65ca4d99d..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/isdn_20.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef GENERIC_ISDN_20_H
-#define GENERIC_ISDN_20_H 1
-
-/* $Id: isdn_20.h,v 1.18 2007/06/19 23:47:17 tbox Exp $ */
-
-/*!
- * \brief Per RFC1183 */
-
-typedef struct dns_rdata_isdn {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- char *isdn;
- char *subaddress;
- isc_uint8_t isdn_len;
- isc_uint8_t subaddress_len;
-} dns_rdata_isdn_t;
-
-#endif /* GENERIC_ISDN_20_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/key_25.c b/contrib/bind9/lib/dns/rdata/generic/key_25.c
deleted file mode 100644
index 1d0ba83a9b31..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/key_25.c
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/*
- * Reviewed: Wed Mar 15 16:47:10 PST 2000 by halley.
- */
-
-/* RFC2535 */
-
-#ifndef RDATA_GENERIC_KEY_25_C
-#define RDATA_GENERIC_KEY_25_C
-
-#include <dst/dst.h>
-
-#define RRTYPE_KEY_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_key(ARGS_FROMTEXT) {
- isc_token_t token;
- dns_secalg_t alg;
- dns_secproto_t proto;
- dns_keyflags_t flags;
-
- REQUIRE(type == 25);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(origin);
- UNUSED(options);
- UNUSED(callbacks);
-
- /* 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_key(ARGS_TOTEXT) {
- isc_region_t sr;
- char buf[sizeof("64000")];
- unsigned int flags;
- unsigned char algorithm;
- char namebuf[DNS_NAME_FORMATSIZE];
-
- REQUIRE(rdata->type == 25);
- REQUIRE(rdata->length != 0);
-
- dns_rdata_toregion(rdata, &sr);
-
- /* 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);
-
- if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0 &&
- algorithm == DNS_KEYALG_PRIVATEDNS) {
- dns_name_t name;
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &sr);
- dns_name_format(&name, namebuf, sizeof(namebuf));
- } else
- namebuf[0] = 0;
-
- /* key */
- if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
- RETERR(str_totext(" (", target));
- RETERR(str_totext(tctx->linebreak, target));
- if (tctx->width == 0) /* No splitting */
- RETERR(isc_base64_totext(&sr, 60, "", target));
- else
- RETERR(isc_base64_totext(&sr, tctx->width - 2,
- tctx->linebreak, target));
-
- if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 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_RRCOMMENT) != 0) {
- isc_region_t tmpr;
-
- RETERR(str_totext(" ; key id = ", target));
- dns_rdata_toregion(rdata, &tmpr);
- sprintf(buf, "%u", dst_region_computeid(&tmpr, algorithm));
- RETERR(str_totext(buf, target));
- if (algorithm == DNS_KEYALG_PRIVATEDNS) {
- RETERR(str_totext(tctx->linebreak, target));
- RETERR(str_totext("; alg = ", target));
- RETERR(str_totext(namebuf, target));
- }
- }
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-fromwire_key(ARGS_FROMWIRE) {
- unsigned char algorithm;
- isc_region_t sr;
-
- REQUIRE(type == 25);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(dctx);
- UNUSED(options);
-
- isc_buffer_activeregion(source, &sr);
- 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));
-}
-
-static inline isc_result_t
-towire_key(ARGS_TOWIRE) {
- isc_region_t sr;
-
- REQUIRE(rdata->type == 25);
- REQUIRE(rdata->length != 0);
-
- UNUSED(cctx);
-
- dns_rdata_toregion(rdata, &sr);
- return (mem_tobuffer(target, sr.base, sr.length));
-}
-
-static inline int
-compare_key(ARGS_COMPARE) {
- isc_region_t r1;
- isc_region_t r2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 25);
- 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_key(ARGS_FROMSTRUCT) {
- dns_rdata_key_t *key = source;
-
- REQUIRE(type == 25);
- REQUIRE(source != NULL);
- REQUIRE(key->common.rdtype == type);
- REQUIRE(key->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- /* Flags */
- RETERR(uint16_tobuffer(key->flags, target));
-
- /* Protocol */
- RETERR(uint8_tobuffer(key->protocol, target));
-
- /* Algorithm */
- RETERR(uint8_tobuffer(key->algorithm, target));
-
- /* Data */
- return (mem_tobuffer(target, key->data, key->datalen));
-}
-
-static inline isc_result_t
-tostruct_key(ARGS_TOSTRUCT) {
- dns_rdata_key_t *key = target;
- isc_region_t sr;
-
- REQUIRE(rdata->type == 25);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- key->common.rdclass = rdata->rdclass;
- key->common.rdtype = rdata->type;
- ISC_LINK_INIT(&key->common, link);
-
- dns_rdata_toregion(rdata, &sr);
-
- /* Flags */
- if (sr.length < 2)
- return (ISC_R_UNEXPECTEDEND);
- key->flags = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
-
- /* Protocol */
- if (sr.length < 1)
- return (ISC_R_UNEXPECTEDEND);
- key->protocol = uint8_fromregion(&sr);
- isc_region_consume(&sr, 1);
-
- /* Algorithm */
- if (sr.length < 1)
- return (ISC_R_UNEXPECTEDEND);
- key->algorithm = uint8_fromregion(&sr);
- isc_region_consume(&sr, 1);
-
- /* Data */
- key->datalen = sr.length;
- key->data = mem_maybedup(mctx, sr.base, key->datalen);
- if (key->data == NULL)
- return (ISC_R_NOMEMORY);
-
- key->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_key(ARGS_FREESTRUCT) {
- dns_rdata_key_t *key = (dns_rdata_key_t *) source;
-
- REQUIRE(source != NULL);
- REQUIRE(key->common.rdtype == 25);
-
- if (key->mctx == NULL)
- return;
-
- if (key->data != NULL)
- isc_mem_free(key->mctx, key->data);
- key->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_key(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 25);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_key(ARGS_DIGEST) {
- isc_region_t r;
-
- REQUIRE(rdata->type == 25);
-
- dns_rdata_toregion(rdata, &r);
-
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_key(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 25);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_key(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 25);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_key(ARGS_COMPARE) {
- return (compare_key(rdata1, rdata2));
-}
-
-#endif /* RDATA_GENERIC_KEY_25_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/key_25.h b/contrib/bind9/lib/dns/rdata/generic/key_25.h
deleted file mode 100644
index bcf9cb6a22bf..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/key_25.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef GENERIC_KEY_25_H
-#define GENERIC_KEY_25_H 1
-
-/* $Id: key_25.h,v 1.19 2007/06/19 23:47:17 tbox Exp $ */
-
-/*!
- * \brief Per RFC2535 */
-
-typedef struct dns_rdata_key_t {
- dns_rdatacommon_t common;
- isc_mem_t * mctx;
- isc_uint16_t flags;
- isc_uint8_t protocol;
- isc_uint8_t algorithm;
- isc_uint16_t datalen;
- unsigned char * data;
-} dns_rdata_key_t;
-
-
-#endif /* GENERIC_KEY_25_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/keydata_65533.c b/contrib/bind9/lib/dns/rdata/generic/keydata_65533.c
deleted file mode 100644
index a2d83f456e49..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/keydata_65533.c
+++ /dev/null
@@ -1,395 +0,0 @@
-/*
- * Copyright (C) 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-#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;
- char algbuf[DNS_NAME_FORMATSIZE];
- const char *keyinfo;
-
- 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));
- if ((flags & DNS_KEYFLAG_KSK) != 0) {
- if (flags & DNS_KEYFLAG_REVOKE)
- keyinfo = "revoked KSK";
- else
- keyinfo = "KSK";
- } else
- keyinfo = "ZSK";
-
- /* protocol */
- sprintf(buf, "%u", sr.base[0]);
- 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));
- if (tctx->width == 0) /* No splitting */
- RETERR(isc_base64_totext(&sr, 60, "", target));
- else
- RETERR(isc_base64_totext(&sr, tctx->width - 2,
- tctx->linebreak, target));
-
- if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 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_RRCOMMENT) != 0) {
- isc_region_t tmpr;
-
- RETERR(str_totext(" ; ", target));
- RETERR(str_totext(keyinfo, target));
- dns_secalg_format((dns_secalg_t) algorithm, algbuf,
- sizeof(algbuf));
- RETERR(str_totext("; alg = ", target));
- RETERR(str_totext(algbuf, target));
- RETERR(str_totext("; key id = ", target));
- dns_rdata_toregion(rdata, &tmpr);
- /* Skip over refresh, addhd, and removehd */
- isc_region_consume(&tmpr, 12);
- 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 < 16)
- 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/contrib/bind9/lib/dns/rdata/generic/keydata_65533.h b/contrib/bind9/lib/dns/rdata/generic/keydata_65533.h
deleted file mode 100644
index 8db827ecd399..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/keydata_65533.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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/contrib/bind9/lib/dns/rdata/generic/l32_105.c b/contrib/bind9/lib/dns/rdata/generic/l32_105.c
deleted file mode 100644
index 763ddb953fed..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/l32_105.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER 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 RDATA_GENERIC_L32_105_C
-#define RDATA_GENERIC_L32_105_C
-
-#include <string.h>
-
-#include <isc/net.h>
-
-#define RRTYPE_L32_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_l32(ARGS_FROMTEXT) {
- isc_token_t token;
- struct in_addr addr;
- isc_region_t region;
-
- REQUIRE(type == 105);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(origin);
- UNUSED(options);
- UNUSED(callbacks);
-
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if (token.value.as_ulong > 0xffffU)
- RETTOK(ISC_R_RANGE);
- RETERR(uint16_tobuffer(token.value.as_ulong, target));
-
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
-
- if (getquad(DNS_AS_STR(token), &addr, lexer, callbacks) != 1)
- RETTOK(DNS_R_BADDOTTEDQUAD);
- isc_buffer_availableregion(target, &region);
- if (region.length < 4)
- return (ISC_R_NOSPACE);
- memcpy(region.base, &addr, 4);
- isc_buffer_add(target, 4);
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_l32(ARGS_TOTEXT) {
- isc_region_t region;
- char buf[sizeof("65000")];
- unsigned short num;
-
- REQUIRE(rdata->type == 105);
- REQUIRE(rdata->length == 6);
-
- UNUSED(tctx);
-
- dns_rdata_toregion(rdata, &region);
- num = uint16_fromregion(&region);
- isc_region_consume(&region, 2);
- sprintf(buf, "%u", num);
- RETERR(str_totext(buf, target));
-
- RETERR(str_totext(" ", target));
-
- return (inet_totext(AF_INET, &region, target));
-}
-
-static inline isc_result_t
-fromwire_l32(ARGS_FROMWIRE) {
- isc_region_t sregion;
-
- REQUIRE(type == 105);
-
- UNUSED(type);
- UNUSED(options);
- UNUSED(rdclass);
- UNUSED(dctx);
-
- isc_buffer_activeregion(source, &sregion);
- if (sregion.length != 6)
- return (DNS_R_FORMERR);
- isc_buffer_forward(source, sregion.length);
- return (mem_tobuffer(target, sregion.base, sregion.length));
-}
-
-static inline isc_result_t
-towire_l32(ARGS_TOWIRE) {
-
- REQUIRE(rdata->type == 105);
- REQUIRE(rdata->length == 6);
-
- UNUSED(cctx);
-
- return (mem_tobuffer(target, rdata->data, rdata->length));
-}
-
-static inline int
-compare_l32(ARGS_COMPARE) {
- isc_region_t region1;
- isc_region_t region2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 105);
- REQUIRE(rdata1->length == 6);
- REQUIRE(rdata2->length == 6);
-
- dns_rdata_toregion(rdata1, &region1);
- dns_rdata_toregion(rdata2, &region2);
- return (isc_region_compare(&region1, &region2));
-}
-
-static inline isc_result_t
-fromstruct_l32(ARGS_FROMSTRUCT) {
- dns_rdata_l32_t *l32 = source;
- isc_uint32_t n;
-
- REQUIRE(type == 105);
- REQUIRE(source != NULL);
- REQUIRE(l32->common.rdtype == type);
- REQUIRE(l32->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- RETERR(uint16_tobuffer(l32->pref, target));
- n = ntohl(l32->l32.s_addr);
- return (uint32_tobuffer(n, target));
-}
-
-static inline isc_result_t
-tostruct_l32(ARGS_TOSTRUCT) {
- isc_region_t region;
- dns_rdata_l32_t *l32 = target;
- isc_uint32_t n;
-
- REQUIRE(rdata->type == 105);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length == 6);
-
- UNUSED(mctx);
-
- l32->common.rdclass = rdata->rdclass;
- l32->common.rdtype = rdata->type;
- ISC_LINK_INIT(&l32->common, link);
-
- dns_rdata_toregion(rdata, &region);
- l32->pref = uint16_fromregion(&region);
- n = uint32_fromregion(&region);
- l32->l32.s_addr = htonl(n);
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_l32(ARGS_FREESTRUCT) {
- dns_rdata_l32_t *l32 = source;
-
- REQUIRE(source != NULL);
- REQUIRE(l32->common.rdtype == 105);
-
- return;
-}
-
-static inline isc_result_t
-additionaldata_l32(ARGS_ADDLDATA) {
-
- REQUIRE(rdata->type == 105);
- REQUIRE(rdata->length == 6);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_l32(ARGS_DIGEST) {
- isc_region_t r;
-
- REQUIRE(rdata->type == 105);
- REQUIRE(rdata->length == 6);
-
- dns_rdata_toregion(rdata, &r);
-
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_l32(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 105);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_l32(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 105);
- REQUIRE(rdata->length == 6);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_l32(ARGS_COMPARE) {
- return (compare_l32(rdata1, rdata2));
-}
-
-#endif /* RDATA_GENERIC_L32_105_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/l32_105.h b/contrib/bind9/lib/dns/rdata/generic/l32_105.h
deleted file mode 100644
index f95db22e8837..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/l32_105.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER 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_L32_105_H
-#define GENERIC_L32_105_H 1
-
-typedef struct dns_rdata_l32 {
- dns_rdatacommon_t common;
- isc_uint16_t pref;
- struct in_addr l32;
-} dns_rdata_l32_t;
-
-#endif /* GENERIC_L32_105_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/l64_106.c b/contrib/bind9/lib/dns/rdata/generic/l64_106.c
deleted file mode 100644
index ff20663355ca..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/l64_106.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER 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 RDATA_GENERIC_L64_106_C
-#define RDATA_GENERIC_L64_106_C
-
-#include <string.h>
-
-#include <isc/net.h>
-
-#define RRTYPE_L64_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_l64(ARGS_FROMTEXT) {
- isc_token_t token;
- unsigned char locator[NS_LOCATORSZ];
-
- REQUIRE(type == 106);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(origin);
- UNUSED(options);
- UNUSED(callbacks);
-
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if (token.value.as_ulong > 0xffffU)
- RETTOK(ISC_R_RANGE);
- RETERR(uint16_tobuffer(token.value.as_ulong, target));
-
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
-
- if (locator_pton(DNS_AS_STR(token), locator) != 1)
- RETTOK(DNS_R_SYNTAX);
- return (mem_tobuffer(target, locator, NS_LOCATORSZ));
-}
-
-static inline isc_result_t
-totext_l64(ARGS_TOTEXT) {
- isc_region_t region;
- char buf[sizeof("xxxx:xxxx:xxxx:xxxx")];
- unsigned short num;
-
- REQUIRE(rdata->type == 106);
- REQUIRE(rdata->length == 10);
-
- UNUSED(tctx);
-
- dns_rdata_toregion(rdata, &region);
- num = uint16_fromregion(&region);
- isc_region_consume(&region, 2);
- sprintf(buf, "%u", num);
- RETERR(str_totext(buf, target));
-
- RETERR(str_totext(" ", target));
-
- sprintf(buf, "%x:%x:%x:%x",
- region.base[0]<<8 | region.base[1],
- region.base[2]<<8 | region.base[3],
- region.base[4]<<8 | region.base[5],
- region.base[6]<<8 | region.base[7]);
- return (str_totext(buf, target));
-}
-
-static inline isc_result_t
-fromwire_l64(ARGS_FROMWIRE) {
- isc_region_t sregion;
-
- REQUIRE(type == 106);
-
- UNUSED(type);
- UNUSED(options);
- UNUSED(rdclass);
- UNUSED(dctx);
-
- isc_buffer_activeregion(source, &sregion);
- if (sregion.length != 10)
- return (DNS_R_FORMERR);
- isc_buffer_forward(source, sregion.length);
- return (mem_tobuffer(target, sregion.base, sregion.length));
-}
-
-static inline isc_result_t
-towire_l64(ARGS_TOWIRE) {
-
- REQUIRE(rdata->type == 106);
- REQUIRE(rdata->length == 10);
-
- UNUSED(cctx);
-
- return (mem_tobuffer(target, rdata->data, rdata->length));
-}
-
-static inline int
-compare_l64(ARGS_COMPARE) {
- isc_region_t region1;
- isc_region_t region2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 106);
- REQUIRE(rdata1->length == 10);
- REQUIRE(rdata2->length == 10);
-
- dns_rdata_toregion(rdata1, &region1);
- dns_rdata_toregion(rdata2, &region2);
- return (isc_region_compare(&region1, &region2));
-}
-
-static inline isc_result_t
-fromstruct_l64(ARGS_FROMSTRUCT) {
- dns_rdata_l64_t *l64 = source;
-
- REQUIRE(type == 106);
- REQUIRE(source != NULL);
- REQUIRE(l64->common.rdtype == type);
- REQUIRE(l64->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- RETERR(uint16_tobuffer(l64->pref, target));
- return (mem_tobuffer(target, l64->l64, sizeof(l64->l64)));
-}
-
-static inline isc_result_t
-tostruct_l64(ARGS_TOSTRUCT) {
- isc_region_t region;
- dns_rdata_l64_t *l64 = target;
-
- REQUIRE(rdata->type == 106);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length == 10);
-
- UNUSED(mctx);
-
- l64->common.rdclass = rdata->rdclass;
- l64->common.rdtype = rdata->type;
- ISC_LINK_INIT(&l64->common, link);
-
- dns_rdata_toregion(rdata, &region);
- l64->pref = uint16_fromregion(&region);
- memcpy(l64->l64, region.base, region.length);
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_l64(ARGS_FREESTRUCT) {
- dns_rdata_l64_t *l64 = source;
-
- REQUIRE(source != NULL);
- REQUIRE(l64->common.rdtype == 106);
-
- return;
-}
-
-static inline isc_result_t
-additionaldata_l64(ARGS_ADDLDATA) {
-
- REQUIRE(rdata->type == 106);
- REQUIRE(rdata->length == 10);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_l64(ARGS_DIGEST) {
- isc_region_t r;
-
- REQUIRE(rdata->type == 106);
- REQUIRE(rdata->length == 10);
-
- dns_rdata_toregion(rdata, &r);
-
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_l64(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 106);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_l64(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 106);
- REQUIRE(rdata->length == 10);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_l64(ARGS_COMPARE) {
- return (compare_l64(rdata1, rdata2));
-}
-
-#endif /* RDATA_GENERIC_L64_106_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/l64_106.h b/contrib/bind9/lib/dns/rdata/generic/l64_106.h
deleted file mode 100644
index 8f93fc513f67..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/l64_106.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER 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_L64_106_H
-#define GENERIC_L64_106_H 1
-
-typedef struct dns_rdata_l64 {
- dns_rdatacommon_t common;
- isc_uint16_t pref;
- unsigned char l64[8];
-} dns_rdata_l64_t;
-
-#endif /* GENERIC_L64_106_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/loc_29.c b/contrib/bind9/lib/dns/rdata/generic/loc_29.c
deleted file mode 100644
index 904dbb402a97..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/loc_29.c
+++ /dev/null
@@ -1,804 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $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 */
-
-/* RFC1876 */
-
-#ifndef RDATA_GENERIC_LOC_29_C
-#define RDATA_GENERIC_LOC_29_C
-
-#define RRTYPE_LOC_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_loc(ARGS_FROMTEXT) {
- isc_token_t token;
- int d1, m1, s1;
- int d2, m2, s2;
- unsigned char size;
- unsigned char hp;
- unsigned char vp;
- unsigned char version;
- isc_boolean_t east = ISC_FALSE;
- isc_boolean_t north = ISC_FALSE;
- long tmp;
- long m;
- long cm;
- long poweroften[8] = { 1, 10, 100, 1000,
- 10000, 100000, 1000000, 10000000 };
- int man;
- int exp;
- char *e;
- int i;
- unsigned long latitude;
- unsigned long longitude;
- unsigned long altitude;
-
- REQUIRE(type == 29);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(origin);
- UNUSED(options);
-
- /*
- * Defaults.
- */
- m1 = s1 = 0;
- m2 = s2 = 0;
- size = 0x12; /* 1.00m */
- hp = 0x16; /* 10000.00 m */
- vp = 0x13; /* 10.00 m */
- version = 0;
-
- /*
- * Degrees.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if (token.value.as_ulong > 90U)
- RETTOK(ISC_R_RANGE);
- d1 = (int)token.value.as_ulong;
- /*
- * Minutes.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- if (strcasecmp(DNS_AS_STR(token), "N") == 0)
- north = ISC_TRUE;
- if (north || strcasecmp(DNS_AS_STR(token), "S") == 0)
- goto getlong;
- m1 = strtol(DNS_AS_STR(token), &e, 10);
- if (*e != 0)
- RETTOK(DNS_R_SYNTAX);
- if (m1 < 0 || m1 > 59)
- RETTOK(ISC_R_RANGE);
- if (d1 == 90 && m1 != 0)
- RETTOK(ISC_R_RANGE);
-
- /*
- * Seconds.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- if (strcasecmp(DNS_AS_STR(token), "N") == 0)
- north = ISC_TRUE;
- if (north || strcasecmp(DNS_AS_STR(token), "S") == 0)
- goto getlong;
- s1 = strtol(DNS_AS_STR(token), &e, 10);
- if (*e != 0 && *e != '.')
- RETTOK(DNS_R_SYNTAX);
- if (s1 < 0 || s1 > 59)
- RETTOK(ISC_R_RANGE);
- if (*e == '.') {
- const char *l;
- e++;
- for (i = 0; i < 3; i++) {
- if (*e == 0)
- break;
- if ((tmp = decvalue(*e++)) < 0)
- RETTOK(DNS_R_SYNTAX);
- s1 *= 10;
- s1 += tmp;
- }
- for (; i < 3; i++)
- s1 *= 10;
- l = e;
- while (*e != 0) {
- if (decvalue(*e++) < 0)
- RETTOK(DNS_R_SYNTAX);
- }
- if (*l != '\0' && callbacks != NULL) {
- const char *file = isc_lex_getsourcename(lexer);
- unsigned long line = isc_lex_getsourceline(lexer);
-
- if (file == NULL)
- file = "UNKNOWN";
- (*callbacks->warn)(callbacks, "%s: %s:%u: '%s' extra "
- "precision digits ignored",
- "dns_rdata_fromtext", file, line,
- DNS_AS_STR(token));
- }
- } else
- s1 *= 1000;
- if (d1 == 90 && s1 != 0)
- RETTOK(ISC_R_RANGE);
-
- /*
- * Direction.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- if (strcasecmp(DNS_AS_STR(token), "N") == 0)
- north = ISC_TRUE;
- if (!north && strcasecmp(DNS_AS_STR(token), "S") != 0)
- RETTOK(DNS_R_SYNTAX);
-
- getlong:
- /*
- * Degrees.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if (token.value.as_ulong > 180U)
- RETTOK(ISC_R_RANGE);
- d2 = (int)token.value.as_ulong;
-
- /*
- * Minutes.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- if (strcasecmp(DNS_AS_STR(token), "E") == 0)
- east = ISC_TRUE;
- if (east || strcasecmp(DNS_AS_STR(token), "W") == 0)
- goto getalt;
- m2 = strtol(DNS_AS_STR(token), &e, 10);
- if (*e != 0)
- RETTOK(DNS_R_SYNTAX);
- if (m2 < 0 || m2 > 59)
- RETTOK(ISC_R_RANGE);
- if (d2 == 180 && m2 != 0)
- RETTOK(ISC_R_RANGE);
-
- /*
- * Seconds.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- if (strcasecmp(DNS_AS_STR(token), "E") == 0)
- east = ISC_TRUE;
- if (east || strcasecmp(DNS_AS_STR(token), "W") == 0)
- goto getalt;
- s2 = strtol(DNS_AS_STR(token), &e, 10);
- if (*e != 0 && *e != '.')
- RETTOK(DNS_R_SYNTAX);
- if (s2 < 0 || s2 > 59)
- RETTOK(ISC_R_RANGE);
- if (*e == '.') {
- const char *l;
- e++;
- for (i = 0; i < 3; i++) {
- if (*e == 0)
- break;
- if ((tmp = decvalue(*e++)) < 0)
- RETTOK(DNS_R_SYNTAX);
- s2 *= 10;
- s2 += tmp;
- }
- for (; i < 3; i++)
- s2 *= 10;
- l = e;
- while (*e != 0) {
- if (decvalue(*e++) < 0)
- RETTOK(DNS_R_SYNTAX);
- }
- if (*l != '\0' && callbacks != NULL) {
- const char *file = isc_lex_getsourcename(lexer);
- unsigned long line = isc_lex_getsourceline(lexer);
-
- if (file == NULL)
- file = "UNKNOWN";
- (*callbacks->warn)(callbacks, "%s: %s:%u: '%s' extra "
- "precision digits ignored",
- "dns_rdata_fromtext",
- file, line, DNS_AS_STR(token));
- }
- } else
- s2 *= 1000;
- if (d2 == 180 && s2 != 0)
- RETTOK(ISC_R_RANGE);
-
- /*
- * Direction.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- if (strcasecmp(DNS_AS_STR(token), "E") == 0)
- east = ISC_TRUE;
- if (!east && strcasecmp(DNS_AS_STR(token), "W") != 0)
- RETTOK(DNS_R_SYNTAX);
-
- getalt:
- /*
- * Altitude.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- m = strtol(DNS_AS_STR(token), &e, 10);
- if (*e != 0 && *e != '.' && *e != 'm')
- RETTOK(DNS_R_SYNTAX);
- if (m < -100000 || m > 42849672)
- RETTOK(ISC_R_RANGE);
- cm = 0;
- if (*e == '.') {
- e++;
- for (i = 0; i < 2; i++) {
- if (*e == 0 || *e == 'm')
- break;
- if ((tmp = decvalue(*e++)) < 0)
- return (DNS_R_SYNTAX);
- cm *= 10;
- if (m < 0)
- cm -= tmp;
- else
- cm += tmp;
- }
- for (; i < 2; i++)
- cm *= 10;
- }
- if (*e == 'm')
- e++;
- if (*e != 0)
- RETTOK(DNS_R_SYNTAX);
- if (m == -100000 && cm != 0)
- RETTOK(ISC_R_RANGE);
- if (m == 42849672 && cm > 95)
- RETTOK(ISC_R_RANGE);
- /*
- * Adjust base.
- */
- altitude = m + 100000;
- altitude *= 100;
- altitude += cm;
-
- /*
- * Size: optional.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_TRUE));
- if (token.type == isc_tokentype_eol ||
- token.type == isc_tokentype_eof) {
- isc_lex_ungettoken(lexer, &token);
- goto encode;
- }
- m = strtol(DNS_AS_STR(token), &e, 10);
- if (*e != 0 && *e != '.' && *e != 'm')
- RETTOK(DNS_R_SYNTAX);
- if (m < 0 || m > 90000000)
- RETTOK(ISC_R_RANGE);
- cm = 0;
- if (*e == '.') {
- e++;
- for (i = 0; i < 2; i++) {
- if (*e == 0 || *e == 'm')
- break;
- if ((tmp = decvalue(*e++)) < 0)
- RETTOK(DNS_R_SYNTAX);
- cm *= 10;
- cm += tmp;
- }
- for (; i < 2; i++)
- cm *= 10;
- }
- if (*e == 'm')
- e++;
- if (*e != 0)
- RETTOK(DNS_R_SYNTAX);
- /*
- * We don't just multiply out as we will overflow.
- */
- if (m > 0) {
- for (exp = 0; exp < 7; exp++)
- if (m < poweroften[exp+1])
- break;
- man = m / poweroften[exp];
- exp += 2;
- } else {
- if (cm >= 10) {
- man = cm / 10;
- exp = 1;
- } else {
- man = cm;
- exp = 0;
- }
- }
- size = (man << 4) + exp;
-
- /*
- * Horizontal precision: optional.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_TRUE));
- if (token.type == isc_tokentype_eol ||
- token.type == isc_tokentype_eof) {
- isc_lex_ungettoken(lexer, &token);
- goto encode;
- }
- m = strtol(DNS_AS_STR(token), &e, 10);
- if (*e != 0 && *e != '.' && *e != 'm')
- RETTOK(DNS_R_SYNTAX);
- if (m < 0 || m > 90000000)
- RETTOK(ISC_R_RANGE);
- cm = 0;
- if (*e == '.') {
- e++;
- for (i = 0; i < 2; i++) {
- if (*e == 0 || *e == 'm')
- break;
- if ((tmp = decvalue(*e++)) < 0)
- RETTOK(DNS_R_SYNTAX);
- cm *= 10;
- cm += tmp;
- }
- for (; i < 2; i++)
- cm *= 10;
- }
- if (*e == 'm')
- e++;
- if (*e != 0)
- RETTOK(DNS_R_SYNTAX);
- /*
- * We don't just multiply out as we will overflow.
- */
- if (m > 0) {
- for (exp = 0; exp < 7; exp++)
- if (m < poweroften[exp+1])
- break;
- man = m / poweroften[exp];
- exp += 2;
- } else if (cm >= 10) {
- man = cm / 10;
- exp = 1;
- } else {
- man = cm;
- exp = 0;
- }
- hp = (man << 4) + exp;
-
- /*
- * Vertical precision: optional.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_TRUE));
- if (token.type == isc_tokentype_eol ||
- token.type == isc_tokentype_eof) {
- isc_lex_ungettoken(lexer, &token);
- goto encode;
- }
- m = strtol(DNS_AS_STR(token), &e, 10);
- if (*e != 0 && *e != '.' && *e != 'm')
- RETTOK(DNS_R_SYNTAX);
- if (m < 0 || m > 90000000)
- RETTOK(ISC_R_RANGE);
- cm = 0;
- if (*e == '.') {
- e++;
- for (i = 0; i < 2; i++) {
- if (*e == 0 || *e == 'm')
- break;
- if ((tmp = decvalue(*e++)) < 0)
- RETTOK(DNS_R_SYNTAX);
- cm *= 10;
- cm += tmp;
- }
- for (; i < 2; i++)
- cm *= 10;
- }
- if (*e == 'm')
- e++;
- if (*e != 0)
- RETTOK(DNS_R_SYNTAX);
- /*
- * We don't just multiply out as we will overflow.
- */
- if (m > 0) {
- for (exp = 0; exp < 7; exp++)
- if (m < poweroften[exp+1])
- break;
- man = m / poweroften[exp];
- exp += 2;
- } else if (cm >= 10) {
- man = cm / 10;
- exp = 1;
- } else {
- man = cm;
- exp = 0;
- }
- vp = (man << 4) + exp;
-
- encode:
- RETERR(mem_tobuffer(target, &version, 1));
- RETERR(mem_tobuffer(target, &size, 1));
- RETERR(mem_tobuffer(target, &hp, 1));
- RETERR(mem_tobuffer(target, &vp, 1));
- if (north)
- latitude = 0x80000000 + ( d1 * 3600 + m1 * 60 ) * 1000 + s1;
- else
- latitude = 0x80000000 - ( d1 * 3600 + m1 * 60 ) * 1000 - s1;
- RETERR(uint32_tobuffer(latitude, target));
-
- if (east)
- longitude = 0x80000000 + ( d2 * 3600 + m2 * 60 ) * 1000 + s2;
- else
- longitude = 0x80000000 - ( d2 * 3600 + m2 * 60 ) * 1000 - s2;
- RETERR(uint32_tobuffer(longitude, target));
-
- return (uint32_tobuffer(altitude, target));
-}
-
-static inline isc_result_t
-totext_loc(ARGS_TOTEXT) {
- int d1, m1, s1, fs1;
- int d2, m2, s2, fs2;
- unsigned long latitude;
- unsigned long longitude;
- unsigned long altitude;
- isc_boolean_t north;
- isc_boolean_t east;
- isc_boolean_t below;
- isc_region_t sr;
- char buf[sizeof("89 59 59.999 N 179 59 59.999 E "
- "42849672.95m 90000000m 90000000m 90000000m")];
- char sbuf[sizeof("90000000m")];
- char hbuf[sizeof("90000000m")];
- char vbuf[sizeof("90000000m")];
- unsigned char size, hp, vp;
- unsigned long poweroften[8] = { 1, 10, 100, 1000,
- 10000, 100000, 1000000, 10000000 };
-
- UNUSED(tctx);
-
- REQUIRE(rdata->type == 29);
- REQUIRE(rdata->length != 0);
-
- dns_rdata_toregion(rdata, &sr);
-
- /* version = sr.base[0]; */
- size = sr.base[1];
- INSIST((size&0x0f) < 10 && (size>>4) < 10);
- if ((size&0x0f)> 1)
- sprintf(sbuf, "%lum", (size>>4) * poweroften[(size&0x0f)-2]);
- else
- sprintf(sbuf, "0.%02lum", (size>>4) * poweroften[(size&0x0f)]);
- hp = sr.base[2];
- INSIST((hp&0x0f) < 10 && (hp>>4) < 10);
- if ((hp&0x0f)> 1)
- sprintf(hbuf, "%lum", (hp>>4) * poweroften[(hp&0x0f)-2]);
- else
- sprintf(hbuf, "0.%02lum", (hp>>4) * poweroften[(hp&0x0f)]);
- vp = sr.base[3];
- INSIST((vp&0x0f) < 10 && (vp>>4) < 10);
- if ((vp&0x0f)> 1)
- sprintf(vbuf, "%lum", (vp>>4) * poweroften[(vp&0x0f)-2]);
- else
- sprintf(vbuf, "0.%02lum", (vp>>4) * poweroften[(vp&0x0f)]);
- isc_region_consume(&sr, 4);
-
- latitude = uint32_fromregion(&sr);
- isc_region_consume(&sr, 4);
- if (latitude >= 0x80000000) {
- north = ISC_TRUE;
- latitude -= 0x80000000;
- } else {
- north = ISC_FALSE;
- latitude = 0x80000000 - latitude;
- }
- fs1 = (int)(latitude % 1000);
- latitude /= 1000;
- s1 = (int)(latitude % 60);
- latitude /= 60;
- m1 = (int)(latitude % 60);
- latitude /= 60;
- d1 = (int)latitude;
- INSIST(latitude <= 90U);
-
- longitude = uint32_fromregion(&sr);
- isc_region_consume(&sr, 4);
- if (longitude >= 0x80000000) {
- east = ISC_TRUE;
- longitude -= 0x80000000;
- } else {
- east = ISC_FALSE;
- longitude = 0x80000000 - longitude;
- }
- fs2 = (int)(longitude % 1000);
- longitude /= 1000;
- s2 = (int)(longitude % 60);
- longitude /= 60;
- m2 = (int)(longitude % 60);
- longitude /= 60;
- d2 = (int)longitude;
- INSIST(longitude <= 180U);
-
- altitude = uint32_fromregion(&sr);
- isc_region_consume(&sr, 4);
- if (altitude < 10000000U) {
- below = ISC_TRUE;
- altitude = 10000000 - altitude;
- } else {
- below =ISC_FALSE;
- altitude -= 10000000;
- }
-
- sprintf(buf, "%d %d %d.%03d %s %d %d %d.%03d %s %s%ld.%02ldm %s %s %s",
- d1, m1, s1, fs1, north ? "N" : "S",
- d2, m2, s2, fs2, east ? "E" : "W",
- below ? "-" : "", altitude/100, altitude % 100,
- sbuf, hbuf, vbuf);
-
- return (str_totext(buf, target));
-}
-
-static inline isc_result_t
-fromwire_loc(ARGS_FROMWIRE) {
- isc_region_t sr;
- unsigned char c;
- unsigned long latitude;
- unsigned long longitude;
-
- REQUIRE(type == 29);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(dctx);
- UNUSED(options);
-
- isc_buffer_activeregion(source, &sr);
- if (sr.length < 1)
- return (ISC_R_UNEXPECTEDEND);
- if (sr.base[0] != 0)
- return (ISC_R_NOTIMPLEMENTED);
- if (sr.length < 16)
- return (ISC_R_UNEXPECTEDEND);
-
- /*
- * Size.
- */
- c = sr.base[1];
- if (c != 0)
- if ((c&0xf) > 9 || ((c>>4)&0xf) > 9 || ((c>>4)&0xf) == 0)
- return (ISC_R_RANGE);
-
- /*
- * Horizontal precision.
- */
- c = sr.base[2];
- if (c != 0)
- if ((c&0xf) > 9 || ((c>>4)&0xf) > 9 || ((c>>4)&0xf) == 0)
- return (ISC_R_RANGE);
-
- /*
- * Vertical precision.
- */
- c = sr.base[3];
- if (c != 0)
- if ((c&0xf) > 9 || ((c>>4)&0xf) > 9 || ((c>>4)&0xf) == 0)
- return (ISC_R_RANGE);
- isc_region_consume(&sr, 4);
-
- /*
- * Latitude.
- */
- latitude = uint32_fromregion(&sr);
- if (latitude < (0x80000000UL - 90 * 3600000) ||
- latitude > (0x80000000UL + 90 * 3600000))
- return (ISC_R_RANGE);
- isc_region_consume(&sr, 4);
-
- /*
- * Longitude.
- */
- longitude = uint32_fromregion(&sr);
- if (longitude < (0x80000000UL - 180 * 3600000) ||
- longitude > (0x80000000UL + 180 * 3600000))
- return (ISC_R_RANGE);
-
- /*
- * Altitude.
- * All values possible.
- */
-
- isc_buffer_activeregion(source, &sr);
- isc_buffer_forward(source, 16);
- return (mem_tobuffer(target, sr.base, 16));
-}
-
-static inline isc_result_t
-towire_loc(ARGS_TOWIRE) {
- UNUSED(cctx);
-
- REQUIRE(rdata->type == 29);
- REQUIRE(rdata->length != 0);
-
- return (mem_tobuffer(target, rdata->data, rdata->length));
-}
-
-static inline int
-compare_loc(ARGS_COMPARE) {
- isc_region_t r1;
- isc_region_t r2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 29);
- 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_loc(ARGS_FROMSTRUCT) {
- dns_rdata_loc_t *loc = source;
- isc_uint8_t c;
-
- REQUIRE(type == 29);
- REQUIRE(source != NULL);
- REQUIRE(loc->common.rdtype == type);
- REQUIRE(loc->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- if (loc->v.v0.version != 0)
- return (ISC_R_NOTIMPLEMENTED);
- RETERR(uint8_tobuffer(loc->v.v0.version, target));
-
- c = loc->v.v0.size;
- if ((c&0xf) > 9 || ((c>>4)&0xf) > 9 || ((c>>4)&0xf) == 0)
- return (ISC_R_RANGE);
- RETERR(uint8_tobuffer(loc->v.v0.size, target));
-
- c = loc->v.v0.horizontal;
- if ((c&0xf) > 9 || ((c>>4)&0xf) > 9 || ((c>>4)&0xf) == 0)
- return (ISC_R_RANGE);
- RETERR(uint8_tobuffer(loc->v.v0.horizontal, target));
-
- c = loc->v.v0.vertical;
- if ((c&0xf) > 9 || ((c>>4)&0xf) > 9 || ((c>>4)&0xf) == 0)
- return (ISC_R_RANGE);
- RETERR(uint8_tobuffer(loc->v.v0.vertical, target));
-
- if (loc->v.v0.latitude < (0x80000000UL - 90 * 3600000) ||
- loc->v.v0.latitude > (0x80000000UL + 90 * 3600000))
- return (ISC_R_RANGE);
- RETERR(uint32_tobuffer(loc->v.v0.latitude, target));
-
- if (loc->v.v0.longitude < (0x80000000UL - 180 * 3600000) ||
- loc->v.v0.longitude > (0x80000000UL + 180 * 3600000))
- return (ISC_R_RANGE);
- RETERR(uint32_tobuffer(loc->v.v0.longitude, target));
- return (uint32_tobuffer(loc->v.v0.altitude, target));
-}
-
-static inline isc_result_t
-tostruct_loc(ARGS_TOSTRUCT) {
- dns_rdata_loc_t *loc = target;
- isc_region_t r;
- isc_uint8_t version;
-
- REQUIRE(rdata->type == 29);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- UNUSED(mctx);
-
- dns_rdata_toregion(rdata, &r);
- version = uint8_fromregion(&r);
- if (version != 0)
- return (ISC_R_NOTIMPLEMENTED);
-
- loc->common.rdclass = rdata->rdclass;
- loc->common.rdtype = rdata->type;
- ISC_LINK_INIT(&loc->common, link);
-
- loc->v.v0.version = version;
- isc_region_consume(&r, 1);
- loc->v.v0.size = uint8_fromregion(&r);
- isc_region_consume(&r, 1);
- loc->v.v0.horizontal = uint8_fromregion(&r);
- isc_region_consume(&r, 1);
- loc->v.v0.vertical = uint8_fromregion(&r);
- isc_region_consume(&r, 1);
- loc->v.v0.latitude = uint32_fromregion(&r);
- isc_region_consume(&r, 4);
- loc->v.v0.longitude = uint32_fromregion(&r);
- isc_region_consume(&r, 4);
- loc->v.v0.altitude = uint32_fromregion(&r);
- isc_region_consume(&r, 4);
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_loc(ARGS_FREESTRUCT) {
- dns_rdata_loc_t *loc = source;
-
- REQUIRE(source != NULL);
- REQUIRE(loc->common.rdtype == 29);
-
- UNUSED(source);
- UNUSED(loc);
-}
-
-static inline isc_result_t
-additionaldata_loc(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 29);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_loc(ARGS_DIGEST) {
- isc_region_t r;
-
- REQUIRE(rdata->type == 29);
-
- dns_rdata_toregion(rdata, &r);
-
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_loc(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 29);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_loc(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 29);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_loc(ARGS_COMPARE) {
- return (compare_loc(rdata1, rdata2));
-}
-
-#endif /* RDATA_GENERIC_LOC_29_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/loc_29.h b/contrib/bind9/lib/dns/rdata/generic/loc_29.h
deleted file mode 100644
index f053c60a9188..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/loc_29.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef GENERIC_LOC_29_H
-#define GENERIC_LOC_29_H 1
-
-/* $Id: loc_29.h,v 1.19 2007/06/19 23:47:17 tbox Exp $ */
-
-/*!
- * \brief Per RFC1876 */
-
-typedef struct dns_rdata_loc_0 {
- isc_uint8_t version; /* must be first and zero */
- isc_uint8_t size;
- isc_uint8_t horizontal;
- isc_uint8_t vertical;
- isc_uint32_t latitude;
- isc_uint32_t longitude;
- isc_uint32_t altitude;
-} dns_rdata_loc_0_t;
-
-typedef struct dns_rdata_loc {
- dns_rdatacommon_t common;
- union {
- dns_rdata_loc_0_t v0;
- } v;
-} dns_rdata_loc_t;
-
-#endif /* GENERIC_LOC_29_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/lp_107.c b/contrib/bind9/lib/dns/rdata/generic/lp_107.c
deleted file mode 100644
index 732ef7fa88f5..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/lp_107.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER 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 RDATA_GENERIC_LP_107_C
-#define RDATA_GENERIC_LP_107_C
-
-#include <string.h>
-
-#include <isc/net.h>
-
-#define RRTYPE_LP_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_lp(ARGS_FROMTEXT) {
- isc_token_t token;
- dns_name_t name;
- isc_buffer_t buffer;
-
- REQUIRE(type == 107);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(callbacks);
-
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if (token.value.as_ulong > 0xffffU)
- RETTOK(ISC_R_RANGE);
- RETERR(uint16_tobuffer(token.value.as_ulong, target));
-
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
-
- dns_name_init(&name, NULL);
- buffer_fromregion(&buffer, &token.value.as_region);
- origin = (origin != NULL) ? origin : dns_rootname;
- return (dns_name_fromtext(&name, &buffer, origin, options, target));
-}
-
-static inline isc_result_t
-totext_lp(ARGS_TOTEXT) {
- isc_region_t region;
- dns_name_t name;
- dns_name_t prefix;
- isc_boolean_t sub;
- char buf[sizeof("64000")];
- unsigned short num;
-
- REQUIRE(rdata->type == 107);
- REQUIRE(rdata->length != 0);
-
- dns_name_init(&name, NULL);
- dns_name_init(&prefix, NULL);
-
- dns_rdata_toregion(rdata, &region);
- num = uint16_fromregion(&region);
- isc_region_consume(&region, 2);
- sprintf(buf, "%u", num);
- RETERR(str_totext(buf, target));
-
- RETERR(str_totext(" ", target));
-
- dns_name_fromregion(&name, &region);
- sub = name_prefix(&name, tctx->origin, &prefix);
- return (dns_name_totext(&prefix, sub, target));
-}
-
-static inline isc_result_t
-fromwire_lp(ARGS_FROMWIRE) {
- dns_name_t name;
- isc_region_t sregion;
-
- REQUIRE(type == 107);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14);
-
- dns_name_init(&name, NULL);
-
- isc_buffer_activeregion(source, &sregion);
- if (sregion.length < 2)
- return (ISC_R_UNEXPECTEDEND);
- RETERR(mem_tobuffer(target, sregion.base, 2));
- isc_buffer_forward(source, 2);
- return (dns_name_fromwire(&name, source, dctx, options, target));
-}
-
-static inline isc_result_t
-towire_lp(ARGS_TOWIRE) {
-
- REQUIRE(rdata->type == 107);
- REQUIRE(rdata->length != 0);
-
- UNUSED(cctx);
-
- return (mem_tobuffer(target, rdata->data, rdata->length));
-}
-
-static inline int
-compare_lp(ARGS_COMPARE) {
- isc_region_t region1;
- isc_region_t region2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 107);
- 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_lp(ARGS_FROMSTRUCT) {
- dns_rdata_lp_t *lp = source;
- isc_region_t region;
-
- REQUIRE(type == 107);
- REQUIRE(source != NULL);
- REQUIRE(lp->common.rdtype == type);
- REQUIRE(lp->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- RETERR(uint16_tobuffer(lp->pref, target));
- dns_name_toregion(&lp->lp, &region);
- return (isc_buffer_copyregion(target, &region));
-}
-
-static inline isc_result_t
-tostruct_lp(ARGS_TOSTRUCT) {
- isc_region_t region;
- dns_rdata_lp_t *lp = target;
- dns_name_t name;
-
- REQUIRE(rdata->type == 107);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- lp->common.rdclass = rdata->rdclass;
- lp->common.rdtype = rdata->type;
- ISC_LINK_INIT(&lp->common, link);
-
- dns_name_init(&name, NULL);
- dns_rdata_toregion(rdata, &region);
- lp->pref = uint16_fromregion(&region);
- isc_region_consume(&region, 2);
- dns_name_fromregion(&name, &region);
- dns_name_init(&lp->lp, NULL);
- RETERR(name_duporclone(&name, mctx, &lp->lp));
- lp->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_lp(ARGS_FREESTRUCT) {
- dns_rdata_lp_t *lp = source;
-
- REQUIRE(source != NULL);
- REQUIRE(lp->common.rdtype == 107);
-
- if (lp->mctx == NULL)
- return;
-
- dns_name_free(&lp->lp, lp->mctx);
- lp->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_lp(ARGS_ADDLDATA) {
- dns_name_t name;
- dns_offsets_t offsets;
- isc_region_t region;
- isc_result_t result;
-
- REQUIRE(rdata->type == 107);
-
- dns_name_init(&name, offsets);
- dns_rdata_toregion(rdata, &region);
- isc_region_consume(&region, 2);
- dns_name_fromregion(&name, &region);
-
- result = (add)(arg, &name, dns_rdatatype_l32);
- if (result != ISC_R_SUCCESS)
- return (result);
- return ((add)(arg, &name, dns_rdatatype_l64));
-}
-
-static inline isc_result_t
-digest_lp(ARGS_DIGEST) {
- isc_region_t region;
-
- REQUIRE(rdata->type == 107);
-
- dns_rdata_toregion(rdata, &region);
- return ((digest)(arg, &region));
-}
-
-static inline isc_boolean_t
-checkowner_lp(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 107);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(name);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_lp(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 107);
-
- UNUSED(bad);
- UNUSED(owner);
-
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_lp(ARGS_COMPARE) {
- dns_name_t name1;
- dns_name_t name2;
- isc_region_t region1;
- isc_region_t region2;
- int order;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 107);
- REQUIRE(rdata1->length != 0);
- REQUIRE(rdata2->length != 0);
-
- order = memcmp(rdata1->data, rdata2->data, 2);
- if (order != 0)
- return (order < 0 ? -1 : 1);
-
- dns_name_init(&name1, NULL);
- dns_name_init(&name2, NULL);
-
- dns_rdata_toregion(rdata1, &region1);
- dns_rdata_toregion(rdata2, &region2);
-
- isc_region_consume(&region1, 2);
- isc_region_consume(&region2, 2);
-
- dns_name_fromregion(&name1, &region1);
- dns_name_fromregion(&name2, &region2);
-
- return (dns_name_rdatacompare(&name1, &name2));
-}
-
-#endif /* RDATA_GENERIC_LP_107_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/lp_107.h b/contrib/bind9/lib/dns/rdata/generic/lp_107.h
deleted file mode 100644
index cbfee8a49cb1..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/lp_107.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER 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_LP_107_H
-#define GENERIC_LP_107_H 1
-
-typedef struct dns_rdata_lp {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- isc_uint16_t pref;
- dns_name_t lp;
-} dns_rdata_lp_t;
-
-#endif /* GENERIC_LP_107_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/mb_7.c b/contrib/bind9/lib/dns/rdata/generic/mb_7.c
deleted file mode 100644
index 8e588fc7b8a5..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/mb_7.c
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $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 */
-
-#ifndef RDATA_GENERIC_MB_7_C
-#define RDATA_GENERIC_MB_7_C
-
-#define RRTYPE_MB_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_mb(ARGS_FROMTEXT) {
- isc_token_t token;
- dns_name_t name;
- isc_buffer_t buffer;
-
- REQUIRE(type == 7);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(callbacks);
-
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
-
- dns_name_init(&name, NULL);
- buffer_fromregion(&buffer, &token.value.as_region);
- origin = (origin != NULL) ? origin : dns_rootname;
- RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_mb(ARGS_TOTEXT) {
- isc_region_t region;
- dns_name_t name;
- dns_name_t prefix;
- isc_boolean_t sub;
-
- REQUIRE(rdata->type == 7);
- REQUIRE(rdata->length != 0);
-
- dns_name_init(&name, NULL);
- dns_name_init(&prefix, NULL);
-
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
-
- sub = name_prefix(&name, tctx->origin, &prefix);
-
- return (dns_name_totext(&prefix, sub, target));
-}
-
-static inline isc_result_t
-fromwire_mb(ARGS_FROMWIRE) {
- dns_name_t name;
-
- REQUIRE(type == 7);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14);
-
- dns_name_init(&name, NULL);
- return (dns_name_fromwire(&name, source, dctx, options, target));
-}
-
-static inline isc_result_t
-towire_mb(ARGS_TOWIRE) {
- dns_name_t name;
- dns_offsets_t offsets;
- isc_region_t region;
-
- REQUIRE(rdata->type == 7);
- REQUIRE(rdata->length != 0);
-
- dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
-
- dns_name_init(&name, offsets);
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
-
- return (dns_name_towire(&name, cctx, target));
-}
-
-static inline int
-compare_mb(ARGS_COMPARE) {
- dns_name_t name1;
- dns_name_t name2;
- isc_region_t region1;
- isc_region_t region2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 7);
- 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);
-
- return (dns_name_rdatacompare(&name1, &name2));
-}
-
-static inline isc_result_t
-fromstruct_mb(ARGS_FROMSTRUCT) {
- dns_rdata_mb_t *mb = source;
- isc_region_t region;
-
- REQUIRE(type == 7);
- REQUIRE(source != NULL);
- REQUIRE(mb->common.rdtype == type);
- REQUIRE(mb->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_name_toregion(&mb->mb, &region);
- return (isc_buffer_copyregion(target, &region));
-}
-
-static inline isc_result_t
-tostruct_mb(ARGS_TOSTRUCT) {
- isc_region_t region;
- dns_rdata_mb_t *mb = target;
- dns_name_t name;
-
- REQUIRE(rdata->type == 7);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- mb->common.rdclass = rdata->rdclass;
- mb->common.rdtype = rdata->type;
- ISC_LINK_INIT(&mb->common, link);
-
- dns_name_init(&name, NULL);
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
- dns_name_init(&mb->mb, NULL);
- RETERR(name_duporclone(&name, mctx, &mb->mb));
- mb->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_mb(ARGS_FREESTRUCT) {
- dns_rdata_mb_t *mb = source;
-
- REQUIRE(source != NULL);
-
- if (mb->mctx == NULL)
- return;
-
- dns_name_free(&mb->mb, mb->mctx);
- mb->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_mb(ARGS_ADDLDATA) {
- dns_name_t name;
- dns_offsets_t offsets;
- isc_region_t region;
-
- REQUIRE(rdata->type == 7);
-
- dns_name_init(&name, offsets);
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
-
- return ((add)(arg, &name, dns_rdatatype_a));
-}
-
-static inline isc_result_t
-digest_mb(ARGS_DIGEST) {
- isc_region_t r;
- dns_name_t name;
-
- REQUIRE(rdata->type == 7);
-
- dns_rdata_toregion(rdata, &r);
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &r);
-
- return (dns_name_digest(&name, digest, arg));
-}
-
-static inline isc_boolean_t
-checkowner_mb(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 7);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (dns_name_ismailbox(name));
-}
-
-static inline isc_boolean_t
-checknames_mb(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 7);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_mb(ARGS_COMPARE) {
- return (compare_mb(rdata1, rdata2));
-}
-
-#endif /* RDATA_GENERIC_MB_7_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/mb_7.h b/contrib/bind9/lib/dns/rdata/generic/mb_7.h
deleted file mode 100644
index b427ee9b665d..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/mb_7.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* */
-#ifndef GENERIC_MB_7_H
-#define GENERIC_MB_7_H 1
-
-/* $Id: mb_7.h,v 1.27 2007/06/19 23:47:17 tbox Exp $ */
-
-typedef struct dns_rdata_mb {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- dns_name_t mb;
-} dns_rdata_mb_t;
-
-#endif /* GENERIC_MB_7_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/md_3.c b/contrib/bind9/lib/dns/rdata/generic/md_3.c
deleted file mode 100644
index e00f1f6ca368..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/md_3.c
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $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 */
-
-#ifndef RDATA_GENERIC_MD_3_C
-#define RDATA_GENERIC_MD_3_C
-
-#define RRTYPE_MD_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_md(ARGS_FROMTEXT) {
- isc_token_t token;
- dns_name_t name;
- isc_buffer_t buffer;
-
- REQUIRE(type == 3);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(callbacks);
-
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
-
- dns_name_init(&name, NULL);
- buffer_fromregion(&buffer, &token.value.as_region);
- origin = (origin != NULL) ? origin : dns_rootname;
- RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_md(ARGS_TOTEXT) {
- isc_region_t region;
- dns_name_t name;
- dns_name_t prefix;
- isc_boolean_t sub;
-
- REQUIRE(rdata->type == 3);
- REQUIRE(rdata->length != 0);
-
- dns_name_init(&name, NULL);
- dns_name_init(&prefix, NULL);
-
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
-
- sub = name_prefix(&name, tctx->origin, &prefix);
-
- return (dns_name_totext(&prefix, sub, target));
-}
-
-static inline isc_result_t
-fromwire_md(ARGS_FROMWIRE) {
- dns_name_t name;
-
- REQUIRE(type == 3);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14);
-
- dns_name_init(&name, NULL);
- return (dns_name_fromwire(&name, source, dctx, options, target));
-}
-
-static inline isc_result_t
-towire_md(ARGS_TOWIRE) {
- dns_name_t name;
- dns_offsets_t offsets;
- isc_region_t region;
-
- REQUIRE(rdata->type == 3);
- REQUIRE(rdata->length != 0);
-
- dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
-
- dns_name_init(&name, offsets);
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
-
- return (dns_name_towire(&name, cctx, target));
-}
-
-static inline int
-compare_md(ARGS_COMPARE) {
- dns_name_t name1;
- dns_name_t name2;
- isc_region_t region1;
- isc_region_t region2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 3);
- 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);
-
- return (dns_name_rdatacompare(&name1, &name2));
-}
-
-static inline isc_result_t
-fromstruct_md(ARGS_FROMSTRUCT) {
- dns_rdata_md_t *md = source;
- isc_region_t region;
-
- REQUIRE(type == 3);
- REQUIRE(source != NULL);
- REQUIRE(md->common.rdtype == type);
- REQUIRE(md->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_name_toregion(&md->md, &region);
- return (isc_buffer_copyregion(target, &region));
-}
-
-static inline isc_result_t
-tostruct_md(ARGS_TOSTRUCT) {
- dns_rdata_md_t *md = target;
- isc_region_t r;
- dns_name_t name;
-
- REQUIRE(rdata->type == 3);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- md->common.rdclass = rdata->rdclass;
- md->common.rdtype = rdata->type;
- ISC_LINK_INIT(&md->common, link);
-
- dns_name_init(&name, NULL);
- dns_rdata_toregion(rdata, &r);
- dns_name_fromregion(&name, &r);
- dns_name_init(&md->md, NULL);
- RETERR(name_duporclone(&name, mctx, &md->md));
- md->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_md(ARGS_FREESTRUCT) {
- dns_rdata_md_t *md = source;
-
- REQUIRE(source != NULL);
- REQUIRE(md->common.rdtype == 3);
-
- if (md->mctx == NULL)
- return;
-
- dns_name_free(&md->md, md->mctx);
- md->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_md(ARGS_ADDLDATA) {
- dns_name_t name;
- dns_offsets_t offsets;
- isc_region_t region;
-
- REQUIRE(rdata->type == 3);
-
- dns_name_init(&name, offsets);
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
-
- return ((add)(arg, &name, dns_rdatatype_a));
-}
-
-static inline isc_result_t
-digest_md(ARGS_DIGEST) {
- isc_region_t r;
- dns_name_t name;
-
- REQUIRE(rdata->type == 3);
-
- dns_rdata_toregion(rdata, &r);
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &r);
-
- return (dns_name_digest(&name, digest, arg));
-}
-
-static inline isc_boolean_t
-checkowner_md(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 3);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_md(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 3);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_md(ARGS_COMPARE) {
- return (compare_md(rdata1, rdata2));
-}
-
-#endif /* RDATA_GENERIC_MD_3_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/md_3.h b/contrib/bind9/lib/dns/rdata/generic/md_3.h
deleted file mode 100644
index ba70d18d952f..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/md_3.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* */
-#ifndef GENERIC_MD_3_H
-#define GENERIC_MD_3_H 1
-
-/* $Id: md_3.h,v 1.28 2007/06/19 23:47:17 tbox Exp $ */
-
-typedef struct dns_rdata_md {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- dns_name_t md;
-} dns_rdata_md_t;
-
-
-#endif /* GENERIC_MD_3_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/mf_4.c b/contrib/bind9/lib/dns/rdata/generic/mf_4.c
deleted file mode 100644
index a85809aef223..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/mf_4.c
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $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 */
-
-#ifndef RDATA_GENERIC_MF_4_C
-#define RDATA_GENERIC_MF_4_C
-
-#define RRTYPE_MF_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_mf(ARGS_FROMTEXT) {
- isc_token_t token;
- dns_name_t name;
- isc_buffer_t buffer;
-
- REQUIRE(type == 4);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(callbacks);
-
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
-
- dns_name_init(&name, NULL);
- buffer_fromregion(&buffer, &token.value.as_region);
- origin = (origin != NULL) ? origin : dns_rootname;
- RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_mf(ARGS_TOTEXT) {
- isc_region_t region;
- dns_name_t name;
- dns_name_t prefix;
- isc_boolean_t sub;
-
- REQUIRE(rdata->type == 4);
- REQUIRE(rdata->length != 0);
-
- dns_name_init(&name, NULL);
- dns_name_init(&prefix, NULL);
-
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
-
- sub = name_prefix(&name, tctx->origin, &prefix);
-
- return (dns_name_totext(&prefix, sub, target));
-}
-
-static inline isc_result_t
-fromwire_mf(ARGS_FROMWIRE) {
- dns_name_t name;
-
- REQUIRE(type == 4);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14);
-
- dns_name_init(&name, NULL);
- return (dns_name_fromwire(&name, source, dctx, options, target));
-}
-
-static inline isc_result_t
-towire_mf(ARGS_TOWIRE) {
- dns_name_t name;
- dns_offsets_t offsets;
- isc_region_t region;
-
- REQUIRE(rdata->type == 4);
- REQUIRE(rdata->length != 0);
-
- dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
-
- dns_name_init(&name, offsets);
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
-
- return (dns_name_towire(&name, cctx, target));
-}
-
-static inline int
-compare_mf(ARGS_COMPARE) {
- dns_name_t name1;
- dns_name_t name2;
- isc_region_t region1;
- isc_region_t region2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 4);
- 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);
-
- return (dns_name_rdatacompare(&name1, &name2));
-}
-
-static inline isc_result_t
-fromstruct_mf(ARGS_FROMSTRUCT) {
- dns_rdata_mf_t *mf = source;
- isc_region_t region;
-
- REQUIRE(type == 4);
- REQUIRE(source != NULL);
- REQUIRE(mf->common.rdtype == type);
- REQUIRE(mf->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_name_toregion(&mf->mf, &region);
- return (isc_buffer_copyregion(target, &region));
-}
-
-static inline isc_result_t
-tostruct_mf(ARGS_TOSTRUCT) {
- dns_rdata_mf_t *mf = target;
- isc_region_t r;
- dns_name_t name;
-
- REQUIRE(rdata->type == 4);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- mf->common.rdclass = rdata->rdclass;
- mf->common.rdtype = rdata->type;
- ISC_LINK_INIT(&mf->common, link);
-
- dns_name_init(&name, NULL);
- dns_rdata_toregion(rdata, &r);
- dns_name_fromregion(&name, &r);
- dns_name_init(&mf->mf, NULL);
- RETERR(name_duporclone(&name, mctx, &mf->mf));
- mf->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_mf(ARGS_FREESTRUCT) {
- dns_rdata_mf_t *mf = source;
-
- REQUIRE(source != NULL);
- REQUIRE(mf->common.rdtype == 4);
-
- if (mf->mctx == NULL)
- return;
- dns_name_free(&mf->mf, mf->mctx);
- mf->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_mf(ARGS_ADDLDATA) {
- dns_name_t name;
- dns_offsets_t offsets;
- isc_region_t region;
-
- REQUIRE(rdata->type == 4);
-
- dns_name_init(&name, offsets);
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
-
- return ((add)(arg, &name, dns_rdatatype_a));
-}
-
-static inline isc_result_t
-digest_mf(ARGS_DIGEST) {
- isc_region_t r;
- dns_name_t name;
-
- REQUIRE(rdata->type == 4);
-
- dns_rdata_toregion(rdata, &r);
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &r);
-
- return (dns_name_digest(&name, digest, arg));
-}
-
-static inline isc_boolean_t
-checkowner_mf(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 4);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_mf(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 4);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_mf(ARGS_COMPARE) {
- return (compare_mf(rdata1, rdata2));
-}
-
-#endif /* RDATA_GENERIC_MF_4_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/mf_4.h b/contrib/bind9/lib/dns/rdata/generic/mf_4.h
deleted file mode 100644
index 32d249358146..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/mf_4.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* */
-#ifndef GENERIC_MF_4_H
-#define GENERIC_MF_4_H 1
-
-/* $Id: mf_4.h,v 1.26 2007/06/19 23:47:17 tbox Exp $ */
-
-typedef struct dns_rdata_mf {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- dns_name_t mf;
-} dns_rdata_mf_t;
-
-#endif /* GENERIC_MF_4_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/mg_8.c b/contrib/bind9/lib/dns/rdata/generic/mg_8.c
deleted file mode 100644
index d0af188e7373..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/mg_8.c
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $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 */
-
-#ifndef RDATA_GENERIC_MG_8_C
-#define RDATA_GENERIC_MG_8_C
-
-#define RRTYPE_MG_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_mg(ARGS_FROMTEXT) {
- isc_token_t token;
- dns_name_t name;
- isc_buffer_t buffer;
-
- REQUIRE(type == 8);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(callbacks);
-
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
-
- dns_name_init(&name, NULL);
- buffer_fromregion(&buffer, &token.value.as_region);
- origin = (origin != NULL) ? origin : dns_rootname;
- RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_mg(ARGS_TOTEXT) {
- isc_region_t region;
- dns_name_t name;
- dns_name_t prefix;
- isc_boolean_t sub;
-
- REQUIRE(rdata->type == 8);
- REQUIRE(rdata->length != 0);
-
- dns_name_init(&name, NULL);
- dns_name_init(&prefix, NULL);
-
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
-
- sub = name_prefix(&name, tctx->origin, &prefix);
-
- return (dns_name_totext(&prefix, sub, target));
-}
-
-static inline isc_result_t
-fromwire_mg(ARGS_FROMWIRE) {
- dns_name_t name;
-
- REQUIRE(type == 8);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14);
-
- dns_name_init(&name, NULL);
- return (dns_name_fromwire(&name, source, dctx, options, target));
-}
-
-static inline isc_result_t
-towire_mg(ARGS_TOWIRE) {
- dns_name_t name;
- dns_offsets_t offsets;
- isc_region_t region;
-
- REQUIRE(rdata->type == 8);
- REQUIRE(rdata->length != 0);
-
- dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
-
- dns_name_init(&name, offsets);
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
-
- return (dns_name_towire(&name, cctx, target));
-}
-
-static inline int
-compare_mg(ARGS_COMPARE) {
- dns_name_t name1;
- dns_name_t name2;
- isc_region_t region1;
- isc_region_t region2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 8);
- 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);
-
- return (dns_name_rdatacompare(&name1, &name2));
-}
-
-static inline isc_result_t
-fromstruct_mg(ARGS_FROMSTRUCT) {
- dns_rdata_mg_t *mg = source;
- isc_region_t region;
-
- REQUIRE(type == 8);
- REQUIRE(source != NULL);
- REQUIRE(mg->common.rdtype == type);
- REQUIRE(mg->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_name_toregion(&mg->mg, &region);
- return (isc_buffer_copyregion(target, &region));
-}
-
-static inline isc_result_t
-tostruct_mg(ARGS_TOSTRUCT) {
- isc_region_t region;
- dns_rdata_mg_t *mg = target;
- dns_name_t name;
-
- REQUIRE(rdata->type == 8);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- mg->common.rdclass = rdata->rdclass;
- mg->common.rdtype = rdata->type;
- ISC_LINK_INIT(&mg->common, link);
-
- dns_name_init(&name, NULL);
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
- dns_name_init(&mg->mg, NULL);
- RETERR(name_duporclone(&name, mctx, &mg->mg));
- mg->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_mg(ARGS_FREESTRUCT) {
- dns_rdata_mg_t *mg = source;
-
- REQUIRE(source != NULL);
- REQUIRE(mg->common.rdtype == 8);
-
- if (mg->mctx == NULL)
- return;
- dns_name_free(&mg->mg, mg->mctx);
- mg->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_mg(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 8);
-
- UNUSED(add);
- UNUSED(arg);
- UNUSED(rdata);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_mg(ARGS_DIGEST) {
- isc_region_t r;
- dns_name_t name;
-
- REQUIRE(rdata->type == 8);
-
- dns_rdata_toregion(rdata, &r);
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &r);
-
- return (dns_name_digest(&name, digest, arg));
-}
-
-static inline isc_boolean_t
-checkowner_mg(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 8);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (dns_name_ismailbox(name));
-}
-
-static inline isc_boolean_t
-checknames_mg(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 8);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_mg(ARGS_COMPARE) {
- return (compare_mg(rdata1, rdata2));
-}
-
-#endif /* RDATA_GENERIC_MG_8_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/mg_8.h b/contrib/bind9/lib/dns/rdata/generic/mg_8.h
deleted file mode 100644
index 8fa143a370d8..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/mg_8.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* */
-#ifndef GENERIC_MG_8_H
-#define GENERIC_MG_8_H 1
-
-/* $Id: mg_8.h,v 1.26 2007/06/19 23:47:17 tbox Exp $ */
-
-typedef struct dns_rdata_mg {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- dns_name_t mg;
-} dns_rdata_mg_t;
-
-#endif /* GENERIC_MG_8_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/minfo_14.c b/contrib/bind9/lib/dns/rdata/generic/minfo_14.c
deleted file mode 100644
index 9e2214c98aa3..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/minfo_14.c
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $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 */
-
-#ifndef RDATA_GENERIC_MINFO_14_C
-#define RDATA_GENERIC_MINFO_14_C
-
-#define RRTYPE_MINFO_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_minfo(ARGS_FROMTEXT) {
- isc_token_t token;
- dns_name_t name;
- isc_buffer_t buffer;
- int i;
- isc_boolean_t ok;
-
- REQUIRE(type == 14);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(callbacks);
-
- for (i = 0; i < 2; i++) {
- RETERR(isc_lex_getmastertoken(lexer, &token,
- isc_tokentype_string,
- ISC_FALSE));
- dns_name_init(&name, NULL);
- buffer_fromregion(&buffer, &token.value.as_region);
- origin = (origin != NULL) ? origin : dns_rootname;
- RETTOK(dns_name_fromtext(&name, &buffer, origin,
- options, target));
- ok = ISC_TRUE;
- if ((options & DNS_RDATA_CHECKNAMES) != 0)
- ok = dns_name_ismailbox(&name);
- if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0)
- RETTOK(DNS_R_BADNAME);
- if (!ok && callbacks != NULL)
- warn_badname(&name, lexer, callbacks);
- }
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_minfo(ARGS_TOTEXT) {
- isc_region_t region;
- dns_name_t rmail;
- dns_name_t email;
- dns_name_t prefix;
- isc_boolean_t sub;
-
- REQUIRE(rdata->type == 14);
- REQUIRE(rdata->length != 0);
-
- dns_name_init(&rmail, NULL);
- dns_name_init(&email, NULL);
- dns_name_init(&prefix, NULL);
-
- dns_rdata_toregion(rdata, &region);
-
- dns_name_fromregion(&rmail, &region);
- isc_region_consume(&region, rmail.length);
-
- dns_name_fromregion(&email, &region);
- isc_region_consume(&region, email.length);
-
- sub = name_prefix(&rmail, tctx->origin, &prefix);
-
- RETERR(dns_name_totext(&prefix, sub, target));
-
- RETERR(str_totext(" ", target));
-
- sub = name_prefix(&email, tctx->origin, &prefix);
- return (dns_name_totext(&prefix, sub, target));
-}
-
-static inline isc_result_t
-fromwire_minfo(ARGS_FROMWIRE) {
- dns_name_t rmail;
- dns_name_t email;
-
- REQUIRE(type == 14);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14);
-
- 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));
-}
-
-static inline isc_result_t
-towire_minfo(ARGS_TOWIRE) {
- isc_region_t region;
- dns_name_t rmail;
- dns_name_t email;
- dns_offsets_t roffsets;
- dns_offsets_t eoffsets;
-
- REQUIRE(rdata->type == 14);
- REQUIRE(rdata->length != 0);
-
- dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
-
- dns_name_init(&rmail, roffsets);
- dns_name_init(&email, eoffsets);
-
- dns_rdata_toregion(rdata, &region);
-
- dns_name_fromregion(&rmail, &region);
- isc_region_consume(&region, name_length(&rmail));
-
- RETERR(dns_name_towire(&rmail, cctx, target));
-
- dns_name_fromregion(&rmail, &region);
- isc_region_consume(&region, rmail.length);
-
- return (dns_name_towire(&rmail, cctx, target));
-}
-
-static inline int
-compare_minfo(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 == 14);
- 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));
-
- dns_name_init(&name1, NULL);
- dns_name_init(&name2, NULL);
-
- dns_name_fromregion(&name1, &region1);
- dns_name_fromregion(&name2, &region2);
-
- order = dns_name_rdatacompare(&name1, &name2);
- return (order);
-}
-
-static inline isc_result_t
-fromstruct_minfo(ARGS_FROMSTRUCT) {
- dns_rdata_minfo_t *minfo = source;
- isc_region_t region;
-
- REQUIRE(type == 14);
- REQUIRE(source != NULL);
- REQUIRE(minfo->common.rdtype == type);
- REQUIRE(minfo->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_name_toregion(&minfo->rmailbox, &region);
- RETERR(isc_buffer_copyregion(target, &region));
- dns_name_toregion(&minfo->emailbox, &region);
- return (isc_buffer_copyregion(target, &region));
-}
-
-static inline isc_result_t
-tostruct_minfo(ARGS_TOSTRUCT) {
- dns_rdata_minfo_t *minfo = target;
- isc_region_t region;
- dns_name_t name;
- isc_result_t result;
-
- REQUIRE(rdata->type == 14);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- minfo->common.rdclass = rdata->rdclass;
- minfo->common.rdtype = rdata->type;
- ISC_LINK_INIT(&minfo->common, link);
-
- dns_name_init(&name, NULL);
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
- dns_name_init(&minfo->rmailbox, NULL);
- RETERR(name_duporclone(&name, mctx, &minfo->rmailbox));
- isc_region_consume(&region, name_length(&name));
-
- dns_name_fromregion(&name, &region);
- dns_name_init(&minfo->emailbox, NULL);
- result = name_duporclone(&name, mctx, &minfo->emailbox);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- minfo->mctx = mctx;
- return (ISC_R_SUCCESS);
-
- cleanup:
- if (mctx != NULL)
- dns_name_free(&minfo->rmailbox, mctx);
- return (ISC_R_NOMEMORY);
-}
-
-static inline void
-freestruct_minfo(ARGS_FREESTRUCT) {
- dns_rdata_minfo_t *minfo = source;
-
- REQUIRE(source != NULL);
- REQUIRE(minfo->common.rdtype == 14);
-
- if (minfo->mctx == NULL)
- return;
-
- dns_name_free(&minfo->rmailbox, minfo->mctx);
- dns_name_free(&minfo->emailbox, minfo->mctx);
- minfo->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_minfo(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 14);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_minfo(ARGS_DIGEST) {
- isc_region_t r;
- dns_name_t name;
- isc_result_t result;
-
- REQUIRE(rdata->type == 14);
-
- dns_rdata_toregion(rdata, &r);
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &r);
- result = dns_name_digest(&name, digest, arg);
- if (result != ISC_R_SUCCESS)
- return (result);
- isc_region_consume(&r, name_length(&name));
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &r);
-
- return (dns_name_digest(&name, digest, arg));
-}
-
-static inline isc_boolean_t
-checkowner_minfo(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 14);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_minfo(ARGS_CHECKNAMES) {
- isc_region_t region;
- dns_name_t name;
-
- REQUIRE(rdata->type == 14);
-
- UNUSED(owner);
-
- dns_rdata_toregion(rdata, &region);
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &region);
- if (!dns_name_ismailbox(&name)) {
- if (bad != NULL)
- dns_name_clone(&name, bad);
- return (ISC_FALSE);
- }
- isc_region_consume(&region, name_length(&name));
- dns_name_fromregion(&name, &region);
- if (!dns_name_ismailbox(&name)) {
- if (bad != NULL)
- dns_name_clone(&name, bad);
- return (ISC_FALSE);
- }
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_minfo(ARGS_COMPARE) {
- return (compare_minfo(rdata1, rdata2));
-}
-
-#endif /* RDATA_GENERIC_MINFO_14_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/minfo_14.h b/contrib/bind9/lib/dns/rdata/generic/minfo_14.h
deleted file mode 100644
index 76195c52f34d..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/minfo_14.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* */
-#ifndef GENERIC_MINFO_14_H
-#define GENERIC_MINFO_14_H 1
-
-/* $Id: minfo_14.h,v 1.27 2007/06/19 23:47:17 tbox Exp $ */
-
-typedef struct dns_rdata_minfo {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- dns_name_t rmailbox;
- dns_name_t emailbox;
-} dns_rdata_minfo_t;
-
-#endif /* GENERIC_MINFO_14_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/mr_9.c b/contrib/bind9/lib/dns/rdata/generic/mr_9.c
deleted file mode 100644
index 590235d961bb..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/mr_9.c
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $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 */
-
-#ifndef RDATA_GENERIC_MR_9_C
-#define RDATA_GENERIC_MR_9_C
-
-#define RRTYPE_MR_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_mr(ARGS_FROMTEXT) {
- isc_token_t token;
- dns_name_t name;
- isc_buffer_t buffer;
-
- REQUIRE(type == 9);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(callbacks);
-
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
-
- dns_name_init(&name, NULL);
- buffer_fromregion(&buffer, &token.value.as_region);
- origin = (origin != NULL) ? origin : dns_rootname;
- RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_mr(ARGS_TOTEXT) {
- isc_region_t region;
- dns_name_t name;
- dns_name_t prefix;
- isc_boolean_t sub;
-
- REQUIRE(rdata->type == 9);
- REQUIRE(rdata->length != 0);
-
- dns_name_init(&name, NULL);
- dns_name_init(&prefix, NULL);
-
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
-
- sub = name_prefix(&name, tctx->origin, &prefix);
-
- return (dns_name_totext(&prefix, sub, target));
-}
-
-static inline isc_result_t
-fromwire_mr(ARGS_FROMWIRE) {
- dns_name_t name;
-
- REQUIRE(type == 9);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14);
-
- dns_name_init(&name, NULL);
- return (dns_name_fromwire(&name, source, dctx, options, target));
-}
-
-static inline isc_result_t
-towire_mr(ARGS_TOWIRE) {
- dns_name_t name;
- dns_offsets_t offsets;
- isc_region_t region;
-
- REQUIRE(rdata->type == 9);
- REQUIRE(rdata->length != 0);
-
- dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
-
- dns_name_init(&name, offsets);
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
-
- return (dns_name_towire(&name, cctx, target));
-}
-
-static inline int
-compare_mr(ARGS_COMPARE) {
- dns_name_t name1;
- dns_name_t name2;
- isc_region_t region1;
- isc_region_t region2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 9);
- 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);
-
- return (dns_name_rdatacompare(&name1, &name2));
-}
-
-static inline isc_result_t
-fromstruct_mr(ARGS_FROMSTRUCT) {
- dns_rdata_mr_t *mr = source;
- isc_region_t region;
-
- REQUIRE(type == 9);
- REQUIRE(source != NULL);
- REQUIRE(mr->common.rdtype == type);
- REQUIRE(mr->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_name_toregion(&mr->mr, &region);
- return (isc_buffer_copyregion(target, &region));
-}
-
-static inline isc_result_t
-tostruct_mr(ARGS_TOSTRUCT) {
- isc_region_t region;
- dns_rdata_mr_t *mr = target;
- dns_name_t name;
-
- REQUIRE(rdata->type == 9);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- mr->common.rdclass = rdata->rdclass;
- mr->common.rdtype = rdata->type;
- ISC_LINK_INIT(&mr->common, link);
-
- dns_name_init(&name, NULL);
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
- dns_name_init(&mr->mr, NULL);
- RETERR(name_duporclone(&name, mctx, &mr->mr));
- mr->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_mr(ARGS_FREESTRUCT) {
- dns_rdata_mr_t *mr = source;
-
- REQUIRE(source != NULL);
- REQUIRE(mr->common.rdtype == 9);
-
- if (mr->mctx == NULL)
- return;
- dns_name_free(&mr->mr, mr->mctx);
- mr->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_mr(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 9);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_mr(ARGS_DIGEST) {
- isc_region_t r;
- dns_name_t name;
-
- REQUIRE(rdata->type == 9);
-
- dns_rdata_toregion(rdata, &r);
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &r);
-
- return (dns_name_digest(&name, digest, arg));
-}
-
-static inline isc_boolean_t
-checkowner_mr(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 9);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_mr(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 9);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_mr(ARGS_COMPARE) {
- return (compare_mr(rdata1, rdata2));
-}
-
-#endif /* RDATA_GENERIC_MR_9_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/mr_9.h b/contrib/bind9/lib/dns/rdata/generic/mr_9.h
deleted file mode 100644
index 3d81bdd94cbe..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/mr_9.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* */
-#ifndef GENERIC_MR_9_H
-#define GENERIC_MR_9_H 1
-
-/* $Id: mr_9.h,v 1.26 2007/06/19 23:47:17 tbox Exp $ */
-
-typedef struct dns_rdata_mr {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- dns_name_t mr;
-} dns_rdata_mr_t;
-
-#endif /* GENERIC_MR_9_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/mx_15.c b/contrib/bind9/lib/dns/rdata/generic/mx_15.c
deleted file mode 100644
index 77eee158b705..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/mx_15.c
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007, 2009, 2012 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $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 */
-
-#ifndef RDATA_GENERIC_MX_15_C
-#define RDATA_GENERIC_MX_15_C
-
-#include <string.h>
-
-#include <isc/net.h>
-
-#define RRTYPE_MX_ATTRIBUTES (0)
-
-static isc_boolean_t
-check_mx(isc_token_t *token) {
- char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:123.123.123.123.")];
- struct in_addr addr;
- struct in6_addr addr6;
-
- if (strlcpy(tmp, DNS_AS_STR(*token), sizeof(tmp)) >= sizeof(tmp))
- return (ISC_TRUE);
-
- if (tmp[strlen(tmp) - 1] == '.')
- tmp[strlen(tmp) - 1] = '\0';
- if (inet_aton(tmp, &addr) == 1 ||
- inet_pton(AF_INET6, tmp, &addr6) == 1)
- return (ISC_FALSE);
-
- return (ISC_TRUE);
-}
-
-static inline isc_result_t
-fromtext_mx(ARGS_FROMTEXT) {
- isc_token_t token;
- dns_name_t name;
- isc_buffer_t buffer;
- isc_boolean_t ok;
-
- REQUIRE(type == 15);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if (token.value.as_ulong > 0xffffU)
- RETTOK(ISC_R_RANGE);
- RETERR(uint16_tobuffer(token.value.as_ulong, target));
-
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
-
- ok = ISC_TRUE;
- if ((options & DNS_RDATA_CHECKMX) != 0)
- ok = check_mx(&token);
- if (!ok && (options & DNS_RDATA_CHECKMXFAIL) != 0)
- RETTOK(DNS_R_MXISADDRESS);
- if (!ok && callbacks != NULL)
- warn_badmx(&token, lexer, callbacks);
-
- dns_name_init(&name, NULL);
- buffer_fromregion(&buffer, &token.value.as_region);
- origin = (origin != NULL) ? origin : dns_rootname;
- RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
- ok = ISC_TRUE;
- if ((options & DNS_RDATA_CHECKNAMES) != 0)
- ok = dns_name_ishostname(&name, ISC_FALSE);
- if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0)
- RETTOK(DNS_R_BADNAME);
- if (!ok && callbacks != NULL)
- warn_badname(&name, lexer, callbacks);
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_mx(ARGS_TOTEXT) {
- isc_region_t region;
- dns_name_t name;
- dns_name_t prefix;
- isc_boolean_t sub;
- char buf[sizeof("64000")];
- unsigned short num;
-
- REQUIRE(rdata->type == 15);
- REQUIRE(rdata->length != 0);
-
- dns_name_init(&name, NULL);
- dns_name_init(&prefix, NULL);
-
- dns_rdata_toregion(rdata, &region);
- num = uint16_fromregion(&region);
- isc_region_consume(&region, 2);
- sprintf(buf, "%u", num);
- RETERR(str_totext(buf, target));
-
- RETERR(str_totext(" ", target));
-
- dns_name_fromregion(&name, &region);
- sub = name_prefix(&name, tctx->origin, &prefix);
- return (dns_name_totext(&prefix, sub, target));
-}
-
-static inline isc_result_t
-fromwire_mx(ARGS_FROMWIRE) {
- dns_name_t name;
- isc_region_t sregion;
-
- REQUIRE(type == 15);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14);
-
- dns_name_init(&name, NULL);
-
- isc_buffer_activeregion(source, &sregion);
- if (sregion.length < 2)
- return (ISC_R_UNEXPECTEDEND);
- RETERR(mem_tobuffer(target, sregion.base, 2));
- isc_buffer_forward(source, 2);
- return (dns_name_fromwire(&name, source, dctx, options, target));
-}
-
-static inline isc_result_t
-towire_mx(ARGS_TOWIRE) {
- dns_name_t name;
- dns_offsets_t offsets;
- isc_region_t region;
-
- REQUIRE(rdata->type == 15);
- REQUIRE(rdata->length != 0);
-
- dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
-
- dns_rdata_toregion(rdata, &region);
- RETERR(mem_tobuffer(target, region.base, 2));
- isc_region_consume(&region, 2);
-
- dns_name_init(&name, offsets);
- dns_name_fromregion(&name, &region);
-
- return (dns_name_towire(&name, cctx, target));
-}
-
-static inline int
-compare_mx(ARGS_COMPARE) {
- dns_name_t name1;
- dns_name_t name2;
- isc_region_t region1;
- isc_region_t region2;
- int order;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 15);
- REQUIRE(rdata1->length != 0);
- REQUIRE(rdata2->length != 0);
-
- order = memcmp(rdata1->data, rdata2->data, 2);
- if (order != 0)
- return (order < 0 ? -1 : 1);
-
- dns_name_init(&name1, NULL);
- dns_name_init(&name2, NULL);
-
- dns_rdata_toregion(rdata1, &region1);
- dns_rdata_toregion(rdata2, &region2);
-
- isc_region_consume(&region1, 2);
- isc_region_consume(&region2, 2);
-
- dns_name_fromregion(&name1, &region1);
- dns_name_fromregion(&name2, &region2);
-
- return (dns_name_rdatacompare(&name1, &name2));
-}
-
-static inline isc_result_t
-fromstruct_mx(ARGS_FROMSTRUCT) {
- dns_rdata_mx_t *mx = source;
- isc_region_t region;
-
- REQUIRE(type == 15);
- REQUIRE(source != NULL);
- REQUIRE(mx->common.rdtype == type);
- REQUIRE(mx->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- RETERR(uint16_tobuffer(mx->pref, target));
- dns_name_toregion(&mx->mx, &region);
- return (isc_buffer_copyregion(target, &region));
-}
-
-static inline isc_result_t
-tostruct_mx(ARGS_TOSTRUCT) {
- isc_region_t region;
- dns_rdata_mx_t *mx = target;
- dns_name_t name;
-
- REQUIRE(rdata->type == 15);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- mx->common.rdclass = rdata->rdclass;
- mx->common.rdtype = rdata->type;
- ISC_LINK_INIT(&mx->common, link);
-
- dns_name_init(&name, NULL);
- dns_rdata_toregion(rdata, &region);
- mx->pref = uint16_fromregion(&region);
- isc_region_consume(&region, 2);
- dns_name_fromregion(&name, &region);
- dns_name_init(&mx->mx, NULL);
- RETERR(name_duporclone(&name, mctx, &mx->mx));
- mx->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_mx(ARGS_FREESTRUCT) {
- dns_rdata_mx_t *mx = source;
-
- REQUIRE(source != NULL);
- REQUIRE(mx->common.rdtype == 15);
-
- if (mx->mctx == NULL)
- return;
-
- dns_name_free(&mx->mx, mx->mctx);
- mx->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_mx(ARGS_ADDLDATA) {
- dns_name_t name;
- dns_offsets_t offsets;
- isc_region_t region;
-
- REQUIRE(rdata->type == 15);
-
- dns_name_init(&name, offsets);
- dns_rdata_toregion(rdata, &region);
- isc_region_consume(&region, 2);
- dns_name_fromregion(&name, &region);
-
- return ((add)(arg, &name, dns_rdatatype_a));
-}
-
-static inline isc_result_t
-digest_mx(ARGS_DIGEST) {
- isc_region_t r1, r2;
- dns_name_t name;
-
- REQUIRE(rdata->type == 15);
-
- dns_rdata_toregion(rdata, &r1);
- r2 = r1;
- isc_region_consume(&r2, 2);
- r1.length = 2;
- RETERR((digest)(arg, &r1));
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &r2);
- return (dns_name_digest(&name, digest, arg));
-}
-
-static inline isc_boolean_t
-checkowner_mx(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 15);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- return (dns_name_ishostname(name, wildcard));
-}
-
-static inline isc_boolean_t
-checknames_mx(ARGS_CHECKNAMES) {
- isc_region_t region;
- dns_name_t name;
-
- REQUIRE(rdata->type == 15);
-
- UNUSED(owner);
-
- dns_rdata_toregion(rdata, &region);
- isc_region_consume(&region, 2);
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &region);
- if (!dns_name_ishostname(&name, ISC_FALSE)) {
- if (bad != NULL)
- dns_name_clone(&name, bad);
- return (ISC_FALSE);
- }
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_mx(ARGS_COMPARE) {
- return (compare_mx(rdata1, rdata2));
-}
-
-#endif /* RDATA_GENERIC_MX_15_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/mx_15.h b/contrib/bind9/lib/dns/rdata/generic/mx_15.h
deleted file mode 100644
index 25d5ac5b728e..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/mx_15.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* */
-#ifndef GENERIC_MX_15_H
-#define GENERIC_MX_15_H 1
-
-/* $Id: mx_15.h,v 1.29 2007/06/19 23:47:17 tbox Exp $ */
-
-typedef struct dns_rdata_mx {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- isc_uint16_t pref;
- dns_name_t mx;
-} dns_rdata_mx_t;
-
-#endif /* GENERIC_MX_15_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/naptr_35.c b/contrib/bind9/lib/dns/rdata/generic/naptr_35.c
deleted file mode 100644
index 83439a59293e..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/naptr_35.c
+++ /dev/null
@@ -1,671 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007-2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001, 2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/* Reviewed: Thu Mar 16 16:52:50 PST 2000 by bwelling */
-
-/* RFC2915 */
-
-#ifndef RDATA_GENERIC_NAPTR_35_C
-#define RDATA_GENERIC_NAPTR_35_C
-
-#define RRTYPE_NAPTR_ATTRIBUTES (0)
-
-#include <isc/regex.h>
-
-/*
- * Check the wire format of the Regexp field.
- * Don't allow embeded NUL's.
- */
-static inline isc_result_t
-txt_valid_regex(const unsigned char *txt) {
- unsigned int nsub = 0;
- char regex[256];
- char *cp;
- isc_boolean_t flags = ISC_FALSE;
- isc_boolean_t replace = ISC_FALSE;
- unsigned char c;
- unsigned char delim;
- unsigned int len;
- int n;
-
- len = *txt++;
- if (len == 0U)
- return (ISC_R_SUCCESS);
-
- delim = *txt++;
- len--;
-
- /*
- * Digits, backslash and flags can't be delimiters.
- */
- switch (delim) {
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- case '\\': case 'i': case 0:
- return (DNS_R_SYNTAX);
- }
-
- cp = regex;
- while (len-- > 0) {
- c = *txt++;
- if (c == 0)
- return (DNS_R_SYNTAX);
- if (c == delim && !replace) {
- replace = ISC_TRUE;
- continue;
- } else if (c == delim && !flags) {
- flags = ISC_TRUE;
- continue;
- } else if (c == delim)
- return (DNS_R_SYNTAX);
- /*
- * Flags are not escaped.
- */
- if (flags) {
- switch (c) {
- case 'i':
- continue;
- default:
- return (DNS_R_SYNTAX);
- }
- }
- if (!replace)
- *cp++ = c;
- if (c == '\\') {
- if (len == 0)
- return (DNS_R_SYNTAX);
- c = *txt++;
- if (c == 0)
- return (DNS_R_SYNTAX);
- len--;
- if (replace)
- switch (c) {
- case '0': return (DNS_R_SYNTAX);
- case '1': if (nsub < 1) nsub = 1; break;
- case '2': if (nsub < 2) nsub = 2; break;
- case '3': if (nsub < 3) nsub = 3; break;
- case '4': if (nsub < 4) nsub = 4; break;
- case '5': if (nsub < 5) nsub = 5; break;
- case '6': if (nsub < 6) nsub = 6; break;
- case '7': if (nsub < 7) nsub = 7; break;
- case '8': if (nsub < 8) nsub = 8; break;
- case '9': if (nsub < 9) nsub = 9; break;
- }
- if (!replace)
- *cp++ = c;
- }
- }
- if (!flags)
- return (DNS_R_SYNTAX);
- *cp = '\0';
- n = isc_regex_validate(regex);
- if (n < 0 || nsub > (unsigned int)n)
- return (DNS_R_SYNTAX);
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-fromtext_naptr(ARGS_FROMTEXT) {
- isc_token_t token;
- dns_name_t name;
- isc_buffer_t buffer;
- unsigned char *regex;
-
- REQUIRE(type == 35);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(callbacks);
-
- /*
- * Order.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if (token.value.as_ulong > 0xffffU)
- RETTOK(ISC_R_RANGE);
- RETERR(uint16_tobuffer(token.value.as_ulong, target));
-
- /*
- * Preference.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if (token.value.as_ulong > 0xffffU)
- RETTOK(ISC_R_RANGE);
- RETERR(uint16_tobuffer(token.value.as_ulong, target));
-
- /*
- * Flags.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring,
- ISC_FALSE));
- RETTOK(txt_fromtext(&token.value.as_textregion, target));
-
- /*
- * Service.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring,
- ISC_FALSE));
- RETTOK(txt_fromtext(&token.value.as_textregion, target));
-
- /*
- * Regexp.
- */
- regex = isc_buffer_used(target);
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring,
- ISC_FALSE));
- RETTOK(txt_fromtext(&token.value.as_textregion, target));
- RETTOK(txt_valid_regex(regex));
-
- /*
- * Replacement.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- dns_name_init(&name, NULL);
- buffer_fromregion(&buffer, &token.value.as_region);
- origin = (origin != NULL) ? origin : dns_rootname;
- RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_naptr(ARGS_TOTEXT) {
- isc_region_t region;
- dns_name_t name;
- dns_name_t prefix;
- isc_boolean_t sub;
- char buf[sizeof("64000")];
- unsigned short num;
-
- REQUIRE(rdata->type == 35);
- REQUIRE(rdata->length != 0);
-
- dns_name_init(&name, NULL);
- dns_name_init(&prefix, NULL);
-
- dns_rdata_toregion(rdata, &region);
-
- /*
- * Order.
- */
- num = uint16_fromregion(&region);
- isc_region_consume(&region, 2);
- sprintf(buf, "%u", num);
- RETERR(str_totext(buf, target));
- RETERR(str_totext(" ", target));
-
- /*
- * Preference.
- */
- num = uint16_fromregion(&region);
- isc_region_consume(&region, 2);
- sprintf(buf, "%u", num);
- RETERR(str_totext(buf, target));
- RETERR(str_totext(" ", target));
-
- /*
- * Flags.
- */
- RETERR(txt_totext(&region, target));
- RETERR(str_totext(" ", target));
-
- /*
- * Service.
- */
- RETERR(txt_totext(&region, target));
- RETERR(str_totext(" ", target));
-
- /*
- * Regexp.
- */
- RETERR(txt_totext(&region, target));
- RETERR(str_totext(" ", target));
-
- /*
- * Replacement.
- */
- dns_name_fromregion(&name, &region);
- sub = name_prefix(&name, tctx->origin, &prefix);
- return (dns_name_totext(&prefix, sub, target));
-}
-
-static inline isc_result_t
-fromwire_naptr(ARGS_FROMWIRE) {
- dns_name_t name;
- isc_region_t sr;
- unsigned char *regex;
-
- REQUIRE(type == 35);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
-
- dns_name_init(&name, NULL);
-
- /*
- * Order, preference.
- */
- isc_buffer_activeregion(source, &sr);
- if (sr.length < 4)
- return (ISC_R_UNEXPECTEDEND);
- RETERR(mem_tobuffer(target, sr.base, 4));
- isc_buffer_forward(source, 4);
-
- /*
- * Flags.
- */
- RETERR(txt_fromwire(source, target));
-
- /*
- * Service.
- */
- RETERR(txt_fromwire(source, target));
-
- /*
- * Regexp.
- */
- regex = isc_buffer_used(target);
- RETERR(txt_fromwire(source, target));
- RETERR(txt_valid_regex(regex));
-
- /*
- * Replacement.
- */
- return (dns_name_fromwire(&name, source, dctx, options, target));
-}
-
-static inline isc_result_t
-towire_naptr(ARGS_TOWIRE) {
- dns_name_t name;
- dns_offsets_t offsets;
- isc_region_t sr;
-
- REQUIRE(rdata->type == 35);
- REQUIRE(rdata->length != 0);
-
- dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
- /*
- * Order, preference.
- */
- dns_rdata_toregion(rdata, &sr);
- RETERR(mem_tobuffer(target, sr.base, 4));
- isc_region_consume(&sr, 4);
-
- /*
- * Flags.
- */
- RETERR(mem_tobuffer(target, sr.base, sr.base[0] + 1));
- isc_region_consume(&sr, sr.base[0] + 1);
-
- /*
- * Service.
- */
- RETERR(mem_tobuffer(target, sr.base, sr.base[0] + 1));
- isc_region_consume(&sr, sr.base[0] + 1);
-
- /*
- * Regexp.
- */
- RETERR(mem_tobuffer(target, sr.base, sr.base[0] + 1));
- isc_region_consume(&sr, sr.base[0] + 1);
-
- /*
- * Replacement.
- */
- dns_name_init(&name, offsets);
- dns_name_fromregion(&name, &sr);
- return (dns_name_towire(&name, cctx, target));
-}
-
-static inline int
-compare_naptr(ARGS_COMPARE) {
- dns_name_t name1;
- dns_name_t name2;
- isc_region_t region1;
- isc_region_t region2;
- int order, len;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 35);
- REQUIRE(rdata1->length != 0);
- REQUIRE(rdata2->length != 0);
-
- dns_rdata_toregion(rdata1, &region1);
- dns_rdata_toregion(rdata2, &region2);
-
- /*
- * Order, preference.
- */
- order = memcmp(region1.base, region2.base, 4);
- if (order != 0)
- return (order < 0 ? -1 : 1);
- isc_region_consume(&region1, 4);
- isc_region_consume(&region2, 4);
-
- /*
- * Flags.
- */
- len = ISC_MIN(region1.base[0], region2.base[0]);
- order = memcmp(region1.base, region2.base, len + 1);
- if (order != 0)
- return (order < 0 ? -1 : 1);
- isc_region_consume(&region1, region1.base[0] + 1);
- isc_region_consume(&region2, region2.base[0] + 1);
-
- /*
- * Service.
- */
- len = ISC_MIN(region1.base[0], region2.base[0]);
- order = memcmp(region1.base, region2.base, len + 1);
- if (order != 0)
- return (order < 0 ? -1 : 1);
- isc_region_consume(&region1, region1.base[0] + 1);
- isc_region_consume(&region2, region2.base[0] + 1);
-
- /*
- * Regexp.
- */
- len = ISC_MIN(region1.base[0], region2.base[0]);
- order = memcmp(region1.base, region2.base, len + 1);
- if (order != 0)
- return (order < 0 ? -1 : 1);
- isc_region_consume(&region1, region1.base[0] + 1);
- isc_region_consume(&region2, region2.base[0] + 1);
-
- /*
- * Replacement.
- */
- dns_name_init(&name1, NULL);
- dns_name_init(&name2, NULL);
-
- dns_name_fromregion(&name1, &region1);
- dns_name_fromregion(&name2, &region2);
-
- return (dns_name_rdatacompare(&name1, &name2));
-}
-
-static inline isc_result_t
-fromstruct_naptr(ARGS_FROMSTRUCT) {
- dns_rdata_naptr_t *naptr = source;
- isc_region_t region;
-
- REQUIRE(type == 35);
- REQUIRE(source != NULL);
- REQUIRE(naptr->common.rdtype == type);
- REQUIRE(naptr->common.rdclass == rdclass);
- REQUIRE(naptr->flags != NULL || naptr->flags_len == 0);
- REQUIRE(naptr->service != NULL || naptr->service_len == 0);
- REQUIRE(naptr->regexp != NULL || naptr->regexp_len == 0);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- RETERR(uint16_tobuffer(naptr->order, target));
- RETERR(uint16_tobuffer(naptr->preference, target));
- RETERR(uint8_tobuffer(naptr->flags_len, target));
- RETERR(mem_tobuffer(target, naptr->flags, naptr->flags_len));
- RETERR(uint8_tobuffer(naptr->service_len, target));
- RETERR(mem_tobuffer(target, naptr->service, naptr->service_len));
- RETERR(uint8_tobuffer(naptr->regexp_len, target));
- RETERR(mem_tobuffer(target, naptr->regexp, naptr->regexp_len));
- dns_name_toregion(&naptr->replacement, &region);
- return (isc_buffer_copyregion(target, &region));
-}
-
-static inline isc_result_t
-tostruct_naptr(ARGS_TOSTRUCT) {
- dns_rdata_naptr_t *naptr = target;
- isc_region_t r;
- isc_result_t result;
- dns_name_t name;
-
- REQUIRE(rdata->type == 35);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- naptr->common.rdclass = rdata->rdclass;
- naptr->common.rdtype = rdata->type;
- ISC_LINK_INIT(&naptr->common, link);
-
- naptr->flags = NULL;
- naptr->service = NULL;
- naptr->regexp = NULL;
-
- dns_rdata_toregion(rdata, &r);
-
- naptr->order = uint16_fromregion(&r);
- isc_region_consume(&r, 2);
-
- naptr->preference = uint16_fromregion(&r);
- isc_region_consume(&r, 2);
-
- naptr->flags_len = uint8_fromregion(&r);
- isc_region_consume(&r, 1);
- INSIST(naptr->flags_len <= r.length);
- naptr->flags = mem_maybedup(mctx, r.base, naptr->flags_len);
- if (naptr->flags == NULL)
- goto cleanup;
- isc_region_consume(&r, naptr->flags_len);
-
- naptr->service_len = uint8_fromregion(&r);
- isc_region_consume(&r, 1);
- INSIST(naptr->service_len <= r.length);
- naptr->service = mem_maybedup(mctx, r.base, naptr->service_len);
- if (naptr->service == NULL)
- goto cleanup;
- isc_region_consume(&r, naptr->service_len);
-
- naptr->regexp_len = uint8_fromregion(&r);
- isc_region_consume(&r, 1);
- INSIST(naptr->regexp_len <= r.length);
- naptr->regexp = mem_maybedup(mctx, r.base, naptr->regexp_len);
- if (naptr->regexp == NULL)
- goto cleanup;
- isc_region_consume(&r, naptr->regexp_len);
-
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &r);
- dns_name_init(&naptr->replacement, NULL);
- result = name_duporclone(&name, mctx, &naptr->replacement);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- naptr->mctx = mctx;
- return (ISC_R_SUCCESS);
-
- cleanup:
- if (mctx != NULL && naptr->flags != NULL)
- isc_mem_free(mctx, naptr->flags);
- if (mctx != NULL && naptr->service != NULL)
- isc_mem_free(mctx, naptr->service);
- if (mctx != NULL && naptr->regexp != NULL)
- isc_mem_free(mctx, naptr->regexp);
- return (ISC_R_NOMEMORY);
-}
-
-static inline void
-freestruct_naptr(ARGS_FREESTRUCT) {
- dns_rdata_naptr_t *naptr = source;
-
- REQUIRE(source != NULL);
- REQUIRE(naptr->common.rdtype == 35);
-
- if (naptr->mctx == NULL)
- return;
-
- if (naptr->flags != NULL)
- isc_mem_free(naptr->mctx, naptr->flags);
- if (naptr->service != NULL)
- isc_mem_free(naptr->mctx, naptr->service);
- if (naptr->regexp != NULL)
- isc_mem_free(naptr->mctx, naptr->regexp);
- dns_name_free(&naptr->replacement, naptr->mctx);
- naptr->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_naptr(ARGS_ADDLDATA) {
- dns_name_t name;
- dns_offsets_t offsets;
- isc_region_t sr;
- dns_rdatatype_t atype;
- unsigned int i, flagslen;
- char *cp;
-
- REQUIRE(rdata->type == 35);
-
- /*
- * Order, preference.
- */
- dns_rdata_toregion(rdata, &sr);
- isc_region_consume(&sr, 4);
-
- /*
- * Flags.
- */
- atype = 0;
- flagslen = sr.base[0];
- cp = (char *)&sr.base[1];
- for (i = 0; i < flagslen; i++, cp++) {
- if (*cp == 'S' || *cp == 's') {
- atype = dns_rdatatype_srv;
- break;
- }
- if (*cp == 'A' || *cp == 'a') {
- atype = dns_rdatatype_a;
- break;
- }
- }
- isc_region_consume(&sr, flagslen + 1);
-
- /*
- * Service.
- */
- isc_region_consume(&sr, sr.base[0] + 1);
-
- /*
- * Regexp.
- */
- isc_region_consume(&sr, sr.base[0] + 1);
-
- /*
- * Replacement.
- */
- dns_name_init(&name, offsets);
- dns_name_fromregion(&name, &sr);
-
- if (atype != 0)
- return ((add)(arg, &name, atype));
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_naptr(ARGS_DIGEST) {
- isc_region_t r1, r2;
- unsigned int length, n;
- isc_result_t result;
- dns_name_t name;
-
- REQUIRE(rdata->type == 35);
-
- dns_rdata_toregion(rdata, &r1);
- r2 = r1;
- length = 0;
-
- /*
- * Order, preference.
- */
- length += 4;
- isc_region_consume(&r2, 4);
-
- /*
- * Flags.
- */
- n = r2.base[0] + 1;
- length += n;
- isc_region_consume(&r2, n);
-
- /*
- * Service.
- */
- n = r2.base[0] + 1;
- length += n;
- isc_region_consume(&r2, n);
-
- /*
- * Regexp.
- */
- n = r2.base[0] + 1;
- length += n;
- isc_region_consume(&r2, n);
-
- /*
- * Digest the RR up to the replacement name.
- */
- r1.length = length;
- result = (digest)(arg, &r1);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- /*
- * Replacement.
- */
-
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &r2);
-
- return (dns_name_digest(&name, digest, arg));
-}
-
-static inline isc_boolean_t
-checkowner_naptr(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 35);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_naptr(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 35);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_naptr(ARGS_COMPARE) {
- return (compare_naptr(rdata1, rdata2));
-}
-
-#endif /* RDATA_GENERIC_NAPTR_35_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/naptr_35.h b/contrib/bind9/lib/dns/rdata/generic/naptr_35.h
deleted file mode 100644
index f88c52336f82..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/naptr_35.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef GENERIC_NAPTR_35_H
-#define GENERIC_NAPTR_35_H 1
-
-/* $Id$ */
-
-/*!
- * \brief Per RFC2915 */
-
-typedef struct dns_rdata_naptr {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- isc_uint16_t order;
- isc_uint16_t preference;
- char *flags;
- isc_uint8_t flags_len;
- char *service;
- isc_uint8_t service_len;
- char *regexp;
- isc_uint8_t regexp_len;
- dns_name_t replacement;
-} dns_rdata_naptr_t;
-
-#endif /* GENERIC_NAPTR_35_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/nid_104.c b/contrib/bind9/lib/dns/rdata/generic/nid_104.c
deleted file mode 100644
index c96b0bf9c980..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/nid_104.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER 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 RDATA_GENERIC_NID_104_C
-#define RDATA_GENERIC_NID_104_C
-
-#include <string.h>
-
-#include <isc/net.h>
-
-#define RRTYPE_NID_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_nid(ARGS_FROMTEXT) {
- isc_token_t token;
- unsigned char locator[NS_LOCATORSZ];
-
- REQUIRE(type == 104);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(origin);
- UNUSED(options);
- UNUSED(callbacks);
-
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if (token.value.as_ulong > 0xffffU)
- RETTOK(ISC_R_RANGE);
- RETERR(uint16_tobuffer(token.value.as_ulong, target));
-
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
-
- if (locator_pton(DNS_AS_STR(token), locator) != 1)
- RETTOK(DNS_R_SYNTAX);
- return (mem_tobuffer(target, locator, NS_LOCATORSZ));
-}
-
-static inline isc_result_t
-totext_nid(ARGS_TOTEXT) {
- isc_region_t region;
- char buf[sizeof("xxxx:xxxx:xxxx:xxxx")];
- unsigned short num;
-
- REQUIRE(rdata->type == 104);
- REQUIRE(rdata->length != 0);
-
- UNUSED(tctx);
-
- dns_rdata_toregion(rdata, &region);
- num = uint16_fromregion(&region);
- isc_region_consume(&region, 2);
- sprintf(buf, "%u", num);
- RETERR(str_totext(buf, target));
-
- RETERR(str_totext(" ", target));
-
- sprintf(buf, "%x:%x:%x:%x",
- region.base[0]<<8 | region.base[1],
- region.base[2]<<8 | region.base[3],
- region.base[4]<<8 | region.base[5],
- region.base[6]<<8 | region.base[7]);
- return (str_totext(buf, target));
-}
-
-static inline isc_result_t
-fromwire_nid(ARGS_FROMWIRE) {
- isc_region_t sregion;
-
- REQUIRE(type == 104);
-
- UNUSED(type);
- UNUSED(options);
- UNUSED(rdclass);
- UNUSED(dctx);
-
- isc_buffer_activeregion(source, &sregion);
- if (sregion.length != 10)
- return (DNS_R_FORMERR);
- isc_buffer_forward(source, sregion.length);
- return (mem_tobuffer(target, sregion.base, sregion.length));
-}
-
-static inline isc_result_t
-towire_nid(ARGS_TOWIRE) {
-
- REQUIRE(rdata->type == 104);
- REQUIRE(rdata->length == 10);
-
- UNUSED(cctx);
-
- return (mem_tobuffer(target, rdata->data, rdata->length));
-}
-
-static inline int
-compare_nid(ARGS_COMPARE) {
- isc_region_t region1;
- isc_region_t region2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 104);
- REQUIRE(rdata1->length == 10);
- REQUIRE(rdata2->length == 10);
-
- dns_rdata_toregion(rdata1, &region1);
- dns_rdata_toregion(rdata2, &region2);
- return (isc_region_compare(&region1, &region2));
-}
-
-static inline isc_result_t
-fromstruct_nid(ARGS_FROMSTRUCT) {
- dns_rdata_nid_t *nid = source;
-
- REQUIRE(type == 104);
- REQUIRE(source != NULL);
- REQUIRE(nid->common.rdtype == type);
- REQUIRE(nid->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- RETERR(uint16_tobuffer(nid->pref, target));
- return (mem_tobuffer(target, nid->nid, sizeof(nid->nid)));
-}
-
-static inline isc_result_t
-tostruct_nid(ARGS_TOSTRUCT) {
- isc_region_t region;
- dns_rdata_nid_t *nid = target;
-
- REQUIRE(rdata->type == 104);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length == 10);
-
- UNUSED(mctx);
-
- nid->common.rdclass = rdata->rdclass;
- nid->common.rdtype = rdata->type;
- ISC_LINK_INIT(&nid->common, link);
-
- dns_rdata_toregion(rdata, &region);
- nid->pref = uint16_fromregion(&region);
- memcpy(nid->nid, region.base, region.length);
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_nid(ARGS_FREESTRUCT) {
- dns_rdata_nid_t *nid = source;
-
- REQUIRE(source != NULL);
- REQUIRE(nid->common.rdtype == 104);
-
- return;
-}
-
-static inline isc_result_t
-additionaldata_nid(ARGS_ADDLDATA) {
-
- REQUIRE(rdata->type == 104);
- REQUIRE(rdata->length == 10);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_nid(ARGS_DIGEST) {
- isc_region_t r;
-
- REQUIRE(rdata->type == 104);
- REQUIRE(rdata->length == 10);
-
- dns_rdata_toregion(rdata, &r);
-
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_nid(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 104);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_nid(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 104);
- REQUIRE(rdata->length == 10);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_nid(ARGS_COMPARE) {
- return (compare_nid(rdata1, rdata2));
-}
-
-#endif /* RDATA_GENERIC_NID_104_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/nid_104.h b/contrib/bind9/lib/dns/rdata/generic/nid_104.h
deleted file mode 100644
index 64a3ba477dfc..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/nid_104.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER 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_NID_104_H
-#define GENERIC_NID_104_H 1
-
-typedef struct dns_rdata_nid {
- dns_rdatacommon_t common;
- isc_uint16_t pref;
- unsigned char nid[8];
-} dns_rdata_nid_t;
-
-#endif /* GENERIC_NID_104_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/ns_2.c b/contrib/bind9/lib/dns/rdata/generic/ns_2.c
deleted file mode 100644
index 5db81e7cb390..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/ns_2.c
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: ns_2.c,v 1.48 2009/12/04 22:06:37 tbox Exp $ */
-
-/* Reviewed: Wed Mar 15 18:15:00 PST 2000 by bwelling */
-
-#ifndef RDATA_GENERIC_NS_2_C
-#define RDATA_GENERIC_NS_2_C
-
-#define RRTYPE_NS_ATTRIBUTES (DNS_RDATATYPEATTR_ZONECUTAUTH)
-
-static inline isc_result_t
-fromtext_ns(ARGS_FROMTEXT) {
- isc_token_t token;
- dns_name_t name;
- isc_buffer_t buffer;
- isc_boolean_t ok;
-
- REQUIRE(type == 2);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(callbacks);
-
- RETERR(isc_lex_getmastertoken(lexer, &token,isc_tokentype_string,
- ISC_FALSE));
-
- dns_name_init(&name, NULL);
- buffer_fromregion(&buffer, &token.value.as_region);
- origin = (origin != NULL) ? origin : dns_rootname;
- RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
- ok = ISC_TRUE;
- if ((options & DNS_RDATA_CHECKNAMES) != 0)
- ok = dns_name_ishostname(&name, ISC_FALSE);
- if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0)
- RETTOK(DNS_R_BADNAME);
- if (!ok && callbacks != NULL)
- warn_badname(&name, lexer, callbacks);
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_ns(ARGS_TOTEXT) {
- isc_region_t region;
- dns_name_t name;
- dns_name_t prefix;
- isc_boolean_t sub;
-
- REQUIRE(rdata->type == 2);
- REQUIRE(rdata->length != 0);
-
- dns_name_init(&name, NULL);
- dns_name_init(&prefix, NULL);
-
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
-
- sub = name_prefix(&name, tctx->origin, &prefix);
-
- return (dns_name_totext(&prefix, sub, target));
-}
-
-static inline isc_result_t
-fromwire_ns(ARGS_FROMWIRE) {
- dns_name_t name;
-
- REQUIRE(type == 2);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14);
-
- dns_name_init(&name, NULL);
- return (dns_name_fromwire(&name, source, dctx, options, target));
-}
-
-static inline isc_result_t
-towire_ns(ARGS_TOWIRE) {
- dns_name_t name;
- dns_offsets_t offsets;
- isc_region_t region;
-
- REQUIRE(rdata->type == 2);
- REQUIRE(rdata->length != 0);
-
- dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
-
- dns_name_init(&name, offsets);
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
-
- return (dns_name_towire(&name, cctx, target));
-}
-
-static inline int
-compare_ns(ARGS_COMPARE) {
- dns_name_t name1;
- dns_name_t name2;
- isc_region_t region1;
- isc_region_t region2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 2);
- 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);
-
- return (dns_name_rdatacompare(&name1, &name2));
-}
-
-static inline isc_result_t
-fromstruct_ns(ARGS_FROMSTRUCT) {
- dns_rdata_ns_t *ns = source;
- isc_region_t region;
-
- REQUIRE(type == 2);
- REQUIRE(source != NULL);
- REQUIRE(ns->common.rdtype == type);
- REQUIRE(ns->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_name_toregion(&ns->name, &region);
- return (isc_buffer_copyregion(target, &region));
-}
-
-static inline isc_result_t
-tostruct_ns(ARGS_TOSTRUCT) {
- isc_region_t region;
- dns_rdata_ns_t *ns = target;
- dns_name_t name;
-
- REQUIRE(rdata->type == 2);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- ns->common.rdclass = rdata->rdclass;
- ns->common.rdtype = rdata->type;
- ISC_LINK_INIT(&ns->common, link);
-
- dns_name_init(&name, NULL);
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
- dns_name_init(&ns->name, NULL);
- RETERR(name_duporclone(&name, mctx, &ns->name));
- ns->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_ns(ARGS_FREESTRUCT) {
- dns_rdata_ns_t *ns = source;
-
- REQUIRE(source != NULL);
-
- if (ns->mctx == NULL)
- return;
-
- dns_name_free(&ns->name, ns->mctx);
- ns->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_ns(ARGS_ADDLDATA) {
- dns_name_t name;
- dns_offsets_t offsets;
- isc_region_t region;
-
- REQUIRE(rdata->type == 2);
-
- dns_name_init(&name, offsets);
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
-
- return ((add)(arg, &name, dns_rdatatype_a));
-}
-
-static inline isc_result_t
-digest_ns(ARGS_DIGEST) {
- isc_region_t r;
- dns_name_t name;
-
- REQUIRE(rdata->type == 2);
-
- dns_rdata_toregion(rdata, &r);
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &r);
-
- return (dns_name_digest(&name, digest, arg));
-}
-
-static inline isc_boolean_t
-checkowner_ns(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 2);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_ns(ARGS_CHECKNAMES) {
- isc_region_t region;
- dns_name_t name;
-
- REQUIRE(rdata->type == 2);
-
- UNUSED(owner);
-
- dns_rdata_toregion(rdata, &region);
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &region);
- if (!dns_name_ishostname(&name, ISC_FALSE)) {
- if (bad != NULL)
- dns_name_clone(&name, bad);
- return (ISC_FALSE);
- }
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_ns(ARGS_COMPARE) {
- return (compare_ns(rdata1, rdata2));
-}
-
-#endif /* RDATA_GENERIC_NS_2_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/ns_2.h b/contrib/bind9/lib/dns/rdata/generic/ns_2.h
deleted file mode 100644
index 546e71af06e3..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/ns_2.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* */
-#ifndef GENERIC_NS_2_H
-#define GENERIC_NS_2_H 1
-
-/* $Id: ns_2.h,v 1.27 2007/06/19 23:47:17 tbox Exp $ */
-
-typedef struct dns_rdata_ns {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- dns_name_t name;
-} dns_rdata_ns_t;
-
-
-#endif /* GENERIC_NS_2_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/nsec3_50.c b/contrib/bind9/lib/dns/rdata/generic/nsec3_50.c
deleted file mode 100644
index 19b94efa06dc..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/nsec3_50.c
+++ /dev/null
@@ -1,505 +0,0 @@
-/*
- * Copyright (C) 2008, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN 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 (C) 2004 Nominet, Ltd.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND NOMINET DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* RFC 5155 */
-
-#ifndef RDATA_GENERIC_NSEC3_50_C
-#define RDATA_GENERIC_NSEC3_50_C
-
-#include <isc/iterated_hash.h>
-#include <isc/base32.h>
-
-#define RRTYPE_NSEC3_ATTRIBUTES DNS_RDATATYPEATTR_DNSSEC
-
-static inline isc_result_t
-fromtext_nsec3(ARGS_FROMTEXT) {
- isc_token_t token;
- unsigned char bm[8*1024]; /* 64k bits */
- dns_rdatatype_t covered;
- int octet;
- int window;
- unsigned int flags;
- unsigned char hashalg;
- isc_buffer_t b;
-
- REQUIRE(type == 50);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(callbacks);
- UNUSED(origin);
- UNUSED(options);
-
- /* Hash. */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- RETTOK(dns_hashalg_fromtext(&hashalg, &token.value.as_textregion));
- RETERR(uint8_tobuffer(hashalg, target));
-
- /* Flags. */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- flags = token.value.as_ulong;
- if (flags > 255U)
- RETTOK(ISC_R_RANGE);
- RETERR(uint8_tobuffer(flags, target));
-
- /* Iterations. */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if (token.value.as_ulong > 0xffffU)
- RETTOK(ISC_R_RANGE);
- RETERR(uint16_tobuffer(token.value.as_ulong, target));
-
- /* salt */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- if (token.value.as_textregion.length > (255*2))
- RETTOK(DNS_R_TEXTTOOLONG);
- if (strcmp(DNS_AS_STR(token), "-") == 0) {
- RETERR(uint8_tobuffer(0, target));
- } else {
- RETERR(uint8_tobuffer(strlen(DNS_AS_STR(token)) / 2, target));
- RETERR(isc_hex_decodestring(DNS_AS_STR(token), target));
- }
-
- /*
- * Next hash a single base32hex word.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- isc_buffer_init(&b, bm, sizeof(bm));
- RETTOK(isc_base32hex_decodestring(DNS_AS_STR(token), &b));
- if (isc_buffer_usedlength(&b) > 0xffU)
- RETTOK(ISC_R_RANGE);
- RETERR(uint8_tobuffer(isc_buffer_usedlength(&b), target));
- RETERR(mem_tobuffer(target, &bm, isc_buffer_usedlength(&b)));
-
- memset(bm, 0, sizeof(bm));
- do {
- RETERR(isc_lex_getmastertoken(lexer, &token,
- isc_tokentype_string, ISC_TRUE));
- if (token.type != isc_tokentype_string)
- break;
- RETTOK(dns_rdatatype_fromtext(&covered,
- &token.value.as_textregion));
- bm[covered/8] |= (0x80>>(covered%8));
- } while (1);
- isc_lex_ungettoken(lexer, &token);
- for (window = 0; window < 256 ; window++) {
- /*
- * Find if we have a type in this window.
- */
- for (octet = 31; octet >= 0; octet--)
- if (bm[window * 32 + octet] != 0)
- break;
- if (octet < 0)
- continue;
- RETERR(uint8_tobuffer(window, target));
- RETERR(uint8_tobuffer(octet + 1, target));
- RETERR(mem_tobuffer(target, &bm[window * 32], octet + 1));
- }
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_nsec3(ARGS_TOTEXT) {
- isc_region_t sr;
- unsigned int i, j, k;
- unsigned int window, len;
- unsigned char hash;
- unsigned char flags;
- char buf[sizeof("65535 ")];
- isc_uint32_t iterations;
- isc_boolean_t first;
-
- REQUIRE(rdata->type == 50);
- REQUIRE(rdata->length != 0);
-
- dns_rdata_toregion(rdata, &sr);
-
- /* Hash */
- hash = uint8_fromregion(&sr);
- isc_region_consume(&sr, 1);
- sprintf(buf, "%u ", hash);
- RETERR(str_totext(buf, target));
-
- /* Flags */
- flags = uint8_fromregion(&sr);
- isc_region_consume(&sr, 1);
- sprintf(buf, "%u ", flags);
- RETERR(str_totext(buf, target));
-
- /* Iterations */
- iterations = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
- sprintf(buf, "%u ", iterations);
- RETERR(str_totext(buf, target));
-
- /* Salt */
- j = uint8_fromregion(&sr);
- isc_region_consume(&sr, 1);
- INSIST(j <= sr.length);
-
- if (j != 0) {
- i = sr.length;
- sr.length = j;
- RETERR(isc_hex_totext(&sr, 1, "", target));
- sr.length = i - j;
- } else
- RETERR(str_totext("-", target));
-
- if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
- RETERR(str_totext(" (", target));
- RETERR(str_totext(tctx->linebreak, target));
-
- /* Next hash */
- j = uint8_fromregion(&sr);
- isc_region_consume(&sr, 1);
- INSIST(j <= sr.length);
-
- i = sr.length;
- sr.length = j;
- RETERR(isc_base32hex_totext(&sr, 1, "", target));
- sr.length = i - j;
-
- if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) == 0)
- RETERR(str_totext(" ", target));
-
- /* Types covered */
- first = ISC_TRUE;
- for (i = 0; i < sr.length; i += len) {
- if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
- RETERR(str_totext(tctx->linebreak, target));
- first = ISC_TRUE;
- }
- INSIST(i + 2 <= sr.length);
- window = sr.base[i];
- len = sr.base[i + 1];
- INSIST(len > 0 && len <= 32);
- i += 2;
- INSIST(i + len <= sr.length);
- for (j = 0; j < len; j++) {
- dns_rdatatype_t t;
- if (sr.base[i + j] == 0)
- continue;
- for (k = 0; k < 8; k++) {
- if ((sr.base[i + j] & (0x80 >> k)) == 0)
- continue;
- t = window * 256 + j * 8 + k;
- if (!first)
- RETERR(str_totext(" ", target));
- first = ISC_FALSE;
- if (dns_rdatatype_isknown(t)) {
- RETERR(dns_rdatatype_totext(t, target));
- } else {
- char buf[sizeof("TYPE65535")];
- sprintf(buf, "TYPE%u", t);
- RETERR(str_totext(buf, target));
- }
- }
- }
- }
-
- if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
- RETERR(str_totext(" )", target));
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-fromwire_nsec3(ARGS_FROMWIRE) {
- isc_region_t sr, rr;
- unsigned int window, lastwindow = 0;
- unsigned int len;
- unsigned int saltlen, hashlen;
- isc_boolean_t first = ISC_TRUE;
- unsigned int i;
-
- REQUIRE(type == 50);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(options);
- UNUSED(dctx);
-
- isc_buffer_activeregion(source, &sr);
- rr = sr;
-
- /* hash(1), flags(1), iteration(2), saltlen(1) */
- if (sr.length < 5U)
- RETERR(DNS_R_FORMERR);
- saltlen = sr.base[4];
- isc_region_consume(&sr, 5);
-
- if (sr.length < saltlen)
- RETERR(DNS_R_FORMERR);
- isc_region_consume(&sr, saltlen);
-
- if (sr.length < 1U)
- RETERR(DNS_R_FORMERR);
- hashlen = sr.base[0];
- isc_region_consume(&sr, 1);
-
- if (sr.length < hashlen)
- RETERR(DNS_R_FORMERR);
- isc_region_consume(&sr, hashlen);
-
- for (i = 0; i < sr.length; i += len) {
- /*
- * Check for overflow.
- */
- if (i + 2 > sr.length)
- RETERR(DNS_R_FORMERR);
- window = sr.base[i];
- len = sr.base[i + 1];
- i += 2;
- /*
- * Check that bitmap windows are in the correct order.
- */
- if (!first && window <= lastwindow)
- RETERR(DNS_R_FORMERR);
- /*
- * Check for legal lengths.
- */
- if (len < 1 || len > 32)
- RETERR(DNS_R_FORMERR);
- /*
- * Check for overflow.
- */
- if (i + len > sr.length)
- RETERR(DNS_R_FORMERR);
- /*
- * The last octet of the bitmap must be non zero.
- */
- if (sr.base[i + len - 1] == 0)
- RETERR(DNS_R_FORMERR);
- lastwindow = window;
- first = ISC_FALSE;
- }
- if (i != sr.length)
- return (DNS_R_EXTRADATA);
- RETERR(mem_tobuffer(target, rr.base, rr.length));
- isc_buffer_forward(source, rr.length);
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-towire_nsec3(ARGS_TOWIRE) {
- isc_region_t sr;
-
- REQUIRE(rdata->type == 50);
- REQUIRE(rdata->length != 0);
-
- UNUSED(cctx);
-
- dns_rdata_toregion(rdata, &sr);
- return (mem_tobuffer(target, sr.base, sr.length));
-}
-
-static inline int
-compare_nsec3(ARGS_COMPARE) {
- isc_region_t r1;
- isc_region_t r2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 50);
- 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_nsec3(ARGS_FROMSTRUCT) {
- dns_rdata_nsec3_t *nsec3 = source;
- unsigned int i, len, window, lastwindow = 0;
- isc_boolean_t first = ISC_TRUE;
-
- REQUIRE(type == 50);
- REQUIRE(source != NULL);
- REQUIRE(nsec3->common.rdtype == type);
- REQUIRE(nsec3->common.rdclass == rdclass);
- REQUIRE(nsec3->typebits != NULL || nsec3->len == 0);
- REQUIRE(nsec3->hash == dns_hash_sha1);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- RETERR(uint8_tobuffer(nsec3->hash, target));
- RETERR(uint8_tobuffer(nsec3->flags, target));
- RETERR(uint16_tobuffer(nsec3->iterations, target));
- RETERR(uint8_tobuffer(nsec3->salt_length, target));
- RETERR(mem_tobuffer(target, nsec3->salt, nsec3->salt_length));
- RETERR(uint8_tobuffer(nsec3->next_length, target));
- RETERR(mem_tobuffer(target, nsec3->next, nsec3->next_length));
-
- /*
- * Perform sanity check.
- */
- for (i = 0; i < nsec3->len ; i += len) {
- INSIST(i + 2 <= nsec3->len);
- window = nsec3->typebits[i];
- len = nsec3->typebits[i+1];
- i += 2;
- INSIST(first || window > lastwindow);
- INSIST(len > 0 && len <= 32);
- INSIST(i + len <= nsec3->len);
- INSIST(nsec3->typebits[i + len - 1] != 0);
- lastwindow = window;
- first = ISC_FALSE;
- }
- return (mem_tobuffer(target, nsec3->typebits, nsec3->len));
-}
-
-static inline isc_result_t
-tostruct_nsec3(ARGS_TOSTRUCT) {
- isc_region_t region;
- dns_rdata_nsec3_t *nsec3 = target;
-
- REQUIRE(rdata->type == 50);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- nsec3->common.rdclass = rdata->rdclass;
- nsec3->common.rdtype = rdata->type;
- ISC_LINK_INIT(&nsec3->common, link);
-
- region.base = rdata->data;
- region.length = rdata->length;
- nsec3->hash = uint8_consume_fromregion(&region);
- nsec3->flags = uint8_consume_fromregion(&region);
- nsec3->iterations = uint16_consume_fromregion(&region);
-
- nsec3->salt_length = uint8_consume_fromregion(&region);
- nsec3->salt = mem_maybedup(mctx, region.base, nsec3->salt_length);
- if (nsec3->salt == NULL)
- return (ISC_R_NOMEMORY);
- isc_region_consume(&region, nsec3->salt_length);
-
- nsec3->next_length = uint8_consume_fromregion(&region);
- nsec3->next = mem_maybedup(mctx, region.base, nsec3->next_length);
- if (nsec3->next == NULL)
- goto cleanup;
- isc_region_consume(&region, nsec3->next_length);
-
- nsec3->len = region.length;
- nsec3->typebits = mem_maybedup(mctx, region.base, region.length);
- if (nsec3->typebits == NULL)
- goto cleanup;
-
- nsec3->mctx = mctx;
- return (ISC_R_SUCCESS);
-
- cleanup:
- if (nsec3->next != NULL)
- isc_mem_free(mctx, nsec3->next);
- isc_mem_free(mctx, nsec3->salt);
- return (ISC_R_NOMEMORY);
-}
-
-static inline void
-freestruct_nsec3(ARGS_FREESTRUCT) {
- dns_rdata_nsec3_t *nsec3 = source;
-
- REQUIRE(source != NULL);
- REQUIRE(nsec3->common.rdtype == 50);
-
- if (nsec3->mctx == NULL)
- return;
-
- if (nsec3->salt != NULL)
- isc_mem_free(nsec3->mctx, nsec3->salt);
- if (nsec3->next != NULL)
- isc_mem_free(nsec3->mctx, nsec3->next);
- if (nsec3->typebits != NULL)
- isc_mem_free(nsec3->mctx, nsec3->typebits);
- nsec3->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_nsec3(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 50);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_nsec3(ARGS_DIGEST) {
- isc_region_t r;
-
- REQUIRE(rdata->type == 50);
-
- dns_rdata_toregion(rdata, &r);
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_nsec3(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 50);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_nsec3(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 50);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_nsec3(ARGS_COMPARE) {
- return (compare_nsec3(rdata1, rdata2));
-}
-
-#endif /* RDATA_GENERIC_NSEC3_50_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/nsec3_50.h b/contrib/bind9/lib/dns/rdata/generic/nsec3_50.h
deleted file mode 100644
index 5f2afb863b93..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/nsec3_50.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2008, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER 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_NSEC3_50_H
-#define GENERIC_NSEC3_50_H 1
-
-/* $Id$ */
-
-/*!
- * \brief Per RFC 5155 */
-
-#include <isc/iterated_hash.h>
-
-typedef struct dns_rdata_nsec3 {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- dns_hash_t hash;
- unsigned char flags;
- dns_iterations_t iterations;
- unsigned char salt_length;
- unsigned char next_length;
- isc_uint16_t len;
- unsigned char *salt;
- unsigned char *next;
- unsigned char *typebits;
-} dns_rdata_nsec3_t;
-
-/*
- * The corresponding NSEC3 interval is OPTOUT indicating possible
- * insecure delegations.
- */
-#define DNS_NSEC3FLAG_OPTOUT 0x01U
-
-/*%
- * The following flags are used in the private-type record (implemented in
- * lib/dns/private.c) which is used to store NSEC3PARAM data during the
- * time when it is not legal to have an actual NSEC3PARAM record in the
- * zone. They are defined here because the private-type record uses the
- * same flags field for the OPTOUT flag above and for the private flags
- * below. XXX: This should be considered for refactoring.
- */
-
-/*%
- * Non-standard, private type only.
- *
- * Create a corresponding NSEC3 chain.
- * Once the NSEC3 chain is complete this flag will be removed to signal
- * that there is a complete chain.
- *
- * This flag is automatically set when a NSEC3PARAM record is added to
- * the zone via UPDATE.
- *
- * NSEC3PARAM records containing this flag should never be published,
- * but if they are, they should be ignored by RFC 5155 compliant
- * nameservers.
- */
-#define DNS_NSEC3FLAG_CREATE 0x80U
-
-/*%
- * Non-standard, private type only.
- *
- * The corresponding NSEC3 set is to be removed once the NSEC chain
- * has been generated.
- *
- * This flag is automatically set when the last active NSEC3PARAM record
- * is removed from the zone via UPDATE.
- *
- * NSEC3PARAM records containing this flag should never be published,
- * but if they are, they should be ignored by RFC 5155 compliant
- * nameservers.
- */
-#define DNS_NSEC3FLAG_REMOVE 0x40U
-
-/*%
- * Non-standard, private type only.
- *
- * When set with the CREATE flag, a corresponding NSEC3 chain will be
- * created when the zone becomes capable of supporting one (i.e., when it
- * has a DNSKEY RRset containing at least one NSEC3-capable algorithm).
- * Without this flag, NSEC3 chain creation would be attempted immediately,
- * fail, and the private type record would be removed. With it, the NSEC3
- * parameters are stored until they can be used. When the zone has the
- * necessary prerequisites for NSEC3, then the INITIAL flag can be cleared,
- * and the record will be cleaned up normally.
- *
- * NSEC3PARAM records containing this flag should never be published, but
- * if they are, they should be ignored by RFC 5155 compliant nameservers.
- */
-#define DNS_NSEC3FLAG_INITIAL 0x20U
-
-/*%
- * Non-standard, private type only.
- *
- * Prevent the creation of a NSEC chain before the last NSEC3 chain
- * is removed. This will normally only be set when the zone is
- * transitioning from secure with NSEC3 chains to insecure.
- *
- * NSEC3PARAM records containing this flag should never be published,
- * but if they are, they should be ignored by RFC 5155 compliant
- * nameservers.
- */
-#define DNS_NSEC3FLAG_NONSEC 0x10U
-
-#endif /* GENERIC_NSEC3_50_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/nsec3param_51.c b/contrib/bind9/lib/dns/rdata/generic/nsec3param_51.c
deleted file mode 100644
index 379a46b53542..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/nsec3param_51.c
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * Copyright (C) 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: nsec3param_51.c,v 1.7 2009/12/04 21:09:34 marka Exp $ */
-
-/*
- * Copyright (C) 2004 Nominet, Ltd.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND NOMINET DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* RFC 5155 */
-
-#ifndef RDATA_GENERIC_NSEC3PARAM_51_C
-#define RDATA_GENERIC_NSEC3PARAM_51_C
-
-#include <isc/iterated_hash.h>
-#include <isc/base32.h>
-
-#define RRTYPE_NSEC3PARAM_ATTRIBUTES (DNS_RDATATYPEATTR_DNSSEC)
-
-static inline isc_result_t
-fromtext_nsec3param(ARGS_FROMTEXT) {
- isc_token_t token;
- unsigned int flags = 0;
- unsigned char hashalg;
-
- REQUIRE(type == 51);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(callbacks);
- UNUSED(origin);
- UNUSED(options);
-
- /* Hash. */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- RETTOK(dns_hashalg_fromtext(&hashalg, &token.value.as_textregion));
- RETERR(uint8_tobuffer(hashalg, target));
-
- /* Flags. */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- flags = token.value.as_ulong;
- if (flags > 255U)
- RETTOK(ISC_R_RANGE);
- RETERR(uint8_tobuffer(flags, target));
-
- /* Iterations. */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if (token.value.as_ulong > 0xffffU)
- RETTOK(ISC_R_RANGE);
- RETERR(uint16_tobuffer(token.value.as_ulong, target));
-
- /* Salt. */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- if (token.value.as_textregion.length > (255*2))
- RETTOK(DNS_R_TEXTTOOLONG);
- if (strcmp(DNS_AS_STR(token), "-") == 0) {
- RETERR(uint8_tobuffer(0, target));
- } else {
- RETERR(uint8_tobuffer(strlen(DNS_AS_STR(token)) / 2, target));
- RETERR(isc_hex_decodestring(DNS_AS_STR(token), target));
- }
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_nsec3param(ARGS_TOTEXT) {
- isc_region_t sr;
- unsigned int i, j;
- unsigned char hash;
- unsigned char flags;
- char buf[sizeof("65535 ")];
- isc_uint32_t iterations;
-
- REQUIRE(rdata->type == 51);
- REQUIRE(rdata->length != 0);
-
- UNUSED(tctx);
-
- dns_rdata_toregion(rdata, &sr);
-
- hash = uint8_fromregion(&sr);
- isc_region_consume(&sr, 1);
-
- flags = uint8_fromregion(&sr);
- isc_region_consume(&sr, 1);
-
- iterations = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
-
- sprintf(buf, "%u ", hash);
- RETERR(str_totext(buf, target));
-
- sprintf(buf, "%u ", flags);
- RETERR(str_totext(buf, target));
-
- sprintf(buf, "%u ", iterations);
- RETERR(str_totext(buf, target));
-
- j = uint8_fromregion(&sr);
- isc_region_consume(&sr, 1);
- INSIST(j <= sr.length);
-
- if (j != 0) {
- i = sr.length;
- sr.length = j;
- RETERR(isc_hex_totext(&sr, 1, "", target));
- sr.length = i - j;
- } else
- RETERR(str_totext("-", target));
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-fromwire_nsec3param(ARGS_FROMWIRE) {
- isc_region_t sr, rr;
- unsigned int saltlen;
-
- REQUIRE(type == 51);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(options);
- UNUSED(dctx);
-
- isc_buffer_activeregion(source, &sr);
- rr = sr;
-
- /* hash(1), flags(1), iterations(2), saltlen(1) */
- if (sr.length < 5U)
- RETERR(DNS_R_FORMERR);
- saltlen = sr.base[4];
- isc_region_consume(&sr, 5);
-
- if (sr.length < saltlen)
- RETERR(DNS_R_FORMERR);
- isc_region_consume(&sr, saltlen);
- RETERR(mem_tobuffer(target, rr.base, rr.length));
- isc_buffer_forward(source, rr.length);
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-towire_nsec3param(ARGS_TOWIRE) {
- isc_region_t sr;
-
- REQUIRE(rdata->type == 51);
- REQUIRE(rdata->length != 0);
-
- UNUSED(cctx);
-
- dns_rdata_toregion(rdata, &sr);
- return (mem_tobuffer(target, sr.base, sr.length));
-}
-
-static inline int
-compare_nsec3param(ARGS_COMPARE) {
- isc_region_t r1;
- isc_region_t r2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 51);
- 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_nsec3param(ARGS_FROMSTRUCT) {
- dns_rdata_nsec3param_t *nsec3param = source;
-
- REQUIRE(type == 51);
- REQUIRE(source != NULL);
- REQUIRE(nsec3param->common.rdtype == type);
- REQUIRE(nsec3param->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- RETERR(uint8_tobuffer(nsec3param->hash, target));
- RETERR(uint8_tobuffer(nsec3param->flags, target));
- RETERR(uint16_tobuffer(nsec3param->iterations, target));
- RETERR(uint8_tobuffer(nsec3param->salt_length, target));
- RETERR(mem_tobuffer(target, nsec3param->salt,
- nsec3param->salt_length));
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-tostruct_nsec3param(ARGS_TOSTRUCT) {
- isc_region_t region;
- dns_rdata_nsec3param_t *nsec3param = target;
-
- REQUIRE(rdata->type == 51);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- nsec3param->common.rdclass = rdata->rdclass;
- nsec3param->common.rdtype = rdata->type;
- ISC_LINK_INIT(&nsec3param->common, link);
-
- region.base = rdata->data;
- region.length = rdata->length;
- nsec3param->hash = uint8_consume_fromregion(&region);
- nsec3param->flags = uint8_consume_fromregion(&region);
- nsec3param->iterations = uint16_consume_fromregion(&region);
-
- nsec3param->salt_length = uint8_consume_fromregion(&region);
- nsec3param->salt = mem_maybedup(mctx, region.base,
- nsec3param->salt_length);
- if (nsec3param->salt == NULL)
- return (ISC_R_NOMEMORY);
- isc_region_consume(&region, nsec3param->salt_length);
-
- nsec3param->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_nsec3param(ARGS_FREESTRUCT) {
- dns_rdata_nsec3param_t *nsec3param = source;
-
- REQUIRE(source != NULL);
- REQUIRE(nsec3param->common.rdtype == 51);
-
- if (nsec3param->mctx == NULL)
- return;
-
- if (nsec3param->salt != NULL)
- isc_mem_free(nsec3param->mctx, nsec3param->salt);
- nsec3param->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_nsec3param(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 51);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_nsec3param(ARGS_DIGEST) {
- isc_region_t r;
-
- REQUIRE(rdata->type == 51);
-
- dns_rdata_toregion(rdata, &r);
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_nsec3param(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 51);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_nsec3param(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 51);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_nsec3param(ARGS_COMPARE) {
- return (compare_nsec3param(rdata1, rdata2));
-}
-
-#endif /* RDATA_GENERIC_NSEC3PARAM_51_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/nsec3param_51.h b/contrib/bind9/lib/dns/rdata/generic/nsec3param_51.h
deleted file mode 100644
index 2efd7e6cf068..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/nsec3param_51.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2008 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_NSEC3PARAM_51_H
-#define GENERIC_NSEC3PARAM_51_H 1
-
-/* $Id: nsec3param_51.h,v 1.4 2008/09/25 04:02:39 tbox Exp $ */
-
-/*!
- * \brief Per RFC 5155 */
-
-#include <isc/iterated_hash.h>
-
-typedef struct dns_rdata_nsec3param {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- dns_hash_t hash;
- unsigned char flags; /* DNS_NSEC3FLAG_* */
- dns_iterations_t iterations;
- unsigned char salt_length;
- unsigned char *salt;
-} dns_rdata_nsec3param_t;
-
-#endif /* GENERIC_NSEC3PARAM_51_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/nsec_47.c b/contrib/bind9/lib/dns/rdata/generic/nsec_47.c
deleted file mode 100644
index 095f42eba899..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/nsec_47.c
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $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 */
-
-/* RFC 3845 */
-
-#ifndef RDATA_GENERIC_NSEC_47_C
-#define RDATA_GENERIC_NSEC_47_C
-
-/*
- * The attributes do not include DNS_RDATATYPEATTR_SINGLETON
- * because we must be able to handle a parent/child NSEC pair.
- */
-#define RRTYPE_NSEC_ATTRIBUTES (DNS_RDATATYPEATTR_DNSSEC)
-
-static inline isc_result_t
-fromtext_nsec(ARGS_FROMTEXT) {
- isc_token_t token;
- dns_name_t name;
- isc_buffer_t buffer;
- unsigned char bm[8*1024]; /* 64k bits */
- dns_rdatatype_t covered;
- int octet;
- int window;
-
- REQUIRE(type == 47);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(callbacks);
-
- /*
- * Next domain.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- dns_name_init(&name, NULL);
- buffer_fromregion(&buffer, &token.value.as_region);
- origin = (origin != NULL) ? origin : dns_rootname;
- RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
-
- memset(bm, 0, sizeof(bm));
- do {
- RETERR(isc_lex_getmastertoken(lexer, &token,
- isc_tokentype_string, ISC_TRUE));
- if (token.type != isc_tokentype_string)
- break;
- RETTOK(dns_rdatatype_fromtext(&covered,
- &token.value.as_textregion));
- bm[covered/8] |= (0x80>>(covered%8));
- } while (1);
- isc_lex_ungettoken(lexer, &token);
- for (window = 0; window < 256 ; window++) {
- /*
- * Find if we have a type in this window.
- */
- for (octet = 31; octet >= 0; octet--)
- if (bm[window * 32 + octet] != 0)
- break;
- if (octet < 0)
- continue;
- RETERR(uint8_tobuffer(window, target));
- RETERR(uint8_tobuffer(octet + 1, target));
- RETERR(mem_tobuffer(target, &bm[window * 32], octet + 1));
- }
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_nsec(ARGS_TOTEXT) {
- isc_region_t sr;
- unsigned int i, j, k;
- dns_name_t name;
- unsigned int window, len;
-
- REQUIRE(rdata->type == 47);
- REQUIRE(rdata->length != 0);
-
- UNUSED(tctx);
-
- dns_name_init(&name, NULL);
- dns_rdata_toregion(rdata, &sr);
- dns_name_fromregion(&name, &sr);
- isc_region_consume(&sr, name_length(&name));
- RETERR(dns_name_totext(&name, ISC_FALSE, target));
-
-
- for (i = 0; i < sr.length; i += len) {
- INSIST(i + 2 <= sr.length);
- window = sr.base[i];
- len = sr.base[i + 1];
- INSIST(len > 0 && len <= 32);
- i += 2;
- INSIST(i + len <= sr.length);
- for (j = 0; j < len; j++) {
- dns_rdatatype_t t;
- if (sr.base[i + j] == 0)
- continue;
- for (k = 0; k < 8; k++) {
- if ((sr.base[i + j] & (0x80 >> k)) == 0)
- continue;
- t = window * 256 + j * 8 + k;
- RETERR(str_totext(" ", target));
- if (dns_rdatatype_isknown(t)) {
- RETERR(dns_rdatatype_totext(t, target));
- } else {
- char buf[sizeof("TYPE65535")];
- sprintf(buf, "TYPE%u", t);
- RETERR(str_totext(buf, target));
- }
- }
- }
- }
- return (ISC_R_SUCCESS);
-}
-
-static /* inline */ isc_result_t
-fromwire_nsec(ARGS_FROMWIRE) {
- isc_region_t sr;
- dns_name_t name;
- unsigned int window, lastwindow = 0;
- unsigned int len;
- isc_boolean_t first = ISC_TRUE;
- unsigned int i;
-
- REQUIRE(type == 47);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- 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);
- for (i = 0; i < sr.length; i += len) {
- /*
- * Check for overflow.
- */
- if (i + 2 > sr.length)
- RETERR(DNS_R_FORMERR);
- window = sr.base[i];
- len = sr.base[i + 1];
- i += 2;
- /*
- * Check that bitmap windows are in the correct order.
- */
- if (!first && window <= lastwindow)
- RETERR(DNS_R_FORMERR);
- /*
- * Check for legal lengths.
- */
- if (len < 1 || len > 32)
- RETERR(DNS_R_FORMERR);
- /*
- * Check for overflow.
- */
- if (i + len > sr.length)
- RETERR(DNS_R_FORMERR);
- /*
- * The last octet of the bitmap must be non zero.
- */
- if (sr.base[i + len - 1] == 0)
- RETERR(DNS_R_FORMERR);
- lastwindow = window;
- first = ISC_FALSE;
- }
- if (i != sr.length)
- return (DNS_R_EXTRADATA);
- if (first)
- RETERR(DNS_R_FORMERR);
- RETERR(mem_tobuffer(target, sr.base, sr.length));
- isc_buffer_forward(source, sr.length);
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-towire_nsec(ARGS_TOWIRE) {
- isc_region_t sr;
- dns_name_t name;
- dns_offsets_t offsets;
-
- REQUIRE(rdata->type == 47);
- REQUIRE(rdata->length != 0);
-
- dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
- dns_name_init(&name, offsets);
- dns_rdata_toregion(rdata, &sr);
- dns_name_fromregion(&name, &sr);
- isc_region_consume(&sr, name_length(&name));
- RETERR(dns_name_towire(&name, cctx, target));
-
- return (mem_tobuffer(target, sr.base, sr.length));
-}
-
-static inline int
-compare_nsec(ARGS_COMPARE) {
- isc_region_t r1;
- isc_region_t r2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 47);
- 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_nsec(ARGS_FROMSTRUCT) {
- dns_rdata_nsec_t *nsec = source;
- isc_region_t region;
- unsigned int i, len, window, lastwindow = 0;
- isc_boolean_t first = ISC_TRUE;
-
- REQUIRE(type == 47);
- REQUIRE(source != NULL);
- REQUIRE(nsec->common.rdtype == type);
- REQUIRE(nsec->common.rdclass == rdclass);
- REQUIRE(nsec->typebits != NULL || nsec->len == 0);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_name_toregion(&nsec->next, &region);
- RETERR(isc_buffer_copyregion(target, &region));
- /*
- * Perform sanity check.
- */
- for (i = 0; i < nsec->len ; i += len) {
- INSIST(i + 2 <= nsec->len);
- window = nsec->typebits[i];
- len = nsec->typebits[i+1];
- i += 2;
- INSIST(first || window > lastwindow);
- INSIST(len > 0 && len <= 32);
- INSIST(i + len <= nsec->len);
- INSIST(nsec->typebits[i + len - 1] != 0);
- lastwindow = window;
- first = ISC_FALSE;
- }
- INSIST(!first);
- return (mem_tobuffer(target, nsec->typebits, nsec->len));
-}
-
-static inline isc_result_t
-tostruct_nsec(ARGS_TOSTRUCT) {
- isc_region_t region;
- dns_rdata_nsec_t *nsec = target;
- dns_name_t name;
-
- REQUIRE(rdata->type == 47);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- nsec->common.rdclass = rdata->rdclass;
- nsec->common.rdtype = rdata->type;
- ISC_LINK_INIT(&nsec->common, link);
-
- dns_name_init(&name, NULL);
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
- isc_region_consume(&region, name_length(&name));
- dns_name_init(&nsec->next, NULL);
- RETERR(name_duporclone(&name, mctx, &nsec->next));
-
- nsec->len = region.length;
- nsec->typebits = mem_maybedup(mctx, region.base, region.length);
- if (nsec->typebits == NULL)
- goto cleanup;
-
- nsec->mctx = mctx;
- return (ISC_R_SUCCESS);
-
- cleanup:
- if (mctx != NULL)
- dns_name_free(&nsec->next, mctx);
- return (ISC_R_NOMEMORY);
-}
-
-static inline void
-freestruct_nsec(ARGS_FREESTRUCT) {
- dns_rdata_nsec_t *nsec = source;
-
- REQUIRE(source != NULL);
- REQUIRE(nsec->common.rdtype == 47);
-
- if (nsec->mctx == NULL)
- return;
-
- dns_name_free(&nsec->next, nsec->mctx);
- if (nsec->typebits != NULL)
- isc_mem_free(nsec->mctx, nsec->typebits);
- nsec->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_nsec(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 47);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_nsec(ARGS_DIGEST) {
- isc_region_t r;
-
- REQUIRE(rdata->type == 47);
-
- dns_rdata_toregion(rdata, &r);
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_nsec(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 47);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_nsec(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 47);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- 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/contrib/bind9/lib/dns/rdata/generic/nsec_47.h b/contrib/bind9/lib/dns/rdata/generic/nsec_47.h
deleted file mode 100644
index 2b3c6b6ba489..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/nsec_47.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 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.
- */
-
-#ifndef GENERIC_NSEC_47_H
-#define GENERIC_NSEC_47_H 1
-
-/* $Id: nsec_47.h,v 1.10 2008/07/15 23:47:21 tbox Exp $ */
-
-/*!
- * \brief Per RFC 3845 */
-
-typedef struct dns_rdata_nsec {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- dns_name_t next;
- unsigned char *typebits;
- isc_uint16_t len;
-} dns_rdata_nsec_t;
-
-#endif /* GENERIC_NSEC_47_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/null_10.c b/contrib/bind9/lib/dns/rdata/generic/null_10.c
deleted file mode 100644
index 8ba86fbca9b7..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/null_10.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (C) 2004, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-2002 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/* Reviewed: Thu Mar 16 13:57:50 PST 2000 by explorer */
-
-#ifndef RDATA_GENERIC_NULL_10_C
-#define RDATA_GENERIC_NULL_10_C
-
-#define RRTYPE_NULL_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_null(ARGS_FROMTEXT) {
- REQUIRE(type == 10);
-
- UNUSED(rdclass);
- UNUSED(type);
- UNUSED(lexer);
- UNUSED(origin);
- UNUSED(options);
- UNUSED(target);
- UNUSED(callbacks);
-
- return (DNS_R_SYNTAX);
-}
-
-static inline isc_result_t
-totext_null(ARGS_TOTEXT) {
- REQUIRE(rdata->type == 10);
-
- return (unknown_totext(rdata, tctx, target));
-}
-
-static inline isc_result_t
-fromwire_null(ARGS_FROMWIRE) {
- isc_region_t sr;
-
- REQUIRE(type == 10);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(dctx);
- UNUSED(options);
-
- isc_buffer_activeregion(source, &sr);
- isc_buffer_forward(source, sr.length);
- return (mem_tobuffer(target, sr.base, sr.length));
-}
-
-static inline isc_result_t
-towire_null(ARGS_TOWIRE) {
- REQUIRE(rdata->type == 10);
-
- UNUSED(cctx);
-
- return (mem_tobuffer(target, rdata->data, rdata->length));
-}
-
-static inline int
-compare_null(ARGS_COMPARE) {
- isc_region_t r1;
- isc_region_t r2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 10);
-
- dns_rdata_toregion(rdata1, &r1);
- dns_rdata_toregion(rdata2, &r2);
- return (isc_region_compare(&r1, &r2));
-}
-
-static inline isc_result_t
-fromstruct_null(ARGS_FROMSTRUCT) {
- dns_rdata_null_t *null = source;
-
- REQUIRE(type == 10);
- REQUIRE(source != NULL);
- REQUIRE(null->common.rdtype == type);
- REQUIRE(null->common.rdclass == rdclass);
- REQUIRE(null->data != NULL || null->length == 0);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- return (mem_tobuffer(target, null->data, null->length));
-}
-
-static inline isc_result_t
-tostruct_null(ARGS_TOSTRUCT) {
- dns_rdata_null_t *null = target;
- isc_region_t r;
-
- REQUIRE(rdata->type == 10);
- REQUIRE(target != NULL);
-
- null->common.rdclass = rdata->rdclass;
- null->common.rdtype = rdata->type;
- ISC_LINK_INIT(&null->common, link);
-
- dns_rdata_toregion(rdata, &r);
- null->length = r.length;
- null->data = mem_maybedup(mctx, r.base, r.length);
- if (null->data == NULL)
- return (ISC_R_NOMEMORY);
-
- null->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_null(ARGS_FREESTRUCT) {
- dns_rdata_null_t *null = source;
-
- REQUIRE(source != NULL);
- REQUIRE(null->common.rdtype == 10);
-
- if (null->mctx == NULL)
- return;
-
- if (null->data != NULL)
- isc_mem_free(null->mctx, null->data);
- null->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_null(ARGS_ADDLDATA) {
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- REQUIRE(rdata->type == 10);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_null(ARGS_DIGEST) {
- isc_region_t r;
-
- REQUIRE(rdata->type == 10);
-
- dns_rdata_toregion(rdata, &r);
-
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_null(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 10);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_null(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 10);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_null(ARGS_COMPARE) {
- return (compare_null(rdata1, rdata2));
-}
-
-#endif /* RDATA_GENERIC_NULL_10_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/null_10.h b/contrib/bind9/lib/dns/rdata/generic/null_10.h
deleted file mode 100644
index ceeb0185c6e4..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/null_10.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* */
-#ifndef GENERIC_NULL_10_H
-#define GENERIC_NULL_10_H 1
-
-/* $Id: null_10.h,v 1.25 2007/06/19 23:47:17 tbox Exp $ */
-
-typedef struct dns_rdata_null {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- isc_uint16_t length;
- unsigned char *data;
-} dns_rdata_null_t;
-
-
-#endif /* GENERIC_NULL_10_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/nxt_30.c b/contrib/bind9/lib/dns/rdata/generic/nxt_30.c
deleted file mode 100644
index 4d291a8e6f6e..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/nxt_30.c
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $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 */
-
-/* RFC2535 */
-
-#ifndef RDATA_GENERIC_NXT_30_C
-#define RDATA_GENERIC_NXT_30_C
-
-/*
- * The attributes do not include DNS_RDATATYPEATTR_SINGLETON
- * because we must be able to handle a parent/child NXT pair.
- */
-#define RRTYPE_NXT_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_nxt(ARGS_FROMTEXT) {
- isc_token_t token;
- dns_name_t name;
- isc_buffer_t buffer;
- char *e;
- unsigned char bm[8*1024]; /* 64k bits */
- dns_rdatatype_t covered;
- dns_rdatatype_t maxcovered = 0;
- isc_boolean_t first = ISC_TRUE;
- long n;
-
- REQUIRE(type == 30);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(callbacks);
-
- /*
- * Next domain.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- dns_name_init(&name, NULL);
- buffer_fromregion(&buffer, &token.value.as_region);
- origin = (origin != NULL) ? origin : dns_rootname;
- RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
-
- memset(bm, 0, sizeof(bm));
- do {
- RETERR(isc_lex_getmastertoken(lexer, &token,
- isc_tokentype_string, ISC_TRUE));
- if (token.type != isc_tokentype_string)
- break;
- n = strtol(DNS_AS_STR(token), &e, 10);
- if (e != DNS_AS_STR(token) && *e == '\0') {
- covered = (dns_rdatatype_t)n;
- } else if (dns_rdatatype_fromtext(&covered,
- &token.value.as_textregion) == DNS_R_UNKNOWN)
- RETTOK(DNS_R_UNKNOWN);
- /*
- * NXT is only specified for types 1..127.
- */
- if (covered < 1 || covered > 127)
- return (ISC_R_RANGE);
- if (first || covered > maxcovered)
- maxcovered = covered;
- first = ISC_FALSE;
- bm[covered/8] |= (0x80>>(covered%8));
- } while (1);
- isc_lex_ungettoken(lexer, &token);
- if (first)
- return (ISC_R_SUCCESS);
- n = (maxcovered + 8) / 8;
- return (mem_tobuffer(target, bm, n));
-}
-
-static inline isc_result_t
-totext_nxt(ARGS_TOTEXT) {
- isc_region_t sr;
- unsigned int i, j;
- dns_name_t name;
- dns_name_t prefix;
- isc_boolean_t sub;
-
- REQUIRE(rdata->type == 30);
- REQUIRE(rdata->length != 0);
-
- dns_name_init(&name, NULL);
- dns_name_init(&prefix, NULL);
- dns_rdata_toregion(rdata, &sr);
- dns_name_fromregion(&name, &sr);
- isc_region_consume(&sr, name_length(&name));
- sub = name_prefix(&name, tctx->origin, &prefix);
- RETERR(dns_name_totext(&prefix, sub, target));
-
- for (i = 0; i < sr.length; i++) {
- if (sr.base[i] != 0)
- for (j = 0; j < 8; j++)
- if ((sr.base[i] & (0x80 >> j)) != 0) {
- dns_rdatatype_t t = i * 8 + j;
- RETERR(str_totext(" ", target));
- if (dns_rdatatype_isknown(t)) {
- RETERR(dns_rdatatype_totext(t,
- target));
- } else {
- char buf[sizeof("65535")];
- sprintf(buf, "%u", t);
- RETERR(str_totext(buf,
- target));
- }
- }
- }
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-fromwire_nxt(ARGS_FROMWIRE) {
- isc_region_t sr;
- dns_name_t name;
-
- REQUIRE(type == 30);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- 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);
- if (sr.length > 0 && (sr.base[0] & 0x80) == 0 &&
- ((sr.length > 16) || sr.base[sr.length - 1] == 0))
- return (DNS_R_BADBITMAP);
- RETERR(mem_tobuffer(target, sr.base, sr.length));
- isc_buffer_forward(source, sr.length);
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-towire_nxt(ARGS_TOWIRE) {
- isc_region_t sr;
- dns_name_t name;
- dns_offsets_t offsets;
-
- REQUIRE(rdata->type == 30);
- REQUIRE(rdata->length != 0);
-
- dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
- dns_name_init(&name, offsets);
- dns_rdata_toregion(rdata, &sr);
- dns_name_fromregion(&name, &sr);
- isc_region_consume(&sr, name_length(&name));
- RETERR(dns_name_towire(&name, cctx, target));
-
- return (mem_tobuffer(target, sr.base, sr.length));
-}
-
-static inline int
-compare_nxt(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 == 30);
- REQUIRE(rdata1->length != 0);
- REQUIRE(rdata2->length != 0);
-
- dns_name_init(&name1, NULL);
- dns_name_init(&name2, NULL);
- dns_rdata_toregion(rdata1, &r1);
- dns_rdata_toregion(rdata2, &r2);
- dns_name_fromregion(&name1, &r1);
- dns_name_fromregion(&name2, &r2);
- order = dns_name_rdatacompare(&name1, &name2);
- if (order != 0)
- return (order);
-
- return (isc_region_compare(&r1, &r2));
-}
-
-static inline isc_result_t
-fromstruct_nxt(ARGS_FROMSTRUCT) {
- dns_rdata_nxt_t *nxt = source;
- isc_region_t region;
-
- REQUIRE(type == 30);
- REQUIRE(source != NULL);
- REQUIRE(nxt->common.rdtype == type);
- REQUIRE(nxt->common.rdclass == rdclass);
- REQUIRE(nxt->typebits != NULL || nxt->len == 0);
- if (nxt->typebits != NULL && (nxt->typebits[0] & 0x80) == 0) {
- REQUIRE(nxt->len <= 16);
- REQUIRE(nxt->typebits[nxt->len - 1] != 0);
- }
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_name_toregion(&nxt->next, &region);
- RETERR(isc_buffer_copyregion(target, &region));
-
- return (mem_tobuffer(target, nxt->typebits, nxt->len));
-}
-
-static inline isc_result_t
-tostruct_nxt(ARGS_TOSTRUCT) {
- isc_region_t region;
- dns_rdata_nxt_t *nxt = target;
- dns_name_t name;
-
- REQUIRE(rdata->type == 30);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- nxt->common.rdclass = rdata->rdclass;
- nxt->common.rdtype = rdata->type;
- ISC_LINK_INIT(&nxt->common, link);
-
- dns_name_init(&name, NULL);
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
- isc_region_consume(&region, name_length(&name));
- dns_name_init(&nxt->next, NULL);
- RETERR(name_duporclone(&name, mctx, &nxt->next));
-
- nxt->len = region.length;
- nxt->typebits = mem_maybedup(mctx, region.base, region.length);
- if (nxt->typebits == NULL)
- goto cleanup;
-
- nxt->mctx = mctx;
- return (ISC_R_SUCCESS);
-
- cleanup:
- if (mctx != NULL)
- dns_name_free(&nxt->next, mctx);
- return (ISC_R_NOMEMORY);
-}
-
-static inline void
-freestruct_nxt(ARGS_FREESTRUCT) {
- dns_rdata_nxt_t *nxt = source;
-
- REQUIRE(source != NULL);
- REQUIRE(nxt->common.rdtype == 30);
-
- if (nxt->mctx == NULL)
- return;
-
- dns_name_free(&nxt->next, nxt->mctx);
- if (nxt->typebits != NULL)
- isc_mem_free(nxt->mctx, nxt->typebits);
- nxt->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_nxt(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 30);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_nxt(ARGS_DIGEST) {
- isc_region_t r;
- dns_name_t name;
- isc_result_t result;
-
- REQUIRE(rdata->type == 30);
-
- dns_rdata_toregion(rdata, &r);
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &r);
- result = dns_name_digest(&name, digest, arg);
- if (result != ISC_R_SUCCESS)
- return (result);
- isc_region_consume(&r, name_length(&name));
-
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_nxt(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 30);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_nxt(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 30);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_nxt(ARGS_COMPARE) {
- return (compare_nxt(rdata1, rdata2));
-}
-#endif /* RDATA_GENERIC_NXT_30_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/nxt_30.h b/contrib/bind9/lib/dns/rdata/generic/nxt_30.h
deleted file mode 100644
index e2e8688f7216..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/nxt_30.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2002 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef GENERIC_NXT_30_H
-#define GENERIC_NXT_30_H 1
-
-/* $Id: nxt_30.h,v 1.25 2007/06/19 23:47:17 tbox Exp $ */
-
-/*!
- * \brief RFC2535 */
-
-typedef struct dns_rdata_nxt {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- dns_name_t next;
- unsigned char *typebits;
- isc_uint16_t len;
-} dns_rdata_nxt_t;
-
-#endif /* GENERIC_NXT_30_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/opt_41.c b/contrib/bind9/lib/dns/rdata/generic/opt_41.c
deleted file mode 100644
index 4b51804317cc..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/opt_41.c
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-2002 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/* Reviewed: Thu Mar 16 14:06:44 PST 2000 by gson */
-
-/* RFC2671 */
-
-#ifndef RDATA_GENERIC_OPT_41_C
-#define RDATA_GENERIC_OPT_41_C
-
-#define RRTYPE_OPT_ATTRIBUTES (DNS_RDATATYPEATTR_SINGLETON | \
- DNS_RDATATYPEATTR_META | \
- DNS_RDATATYPEATTR_NOTQUESTION)
-
-static inline isc_result_t
-fromtext_opt(ARGS_FROMTEXT) {
- /*
- * OPT records do not have a text format.
- */
-
- REQUIRE(type == 41);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(lexer);
- UNUSED(origin);
- UNUSED(options);
- UNUSED(target);
- UNUSED(callbacks);
-
- return (ISC_R_NOTIMPLEMENTED);
-}
-
-static inline isc_result_t
-totext_opt(ARGS_TOTEXT) {
- isc_region_t r;
- isc_region_t or;
- isc_uint16_t option;
- isc_uint16_t length;
- char buf[sizeof("64000 64000")];
-
- /*
- * OPT records do not have a text format.
- */
-
- REQUIRE(rdata->type == 41);
-
- dns_rdata_toregion(rdata, &r);
- while (r.length > 0) {
- option = uint16_fromregion(&r);
- isc_region_consume(&r, 2);
- length = uint16_fromregion(&r);
- isc_region_consume(&r, 2);
- sprintf(buf, "%u %u", option, length);
- RETERR(str_totext(buf, target));
- INSIST(r.length >= length);
- if (length > 0) {
- if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
- RETERR(str_totext(" (", target));
- RETERR(str_totext(tctx->linebreak, target));
- or = r;
- or.length = length;
- if (tctx->width == 0) /* No splitting */
- RETERR(isc_base64_totext(&or, 60, "", target));
- else
- RETERR(isc_base64_totext(&or, tctx->width - 2,
- tctx->linebreak,
- target));
- isc_region_consume(&r, length);
- if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
- RETERR(str_totext(" )", target));
- }
- if (r.length > 0)
- RETERR(str_totext(" ", target));
- }
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-fromwire_opt(ARGS_FROMWIRE) {
- isc_region_t sregion;
- isc_region_t tregion;
- isc_uint16_t length;
- unsigned int total;
-
- REQUIRE(type == 41);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(dctx);
- UNUSED(options);
-
- isc_buffer_activeregion(source, &sregion);
- total = 0;
- while (sregion.length != 0) {
- if (sregion.length < 4)
- return (ISC_R_UNEXPECTEDEND);
- /*
- * Eat the 16bit option code. There is nothing to
- * be done with it currently.
- */
- isc_region_consume(&sregion, 2);
- length = uint16_fromregion(&sregion);
- isc_region_consume(&sregion, 2);
- total += 4;
- if (sregion.length < length)
- return (ISC_R_UNEXPECTEDEND);
- isc_region_consume(&sregion, length);
- total += length;
- }
-
- isc_buffer_activeregion(source, &sregion);
- isc_buffer_availableregion(target, &tregion);
- if (tregion.length < total)
- return (ISC_R_NOSPACE);
- memcpy(tregion.base, sregion.base, total);
- isc_buffer_forward(source, total);
- isc_buffer_add(target, total);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-towire_opt(ARGS_TOWIRE) {
-
- REQUIRE(rdata->type == 41);
-
- UNUSED(cctx);
-
- return (mem_tobuffer(target, rdata->data, rdata->length));
-}
-
-static inline int
-compare_opt(ARGS_COMPARE) {
- isc_region_t r1;
- isc_region_t r2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 41);
-
- dns_rdata_toregion(rdata1, &r1);
- dns_rdata_toregion(rdata2, &r2);
- return (isc_region_compare(&r1, &r2));
-}
-
-static inline isc_result_t
-fromstruct_opt(ARGS_FROMSTRUCT) {
- dns_rdata_opt_t *opt = source;
- isc_region_t region;
- isc_uint16_t length;
-
- REQUIRE(type == 41);
- REQUIRE(source != NULL);
- REQUIRE(opt->common.rdtype == type);
- REQUIRE(opt->common.rdclass == rdclass);
- REQUIRE(opt->options != NULL || opt->length == 0);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- region.base = opt->options;
- region.length = opt->length;
- while (region.length >= 4) {
- isc_region_consume(&region, 2); /* opt */
- length = uint16_fromregion(&region);
- isc_region_consume(&region, 2);
- if (region.length < length)
- return (ISC_R_UNEXPECTEDEND);
- isc_region_consume(&region, length);
- }
- if (region.length != 0)
- return (ISC_R_UNEXPECTEDEND);
-
- return (mem_tobuffer(target, opt->options, opt->length));
-}
-
-static inline isc_result_t
-tostruct_opt(ARGS_TOSTRUCT) {
- dns_rdata_opt_t *opt = target;
- isc_region_t r;
-
- REQUIRE(rdata->type == 41);
- REQUIRE(target != NULL);
-
- opt->common.rdclass = rdata->rdclass;
- opt->common.rdtype = rdata->type;
- ISC_LINK_INIT(&opt->common, link);
-
- dns_rdata_toregion(rdata, &r);
- opt->length = r.length;
- opt->options = mem_maybedup(mctx, r.base, r.length);
- if (opt->options == NULL)
- return (ISC_R_NOMEMORY);
-
- opt->offset = 0;
- opt->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_opt(ARGS_FREESTRUCT) {
- dns_rdata_opt_t *opt = source;
-
- REQUIRE(source != NULL);
- REQUIRE(opt->common.rdtype == 41);
-
- if (opt->mctx == NULL)
- return;
-
- if (opt->options != NULL)
- isc_mem_free(opt->mctx, opt->options);
- opt->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_opt(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 41);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_opt(ARGS_DIGEST) {
-
- /*
- * OPT records are not digested.
- */
-
- REQUIRE(rdata->type == 41);
-
- UNUSED(rdata);
- UNUSED(digest);
- UNUSED(arg);
-
- return (ISC_R_NOTIMPLEMENTED);
-}
-
-static inline isc_boolean_t
-checkowner_opt(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 41);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (dns_name_equal(name, dns_rootname));
-}
-
-static inline isc_boolean_t
-checknames_opt(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 41);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_opt(ARGS_COMPARE) {
- return (compare_opt(rdata1, rdata2));
-}
-
-#endif /* RDATA_GENERIC_OPT_41_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/opt_41.h b/contrib/bind9/lib/dns/rdata/generic/opt_41.h
deleted file mode 100644
index d6539cf4946e..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/opt_41.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef GENERIC_OPT_41_H
-#define GENERIC_OPT_41_H 1
-
-/* $Id: opt_41.h,v 1.18 2007/06/19 23:47:17 tbox Exp $ */
-
-/*!
- * \brief Per RFC2671 */
-
-typedef struct dns_rdata_opt_opcode {
- isc_uint16_t opcode;
- isc_uint16_t length;
- unsigned char *data;
-} dns_rdata_opt_opcode_t;
-
-typedef struct dns_rdata_opt {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- unsigned char *options;
- isc_uint16_t length;
- /* private */
- isc_uint16_t offset;
-} dns_rdata_opt_t;
-
-/*
- * ISC_LANG_BEGINDECLS and ISC_LANG_ENDDECLS are already done
- * via rdatastructpre.h and rdatastructsuf.h.
- */
-
-isc_result_t
-dns_rdata_opt_first(dns_rdata_opt_t *);
-
-isc_result_t
-dns_rdata_opt_next(dns_rdata_opt_t *);
-
-isc_result_t
-dns_rdata_opt_current(dns_rdata_opt_t *, dns_rdata_opt_opcode_t *);
-
-#endif /* GENERIC_OPT_41_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/proforma.c b/contrib/bind9/lib/dns/rdata/generic/proforma.c
deleted file mode 100644
index d1a5ecd77cc2..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/proforma.c
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: proforma.c,v 1.38 2009/12/04 22:06:37 tbox Exp $ */
-
-#ifndef RDATA_GENERIC_#_#_C
-#define RDATA_GENERIC_#_#_C
-
-#define RRTYPE_#_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_#(ARGS_FROMTEXT) {
- isc_token_t token;
-
- REQUIRE(type == #);
- REQUIRE(rdclass == #);
-
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
-
- return (ISC_R_NOTIMPLEMENTED);
-}
-
-static inline isc_result_t
-totext_#(ARGS_TOTEXT) {
-
- REQUIRE(rdata->type == #);
- REQUIRE(rdata->rdclass == #);
- REQUIRE(rdata->length != 0); /* XXX */
-
- return (ISC_R_NOTIMPLEMENTED);
-}
-
-static inline isc_result_t
-fromwire_#(ARGS_FROMWIRE) {
-
- REQUIRE(type == #);
- REQUIRE(rdclass == #);
-
- /* NONE or GLOBAL14 */
- dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
-
- return (ISC_R_NOTIMPLEMENTED);
-}
-
-static inline isc_result_t
-towire_#(ARGS_TOWIRE) {
-
- REQUIRE(rdata->type == #);
- REQUIRE(rdata->rdclass == #);
- REQUIRE(rdata->length != 0); /* XXX */
-
- /* NONE or GLOBAL14 */
- dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
-
- return (ISC_R_NOTIMPLEMENTED);
-}
-
-static inline int
-compare_#(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));
-}
-
-static inline isc_result_t
-fromstruct_#(ARGS_FROMSTRUCT) {
- dns_rdata_#_t *# = source;
-
- REQUIRE(type == #);
- REQUIRE(rdclass == #);
- REQUIRE(source != NULL);
- REQUIRE(#->common.rdtype == type);
- REQUIRE(#->common.rdclass == rdclass);
-
- return (ISC_R_NOTIMPLEMENTED);
-}
-
-static inline isc_result_t
-tostruct_#(ARGS_TOSTRUCT) {
-
- REQUIRE(rdata->type == #);
- REQUIRE(rdata->rdclass == #);
- REQUIRE(rdata->length != 0); /* XXX */
-
- return (ISC_R_NOTIMPLEMENTED);
-}
-
-static inline void
-freestruct_#(ARGS_FREESTRUCT) {
- dns_rdata_#_t *# = source;
-
- REQUIRE(source != NULL);
- REQUIRE(#->common.rdtype == #);
- REQUIRE(#->common.rdclass == #);
-
-}
-
-static inline isc_result_t
-additionaldata_#(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == #);
- REQUIRE(rdata->rdclass == #);
-
- (void)add;
- (void)arg;
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_#(ARGS_DIGEST) {
- isc_region_t r;
-
- REQUIRE(rdata->type == #);
- REQUIRE(rdata->rdclass == #);
-
- dns_rdata_toregion(rdata, &r);
-
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_#(ARGS_CHECKOWNER) {
-
- REQUIRE(type == #);
- REQUIRE(rdclass == #);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_#(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == #);
- REQUIRE(rdata->rdclass == #);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- 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/contrib/bind9/lib/dns/rdata/generic/proforma.h b/contrib/bind9/lib/dns/rdata/generic/proforma.h
deleted file mode 100644
index e5c420ac2b6e..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/proforma.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* */
-#ifndef GENERIC_PROFORMA_H
-#define GENERIC_PROFORMA_H 1
-
-/* $Id: proforma.h,v 1.23 2007/06/19 23:47:17 tbox Exp $ */
-
-typedef struct dns_rdata_# {
- dns_rdatacommon_t common;
- isc_mem_t *mctx; /* if required */
- /* type & class specific elements */
-} dns_rdata_#_t;
-
-#endif /* GENERIC_PROFORMA_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/ptr_12.c b/contrib/bind9/lib/dns/rdata/generic/ptr_12.c
deleted file mode 100644
index a619f137a877..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/ptr_12.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $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 */
-
-#ifndef RDATA_GENERIC_PTR_12_C
-#define RDATA_GENERIC_PTR_12_C
-
-#define RRTYPE_PTR_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_ptr(ARGS_FROMTEXT) {
- isc_token_t token;
- dns_name_t name;
- isc_buffer_t buffer;
-
- REQUIRE(type == 12);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(callbacks);
-
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
-
- dns_name_init(&name, NULL);
- buffer_fromregion(&buffer, &token.value.as_region);
- origin = (origin != NULL) ? origin : dns_rootname;
- RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
- if (rdclass == dns_rdataclass_in &&
- (options & DNS_RDATA_CHECKNAMES) != 0 &&
- (options & DNS_RDATA_CHECKREVERSE) != 0) {
- isc_boolean_t ok;
- ok = dns_name_ishostname(&name, ISC_FALSE);
- if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0)
- RETTOK(DNS_R_BADNAME);
- if (!ok && callbacks != NULL)
- warn_badname(&name, lexer, callbacks);
- }
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_ptr(ARGS_TOTEXT) {
- isc_region_t region;
- dns_name_t name;
- dns_name_t prefix;
- isc_boolean_t sub;
-
- REQUIRE(rdata->type == 12);
- REQUIRE(rdata->length != 0);
-
- dns_name_init(&name, NULL);
- dns_name_init(&prefix, NULL);
-
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
-
- sub = name_prefix(&name, tctx->origin, &prefix);
-
- return (dns_name_totext(&prefix, sub, target));
-}
-
-static inline isc_result_t
-fromwire_ptr(ARGS_FROMWIRE) {
- dns_name_t name;
-
- REQUIRE(type == 12);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14);
-
- dns_name_init(&name, NULL);
- return (dns_name_fromwire(&name, source, dctx, options, target));
-}
-
-static inline isc_result_t
-towire_ptr(ARGS_TOWIRE) {
- dns_name_t name;
- dns_offsets_t offsets;
- isc_region_t region;
-
- REQUIRE(rdata->type == 12);
- REQUIRE(rdata->length != 0);
-
- dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
-
- dns_name_init(&name, offsets);
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
-
- return (dns_name_towire(&name, cctx, target));
-}
-
-static inline int
-compare_ptr(ARGS_COMPARE) {
- dns_name_t name1;
- dns_name_t name2;
- isc_region_t region1;
- isc_region_t region2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 12);
- 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);
-
- return (dns_name_rdatacompare(&name1, &name2));
-}
-
-static inline isc_result_t
-fromstruct_ptr(ARGS_FROMSTRUCT) {
- dns_rdata_ptr_t *ptr = source;
- isc_region_t region;
-
- REQUIRE(type == 12);
- REQUIRE(source != NULL);
- REQUIRE(ptr->common.rdtype == type);
- REQUIRE(ptr->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_name_toregion(&ptr->ptr, &region);
- return (isc_buffer_copyregion(target, &region));
-}
-
-static inline isc_result_t
-tostruct_ptr(ARGS_TOSTRUCT) {
- isc_region_t region;
- dns_rdata_ptr_t *ptr = target;
- dns_name_t name;
-
- REQUIRE(rdata->type == 12);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- ptr->common.rdclass = rdata->rdclass;
- ptr->common.rdtype = rdata->type;
- ISC_LINK_INIT(&ptr->common, link);
-
- dns_name_init(&name, NULL);
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
- dns_name_init(&ptr->ptr, NULL);
- RETERR(name_duporclone(&name, mctx, &ptr->ptr));
- ptr->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_ptr(ARGS_FREESTRUCT) {
- dns_rdata_ptr_t *ptr = source;
-
- REQUIRE(source != NULL);
- REQUIRE(ptr->common.rdtype == 12);
-
- if (ptr->mctx == NULL)
- return;
-
- dns_name_free(&ptr->ptr, ptr->mctx);
- ptr->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_ptr(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 12);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_ptr(ARGS_DIGEST) {
- isc_region_t r;
- dns_name_t name;
-
- REQUIRE(rdata->type == 12);
-
- dns_rdata_toregion(rdata, &r);
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &r);
-
- return (dns_name_digest(&name, digest, arg));
-}
-
-static inline isc_boolean_t
-checkowner_ptr(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 12);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static unsigned char ip6_arpa_data[] = "\003IP6\004ARPA";
-static unsigned char ip6_arpa_offsets[] = { 0, 4, 9 };
-static const dns_name_t ip6_arpa =
-{
- DNS_NAME_MAGIC,
- ip6_arpa_data, 10, 3,
- DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE,
- ip6_arpa_offsets, NULL,
- {(void *)-1, (void *)-1},
- {NULL, NULL}
-};
-
-static unsigned char ip6_int_data[] = "\003IP6\003INT";
-static unsigned char ip6_int_offsets[] = { 0, 4, 8 };
-static const dns_name_t ip6_int =
-{
- DNS_NAME_MAGIC,
- ip6_int_data, 9, 3,
- DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE,
- ip6_int_offsets, NULL,
- {(void *)-1, (void *)-1},
- {NULL, NULL}
-};
-
-static unsigned char in_addr_arpa_data[] = "\007IN-ADDR\004ARPA";
-static unsigned char in_addr_arpa_offsets[] = { 0, 8, 13 };
-static const dns_name_t in_addr_arpa =
-{
- DNS_NAME_MAGIC,
- in_addr_arpa_data, 14, 3,
- DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE,
- in_addr_arpa_offsets, NULL,
- {(void *)-1, (void *)-1},
- {NULL, NULL}
-};
-
-static inline isc_boolean_t
-checknames_ptr(ARGS_CHECKNAMES) {
- isc_region_t region;
- dns_name_t name;
-
- REQUIRE(rdata->type == 12);
-
- if (rdata->rdclass != dns_rdataclass_in)
- return (ISC_TRUE);
-
- if (dns_name_issubdomain(owner, &in_addr_arpa) ||
- dns_name_issubdomain(owner, &ip6_arpa) ||
- dns_name_issubdomain(owner, &ip6_int)) {
- dns_rdata_toregion(rdata, &region);
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &region);
- if (!dns_name_ishostname(&name, ISC_FALSE)) {
- if (bad != NULL)
- dns_name_clone(&name, bad);
- return (ISC_FALSE);
- }
- }
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_ptr(ARGS_COMPARE) {
- return (compare_ptr(rdata1, rdata2));
-}
-#endif /* RDATA_GENERIC_PTR_12_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/ptr_12.h b/contrib/bind9/lib/dns/rdata/generic/ptr_12.h
deleted file mode 100644
index 304dcc4e5c47..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/ptr_12.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* */
-#ifndef GENERIC_PTR_12_H
-#define GENERIC_PTR_12_H 1
-
-/* $Id: ptr_12.h,v 1.27 2007/06/19 23:47:17 tbox Exp $ */
-
-typedef struct dns_rdata_ptr {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- dns_name_t ptr;
-} dns_rdata_ptr_t;
-
-#endif /* GENERIC_PTR_12_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/rp_17.c b/contrib/bind9/lib/dns/rdata/generic/rp_17.c
deleted file mode 100644
index 3291f7bb55cd..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/rp_17.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: rp_17.c,v 1.44 2009/12/04 22:06:37 tbox Exp $ */
-
-/* RFC1183 */
-
-#ifndef RDATA_GENERIC_RP_17_C
-#define RDATA_GENERIC_RP_17_C
-
-#define RRTYPE_RP_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_rp(ARGS_FROMTEXT) {
- isc_token_t token;
- dns_name_t name;
- isc_buffer_t buffer;
- int i;
- isc_boolean_t ok;
-
- REQUIRE(type == 17);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(callbacks);
-
- origin = (origin != NULL) ? origin : dns_rootname;
-
- for (i = 0; i < 2; i++) {
- RETERR(isc_lex_getmastertoken(lexer, &token,
- isc_tokentype_string,
- ISC_FALSE));
- dns_name_init(&name, NULL);
- buffer_fromregion(&buffer, &token.value.as_region);
- RETTOK(dns_name_fromtext(&name, &buffer, origin,
- options, target));
- ok = ISC_TRUE;
- if ((options & DNS_RDATA_CHECKNAMES) != 0 && i == 0)
- ok = dns_name_ismailbox(&name);
- if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0)
- RETTOK(DNS_R_BADNAME);
- if (!ok && callbacks != NULL)
- warn_badname(&name, lexer, callbacks);
- }
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_rp(ARGS_TOTEXT) {
- isc_region_t region;
- dns_name_t rmail;
- dns_name_t email;
- dns_name_t prefix;
- isc_boolean_t sub;
-
- REQUIRE(rdata->type == 17);
- REQUIRE(rdata->length != 0);
-
- dns_name_init(&rmail, NULL);
- dns_name_init(&email, NULL);
- dns_name_init(&prefix, NULL);
-
- dns_rdata_toregion(rdata, &region);
-
- dns_name_fromregion(&rmail, &region);
- isc_region_consume(&region, rmail.length);
-
- dns_name_fromregion(&email, &region);
- isc_region_consume(&region, email.length);
-
- sub = name_prefix(&rmail, tctx->origin, &prefix);
- RETERR(dns_name_totext(&prefix, sub, target));
-
- RETERR(str_totext(" ", target));
-
- sub = name_prefix(&email, tctx->origin, &prefix);
- return (dns_name_totext(&prefix, sub, target));
-}
-
-static inline isc_result_t
-fromwire_rp(ARGS_FROMWIRE) {
- dns_name_t rmail;
- dns_name_t email;
-
- REQUIRE(type == 17);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
-
- 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));
-}
-
-static inline isc_result_t
-towire_rp(ARGS_TOWIRE) {
- isc_region_t region;
- dns_name_t rmail;
- dns_name_t email;
- dns_offsets_t roffsets;
- dns_offsets_t eoffsets;
-
- REQUIRE(rdata->type == 17);
- REQUIRE(rdata->length != 0);
-
- dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
- dns_name_init(&rmail, roffsets);
- dns_name_init(&email, eoffsets);
-
- dns_rdata_toregion(rdata, &region);
-
- dns_name_fromregion(&rmail, &region);
- isc_region_consume(&region, rmail.length);
-
- RETERR(dns_name_towire(&rmail, cctx, target));
-
- dns_name_fromregion(&rmail, &region);
- isc_region_consume(&region, rmail.length);
-
- return (dns_name_towire(&rmail, cctx, target));
-}
-
-static inline int
-compare_rp(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 == 17);
- 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));
-
- dns_name_init(&name1, NULL);
- dns_name_init(&name2, NULL);
-
- dns_name_fromregion(&name1, &region1);
- dns_name_fromregion(&name2, &region2);
-
- return (dns_name_rdatacompare(&name1, &name2));
-}
-
-static inline isc_result_t
-fromstruct_rp(ARGS_FROMSTRUCT) {
- dns_rdata_rp_t *rp = source;
- isc_region_t region;
-
- REQUIRE(type == 17);
- REQUIRE(source != NULL);
- REQUIRE(rp->common.rdtype == type);
- REQUIRE(rp->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_name_toregion(&rp->mail, &region);
- RETERR(isc_buffer_copyregion(target, &region));
- dns_name_toregion(&rp->text, &region);
- return (isc_buffer_copyregion(target, &region));
-}
-
-static inline isc_result_t
-tostruct_rp(ARGS_TOSTRUCT) {
- isc_result_t result;
- isc_region_t region;
- dns_rdata_rp_t *rp = target;
- dns_name_t name;
-
- REQUIRE(rdata->type == 17);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- rp->common.rdclass = rdata->rdclass;
- rp->common.rdtype = rdata->type;
- ISC_LINK_INIT(&rp->common, link);
-
- dns_name_init(&name, NULL);
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
- dns_name_init(&rp->mail, NULL);
- RETERR(name_duporclone(&name, mctx, &rp->mail));
- isc_region_consume(&region, name_length(&name));
- dns_name_fromregion(&name, &region);
- dns_name_init(&rp->text, NULL);
- result = name_duporclone(&name, mctx, &rp->text);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- rp->mctx = mctx;
- return (ISC_R_SUCCESS);
-
- cleanup:
- if (mctx != NULL)
- dns_name_free(&rp->mail, mctx);
- return (ISC_R_NOMEMORY);
-}
-
-static inline void
-freestruct_rp(ARGS_FREESTRUCT) {
- dns_rdata_rp_t *rp = source;
-
- REQUIRE(source != NULL);
- REQUIRE(rp->common.rdtype == 17);
-
- if (rp->mctx == NULL)
- return;
-
- dns_name_free(&rp->mail, rp->mctx);
- dns_name_free(&rp->text, rp->mctx);
- rp->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_rp(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 17);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_rp(ARGS_DIGEST) {
- isc_region_t r;
- dns_name_t name;
-
- REQUIRE(rdata->type == 17);
-
- dns_rdata_toregion(rdata, &r);
- dns_name_init(&name, NULL);
-
- dns_name_fromregion(&name, &r);
- RETERR(dns_name_digest(&name, digest, arg));
- isc_region_consume(&r, name_length(&name));
-
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &r);
-
- return (dns_name_digest(&name, digest, arg));
-}
-
-static inline isc_boolean_t
-checkowner_rp(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 17);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_rp(ARGS_CHECKNAMES) {
- isc_region_t region;
- dns_name_t name;
-
- REQUIRE(rdata->type == 17);
-
- UNUSED(owner);
-
- dns_rdata_toregion(rdata, &region);
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &region);
- if (!dns_name_ismailbox(&name)) {
- if (bad != NULL)
- dns_name_clone(&name, bad);
- return (ISC_FALSE);
- }
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_rp(ARGS_COMPARE) {
- return (compare_rp(rdata1, rdata2));
-}
-#endif /* RDATA_GENERIC_RP_17_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/rp_17.h b/contrib/bind9/lib/dns/rdata/generic/rp_17.h
deleted file mode 100644
index 6223038c8321..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/rp_17.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef GENERIC_RP_17_H
-#define GENERIC_RP_17_H 1
-
-/* $Id: rp_17.h,v 1.21 2007/06/19 23:47:17 tbox Exp $ */
-
-/*!
- * \brief Per RFC1183 */
-
-typedef struct dns_rdata_rp {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- dns_name_t mail;
- dns_name_t text;
-} dns_rdata_rp_t;
-
-
-#endif /* GENERIC_RP_17_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/rrsig_46.c b/contrib/bind9/lib/dns/rdata/generic/rrsig_46.c
deleted file mode 100644
index 58a327c02ed7..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/rrsig_46.c
+++ /dev/null
@@ -1,593 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/* Reviewed: Fri Mar 17 09:05:02 PST 2000 by gson */
-
-/* RFC2535 */
-
-#ifndef RDATA_GENERIC_RRSIG_46_C
-#define RDATA_GENERIC_RRSIG_46_C
-
-#define RRTYPE_RRSIG_ATTRIBUTES (DNS_RDATATYPEATTR_DNSSEC)
-
-static inline isc_result_t
-fromtext_rrsig(ARGS_FROMTEXT) {
- isc_token_t token;
- unsigned char c;
- long i;
- dns_rdatatype_t covered;
- char *e;
- isc_result_t result;
- dns_name_t name;
- isc_buffer_t buffer;
- isc_uint32_t time_signed, time_expire;
-
- REQUIRE(type == 46);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(callbacks);
-
- /*
- * Type covered.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- result = dns_rdatatype_fromtext(&covered, &token.value.as_textregion);
- if (result != ISC_R_SUCCESS && result != ISC_R_NOTIMPLEMENTED) {
- i = strtol(DNS_AS_STR(token), &e, 10);
- if (i < 0 || i > 65535)
- RETTOK(ISC_R_RANGE);
- if (*e != 0)
- RETTOK(result);
- covered = (dns_rdatatype_t)i;
- }
- RETERR(uint16_tobuffer(covered, target));
-
- /*
- * Algorithm.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- RETTOK(dns_secalg_fromtext(&c, &token.value.as_textregion));
- RETERR(mem_tobuffer(target, &c, 1));
-
- /*
- * Labels.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if (token.value.as_ulong > 0xffU)
- RETTOK(ISC_R_RANGE);
- c = (unsigned char)token.value.as_ulong;
- RETERR(mem_tobuffer(target, &c, 1));
-
- /*
- * Original ttl.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- RETERR(uint32_tobuffer(token.value.as_ulong, target));
-
- /*
- * Signature expiration.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &time_expire));
- RETERR(uint32_tobuffer(time_expire, target));
-
- /*
- * Time signed.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &time_signed));
- RETERR(uint32_tobuffer(time_signed, target));
-
- /*
- * Key footprint.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- RETERR(uint16_tobuffer(token.value.as_ulong, target));
-
- /*
- * Signer.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- dns_name_init(&name, NULL);
- buffer_fromregion(&buffer, &token.value.as_region);
- origin = (origin != NULL) ? origin : dns_rootname;
- RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
-
- /*
- * Sig.
- */
- return (isc_base64_tobuffer(lexer, target, -1));
-}
-
-static inline isc_result_t
-totext_rrsig(ARGS_TOTEXT) {
- isc_region_t sr;
- char buf[sizeof("4294967295")];
- dns_rdatatype_t covered;
- unsigned long ttl;
- unsigned long when;
- unsigned long exp;
- unsigned long foot;
- dns_name_t name;
-
- REQUIRE(rdata->type == 46);
- REQUIRE(rdata->length != 0);
-
- dns_rdata_toregion(rdata, &sr);
-
- /*
- * Type covered.
- */
- covered = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
- /*
- * XXXAG We should have something like dns_rdatatype_isknown()
- * that does the right thing with type 0.
- */
- if (dns_rdatatype_isknown(covered) && covered != 0) {
- RETERR(dns_rdatatype_totext(covered, target));
- } else {
- char buf[sizeof("TYPE65535")];
- sprintf(buf, "TYPE%u", covered);
- RETERR(str_totext(buf, target));
- }
- RETERR(str_totext(" ", target));
-
- /*
- * Algorithm.
- */
- sprintf(buf, "%u", sr.base[0]);
- isc_region_consume(&sr, 1);
- RETERR(str_totext(buf, target));
- RETERR(str_totext(" ", target));
-
- /*
- * Labels.
- */
- sprintf(buf, "%u", sr.base[0]);
- isc_region_consume(&sr, 1);
- RETERR(str_totext(buf, target));
- RETERR(str_totext(" ", target));
-
- /*
- * Ttl.
- */
- ttl = uint32_fromregion(&sr);
- isc_region_consume(&sr, 4);
- sprintf(buf, "%lu", ttl);
- RETERR(str_totext(buf, target));
-
- if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
- RETERR(str_totext(" (", target));
- RETERR(str_totext(tctx->linebreak, target));
-
- /*
- * Sig exp.
- */
- exp = uint32_fromregion(&sr);
- isc_region_consume(&sr, 4);
- RETERR(dns_time32_totext(exp, target));
- RETERR(str_totext(" ", target));
-
- /*
- * Time signed.
- */
- when = uint32_fromregion(&sr);
- isc_region_consume(&sr, 4);
- RETERR(dns_time32_totext(when, target));
- RETERR(str_totext(" ", target));
-
- /*
- * Footprint.
- */
- foot = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
- sprintf(buf, "%lu", foot);
- RETERR(str_totext(buf, target));
- RETERR(str_totext(" ", target));
-
- /*
- * Signer.
- */
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &sr);
- isc_region_consume(&sr, name_length(&name));
- RETERR(dns_name_totext(&name, ISC_FALSE, target));
-
- /*
- * Sig.
- */
- RETERR(str_totext(tctx->linebreak, target));
- if (tctx->width == 0) /* No splitting */
- RETERR(isc_base64_totext(&sr, 60, "", target));
- else
- RETERR(isc_base64_totext(&sr, tctx->width - 2,
- tctx->linebreak, target));
- if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
- RETERR(str_totext(" )", target));
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-fromwire_rrsig(ARGS_FROMWIRE) {
- isc_region_t sr;
- dns_name_t name;
-
- REQUIRE(type == 46);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
-
- isc_buffer_activeregion(source, &sr);
- /*
- * type covered: 2
- * algorithm: 1
- * labels: 1
- * original ttl: 4
- * signature expiration: 4
- * time signed: 4
- * key footprint: 2
- */
- if (sr.length < 18)
- return (ISC_R_UNEXPECTEDEND);
-
- isc_buffer_forward(source, 18);
- RETERR(mem_tobuffer(target, sr.base, 18));
-
- /*
- * Signer.
- */
- dns_name_init(&name, NULL);
- RETERR(dns_name_fromwire(&name, source, dctx, options, target));
-
- /*
- * Sig.
- */
- isc_buffer_activeregion(source, &sr);
- isc_buffer_forward(source, sr.length);
- return (mem_tobuffer(target, sr.base, sr.length));
-}
-
-static inline isc_result_t
-towire_rrsig(ARGS_TOWIRE) {
- isc_region_t sr;
- dns_name_t name;
- dns_offsets_t offsets;
-
- REQUIRE(rdata->type == 46);
- REQUIRE(rdata->length != 0);
-
- dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
- dns_rdata_toregion(rdata, &sr);
- /*
- * type covered: 2
- * algorithm: 1
- * labels: 1
- * original ttl: 4
- * signature expiration: 4
- * time signed: 4
- * key footprint: 2
- */
- RETERR(mem_tobuffer(target, sr.base, 18));
- isc_region_consume(&sr, 18);
-
- /*
- * Signer.
- */
- dns_name_init(&name, offsets);
- dns_name_fromregion(&name, &sr);
- isc_region_consume(&sr, name_length(&name));
- RETERR(dns_name_towire(&name, cctx, target));
-
- /*
- * Signature.
- */
- return (mem_tobuffer(target, sr.base, sr.length));
-}
-
-static inline int
-compare_rrsig(ARGS_COMPARE) {
- isc_region_t r1;
- isc_region_t r2;
-
- 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);
- return (isc_region_compare(&r1, &r2));
-}
-
-static inline isc_result_t
-fromstruct_rrsig(ARGS_FROMSTRUCT) {
- dns_rdata_rrsig_t *sig = source;
-
- REQUIRE(type == 46);
- REQUIRE(source != NULL);
- REQUIRE(sig->common.rdtype == type);
- REQUIRE(sig->common.rdclass == rdclass);
- REQUIRE(sig->signature != NULL || sig->siglen == 0);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- /*
- * Type covered.
- */
- RETERR(uint16_tobuffer(sig->covered, target));
-
- /*
- * Algorithm.
- */
- RETERR(uint8_tobuffer(sig->algorithm, target));
-
- /*
- * Labels.
- */
- RETERR(uint8_tobuffer(sig->labels, target));
-
- /*
- * Original TTL.
- */
- RETERR(uint32_tobuffer(sig->originalttl, target));
-
- /*
- * Expire time.
- */
- RETERR(uint32_tobuffer(sig->timeexpire, target));
-
- /*
- * Time signed.
- */
- RETERR(uint32_tobuffer(sig->timesigned, target));
-
- /*
- * Key ID.
- */
- RETERR(uint16_tobuffer(sig->keyid, target));
-
- /*
- * Signer name.
- */
- RETERR(name_tobuffer(&sig->signer, target));
-
- /*
- * Signature.
- */
- return (mem_tobuffer(target, sig->signature, sig->siglen));
-}
-
-static inline isc_result_t
-tostruct_rrsig(ARGS_TOSTRUCT) {
- isc_region_t sr;
- dns_rdata_rrsig_t *sig = target;
- dns_name_t signer;
-
- REQUIRE(rdata->type == 46);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- sig->common.rdclass = rdata->rdclass;
- sig->common.rdtype = rdata->type;
- ISC_LINK_INIT(&sig->common, link);
-
- dns_rdata_toregion(rdata, &sr);
-
- /*
- * Type covered.
- */
- sig->covered = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
-
- /*
- * Algorithm.
- */
- sig->algorithm = uint8_fromregion(&sr);
- isc_region_consume(&sr, 1);
-
- /*
- * Labels.
- */
- sig->labels = uint8_fromregion(&sr);
- isc_region_consume(&sr, 1);
-
- /*
- * Original TTL.
- */
- sig->originalttl = uint32_fromregion(&sr);
- isc_region_consume(&sr, 4);
-
- /*
- * Expire time.
- */
- sig->timeexpire = uint32_fromregion(&sr);
- isc_region_consume(&sr, 4);
-
- /*
- * Time signed.
- */
- sig->timesigned = uint32_fromregion(&sr);
- isc_region_consume(&sr, 4);
-
- /*
- * Key ID.
- */
- sig->keyid = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
-
- dns_name_init(&signer, NULL);
- dns_name_fromregion(&signer, &sr);
- dns_name_init(&sig->signer, NULL);
- RETERR(name_duporclone(&signer, mctx, &sig->signer));
- isc_region_consume(&sr, name_length(&sig->signer));
-
- /*
- * Signature.
- */
- sig->siglen = sr.length;
- sig->signature = mem_maybedup(mctx, sr.base, sig->siglen);
- if (sig->signature == NULL)
- goto cleanup;
-
-
- sig->mctx = mctx;
- return (ISC_R_SUCCESS);
-
- cleanup:
- if (mctx != NULL)
- dns_name_free(&sig->signer, mctx);
- return (ISC_R_NOMEMORY);
-}
-
-static inline void
-freestruct_rrsig(ARGS_FREESTRUCT) {
- dns_rdata_rrsig_t *sig = (dns_rdata_rrsig_t *) source;
-
- REQUIRE(source != NULL);
- REQUIRE(sig->common.rdtype == 46);
-
- if (sig->mctx == NULL)
- return;
-
- dns_name_free(&sig->signer, sig->mctx);
- if (sig->signature != NULL)
- isc_mem_free(sig->mctx, sig->signature);
- sig->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_rrsig(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 46);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_rrsig(ARGS_DIGEST) {
-
- REQUIRE(rdata->type == 46);
-
- UNUSED(rdata);
- UNUSED(digest);
- UNUSED(arg);
-
- return (ISC_R_NOTIMPLEMENTED);
-}
-
-static inline dns_rdatatype_t
-covers_rrsig(dns_rdata_t *rdata) {
- dns_rdatatype_t type;
- isc_region_t r;
-
- REQUIRE(rdata->type == 46);
-
- dns_rdata_toregion(rdata, &r);
- type = uint16_fromregion(&r);
-
- return (type);
-}
-
-static inline isc_boolean_t
-checkowner_rrsig(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 46);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_rrsig(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 46);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- 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/contrib/bind9/lib/dns/rdata/generic/rrsig_46.h b/contrib/bind9/lib/dns/rdata/generic/rrsig_46.h
deleted file mode 100644
index 8e8dc4efb328..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/rrsig_46.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 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.
- */
-
-#ifndef GENERIC_DNSSIG_46_H
-#define GENERIC_DNSSIG_46_H 1
-
-/* $Id: rrsig_46.h,v 1.7 2007/06/19 23:47:17 tbox Exp $ */
-
-/*!
- * \brief Per RFC2535 */
-typedef struct dns_rdata_rrsig {
- dns_rdatacommon_t common;
- isc_mem_t * mctx;
- dns_rdatatype_t covered;
- dns_secalg_t algorithm;
- isc_uint8_t labels;
- isc_uint32_t originalttl;
- isc_uint32_t timeexpire;
- isc_uint32_t timesigned;
- isc_uint16_t keyid;
- dns_name_t signer;
- isc_uint16_t siglen;
- unsigned char * signature;
-} dns_rdata_rrsig_t;
-
-
-#endif /* GENERIC_DNSSIG_46_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/rt_21.c b/contrib/bind9/lib/dns/rdata/generic/rt_21.c
deleted file mode 100644
index 8f71a2afc850..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/rt_21.c
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $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 */
-
-/* RFC1183 */
-
-#ifndef RDATA_GENERIC_RT_21_C
-#define RDATA_GENERIC_RT_21_C
-
-#define RRTYPE_RT_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_rt(ARGS_FROMTEXT) {
- isc_token_t token;
- dns_name_t name;
- isc_buffer_t buffer;
- isc_boolean_t ok;
-
- REQUIRE(type == 21);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(callbacks);
-
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if (token.value.as_ulong > 0xffffU)
- RETTOK(ISC_R_RANGE);
- RETERR(uint16_tobuffer(token.value.as_ulong, target));
-
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
-
- dns_name_init(&name, NULL);
- buffer_fromregion(&buffer, &token.value.as_region);
- origin = (origin != NULL) ? origin : dns_rootname;
- RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
- ok = ISC_TRUE;
- if ((options & DNS_RDATA_CHECKNAMES) != 0)
- ok = dns_name_ishostname(&name, ISC_FALSE);
- if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0)
- RETTOK(DNS_R_BADNAME);
- if (!ok && callbacks != NULL)
- warn_badname(&name, lexer, callbacks);
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_rt(ARGS_TOTEXT) {
- isc_region_t region;
- dns_name_t name;
- dns_name_t prefix;
- isc_boolean_t sub;
- char buf[sizeof("64000")];
- unsigned short num;
-
- REQUIRE(rdata->type == 21);
- REQUIRE(rdata->length != 0);
-
- dns_name_init(&name, NULL);
- dns_name_init(&prefix, NULL);
-
- dns_rdata_toregion(rdata, &region);
- num = uint16_fromregion(&region);
- isc_region_consume(&region, 2);
- sprintf(buf, "%u", num);
- RETERR(str_totext(buf, target));
- RETERR(str_totext(" ", target));
- dns_name_fromregion(&name, &region);
- sub = name_prefix(&name, tctx->origin, &prefix);
- return (dns_name_totext(&prefix, sub, target));
-}
-
-static inline isc_result_t
-fromwire_rt(ARGS_FROMWIRE) {
- dns_name_t name;
- isc_region_t sregion;
- isc_region_t tregion;
-
- REQUIRE(type == 21);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
-
- dns_name_init(&name, NULL);
-
- isc_buffer_activeregion(source, &sregion);
- isc_buffer_availableregion(target, &tregion);
- if (tregion.length < 2)
- return (ISC_R_NOSPACE);
- if (sregion.length < 2)
- return (ISC_R_UNEXPECTEDEND);
- memcpy(tregion.base, sregion.base, 2);
- isc_buffer_forward(source, 2);
- isc_buffer_add(target, 2);
- return (dns_name_fromwire(&name, source, dctx, options, target));
-}
-
-static inline isc_result_t
-towire_rt(ARGS_TOWIRE) {
- dns_name_t name;
- dns_offsets_t offsets;
- isc_region_t region;
- isc_region_t tr;
-
- REQUIRE(rdata->type == 21);
- REQUIRE(rdata->length != 0);
-
- dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
- isc_buffer_availableregion(target, &tr);
- dns_rdata_toregion(rdata, &region);
- if (tr.length < 2)
- return (ISC_R_NOSPACE);
- memcpy(tr.base, region.base, 2);
- isc_region_consume(&region, 2);
- isc_buffer_add(target, 2);
-
- dns_name_init(&name, offsets);
- dns_name_fromregion(&name, &region);
-
- return (dns_name_towire(&name, cctx, target));
-}
-
-static inline int
-compare_rt(ARGS_COMPARE) {
- dns_name_t name1;
- dns_name_t name2;
- isc_region_t region1;
- isc_region_t region2;
- int order;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 21);
- REQUIRE(rdata1->length != 0);
- REQUIRE(rdata2->length != 0);
-
- order = memcmp(rdata1->data, rdata2->data, 2);
- if (order != 0)
- return (order < 0 ? -1 : 1);
-
- dns_name_init(&name1, NULL);
- dns_name_init(&name2, NULL);
-
- dns_rdata_toregion(rdata1, &region1);
- dns_rdata_toregion(rdata2, &region2);
-
- isc_region_consume(&region1, 2);
- isc_region_consume(&region2, 2);
-
- dns_name_fromregion(&name1, &region1);
- dns_name_fromregion(&name2, &region2);
-
- return (dns_name_rdatacompare(&name1, &name2));
-}
-
-static inline isc_result_t
-fromstruct_rt(ARGS_FROMSTRUCT) {
- dns_rdata_rt_t *rt = source;
- isc_region_t region;
-
- REQUIRE(type == 21);
- REQUIRE(source != NULL);
- REQUIRE(rt->common.rdtype == type);
- REQUIRE(rt->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- RETERR(uint16_tobuffer(rt->preference, target));
- dns_name_toregion(&rt->host, &region);
- return (isc_buffer_copyregion(target, &region));
-}
-
-static inline isc_result_t
-tostruct_rt(ARGS_TOSTRUCT) {
- isc_region_t region;
- dns_rdata_rt_t *rt = target;
- dns_name_t name;
-
- REQUIRE(rdata->type == 21);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- rt->common.rdclass = rdata->rdclass;
- rt->common.rdtype = rdata->type;
- ISC_LINK_INIT(&rt->common, link);
-
- dns_name_init(&name, NULL);
- dns_rdata_toregion(rdata, &region);
- rt->preference = uint16_fromregion(&region);
- isc_region_consume(&region, 2);
- dns_name_fromregion(&name, &region);
- dns_name_init(&rt->host, NULL);
- RETERR(name_duporclone(&name, mctx, &rt->host));
-
- rt->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_rt(ARGS_FREESTRUCT) {
- dns_rdata_rt_t *rt = source;
-
- REQUIRE(source != NULL);
- REQUIRE(rt->common.rdtype == 21);
-
- if (rt->mctx == NULL)
- return;
-
- dns_name_free(&rt->host, rt->mctx);
- rt->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_rt(ARGS_ADDLDATA) {
- dns_name_t name;
- dns_offsets_t offsets;
- isc_region_t region;
- isc_result_t result;
-
- REQUIRE(rdata->type == 21);
-
- dns_name_init(&name, offsets);
- dns_rdata_toregion(rdata, &region);
- isc_region_consume(&region, 2);
- dns_name_fromregion(&name, &region);
-
- result = (add)(arg, &name, dns_rdatatype_x25);
- if (result != ISC_R_SUCCESS)
- return (result);
- result = (add)(arg, &name, dns_rdatatype_isdn);
- if (result != ISC_R_SUCCESS)
- return (result);
- return ((add)(arg, &name, dns_rdatatype_a));
-}
-
-static inline isc_result_t
-digest_rt(ARGS_DIGEST) {
- isc_region_t r1, r2;
- isc_result_t result;
- dns_name_t name;
-
- REQUIRE(rdata->type == 21);
-
- dns_rdata_toregion(rdata, &r1);
- r2 = r1;
- isc_region_consume(&r2, 2);
- r1.length = 2;
- result = (digest)(arg, &r1);
- if (result != ISC_R_SUCCESS)
- return (result);
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &r2);
- return (dns_name_digest(&name, digest, arg));
-}
-
-static inline isc_boolean_t
-checkowner_rt(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 21);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_rt(ARGS_CHECKNAMES) {
- isc_region_t region;
- dns_name_t name;
-
- REQUIRE(rdata->type == 21);
-
- UNUSED(owner);
-
- dns_rdata_toregion(rdata, &region);
- isc_region_consume(&region, 2);
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &region);
- if (!dns_name_ishostname(&name, ISC_FALSE)) {
- if (bad != NULL)
- dns_name_clone(&name, bad);
- return (ISC_FALSE);
- }
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_rt(ARGS_COMPARE) {
- return (compare_rt(rdata1, rdata2));
-}
-
-#endif /* RDATA_GENERIC_RT_21_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/rt_21.h b/contrib/bind9/lib/dns/rdata/generic/rt_21.h
deleted file mode 100644
index 2c0e9fc27fc9..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/rt_21.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef GENERIC_RT_21_H
-#define GENERIC_RT_21_H 1
-
-/* $Id: rt_21.h,v 1.21 2007/06/19 23:47:17 tbox Exp $ */
-
-/*!
- * \brief Per RFC1183 */
-
-typedef struct dns_rdata_rt {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- isc_uint16_t preference;
- dns_name_t host;
-} dns_rdata_rt_t;
-
-#endif /* GENERIC_RT_21_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/sig_24.c b/contrib/bind9/lib/dns/rdata/generic/sig_24.c
deleted file mode 100644
index 803a864067f0..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/sig_24.c
+++ /dev/null
@@ -1,585 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/* Reviewed: Fri Mar 17 09:05:02 PST 2000 by gson */
-
-/* RFC2535 */
-
-#ifndef RDATA_GENERIC_SIG_24_C
-#define RDATA_GENERIC_SIG_24_C
-
-#define RRTYPE_SIG_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_sig(ARGS_FROMTEXT) {
- isc_token_t token;
- unsigned char c;
- long i;
- dns_rdatatype_t covered;
- char *e;
- isc_result_t result;
- dns_name_t name;
- isc_buffer_t buffer;
- isc_uint32_t time_signed, time_expire;
-
- REQUIRE(type == 24);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(callbacks);
-
- /*
- * Type covered.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- result = dns_rdatatype_fromtext(&covered, &token.value.as_textregion);
- if (result != ISC_R_SUCCESS && result != ISC_R_NOTIMPLEMENTED) {
- i = strtol(DNS_AS_STR(token), &e, 10);
- if (i < 0 || i > 65535)
- RETTOK(ISC_R_RANGE);
- if (*e != 0)
- RETTOK(result);
- covered = (dns_rdatatype_t)i;
- }
- RETERR(uint16_tobuffer(covered, target));
-
- /*
- * Algorithm.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- RETTOK(dns_secalg_fromtext(&c, &token.value.as_textregion));
- RETERR(mem_tobuffer(target, &c, 1));
-
- /*
- * Labels.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if (token.value.as_ulong > 0xffU)
- RETTOK(ISC_R_RANGE);
- c = (unsigned char)token.value.as_ulong;
- RETERR(mem_tobuffer(target, &c, 1));
-
- /*
- * Original ttl.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- RETERR(uint32_tobuffer(token.value.as_ulong, target));
-
- /*
- * Signature expiration.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &time_expire));
- RETERR(uint32_tobuffer(time_expire, target));
-
- /*
- * Time signed.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &time_signed));
- RETERR(uint32_tobuffer(time_signed, target));
-
- /*
- * Key footprint.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- RETERR(uint16_tobuffer(token.value.as_ulong, target));
-
- /*
- * Signer.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- dns_name_init(&name, NULL);
- buffer_fromregion(&buffer, &token.value.as_region);
- origin = (origin != NULL) ? origin : dns_rootname;
- RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
-
- /*
- * Sig.
- */
- return (isc_base64_tobuffer(lexer, target, -1));
-}
-
-static inline isc_result_t
-totext_sig(ARGS_TOTEXT) {
- isc_region_t sr;
- char buf[sizeof("4294967295")];
- dns_rdatatype_t covered;
- unsigned long ttl;
- unsigned long when;
- unsigned long exp;
- unsigned long foot;
- dns_name_t name;
- dns_name_t prefix;
- isc_boolean_t sub;
-
- REQUIRE(rdata->type == 24);
- REQUIRE(rdata->length != 0);
-
- dns_rdata_toregion(rdata, &sr);
-
- /*
- * Type covered.
- */
- covered = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
- /*
- * XXXAG We should have something like dns_rdatatype_isknown()
- * that does the right thing with type 0.
- */
- if (dns_rdatatype_isknown(covered) && covered != 0) {
- RETERR(dns_rdatatype_totext(covered, target));
- } else {
- char buf[sizeof("65535")];
- sprintf(buf, "%u", covered);
- RETERR(str_totext(buf, target));
- }
- RETERR(str_totext(" ", target));
-
- /*
- * Algorithm.
- */
- sprintf(buf, "%u", sr.base[0]);
- isc_region_consume(&sr, 1);
- RETERR(str_totext(buf, target));
- RETERR(str_totext(" ", target));
-
- /*
- * Labels.
- */
- sprintf(buf, "%u", sr.base[0]);
- isc_region_consume(&sr, 1);
- RETERR(str_totext(buf, target));
- RETERR(str_totext(" ", target));
-
- /*
- * Ttl.
- */
- ttl = uint32_fromregion(&sr);
- isc_region_consume(&sr, 4);
- sprintf(buf, "%lu", ttl);
- RETERR(str_totext(buf, target));
- RETERR(str_totext(" ", target));
-
- /*
- * Sig exp.
- */
- exp = uint32_fromregion(&sr);
- isc_region_consume(&sr, 4);
- RETERR(dns_time32_totext(exp, target));
-
- if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
- RETERR(str_totext(" (", target));
- RETERR(str_totext(tctx->linebreak, target));
-
- /*
- * Time signed.
- */
- when = uint32_fromregion(&sr);
- isc_region_consume(&sr, 4);
- RETERR(dns_time32_totext(when, target));
- RETERR(str_totext(" ", target));
-
- /*
- * Footprint.
- */
- foot = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
- sprintf(buf, "%lu", foot);
- RETERR(str_totext(buf, target));
- RETERR(str_totext(" ", target));
-
- /*
- * Signer.
- */
- dns_name_init(&name, NULL);
- dns_name_init(&prefix, NULL);
- dns_name_fromregion(&name, &sr);
- isc_region_consume(&sr, name_length(&name));
- sub = name_prefix(&name, tctx->origin, &prefix);
- RETERR(dns_name_totext(&prefix, sub, target));
-
- /*
- * Sig.
- */
- RETERR(str_totext(tctx->linebreak, target));
- if (tctx->width == 0) /* No splitting */
- RETERR(isc_base64_totext(&sr, 60, "", target));
- else
- RETERR(isc_base64_totext(&sr, tctx->width - 2,
- tctx->linebreak, target));
- if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
- RETERR(str_totext(" )", target));
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-fromwire_sig(ARGS_FROMWIRE) {
- isc_region_t sr;
- dns_name_t name;
-
- REQUIRE(type == 24);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
-
- isc_buffer_activeregion(source, &sr);
- /*
- * type covered: 2
- * algorithm: 1
- * labels: 1
- * original ttl: 4
- * signature expiration: 4
- * time signed: 4
- * key footprint: 2
- */
- if (sr.length < 18)
- return (ISC_R_UNEXPECTEDEND);
-
- isc_buffer_forward(source, 18);
- RETERR(mem_tobuffer(target, sr.base, 18));
-
- /*
- * Signer.
- */
- dns_name_init(&name, NULL);
- RETERR(dns_name_fromwire(&name, source, dctx, options, target));
-
- /*
- * Sig.
- */
- isc_buffer_activeregion(source, &sr);
- isc_buffer_forward(source, sr.length);
- return (mem_tobuffer(target, sr.base, sr.length));
-}
-
-static inline isc_result_t
-towire_sig(ARGS_TOWIRE) {
- isc_region_t sr;
- dns_name_t name;
- dns_offsets_t offsets;
-
- REQUIRE(rdata->type == 24);
- REQUIRE(rdata->length != 0);
-
- dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
- dns_rdata_toregion(rdata, &sr);
- /*
- * type covered: 2
- * algorithm: 1
- * labels: 1
- * original ttl: 4
- * signature expiration: 4
- * time signed: 4
- * key footprint: 2
- */
- RETERR(mem_tobuffer(target, sr.base, 18));
- isc_region_consume(&sr, 18);
-
- /*
- * Signer.
- */
- dns_name_init(&name, offsets);
- dns_name_fromregion(&name, &sr);
- isc_region_consume(&sr, name_length(&name));
- RETERR(dns_name_towire(&name, cctx, target));
-
- /*
- * Signature.
- */
- return (mem_tobuffer(target, sr.base, sr.length));
-}
-
-static inline int
-compare_sig(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 == 24);
- 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));
-}
-
-static inline isc_result_t
-fromstruct_sig(ARGS_FROMSTRUCT) {
- dns_rdata_sig_t *sig = source;
-
- REQUIRE(type == 24);
- REQUIRE(source != NULL);
- REQUIRE(sig->common.rdtype == type);
- REQUIRE(sig->common.rdclass == rdclass);
- REQUIRE(sig->signature != NULL || sig->siglen == 0);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- /*
- * Type covered.
- */
- RETERR(uint16_tobuffer(sig->covered, target));
-
- /*
- * Algorithm.
- */
- RETERR(uint8_tobuffer(sig->algorithm, target));
-
- /*
- * Labels.
- */
- RETERR(uint8_tobuffer(sig->labels, target));
-
- /*
- * Original TTL.
- */
- RETERR(uint32_tobuffer(sig->originalttl, target));
-
- /*
- * Expire time.
- */
- RETERR(uint32_tobuffer(sig->timeexpire, target));
-
- /*
- * Time signed.
- */
- RETERR(uint32_tobuffer(sig->timesigned, target));
-
- /*
- * Key ID.
- */
- RETERR(uint16_tobuffer(sig->keyid, target));
-
- /*
- * Signer name.
- */
- RETERR(name_tobuffer(&sig->signer, target));
-
- /*
- * Signature.
- */
- return (mem_tobuffer(target, sig->signature, sig->siglen));
-}
-
-static inline isc_result_t
-tostruct_sig(ARGS_TOSTRUCT) {
- isc_region_t sr;
- dns_rdata_sig_t *sig = target;
- dns_name_t signer;
-
- REQUIRE(rdata->type == 24);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- sig->common.rdclass = rdata->rdclass;
- sig->common.rdtype = rdata->type;
- ISC_LINK_INIT(&sig->common, link);
-
- dns_rdata_toregion(rdata, &sr);
-
- /*
- * Type covered.
- */
- sig->covered = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
-
- /*
- * Algorithm.
- */
- sig->algorithm = uint8_fromregion(&sr);
- isc_region_consume(&sr, 1);
-
- /*
- * Labels.
- */
- sig->labels = uint8_fromregion(&sr);
- isc_region_consume(&sr, 1);
-
- /*
- * Original TTL.
- */
- sig->originalttl = uint32_fromregion(&sr);
- isc_region_consume(&sr, 4);
-
- /*
- * Expire time.
- */
- sig->timeexpire = uint32_fromregion(&sr);
- isc_region_consume(&sr, 4);
-
- /*
- * Time signed.
- */
- sig->timesigned = uint32_fromregion(&sr);
- isc_region_consume(&sr, 4);
-
- /*
- * Key ID.
- */
- sig->keyid = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
-
- dns_name_init(&signer, NULL);
- dns_name_fromregion(&signer, &sr);
- dns_name_init(&sig->signer, NULL);
- RETERR(name_duporclone(&signer, mctx, &sig->signer));
- isc_region_consume(&sr, name_length(&sig->signer));
-
- /*
- * Signature.
- */
- sig->siglen = sr.length;
- sig->signature = mem_maybedup(mctx, sr.base, sig->siglen);
- if (sig->signature == NULL)
- goto cleanup;
-
-
- sig->mctx = mctx;
- return (ISC_R_SUCCESS);
-
- cleanup:
- if (mctx != NULL)
- dns_name_free(&sig->signer, mctx);
- return (ISC_R_NOMEMORY);
-}
-
-static inline void
-freestruct_sig(ARGS_FREESTRUCT) {
- dns_rdata_sig_t *sig = (dns_rdata_sig_t *) source;
-
- REQUIRE(source != NULL);
- REQUIRE(sig->common.rdtype == 24);
-
- if (sig->mctx == NULL)
- return;
-
- dns_name_free(&sig->signer, sig->mctx);
- if (sig->signature != NULL)
- isc_mem_free(sig->mctx, sig->signature);
- sig->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_sig(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 24);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_sig(ARGS_DIGEST) {
-
- REQUIRE(rdata->type == 24);
-
- UNUSED(rdata);
- UNUSED(digest);
- UNUSED(arg);
-
- return (ISC_R_NOTIMPLEMENTED);
-}
-
-static inline dns_rdatatype_t
-covers_sig(dns_rdata_t *rdata) {
- dns_rdatatype_t type;
- isc_region_t r;
-
- REQUIRE(rdata->type == 24);
-
- dns_rdata_toregion(rdata, &r);
- type = uint16_fromregion(&r);
-
- return (type);
-}
-
-static inline isc_boolean_t
-checkowner_sig(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 24);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_sig(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 24);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_sig(ARGS_COMPARE) {
- return (compare_sig(rdata1, rdata2));
-}
-#endif /* RDATA_GENERIC_SIG_24_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/sig_24.h b/contrib/bind9/lib/dns/rdata/generic/sig_24.h
deleted file mode 100644
index 7212d4d61290..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/sig_24.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef GENERIC_SIG_24_H
-#define GENERIC_SIG_24_H 1
-
-/* $Id: sig_24.h,v 1.26 2007/06/19 23:47:17 tbox Exp $ */
-
-/*!
- * \brief Per RFC2535 */
-
-typedef struct dns_rdata_sig_t {
- dns_rdatacommon_t common;
- isc_mem_t * mctx;
- dns_rdatatype_t covered;
- dns_secalg_t algorithm;
- isc_uint8_t labels;
- isc_uint32_t originalttl;
- isc_uint32_t timeexpire;
- isc_uint32_t timesigned;
- isc_uint16_t keyid;
- dns_name_t signer;
- isc_uint16_t siglen;
- unsigned char * signature;
-} dns_rdata_sig_t;
-
-
-#endif /* GENERIC_SIG_24_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/soa_6.c b/contrib/bind9/lib/dns/rdata/generic/soa_6.c
deleted file mode 100644
index ac0a38f7c19e..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/soa_6.c
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * Copyright (C) 2004, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-2002 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/* Reviewed: Thu Mar 16 15:18:32 PST 2000 by explorer */
-
-#ifndef RDATA_GENERIC_SOA_6_C
-#define RDATA_GENERIC_SOA_6_C
-
-#define RRTYPE_SOA_ATTRIBUTES (DNS_RDATATYPEATTR_SINGLETON)
-
-static inline isc_result_t
-fromtext_soa(ARGS_FROMTEXT) {
- isc_token_t token;
- dns_name_t name;
- isc_buffer_t buffer;
- int i;
- isc_uint32_t n;
- isc_boolean_t ok;
-
- REQUIRE(type == 6);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(callbacks);
-
- origin = (origin != NULL) ? origin : dns_rootname;
-
- for (i = 0; i < 2; i++) {
- RETERR(isc_lex_getmastertoken(lexer, &token,
- isc_tokentype_string,
- ISC_FALSE));
-
- dns_name_init(&name, NULL);
- buffer_fromregion(&buffer, &token.value.as_region);
- RETTOK(dns_name_fromtext(&name, &buffer, origin,
- options, target));
- ok = ISC_TRUE;
- if ((options & DNS_RDATA_CHECKNAMES) != 0)
- switch (i) {
- case 0:
- ok = dns_name_ishostname(&name, ISC_FALSE);
- break;
- case 1:
- ok = dns_name_ismailbox(&name);
- break;
-
- }
- if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0)
- RETTOK(DNS_R_BADNAME);
- if (!ok && callbacks != NULL)
- warn_badname(&name, lexer, callbacks);
- }
-
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- RETERR(uint32_tobuffer(token.value.as_ulong, target));
-
- for (i = 0; i < 4; i++) {
- RETERR(isc_lex_getmastertoken(lexer, &token,
- isc_tokentype_string,
- ISC_FALSE));
- RETTOK(dns_counter_fromtext(&token.value.as_textregion, &n));
- RETERR(uint32_tobuffer(n, target));
- }
-
- return (ISC_R_SUCCESS);
-}
-
-static const char *soa_fieldnames[5] = {
- "serial", "refresh", "retry", "expire", "minimum"
-};
-
-static inline isc_result_t
-totext_soa(ARGS_TOTEXT) {
- isc_region_t dregion;
- dns_name_t mname;
- dns_name_t rname;
- dns_name_t prefix;
- isc_boolean_t sub;
- int i;
- isc_boolean_t multiline;
- isc_boolean_t comment;
-
- REQUIRE(rdata->type == 6);
- REQUIRE(rdata->length != 0);
-
- multiline = ISC_TF((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0);
- if (multiline)
- comment = ISC_TF((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0);
- else
- comment = ISC_FALSE;
-
-
- dns_name_init(&mname, NULL);
- dns_name_init(&rname, NULL);
- dns_name_init(&prefix, NULL);
-
- dns_rdata_toregion(rdata, &dregion);
-
- dns_name_fromregion(&mname, &dregion);
- isc_region_consume(&dregion, name_length(&mname));
-
- dns_name_fromregion(&rname, &dregion);
- isc_region_consume(&dregion, name_length(&rname));
-
- sub = name_prefix(&mname, tctx->origin, &prefix);
- RETERR(dns_name_totext(&prefix, sub, target));
-
- RETERR(str_totext(" ", target));
-
- sub = name_prefix(&rname, tctx->origin, &prefix);
- RETERR(dns_name_totext(&prefix, sub, target));
-
- if (multiline)
- RETERR(str_totext(" (" , target));
- RETERR(str_totext(tctx->linebreak, target));
-
- for (i = 0; i < 5; i++) {
- char buf[sizeof("0123456789 ; ")];
- unsigned long num;
- num = uint32_fromregion(&dregion);
- isc_region_consume(&dregion, 4);
- sprintf(buf, comment ? "%-10lu ; " : "%lu", num);
- RETERR(str_totext(buf, target));
- if (comment) {
- RETERR(str_totext(soa_fieldnames[i], target));
- /* Print times in week/day/hour/minute/second form */
- if (i >= 1) {
- RETERR(str_totext(" (", target));
- RETERR(dns_ttl_totext(num, ISC_TRUE, target));
- RETERR(str_totext(")", target));
- }
- RETERR(str_totext(tctx->linebreak, target));
- } else if (i < 4) {
- RETERR(str_totext(tctx->linebreak, target));
- }
- }
-
- if (multiline)
- RETERR(str_totext(")", target));
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-fromwire_soa(ARGS_FROMWIRE) {
- dns_name_t mname;
- dns_name_t rname;
- isc_region_t sregion;
- isc_region_t tregion;
-
- REQUIRE(type == 6);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14);
-
- dns_name_init(&mname, NULL);
- dns_name_init(&rname, NULL);
-
- RETERR(dns_name_fromwire(&mname, source, dctx, options, target));
- RETERR(dns_name_fromwire(&rname, source, dctx, options, target));
-
- isc_buffer_activeregion(source, &sregion);
- isc_buffer_availableregion(target, &tregion);
-
- if (sregion.length < 20)
- return (ISC_R_UNEXPECTEDEND);
- if (tregion.length < 20)
- return (ISC_R_NOSPACE);
-
- memcpy(tregion.base, sregion.base, 20);
- isc_buffer_forward(source, 20);
- isc_buffer_add(target, 20);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-towire_soa(ARGS_TOWIRE) {
- isc_region_t sregion;
- isc_region_t tregion;
- dns_name_t mname;
- dns_name_t rname;
- dns_offsets_t moffsets;
- dns_offsets_t roffsets;
-
- REQUIRE(rdata->type == 6);
- REQUIRE(rdata->length != 0);
-
- dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
-
- dns_name_init(&mname, moffsets);
- dns_name_init(&rname, roffsets);
-
- dns_rdata_toregion(rdata, &sregion);
-
- dns_name_fromregion(&mname, &sregion);
- isc_region_consume(&sregion, name_length(&mname));
- RETERR(dns_name_towire(&mname, cctx, target));
-
- dns_name_fromregion(&rname, &sregion);
- isc_region_consume(&sregion, name_length(&rname));
- RETERR(dns_name_towire(&rname, cctx, target));
-
- isc_buffer_availableregion(target, &tregion);
- if (tregion.length < 20)
- return (ISC_R_NOSPACE);
-
- memcpy(tregion.base, sregion.base, 20);
- isc_buffer_add(target, 20);
- return (ISC_R_SUCCESS);
-}
-
-static inline int
-compare_soa(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 == 6);
- 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));
-
- dns_name_init(&name1, NULL);
- dns_name_init(&name2, NULL);
-
- 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));
-}
-
-static inline isc_result_t
-fromstruct_soa(ARGS_FROMSTRUCT) {
- dns_rdata_soa_t *soa = source;
- isc_region_t region;
-
- REQUIRE(type == 6);
- REQUIRE(source != NULL);
- REQUIRE(soa->common.rdtype == type);
- REQUIRE(soa->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_name_toregion(&soa->origin, &region);
- RETERR(isc_buffer_copyregion(target, &region));
- dns_name_toregion(&soa->contact, &region);
- RETERR(isc_buffer_copyregion(target, &region));
- RETERR(uint32_tobuffer(soa->serial, target));
- RETERR(uint32_tobuffer(soa->refresh, target));
- RETERR(uint32_tobuffer(soa->retry, target));
- RETERR(uint32_tobuffer(soa->expire, target));
- return (uint32_tobuffer(soa->minimum, target));
-}
-
-static inline isc_result_t
-tostruct_soa(ARGS_TOSTRUCT) {
- isc_region_t region;
- dns_rdata_soa_t *soa = target;
- dns_name_t name;
- isc_result_t result;
-
- REQUIRE(rdata->type == 6);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- soa->common.rdclass = rdata->rdclass;
- soa->common.rdtype = rdata->type;
- ISC_LINK_INIT(&soa->common, link);
-
-
- dns_rdata_toregion(rdata, &region);
-
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &region);
- isc_region_consume(&region, name_length(&name));
- dns_name_init(&soa->origin, NULL);
- RETERR(name_duporclone(&name, mctx, &soa->origin));
-
- dns_name_fromregion(&name, &region);
- isc_region_consume(&region, name_length(&name));
- dns_name_init(&soa->contact, NULL);
- result = name_duporclone(&name, mctx, &soa->contact);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- soa->serial = uint32_fromregion(&region);
- isc_region_consume(&region, 4);
-
- soa->refresh = uint32_fromregion(&region);
- isc_region_consume(&region, 4);
-
- soa->retry = uint32_fromregion(&region);
- isc_region_consume(&region, 4);
-
- soa->expire = uint32_fromregion(&region);
- isc_region_consume(&region, 4);
-
- soa->minimum = uint32_fromregion(&region);
-
- soa->mctx = mctx;
- return (ISC_R_SUCCESS);
-
- cleanup:
- if (mctx != NULL)
- dns_name_free(&soa->origin, mctx);
- return (ISC_R_NOMEMORY);
-}
-
-static inline void
-freestruct_soa(ARGS_FREESTRUCT) {
- dns_rdata_soa_t *soa = source;
-
- REQUIRE(source != NULL);
- REQUIRE(soa->common.rdtype == 6);
-
- if (soa->mctx == NULL)
- return;
-
- dns_name_free(&soa->origin, soa->mctx);
- dns_name_free(&soa->contact, soa->mctx);
- soa->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_soa(ARGS_ADDLDATA) {
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- REQUIRE(rdata->type == 6);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_soa(ARGS_DIGEST) {
- isc_region_t r;
- dns_name_t name;
-
- REQUIRE(rdata->type == 6);
-
- dns_rdata_toregion(rdata, &r);
-
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &r);
- RETERR(dns_name_digest(&name, digest, arg));
- isc_region_consume(&r, name_length(&name));
-
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &r);
- RETERR(dns_name_digest(&name, digest, arg));
- isc_region_consume(&r, name_length(&name));
-
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_soa(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 6);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_soa(ARGS_CHECKNAMES) {
- isc_region_t region;
- dns_name_t name;
-
- REQUIRE(rdata->type == 6);
-
- UNUSED(owner);
-
- dns_rdata_toregion(rdata, &region);
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &region);
- if (!dns_name_ishostname(&name, ISC_FALSE)) {
- if (bad != NULL)
- dns_name_clone(&name, bad);
- return (ISC_FALSE);
- }
- isc_region_consume(&region, name_length(&name));
- dns_name_fromregion(&name, &region);
- if (!dns_name_ismailbox(&name)) {
- if (bad != NULL)
- dns_name_clone(&name, bad);
- return (ISC_FALSE);
- }
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_soa(ARGS_COMPARE) {
- return (compare_soa(rdata1, rdata2));
-}
-
-#endif /* RDATA_GENERIC_SOA_6_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/soa_6.h b/contrib/bind9/lib/dns/rdata/generic/soa_6.h
deleted file mode 100644
index 7443b041c58d..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/soa_6.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* */
-#ifndef GENERIC_SOA_6_H
-#define GENERIC_SOA_6_H 1
-
-/* $Id: soa_6.h,v 1.32 2007/06/19 23:47:17 tbox Exp $ */
-
-typedef struct dns_rdata_soa {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- dns_name_t origin;
- dns_name_t contact;
- isc_uint32_t serial; /*%< host order */
- isc_uint32_t refresh; /*%< host order */
- isc_uint32_t retry; /*%< host order */
- isc_uint32_t expire; /*%< host order */
- isc_uint32_t minimum; /*%< host order */
-} dns_rdata_soa_t;
-
-
-#endif /* GENERIC_SOA_6_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/spf_99.c b/contrib/bind9/lib/dns/rdata/generic/spf_99.c
deleted file mode 100644
index 492e315d4542..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/spf_99.c
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $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 */
-
-#ifndef RDATA_GENERIC_SPF_99_C
-#define RDATA_GENERIC_SPF_99_C
-
-#define RRTYPE_SPF_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_spf(ARGS_FROMTEXT) {
- isc_token_t token;
- int strings;
-
- REQUIRE(type == 99);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(origin);
- UNUSED(options);
- UNUSED(callbacks);
-
- strings = 0;
- for (;;) {
- RETERR(isc_lex_getmastertoken(lexer, &token,
- isc_tokentype_qstring,
- ISC_TRUE));
- if (token.type != isc_tokentype_qstring &&
- token.type != isc_tokentype_string)
- break;
- RETTOK(txt_fromtext(&token.value.as_textregion, target));
- strings++;
- }
- /* Let upper layer handle eol/eof. */
- isc_lex_ungettoken(lexer, &token);
- return (strings == 0 ? ISC_R_UNEXPECTEDEND : ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_spf(ARGS_TOTEXT) {
- isc_region_t region;
-
- UNUSED(tctx);
-
- REQUIRE(rdata->type == 99);
-
- dns_rdata_toregion(rdata, &region);
-
- while (region.length > 0) {
- RETERR(txt_totext(&region, target));
- if (region.length > 0)
- RETERR(str_totext(" ", target));
- }
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-fromwire_spf(ARGS_FROMWIRE) {
- isc_result_t result;
-
- REQUIRE(type == 99);
-
- UNUSED(type);
- UNUSED(dctx);
- UNUSED(rdclass);
- UNUSED(options);
-
- do {
- result = txt_fromwire(source, target);
- if (result != ISC_R_SUCCESS)
- return (result);
- } while (!buffer_empty(source));
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-towire_spf(ARGS_TOWIRE) {
- isc_region_t region;
-
- REQUIRE(rdata->type == 99);
-
- UNUSED(cctx);
-
- isc_buffer_availableregion(target, &region);
- if (region.length < rdata->length)
- return (ISC_R_NOSPACE);
-
- memcpy(region.base, rdata->data, rdata->length);
- isc_buffer_add(target, rdata->length);
- return (ISC_R_SUCCESS);
-}
-
-static inline int
-compare_spf(ARGS_COMPARE) {
- isc_region_t r1;
- isc_region_t r2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 99);
-
- dns_rdata_toregion(rdata1, &r1);
- dns_rdata_toregion(rdata2, &r2);
- return (isc_region_compare(&r1, &r2));
-}
-
-static inline isc_result_t
-fromstruct_spf(ARGS_FROMSTRUCT) {
- dns_rdata_spf_t *txt = source;
- isc_region_t region;
- isc_uint8_t length;
-
- REQUIRE(type == 99);
- REQUIRE(source != NULL);
- REQUIRE(txt->common.rdtype == type);
- REQUIRE(txt->common.rdclass == rdclass);
- REQUIRE(txt->txt != NULL && txt->txt_len != 0);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- region.base = txt->txt;
- region.length = txt->txt_len;
- while (region.length > 0) {
- length = uint8_fromregion(&region);
- isc_region_consume(&region, 1);
- if (region.length <= length)
- return (ISC_R_UNEXPECTEDEND);
- isc_region_consume(&region, length);
- }
-
- return (mem_tobuffer(target, txt->txt, txt->txt_len));
-}
-
-static inline isc_result_t
-tostruct_spf(ARGS_TOSTRUCT) {
- dns_rdata_spf_t *txt = target;
- isc_region_t r;
-
- REQUIRE(rdata->type == 99);
- REQUIRE(target != NULL);
-
- txt->common.rdclass = rdata->rdclass;
- txt->common.rdtype = rdata->type;
- ISC_LINK_INIT(&txt->common, link);
-
- dns_rdata_toregion(rdata, &r);
- txt->txt_len = r.length;
- txt->txt = mem_maybedup(mctx, r.base, r.length);
- if (txt->txt == NULL)
- return (ISC_R_NOMEMORY);
-
- txt->offset = 0;
- txt->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_spf(ARGS_FREESTRUCT) {
- dns_rdata_spf_t *txt = source;
-
- REQUIRE(source != NULL);
- REQUIRE(txt->common.rdtype == 99);
-
- if (txt->mctx == NULL)
- return;
-
- if (txt->txt != NULL)
- isc_mem_free(txt->mctx, txt->txt);
- txt->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_spf(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 99);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_spf(ARGS_DIGEST) {
- isc_region_t r;
-
- REQUIRE(rdata->type == 99);
-
- dns_rdata_toregion(rdata, &r);
-
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_spf(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 99);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_spf(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 99);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_spf(ARGS_COMPARE) {
- return (compare_spf(rdata1, rdata2));
-}
-#endif /* RDATA_GENERIC_SPF_99_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/spf_99.h b/contrib/bind9/lib/dns/rdata/generic/spf_99.h
deleted file mode 100644
index be5e9789842a..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/spf_99.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef GENERIC_SPF_99_H
-#define GENERIC_SPF_99_H 1
-
-/* $Id: spf_99.h,v 1.4 2007/06/19 23:47:17 tbox Exp $ */
-
-typedef struct dns_rdata_spf_string {
- isc_uint8_t length;
- unsigned char *data;
-} dns_rdata_spf_string_t;
-
-typedef struct dns_rdata_spf {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- unsigned char *txt;
- isc_uint16_t txt_len;
- /* private */
- isc_uint16_t offset;
-} dns_rdata_spf_t;
-
-/*
- * ISC_LANG_BEGINDECLS and ISC_LANG_ENDDECLS are already done
- * via rdatastructpre.h and rdatastructsuf.h.
- */
-
-isc_result_t
-dns_rdata_spf_first(dns_rdata_spf_t *);
-
-isc_result_t
-dns_rdata_spf_next(dns_rdata_spf_t *);
-
-isc_result_t
-dns_rdata_spf_current(dns_rdata_spf_t *, dns_rdata_spf_string_t *);
-
-#endif /* GENERIC_SPF_99_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/sshfp_44.c b/contrib/bind9/lib/dns/rdata/generic/sshfp_44.c
deleted file mode 100644
index d553cd40380d..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/sshfp_44.c
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Copyright (C) 2004, 2006, 2007, 2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/* RFC 4255 */
-
-#ifndef RDATA_GENERIC_SSHFP_44_C
-#define RDATA_GENERIC_SSHFP_44_C
-
-#define RRTYPE_SSHFP_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_sshfp(ARGS_FROMTEXT) {
- isc_token_t token;
-
- REQUIRE(type == 44);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(origin);
- UNUSED(options);
- UNUSED(callbacks);
-
- /*
- * 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));
-
- /*
- * Digest type.
- */
- 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));
-
- /*
- * Digest.
- */
- return (isc_hex_tobuffer(lexer, target, -1));
-}
-
-static inline isc_result_t
-totext_sshfp(ARGS_TOTEXT) {
- isc_region_t sr;
- char buf[sizeof("64000 ")];
- unsigned int n;
-
- REQUIRE(rdata->type == 44);
- REQUIRE(rdata->length != 0);
-
- UNUSED(tctx);
-
- dns_rdata_toregion(rdata, &sr);
-
- /*
- * Algorithm.
- */
- n = uint8_fromregion(&sr);
- isc_region_consume(&sr, 1);
- sprintf(buf, "%u ", n);
- RETERR(str_totext(buf, target));
-
- /*
- * Digest type.
- */
- n = uint8_fromregion(&sr);
- isc_region_consume(&sr, 1);
- sprintf(buf, "%u", n);
- RETERR(str_totext(buf, target));
-
- /*
- * Digest.
- */
- if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
- RETERR(str_totext(" (", target));
- RETERR(str_totext(tctx->linebreak, target));
- if (tctx->width == 0) /* No splitting */
- RETERR(isc_hex_totext(&sr, 0, "", target));
- else
- RETERR(isc_hex_totext(&sr, tctx->width - 2,
- tctx->linebreak, target));
- if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
- RETERR(str_totext(" )", target));
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-fromwire_sshfp(ARGS_FROMWIRE) {
- isc_region_t sr;
-
- REQUIRE(type == 44);
-
- 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_sshfp(ARGS_TOWIRE) {
- isc_region_t sr;
-
- REQUIRE(rdata->type == 44);
- REQUIRE(rdata->length != 0);
-
- UNUSED(cctx);
-
- dns_rdata_toregion(rdata, &sr);
- return (mem_tobuffer(target, sr.base, sr.length));
-}
-
-static inline int
-compare_sshfp(ARGS_COMPARE) {
- isc_region_t r1;
- isc_region_t r2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 44);
- 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_sshfp(ARGS_FROMSTRUCT) {
- dns_rdata_sshfp_t *sshfp = source;
-
- REQUIRE(type == 44);
- REQUIRE(source != NULL);
- REQUIRE(sshfp->common.rdtype == type);
- REQUIRE(sshfp->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- RETERR(uint8_tobuffer(sshfp->algorithm, target));
- RETERR(uint8_tobuffer(sshfp->digest_type, target));
-
- return (mem_tobuffer(target, sshfp->digest, sshfp->length));
-}
-
-static inline isc_result_t
-tostruct_sshfp(ARGS_TOSTRUCT) {
- dns_rdata_sshfp_t *sshfp = target;
- isc_region_t region;
-
- REQUIRE(rdata->type == 44);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- sshfp->common.rdclass = rdata->rdclass;
- sshfp->common.rdtype = rdata->type;
- ISC_LINK_INIT(&sshfp->common, link);
-
- dns_rdata_toregion(rdata, &region);
-
- sshfp->algorithm = uint8_fromregion(&region);
- isc_region_consume(&region, 1);
- sshfp->digest_type = uint8_fromregion(&region);
- isc_region_consume(&region, 1);
- sshfp->length = region.length;
-
- sshfp->digest = mem_maybedup(mctx, region.base, region.length);
- if (sshfp->digest == NULL)
- return (ISC_R_NOMEMORY);
-
- sshfp->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_sshfp(ARGS_FREESTRUCT) {
- dns_rdata_sshfp_t *sshfp = source;
-
- REQUIRE(sshfp != NULL);
- REQUIRE(sshfp->common.rdtype == 44);
-
- if (sshfp->mctx == NULL)
- return;
-
- if (sshfp->digest != NULL)
- isc_mem_free(sshfp->mctx, sshfp->digest);
- sshfp->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_sshfp(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 44);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_sshfp(ARGS_DIGEST) {
- isc_region_t r;
-
- REQUIRE(rdata->type == 44);
-
- dns_rdata_toregion(rdata, &r);
-
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_sshfp(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 44);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_sshfp(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 44);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_sshfp(ARGS_COMPARE) {
- return (compare_sshfp(rdata1, rdata2));
-}
-
-#endif /* RDATA_GENERIC_SSHFP_44_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/sshfp_44.h b/contrib/bind9/lib/dns/rdata/generic/sshfp_44.h
deleted file mode 100644
index daea74c3a46a..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/sshfp_44.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 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: sshfp_44.h,v 1.8 2007/06/19 23:47:17 tbox Exp $ */
-
-/*!
- * \brief Per RFC 4255 */
-
-#ifndef GENERIC_SSHFP_44_H
-#define GENERIC_SSHFP_44_H 1
-
-typedef struct dns_rdata_sshfp {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- isc_uint8_t algorithm;
- isc_uint8_t digest_type;
- isc_uint16_t length;
- unsigned char *digest;
-} dns_rdata_sshfp_t;
-
-#endif /* GENERIC_SSHFP_44_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/tkey_249.c b/contrib/bind9/lib/dns/rdata/generic/tkey_249.c
deleted file mode 100644
index 6f1ec0253881..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/tkey_249.c
+++ /dev/null
@@ -1,565 +0,0 @@
-/*
- * Copyright (C) 2004, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/*
- * Reviewed: Thu Mar 16 17:35:30 PST 2000 by halley.
- */
-
-/* draft-ietf-dnsext-tkey-01.txt */
-
-#ifndef RDATA_GENERIC_TKEY_249_C
-#define RDATA_GENERIC_TKEY_249_C
-
-#define RRTYPE_TKEY_ATTRIBUTES (DNS_RDATATYPEATTR_META)
-
-static inline isc_result_t
-fromtext_tkey(ARGS_FROMTEXT) {
- isc_token_t token;
- dns_rcode_t rcode;
- dns_name_t name;
- isc_buffer_t buffer;
- long i;
- char *e;
-
- REQUIRE(type == 249);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(callbacks);
-
- /*
- * Algorithm.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- dns_name_init(&name, NULL);
- buffer_fromregion(&buffer, &token.value.as_region);
- origin = (origin != NULL) ? origin : dns_rootname;
- RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
-
-
- /*
- * Inception.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- RETERR(uint32_tobuffer(token.value.as_ulong, target));
-
- /*
- * Expiration.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- RETERR(uint32_tobuffer(token.value.as_ulong, target));
-
- /*
- * Mode.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if (token.value.as_ulong > 0xffffU)
- RETTOK(ISC_R_RANGE);
- RETERR(uint16_tobuffer(token.value.as_ulong, target));
-
- /*
- * Error.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- if (dns_tsigrcode_fromtext(&rcode, &token.value.as_textregion)
- != ISC_R_SUCCESS)
- {
- i = strtol(DNS_AS_STR(token), &e, 10);
- if (*e != 0)
- RETTOK(DNS_R_UNKNOWN);
- if (i < 0 || i > 0xffff)
- RETTOK(ISC_R_RANGE);
- rcode = (dns_rcode_t)i;
- }
- RETERR(uint16_tobuffer(rcode, target));
-
- /*
- * Key Size.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if (token.value.as_ulong > 0xffffU)
- RETTOK(ISC_R_RANGE);
- RETERR(uint16_tobuffer(token.value.as_ulong, target));
-
- /*
- * Key Data.
- */
- RETERR(isc_base64_tobuffer(lexer, target, (int)token.value.as_ulong));
-
- /*
- * Other Size.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if (token.value.as_ulong > 0xffffU)
- RETTOK(ISC_R_RANGE);
- RETERR(uint16_tobuffer(token.value.as_ulong, target));
-
- /*
- * Other Data.
- */
- return (isc_base64_tobuffer(lexer, target, (int)token.value.as_ulong));
-}
-
-static inline isc_result_t
-totext_tkey(ARGS_TOTEXT) {
- isc_region_t sr, dr;
- char buf[sizeof("4294967295 ")];
- unsigned long n;
- dns_name_t name;
- dns_name_t prefix;
- isc_boolean_t sub;
-
- REQUIRE(rdata->type == 249);
- REQUIRE(rdata->length != 0);
-
- dns_rdata_toregion(rdata, &sr);
-
- /*
- * Algorithm.
- */
- dns_name_init(&name, NULL);
- dns_name_init(&prefix, NULL);
- dns_name_fromregion(&name, &sr);
- sub = name_prefix(&name, tctx->origin, &prefix);
- RETERR(dns_name_totext(&prefix, sub, target));
- RETERR(str_totext(" ", target));
- isc_region_consume(&sr, name_length(&name));
-
- /*
- * Inception.
- */
- n = uint32_fromregion(&sr);
- isc_region_consume(&sr, 4);
- sprintf(buf, "%lu ", n);
- RETERR(str_totext(buf, target));
-
- /*
- * Expiration.
- */
- n = uint32_fromregion(&sr);
- isc_region_consume(&sr, 4);
- sprintf(buf, "%lu ", n);
- RETERR(str_totext(buf, target));
-
- /*
- * Mode.
- */
- n = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
- sprintf(buf, "%lu ", n);
- RETERR(str_totext(buf, target));
-
- /*
- * Error.
- */
- n = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
- if (dns_tsigrcode_totext((dns_rcode_t)n, target) == ISC_R_SUCCESS)
- RETERR(str_totext(" ", target));
- else {
- sprintf(buf, "%lu ", n);
- RETERR(str_totext(buf, target));
- }
-
- /*
- * Key Size.
- */
- n = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
- sprintf(buf, "%lu", n);
- RETERR(str_totext(buf, target));
-
- /*
- * Key Data.
- */
- REQUIRE(n <= sr.length);
- dr = sr;
- dr.length = n;
- if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
- RETERR(str_totext(" (", target));
- RETERR(str_totext(tctx->linebreak, target));
- if (tctx->width == 0) /* No splitting */
- RETERR(isc_base64_totext(&dr, 60, "", target));
- else
- RETERR(isc_base64_totext(&dr, tctx->width - 2,
- tctx->linebreak, target));
- if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
- RETERR(str_totext(" ) ", target));
- else
- RETERR(str_totext(" ", target));
- isc_region_consume(&sr, n);
-
- /*
- * Other Size.
- */
- n = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
- sprintf(buf, "%lu", n);
- RETERR(str_totext(buf, target));
-
- /*
- * Other Data.
- */
- REQUIRE(n <= sr.length);
- if (n != 0U) {
- dr = sr;
- dr.length = n;
- if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
- RETERR(str_totext(" (", target));
- RETERR(str_totext(tctx->linebreak, target));
- if (tctx->width == 0) /* No splitting */
- RETERR(isc_base64_totext(&dr, 60, "", target));
- else
- RETERR(isc_base64_totext(&dr, tctx->width - 2,
- tctx->linebreak, target));
- if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
- RETERR(str_totext(" )", target));
- }
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-fromwire_tkey(ARGS_FROMWIRE) {
- isc_region_t sr;
- unsigned long n;
- dns_name_t name;
-
- REQUIRE(type == 249);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
-
- /*
- * Algorithm.
- */
- dns_name_init(&name, NULL);
- RETERR(dns_name_fromwire(&name, source, dctx, options, target));
-
- /*
- * Inception: 4
- * Expiration: 4
- * Mode: 2
- * Error: 2
- */
- isc_buffer_activeregion(source, &sr);
- if (sr.length < 12)
- return (ISC_R_UNEXPECTEDEND);
- RETERR(mem_tobuffer(target, sr.base, 12));
- isc_region_consume(&sr, 12);
- isc_buffer_forward(source, 12);
-
- /*
- * Key Length + Key Data.
- */
- if (sr.length < 2)
- return (ISC_R_UNEXPECTEDEND);
- n = uint16_fromregion(&sr);
- if (sr.length < n + 2)
- return (ISC_R_UNEXPECTEDEND);
- RETERR(mem_tobuffer(target, sr.base, n + 2));
- isc_region_consume(&sr, n + 2);
- isc_buffer_forward(source, n + 2);
-
- /*
- * Other Length + Other Data.
- */
- if (sr.length < 2)
- return (ISC_R_UNEXPECTEDEND);
- n = uint16_fromregion(&sr);
- if (sr.length < n + 2)
- return (ISC_R_UNEXPECTEDEND);
- isc_buffer_forward(source, n + 2);
- return (mem_tobuffer(target, sr.base, n + 2));
-}
-
-static inline isc_result_t
-towire_tkey(ARGS_TOWIRE) {
- isc_region_t sr;
- dns_name_t name;
- dns_offsets_t offsets;
-
- REQUIRE(rdata->type == 249);
- REQUIRE(rdata->length != 0);
-
- dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
- /*
- * Algorithm.
- */
- dns_rdata_toregion(rdata, &sr);
- dns_name_init(&name, offsets);
- dns_name_fromregion(&name, &sr);
- RETERR(dns_name_towire(&name, cctx, target));
- isc_region_consume(&sr, name_length(&name));
-
- return (mem_tobuffer(target, sr.base, sr.length));
-}
-
-static inline int
-compare_tkey(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 == 249);
- REQUIRE(rdata1->length != 0);
- REQUIRE(rdata2->length != 0);
-
- /*
- * Algorithm.
- */
- dns_rdata_toregion(rdata1, &r1);
- dns_rdata_toregion(rdata2, &r2);
- dns_name_init(&name1, NULL);
- dns_name_init(&name2, NULL);
- dns_name_fromregion(&name1, &r1);
- dns_name_fromregion(&name2, &r2);
- if ((order = dns_name_rdatacompare(&name1, &name2)) != 0)
- return (order);
- isc_region_consume(&r1, name_length(&name1));
- isc_region_consume(&r2, name_length(&name2));
- return (isc_region_compare(&r1, &r2));
-}
-
-static inline isc_result_t
-fromstruct_tkey(ARGS_FROMSTRUCT) {
- dns_rdata_tkey_t *tkey = source;
-
- REQUIRE(type == 249);
- REQUIRE(source != NULL);
- REQUIRE(tkey->common.rdtype == type);
- REQUIRE(tkey->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- /*
- * Algorithm Name.
- */
- RETERR(name_tobuffer(&tkey->algorithm, target));
-
- /*
- * Inception: 32 bits.
- */
- RETERR(uint32_tobuffer(tkey->inception, target));
-
- /*
- * Expire: 32 bits.
- */
- RETERR(uint32_tobuffer(tkey->expire, target));
-
- /*
- * Mode: 16 bits.
- */
- RETERR(uint16_tobuffer(tkey->mode, target));
-
- /*
- * Error: 16 bits.
- */
- RETERR(uint16_tobuffer(tkey->error, target));
-
- /*
- * Key size: 16 bits.
- */
- RETERR(uint16_tobuffer(tkey->keylen, target));
-
- /*
- * Key.
- */
- RETERR(mem_tobuffer(target, tkey->key, tkey->keylen));
-
- /*
- * Other size: 16 bits.
- */
- RETERR(uint16_tobuffer(tkey->otherlen, target));
-
- /*
- * Other data.
- */
- return (mem_tobuffer(target, tkey->other, tkey->otherlen));
-}
-
-static inline isc_result_t
-tostruct_tkey(ARGS_TOSTRUCT) {
- dns_rdata_tkey_t *tkey = target;
- dns_name_t alg;
- isc_region_t sr;
-
- REQUIRE(rdata->type == 249);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- tkey->common.rdclass = rdata->rdclass;
- tkey->common.rdtype = rdata->type;
- ISC_LINK_INIT(&tkey->common, link);
-
- dns_rdata_toregion(rdata, &sr);
-
- /*
- * Algorithm Name.
- */
- dns_name_init(&alg, NULL);
- dns_name_fromregion(&alg, &sr);
- dns_name_init(&tkey->algorithm, NULL);
- RETERR(name_duporclone(&alg, mctx, &tkey->algorithm));
- isc_region_consume(&sr, name_length(&tkey->algorithm));
-
- /*
- * Inception.
- */
- tkey->inception = uint32_fromregion(&sr);
- isc_region_consume(&sr, 4);
-
- /*
- * Expire.
- */
- tkey->expire = uint32_fromregion(&sr);
- isc_region_consume(&sr, 4);
-
- /*
- * Mode.
- */
- tkey->mode = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
-
- /*
- * Error.
- */
- tkey->error = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
-
- /*
- * Key size.
- */
- tkey->keylen = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
-
- /*
- * Key.
- */
- tkey->key = mem_maybedup(mctx, sr.base, tkey->keylen);
- if (tkey->key == NULL)
- goto cleanup;
- isc_region_consume(&sr, tkey->keylen);
-
- /*
- * Other size.
- */
- tkey->otherlen = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
-
- /*
- * Other.
- */
- tkey->other = mem_maybedup(mctx, sr.base, tkey->otherlen);
- if (tkey->other == NULL)
- goto cleanup;
-
- tkey->mctx = mctx;
- return (ISC_R_SUCCESS);
-
- cleanup:
- if (mctx != NULL)
- dns_name_free(&tkey->algorithm, mctx);
- if (mctx != NULL && tkey->key != NULL)
- isc_mem_free(mctx, tkey->key);
- return (ISC_R_NOMEMORY);
-}
-
-static inline void
-freestruct_tkey(ARGS_FREESTRUCT) {
- dns_rdata_tkey_t *tkey = (dns_rdata_tkey_t *) source;
-
- REQUIRE(source != NULL);
-
- if (tkey->mctx == NULL)
- return;
-
- dns_name_free(&tkey->algorithm, tkey->mctx);
- if (tkey->key != NULL)
- isc_mem_free(tkey->mctx, tkey->key);
- if (tkey->other != NULL)
- isc_mem_free(tkey->mctx, tkey->other);
- tkey->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_tkey(ARGS_ADDLDATA) {
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- REQUIRE(rdata->type == 249);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_tkey(ARGS_DIGEST) {
- UNUSED(rdata);
- UNUSED(digest);
- UNUSED(arg);
-
- REQUIRE(rdata->type == 249);
-
- return (ISC_R_NOTIMPLEMENTED);
-}
-
-static inline isc_boolean_t
-checkowner_tkey(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 249);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_tkey(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 249);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- 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/contrib/bind9/lib/dns/rdata/generic/tkey_249.h b/contrib/bind9/lib/dns/rdata/generic/tkey_249.h
deleted file mode 100644
index 34d5646828bb..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/tkey_249.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001, 2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef GENERIC_TKEY_249_H
-#define GENERIC_TKEY_249_H 1
-
-/* $Id: tkey_249.h,v 1.24 2007/06/19 23:47:17 tbox Exp $ */
-
-/*!
- * \brief Per draft-ietf-dnsind-tkey-00.txt */
-
-typedef struct dns_rdata_tkey {
- dns_rdatacommon_t common;
- isc_mem_t * mctx;
- dns_name_t algorithm;
- isc_uint32_t inception;
- isc_uint32_t expire;
- isc_uint16_t mode;
- isc_uint16_t error;
- isc_uint16_t keylen;
- unsigned char * key;
- isc_uint16_t otherlen;
- unsigned char * other;
-} dns_rdata_tkey_t;
-
-
-#endif /* GENERIC_TKEY_249_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/tlsa_52.c b/contrib/bind9/lib/dns/rdata/generic/tlsa_52.c
deleted file mode 100644
index 11c6d7528f98..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/tlsa_52.c
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/* draft-ietf-dane-protocol-19.txt */
-
-#ifndef RDATA_GENERIC_TLSA_52_C
-#define RDATA_GENERIC_TLSA_52_C
-
-#define RRTYPE_TLSA_ATTRIBUTES 0
-
-static inline isc_result_t
-fromtext_tlsa(ARGS_FROMTEXT) {
- isc_token_t token;
-
- REQUIRE(type == 52);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(origin);
- UNUSED(options);
- UNUSED(callbacks);
-
- /*
- * Certificate Usage.
- */
- 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));
-
- /*
- * Selector.
- */
- 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));
-
- /*
- * Matching type.
- */
- 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));
-
- /*
- * Certificate Association Data.
- */
- return (isc_hex_tobuffer(lexer, target, -1));
-}
-
-static inline isc_result_t
-totext_tlsa(ARGS_TOTEXT) {
- isc_region_t sr;
- char buf[sizeof("64000 ")];
- unsigned int n;
-
- REQUIRE(rdata->type == 52);
- REQUIRE(rdata->length != 0);
-
- UNUSED(tctx);
-
- dns_rdata_toregion(rdata, &sr);
-
- /*
- * Certificate Usage.
- */
- n = uint8_fromregion(&sr);
- isc_region_consume(&sr, 1);
- sprintf(buf, "%u ", n);
- RETERR(str_totext(buf, target));
-
- /*
- * Selector.
- */
- n = uint8_fromregion(&sr);
- isc_region_consume(&sr, 1);
- sprintf(buf, "%u ", n);
- RETERR(str_totext(buf, target));
-
- /*
- * Matching type.
- */
- n = uint8_fromregion(&sr);
- isc_region_consume(&sr, 1);
- sprintf(buf, "%u", n);
- RETERR(str_totext(buf, target));
-
- /*
- * Certificate Association Data.
- */
- if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
- RETERR(str_totext(" (", target));
- RETERR(str_totext(tctx->linebreak, target));
- if (tctx->width == 0) /* No splitting */
- RETERR(isc_hex_totext(&sr, 0, "", target));
- else
- RETERR(isc_hex_totext(&sr, tctx->width - 2,
- tctx->linebreak, target));
- if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
- RETERR(str_totext(" )", target));
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-fromwire_tlsa(ARGS_FROMWIRE) {
- isc_region_t sr;
-
- REQUIRE(type == 52);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(dctx);
- UNUSED(options);
-
- isc_buffer_activeregion(source, &sr);
-
- if (sr.length < 3)
- return (ISC_R_UNEXPECTEDEND);
-
- isc_buffer_forward(source, sr.length);
- return (mem_tobuffer(target, sr.base, sr.length));
-}
-
-static inline isc_result_t
-towire_tlsa(ARGS_TOWIRE) {
- isc_region_t sr;
-
- REQUIRE(rdata->type == 52);
- REQUIRE(rdata->length != 0);
-
- UNUSED(cctx);
-
- dns_rdata_toregion(rdata, &sr);
- return (mem_tobuffer(target, sr.base, sr.length));
-}
-
-static inline int
-compare_tlsa(ARGS_COMPARE) {
- isc_region_t r1;
- isc_region_t r2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 52);
- 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_tlsa(ARGS_FROMSTRUCT) {
- dns_rdata_tlsa_t *tlsa = source;
-
- REQUIRE(type == 52);
- REQUIRE(source != NULL);
- REQUIRE(tlsa->common.rdtype == type);
- REQUIRE(tlsa->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- RETERR(uint8_tobuffer(tlsa->usage, target));
- RETERR(uint8_tobuffer(tlsa->selector, target));
- RETERR(uint8_tobuffer(tlsa->match, target));
-
- return (mem_tobuffer(target, tlsa->data, tlsa->length));
-}
-
-static inline isc_result_t
-tostruct_tlsa(ARGS_TOSTRUCT) {
- dns_rdata_tlsa_t *tlsa = target;
- isc_region_t region;
-
- REQUIRE(rdata->type == 52);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- tlsa->common.rdclass = rdata->rdclass;
- tlsa->common.rdtype = rdata->type;
- ISC_LINK_INIT(&tlsa->common, link);
-
- dns_rdata_toregion(rdata, &region);
-
- tlsa->usage = uint8_fromregion(&region);
- isc_region_consume(&region, 1);
- tlsa->selector = uint8_fromregion(&region);
- isc_region_consume(&region, 1);
- tlsa->match = uint8_fromregion(&region);
- isc_region_consume(&region, 1);
- tlsa->length = region.length;
-
- tlsa->data = mem_maybedup(mctx, region.base, region.length);
- if (tlsa->data == NULL)
- return (ISC_R_NOMEMORY);
-
- tlsa->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_tlsa(ARGS_FREESTRUCT) {
- dns_rdata_tlsa_t *tlsa = source;
-
- REQUIRE(tlsa != NULL);
- REQUIRE(tlsa->common.rdtype == 52);
-
- if (tlsa->mctx == NULL)
- return;
-
- if (tlsa->data != NULL)
- isc_mem_free(tlsa->mctx, tlsa->data);
- tlsa->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_tlsa(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 52);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_tlsa(ARGS_DIGEST) {
- isc_region_t r;
-
- REQUIRE(rdata->type == 52);
-
- dns_rdata_toregion(rdata, &r);
-
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_tlsa(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 52);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_tlsa(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 52);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_tlsa(ARGS_COMPARE) {
- return (compare_tlsa(rdata1, rdata2));
-}
-
-#endif /* RDATA_GENERIC_TLSA_52_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/tlsa_52.h b/contrib/bind9/lib/dns/rdata/generic/tlsa_52.h
deleted file mode 100644
index 83ce9529976d..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/tlsa_52.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-#ifndef GENERIC_TLSA_52_H
-#define GENERIC_TLSA_52_H 1
-
-/*!
- * \brief per draft-ietf-dane-protocol-19.txt
- */
-typedef struct dns_rdata_tlsa {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- isc_uint8_t usage;
- isc_uint8_t selector;
- isc_uint8_t match;
- isc_uint16_t length;
- unsigned char *data;
-} dns_rdata_tlsa_t;
-
-#endif /* GENERIC_TLSA_52_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/txt_16.c b/contrib/bind9/lib/dns/rdata/generic/txt_16.c
deleted file mode 100644
index e1bce6a0deb9..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/txt_16.c
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * Copyright (C) 2004, 2007-2009, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-2002 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $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 */
-
-#ifndef RDATA_GENERIC_TXT_16_C
-#define RDATA_GENERIC_TXT_16_C
-
-#define RRTYPE_TXT_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_txt(ARGS_FROMTEXT) {
- isc_token_t token;
- int strings;
-
- REQUIRE(type == 16);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(origin);
- UNUSED(options);
- UNUSED(callbacks);
-
- strings = 0;
- if ((options & DNS_RDATA_UNKNOWNESCAPE) != 0) {
- isc_textregion_t r;
- DE_CONST("#", r.base);
- r.length = 1;
- RETERR(txt_fromtext(&r, target));
- strings++;
- }
- for (;;) {
- RETERR(isc_lex_getmastertoken(lexer, &token,
- isc_tokentype_qstring,
- ISC_TRUE));
- if (token.type != isc_tokentype_qstring &&
- token.type != isc_tokentype_string)
- break;
- RETTOK(txt_fromtext(&token.value.as_textregion, target));
- strings++;
- }
- /* Let upper layer handle eol/eof. */
- isc_lex_ungettoken(lexer, &token);
- return (strings == 0 ? ISC_R_UNEXPECTEDEND : ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_txt(ARGS_TOTEXT) {
- isc_region_t region;
-
- UNUSED(tctx);
-
- REQUIRE(rdata->type == 16);
-
- dns_rdata_toregion(rdata, &region);
-
- while (region.length > 0) {
- RETERR(txt_totext(&region, target));
- if (region.length > 0)
- RETERR(str_totext(" ", target));
- }
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-fromwire_txt(ARGS_FROMWIRE) {
- isc_result_t result;
-
- REQUIRE(type == 16);
-
- UNUSED(type);
- UNUSED(dctx);
- UNUSED(rdclass);
- UNUSED(options);
-
- do {
- result = txt_fromwire(source, target);
- if (result != ISC_R_SUCCESS)
- return (result);
- } while (!buffer_empty(source));
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-towire_txt(ARGS_TOWIRE) {
- isc_region_t region;
-
- REQUIRE(rdata->type == 16);
-
- UNUSED(cctx);
-
- isc_buffer_availableregion(target, &region);
- if (region.length < rdata->length)
- return (ISC_R_NOSPACE);
-
- memcpy(region.base, rdata->data, rdata->length);
- isc_buffer_add(target, rdata->length);
- return (ISC_R_SUCCESS);
-}
-
-static inline int
-compare_txt(ARGS_COMPARE) {
- isc_region_t r1;
- isc_region_t r2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 16);
-
- dns_rdata_toregion(rdata1, &r1);
- dns_rdata_toregion(rdata2, &r2);
- return (isc_region_compare(&r1, &r2));
-}
-
-static inline isc_result_t
-fromstruct_txt(ARGS_FROMSTRUCT) {
- dns_rdata_txt_t *txt = source;
- isc_region_t region;
- isc_uint8_t length;
-
- REQUIRE(type == 16);
- REQUIRE(source != NULL);
- REQUIRE(txt->common.rdtype == type);
- REQUIRE(txt->common.rdclass == rdclass);
- REQUIRE(txt->txt != NULL && txt->txt_len != 0);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- region.base = txt->txt;
- region.length = txt->txt_len;
- while (region.length > 0) {
- length = uint8_fromregion(&region);
- isc_region_consume(&region, 1);
- if (region.length < length)
- return (ISC_R_UNEXPECTEDEND);
- isc_region_consume(&region, length);
- }
-
- return (mem_tobuffer(target, txt->txt, txt->txt_len));
-}
-
-static inline isc_result_t
-tostruct_txt(ARGS_TOSTRUCT) {
- dns_rdata_txt_t *txt = target;
- isc_region_t r;
-
- REQUIRE(rdata->type == 16);
- REQUIRE(target != NULL);
-
- txt->common.rdclass = rdata->rdclass;
- txt->common.rdtype = rdata->type;
- ISC_LINK_INIT(&txt->common, link);
-
- dns_rdata_toregion(rdata, &r);
- txt->txt_len = r.length;
- txt->txt = mem_maybedup(mctx, r.base, r.length);
- if (txt->txt == NULL)
- return (ISC_R_NOMEMORY);
-
- txt->offset = 0;
- txt->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_txt(ARGS_FREESTRUCT) {
- dns_rdata_txt_t *txt = source;
-
- REQUIRE(source != NULL);
- REQUIRE(txt->common.rdtype == 16);
-
- if (txt->mctx == NULL)
- return;
-
- if (txt->txt != NULL)
- isc_mem_free(txt->mctx, txt->txt);
- txt->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_txt(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 16);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_txt(ARGS_DIGEST) {
- isc_region_t r;
-
- REQUIRE(rdata->type == 16);
-
- dns_rdata_toregion(rdata, &r);
-
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_txt(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 16);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_txt(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 16);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- 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/contrib/bind9/lib/dns/rdata/generic/txt_16.h b/contrib/bind9/lib/dns/rdata/generic/txt_16.h
deleted file mode 100644
index fc46486c7448..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/txt_16.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* */
-#ifndef GENERIC_TXT_16_H
-#define GENERIC_TXT_16_H 1
-
-/* $Id: txt_16.h,v 1.28 2007/06/19 23:47:17 tbox Exp $ */
-
-typedef struct dns_rdata_txt_string {
- isc_uint8_t length;
- unsigned char *data;
-} dns_rdata_txt_string_t;
-
-typedef struct dns_rdata_txt {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- unsigned char *txt;
- isc_uint16_t txt_len;
- /* private */
- isc_uint16_t offset;
-} dns_rdata_txt_t;
-
-/*
- * ISC_LANG_BEGINDECLS and ISC_LANG_ENDDECLS are already done
- * via rdatastructpre.h and rdatastructsuf.h.
- */
-
-isc_result_t
-dns_rdata_txt_first(dns_rdata_txt_t *);
-
-isc_result_t
-dns_rdata_txt_next(dns_rdata_txt_t *);
-
-isc_result_t
-dns_rdata_txt_current(dns_rdata_txt_t *, dns_rdata_txt_string_t *);
-
-#endif /* GENERIC_TXT_16_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/unspec_103.c b/contrib/bind9/lib/dns/rdata/generic/unspec_103.c
deleted file mode 100644
index c335c6751da7..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/unspec_103.c
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $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
-
-#define RRTYPE_UNSPEC_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_unspec(ARGS_FROMTEXT) {
-
- REQUIRE(type == 103);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(origin);
- UNUSED(options);
- UNUSED(callbacks);
-
- return (atob_tobuffer(lexer, target));
-}
-
-static inline isc_result_t
-totext_unspec(ARGS_TOTEXT) {
-
- REQUIRE(rdata->type == 103);
-
- UNUSED(tctx);
-
- return (btoa_totext(rdata->data, rdata->length, target));
-}
-
-static inline isc_result_t
-fromwire_unspec(ARGS_FROMWIRE) {
- isc_region_t sr;
-
- REQUIRE(type == 103);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(dctx);
- UNUSED(options);
-
- isc_buffer_activeregion(source, &sr);
- isc_buffer_forward(source, sr.length);
- return (mem_tobuffer(target, sr.base, sr.length));
-}
-
-static inline isc_result_t
-towire_unspec(ARGS_TOWIRE) {
-
- REQUIRE(rdata->type == 103);
-
- UNUSED(cctx);
-
- return (mem_tobuffer(target, rdata->data, rdata->length));
-}
-
-static inline int
-compare_unspec(ARGS_COMPARE) {
- isc_region_t r1;
- isc_region_t r2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 103);
-
- dns_rdata_toregion(rdata1, &r1);
- dns_rdata_toregion(rdata2, &r2);
- return (isc_region_compare(&r1, &r2));
-}
-
-static inline isc_result_t
-fromstruct_unspec(ARGS_FROMSTRUCT) {
- dns_rdata_unspec_t *unspec = source;
-
- REQUIRE(type == 103);
- REQUIRE(source != NULL);
- REQUIRE(unspec->common.rdtype == type);
- REQUIRE(unspec->common.rdclass == rdclass);
- REQUIRE(unspec->data != NULL || unspec->datalen == 0);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- return (mem_tobuffer(target, unspec->data, unspec->datalen));
-}
-
-static inline isc_result_t
-tostruct_unspec(ARGS_TOSTRUCT) {
- dns_rdata_unspec_t *unspec = target;
- isc_region_t r;
-
- REQUIRE(rdata->type == 103);
- REQUIRE(target != NULL);
-
- unspec->common.rdclass = rdata->rdclass;
- unspec->common.rdtype = rdata->type;
- ISC_LINK_INIT(&unspec->common, link);
-
- dns_rdata_toregion(rdata, &r);
- unspec->datalen = r.length;
- unspec->data = mem_maybedup(mctx, r.base, r.length);
- if (unspec->data == NULL)
- return (ISC_R_NOMEMORY);
-
- unspec->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_unspec(ARGS_FREESTRUCT) {
- dns_rdata_unspec_t *unspec = source;
-
- REQUIRE(source != NULL);
- REQUIRE(unspec->common.rdtype == 103);
-
- if (unspec->mctx == NULL)
- return;
-
- if (unspec->data != NULL)
- isc_mem_free(unspec->mctx, unspec->data);
- unspec->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_unspec(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 103);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_unspec(ARGS_DIGEST) {
- isc_region_t r;
-
- REQUIRE(rdata->type == 103);
-
- dns_rdata_toregion(rdata, &r);
-
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_unspec(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 103);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_unspec(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 103);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_unspec(ARGS_COMPARE) {
- return (compare_unspec(rdata1, rdata2));
-}
-
-#endif /* RDATA_GENERIC_UNSPEC_103_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/unspec_103.h b/contrib/bind9/lib/dns/rdata/generic/unspec_103.h
deleted file mode 100644
index 4b2d3108f4df..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/unspec_103.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* */
-#ifndef GENERIC_UNSPEC_103_H
-#define GENERIC_UNSPEC_103_H 1
-
-/* $Id: unspec_103.h,v 1.17 2007/06/19 23:47:17 tbox Exp $ */
-
-typedef struct dns_rdata_unspec_t {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- unsigned char *data;
- isc_uint16_t datalen;
-} dns_rdata_unspec_t;
-
-#endif /* GENERIC_UNSPEC_103_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/uri_256.c b/contrib/bind9/lib/dns/rdata/generic/uri_256.c
deleted file mode 100644
index 799eb694e666..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/uri_256.c
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-#ifndef GENERIC_URI_256_C
-#define GENERIC_URI_256_C 1
-
-#define RRTYPE_URI_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_uri(ARGS_FROMTEXT) {
- isc_token_t token;
-
- REQUIRE(type == 256);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(origin);
- UNUSED(options);
- UNUSED(callbacks);
-
- /*
- * Priority
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if (token.value.as_ulong > 0xffffU)
- RETTOK(ISC_R_RANGE);
- RETERR(uint16_tobuffer(token.value.as_ulong, target));
-
- /*
- * Weight
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if (token.value.as_ulong > 0xffffU)
- RETTOK(ISC_R_RANGE);
- RETERR(uint16_tobuffer(token.value.as_ulong, target));
-
- /*
- * Target URI
- */
- RETERR(isc_lex_getmastertoken(lexer, &token,
- isc_tokentype_qstring, ISC_FALSE));
- if (token.type != isc_tokentype_qstring)
- RETTOK(DNS_R_SYNTAX);
- RETTOK(multitxt_fromtext(&token.value.as_textregion, target));
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_uri(ARGS_TOTEXT) {
- isc_region_t region;
- unsigned short priority, weight;
- char buf[sizeof("65000 ")];
-
- UNUSED(tctx);
-
- REQUIRE(rdata->type == 256);
- REQUIRE(rdata->length != 0);
-
- dns_rdata_toregion(rdata, &region);
-
- /*
- * Priority
- */
- priority = uint16_fromregion(&region);
- isc_region_consume(&region, 2);
- sprintf(buf, "%u ", priority);
- RETERR(str_totext(buf, target));
-
- /*
- * Weight
- */
- weight = uint16_fromregion(&region);
- isc_region_consume(&region, 2);
- sprintf(buf, "%u ", weight);
- RETERR(str_totext(buf, target));
-
- /*
- * Target URI
- */
- RETERR(multitxt_totext(&region, target));
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-fromwire_uri(ARGS_FROMWIRE) {
- isc_region_t region;
-
- REQUIRE(type == 256);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(dctx);
- UNUSED(options);
-
- /*
- * Priority, weight
- */
- isc_buffer_activeregion(source, &region);
- if (region.length < 4)
- return (ISC_R_UNEXPECTEDEND);
- RETERR(mem_tobuffer(target, region.base, 4));
- isc_buffer_forward(source, 4);
-
- /*
- * Target URI
- */
- RETERR(multitxt_fromwire(source, target));
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-towire_uri(ARGS_TOWIRE) {
- isc_region_t region;
-
- REQUIRE(rdata->type == 256);
- REQUIRE(rdata->length != 0);
-
- UNUSED(cctx);
-
- dns_rdata_toregion(rdata, &region);
- return (mem_tobuffer(target, region.base, region.length));
-}
-
-static inline int
-compare_uri(ARGS_COMPARE) {
- isc_region_t r1;
- isc_region_t r2;
- int order;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 256);
- REQUIRE(rdata1->length != 0);
- REQUIRE(rdata2->length != 0);
-
- dns_rdata_toregion(rdata1, &r1);
- dns_rdata_toregion(rdata2, &r2);
-
- /*
- * Priority
- */
- order = memcmp(r1.base, r2.base, 2);
- if (order != 0)
- return (order < 0 ? -1 : 1);
- isc_region_consume(&r1, 2);
- isc_region_consume(&r2, 2);
-
- /*
- * Weight
- */
- order = memcmp(r1.base, r2.base, 2);
- if (order != 0)
- return (order < 0 ? -1 : 1);
- isc_region_consume(&r1, 2);
- isc_region_consume(&r2, 2);
-
- return (isc_region_compare(&r1, &r2));
-}
-
-static inline isc_result_t
-fromstruct_uri(ARGS_FROMSTRUCT) {
- dns_rdata_uri_t *uri = source;
- isc_region_t region;
- isc_uint8_t len;
-
- REQUIRE(type == 256);
- REQUIRE(source != NULL);
- REQUIRE(uri->common.rdtype == type);
- REQUIRE(uri->common.rdclass == rdclass);
- REQUIRE(uri->target != NULL && uri->tgt_len != 0);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- /*
- * Priority
- */
- RETERR(uint16_tobuffer(uri->priority, target));
-
- /*
- * Weight
- */
- RETERR(uint16_tobuffer(uri->weight, target));
-
- /*
- * Target URI
- */
- len = 255U;
- region.base = uri->target;
- region.length = uri->tgt_len;
- while (region.length > 0) {
- REQUIRE(len == 255U);
- len = uint8_fromregion(&region);
- isc_region_consume(&region, 1);
- if (region.length < len)
- return (ISC_R_UNEXPECTEDEND);
- isc_region_consume(&region, len);
- }
-
- return (mem_tobuffer(target, uri->target, uri->tgt_len));
-}
-
-static inline isc_result_t
-tostruct_uri(ARGS_TOSTRUCT) {
- dns_rdata_uri_t *uri = target;
- isc_region_t sr;
-
- REQUIRE(rdata->type == 256);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- uri->common.rdclass = rdata->rdclass;
- uri->common.rdtype = rdata->type;
- ISC_LINK_INIT(&uri->common, link);
-
- dns_rdata_toregion(rdata, &sr);
-
- /*
- * Priority
- */
- if (sr.length < 2)
- return (ISC_R_UNEXPECTEDEND);
- uri->priority = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
-
- /*
- * Weight
- */
- if (sr.length < 2)
- return (ISC_R_UNEXPECTEDEND);
- uri->weight = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
-
- /*
- * Target URI
- */
- uri->tgt_len = sr.length;
- uri->target = mem_maybedup(mctx, sr.base, sr.length);
- if (uri->target == NULL)
- return (ISC_R_NOMEMORY);
-
- uri->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_uri(ARGS_FREESTRUCT) {
- dns_rdata_uri_t *uri = (dns_rdata_uri_t *) source;
-
- REQUIRE(source != NULL);
- REQUIRE(uri->common.rdtype == 256);
-
- if (uri->mctx == NULL)
- return;
-
- if (uri->target != NULL)
- isc_mem_free(uri->mctx, uri->target);
- uri->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_uri(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 256);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_uri(ARGS_DIGEST) {
- isc_region_t r;
-
- REQUIRE(rdata->type == 256);
-
- dns_rdata_toregion(rdata, &r);
-
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_uri(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 256);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_uri(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 256);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_uri(ARGS_COMPARE) {
- return (compare_uri(rdata1, rdata2));
-}
-
-#endif /* GENERIC_URI_256_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/uri_256.h b/contrib/bind9/lib/dns/rdata/generic/uri_256.h
deleted file mode 100644
index 13c8fd238b89..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/uri_256.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER 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_URI_256_H
-#define GENERIC_URI_256_H 1
-
-/* $Id$ */
-
-typedef struct dns_rdata_uri {
- dns_rdatacommon_t common;
- isc_mem_t * mctx;
- isc_uint16_t priority;
- isc_uint16_t weight;
- unsigned char * target;
- isc_uint16_t tgt_len;
-} dns_rdata_uri_t;
-
-#endif /* GENERIC_URI_256_H */
diff --git a/contrib/bind9/lib/dns/rdata/generic/x25_19.c b/contrib/bind9/lib/dns/rdata/generic/x25_19.c
deleted file mode 100644
index 6867fecd86f8..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/x25_19.c
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $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 */
-
-/* RFC1183 */
-
-#ifndef RDATA_GENERIC_X25_19_C
-#define RDATA_GENERIC_X25_19_C
-
-#define RRTYPE_X25_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_x25(ARGS_FROMTEXT) {
- isc_token_t token;
- unsigned int i;
-
- REQUIRE(type == 19);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(origin);
- UNUSED(options);
- UNUSED(callbacks);
-
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring,
- ISC_FALSE));
- if (token.value.as_textregion.length < 4)
- RETTOK(DNS_R_SYNTAX);
- for (i = 0; i < token.value.as_textregion.length; i++)
- if (!isdigit(token.value.as_textregion.base[i] & 0xff))
- RETTOK(ISC_R_RANGE);
- RETTOK(txt_fromtext(&token.value.as_textregion, target));
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_x25(ARGS_TOTEXT) {
- isc_region_t region;
-
- UNUSED(tctx);
-
- REQUIRE(rdata->type == 19);
- REQUIRE(rdata->length != 0);
-
- dns_rdata_toregion(rdata, &region);
- return (txt_totext(&region, target));
-}
-
-static inline isc_result_t
-fromwire_x25(ARGS_FROMWIRE) {
- isc_region_t sr;
-
- REQUIRE(type == 19);
-
- UNUSED(type);
- UNUSED(dctx);
- UNUSED(rdclass);
- UNUSED(options);
-
- isc_buffer_activeregion(source, &sr);
- if (sr.length < 5)
- return (DNS_R_FORMERR);
- return (txt_fromwire(source, target));
-}
-
-static inline isc_result_t
-towire_x25(ARGS_TOWIRE) {
- UNUSED(cctx);
-
- REQUIRE(rdata->type == 19);
- REQUIRE(rdata->length != 0);
-
- return (mem_tobuffer(target, rdata->data, rdata->length));
-}
-
-static inline int
-compare_x25(ARGS_COMPARE) {
- isc_region_t r1;
- isc_region_t r2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 19);
- 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_x25(ARGS_FROMSTRUCT) {
- dns_rdata_x25_t *x25 = source;
- isc_uint8_t i;
-
- REQUIRE(type == 19);
- REQUIRE(source != NULL);
- REQUIRE(x25->common.rdtype == type);
- REQUIRE(x25->common.rdclass == rdclass);
- REQUIRE(x25->x25 != NULL && x25->x25_len != 0);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- if (x25->x25_len < 4)
- return (ISC_R_RANGE);
-
- for (i = 0; i < x25->x25_len; i++)
- if (!isdigit(x25->x25[i] & 0xff))
- return (ISC_R_RANGE);
-
- RETERR(uint8_tobuffer(x25->x25_len, target));
- return (mem_tobuffer(target, x25->x25, x25->x25_len));
-}
-
-static inline isc_result_t
-tostruct_x25(ARGS_TOSTRUCT) {
- dns_rdata_x25_t *x25 = target;
- isc_region_t r;
-
- REQUIRE(rdata->type == 19);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- x25->common.rdclass = rdata->rdclass;
- x25->common.rdtype = rdata->type;
- ISC_LINK_INIT(&x25->common, link);
-
- dns_rdata_toregion(rdata, &r);
- x25->x25_len = uint8_fromregion(&r);
- isc_region_consume(&r, 1);
- x25->x25 = mem_maybedup(mctx, r.base, x25->x25_len);
- if (x25->x25 == NULL)
- return (ISC_R_NOMEMORY);
-
- x25->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_x25(ARGS_FREESTRUCT) {
- dns_rdata_x25_t *x25 = source;
- REQUIRE(source != NULL);
- REQUIRE(x25->common.rdtype == 19);
-
- if (x25->mctx == NULL)
- return;
-
- if (x25->x25 != NULL)
- isc_mem_free(x25->mctx, x25->x25);
- x25->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_x25(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 19);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_x25(ARGS_DIGEST) {
- isc_region_t r;
-
- REQUIRE(rdata->type == 19);
-
- dns_rdata_toregion(rdata, &r);
-
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_x25(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 19);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_x25(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 19);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- return (ISC_TRUE);
-}
-
-static inline int
-casecompare_x25(ARGS_COMPARE) {
- return (compare_x25(rdata1, rdata2));
-}
-
-#endif /* RDATA_GENERIC_X25_19_C */
diff --git a/contrib/bind9/lib/dns/rdata/generic/x25_19.h b/contrib/bind9/lib/dns/rdata/generic/x25_19.h
deleted file mode 100644
index 5ebc230589a2..000000000000
--- a/contrib/bind9/lib/dns/rdata/generic/x25_19.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef GENERIC_X25_19_H
-#define GENERIC_X25_19_H 1
-
-/* $Id: x25_19.h,v 1.18 2007/06/19 23:47:17 tbox Exp $ */
-
-/*!
- * \brief Per RFC1183 */
-
-typedef struct dns_rdata_x25 {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- unsigned char *x25;
- isc_uint8_t x25_len;
-} dns_rdata_x25_t;
-
-#endif /* GENERIC_X25_19_H */
diff --git a/contrib/bind9/lib/dns/rdata/hs_4/a_1.c b/contrib/bind9/lib/dns/rdata/hs_4/a_1.c
deleted file mode 100644
index 50ae25d52b83..000000000000
--- a/contrib/bind9/lib/dns/rdata/hs_4/a_1.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $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 */
-
-#ifndef RDATA_HS_4_A_1_C
-#define RDATA_HS_4_A_1_C
-
-#include <isc/net.h>
-
-#define RRTYPE_A_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_hs_a(ARGS_FROMTEXT) {
- isc_token_t token;
- struct in_addr addr;
- isc_region_t region;
-
- REQUIRE(type == 1);
- REQUIRE(rdclass == 4);
-
- UNUSED(type);
- UNUSED(origin);
- UNUSED(options);
- UNUSED(rdclass);
-
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
-
- if (getquad(DNS_AS_STR(token), &addr, lexer, callbacks) != 1)
- RETTOK(DNS_R_BADDOTTEDQUAD);
- isc_buffer_availableregion(target, &region);
- if (region.length < 4)
- return (ISC_R_NOSPACE);
- memcpy(region.base, &addr, 4);
- isc_buffer_add(target, 4);
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_hs_a(ARGS_TOTEXT) {
- isc_region_t region;
-
- REQUIRE(rdata->type == 1);
- REQUIRE(rdata->rdclass == 4);
- REQUIRE(rdata->length == 4);
-
- UNUSED(tctx);
-
- dns_rdata_toregion(rdata, &region);
- return (inet_totext(AF_INET, &region, target));
-}
-
-static inline isc_result_t
-fromwire_hs_a(ARGS_FROMWIRE) {
- isc_region_t sregion;
- isc_region_t tregion;
-
- REQUIRE(type == 1);
- REQUIRE(rdclass == 4);
-
- UNUSED(type);
- UNUSED(dctx);
- UNUSED(options);
- UNUSED(rdclass);
-
- isc_buffer_activeregion(source, &sregion);
- isc_buffer_availableregion(target, &tregion);
- if (sregion.length < 4)
- return (ISC_R_UNEXPECTEDEND);
- if (tregion.length < 4)
- return (ISC_R_NOSPACE);
-
- memcpy(tregion.base, sregion.base, 4);
- isc_buffer_forward(source, 4);
- isc_buffer_add(target, 4);
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-towire_hs_a(ARGS_TOWIRE) {
- isc_region_t region;
-
- REQUIRE(rdata->type == 1);
- REQUIRE(rdata->rdclass == 4);
- REQUIRE(rdata->length == 4);
-
- UNUSED(cctx);
-
- isc_buffer_availableregion(target, &region);
- if (region.length < rdata->length)
- return (ISC_R_NOSPACE);
- memcpy(region.base, rdata->data, rdata->length);
- isc_buffer_add(target, 4);
- return (ISC_R_SUCCESS);
-}
-
-static inline int
-compare_hs_a(ARGS_COMPARE) {
- int order;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 1);
- REQUIRE(rdata1->rdclass == 4);
- REQUIRE(rdata1->length == 4);
- REQUIRE(rdata2->length == 4);
-
- order = memcmp(rdata1->data, rdata2->data, 4);
- if (order != 0)
- order = (order < 0) ? -1 : 1;
-
- return (order);
-}
-
-static inline isc_result_t
-fromstruct_hs_a(ARGS_FROMSTRUCT) {
- dns_rdata_hs_a_t *a = source;
- isc_uint32_t n;
-
- REQUIRE(type == 1);
- REQUIRE(rdclass == 4);
- REQUIRE(source != NULL);
- REQUIRE(a->common.rdtype == type);
- REQUIRE(a->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- n = ntohl(a->in_addr.s_addr);
-
- return (uint32_tobuffer(n, target));
-}
-
-static inline isc_result_t
-tostruct_hs_a(ARGS_TOSTRUCT) {
- dns_rdata_hs_a_t *a = target;
- isc_uint32_t n;
- isc_region_t region;
-
- REQUIRE(rdata->type == 1);
- REQUIRE(rdata->rdclass == 4);
- REQUIRE(rdata->length == 4);
-
- UNUSED(mctx);
-
- a->common.rdclass = rdata->rdclass;
- a->common.rdtype = rdata->type;
- ISC_LINK_INIT(&a->common, link);
-
- dns_rdata_toregion(rdata, &region);
- n = uint32_fromregion(&region);
- a->in_addr.s_addr = htonl(n);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_hs_a(ARGS_FREESTRUCT) {
- UNUSED(source);
-
- REQUIRE(source != NULL);
-}
-
-static inline isc_result_t
-additionaldata_hs_a(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 1);
- REQUIRE(rdata->rdclass == 4);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_hs_a(ARGS_DIGEST) {
- isc_region_t r;
-
- REQUIRE(rdata->type == 1);
- REQUIRE(rdata->rdclass == 4);
-
- dns_rdata_toregion(rdata, &r);
-
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_hs_a(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 1);
- REQUIRE(rdclass == 4);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_hs_a(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 1);
- REQUIRE(rdata->rdclass == 4);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- 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/contrib/bind9/lib/dns/rdata/hs_4/a_1.h b/contrib/bind9/lib/dns/rdata/hs_4/a_1.h
deleted file mode 100644
index dee812fcb26d..000000000000
--- a/contrib/bind9/lib/dns/rdata/hs_4/a_1.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* */
-#ifndef HS_4_A_1_H
-#define HS_4_A_1_H 1
-
-/* $Id: a_1.h,v 1.12 2007/06/19 23:47:17 tbox Exp $ */
-
-typedef struct dns_rdata_hs_a {
- dns_rdatacommon_t common;
- struct in_addr in_addr;
-} dns_rdata_hs_a_t;
-
-#endif /* HS_4_A_1_H */
diff --git a/contrib/bind9/lib/dns/rdata/in_1/a6_38.c b/contrib/bind9/lib/dns/rdata/in_1/a6_38.c
deleted file mode 100644
index 8619f8a21363..000000000000
--- a/contrib/bind9/lib/dns/rdata/in_1/a6_38.c
+++ /dev/null
@@ -1,466 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: a6_38.c,v 1.56 2009/12/04 22:06:37 tbox Exp $ */
-
-/* RFC2874 */
-
-#ifndef RDATA_IN_1_A6_28_C
-#define RDATA_IN_1_A6_28_C
-
-#include <isc/net.h>
-
-#define RRTYPE_A6_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_in_a6(ARGS_FROMTEXT) {
- isc_token_t token;
- unsigned char addr[16];
- unsigned char prefixlen;
- unsigned char octets;
- unsigned char mask;
- dns_name_t name;
- isc_buffer_t buffer;
- isc_boolean_t ok;
-
- REQUIRE(type == 38);
- REQUIRE(rdclass == 1);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(callbacks);
-
- /*
- * Prefix length.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if (token.value.as_ulong > 128U)
- RETTOK(ISC_R_RANGE);
-
- prefixlen = (unsigned char)token.value.as_ulong;
- RETERR(mem_tobuffer(target, &prefixlen, 1));
-
- /*
- * Suffix.
- */
- if (prefixlen != 128) {
- /*
- * Prefix 0..127.
- */
- octets = prefixlen/8;
- /*
- * Octets 0..15.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token,
- isc_tokentype_string,
- ISC_FALSE));
- if (inet_pton(AF_INET6, DNS_AS_STR(token), addr) != 1)
- RETTOK(DNS_R_BADAAAA);
- mask = 0xff >> (prefixlen % 8);
- addr[octets] &= mask;
- RETERR(mem_tobuffer(target, &addr[octets], 16 - octets));
- }
-
- if (prefixlen == 0)
- return (ISC_R_SUCCESS);
-
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- dns_name_init(&name, NULL);
- buffer_fromregion(&buffer, &token.value.as_region);
- origin = (origin != NULL) ? origin : dns_rootname;
- RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
- ok = ISC_TRUE;
- if ((options & DNS_RDATA_CHECKNAMES) != 0)
- ok = dns_name_ishostname(&name, ISC_FALSE);
- if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0)
- RETTOK(DNS_R_BADNAME);
- if (!ok && callbacks != NULL)
- warn_badname(&name, lexer, callbacks);
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_in_a6(ARGS_TOTEXT) {
- isc_region_t sr, ar;
- unsigned char addr[16];
- unsigned char prefixlen;
- unsigned char octets;
- unsigned char mask;
- char buf[sizeof("128")];
- dns_name_t name;
- dns_name_t prefix;
- isc_boolean_t sub;
-
- REQUIRE(rdata->type == 38);
- REQUIRE(rdata->rdclass == 1);
- REQUIRE(rdata->length != 0);
-
- dns_rdata_toregion(rdata, &sr);
- prefixlen = sr.base[0];
- INSIST(prefixlen <= 128);
- isc_region_consume(&sr, 1);
- sprintf(buf, "%u", prefixlen);
- RETERR(str_totext(buf, target));
- RETERR(str_totext(" ", target));
-
- if (prefixlen != 128) {
- octets = prefixlen/8;
- memset(addr, 0, sizeof(addr));
- memcpy(&addr[octets], sr.base, 16 - octets);
- mask = 0xff >> (prefixlen % 8);
- addr[octets] &= mask;
- ar.base = addr;
- ar.length = sizeof(addr);
- RETERR(inet_totext(AF_INET6, &ar, target));
- isc_region_consume(&sr, 16 - octets);
- }
-
- if (prefixlen == 0)
- return (ISC_R_SUCCESS);
-
- RETERR(str_totext(" ", target));
- dns_name_init(&name, NULL);
- dns_name_init(&prefix, NULL);
- dns_name_fromregion(&name, &sr);
- sub = name_prefix(&name, tctx->origin, &prefix);
- return (dns_name_totext(&prefix, sub, target));
-}
-
-static inline isc_result_t
-fromwire_in_a6(ARGS_FROMWIRE) {
- isc_region_t sr;
- unsigned char prefixlen;
- unsigned char octets;
- unsigned char mask;
- dns_name_t name;
-
- REQUIRE(type == 38);
- REQUIRE(rdclass == 1);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
-
- isc_buffer_activeregion(source, &sr);
- /*
- * Prefix length.
- */
- if (sr.length < 1)
- return (ISC_R_UNEXPECTEDEND);
- prefixlen = sr.base[0];
- if (prefixlen > 128)
- return (ISC_R_RANGE);
- isc_region_consume(&sr, 1);
- RETERR(mem_tobuffer(target, &prefixlen, 1));
- isc_buffer_forward(source, 1);
-
- /*
- * Suffix.
- */
- if (prefixlen != 128) {
- octets = 16 - prefixlen / 8;
- if (sr.length < octets)
- return (ISC_R_UNEXPECTEDEND);
- mask = 0xff >> (prefixlen % 8);
- sr.base[0] &= mask; /* Ensure pad bits are zero. */
- RETERR(mem_tobuffer(target, sr.base, octets));
- isc_buffer_forward(source, octets);
- }
-
- if (prefixlen == 0)
- return (ISC_R_SUCCESS);
-
- dns_name_init(&name, NULL);
- return (dns_name_fromwire(&name, source, dctx, options, target));
-}
-
-static inline isc_result_t
-towire_in_a6(ARGS_TOWIRE) {
- isc_region_t sr;
- dns_name_t name;
- dns_offsets_t offsets;
- unsigned char prefixlen;
- unsigned char octets;
-
- REQUIRE(rdata->type == 38);
- REQUIRE(rdata->rdclass == 1);
- REQUIRE(rdata->length != 0);
-
- dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
- dns_rdata_toregion(rdata, &sr);
- prefixlen = sr.base[0];
- INSIST(prefixlen <= 128);
-
- octets = 1 + 16 - prefixlen / 8;
- RETERR(mem_tobuffer(target, sr.base, octets));
- isc_region_consume(&sr, octets);
-
- if (prefixlen == 0)
- return (ISC_R_SUCCESS);
-
- dns_name_init(&name, offsets);
- dns_name_fromregion(&name, &sr);
- return (dns_name_towire(&name, cctx, target));
-}
-
-static inline int
-compare_in_a6(ARGS_COMPARE) {
- int order;
- unsigned char prefixlen1, prefixlen2;
- unsigned char octets;
- dns_name_t name1;
- dns_name_t name2;
- isc_region_t region1;
- isc_region_t region2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 38);
- REQUIRE(rdata1->rdclass == 1);
- REQUIRE(rdata1->length != 0);
- REQUIRE(rdata2->length != 0);
-
- dns_rdata_toregion(rdata1, &region1);
- dns_rdata_toregion(rdata2, &region2);
- prefixlen1 = region1.base[0];
- prefixlen2 = region2.base[0];
- isc_region_consume(&region1, 1);
- isc_region_consume(&region2, 1);
- if (prefixlen1 < prefixlen2)
- return (-1);
- else if (prefixlen1 > prefixlen2)
- return (1);
- /*
- * Prefix lengths are equal.
- */
- octets = 16 - prefixlen1 / 8;
-
- if (octets > 0) {
- order = memcmp(region1.base, region2.base, octets);
- if (order < 0)
- return (-1);
- else if (order > 0)
- return (1);
- /*
- * Address suffixes are equal.
- */
- if (prefixlen1 == 0)
- return (order);
- isc_region_consume(&region1, octets);
- isc_region_consume(&region2, octets);
- }
-
- dns_name_init(&name1, NULL);
- dns_name_init(&name2, NULL);
- dns_name_fromregion(&name1, &region1);
- dns_name_fromregion(&name2, &region2);
- return (dns_name_rdatacompare(&name1, &name2));
-}
-
-static inline isc_result_t
-fromstruct_in_a6(ARGS_FROMSTRUCT) {
- dns_rdata_in_a6_t *a6 = source;
- isc_region_t region;
- int octets;
- isc_uint8_t bits;
- isc_uint8_t first;
- isc_uint8_t mask;
-
- REQUIRE(type == 38);
- REQUIRE(rdclass == 1);
- REQUIRE(source != NULL);
- REQUIRE(a6->common.rdtype == type);
- REQUIRE(a6->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- if (a6->prefixlen > 128)
- return (ISC_R_RANGE);
-
- RETERR(uint8_tobuffer(a6->prefixlen, target));
-
- /* Suffix */
- if (a6->prefixlen != 128) {
- octets = 16 - a6->prefixlen / 8;
- bits = a6->prefixlen % 8;
- if (bits != 0) {
- mask = 0xffU >> bits;
- first = a6->in6_addr.s6_addr[16 - octets] & mask;
- RETERR(uint8_tobuffer(first, target));
- octets--;
- }
- if (octets > 0)
- RETERR(mem_tobuffer(target,
- a6->in6_addr.s6_addr + 16 - octets,
- octets));
- }
-
- if (a6->prefixlen == 0)
- return (ISC_R_SUCCESS);
- dns_name_toregion(&a6->prefix, &region);
- return (isc_buffer_copyregion(target, &region));
-}
-
-static inline isc_result_t
-tostruct_in_a6(ARGS_TOSTRUCT) {
- dns_rdata_in_a6_t *a6 = target;
- unsigned char octets;
- dns_name_t name;
- isc_region_t r;
-
- REQUIRE(rdata->type == 38);
- REQUIRE(rdata->rdclass == 1);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- a6->common.rdclass = rdata->rdclass;
- a6->common.rdtype = rdata->type;
- ISC_LINK_INIT(&a6->common, link);
-
- dns_rdata_toregion(rdata, &r);
-
- a6->prefixlen = uint8_fromregion(&r);
- isc_region_consume(&r, 1);
- memset(a6->in6_addr.s6_addr, 0, sizeof(a6->in6_addr.s6_addr));
-
- /*
- * Suffix.
- */
- if (a6->prefixlen != 128) {
- octets = 16 - a6->prefixlen / 8;
- INSIST(r.length >= octets);
- memcpy(a6->in6_addr.s6_addr + 16 - octets, r.base, octets);
- isc_region_consume(&r, octets);
- }
-
- /*
- * Prefix.
- */
- dns_name_init(&a6->prefix, NULL);
- if (a6->prefixlen != 0) {
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &r);
- RETERR(name_duporclone(&name, mctx, &a6->prefix));
- }
- a6->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_in_a6(ARGS_FREESTRUCT) {
- dns_rdata_in_a6_t *a6 = source;
-
- REQUIRE(source != NULL);
- REQUIRE(a6->common.rdclass == 1);
- REQUIRE(a6->common.rdtype == 38);
-
- if (a6->mctx == NULL)
- return;
-
- if (dns_name_dynamic(&a6->prefix))
- dns_name_free(&a6->prefix, a6->mctx);
- a6->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_in_a6(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 38);
- REQUIRE(rdata->rdclass == 1);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_in_a6(ARGS_DIGEST) {
- isc_region_t r1, r2;
- unsigned char prefixlen, octets;
- isc_result_t result;
- dns_name_t name;
-
- REQUIRE(rdata->type == 38);
- REQUIRE(rdata->rdclass == 1);
-
- dns_rdata_toregion(rdata, &r1);
- r2 = r1;
- prefixlen = r1.base[0];
- octets = 1 + 16 - prefixlen / 8;
-
- r1.length = octets;
- result = (digest)(arg, &r1);
- if (result != ISC_R_SUCCESS)
- return (result);
- if (prefixlen == 0)
- return (ISC_R_SUCCESS);
-
- isc_region_consume(&r2, octets);
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &r2);
- return (dns_name_digest(&name, digest, arg));
-}
-
-static inline isc_boolean_t
-checkowner_in_a6(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 38);
- REQUIRE(rdclass == 1);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- return (dns_name_ishostname(name, wildcard));
-}
-
-static inline isc_boolean_t
-checknames_in_a6(ARGS_CHECKNAMES) {
- isc_region_t region;
- dns_name_t name;
- unsigned int prefixlen;
-
- REQUIRE(rdata->type == 38);
- REQUIRE(rdata->rdclass == 1);
-
- UNUSED(owner);
-
- dns_rdata_toregion(rdata, &region);
- prefixlen = uint8_fromregion(&region);
- if (prefixlen == 0)
- return (ISC_TRUE);
- isc_region_consume(&region, 1 + 16 - prefixlen / 8);
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &region);
- if (!dns_name_ishostname(&name, ISC_FALSE)) {
- if (bad != NULL)
- dns_name_clone(&name, bad);
- return (ISC_FALSE);
- }
- 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/contrib/bind9/lib/dns/rdata/in_1/a6_38.h b/contrib/bind9/lib/dns/rdata/in_1/a6_38.h
deleted file mode 100644
index 75e53f138f6a..000000000000
--- a/contrib/bind9/lib/dns/rdata/in_1/a6_38.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef IN_1_A6_38_H
-#define IN_1_A6_38_H 1
-
-/* $Id: a6_38.h,v 1.24 2007/06/19 23:47:17 tbox Exp $ */
-
-/*!
- * \brief Per RFC2874 */
-
-typedef struct dns_rdata_in_a6 {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- dns_name_t prefix;
- isc_uint8_t prefixlen;
- struct in6_addr in6_addr;
-} dns_rdata_in_a6_t;
-
-#endif /* IN_1_A6_38_H */
diff --git a/contrib/bind9/lib/dns/rdata/in_1/a_1.c b/contrib/bind9/lib/dns/rdata/in_1/a_1.c
deleted file mode 100644
index 902932e02548..000000000000
--- a/contrib/bind9/lib/dns/rdata/in_1/a_1.c
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $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 */
-
-#ifndef RDATA_IN_1_A_1_C
-#define RDATA_IN_1_A_1_C
-
-#include <string.h>
-
-#include <isc/net.h>
-
-#define RRTYPE_A_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_in_a(ARGS_FROMTEXT) {
- isc_token_t token;
- struct in_addr addr;
- isc_region_t region;
-
- REQUIRE(type == 1);
- REQUIRE(rdclass == 1);
-
- UNUSED(type);
- UNUSED(origin);
- UNUSED(options);
- UNUSED(rdclass);
-
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
-
- if (getquad(DNS_AS_STR(token), &addr, lexer, callbacks) != 1)
- RETTOK(DNS_R_BADDOTTEDQUAD);
- isc_buffer_availableregion(target, &region);
- if (region.length < 4)
- return (ISC_R_NOSPACE);
- memcpy(region.base, &addr, 4);
- isc_buffer_add(target, 4);
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_in_a(ARGS_TOTEXT) {
- isc_region_t region;
-
- REQUIRE(rdata->type == 1);
- REQUIRE(rdata->rdclass == 1);
- REQUIRE(rdata->length == 4);
-
- UNUSED(tctx);
-
- dns_rdata_toregion(rdata, &region);
- return (inet_totext(AF_INET, &region, target));
-}
-
-static inline isc_result_t
-fromwire_in_a(ARGS_FROMWIRE) {
- isc_region_t sregion;
- isc_region_t tregion;
-
- REQUIRE(type == 1);
- REQUIRE(rdclass == 1);
-
- UNUSED(type);
- UNUSED(dctx);
- UNUSED(options);
- UNUSED(rdclass);
-
- isc_buffer_activeregion(source, &sregion);
- isc_buffer_availableregion(target, &tregion);
- if (sregion.length < 4)
- return (ISC_R_UNEXPECTEDEND);
- if (tregion.length < 4)
- return (ISC_R_NOSPACE);
-
- memcpy(tregion.base, sregion.base, 4);
- isc_buffer_forward(source, 4);
- isc_buffer_add(target, 4);
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-towire_in_a(ARGS_TOWIRE) {
- isc_region_t region;
-
- REQUIRE(rdata->type == 1);
- REQUIRE(rdata->rdclass == 1);
- REQUIRE(rdata->length == 4);
-
- UNUSED(cctx);
-
- isc_buffer_availableregion(target, &region);
- if (region.length < rdata->length)
- return (ISC_R_NOSPACE);
- memcpy(region.base, rdata->data, rdata->length);
- isc_buffer_add(target, 4);
- return (ISC_R_SUCCESS);
-}
-
-static inline int
-compare_in_a(ARGS_COMPARE) {
- isc_region_t r1;
- isc_region_t r2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 1);
- REQUIRE(rdata1->rdclass == 1);
- REQUIRE(rdata1->length == 4);
- REQUIRE(rdata2->length == 4);
-
- dns_rdata_toregion(rdata1, &r1);
- dns_rdata_toregion(rdata2, &r2);
- return (isc_region_compare(&r1, &r2));
-}
-
-static inline isc_result_t
-fromstruct_in_a(ARGS_FROMSTRUCT) {
- dns_rdata_in_a_t *a = source;
- isc_uint32_t n;
-
- REQUIRE(type == 1);
- REQUIRE(rdclass == 1);
- REQUIRE(source != NULL);
- REQUIRE(a->common.rdtype == type);
- REQUIRE(a->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- n = ntohl(a->in_addr.s_addr);
-
- return (uint32_tobuffer(n, target));
-}
-
-
-static inline isc_result_t
-tostruct_in_a(ARGS_TOSTRUCT) {
- dns_rdata_in_a_t *a = target;
- isc_uint32_t n;
- isc_region_t region;
-
- REQUIRE(rdata->type == 1);
- REQUIRE(rdata->rdclass == 1);
- REQUIRE(rdata->length == 4);
-
- UNUSED(mctx);
-
- a->common.rdclass = rdata->rdclass;
- a->common.rdtype = rdata->type;
- ISC_LINK_INIT(&a->common, link);
-
- dns_rdata_toregion(rdata, &region);
- n = uint32_fromregion(&region);
- a->in_addr.s_addr = htonl(n);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_in_a(ARGS_FREESTRUCT) {
- dns_rdata_in_a_t *a = source;
-
- REQUIRE(source != NULL);
- REQUIRE(a->common.rdtype == 1);
- REQUIRE(a->common.rdclass == 1);
-
- UNUSED(a);
-}
-
-static inline isc_result_t
-additionaldata_in_a(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 1);
- REQUIRE(rdata->rdclass == 1);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_in_a(ARGS_DIGEST) {
- isc_region_t r;
-
- REQUIRE(rdata->type == 1);
- REQUIRE(rdata->rdclass == 1);
-
- dns_rdata_toregion(rdata, &r);
-
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_in_a(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 1);
- REQUIRE(rdclass == 1);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- return (dns_name_ishostname(name, wildcard));
-}
-
-static inline isc_boolean_t
-checknames_in_a(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 1);
- REQUIRE(rdata->rdclass == 1);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- 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/contrib/bind9/lib/dns/rdata/in_1/a_1.h b/contrib/bind9/lib/dns/rdata/in_1/a_1.h
deleted file mode 100644
index c192d1a7bdb1..000000000000
--- a/contrib/bind9/lib/dns/rdata/in_1/a_1.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* */
-#ifndef IN_1_A_1_H
-#define IN_1_A_1_H 1
-
-/* $Id: a_1.h,v 1.28 2007/06/19 23:47:17 tbox Exp $ */
-
-typedef struct dns_rdata_in_a {
- dns_rdatacommon_t common;
- struct in_addr in_addr;
-} dns_rdata_in_a_t;
-
-#endif /* IN_1_A_1_H */
diff --git a/contrib/bind9/lib/dns/rdata/in_1/aaaa_28.c b/contrib/bind9/lib/dns/rdata/in_1/aaaa_28.c
deleted file mode 100644
index 5aa59b2ccc2c..000000000000
--- a/contrib/bind9/lib/dns/rdata/in_1/aaaa_28.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $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 */
-
-/* RFC1886 */
-
-#ifndef RDATA_IN_1_AAAA_28_C
-#define RDATA_IN_1_AAAA_28_C
-
-#include <isc/net.h>
-
-#define RRTYPE_AAAA_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_in_aaaa(ARGS_FROMTEXT) {
- isc_token_t token;
- unsigned char addr[16];
- isc_region_t region;
-
- REQUIRE(type == 28);
- REQUIRE(rdclass == 1);
-
- UNUSED(type);
- UNUSED(origin);
- UNUSED(options);
- UNUSED(rdclass);
- UNUSED(callbacks);
-
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
-
- if (inet_pton(AF_INET6, DNS_AS_STR(token), addr) != 1)
- RETTOK(DNS_R_BADAAAA);
- isc_buffer_availableregion(target, &region);
- if (region.length < 16)
- return (ISC_R_NOSPACE);
- memcpy(region.base, addr, 16);
- isc_buffer_add(target, 16);
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_in_aaaa(ARGS_TOTEXT) {
- isc_region_t region;
-
- UNUSED(tctx);
-
- REQUIRE(rdata->type == 28);
- REQUIRE(rdata->rdclass == 1);
- REQUIRE(rdata->length == 16);
-
- dns_rdata_toregion(rdata, &region);
- return (inet_totext(AF_INET6, &region, target));
-}
-
-static inline isc_result_t
-fromwire_in_aaaa(ARGS_FROMWIRE) {
- isc_region_t sregion;
- isc_region_t tregion;
-
- REQUIRE(type == 28);
- REQUIRE(rdclass == 1);
-
- UNUSED(type);
- UNUSED(dctx);
- UNUSED(options);
- UNUSED(rdclass);
-
- isc_buffer_activeregion(source, &sregion);
- isc_buffer_availableregion(target, &tregion);
- if (sregion.length < 16)
- return (ISC_R_UNEXPECTEDEND);
- if (tregion.length < 16)
- return (ISC_R_NOSPACE);
-
- memcpy(tregion.base, sregion.base, 16);
- isc_buffer_forward(source, 16);
- isc_buffer_add(target, 16);
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-towire_in_aaaa(ARGS_TOWIRE) {
- isc_region_t region;
-
- UNUSED(cctx);
-
- REQUIRE(rdata->type == 28);
- REQUIRE(rdata->rdclass == 1);
- REQUIRE(rdata->length == 16);
-
- isc_buffer_availableregion(target, &region);
- if (region.length < rdata->length)
- return (ISC_R_NOSPACE);
- memcpy(region.base, rdata->data, rdata->length);
- isc_buffer_add(target, 16);
- return (ISC_R_SUCCESS);
-}
-
-static inline int
-compare_in_aaaa(ARGS_COMPARE) {
- isc_region_t r1;
- isc_region_t r2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 28);
- REQUIRE(rdata1->rdclass == 1);
- REQUIRE(rdata1->length == 16);
- REQUIRE(rdata2->length == 16);
-
- dns_rdata_toregion(rdata1, &r1);
- dns_rdata_toregion(rdata2, &r2);
- return (isc_region_compare(&r1, &r2));
-}
-
-static inline isc_result_t
-fromstruct_in_aaaa(ARGS_FROMSTRUCT) {
- dns_rdata_in_aaaa_t *aaaa = source;
-
- REQUIRE(type == 28);
- REQUIRE(rdclass == 1);
- REQUIRE(source != NULL);
- REQUIRE(aaaa->common.rdtype == type);
- REQUIRE(aaaa->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- return (mem_tobuffer(target, aaaa->in6_addr.s6_addr, 16));
-}
-
-static inline isc_result_t
-tostruct_in_aaaa(ARGS_TOSTRUCT) {
- dns_rdata_in_aaaa_t *aaaa = target;
- isc_region_t r;
-
- REQUIRE(rdata->type == 28);
- REQUIRE(rdata->rdclass == 1);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length == 16);
-
- UNUSED(mctx);
-
- aaaa->common.rdclass = rdata->rdclass;
- aaaa->common.rdtype = rdata->type;
- ISC_LINK_INIT(&aaaa->common, link);
-
- dns_rdata_toregion(rdata, &r);
- INSIST(r.length == 16);
- memcpy(aaaa->in6_addr.s6_addr, r.base, 16);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_in_aaaa(ARGS_FREESTRUCT) {
- dns_rdata_in_aaaa_t *aaaa = source;
-
- REQUIRE(source != NULL);
- REQUIRE(aaaa->common.rdclass == 1);
- REQUIRE(aaaa->common.rdtype == 28);
-
- UNUSED(aaaa);
-}
-
-static inline isc_result_t
-additionaldata_in_aaaa(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 28);
- REQUIRE(rdata->rdclass == 1);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_in_aaaa(ARGS_DIGEST) {
- isc_region_t r;
-
- REQUIRE(rdata->type == 28);
- REQUIRE(rdata->rdclass == 1);
-
- dns_rdata_toregion(rdata, &r);
-
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_in_aaaa(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 28);
- REQUIRE(rdclass == 1);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- return (dns_name_ishostname(name, wildcard));
-}
-
-static inline isc_boolean_t
-checknames_in_aaaa(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 28);
- REQUIRE(rdata->rdclass == 1);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- 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/contrib/bind9/lib/dns/rdata/in_1/aaaa_28.h b/contrib/bind9/lib/dns/rdata/in_1/aaaa_28.h
deleted file mode 100644
index 54a0cb3767db..000000000000
--- a/contrib/bind9/lib/dns/rdata/in_1/aaaa_28.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef IN_1_AAAA_28_H
-#define IN_1_AAAA_28_H 1
-
-/* $Id: aaaa_28.h,v 1.21 2007/06/19 23:47:17 tbox Exp $ */
-
-/*!
- * \brief Per RFC1886 */
-
-typedef struct dns_rdata_in_aaaa {
- dns_rdatacommon_t common;
- struct in6_addr in6_addr;
-} dns_rdata_in_aaaa_t;
-
-#endif /* IN_1_AAAA_28_H */
diff --git a/contrib/bind9/lib/dns/rdata/in_1/apl_42.c b/contrib/bind9/lib/dns/rdata/in_1/apl_42.c
deleted file mode 100644
index eb927b9219e3..000000000000
--- a/contrib/bind9/lib/dns/rdata/in_1/apl_42.c
+++ /dev/null
@@ -1,458 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: apl_42.c,v 1.16 2009/12/04 22:06:37 tbox Exp $ */
-
-/* RFC3123 */
-
-#ifndef RDATA_IN_1_APL_42_C
-#define RDATA_IN_1_APL_42_C
-
-#define RRTYPE_APL_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_in_apl(ARGS_FROMTEXT) {
- isc_token_t token;
- unsigned char addr[16];
- unsigned long afi;
- isc_uint8_t prefix;
- isc_uint8_t len;
- isc_boolean_t neg;
- char *cp, *ap, *slash;
- int n;
-
- REQUIRE(type == 42);
- REQUIRE(rdclass == 1);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(origin);
- UNUSED(options);
- UNUSED(callbacks);
-
- do {
- RETERR(isc_lex_getmastertoken(lexer, &token,
- isc_tokentype_string, ISC_TRUE));
- if (token.type != isc_tokentype_string)
- break;
-
- cp = DNS_AS_STR(token);
- neg = ISC_TF(*cp == '!');
- if (neg)
- cp++;
- afi = strtoul(cp, &ap, 10);
- if (*ap++ != ':' || cp == ap)
- RETTOK(DNS_R_SYNTAX);
- if (afi > 0xffffU)
- RETTOK(ISC_R_RANGE);
- slash = strchr(ap, '/');
- if (slash == NULL || slash == ap)
- RETTOK(DNS_R_SYNTAX);
- RETTOK(isc_parse_uint8(&prefix, slash + 1, 10));
- switch (afi) {
- case 1:
- *slash = '\0';
- n = inet_pton(AF_INET, ap, addr);
- *slash = '/';
- if (n != 1)
- RETTOK(DNS_R_BADDOTTEDQUAD);
- if (prefix > 32)
- RETTOK(ISC_R_RANGE);
- for (len = 4; len > 0; len--)
- if (addr[len - 1] != 0)
- break;
- break;
-
- case 2:
- *slash = '\0';
- n = inet_pton(AF_INET6, ap, addr);
- *slash = '/';
- if (n != 1)
- RETTOK(DNS_R_BADAAAA);
- if (prefix > 128)
- RETTOK(ISC_R_RANGE);
- for (len = 16; len > 0; len--)
- if (addr[len - 1] != 0)
- break;
- break;
-
- default:
- RETTOK(ISC_R_NOTIMPLEMENTED);
- }
- RETERR(uint16_tobuffer(afi, target));
- RETERR(uint8_tobuffer(prefix, target));
- RETERR(uint8_tobuffer(len | ((neg) ? 0x80 : 0), target));
- RETERR(mem_tobuffer(target, addr, len));
- } while (1);
-
- /*
- * Let upper layer handle eol/eof.
- */
- isc_lex_ungettoken(lexer, &token);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_in_apl(ARGS_TOTEXT) {
- isc_region_t sr;
- isc_region_t ir;
- isc_uint16_t afi;
- isc_uint8_t prefix;
- isc_uint8_t len;
- isc_boolean_t neg;
- unsigned char buf[16];
- char txt[sizeof(" !64000")];
- const char *sep = "";
- int n;
-
- REQUIRE(rdata->type == 42);
- REQUIRE(rdata->rdclass == 1);
-
- UNUSED(tctx);
-
- dns_rdata_toregion(rdata, &sr);
- ir.base = buf;
- ir.length = sizeof(buf);
-
- while (sr.length > 0) {
- INSIST(sr.length >= 4);
- afi = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
- prefix = *sr.base;
- isc_region_consume(&sr, 1);
- len = (*sr.base & 0x7f);
- neg = ISC_TF((*sr.base & 0x80) != 0);
- isc_region_consume(&sr, 1);
- INSIST(len <= sr.length);
- n = snprintf(txt, sizeof(txt), "%s%s%u:", sep,
- neg ? "!": "", afi);
- INSIST(n < (int)sizeof(txt));
- RETERR(str_totext(txt, target));
- switch (afi) {
- case 1:
- INSIST(len <= 4);
- INSIST(prefix <= 32);
- memset(buf, 0, sizeof(buf));
- memcpy(buf, sr.base, len);
- RETERR(inet_totext(AF_INET, &ir, target));
- break;
-
- case 2:
- INSIST(len <= 16);
- INSIST(prefix <= 128);
- memset(buf, 0, sizeof(buf));
- memcpy(buf, sr.base, len);
- RETERR(inet_totext(AF_INET6, &ir, target));
- break;
-
- default:
- return (ISC_R_NOTIMPLEMENTED);
- }
- n = snprintf(txt, sizeof(txt), "/%u", prefix);
- INSIST(n < (int)sizeof(txt));
- RETERR(str_totext(txt, target));
- isc_region_consume(&sr, len);
- sep = " ";
- }
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-fromwire_in_apl(ARGS_FROMWIRE) {
- isc_region_t sr, sr2;
- isc_region_t tr;
- isc_uint16_t afi;
- isc_uint8_t prefix;
- isc_uint8_t len;
-
- REQUIRE(type == 42);
- REQUIRE(rdclass == 1);
-
- UNUSED(type);
- UNUSED(dctx);
- UNUSED(rdclass);
- UNUSED(options);
-
- isc_buffer_activeregion(source, &sr);
- isc_buffer_availableregion(target, &tr);
- if (sr.length > tr.length)
- return (ISC_R_NOSPACE);
- sr2 = sr;
-
- /* Zero or more items */
- while (sr.length > 0) {
- if (sr.length < 4)
- return (ISC_R_UNEXPECTEDEND);
- afi = uint16_fromregion(&sr);
- isc_region_consume(&sr, 2);
- prefix = *sr.base;
- isc_region_consume(&sr, 1);
- len = (*sr.base & 0x7f);
- isc_region_consume(&sr, 1);
- if (len > sr.length)
- return (ISC_R_UNEXPECTEDEND);
- switch (afi) {
- case 1:
- if (prefix > 32 || len > 4)
- return (ISC_R_RANGE);
- break;
- case 2:
- if (prefix > 128 || len > 16)
- return (ISC_R_RANGE);
- }
- if (len > 0 && sr.base[len - 1] == 0)
- return (DNS_R_FORMERR);
- isc_region_consume(&sr, len);
- }
- isc_buffer_forward(source, sr2.length);
- return (mem_tobuffer(target, sr2.base, sr2.length));
-}
-
-static inline isc_result_t
-towire_in_apl(ARGS_TOWIRE) {
- UNUSED(cctx);
-
- REQUIRE(rdata->type == 42);
- REQUIRE(rdata->rdclass == 1);
-
- return (mem_tobuffer(target, rdata->data, rdata->length));
-}
-
-static inline int
-compare_in_apl(ARGS_COMPARE) {
- isc_region_t r1;
- isc_region_t r2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 42);
- REQUIRE(rdata1->rdclass == 1);
-
- dns_rdata_toregion(rdata1, &r1);
- dns_rdata_toregion(rdata2, &r2);
- return (isc_region_compare(&r1, &r2));
-}
-
-static inline isc_result_t
-fromstruct_in_apl(ARGS_FROMSTRUCT) {
- dns_rdata_in_apl_t *apl = source;
- isc_buffer_t b;
-
- REQUIRE(type == 42);
- REQUIRE(rdclass == 1);
- REQUIRE(source != NULL);
- REQUIRE(apl->common.rdtype == type);
- REQUIRE(apl->common.rdclass == rdclass);
- REQUIRE(apl->apl != NULL || apl->apl_len == 0);
-
- isc_buffer_init(&b, apl->apl, apl->apl_len);
- isc_buffer_add(&b, apl->apl_len);
- isc_buffer_setactive(&b, apl->apl_len);
- return(fromwire_in_apl(rdclass, type, &b, NULL, ISC_FALSE, target));
-}
-
-static inline isc_result_t
-tostruct_in_apl(ARGS_TOSTRUCT) {
- dns_rdata_in_apl_t *apl = target;
- isc_region_t r;
-
- REQUIRE(rdata->type == 42);
- REQUIRE(rdata->rdclass == 1);
-
- apl->common.rdclass = rdata->rdclass;
- apl->common.rdtype = rdata->type;
- ISC_LINK_INIT(&apl->common, link);
-
- dns_rdata_toregion(rdata, &r);
- apl->apl_len = r.length;
- apl->apl = mem_maybedup(mctx, r.base, r.length);
- if (apl->apl == NULL)
- return (ISC_R_NOMEMORY);
-
- apl->offset = 0;
- apl->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_in_apl(ARGS_FREESTRUCT) {
- dns_rdata_in_apl_t *apl = source;
-
- REQUIRE(source != NULL);
- REQUIRE(apl->common.rdtype == 42);
- REQUIRE(apl->common.rdclass == 1);
-
- if (apl->mctx == NULL)
- return;
- if (apl->apl != NULL)
- isc_mem_free(apl->mctx, apl->apl);
- apl->mctx = NULL;
-}
-
-isc_result_t
-dns_rdata_apl_first(dns_rdata_in_apl_t *apl) {
- isc_uint32_t length;
-
- REQUIRE(apl != NULL);
- REQUIRE(apl->common.rdtype == 42);
- REQUIRE(apl->common.rdclass == 1);
- REQUIRE(apl->apl != NULL || apl->apl_len == 0);
-
- /*
- * If no APL return ISC_R_NOMORE.
- */
- if (apl->apl == NULL)
- return (ISC_R_NOMORE);
-
- /*
- * Sanity check data.
- */
- INSIST(apl->apl_len > 3U);
- length = apl->apl[apl->offset + 3] & 0x7f;
- INSIST(length <= apl->apl_len);
-
- apl->offset = 0;
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_rdata_apl_next(dns_rdata_in_apl_t *apl) {
- isc_uint32_t length;
-
- REQUIRE(apl != NULL);
- REQUIRE(apl->common.rdtype == 42);
- REQUIRE(apl->common.rdclass == 1);
- REQUIRE(apl->apl != NULL || apl->apl_len == 0);
-
- /*
- * No APL or have already reached the end return ISC_R_NOMORE.
- */
- if (apl->apl == NULL || apl->offset == apl->apl_len)
- return (ISC_R_NOMORE);
-
- /*
- * Sanity check data.
- */
- INSIST(apl->offset < apl->apl_len);
- INSIST(apl->apl_len > 3U);
- INSIST(apl->offset <= apl->apl_len - 4U);
- length = apl->apl[apl->offset + 3] & 0x7f;
- /*
- * 16 to 32 bits promotion as 'length' is 32 bits so there is
- * no overflow problems.
- */
- INSIST(length + apl->offset <= apl->apl_len);
-
- apl->offset += apl->apl[apl->offset + 3] & 0x7f;
- return ((apl->offset >= apl->apl_len) ? ISC_R_SUCCESS : ISC_R_NOMORE);
-}
-
-isc_result_t
-dns_rdata_apl_current(dns_rdata_in_apl_t *apl, dns_rdata_apl_ent_t *ent) {
- isc_uint32_t length;
-
- REQUIRE(apl != NULL);
- REQUIRE(apl->common.rdtype == 42);
- REQUIRE(apl->common.rdclass == 1);
- REQUIRE(ent != NULL);
- REQUIRE(apl->apl != NULL || apl->apl_len == 0);
- REQUIRE(apl->offset <= apl->apl_len);
-
- if (apl->offset == apl->apl_len)
- return (ISC_R_NOMORE);
-
- /*
- * Sanity check data.
- */
- INSIST(apl->apl_len > 3U);
- INSIST(apl->offset <= apl->apl_len - 4U);
- length = apl->apl[apl->offset + 3] & 0x7f;
- /*
- * 16 to 32 bits promotion as 'length' is 32 bits so there is
- * no overflow problems.
- */
- INSIST(length + apl->offset <= apl->apl_len);
-
- ent->family = (apl->apl[apl->offset] << 8) + apl->apl[apl->offset + 1];
- ent->prefix = apl->apl[apl->offset + 2];
- ent->length = apl->apl[apl->offset + 3] & 0x7f;
- ent->negative = ISC_TF((apl->apl[apl->offset + 3] & 0x80) != 0);
- if (ent->length != 0)
- ent->data = &apl->apl[apl->offset + 4];
- else
- ent->data = NULL;
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-additionaldata_in_apl(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 42);
- REQUIRE(rdata->rdclass == 1);
-
- (void)add;
- (void)arg;
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_in_apl(ARGS_DIGEST) {
- isc_region_t r;
-
- REQUIRE(rdata->type == 42);
- REQUIRE(rdata->rdclass == 1);
-
- dns_rdata_toregion(rdata, &r);
-
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_in_apl(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 42);
- REQUIRE(rdclass == 1);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-
-static inline isc_boolean_t
-checknames_in_apl(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 42);
- REQUIRE(rdata->rdclass == 1);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- 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/contrib/bind9/lib/dns/rdata/in_1/apl_42.h b/contrib/bind9/lib/dns/rdata/in_1/apl_42.h
deleted file mode 100644
index 2d01040ba899..000000000000
--- a/contrib/bind9/lib/dns/rdata/in_1/apl_42.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2002 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* */
-#ifndef IN_1_APL_42_H
-#define IN_1_APL_42_H 1
-
-/* $Id: apl_42.h,v 1.6 2007/06/19 23:47:17 tbox Exp $ */
-
-typedef struct dns_rdata_apl_ent {
- isc_boolean_t negative;
- isc_uint16_t family;
- isc_uint8_t prefix;
- isc_uint8_t length;
- unsigned char *data;
-} dns_rdata_apl_ent_t;
-
-typedef struct dns_rdata_in_apl {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- /* type & class specific elements */
- unsigned char *apl;
- isc_uint16_t apl_len;
- /* private */
- isc_uint16_t offset;
-} dns_rdata_in_apl_t;
-
-/*
- * ISC_LANG_BEGINDECLS and ISC_LANG_ENDDECLS are already done
- * via rdatastructpre.h and rdatastructsuf.h.
- */
-
-isc_result_t
-dns_rdata_apl_first(dns_rdata_in_apl_t *);
-
-isc_result_t
-dns_rdata_apl_next(dns_rdata_in_apl_t *);
-
-isc_result_t
-dns_rdata_apl_current(dns_rdata_in_apl_t *, dns_rdata_apl_ent_t *);
-
-#endif /* IN_1_APL_42_H */
diff --git a/contrib/bind9/lib/dns/rdata/in_1/dhcid_49.c b/contrib/bind9/lib/dns/rdata/in_1/dhcid_49.c
deleted file mode 100644
index 7575da0d1930..000000000000
--- a/contrib/bind9/lib/dns/rdata/in_1/dhcid_49.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/* RFC 4701 */
-
-#ifndef RDATA_IN_1_DHCID_49_C
-#define RDATA_IN_1_DHCID_49_C 1
-
-#define RRTYPE_DHCID_ATTRIBUTES 0
-
-static inline isc_result_t
-fromtext_in_dhcid(ARGS_FROMTEXT) {
-
- REQUIRE(type == 49);
- REQUIRE(rdclass == 1);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(origin);
- UNUSED(options);
- UNUSED(callbacks);
-
- return (isc_base64_tobuffer(lexer, target, -1));
-}
-
-static inline isc_result_t
-totext_in_dhcid(ARGS_TOTEXT) {
- isc_region_t sr;
- char buf[sizeof(" ; 64000 255 64000")];
- size_t n;
-
- REQUIRE(rdata->type == 49);
- REQUIRE(rdata->rdclass == 1);
- REQUIRE(rdata->length != 0);
-
- dns_rdata_toregion(rdata, &sr);
-
- if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
- RETERR(str_totext("( " /*)*/, target));
- if (tctx->width == 0) /* No splitting */
- RETERR(isc_base64_totext(&sr, 60, "", target));
- else
- RETERR(isc_base64_totext(&sr, tctx->width - 2,
- tctx->linebreak, target));
- if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
- RETERR(str_totext(/* ( */ " )", target));
- if (rdata->length > 2) {
- n = snprintf(buf, sizeof(buf), " ; %u %u %u",
- sr.base[0] * 256 + sr.base[1],
- sr.base[2], rdata->length - 3);
- INSIST(n < sizeof(buf));
- RETERR(str_totext(buf, target));
- }
- }
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-fromwire_in_dhcid(ARGS_FROMWIRE) {
- isc_region_t sr;
-
- REQUIRE(type == 49);
- REQUIRE(rdclass == 1);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(dctx);
- UNUSED(options);
-
- isc_buffer_activeregion(source, &sr);
- if (sr.length == 0)
- return (ISC_R_UNEXPECTEDEND);
-
- isc_buffer_forward(source, sr.length);
- return (mem_tobuffer(target, sr.base, sr.length));
-}
-
-static inline isc_result_t
-towire_in_dhcid(ARGS_TOWIRE) {
- isc_region_t sr;
-
- REQUIRE(rdata->type == 49);
- REQUIRE(rdata->rdclass == 1);
- REQUIRE(rdata->length != 0);
-
- UNUSED(cctx);
-
- dns_rdata_toregion(rdata, &sr);
- return (mem_tobuffer(target, sr.base, sr.length));
-}
-
-static inline int
-compare_in_dhcid(ARGS_COMPARE) {
- isc_region_t r1;
- isc_region_t r2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 49);
- REQUIRE(rdata1->rdclass == 1);
- 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_in_dhcid(ARGS_FROMSTRUCT) {
- dns_rdata_in_dhcid_t *dhcid = source;
-
- REQUIRE(type == 49);
- REQUIRE(rdclass == 1);
- REQUIRE(source != NULL);
- REQUIRE(dhcid->common.rdtype == type);
- REQUIRE(dhcid->common.rdclass == rdclass);
- REQUIRE(dhcid->length != 0);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- return (mem_tobuffer(target, dhcid->dhcid, dhcid->length));
-}
-
-static inline isc_result_t
-tostruct_in_dhcid(ARGS_TOSTRUCT) {
- dns_rdata_in_dhcid_t *dhcid = target;
- isc_region_t region;
-
- REQUIRE(rdata->type == 49);
- REQUIRE(rdata->rdclass == 1);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- dhcid->common.rdclass = rdata->rdclass;
- dhcid->common.rdtype = rdata->type;
- ISC_LINK_INIT(&dhcid->common, link);
-
- dns_rdata_toregion(rdata, &region);
-
- dhcid->dhcid = mem_maybedup(mctx, region.base, region.length);
- if (dhcid->dhcid == NULL)
- return (ISC_R_NOMEMORY);
-
- dhcid->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_in_dhcid(ARGS_FREESTRUCT) {
- dns_rdata_in_dhcid_t *dhcid = source;
-
- REQUIRE(dhcid != NULL);
- REQUIRE(dhcid->common.rdtype == 49);
- REQUIRE(dhcid->common.rdclass == 1);
-
- if (dhcid->mctx == NULL)
- return;
-
- if (dhcid->dhcid != NULL)
- isc_mem_free(dhcid->mctx, dhcid->dhcid);
- dhcid->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_in_dhcid(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 49);
- REQUIRE(rdata->rdclass == 1);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_in_dhcid(ARGS_DIGEST) {
- isc_region_t r;
-
- REQUIRE(rdata->type == 49);
- REQUIRE(rdata->rdclass == 1);
-
- dns_rdata_toregion(rdata, &r);
-
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_in_dhcid(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 49);
- REQUIRE(rdclass == 1);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_in_dhcid(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 49);
- REQUIRE(rdata->rdclass == 1);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- 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/contrib/bind9/lib/dns/rdata/in_1/dhcid_49.h b/contrib/bind9/lib/dns/rdata/in_1/dhcid_49.h
deleted file mode 100644
index 279719251bef..000000000000
--- a/contrib/bind9/lib/dns/rdata/in_1/dhcid_49.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2006, 2007 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 IN_1_DHCID_49_H
-#define IN_1_DHCID_49_H 1
-
-/* $Id: dhcid_49.h,v 1.5 2007/06/19 23:47:17 tbox Exp $ */
-
-typedef struct dns_rdata_in_dhcid {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- unsigned char *dhcid;
- unsigned int length;
-} dns_rdata_in_dhcid_t;
-
-#endif /* IN_1_DHCID_49_H */
diff --git a/contrib/bind9/lib/dns/rdata/in_1/kx_36.c b/contrib/bind9/lib/dns/rdata/in_1/kx_36.c
deleted file mode 100644
index fbe3b71deaa0..000000000000
--- a/contrib/bind9/lib/dns/rdata/in_1/kx_36.c
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $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 */
-
-/* RFC2230 */
-
-#ifndef RDATA_IN_1_KX_36_C
-#define RDATA_IN_1_KX_36_C
-
-#define RRTYPE_KX_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_in_kx(ARGS_FROMTEXT) {
- isc_token_t token;
- dns_name_t name;
- isc_buffer_t buffer;
-
- REQUIRE(type == 36);
- REQUIRE(rdclass == 1);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(callbacks);
-
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if (token.value.as_ulong > 0xffffU)
- RETTOK(ISC_R_RANGE);
- RETERR(uint16_tobuffer(token.value.as_ulong, target));
-
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- dns_name_init(&name, NULL);
- buffer_fromregion(&buffer, &token.value.as_region);
- origin = (origin != NULL) ? origin : dns_rootname;
- RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_in_kx(ARGS_TOTEXT) {
- isc_region_t region;
- dns_name_t name;
- dns_name_t prefix;
- isc_boolean_t sub;
- char buf[sizeof("64000")];
- unsigned short num;
-
- REQUIRE(rdata->type == 36);
- REQUIRE(rdata->rdclass == 1);
- REQUIRE(rdata->length != 0);
-
- dns_name_init(&name, NULL);
- dns_name_init(&prefix, NULL);
-
- dns_rdata_toregion(rdata, &region);
- num = uint16_fromregion(&region);
- isc_region_consume(&region, 2);
- sprintf(buf, "%u", num);
- RETERR(str_totext(buf, target));
-
- RETERR(str_totext(" ", target));
-
- dns_name_fromregion(&name, &region);
- sub = name_prefix(&name, tctx->origin, &prefix);
- return (dns_name_totext(&prefix, sub, target));
-}
-
-static inline isc_result_t
-fromwire_in_kx(ARGS_FROMWIRE) {
- dns_name_t name;
- isc_region_t sregion;
-
- REQUIRE(type == 36);
- REQUIRE(rdclass == 1);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
-
- dns_name_init(&name, NULL);
-
- isc_buffer_activeregion(source, &sregion);
- if (sregion.length < 2)
- return (ISC_R_UNEXPECTEDEND);
- RETERR(mem_tobuffer(target, sregion.base, 2));
- isc_buffer_forward(source, 2);
- return (dns_name_fromwire(&name, source, dctx, options, target));
-}
-
-static inline isc_result_t
-towire_in_kx(ARGS_TOWIRE) {
- dns_name_t name;
- dns_offsets_t offsets;
- isc_region_t region;
-
- REQUIRE(rdata->type == 36);
- REQUIRE(rdata->rdclass == 1);
- REQUIRE(rdata->length != 0);
-
- dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
- dns_rdata_toregion(rdata, &region);
- RETERR(mem_tobuffer(target, region.base, 2));
- isc_region_consume(&region, 2);
-
- dns_name_init(&name, offsets);
- dns_name_fromregion(&name, &region);
-
- return (dns_name_towire(&name, cctx, target));
-}
-
-static inline int
-compare_in_kx(ARGS_COMPARE) {
- dns_name_t name1;
- dns_name_t name2;
- isc_region_t region1;
- isc_region_t region2;
- int order;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 36);
- REQUIRE(rdata1->rdclass == 1);
- REQUIRE(rdata1->length != 0);
- REQUIRE(rdata2->length != 0);
-
- order = memcmp(rdata1->data, rdata2->data, 2);
- if (order != 0)
- return (order < 0 ? -1 : 1);
-
- dns_name_init(&name1, NULL);
- dns_name_init(&name2, NULL);
-
- dns_rdata_toregion(rdata1, &region1);
- dns_rdata_toregion(rdata2, &region2);
-
- isc_region_consume(&region1, 2);
- isc_region_consume(&region2, 2);
-
- dns_name_fromregion(&name1, &region1);
- dns_name_fromregion(&name2, &region2);
-
- return (dns_name_rdatacompare(&name1, &name2));
-}
-
-static inline isc_result_t
-fromstruct_in_kx(ARGS_FROMSTRUCT) {
- dns_rdata_in_kx_t *kx = source;
- isc_region_t region;
-
- REQUIRE(type == 36);
- REQUIRE(rdclass == 1);
- REQUIRE(source != NULL);
- REQUIRE(kx->common.rdtype == type);
- REQUIRE(kx->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- RETERR(uint16_tobuffer(kx->preference, target));
- dns_name_toregion(&kx->exchange, &region);
- return (isc_buffer_copyregion(target, &region));
-}
-
-static inline isc_result_t
-tostruct_in_kx(ARGS_TOSTRUCT) {
- isc_region_t region;
- dns_rdata_in_kx_t *kx = target;
- dns_name_t name;
-
- REQUIRE(rdata->type == 36);
- REQUIRE(rdata->rdclass == 1);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- kx->common.rdclass = rdata->rdclass;
- kx->common.rdtype = rdata->type;
- ISC_LINK_INIT(&kx->common, link);
-
- dns_name_init(&name, NULL);
- dns_rdata_toregion(rdata, &region);
-
- kx->preference = uint16_fromregion(&region);
- isc_region_consume(&region, 2);
-
- dns_name_fromregion(&name, &region);
- dns_name_init(&kx->exchange, NULL);
- RETERR(name_duporclone(&name, mctx, &kx->exchange));
- kx->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_in_kx(ARGS_FREESTRUCT) {
- dns_rdata_in_kx_t *kx = source;
-
- REQUIRE(source != NULL);
- REQUIRE(kx->common.rdclass == 1);
- REQUIRE(kx->common.rdtype == 36);
-
- if (kx->mctx == NULL)
- return;
-
- dns_name_free(&kx->exchange, kx->mctx);
- kx->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_in_kx(ARGS_ADDLDATA) {
- dns_name_t name;
- dns_offsets_t offsets;
- isc_region_t region;
-
- REQUIRE(rdata->type == 36);
- REQUIRE(rdata->rdclass == 1);
-
- dns_name_init(&name, offsets);
- dns_rdata_toregion(rdata, &region);
- isc_region_consume(&region, 2);
- dns_name_fromregion(&name, &region);
-
- return ((add)(arg, &name, dns_rdatatype_a));
-}
-
-static inline isc_result_t
-digest_in_kx(ARGS_DIGEST) {
- isc_region_t r1, r2;
- dns_name_t name;
-
- REQUIRE(rdata->type == 36);
- REQUIRE(rdata->rdclass == 1);
-
- dns_rdata_toregion(rdata, &r1);
- r2 = r1;
- isc_region_consume(&r2, 2);
- r1.length = 2;
- RETERR((digest)(arg, &r1));
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &r2);
- return (dns_name_digest(&name, digest, arg));
-}
-
-static inline isc_boolean_t
-checkowner_in_kx(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 36);
- REQUIRE(rdclass == 1);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_in_kx(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 36);
- REQUIRE(rdata->rdclass == 1);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- 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/contrib/bind9/lib/dns/rdata/in_1/kx_36.h b/contrib/bind9/lib/dns/rdata/in_1/kx_36.h
deleted file mode 100644
index 391ae27dd960..000000000000
--- a/contrib/bind9/lib/dns/rdata/in_1/kx_36.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef IN_1_KX_36_H
-#define IN_1_KX_36_H 1
-
-/* $Id: kx_36.h,v 1.20 2007/06/19 23:47:17 tbox Exp $ */
-
-/*!
- * \brief Per RFC2230 */
-
-typedef struct dns_rdata_in_kx {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- isc_uint16_t preference;
- dns_name_t exchange;
-} dns_rdata_in_kx_t;
-
-#endif /* IN_1_KX_36_H */
diff --git a/contrib/bind9/lib/dns/rdata/in_1/nsap-ptr_23.c b/contrib/bind9/lib/dns/rdata/in_1/nsap-ptr_23.c
deleted file mode 100644
index 78df645a2a1f..000000000000
--- a/contrib/bind9/lib/dns/rdata/in_1/nsap-ptr_23.c
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $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 */
-
-/* RFC1348. Obsoleted in RFC 1706 - use PTR instead. */
-
-#ifndef RDATA_IN_1_NSAP_PTR_23_C
-#define RDATA_IN_1_NSAP_PTR_23_C
-
-#define RRTYPE_NSAP_PTR_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_in_nsap_ptr(ARGS_FROMTEXT) {
- isc_token_t token;
- dns_name_t name;
- isc_buffer_t buffer;
-
- REQUIRE(type == 23);
- REQUIRE(rdclass == 1);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(callbacks);
-
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
-
- dns_name_init(&name, NULL);
- buffer_fromregion(&buffer, &token.value.as_region);
- origin = (origin != NULL) ? origin : dns_rootname;
- RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_in_nsap_ptr(ARGS_TOTEXT) {
- isc_region_t region;
- dns_name_t name;
- dns_name_t prefix;
- isc_boolean_t sub;
-
- REQUIRE(rdata->type == 23);
- REQUIRE(rdata->rdclass == 1);
- REQUIRE(rdata->length != 0);
-
- dns_name_init(&name, NULL);
- dns_name_init(&prefix, NULL);
-
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
-
- sub = name_prefix(&name, tctx->origin, &prefix);
-
- return (dns_name_totext(&prefix, sub, target));
-}
-
-static inline isc_result_t
-fromwire_in_nsap_ptr(ARGS_FROMWIRE) {
- dns_name_t name;
-
- REQUIRE(type == 23);
- REQUIRE(rdclass == 1);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
-
- dns_name_init(&name, NULL);
- return (dns_name_fromwire(&name, source, dctx, options, target));
-}
-
-static inline isc_result_t
-towire_in_nsap_ptr(ARGS_TOWIRE) {
- dns_name_t name;
- dns_offsets_t offsets;
- isc_region_t region;
-
- REQUIRE(rdata->type == 23);
- REQUIRE(rdata->rdclass == 1);
- REQUIRE(rdata->length != 0);
-
- dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
- dns_name_init(&name, offsets);
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
-
- return (dns_name_towire(&name, cctx, target));
-}
-
-static inline int
-compare_in_nsap_ptr(ARGS_COMPARE) {
- dns_name_t name1;
- dns_name_t name2;
- isc_region_t region1;
- isc_region_t region2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 23);
- REQUIRE(rdata1->rdclass == 1);
- 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);
-
- return (dns_name_rdatacompare(&name1, &name2));
-}
-
-static inline isc_result_t
-fromstruct_in_nsap_ptr(ARGS_FROMSTRUCT) {
- dns_rdata_in_nsap_ptr_t *nsap_ptr = source;
- isc_region_t region;
-
- REQUIRE(type == 23);
- REQUIRE(rdclass == 1);
- REQUIRE(source != NULL);
- REQUIRE(nsap_ptr->common.rdtype == type);
- REQUIRE(nsap_ptr->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_name_toregion(&nsap_ptr->owner, &region);
- return (isc_buffer_copyregion(target, &region));
-}
-
-static inline isc_result_t
-tostruct_in_nsap_ptr(ARGS_TOSTRUCT) {
- isc_region_t region;
- dns_rdata_in_nsap_ptr_t *nsap_ptr = target;
- dns_name_t name;
-
- REQUIRE(rdata->type == 23);
- REQUIRE(rdata->rdclass == 1);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- nsap_ptr->common.rdclass = rdata->rdclass;
- nsap_ptr->common.rdtype = rdata->type;
- ISC_LINK_INIT(&nsap_ptr->common, link);
-
- dns_name_init(&name, NULL);
- dns_rdata_toregion(rdata, &region);
- dns_name_fromregion(&name, &region);
- dns_name_init(&nsap_ptr->owner, NULL);
- RETERR(name_duporclone(&name, mctx, &nsap_ptr->owner));
- nsap_ptr->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_in_nsap_ptr(ARGS_FREESTRUCT) {
- dns_rdata_in_nsap_ptr_t *nsap_ptr = source;
-
- REQUIRE(source != NULL);
- REQUIRE(nsap_ptr->common.rdclass == 1);
- REQUIRE(nsap_ptr->common.rdtype == 23);
-
- if (nsap_ptr->mctx == NULL)
- return;
-
- dns_name_free(&nsap_ptr->owner, nsap_ptr->mctx);
- nsap_ptr->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_in_nsap_ptr(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 23);
- REQUIRE(rdata->rdclass == 1);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_in_nsap_ptr(ARGS_DIGEST) {
- isc_region_t r;
- dns_name_t name;
-
- REQUIRE(rdata->type == 23);
- REQUIRE(rdata->rdclass == 1);
-
- dns_rdata_toregion(rdata, &r);
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &r);
-
- return (dns_name_digest(&name, digest, arg));
-}
-
-static inline isc_boolean_t
-checkowner_in_nsap_ptr(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 23);
- REQUIRE(rdclass == 1);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_in_nsap_ptr(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 23);
- REQUIRE(rdata->rdclass == 1);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- 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/contrib/bind9/lib/dns/rdata/in_1/nsap-ptr_23.h b/contrib/bind9/lib/dns/rdata/in_1/nsap-ptr_23.h
deleted file mode 100644
index 14a8b19559af..000000000000
--- a/contrib/bind9/lib/dns/rdata/in_1/nsap-ptr_23.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef IN_1_NSAP_PTR_23_H
-#define IN_1_NSAP_PTR_23_H 1
-
-/* $Id: nsap-ptr_23.h,v 1.19 2007/06/19 23:47:17 tbox Exp $ */
-
-/*!
- * \brief Per RFC1348. Obsoleted in RFC 1706 - use PTR instead. */
-
-typedef struct dns_rdata_in_nsap_ptr {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- dns_name_t owner;
-} dns_rdata_in_nsap_ptr_t;
-
-#endif /* IN_1_NSAP_PTR_23_H */
diff --git a/contrib/bind9/lib/dns/rdata/in_1/nsap_22.c b/contrib/bind9/lib/dns/rdata/in_1/nsap_22.c
deleted file mode 100644
index 66129fe0fdfa..000000000000
--- a/contrib/bind9/lib/dns/rdata/in_1/nsap_22.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007, 2009, 2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2002 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $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 */
-
-/* RFC1706 */
-
-#ifndef RDATA_IN_1_NSAP_22_C
-#define RDATA_IN_1_NSAP_22_C
-
-#define RRTYPE_NSAP_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_in_nsap(ARGS_FROMTEXT) {
- isc_token_t token;
- isc_textregion_t *sr;
- int n;
- int digits;
- unsigned char c = 0;
-
- REQUIRE(type == 22);
- REQUIRE(rdclass == 1);
-
- UNUSED(type);
- UNUSED(origin);
- UNUSED(options);
- UNUSED(rdclass);
- UNUSED(callbacks);
-
- /* 0x<hex.string.with.periods> */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- sr = &token.value.as_textregion;
- if (sr->length < 2)
- RETTOK(ISC_R_UNEXPECTEDEND);
- if (sr->base[0] != '0' || (sr->base[1] != 'x' && sr->base[1] != 'X'))
- RETTOK(DNS_R_SYNTAX);
- isc_textregion_consume(sr, 2);
- digits = 0;
- while (sr->length > 0) {
- if (sr->base[0] == '.') {
- isc_textregion_consume(sr, 1);
- continue;
- }
- if ((n = hexvalue(sr->base[0])) == -1)
- RETTOK(DNS_R_SYNTAX);
- c <<= 4;
- c += n;
- if (++digits == 2) {
- RETERR(mem_tobuffer(target, &c, 1));
- digits = 0;
- }
- isc_textregion_consume(sr, 1);
- }
- if (digits)
- RETTOK(ISC_R_UNEXPECTEDEND);
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_in_nsap(ARGS_TOTEXT) {
- isc_region_t region;
- char buf[sizeof("xx")];
-
- REQUIRE(rdata->type == 22);
- REQUIRE(rdata->rdclass == 1);
- REQUIRE(rdata->length != 0);
-
- UNUSED(tctx);
-
- dns_rdata_toregion(rdata, &region);
- RETERR(str_totext("0x", target));
- while (region.length != 0) {
- sprintf(buf, "%02x", region.base[0]);
- isc_region_consume(&region, 1);
- RETERR(str_totext(buf, target));
- }
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-fromwire_in_nsap(ARGS_FROMWIRE) {
- isc_region_t region;
-
- REQUIRE(type == 22);
- REQUIRE(rdclass == 1);
-
- UNUSED(type);
- UNUSED(dctx);
- UNUSED(options);
- UNUSED(rdclass);
-
- isc_buffer_activeregion(source, &region);
- if (region.length < 1)
- return (ISC_R_UNEXPECTEDEND);
-
- RETERR(mem_tobuffer(target, region.base, region.length));
- isc_buffer_forward(source, region.length);
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-towire_in_nsap(ARGS_TOWIRE) {
- REQUIRE(rdata->type == 22);
- REQUIRE(rdata->rdclass == 1);
- REQUIRE(rdata->length != 0);
-
- UNUSED(cctx);
-
- return (mem_tobuffer(target, rdata->data, rdata->length));
-}
-
-static inline int
-compare_in_nsap(ARGS_COMPARE) {
- isc_region_t r1;
- isc_region_t r2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 22);
- REQUIRE(rdata1->rdclass == 1);
- 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_in_nsap(ARGS_FROMSTRUCT) {
- dns_rdata_in_nsap_t *nsap = source;
-
- REQUIRE(type == 22);
- REQUIRE(rdclass == 1);
- REQUIRE(source != NULL);
- REQUIRE(nsap->common.rdtype == type);
- REQUIRE(nsap->common.rdclass == rdclass);
- REQUIRE(nsap->nsap != NULL || nsap->nsap_len == 0);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- return (mem_tobuffer(target, nsap->nsap, nsap->nsap_len));
-}
-
-static inline isc_result_t
-tostruct_in_nsap(ARGS_TOSTRUCT) {
- dns_rdata_in_nsap_t *nsap = target;
- isc_region_t r;
-
- REQUIRE(rdata->type == 22);
- REQUIRE(rdata->rdclass == 1);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- nsap->common.rdclass = rdata->rdclass;
- nsap->common.rdtype = rdata->type;
- ISC_LINK_INIT(&nsap->common, link);
-
- dns_rdata_toregion(rdata, &r);
- nsap->nsap_len = r.length;
- nsap->nsap = mem_maybedup(mctx, r.base, r.length);
- if (nsap->nsap == NULL)
- return (ISC_R_NOMEMORY);
-
- nsap->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_in_nsap(ARGS_FREESTRUCT) {
- dns_rdata_in_nsap_t *nsap = source;
-
- REQUIRE(source != NULL);
- REQUIRE(nsap->common.rdclass == 1);
- REQUIRE(nsap->common.rdtype == 22);
-
- if (nsap->mctx == NULL)
- return;
-
- if (nsap->nsap != NULL)
- isc_mem_free(nsap->mctx, nsap->nsap);
- nsap->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_in_nsap(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 22);
- REQUIRE(rdata->rdclass == 1);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_in_nsap(ARGS_DIGEST) {
- isc_region_t r;
-
- REQUIRE(rdata->type == 22);
- REQUIRE(rdata->rdclass == 1);
-
- dns_rdata_toregion(rdata, &r);
-
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_in_nsap(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 22);
- REQUIRE(rdclass == 1);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_in_nsap(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 22);
- REQUIRE(rdata->rdclass == 1);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- 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/contrib/bind9/lib/dns/rdata/in_1/nsap_22.h b/contrib/bind9/lib/dns/rdata/in_1/nsap_22.h
deleted file mode 100644
index 11e3f66ce8d8..000000000000
--- a/contrib/bind9/lib/dns/rdata/in_1/nsap_22.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef IN_1_NSAP_22_H
-#define IN_1_NSAP_22_H 1
-
-/* $Id: nsap_22.h,v 1.18 2007/06/19 23:47:17 tbox Exp $ */
-
-/*!
- * \brief Per RFC1706 */
-
-typedef struct dns_rdata_in_nsap {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- unsigned char *nsap;
- isc_uint16_t nsap_len;
-} dns_rdata_in_nsap_t;
-
-#endif /* IN_1_NSAP_22_H */
diff --git a/contrib/bind9/lib/dns/rdata/in_1/px_26.c b/contrib/bind9/lib/dns/rdata/in_1/px_26.c
deleted file mode 100644
index a4111ad5bb76..000000000000
--- a/contrib/bind9/lib/dns/rdata/in_1/px_26.c
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: px_26.c,v 1.45 2009/12/04 22:06:37 tbox Exp $ */
-
-/* Reviewed: Mon Mar 20 10:44:27 PST 2000 */
-
-/* RFC2163 */
-
-#ifndef RDATA_IN_1_PX_26_C
-#define RDATA_IN_1_PX_26_C
-
-#define RRTYPE_PX_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_in_px(ARGS_FROMTEXT) {
- isc_token_t token;
- dns_name_t name;
- isc_buffer_t buffer;
-
- REQUIRE(type == 26);
- REQUIRE(rdclass == 1);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(callbacks);
-
- /*
- * Preference.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if (token.value.as_ulong > 0xffffU)
- RETTOK(ISC_R_RANGE);
- RETERR(uint16_tobuffer(token.value.as_ulong, target));
-
- /*
- * MAP822.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- dns_name_init(&name, NULL);
- buffer_fromregion(&buffer, &token.value.as_region);
- origin = (origin != NULL) ? origin : dns_rootname;
- RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
-
- /*
- * MAPX400.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- dns_name_init(&name, NULL);
- buffer_fromregion(&buffer, &token.value.as_region);
- origin = (origin != NULL) ? origin : dns_rootname;
- RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_in_px(ARGS_TOTEXT) {
- isc_region_t region;
- dns_name_t name;
- dns_name_t prefix;
- isc_boolean_t sub;
- char buf[sizeof("64000")];
- unsigned short num;
-
- REQUIRE(rdata->type == 26);
- REQUIRE(rdata->rdclass == 1);
- REQUIRE(rdata->length != 0);
-
- dns_name_init(&name, NULL);
- dns_name_init(&prefix, NULL);
-
- /*
- * Preference.
- */
- dns_rdata_toregion(rdata, &region);
- num = uint16_fromregion(&region);
- isc_region_consume(&region, 2);
- sprintf(buf, "%u", num);
- RETERR(str_totext(buf, target));
- RETERR(str_totext(" ", target));
-
- /*
- * MAP822.
- */
- dns_name_fromregion(&name, &region);
- sub = name_prefix(&name, tctx->origin, &prefix);
- isc_region_consume(&region, name_length(&name));
- RETERR(dns_name_totext(&prefix, sub, target));
- RETERR(str_totext(" ", target));
-
- /*
- * MAPX400.
- */
- dns_name_fromregion(&name, &region);
- sub = name_prefix(&name, tctx->origin, &prefix);
- return(dns_name_totext(&prefix, sub, target));
-}
-
-static inline isc_result_t
-fromwire_in_px(ARGS_FROMWIRE) {
- dns_name_t name;
- isc_region_t sregion;
-
- REQUIRE(type == 26);
- REQUIRE(rdclass == 1);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
-
- dns_name_init(&name, NULL);
-
- /*
- * Preference.
- */
- isc_buffer_activeregion(source, &sregion);
- if (sregion.length < 2)
- return (ISC_R_UNEXPECTEDEND);
- RETERR(mem_tobuffer(target, sregion.base, 2));
- isc_buffer_forward(source, 2);
-
- /*
- * MAP822.
- */
- RETERR(dns_name_fromwire(&name, source, dctx, options, target));
-
- /*
- * MAPX400.
- */
- return (dns_name_fromwire(&name, source, dctx, options, target));
-}
-
-static inline isc_result_t
-towire_in_px(ARGS_TOWIRE) {
- dns_name_t name;
- dns_offsets_t offsets;
- isc_region_t region;
-
- REQUIRE(rdata->type == 26);
- REQUIRE(rdata->rdclass == 1);
- REQUIRE(rdata->length != 0);
-
- dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
- /*
- * Preference.
- */
- dns_rdata_toregion(rdata, &region);
- RETERR(mem_tobuffer(target, region.base, 2));
- isc_region_consume(&region, 2);
-
- /*
- * MAP822.
- */
- dns_name_init(&name, offsets);
- dns_name_fromregion(&name, &region);
- RETERR(dns_name_towire(&name, cctx, target));
- isc_region_consume(&region, name_length(&name));
-
- /*
- * MAPX400.
- */
- dns_name_init(&name, offsets);
- dns_name_fromregion(&name, &region);
- return (dns_name_towire(&name, cctx, target));
-}
-
-static inline int
-compare_in_px(ARGS_COMPARE) {
- dns_name_t name1;
- dns_name_t name2;
- isc_region_t region1;
- isc_region_t region2;
- int order;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 26);
- REQUIRE(rdata1->rdclass == 1);
- REQUIRE(rdata1->length != 0);
- REQUIRE(rdata2->length != 0);
-
- order = memcmp(rdata1->data, rdata2->data, 2);
- if (order != 0)
- return (order < 0 ? -1 : 1);
-
- dns_name_init(&name1, NULL);
- dns_name_init(&name2, NULL);
-
- dns_rdata_toregion(rdata1, &region1);
- dns_rdata_toregion(rdata2, &region2);
-
- isc_region_consume(&region1, 2);
- isc_region_consume(&region2, 2);
-
- 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));
-
- dns_name_fromregion(&name1, &region1);
- dns_name_fromregion(&name2, &region2);
-
- return (dns_name_rdatacompare(&name1, &name2));
-}
-
-static inline isc_result_t
-fromstruct_in_px(ARGS_FROMSTRUCT) {
- dns_rdata_in_px_t *px = source;
- isc_region_t region;
-
- REQUIRE(type == 26);
- REQUIRE(rdclass == 1);
- REQUIRE(source != NULL);
- REQUIRE(px->common.rdtype == type);
- REQUIRE(px->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- RETERR(uint16_tobuffer(px->preference, target));
- dns_name_toregion(&px->map822, &region);
- RETERR(isc_buffer_copyregion(target, &region));
- dns_name_toregion(&px->mapx400, &region);
- return (isc_buffer_copyregion(target, &region));
-}
-
-static inline isc_result_t
-tostruct_in_px(ARGS_TOSTRUCT) {
- dns_rdata_in_px_t *px = target;
- dns_name_t name;
- isc_region_t region;
- isc_result_t result;
-
- REQUIRE(rdata->type == 26);
- REQUIRE(rdata->rdclass == 1);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- px->common.rdclass = rdata->rdclass;
- px->common.rdtype = rdata->type;
- ISC_LINK_INIT(&px->common, link);
-
- dns_name_init(&name, NULL);
- dns_rdata_toregion(rdata, &region);
-
- px->preference = uint16_fromregion(&region);
- isc_region_consume(&region, 2);
-
- dns_name_fromregion(&name, &region);
-
- dns_name_init(&px->map822, NULL);
- RETERR(name_duporclone(&name, mctx, &px->map822));
- isc_region_consume(&region, name_length(&px->map822));
-
- dns_name_init(&px->mapx400, NULL);
- result = name_duporclone(&name, mctx, &px->mapx400);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- px->mctx = mctx;
- return (result);
-
- cleanup:
- dns_name_free(&px->map822, mctx);
- return (ISC_R_NOMEMORY);
-}
-
-static inline void
-freestruct_in_px(ARGS_FREESTRUCT) {
- dns_rdata_in_px_t *px = source;
-
- REQUIRE(source != NULL);
- REQUIRE(px->common.rdclass == 1);
- REQUIRE(px->common.rdtype == 26);
-
- if (px->mctx == NULL)
- return;
-
- dns_name_free(&px->map822, px->mctx);
- dns_name_free(&px->mapx400, px->mctx);
- px->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_in_px(ARGS_ADDLDATA) {
- REQUIRE(rdata->type == 26);
- REQUIRE(rdata->rdclass == 1);
-
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_in_px(ARGS_DIGEST) {
- isc_region_t r1, r2;
- dns_name_t name;
- isc_result_t result;
-
- REQUIRE(rdata->type == 26);
- REQUIRE(rdata->rdclass == 1);
-
- dns_rdata_toregion(rdata, &r1);
- r2 = r1;
- isc_region_consume(&r2, 2);
- r1.length = 2;
- result = (digest)(arg, &r1);
- if (result != ISC_R_SUCCESS)
- return (result);
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &r2);
- result = dns_name_digest(&name, digest, arg);
- if (result != ISC_R_SUCCESS)
- return (result);
- isc_region_consume(&r2, name_length(&name));
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &r2);
-
- return (dns_name_digest(&name, digest, arg));
-}
-
-static inline isc_boolean_t
-checkowner_in_px(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 26);
- REQUIRE(rdclass == 1);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_in_px(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 26);
- REQUIRE(rdata->rdclass == 1);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- 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/contrib/bind9/lib/dns/rdata/in_1/px_26.h b/contrib/bind9/lib/dns/rdata/in_1/px_26.h
deleted file mode 100644
index 69a7baedff67..000000000000
--- a/contrib/bind9/lib/dns/rdata/in_1/px_26.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef IN_1_PX_26_H
-#define IN_1_PX_26_H 1
-
-/* $Id: px_26.h,v 1.19 2007/06/19 23:47:17 tbox Exp $ */
-
-/*!
- * \brief Per RFC2163 */
-
-typedef struct dns_rdata_in_px {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- isc_uint16_t preference;
- dns_name_t map822;
- dns_name_t mapx400;
-} dns_rdata_in_px_t;
-
-#endif /* IN_1_PX_26_H */
diff --git a/contrib/bind9/lib/dns/rdata/in_1/srv_33.c b/contrib/bind9/lib/dns/rdata/in_1/srv_33.c
deleted file mode 100644
index ea4f3edbcdef..000000000000
--- a/contrib/bind9/lib/dns/rdata/in_1/srv_33.c
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $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 */
-
-/* RFC2782 */
-
-#ifndef RDATA_IN_1_SRV_33_C
-#define RDATA_IN_1_SRV_33_C
-
-#define RRTYPE_SRV_ATTRIBUTES (0)
-
-static inline isc_result_t
-fromtext_in_srv(ARGS_FROMTEXT) {
- isc_token_t token;
- dns_name_t name;
- isc_buffer_t buffer;
- isc_boolean_t ok;
-
- REQUIRE(type == 33);
- REQUIRE(rdclass == 1);
-
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(callbacks);
-
- /*
- * Priority.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if (token.value.as_ulong > 0xffffU)
- RETTOK(ISC_R_RANGE);
- RETERR(uint16_tobuffer(token.value.as_ulong, target));
-
- /*
- * Weight.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if (token.value.as_ulong > 0xffffU)
- RETTOK(ISC_R_RANGE);
- RETERR(uint16_tobuffer(token.value.as_ulong, target));
-
- /*
- * Port.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE));
- if (token.value.as_ulong > 0xffffU)
- RETTOK(ISC_R_RANGE);
- RETERR(uint16_tobuffer(token.value.as_ulong, target));
-
- /*
- * Target.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
- dns_name_init(&name, NULL);
- buffer_fromregion(&buffer, &token.value.as_region);
- origin = (origin != NULL) ? origin : dns_rootname;
- RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
- ok = ISC_TRUE;
- if ((options & DNS_RDATA_CHECKNAMES) != 0)
- ok = dns_name_ishostname(&name, ISC_FALSE);
- if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0)
- RETTOK(DNS_R_BADNAME);
- if (!ok && callbacks != NULL)
- warn_badname(&name, lexer, callbacks);
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-totext_in_srv(ARGS_TOTEXT) {
- isc_region_t region;
- dns_name_t name;
- dns_name_t prefix;
- isc_boolean_t sub;
- char buf[sizeof("64000")];
- unsigned short num;
-
- REQUIRE(rdata->type == 33);
- REQUIRE(rdata->rdclass == 1);
- REQUIRE(rdata->length != 0);
-
- dns_name_init(&name, NULL);
- dns_name_init(&prefix, NULL);
-
- /*
- * Priority.
- */
- dns_rdata_toregion(rdata, &region);
- num = uint16_fromregion(&region);
- isc_region_consume(&region, 2);
- sprintf(buf, "%u", num);
- RETERR(str_totext(buf, target));
- RETERR(str_totext(" ", target));
-
- /*
- * Weight.
- */
- num = uint16_fromregion(&region);
- isc_region_consume(&region, 2);
- sprintf(buf, "%u", num);
- RETERR(str_totext(buf, target));
- RETERR(str_totext(" ", target));
-
- /*
- * Port.
- */
- num = uint16_fromregion(&region);
- isc_region_consume(&region, 2);
- sprintf(buf, "%u", num);
- RETERR(str_totext(buf, target));
- RETERR(str_totext(" ", target));
-
- /*
- * Target.
- */
- dns_name_fromregion(&name, &region);
- sub = name_prefix(&name, tctx->origin, &prefix);
- return (dns_name_totext(&prefix, sub, target));
-}
-
-static inline isc_result_t
-fromwire_in_srv(ARGS_FROMWIRE) {
- dns_name_t name;
- isc_region_t sr;
-
- REQUIRE(type == 33);
- REQUIRE(rdclass == 1);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
-
- dns_name_init(&name, NULL);
-
- /*
- * Priority, weight, port.
- */
- isc_buffer_activeregion(source, &sr);
- if (sr.length < 6)
- return (ISC_R_UNEXPECTEDEND);
- RETERR(mem_tobuffer(target, sr.base, 6));
- isc_buffer_forward(source, 6);
-
- /*
- * Target.
- */
- return (dns_name_fromwire(&name, source, dctx, options, target));
-}
-
-static inline isc_result_t
-towire_in_srv(ARGS_TOWIRE) {
- dns_name_t name;
- dns_offsets_t offsets;
- isc_region_t sr;
-
- REQUIRE(rdata->type == 33);
- REQUIRE(rdata->length != 0);
-
- dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
- /*
- * Priority, weight, port.
- */
- dns_rdata_toregion(rdata, &sr);
- RETERR(mem_tobuffer(target, sr.base, 6));
- isc_region_consume(&sr, 6);
-
- /*
- * Target.
- */
- dns_name_init(&name, offsets);
- dns_name_fromregion(&name, &sr);
- return (dns_name_towire(&name, cctx, target));
-}
-
-static inline int
-compare_in_srv(ARGS_COMPARE) {
- dns_name_t name1;
- dns_name_t name2;
- isc_region_t region1;
- isc_region_t region2;
- int order;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 33);
- REQUIRE(rdata1->rdclass == 1);
- REQUIRE(rdata1->length != 0);
- REQUIRE(rdata2->length != 0);
-
- /*
- * Priority, weight, port.
- */
- order = memcmp(rdata1->data, rdata2->data, 6);
- if (order != 0)
- return (order < 0 ? -1 : 1);
-
- /*
- * Target.
- */
- dns_name_init(&name1, NULL);
- dns_name_init(&name2, NULL);
-
- dns_rdata_toregion(rdata1, &region1);
- dns_rdata_toregion(rdata2, &region2);
-
- isc_region_consume(&region1, 6);
- isc_region_consume(&region2, 6);
-
- dns_name_fromregion(&name1, &region1);
- dns_name_fromregion(&name2, &region2);
-
- return (dns_name_rdatacompare(&name1, &name2));
-}
-
-static inline isc_result_t
-fromstruct_in_srv(ARGS_FROMSTRUCT) {
- dns_rdata_in_srv_t *srv = source;
- isc_region_t region;
-
- REQUIRE(type == 33);
- REQUIRE(rdclass == 1);
- REQUIRE(source != NULL);
- REQUIRE(srv->common.rdtype == type);
- REQUIRE(srv->common.rdclass == rdclass);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- RETERR(uint16_tobuffer(srv->priority, target));
- RETERR(uint16_tobuffer(srv->weight, target));
- RETERR(uint16_tobuffer(srv->port, target));
- dns_name_toregion(&srv->target, &region);
- return (isc_buffer_copyregion(target, &region));
-}
-
-static inline isc_result_t
-tostruct_in_srv(ARGS_TOSTRUCT) {
- isc_region_t region;
- dns_rdata_in_srv_t *srv = target;
- dns_name_t name;
-
- REQUIRE(rdata->rdclass == 1);
- REQUIRE(rdata->type == 33);
- REQUIRE(target != NULL);
- REQUIRE(rdata->length != 0);
-
- srv->common.rdclass = rdata->rdclass;
- srv->common.rdtype = rdata->type;
- ISC_LINK_INIT(&srv->common, link);
-
- dns_name_init(&name, NULL);
- dns_rdata_toregion(rdata, &region);
- srv->priority = uint16_fromregion(&region);
- isc_region_consume(&region, 2);
- srv->weight = uint16_fromregion(&region);
- isc_region_consume(&region, 2);
- srv->port = uint16_fromregion(&region);
- isc_region_consume(&region, 2);
- dns_name_fromregion(&name, &region);
- dns_name_init(&srv->target, NULL);
- RETERR(name_duporclone(&name, mctx, &srv->target));
- srv->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_in_srv(ARGS_FREESTRUCT) {
- dns_rdata_in_srv_t *srv = source;
-
- REQUIRE(source != NULL);
- REQUIRE(srv->common.rdclass == 1);
- REQUIRE(srv->common.rdtype == 33);
-
- if (srv->mctx == NULL)
- return;
-
- dns_name_free(&srv->target, srv->mctx);
- srv->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_in_srv(ARGS_ADDLDATA) {
- dns_name_t name;
- dns_offsets_t offsets;
- isc_region_t region;
-
- REQUIRE(rdata->type == 33);
- REQUIRE(rdata->rdclass == 1);
-
- dns_name_init(&name, offsets);
- dns_rdata_toregion(rdata, &region);
- isc_region_consume(&region, 6);
- dns_name_fromregion(&name, &region);
-
- return ((add)(arg, &name, dns_rdatatype_a));
-}
-
-static inline isc_result_t
-digest_in_srv(ARGS_DIGEST) {
- isc_region_t r1, r2;
- dns_name_t name;
-
- REQUIRE(rdata->type == 33);
- REQUIRE(rdata->rdclass == 1);
-
- dns_rdata_toregion(rdata, &r1);
- r2 = r1;
- isc_region_consume(&r2, 6);
- r1.length = 6;
- RETERR((digest)(arg, &r1));
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &r2);
- return (dns_name_digest(&name, digest, arg));
-}
-
-static inline isc_boolean_t
-checkowner_in_srv(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 33);
- REQUIRE(rdclass == 1);
-
- UNUSED(name);
- UNUSED(type);
- UNUSED(rdclass);
- UNUSED(wildcard);
-
- return (ISC_TRUE);
-}
-
-static inline isc_boolean_t
-checknames_in_srv(ARGS_CHECKNAMES) {
- isc_region_t region;
- dns_name_t name;
-
- REQUIRE(rdata->type == 33);
- REQUIRE(rdata->rdclass == 1);
-
- UNUSED(owner);
-
- dns_rdata_toregion(rdata, &region);
- isc_region_consume(&region, 6);
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &region);
- if (!dns_name_ishostname(&name, ISC_FALSE)) {
- if (bad != NULL)
- dns_name_clone(&name, bad);
- return (ISC_FALSE);
- }
- 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/contrib/bind9/lib/dns/rdata/in_1/srv_33.h b/contrib/bind9/lib/dns/rdata/in_1/srv_33.h
deleted file mode 100644
index e019698734de..000000000000
--- a/contrib/bind9/lib/dns/rdata/in_1/srv_33.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef IN_1_SRV_33_H
-#define IN_1_SRV_33_H 1
-
-/* $Id: srv_33.h,v 1.19 2007/06/19 23:47:17 tbox Exp $ */
-
-/* Reviewed: Fri Mar 17 13:01:00 PST 2000 by bwelling */
-
-/*!
- * \brief Per RFC2782 */
-
-typedef struct dns_rdata_in_srv {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- isc_uint16_t priority;
- isc_uint16_t weight;
- isc_uint16_t port;
- dns_name_t target;
-} dns_rdata_in_srv_t;
-
-#endif /* IN_1_SRV_33_H */
diff --git a/contrib/bind9/lib/dns/rdata/in_1/wks_11.c b/contrib/bind9/lib/dns/rdata/in_1/wks_11.c
deleted file mode 100644
index 1da2611da9b5..000000000000
--- a/contrib/bind9/lib/dns/rdata/in_1/wks_11.c
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
- * Copyright (C) 2004, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2002 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/* Reviewed: Fri Mar 17 15:01:49 PST 2000 by explorer */
-
-#ifndef RDATA_IN_1_WKS_11_C
-#define RDATA_IN_1_WKS_11_C
-
-#include <limits.h>
-#include <stdlib.h>
-
-#include <isc/net.h>
-#include <isc/netdb.h>
-#include <isc/once.h>
-
-#define RRTYPE_WKS_ATTRIBUTES (0)
-
-static isc_mutex_t wks_lock;
-
-static void init_lock(void) {
- RUNTIME_CHECK(isc_mutex_init(&wks_lock) == ISC_R_SUCCESS);
-}
-
-static isc_boolean_t
-mygetprotobyname(const char *name, long *proto) {
- struct protoent *pe;
-
- LOCK(&wks_lock);
- pe = getprotobyname(name);
- if (pe != NULL)
- *proto = pe->p_proto;
- UNLOCK(&wks_lock);
- return (ISC_TF(pe != NULL));
-}
-
-static isc_boolean_t
-mygetservbyname(const char *name, const char *proto, long *port) {
- struct servent *se;
-
- LOCK(&wks_lock);
- se = getservbyname(name, proto);
- if (se != NULL)
- *port = ntohs(se->s_port);
- UNLOCK(&wks_lock);
- return (ISC_TF(se != NULL));
-}
-
-static inline isc_result_t
-fromtext_in_wks(ARGS_FROMTEXT) {
- static isc_once_t once = ISC_ONCE_INIT;
- isc_token_t token;
- isc_region_t region;
- struct in_addr addr;
- char *e;
- long proto;
- unsigned char bm[8*1024]; /* 64k bits */
- long port;
- long maxport = -1;
- const char *ps = NULL;
- unsigned int n;
- char service[32];
- int i;
-
- REQUIRE(type == 11);
- REQUIRE(rdclass == 1);
-
- UNUSED(type);
- UNUSED(origin);
- UNUSED(options);
- UNUSED(rdclass);
-
- RUNTIME_CHECK(isc_once_do(&once, init_lock) == ISC_R_SUCCESS);
-
- /*
- * IPv4 dotted quad.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
-
- isc_buffer_availableregion(target, &region);
- if (getquad(DNS_AS_STR(token), &addr, lexer, callbacks) != 1)
- RETTOK(DNS_R_BADDOTTEDQUAD);
- if (region.length < 4)
- return (ISC_R_NOSPACE);
- memcpy(region.base, &addr, 4);
- isc_buffer_add(target, 4);
-
- /*
- * Protocol.
- */
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
- ISC_FALSE));
-
- proto = strtol(DNS_AS_STR(token), &e, 10);
- if (*e == 0)
- ;
- else if (!mygetprotobyname(DNS_AS_STR(token), &proto))
- RETTOK(DNS_R_UNKNOWNPROTO);
-
- if (proto < 0 || proto > 0xff)
- RETTOK(ISC_R_RANGE);
-
- if (proto == IPPROTO_TCP)
- ps = "tcp";
- else if (proto == IPPROTO_UDP)
- ps = "udp";
-
- RETERR(uint8_tobuffer(proto, target));
-
- memset(bm, 0, sizeof(bm));
- do {
- RETERR(isc_lex_getmastertoken(lexer, &token,
- isc_tokentype_string, ISC_TRUE));
- if (token.type != isc_tokentype_string)
- break;
-
- /*
- * Lowercase the service string as some getservbyname() are
- * case sensitive and the database is usually in lowercase.
- */
- strncpy(service, DNS_AS_STR(token), sizeof(service));
- service[sizeof(service)-1] = '\0';
- for (i = strlen(service) - 1; i >= 0; i--)
- if (isupper(service[i]&0xff))
- service[i] = tolower(service[i]&0xff);
-
- port = strtol(DNS_AS_STR(token), &e, 10);
- if (*e == 0)
- ;
- else if (!mygetservbyname(service, ps, &port) &&
- !mygetservbyname(DNS_AS_STR(token), ps, &port))
- RETTOK(DNS_R_UNKNOWNSERVICE);
- if (port < 0 || port > 0xffff)
- RETTOK(ISC_R_RANGE);
- if (port > maxport)
- maxport = port;
- bm[port / 8] |= (0x80 >> (port % 8));
- } while (1);
-
- /*
- * Let upper layer handle eol/eof.
- */
- isc_lex_ungettoken(lexer, &token);
-
- n = (maxport + 8) / 8;
- return (mem_tobuffer(target, bm, n));
-}
-
-static inline isc_result_t
-totext_in_wks(ARGS_TOTEXT) {
- isc_region_t sr;
- unsigned short proto;
- char buf[sizeof("65535")];
- unsigned int i, j;
-
- UNUSED(tctx);
-
- REQUIRE(rdata->type == 11);
- REQUIRE(rdata->rdclass == 1);
- REQUIRE(rdata->length >= 5);
-
- dns_rdata_toregion(rdata, &sr);
- RETERR(inet_totext(AF_INET, &sr, target));
- isc_region_consume(&sr, 4);
-
- proto = uint8_fromregion(&sr);
- sprintf(buf, "%u", proto);
- RETERR(str_totext(" ", target));
- RETERR(str_totext(buf, target));
- isc_region_consume(&sr, 1);
-
- INSIST(sr.length <= 8*1024);
- for (i = 0; i < sr.length; i++) {
- if (sr.base[i] != 0)
- for (j = 0; j < 8; j++)
- if ((sr.base[i] & (0x80 >> j)) != 0) {
- sprintf(buf, "%u", i * 8 + j);
- RETERR(str_totext(" ", target));
- RETERR(str_totext(buf, target));
- }
- }
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-fromwire_in_wks(ARGS_FROMWIRE) {
- isc_region_t sr;
- isc_region_t tr;
-
- REQUIRE(type == 11);
- REQUIRE(rdclass == 1);
-
- UNUSED(type);
- UNUSED(dctx);
- UNUSED(options);
- UNUSED(rdclass);
-
- isc_buffer_activeregion(source, &sr);
- isc_buffer_availableregion(target, &tr);
-
- if (sr.length < 5)
- return (ISC_R_UNEXPECTEDEND);
- if (sr.length > 8 * 1024 + 5)
- return (DNS_R_EXTRADATA);
- if (tr.length < sr.length)
- return (ISC_R_NOSPACE);
-
- memcpy(tr.base, sr.base, sr.length);
- isc_buffer_add(target, sr.length);
- isc_buffer_forward(source, sr.length);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-towire_in_wks(ARGS_TOWIRE) {
- isc_region_t sr;
-
- UNUSED(cctx);
-
- REQUIRE(rdata->type == 11);
- REQUIRE(rdata->rdclass == 1);
- REQUIRE(rdata->length != 0);
-
- dns_rdata_toregion(rdata, &sr);
- return (mem_tobuffer(target, sr.base, sr.length));
-}
-
-static inline int
-compare_in_wks(ARGS_COMPARE) {
- isc_region_t r1;
- isc_region_t r2;
-
- REQUIRE(rdata1->type == rdata2->type);
- REQUIRE(rdata1->rdclass == rdata2->rdclass);
- REQUIRE(rdata1->type == 11);
- REQUIRE(rdata1->rdclass == 1);
- 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_in_wks(ARGS_FROMSTRUCT) {
- dns_rdata_in_wks_t *wks = source;
- isc_uint32_t a;
-
- REQUIRE(type == 11);
- REQUIRE(rdclass == 1);
- REQUIRE(source != NULL);
- REQUIRE(wks->common.rdtype == type);
- REQUIRE(wks->common.rdclass == rdclass);
- REQUIRE((wks->map != NULL && wks->map_len <= 8*1024) ||
- wks->map_len == 0);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- a = ntohl(wks->in_addr.s_addr);
- RETERR(uint32_tobuffer(a, target));
- RETERR(uint16_tobuffer(wks->protocol, target));
- return (mem_tobuffer(target, wks->map, wks->map_len));
-}
-
-static inline isc_result_t
-tostruct_in_wks(ARGS_TOSTRUCT) {
- dns_rdata_in_wks_t *wks = target;
- isc_uint32_t n;
- isc_region_t region;
-
- REQUIRE(rdata->type == 11);
- REQUIRE(rdata->rdclass == 1);
- REQUIRE(rdata->length != 0);
-
- wks->common.rdclass = rdata->rdclass;
- wks->common.rdtype = rdata->type;
- ISC_LINK_INIT(&wks->common, link);
-
- dns_rdata_toregion(rdata, &region);
- n = uint32_fromregion(&region);
- wks->in_addr.s_addr = htonl(n);
- isc_region_consume(&region, 4);
- wks->protocol = uint16_fromregion(&region);
- isc_region_consume(&region, 2);
- wks->map_len = region.length;
- wks->map = mem_maybedup(mctx, region.base, region.length);
- if (wks->map == NULL)
- return (ISC_R_NOMEMORY);
- wks->mctx = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-freestruct_in_wks(ARGS_FREESTRUCT) {
- dns_rdata_in_wks_t *wks = source;
-
- REQUIRE(source != NULL);
- REQUIRE(wks->common.rdtype == 11);
- REQUIRE(wks->common.rdclass == 1);
-
- if (wks->mctx == NULL)
- return;
-
- if (wks->map != NULL)
- isc_mem_free(wks->mctx, wks->map);
- wks->mctx = NULL;
-}
-
-static inline isc_result_t
-additionaldata_in_wks(ARGS_ADDLDATA) {
- UNUSED(rdata);
- UNUSED(add);
- UNUSED(arg);
-
- REQUIRE(rdata->type == 11);
- REQUIRE(rdata->rdclass == 1);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-digest_in_wks(ARGS_DIGEST) {
- isc_region_t r;
-
- REQUIRE(rdata->type == 11);
- REQUIRE(rdata->rdclass == 1);
-
- dns_rdata_toregion(rdata, &r);
-
- return ((digest)(arg, &r));
-}
-
-static inline isc_boolean_t
-checkowner_in_wks(ARGS_CHECKOWNER) {
-
- REQUIRE(type == 11);
- REQUIRE(rdclass == 1);
-
- UNUSED(type);
- UNUSED(rdclass);
-
- return (dns_name_ishostname(name, wildcard));
-}
-
-static inline isc_boolean_t
-checknames_in_wks(ARGS_CHECKNAMES) {
-
- REQUIRE(rdata->type == 11);
- REQUIRE(rdata->rdclass == 1);
-
- UNUSED(rdata);
- UNUSED(owner);
- UNUSED(bad);
-
- 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/contrib/bind9/lib/dns/rdata/in_1/wks_11.h b/contrib/bind9/lib/dns/rdata/in_1/wks_11.h
deleted file mode 100644
index 2fd26e8f94b0..000000000000
--- a/contrib/bind9/lib/dns/rdata/in_1/wks_11.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef IN_1_WKS_11_H
-#define IN_1_WKS_11_H 1
-
-/* $Id: wks_11.h,v 1.22 2007/06/19 23:47:17 tbox Exp $ */
-
-typedef struct dns_rdata_in_wks {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- struct in_addr in_addr;
- isc_uint16_t protocol;
- unsigned char *map;
- isc_uint16_t map_len;
-} dns_rdata_in_wks_t;
-
-#endif /* IN_1_WKS_11_H */
diff --git a/contrib/bind9/lib/dns/rdata/rdatastructpre.h b/contrib/bind9/lib/dns/rdata/rdatastructpre.h
deleted file mode 100644
index ab7e05103efc..000000000000
--- a/contrib/bind9/lib/dns/rdata/rdatastructpre.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: rdatastructpre.h,v 1.16 2007/06/19 23:47:17 tbox Exp $ */
-
-#ifndef DNS_RDATASTRUCT_H
-#define DNS_RDATASTRUCT_H 1
-
-#include <isc/lang.h>
-#include <isc/sockaddr.h>
-
-#include <dns/name.h>
-#include <dns/types.h>
-
-ISC_LANG_BEGINDECLS
-
-typedef struct dns_rdatacommon {
- dns_rdataclass_t rdclass;
- dns_rdatatype_t rdtype;
- ISC_LINK(struct dns_rdatacommon) link;
-} dns_rdatacommon_t;
-
-#define DNS_RDATACOMMON_INIT(_data, _rdtype, _rdclass) \
- do { \
- (_data)->common.rdtype = (_rdtype); \
- (_data)->common.rdclass = (_rdclass); \
- ISC_LINK_INIT(&(_data)->common, link); \
- } while (0)
diff --git a/contrib/bind9/lib/dns/rdata/rdatastructsuf.h b/contrib/bind9/lib/dns/rdata/rdatastructsuf.h
deleted file mode 100644
index 3ba1275ed729..000000000000
--- a/contrib/bind9/lib/dns/rdata/rdatastructsuf.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: rdatastructsuf.h,v 1.10 2007/06/19 23:47:17 tbox Exp $ */
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_RDATASTRUCT_H */
diff --git a/contrib/bind9/lib/dns/rdatalist.c b/contrib/bind9/lib/dns/rdatalist.c
deleted file mode 100644
index 63d8b116cf1b..000000000000
--- a/contrib/bind9/lib/dns/rdatalist.c
+++ /dev/null
@@ -1,369 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007, 2008, 2010-2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001, 2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <stddef.h>
-
-#include <isc/util.h>
-
-#include <dns/name.h>
-#include <dns/nsec3.h>
-#include <dns/rdata.h>
-#include <dns/rdatalist.h>
-#include <dns/rdataset.h>
-
-#include "rdatalist_p.h"
-
-static dns_rdatasetmethods_t methods = {
- isc__rdatalist_disassociate,
- isc__rdatalist_first,
- isc__rdatalist_next,
- isc__rdatalist_current,
- isc__rdatalist_clone,
- isc__rdatalist_count,
- isc__rdatalist_addnoqname,
- isc__rdatalist_getnoqname,
- isc__rdatalist_addclosest,
- isc__rdatalist_getclosest,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-void
-dns_rdatalist_init(dns_rdatalist_t *rdatalist) {
-
- REQUIRE(rdatalist != NULL);
-
- /*
- * Initialize rdatalist.
- */
-
- rdatalist->rdclass = 0;
- rdatalist->type = 0;
- rdatalist->covers = 0;
- rdatalist->ttl = 0;
- ISC_LIST_INIT(rdatalist->rdata);
- ISC_LINK_INIT(rdatalist, link);
-}
-
-isc_result_t
-dns_rdatalist_tordataset(dns_rdatalist_t *rdatalist,
- dns_rdataset_t *rdataset)
-{
- /*
- * Make 'rdataset' refer to the rdata in 'rdatalist'.
- */
-
- REQUIRE(rdatalist != NULL);
- REQUIRE(DNS_RDATASET_VALID(rdataset));
- REQUIRE(! dns_rdataset_isassociated(rdataset));
-
- rdataset->methods = &methods;
- rdataset->rdclass = rdatalist->rdclass;
- rdataset->type = rdatalist->type;
- rdataset->covers = rdatalist->covers;
- rdataset->ttl = rdatalist->ttl;
- rdataset->trust = 0;
- rdataset->private1 = rdatalist;
- rdataset->private2 = NULL;
- rdataset->private3 = NULL;
- rdataset->privateuint4 = 0;
- rdataset->private5 = NULL;
-
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_rdatalist_fromrdataset(dns_rdataset_t *rdataset,
- dns_rdatalist_t **rdatalist)
-{
- REQUIRE(rdatalist != NULL && rdataset != NULL);
- *rdatalist = rdataset->private1;
-
- return (ISC_R_SUCCESS);
-}
-
-void
-isc__rdatalist_disassociate(dns_rdataset_t *rdataset) {
- UNUSED(rdataset);
-}
-
-isc_result_t
-isc__rdatalist_first(dns_rdataset_t *rdataset) {
- dns_rdatalist_t *rdatalist;
-
- rdatalist = rdataset->private1;
- rdataset->private2 = ISC_LIST_HEAD(rdatalist->rdata);
-
- if (rdataset->private2 == NULL)
- return (ISC_R_NOMORE);
-
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-isc__rdatalist_next(dns_rdataset_t *rdataset) {
- dns_rdata_t *rdata;
-
- REQUIRE(rdataset != NULL);
-
- rdata = rdataset->private2;
- if (rdata == NULL)
- return (ISC_R_NOMORE);
-
- rdataset->private2 = ISC_LIST_NEXT(rdata, link);
-
- if (rdataset->private2 == NULL)
- return (ISC_R_NOMORE);
-
- return (ISC_R_SUCCESS);
-}
-
-void
-isc__rdatalist_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
- dns_rdata_t *list_rdata;
-
- REQUIRE(rdataset != NULL);
-
- list_rdata = rdataset->private2;
- INSIST(list_rdata != NULL);
-
- dns_rdata_clone(list_rdata, rdata);
-}
-
-void
-isc__rdatalist_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
-
- REQUIRE(source != NULL);
- REQUIRE(target != NULL);
-
- *target = *source;
-
- /*
- * Reset iterator state.
- */
- target->private2 = NULL;
-}
-
-unsigned int
-isc__rdatalist_count(dns_rdataset_t *rdataset) {
- dns_rdatalist_t *rdatalist;
- dns_rdata_t *rdata;
- unsigned int count;
-
- REQUIRE(rdataset != NULL);
-
- rdatalist = rdataset->private1;
-
- count = 0;
- for (rdata = ISC_LIST_HEAD(rdatalist->rdata);
- rdata != NULL;
- rdata = ISC_LIST_NEXT(rdata, link))
- count++;
-
- return (count);
-}
-
-isc_result_t
-isc__rdatalist_addnoqname(dns_rdataset_t *rdataset, dns_name_t *name) {
- dns_rdataset_t *neg = NULL;
- dns_rdataset_t *negsig = NULL;
- dns_rdataset_t *rdset;
- dns_ttl_t ttl;
-
- REQUIRE(rdataset != NULL);
-
- for (rdset = ISC_LIST_HEAD(name->list);
- rdset != NULL;
- rdset = ISC_LIST_NEXT(rdset, link))
- {
- if (rdset->rdclass != rdataset->rdclass)
- continue;
- if (rdset->type == dns_rdatatype_nsec ||
- rdset->type == dns_rdatatype_nsec3)
- neg = rdset;
- }
- if (neg == NULL)
- return (ISC_R_NOTFOUND);
-
- for (rdset = ISC_LIST_HEAD(name->list);
- rdset != NULL;
- rdset = ISC_LIST_NEXT(rdset, link))
- {
- if (rdset->type == dns_rdatatype_rrsig &&
- rdset->covers == neg->type)
- negsig = rdset;
- }
-
- if (negsig == NULL)
- return (ISC_R_NOTFOUND);
- /*
- * Minimise ttl.
- */
- ttl = rdataset->ttl;
- if (neg->ttl < ttl)
- ttl = neg->ttl;
- if (negsig->ttl < ttl)
- ttl = negsig->ttl;
- rdataset->ttl = neg->ttl = negsig->ttl = ttl;
- rdataset->attributes |= DNS_RDATASETATTR_NOQNAME;
- rdataset->private6 = name;
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-isc__rdatalist_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name,
- dns_rdataset_t *neg, dns_rdataset_t *negsig)
-{
- dns_rdataclass_t rdclass = rdataset->rdclass;
- dns_rdataset_t *tneg = NULL;
- dns_rdataset_t *tnegsig = NULL;
- dns_name_t *noqname = rdataset->private6;
-
- REQUIRE(rdataset != NULL);
- REQUIRE((rdataset->attributes & DNS_RDATASETATTR_NOQNAME) != 0);
-
- (void)dns_name_dynamic(noqname); /* Sanity Check. */
-
- for (rdataset = ISC_LIST_HEAD(noqname->list);
- rdataset != NULL;
- rdataset = ISC_LIST_NEXT(rdataset, link))
- {
- if (rdataset->rdclass != rdclass)
- continue;
- if (rdataset->type == dns_rdatatype_nsec ||
- rdataset->type == dns_rdatatype_nsec3)
- tneg = rdataset;
- }
- if (tneg == NULL)
- return (ISC_R_NOTFOUND);
-
- for (rdataset = ISC_LIST_HEAD(noqname->list);
- rdataset != NULL;
- rdataset = ISC_LIST_NEXT(rdataset, link))
- {
- if (rdataset->type == dns_rdatatype_rrsig &&
- rdataset->covers == tneg->type)
- tnegsig = rdataset;
- }
- if (tnegsig == NULL)
- return (ISC_R_NOTFOUND);
-
- dns_name_clone(noqname, name);
- dns_rdataset_clone(tneg, neg);
- dns_rdataset_clone(tnegsig, negsig);
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-isc__rdatalist_addclosest(dns_rdataset_t *rdataset, dns_name_t *name) {
- dns_rdataset_t *neg = NULL;
- dns_rdataset_t *negsig = NULL;
- dns_rdataset_t *rdset;
- dns_ttl_t ttl;
-
- REQUIRE(rdataset != NULL);
-
- for (rdset = ISC_LIST_HEAD(name->list);
- rdset != NULL;
- rdset = ISC_LIST_NEXT(rdset, link))
- {
- if (rdset->rdclass != rdataset->rdclass)
- continue;
- if (rdset->type == dns_rdatatype_nsec ||
- rdset->type == dns_rdatatype_nsec3)
- neg = rdset;
- }
- if (neg == NULL)
- return (ISC_R_NOTFOUND);
-
- for (rdset = ISC_LIST_HEAD(name->list);
- rdset != NULL;
- rdset = ISC_LIST_NEXT(rdset, link))
- {
- if (rdset->type == dns_rdatatype_rrsig &&
- rdset->covers == neg->type)
- negsig = rdset;
- }
-
- if (negsig == NULL)
- return (ISC_R_NOTFOUND);
- /*
- * Minimise ttl.
- */
- ttl = rdataset->ttl;
- if (neg->ttl < ttl)
- ttl = neg->ttl;
- if (negsig->ttl < ttl)
- ttl = negsig->ttl;
- rdataset->ttl = neg->ttl = negsig->ttl = ttl;
- rdataset->attributes |= DNS_RDATASETATTR_CLOSEST;
- rdataset->private7 = name;
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-isc__rdatalist_getclosest(dns_rdataset_t *rdataset, dns_name_t *name,
- dns_rdataset_t *neg, dns_rdataset_t *negsig)
-{
- dns_rdataclass_t rdclass = rdataset->rdclass;
- dns_rdataset_t *tneg = NULL;
- dns_rdataset_t *tnegsig = NULL;
- dns_name_t *closest = rdataset->private7;
-
- REQUIRE(rdataset != NULL);
- REQUIRE((rdataset->attributes & DNS_RDATASETATTR_CLOSEST) != 0);
-
- (void)dns_name_dynamic(closest); /* Sanity Check. */
-
- for (rdataset = ISC_LIST_HEAD(closest->list);
- rdataset != NULL;
- rdataset = ISC_LIST_NEXT(rdataset, link))
- {
- if (rdataset->rdclass != rdclass)
- continue;
- if (rdataset->type == dns_rdatatype_nsec ||
- rdataset->type == dns_rdatatype_nsec3)
- tneg = rdataset;
- }
- if (tneg == NULL)
- return (ISC_R_NOTFOUND);
-
- for (rdataset = ISC_LIST_HEAD(closest->list);
- rdataset != NULL;
- rdataset = ISC_LIST_NEXT(rdataset, link))
- {
- if (rdataset->type == dns_rdatatype_rrsig &&
- rdataset->covers == tneg->type)
- tnegsig = rdataset;
- }
- if (tnegsig == NULL)
- return (ISC_R_NOTFOUND);
-
- dns_name_clone(closest, name);
- dns_rdataset_clone(tneg, neg);
- dns_rdataset_clone(tnegsig, negsig);
- return (ISC_R_SUCCESS);
-}
diff --git a/contrib/bind9/lib/dns/rdatalist_p.h b/contrib/bind9/lib/dns/rdatalist_p.h
deleted file mode 100644
index 3e73e20aa5ad..000000000000
--- a/contrib/bind9/lib/dns/rdatalist_p.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: rdatalist_p.h,v 1.11 2008/09/25 04:02:38 tbox Exp $ */
-
-#ifndef DNS_RDATALIST_P_H
-#define DNS_RDATALIST_P_H
-
-/*! \file */
-
-#include <isc/result.h>
-#include <dns/types.h>
-
-ISC_LANG_BEGINDECLS
-
-void
-isc__rdatalist_disassociate(dns_rdataset_t *rdatasetp);
-
-isc_result_t
-isc__rdatalist_first(dns_rdataset_t *rdataset);
-
-isc_result_t
-isc__rdatalist_next(dns_rdataset_t *rdataset);
-
-void
-isc__rdatalist_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata);
-
-void
-isc__rdatalist_clone(dns_rdataset_t *source, dns_rdataset_t *target);
-
-unsigned int
-isc__rdatalist_count(dns_rdataset_t *rdataset);
-
-isc_result_t
-isc__rdatalist_addnoqname(dns_rdataset_t *rdataset, dns_name_t *name);
-
-isc_result_t
-isc__rdatalist_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name,
- dns_rdataset_t *neg, dns_rdataset_t *negsig);
-
-isc_result_t
-isc__rdatalist_addclosest(dns_rdataset_t *rdataset, dns_name_t *name);
-
-isc_result_t
-isc__rdatalist_getclosest(dns_rdataset_t *rdataset, dns_name_t *name,
- dns_rdataset_t *neg, dns_rdataset_t *negsig);
-
-ISC_LANG_ENDDECLS
-
-#endif /* DNS_RDATALIST_P_H */
diff --git a/contrib/bind9/lib/dns/rdataset.c b/contrib/bind9/lib/dns/rdataset.c
deleted file mode 100644
index 026d771235cc..000000000000
--- a/contrib/bind9/lib/dns/rdataset.c
+++ /dev/null
@@ -1,802 +0,0 @@
-/*
- * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <stdlib.h>
-
-#include <isc/buffer.h>
-#include <isc/mem.h>
-#include <isc/random.h>
-#include <isc/serial.h>
-#include <isc/util.h>
-
-#include <dns/name.h>
-#include <dns/ncache.h>
-#include <dns/rdata.h>
-#include <dns/rdataset.h>
-#include <dns/compress.h>
-
-static const char *trustnames[] = {
- "none",
- "pending-additional",
- "pending-answer",
- "additional",
- "glue",
- "answer",
- "authauthority",
- "authanswer",
- "secure",
- "local" /* aka ultimate */
-};
-
-const char *
-dns_trust_totext(dns_trust_t trust) {
- if (trust >= sizeof(trustnames)/sizeof(*trustnames))
- return ("bad");
- return (trustnames[trust]);
-}
-
-void
-dns_rdataset_init(dns_rdataset_t *rdataset) {
-
- /*
- * Make 'rdataset' a valid, disassociated rdataset.
- */
-
- REQUIRE(rdataset != NULL);
-
- rdataset->magic = DNS_RDATASET_MAGIC;
- rdataset->methods = NULL;
- ISC_LINK_INIT(rdataset, link);
- rdataset->rdclass = 0;
- rdataset->type = 0;
- rdataset->ttl = 0;
- rdataset->trust = 0;
- rdataset->covers = 0;
- rdataset->attributes = 0;
- rdataset->count = ISC_UINT32_MAX;
- rdataset->private1 = NULL;
- rdataset->private2 = NULL;
- rdataset->private3 = NULL;
- rdataset->privateuint4 = 0;
- rdataset->private5 = NULL;
- rdataset->private6 = NULL;
- rdataset->resign = 0;
-}
-
-void
-dns_rdataset_invalidate(dns_rdataset_t *rdataset) {
-
- /*
- * Invalidate 'rdataset'.
- */
-
- REQUIRE(DNS_RDATASET_VALID(rdataset));
- REQUIRE(rdataset->methods == NULL);
-
- rdataset->magic = 0;
- ISC_LINK_INIT(rdataset, link);
- rdataset->rdclass = 0;
- rdataset->type = 0;
- rdataset->ttl = 0;
- rdataset->trust = 0;
- rdataset->covers = 0;
- rdataset->attributes = 0;
- rdataset->count = ISC_UINT32_MAX;
- rdataset->private1 = NULL;
- rdataset->private2 = NULL;
- rdataset->private3 = NULL;
- rdataset->privateuint4 = 0;
- rdataset->private5 = NULL;
-}
-
-void
-dns_rdataset_disassociate(dns_rdataset_t *rdataset) {
-
- /*
- * Disassociate 'rdataset' from its rdata, allowing it to be reused.
- */
-
- REQUIRE(DNS_RDATASET_VALID(rdataset));
- REQUIRE(rdataset->methods != NULL);
-
- (rdataset->methods->disassociate)(rdataset);
- rdataset->methods = NULL;
- ISC_LINK_INIT(rdataset, link);
- rdataset->rdclass = 0;
- rdataset->type = 0;
- rdataset->ttl = 0;
- rdataset->trust = 0;
- rdataset->covers = 0;
- rdataset->attributes = 0;
- rdataset->count = ISC_UINT32_MAX;
- rdataset->private1 = NULL;
- rdataset->private2 = NULL;
- rdataset->private3 = NULL;
- rdataset->privateuint4 = 0;
- rdataset->private5 = NULL;
- rdataset->private6 = NULL;
-}
-
-isc_boolean_t
-dns_rdataset_isassociated(dns_rdataset_t *rdataset) {
- /*
- * Is 'rdataset' associated?
- */
-
- REQUIRE(DNS_RDATASET_VALID(rdataset));
-
- if (rdataset->methods != NULL)
- return (ISC_TRUE);
-
- return (ISC_FALSE);
-}
-
-static void
-question_disassociate(dns_rdataset_t *rdataset) {
- UNUSED(rdataset);
-}
-
-static isc_result_t
-question_cursor(dns_rdataset_t *rdataset) {
- UNUSED(rdataset);
-
- return (ISC_R_NOMORE);
-}
-
-static void
-question_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
- /*
- * This routine should never be called.
- */
- UNUSED(rdataset);
- UNUSED(rdata);
-
- REQUIRE(0);
-}
-
-static void
-question_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
- *target = *source;
-}
-
-static unsigned int
-question_count(dns_rdataset_t *rdataset) {
- /*
- * This routine should never be called.
- */
- UNUSED(rdataset);
- REQUIRE(0);
-
- return (0);
-}
-
-static dns_rdatasetmethods_t question_methods = {
- question_disassociate,
- question_cursor,
- question_cursor,
- question_current,
- question_clone,
- question_count,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-void
-dns_rdataset_makequestion(dns_rdataset_t *rdataset, dns_rdataclass_t rdclass,
- dns_rdatatype_t type)
-{
-
- /*
- * Make 'rdataset' a valid, associated, question rdataset, with a
- * question class of 'rdclass' and type 'type'.
- */
-
- REQUIRE(DNS_RDATASET_VALID(rdataset));
- REQUIRE(rdataset->methods == NULL);
-
- rdataset->methods = &question_methods;
- rdataset->rdclass = rdclass;
- rdataset->type = type;
- rdataset->attributes |= DNS_RDATASETATTR_QUESTION;
-}
-
-unsigned int
-dns_rdataset_count(dns_rdataset_t *rdataset) {
-
- /*
- * Return the number of records in 'rdataset'.
- */
-
- REQUIRE(DNS_RDATASET_VALID(rdataset));
- REQUIRE(rdataset->methods != NULL);
-
- return ((rdataset->methods->count)(rdataset));
-}
-
-void
-dns_rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
-
- /*
- * Make 'target' refer to the same rdataset as 'source'.
- */
-
- REQUIRE(DNS_RDATASET_VALID(source));
- REQUIRE(source->methods != NULL);
- REQUIRE(DNS_RDATASET_VALID(target));
- REQUIRE(target->methods == NULL);
-
- (source->methods->clone)(source, target);
-}
-
-isc_result_t
-dns_rdataset_first(dns_rdataset_t *rdataset) {
-
- /*
- * Move the rdata cursor to the first rdata in the rdataset (if any).
- */
-
- REQUIRE(DNS_RDATASET_VALID(rdataset));
- REQUIRE(rdataset->methods != NULL);
-
- return ((rdataset->methods->first)(rdataset));
-}
-
-isc_result_t
-dns_rdataset_next(dns_rdataset_t *rdataset) {
-
- /*
- * Move the rdata cursor to the next rdata in the rdataset (if any).
- */
-
- REQUIRE(DNS_RDATASET_VALID(rdataset));
- REQUIRE(rdataset->methods != NULL);
-
- return ((rdataset->methods->next)(rdataset));
-}
-
-void
-dns_rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
-
- /*
- * Make 'rdata' refer to the current rdata.
- */
-
- REQUIRE(DNS_RDATASET_VALID(rdataset));
- REQUIRE(rdataset->methods != NULL);
-
- (rdataset->methods->current)(rdataset, rdata);
-}
-
-#define MAX_SHUFFLE 32
-#define WANT_FIXED(r) (((r)->attributes & DNS_RDATASETATTR_FIXEDORDER) != 0)
-#define WANT_RANDOM(r) (((r)->attributes & DNS_RDATASETATTR_RANDOMIZE) != 0)
-
-struct towire_sort {
- int key;
- dns_rdata_t *rdata;
-};
-
-static int
-towire_compare(const void *av, const void *bv) {
- const struct towire_sort *a = (const struct towire_sort *) av;
- const struct towire_sort *b = (const struct towire_sort *) bv;
- return (a->key - b->key);
-}
-
-static isc_result_t
-towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
- dns_compress_t *cctx, isc_buffer_t *target,
- dns_rdatasetorderfunc_t order, const void *order_arg,
- isc_boolean_t partial, unsigned int options,
- unsigned int *countp, void **state)
-{
- dns_rdata_t rdata = DNS_RDATA_INIT;
- isc_region_t r;
- isc_result_t result;
- unsigned int i, count = 0, added, choice;
- isc_buffer_t savedbuffer, rdlen, rrbuffer;
- unsigned int headlen;
- isc_boolean_t question = ISC_FALSE;
- isc_boolean_t shuffle = ISC_FALSE;
- dns_rdata_t *shuffled = NULL, shuffled_fixed[MAX_SHUFFLE];
- struct towire_sort *sorted = NULL, sorted_fixed[MAX_SHUFFLE];
-
- UNUSED(state);
-
- /*
- * Convert 'rdataset' to wire format, compressing names as specified
- * in cctx, and storing the result in 'target'.
- */
-
- REQUIRE(DNS_RDATASET_VALID(rdataset));
- REQUIRE(countp != NULL);
- REQUIRE((order == NULL) == (order_arg == NULL));
- REQUIRE(cctx != NULL && cctx->mctx != NULL);
-
- if ((rdataset->attributes & DNS_RDATASETATTR_QUESTION) != 0) {
- question = ISC_TRUE;
- count = 1;
- result = dns_rdataset_first(rdataset);
- INSIST(result == ISC_R_NOMORE);
- } else if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) {
- /*
- * This is a negative caching rdataset.
- */
- unsigned int ncache_opts = 0;
- if ((options & DNS_RDATASETTOWIRE_OMITDNSSEC) != 0)
- ncache_opts |= DNS_NCACHETOWIRE_OMITDNSSEC;
- return (dns_ncache_towire(rdataset, cctx, target, ncache_opts,
- countp));
- } else {
- count = (rdataset->methods->count)(rdataset);
- result = dns_rdataset_first(rdataset);
- if (result == ISC_R_NOMORE)
- return (ISC_R_SUCCESS);
- if (result != ISC_R_SUCCESS)
- return (result);
- }
-
- /*
- * Do we want to shuffle this answer?
- */
- if (!question && count > 1 &&
- (!WANT_FIXED(rdataset) || order != NULL) &&
- rdataset->type != dns_rdatatype_rrsig)
- shuffle = ISC_TRUE;
-
- if (shuffle && count > MAX_SHUFFLE) {
- shuffled = isc_mem_get(cctx->mctx, count * sizeof(*shuffled));
- sorted = isc_mem_get(cctx->mctx, count * sizeof(*sorted));
- if (shuffled == NULL || sorted == NULL)
- shuffle = ISC_FALSE;
- } else {
- shuffled = shuffled_fixed;
- sorted = sorted_fixed;
- }
-
- if (shuffle) {
- /*
- * First we get handles to all of the rdata.
- */
- i = 0;
- do {
- INSIST(i < count);
- dns_rdata_init(&shuffled[i]);
- dns_rdataset_current(rdataset, &shuffled[i]);
- i++;
- result = dns_rdataset_next(rdataset);
- } while (result == ISC_R_SUCCESS);
- if (result != ISC_R_NOMORE)
- goto cleanup;
- INSIST(i == count);
-
- /*
- * Now we shuffle.
- */
- if (WANT_FIXED(rdataset)) {
- /*
- * 'Fixed' order.
- */
- INSIST(order != NULL);
- for (i = 0; i < count; i++) {
- sorted[i].key = (*order)(&shuffled[i],
- order_arg);
- sorted[i].rdata = &shuffled[i];
- }
- } else if (WANT_RANDOM(rdataset)) {
- /*
- * 'Random' order.
- */
- for (i = 0; i < count; i++) {
- dns_rdata_t rdata;
- isc_uint32_t val;
-
- isc_random_get(&val);
- choice = i + (val % (count - i));
- rdata = shuffled[i];
- shuffled[i] = shuffled[choice];
- shuffled[choice] = rdata;
- if (order != NULL)
- sorted[i].key = (*order)(&shuffled[i],
- order_arg);
- else
- sorted[i].key = 0; /* Unused */
- sorted[i].rdata = &shuffled[i];
- }
- } else {
- /*
- * "Cyclic" order.
- */
- isc_uint32_t val;
- unsigned int j;
-
- val = rdataset->count;
- if (val == ISC_UINT32_MAX)
- isc_random_get(&val);
- j = val % count;
- for (i = 0; i < count; i++) {
- if (order != NULL)
- sorted[i].key = (*order)(&shuffled[j],
- order_arg);
- else
- sorted[i].key = 0; /* Unused */
- sorted[i].rdata = &shuffled[j];
- j++;
- if (j == count)
- j = 0; /* Wrap around. */
- }
- }
-
- /*
- * Sorted order.
- */
- if (order != NULL)
- qsort(sorted, count, sizeof(sorted[0]),
- towire_compare);
- }
-
- savedbuffer = *target;
- i = 0;
- added = 0;
-
- do {
- /*
- * Copy out the name, type, class, ttl.
- */
-
- rrbuffer = *target;
- dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
- result = dns_name_towire(owner_name, cctx, target);
- if (result != ISC_R_SUCCESS)
- goto rollback;
- headlen = sizeof(dns_rdataclass_t) + sizeof(dns_rdatatype_t);
- if (!question)
- headlen += sizeof(dns_ttl_t)
- + 2; /* XXX 2 for rdata len */
- isc_buffer_availableregion(target, &r);
- if (r.length < headlen) {
- result = ISC_R_NOSPACE;
- goto rollback;
- }
- isc_buffer_putuint16(target, rdataset->type);
- isc_buffer_putuint16(target, rdataset->rdclass);
- if (!question) {
- isc_buffer_putuint32(target, rdataset->ttl);
-
- /*
- * Save space for rdlen.
- */
- rdlen = *target;
- isc_buffer_add(target, 2);
-
- /*
- * Copy out the rdata
- */
- if (shuffle)
- rdata = *(sorted[i].rdata);
- else {
- dns_rdata_reset(&rdata);
- dns_rdataset_current(rdataset, &rdata);
- }
- result = dns_rdata_towire(&rdata, cctx, target);
- if (result != ISC_R_SUCCESS)
- goto rollback;
- INSIST((target->used >= rdlen.used + 2) &&
- (target->used - rdlen.used - 2 < 65536));
- isc_buffer_putuint16(&rdlen,
- (isc_uint16_t)(target->used -
- rdlen.used - 2));
- added++;
- }
-
- if (shuffle) {
- i++;
- if (i == count)
- result = ISC_R_NOMORE;
- else
- result = ISC_R_SUCCESS;
- } else {
- result = dns_rdataset_next(rdataset);
- }
- } while (result == ISC_R_SUCCESS);
-
- if (result != ISC_R_NOMORE)
- goto rollback;
-
- *countp += count;
-
- result = ISC_R_SUCCESS;
- goto cleanup;
-
- rollback:
- if (partial && result == ISC_R_NOSPACE) {
- INSIST(rrbuffer.used < 65536);
- dns_compress_rollback(cctx, (isc_uint16_t)rrbuffer.used);
- *countp += added;
- *target = rrbuffer;
- goto cleanup;
- }
- INSIST(savedbuffer.used < 65536);
- dns_compress_rollback(cctx, (isc_uint16_t)savedbuffer.used);
- *countp = 0;
- *target = savedbuffer;
-
- cleanup:
- if (sorted != NULL && sorted != sorted_fixed)
- isc_mem_put(cctx->mctx, sorted, count * sizeof(*sorted));
- if (shuffled != NULL && shuffled != shuffled_fixed)
- isc_mem_put(cctx->mctx, shuffled, count * sizeof(*shuffled));
- return (result);
-}
-
-isc_result_t
-dns_rdataset_towiresorted(dns_rdataset_t *rdataset,
- const dns_name_t *owner_name,
- dns_compress_t *cctx,
- isc_buffer_t *target,
- dns_rdatasetorderfunc_t order,
- const void *order_arg,
- unsigned int options,
- unsigned int *countp)
-{
- return (towiresorted(rdataset, owner_name, cctx, target,
- order, order_arg, ISC_FALSE, options,
- countp, NULL));
-}
-
-isc_result_t
-dns_rdataset_towirepartial(dns_rdataset_t *rdataset,
- const dns_name_t *owner_name,
- dns_compress_t *cctx,
- isc_buffer_t *target,
- dns_rdatasetorderfunc_t order,
- const void *order_arg,
- unsigned int options,
- unsigned int *countp,
- void **state)
-{
- REQUIRE(state == NULL); /* XXX remove when implemented */
- return (towiresorted(rdataset, owner_name, cctx, target,
- order, order_arg, ISC_TRUE, options,
- countp, state));
-}
-
-isc_result_t
-dns_rdataset_towire(dns_rdataset_t *rdataset,
- dns_name_t *owner_name,
- dns_compress_t *cctx,
- isc_buffer_t *target,
- unsigned int options,
- unsigned int *countp)
-{
- return (towiresorted(rdataset, owner_name, cctx, target,
- NULL, NULL, ISC_FALSE, options, countp, NULL));
-}
-
-isc_result_t
-dns_rdataset_additionaldata(dns_rdataset_t *rdataset,
- dns_additionaldatafunc_t add, void *arg)
-{
- dns_rdata_t rdata = DNS_RDATA_INIT;
- isc_result_t result;
-
- /*
- * For each rdata in rdataset, call 'add' for each name and type in the
- * rdata which is subject to additional section processing.
- */
-
- REQUIRE(DNS_RDATASET_VALID(rdataset));
- REQUIRE((rdataset->attributes & DNS_RDATASETATTR_QUESTION) == 0);
-
- result = dns_rdataset_first(rdataset);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- do {
- dns_rdataset_current(rdataset, &rdata);
- result = dns_rdata_additionaldata(&rdata, add, arg);
- if (result == ISC_R_SUCCESS)
- result = dns_rdataset_next(rdataset);
- dns_rdata_reset(&rdata);
- } while (result == ISC_R_SUCCESS);
-
- if (result != ISC_R_NOMORE)
- return (result);
-
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_rdataset_addnoqname(dns_rdataset_t *rdataset, dns_name_t *name) {
-
- REQUIRE(DNS_RDATASET_VALID(rdataset));
- REQUIRE(rdataset->methods != NULL);
- if (rdataset->methods->addnoqname == NULL)
- return (ISC_R_NOTIMPLEMENTED);
- return((rdataset->methods->addnoqname)(rdataset, name));
-}
-
-isc_result_t
-dns_rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name,
- dns_rdataset_t *neg, dns_rdataset_t *negsig)
-{
- REQUIRE(DNS_RDATASET_VALID(rdataset));
- REQUIRE(rdataset->methods != NULL);
-
- if (rdataset->methods->getnoqname == NULL)
- return (ISC_R_NOTIMPLEMENTED);
- return((rdataset->methods->getnoqname)(rdataset, name, neg, negsig));
-}
-
-isc_result_t
-dns_rdataset_addclosest(dns_rdataset_t *rdataset, dns_name_t *name) {
-
- REQUIRE(DNS_RDATASET_VALID(rdataset));
- REQUIRE(rdataset->methods != NULL);
- if (rdataset->methods->addclosest == NULL)
- return (ISC_R_NOTIMPLEMENTED);
- return((rdataset->methods->addclosest)(rdataset, name));
-}
-
-isc_result_t
-dns_rdataset_getclosest(dns_rdataset_t *rdataset, dns_name_t *name,
- dns_rdataset_t *neg, dns_rdataset_t *negsig)
-{
- REQUIRE(DNS_RDATASET_VALID(rdataset));
- REQUIRE(rdataset->methods != NULL);
-
- if (rdataset->methods->getclosest == NULL)
- return (ISC_R_NOTIMPLEMENTED);
- return((rdataset->methods->getclosest)(rdataset, name, neg, negsig));
-}
-
-/*
- * Additional cache stuff
- */
-isc_result_t
-dns_rdataset_getadditional(dns_rdataset_t *rdataset,
- dns_rdatasetadditional_t type,
- dns_rdatatype_t qtype,
- dns_acache_t *acache,
- dns_zone_t **zonep,
- dns_db_t **dbp,
- dns_dbversion_t **versionp,
- dns_dbnode_t **nodep,
- dns_name_t *fname,
- dns_message_t *msg,
- isc_stdtime_t now)
-{
- REQUIRE(DNS_RDATASET_VALID(rdataset));
- REQUIRE(rdataset->methods != NULL);
- REQUIRE(zonep == NULL || *zonep == NULL);
- REQUIRE(dbp != NULL && *dbp == NULL);
- REQUIRE(versionp != NULL && *versionp == NULL);
- REQUIRE(nodep != NULL && *nodep == NULL);
- REQUIRE(fname != NULL);
- REQUIRE(msg != NULL);
-
- if (acache != NULL && rdataset->methods->getadditional != NULL) {
- return ((rdataset->methods->getadditional)(rdataset, type,
- qtype, acache,
- zonep, dbp,
- versionp, nodep,
- fname, msg, now));
- }
-
- return (ISC_R_FAILURE);
-}
-
-isc_result_t
-dns_rdataset_setadditional(dns_rdataset_t *rdataset,
- dns_rdatasetadditional_t type,
- dns_rdatatype_t qtype,
- dns_acache_t *acache,
- dns_zone_t *zone,
- dns_db_t *db,
- dns_dbversion_t *version,
- dns_dbnode_t *node,
- dns_name_t *fname)
-{
- REQUIRE(DNS_RDATASET_VALID(rdataset));
- REQUIRE(rdataset->methods != NULL);
-
- if (acache != NULL && rdataset->methods->setadditional != NULL) {
- return ((rdataset->methods->setadditional)(rdataset, type,
- qtype, acache, zone,
- db, version,
- node, fname));
- }
-
- return (ISC_R_FAILURE);
-}
-
-isc_result_t
-dns_rdataset_putadditional(dns_acache_t *acache,
- dns_rdataset_t *rdataset,
- dns_rdatasetadditional_t type,
- dns_rdatatype_t qtype)
-{
- REQUIRE(DNS_RDATASET_VALID(rdataset));
- REQUIRE(rdataset->methods != NULL);
-
- if (acache != NULL && rdataset->methods->putadditional != NULL) {
- return ((rdataset->methods->putadditional)(acache, rdataset,
- type, qtype));
- }
-
- return (ISC_R_FAILURE);
-}
-
-void
-dns_rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) {
- REQUIRE(DNS_RDATASET_VALID(rdataset));
- REQUIRE(rdataset->methods != NULL);
-
- if (rdataset->methods->settrust != NULL)
- (rdataset->methods->settrust)(rdataset, trust);
- else
- rdataset->trust = trust;
-}
-
-void
-dns_rdataset_expire(dns_rdataset_t *rdataset) {
- REQUIRE(DNS_RDATASET_VALID(rdataset));
- REQUIRE(rdataset->methods != NULL);
-
- if (rdataset->methods->expire != NULL)
- (rdataset->methods->expire)(rdataset);
-}
-
-void
-dns_rdataset_trimttl(dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
- dns_rdata_rrsig_t *rrsig, isc_stdtime_t now,
- isc_boolean_t acceptexpired)
-{
- isc_uint32_t ttl = 0;
-
- REQUIRE(DNS_RDATASET_VALID(rdataset));
- REQUIRE(DNS_RDATASET_VALID(sigrdataset));
- REQUIRE(rrsig != NULL);
-
- /*
- * If we accept expired RRsets keep them for no more than 120 seconds.
- */
- if (acceptexpired &&
- (isc_serial_le(rrsig->timeexpire, ((now + 120) & 0xffffffff)) ||
- isc_serial_le(rrsig->timeexpire, now)))
- ttl = 120;
- else if (isc_serial_ge(rrsig->timeexpire, now))
- ttl = rrsig->timeexpire - now;
-
- ttl = ISC_MIN(ISC_MIN(rdataset->ttl, sigrdataset->ttl),
- ISC_MIN(rrsig->originalttl, ttl));
- rdataset->ttl = ttl;
- sigrdataset->ttl = ttl;
-}
diff --git a/contrib/bind9/lib/dns/rdatasetiter.c b/contrib/bind9/lib/dns/rdatasetiter.c
deleted file mode 100644
index 7ed30301ed7b..000000000000
--- a/contrib/bind9/lib/dns/rdatasetiter.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: rdatasetiter.c,v 1.16 2007/06/19 23:47:16 tbox Exp $ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <stddef.h>
-
-#include <isc/util.h>
-
-#include <dns/rdataset.h>
-#include <dns/rdatasetiter.h>
-
-void
-dns_rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp) {
- /*
- * Destroy '*iteratorp'.
- */
-
- REQUIRE(iteratorp != NULL);
- REQUIRE(DNS_RDATASETITER_VALID(*iteratorp));
-
- (*iteratorp)->methods->destroy(iteratorp);
-
- ENSURE(*iteratorp == NULL);
-}
-
-isc_result_t
-dns_rdatasetiter_first(dns_rdatasetiter_t *iterator) {
- /*
- * Move the rdataset cursor to the first rdataset at the node (if any).
- */
-
- REQUIRE(DNS_RDATASETITER_VALID(iterator));
-
- return (iterator->methods->first(iterator));
-}
-
-isc_result_t
-dns_rdatasetiter_next(dns_rdatasetiter_t *iterator) {
- /*
- * Move the rdataset cursor to the next rdataset at the node (if any).
- */
-
- REQUIRE(DNS_RDATASETITER_VALID(iterator));
-
- return (iterator->methods->next(iterator));
-}
-
-void
-dns_rdatasetiter_current(dns_rdatasetiter_t *iterator,
- dns_rdataset_t *rdataset)
-{
- /*
- * Return the current rdataset.
- */
-
- REQUIRE(DNS_RDATASETITER_VALID(iterator));
- REQUIRE(DNS_RDATASET_VALID(rdataset));
- REQUIRE(! dns_rdataset_isassociated(rdataset));
-
- iterator->methods->current(iterator, rdataset);
-}
diff --git a/contrib/bind9/lib/dns/rdataslab.c b/contrib/bind9/lib/dns/rdataslab.c
deleted file mode 100644
index cb9ae5425ef9..000000000000
--- a/contrib/bind9/lib/dns/rdataslab.c
+++ /dev/null
@@ -1,1109 +0,0 @@
-/*
- * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <stdlib.h>
-
-#include <isc/mem.h>
-#include <isc/region.h>
-#include <isc/string.h> /* Required for HP/UX (and others?) */
-#include <isc/util.h>
-
-#include <dns/result.h>
-#include <dns/rdata.h>
-#include <dns/rdataset.h>
-#include <dns/rdataslab.h>
-
-/*
- * The rdataslab structure allows iteration to occur in both load order
- * and DNSSEC order. The structure is as follows:
- *
- * header (reservelen bytes)
- * record count (2 bytes)
- * offset table (4 x record count bytes in load order)
- * data records
- * data length (2 bytes)
- * order (2 bytes)
- * meta data (1 byte for RRSIG's)
- * data (data length bytes)
- *
- * If DNS_RDATASET_FIXED is defined to be zero (0) the format of a
- * rdataslab is as follows:
- *
- * header (reservelen bytes)
- * record count (2 bytes)
- * data records
- * data length (2 bytes)
- * meta data (1 byte for RRSIG's)
- * data (data length bytes)
- *
- * Offsets are from the end of the header.
- *
- * Load order traversal is performed by walking the offset table to find
- * the start of the record (DNS_RDATASET_FIXED = 1).
- *
- * DNSSEC order traversal is performed by walking the data records.
- *
- * The order is stored with record to allow for efficient reconstruction
- * of the offset table following a merge or subtraction.
- *
- * The iterator methods here currently only support DNSSEC order iteration.
- *
- * The iterator methods in rbtdb support both load order and DNSSEC order
- * iteration.
- *
- * WARNING:
- * rbtdb.c directly interacts with the slab's raw structures. If the
- * structure changes then rbtdb.c also needs to be updated to reflect
- * the changes. See the areas tagged with "RDATASLAB".
- */
-
-struct xrdata {
- dns_rdata_t rdata;
- unsigned int order;
-};
-
-/*% Note: the "const void *" are just to make qsort happy. */
-static int
-compare_rdata(const void *p1, const void *p2) {
- const struct xrdata *x1 = p1;
- const struct xrdata *x2 = p2;
- return (dns_rdata_compare(&x1->rdata, &x2->rdata));
-}
-
-#if DNS_RDATASET_FIXED
-static void
-fillin_offsets(unsigned char *offsetbase, unsigned int *offsettable,
- unsigned length)
-{
- unsigned int i, j;
- unsigned char *raw;
-
- for (i = 0, j = 0; i < length; i++) {
-
- if (offsettable[i] == 0)
- continue;
-
- /*
- * Fill in offset table.
- */
- raw = &offsetbase[j*4 + 2];
- *raw++ = (offsettable[i] & 0xff000000) >> 24;
- *raw++ = (offsettable[i] & 0xff0000) >> 16;
- *raw++ = (offsettable[i] & 0xff00) >> 8;
- *raw = offsettable[i] & 0xff;
-
- /*
- * Fill in table index.
- */
- raw = offsetbase + offsettable[i] + 2;
- *raw++ = (j & 0xff00) >> 8;
- *raw = j++ & 0xff;
- }
-}
-#endif
-
-isc_result_t
-dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
- isc_region_t *region, unsigned int reservelen)
-{
- /*
- * Use &removed as a sentinal pointer for duplicate
- * rdata as rdata.data == NULL is valid.
- */
- static unsigned char removed;
- struct xrdata *x;
- unsigned char *rawbuf;
-#if DNS_RDATASET_FIXED
- unsigned char *offsetbase;
-#endif
- unsigned int buflen;
- isc_result_t result;
- unsigned int nitems;
- unsigned int nalloc;
- unsigned int i;
-#if DNS_RDATASET_FIXED
- unsigned int *offsettable;
-#endif
- unsigned int length;
-
- buflen = reservelen + 2;
-
- nalloc = dns_rdataset_count(rdataset);
- nitems = nalloc;
- if (nitems == 0 && rdataset->type != 0)
- return (ISC_R_FAILURE);
-
- if (nalloc > 0xffff)
- return (ISC_R_NOSPACE);
-
-
- 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 && result != ISC_R_NOMORE)
- goto free_rdatas;
- for (i = 0; i < nalloc && result == ISC_R_SUCCESS; i++) {
- INSIST(result == ISC_R_SUCCESS);
- dns_rdata_init(&x[i].rdata);
- dns_rdataset_current(rdataset, &x[i].rdata);
- INSIST(x[i].rdata.data != &removed);
-#if DNS_RDATASET_FIXED
- x[i].order = i;
-#endif
- result = dns_rdataset_next(rdataset);
- }
- if (result != ISC_R_NOMORE)
- goto free_rdatas;
- if (i != nalloc) {
- /*
- * Somehow we iterated over fewer rdatas than
- * dns_rdataset_count() said there were!
- */
- result = ISC_R_FAILURE;
- goto free_rdatas;
- }
-
- /*
- * Put into DNSSEC order.
- */
- qsort(x, nalloc, sizeof(struct xrdata), compare_rdata);
-
- /*
- * Remove duplicates and compute the total storage required.
- *
- * If an rdata is not a duplicate, accumulate the storage size
- * required for the rdata. We do not store the class, type, etc,
- * just the rdata, so our overhead is 2 bytes for the number of
- * records, and 8 for each rdata, (length(2), offset(4) and order(2))
- * and then the rdata itself.
- */
- for (i = 1; i < nalloc; i++) {
- if (compare_rdata(&x[i-1].rdata, &x[i].rdata) == 0) {
- x[i-1].rdata.data = &removed;
-#if DNS_RDATASET_FIXED
- /*
- * Preserve the least order so A, B, A -> A, B
- * after duplicate removal.
- */
- if (x[i-1].order < x[i].order)
- x[i].order = x[i-1].order;
-#endif
- nitems--;
- } else {
-#if DNS_RDATASET_FIXED
- buflen += (8 + x[i-1].rdata.length);
-#else
- buflen += (2 + x[i-1].rdata.length);
-#endif
- /*
- * Provide space to store the per RR meta data.
- */
- if (rdataset->type == dns_rdatatype_rrsig)
- buflen++;
- }
- }
- /*
- * Don't forget the last item!
- */
- if (nalloc != 0) {
-#if DNS_RDATASET_FIXED
- buflen += (8 + x[i-1].rdata.length);
-#else
- buflen += (2 + x[i-1].rdata.length);
-#endif
- }
-
- /*
- * Provide space to store the per RR meta data.
- */
- if (rdataset->type == dns_rdatatype_rrsig)
- buflen++;
-
- /*
- * Ensure that singleton types are actually singletons.
- */
- if (nitems > 1 && dns_rdatatype_issingleton(rdataset->type)) {
- /*
- * We have a singleton type, but there's more than one
- * RR in the rdataset.
- */
- result = DNS_R_SINGLETON;
- goto free_rdatas;
- }
-
- /*
- * Allocate the memory, set up a buffer, start copying in
- * data.
- */
- rawbuf = isc_mem_get(mctx, buflen);
- if (rawbuf == NULL) {
- result = ISC_R_NOMEMORY;
- goto free_rdatas;
- }
-
-#if DNS_RDATASET_FIXED
- /* Allocate temporary offset table. */
- offsettable = isc_mem_get(mctx, nalloc * sizeof(unsigned int));
- if (offsettable == NULL) {
- isc_mem_put(mctx, rawbuf, buflen);
- result = ISC_R_NOMEMORY;
- goto free_rdatas;
- }
- memset(offsettable, 0, nalloc * sizeof(unsigned int));
-#endif
-
- region->base = rawbuf;
- region->length = buflen;
-
- rawbuf += reservelen;
-#if DNS_RDATASET_FIXED
- offsetbase = rawbuf;
-#endif
-
- *rawbuf++ = (nitems & 0xff00) >> 8;
- *rawbuf++ = (nitems & 0x00ff);
-
-#if DNS_RDATASET_FIXED
- /* Skip load order table. Filled in later. */
- rawbuf += nitems * 4;
-#endif
-
- for (i = 0; i < nalloc; i++) {
- if (x[i].rdata.data == &removed)
- continue;
-#if DNS_RDATASET_FIXED
- offsettable[x[i].order] = rawbuf - offsetbase;
-#endif
- length = x[i].rdata.length;
- if (rdataset->type == dns_rdatatype_rrsig)
- length++;
- INSIST(length <= 0xffff);
- *rawbuf++ = (length & 0xff00) >> 8;
- *rawbuf++ = (length & 0x00ff);
-#if DNS_RDATASET_FIXED
- rawbuf += 2; /* filled in later */
-#endif
- /*
- * Store the per RR meta data.
- */
- if (rdataset->type == dns_rdatatype_rrsig) {
- *rawbuf++ |= (x[i].rdata.flags & DNS_RDATA_OFFLINE) ?
- DNS_RDATASLAB_OFFLINE : 0;
- }
- memcpy(rawbuf, x[i].rdata.data, x[i].rdata.length);
- rawbuf += x[i].rdata.length;
- }
-
-#if DNS_RDATASET_FIXED
- fillin_offsets(offsetbase, offsettable, nalloc);
- isc_mem_put(mctx, offsettable, nalloc * sizeof(unsigned int));
-#endif
-
- result = ISC_R_SUCCESS;
-
- free_rdatas:
- if (x != NULL)
- isc_mem_put(mctx, x, nalloc * sizeof(struct xrdata));
- return (result);
-}
-
-static void
-rdataset_disassociate(dns_rdataset_t *rdataset) {
- UNUSED(rdataset);
-}
-
-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);
- }
-#if DNS_RDATASET_FIXED
- raw += 2 + (4 * count);
-#else
- raw += 2;
-#endif
- /*
- * 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];
-#if DNS_RDATASET_FIXED
- raw += length + 4;
-#else
- raw += length + 2;
-#endif
- 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];
-#if DNS_RDATASET_FIXED
- raw += 4;
-#else
- raw += 2;
-#endif
- 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) {
- *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 dns_rdatasetmethods_t rdataset_methods = {
- rdataset_disassociate,
- rdataset_first,
- rdataset_next,
- rdataset_current,
- rdataset_clone,
- rdataset_count,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-void
-dns_rdataslab_tordataset(unsigned char *slab, unsigned int reservelen,
- dns_rdataclass_t rdclass, dns_rdatatype_t rdtype,
- dns_rdatatype_t covers, dns_ttl_t ttl,
- dns_rdataset_t *rdataset)
-{
- REQUIRE(slab != NULL);
- REQUIRE(!dns_rdataset_isassociated(rdataset));
-
- rdataset->methods = &rdataset_methods;
- rdataset->rdclass = rdclass;
- rdataset->type = rdtype;
- rdataset->covers = covers;
- rdataset->ttl = ttl;
- rdataset->trust = 0;
- rdataset->private1 = NULL;
- rdataset->private2 = NULL;
- rdataset->private3 = slab + reservelen;
-
- /*
- * Reset iterator state.
- */
- rdataset->privateuint4 = 0;
- rdataset->private5 = NULL;
-}
-
-unsigned int
-dns_rdataslab_size(unsigned char *slab, unsigned int reservelen) {
- unsigned int count, length;
- unsigned char *current;
-
- REQUIRE(slab != NULL);
-
- current = slab + reservelen;
- count = *current++ * 256;
- count += *current++;
-#if DNS_RDATASET_FIXED
- current += (4 * count);
-#endif
- while (count > 0) {
- count--;
- length = *current++ * 256;
- length += *current++;
-#if DNS_RDATASET_FIXED
- current += length + 2;
-#else
- current += length;
-#endif
- }
-
- return ((unsigned int)(current - slab));
-}
-
-/*
- * Make the dns_rdata_t 'rdata' refer to the slab item
- * beginning at '*current', which is part of a slab of type
- * 'type' and class 'rdclass', and advance '*current' to
- * point to the next item in the slab.
- */
-static inline void
-rdata_from_slab(unsigned char **current,
- dns_rdataclass_t rdclass, dns_rdatatype_t type,
- dns_rdata_t *rdata)
-{
- unsigned char *tcurrent = *current;
- isc_region_t region;
- unsigned int length;
- isc_boolean_t offline = ISC_FALSE;
-
- length = *tcurrent++ * 256;
- length += *tcurrent++;
-
- if (type == dns_rdatatype_rrsig) {
- if ((*tcurrent & DNS_RDATASLAB_OFFLINE) != 0)
- offline = ISC_TRUE;
- length--;
- tcurrent++;
- }
- region.length = length;
-#if DNS_RDATASET_FIXED
- tcurrent += 2;
-#endif
- region.base = tcurrent;
- tcurrent += region.length;
- dns_rdata_fromregion(rdata, rdclass, type, &region);
- if (offline)
- rdata->flags |= DNS_RDATA_OFFLINE;
- *current = tcurrent;
-}
-
-/*
- * Return true iff 'slab' (slab data of type 'type' and class 'rdclass')
- * contains an rdata identical to 'rdata'. This does case insensitive
- * comparisons per DNSSEC.
- */
-static inline isc_boolean_t
-rdata_in_slab(unsigned char *slab, unsigned int reservelen,
- dns_rdataclass_t rdclass, dns_rdatatype_t type,
- dns_rdata_t *rdata)
-{
- unsigned int count, i;
- unsigned char *current;
- dns_rdata_t trdata = DNS_RDATA_INIT;
- int n;
-
- current = slab + reservelen;
- count = *current++ * 256;
- count += *current++;
-
-#if DNS_RDATASET_FIXED
- current += (4 * count);
-#endif
-
- for (i = 0; i < count; i++) {
- rdata_from_slab(&current, rdclass, type, &trdata);
-
- n = dns_rdata_compare(&trdata, rdata);
- if (n == 0)
- return (ISC_TRUE);
- if (n > 0) /* In DNSSEC order. */
- break;
- dns_rdata_reset(&trdata);
- }
- return (ISC_FALSE);
-}
-
-isc_result_t
-dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
- unsigned int reservelen, isc_mem_t *mctx,
- dns_rdataclass_t rdclass, dns_rdatatype_t type,
- unsigned int flags, unsigned char **tslabp)
-{
- unsigned char *ocurrent, *ostart, *ncurrent, *tstart, *tcurrent, *data;
- unsigned int ocount, ncount, count, olength, tlength, tcount, length;
- dns_rdata_t ordata = DNS_RDATA_INIT;
- dns_rdata_t nrdata = DNS_RDATA_INIT;
- isc_boolean_t added_something = ISC_FALSE;
- unsigned int oadded = 0;
- unsigned int nadded = 0;
- unsigned int nncount = 0;
-#if DNS_RDATASET_FIXED
- unsigned int oncount;
- unsigned int norder = 0;
- unsigned int oorder = 0;
- unsigned char *offsetbase;
- unsigned int *offsettable;
-#endif
-
- /*
- * XXX Need parameter to allow "delete rdatasets in nslab" merge,
- * or perhaps another merge routine for this purpose.
- */
-
- REQUIRE(tslabp != NULL && *tslabp == NULL);
- REQUIRE(oslab != NULL && nslab != NULL);
-
- ocurrent = oslab + reservelen;
- ocount = *ocurrent++ * 256;
- ocount += *ocurrent++;
-#if DNS_RDATASET_FIXED
- ocurrent += (4 * ocount);
-#endif
- ostart = ocurrent;
- ncurrent = nslab + reservelen;
- ncount = *ncurrent++ * 256;
- ncount += *ncurrent++;
-#if DNS_RDATASET_FIXED
- ncurrent += (4 * ncount);
-#endif
- INSIST(ocount > 0 && ncount > 0);
-
-#if DNS_RDATASET_FIXED
- oncount = ncount;
-#endif
-
- /*
- * Yes, this is inefficient!
- */
-
- /*
- * Figure out the length of the old slab's data.
- */
- olength = 0;
- for (count = 0; count < ocount; count++) {
- length = *ocurrent++ * 256;
- length += *ocurrent++;
-#if DNS_RDATASET_FIXED
- olength += length + 8;
- ocurrent += length + 2;
-#else
- olength += length + 2;
- ocurrent += length;
-#endif
- }
-
- /*
- * Start figuring out the target length and count.
- */
- tlength = reservelen + 2 + olength;
- tcount = ocount;
-
- /*
- * Add in the length of rdata in the new slab that aren't in
- * the old slab.
- */
- do {
- dns_rdata_init(&nrdata);
- rdata_from_slab(&ncurrent, rdclass, type, &nrdata);
- if (!rdata_in_slab(oslab, reservelen, rdclass, type, &nrdata))
- {
- /*
- * This rdata isn't in the old slab.
- */
-#if DNS_RDATASET_FIXED
- tlength += nrdata.length + 8;
-#else
- tlength += nrdata.length + 2;
-#endif
- if (type == dns_rdatatype_rrsig)
- tlength++;
- tcount++;
- nncount++;
- added_something = ISC_TRUE;
- }
- ncount--;
- } while (ncount > 0);
- ncount = nncount;
-
- if (((flags & DNS_RDATASLAB_EXACT) != 0) &&
- (tcount != ncount + ocount))
- return (DNS_R_NOTEXACT);
-
- if (!added_something && (flags & DNS_RDATASLAB_FORCE) == 0)
- return (DNS_R_UNCHANGED);
-
- /*
- * Ensure that singleton types are actually singletons.
- */
- if (tcount > 1 && dns_rdatatype_issingleton(type)) {
- /*
- * We have a singleton type, but there's more than one
- * RR in the rdataset.
- */
- return (DNS_R_SINGLETON);
- }
-
- if (tcount > 0xffff)
- return (ISC_R_NOSPACE);
-
- /*
- * Copy the reserved area from the new slab.
- */
- tstart = isc_mem_get(mctx, tlength);
- if (tstart == NULL)
- return (ISC_R_NOMEMORY);
- memcpy(tstart, nslab, reservelen);
- tcurrent = tstart + reservelen;
-#if DNS_RDATASET_FIXED
- offsetbase = tcurrent;
-#endif
-
- /*
- * Write the new count.
- */
- *tcurrent++ = (tcount & 0xff00) >> 8;
- *tcurrent++ = (tcount & 0x00ff);
-
-#if DNS_RDATASET_FIXED
- /*
- * Skip offset table.
- */
- tcurrent += (tcount * 4);
-
- offsettable = isc_mem_get(mctx,
- (ocount + oncount) * sizeof(unsigned int));
- if (offsettable == NULL) {
- isc_mem_put(mctx, tstart, tlength);
- return (ISC_R_NOMEMORY);
- }
- memset(offsettable, 0, (ocount + oncount) * sizeof(unsigned int));
-#endif
-
- /*
- * Merge the two slabs.
- */
- ocurrent = ostart;
- INSIST(ocount != 0);
-#if DNS_RDATASET_FIXED
- oorder = ocurrent[2] * 256 + ocurrent[3];
- INSIST(oorder < ocount);
-#endif
- rdata_from_slab(&ocurrent, rdclass, type, &ordata);
-
- ncurrent = nslab + reservelen + 2;
-#if DNS_RDATASET_FIXED
- ncurrent += (4 * oncount);
-#endif
-
- if (ncount > 0) {
- do {
- dns_rdata_reset(&nrdata);
-#if DNS_RDATASET_FIXED
- norder = ncurrent[2] * 256 + ncurrent[3];
-
- INSIST(norder < oncount);
-#endif
- rdata_from_slab(&ncurrent, rdclass, type, &nrdata);
- } while (rdata_in_slab(oslab, reservelen, rdclass,
- type, &nrdata));
- }
-
- while (oadded < ocount || nadded < ncount) {
- isc_boolean_t fromold;
- if (oadded == ocount)
- fromold = ISC_FALSE;
- else if (nadded == ncount)
- fromold = ISC_TRUE;
- else
- fromold = ISC_TF(compare_rdata(&ordata, &nrdata) < 0);
- if (fromold) {
-#if DNS_RDATASET_FIXED
- offsettable[oorder] = tcurrent - offsetbase;
-#endif
- length = ordata.length;
- data = ordata.data;
- if (type == dns_rdatatype_rrsig) {
- length++;
- data--;
- }
- *tcurrent++ = (length & 0xff00) >> 8;
- *tcurrent++ = (length & 0x00ff);
-#if DNS_RDATASET_FIXED
- tcurrent += 2; /* fill in later */
-#endif
- memcpy(tcurrent, data, length);
- tcurrent += length;
- oadded++;
- if (oadded < ocount) {
- dns_rdata_reset(&ordata);
-#if DNS_RDATASET_FIXED
- oorder = ocurrent[2] * 256 + ocurrent[3];
- INSIST(oorder < ocount);
-#endif
- rdata_from_slab(&ocurrent, rdclass, type,
- &ordata);
- }
- } else {
-#if DNS_RDATASET_FIXED
- offsettable[ocount + norder] = tcurrent - offsetbase;
-#endif
- length = nrdata.length;
- data = nrdata.data;
- if (type == dns_rdatatype_rrsig) {
- length++;
- data--;
- }
- *tcurrent++ = (length & 0xff00) >> 8;
- *tcurrent++ = (length & 0x00ff);
-#if DNS_RDATASET_FIXED
- tcurrent += 2; /* fill in later */
-#endif
- memcpy(tcurrent, data, length);
- tcurrent += length;
- nadded++;
- if (nadded < ncount) {
- do {
- dns_rdata_reset(&nrdata);
-#if DNS_RDATASET_FIXED
- norder = ncurrent[2] * 256 + ncurrent[3];
- INSIST(norder < oncount);
-#endif
- rdata_from_slab(&ncurrent, rdclass,
- type, &nrdata);
- } while (rdata_in_slab(oslab, reservelen,
- rdclass, type,
- &nrdata));
- }
- }
- }
-
-#if DNS_RDATASET_FIXED
- fillin_offsets(offsetbase, offsettable, ocount + oncount);
-
- isc_mem_put(mctx, offsettable,
- (ocount + oncount) * sizeof(unsigned int));
-#endif
-
- INSIST(tcurrent == tstart + tlength);
-
- *tslabp = tstart;
-
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_rdataslab_subtract(unsigned char *mslab, unsigned char *sslab,
- unsigned int reservelen, isc_mem_t *mctx,
- dns_rdataclass_t rdclass, dns_rdatatype_t type,
- unsigned int flags, unsigned char **tslabp)
-{
- unsigned char *mcurrent, *sstart, *scurrent, *tstart, *tcurrent;
- unsigned int mcount, scount, rcount ,count, tlength, tcount, i;
- dns_rdata_t srdata = DNS_RDATA_INIT;
- dns_rdata_t mrdata = DNS_RDATA_INIT;
-#if DNS_RDATASET_FIXED
- unsigned char *offsetbase;
- unsigned int *offsettable;
- unsigned int order;
-#endif
-
- REQUIRE(tslabp != NULL && *tslabp == NULL);
- REQUIRE(mslab != NULL && sslab != NULL);
-
- mcurrent = mslab + reservelen;
- mcount = *mcurrent++ * 256;
- mcount += *mcurrent++;
- scurrent = sslab + reservelen;
- scount = *scurrent++ * 256;
- scount += *scurrent++;
- INSIST(mcount > 0 && scount > 0);
-
- /*
- * Yes, this is inefficient!
- */
-
- /*
- * Start figuring out the target length and count.
- */
- tlength = reservelen + 2;
- tcount = 0;
- rcount = 0;
-
-#if DNS_RDATASET_FIXED
- mcurrent += 4 * mcount;
- scurrent += 4 * scount;
-#endif
- sstart = scurrent;
-
- /*
- * Add in the length of rdata in the mslab that aren't in
- * the sslab.
- */
- for (i = 0; i < mcount; i++) {
- unsigned char *mrdatabegin = mcurrent;
- rdata_from_slab(&mcurrent, rdclass, type, &mrdata);
- scurrent = sstart;
- for (count = 0; count < scount; count++) {
- dns_rdata_reset(&srdata);
- rdata_from_slab(&scurrent, rdclass, type, &srdata);
- if (dns_rdata_compare(&mrdata, &srdata) == 0)
- break;
- }
- if (count == scount) {
- /*
- * This rdata isn't in the sslab, and thus isn't
- * being subtracted.
- */
- tlength += mcurrent - mrdatabegin;
- tcount++;
- } else
- rcount++;
- dns_rdata_reset(&mrdata);
- }
-
-#if DNS_RDATASET_FIXED
- tlength += (4 * tcount);
-#endif
-
- /*
- * Check that all the records originally existed. The numeric
- * check only works as rdataslabs do not contain duplicates.
- */
- if (((flags & DNS_RDATASLAB_EXACT) != 0) && (rcount != scount))
- return (DNS_R_NOTEXACT);
-
- /*
- * Don't continue if the new rdataslab would be empty.
- */
- if (tcount == 0)
- return (DNS_R_NXRRSET);
-
- /*
- * If nothing is going to change, we can stop.
- */
- if (rcount == 0)
- return (DNS_R_UNCHANGED);
-
- /*
- * Copy the reserved area from the mslab.
- */
- tstart = isc_mem_get(mctx, tlength);
- if (tstart == NULL)
- return (ISC_R_NOMEMORY);
- memcpy(tstart, mslab, reservelen);
- tcurrent = tstart + reservelen;
-#if DNS_RDATASET_FIXED
- offsetbase = tcurrent;
-
- offsettable = isc_mem_get(mctx, mcount * sizeof(unsigned int));
- if (offsettable == NULL) {
- isc_mem_put(mctx, tstart, tlength);
- return (ISC_R_NOMEMORY);
- }
- memset(offsettable, 0, mcount * sizeof(unsigned int));
-#endif
-
- /*
- * Write the new count.
- */
- *tcurrent++ = (tcount & 0xff00) >> 8;
- *tcurrent++ = (tcount & 0x00ff);
-
-#if DNS_RDATASET_FIXED
- tcurrent += (4 * tcount);
-#endif
-
- /*
- * Copy the parts of mslab not in sslab.
- */
- mcurrent = mslab + reservelen;
- mcount = *mcurrent++ * 256;
- mcount += *mcurrent++;
-#if DNS_RDATASET_FIXED
- mcurrent += (4 * mcount);
-#endif
- for (i = 0; i < mcount; i++) {
- unsigned char *mrdatabegin = mcurrent;
-#if DNS_RDATASET_FIXED
- order = mcurrent[2] * 256 + mcurrent[3];
- INSIST(order < mcount);
-#endif
- rdata_from_slab(&mcurrent, rdclass, type, &mrdata);
- scurrent = sstart;
- for (count = 0; count < scount; count++) {
- dns_rdata_reset(&srdata);
- rdata_from_slab(&scurrent, rdclass, type, &srdata);
- if (dns_rdata_compare(&mrdata, &srdata) == 0)
- break;
- }
- if (count == scount) {
- /*
- * This rdata isn't in the sslab, and thus should be
- * copied to the tslab.
- */
- unsigned int length = mcurrent - mrdatabegin;
-#if DNS_RDATASET_FIXED
- offsettable[order] = tcurrent - offsetbase;
-#endif
- memcpy(tcurrent, mrdatabegin, length);
- tcurrent += length;
- }
- dns_rdata_reset(&mrdata);
- }
-
-#if DNS_RDATASET_FIXED
- fillin_offsets(offsetbase, offsettable, mcount);
-
- isc_mem_put(mctx, offsettable, mcount * sizeof(unsigned int));
-#endif
-
- INSIST(tcurrent == tstart + tlength);
-
- *tslabp = tstart;
-
- return (ISC_R_SUCCESS);
-}
-
-isc_boolean_t
-dns_rdataslab_equal(unsigned char *slab1, unsigned char *slab2,
- unsigned int reservelen)
-{
- unsigned char *current1, *current2;
- unsigned int count1, count2;
- unsigned int length1, length2;
-
- current1 = slab1 + reservelen;
- count1 = *current1++ * 256;
- count1 += *current1++;
-
- current2 = slab2 + reservelen;
- count2 = *current2++ * 256;
- count2 += *current2++;
-
- if (count1 != count2)
- return (ISC_FALSE);
-
-#if DNS_RDATASET_FIXED
- current1 += (4 * count1);
- current2 += (4 * count2);
-#endif
-
- while (count1 > 0) {
- length1 = *current1++ * 256;
- length1 += *current1++;
-
- length2 = *current2++ * 256;
- length2 += *current2++;
-
-#if DNS_RDATASET_FIXED
- current1 += 2;
- current2 += 2;
-#endif
-
- if (length1 != length2 ||
- memcmp(current1, current2, length1) != 0)
- return (ISC_FALSE);
-
- current1 += length1;
- current2 += length1;
-
- count1--;
- }
- return (ISC_TRUE);
-}
-
-isc_boolean_t
-dns_rdataslab_equalx(unsigned char *slab1, unsigned char *slab2,
- unsigned int reservelen, dns_rdataclass_t rdclass,
- dns_rdatatype_t type)
-{
- unsigned char *current1, *current2;
- unsigned int count1, count2;
- dns_rdata_t rdata1 = DNS_RDATA_INIT;
- dns_rdata_t rdata2 = DNS_RDATA_INIT;
-
- current1 = slab1 + reservelen;
- count1 = *current1++ * 256;
- count1 += *current1++;
-
- current2 = slab2 + reservelen;
- count2 = *current2++ * 256;
- count2 += *current2++;
-
- if (count1 != count2)
- return (ISC_FALSE);
-
-#if DNS_RDATASET_FIXED
- current1 += (4 * count1);
- current2 += (4 * count2);
-#endif
-
- while (count1-- > 0) {
- rdata_from_slab(&current1, rdclass, type, &rdata1);
- rdata_from_slab(&current2, rdclass, type, &rdata2);
- if (dns_rdata_compare(&rdata1, &rdata2) != 0)
- return (ISC_FALSE);
- dns_rdata_reset(&rdata1);
- dns_rdata_reset(&rdata2);
- }
- return (ISC_TRUE);
-}
diff --git a/contrib/bind9/lib/dns/request.c b/contrib/bind9/lib/dns/request.c
deleted file mode 100644
index 1316e6994110..000000000000
--- a/contrib/bind9/lib/dns/request.c
+++ /dev/null
@@ -1,1499 +0,0 @@
-/*
- * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2000-2002 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <isc/magic.h>
-#include <isc/mem.h>
-#include <isc/task.h>
-#include <isc/timer.h>
-#include <isc/util.h>
-
-#include <dns/acl.h>
-#include <dns/compress.h>
-#include <dns/dispatch.h>
-#include <dns/events.h>
-#include <dns/log.h>
-#include <dns/message.h>
-#include <dns/rdata.h>
-#include <dns/rdatastruct.h>
-#include <dns/request.h>
-#include <dns/result.h>
-#include <dns/tsig.h>
-
-#define REQUESTMGR_MAGIC ISC_MAGIC('R', 'q', 'u', 'M')
-#define VALID_REQUESTMGR(mgr) ISC_MAGIC_VALID(mgr, REQUESTMGR_MAGIC)
-
-#define REQUEST_MAGIC ISC_MAGIC('R', 'q', 'u', '!')
-#define VALID_REQUEST(request) ISC_MAGIC_VALID(request, REQUEST_MAGIC)
-
-typedef ISC_LIST(dns_request_t) dns_requestlist_t;
-
-#define DNS_REQUEST_NLOCKS 7
-
-struct dns_requestmgr {
- unsigned int magic;
- isc_mutex_t lock;
- isc_mem_t *mctx;
-
- /* locked */
- isc_int32_t eref;
- isc_int32_t iref;
- isc_timermgr_t *timermgr;
- isc_socketmgr_t *socketmgr;
- isc_taskmgr_t *taskmgr;
- dns_dispatchmgr_t *dispatchmgr;
- dns_dispatch_t *dispatchv4;
- dns_dispatch_t *dispatchv6;
- isc_boolean_t exiting;
- isc_eventlist_t whenshutdown;
- unsigned int hash;
- isc_mutex_t locks[DNS_REQUEST_NLOCKS];
- dns_requestlist_t requests;
-};
-
-struct dns_request {
- unsigned int magic;
- unsigned int hash;
- isc_mem_t *mctx;
- isc_int32_t flags;
- ISC_LINK(dns_request_t) link;
- isc_buffer_t *query;
- isc_buffer_t *answer;
- dns_requestevent_t *event;
- dns_dispatch_t *dispatch;
- dns_dispentry_t *dispentry;
- isc_timer_t *timer;
- dns_requestmgr_t *requestmgr;
- isc_buffer_t *tsig;
- dns_tsigkey_t *tsigkey;
- isc_event_t ctlevent;
- isc_boolean_t canceling; /* ctlevent outstanding */
- isc_sockaddr_t destaddr;
- unsigned int udpcount;
-};
-
-#define DNS_REQUEST_F_CONNECTING 0x0001
-#define DNS_REQUEST_F_SENDING 0x0002
-#define DNS_REQUEST_F_CANCELED 0x0004 /*%< ctlevent received, or otherwise
- synchronously canceled */
-#define DNS_REQUEST_F_TIMEDOUT 0x0008 /*%< canceled due to a timeout */
-#define DNS_REQUEST_F_TCP 0x0010 /*%< This request used TCP */
-#define DNS_REQUEST_CANCELED(r) \
- (((r)->flags & DNS_REQUEST_F_CANCELED) != 0)
-#define DNS_REQUEST_CONNECTING(r) \
- (((r)->flags & DNS_REQUEST_F_CONNECTING) != 0)
-#define DNS_REQUEST_SENDING(r) \
- (((r)->flags & DNS_REQUEST_F_SENDING) != 0)
-#define DNS_REQUEST_TIMEDOUT(r) \
- (((r)->flags & DNS_REQUEST_F_TIMEDOUT) != 0)
-
-
-/***
- *** Forward
- ***/
-
-static void mgr_destroy(dns_requestmgr_t *requestmgr);
-static void mgr_shutdown(dns_requestmgr_t *requestmgr);
-static unsigned int mgr_gethash(dns_requestmgr_t *requestmgr);
-static void send_shutdown_events(dns_requestmgr_t *requestmgr);
-
-static isc_result_t req_render(dns_message_t *message, isc_buffer_t **buffer,
- unsigned int options, isc_mem_t *mctx);
-static void req_senddone(isc_task_t *task, isc_event_t *event);
-static void req_response(isc_task_t *task, isc_event_t *event);
-static void req_timeout(isc_task_t *task, isc_event_t *event);
-static isc_socket_t * req_getsocket(dns_request_t *request);
-static void req_connected(isc_task_t *task, isc_event_t *event);
-static void req_sendevent(dns_request_t *request, isc_result_t result);
-static void req_cancel(dns_request_t *request);
-static void req_destroy(dns_request_t *request);
-static void req_log(int level, const char *fmt, ...) ISC_FORMAT_PRINTF(2, 3);
-static void do_cancel(isc_task_t *task, isc_event_t *event);
-
-/***
- *** Public
- ***/
-
-isc_result_t
-dns_requestmgr_create(isc_mem_t *mctx,
- isc_timermgr_t *timermgr,
- isc_socketmgr_t *socketmgr,
- isc_taskmgr_t *taskmgr,
- dns_dispatchmgr_t *dispatchmgr,
- dns_dispatch_t *dispatchv4,
- dns_dispatch_t *dispatchv6,
- dns_requestmgr_t **requestmgrp)
-{
- dns_requestmgr_t *requestmgr;
- isc_socket_t *socket;
- isc_result_t result;
- int i;
- unsigned int dispattr;
-
- req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_create");
-
- REQUIRE(requestmgrp != NULL && *requestmgrp == NULL);
- REQUIRE(timermgr != NULL);
- REQUIRE(socketmgr != NULL);
- REQUIRE(taskmgr != NULL);
- REQUIRE(dispatchmgr != NULL);
- UNUSED(socket);
- if (dispatchv4 != NULL) {
- dispattr = dns_dispatch_getattributes(dispatchv4);
- REQUIRE((dispattr & DNS_DISPATCHATTR_UDP) != 0);
- }
- if (dispatchv6 != NULL) {
- dispattr = dns_dispatch_getattributes(dispatchv6);
- REQUIRE((dispattr & DNS_DISPATCHATTR_UDP) != 0);
- }
-
- requestmgr = isc_mem_get(mctx, sizeof(*requestmgr));
- if (requestmgr == NULL)
- return (ISC_R_NOMEMORY);
-
- result = isc_mutex_init(&requestmgr->lock);
- if (result != ISC_R_SUCCESS) {
- isc_mem_put(mctx, requestmgr, sizeof(*requestmgr));
- return (result);
- }
- for (i = 0; i < DNS_REQUEST_NLOCKS; i++) {
- result = isc_mutex_init(&requestmgr->locks[i]);
- if (result != ISC_R_SUCCESS) {
- while (--i >= 0)
- DESTROYLOCK(&requestmgr->locks[i]);
- DESTROYLOCK(&requestmgr->lock);
- isc_mem_put(mctx, requestmgr, sizeof(*requestmgr));
- return (result);
- }
- }
- requestmgr->timermgr = timermgr;
- requestmgr->socketmgr = socketmgr;
- requestmgr->taskmgr = taskmgr;
- requestmgr->dispatchmgr = dispatchmgr;
- requestmgr->dispatchv4 = NULL;
- if (dispatchv4 != NULL)
- dns_dispatch_attach(dispatchv4, &requestmgr->dispatchv4);
- requestmgr->dispatchv6 = NULL;
- if (dispatchv6 != NULL)
- dns_dispatch_attach(dispatchv6, &requestmgr->dispatchv6);
- requestmgr->mctx = NULL;
- isc_mem_attach(mctx, &requestmgr->mctx);
- requestmgr->eref = 1; /* implicit attach */
- requestmgr->iref = 0;
- ISC_LIST_INIT(requestmgr->whenshutdown);
- ISC_LIST_INIT(requestmgr->requests);
- requestmgr->exiting = ISC_FALSE;
- requestmgr->hash = 0;
- requestmgr->magic = REQUESTMGR_MAGIC;
-
- req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_create: %p", requestmgr);
-
- *requestmgrp = requestmgr;
- return (ISC_R_SUCCESS);
-}
-
-void
-dns_requestmgr_whenshutdown(dns_requestmgr_t *requestmgr, isc_task_t *task,
- isc_event_t **eventp)
-{
- isc_task_t *clone;
- isc_event_t *event;
-
- req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_whenshutdown");
-
- REQUIRE(VALID_REQUESTMGR(requestmgr));
- REQUIRE(eventp != NULL);
-
- event = *eventp;
- *eventp = NULL;
-
- LOCK(&requestmgr->lock);
-
- if (requestmgr->exiting) {
- /*
- * We're already shutdown. Send the event.
- */
- event->ev_sender = requestmgr;
- isc_task_send(task, &event);
- } else {
- clone = NULL;
- isc_task_attach(task, &clone);
- event->ev_sender = clone;
- ISC_LIST_APPEND(requestmgr->whenshutdown, event, ev_link);
- }
- UNLOCK(&requestmgr->lock);
-}
-
-void
-dns_requestmgr_shutdown(dns_requestmgr_t *requestmgr) {
-
- REQUIRE(VALID_REQUESTMGR(requestmgr));
-
- req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_shutdown: %p", requestmgr);
-
- LOCK(&requestmgr->lock);
- mgr_shutdown(requestmgr);
- UNLOCK(&requestmgr->lock);
-}
-
-static void
-mgr_shutdown(dns_requestmgr_t *requestmgr) {
- dns_request_t *request;
-
- /*
- * Caller holds lock.
- */
- if (!requestmgr->exiting) {
- requestmgr->exiting = ISC_TRUE;
- for (request = ISC_LIST_HEAD(requestmgr->requests);
- request != NULL;
- request = ISC_LIST_NEXT(request, link)) {
- dns_request_cancel(request);
- }
- if (requestmgr->iref == 0) {
- INSIST(ISC_LIST_EMPTY(requestmgr->requests));
- send_shutdown_events(requestmgr);
- }
- }
-}
-
-static void
-requestmgr_attach(dns_requestmgr_t *source, dns_requestmgr_t **targetp) {
-
- /*
- * Locked by caller.
- */
-
- REQUIRE(VALID_REQUESTMGR(source));
- REQUIRE(targetp != NULL && *targetp == NULL);
-
- REQUIRE(!source->exiting);
-
- source->iref++;
- *targetp = source;
-
- req_log(ISC_LOG_DEBUG(3), "requestmgr_attach: %p: eref %d iref %d",
- source, source->eref, source->iref);
-}
-
-static void
-requestmgr_detach(dns_requestmgr_t **requestmgrp) {
- dns_requestmgr_t *requestmgr;
- isc_boolean_t need_destroy = ISC_FALSE;
-
- REQUIRE(requestmgrp != NULL);
- requestmgr = *requestmgrp;
- REQUIRE(VALID_REQUESTMGR(requestmgr));
-
- *requestmgrp = NULL;
- LOCK(&requestmgr->lock);
- INSIST(requestmgr->iref > 0);
- requestmgr->iref--;
-
- req_log(ISC_LOG_DEBUG(3), "requestmgr_detach: %p: eref %d iref %d",
- requestmgr, requestmgr->eref, requestmgr->iref);
-
- if (requestmgr->iref == 0 && requestmgr->exiting) {
- INSIST(ISC_LIST_HEAD(requestmgr->requests) == NULL);
- send_shutdown_events(requestmgr);
- if (requestmgr->eref == 0)
- need_destroy = ISC_TRUE;
- }
- UNLOCK(&requestmgr->lock);
-
- if (need_destroy)
- mgr_destroy(requestmgr);
-}
-
-void
-dns_requestmgr_attach(dns_requestmgr_t *source, dns_requestmgr_t **targetp) {
-
- REQUIRE(VALID_REQUESTMGR(source));
- REQUIRE(targetp != NULL && *targetp == NULL);
- REQUIRE(!source->exiting);
-
- LOCK(&source->lock);
- source->eref++;
- *targetp = source;
- UNLOCK(&source->lock);
-
- req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_attach: %p: eref %d iref %d",
- source, source->eref, source->iref);
-}
-
-void
-dns_requestmgr_detach(dns_requestmgr_t **requestmgrp) {
- dns_requestmgr_t *requestmgr;
- isc_boolean_t need_destroy = ISC_FALSE;
-
- REQUIRE(requestmgrp != NULL);
- requestmgr = *requestmgrp;
- REQUIRE(VALID_REQUESTMGR(requestmgr));
-
- LOCK(&requestmgr->lock);
- INSIST(requestmgr->eref > 0);
- requestmgr->eref--;
-
- req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_detach: %p: eref %d iref %d",
- requestmgr, requestmgr->eref, requestmgr->iref);
-
- if (requestmgr->eref == 0 && requestmgr->iref == 0) {
- INSIST(requestmgr->exiting &&
- ISC_LIST_HEAD(requestmgr->requests) == NULL);
- need_destroy = ISC_TRUE;
- }
- UNLOCK(&requestmgr->lock);
-
- if (need_destroy)
- mgr_destroy(requestmgr);
-
- *requestmgrp = NULL;
-}
-
-static void
-send_shutdown_events(dns_requestmgr_t *requestmgr) {
- isc_event_t *event, *next_event;
- isc_task_t *etask;
-
- req_log(ISC_LOG_DEBUG(3), "send_shutdown_events: %p", requestmgr);
-
- /*
- * Caller must be holding the manager lock.
- */
- for (event = ISC_LIST_HEAD(requestmgr->whenshutdown);
- event != NULL;
- event = next_event) {
- next_event = ISC_LIST_NEXT(event, ev_link);
- ISC_LIST_UNLINK(requestmgr->whenshutdown, event, ev_link);
- etask = event->ev_sender;
- event->ev_sender = requestmgr;
- isc_task_sendanddetach(&etask, &event);
- }
-}
-
-static void
-mgr_destroy(dns_requestmgr_t *requestmgr) {
- int i;
- isc_mem_t *mctx;
-
- req_log(ISC_LOG_DEBUG(3), "mgr_destroy");
-
- REQUIRE(requestmgr->eref == 0);
- REQUIRE(requestmgr->iref == 0);
-
- DESTROYLOCK(&requestmgr->lock);
- for (i = 0; i < DNS_REQUEST_NLOCKS; i++)
- DESTROYLOCK(&requestmgr->locks[i]);
- if (requestmgr->dispatchv4 != NULL)
- dns_dispatch_detach(&requestmgr->dispatchv4);
- if (requestmgr->dispatchv6 != NULL)
- dns_dispatch_detach(&requestmgr->dispatchv6);
- requestmgr->magic = 0;
- mctx = requestmgr->mctx;
- isc_mem_put(mctx, requestmgr, sizeof(*requestmgr));
- isc_mem_detach(&mctx);
-}
-
-static unsigned int
-mgr_gethash(dns_requestmgr_t *requestmgr) {
- req_log(ISC_LOG_DEBUG(3), "mgr_gethash");
- /*
- * Locked by caller.
- */
- requestmgr->hash++;
- return (requestmgr->hash % DNS_REQUEST_NLOCKS);
-}
-
-static inline isc_result_t
-req_send(dns_request_t *request, isc_task_t *task, isc_sockaddr_t *address) {
- isc_region_t r;
- isc_socket_t *socket;
- isc_result_t result;
-
- req_log(ISC_LOG_DEBUG(3), "req_send: request %p", request);
-
- REQUIRE(VALID_REQUEST(request));
- socket = req_getsocket(request);
- isc_buffer_usedregion(request->query, &r);
- /*
- * We could connect the socket when we are using an exclusive dispatch
- * as we do in resolver.c, but we prefer implementation simplicity
- * at this moment.
- */
- result = isc_socket_sendto(socket, &r, task, req_senddone,
- request, address, NULL);
- if (result == ISC_R_SUCCESS)
- request->flags |= DNS_REQUEST_F_SENDING;
- return (result);
-}
-
-static isc_result_t
-new_request(isc_mem_t *mctx, dns_request_t **requestp)
-{
- dns_request_t *request;
-
- request = isc_mem_get(mctx, sizeof(*request));
- if (request == NULL)
- return (ISC_R_NOMEMORY);
-
- /*
- * Zero structure.
- */
- request->magic = 0;
- request->mctx = NULL;
- request->flags = 0;
- ISC_LINK_INIT(request, link);
- request->query = NULL;
- request->answer = NULL;
- request->event = NULL;
- request->dispatch = NULL;
- request->dispentry = NULL;
- request->timer = NULL;
- request->requestmgr = NULL;
- request->tsig = NULL;
- request->tsigkey = NULL;
- ISC_EVENT_INIT(&request->ctlevent, sizeof(request->ctlevent), 0, NULL,
- DNS_EVENT_REQUESTCONTROL, do_cancel, request, NULL,
- NULL, NULL);
- request->canceling = ISC_FALSE;
- request->udpcount = 0;
-
- isc_mem_attach(mctx, &request->mctx);
-
- request->magic = REQUEST_MAGIC;
- *requestp = request;
- return (ISC_R_SUCCESS);
-}
-
-
-static isc_boolean_t
-isblackholed(dns_dispatchmgr_t *dispatchmgr, isc_sockaddr_t *destaddr) {
- dns_acl_t *blackhole;
- isc_netaddr_t netaddr;
- int match;
- isc_boolean_t drop = ISC_FALSE;
- char netaddrstr[ISC_NETADDR_FORMATSIZE];
-
- blackhole = dns_dispatchmgr_getblackhole(dispatchmgr);
- if (blackhole != NULL) {
- isc_netaddr_fromsockaddr(&netaddr, destaddr);
- if (dns_acl_match(&netaddr, NULL, blackhole,
- NULL, &match, NULL) == ISC_R_SUCCESS &&
- match > 0)
- drop = ISC_TRUE;
- }
- if (drop) {
- isc_netaddr_format(&netaddr, netaddrstr, sizeof(netaddrstr));
- req_log(ISC_LOG_DEBUG(10), "blackholed address %s", netaddrstr);
- }
- return (drop);
-}
-
-static isc_result_t
-create_tcp_dispatch(dns_requestmgr_t *requestmgr, isc_sockaddr_t *srcaddr,
- isc_sockaddr_t *destaddr, dns_dispatch_t **dispatchp)
-{
- isc_result_t result;
- isc_socket_t *socket = NULL;
- isc_sockaddr_t src;
- unsigned int attrs;
- isc_sockaddr_t bind_any;
-
- result = isc_socket_create(requestmgr->socketmgr,
- isc_sockaddr_pf(destaddr),
- isc_sockettype_tcp, &socket);
- if (result != ISC_R_SUCCESS)
- return (result);
-#ifndef BROKEN_TCP_BIND_BEFORE_CONNECT
- if (srcaddr == NULL) {
- isc_sockaddr_anyofpf(&bind_any,
- isc_sockaddr_pf(destaddr));
- result = isc_socket_bind(socket, &bind_any, 0);
- } else {
- src = *srcaddr;
- isc_sockaddr_setport(&src, 0);
- result = isc_socket_bind(socket, &src, 0);
- }
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-#endif
- attrs = 0;
- attrs |= DNS_DISPATCHATTR_TCP;
- attrs |= DNS_DISPATCHATTR_PRIVATE;
- if (isc_sockaddr_pf(destaddr) == AF_INET)
- attrs |= DNS_DISPATCHATTR_IPV4;
- else
- attrs |= DNS_DISPATCHATTR_IPV6;
- attrs |= DNS_DISPATCHATTR_MAKEQUERY;
- result = dns_dispatch_createtcp(requestmgr->dispatchmgr,
- socket, requestmgr->taskmgr,
- 4096, 2, 1, 1, 3, attrs,
- dispatchp);
-cleanup:
- isc_socket_detach(&socket);
- return (result);
-}
-
-static isc_result_t
-find_udp_dispatch(dns_requestmgr_t *requestmgr, isc_sockaddr_t *srcaddr,
- isc_sockaddr_t *destaddr, dns_dispatch_t **dispatchp)
-{
- dns_dispatch_t *disp = NULL;
- unsigned int attrs, attrmask;
-
- if (srcaddr == NULL) {
- switch (isc_sockaddr_pf(destaddr)) {
- case PF_INET:
- disp = requestmgr->dispatchv4;
- break;
-
- case PF_INET6:
- disp = requestmgr->dispatchv6;
- break;
-
- default:
- return (ISC_R_NOTIMPLEMENTED);
- }
- if (disp == NULL)
- return (ISC_R_FAMILYNOSUPPORT);
- dns_dispatch_attach(disp, dispatchp);
- return (ISC_R_SUCCESS);
- }
- attrs = 0;
- attrs |= DNS_DISPATCHATTR_UDP;
- switch (isc_sockaddr_pf(srcaddr)) {
- case PF_INET:
- attrs |= DNS_DISPATCHATTR_IPV4;
- break;
-
- case PF_INET6:
- attrs |= DNS_DISPATCHATTR_IPV6;
- break;
-
- default:
- return (ISC_R_NOTIMPLEMENTED);
- }
- attrmask = 0;
- attrmask |= DNS_DISPATCHATTR_UDP;
- attrmask |= DNS_DISPATCHATTR_TCP;
- attrmask |= DNS_DISPATCHATTR_IPV4;
- attrmask |= DNS_DISPATCHATTR_IPV6;
- return (dns_dispatch_getudp(requestmgr->dispatchmgr,
- requestmgr->socketmgr,
- requestmgr->taskmgr,
- srcaddr, 4096,
- 1000, 32768, 16411, 16433,
- attrs, attrmask,
- dispatchp));
-}
-
-static isc_result_t
-get_dispatch(isc_boolean_t tcp, dns_requestmgr_t *requestmgr,
- isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
- dns_dispatch_t **dispatchp)
-{
- isc_result_t result;
- if (tcp)
- result = create_tcp_dispatch(requestmgr, srcaddr,
- destaddr, dispatchp);
- else
- result = find_udp_dispatch(requestmgr, srcaddr,
- destaddr, dispatchp);
- return (result);
-}
-
-static isc_result_t
-set_timer(isc_timer_t *timer, unsigned int timeout, unsigned int udpresend) {
- isc_time_t expires;
- isc_interval_t interval;
- isc_result_t result;
- isc_timertype_t timertype;
-
- isc_interval_set(&interval, timeout, 0);
- result = isc_time_nowplusinterval(&expires, &interval);
- isc_interval_set(&interval, udpresend, 0);
-
- timertype = udpresend != 0 ? isc_timertype_limited : isc_timertype_once;
- if (result == ISC_R_SUCCESS)
- result = isc_timer_reset(timer, timertype, &expires,
- &interval, ISC_FALSE);
- return (result);
-}
-
-isc_result_t
-dns_request_createraw(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
- isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
- unsigned int options, unsigned int timeout,
- isc_task_t *task, isc_taskaction_t action, void *arg,
- dns_request_t **requestp)
-{
- return(dns_request_createraw3(requestmgr, msgbuf, srcaddr, destaddr,
- options, timeout, 0, 0, task, action,
- arg, requestp));
-}
-
-isc_result_t
-dns_request_createraw2(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
- isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
- unsigned int options, unsigned int timeout,
- unsigned int udptimeout, isc_task_t *task,
- isc_taskaction_t action, void *arg,
- dns_request_t **requestp)
-{
- unsigned int udpretries = 0;
-
- if (udptimeout != 0)
- udpretries = timeout / udptimeout;
-
- return (dns_request_createraw3(requestmgr, msgbuf, srcaddr, destaddr,
- options, timeout, udptimeout,
- udpretries, task, action, arg,
- requestp));
-}
-
-isc_result_t
-dns_request_createraw3(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
- isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
- unsigned int options, unsigned int timeout,
- unsigned int udptimeout, unsigned int udpretries,
- isc_task_t *task, isc_taskaction_t action, void *arg,
- dns_request_t **requestp)
-{
- dns_request_t *request = NULL;
- isc_task_t *tclone = NULL;
- isc_socket_t *socket = NULL;
- isc_result_t result;
- isc_mem_t *mctx;
- dns_messageid_t id;
- isc_boolean_t tcp = ISC_FALSE;
- isc_region_t r;
-
- REQUIRE(VALID_REQUESTMGR(requestmgr));
- REQUIRE(msgbuf != NULL);
- REQUIRE(destaddr != NULL);
- REQUIRE(task != NULL);
- REQUIRE(action != NULL);
- REQUIRE(requestp != NULL && *requestp == NULL);
- REQUIRE(timeout > 0);
- if (srcaddr != NULL)
- REQUIRE(isc_sockaddr_pf(srcaddr) == isc_sockaddr_pf(destaddr));
-
- mctx = requestmgr->mctx;
-
- req_log(ISC_LOG_DEBUG(3), "dns_request_createraw");
-
- if (isblackholed(requestmgr->dispatchmgr, destaddr))
- return (DNS_R_BLACKHOLED);
-
- request = NULL;
- result = new_request(mctx, &request);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- if (udptimeout == 0 && udpretries != 0) {
- udptimeout = timeout / (udpretries + 1);
- if (udptimeout == 0)
- udptimeout = 1;
- }
- request->udpcount = udpretries;
-
- /*
- * Create timer now. We will set it below once.
- */
- result = isc_timer_create(requestmgr->timermgr, isc_timertype_inactive,
- NULL, NULL, task, req_timeout, request,
- &request->timer);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- request->event = (dns_requestevent_t *)
- isc_event_allocate(mctx, task, DNS_EVENT_REQUESTDONE,
- action, arg, sizeof(dns_requestevent_t));
- if (request->event == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup;
- }
- isc_task_attach(task, &tclone);
- request->event->ev_sender = task;
- request->event->request = request;
- request->event->result = ISC_R_FAILURE;
-
- isc_buffer_usedregion(msgbuf, &r);
- if (r.length < DNS_MESSAGE_HEADERLEN || r.length > 65535) {
- result = DNS_R_FORMERR;
- goto cleanup;
- }
-
- if ((options & DNS_REQUESTOPT_TCP) != 0 || r.length > 512)
- tcp = ISC_TRUE;
-
- result = get_dispatch(tcp, requestmgr, srcaddr, destaddr,
- &request->dispatch);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- result = dns_dispatch_addresponse2(request->dispatch, destaddr, task,
- req_response, request, &id,
- &request->dispentry,
- requestmgr->socketmgr);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- socket = req_getsocket(request);
- INSIST(socket != NULL);
-
- result = isc_buffer_allocate(mctx, &request->query,
- r.length + (tcp ? 2 : 0));
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- if (tcp)
- isc_buffer_putuint16(request->query, (isc_uint16_t)r.length);
- result = isc_buffer_copyregion(request->query, &r);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- /* Add message ID. */
- isc_buffer_usedregion(request->query, &r);
- if (tcp)
- isc_region_consume(&r, 2);
- r.base[0] = (id>>8) & 0xff;
- r.base[1] = id & 0xff;
-
- LOCK(&requestmgr->lock);
- if (requestmgr->exiting) {
- UNLOCK(&requestmgr->lock);
- result = ISC_R_SHUTTINGDOWN;
- goto cleanup;
- }
- requestmgr_attach(requestmgr, &request->requestmgr);
- request->hash = mgr_gethash(requestmgr);
- ISC_LIST_APPEND(requestmgr->requests, request, link);
- UNLOCK(&requestmgr->lock);
-
- result = set_timer(request->timer, timeout, tcp ? 0 : udptimeout);
- if (result != ISC_R_SUCCESS)
- goto unlink;
-
- request->destaddr = *destaddr;
- if (tcp) {
- result = isc_socket_connect(socket, destaddr, task,
- req_connected, request);
- if (result != ISC_R_SUCCESS)
- goto unlink;
- request->flags |= DNS_REQUEST_F_CONNECTING|DNS_REQUEST_F_TCP;
- } else {
- result = req_send(request, task, destaddr);
- if (result != ISC_R_SUCCESS)
- goto unlink;
- }
-
- req_log(ISC_LOG_DEBUG(3), "dns_request_createraw: request %p",
- request);
- *requestp = request;
- return (ISC_R_SUCCESS);
-
- unlink:
- LOCK(&requestmgr->lock);
- ISC_LIST_UNLINK(requestmgr->requests, request, link);
- UNLOCK(&requestmgr->lock);
-
- cleanup:
- if (tclone != NULL)
- isc_task_detach(&tclone);
- req_destroy(request);
- req_log(ISC_LOG_DEBUG(3), "dns_request_createraw: failed %s",
- dns_result_totext(result));
- return (result);
-}
-
-isc_result_t
-dns_request_create(dns_requestmgr_t *requestmgr, dns_message_t *message,
- isc_sockaddr_t *address, unsigned int options,
- dns_tsigkey_t *key,
- unsigned int timeout, isc_task_t *task,
- isc_taskaction_t action, void *arg,
- dns_request_t **requestp)
-{
- return (dns_request_createvia3(requestmgr, message, NULL, address,
- options, key, timeout, 0, 0, task,
- action, arg, requestp));
-}
-
-isc_result_t
-dns_request_createvia(dns_requestmgr_t *requestmgr, dns_message_t *message,
- isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
- unsigned int options, dns_tsigkey_t *key,
- unsigned int timeout, isc_task_t *task,
- isc_taskaction_t action, void *arg,
- dns_request_t **requestp)
-{
- return(dns_request_createvia3(requestmgr, message, srcaddr, destaddr,
- options, key, timeout, 0, 0, task,
- action, arg, requestp));
-}
-
-isc_result_t
-dns_request_createvia2(dns_requestmgr_t *requestmgr, dns_message_t *message,
- isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
- unsigned int options, dns_tsigkey_t *key,
- unsigned int timeout, unsigned int udptimeout,
- isc_task_t *task, isc_taskaction_t action, void *arg,
- dns_request_t **requestp)
-{
- unsigned int udpretries = 0;
-
- if (udptimeout != 0)
- udpretries = timeout / udptimeout;
- return (dns_request_createvia3(requestmgr, message, srcaddr, destaddr,
- options, key, timeout, udptimeout,
- udpretries, task, action, arg,
- requestp));
-}
-
-isc_result_t
-dns_request_createvia3(dns_requestmgr_t *requestmgr, dns_message_t *message,
- isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
- unsigned int options, dns_tsigkey_t *key,
- unsigned int timeout, unsigned int udptimeout,
- unsigned int udpretries, isc_task_t *task,
- isc_taskaction_t action, void *arg,
- dns_request_t **requestp)
-{
- dns_request_t *request = NULL;
- isc_task_t *tclone = NULL;
- isc_socket_t *socket = NULL;
- isc_result_t result;
- isc_mem_t *mctx;
- dns_messageid_t id;
- isc_boolean_t tcp;
- isc_boolean_t setkey = ISC_TRUE;
-
- REQUIRE(VALID_REQUESTMGR(requestmgr));
- REQUIRE(message != NULL);
- REQUIRE(destaddr != NULL);
- REQUIRE(task != NULL);
- REQUIRE(action != NULL);
- REQUIRE(requestp != NULL && *requestp == NULL);
- REQUIRE(timeout > 0);
-
- mctx = requestmgr->mctx;
-
- req_log(ISC_LOG_DEBUG(3), "dns_request_createvia");
-
- if (srcaddr != NULL &&
- isc_sockaddr_pf(srcaddr) != isc_sockaddr_pf(destaddr))
- return (ISC_R_FAMILYMISMATCH);
-
- if (isblackholed(requestmgr->dispatchmgr, destaddr))
- return (DNS_R_BLACKHOLED);
-
- request = NULL;
- result = new_request(mctx, &request);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- if (udptimeout == 0 && udpretries != 0) {
- udptimeout = timeout / (udpretries + 1);
- if (udptimeout == 0)
- udptimeout = 1;
- }
- request->udpcount = udpretries;
-
- /*
- * Create timer now. We will set it below once.
- */
- result = isc_timer_create(requestmgr->timermgr, isc_timertype_inactive,
- NULL, NULL, task, req_timeout, request,
- &request->timer);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- request->event = (dns_requestevent_t *)
- isc_event_allocate(mctx, task, DNS_EVENT_REQUESTDONE,
- action, arg, sizeof(dns_requestevent_t));
- if (request->event == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup;
- }
- isc_task_attach(task, &tclone);
- request->event->ev_sender = task;
- request->event->request = request;
- request->event->result = ISC_R_FAILURE;
- if (key != NULL)
- dns_tsigkey_attach(key, &request->tsigkey);
-
- use_tcp:
- tcp = ISC_TF((options & DNS_REQUESTOPT_TCP) != 0);
- result = get_dispatch(tcp, requestmgr, srcaddr, destaddr,
- &request->dispatch);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- result = dns_dispatch_addresponse2(request->dispatch, destaddr, task,
- req_response, request, &id,
- &request->dispentry,
- requestmgr->socketmgr);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- socket = req_getsocket(request);
- INSIST(socket != NULL);
-
- message->id = id;
- if (setkey) {
- result = dns_message_settsigkey(message, request->tsigkey);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- }
- result = req_render(message, &request->query, options, mctx);
- if (result == DNS_R_USETCP &&
- (options & DNS_REQUESTOPT_TCP) == 0) {
- /*
- * Try again using TCP.
- */
- dns_message_renderreset(message);
- dns_dispatch_removeresponse(&request->dispentry, NULL);
- dns_dispatch_detach(&request->dispatch);
- socket = NULL;
- options |= DNS_REQUESTOPT_TCP;
- setkey = ISC_FALSE;
- goto use_tcp;
- }
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- result = dns_message_getquerytsig(message, mctx, &request->tsig);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- LOCK(&requestmgr->lock);
- if (requestmgr->exiting) {
- UNLOCK(&requestmgr->lock);
- result = ISC_R_SHUTTINGDOWN;
- goto cleanup;
- }
- requestmgr_attach(requestmgr, &request->requestmgr);
- request->hash = mgr_gethash(requestmgr);
- ISC_LIST_APPEND(requestmgr->requests, request, link);
- UNLOCK(&requestmgr->lock);
-
- result = set_timer(request->timer, timeout, tcp ? 0 : udptimeout);
- if (result != ISC_R_SUCCESS)
- goto unlink;
-
- request->destaddr = *destaddr;
- if (tcp) {
- result = isc_socket_connect(socket, destaddr, task,
- req_connected, request);
- if (result != ISC_R_SUCCESS)
- goto unlink;
- request->flags |= DNS_REQUEST_F_CONNECTING|DNS_REQUEST_F_TCP;
- } else {
- result = req_send(request, task, destaddr);
- if (result != ISC_R_SUCCESS)
- goto unlink;
- }
-
- req_log(ISC_LOG_DEBUG(3), "dns_request_createvia: request %p",
- request);
- *requestp = request;
- return (ISC_R_SUCCESS);
-
- unlink:
- LOCK(&requestmgr->lock);
- ISC_LIST_UNLINK(requestmgr->requests, request, link);
- UNLOCK(&requestmgr->lock);
-
- cleanup:
- if (tclone != NULL)
- isc_task_detach(&tclone);
- req_destroy(request);
- req_log(ISC_LOG_DEBUG(3), "dns_request_createvia: failed %s",
- dns_result_totext(result));
- return (result);
-}
-
-static isc_result_t
-req_render(dns_message_t *message, isc_buffer_t **bufferp,
- unsigned int options, isc_mem_t *mctx)
-{
- isc_buffer_t *buf1 = NULL;
- isc_buffer_t *buf2 = NULL;
- isc_result_t result;
- isc_region_t r;
- isc_boolean_t tcp = ISC_FALSE;
- dns_compress_t cctx;
- isc_boolean_t cleanup_cctx = ISC_FALSE;
-
- REQUIRE(bufferp != NULL && *bufferp == NULL);
-
- req_log(ISC_LOG_DEBUG(3), "request_render");
-
- /*
- * Create buffer able to hold largest possible message.
- */
- result = isc_buffer_allocate(mctx, &buf1, 65535);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- result = dns_compress_init(&cctx, -1, mctx);
- if (result != ISC_R_SUCCESS)
- return (result);
- cleanup_cctx = ISC_TRUE;
-
- if ((options & DNS_REQUESTOPT_CASE) != 0)
- dns_compress_setsensitive(&cctx, ISC_TRUE);
-
- /*
- * Render message.
- */
- result = dns_message_renderbegin(message, &cctx, buf1);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- result = dns_message_rendersection(message, DNS_SECTION_QUESTION, 0);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- result = dns_message_rendersection(message, DNS_SECTION_ANSWER, 0);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- result = dns_message_rendersection(message, DNS_SECTION_AUTHORITY, 0);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- result = dns_message_rendersection(message, DNS_SECTION_ADDITIONAL, 0);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- result = dns_message_renderend(message);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- dns_compress_invalidate(&cctx);
- cleanup_cctx = ISC_FALSE;
-
- /*
- * Copy rendered message to exact sized buffer.
- */
- isc_buffer_usedregion(buf1, &r);
- if ((options & DNS_REQUESTOPT_TCP) != 0) {
- tcp = ISC_TRUE;
- } else if (r.length > 512) {
- result = DNS_R_USETCP;
- goto cleanup;
- }
- result = isc_buffer_allocate(mctx, &buf2, r.length + (tcp ? 2 : 0));
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- if (tcp)
- isc_buffer_putuint16(buf2, (isc_uint16_t)r.length);
- result = isc_buffer_copyregion(buf2, &r);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- /*
- * Cleanup and return.
- */
- isc_buffer_free(&buf1);
- *bufferp = buf2;
- return (ISC_R_SUCCESS);
-
- cleanup:
- dns_message_renderreset(message);
- if (buf1 != NULL)
- isc_buffer_free(&buf1);
- if (buf2 != NULL)
- isc_buffer_free(&buf2);
- if (cleanup_cctx)
- dns_compress_invalidate(&cctx);
- return (result);
-}
-
-
-/*
- * If this request is no longer waiting for events,
- * send the completion event. This will ultimately
- * cause the request to be destroyed.
- *
- * Requires:
- * 'request' is locked by the caller.
- */
-static void
-send_if_done(dns_request_t *request, isc_result_t result) {
- if (request->event != NULL && !request->canceling)
- req_sendevent(request, result);
-}
-
-/*
- * Handle the control event.
- */
-static void
-do_cancel(isc_task_t *task, isc_event_t *event) {
- dns_request_t *request = event->ev_arg;
- UNUSED(task);
- INSIST(event->ev_type == DNS_EVENT_REQUESTCONTROL);
- LOCK(&request->requestmgr->locks[request->hash]);
- request->canceling = ISC_FALSE;
- if (!DNS_REQUEST_CANCELED(request))
- req_cancel(request);
- send_if_done(request, ISC_R_CANCELED);
- UNLOCK(&request->requestmgr->locks[request->hash]);
-}
-
-void
-dns_request_cancel(dns_request_t *request) {
- REQUIRE(VALID_REQUEST(request));
-
- req_log(ISC_LOG_DEBUG(3), "dns_request_cancel: request %p", request);
-
- REQUIRE(VALID_REQUEST(request));
-
- LOCK(&request->requestmgr->locks[request->hash]);
- if (!request->canceling && !DNS_REQUEST_CANCELED(request)) {
- isc_event_t *ev = &request->ctlevent;
- isc_task_send(request->event->ev_sender, &ev);
- request->canceling = ISC_TRUE;
- }
- UNLOCK(&request->requestmgr->locks[request->hash]);
-}
-
-isc_result_t
-dns_request_getresponse(dns_request_t *request, dns_message_t *message,
- unsigned int options)
-{
- isc_result_t result;
-
- REQUIRE(VALID_REQUEST(request));
- REQUIRE(request->answer != NULL);
-
- req_log(ISC_LOG_DEBUG(3), "dns_request_getresponse: request %p",
- request);
-
- result = dns_message_setquerytsig(message, request->tsig);
- if (result != ISC_R_SUCCESS)
- return (result);
- result = dns_message_settsigkey(message, request->tsigkey);
- if (result != ISC_R_SUCCESS)
- return (result);
- result = dns_message_parse(message, request->answer, options);
- if (result != ISC_R_SUCCESS)
- return (result);
- if (request->tsigkey != NULL)
- result = dns_tsig_verify(request->answer, message, NULL, NULL);
- return (result);
-}
-
-isc_boolean_t
-dns_request_usedtcp(dns_request_t *request) {
- REQUIRE(VALID_REQUEST(request));
-
- return (ISC_TF((request->flags & DNS_REQUEST_F_TCP) != 0));
-}
-
-void
-dns_request_destroy(dns_request_t **requestp) {
- dns_request_t *request;
-
- REQUIRE(requestp != NULL && VALID_REQUEST(*requestp));
-
- request = *requestp;
-
- req_log(ISC_LOG_DEBUG(3), "dns_request_destroy: request %p", request);
-
- LOCK(&request->requestmgr->lock);
- LOCK(&request->requestmgr->locks[request->hash]);
- ISC_LIST_UNLINK(request->requestmgr->requests, request, link);
- INSIST(!DNS_REQUEST_CONNECTING(request));
- INSIST(!DNS_REQUEST_SENDING(request));
- UNLOCK(&request->requestmgr->locks[request->hash]);
- UNLOCK(&request->requestmgr->lock);
-
- /*
- * These should have been cleaned up by req_cancel() before
- * the completion event was sent.
- */
- INSIST(!ISC_LINK_LINKED(request, link));
- INSIST(request->dispentry == NULL);
- INSIST(request->dispatch == NULL);
- INSIST(request->timer == NULL);
-
- req_destroy(request);
-
- *requestp = NULL;
-}
-
-/***
- *** Private: request.
- ***/
-
-static isc_socket_t *
-req_getsocket(dns_request_t *request) {
- unsigned int dispattr;
- isc_socket_t *socket;
-
- dispattr = dns_dispatch_getattributes(request->dispatch);
- if ((dispattr & DNS_DISPATCHATTR_EXCLUSIVE) != 0) {
- INSIST(request->dispentry != NULL);
- socket = dns_dispatch_getentrysocket(request->dispentry);
- } else
- socket = dns_dispatch_getsocket(request->dispatch);
-
- return (socket);
-}
-
-static void
-req_connected(isc_task_t *task, isc_event_t *event) {
- isc_socketevent_t *sevent = (isc_socketevent_t *)event;
- isc_result_t result;
- dns_request_t *request = event->ev_arg;
-
- REQUIRE(event->ev_type == ISC_SOCKEVENT_CONNECT);
- REQUIRE(VALID_REQUEST(request));
- REQUIRE(DNS_REQUEST_CONNECTING(request));
-
- req_log(ISC_LOG_DEBUG(3), "req_connected: request %p", request);
-
- LOCK(&request->requestmgr->locks[request->hash]);
- request->flags &= ~DNS_REQUEST_F_CONNECTING;
-
- if (DNS_REQUEST_CANCELED(request)) {
- /*
- * Send delayed event.
- */
- if (DNS_REQUEST_TIMEDOUT(request))
- send_if_done(request, ISC_R_TIMEDOUT);
- else
- send_if_done(request, ISC_R_CANCELED);
- } else {
- dns_dispatch_starttcp(request->dispatch);
- result = sevent->result;
- if (result == ISC_R_SUCCESS)
- result = req_send(request, task, NULL);
-
- if (result != ISC_R_SUCCESS) {
- req_cancel(request);
- send_if_done(request, ISC_R_CANCELED);
- }
- }
- UNLOCK(&request->requestmgr->locks[request->hash]);
- isc_event_free(&event);
-}
-
-static void
-req_senddone(isc_task_t *task, isc_event_t *event) {
- isc_socketevent_t *sevent = (isc_socketevent_t *)event;
- dns_request_t *request = event->ev_arg;
-
- REQUIRE(event->ev_type == ISC_SOCKEVENT_SENDDONE);
- REQUIRE(VALID_REQUEST(request));
- REQUIRE(DNS_REQUEST_SENDING(request));
-
- req_log(ISC_LOG_DEBUG(3), "req_senddone: request %p", request);
-
- UNUSED(task);
-
- LOCK(&request->requestmgr->locks[request->hash]);
- request->flags &= ~DNS_REQUEST_F_SENDING;
-
- if (DNS_REQUEST_CANCELED(request)) {
- /*
- * Send delayed event.
- */
- if (DNS_REQUEST_TIMEDOUT(request))
- send_if_done(request, ISC_R_TIMEDOUT);
- else
- send_if_done(request, ISC_R_CANCELED);
- } else if (sevent->result != ISC_R_SUCCESS) {
- req_cancel(request);
- send_if_done(request, ISC_R_CANCELED);
- }
- UNLOCK(&request->requestmgr->locks[request->hash]);
-
- isc_event_free(&event);
-}
-
-static void
-req_response(isc_task_t *task, isc_event_t *event) {
- isc_result_t result;
- dns_request_t *request = event->ev_arg;
- dns_dispatchevent_t *devent = (dns_dispatchevent_t *)event;
- isc_region_t r;
-
- REQUIRE(VALID_REQUEST(request));
- REQUIRE(event->ev_type == DNS_EVENT_DISPATCH);
-
- UNUSED(task);
-
- req_log(ISC_LOG_DEBUG(3), "req_response: request %p: %s", request,
- dns_result_totext(devent->result));
-
- LOCK(&request->requestmgr->locks[request->hash]);
- result = devent->result;
- if (result != ISC_R_SUCCESS)
- goto done;
-
- /*
- * Copy buffer to request.
- */
- isc_buffer_usedregion(&devent->buffer, &r);
- result = isc_buffer_allocate(request->mctx, &request->answer,
- r.length);
- if (result != ISC_R_SUCCESS)
- goto done;
- result = isc_buffer_copyregion(request->answer, &r);
- if (result != ISC_R_SUCCESS)
- isc_buffer_free(&request->answer);
- done:
- /*
- * Cleanup.
- */
- dns_dispatch_removeresponse(&request->dispentry, &devent);
- req_cancel(request);
- /*
- * Send completion event.
- */
- send_if_done(request, result);
- UNLOCK(&request->requestmgr->locks[request->hash]);
-}
-
-static void
-req_timeout(isc_task_t *task, isc_event_t *event) {
- dns_request_t *request = event->ev_arg;
- isc_result_t result;
-
- REQUIRE(VALID_REQUEST(request));
-
- req_log(ISC_LOG_DEBUG(3), "req_timeout: request %p", request);
-
- UNUSED(task);
- LOCK(&request->requestmgr->locks[request->hash]);
- if (event->ev_type == ISC_TIMEREVENT_TICK &&
- request->udpcount-- != 0) {
- if (! DNS_REQUEST_SENDING(request)) {
- result = req_send(request, task, &request->destaddr);
- if (result != ISC_R_SUCCESS) {
- req_cancel(request);
- send_if_done(request, result);
- }
- }
- } else {
- request->flags |= DNS_REQUEST_F_TIMEDOUT;
- req_cancel(request);
- send_if_done(request, ISC_R_TIMEDOUT);
- }
- UNLOCK(&request->requestmgr->locks[request->hash]);
- isc_event_free(&event);
-}
-
-static void
-req_sendevent(dns_request_t *request, isc_result_t result) {
- isc_task_t *task;
-
- REQUIRE(VALID_REQUEST(request));
-
- req_log(ISC_LOG_DEBUG(3), "req_sendevent: request %p", request);
-
- /*
- * Lock held by caller.
- */
- task = request->event->ev_sender;
- request->event->ev_sender = request;
- request->event->result = result;
- isc_task_sendanddetach(&task, (isc_event_t **)&request->event);
-}
-
-static void
-req_destroy(dns_request_t *request) {
- isc_mem_t *mctx;
-
- REQUIRE(VALID_REQUEST(request));
-
- req_log(ISC_LOG_DEBUG(3), "req_destroy: request %p", request);
-
- request->magic = 0;
- if (request->query != NULL)
- isc_buffer_free(&request->query);
- if (request->answer != NULL)
- isc_buffer_free(&request->answer);
- if (request->event != NULL)
- isc_event_free((isc_event_t **)&request->event);
- if (request->dispentry != NULL)
- dns_dispatch_removeresponse(&request->dispentry, NULL);
- if (request->dispatch != NULL)
- dns_dispatch_detach(&request->dispatch);
- if (request->timer != NULL)
- isc_timer_detach(&request->timer);
- if (request->tsig != NULL)
- isc_buffer_free(&request->tsig);
- if (request->tsigkey != NULL)
- dns_tsigkey_detach(&request->tsigkey);
- if (request->requestmgr != NULL)
- requestmgr_detach(&request->requestmgr);
- mctx = request->mctx;
- isc_mem_put(mctx, request, sizeof(*request));
- isc_mem_detach(&mctx);
-}
-
-/*
- * Stop the current request. Must be called from the request's task.
- */
-static void
-req_cancel(dns_request_t *request) {
- isc_socket_t *socket;
- unsigned int dispattr;
-
- REQUIRE(VALID_REQUEST(request));
-
- req_log(ISC_LOG_DEBUG(3), "req_cancel: request %p", request);
-
- /*
- * Lock held by caller.
- */
- request->flags |= DNS_REQUEST_F_CANCELED;
-
- if (request->timer != NULL)
- isc_timer_detach(&request->timer);
- dispattr = dns_dispatch_getattributes(request->dispatch);
- socket = NULL;
- if (DNS_REQUEST_CONNECTING(request) || DNS_REQUEST_SENDING(request)) {
- if ((dispattr & DNS_DISPATCHATTR_EXCLUSIVE) != 0) {
- if (request->dispentry != NULL) {
- socket = dns_dispatch_getentrysocket(
- request->dispentry);
- }
- } else
- socket = dns_dispatch_getsocket(request->dispatch);
- if (DNS_REQUEST_CONNECTING(request) && socket != NULL)
- isc_socket_cancel(socket, NULL, ISC_SOCKCANCEL_CONNECT);
- if (DNS_REQUEST_SENDING(request) && socket != NULL)
- isc_socket_cancel(socket, NULL, ISC_SOCKCANCEL_SEND);
- }
- if (request->dispentry != NULL)
- dns_dispatch_removeresponse(&request->dispentry, NULL);
- dns_dispatch_detach(&request->dispatch);
-}
-
-static void
-req_log(int level, const char *fmt, ...) {
- va_list ap;
-
- va_start(ap, fmt);
- isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL,
- DNS_LOGMODULE_REQUEST, level, fmt, ap);
- va_end(ap);
-}
diff --git a/contrib/bind9/lib/dns/resolver.c b/contrib/bind9/lib/dns/resolver.c
deleted file mode 100644
index 27d15b9329cd..000000000000
--- a/contrib/bind9/lib/dns/resolver.c
+++ /dev/null
@@ -1,9040 +0,0 @@
-/*
- * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <isc/log.h>
-#include <isc/platform.h>
-#include <isc/print.h>
-#include <isc/string.h>
-#include <isc/random.h>
-#include <isc/socket.h>
-#include <isc/stats.h>
-#include <isc/task.h>
-#include <isc/timer.h>
-#include <isc/util.h>
-
-#include <dns/acl.h>
-#include <dns/adb.h>
-#include <dns/cache.h>
-#include <dns/db.h>
-#include <dns/dispatch.h>
-#include <dns/ds.h>
-#include <dns/events.h>
-#include <dns/forward.h>
-#include <dns/keytable.h>
-#include <dns/log.h>
-#include <dns/message.h>
-#include <dns/ncache.h>
-#include <dns/nsec.h>
-#include <dns/nsec3.h>
-#include <dns/opcode.h>
-#include <dns/peer.h>
-#include <dns/rbt.h>
-#include <dns/rcode.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/resolver.h>
-#include <dns/result.h>
-#include <dns/rootns.h>
-#include <dns/stats.h>
-#include <dns/tsig.h>
-#include <dns/validator.h>
-
-#define DNS_RESOLVER_TRACE
-#ifdef DNS_RESOLVER_TRACE
-#define RTRACE(m) isc_log_write(dns_lctx, \
- DNS_LOGCATEGORY_RESOLVER, \
- DNS_LOGMODULE_RESOLVER, \
- ISC_LOG_DEBUG(3), \
- "res %p: %s", res, (m))
-#define RRTRACE(r, m) isc_log_write(dns_lctx, \
- DNS_LOGCATEGORY_RESOLVER, \
- DNS_LOGMODULE_RESOLVER, \
- ISC_LOG_DEBUG(3), \
- "res %p: %s", (r), (m))
-#define FCTXTRACE(m) isc_log_write(dns_lctx, \
- DNS_LOGCATEGORY_RESOLVER, \
- DNS_LOGMODULE_RESOLVER, \
- ISC_LOG_DEBUG(3), \
- "fctx %p(%s): %s", fctx, fctx->info, (m))
-#define FCTXTRACE2(m1, m2) \
- isc_log_write(dns_lctx, \
- DNS_LOGCATEGORY_RESOLVER, \
- DNS_LOGMODULE_RESOLVER, \
- ISC_LOG_DEBUG(3), \
- "fctx %p(%s): %s %s", \
- fctx, fctx->info, (m1), (m2))
-#define FTRACE(m) isc_log_write(dns_lctx, \
- DNS_LOGCATEGORY_RESOLVER, \
- DNS_LOGMODULE_RESOLVER, \
- ISC_LOG_DEBUG(3), \
- "fetch %p (fctx %p(%s)): %s", \
- fetch, fetch->private, \
- fetch->private->info, (m))
-#define QTRACE(m) isc_log_write(dns_lctx, \
- DNS_LOGCATEGORY_RESOLVER, \
- DNS_LOGMODULE_RESOLVER, \
- ISC_LOG_DEBUG(3), \
- "resquery %p (fctx %p(%s)): %s", \
- query, query->fctx, \
- query->fctx->info, (m))
-#else
-#define RTRACE(m)
-#define RRTRACE(r, m)
-#define FCTXTRACE(m)
-#define FTRACE(m)
-#define QTRACE(m)
-#endif
-
-#define US_PER_SEC 1000000U
-/*
- * The maximum time we will wait for a single query.
- */
-#define MAX_SINGLE_QUERY_TIMEOUT 9U
-#define MAX_SINGLE_QUERY_TIMEOUT_US (MAX_SINGLE_QUERY_TIMEOUT*US_PER_SEC)
-
-/*
- * We need to allow a individual query time to complete / timeout.
- */
-#define MINIMUM_QUERY_TIMEOUT (MAX_SINGLE_QUERY_TIMEOUT + 1U)
-
-/* The default time in seconds for the whole query to live. */
-#ifndef DEFAULT_QUERY_TIMEOUT
-#define DEFAULT_QUERY_TIMEOUT MINIMUM_QUERY_TIMEOUT
-#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.
- */
-#define RECV_BUFFER_SIZE 4096 /* XXXRTH Constant. */
-#define EDNSOPTS 2
-
-/*%
- * This defines the maximum number of timeouts we will permit before we
- * disable EDNS0 on the query.
- */
-#define MAX_EDNS0_TIMEOUTS 3
-
-typedef struct fetchctx fetchctx_t;
-
-typedef struct query {
- /* Locked by task event serialization. */
- unsigned int magic;
- fetchctx_t * fctx;
- isc_mem_t * mctx;
- dns_dispatchmgr_t * dispatchmgr;
- dns_dispatch_t * dispatch;
- isc_boolean_t exclusivesocket;
- dns_adbaddrinfo_t * addrinfo;
- isc_socket_t * tcpsocket;
- isc_time_t start;
- dns_messageid_t id;
- dns_dispentry_t * dispentry;
- ISC_LINK(struct query) link;
- isc_buffer_t buffer;
- isc_buffer_t *tsig;
- dns_tsigkey_t *tsigkey;
- isc_socketevent_t sendevent;
- unsigned int options;
- unsigned int attributes;
- unsigned int sends;
- unsigned int connects;
- unsigned char data[512];
-} resquery_t;
-
-#define QUERY_MAGIC ISC_MAGIC('Q', '!', '!', '!')
-#define VALID_QUERY(query) ISC_MAGIC_VALID(query, QUERY_MAGIC)
-
-#define RESQUERY_ATTR_CANCELED 0x02
-
-#define RESQUERY_CONNECTING(q) ((q)->connects > 0)
-#define RESQUERY_CANCELED(q) (((q)->attributes & \
- RESQUERY_ATTR_CANCELED) != 0)
-#define RESQUERY_SENDING(q) ((q)->sends > 0)
-
-typedef enum {
- fetchstate_init = 0, /*%< Start event has not run yet. */
- fetchstate_active,
- fetchstate_done /*%< FETCHDONE events posted. */
-} fetchstate;
-
-typedef enum {
- badns_unreachable = 0,
- badns_response,
- badns_validation
-} badnstype_t;
-
-struct fetchctx {
- /*% Not locked. */
- unsigned int magic;
- dns_resolver_t * res;
- dns_name_t name;
- dns_rdatatype_t type;
- unsigned int options;
- unsigned int bucketnum;
- char * info;
- isc_mem_t * mctx;
-
- /*% Locked by appropriate bucket lock. */
- fetchstate state;
- isc_boolean_t want_shutdown;
- isc_boolean_t cloned;
- isc_boolean_t spilled;
- unsigned int references;
- isc_event_t control_event;
- ISC_LINK(struct fetchctx) link;
- ISC_LIST(dns_fetchevent_t) events;
- /*% Locked by task event serialization. */
- dns_name_t domain;
- dns_rdataset_t nameservers;
- unsigned int attributes;
- isc_timer_t * timer;
- isc_time_t expires;
- isc_interval_t interval;
- dns_message_t * qmessage;
- dns_message_t * rmessage;
- ISC_LIST(resquery_t) queries;
- dns_adbfindlist_t finds;
- dns_adbfind_t * find;
- dns_adbfindlist_t altfinds;
- dns_adbfind_t * altfind;
- dns_adbaddrinfolist_t forwaddrs;
- dns_adbaddrinfolist_t altaddrs;
- isc_sockaddrlist_t forwarders;
- dns_fwdpolicy_t fwdpolicy;
- isc_sockaddrlist_t bad;
- isc_sockaddrlist_t edns;
- isc_sockaddrlist_t edns512;
- isc_sockaddrlist_t bad_edns;
- dns_validator_t *validator;
- ISC_LIST(dns_validator_t) validators;
- dns_db_t * cache;
- dns_adb_t * adb;
- isc_boolean_t ns_ttl_ok;
- isc_uint32_t ns_ttl;
-
- /*%
- * The number of events we're waiting for.
- */
- unsigned int pending;
-
- /*%
- * The number of times we've "restarted" the current
- * nameserver set. This acts as a failsafe to prevent
- * us from pounding constantly on a particular set of
- * servers that, for whatever reason, are not giving
- * us useful responses, but are responding in such a
- * way that they are not marked "bad".
- */
- unsigned int restarts;
-
- /*%
- * The number of timeouts that have occurred since we
- * last successfully received a response packet. This
- * is used for EDNS0 black hole detection.
- */
- unsigned int timeouts;
-
- /*%
- * Look aside state for DS lookups.
- */
- dns_name_t nsname;
- dns_fetch_t * nsfetch;
- dns_rdataset_t nsrrset;
-
- /*%
- * Number of queries that reference this context.
- */
- unsigned int nqueries;
-
- /*%
- * The reason to print when logging a successful
- * response to a query.
- */
- const char * reason;
-
- /*%
- * Random numbers to use for mixing up server addresses.
- */
- isc_uint32_t rand_buf;
- isc_uint32_t rand_bits;
-
- /*%
- * Fetch-local statistics for detailed logging.
- */
- isc_result_t result; /*%< fetch result */
- isc_result_t vresult; /*%< validation result */
- int exitline;
- isc_time_t start;
- isc_uint64_t duration;
- isc_boolean_t logged;
- unsigned int querysent;
- unsigned int referrals;
- unsigned int lamecount;
- unsigned int neterr;
- unsigned int badresp;
- unsigned int adberr;
- unsigned int findfail;
- unsigned int valfail;
- isc_boolean_t timeout;
- dns_adbaddrinfo_t *addrinfo;
- isc_sockaddr_t *client;
-};
-
-#define FCTX_MAGIC ISC_MAGIC('F', '!', '!', '!')
-#define VALID_FCTX(fctx) ISC_MAGIC_VALID(fctx, FCTX_MAGIC)
-
-#define FCTX_ATTR_HAVEANSWER 0x0001
-#define FCTX_ATTR_GLUING 0x0002
-#define FCTX_ATTR_ADDRWAIT 0x0004
-#define FCTX_ATTR_SHUTTINGDOWN 0x0008
-#define FCTX_ATTR_WANTCACHE 0x0010
-#define FCTX_ATTR_WANTNCACHE 0x0020
-#define FCTX_ATTR_NEEDEDNS0 0x0040
-#define FCTX_ATTR_TRIEDFIND 0x0080
-#define FCTX_ATTR_TRIEDALT 0x0100
-
-#define HAVE_ANSWER(f) (((f)->attributes & FCTX_ATTR_HAVEANSWER) != \
- 0)
-#define GLUING(f) (((f)->attributes & FCTX_ATTR_GLUING) != \
- 0)
-#define ADDRWAIT(f) (((f)->attributes & FCTX_ATTR_ADDRWAIT) != \
- 0)
-#define SHUTTINGDOWN(f) (((f)->attributes & FCTX_ATTR_SHUTTINGDOWN) \
- != 0)
-#define WANTCACHE(f) (((f)->attributes & FCTX_ATTR_WANTCACHE) != 0)
-#define WANTNCACHE(f) (((f)->attributes & FCTX_ATTR_WANTNCACHE) != 0)
-#define NEEDEDNS0(f) (((f)->attributes & FCTX_ATTR_NEEDEDNS0) != 0)
-#define TRIEDFIND(f) (((f)->attributes & FCTX_ATTR_TRIEDFIND) != 0)
-#define TRIEDALT(f) (((f)->attributes & FCTX_ATTR_TRIEDALT) != 0)
-
-typedef struct {
- dns_adbaddrinfo_t * addrinfo;
- fetchctx_t * fctx;
-} dns_valarg_t;
-
-struct dns_fetch {
- unsigned int magic;
- fetchctx_t * private;
-};
-
-#define DNS_FETCH_MAGIC ISC_MAGIC('F', 't', 'c', 'h')
-#define DNS_FETCH_VALID(fetch) ISC_MAGIC_VALID(fetch, DNS_FETCH_MAGIC)
-
-typedef struct fctxbucket {
- isc_task_t * task;
- isc_mutex_t lock;
- ISC_LIST(fetchctx_t) fctxs;
- isc_boolean_t exiting;
- isc_mem_t * mctx;
-} fctxbucket_t;
-
-typedef struct alternate {
- isc_boolean_t isaddress;
- union {
- isc_sockaddr_t addr;
- struct {
- dns_name_t name;
- in_port_t port;
- } _n;
- } _u;
- ISC_LINK(struct alternate) link;
-} alternate_t;
-
-typedef struct dns_badcache dns_badcache_t;
-struct dns_badcache {
- dns_badcache_t * next;
- dns_rdatatype_t type;
- isc_time_t expire;
- unsigned int hashval;
- dns_name_t name;
-};
-#define DNS_BADCACHE_SIZE 1021
-#define DNS_BADCACHE_TTL(fctx) \
- (((fctx)->res->lame_ttl > 30 ) ? (fctx)->res->lame_ttl : 30)
-
-struct dns_resolver {
- /* Unlocked. */
- unsigned int magic;
- isc_mem_t * mctx;
- isc_mutex_t lock;
- isc_mutex_t nlock;
- isc_mutex_t primelock;
- dns_rdataclass_t rdclass;
- isc_socketmgr_t * socketmgr;
- isc_timermgr_t * timermgr;
- isc_taskmgr_t * taskmgr;
- dns_view_t * view;
- isc_boolean_t frozen;
- unsigned int options;
- dns_dispatchmgr_t * dispatchmgr;
- dns_dispatchset_t * dispatches4;
- isc_boolean_t exclusivev4;
- dns_dispatchset_t * dispatches6;
- isc_boolean_t exclusivev6;
- unsigned int nbuckets;
- fctxbucket_t * buckets;
- isc_uint32_t lame_ttl;
- ISC_LIST(alternate_t) alternates;
- isc_uint16_t udpsize;
-#if USE_ALGLOCK
- isc_rwlock_t alglock;
-#endif
- dns_rbt_t * algorithms;
-#if USE_MBSLOCK
- isc_rwlock_t mbslock;
-#endif
- dns_rbt_t * mustbesecure;
- unsigned int spillatmax;
- unsigned int spillatmin;
- isc_timer_t * spillattimer;
- isc_boolean_t zero_no_soa_ttl;
- unsigned int query_timeout;
-
- /* Locked by lock. */
- unsigned int references;
- isc_boolean_t exiting;
- isc_eventlist_t whenshutdown;
- unsigned int activebuckets;
- isc_boolean_t priming;
- unsigned int spillat; /* clients-per-query */
-
- /* Bad cache. */
- dns_badcache_t ** badcache;
- unsigned int badcount;
- unsigned int badhash;
- unsigned int badsweep;
-
- /* Locked by primelock. */
- dns_fetch_t * primefetch;
- /* Locked by nlock. */
- unsigned int nfctx;
-};
-
-#define RES_MAGIC ISC_MAGIC('R', 'e', 's', '!')
-#define VALID_RESOLVER(res) ISC_MAGIC_VALID(res, RES_MAGIC)
-
-/*%
- * Private addrinfo flags. These must not conflict with DNS_FETCHOPT_NOEDNS0,
- * which we also use as an addrinfo flag.
- */
-#define FCTX_ADDRINFO_MARK 0x0001
-#define FCTX_ADDRINFO_FORWARDER 0x1000
-#define FCTX_ADDRINFO_TRIED 0x2000
-#define UNMARKED(a) (((a)->flags & FCTX_ADDRINFO_MARK) \
- == 0)
-#define ISFORWARDER(a) (((a)->flags & \
- FCTX_ADDRINFO_FORWARDER) != 0)
-#define TRIED(a) (((a)->flags & \
- FCTX_ADDRINFO_TRIED) != 0)
-
-#define NXDOMAIN(r) (((r)->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0)
-#define NEGATIVE(r) (((r)->attributes & DNS_RDATASETATTR_NEGATIVE) != 0)
-
-static void destroy(dns_resolver_t *res);
-static void empty_bucket(dns_resolver_t *res);
-static isc_result_t resquery_send(resquery_t *query);
-static void resquery_response(isc_task_t *task, isc_event_t *event);
-static void resquery_connected(isc_task_t *task, isc_event_t *event);
-static void fctx_try(fetchctx_t *fctx, isc_boolean_t retrying,
- isc_boolean_t badcache);
-static void fctx_destroy(fetchctx_t *fctx);
-static isc_boolean_t fctx_unlink(fetchctx_t *fctx);
-static isc_result_t ncache_adderesult(dns_message_t *message,
- dns_db_t *cache, dns_dbnode_t *node,
- dns_rdatatype_t covers,
- isc_stdtime_t now, dns_ttl_t maxttl,
- isc_boolean_t optout,
- isc_boolean_t secure,
- dns_rdataset_t *ardataset,
- isc_result_t *eresultp);
-static void validated(isc_task_t *task, isc_event_t *event);
-static isc_boolean_t maybe_destroy(fetchctx_t *fctx, isc_boolean_t locked);
-static void add_bad(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
- isc_result_t reason, badnstype_t badtype);
-static inline isc_result_t findnoqname(fetchctx_t *fctx, dns_name_t *name,
- dns_rdatatype_t type,
- dns_name_t **noqname);
-
-/*%
- * Increment resolver-related statistics counters.
- */
-static inline void
-inc_stats(dns_resolver_t *res, isc_statscounter_t counter) {
- if (res->view->resstats != NULL)
- isc_stats_increment(res->view->resstats, counter);
-}
-
-static isc_result_t
-valcreate(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, dns_name_t *name,
- dns_rdatatype_t type, dns_rdataset_t *rdataset,
- dns_rdataset_t *sigrdataset, unsigned int valoptions,
- isc_task_t *task)
-{
- dns_validator_t *validator = NULL;
- dns_valarg_t *valarg;
- isc_result_t result;
-
- valarg = isc_mem_get(fctx->mctx, sizeof(*valarg));
- if (valarg == NULL)
- return (ISC_R_NOMEMORY);
-
- valarg->fctx = fctx;
- valarg->addrinfo = addrinfo;
-
- if (!ISC_LIST_EMPTY(fctx->validators))
- INSIST((valoptions & DNS_VALIDATOR_DEFER) != 0);
-
- result = dns_validator_create(fctx->res->view, name, type, rdataset,
- sigrdataset, fctx->rmessage,
- valoptions, task, validated, valarg,
- &validator);
- if (result == ISC_R_SUCCESS) {
- inc_stats(fctx->res, dns_resstatscounter_val);
- if ((valoptions & DNS_VALIDATOR_DEFER) == 0) {
- INSIST(fctx->validator == NULL);
- fctx->validator = validator;
- }
- ISC_LIST_APPEND(fctx->validators, validator, link);
- } else
- isc_mem_put(fctx->mctx, valarg, sizeof(*valarg));
- return (result);
-}
-
-static isc_boolean_t
-rrsig_fromchildzone(fetchctx_t *fctx, dns_rdataset_t *rdataset) {
- dns_namereln_t namereln;
- dns_rdata_rrsig_t rrsig;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- int order;
- isc_result_t result;
- unsigned int labels;
-
- 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);
- namereln = dns_name_fullcompare(&rrsig.signer, &fctx->domain,
- &order, &labels);
- if (namereln == dns_namereln_subdomain)
- return (ISC_TRUE);
- dns_rdata_reset(&rdata);
- }
- return (ISC_FALSE);
-}
-
-static isc_boolean_t
-fix_mustbedelegationornxdomain(dns_message_t *message, fetchctx_t *fctx) {
- dns_name_t *name;
- dns_name_t *domain = &fctx->domain;
- dns_rdataset_t *rdataset;
- dns_rdatatype_t type;
- isc_result_t result;
- isc_boolean_t keep_auth = ISC_FALSE;
-
- if (message->rcode == dns_rcode_nxdomain)
- return (ISC_FALSE);
-
- /*
- * A DS RRset can appear anywhere in a zone, even for a delegation-only
- * zone. So a response to an explicit query for this type should be
- * excluded from delegation-only fixup.
- *
- * SOA, NS, and DNSKEY can only exist at a zone apex, so a postive
- * response to a query for these types can never violate the
- * delegation-only assumption: if the query name is below a
- * zone cut, the response should normally be a referral, which should
- * be accepted; if the query name is below a zone cut but the server
- * happens to have authority for the zone of the query name, the
- * response is a (non-referral) answer. But this does not violate
- * delegation-only because the query name must be in a different zone
- * due to the "apex-only" nature of these types. Note that if the
- * remote server happens to have authority for a child zone of a
- * delegation-only zone, we may still incorrectly "fix" the response
- * with NXDOMAIN for queries for other types. Unfortunately it's
- * generally impossible to differentiate this case from violation of
- * the delegation-only assumption. Once the resolver learns the
- * correct zone cut, possibly via a separate query for an "apex-only"
- * type, queries for other types will be resolved correctly.
- *
- * A query for type ANY will be accepted if it hits an exceptional
- * type above in the answer section as it should be from a child
- * zone.
- *
- * Also accept answers with RRSIG records from the child zone.
- * Direct queries for RRSIG records should not be answered from
- * the parent zone.
- */
-
- if (message->counts[DNS_SECTION_ANSWER] != 0 &&
- (fctx->type == dns_rdatatype_ns ||
- fctx->type == dns_rdatatype_ds ||
- fctx->type == dns_rdatatype_soa ||
- fctx->type == dns_rdatatype_any ||
- fctx->type == dns_rdatatype_rrsig ||
- fctx->type == dns_rdatatype_dnskey)) {
- result = dns_message_firstname(message, DNS_SECTION_ANSWER);
- while (result == ISC_R_SUCCESS) {
- name = NULL;
- dns_message_currentname(message, DNS_SECTION_ANSWER,
- &name);
- for (rdataset = ISC_LIST_HEAD(name->list);
- rdataset != NULL;
- rdataset = ISC_LIST_NEXT(rdataset, link)) {
- if (!dns_name_equal(name, &fctx->name))
- continue;
- type = rdataset->type;
- /*
- * RRsig from child?
- */
- if (type == dns_rdatatype_rrsig &&
- rrsig_fromchildzone(fctx, rdataset))
- return (ISC_FALSE);
- /*
- * Direct query for apex records or DS.
- */
- if (fctx->type == type &&
- (type == dns_rdatatype_ds ||
- type == dns_rdatatype_ns ||
- type == dns_rdatatype_soa ||
- type == dns_rdatatype_dnskey))
- return (ISC_FALSE);
- /*
- * Indirect query for apex records or DS.
- */
- if (fctx->type == dns_rdatatype_any &&
- (type == dns_rdatatype_ns ||
- type == dns_rdatatype_ds ||
- type == dns_rdatatype_soa ||
- type == dns_rdatatype_dnskey))
- return (ISC_FALSE);
- }
- result = dns_message_nextname(message,
- DNS_SECTION_ANSWER);
- }
- }
-
- /*
- * A NODATA response to a DS query?
- */
- if (fctx->type == dns_rdatatype_ds &&
- message->counts[DNS_SECTION_ANSWER] == 0)
- return (ISC_FALSE);
-
- /* Look for referral or indication of answer from child zone? */
- if (message->counts[DNS_SECTION_AUTHORITY] == 0)
- goto munge;
-
- result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
- while (result == ISC_R_SUCCESS) {
- name = NULL;
- dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name);
- for (rdataset = ISC_LIST_HEAD(name->list);
- rdataset != NULL;
- rdataset = ISC_LIST_NEXT(rdataset, link)) {
- type = rdataset->type;
- if (type == dns_rdatatype_soa &&
- dns_name_equal(name, domain))
- keep_auth = ISC_TRUE;
-
- if (type != dns_rdatatype_ns &&
- type != dns_rdatatype_soa &&
- type != dns_rdatatype_rrsig)
- continue;
-
- if (type == dns_rdatatype_rrsig) {
- if (rrsig_fromchildzone(fctx, rdataset))
- return (ISC_FALSE);
- else
- continue;
- }
-
- /* NS or SOA records. */
- if (dns_name_equal(name, domain)) {
- /*
- * If a query for ANY causes a negative
- * response, we can be sure that this is
- * an empty node. For other type of queries
- * we cannot differentiate an empty node
- * from a node that just doesn't have that
- * type of record. We only accept the former
- * case.
- */
- if (message->counts[DNS_SECTION_ANSWER] == 0 &&
- fctx->type == dns_rdatatype_any)
- return (ISC_FALSE);
- } else if (dns_name_issubdomain(name, domain)) {
- /* Referral or answer from child zone. */
- return (ISC_FALSE);
- }
- }
- result = dns_message_nextname(message, DNS_SECTION_AUTHORITY);
- }
-
- munge:
- message->rcode = dns_rcode_nxdomain;
- message->counts[DNS_SECTION_ANSWER] = 0;
- if (!keep_auth)
- message->counts[DNS_SECTION_AUTHORITY] = 0;
- message->counts[DNS_SECTION_ADDITIONAL] = 0;
- return (ISC_TRUE);
-}
-
-static inline isc_result_t
-fctx_starttimer(fetchctx_t *fctx) {
- /*
- * Start the lifetime timer for fctx.
- *
- * This is also used for stopping the idle timer; in that
- * case we must purge events already posted to ensure that
- * no further idle events are delivered.
- */
- return (isc_timer_reset(fctx->timer, isc_timertype_once,
- &fctx->expires, NULL, ISC_TRUE));
-}
-
-static inline void
-fctx_stoptimer(fetchctx_t *fctx) {
- isc_result_t result;
-
- /*
- * We don't return a result if resetting the timer to inactive fails
- * since there's nothing to be done about it. Resetting to inactive
- * should never fail anyway, since the code as currently written
- * cannot fail in that case.
- */
- result = isc_timer_reset(fctx->timer, isc_timertype_inactive,
- NULL, NULL, ISC_TRUE);
- if (result != ISC_R_SUCCESS) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_timer_reset(): %s",
- isc_result_totext(result));
- }
-}
-
-
-static inline isc_result_t
-fctx_startidletimer(fetchctx_t *fctx, isc_interval_t *interval) {
- /*
- * Start the idle timer for fctx. The lifetime timer continues
- * to be in effect.
- */
- return (isc_timer_reset(fctx->timer, isc_timertype_once,
- &fctx->expires, interval, ISC_FALSE));
-}
-
-/*
- * Stopping the idle timer is equivalent to calling fctx_starttimer(), but
- * we use fctx_stopidletimer for readability in the code below.
- */
-#define fctx_stopidletimer fctx_starttimer
-
-
-static inline void
-resquery_destroy(resquery_t **queryp) {
- resquery_t *query;
-
- REQUIRE(queryp != NULL);
- query = *queryp;
- REQUIRE(!ISC_LINK_LINKED(query, link));
-
- INSIST(query->tcpsocket == NULL);
-
- query->fctx->nqueries--;
- if (SHUTTINGDOWN(query->fctx)) {
- dns_resolver_t *res = query->fctx->res;
- if (maybe_destroy(query->fctx, ISC_FALSE))
- empty_bucket(res);
- }
- query->magic = 0;
- isc_mem_put(query->mctx, query, sizeof(*query));
- *queryp = NULL;
-}
-
-static void
-fctx_cancelquery(resquery_t **queryp, dns_dispatchevent_t **deventp,
- isc_time_t *finish, isc_boolean_t no_response)
-{
- fetchctx_t *fctx;
- resquery_t *query;
- unsigned int rtt, rttms;
- unsigned int factor;
- dns_adbfind_t *find;
- dns_adbaddrinfo_t *addrinfo;
- isc_socket_t *socket;
-
- query = *queryp;
- fctx = query->fctx;
-
- FCTXTRACE("cancelquery");
-
- REQUIRE(!RESQUERY_CANCELED(query));
-
- query->attributes |= RESQUERY_ATTR_CANCELED;
-
- /*
- * Should we update the RTT?
- */
- if (finish != NULL || no_response) {
- if (finish != NULL) {
- /*
- * We have both the start and finish times for this
- * packet, so we can compute a real RTT.
- */
- rtt = (unsigned int)isc_time_microdiff(finish,
- &query->start);
- factor = DNS_ADB_RTTADJDEFAULT;
-
- rttms = rtt / 1000;
- if (rttms < DNS_RESOLVER_QRYRTTCLASS0) {
- inc_stats(fctx->res,
- dns_resstatscounter_queryrtt0);
- } else if (rttms < DNS_RESOLVER_QRYRTTCLASS1) {
- inc_stats(fctx->res,
- dns_resstatscounter_queryrtt1);
- } else if (rttms < DNS_RESOLVER_QRYRTTCLASS2) {
- inc_stats(fctx->res,
- dns_resstatscounter_queryrtt2);
- } else if (rttms < DNS_RESOLVER_QRYRTTCLASS3) {
- inc_stats(fctx->res,
- dns_resstatscounter_queryrtt3);
- } else if (rttms < DNS_RESOLVER_QRYRTTCLASS4) {
- inc_stats(fctx->res,
- dns_resstatscounter_queryrtt4);
- } else {
- inc_stats(fctx->res,
- dns_resstatscounter_queryrtt5);
- }
- } else {
- /*
- * We don't have an RTT for this query. Maybe the
- * packet was lost, or maybe this server is very
- * slow. We don't know. Increase the RTT.
- */
- INSIST(no_response);
- rtt = query->addrinfo->srtt + 200000;
- if (rtt > MAX_SINGLE_QUERY_TIMEOUT_US)
- rtt = MAX_SINGLE_QUERY_TIMEOUT_US;
- /*
- * Replace the current RTT with our value.
- */
- factor = DNS_ADB_RTTADJREPLACE;
- }
- dns_adb_adjustsrtt(fctx->adb, query->addrinfo, rtt, factor);
- }
-
- /* Remember that the server has been tried. */
- if (!TRIED(query->addrinfo)) {
- dns_adb_changeflags(fctx->adb, query->addrinfo,
- FCTX_ADDRINFO_TRIED, FCTX_ADDRINFO_TRIED);
- }
-
- /*
- * Age RTTs of servers not tried.
- */
- factor = DNS_ADB_RTTADJAGE;
- if (finish != NULL)
- for (addrinfo = ISC_LIST_HEAD(fctx->forwaddrs);
- addrinfo != NULL;
- addrinfo = ISC_LIST_NEXT(addrinfo, publink))
- if (UNMARKED(addrinfo))
- dns_adb_adjustsrtt(fctx->adb, addrinfo,
- 0, factor);
-
- if (finish != NULL && TRIEDFIND(fctx))
- for (find = ISC_LIST_HEAD(fctx->finds);
- find != NULL;
- find = ISC_LIST_NEXT(find, publink))
- for (addrinfo = ISC_LIST_HEAD(find->list);
- addrinfo != NULL;
- addrinfo = ISC_LIST_NEXT(addrinfo, publink))
- if (UNMARKED(addrinfo))
- dns_adb_adjustsrtt(fctx->adb, addrinfo,
- 0, factor);
-
- if (finish != NULL && TRIEDALT(fctx)) {
- for (addrinfo = ISC_LIST_HEAD(fctx->altaddrs);
- addrinfo != NULL;
- addrinfo = ISC_LIST_NEXT(addrinfo, publink))
- if (UNMARKED(addrinfo))
- dns_adb_adjustsrtt(fctx->adb, addrinfo,
- 0, factor);
- for (find = ISC_LIST_HEAD(fctx->altfinds);
- find != NULL;
- find = ISC_LIST_NEXT(find, publink))
- for (addrinfo = ISC_LIST_HEAD(find->list);
- addrinfo != NULL;
- addrinfo = ISC_LIST_NEXT(addrinfo, publink))
- if (UNMARKED(addrinfo))
- dns_adb_adjustsrtt(fctx->adb, addrinfo,
- 0, factor);
- }
-
- /*
- * Check for any outstanding socket events. If they exist, cancel
- * them and let the event handlers finish the cleanup. The resolver
- * only needs to worry about managing the connect and send events;
- * the dispatcher manages the recv events.
- */
- if (RESQUERY_CONNECTING(query)) {
- /*
- * Cancel the connect.
- */
- if (query->tcpsocket != NULL) {
- isc_socket_cancel(query->tcpsocket, NULL,
- ISC_SOCKCANCEL_CONNECT);
- } else if (query->dispentry != NULL) {
- INSIST(query->exclusivesocket);
- socket = dns_dispatch_getentrysocket(query->dispentry);
- if (socket != NULL)
- isc_socket_cancel(socket, NULL,
- ISC_SOCKCANCEL_CONNECT);
- }
- } else if (RESQUERY_SENDING(query)) {
- /*
- * Cancel the pending send.
- */
- if (query->exclusivesocket && query->dispentry != NULL)
- socket = dns_dispatch_getentrysocket(query->dispentry);
- else
- socket = dns_dispatch_getsocket(query->dispatch);
- if (socket != NULL)
- isc_socket_cancel(socket, NULL, ISC_SOCKCANCEL_SEND);
- }
-
- if (query->dispentry != NULL)
- dns_dispatch_removeresponse(&query->dispentry, deventp);
-
- ISC_LIST_UNLINK(fctx->queries, query, link);
-
- if (query->tsig != NULL)
- isc_buffer_free(&query->tsig);
-
- if (query->tsigkey != NULL)
- dns_tsigkey_detach(&query->tsigkey);
-
- if (query->dispatch != NULL)
- dns_dispatch_detach(&query->dispatch);
-
- if (! (RESQUERY_CONNECTING(query) || RESQUERY_SENDING(query)))
- /*
- * It's safe to destroy the query now.
- */
- resquery_destroy(&query);
-}
-
-static void
-fctx_cancelqueries(fetchctx_t *fctx, isc_boolean_t no_response) {
- resquery_t *query, *next_query;
-
- FCTXTRACE("cancelqueries");
-
- for (query = ISC_LIST_HEAD(fctx->queries);
- query != NULL;
- query = next_query) {
- next_query = ISC_LIST_NEXT(query, link);
- fctx_cancelquery(&query, NULL, NULL, no_response);
- }
-}
-
-static void
-fctx_cleanupfinds(fetchctx_t *fctx) {
- dns_adbfind_t *find, *next_find;
-
- REQUIRE(ISC_LIST_EMPTY(fctx->queries));
-
- for (find = ISC_LIST_HEAD(fctx->finds);
- find != NULL;
- find = next_find) {
- next_find = ISC_LIST_NEXT(find, publink);
- ISC_LIST_UNLINK(fctx->finds, find, publink);
- dns_adb_destroyfind(&find);
- }
- fctx->find = NULL;
-}
-
-static void
-fctx_cleanupaltfinds(fetchctx_t *fctx) {
- dns_adbfind_t *find, *next_find;
-
- REQUIRE(ISC_LIST_EMPTY(fctx->queries));
-
- for (find = ISC_LIST_HEAD(fctx->altfinds);
- find != NULL;
- find = next_find) {
- next_find = ISC_LIST_NEXT(find, publink);
- ISC_LIST_UNLINK(fctx->altfinds, find, publink);
- dns_adb_destroyfind(&find);
- }
- fctx->altfind = NULL;
-}
-
-static void
-fctx_cleanupforwaddrs(fetchctx_t *fctx) {
- dns_adbaddrinfo_t *addr, *next_addr;
-
- REQUIRE(ISC_LIST_EMPTY(fctx->queries));
-
- for (addr = ISC_LIST_HEAD(fctx->forwaddrs);
- addr != NULL;
- addr = next_addr) {
- next_addr = ISC_LIST_NEXT(addr, publink);
- ISC_LIST_UNLINK(fctx->forwaddrs, addr, publink);
- dns_adb_freeaddrinfo(fctx->adb, &addr);
- }
-}
-
-static void
-fctx_cleanupaltaddrs(fetchctx_t *fctx) {
- dns_adbaddrinfo_t *addr, *next_addr;
-
- REQUIRE(ISC_LIST_EMPTY(fctx->queries));
-
- for (addr = ISC_LIST_HEAD(fctx->altaddrs);
- addr != NULL;
- addr = next_addr) {
- next_addr = ISC_LIST_NEXT(addr, publink);
- ISC_LIST_UNLINK(fctx->altaddrs, addr, publink);
- dns_adb_freeaddrinfo(fctx->adb, &addr);
- }
-}
-
-static inline void
-fctx_stopeverything(fetchctx_t *fctx, isc_boolean_t no_response) {
- FCTXTRACE("stopeverything");
- fctx_cancelqueries(fctx, no_response);
- fctx_cleanupfinds(fctx);
- fctx_cleanupaltfinds(fctx);
- fctx_cleanupforwaddrs(fctx);
- fctx_cleanupaltaddrs(fctx);
- fctx_stoptimer(fctx);
-}
-
-static inline void
-fctx_sendevents(fetchctx_t *fctx, isc_result_t result, int line) {
- dns_fetchevent_t *event, *next_event;
- isc_task_t *task;
- unsigned int count = 0;
- isc_interval_t i;
- isc_boolean_t logit = ISC_FALSE;
- isc_time_t now;
- unsigned int old_spillat;
- unsigned int new_spillat = 0; /* initialized to silence
- compiler warnings */
-
- /*
- * Caller must be holding the appropriate bucket lock.
- */
- REQUIRE(fctx->state == fetchstate_done);
-
- FCTXTRACE("sendevents");
-
- /*
- * Keep some record of fetch result for logging later (if required).
- */
- fctx->result = result;
- fctx->exitline = line;
- TIME_NOW(&now);
- fctx->duration = isc_time_microdiff(&now, &fctx->start);
-
- for (event = ISC_LIST_HEAD(fctx->events);
- event != NULL;
- event = next_event) {
- next_event = ISC_LIST_NEXT(event, ev_link);
- 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;
-
- INSIST(result != ISC_R_SUCCESS ||
- dns_rdataset_isassociated(event->rdataset) ||
- fctx->type == dns_rdatatype_any ||
- fctx->type == dns_rdatatype_rrsig ||
- fctx->type == dns_rdatatype_sig);
-
- /*
- * Negative results must be indicated in event->result.
- */
- if (dns_rdataset_isassociated(event->rdataset) &&
- NEGATIVE(event->rdataset)) {
- INSIST(event->result == DNS_R_NCACHENXDOMAIN ||
- event->result == DNS_R_NCACHENXRRSET);
- }
-
- isc_task_sendanddetach(&task, ISC_EVENT_PTR(&event));
- count++;
- }
-
- if ((fctx->attributes & FCTX_ATTR_HAVEANSWER) != 0 &&
- fctx->spilled &&
- (count < fctx->res->spillatmax || fctx->res->spillatmax == 0)) {
- LOCK(&fctx->res->lock);
- if (count == fctx->res->spillat && !fctx->res->exiting) {
- old_spillat = fctx->res->spillat;
- fctx->res->spillat += 5;
- if (fctx->res->spillat > fctx->res->spillatmax &&
- fctx->res->spillatmax != 0)
- fctx->res->spillat = fctx->res->spillatmax;
- new_spillat = fctx->res->spillat;
- if (new_spillat != old_spillat) {
- logit = ISC_TRUE;
- }
- isc_interval_set(&i, 20 * 60, 0);
- result = isc_timer_reset(fctx->res->spillattimer,
- isc_timertype_ticker, NULL,
- &i, ISC_TRUE);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- }
- UNLOCK(&fctx->res->lock);
- if (logit)
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
- DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE,
- "clients-per-query increased to %u",
- new_spillat);
- }
-}
-
-static inline void
-log_edns(fetchctx_t *fctx) {
- char domainbuf[DNS_NAME_FORMATSIZE];
-
- if (fctx->reason == NULL)
- return;
-
- dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf));
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_EDNS_DISABLED,
- DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO,
- "success resolving '%s' (in '%s'?) after %s",
- fctx->info, domainbuf, fctx->reason);
-
- fctx->reason = NULL;
-}
-
-static void
-fctx_done(fetchctx_t *fctx, isc_result_t result, int line) {
- dns_resolver_t *res;
- isc_boolean_t no_response;
-
- REQUIRE(line >= 0);
-
- FCTXTRACE("done");
-
- res = fctx->res;
-
- if (result == ISC_R_SUCCESS) {
- /*%
- * Log any deferred EDNS timeout messages.
- */
- log_edns(fctx);
- no_response = ISC_TRUE;
- } else
- no_response = ISC_FALSE;
-
- fctx->reason = NULL;
- fctx_stopeverything(fctx, no_response);
-
- LOCK(&res->buckets[fctx->bucketnum].lock);
-
- fctx->state = fetchstate_done;
- fctx->attributes &= ~FCTX_ATTR_ADDRWAIT;
- fctx_sendevents(fctx, result, line);
-
- UNLOCK(&res->buckets[fctx->bucketnum].lock);
-}
-
-static void
-process_sendevent(resquery_t *query, isc_event_t *event) {
- isc_socketevent_t *sevent = (isc_socketevent_t *)event;
- isc_boolean_t retry = ISC_FALSE;
- isc_result_t result;
- fetchctx_t *fctx;
-
- fctx = query->fctx;
-
- if (RESQUERY_CANCELED(query)) {
- if (query->sends == 0 && query->connects == 0) {
- /*
- * This query was canceled while the
- * isc_socket_sendto/connect() was in progress.
- */
- if (query->tcpsocket != NULL)
- isc_socket_detach(&query->tcpsocket);
- resquery_destroy(&query);
- }
- } else {
- switch (sevent->result) {
- case ISC_R_SUCCESS:
- break;
-
- case ISC_R_HOSTUNREACH:
- case ISC_R_NETUNREACH:
- case ISC_R_NOPERM:
- case ISC_R_ADDRNOTAVAIL:
- case ISC_R_CONNREFUSED:
-
- /*
- * No route to remote.
- */
- add_bad(fctx, query->addrinfo, sevent->result,
- badns_unreachable);
- fctx_cancelquery(&query, NULL, NULL, ISC_TRUE);
- retry = ISC_TRUE;
- break;
-
- default:
- fctx_cancelquery(&query, NULL, NULL, ISC_FALSE);
- break;
- }
- }
-
- if (event->ev_type == ISC_SOCKEVENT_CONNECT)
- isc_event_free(&event);
-
- if (retry) {
- /*
- * Behave as if the idle timer has expired. For TCP
- * this may not actually reflect the latest timer.
- */
- fctx->attributes &= ~FCTX_ATTR_ADDRWAIT;
- result = fctx_stopidletimer(fctx);
- if (result != ISC_R_SUCCESS)
- fctx_done(fctx, result, __LINE__);
- else
- fctx_try(fctx, ISC_TRUE, ISC_FALSE);
- }
-}
-
-static void
-resquery_udpconnected(isc_task_t *task, isc_event_t *event) {
- resquery_t *query = event->ev_arg;
-
- REQUIRE(event->ev_type == ISC_SOCKEVENT_CONNECT);
-
- QTRACE("udpconnected");
-
- UNUSED(task);
-
- INSIST(RESQUERY_CONNECTING(query));
-
- query->connects--;
-
- process_sendevent(query, event);
-}
-
-static void
-resquery_senddone(isc_task_t *task, isc_event_t *event) {
- resquery_t *query = event->ev_arg;
-
- REQUIRE(event->ev_type == ISC_SOCKEVENT_SENDDONE);
-
- QTRACE("senddone");
-
- /*
- * XXXRTH
- *
- * Currently we don't wait for the senddone event before retrying
- * a query. This means that if we get really behind, we may end
- * up doing extra work!
- */
-
- UNUSED(task);
-
- INSIST(RESQUERY_SENDING(query));
-
- query->sends--;
-
- process_sendevent(query, event);
-}
-
-static inline isc_result_t
-fctx_addopt(dns_message_t *message, unsigned int version,
- isc_uint16_t udpsize, dns_ednsopt_t *ednsopts, size_t count)
-{
- dns_rdataset_t *rdataset = NULL;
- isc_result_t result;
-
- result = dns_message_buildopt(message, &rdataset, version, udpsize,
- DNS_MESSAGEEXTFLAG_DO, ednsopts, count);
- if (result != ISC_R_SUCCESS)
- return (result);
- return (dns_message_setopt(message, rdataset));
-}
-
-static inline void
-fctx_setretryinterval(fetchctx_t *fctx, unsigned int rtt) {
- unsigned int seconds;
- unsigned int us;
-
- /*
- * We retry every .8 seconds the first two times through the address
- * list, and then we do exponential back-off.
- */
- if (fctx->restarts < 3)
- us = 800000;
- else
- us = (800000 << (fctx->restarts - 2));
-
- /*
- * Add a fudge factor to the expected rtt based on the current
- * estimate.
- */
- if (rtt < 50000)
- rtt += 50000;
- else if (rtt < 100000)
- rtt += 100000;
- else
- rtt += 200000;
-
- /*
- * Always wait for at least the expected rtt.
- */
- if (us < rtt)
- us = rtt;
-
- /*
- * But don't ever wait for more than 10 seconds.
- */
- if (us > MAX_SINGLE_QUERY_TIMEOUT_US)
- us = MAX_SINGLE_QUERY_TIMEOUT_US;
-
- seconds = us / US_PER_SEC;
- us -= seconds * US_PER_SEC;
- isc_interval_set(&fctx->interval, seconds, us * 1000);
-}
-
-static isc_result_t
-fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
- unsigned int options)
-{
- dns_resolver_t *res;
- isc_task_t *task;
- isc_result_t result;
- resquery_t *query;
- isc_sockaddr_t addr;
- isc_boolean_t have_addr = ISC_FALSE;
- unsigned int srtt;
-
- FCTXTRACE("query");
-
- res = fctx->res;
- task = res->buckets[fctx->bucketnum].task;
-
- srtt = addrinfo->srtt;
-
- /*
- * A forwarder needs to make multiple queries. Give it at least
- * a second to do these in.
- */
- if (ISFORWARDER(addrinfo) && srtt < 1000000)
- srtt = 1000000;
-
- fctx_setretryinterval(fctx, srtt);
- result = fctx_startidletimer(fctx, &fctx->interval);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- INSIST(ISC_LIST_EMPTY(fctx->validators));
-
- dns_message_reset(fctx->rmessage, DNS_MESSAGE_INTENTPARSE);
-
- query = isc_mem_get(fctx->mctx, sizeof(*query));
- if (query == NULL) {
- result = ISC_R_NOMEMORY;
- goto stop_idle_timer;
- }
- query->mctx = fctx->mctx;
- query->options = options;
- query->attributes = 0;
- query->sends = 0;
- query->connects = 0;
- /*
- * Note that the caller MUST guarantee that 'addrinfo' will remain
- * valid until this query is canceled.
- */
- query->addrinfo = addrinfo;
- TIME_NOW(&query->start);
-
- /*
- * If this is a TCP query, then we need to make a socket and
- * a dispatch for it here. Otherwise we use the resolver's
- * shared dispatch.
- */
- query->dispatchmgr = res->dispatchmgr;
- query->dispatch = NULL;
- query->exclusivesocket = ISC_FALSE;
- query->tcpsocket = NULL;
- if (res->view->peers != NULL) {
- dns_peer_t *peer = NULL;
- isc_netaddr_t dstip;
- isc_netaddr_fromsockaddr(&dstip, &addrinfo->sockaddr);
- result = dns_peerlist_peerbyaddr(res->view->peers,
- &dstip, &peer);
- if (result == ISC_R_SUCCESS) {
- result = dns_peer_getquerysource(peer, &addr);
- if (result == ISC_R_SUCCESS)
- have_addr = ISC_TRUE;
- }
- }
-
- if ((query->options & DNS_FETCHOPT_TCP) != 0) {
- int pf;
-
- pf = isc_sockaddr_pf(&addrinfo->sockaddr);
- if (!have_addr) {
- switch (pf) {
- case PF_INET:
- result = dns_dispatch_getlocaladdress(
- res->dispatches4->dispatches[0],
- &addr);
- break;
- case PF_INET6:
- result = dns_dispatch_getlocaladdress(
- res->dispatches6->dispatches[0],
- &addr);
- break;
- default:
- result = ISC_R_NOTIMPLEMENTED;
- break;
- }
- if (result != ISC_R_SUCCESS)
- goto cleanup_query;
- }
- isc_sockaddr_setport(&addr, 0);
-
- result = isc_socket_create(res->socketmgr, pf,
- isc_sockettype_tcp,
- &query->tcpsocket);
- if (result != ISC_R_SUCCESS)
- goto cleanup_query;
-
-#ifndef BROKEN_TCP_BIND_BEFORE_CONNECT
- result = isc_socket_bind(query->tcpsocket, &addr, 0);
- if (result != ISC_R_SUCCESS)
- goto cleanup_socket;
-#endif
-
- /*
- * A dispatch will be created once the connect succeeds.
- */
- } else {
- if (have_addr) {
- unsigned int attrs, attrmask;
- attrs = DNS_DISPATCHATTR_UDP;
- switch (isc_sockaddr_pf(&addr)) {
- case AF_INET:
- attrs |= DNS_DISPATCHATTR_IPV4;
- break;
- case AF_INET6:
- attrs |= DNS_DISPATCHATTR_IPV6;
- break;
- default:
- result = ISC_R_NOTIMPLEMENTED;
- goto cleanup_query;
- }
- attrmask = DNS_DISPATCHATTR_UDP;
- attrmask |= DNS_DISPATCHATTR_TCP;
- attrmask |= DNS_DISPATCHATTR_IPV4;
- attrmask |= DNS_DISPATCHATTR_IPV6;
- result = dns_dispatch_getudp(res->dispatchmgr,
- res->socketmgr,
- res->taskmgr, &addr,
- 4096, 1000, 32768, 16411,
- 16433, attrs, attrmask,
- &query->dispatch);
- if (result != ISC_R_SUCCESS)
- goto cleanup_query;
- } else {
- switch (isc_sockaddr_pf(&addrinfo->sockaddr)) {
- case PF_INET:
- dns_dispatch_attach(
- dns_resolver_dispatchv4(res),
- &query->dispatch);
- query->exclusivesocket = res->exclusivev4;
- break;
- case PF_INET6:
- dns_dispatch_attach(
- dns_resolver_dispatchv6(res),
- &query->dispatch);
- query->exclusivesocket = res->exclusivev6;
- break;
- default:
- result = ISC_R_NOTIMPLEMENTED;
- goto cleanup_query;
- }
- }
- /*
- * We should always have a valid dispatcher here. If we
- * don't support a protocol family, then its dispatcher
- * will be NULL, but we shouldn't be finding addresses for
- * protocol types we don't support, so the dispatcher
- * we found should never be NULL.
- */
- INSIST(query->dispatch != NULL);
- }
-
- query->dispentry = NULL;
- query->fctx = fctx;
- query->tsig = NULL;
- query->tsigkey = NULL;
- ISC_LINK_INIT(query, link);
- query->magic = QUERY_MAGIC;
-
- if ((query->options & DNS_FETCHOPT_TCP) != 0) {
- /*
- * Connect to the remote server.
- *
- * XXXRTH Should we attach to the socket?
- */
- result = isc_socket_connect(query->tcpsocket,
- &addrinfo->sockaddr, task,
- resquery_connected, query);
- if (result != ISC_R_SUCCESS)
- goto cleanup_socket;
- query->connects++;
- QTRACE("connecting via TCP");
- } else {
- result = resquery_send(query);
- if (result != ISC_R_SUCCESS)
- goto cleanup_dispatch;
- }
- fctx->querysent++;
-
- ISC_LIST_APPEND(fctx->queries, query, link);
- query->fctx->nqueries++;
- if (isc_sockaddr_pf(&addrinfo->sockaddr) == PF_INET)
- inc_stats(res, dns_resstatscounter_queryv4);
- else
- inc_stats(res, dns_resstatscounter_queryv6);
- if (res->view->resquerystats != NULL)
- dns_rdatatypestats_increment(res->view->resquerystats,
- fctx->type);
-
- return (ISC_R_SUCCESS);
-
- cleanup_socket:
- isc_socket_detach(&query->tcpsocket);
-
- cleanup_dispatch:
- if (query->dispatch != NULL)
- dns_dispatch_detach(&query->dispatch);
-
- cleanup_query:
- if (query->connects == 0) {
- query->magic = 0;
- isc_mem_put(fctx->mctx, query, sizeof(*query));
- }
-
- stop_idle_timer:
- RUNTIME_CHECK(fctx_stopidletimer(fctx) == ISC_R_SUCCESS);
-
- return (result);
-}
-
-static isc_boolean_t
-bad_edns(fetchctx_t *fctx, isc_sockaddr_t *address) {
- isc_sockaddr_t *sa;
-
- for (sa = ISC_LIST_HEAD(fctx->bad_edns);
- sa != NULL;
- sa = ISC_LIST_NEXT(sa, link)) {
- if (isc_sockaddr_equal(sa, address))
- return (ISC_TRUE);
- }
-
- return (ISC_FALSE);
-}
-
-static void
-add_bad_edns(fetchctx_t *fctx, isc_sockaddr_t *address) {
- isc_sockaddr_t *sa;
-
- if (bad_edns(fctx, address))
- return;
-
- sa = isc_mem_get(fctx->mctx, sizeof(*sa));
- if (sa == NULL)
- return;
-
- *sa = *address;
- ISC_LIST_INITANDAPPEND(fctx->bad_edns, sa, link);
-}
-
-static isc_boolean_t
-triededns(fetchctx_t *fctx, isc_sockaddr_t *address) {
- isc_sockaddr_t *sa;
-
- for (sa = ISC_LIST_HEAD(fctx->edns);
- sa != NULL;
- sa = ISC_LIST_NEXT(sa, link)) {
- if (isc_sockaddr_equal(sa, address))
- return (ISC_TRUE);
- }
-
- return (ISC_FALSE);
-}
-
-static void
-add_triededns(fetchctx_t *fctx, isc_sockaddr_t *address) {
- isc_sockaddr_t *sa;
-
- if (triededns(fctx, address))
- return;
-
- sa = isc_mem_get(fctx->mctx, sizeof(*sa));
- if (sa == NULL)
- return;
-
- *sa = *address;
- ISC_LIST_INITANDAPPEND(fctx->edns, sa, link);
-}
-
-static isc_boolean_t
-triededns512(fetchctx_t *fctx, isc_sockaddr_t *address) {
- isc_sockaddr_t *sa;
-
- for (sa = ISC_LIST_HEAD(fctx->edns512);
- sa != NULL;
- sa = ISC_LIST_NEXT(sa, link)) {
- if (isc_sockaddr_equal(sa, address))
- return (ISC_TRUE);
- }
-
- return (ISC_FALSE);
-}
-
-static void
-add_triededns512(fetchctx_t *fctx, isc_sockaddr_t *address) {
- isc_sockaddr_t *sa;
-
- if (triededns512(fctx, address))
- return;
-
- sa = isc_mem_get(fctx->mctx, sizeof(*sa));
- if (sa == NULL)
- return;
-
- *sa = *address;
- ISC_LIST_INITANDAPPEND(fctx->edns512, sa, link);
-}
-
-static isc_result_t
-resquery_send(resquery_t *query) {
- fetchctx_t *fctx;
- isc_result_t result;
- dns_name_t *qname = NULL;
- dns_rdataset_t *qrdataset = NULL;
- isc_region_t r;
- dns_resolver_t *res;
- isc_task_t *task;
- isc_socket_t *socket;
- isc_buffer_t tcpbuffer;
- isc_sockaddr_t *address;
- isc_buffer_t *buffer;
- isc_netaddr_t ipaddr;
- dns_tsigkey_t *tsigkey = NULL;
- dns_peer_t *peer = NULL;
- isc_boolean_t useedns;
- dns_compress_t cctx;
- isc_boolean_t cleanup_cctx = ISC_FALSE;
- isc_boolean_t secure_domain;
- isc_boolean_t connecting = ISC_FALSE;
- dns_ednsopt_t ednsopts[EDNSOPTS];
- unsigned ednsopt = 0;
-
- fctx = query->fctx;
- QTRACE("send");
-
- res = fctx->res;
- task = res->buckets[fctx->bucketnum].task;
- address = NULL;
-
- if ((query->options & DNS_FETCHOPT_TCP) != 0) {
- /*
- * Reserve space for the TCP message length.
- */
- isc_buffer_init(&tcpbuffer, query->data, sizeof(query->data));
- isc_buffer_init(&query->buffer, query->data + 2,
- sizeof(query->data) - 2);
- buffer = &tcpbuffer;
- } else {
- isc_buffer_init(&query->buffer, query->data,
- sizeof(query->data));
- buffer = &query->buffer;
- }
-
- result = dns_message_gettempname(fctx->qmessage, &qname);
- if (result != ISC_R_SUCCESS)
- goto cleanup_temps;
- result = dns_message_gettemprdataset(fctx->qmessage, &qrdataset);
- if (result != ISC_R_SUCCESS)
- goto cleanup_temps;
-
- /*
- * Get a query id from the dispatch.
- */
- result = dns_dispatch_addresponse2(query->dispatch,
- &query->addrinfo->sockaddr,
- task,
- resquery_response,
- query,
- &query->id,
- &query->dispentry,
- res->socketmgr);
- if (result != ISC_R_SUCCESS)
- goto cleanup_temps;
-
- fctx->qmessage->opcode = dns_opcode_query;
-
- /*
- * Set up question.
- */
- dns_name_init(qname, NULL);
- dns_name_clone(&fctx->name, qname);
- dns_rdataset_init(qrdataset);
- dns_rdataset_makequestion(qrdataset, res->rdclass, fctx->type);
- ISC_LIST_APPEND(qname->list, qrdataset, link);
- dns_message_addname(fctx->qmessage, qname, DNS_SECTION_QUESTION);
- qname = NULL;
- qrdataset = NULL;
-
- /*
- * Set RD if the client has requested that we do a recursive query,
- * or if we're sending to a forwarder.
- */
- if ((query->options & DNS_FETCHOPT_RECURSIVE) != 0 ||
- ISFORWARDER(query->addrinfo))
- fctx->qmessage->flags |= DNS_MESSAGEFLAG_RD;
-
- /*
- * Set CD if the client says don't validate or the question is
- * under a secure entry point.
- */
- if ((query->options & DNS_FETCHOPT_NOVALIDATE) != 0) {
- fctx->qmessage->flags |= DNS_MESSAGEFLAG_CD;
- } else if (res->view->enablevalidation) {
- result = dns_view_issecuredomain(res->view, &fctx->name,
- &secure_domain);
- if (result != ISC_R_SUCCESS)
- secure_domain = ISC_FALSE;
- if (res->view->dlv != NULL)
- secure_domain = ISC_TRUE;
- if (secure_domain)
- fctx->qmessage->flags |= DNS_MESSAGEFLAG_CD;
- }
-
- /*
- * We don't have to set opcode because it defaults to query.
- */
- fctx->qmessage->id = query->id;
-
- /*
- * Convert the question to wire format.
- */
- result = dns_compress_init(&cctx, -1, fctx->res->mctx);
- if (result != ISC_R_SUCCESS)
- goto cleanup_message;
- cleanup_cctx = ISC_TRUE;
-
- result = dns_message_renderbegin(fctx->qmessage, &cctx,
- &query->buffer);
- if (result != ISC_R_SUCCESS)
- goto cleanup_message;
-
- result = dns_message_rendersection(fctx->qmessage,
- DNS_SECTION_QUESTION, 0);
- if (result != ISC_R_SUCCESS)
- goto cleanup_message;
-
- peer = NULL;
- isc_netaddr_fromsockaddr(&ipaddr, &query->addrinfo->sockaddr);
- (void) dns_peerlist_peerbyaddr(fctx->res->view->peers, &ipaddr, &peer);
-
- /*
- * The ADB does not know about servers with "edns no". Check this,
- * and then inform the ADB for future use.
- */
- if ((query->addrinfo->flags & DNS_FETCHOPT_NOEDNS0) == 0 &&
- peer != NULL &&
- dns_peer_getsupportedns(peer, &useedns) == ISC_R_SUCCESS &&
- !useedns)
- {
- query->options |= DNS_FETCHOPT_NOEDNS0;
- dns_adb_changeflags(fctx->adb, query->addrinfo,
- DNS_FETCHOPT_NOEDNS0,
- DNS_FETCHOPT_NOEDNS0);
- }
-
- /* Sync NOEDNS0 flag in addrinfo->flags and options now. */
- if ((query->addrinfo->flags & DNS_FETCHOPT_NOEDNS0) != 0)
- query->options |= DNS_FETCHOPT_NOEDNS0;
-
- /*
- * Handle timeouts by reducing the UDP response size to 512 bytes
- * then if that doesn't work disabling EDNS (includes DO) and CD.
- *
- * These timeout can be due to:
- * * broken nameservers that don't respond to EDNS queries.
- * * broken/misconfigured firewalls and NAT implementations
- * that don't handle IP fragmentation.
- * * broken/misconfigured firewalls that don't handle responses
- * greater than 512 bytes.
- * * broken/misconfigured firewalls that don't handle EDNS, DO
- * or CD.
- * * packet loss / link outage.
- */
- if (fctx->timeout) {
- if ((triededns512(fctx, &query->addrinfo->sockaddr) ||
- fctx->timeouts >= (MAX_EDNS0_TIMEOUTS * 2)) &&
- (query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
- query->options |= DNS_FETCHOPT_NOEDNS0;
- fctx->reason = "disabling EDNS";
- } else if ((triededns(fctx, &query->addrinfo->sockaddr) ||
- fctx->timeouts >= MAX_EDNS0_TIMEOUTS) &&
- (query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
- query->options |= DNS_FETCHOPT_EDNS512;
- fctx->reason = "reducing the advertised EDNS UDP "
- "packet size to 512 octets";
- }
- fctx->timeout = ISC_FALSE;
- }
-
- /*
- * Use EDNS0, unless the caller doesn't want it, or we know that
- * the remote server doesn't like it.
- */
- if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
- if ((query->addrinfo->flags & DNS_FETCHOPT_NOEDNS0) == 0) {
- unsigned int version = 0; /* Default version. */
- unsigned int flags;
- isc_uint16_t udpsize = res->udpsize;
- isc_boolean_t reqnsid = res->view->requestnsid;
-
- flags = query->addrinfo->flags;
- if ((flags & DNS_FETCHOPT_EDNSVERSIONSET) != 0) {
- version = flags & DNS_FETCHOPT_EDNSVERSIONMASK;
- version >>= DNS_FETCHOPT_EDNSVERSIONSHIFT;
- }
- if ((query->options & DNS_FETCHOPT_EDNS512) != 0)
- udpsize = 512;
- else if (peer != NULL)
- (void)dns_peer_getudpsize(peer, &udpsize);
-
- /* request NSID for current view or peer? */
- if (peer != NULL)
- (void) dns_peer_getrequestnsid(peer, &reqnsid);
- if (reqnsid) {
- INSIST(ednsopt < EDNSOPTS);
- ednsopts[ednsopt].code = DNS_OPT_NSID;
- ednsopts[ednsopt].length = 0;
- ednsopts[ednsopt].value = NULL;
- ednsopt++;
- }
- result = fctx_addopt(fctx->qmessage, version,
- udpsize, ednsopts, ednsopt);
- if (reqnsid && result == ISC_R_SUCCESS) {
- query->options |= DNS_FETCHOPT_WANTNSID;
- } else if (result != ISC_R_SUCCESS) {
- /*
- * We couldn't add the OPT, but we'll press on.
- * We're not using EDNS0, so set the NOEDNS0
- * bit.
- */
- query->options |= DNS_FETCHOPT_NOEDNS0;
- }
- } else {
- /*
- * We know this server doesn't like EDNS0, so we
- * won't use it. Set the NOEDNS0 bit since we're
- * not using EDNS0.
- */
- query->options |= DNS_FETCHOPT_NOEDNS0;
- }
- }
-
- /*
- * If we need EDNS0 to do this query and aren't using it, we lose.
- */
- if (NEEDEDNS0(fctx) && (query->options & DNS_FETCHOPT_NOEDNS0) != 0) {
- result = DNS_R_SERVFAIL;
- goto cleanup_message;
- }
-
- if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0)
- add_triededns(fctx, &query->addrinfo->sockaddr);
-
- if ((query->options & DNS_FETCHOPT_EDNS512) != 0)
- add_triededns512(fctx, &query->addrinfo->sockaddr);
-
- /*
- * Clear CD if EDNS is not in use.
- */
- if ((query->options & DNS_FETCHOPT_NOEDNS0) != 0)
- fctx->qmessage->flags &= ~DNS_MESSAGEFLAG_CD;
-
- /*
- * Add TSIG record tailored to the current recipient.
- */
- result = dns_view_getpeertsig(fctx->res->view, &ipaddr, &tsigkey);
- if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
- goto cleanup_message;
-
- if (tsigkey != NULL) {
- result = dns_message_settsigkey(fctx->qmessage, tsigkey);
- dns_tsigkey_detach(&tsigkey);
- if (result != ISC_R_SUCCESS)
- goto cleanup_message;
- }
-
- result = dns_message_rendersection(fctx->qmessage,
- DNS_SECTION_ADDITIONAL, 0);
- if (result != ISC_R_SUCCESS)
- goto cleanup_message;
-
- result = dns_message_renderend(fctx->qmessage);
- if (result != ISC_R_SUCCESS)
- goto cleanup_message;
-
- dns_compress_invalidate(&cctx);
- cleanup_cctx = ISC_FALSE;
-
- if (dns_message_gettsigkey(fctx->qmessage) != NULL) {
- dns_tsigkey_attach(dns_message_gettsigkey(fctx->qmessage),
- &query->tsigkey);
- result = dns_message_getquerytsig(fctx->qmessage,
- fctx->res->mctx,
- &query->tsig);
- if (result != ISC_R_SUCCESS)
- goto cleanup_message;
- }
-
- /*
- * If using TCP, write the length of the message at the beginning
- * of the buffer.
- */
- if ((query->options & DNS_FETCHOPT_TCP) != 0) {
- isc_buffer_usedregion(&query->buffer, &r);
- isc_buffer_putuint16(&tcpbuffer, (isc_uint16_t)r.length);
- isc_buffer_add(&tcpbuffer, r.length);
- }
-
- /*
- * We're now done with the query message.
- */
- dns_message_reset(fctx->qmessage, DNS_MESSAGE_INTENTRENDER);
-
- if (query->exclusivesocket)
- socket = dns_dispatch_getentrysocket(query->dispentry);
- else
- socket = dns_dispatch_getsocket(query->dispatch);
- /*
- * Send the query!
- */
- if ((query->options & DNS_FETCHOPT_TCP) == 0) {
- address = &query->addrinfo->sockaddr;
- if (query->exclusivesocket) {
- result = isc_socket_connect(socket, address, task,
- resquery_udpconnected,
- query);
- if (result != ISC_R_SUCCESS)
- goto cleanup_message;
- connecting = ISC_TRUE;
- query->connects++;
- }
- }
- isc_buffer_usedregion(buffer, &r);
-
- /*
- * XXXRTH Make sure we don't send to ourselves! We should probably
- * prune out these addresses when we get them from the ADB.
- */
- ISC_EVENT_INIT(&query->sendevent, sizeof(query->sendevent), 0, NULL,
- ISC_SOCKEVENT_SENDDONE, resquery_senddone, query,
- NULL, NULL, NULL);
- result = isc_socket_sendto2(socket, &r, task, address, NULL,
- &query->sendevent, 0);
- if (result != ISC_R_SUCCESS) {
- if (connecting) {
- /*
- * This query is still connecting.
- * Mark it as canceled so that it will just be
- * cleaned up when the connected event is received.
- * Keep fctx around until the event is processed.
- */
- query->fctx->nqueries++;
- query->attributes |= RESQUERY_ATTR_CANCELED;
- }
- goto cleanup_message;
- }
-
- query->sends++;
-
- QTRACE("sent");
-
- return (ISC_R_SUCCESS);
-
- cleanup_message:
- if (cleanup_cctx)
- dns_compress_invalidate(&cctx);
-
- dns_message_reset(fctx->qmessage, DNS_MESSAGE_INTENTRENDER);
-
- /*
- * Stop the dispatcher from listening.
- */
- dns_dispatch_removeresponse(&query->dispentry, NULL);
-
- cleanup_temps:
- if (qname != NULL)
- dns_message_puttempname(fctx->qmessage, &qname);
- if (qrdataset != NULL)
- dns_message_puttemprdataset(fctx->qmessage, &qrdataset);
-
- return (result);
-}
-
-static void
-resquery_connected(isc_task_t *task, isc_event_t *event) {
- isc_socketevent_t *sevent = (isc_socketevent_t *)event;
- resquery_t *query = event->ev_arg;
- isc_boolean_t retry = ISC_FALSE;
- isc_interval_t interval;
- isc_result_t result;
- unsigned int attrs;
- fetchctx_t *fctx;
-
- REQUIRE(event->ev_type == ISC_SOCKEVENT_CONNECT);
- REQUIRE(VALID_QUERY(query));
-
- QTRACE("connected");
-
- UNUSED(task);
-
- /*
- * XXXRTH
- *
- * Currently we don't wait for the connect event before retrying
- * a query. This means that if we get really behind, we may end
- * up doing extra work!
- */
-
- query->connects--;
- fctx = query->fctx;
-
- if (RESQUERY_CANCELED(query)) {
- /*
- * This query was canceled while the connect() was in
- * progress.
- */
- isc_socket_detach(&query->tcpsocket);
- resquery_destroy(&query);
- } else {
- switch (sevent->result) {
- case ISC_R_SUCCESS:
-
- /*
- * Extend the idle timer for TCP. 20 seconds
- * should be long enough for a TCP connection to be
- * established, a single DNS request to be sent,
- * and the response received.
- */
- isc_interval_set(&interval, 20, 0);
- result = fctx_startidletimer(query->fctx, &interval);
- if (result != ISC_R_SUCCESS) {
- fctx_cancelquery(&query, NULL, NULL, ISC_FALSE);
- fctx_done(fctx, result, __LINE__);
- break;
- }
- /*
- * We are connected. Create a dispatcher and
- * send the query.
- */
- attrs = 0;
- attrs |= DNS_DISPATCHATTR_TCP;
- attrs |= DNS_DISPATCHATTR_PRIVATE;
- attrs |= DNS_DISPATCHATTR_CONNECTED;
- if (isc_sockaddr_pf(&query->addrinfo->sockaddr) ==
- AF_INET)
- attrs |= DNS_DISPATCHATTR_IPV4;
- else
- attrs |= DNS_DISPATCHATTR_IPV6;
- attrs |= DNS_DISPATCHATTR_MAKEQUERY;
-
- result = dns_dispatch_createtcp(query->dispatchmgr,
- query->tcpsocket,
- query->fctx->res->taskmgr,
- 4096, 2, 1, 1, 3, attrs,
- &query->dispatch);
-
- /*
- * Regardless of whether dns_dispatch_create()
- * succeeded or not, we don't need our reference
- * to the socket anymore.
- */
- isc_socket_detach(&query->tcpsocket);
-
- if (result == ISC_R_SUCCESS)
- result = resquery_send(query);
-
- if (result != ISC_R_SUCCESS) {
- fctx_cancelquery(&query, NULL, NULL, ISC_FALSE);
- fctx_done(fctx, result, __LINE__);
- }
- break;
-
- case ISC_R_NETUNREACH:
- case ISC_R_HOSTUNREACH:
- case ISC_R_CONNREFUSED:
- case ISC_R_NOPERM:
- case ISC_R_ADDRNOTAVAIL:
- case ISC_R_CONNECTIONRESET:
- /*
- * No route to remote.
- */
- isc_socket_detach(&query->tcpsocket);
- fctx_cancelquery(&query, NULL, NULL, ISC_TRUE);
- retry = ISC_TRUE;
- break;
-
- default:
- isc_socket_detach(&query->tcpsocket);
- fctx_cancelquery(&query, NULL, NULL, ISC_FALSE);
- break;
- }
- }
-
- isc_event_free(&event);
-
- if (retry) {
- /*
- * Behave as if the idle timer has expired. For TCP
- * connections this may not actually reflect the latest timer.
- */
- fctx->attributes &= ~FCTX_ATTR_ADDRWAIT;
- result = fctx_stopidletimer(fctx);
- if (result != ISC_R_SUCCESS)
- fctx_done(fctx, result, __LINE__);
- else
- fctx_try(fctx, ISC_TRUE, ISC_FALSE);
- }
-}
-
-static void
-fctx_finddone(isc_task_t *task, isc_event_t *event) {
- fetchctx_t *fctx;
- dns_adbfind_t *find;
- dns_resolver_t *res;
- isc_boolean_t want_try = ISC_FALSE;
- isc_boolean_t want_done = ISC_FALSE;
- isc_boolean_t bucket_empty = ISC_FALSE;
- unsigned int bucketnum;
- isc_boolean_t destroy = ISC_FALSE;
-
- find = event->ev_sender;
- fctx = event->ev_arg;
- REQUIRE(VALID_FCTX(fctx));
- res = fctx->res;
-
- UNUSED(task);
-
- FCTXTRACE("finddone");
-
- bucketnum = fctx->bucketnum;
- LOCK(&res->buckets[bucketnum].lock);
-
- INSIST(fctx->pending > 0);
- fctx->pending--;
-
- if (ADDRWAIT(fctx)) {
- /*
- * The fetch is waiting for a name to be found.
- */
- INSIST(!SHUTTINGDOWN(fctx));
- fctx->attributes &= ~FCTX_ATTR_ADDRWAIT;
- if (event->ev_type == DNS_EVENT_ADBMOREADDRESSES)
- want_try = ISC_TRUE;
- else {
- fctx->findfail++;
- if (fctx->pending == 0) {
- /*
- * We've got nothing else to wait for and don't
- * know the answer. There's nothing to do but
- * fail the fctx.
- */
- want_done = ISC_TRUE;
- }
- }
- } else if (SHUTTINGDOWN(fctx) && fctx->pending == 0 &&
- fctx->nqueries == 0 && ISC_LIST_EMPTY(fctx->validators)) {
-
- if (fctx->references == 0) {
- bucket_empty = fctx_unlink(fctx);
- destroy = ISC_TRUE;
- }
- }
- UNLOCK(&res->buckets[bucketnum].lock);
-
- isc_event_free(&event);
- dns_adb_destroyfind(&find);
-
- if (want_try)
- fctx_try(fctx, ISC_TRUE, ISC_FALSE);
- else if (want_done)
- fctx_done(fctx, ISC_R_FAILURE, __LINE__);
- else if (destroy) {
- fctx_destroy(fctx);
- if (bucket_empty)
- empty_bucket(res);
- }
-}
-
-
-static inline isc_boolean_t
-bad_server(fetchctx_t *fctx, isc_sockaddr_t *address) {
- isc_sockaddr_t *sa;
-
- for (sa = ISC_LIST_HEAD(fctx->bad);
- sa != NULL;
- sa = ISC_LIST_NEXT(sa, link)) {
- if (isc_sockaddr_equal(sa, address))
- return (ISC_TRUE);
- }
-
- return (ISC_FALSE);
-}
-
-static inline isc_boolean_t
-mark_bad(fetchctx_t *fctx) {
- dns_adbfind_t *curr;
- dns_adbaddrinfo_t *addrinfo;
- isc_boolean_t all_bad = ISC_TRUE;
-
- /*
- * Mark all known bad servers, so we don't try to talk to them
- * again.
- */
-
- /*
- * Mark any bad nameservers.
- */
- for (curr = ISC_LIST_HEAD(fctx->finds);
- curr != NULL;
- curr = ISC_LIST_NEXT(curr, publink)) {
- for (addrinfo = ISC_LIST_HEAD(curr->list);
- addrinfo != NULL;
- addrinfo = ISC_LIST_NEXT(addrinfo, publink)) {
- if (bad_server(fctx, &addrinfo->sockaddr))
- addrinfo->flags |= FCTX_ADDRINFO_MARK;
- else
- all_bad = ISC_FALSE;
- }
- }
-
- /*
- * Mark any bad forwarders.
- */
- for (addrinfo = ISC_LIST_HEAD(fctx->forwaddrs);
- addrinfo != NULL;
- addrinfo = ISC_LIST_NEXT(addrinfo, publink)) {
- if (bad_server(fctx, &addrinfo->sockaddr))
- addrinfo->flags |= FCTX_ADDRINFO_MARK;
- else
- all_bad = ISC_FALSE;
- }
-
- /*
- * Mark any bad alternates.
- */
- for (curr = ISC_LIST_HEAD(fctx->altfinds);
- curr != NULL;
- curr = ISC_LIST_NEXT(curr, publink)) {
- for (addrinfo = ISC_LIST_HEAD(curr->list);
- addrinfo != NULL;
- addrinfo = ISC_LIST_NEXT(addrinfo, publink)) {
- if (bad_server(fctx, &addrinfo->sockaddr))
- addrinfo->flags |= FCTX_ADDRINFO_MARK;
- else
- all_bad = ISC_FALSE;
- }
- }
-
- for (addrinfo = ISC_LIST_HEAD(fctx->altaddrs);
- addrinfo != NULL;
- addrinfo = ISC_LIST_NEXT(addrinfo, publink)) {
- if (bad_server(fctx, &addrinfo->sockaddr))
- addrinfo->flags |= FCTX_ADDRINFO_MARK;
- else
- all_bad = ISC_FALSE;
- }
-
- return (all_bad);
-}
-
-static void
-add_bad(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, isc_result_t reason,
- badnstype_t badtype)
-{
- char namebuf[DNS_NAME_FORMATSIZE];
- char addrbuf[ISC_SOCKADDR_FORMATSIZE];
- char classbuf[64];
- char typebuf[64];
- char code[64];
- isc_buffer_t b;
- isc_sockaddr_t *sa;
- const char *spc = "";
- isc_sockaddr_t *address = &addrinfo->sockaddr;
-
- if (reason == DNS_R_LAME)
- fctx->lamecount++;
- else {
- switch (badtype) {
- case badns_unreachable:
- fctx->neterr++;
- break;
- case badns_response:
- fctx->badresp++;
- break;
- case badns_validation:
- break; /* counted as 'valfail' */
- }
- }
-
- if (bad_server(fctx, address)) {
- /*
- * We already know this server is bad.
- */
- return;
- }
-
- FCTXTRACE("add_bad");
-
- sa = isc_mem_get(fctx->mctx, sizeof(*sa));
- if (sa == NULL)
- return;
- *sa = *address;
- ISC_LIST_INITANDAPPEND(fctx->bad, sa, link);
-
- if (reason == DNS_R_LAME) /* already logged */
- return;
-
- if (reason == DNS_R_UNEXPECTEDRCODE &&
- fctx->rmessage->rcode == dns_rcode_servfail &&
- ISFORWARDER(addrinfo))
- return;
-
- if (reason == DNS_R_UNEXPECTEDRCODE) {
- isc_buffer_init(&b, code, sizeof(code) - 1);
- dns_rcode_totext(fctx->rmessage->rcode, &b);
- code[isc_buffer_usedlength(&b)] = '\0';
- 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';
- spc = " ";
- } else {
- code[0] = '\0';
- }
- dns_name_format(&fctx->name, namebuf, sizeof(namebuf));
- dns_rdatatype_format(fctx->type, typebuf, sizeof(typebuf));
- dns_rdataclass_format(fctx->res->rdclass, classbuf, sizeof(classbuf));
- isc_sockaddr_format(address, addrbuf, sizeof(addrbuf));
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_LAME_SERVERS,
- DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO,
- "error (%s%s%s) resolving '%s/%s/%s': %s",
- dns_result_totext(reason), spc, code,
- namebuf, typebuf, classbuf, addrbuf);
-}
-
-/*
- * Sort addrinfo list by RTT.
- */
-static void
-sort_adbfind(dns_adbfind_t *find) {
- dns_adbaddrinfo_t *best, *curr;
- dns_adbaddrinfolist_t sorted;
-
- /* Lame N^2 bubble sort. */
- ISC_LIST_INIT(sorted);
- while (!ISC_LIST_EMPTY(find->list)) {
- best = ISC_LIST_HEAD(find->list);
- curr = ISC_LIST_NEXT(best, publink);
- while (curr != NULL) {
- if (curr->srtt < best->srtt)
- best = curr;
- curr = ISC_LIST_NEXT(curr, publink);
- }
- ISC_LIST_UNLINK(find->list, best, publink);
- ISC_LIST_APPEND(sorted, best, publink);
- }
- find->list = sorted;
-}
-
-/*
- * Sort a list of finds by server RTT.
- */
-static void
-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. */
- for (curr = ISC_LIST_HEAD(*findlist);
- curr != NULL;
- curr = ISC_LIST_NEXT(curr, publink))
- sort_adbfind(curr);
-
- /* Lame N^2 bubble sort. */
- ISC_LIST_INIT(sorted);
- while (!ISC_LIST_EMPTY(*findlist)) {
- best = ISC_LIST_HEAD(*findlist);
- bestaddrinfo = ISC_LIST_HEAD(best->list);
- INSIST(bestaddrinfo != NULL);
- curr = ISC_LIST_NEXT(best, publink);
- while (curr != NULL) {
- addrinfo = ISC_LIST_HEAD(curr->list);
- INSIST(addrinfo != NULL);
- if (addrinfo->srtt < bestaddrinfo->srtt) {
- best = curr;
- bestaddrinfo = addrinfo;
- }
- curr = ISC_LIST_NEXT(curr, publink);
- }
- ISC_LIST_UNLINK(*findlist, best, publink);
- ISC_LIST_APPEND(sorted, best, publink);
- }
- *findlist = sorted;
-}
-
-static void
-findname(fetchctx_t *fctx, dns_name_t *name, in_port_t port,
- unsigned int options, unsigned int flags, isc_stdtime_t now,
- isc_boolean_t *need_alternate)
-{
- dns_adbaddrinfo_t *ai;
- dns_adbfind_t *find;
- dns_resolver_t *res;
- isc_boolean_t unshared;
- isc_result_t result;
-
- res = fctx->res;
- unshared = ISC_TF((fctx->options & DNS_FETCHOPT_UNSHARED) != 0);
- /*
- * If this name is a subdomain of the query domain, tell
- * the ADB to start looking using zone/hint data. This keeps us
- * from getting stuck if the nameserver is beneath the zone cut
- * and we don't know its address (e.g. because the A record has
- * expired).
- */
- if (dns_name_issubdomain(name, &fctx->domain))
- options |= DNS_ADBFIND_STARTATZONE;
- options |= DNS_ADBFIND_GLUEOK;
- options |= DNS_ADBFIND_HINTOK;
-
- /*
- * See what we know about this address.
- */
- find = NULL;
- result = dns_adb_createfind(fctx->adb,
- res->buckets[fctx->bucketnum].task,
- fctx_finddone, fctx, name,
- &fctx->name, fctx->type,
- options, now, NULL,
- res->view->dstport, &find);
- if (result != ISC_R_SUCCESS) {
- if (result == DNS_R_ALIAS) {
- /*
- * XXXRTH Follow the CNAME/DNAME chain?
- */
- dns_adb_destroyfind(&find);
- fctx->adberr++;
- }
- } else if (!ISC_LIST_EMPTY(find->list)) {
- /*
- * We have at least some of the addresses for the
- * name.
- */
- INSIST((find->options & DNS_ADBFIND_WANTEVENT) == 0);
- if (flags != 0 || port != 0) {
- for (ai = ISC_LIST_HEAD(find->list);
- ai != NULL;
- ai = ISC_LIST_NEXT(ai, publink)) {
- ai->flags |= flags;
- if (port != 0)
- isc_sockaddr_setport(&ai->sockaddr,
- port);
- }
- }
- if ((flags & FCTX_ADDRINFO_FORWARDER) != 0)
- ISC_LIST_APPEND(fctx->altfinds, find, publink);
- else
- ISC_LIST_APPEND(fctx->finds, find, publink);
- } else {
- /*
- * We don't know any of the addresses for this
- * name.
- */
- if ((find->options & DNS_ADBFIND_WANTEVENT) != 0) {
- /*
- * We're looking for them and will get an
- * event about it later.
- */
- fctx->pending++;
- /*
- * Bootstrap.
- */
- if (need_alternate != NULL &&
- !*need_alternate && unshared &&
- ((res->dispatches4 == NULL &&
- find->result_v6 != DNS_R_NXDOMAIN) ||
- (res->dispatches6 == NULL &&
- find->result_v4 != DNS_R_NXDOMAIN)))
- *need_alternate = ISC_TRUE;
- } else {
- if ((find->options & DNS_ADBFIND_LAMEPRUNED) != 0)
- fctx->lamecount++; /* cached lame server */
- else
- fctx->adberr++; /* unreachable server, etc. */
-
- /*
- * If we know there are no addresses for
- * the family we are using then try to add
- * an alternative server.
- */
- if (need_alternate != NULL && !*need_alternate &&
- ((res->dispatches4 == NULL &&
- find->result_v6 == DNS_R_NXRRSET) ||
- (res->dispatches6 == NULL &&
- find->result_v4 == DNS_R_NXRRSET)))
- *need_alternate = ISC_TRUE;
- dns_adb_destroyfind(&find);
- }
- }
-}
-
-static isc_boolean_t
-isstrictsubdomain(dns_name_t *name1, dns_name_t *name2) {
- int order;
- unsigned int nlabels;
- dns_namereln_t namereln;
-
- namereln = dns_name_fullcompare(name1, name2, &order, &nlabels);
- return (ISC_TF(namereln == dns_namereln_subdomain));
-}
-
-static isc_result_t
-fctx_getaddresses(fetchctx_t *fctx, isc_boolean_t badcache) {
- dns_rdata_t rdata = DNS_RDATA_INIT;
- isc_result_t result;
- dns_resolver_t *res;
- isc_stdtime_t now;
- unsigned int stdoptions = 0;
- isc_sockaddr_t *sa;
- dns_adbaddrinfo_t *ai;
- isc_boolean_t all_bad;
- dns_rdata_ns_t ns;
- isc_boolean_t need_alternate = ISC_FALSE;
-
- FCTXTRACE("getaddresses");
-
- /*
- * Don't pound on remote servers. (Failsafe!)
- */
- fctx->restarts++;
- if (fctx->restarts > 10) {
- FCTXTRACE("too many restarts");
- return (DNS_R_SERVFAIL);
- }
-
- res = fctx->res;
-
- /*
- * Forwarders.
- */
-
- INSIST(ISC_LIST_EMPTY(fctx->forwaddrs));
- INSIST(ISC_LIST_EMPTY(fctx->altaddrs));
-
- /*
- * If this fctx has forwarders, use them; otherwise use any
- * selective forwarders specified in the view; otherwise use the
- * resolver's forwarders (if any).
- */
- sa = ISC_LIST_HEAD(fctx->forwarders);
- if (sa == NULL) {
- dns_forwarders_t *forwarders = NULL;
- dns_name_t *name = &fctx->name;
- dns_name_t suffix;
- unsigned int labels;
- dns_fixedname_t fixed;
- dns_name_t *domain;
-
- /*
- * DS records are found in the parent server.
- * Strip label to get the correct forwarder (if any).
- */
- if (dns_rdatatype_atparent(fctx->type) &&
- dns_name_countlabels(name) > 1) {
- dns_name_init(&suffix, NULL);
- labels = dns_name_countlabels(name);
- dns_name_getlabelsequence(name, 1, labels - 1, &suffix);
- name = &suffix;
- }
-
- dns_fixedname_init(&fixed);
- domain = dns_fixedname_name(&fixed);
- result = dns_fwdtable_find2(fctx->res->view->fwdtable, name,
- domain, &forwarders);
- if (result == ISC_R_SUCCESS) {
- sa = ISC_LIST_HEAD(forwarders->addrs);
- fctx->fwdpolicy = forwarders->fwdpolicy;
- if (fctx->fwdpolicy == dns_fwdpolicy_only &&
- isstrictsubdomain(domain, &fctx->domain)) {
- dns_name_free(&fctx->domain, fctx->mctx);
- dns_name_init(&fctx->domain, NULL);
- result = dns_name_dup(domain, fctx->mctx,
- &fctx->domain);
- if (result != ISC_R_SUCCESS)
- return (result);
- }
- }
- }
-
- while (sa != NULL) {
- if ((isc_sockaddr_pf(sa) == AF_INET &&
- fctx->res->dispatches4 == NULL) ||
- (isc_sockaddr_pf(sa) == AF_INET6 &&
- fctx->res->dispatches6 == NULL)) {
- sa = ISC_LIST_NEXT(sa, link);
- continue;
- }
- ai = NULL;
- result = dns_adb_findaddrinfo(fctx->adb,
- sa, &ai, 0); /* XXXMLG */
- if (result == ISC_R_SUCCESS) {
- dns_adbaddrinfo_t *cur;
- ai->flags |= FCTX_ADDRINFO_FORWARDER;
- cur = ISC_LIST_HEAD(fctx->forwaddrs);
- while (cur != NULL && cur->srtt < ai->srtt)
- cur = ISC_LIST_NEXT(cur, publink);
- if (cur != NULL)
- ISC_LIST_INSERTBEFORE(fctx->forwaddrs, cur,
- ai, publink);
- else
- ISC_LIST_APPEND(fctx->forwaddrs, ai, publink);
- }
- sa = ISC_LIST_NEXT(sa, link);
- }
-
- /*
- * If the forwarding policy is "only", we don't need the addresses
- * of the nameservers.
- */
- if (fctx->fwdpolicy == dns_fwdpolicy_only)
- goto out;
-
- /*
- * Normal nameservers.
- */
-
- stdoptions = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_EMPTYEVENT;
- if (fctx->restarts == 1) {
- /*
- * To avoid sending out a flood of queries likely to
- * result in NXRRSET, we suppress fetches for address
- * families we don't have the first time through,
- * provided that we have addresses in some family we
- * can use.
- *
- * We don't want to set this option all the time, since
- * if fctx->restarts > 1, we've clearly been having trouble
- * with the addresses we had, so getting more could help.
- */
- stdoptions |= DNS_ADBFIND_AVOIDFETCHES;
- }
- if (res->dispatches4 != NULL)
- stdoptions |= DNS_ADBFIND_INET;
- if (res->dispatches6 != NULL)
- stdoptions |= DNS_ADBFIND_INET6;
- isc_stdtime_get(&now);
-
- INSIST(ISC_LIST_EMPTY(fctx->finds));
- INSIST(ISC_LIST_EMPTY(fctx->altfinds));
-
- for (result = dns_rdataset_first(&fctx->nameservers);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(&fctx->nameservers))
- {
- dns_rdataset_current(&fctx->nameservers, &rdata);
- /*
- * Extract the name from the NS record.
- */
- result = dns_rdata_tostruct(&rdata, &ns, NULL);
- if (result != ISC_R_SUCCESS)
- continue;
-
- findname(fctx, &ns.name, 0, stdoptions, 0, now,
- &need_alternate);
- dns_rdata_reset(&rdata);
- dns_rdata_freestruct(&ns);
- }
- if (result != ISC_R_NOMORE)
- return (result);
-
- /*
- * Do we need to use 6 to 4?
- */
- if (need_alternate) {
- int family;
- alternate_t *a;
- family = (res->dispatches6 != NULL) ? AF_INET6 : AF_INET;
- for (a = ISC_LIST_HEAD(fctx->res->alternates);
- a != NULL;
- a = ISC_LIST_NEXT(a, link)) {
- if (!a->isaddress) {
- findname(fctx, &a->_u._n.name, a->_u._n.port,
- stdoptions, FCTX_ADDRINFO_FORWARDER,
- now, NULL);
- continue;
- }
- if (isc_sockaddr_pf(&a->_u.addr) != family)
- continue;
- ai = NULL;
- result = dns_adb_findaddrinfo(fctx->adb, &a->_u.addr,
- &ai, 0);
- if (result == ISC_R_SUCCESS) {
- dns_adbaddrinfo_t *cur;
- ai->flags |= FCTX_ADDRINFO_FORWARDER;
- cur = ISC_LIST_HEAD(fctx->altaddrs);
- while (cur != NULL && cur->srtt < ai->srtt)
- cur = ISC_LIST_NEXT(cur, publink);
- if (cur != NULL)
- ISC_LIST_INSERTBEFORE(fctx->altaddrs,
- cur, ai, publink);
- else
- ISC_LIST_APPEND(fctx->altaddrs, ai,
- publink);
- }
- }
- }
-
- out:
- /*
- * Mark all known bad servers.
- */
- all_bad = mark_bad(fctx);
-
- /*
- * How are we doing?
- */
- if (all_bad) {
- /*
- * We've got no addresses.
- */
- if (fctx->pending > 0) {
- /*
- * We're fetching the addresses, but don't have any
- * yet. Tell the caller to wait for an answer.
- */
- result = DNS_R_WAIT;
- } else {
- isc_time_t expire;
- isc_interval_t i;
- /*
- * We've lost completely. We don't know any
- * addresses, and the ADB has told us it can't get
- * them.
- */
- FCTXTRACE("no addresses");
- isc_interval_set(&i, DNS_BADCACHE_TTL(fctx), 0);
- result = isc_time_nowplusinterval(&expire, &i);
- if (badcache &&
- (fctx->type == dns_rdatatype_dnskey ||
- fctx->type == dns_rdatatype_dlv ||
- fctx->type == dns_rdatatype_ds) &&
- result == ISC_R_SUCCESS)
- dns_resolver_addbadcache(fctx->res,
- &fctx->name,
- fctx->type, &expire);
- result = ISC_R_FAILURE;
- }
- } else {
- /*
- * We've found some addresses. We might still be looking
- * for more addresses.
- */
- sort_finds(&fctx->finds);
- sort_finds(&fctx->altfinds);
- result = ISC_R_SUCCESS;
- }
-
- return (result);
-}
-
-static inline void
-possibly_mark(fetchctx_t *fctx, dns_adbaddrinfo_t *addr)
-{
- isc_netaddr_t na;
- char buf[ISC_NETADDR_FORMATSIZE];
- isc_sockaddr_t *sa;
- isc_boolean_t aborted = ISC_FALSE;
- isc_boolean_t bogus;
- dns_acl_t *blackhole;
- isc_netaddr_t ipaddr;
- dns_peer_t *peer = NULL;
- dns_resolver_t *res;
- const char *msg = NULL;
-
- sa = &addr->sockaddr;
-
- res = fctx->res;
- isc_netaddr_fromsockaddr(&ipaddr, sa);
- blackhole = dns_dispatchmgr_getblackhole(res->dispatchmgr);
- (void) dns_peerlist_peerbyaddr(res->view->peers, &ipaddr, &peer);
-
- if (blackhole != NULL) {
- int match;
-
- if (dns_acl_match(&ipaddr, NULL, blackhole,
- &res->view->aclenv,
- &match, NULL) == ISC_R_SUCCESS &&
- match > 0)
- aborted = ISC_TRUE;
- }
-
- if (peer != NULL &&
- dns_peer_getbogus(peer, &bogus) == ISC_R_SUCCESS &&
- bogus)
- aborted = ISC_TRUE;
-
- if (aborted) {
- addr->flags |= FCTX_ADDRINFO_MARK;
- msg = "ignoring blackholed / bogus server: ";
- } else if (isc_sockaddr_ismulticast(sa)) {
- addr->flags |= FCTX_ADDRINFO_MARK;
- msg = "ignoring multicast address: ";
- } else if (isc_sockaddr_isexperimental(sa)) {
- addr->flags |= FCTX_ADDRINFO_MARK;
- msg = "ignoring experimental address: ";
- } else if (sa->type.sa.sa_family != AF_INET6) {
- return;
- } else if (IN6_IS_ADDR_V4MAPPED(&sa->type.sin6.sin6_addr)) {
- addr->flags |= FCTX_ADDRINFO_MARK;
- msg = "ignoring IPv6 mapped IPV4 address: ";
- } else if (IN6_IS_ADDR_V4COMPAT(&sa->type.sin6.sin6_addr)) {
- addr->flags |= FCTX_ADDRINFO_MARK;
- msg = "ignoring IPv6 compatibility IPV4 address: ";
- } else
- return;
-
- if (!isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3)))
- return;
-
- isc_netaddr_fromsockaddr(&na, sa);
- isc_netaddr_format(&na, buf, sizeof(buf));
- FCTXTRACE2(msg, buf);
-}
-
-static inline dns_adbaddrinfo_t *
-fctx_nextaddress(fetchctx_t *fctx) {
- dns_adbfind_t *find, *start;
- dns_adbaddrinfo_t *addrinfo;
- dns_adbaddrinfo_t *faddrinfo;
-
- /*
- * Return the next untried address, if any.
- */
-
- /*
- * Find the first unmarked forwarder (if any).
- */
- for (addrinfo = ISC_LIST_HEAD(fctx->forwaddrs);
- addrinfo != NULL;
- addrinfo = ISC_LIST_NEXT(addrinfo, publink)) {
- if (!UNMARKED(addrinfo))
- continue;
- possibly_mark(fctx, addrinfo);
- if (UNMARKED(addrinfo)) {
- addrinfo->flags |= FCTX_ADDRINFO_MARK;
- fctx->find = NULL;
- return (addrinfo);
- }
- }
-
- /*
- * No forwarders. Move to the next find.
- */
-
- fctx->attributes |= FCTX_ATTR_TRIEDFIND;
-
- find = fctx->find;
- if (find == NULL)
- find = ISC_LIST_HEAD(fctx->finds);
- else {
- find = ISC_LIST_NEXT(find, publink);
- if (find == NULL)
- find = ISC_LIST_HEAD(fctx->finds);
- }
-
- /*
- * Find the first unmarked addrinfo.
- */
- addrinfo = NULL;
- if (find != NULL) {
- start = find;
- do {
- for (addrinfo = ISC_LIST_HEAD(find->list);
- addrinfo != NULL;
- addrinfo = ISC_LIST_NEXT(addrinfo, publink)) {
- if (!UNMARKED(addrinfo))
- continue;
- possibly_mark(fctx, addrinfo);
- if (UNMARKED(addrinfo)) {
- addrinfo->flags |= FCTX_ADDRINFO_MARK;
- break;
- }
- }
- if (addrinfo != NULL)
- break;
- find = ISC_LIST_NEXT(find, publink);
- if (find == NULL)
- find = ISC_LIST_HEAD(fctx->finds);
- } while (find != start);
- }
-
- fctx->find = find;
- if (addrinfo != NULL)
- return (addrinfo);
-
- /*
- * No nameservers left. Try alternates.
- */
-
- fctx->attributes |= FCTX_ATTR_TRIEDALT;
-
- find = fctx->altfind;
- if (find == NULL)
- find = ISC_LIST_HEAD(fctx->altfinds);
- else {
- find = ISC_LIST_NEXT(find, publink);
- if (find == NULL)
- find = ISC_LIST_HEAD(fctx->altfinds);
- }
-
- /*
- * Find the first unmarked addrinfo.
- */
- addrinfo = NULL;
- if (find != NULL) {
- start = find;
- do {
- for (addrinfo = ISC_LIST_HEAD(find->list);
- addrinfo != NULL;
- addrinfo = ISC_LIST_NEXT(addrinfo, publink)) {
- if (!UNMARKED(addrinfo))
- continue;
- possibly_mark(fctx, addrinfo);
- if (UNMARKED(addrinfo)) {
- addrinfo->flags |= FCTX_ADDRINFO_MARK;
- break;
- }
- }
- if (addrinfo != NULL)
- break;
- find = ISC_LIST_NEXT(find, publink);
- if (find == NULL)
- find = ISC_LIST_HEAD(fctx->altfinds);
- } while (find != start);
- }
-
- faddrinfo = addrinfo;
-
- /*
- * See if we have a better alternate server by address.
- */
-
- for (addrinfo = ISC_LIST_HEAD(fctx->altaddrs);
- addrinfo != NULL;
- addrinfo = ISC_LIST_NEXT(addrinfo, publink)) {
- if (!UNMARKED(addrinfo))
- continue;
- possibly_mark(fctx, addrinfo);
- if (UNMARKED(addrinfo) &&
- (faddrinfo == NULL ||
- addrinfo->srtt < faddrinfo->srtt)) {
- if (faddrinfo != NULL)
- faddrinfo->flags &= ~FCTX_ADDRINFO_MARK;
- addrinfo->flags |= FCTX_ADDRINFO_MARK;
- break;
- }
- }
-
- if (addrinfo == NULL) {
- addrinfo = faddrinfo;
- fctx->altfind = find;
- }
-
- return (addrinfo);
-}
-
-static void
-fctx_try(fetchctx_t *fctx, isc_boolean_t retrying, isc_boolean_t badcache) {
- isc_result_t result;
- dns_adbaddrinfo_t *addrinfo;
-
- FCTXTRACE("try");
-
- REQUIRE(!ADDRWAIT(fctx));
-
- addrinfo = fctx_nextaddress(fctx);
- if (addrinfo == NULL) {
- /*
- * We have no more addresses. Start over.
- */
- fctx_cancelqueries(fctx, ISC_TRUE);
- fctx_cleanupfinds(fctx);
- fctx_cleanupaltfinds(fctx);
- fctx_cleanupforwaddrs(fctx);
- fctx_cleanupaltaddrs(fctx);
- result = fctx_getaddresses(fctx, badcache);
- if (result == DNS_R_WAIT) {
- /*
- * Sleep waiting for addresses.
- */
- FCTXTRACE("addrwait");
- fctx->attributes |= FCTX_ATTR_ADDRWAIT;
- return;
- } else if (result != ISC_R_SUCCESS) {
- /*
- * Something bad happened.
- */
- fctx_done(fctx, result, __LINE__);
- return;
- }
-
- addrinfo = fctx_nextaddress(fctx);
- /*
- * While we may have addresses from the ADB, they
- * might be bad ones. In this case, return SERVFAIL.
- */
- if (addrinfo == NULL) {
- fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
- return;
- }
- }
-
- result = fctx_query(fctx, addrinfo, fctx->options);
- if (result != ISC_R_SUCCESS)
- fctx_done(fctx, result, __LINE__);
- else if (retrying)
- inc_stats(fctx->res, dns_resstatscounter_retry);
-}
-
-static isc_boolean_t
-fctx_unlink(fetchctx_t *fctx) {
- dns_resolver_t *res;
- unsigned int bucketnum;
-
- /*
- * Caller must be holding the bucket lock.
- */
-
- REQUIRE(VALID_FCTX(fctx));
- REQUIRE(fctx->state == fetchstate_done ||
- fctx->state == fetchstate_init);
- REQUIRE(ISC_LIST_EMPTY(fctx->events));
- REQUIRE(ISC_LIST_EMPTY(fctx->queries));
- REQUIRE(ISC_LIST_EMPTY(fctx->finds));
- REQUIRE(ISC_LIST_EMPTY(fctx->altfinds));
- REQUIRE(fctx->pending == 0);
- REQUIRE(fctx->references == 0);
- REQUIRE(ISC_LIST_EMPTY(fctx->validators));
-
- FCTXTRACE("unlink");
-
- res = fctx->res;
- bucketnum = fctx->bucketnum;
-
- ISC_LIST_UNLINK(res->buckets[bucketnum].fctxs, fctx, link);
-
- LOCK(&res->nlock);
- res->nfctx--;
- UNLOCK(&res->nlock);
-
- if (res->buckets[bucketnum].exiting &&
- ISC_LIST_EMPTY(res->buckets[bucketnum].fctxs))
- return (ISC_TRUE);
-
- return (ISC_FALSE);
-}
-
-static void
-fctx_destroy(fetchctx_t *fctx) {
- isc_sockaddr_t *sa, *next_sa;
-
- REQUIRE(VALID_FCTX(fctx));
- REQUIRE(fctx->state == fetchstate_done ||
- fctx->state == fetchstate_init);
- REQUIRE(ISC_LIST_EMPTY(fctx->events));
- REQUIRE(ISC_LIST_EMPTY(fctx->queries));
- REQUIRE(ISC_LIST_EMPTY(fctx->finds));
- REQUIRE(ISC_LIST_EMPTY(fctx->altfinds));
- REQUIRE(fctx->pending == 0);
- REQUIRE(fctx->references == 0);
- REQUIRE(ISC_LIST_EMPTY(fctx->validators));
- REQUIRE(!ISC_LINK_LINKED(fctx, link));
-
- FCTXTRACE("destroy");
-
- /*
- * Free bad.
- */
- for (sa = ISC_LIST_HEAD(fctx->bad);
- sa != NULL;
- sa = next_sa) {
- next_sa = ISC_LIST_NEXT(sa, link);
- ISC_LIST_UNLINK(fctx->bad, sa, link);
- isc_mem_put(fctx->mctx, sa, sizeof(*sa));
- }
-
- for (sa = ISC_LIST_HEAD(fctx->edns);
- sa != NULL;
- sa = next_sa) {
- next_sa = ISC_LIST_NEXT(sa, link);
- ISC_LIST_UNLINK(fctx->edns, sa, link);
- isc_mem_put(fctx->mctx, sa, sizeof(*sa));
- }
-
- for (sa = ISC_LIST_HEAD(fctx->edns512);
- sa != NULL;
- sa = next_sa) {
- next_sa = ISC_LIST_NEXT(sa, link);
- ISC_LIST_UNLINK(fctx->edns512, sa, link);
- isc_mem_put(fctx->mctx, sa, sizeof(*sa));
- }
-
- for (sa = ISC_LIST_HEAD(fctx->bad_edns);
- sa != NULL;
- sa = next_sa) {
- next_sa = ISC_LIST_NEXT(sa, link);
- ISC_LIST_UNLINK(fctx->bad_edns, sa, link);
- isc_mem_put(fctx->mctx, sa, sizeof(*sa));
- }
-
- isc_timer_detach(&fctx->timer);
- dns_message_destroy(&fctx->rmessage);
- dns_message_destroy(&fctx->qmessage);
- if (dns_name_countlabels(&fctx->domain) > 0)
- dns_name_free(&fctx->domain, fctx->mctx);
- if (dns_rdataset_isassociated(&fctx->nameservers))
- dns_rdataset_disassociate(&fctx->nameservers);
- dns_name_free(&fctx->name, fctx->mctx);
- dns_db_detach(&fctx->cache);
- dns_adb_detach(&fctx->adb);
- isc_mem_free(fctx->mctx, fctx->info);
- isc_mem_putanddetach(&fctx->mctx, fctx, sizeof(*fctx));
-}
-
-/*
- * Fetch event handlers.
- */
-
-static void
-fctx_timeout(isc_task_t *task, isc_event_t *event) {
- fetchctx_t *fctx = event->ev_arg;
- isc_timerevent_t *tevent = (isc_timerevent_t *)event;
- resquery_t *query;
-
- REQUIRE(VALID_FCTX(fctx));
-
- UNUSED(task);
-
- FCTXTRACE("timeout");
-
- inc_stats(fctx->res, dns_resstatscounter_querytimeout);
-
- if (event->ev_type == ISC_TIMEREVENT_LIFE) {
- fctx->reason = NULL;
- fctx_done(fctx, ISC_R_TIMEDOUT, __LINE__);
- } else {
- isc_result_t result;
-
- fctx->timeouts++;
- fctx->timeout = ISC_TRUE;
- /*
- * We could cancel the running queries here, or we could let
- * them keep going. Since we normally use separate sockets for
- * different queries, we adopt the former approach to reduce
- * the number of open sockets: cancel the oldest query if it
- * expired after the query had started (this is usually the
- * case but is not always so, depending on the task schedule
- * timing).
- */
- query = ISC_LIST_HEAD(fctx->queries);
- if (query != NULL &&
- isc_time_compare(&tevent->due, &query->start) >= 0) {
- fctx_cancelquery(&query, NULL, NULL, ISC_TRUE);
- }
- fctx->attributes &= ~FCTX_ATTR_ADDRWAIT;
- /*
- * Our timer has triggered. Reestablish the fctx lifetime
- * timer.
- */
- result = fctx_starttimer(fctx);
- if (result != ISC_R_SUCCESS)
- fctx_done(fctx, result, __LINE__);
- else
- /*
- * Keep trying.
- */
- fctx_try(fctx, ISC_TRUE, ISC_FALSE);
- }
-
- isc_event_free(&event);
-}
-
-static void
-fctx_shutdown(fetchctx_t *fctx) {
- isc_event_t *cevent;
-
- /*
- * Start the shutdown process for fctx, if it isn't already underway.
- */
-
- FCTXTRACE("shutdown");
-
- /*
- * The caller must be holding the appropriate bucket lock.
- */
-
- if (fctx->want_shutdown)
- return;
-
- fctx->want_shutdown = ISC_TRUE;
-
- /*
- * Unless we're still initializing (in which case the
- * control event is still outstanding), we need to post
- * the control event to tell the fetch we want it to
- * exit.
- */
- if (fctx->state != fetchstate_init) {
- cevent = &fctx->control_event;
- isc_task_send(fctx->res->buckets[fctx->bucketnum].task,
- &cevent);
- }
-}
-
-static void
-fctx_doshutdown(isc_task_t *task, isc_event_t *event) {
- fetchctx_t *fctx = event->ev_arg;
- isc_boolean_t bucket_empty = ISC_FALSE;
- dns_resolver_t *res;
- unsigned int bucketnum;
- dns_validator_t *validator;
- isc_boolean_t destroy = ISC_FALSE;
-
- REQUIRE(VALID_FCTX(fctx));
-
- UNUSED(task);
-
- res = fctx->res;
- bucketnum = fctx->bucketnum;
-
- FCTXTRACE("doshutdown");
-
- /*
- * An fctx that is shutting down is no longer in ADDRWAIT mode.
- */
- fctx->attributes &= ~FCTX_ATTR_ADDRWAIT;
-
- /*
- * Cancel all pending validators. Note that this must be done
- * without the bucket lock held, since that could cause deadlock.
- */
- validator = ISC_LIST_HEAD(fctx->validators);
- while (validator != NULL) {
- dns_validator_cancel(validator);
- validator = ISC_LIST_NEXT(validator, link);
- }
-
- if (fctx->nsfetch != NULL)
- dns_resolver_cancelfetch(fctx->nsfetch);
-
- /*
- * Shut down anything that is still running on behalf of this
- * fetch. To avoid deadlock with the ADB, we must do this
- * before we lock the bucket lock.
- */
- fctx_stopeverything(fctx, ISC_FALSE);
-
- LOCK(&res->buckets[bucketnum].lock);
-
- fctx->attributes |= FCTX_ATTR_SHUTTINGDOWN;
-
- INSIST(fctx->state == fetchstate_active ||
- fctx->state == fetchstate_done);
- INSIST(fctx->want_shutdown);
-
- if (fctx->state != fetchstate_done) {
- fctx->state = fetchstate_done;
- fctx_sendevents(fctx, ISC_R_CANCELED, __LINE__);
- }
-
- if (fctx->references == 0 && fctx->pending == 0 &&
- fctx->nqueries == 0 && ISC_LIST_EMPTY(fctx->validators)) {
- bucket_empty = fctx_unlink(fctx);
- destroy = ISC_TRUE;
- }
-
- UNLOCK(&res->buckets[bucketnum].lock);
-
- if (destroy) {
- fctx_destroy(fctx);
- if (bucket_empty)
- empty_bucket(res);
- }
-}
-
-static void
-fctx_start(isc_task_t *task, isc_event_t *event) {
- fetchctx_t *fctx = event->ev_arg;
- isc_boolean_t done = ISC_FALSE, bucket_empty = ISC_FALSE;
- dns_resolver_t *res;
- unsigned int bucketnum;
- isc_boolean_t destroy = ISC_FALSE;
-
- REQUIRE(VALID_FCTX(fctx));
-
- UNUSED(task);
-
- res = fctx->res;
- bucketnum = fctx->bucketnum;
-
- FCTXTRACE("start");
-
- LOCK(&res->buckets[bucketnum].lock);
-
- INSIST(fctx->state == fetchstate_init);
- if (fctx->want_shutdown) {
- /*
- * We haven't started this fctx yet, and we've been requested
- * to shut it down.
- */
- fctx->attributes |= FCTX_ATTR_SHUTTINGDOWN;
- fctx->state = fetchstate_done;
- fctx_sendevents(fctx, ISC_R_CANCELED, __LINE__);
- /*
- * Since we haven't started, we INSIST that we have no
- * pending ADB finds and no pending validations.
- */
- INSIST(fctx->pending == 0);
- INSIST(fctx->nqueries == 0);
- INSIST(ISC_LIST_EMPTY(fctx->validators));
- if (fctx->references == 0) {
- /*
- * It's now safe to destroy this fctx.
- */
- bucket_empty = fctx_unlink(fctx);
- destroy = ISC_TRUE;
- }
- done = ISC_TRUE;
- } else {
- /*
- * Normal fctx startup.
- */
- fctx->state = fetchstate_active;
- /*
- * Reset the control event for later use in shutting down
- * the fctx.
- */
- ISC_EVENT_INIT(event, sizeof(*event), 0, NULL,
- DNS_EVENT_FETCHCONTROL, fctx_doshutdown, fctx,
- NULL, NULL, NULL);
- }
-
- UNLOCK(&res->buckets[bucketnum].lock);
-
- if (!done) {
- isc_result_t result;
-
- INSIST(!destroy);
-
- /*
- * All is well. Start working on the fetch.
- */
- result = fctx_starttimer(fctx);
- if (result != ISC_R_SUCCESS)
- fctx_done(fctx, result, __LINE__);
- else
- fctx_try(fctx, ISC_FALSE, ISC_FALSE);
- } else if (destroy) {
- fctx_destroy(fctx);
- if (bucket_empty)
- empty_bucket(res);
- }
-}
-
-/*
- * Fetch Creation, Joining, and Cancelation.
- */
-
-static inline isc_result_t
-fctx_join(fetchctx_t *fctx, isc_task_t *task, isc_sockaddr_t *client,
- dns_messageid_t id, isc_taskaction_t action, void *arg,
- dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
- dns_fetch_t *fetch)
-{
- isc_task_t *clone;
- dns_fetchevent_t *event;
-
- FCTXTRACE("join");
-
- /*
- * We store the task we're going to send this event to in the
- * sender field. We'll make the fetch the sender when we actually
- * send the event.
- */
- clone = NULL;
- isc_task_attach(task, &clone);
- event = (dns_fetchevent_t *)
- isc_event_allocate(fctx->res->mctx, clone, DNS_EVENT_FETCHDONE,
- action, arg, sizeof(*event));
- if (event == NULL) {
- isc_task_detach(&clone);
- return (ISC_R_NOMEMORY);
- }
- event->result = DNS_R_SERVFAIL;
- event->qtype = fctx->type;
- event->db = NULL;
- event->node = NULL;
- event->rdataset = rdataset;
- event->sigrdataset = sigrdataset;
- event->fetch = fetch;
- event->client = client;
- event->id = id;
- dns_fixedname_init(&event->foundname);
-
- /*
- * Make sure that we can store the sigrdataset in the
- * first event if it is needed by any of the events.
- */
- if (event->sigrdataset != NULL)
- ISC_LIST_PREPEND(fctx->events, event, ev_link);
- else
- ISC_LIST_APPEND(fctx->events, event, ev_link);
- fctx->references++;
- fctx->client = client;
-
- fetch->magic = DNS_FETCH_MAGIC;
- fetch->private = fctx;
-
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-log_ns_ttl(fetchctx_t *fctx, const char *where) {
- char namebuf[DNS_NAME_FORMATSIZE];
- char domainbuf[DNS_NAME_FORMATSIZE];
-
- dns_name_format(&fctx->name, namebuf, sizeof(namebuf));
- dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf));
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
- DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(10),
- "log_ns_ttl: fctx %p: %s: %s (in '%s'?): %u %u",
- fctx, where, namebuf, domainbuf,
- fctx->ns_ttl_ok, fctx->ns_ttl);
-}
-
-static isc_result_t
-fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
- dns_name_t *domain, dns_rdataset_t *nameservers,
- unsigned int options, unsigned int bucketnum, fetchctx_t **fctxp)
-{
- fetchctx_t *fctx;
- isc_result_t result;
- isc_result_t iresult;
- isc_interval_t interval;
- dns_fixedname_t fixed;
- unsigned int findoptions = 0;
- char buf[DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE];
- char typebuf[DNS_RDATATYPE_FORMATSIZE];
- dns_name_t suffix;
- isc_mem_t *mctx;
-
- /*
- * Caller must be holding the lock for bucket number 'bucketnum'.
- */
- REQUIRE(fctxp != NULL && *fctxp == NULL);
-
- mctx = res->buckets[bucketnum].mctx;
- fctx = isc_mem_get(mctx, sizeof(*fctx));
- if (fctx == NULL)
- return (ISC_R_NOMEMORY);
- dns_name_format(name, buf, sizeof(buf));
- dns_rdatatype_format(type, typebuf, sizeof(typebuf));
- strcat(buf, "/"); /* checked */
- strcat(buf, typebuf); /* checked */
- fctx->info = isc_mem_strdup(mctx, buf);
- if (fctx->info == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup_fetch;
- }
- FCTXTRACE("create");
- dns_name_init(&fctx->name, NULL);
- result = dns_name_dup(name, mctx, &fctx->name);
- if (result != ISC_R_SUCCESS)
- goto cleanup_info;
- dns_name_init(&fctx->domain, NULL);
- dns_rdataset_init(&fctx->nameservers);
-
- fctx->type = type;
- fctx->options = options;
- /*
- * Note! We do not attach to the task. We are relying on the
- * resolver to ensure that this task doesn't go away while we are
- * using it.
- */
- fctx->res = res;
- fctx->references = 0;
- fctx->bucketnum = bucketnum;
- fctx->state = fetchstate_init;
- fctx->want_shutdown = ISC_FALSE;
- fctx->cloned = ISC_FALSE;
- ISC_LIST_INIT(fctx->queries);
- ISC_LIST_INIT(fctx->finds);
- ISC_LIST_INIT(fctx->altfinds);
- ISC_LIST_INIT(fctx->forwaddrs);
- ISC_LIST_INIT(fctx->altaddrs);
- ISC_LIST_INIT(fctx->forwarders);
- fctx->fwdpolicy = dns_fwdpolicy_none;
- ISC_LIST_INIT(fctx->bad);
- ISC_LIST_INIT(fctx->edns);
- ISC_LIST_INIT(fctx->edns512);
- ISC_LIST_INIT(fctx->bad_edns);
- ISC_LIST_INIT(fctx->validators);
- fctx->validator = NULL;
- fctx->find = NULL;
- fctx->altfind = NULL;
- fctx->pending = 0;
- fctx->restarts = 0;
- fctx->querysent = 0;
- fctx->referrals = 0;
- TIME_NOW(&fctx->start);
- fctx->timeouts = 0;
- fctx->lamecount = 0;
- fctx->adberr = 0;
- fctx->neterr = 0;
- fctx->badresp = 0;
- fctx->findfail = 0;
- fctx->valfail = 0;
- fctx->result = ISC_R_FAILURE;
- fctx->vresult = ISC_R_SUCCESS;
- fctx->exitline = -1; /* sentinel */
- fctx->logged = ISC_FALSE;
- fctx->attributes = 0;
- fctx->spilled = ISC_FALSE;
- fctx->nqueries = 0;
- fctx->reason = NULL;
- fctx->rand_buf = 0;
- fctx->rand_bits = 0;
- fctx->timeout = ISC_FALSE;
- fctx->addrinfo = NULL;
- fctx->client = NULL;
- fctx->ns_ttl = 0;
- fctx->ns_ttl_ok = ISC_FALSE;
-
- dns_name_init(&fctx->nsname, NULL);
- fctx->nsfetch = NULL;
- dns_rdataset_init(&fctx->nsrrset);
-
- if (domain == NULL) {
- dns_forwarders_t *forwarders = NULL;
- unsigned int labels;
- dns_name_t *fwdname = name;
-
- /*
- * DS records are found in the parent server.
- * Strip label to get the correct forwarder (if any).
- */
- if (dns_rdatatype_atparent(fctx->type) &&
- dns_name_countlabels(name) > 1) {
- dns_name_init(&suffix, NULL);
- labels = dns_name_countlabels(name);
- dns_name_getlabelsequence(name, 1, labels - 1, &suffix);
- fwdname = &suffix;
- }
- dns_fixedname_init(&fixed);
- domain = dns_fixedname_name(&fixed);
- result = dns_fwdtable_find2(fctx->res->view->fwdtable, fwdname,
- domain, &forwarders);
- if (result == ISC_R_SUCCESS)
- fctx->fwdpolicy = forwarders->fwdpolicy;
-
- if (fctx->fwdpolicy != dns_fwdpolicy_only) {
- /*
- * The caller didn't supply a query domain and
- * nameservers, and we're not in forward-only mode,
- * so find the best nameservers to use.
- */
- if (dns_rdatatype_atparent(fctx->type))
- findoptions |= DNS_DBFIND_NOEXACT;
- result = dns_view_findzonecut(res->view, name, domain,
- 0, findoptions, ISC_TRUE,
- &fctx->nameservers,
- NULL);
- if (result != ISC_R_SUCCESS)
- goto cleanup_name;
- result = dns_name_dup(domain, mctx, &fctx->domain);
- if (result != ISC_R_SUCCESS) {
- dns_rdataset_disassociate(&fctx->nameservers);
- goto cleanup_name;
- }
- fctx->ns_ttl = fctx->nameservers.ttl;
- fctx->ns_ttl_ok = ISC_TRUE;
- } else {
- /*
- * We're in forward-only mode. Set the query domain.
- */
- result = dns_name_dup(domain, mctx, &fctx->domain);
- if (result != ISC_R_SUCCESS)
- goto cleanup_name;
- }
- } else {
- result = dns_name_dup(domain, mctx, &fctx->domain);
- if (result != ISC_R_SUCCESS)
- goto cleanup_name;
- dns_rdataset_clone(nameservers, &fctx->nameservers);
- fctx->ns_ttl = fctx->nameservers.ttl;
- fctx->ns_ttl_ok = ISC_TRUE;
- }
-
- log_ns_ttl(fctx, "fctx_create");
-
- INSIST(dns_name_issubdomain(&fctx->name, &fctx->domain));
-
- fctx->qmessage = NULL;
- result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER,
- &fctx->qmessage);
-
- if (result != ISC_R_SUCCESS)
- goto cleanup_domain;
-
- fctx->rmessage = NULL;
- result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE,
- &fctx->rmessage);
-
- if (result != ISC_R_SUCCESS)
- goto cleanup_qmessage;
-
- /*
- * Compute an expiration time for the entire fetch.
- */
- isc_interval_set(&interval, res->query_timeout, 0);
- iresult = isc_time_nowplusinterval(&fctx->expires, &interval);
- if (iresult != ISC_R_SUCCESS) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_time_nowplusinterval: %s",
- isc_result_totext(iresult));
- result = ISC_R_UNEXPECTED;
- goto cleanup_rmessage;
- }
-
- /*
- * Default retry interval initialization. We set the interval now
- * mostly so it won't be uninitialized. It will be set to the
- * correct value before a query is issued.
- */
- isc_interval_set(&fctx->interval, 2, 0);
-
- /*
- * Create an inactive timer. It will be made active when the fetch
- * is actually started.
- */
- fctx->timer = NULL;
- iresult = isc_timer_create(res->timermgr, isc_timertype_inactive,
- NULL, NULL,
- res->buckets[bucketnum].task, fctx_timeout,
- fctx, &fctx->timer);
- if (iresult != ISC_R_SUCCESS) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_timer_create: %s",
- isc_result_totext(iresult));
- result = ISC_R_UNEXPECTED;
- goto cleanup_rmessage;
- }
-
- /*
- * Attach to the view's cache and adb.
- */
- fctx->cache = NULL;
- dns_db_attach(res->view->cachedb, &fctx->cache);
- fctx->adb = NULL;
- dns_adb_attach(res->view->adb, &fctx->adb);
- fctx->mctx = NULL;
- isc_mem_attach(mctx, &fctx->mctx);
-
- ISC_LIST_INIT(fctx->events);
- ISC_LINK_INIT(fctx, link);
- fctx->magic = FCTX_MAGIC;
-
- ISC_LIST_APPEND(res->buckets[bucketnum].fctxs, fctx, link);
-
- LOCK(&res->nlock);
- res->nfctx++;
- UNLOCK(&res->nlock);
-
- *fctxp = fctx;
-
- return (ISC_R_SUCCESS);
-
- cleanup_rmessage:
- dns_message_destroy(&fctx->rmessage);
-
- cleanup_qmessage:
- dns_message_destroy(&fctx->qmessage);
-
- cleanup_domain:
- if (dns_name_countlabels(&fctx->domain) > 0)
- dns_name_free(&fctx->domain, mctx);
- if (dns_rdataset_isassociated(&fctx->nameservers))
- dns_rdataset_disassociate(&fctx->nameservers);
-
- cleanup_name:
- dns_name_free(&fctx->name, mctx);
-
- cleanup_info:
- isc_mem_free(mctx, fctx->info);
-
- cleanup_fetch:
- isc_mem_put(mctx, fctx, sizeof(*fctx));
-
- return (result);
-}
-
-/*
- * Handle Responses
- */
-static inline isc_boolean_t
-is_lame(fetchctx_t *fctx) {
- dns_message_t *message = fctx->rmessage;
- dns_name_t *name;
- dns_rdataset_t *rdataset;
- isc_result_t result;
-
- if (message->rcode != dns_rcode_noerror &&
- message->rcode != dns_rcode_nxdomain)
- return (ISC_FALSE);
-
- if (message->counts[DNS_SECTION_ANSWER] != 0)
- return (ISC_FALSE);
-
- if (message->counts[DNS_SECTION_AUTHORITY] == 0)
- return (ISC_FALSE);
-
- result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
- while (result == ISC_R_SUCCESS) {
- name = NULL;
- dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name);
- for (rdataset = ISC_LIST_HEAD(name->list);
- rdataset != NULL;
- rdataset = ISC_LIST_NEXT(rdataset, link)) {
- dns_namereln_t namereln;
- int order;
- unsigned int labels;
- if (rdataset->type != dns_rdatatype_ns)
- continue;
- namereln = dns_name_fullcompare(name, &fctx->domain,
- &order, &labels);
- if (namereln == dns_namereln_equal &&
- (message->flags & DNS_MESSAGEFLAG_AA) != 0)
- return (ISC_FALSE);
- if (namereln == dns_namereln_subdomain)
- return (ISC_FALSE);
- return (ISC_TRUE);
- }
- result = dns_message_nextname(message, DNS_SECTION_AUTHORITY);
- }
-
- return (ISC_FALSE);
-}
-
-static inline void
-log_lame(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo) {
- char namebuf[DNS_NAME_FORMATSIZE];
- char domainbuf[DNS_NAME_FORMATSIZE];
- char addrbuf[ISC_SOCKADDR_FORMATSIZE];
-
- dns_name_format(&fctx->name, namebuf, sizeof(namebuf));
- dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf));
- isc_sockaddr_format(&addrinfo->sockaddr, addrbuf, sizeof(addrbuf));
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_LAME_SERVERS,
- DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO,
- "lame server resolving '%s' (in '%s'?): %s",
- 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;
- dns_message_t *message = fctx->rmessage;
- dns_name_t *name;
- dns_rdataset_t *rdataset;
-
- /*
- * Caller must be holding the fctx lock.
- */
-
- /*
- * XXXRTH Currently we support only one question.
- */
- 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)
- return (result);
- name = NULL;
- dns_message_currentname(message, DNS_SECTION_QUESTION, &name);
- 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)) {
- 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);
-}
-
-static void
-clone_results(fetchctx_t *fctx) {
- dns_fetchevent_t *event, *hevent;
- isc_result_t result;
- dns_name_t *name, *hname;
-
- FCTXTRACE("clone_results");
-
- /*
- * Set up any other events to have the same data as the first
- * event.
- *
- * Caller must be holding the appropriate lock.
- */
-
- fctx->cloned = ISC_TRUE;
- hevent = ISC_LIST_HEAD(fctx->events);
- if (hevent == NULL)
- return;
- hname = dns_fixedname_name(&hevent->foundname);
- for (event = ISC_LIST_NEXT(hevent, ev_link);
- event != NULL;
- event = ISC_LIST_NEXT(event, ev_link)) {
- name = dns_fixedname_name(&event->foundname);
- result = dns_name_copy(hname, name, NULL);
- if (result != ISC_R_SUCCESS)
- event->result = result;
- else
- event->result = hevent->result;
- dns_db_attach(hevent->db, &event->db);
- dns_db_attachnode(hevent->db, hevent->node, &event->node);
- INSIST(hevent->rdataset != NULL);
- INSIST(event->rdataset != NULL);
- if (dns_rdataset_isassociated(hevent->rdataset))
- dns_rdataset_clone(hevent->rdataset, event->rdataset);
- INSIST(! (hevent->sigrdataset == NULL &&
- event->sigrdataset != NULL));
- if (hevent->sigrdataset != NULL &&
- dns_rdataset_isassociated(hevent->sigrdataset) &&
- event->sigrdataset != NULL)
- dns_rdataset_clone(hevent->sigrdataset,
- event->sigrdataset);
- }
-}
-
-#define CACHE(r) (((r)->attributes & DNS_RDATASETATTR_CACHE) != 0)
-#define ANSWER(r) (((r)->attributes & DNS_RDATASETATTR_ANSWER) != 0)
-#define ANSWERSIG(r) (((r)->attributes & DNS_RDATASETATTR_ANSWERSIG) != 0)
-#define EXTERNAL(r) (((r)->attributes & DNS_RDATASETATTR_EXTERNAL) != 0)
-#define CHAINING(r) (((r)->attributes & DNS_RDATASETATTR_CHAINING) != 0)
-#define CHASE(r) (((r)->attributes & DNS_RDATASETATTR_CHASE) != 0)
-#define CHECKNAMES(r) (((r)->attributes & DNS_RDATASETATTR_CHECKNAMES) != 0)
-
-
-/*
- * Destroy '*fctx' if it is ready to be destroyed (i.e., if it has
- * no references and is no longer waiting for any events).
- *
- * Requires:
- * '*fctx' is shutting down.
- *
- * Returns:
- * true if the resolver is exiting and this is the last fctx in the bucket.
- */
-static isc_boolean_t
-maybe_destroy(fetchctx_t *fctx, isc_boolean_t locked) {
- unsigned int bucketnum;
- isc_boolean_t bucket_empty = ISC_FALSE;
- dns_resolver_t *res = fctx->res;
- dns_validator_t *validator, *next_validator;
- isc_boolean_t destroy = ISC_FALSE;
-
- REQUIRE(SHUTTINGDOWN(fctx));
-
- bucketnum = fctx->bucketnum;
- if (!locked)
- LOCK(&res->buckets[bucketnum].lock);
- if (fctx->pending != 0 || fctx->nqueries != 0)
- goto unlock;
-
- for (validator = ISC_LIST_HEAD(fctx->validators);
- validator != NULL; validator = next_validator) {
- next_validator = ISC_LIST_NEXT(validator, link);
- dns_validator_cancel(validator);
- }
-
- if (fctx->references == 0 && ISC_LIST_EMPTY(fctx->validators)) {
- bucket_empty = fctx_unlink(fctx);
- destroy = ISC_TRUE;
- }
- unlock:
- if (!locked)
- UNLOCK(&res->buckets[bucketnum].lock);
- if (destroy)
- fctx_destroy(fctx);
- return (bucket_empty);
-}
-
-/*
- * The validator has finished.
- */
-static void
-validated(isc_task_t *task, isc_event_t *event) {
- dns_adbaddrinfo_t *addrinfo;
- dns_dbnode_t *node = NULL;
- dns_dbnode_t *nsnode = NULL;
- dns_fetchevent_t *hevent;
- dns_name_t *name;
- dns_rdataset_t *ardataset = NULL;
- dns_rdataset_t *asigrdataset = NULL;
- dns_rdataset_t *rdataset;
- dns_rdataset_t *sigrdataset;
- dns_resolver_t *res;
- dns_valarg_t *valarg;
- dns_validatorevent_t *vevent;
- fetchctx_t *fctx;
- isc_boolean_t chaining;
- isc_boolean_t negative;
- isc_boolean_t sentresponse;
- isc_result_t eresult = ISC_R_SUCCESS;
- isc_result_t result = ISC_R_SUCCESS;
- isc_stdtime_t now;
- isc_uint32_t ttl;
-
- UNUSED(task); /* for now */
-
- REQUIRE(event->ev_type == DNS_EVENT_VALIDATORDONE);
- valarg = event->ev_arg;
- fctx = valarg->fctx;
- res = fctx->res;
- addrinfo = valarg->addrinfo;
- REQUIRE(VALID_FCTX(fctx));
- REQUIRE(!ISC_LIST_EMPTY(fctx->validators));
-
- vevent = (dns_validatorevent_t *)event;
- fctx->vresult = vevent->result;
-
- FCTXTRACE("received validation completion event");
-
- LOCK(&res->buckets[fctx->bucketnum].lock);
-
- ISC_LIST_UNLINK(fctx->validators, vevent->validator, link);
- fctx->validator = NULL;
-
- /*
- * Destroy the validator early so that we can
- * destroy the fctx if necessary.
- */
- dns_validator_destroy(&vevent->validator);
- isc_mem_put(fctx->mctx, valarg, sizeof(*valarg));
-
- negative = ISC_TF(vevent->rdataset == NULL);
-
- sentresponse = ISC_TF((fctx->options & DNS_FETCHOPT_NOVALIDATE) != 0);
-
- /*
- * If shutting down, ignore the results. Check to see if we're
- * done waiting for validator completions and ADB pending events; if
- * so, destroy the fctx.
- */
- if (SHUTTINGDOWN(fctx) && !sentresponse) {
- isc_uint32_t bucketnum = fctx->bucketnum;
- isc_boolean_t bucket_empty;
- bucket_empty = maybe_destroy(fctx, ISC_TRUE);
- UNLOCK(&res->buckets[bucketnum].lock);
- if (bucket_empty)
- empty_bucket(res);
- goto cleanup_event;
- }
-
- isc_stdtime_get(&now);
-
- /*
- * If chaining, we need to make sure that the right result code is
- * returned, and that the rdatasets are bound.
- */
- if (vevent->result == ISC_R_SUCCESS &&
- !negative &&
- vevent->rdataset != NULL &&
- CHAINING(vevent->rdataset))
- {
- if (vevent->rdataset->type == dns_rdatatype_cname)
- eresult = DNS_R_CNAME;
- else {
- INSIST(vevent->rdataset->type == dns_rdatatype_dname);
- eresult = DNS_R_DNAME;
- }
- chaining = ISC_TRUE;
- } else
- chaining = ISC_FALSE;
-
- /*
- * Either we're not shutting down, or we are shutting down but want
- * to cache the result anyway (if this was a validation started by
- * a query with cd set)
- */
-
- hevent = ISC_LIST_HEAD(fctx->events);
- if (hevent != NULL) {
- if (!negative && !chaining &&
- (fctx->type == dns_rdatatype_any ||
- fctx->type == dns_rdatatype_rrsig ||
- fctx->type == dns_rdatatype_sig)) {
- /*
- * Don't bind rdatasets; the caller
- * will iterate the node.
- */
- } else {
- ardataset = hevent->rdataset;
- asigrdataset = hevent->sigrdataset;
- }
- }
-
- if (vevent->result != ISC_R_SUCCESS) {
- FCTXTRACE("validation failed");
- inc_stats(res, dns_resstatscounter_valfail);
- fctx->valfail++;
- fctx->vresult = vevent->result;
- if (fctx->vresult != DNS_R_BROKENCHAIN) {
- result = ISC_R_NOTFOUND;
- if (vevent->rdataset != NULL)
- result = dns_db_findnode(fctx->cache,
- vevent->name,
- ISC_TRUE, &node);
- if (result == ISC_R_SUCCESS)
- (void)dns_db_deleterdataset(fctx->cache, node,
- NULL,
- vevent->type, 0);
- if (result == ISC_R_SUCCESS &&
- vevent->sigrdataset != NULL)
- (void)dns_db_deleterdataset(fctx->cache, node,
- NULL,
- dns_rdatatype_rrsig,
- vevent->type);
- if (result == ISC_R_SUCCESS)
- dns_db_detachnode(fctx->cache, &node);
- }
- if (fctx->vresult == DNS_R_BROKENCHAIN && !negative) {
- /*
- * Cache the data as pending for later validation.
- */
- result = ISC_R_NOTFOUND;
- if (vevent->rdataset != NULL)
- result = dns_db_findnode(fctx->cache,
- vevent->name,
- ISC_TRUE, &node);
- if (result == ISC_R_SUCCESS) {
- (void)dns_db_addrdataset(fctx->cache, node,
- NULL, now,
- vevent->rdataset, 0,
- NULL);
- }
- if (result == ISC_R_SUCCESS &&
- vevent->sigrdataset != NULL)
- (void)dns_db_addrdataset(fctx->cache, node,
- NULL, now,
- vevent->sigrdataset,
- 0, NULL);
- if (result == ISC_R_SUCCESS)
- dns_db_detachnode(fctx->cache, &node);
- }
- result = fctx->vresult;
- add_bad(fctx, addrinfo, result, badns_validation);
- isc_event_free(&event);
- UNLOCK(&res->buckets[fctx->bucketnum].lock);
- INSIST(fctx->validator == NULL);
- fctx->validator = ISC_LIST_HEAD(fctx->validators);
- if (fctx->validator != NULL)
- dns_validator_send(fctx->validator);
- else if (sentresponse)
- fctx_done(fctx, result, __LINE__); /* Locks bucket. */
- else if (result == DNS_R_BROKENCHAIN) {
- isc_result_t tresult;
- isc_time_t expire;
- isc_interval_t i;
-
- isc_interval_set(&i, DNS_BADCACHE_TTL(fctx), 0);
- tresult = isc_time_nowplusinterval(&expire, &i);
- if (negative &&
- (fctx->type == dns_rdatatype_dnskey ||
- fctx->type == dns_rdatatype_dlv ||
- fctx->type == dns_rdatatype_ds) &&
- tresult == ISC_R_SUCCESS)
- dns_resolver_addbadcache(res, &fctx->name,
- fctx->type, &expire);
- fctx_done(fctx, result, __LINE__); /* Locks bucket. */
- } else
- fctx_try(fctx, ISC_TRUE, ISC_TRUE); /* Locks bucket. */
- return;
- }
-
-
- if (negative) {
- dns_rdatatype_t covers;
- FCTXTRACE("nonexistence validation OK");
-
- inc_stats(res, dns_resstatscounter_valnegsuccess);
-
- if (fctx->rmessage->rcode == dns_rcode_nxdomain)
- covers = dns_rdatatype_any;
- else
- covers = fctx->type;
-
- result = dns_db_findnode(fctx->cache, vevent->name, ISC_TRUE,
- &node);
- if (result != ISC_R_SUCCESS)
- goto noanswer_response;
-
- /*
- * If we are asking for a SOA record set the cache time
- * to zero to facilitate locating the containing zone of
- * a arbitrary zone.
- */
- ttl = res->view->maxncachettl;
- if (fctx->type == dns_rdatatype_soa &&
- covers == dns_rdatatype_any && res->zero_no_soa_ttl)
- ttl = 0;
-
- result = ncache_adderesult(fctx->rmessage, fctx->cache, node,
- covers, now, ttl, vevent->optout,
- vevent->secure, ardataset, &eresult);
- if (result != ISC_R_SUCCESS)
- goto noanswer_response;
- goto answer_response;
- } else
- inc_stats(res, dns_resstatscounter_valsuccess);
-
- FCTXTRACE("validation OK");
-
- if (vevent->proofs[DNS_VALIDATOR_NOQNAMEPROOF] != NULL) {
- result = dns_rdataset_addnoqname(vevent->rdataset,
- vevent->proofs[DNS_VALIDATOR_NOQNAMEPROOF]);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- INSIST(vevent->sigrdataset != NULL);
- vevent->sigrdataset->ttl = vevent->rdataset->ttl;
- if (vevent->proofs[DNS_VALIDATOR_CLOSESTENCLOSER] != NULL) {
- result = dns_rdataset_addclosest(vevent->rdataset,
- vevent->proofs[DNS_VALIDATOR_CLOSESTENCLOSER]);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- }
- } else if (vevent->rdataset->trust == dns_trust_answer &&
- vevent->rdataset->type != dns_rdatatype_rrsig)
- {
- isc_result_t tresult;
- dns_name_t *noqname = NULL;
- tresult = findnoqname(fctx, vevent->name,
- vevent->rdataset->type, &noqname);
- if (tresult == ISC_R_SUCCESS && noqname != NULL) {
- tresult = dns_rdataset_addnoqname(vevent->rdataset,
- noqname);
- RUNTIME_CHECK(tresult == ISC_R_SUCCESS);
- }
- }
-
- /*
- * The data was already cached as pending data.
- * Re-cache it as secure and bind the cached
- * rdatasets to the first event on the fetch
- * event list.
- */
- result = dns_db_findnode(fctx->cache, vevent->name, ISC_TRUE, &node);
- if (result != ISC_R_SUCCESS)
- goto noanswer_response;
-
- result = dns_db_addrdataset(fctx->cache, node, NULL, now,
- vevent->rdataset, 0, ardataset);
- if (result != ISC_R_SUCCESS &&
- result != DNS_R_UNCHANGED)
- goto noanswer_response;
- if (ardataset != NULL && NEGATIVE(ardataset)) {
- if (NXDOMAIN(ardataset))
- eresult = DNS_R_NCACHENXDOMAIN;
- else
- eresult = DNS_R_NCACHENXRRSET;
- } else if (vevent->sigrdataset != NULL) {
- result = dns_db_addrdataset(fctx->cache, node, NULL, now,
- vevent->sigrdataset, 0,
- asigrdataset);
- if (result != ISC_R_SUCCESS &&
- result != DNS_R_UNCHANGED)
- goto noanswer_response;
- }
-
- if (sentresponse) {
- isc_boolean_t bucket_empty = ISC_FALSE;
- /*
- * If we only deferred the destroy because we wanted to cache
- * the data, destroy now.
- */
- dns_db_detachnode(fctx->cache, &node);
- if (SHUTTINGDOWN(fctx))
- bucket_empty = maybe_destroy(fctx, ISC_TRUE);
- UNLOCK(&res->buckets[fctx->bucketnum].lock);
- if (bucket_empty)
- empty_bucket(res);
- goto cleanup_event;
- }
-
- if (!ISC_LIST_EMPTY(fctx->validators)) {
- INSIST(!negative);
- INSIST(fctx->type == dns_rdatatype_any ||
- fctx->type == dns_rdatatype_rrsig ||
- fctx->type == dns_rdatatype_sig);
- /*
- * Don't send a response yet - we have
- * more rdatasets that still need to
- * be validated.
- */
- dns_db_detachnode(fctx->cache, &node);
- UNLOCK(&res->buckets[fctx->bucketnum].lock);
- dns_validator_send(ISC_LIST_HEAD(fctx->validators));
- goto cleanup_event;
- }
-
- answer_response:
- /*
- * Cache any NS/NSEC records that happened to be validated.
- */
- result = dns_message_firstname(fctx->rmessage, DNS_SECTION_AUTHORITY);
- while (result == ISC_R_SUCCESS) {
- name = NULL;
- dns_message_currentname(fctx->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_ns &&
- rdataset->type != dns_rdatatype_nsec) ||
- rdataset->trust != dns_trust_secure)
- continue;
- for (sigrdataset = ISC_LIST_HEAD(name->list);
- sigrdataset != NULL;
- sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) {
- if (sigrdataset->type != dns_rdatatype_rrsig ||
- sigrdataset->covers != rdataset->type)
- continue;
- break;
- }
- if (sigrdataset == NULL ||
- sigrdataset->trust != dns_trust_secure)
- continue;
- result = dns_db_findnode(fctx->cache, name, ISC_TRUE,
- &nsnode);
- if (result != ISC_R_SUCCESS)
- continue;
-
- result = dns_db_addrdataset(fctx->cache, nsnode, NULL,
- now, rdataset, 0, NULL);
- if (result == ISC_R_SUCCESS)
- result = dns_db_addrdataset(fctx->cache, nsnode,
- NULL, now,
- sigrdataset, 0,
- NULL);
- dns_db_detachnode(fctx->cache, &nsnode);
- if (result != ISC_R_SUCCESS)
- continue;
- }
- result = dns_message_nextname(fctx->rmessage,
- DNS_SECTION_AUTHORITY);
- }
-
- result = ISC_R_SUCCESS;
-
- /*
- * Respond with an answer, positive or negative,
- * as opposed to an error. 'node' must be non-NULL.
- */
-
- fctx->attributes |= FCTX_ATTR_HAVEANSWER;
-
- if (hevent != NULL) {
- /*
- * Negative results must be indicated in event->result.
- */
- if (dns_rdataset_isassociated(hevent->rdataset) &&
- NEGATIVE(hevent->rdataset)) {
- INSIST(eresult == DNS_R_NCACHENXDOMAIN ||
- eresult == DNS_R_NCACHENXRRSET);
- }
- hevent->result = eresult;
- RUNTIME_CHECK(dns_name_copy(vevent->name,
- dns_fixedname_name(&hevent->foundname), NULL)
- == ISC_R_SUCCESS);
- dns_db_attach(fctx->cache, &hevent->db);
- dns_db_transfernode(fctx->cache, &node, &hevent->node);
- clone_results(fctx);
- }
-
- noanswer_response:
- if (node != NULL)
- dns_db_detachnode(fctx->cache, &node);
-
- UNLOCK(&res->buckets[fctx->bucketnum].lock);
- fctx_done(fctx, result, __LINE__); /* Locks bucket. */
-
- cleanup_event:
- INSIST(node == NULL);
- isc_event_free(&event);
-}
-
-static void
-fctx_log(void *arg, int level, const char *fmt, ...) {
- char msgbuf[2048];
- va_list args;
- fetchctx_t *fctx = arg;
-
- va_start(args, fmt);
- vsnprintf(msgbuf, sizeof(msgbuf), fmt, args);
- va_end(args);
-
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
- DNS_LOGMODULE_RESOLVER, level,
- "fctx %p(%s): %s", fctx, fctx->info, msgbuf);
-}
-
-static inline isc_result_t
-findnoqname(fetchctx_t *fctx, dns_name_t *name, dns_rdatatype_t type,
- dns_name_t **noqnamep)
-{
- dns_rdataset_t *nrdataset, *next, *sigrdataset;
- dns_rdata_rrsig_t rrsig;
- isc_result_t result;
- unsigned int labels;
- dns_section_t section;
- dns_name_t *zonename;
- dns_fixedname_t fzonename;
- dns_name_t *closest;
- dns_fixedname_t fclosest;
- dns_name_t *nearest;
- dns_fixedname_t fnearest;
- dns_rdatatype_t found = dns_rdatatype_none;
- dns_name_t *noqname = NULL;
-
- FCTXTRACE("findnoqname");
-
- REQUIRE(noqnamep != NULL && *noqnamep == NULL);
-
- /*
- * Find the SIG for this rdataset, if we have it.
- */
- for (sigrdataset = ISC_LIST_HEAD(name->list);
- sigrdataset != NULL;
- sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) {
- if (sigrdataset->type == dns_rdatatype_rrsig &&
- sigrdataset->covers == type)
- break;
- }
-
- if (sigrdataset == NULL)
- return (ISC_R_NOTFOUND);
-
- labels = dns_name_countlabels(name);
-
- for (result = dns_rdataset_first(sigrdataset);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(sigrdataset)) {
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdataset_current(sigrdataset, &rdata);
- result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- /* Wildcard has rrsig.labels < labels - 1. */
- if (rrsig.labels + 1U >= labels)
- continue;
- break;
- }
-
- if (result == ISC_R_NOMORE)
- return (ISC_R_NOTFOUND);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- dns_fixedname_init(&fzonename);
- zonename = dns_fixedname_name(&fzonename);
- dns_fixedname_init(&fclosest);
- closest = dns_fixedname_name(&fclosest);
- dns_fixedname_init(&fnearest);
- nearest = dns_fixedname_name(&fnearest);
-
-#define NXND(x) ((x) == ISC_R_SUCCESS)
-
- section = DNS_SECTION_AUTHORITY;
- for (result = dns_message_firstname(fctx->rmessage, section);
- result == ISC_R_SUCCESS;
- result = dns_message_nextname(fctx->rmessage, section)) {
- dns_name_t *nsec = NULL;
- dns_message_currentname(fctx->rmessage, section, &nsec);
- for (nrdataset = ISC_LIST_HEAD(nsec->list);
- nrdataset != NULL; nrdataset = next) {
- isc_boolean_t data = ISC_FALSE, exists = ISC_FALSE;
- isc_boolean_t optout = ISC_FALSE, unknown = ISC_FALSE;
- isc_boolean_t setclosest = ISC_FALSE;
- isc_boolean_t setnearest = ISC_FALSE;
-
- next = ISC_LIST_NEXT(nrdataset, link);
- if (nrdataset->type != dns_rdatatype_nsec &&
- nrdataset->type != dns_rdatatype_nsec3)
- continue;
-
- if (nrdataset->type == dns_rdatatype_nsec &&
- NXND(dns_nsec_noexistnodata(type, name, nsec,
- nrdataset, &exists,
- &data, NULL, fctx_log,
- fctx)))
- {
- if (!exists) {
- noqname = nsec;
- found = dns_rdatatype_nsec;
- }
- }
-
- if (nrdataset->type == dns_rdatatype_nsec3 &&
- NXND(dns_nsec3_noexistnodata(type, name, nsec,
- nrdataset, zonename,
- &exists, &data,
- &optout, &unknown,
- &setclosest,
- &setnearest,
- closest, nearest,
- fctx_log, fctx)))
- {
- if (!exists && setnearest) {
- noqname = nsec;
- found = dns_rdatatype_nsec3;
- }
- }
- }
- }
- if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
- if (noqname != NULL) {
- for (sigrdataset = ISC_LIST_HEAD(noqname->list);
- sigrdataset != NULL;
- sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) {
- if (sigrdataset->type == dns_rdatatype_rrsig &&
- sigrdataset->covers == found)
- break;
- }
- if (sigrdataset != NULL)
- *noqnamep = noqname;
- }
- return (result);
-}
-
-static inline isc_result_t
-cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo,
- isc_stdtime_t now)
-{
- dns_rdataset_t *rdataset, *sigrdataset;
- dns_rdataset_t *addedrdataset, *ardataset, *asigrdataset;
- dns_rdataset_t *valrdataset = NULL, *valsigrdataset = NULL;
- dns_dbnode_t *node, **anodep;
- dns_db_t **adbp;
- dns_name_t *aname;
- dns_resolver_t *res;
- isc_boolean_t need_validation, secure_domain, have_answer;
- isc_result_t result, eresult;
- dns_fetchevent_t *event;
- unsigned int options;
- isc_task_t *task;
- isc_boolean_t fail;
- unsigned int valoptions = 0;
-
- /*
- * The appropriate bucket lock must be held.
- */
-
- res = fctx->res;
- need_validation = ISC_FALSE;
- POST(need_validation);
- secure_domain = ISC_FALSE;
- have_answer = ISC_FALSE;
- eresult = ISC_R_SUCCESS;
- task = res->buckets[fctx->bucketnum].task;
-
- /*
- * Is DNSSEC validation required for this name?
- */
- if (res->view->enablevalidation) {
- result = dns_view_issecuredomain(res->view, name,
- &secure_domain);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- if (!secure_domain && res->view->dlv != NULL) {
- valoptions = DNS_VALIDATOR_DLV;
- secure_domain = ISC_TRUE;
- }
- }
-
- if ((fctx->options & DNS_FETCHOPT_NOVALIDATE) != 0)
- need_validation = ISC_FALSE;
- else
- need_validation = secure_domain;
-
- adbp = NULL;
- aname = NULL;
- anodep = NULL;
- ardataset = NULL;
- asigrdataset = NULL;
- event = NULL;
- if ((name->attributes & DNS_NAMEATTR_ANSWER) != 0 &&
- !need_validation) {
- have_answer = ISC_TRUE;
- event = ISC_LIST_HEAD(fctx->events);
- if (event != NULL) {
- adbp = &event->db;
- aname = dns_fixedname_name(&event->foundname);
- result = dns_name_copy(name, aname, NULL);
- if (result != ISC_R_SUCCESS)
- return (result);
- anodep = &event->node;
- /*
- * If this is an ANY, SIG or RRSIG query, we're not
- * going to return any rdatasets, unless we encountered
- * a CNAME or DNAME as "the answer". In this case,
- * we're going to return DNS_R_CNAME or DNS_R_DNAME
- * and we must set up the rdatasets.
- */
- if ((fctx->type != dns_rdatatype_any &&
- fctx->type != dns_rdatatype_rrsig &&
- fctx->type != dns_rdatatype_sig) ||
- (name->attributes & DNS_NAMEATTR_CHAINING) != 0) {
- ardataset = event->rdataset;
- asigrdataset = event->sigrdataset;
- }
- }
- }
-
- /*
- * Find or create the cache node.
- */
- node = NULL;
- result = dns_db_findnode(fctx->cache, name, ISC_TRUE, &node);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- /*
- * Cache or validate each cacheable rdataset.
- */
- fail = ISC_TF((fctx->res->options & DNS_RESOLVER_CHECKNAMESFAIL) != 0);
- for (rdataset = ISC_LIST_HEAD(name->list);
- rdataset != NULL;
- rdataset = ISC_LIST_NEXT(rdataset, link)) {
- if (!CACHE(rdataset))
- continue;
- if (CHECKNAMES(rdataset)) {
- char namebuf[DNS_NAME_FORMATSIZE];
- char typebuf[DNS_RDATATYPE_FORMATSIZE];
- char classbuf[DNS_RDATATYPE_FORMATSIZE];
-
- 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,
- "check-names %s %s/%s/%s",
- fail ? "failure" : "warning",
- namebuf, typebuf, classbuf);
- if (fail) {
- if (ANSWER(rdataset)) {
- dns_db_detachnode(fctx->cache, &node);
- return (DNS_R_BADNAME);
- }
- continue;
- }
- }
-
- /*
- * Enforce the configure maximum cache TTL.
- */
- if (rdataset->ttl > res->view->maxcachettl)
- rdataset->ttl = res->view->maxcachettl;
-
- /*
- * Find the SIG for this rdataset, if we have it.
- */
- for (sigrdataset = ISC_LIST_HEAD(name->list);
- sigrdataset != NULL;
- sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) {
- if (sigrdataset->type == dns_rdatatype_rrsig &&
- sigrdataset->covers == rdataset->type)
- break;
- }
-
- /*
- * If this RRset is in a secure domain, is in bailiwick,
- * and is not glue, attempt DNSSEC validation. (We do not
- * attempt to validate glue or out-of-bailiwick data--even
- * though there might be some performance benefit to doing
- * so--because it makes it simpler and safer to ensure that
- * records from a secure domain are only cached if validated
- * within the context of a query to the domain that owns
- * them.)
- */
- if (secure_domain && rdataset->trust != dns_trust_glue &&
- !EXTERNAL(rdataset)) {
- dns_trust_t trust;
-
- /*
- * RRSIGs are validated as part of validating the
- * type they cover.
- */
- if (rdataset->type == dns_rdatatype_rrsig)
- continue;
-
- if (sigrdataset == NULL) {
- if (!ANSWER(rdataset) && need_validation) {
- /*
- * Ignore non-answer rdatasets that
- * are missing signatures.
- */
- continue;
- }
- }
-
- /*
- * Normalize the rdataset and sigrdataset TTLs.
- */
- if (sigrdataset != NULL) {
- rdataset->ttl = ISC_MIN(rdataset->ttl,
- sigrdataset->ttl);
- sigrdataset->ttl = rdataset->ttl;
- }
-
- /*
- * Cache this rdataset/sigrdataset pair as
- * pending data. Track whether it was additional
- * or not.
- */
- if (rdataset->trust == dns_trust_additional)
- trust = dns_trust_pending_additional;
- else
- trust = dns_trust_pending_answer;
-
- rdataset->trust = trust;
- if (sigrdataset != NULL)
- sigrdataset->trust = trust;
- if (!need_validation || !ANSWER(rdataset)) {
- if (ANSWER(rdataset) &&
- rdataset->type != dns_rdatatype_rrsig) {
- isc_result_t tresult;
- dns_name_t *noqname = NULL;
- tresult = findnoqname(fctx, name,
- rdataset->type,
- &noqname);
- if (tresult == ISC_R_SUCCESS &&
- noqname != NULL) {
- tresult =
- dns_rdataset_addnoqname(
- rdataset, noqname);
- RUNTIME_CHECK(tresult ==
- ISC_R_SUCCESS);
- }
- }
- addedrdataset = ardataset;
- result = dns_db_addrdataset(fctx->cache, node,
- NULL, now, rdataset,
- 0, addedrdataset);
- if (result == DNS_R_UNCHANGED) {
- result = ISC_R_SUCCESS;
- if (!need_validation &&
- ardataset != NULL &&
- NEGATIVE(ardataset)) {
- /*
- * The answer in the cache is
- * better than the answer we
- * found, and is a negative
- * cache entry, so we must set
- * eresult appropriately.
- */
- if (NXDOMAIN(ardataset))
- eresult =
- DNS_R_NCACHENXDOMAIN;
- else
- eresult =
- DNS_R_NCACHENXRRSET;
- /*
- * We have a negative response
- * from the cache so don't
- * attempt to add the RRSIG
- * rrset.
- */
- continue;
- }
- }
- if (result != ISC_R_SUCCESS)
- break;
- if (sigrdataset != NULL) {
- addedrdataset = asigrdataset;
- result = dns_db_addrdataset(fctx->cache,
- node, NULL, now,
- sigrdataset, 0,
- addedrdataset);
- if (result == DNS_R_UNCHANGED)
- result = ISC_R_SUCCESS;
- if (result != ISC_R_SUCCESS)
- break;
- } else if (!ANSWER(rdataset))
- continue;
- }
-
- if (ANSWER(rdataset) && need_validation) {
- if (fctx->type != dns_rdatatype_any &&
- fctx->type != dns_rdatatype_rrsig &&
- fctx->type != dns_rdatatype_sig) {
- /*
- * This is The Answer. We will
- * validate it, but first we cache
- * the rest of the response - it may
- * contain useful keys.
- */
- INSIST(valrdataset == NULL &&
- valsigrdataset == NULL);
- valrdataset = rdataset;
- valsigrdataset = sigrdataset;
- } else {
- /*
- * This is one of (potentially)
- * multiple answers to an ANY
- * or SIG query. To keep things
- * simple, we just start the
- * validator right away rather
- * than caching first and
- * having to remember which
- * rdatasets needed validation.
- */
- result = valcreate(fctx, addrinfo,
- name, rdataset->type,
- rdataset,
- sigrdataset,
- valoptions, task);
- /*
- * Defer any further validations.
- * This prevents multiple validators
- * from manipulating fctx->rmessage
- * simultaneously.
- */
- valoptions |= DNS_VALIDATOR_DEFER;
- }
- } else if (CHAINING(rdataset)) {
- if (rdataset->type == dns_rdatatype_cname)
- eresult = DNS_R_CNAME;
- else {
- INSIST(rdataset->type ==
- dns_rdatatype_dname);
- eresult = DNS_R_DNAME;
- }
- }
- } else if (!EXTERNAL(rdataset)) {
- /*
- * It's OK to cache this rdataset now.
- */
- if (ANSWER(rdataset))
- addedrdataset = ardataset;
- else if (ANSWERSIG(rdataset))
- addedrdataset = asigrdataset;
- else
- addedrdataset = NULL;
- if (CHAINING(rdataset)) {
- if (rdataset->type == dns_rdatatype_cname)
- eresult = DNS_R_CNAME;
- else {
- INSIST(rdataset->type ==
- dns_rdatatype_dname);
- eresult = DNS_R_DNAME;
- }
- }
- if (rdataset->trust == dns_trust_glue &&
- (rdataset->type == dns_rdatatype_ns ||
- (rdataset->type == dns_rdatatype_rrsig &&
- rdataset->covers == dns_rdatatype_ns))) {
- /*
- * If the trust level is 'dns_trust_glue'
- * then we are adding data from a referral
- * we got while executing the search algorithm.
- * New referral data always takes precedence
- * over the existing cache contents.
- */
- options = DNS_DBADD_FORCE;
- } else
- options = 0;
-
- if (ANSWER(rdataset) &&
- rdataset->type != dns_rdatatype_rrsig) {
- isc_result_t tresult;
- dns_name_t *noqname = NULL;
- tresult = findnoqname(fctx, name,
- rdataset->type, &noqname);
- if (tresult == ISC_R_SUCCESS &&
- noqname != NULL) {
- tresult = dns_rdataset_addnoqname(
- rdataset, noqname);
- RUNTIME_CHECK(tresult == ISC_R_SUCCESS);
- }
- }
-
- /*
- * Now we can add the rdataset.
- */
- result = dns_db_addrdataset(fctx->cache,
- node, NULL, now,
- rdataset,
- options,
- addedrdataset);
-
- if (result == DNS_R_UNCHANGED) {
- if (ANSWER(rdataset) &&
- ardataset != NULL &&
- NEGATIVE(ardataset)) {
- /*
- * The answer in the cache is better
- * than the answer we found, and is
- * a negative cache entry, so we
- * must set eresult appropriately.
- */
- if (NXDOMAIN(ardataset))
- eresult = DNS_R_NCACHENXDOMAIN;
- else
- eresult = DNS_R_NCACHENXRRSET;
- }
- result = ISC_R_SUCCESS;
- } else if (result != ISC_R_SUCCESS)
- break;
- }
- }
-
- if (valrdataset != NULL)
- result = valcreate(fctx, addrinfo, name, fctx->type,
- valrdataset, valsigrdataset, valoptions,
- task);
-
- if (result == ISC_R_SUCCESS && have_answer) {
- fctx->attributes |= FCTX_ATTR_HAVEANSWER;
- if (event != NULL) {
- /*
- * Negative results must be indicated in event->result.
- */
- if (dns_rdataset_isassociated(event->rdataset) &&
- NEGATIVE(event->rdataset)) {
- INSIST(eresult == DNS_R_NCACHENXDOMAIN ||
- eresult == DNS_R_NCACHENXRRSET);
- }
- event->result = eresult;
- dns_db_attach(fctx->cache, adbp);
- dns_db_transfernode(fctx->cache, &node, anodep);
- clone_results(fctx);
- }
- }
-
- if (node != NULL)
- dns_db_detachnode(fctx->cache, &node);
-
- return (result);
-}
-
-static inline isc_result_t
-cache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, isc_stdtime_t now)
-{
- isc_result_t result;
- dns_section_t section;
- dns_name_t *name;
-
- FCTXTRACE("cache_message");
-
- fctx->attributes &= ~FCTX_ATTR_WANTCACHE;
-
- LOCK(&fctx->res->buckets[fctx->bucketnum].lock);
-
- for (section = DNS_SECTION_ANSWER;
- section <= DNS_SECTION_ADDITIONAL;
- section++) {
- result = dns_message_firstname(fctx->rmessage, section);
- while (result == ISC_R_SUCCESS) {
- name = NULL;
- dns_message_currentname(fctx->rmessage, section,
- &name);
- if ((name->attributes & DNS_NAMEATTR_CACHE) != 0) {
- result = cache_name(fctx, name, addrinfo, now);
- if (result != ISC_R_SUCCESS)
- break;
- }
- result = dns_message_nextname(fctx->rmessage, section);
- }
- if (result != ISC_R_NOMORE)
- break;
- }
- if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
-
- UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock);
-
- return (result);
-}
-
-/*
- * Do what dns_ncache_addoptout() does, and then compute an appropriate eresult.
- */
-static isc_result_t
-ncache_adderesult(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
- dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl,
- isc_boolean_t optout, isc_boolean_t secure,
- dns_rdataset_t *ardataset, isc_result_t *eresultp)
-{
- isc_result_t result;
- dns_rdataset_t rdataset;
-
- if (ardataset == NULL) {
- dns_rdataset_init(&rdataset);
- ardataset = &rdataset;
- }
- if (secure)
- result = dns_ncache_addoptout(message, cache, node, covers,
- now, maxttl, optout, ardataset);
- else
- result = dns_ncache_add(message, cache, node, covers, now,
- maxttl, ardataset);
- if (result == DNS_R_UNCHANGED || result == ISC_R_SUCCESS) {
- /*
- * If the cache now contains a negative entry and we
- * care about whether it is DNS_R_NCACHENXDOMAIN or
- * DNS_R_NCACHENXRRSET then extract it.
- */
- if (NEGATIVE(ardataset)) {
- /*
- * The cache data is a negative cache entry.
- */
- if (NXDOMAIN(ardataset))
- *eresultp = DNS_R_NCACHENXDOMAIN;
- else
- *eresultp = DNS_R_NCACHENXRRSET;
- } else {
- /*
- * Either we don't care about the nature of the
- * cache rdataset (because no fetch is interested
- * in the outcome), or the cache rdataset is not
- * a negative cache entry. Whichever case it is,
- * we can return success.
- *
- * XXXRTH There's a CNAME/DNAME problem here.
- */
- *eresultp = ISC_R_SUCCESS;
- }
- result = ISC_R_SUCCESS;
- }
- if (ardataset == &rdataset && dns_rdataset_isassociated(ardataset))
- dns_rdataset_disassociate(ardataset);
-
- return (result);
-}
-
-static inline isc_result_t
-ncache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
- dns_rdatatype_t covers, isc_stdtime_t now)
-{
- isc_result_t result, eresult;
- dns_name_t *name;
- dns_resolver_t *res;
- dns_db_t **adbp;
- dns_dbnode_t *node, **anodep;
- dns_rdataset_t *ardataset;
- isc_boolean_t need_validation, secure_domain;
- dns_name_t *aname;
- dns_fetchevent_t *event;
- isc_uint32_t ttl;
- unsigned int valoptions = 0;
-
- FCTXTRACE("ncache_message");
-
- fctx->attributes &= ~FCTX_ATTR_WANTNCACHE;
-
- res = fctx->res;
- need_validation = ISC_FALSE;
- POST(need_validation);
- secure_domain = ISC_FALSE;
- eresult = ISC_R_SUCCESS;
- name = &fctx->name;
- node = NULL;
-
- /*
- * XXXMPA remove when we follow cnames and adjust the setting
- * of FCTX_ATTR_WANTNCACHE in noanswer_response().
- */
- INSIST(fctx->rmessage->counts[DNS_SECTION_ANSWER] == 0);
-
- /*
- * Is DNSSEC validation required for this name?
- */
- if (fctx->res->view->enablevalidation) {
- result = dns_view_issecuredomain(res->view, name,
- &secure_domain);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- if (!secure_domain && res->view->dlv != NULL) {
- valoptions = DNS_VALIDATOR_DLV;
- secure_domain = ISC_TRUE;
- }
- }
-
- if ((fctx->options & DNS_FETCHOPT_NOVALIDATE) != 0)
- need_validation = ISC_FALSE;
- else
- need_validation = secure_domain;
-
- if (secure_domain) {
- /*
- * Mark all rdatasets as pending.
- */
- dns_rdataset_t *trdataset;
- dns_name_t *tname;
-
- result = dns_message_firstname(fctx->rmessage,
- DNS_SECTION_AUTHORITY);
- while (result == ISC_R_SUCCESS) {
- tname = NULL;
- dns_message_currentname(fctx->rmessage,
- DNS_SECTION_AUTHORITY,
- &tname);
- for (trdataset = ISC_LIST_HEAD(tname->list);
- trdataset != NULL;
- trdataset = ISC_LIST_NEXT(trdataset, link))
- trdataset->trust = dns_trust_pending_answer;
- result = dns_message_nextname(fctx->rmessage,
- DNS_SECTION_AUTHORITY);
- }
- if (result != ISC_R_NOMORE)
- return (result);
-
- }
-
- if (need_validation) {
- /*
- * Do negative response validation.
- */
- result = valcreate(fctx, addrinfo, name, fctx->type,
- NULL, NULL, valoptions,
- res->buckets[fctx->bucketnum].task);
- /*
- * If validation is necessary, return now. Otherwise continue
- * to process the message, letting the validation complete
- * in its own good time.
- */
- return (result);
- }
-
- LOCK(&res->buckets[fctx->bucketnum].lock);
-
- adbp = NULL;
- aname = NULL;
- anodep = NULL;
- ardataset = NULL;
- if (!HAVE_ANSWER(fctx)) {
- event = ISC_LIST_HEAD(fctx->events);
- if (event != NULL) {
- adbp = &event->db;
- aname = dns_fixedname_name(&event->foundname);
- result = dns_name_copy(name, aname, NULL);
- if (result != ISC_R_SUCCESS)
- goto unlock;
- anodep = &event->node;
- ardataset = event->rdataset;
- }
- } else
- event = NULL;
-
- result = dns_db_findnode(fctx->cache, name, ISC_TRUE, &node);
- if (result != ISC_R_SUCCESS)
- goto unlock;
-
- /*
- * If we are asking for a SOA record set the cache time
- * to zero to facilitate locating the containing zone of
- * a arbitrary zone.
- */
- ttl = fctx->res->view->maxncachettl;
- if (fctx->type == dns_rdatatype_soa &&
- covers == dns_rdatatype_any &&
- fctx->res->zero_no_soa_ttl)
- ttl = 0;
-
- result = ncache_adderesult(fctx->rmessage, fctx->cache, node,
- covers, now, ttl, ISC_FALSE,
- ISC_FALSE, ardataset, &eresult);
- if (result != ISC_R_SUCCESS)
- goto unlock;
-
- if (!HAVE_ANSWER(fctx)) {
- fctx->attributes |= FCTX_ATTR_HAVEANSWER;
- if (event != NULL) {
- event->result = eresult;
- dns_db_attach(fctx->cache, adbp);
- dns_db_transfernode(fctx->cache, &node, anodep);
- clone_results(fctx);
- }
- }
-
- unlock:
- UNLOCK(&res->buckets[fctx->bucketnum].lock);
-
- if (node != NULL)
- dns_db_detachnode(fctx->cache, &node);
-
- return (result);
-}
-
-static inline void
-mark_related(dns_name_t *name, dns_rdataset_t *rdataset,
- isc_boolean_t external, isc_boolean_t gluing)
-{
- name->attributes |= DNS_NAMEATTR_CACHE;
- if (gluing) {
- rdataset->trust = dns_trust_glue;
- /*
- * Glue with 0 TTL causes problems. We force the TTL to
- * 1 second to prevent this.
- */
- if (rdataset->ttl == 0)
- rdataset->ttl = 1;
- } else
- rdataset->trust = dns_trust_additional;
- /*
- * Avoid infinite loops by only marking new rdatasets.
- */
- if (!CACHE(rdataset)) {
- name->attributes |= DNS_NAMEATTR_CHASE;
- rdataset->attributes |= DNS_RDATASETATTR_CHASE;
- }
- rdataset->attributes |= DNS_RDATASETATTR_CACHE;
- if (external)
- rdataset->attributes |= DNS_RDATASETATTR_EXTERNAL;
-}
-
-static isc_result_t
-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;
- dns_rdataset_t *rdataset;
- isc_boolean_t external;
- dns_rdatatype_t rtype;
- isc_boolean_t gluing;
-
- 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, 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) {
- for (rdataset = ISC_LIST_HEAD(name->list);
- rdataset != NULL;
- rdataset = ISC_LIST_NEXT(rdataset, link)) {
- if (rdataset->type == dns_rdatatype_rrsig)
- rtype = rdataset->covers;
- else
- rtype = rdataset->type;
- if (rtype == dns_rdatatype_a ||
- rtype == dns_rdatatype_aaaa)
- mark_related(name, rdataset, external,
- gluing);
- }
- } else {
- result = dns_message_findtype(name, type, 0,
- &rdataset);
- if (result == ISC_R_SUCCESS) {
- mark_related(name, rdataset, external, gluing);
- /*
- * Do we have its SIG too?
- */
- rdataset = NULL;
- result = dns_message_findtype(name,
- dns_rdatatype_rrsig,
- type, &rdataset);
- if (result == ISC_R_SUCCESS)
- mark_related(name, rdataset, external,
- gluing);
- }
- }
- }
-
- 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;
- dns_section_t section = DNS_SECTION_ADDITIONAL;
- isc_result_t result;
-
- again:
- rescan = ISC_FALSE;
-
- for (result = dns_message_firstname(fctx->rmessage, section);
- result == ISC_R_SUCCESS;
- result = dns_message_nextname(fctx->rmessage, section)) {
- dns_name_t *name = NULL;
- dns_rdataset_t *rdataset;
- dns_message_currentname(fctx->rmessage, DNS_SECTION_ADDITIONAL,
- &name);
- if ((name->attributes & DNS_NAMEATTR_CHASE) == 0)
- continue;
- name->attributes &= ~DNS_NAMEATTR_CHASE;
- for (rdataset = ISC_LIST_HEAD(name->list);
- rdataset != NULL;
- rdataset = ISC_LIST_NEXT(rdataset, link)) {
- if (CHASE(rdataset)) {
- rdataset->attributes &= ~DNS_RDATASETATTR_CHASE;
- (void)dns_rdataset_additionaldata(rdataset,
- check_related,
- fctx);
- rescan = ISC_TRUE;
- }
- }
- }
- if (rescan)
- goto again;
-}
-
-static inline isc_result_t
-cname_target(dns_rdataset_t *rdataset, dns_name_t *tname) {
- isc_result_t result;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdata_cname_t cname;
-
- result = dns_rdataset_first(rdataset);
- if (result != ISC_R_SUCCESS)
- return (result);
- dns_rdataset_current(rdataset, &rdata);
- result = dns_rdata_tostruct(&rdata, &cname, NULL);
- if (result != ISC_R_SUCCESS)
- return (result);
- dns_name_init(tname, NULL);
- dns_name_clone(&cname.cname, tname);
- dns_rdata_freestruct(&cname);
-
- return (ISC_R_SUCCESS);
-}
-
-static inline isc_result_t
-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;
- unsigned int nlabels;
- int order;
- dns_namereln_t namereln;
- dns_rdata_dname_t dname;
- dns_fixedname_t prefix;
-
- /*
- * Get the target name of the DNAME.
- */
- result = dns_rdataset_first(rdataset);
- if (result != ISC_R_SUCCESS)
- return (result);
- dns_rdataset_current(rdataset, &rdata);
- result = dns_rdata_tostruct(&rdata, &dname, NULL);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- /*
- * Get the prefix of qname.
- */
- 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);
- dns_name_split(qname, nlabels, dns_fixedname_name(&prefix), NULL);
- dns_fixedname_init(fixeddname);
- result = dns_name_concatenate(dns_fixedname_name(&prefix),
- &dname.dname,
- dns_fixedname_name(fixeddname), NULL);
- dns_rdata_freestruct(&dname);
- 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);
-}
-
-static void
-trim_ns_ttl(fetchctx_t *fctx, dns_name_t *name, dns_rdataset_t *rdataset) {
- char ns_namebuf[DNS_NAME_FORMATSIZE];
- char namebuf[DNS_NAME_FORMATSIZE];
- char tbuf[DNS_RDATATYPE_FORMATSIZE];
-
- if (fctx->ns_ttl_ok && rdataset->ttl > fctx->ns_ttl) {
- dns_name_format(name, ns_namebuf, sizeof(ns_namebuf));
- dns_name_format(&fctx->name, namebuf, sizeof(namebuf));
- dns_rdatatype_format(fctx->type, tbuf, sizeof(tbuf));
-
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
- DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(10),
- "fctx %p: trimming ttl of %s/NS for %s/%s: "
- "%u -> %u", fctx, ns_namebuf, namebuf, tbuf,
- rdataset->ttl, fctx->ns_ttl);
- rdataset->ttl = fctx->ns_ttl;
- }
-}
-
-/*
- * Handle a no-answer response (NXDOMAIN, NXRRSET, or referral).
- * 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,
- unsigned int look_in_options)
-{
- isc_result_t result;
- dns_message_t *message;
- dns_name_t *name, *qname, *ns_name, *soa_name, *ds_name, *save_name;
- dns_rdataset_t *rdataset, *ns_rdataset;
- isc_boolean_t aa, negative_response;
- dns_rdatatype_t type, save_type;
- 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;
-
- /*
- * Setup qname.
- */
- if (oqname == NULL) {
- /*
- * We have a normal, non-chained negative response or
- * referral.
- */
- if ((message->flags & DNS_MESSAGEFLAG_AA) != 0)
- aa = ISC_TRUE;
- else
- aa = ISC_FALSE;
- qname = &fctx->name;
- } else {
- /*
- * We're being invoked by answer_response() after it has
- * followed a CNAME/DNAME chain.
- */
- qname = oqname;
- aa = ISC_FALSE;
- /*
- * If the current qname is not a subdomain of the query
- * domain, there's no point in looking at the authority
- * section without doing DNSSEC validation.
- *
- * Until we do that validation, we'll just return success
- * in this case.
- */
- if (!dns_name_issubdomain(qname, &fctx->domain))
- return (ISC_R_SUCCESS);
- }
-
- /*
- * We have to figure out if this is a negative response, or a
- * referral.
- */
-
- /*
- * Sometimes we can tell if its a negative response by looking at
- * the message header.
- */
- negative_response = ISC_FALSE;
- if (message->rcode == dns_rcode_nxdomain ||
- (message->counts[DNS_SECTION_ANSWER] == 0 &&
- message->counts[DNS_SECTION_AUTHORITY] == 0))
- negative_response = ISC_TRUE;
-
- /*
- * Process the authority section.
- */
- ns_name = NULL;
- ns_rdataset = NULL;
- soa_name = NULL;
- ds_name = NULL;
- save_name = NULL;
- save_type = dns_rdatatype_none;
- result = dns_message_firstname(message, section);
- while (result == ISC_R_SUCCESS) {
- name = NULL;
- dns_message_currentname(message, section, &name);
- if (dns_name_issubdomain(name, &fctx->domain)) {
- /*
- * Look for NS/SOA RRsets first.
- */
- for (rdataset = ISC_LIST_HEAD(name->list);
- rdataset != NULL;
- rdataset = ISC_LIST_NEXT(rdataset, link)) {
- type = rdataset->type;
- if (type == dns_rdatatype_rrsig)
- type = rdataset->covers;
- if (((type == dns_rdatatype_ns ||
- type == dns_rdatatype_soa) &&
- !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.
- *
- * Only one set of NS RRs is allowed.
- */
- if (rdataset->type ==
- dns_rdatatype_ns) {
- if (ns_name != NULL &&
- name != ns_name) {
- log_formerr(fctx,
- "multiple NS "
- "RRsets in "
- "authority "
- "section");
- return (DNS_R_FORMERR);
- }
- ns_name = name;
- ns_rdataset = rdataset;
- }
- name->attributes |=
- DNS_NAMEATTR_CACHE;
- rdataset->attributes |=
- DNS_RDATASETATTR_CACHE;
- rdataset->trust = dns_trust_glue;
- }
- if (type == dns_rdatatype_soa) {
- /*
- * SOA, or RRSIG SOA.
- *
- * Only one SOA is allowed.
- */
- if (rdataset->type ==
- dns_rdatatype_soa) {
- if (soa_name != NULL &&
- name != soa_name) {
- log_formerr(fctx,
- "multiple SOA "
- "RRs in "
- "authority "
- "section");
- return (DNS_R_FORMERR);
- }
- soa_name = name;
- }
- name->attributes |=
- DNS_NAMEATTR_NCACHE;
- rdataset->attributes |=
- DNS_RDATASETATTR_NCACHE;
- if (aa)
- rdataset->trust =
- dns_trust_authauthority;
- else if (ISFORWARDER(fctx->addrinfo))
- rdataset->trust =
- dns_trust_answer;
- else
- rdataset->trust =
- dns_trust_additional;
- }
- }
- }
- result = dns_message_nextname(message, section);
- if (result == ISC_R_NOMORE)
- break;
- else if (result != ISC_R_SUCCESS)
- return (result);
- }
-
- log_ns_ttl(fctx, "noanswer_response");
-
- if (ns_rdataset != NULL && dns_name_equal(&fctx->domain, ns_name) &&
- !dns_name_equal(ns_name, dns_rootname))
- trim_ns_ttl(fctx, ns_name, ns_rdataset);
-
- /*
- * A negative response has a SOA record (Type 2)
- * and a optional NS RRset (Type 1) or it has neither
- * a SOA or a NS RRset (Type 3, handled above) or
- * rcode is NXDOMAIN (handled above) in which case
- * the NS RRset is allowed (Type 4).
- */
- if (soa_name != NULL)
- negative_response = ISC_TRUE;
-
- result = dns_message_firstname(message, section);
- while (result == ISC_R_SUCCESS) {
- name = NULL;
- dns_message_currentname(message, section, &name);
- if (dns_name_issubdomain(name, &fctx->domain)) {
- for (rdataset = ISC_LIST_HEAD(name->list);
- rdataset != NULL;
- rdataset = ISC_LIST_NEXT(rdataset, link)) {
- type = rdataset->type;
- if (type == dns_rdatatype_rrsig)
- type = rdataset->covers;
- if (type == dns_rdatatype_nsec ||
- type == dns_rdatatype_nsec3) {
- /*
- * NSEC or RRSIG NSEC.
- */
- if (negative_response) {
- name->attributes |=
- DNS_NAMEATTR_NCACHE;
- rdataset->attributes |=
- DNS_RDATASETATTR_NCACHE;
- } else if (type == dns_rdatatype_nsec) {
- name->attributes |=
- DNS_NAMEATTR_CACHE;
- rdataset->attributes |=
- DNS_RDATASETATTR_CACHE;
- }
- if (aa)
- rdataset->trust =
- dns_trust_authauthority;
- else if (ISFORWARDER(fctx->addrinfo))
- rdataset->trust =
- dns_trust_answer;
- else
- rdataset->trust =
- dns_trust_additional;
- /*
- * No additional data needs to be
- * marked.
- */
- } else if (type == dns_rdatatype_ds) {
- /*
- * DS or SIG DS.
- *
- * These should only be here if
- * this is a referral, and there
- * should only be one DS RRset.
- */
- 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) {
- log_formerr(fctx,
- "DS doesn't "
- "match "
- "referral "
- "(NS)");
- return (DNS_R_FORMERR);
- }
- ds_name = name;
- }
- name->attributes |=
- DNS_NAMEATTR_CACHE;
- rdataset->attributes |=
- DNS_RDATASETATTR_CACHE;
- if (aa)
- rdataset->trust =
- dns_trust_authauthority;
- else if (ISFORWARDER(fctx->addrinfo))
- rdataset->trust =
- dns_trust_answer;
- else
- rdataset->trust =
- dns_trust_additional;
- }
- }
- } else {
- save_name = name;
- save_type = ISC_LIST_HEAD(name->list)->type;
- }
- result = dns_message_nextname(message, section);
- if (result == ISC_R_NOMORE)
- break;
- else if (result != ISC_R_SUCCESS)
- return (result);
- }
-
- /*
- * Trigger lookups for DNS nameservers.
- */
- if (negative_response && message->rcode == dns_rcode_noerror &&
- fctx->type == dns_rdatatype_ds && soa_name != NULL &&
- dns_name_equal(soa_name, qname) &&
- !dns_name_equal(qname, dns_rootname))
- return (DNS_R_CHASEDSSERVERS);
-
- /*
- * Did we find anything?
- */
- if (!negative_response && ns_name == NULL) {
- /*
- * Nope.
- */
- if (oqname != NULL) {
- /*
- * We've already got a partial CNAME/DNAME chain,
- * and haven't found else anything useful here, but
- * no error has occurred since we have an answer.
- */
- return (ISC_R_SUCCESS);
- } else {
- /*
- * The responder is insane.
- */
- if (save_name == NULL) {
- log_formerr(fctx, "invalid response");
- return (DNS_R_FORMERR);
- }
- if (!dns_name_issubdomain(save_name, &fctx->domain)) {
- char nbuf[DNS_NAME_FORMATSIZE];
- char dbuf[DNS_NAME_FORMATSIZE];
- char tbuf[DNS_RDATATYPE_FORMATSIZE];
-
- dns_rdatatype_format(save_type, tbuf,
- sizeof(tbuf));
- dns_name_format(save_name, nbuf, sizeof(nbuf));
- dns_name_format(&fctx->domain, dbuf,
- sizeof(dbuf));
-
- log_formerr(fctx, "Name %s (%s) not subdomain"
- " of zone %s -- invalid response",
- nbuf, tbuf, dbuf);
- } else {
- log_formerr(fctx, "invalid response");
- }
- return (DNS_R_FORMERR);
- }
- }
-
- /*
- * If we found both NS and SOA, they should be the same 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
- * we're not following a chain.)
- */
- if (!negative_response && ns_name != NULL && oqname == NULL) {
- /*
- * We already know ns_name is a subdomain of fctx->domain.
- * If ns_name is equal to fctx->domain, we're not making
- * progress. We return DNS_R_FORMERR so that we'll keep
- * trying other servers.
- */
- 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);
- }
-
- /*
- * Mark any additional data related to this rdataset.
- * It's important that we do this before we change the
- * query domain.
- */
- INSIST(ns_rdataset != NULL);
- 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.
- * dns_view_findzonecut() will not find them when we
- * try to follow the referral, and we'll SERVFAIL
- * because the best nameservers are now above QDOMAIN.
- * We force the TTL to 1 second to prevent this.
- */
- if (ns_rdataset->ttl == 0)
- ns_rdataset->ttl = 1;
- /*
- * Set the current query domain to the referral name.
- *
- * XXXRTH We should check if we're in forward-only mode, and
- * if so we should bail out.
- */
- INSIST(dns_name_countlabels(&fctx->domain) > 0);
- dns_name_free(&fctx->domain, fctx->mctx);
- if (dns_rdataset_isassociated(&fctx->nameservers))
- dns_rdataset_disassociate(&fctx->nameservers);
- dns_name_init(&fctx->domain, NULL);
- result = dns_name_dup(ns_name, fctx->mctx, &fctx->domain);
- if (result != ISC_R_SUCCESS)
- return (result);
- fctx->attributes |= FCTX_ATTR_WANTCACHE;
- fctx->ns_ttl_ok = ISC_FALSE;
- log_ns_ttl(fctx, "DELEGATION");
- return (DNS_R_DELEGATION);
- }
-
- /*
- * Since we're not doing a referral, we don't want to cache any
- * NS RRs we may have found.
- */
- if (ns_name != NULL)
- ns_name->attributes &= ~DNS_NAMEATTR_CACHE;
-
- if (negative_response && oqname == NULL)
- fctx->attributes |= FCTX_ATTR_WANTNCACHE;
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-answer_response(fetchctx_t *fctx) {
- isc_result_t result;
- dns_message_t *message;
- dns_name_t *name, *qname, tname, *ns_name;
- dns_rdataset_t *rdataset, *ns_rdataset;
- isc_boolean_t done, external, chaining, aa, found, want_chaining;
- isc_boolean_t have_answer, found_cname, found_type, wanted_chaining;
- unsigned int aflag;
- dns_rdatatype_t type;
- dns_fixedname_t dname, fqname;
- dns_view_t *view;
-
- FCTXTRACE("answer_response");
-
- message = fctx->rmessage;
-
- /*
- * Examine the answer section, marking those rdatasets which are
- * part of the answer and should be cached.
- */
-
- done = ISC_FALSE;
- found_cname = ISC_FALSE;
- found_type = ISC_FALSE;
- chaining = ISC_FALSE;
- have_answer = ISC_FALSE;
- want_chaining = ISC_FALSE;
- POST(want_chaining);
- if ((message->flags & DNS_MESSAGEFLAG_AA) != 0)
- aa = ISC_TRUE;
- else
- 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;
- dns_message_currentname(message, DNS_SECTION_ANSWER, &name);
- external = ISC_TF(!dns_name_issubdomain(name, &fctx->domain));
- if (dns_name_equal(name, qname)) {
- wanted_chaining = ISC_FALSE;
- for (rdataset = ISC_LIST_HEAD(name->list);
- rdataset != NULL;
- rdataset = ISC_LIST_NEXT(rdataset, link)) {
- found = ISC_FALSE;
- want_chaining = ISC_FALSE;
- aflag = 0;
- if (rdataset->type == dns_rdatatype_nsec3) {
- /*
- * 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.
- */
- found = ISC_TRUE;
- found_type = ISC_TRUE;
- done = ISC_TRUE;
- aflag = DNS_RDATASETATTR_ANSWER;
- } else if (type == dns_rdatatype_any) {
- /*
- * We've found an answer matching
- * an ANY query. There may be
- * more.
- */
- found = ISC_TRUE;
- aflag = DNS_RDATASETATTR_ANSWER;
- } else if (rdataset->type == dns_rdatatype_rrsig
- && rdataset->covers == type
- && !found_cname) {
- /*
- * We've found a signature that
- * covers the type we're looking for.
- */
- found = ISC_TRUE;
- found_type = ISC_TRUE;
- aflag = DNS_RDATASETATTR_ANSWERSIG;
- } else if (rdataset->type ==
- dns_rdatatype_cname
- && !found_type) {
- /*
- * We're looking for something else,
- * but we found a CNAME.
- *
- * Getting a CNAME response for some
- * query types is an error, see
- * RFC 4035, Section 2.5.
- */
- if (type == dns_rdatatype_rrsig ||
- type == dns_rdatatype_key ||
- type == dns_rdatatype_nsec) {
- 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;
- aflag = DNS_RDATASETATTR_ANSWER;
- result = cname_target(rdataset,
- &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
- && !found_type) {
- /*
- * We're looking for something else,
- * but we found a SIG CNAME.
- */
- found = ISC_TRUE;
- found_cname = ISC_TRUE;
- aflag = DNS_RDATASETATTR_ANSWERSIG;
- }
-
- if (found) {
- /*
- * We've found an answer to our
- * question.
- */
- name->attributes |=
- DNS_NAMEATTR_CACHE;
- rdataset->attributes |=
- DNS_RDATASETATTR_CACHE;
- rdataset->trust = dns_trust_answer;
- if (!chaining) {
- /*
- * This data is "the" answer
- * to our question only if
- * we're not chaining (i.e.
- * if we haven't followed
- * a CNAME or DNAME).
- */
- INSIST(!external);
- if (aflag ==
- DNS_RDATASETATTR_ANSWER)
- have_answer = ISC_TRUE;
- name->attributes |=
- DNS_NAMEATTR_ANSWER;
- rdataset->attributes |= aflag;
- if (aa)
- rdataset->trust =
- dns_trust_authanswer;
- } else if (external) {
- /*
- * This data is outside of
- * our query domain, and
- * may not be cached.
- */
- rdataset->attributes |=
- DNS_RDATASETATTR_EXTERNAL;
- }
-
- /*
- * Mark any additional data related
- * to this rdataset.
- */
- (void)dns_rdataset_additionaldata(
- rdataset,
- check_related,
- fctx);
-
- /*
- * CNAME chaining.
- */
- if (want_chaining) {
- wanted_chaining = ISC_TRUE;
- name->attributes |=
- DNS_NAMEATTR_CHAINING;
- rdataset->attributes |=
- DNS_RDATASETATTR_CHAINING;
- qname = &tname;
- }
- }
- /*
- * We could add an "else" clause here and
- * log that we're ignoring this rdataset.
- */
- }
- /*
- * If wanted_chaining is true, we've done
- * some chaining as the result of processing
- * this node, and thus we need to set
- * chaining to true.
- *
- * We don't set chaining inside of the
- * rdataset loop because doing that would
- * cause us to ignore the signatures of
- * CNAMEs.
- */
- if (wanted_chaining)
- chaining = ISC_TRUE;
- } else {
- /*
- * Look for a DNAME (or its SIG). Anything else is
- * ignored.
- */
- wanted_chaining = ISC_FALSE;
- for (rdataset = ISC_LIST_HEAD(name->list);
- 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) {
- /*
- * We're looking for something else,
- * but we found a DNAME.
- *
- * If we're not chaining, then the
- * DNAME should not be external.
- */
- if (!chaining && external) {
- log_formerr(fctx,
- "external DNAME");
- return (DNS_R_FORMERR);
- }
- found = ISC_TRUE;
- want_chaining = ISC_TRUE;
- POST(want_chaining);
- aflag = DNS_RDATASETATTR_ANSWER;
- result = dname_target(fctx, rdataset,
- qname, name,
- &dname);
- if (result == ISC_R_NOSPACE) {
- /*
- * We can't construct the
- * DNAME target. Do not
- * try to continue.
- */
- want_chaining = ISC_FALSE;
- POST(want_chaining);
- } else if (result != ISC_R_SUCCESS)
- 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) {
- /*
- * We've found a signature that
- * covers the DNAME.
- */
- found = ISC_TRUE;
- aflag = DNS_RDATASETATTR_ANSWERSIG;
- }
-
- if (found) {
- /*
- * We've found an answer to our
- * question.
- */
- name->attributes |=
- DNS_NAMEATTR_CACHE;
- rdataset->attributes |=
- DNS_RDATASETATTR_CACHE;
- rdataset->trust = dns_trust_answer;
- if (!chaining) {
- /*
- * This data is "the" answer
- * to our question only if
- * we're not chaining.
- */
- INSIST(!external);
- if (aflag ==
- DNS_RDATASETATTR_ANSWER)
- have_answer = ISC_TRUE;
- name->attributes |=
- DNS_NAMEATTR_ANSWER;
- rdataset->attributes |= aflag;
- if (aa)
- rdataset->trust =
- dns_trust_authanswer;
- } else if (external) {
- rdataset->attributes |=
- DNS_RDATASETATTR_EXTERNAL;
- }
-
- /*
- * DNAME chaining.
- */
- if (found_dname) {
- /*
- * Copy the dname into the
- * qname fixed name.
- *
- * Although we check for
- * failure of the copy
- * operation, in practice it
- * should never fail since
- * we already know that the
- * result fits in a fixedname.
- */
- dns_fixedname_init(&fqname);
- result = dns_name_copy(
- dns_fixedname_name(&dname),
- dns_fixedname_name(&fqname),
- NULL);
- if (result != ISC_R_SUCCESS)
- return (result);
- wanted_chaining = ISC_TRUE;
- name->attributes |=
- DNS_NAMEATTR_CHAINING;
- rdataset->attributes |=
- DNS_RDATASETATTR_CHAINING;
- qname = dns_fixedname_name(
- &fqname);
- }
- }
- }
- if (wanted_chaining)
- chaining = ISC_TRUE;
- }
- result = dns_message_nextname(message, DNS_SECTION_ANSWER);
- }
- if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
- if (result != ISC_R_SUCCESS)
- return (result);
-
- /*
- * We should have found an answer.
- */
- if (!have_answer) {
- log_formerr(fctx, "reply has no answer");
- return (DNS_R_FORMERR);
- }
-
- /*
- * This response is now potentially cacheable.
- */
- fctx->attributes |= FCTX_ATTR_WANTCACHE;
-
- /*
- * Did chaining end before we got the final answer?
- */
- if (chaining) {
- /*
- * Yes. This may be a negative reply, so hand off
- * authority section processing to the noanswer code.
- * If it isn't a noanswer response, no harm will be
- * done.
- */
- 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) {
- log_formerr(fctx, "CNAME/DNAME chain complete, but RCODE "
- "indicates error");
- return (DNS_R_FORMERR);
- }
-
- /*
- * Examine the authority section (if there is one).
- *
- * We expect there to be only one owner name for all the rdatasets
- * in this section, and we expect that it is not external.
- */
- done = ISC_FALSE;
- ns_name = NULL;
- ns_rdataset = NULL;
- result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
- while (!done && result == ISC_R_SUCCESS) {
- name = NULL;
- dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name);
- external = ISC_TF(!dns_name_issubdomain(name, &fctx->domain));
- if (!external) {
- /*
- * We expect to find NS or SIG NS rdatasets, and
- * nothing else.
- */
- for (rdataset = ISC_LIST_HEAD(name->list);
- rdataset != NULL;
- rdataset = ISC_LIST_NEXT(rdataset, link)) {
- if (rdataset->type == dns_rdatatype_ns ||
- (rdataset->type == dns_rdatatype_rrsig &&
- rdataset->covers == dns_rdatatype_ns)) {
- name->attributes |=
- DNS_NAMEATTR_CACHE;
- rdataset->attributes |=
- DNS_RDATASETATTR_CACHE;
- if (aa && !chaining)
- rdataset->trust =
- dns_trust_authauthority;
- else
- rdataset->trust =
- dns_trust_additional;
-
- if (rdataset->type == dns_rdatatype_ns) {
- ns_name = name;
- ns_rdataset = rdataset;
- }
- /*
- * Mark any additional data related
- * to this rdataset.
- */
- (void)dns_rdataset_additionaldata(
- rdataset,
- check_related,
- fctx);
- done = ISC_TRUE;
- }
- }
- }
- result = dns_message_nextname(message, DNS_SECTION_AUTHORITY);
- }
- if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
-
- log_ns_ttl(fctx, "answer_response");
-
- if (ns_rdataset != NULL && dns_name_equal(&fctx->domain, ns_name) &&
- !dns_name_equal(ns_name, dns_rootname))
- trim_ns_ttl(fctx, ns_name, ns_rdataset);
-
- return (result);
-}
-
-static isc_boolean_t
-fctx_decreference(fetchctx_t *fctx) {
- isc_boolean_t bucket_empty = ISC_FALSE;
-
- INSIST(fctx->references > 0);
- fctx->references--;
- if (fctx->references == 0) {
- /*
- * No one cares about the result of this fetch anymore.
- */
- if (fctx->pending == 0 && fctx->nqueries == 0 &&
- ISC_LIST_EMPTY(fctx->validators) && SHUTTINGDOWN(fctx)) {
- /*
- * This fctx is already shutdown; we were just
- * waiting for the last reference to go away.
- */
- bucket_empty = fctx_unlink(fctx);
- fctx_destroy(fctx);
- } else {
- /*
- * Initiate shutdown.
- */
- fctx_shutdown(fctx);
- }
- }
- return (bucket_empty);
-}
-
-static void
-resume_dslookup(isc_task_t *task, isc_event_t *event) {
- dns_fetchevent_t *fevent;
- dns_resolver_t *res;
- fetchctx_t *fctx;
- isc_result_t result;
- isc_boolean_t bucket_empty;
- isc_boolean_t locked = ISC_FALSE;
- unsigned int bucketnum;
- dns_rdataset_t nameservers;
- dns_fixedname_t fixed;
- dns_name_t *domain;
-
- REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE);
- fevent = (dns_fetchevent_t *)event;
- fctx = event->ev_arg;
- REQUIRE(VALID_FCTX(fctx));
- res = fctx->res;
-
- UNUSED(task);
- FCTXTRACE("resume_dslookup");
-
- if (fevent->node != NULL)
- dns_db_detachnode(fevent->db, &fevent->node);
- if (fevent->db != NULL)
- dns_db_detach(&fevent->db);
-
- dns_rdataset_init(&nameservers);
-
- bucketnum = fctx->bucketnum;
- if (fevent->result == ISC_R_CANCELED) {
- dns_resolver_destroyfetch(&fctx->nsfetch);
- fctx_done(fctx, ISC_R_CANCELED, __LINE__);
- } else if (fevent->result == ISC_R_SUCCESS) {
-
- FCTXTRACE("resuming DS lookup");
-
- dns_resolver_destroyfetch(&fctx->nsfetch);
- if (dns_rdataset_isassociated(&fctx->nameservers))
- dns_rdataset_disassociate(&fctx->nameservers);
- dns_rdataset_clone(fevent->rdataset, &fctx->nameservers);
- fctx->ns_ttl = fctx->nameservers.ttl;
- fctx->ns_ttl_ok = ISC_TRUE;
- log_ns_ttl(fctx, "resume_dslookup");
- dns_name_free(&fctx->domain, fctx->mctx);
- dns_name_init(&fctx->domain, NULL);
- result = dns_name_dup(&fctx->nsname, fctx->mctx, &fctx->domain);
- if (result != ISC_R_SUCCESS) {
- fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
- goto cleanup;
- }
- /*
- * Try again.
- */
- fctx_try(fctx, ISC_TRUE, ISC_FALSE);
- } else {
- unsigned int n;
- dns_rdataset_t *nsrdataset = NULL;
-
- /*
- * Retrieve state from fctx->nsfetch before we destroy it.
- */
- dns_fixedname_init(&fixed);
- domain = dns_fixedname_name(&fixed);
- dns_name_copy(&fctx->nsfetch->private->domain, domain, NULL);
- if (dns_name_equal(&fctx->nsname, domain)) {
- fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
- dns_resolver_destroyfetch(&fctx->nsfetch);
- goto cleanup;
- }
- if (dns_rdataset_isassociated(
- &fctx->nsfetch->private->nameservers)) {
- dns_rdataset_clone(
- &fctx->nsfetch->private->nameservers,
- &nameservers);
- nsrdataset = &nameservers;
- } else
- domain = NULL;
- dns_resolver_destroyfetch(&fctx->nsfetch);
- n = dns_name_countlabels(&fctx->nsname);
- dns_name_getlabelsequence(&fctx->nsname, 1, n - 1,
- &fctx->nsname);
-
- if (dns_rdataset_isassociated(fevent->rdataset))
- dns_rdataset_disassociate(fevent->rdataset);
- FCTXTRACE("continuing to look for parent's NS records");
- result = dns_resolver_createfetch(fctx->res, &fctx->nsname,
- dns_rdatatype_ns, domain,
- nsrdataset, NULL, 0, task,
- resume_dslookup, fctx,
- &fctx->nsrrset, NULL,
- &fctx->nsfetch);
- if (result != ISC_R_SUCCESS)
- fctx_done(fctx, result, __LINE__);
- else {
- LOCK(&res->buckets[bucketnum].lock);
- locked = ISC_TRUE;
- fctx->references++;
- }
- }
-
- cleanup:
- if (dns_rdataset_isassociated(&nameservers))
- dns_rdataset_disassociate(&nameservers);
- if (dns_rdataset_isassociated(fevent->rdataset))
- dns_rdataset_disassociate(fevent->rdataset);
- INSIST(fevent->sigrdataset == NULL);
- isc_event_free(&event);
- if (!locked)
- LOCK(&res->buckets[bucketnum].lock);
- bucket_empty = fctx_decreference(fctx);
- UNLOCK(&res->buckets[bucketnum].lock);
- if (bucket_empty)
- empty_bucket(res);
-}
-
-static inline void
-checknamessection(dns_message_t *message, dns_section_t section) {
- isc_result_t result;
- dns_name_t *name;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdataset_t *rdataset;
-
- for (result = dns_message_firstname(message, section);
- result == ISC_R_SUCCESS;
- result = dns_message_nextname(message, section))
- {
- name = NULL;
- dns_message_currentname(message, section, &name);
- for (rdataset = ISC_LIST_HEAD(name->list);
- rdataset != NULL;
- rdataset = ISC_LIST_NEXT(rdataset, link)) {
- for (result = dns_rdataset_first(rdataset);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(rdataset)) {
- dns_rdataset_current(rdataset, &rdata);
- if (!dns_rdata_checkowner(name, rdata.rdclass,
- rdata.type,
- ISC_FALSE) ||
- !dns_rdata_checknames(&rdata, name, NULL))
- {
- rdataset->attributes |=
- DNS_RDATASETATTR_CHECKNAMES;
- }
- dns_rdata_reset(&rdata);
- }
- }
- }
-}
-
-static void
-checknames(dns_message_t *message) {
-
- checknamessection(message, DNS_SECTION_ANSWER);
- checknamessection(message, DNS_SECTION_AUTHORITY);
- checknamessection(message, DNS_SECTION_ADDITIONAL);
-}
-
-/*
- * Log server NSID at log level 'level'
- */
-static void
-log_nsid(isc_buffer_t *opt, size_t nsid_len, resquery_t *query,
- int level, isc_mem_t *mctx)
-{
- static const char hex[17] = "0123456789abcdef";
- char addrbuf[ISC_SOCKADDR_FORMATSIZE];
- isc_uint16_t buflen, i;
- unsigned char *p, *buf, *nsid;
-
- /* Allocate buffer for storing hex version of the NSID */
- buflen = nsid_len * 2 + 1;
- buf = isc_mem_get(mctx, buflen);
- if (buf == NULL)
- return;
-
- /* Convert to hex */
- p = buf;
- nsid = isc_buffer_current(opt);
- for (i = 0; i < nsid_len; i++) {
- *p++ = hex[(nsid[0] >> 4) & 0xf];
- *p++ = hex[nsid[0] & 0xf];
- nsid++;
- }
- *p = '\0';
-
- isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf,
- sizeof(addrbuf));
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
- DNS_LOGMODULE_RESOLVER, level,
- "received NSID '%s' from %s", buf, addrbuf);
-
- /* Clean up */
- isc_mem_put(mctx, buf, buflen);
- return;
-}
-
-static void
-log_packet(dns_message_t *message, int level, isc_mem_t *mctx) {
- isc_buffer_t buffer;
- char *buf = NULL;
- int len = 1024;
- isc_result_t result;
-
- if (! isc_log_wouldlog(dns_lctx, level))
- return;
-
- /*
- * Note that these are multiline debug messages. We want a newline
- * to appear in the log after each message.
- */
-
- do {
- buf = isc_mem_get(mctx, len);
- if (buf == NULL)
- break;
- isc_buffer_init(&buffer, buf, len);
- result = dns_message_totext(message, &dns_master_style_debug,
- 0, &buffer);
- if (result == ISC_R_NOSPACE) {
- isc_mem_put(mctx, buf, len);
- len += 1024;
- } else if (result == ISC_R_SUCCESS)
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
- DNS_LOGMODULE_RESOLVER, level,
- "received packet:\n%.*s",
- (int)isc_buffer_usedlength(&buffer),
- buf);
- } while (result == ISC_R_NOSPACE);
-
- if (buf != NULL)
- 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
-process_opt(resquery_t *query, dns_rdataset_t *opt) {
- dns_rdata_t rdata;
- isc_buffer_t optbuf;
- isc_result_t result;
- isc_uint16_t optcode;
- isc_uint16_t optlen;
-
- result = dns_rdataset_first(opt);
- if (result == ISC_R_SUCCESS) {
- dns_rdata_init(&rdata);
- dns_rdataset_current(opt, &rdata);
- isc_buffer_init(&optbuf, rdata.data, rdata.length);
- isc_buffer_add(&optbuf, rdata.length);
- while (isc_buffer_remaininglength(&optbuf) >= 4) {
- optcode = isc_buffer_getuint16(&optbuf);
- optlen = isc_buffer_getuint16(&optbuf);
- INSIST(optlen <= isc_buffer_remaininglength(&optbuf));
- switch (optcode) {
- case DNS_OPT_NSID:
- if (query->options & DNS_FETCHOPT_WANTNSID)
- log_nsid(&optbuf, optlen, query,
- ISC_LOG_INFO,
- query->fctx->res->mctx);
- isc_buffer_forward(&optbuf, optlen);
- break;
- default:
- isc_buffer_forward(&optbuf, optlen);
- break;
- }
- }
- INSIST(isc_buffer_remaininglength(&optbuf) == 0U);
- }
-}
-
-static void
-resquery_response(isc_task_t *task, isc_event_t *event) {
- isc_result_t result = ISC_R_SUCCESS;
- resquery_t *query = event->ev_arg;
- dns_dispatchevent_t *devent = (dns_dispatchevent_t *)event;
- isc_boolean_t keep_trying, get_nameservers, resend;
- isc_boolean_t truncated;
- dns_message_t *message;
- dns_rdataset_t *opt;
- fetchctx_t *fctx;
- dns_name_t *fname;
- dns_fixedname_t foundname;
- isc_stdtime_t now;
- isc_time_t tnow, *finish;
- dns_adbaddrinfo_t *addrinfo;
- unsigned int options;
- unsigned int findoptions;
- isc_result_t broken_server;
- badnstype_t broken_type = badns_response;
- isc_boolean_t no_response;
-
- REQUIRE(VALID_QUERY(query));
- fctx = query->fctx;
- options = query->options;
- REQUIRE(VALID_FCTX(fctx));
- REQUIRE(event->ev_type == DNS_EVENT_DISPATCH);
-
- QTRACE("response");
-
- if (isc_sockaddr_pf(&query->addrinfo->sockaddr) == PF_INET)
- inc_stats(fctx->res, dns_resstatscounter_responsev4);
- else
- inc_stats(fctx->res, dns_resstatscounter_responsev6);
-
- (void)isc_timer_touch(fctx->timer);
-
- keep_trying = ISC_FALSE;
- broken_server = ISC_R_SUCCESS;
- get_nameservers = ISC_FALSE;
- resend = ISC_FALSE;
- truncated = ISC_FALSE;
- finish = NULL;
- no_response = ISC_FALSE;
-
- if (fctx->res->exiting) {
- result = ISC_R_SHUTTINGDOWN;
- goto done;
- }
-
- fctx->timeouts = 0;
- fctx->timeout = ISC_FALSE;
- fctx->addrinfo = query->addrinfo;
-
- /*
- * XXXRTH We should really get the current time just once. We
- * need a routine to convert from an isc_time_t to an
- * isc_stdtime_t.
- */
- TIME_NOW(&tnow);
- finish = &tnow;
- isc_stdtime_get(&now);
-
- /*
- * Did the dispatcher have a problem?
- */
- if (devent->result != ISC_R_SUCCESS) {
- if (devent->result == ISC_R_EOF &&
- (query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
- /*
- * The problem might be that they
- * don't understand EDNS0. Turn it
- * off and try again.
- */
- options |= DNS_FETCHOPT_NOEDNS0;
- resend = ISC_TRUE;
- add_bad_edns(fctx, &query->addrinfo->sockaddr);
- } else {
- /*
- * There's no hope for this query.
- */
- keep_trying = ISC_TRUE;
-
- /*
- * If this is a network error on an exclusive query
- * socket, mark the server as bad so that we won't try
- * it for this fetch again. Also adjust finish and
- * no_response so that we penalize this address in SRTT
- * adjustment later.
- */
- if (query->exclusivesocket &&
- (devent->result == ISC_R_HOSTUNREACH ||
- devent->result == ISC_R_NETUNREACH ||
- devent->result == ISC_R_CONNREFUSED ||
- devent->result == ISC_R_CANCELED)) {
- broken_server = devent->result;
- broken_type = badns_unreachable;
- finish = NULL;
- no_response = ISC_TRUE;
- }
- }
- goto done;
- }
-
- message = fctx->rmessage;
-
- if (query->tsig != NULL) {
- result = dns_message_setquerytsig(message, query->tsig);
- if (result != ISC_R_SUCCESS)
- goto done;
- }
-
- if (query->tsigkey) {
- result = dns_message_settsigkey(message, query->tsigkey);
- if (result != ISC_R_SUCCESS)
- goto done;
- }
-
- result = dns_message_parse(message, &devent->buffer, 0);
- if (result != ISC_R_SUCCESS) {
- switch (result) {
- case ISC_R_UNEXPECTEDEND:
- if (!message->question_ok ||
- (message->flags & DNS_MESSAGEFLAG_TC) == 0 ||
- (options & DNS_FETCHOPT_TCP) != 0) {
- /*
- * Either the message ended prematurely,
- * and/or wasn't marked as being truncated,
- * and/or this is a response to a query we
- * sent over TCP. In all of these cases,
- * something is wrong with the remote
- * server and we don't want to retry using
- * TCP.
- */
- if ((query->options & DNS_FETCHOPT_NOEDNS0)
- == 0) {
- /*
- * The problem might be that they
- * don't understand EDNS0. Turn it
- * off and try again.
- */
- options |= DNS_FETCHOPT_NOEDNS0;
- resend = ISC_TRUE;
- add_bad_edns(fctx,
- &query->addrinfo->sockaddr);
- inc_stats(fctx->res,
- dns_resstatscounter_edns0fail);
- } else {
- broken_server = result;
- keep_trying = ISC_TRUE;
- }
- goto done;
- }
- /*
- * We defer retrying via TCP for a bit so we can
- * check out this message further.
- */
- truncated = ISC_TRUE;
- break;
- case DNS_R_FORMERR:
- if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
- /*
- * The problem might be that they
- * don't understand EDNS0. Turn it
- * off and try again.
- */
- options |= DNS_FETCHOPT_NOEDNS0;
- resend = ISC_TRUE;
- add_bad_edns(fctx, &query->addrinfo->sockaddr);
- inc_stats(fctx->res,
- dns_resstatscounter_edns0fail);
- } else {
- broken_server = DNS_R_UNEXPECTEDRCODE;
- keep_trying = ISC_TRUE;
- }
- goto done;
- default:
- /*
- * Something bad has happened.
- */
- goto done;
- }
- }
-
-
- /*
- * Log the incoming packet.
- */
- log_packet(message, ISC_LOG_DEBUG(10), fctx->res->mctx);
-
- /*
- * Process receive opt record.
- */
- opt = dns_message_getopt(message);
- if (opt != NULL)
- process_opt(query, opt);
-
- /*
- * If the message is signed, check the signature. If not, this
- * returns success anyway.
- */
- result = dns_message_checksig(message, fctx->res->view);
- if (result != ISC_R_SUCCESS)
- goto done;
-
- /*
- * The dispatcher should ensure we only get responses with QR set.
- */
- INSIST((message->flags & DNS_MESSAGEFLAG_QR) != 0);
- /*
- * INSIST() that the message comes from the place we sent it to,
- * since the dispatch code should ensure this.
- *
- * INSIST() that the message id is correct (this should also be
- * ensured by the dispatch code).
- */
-
- /*
- * We have an affirmative response to the query and we have
- * previously got a response from this server which indicated
- * EDNS may not be supported so we can now cache the lack of
- * EDNS support.
- */
- if (opt == NULL &&
- (message->rcode == dns_rcode_noerror ||
- message->rcode == dns_rcode_nxdomain ||
- message->rcode == dns_rcode_refused ||
- message->rcode == dns_rcode_yxdomain) &&
- bad_edns(fctx, &query->addrinfo->sockaddr)) {
- char addrbuf[ISC_SOCKADDR_FORMATSIZE];
- isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf,
- sizeof(addrbuf));
- dns_adb_changeflags(fctx->adb, query->addrinfo,
- DNS_FETCHOPT_NOEDNS0,
- DNS_FETCHOPT_NOEDNS0);
- }
-
- /*
- * Deal with truncated responses by retrying using TCP.
- */
- if ((message->flags & DNS_MESSAGEFLAG_TC) != 0)
- truncated = ISC_TRUE;
-
- if (truncated) {
- inc_stats(fctx->res, dns_resstatscounter_truncated);
- if ((options & DNS_FETCHOPT_TCP) != 0) {
- broken_server = DNS_R_TRUNCATEDTCP;
- keep_trying = ISC_TRUE;
- } else {
- options |= DNS_FETCHOPT_TCP;
- resend = ISC_TRUE;
- }
- goto done;
- }
-
- /*
- * Is it a query response?
- */
- if (message->opcode != dns_opcode_query) {
- /* XXXRTH Log */
- broken_server = DNS_R_UNEXPECTEDOPCODE;
- keep_trying = ISC_TRUE;
- goto done;
- }
-
- /*
- * Update statistics about erroneous responses.
- */
- if (message->rcode != dns_rcode_noerror) {
- switch (message->rcode) {
- case dns_rcode_nxdomain:
- inc_stats(fctx->res, dns_resstatscounter_nxdomain);
- break;
- case dns_rcode_servfail:
- inc_stats(fctx->res, dns_resstatscounter_servfail);
- break;
- case dns_rcode_formerr:
- inc_stats(fctx->res, dns_resstatscounter_formerr);
- break;
- default:
- inc_stats(fctx->res, dns_resstatscounter_othererror);
- break;
- }
- }
-
- /*
- * Is the remote server broken, or does it dislike us?
- */
- if (message->rcode != dns_rcode_noerror &&
- message->rcode != dns_rcode_nxdomain) {
- if (((message->rcode == dns_rcode_formerr ||
- message->rcode == dns_rcode_notimp) ||
- (message->rcode == dns_rcode_servfail &&
- dns_message_getopt(message) == NULL)) &&
- (query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
- /*
- * It's very likely they don't like EDNS0.
- * If the response code is SERVFAIL, also check if the
- * response contains an OPT RR and don't cache the
- * failure since it can be returned for various other
- * reasons.
- *
- * XXXRTH We should check if the question
- * we're asking requires EDNS0, and
- * if so, we should bail out.
- */
- options |= DNS_FETCHOPT_NOEDNS0;
- resend = ISC_TRUE;
- /*
- * Remember that they may not like EDNS0.
- */
- add_bad_edns(fctx, &query->addrinfo->sockaddr);
- inc_stats(fctx->res, dns_resstatscounter_edns0fail);
- } else if (message->rcode == dns_rcode_formerr) {
- if (ISFORWARDER(query->addrinfo)) {
- /*
- * This forwarder doesn't understand us,
- * but other forwarders might. Keep trying.
- */
- broken_server = DNS_R_REMOTEFORMERR;
- keep_trying = ISC_TRUE;
- } else {
- /*
- * The server doesn't understand us. Since
- * all servers for a zone need similar
- * capabilities, we assume that we will get
- * FORMERR from all servers, and thus we
- * 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) {
- /*
- * DNAME mapping failed because the new name
- * was too long. There's no chance of success
- * for this fetch.
- */
- result = DNS_R_YXDOMAIN;
- } else if (message->rcode == dns_rcode_badvers) {
- unsigned int flags, mask;
- unsigned int version;
-
- resend = ISC_TRUE;
- INSIST(opt != NULL);
- version = (opt->ttl >> 16) & 0xff;
- flags = (version << DNS_FETCHOPT_EDNSVERSIONSHIFT) |
- DNS_FETCHOPT_EDNSVERSIONSET;
- mask = DNS_FETCHOPT_EDNSVERSIONMASK |
- DNS_FETCHOPT_EDNSVERSIONSET;
- switch (version) {
- case 0:
- dns_adb_changeflags(fctx->adb, query->addrinfo,
- flags, mask);
- break;
- default:
- broken_server = DNS_R_BADVERS;
- keep_trying = ISC_TRUE;
- break;
- }
- } else {
- /*
- * XXXRTH log.
- */
- broken_server = DNS_R_UNEXPECTEDRCODE;
- INSIST(broken_server != ISC_R_SUCCESS);
- keep_trying = ISC_TRUE;
- }
- goto done;
- }
-
- /*
- * Is the question the same as the one we asked?
- */
- result = same_question(fctx);
- if (result != ISC_R_SUCCESS) {
- /* XXXRTH Log */
- if (result == DNS_R_FORMERR)
- keep_trying = ISC_TRUE;
- goto done;
- }
-
- /*
- * Is the server lame?
- */
- if (fctx->res->lame_ttl != 0 && !ISFORWARDER(query->addrinfo) &&
- is_lame(fctx)) {
- inc_stats(fctx->res, dns_resstatscounter_lame);
- log_lame(fctx, query->addrinfo);
- result = dns_adb_marklame(fctx->adb, query->addrinfo,
- &fctx->name, fctx->type,
- now + fctx->res->lame_ttl);
- if (result != ISC_R_SUCCESS)
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
- DNS_LOGMODULE_RESOLVER, ISC_LOG_ERROR,
- "could not mark server as lame: %s",
- isc_result_totext(result));
- broken_server = DNS_R_LAME;
- keep_trying = ISC_TRUE;
- goto done;
- }
-
- /*
- * Enforce delegations only zones like NET and COM.
- */
- if (!ISFORWARDER(query->addrinfo) &&
- dns_view_isdelegationonly(fctx->res->view, &fctx->domain) &&
- !dns_name_equal(&fctx->domain, &fctx->name) &&
- fix_mustbedelegationornxdomain(message, fctx)) {
- char namebuf[DNS_NAME_FORMATSIZE];
- char domainbuf[DNS_NAME_FORMATSIZE];
- char addrbuf[ISC_SOCKADDR_FORMATSIZE];
- char classbuf[64];
- char typebuf[64];
-
- dns_name_format(&fctx->name, namebuf, sizeof(namebuf));
- dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf));
- dns_rdatatype_format(fctx->type, typebuf, sizeof(typebuf));
- dns_rdataclass_format(fctx->res->rdclass, classbuf,
- sizeof(classbuf));
- isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf,
- sizeof(addrbuf));
-
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DELEGATION_ONLY,
- DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE,
- "enforced delegation-only for '%s' (%s/%s/%s) "
- "from %s",
- domainbuf, namebuf, typebuf, classbuf, addrbuf);
- }
-
- if ((fctx->res->options & DNS_RESOLVER_CHECKNAMES) != 0)
- checknames(message);
-
- /*
- * Clear cache bits.
- */
- fctx->attributes &= ~(FCTX_ATTR_WANTNCACHE | FCTX_ATTR_WANTCACHE);
-
- /*
- * Did we get any answers?
- */
- if (message->counts[DNS_SECTION_ANSWER] > 0 &&
- (message->rcode == dns_rcode_noerror ||
- message->rcode == dns_rcode_nxdomain)) {
- /*
- * [normal case]
- * We've got answers. If it has an authoritative answer or an
- * answer from a forwarder, we're done.
- */
- 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) {
- /*
- * 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;
- keep_trying = ISC_TRUE;
- goto done;
- }
- goto force_referral;
- }
- if (result != ISC_R_SUCCESS) {
- if (result == DNS_R_FORMERR)
- keep_trying = ISC_TRUE;
- goto done;
- }
- } else if (message->counts[DNS_SECTION_AUTHORITY] > 0 ||
- message->rcode == dns_rcode_noerror ||
- message->rcode == dns_rcode_nxdomain) {
- /*
- * NXDOMAIN, NXRDATASET, or referral.
- */
- result = noanswer_response(fctx, NULL, 0);
- if (result == DNS_R_CHASEDSSERVERS) {
- } else if (result == DNS_R_DELEGATION) {
- force_referral:
- /*
- * We don't have the answer, but we know a better
- * place to look.
- */
- get_nameservers = ISC_TRUE;
- keep_trying = ISC_TRUE;
- /*
- * We have a new set of name servers, and it
- * has not experienced any restarts yet.
- */
- fctx->restarts = 0;
-
- /*
- * Update local statistics counters collected for each
- * new zone.
- */
- fctx->referrals++;
- fctx->querysent = 0;
- fctx->lamecount = 0;
- fctx->neterr = 0;
- fctx->badresp = 0;
- fctx->adberr = 0;
-
- result = ISC_R_SUCCESS;
- } else if (result != ISC_R_SUCCESS) {
- /*
- * Something has gone wrong.
- */
- if (result == DNS_R_FORMERR)
- keep_trying = ISC_TRUE;
- goto done;
- }
- } else {
- /*
- * The server is insane.
- */
- /* XXXRTH Log */
- broken_server = DNS_R_UNEXPECTEDRCODE;
- keep_trying = ISC_TRUE;
- goto done;
- }
-
- /*
- * Follow additional section data chains.
- */
- chase_additional(fctx);
-
- /*
- * Cache the cacheable parts of the message. This may also cause
- * work to be queued to the DNSSEC validator.
- */
- if (WANTCACHE(fctx)) {
- result = cache_message(fctx, query->addrinfo, now);
- if (result != ISC_R_SUCCESS)
- goto done;
- }
-
- /*
- * Ncache the negatively cacheable parts of the message. This may
- * also cause work to be queued to the DNSSEC validator.
- */
- if (WANTNCACHE(fctx)) {
- dns_rdatatype_t covers;
- if (message->rcode == dns_rcode_nxdomain)
- covers = dns_rdatatype_any;
- else
- covers = fctx->type;
-
- /*
- * Cache any negative cache entries in the message.
- */
- result = ncache_message(fctx, query->addrinfo, covers, now);
- }
-
- done:
- /*
- * Remember the query's addrinfo, in case we need to mark the
- * server as broken.
- */
- addrinfo = query->addrinfo;
-
- /*
- * Cancel the query.
- *
- * XXXRTH Don't cancel the query if waiting for validation?
- */
- fctx_cancelquery(&query, &devent, finish, no_response);
-
- if (keep_trying) {
- if (result == DNS_R_FORMERR)
- broken_server = DNS_R_FORMERR;
- if (broken_server != ISC_R_SUCCESS) {
- /*
- * Add this server to the list of bad servers for
- * this fctx.
- */
- add_bad(fctx, addrinfo, broken_server, broken_type);
- }
-
- if (get_nameservers) {
- dns_name_t *name;
- dns_fixedname_init(&foundname);
- fname = dns_fixedname_name(&foundname);
- if (result != ISC_R_SUCCESS) {
- fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
- return;
- }
- findoptions = 0;
- if (dns_rdatatype_atparent(fctx->type))
- findoptions |= DNS_DBFIND_NOEXACT;
- if ((options & DNS_FETCHOPT_UNSHARED) == 0)
- name = &fctx->name;
- else
- name = &fctx->domain;
- result = dns_view_findzonecut(fctx->res->view,
- name, fname,
- now, findoptions,
- ISC_TRUE,
- &fctx->nameservers,
- NULL);
- if (result != ISC_R_SUCCESS) {
- FCTXTRACE("couldn't find a zonecut");
- fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
- return;
- }
- if (!dns_name_issubdomain(fname, &fctx->domain)) {
- /*
- * The best nameservers are now above our
- * QDOMAIN.
- */
- FCTXTRACE("nameservers now above QDOMAIN");
- fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
- return;
- }
- dns_name_free(&fctx->domain, fctx->mctx);
- dns_name_init(&fctx->domain, NULL);
- result = dns_name_dup(fname, fctx->mctx, &fctx->domain);
- if (result != ISC_R_SUCCESS) {
- fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
- return;
- }
- fctx->ns_ttl = fctx->nameservers.ttl;
- fctx->ns_ttl_ok = ISC_TRUE;
- fctx_cancelqueries(fctx, ISC_TRUE);
- fctx_cleanupfinds(fctx);
- fctx_cleanupaltfinds(fctx);
- fctx_cleanupforwaddrs(fctx);
- fctx_cleanupaltaddrs(fctx);
- }
- /*
- * Try again.
- */
- fctx_try(fctx, !get_nameservers, ISC_FALSE);
- } else if (resend) {
- /*
- * Resend (probably with changed options).
- */
- FCTXTRACE("resend");
- inc_stats(fctx->res, dns_resstatscounter_retry);
- result = fctx_query(fctx, addrinfo, options);
- if (result != ISC_R_SUCCESS)
- fctx_done(fctx, result, __LINE__);
- } else if (result == ISC_R_SUCCESS && !HAVE_ANSWER(fctx)) {
- /*
- * All has gone well so far, but we are waiting for the
- * DNSSEC validator to validate the answer.
- */
- FCTXTRACE("wait for validator");
- fctx_cancelqueries(fctx, ISC_TRUE);
- /*
- * We must not retransmit while the validator is working;
- * it has references to the current rmessage.
- */
- result = fctx_stopidletimer(fctx);
- if (result != ISC_R_SUCCESS)
- fctx_done(fctx, result, __LINE__);
- } else if (result == DNS_R_CHASEDSSERVERS) {
- unsigned int n;
- add_bad(fctx, addrinfo, result, broken_type);
- fctx_cancelqueries(fctx, ISC_TRUE);
- fctx_cleanupfinds(fctx);
- fctx_cleanupforwaddrs(fctx);
-
- n = dns_name_countlabels(&fctx->name);
- dns_name_getlabelsequence(&fctx->name, 1, n - 1, &fctx->nsname);
-
- FCTXTRACE("suspending DS lookup to find parent's NS records");
-
- result = dns_resolver_createfetch(fctx->res, &fctx->nsname,
- dns_rdatatype_ns,
- NULL, NULL, NULL, 0, task,
- resume_dslookup, fctx,
- &fctx->nsrrset, NULL,
- &fctx->nsfetch);
- if (result != ISC_R_SUCCESS)
- fctx_done(fctx, result, __LINE__);
- else {
- LOCK(&fctx->res->buckets[fctx->bucketnum].lock);
- fctx->references++;
- UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock);
- result = fctx_stopidletimer(fctx);
- if (result != ISC_R_SUCCESS)
- fctx_done(fctx, result, __LINE__);
- }
- } else {
- /*
- * We're done.
- */
- fctx_done(fctx, result, __LINE__);
- }
-}
-
-
-/***
- *** Resolver Methods
- ***/
-static void
-destroy_badcache(dns_resolver_t *res) {
- dns_badcache_t *bad, *next;
- unsigned int i;
-
- if (res->badcache != NULL) {
- for (i = 0; i < res->badhash; i++)
- for (bad = res->badcache[i]; bad != NULL;
- bad = next) {
- next = bad->next;
- isc_mem_put(res->mctx, bad, sizeof(*bad) +
- bad->name.length);
- res->badcount--;
- }
- isc_mem_put(res->mctx, res->badcache,
- sizeof(*res->badcache) * res->badhash);
- res->badcache = NULL;
- res->badhash = 0;
- INSIST(res->badcount == 0);
- }
-}
-
-static void
-destroy(dns_resolver_t *res) {
- unsigned int i;
- alternate_t *a;
-
- REQUIRE(res->references == 0);
- REQUIRE(!res->priming);
- REQUIRE(res->primefetch == NULL);
-
- RTRACE("destroy");
-
- INSIST(res->nfctx == 0);
-
- DESTROYLOCK(&res->primelock);
- DESTROYLOCK(&res->nlock);
- DESTROYLOCK(&res->lock);
- for (i = 0; i < res->nbuckets; i++) {
- INSIST(ISC_LIST_EMPTY(res->buckets[i].fctxs));
- isc_task_shutdown(res->buckets[i].task);
- isc_task_detach(&res->buckets[i].task);
- DESTROYLOCK(&res->buckets[i].lock);
- isc_mem_detach(&res->buckets[i].mctx);
- }
- isc_mem_put(res->mctx, res->buckets,
- res->nbuckets * sizeof(fctxbucket_t));
- if (res->dispatches4 != NULL)
- dns_dispatchset_destroy(&res->dispatches4);
- if (res->dispatches6 != NULL)
- dns_dispatchset_destroy(&res->dispatches6);
- while ((a = ISC_LIST_HEAD(res->alternates)) != NULL) {
- ISC_LIST_UNLINK(res->alternates, a, link);
- if (!a->isaddress)
- dns_name_free(&a->_u._n.name, res->mctx);
- isc_mem_put(res->mctx, a, sizeof(*a));
- }
- dns_resolver_reset_algorithms(res);
- destroy_badcache(res);
- dns_resolver_resetmustbesecure(res);
-#if USE_ALGLOCK
- isc_rwlock_destroy(&res->alglock);
-#endif
-#if USE_MBSLOCK
- isc_rwlock_destroy(&res->mbslock);
-#endif
- isc_timer_detach(&res->spillattimer);
- res->magic = 0;
- isc_mem_put(res->mctx, res, sizeof(*res));
-}
-
-static void
-send_shutdown_events(dns_resolver_t *res) {
- isc_event_t *event, *next_event;
- isc_task_t *etask;
-
- /*
- * Caller must be holding the resolver lock.
- */
-
- for (event = ISC_LIST_HEAD(res->whenshutdown);
- event != NULL;
- event = next_event) {
- next_event = ISC_LIST_NEXT(event, ev_link);
- ISC_LIST_UNLINK(res->whenshutdown, event, ev_link);
- etask = event->ev_sender;
- event->ev_sender = res;
- isc_task_sendanddetach(&etask, &event);
- }
-}
-
-static void
-empty_bucket(dns_resolver_t *res) {
- RTRACE("empty_bucket");
-
- LOCK(&res->lock);
-
- INSIST(res->activebuckets > 0);
- res->activebuckets--;
- if (res->activebuckets == 0)
- send_shutdown_events(res);
-
- UNLOCK(&res->lock);
-}
-
-static void
-spillattimer_countdown(isc_task_t *task, isc_event_t *event) {
- dns_resolver_t *res = event->ev_arg;
- isc_result_t result;
- unsigned int count;
- isc_boolean_t logit = ISC_FALSE;
-
- REQUIRE(VALID_RESOLVER(res));
-
- UNUSED(task);
-
- LOCK(&res->lock);
- INSIST(!res->exiting);
- if (res->spillat > res->spillatmin) {
- res->spillat--;
- logit = ISC_TRUE;
- }
- if (res->spillat <= res->spillatmin) {
- result = isc_timer_reset(res->spillattimer,
- isc_timertype_inactive, NULL,
- NULL, ISC_TRUE);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- }
- count = res->spillat;
- UNLOCK(&res->lock);
- if (logit)
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
- DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE,
- "clients-per-query decreased to %u", count);
-
- isc_event_free(&event);
-}
-
-isc_result_t
-dns_resolver_create(dns_view_t *view,
- isc_taskmgr_t *taskmgr,
- unsigned int ntasks, unsigned int ndisp,
- isc_socketmgr_t *socketmgr,
- isc_timermgr_t *timermgr,
- unsigned int options,
- dns_dispatchmgr_t *dispatchmgr,
- dns_dispatch_t *dispatchv4,
- dns_dispatch_t *dispatchv6,
- dns_resolver_t **resp)
-{
- dns_resolver_t *res;
- isc_result_t result = ISC_R_SUCCESS;
- unsigned int i, buckets_created = 0;
- isc_task_t *task = NULL;
- char name[16];
- unsigned dispattr;
-
- /*
- * Create a resolver.
- */
-
- REQUIRE(DNS_VIEW_VALID(view));
- REQUIRE(ntasks > 0);
- REQUIRE(ndisp > 0);
- REQUIRE(resp != NULL && *resp == NULL);
- REQUIRE(dispatchmgr != NULL);
- REQUIRE(dispatchv4 != NULL || dispatchv6 != NULL);
-
- res = isc_mem_get(view->mctx, sizeof(*res));
- if (res == NULL)
- return (ISC_R_NOMEMORY);
- RTRACE("create");
- res->mctx = view->mctx;
- res->rdclass = view->rdclass;
- res->socketmgr = socketmgr;
- res->timermgr = timermgr;
- res->taskmgr = taskmgr;
- res->dispatchmgr = dispatchmgr;
- res->view = view;
- res->options = options;
- res->lame_ttl = 0;
- ISC_LIST_INIT(res->alternates);
- res->udpsize = RECV_BUFFER_SIZE;
- res->algorithms = NULL;
- res->badcache = NULL;
- res->badcount = 0;
- res->badhash = 0;
- res->badsweep = 0;
- res->mustbesecure = NULL;
- res->spillatmin = res->spillat = 10;
- res->spillatmax = 100;
- res->spillattimer = NULL;
- res->zero_no_soa_ttl = ISC_FALSE;
- res->query_timeout = DEFAULT_QUERY_TIMEOUT;
- res->nbuckets = ntasks;
- res->activebuckets = ntasks;
- res->buckets = isc_mem_get(view->mctx,
- ntasks * sizeof(fctxbucket_t));
- if (res->buckets == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup_res;
- }
- for (i = 0; i < ntasks; i++) {
- result = isc_mutex_init(&res->buckets[i].lock);
- if (result != ISC_R_SUCCESS)
- goto cleanup_buckets;
- res->buckets[i].task = NULL;
- result = isc_task_create(taskmgr, 0, &res->buckets[i].task);
- if (result != ISC_R_SUCCESS) {
- DESTROYLOCK(&res->buckets[i].lock);
- goto cleanup_buckets;
- }
- res->buckets[i].mctx = NULL;
- snprintf(name, sizeof(name), "res%u", i);
-#ifdef ISC_PLATFORM_USETHREADS
- /*
- * Use a separate memory context for each bucket to reduce
- * contention among multiple threads. Do this only when
- * enabling threads because it will be require more memory.
- */
- result = isc_mem_create(0, 0, &res->buckets[i].mctx);
- if (result != ISC_R_SUCCESS) {
- isc_task_detach(&res->buckets[i].task);
- DESTROYLOCK(&res->buckets[i].lock);
- goto cleanup_buckets;
- }
- isc_mem_setname(res->buckets[i].mctx, name, NULL);
-#else
- isc_mem_attach(view->mctx, &res->buckets[i].mctx);
-#endif
- isc_task_setname(res->buckets[i].task, name, res);
- ISC_LIST_INIT(res->buckets[i].fctxs);
- res->buckets[i].exiting = ISC_FALSE;
- buckets_created++;
- }
-
- res->dispatches4 = NULL;
- if (dispatchv4 != NULL) {
- dns_dispatchset_create(view->mctx, socketmgr, taskmgr,
- dispatchv4, &res->dispatches4, ndisp);
- dispattr = dns_dispatch_getattributes(dispatchv4);
- res->exclusivev4 =
- ISC_TF((dispattr & DNS_DISPATCHATTR_EXCLUSIVE) != 0);
- }
-
- res->dispatches6 = NULL;
- if (dispatchv6 != NULL) {
- dns_dispatchset_create(view->mctx, socketmgr, taskmgr,
- dispatchv6, &res->dispatches6, ndisp);
- dispattr = dns_dispatch_getattributes(dispatchv6);
- res->exclusivev6 =
- ISC_TF((dispattr & DNS_DISPATCHATTR_EXCLUSIVE) != 0);
- }
-
- res->references = 1;
- res->exiting = ISC_FALSE;
- res->frozen = ISC_FALSE;
- ISC_LIST_INIT(res->whenshutdown);
- res->priming = ISC_FALSE;
- res->primefetch = NULL;
- res->nfctx = 0;
-
- result = isc_mutex_init(&res->lock);
- if (result != ISC_R_SUCCESS)
- goto cleanup_dispatches;
-
- result = isc_mutex_init(&res->nlock);
- if (result != ISC_R_SUCCESS)
- goto cleanup_lock;
-
- result = isc_mutex_init(&res->primelock);
- if (result != ISC_R_SUCCESS)
- goto cleanup_nlock;
-
- task = NULL;
- result = isc_task_create(taskmgr, 0, &task);
- if (result != ISC_R_SUCCESS)
- goto cleanup_primelock;
-
- result = isc_timer_create(timermgr, isc_timertype_inactive, NULL, NULL,
- task, spillattimer_countdown, res,
- &res->spillattimer);
- isc_task_detach(&task);
- if (result != ISC_R_SUCCESS)
- goto cleanup_primelock;
-
-#if USE_ALGLOCK
- result = isc_rwlock_init(&res->alglock, 0, 0);
- if (result != ISC_R_SUCCESS)
- goto cleanup_spillattimer;
-#endif
-#if USE_MBSLOCK
- result = isc_rwlock_init(&res->mbslock, 0, 0);
- if (result != ISC_R_SUCCESS)
- goto cleanup_alglock;
-#endif
-
- res->magic = RES_MAGIC;
-
- *resp = res;
-
- return (ISC_R_SUCCESS);
-
-#if USE_MBSLOCK
- cleanup_alglock:
-#if USE_ALGLOCK
- isc_rwlock_destroy(&res->alglock);
-#endif
-#endif
-#if USE_ALGLOCK || USE_MBSLOCK
- cleanup_spillattimer:
- isc_timer_detach(&res->spillattimer);
-#endif
-
- cleanup_primelock:
- DESTROYLOCK(&res->primelock);
-
- cleanup_nlock:
- DESTROYLOCK(&res->nlock);
-
- cleanup_lock:
- DESTROYLOCK(&res->lock);
-
- cleanup_dispatches:
- if (res->dispatches6 != NULL)
- dns_dispatchset_destroy(&res->dispatches6);
- if (res->dispatches4 != NULL)
- dns_dispatchset_destroy(&res->dispatches4);
-
- cleanup_buckets:
- for (i = 0; i < buckets_created; i++) {
- isc_mem_detach(&res->buckets[i].mctx);
- DESTROYLOCK(&res->buckets[i].lock);
- isc_task_shutdown(res->buckets[i].task);
- isc_task_detach(&res->buckets[i].task);
- }
- isc_mem_put(view->mctx, res->buckets,
- res->nbuckets * sizeof(fctxbucket_t));
-
- cleanup_res:
- isc_mem_put(view->mctx, res, sizeof(*res));
-
- return (result);
-}
-
-#ifdef BIND9
-static void
-prime_done(isc_task_t *task, isc_event_t *event) {
- dns_resolver_t *res;
- dns_fetchevent_t *fevent;
- dns_fetch_t *fetch;
- dns_db_t *db = NULL;
-
- REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE);
- fevent = (dns_fetchevent_t *)event;
- res = event->ev_arg;
- REQUIRE(VALID_RESOLVER(res));
-
- UNUSED(task);
-
- LOCK(&res->lock);
-
- INSIST(res->priming);
- res->priming = ISC_FALSE;
- LOCK(&res->primelock);
- fetch = res->primefetch;
- res->primefetch = NULL;
- UNLOCK(&res->primelock);
-
- UNLOCK(&res->lock);
-
- if (fevent->result == ISC_R_SUCCESS &&
- res->view->cache != NULL && res->view->hints != NULL) {
- dns_cache_attachdb(res->view->cache, &db);
- dns_root_checkhints(res->view, res->view->hints, db);
- dns_db_detach(&db);
- }
-
- if (fevent->node != NULL)
- dns_db_detachnode(fevent->db, &fevent->node);
- if (fevent->db != NULL)
- dns_db_detach(&fevent->db);
- if (dns_rdataset_isassociated(fevent->rdataset))
- dns_rdataset_disassociate(fevent->rdataset);
- INSIST(fevent->sigrdataset == NULL);
-
- isc_mem_put(res->mctx, fevent->rdataset, sizeof(*fevent->rdataset));
-
- isc_event_free(&event);
- dns_resolver_destroyfetch(&fetch);
-}
-
-void
-dns_resolver_prime(dns_resolver_t *res) {
- isc_boolean_t want_priming = ISC_FALSE;
- dns_rdataset_t *rdataset;
- isc_result_t result;
-
- REQUIRE(VALID_RESOLVER(res));
- REQUIRE(res->frozen);
-
- RTRACE("dns_resolver_prime");
-
- LOCK(&res->lock);
-
- if (!res->exiting && !res->priming) {
- INSIST(res->primefetch == NULL);
- res->priming = ISC_TRUE;
- want_priming = ISC_TRUE;
- }
-
- UNLOCK(&res->lock);
-
- if (want_priming) {
- /*
- * To avoid any possible recursive locking problems, we
- * start the priming fetch like any other fetch, and holding
- * no resolver locks. No one else will try to start it
- * because we're the ones who set res->priming to true.
- * Any other callers of dns_resolver_prime() while we're
- * running will see that res->priming is already true and
- * do nothing.
- */
- RTRACE("priming");
- rdataset = isc_mem_get(res->mctx, sizeof(*rdataset));
- if (rdataset == NULL) {
- LOCK(&res->lock);
- INSIST(res->priming);
- INSIST(res->primefetch == NULL);
- res->priming = ISC_FALSE;
- UNLOCK(&res->lock);
- return;
- }
- dns_rdataset_init(rdataset);
- LOCK(&res->primelock);
- result = dns_resolver_createfetch(res, dns_rootname,
- dns_rdatatype_ns,
- NULL, NULL, NULL, 0,
- res->buckets[0].task,
- prime_done,
- res, rdataset, NULL,
- &res->primefetch);
- UNLOCK(&res->primelock);
- if (result != ISC_R_SUCCESS) {
- LOCK(&res->lock);
- INSIST(res->priming);
- res->priming = ISC_FALSE;
- UNLOCK(&res->lock);
- }
- }
-}
-#endif /* BIND9 */
-
-void
-dns_resolver_freeze(dns_resolver_t *res) {
- /*
- * Freeze resolver.
- */
-
- REQUIRE(VALID_RESOLVER(res));
-
- res->frozen = ISC_TRUE;
-}
-
-void
-dns_resolver_attach(dns_resolver_t *source, dns_resolver_t **targetp) {
- REQUIRE(VALID_RESOLVER(source));
- REQUIRE(targetp != NULL && *targetp == NULL);
-
- RRTRACE(source, "attach");
- LOCK(&source->lock);
- REQUIRE(!source->exiting);
-
- INSIST(source->references > 0);
- source->references++;
- INSIST(source->references != 0);
- UNLOCK(&source->lock);
-
- *targetp = source;
-}
-
-void
-dns_resolver_whenshutdown(dns_resolver_t *res, isc_task_t *task,
- isc_event_t **eventp)
-{
- isc_task_t *clone;
- isc_event_t *event;
-
- REQUIRE(VALID_RESOLVER(res));
- REQUIRE(eventp != NULL);
-
- event = *eventp;
- *eventp = NULL;
-
- LOCK(&res->lock);
-
- if (res->exiting && res->activebuckets == 0) {
- /*
- * We're already shutdown. Send the event.
- */
- event->ev_sender = res;
- isc_task_send(task, &event);
- } else {
- clone = NULL;
- isc_task_attach(task, &clone);
- event->ev_sender = clone;
- ISC_LIST_APPEND(res->whenshutdown, event, ev_link);
- }
-
- UNLOCK(&res->lock);
-}
-
-void
-dns_resolver_shutdown(dns_resolver_t *res) {
- unsigned int i;
- fetchctx_t *fctx;
- isc_result_t result;
-
- REQUIRE(VALID_RESOLVER(res));
-
- RTRACE("shutdown");
-
- LOCK(&res->lock);
-
- if (!res->exiting) {
- RTRACE("exiting");
- res->exiting = ISC_TRUE;
-
- for (i = 0; i < res->nbuckets; i++) {
- LOCK(&res->buckets[i].lock);
- for (fctx = ISC_LIST_HEAD(res->buckets[i].fctxs);
- fctx != NULL;
- fctx = ISC_LIST_NEXT(fctx, link))
- fctx_shutdown(fctx);
- if (res->dispatches4 != NULL && !res->exclusivev4) {
- dns_dispatchset_cancelall(res->dispatches4,
- res->buckets[i].task);
- }
- if (res->dispatches6 != NULL && !res->exclusivev6) {
- dns_dispatchset_cancelall(res->dispatches6,
- res->buckets[i].task);
- }
- res->buckets[i].exiting = ISC_TRUE;
- if (ISC_LIST_EMPTY(res->buckets[i].fctxs)) {
- INSIST(res->activebuckets > 0);
- res->activebuckets--;
- }
- UNLOCK(&res->buckets[i].lock);
- }
- if (res->activebuckets == 0)
- send_shutdown_events(res);
- result = isc_timer_reset(res->spillattimer,
- isc_timertype_inactive, NULL,
- NULL, ISC_TRUE);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- }
-
- UNLOCK(&res->lock);
-}
-
-void
-dns_resolver_detach(dns_resolver_t **resp) {
- dns_resolver_t *res;
- isc_boolean_t need_destroy = ISC_FALSE;
-
- REQUIRE(resp != NULL);
- res = *resp;
- REQUIRE(VALID_RESOLVER(res));
-
- RTRACE("detach");
-
- LOCK(&res->lock);
-
- INSIST(res->references > 0);
- res->references--;
- if (res->references == 0) {
- INSIST(res->exiting && res->activebuckets == 0);
- need_destroy = ISC_TRUE;
- }
-
- UNLOCK(&res->lock);
-
- if (need_destroy)
- destroy(res);
-
- *resp = NULL;
-}
-
-static inline isc_boolean_t
-fctx_match(fetchctx_t *fctx, dns_name_t *name, dns_rdatatype_t type,
- unsigned int options)
-{
- /*
- * Don't match fetch contexts that are shutting down.
- */
- if (fctx->cloned || fctx->state == fetchstate_done ||
- ISC_LIST_EMPTY(fctx->events))
- return (ISC_FALSE);
-
- if (fctx->type != type || fctx->options != options)
- return (ISC_FALSE);
- return (dns_name_equal(&fctx->name, name));
-}
-
-static inline void
-log_fetch(dns_name_t *name, dns_rdatatype_t type) {
- char namebuf[DNS_NAME_FORMATSIZE];
- char typebuf[DNS_RDATATYPE_FORMATSIZE];
- int level = ISC_LOG_DEBUG(1);
-
- if (! isc_log_wouldlog(dns_lctx, level))
- return;
-
- dns_name_format(name, namebuf, sizeof(namebuf));
- dns_rdatatype_format(type, typebuf, sizeof(typebuf));
-
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
- DNS_LOGMODULE_RESOLVER, level,
- "createfetch: %s %s", namebuf, typebuf);
-}
-
-isc_result_t
-dns_resolver_createfetch(dns_resolver_t *res, dns_name_t *name,
- dns_rdatatype_t type,
- dns_name_t *domain, dns_rdataset_t *nameservers,
- dns_forwarders_t *forwarders,
- unsigned int options, isc_task_t *task,
- isc_taskaction_t action, void *arg,
- dns_rdataset_t *rdataset,
- dns_rdataset_t *sigrdataset,
- dns_fetch_t **fetchp)
-{
- return (dns_resolver_createfetch2(res, name, type, domain,
- nameservers, forwarders, NULL, 0,
- options, task, action, arg,
- rdataset, sigrdataset, fetchp));
-}
-
-isc_result_t
-dns_resolver_createfetch2(dns_resolver_t *res, dns_name_t *name,
- dns_rdatatype_t type,
- dns_name_t *domain, dns_rdataset_t *nameservers,
- dns_forwarders_t *forwarders,
- isc_sockaddr_t *client, dns_messageid_t id,
- unsigned int options, isc_task_t *task,
- isc_taskaction_t action, void *arg,
- dns_rdataset_t *rdataset,
- dns_rdataset_t *sigrdataset,
- dns_fetch_t **fetchp)
-{
- dns_fetch_t *fetch;
- fetchctx_t *fctx = NULL;
- isc_result_t result = ISC_R_SUCCESS;
- unsigned int bucketnum;
- isc_boolean_t new_fctx = ISC_FALSE;
- isc_event_t *event;
- unsigned int count = 0;
- unsigned int spillat;
- unsigned int spillatmin;
- isc_boolean_t destroy = ISC_FALSE;
-
- UNUSED(forwarders);
-
- REQUIRE(VALID_RESOLVER(res));
- REQUIRE(res->frozen);
- /* XXXRTH Check for meta type */
- if (domain != NULL) {
- REQUIRE(DNS_RDATASET_VALID(nameservers));
- REQUIRE(nameservers->type == dns_rdatatype_ns);
- } else
- REQUIRE(nameservers == NULL);
- REQUIRE(forwarders == NULL);
- REQUIRE(!dns_rdataset_isassociated(rdataset));
- REQUIRE(sigrdataset == NULL ||
- !dns_rdataset_isassociated(sigrdataset));
- REQUIRE(fetchp != NULL && *fetchp == NULL);
-
- log_fetch(name, type);
-
- /*
- * XXXRTH use a mempool?
- */
- fetch = isc_mem_get(res->mctx, sizeof(*fetch));
- if (fetch == NULL)
- return (ISC_R_NOMEMORY);
-
- bucketnum = dns_name_fullhash(name, ISC_FALSE) % res->nbuckets;
-
- LOCK(&res->lock);
- spillat = res->spillat;
- spillatmin = res->spillatmin;
- UNLOCK(&res->lock);
- LOCK(&res->buckets[bucketnum].lock);
-
- if (res->buckets[bucketnum].exiting) {
- result = ISC_R_SHUTTINGDOWN;
- goto unlock;
- }
-
- if ((options & DNS_FETCHOPT_UNSHARED) == 0) {
- for (fctx = ISC_LIST_HEAD(res->buckets[bucketnum].fctxs);
- fctx != NULL;
- fctx = ISC_LIST_NEXT(fctx, link)) {
- if (fctx_match(fctx, name, type, options))
- break;
- }
- }
-
- /*
- * Is this a duplicate?
- */
- if (fctx != NULL && client != NULL) {
- dns_fetchevent_t *fevent;
- for (fevent = ISC_LIST_HEAD(fctx->events);
- fevent != NULL;
- fevent = ISC_LIST_NEXT(fevent, ev_link)) {
- if (fevent->client != NULL && fevent->id == id &&
- isc_sockaddr_equal(fevent->client, client)) {
- result = DNS_R_DUPLICATE;
- goto unlock;
- }
- count++;
- }
- }
- if (count >= spillatmin && spillatmin != 0) {
- INSIST(fctx != NULL);
- if (count >= spillat)
- fctx->spilled = ISC_TRUE;
- if (fctx->spilled) {
- result = DNS_R_DROP;
- goto unlock;
- }
- }
-
- if (fctx == NULL) {
- result = fctx_create(res, name, type, domain, nameservers,
- options, bucketnum, &fctx);
- if (result != ISC_R_SUCCESS)
- goto unlock;
- new_fctx = ISC_TRUE;
- }
-
- result = fctx_join(fctx, task, client, id, action, arg,
- rdataset, sigrdataset, fetch);
- if (new_fctx) {
- if (result == ISC_R_SUCCESS) {
- /*
- * Launch this fctx.
- */
- event = &fctx->control_event;
- ISC_EVENT_INIT(event, sizeof(*event), 0, NULL,
- DNS_EVENT_FETCHCONTROL,
- fctx_start, fctx, NULL,
- NULL, NULL);
- isc_task_send(res->buckets[bucketnum].task, &event);
- } else {
- /*
- * We don't care about the result of fctx_unlink()
- * since we know we're not exiting.
- */
- (void)fctx_unlink(fctx);
- destroy = ISC_TRUE;
- }
- }
-
- unlock:
- UNLOCK(&res->buckets[bucketnum].lock);
-
- if (destroy)
- fctx_destroy(fctx);
-
- if (result == ISC_R_SUCCESS) {
- FTRACE("created");
- *fetchp = fetch;
- } else
- isc_mem_put(res->mctx, fetch, sizeof(*fetch));
-
- return (result);
-}
-
-void
-dns_resolver_cancelfetch(dns_fetch_t *fetch) {
- fetchctx_t *fctx;
- dns_resolver_t *res;
- dns_fetchevent_t *event, *next_event;
- isc_task_t *etask;
-
- REQUIRE(DNS_FETCH_VALID(fetch));
- fctx = fetch->private;
- REQUIRE(VALID_FCTX(fctx));
- res = fctx->res;
-
- FTRACE("cancelfetch");
-
- LOCK(&res->buckets[fctx->bucketnum].lock);
-
- /*
- * Find the completion event for this fetch (as opposed
- * to those for other fetches that have joined the same
- * fctx) and send it with result = ISC_R_CANCELED.
- */
- event = NULL;
- if (fctx->state != fetchstate_done) {
- for (event = ISC_LIST_HEAD(fctx->events);
- event != NULL;
- event = next_event) {
- next_event = ISC_LIST_NEXT(event, ev_link);
- if (event->fetch == fetch) {
- ISC_LIST_UNLINK(fctx->events, event, ev_link);
- break;
- }
- }
- }
- if (event != NULL) {
- etask = event->ev_sender;
- event->ev_sender = fctx;
- event->result = ISC_R_CANCELED;
- isc_task_sendanddetach(&etask, ISC_EVENT_PTR(&event));
- }
- /*
- * The fctx continues running even if no fetches remain;
- * the answer is still cached.
- */
-
- UNLOCK(&res->buckets[fctx->bucketnum].lock);
-}
-
-void
-dns_resolver_destroyfetch(dns_fetch_t **fetchp) {
- dns_fetch_t *fetch;
- dns_resolver_t *res;
- dns_fetchevent_t *event, *next_event;
- fetchctx_t *fctx;
- unsigned int bucketnum;
- isc_boolean_t bucket_empty;
-
- REQUIRE(fetchp != NULL);
- fetch = *fetchp;
- REQUIRE(DNS_FETCH_VALID(fetch));
- fctx = fetch->private;
- REQUIRE(VALID_FCTX(fctx));
- res = fctx->res;
-
- FTRACE("destroyfetch");
-
- bucketnum = fctx->bucketnum;
- LOCK(&res->buckets[bucketnum].lock);
-
- /*
- * Sanity check: the caller should have gotten its event before
- * trying to destroy the fetch.
- */
- event = NULL;
- if (fctx->state != fetchstate_done) {
- for (event = ISC_LIST_HEAD(fctx->events);
- event != NULL;
- event = next_event) {
- next_event = ISC_LIST_NEXT(event, ev_link);
- RUNTIME_CHECK(event->fetch != fetch);
- }
- }
-
- bucket_empty = fctx_decreference(fctx);
-
- UNLOCK(&res->buckets[bucketnum].lock);
-
- isc_mem_put(res->mctx, fetch, sizeof(*fetch));
- *fetchp = NULL;
-
- if (bucket_empty)
- empty_bucket(res);
-}
-
-void
-dns_resolver_logfetch(dns_fetch_t *fetch, isc_log_t *lctx,
- isc_logcategory_t *category, isc_logmodule_t *module,
- int level, isc_boolean_t duplicateok)
-{
- fetchctx_t *fctx;
- dns_resolver_t *res;
- char domainbuf[DNS_NAME_FORMATSIZE];
-
- REQUIRE(DNS_FETCH_VALID(fetch));
- fctx = fetch->private;
- REQUIRE(VALID_FCTX(fctx));
- res = fctx->res;
-
- LOCK(&res->buckets[fctx->bucketnum].lock);
-
- INSIST(fctx->exitline >= 0);
- if (!fctx->logged || duplicateok) {
- dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf));
- isc_log_write(lctx, category, module, level,
- "fetch completed at %s:%d for %s in "
- "%" ISC_PRINT_QUADFORMAT "u."
- "%06" ISC_PRINT_QUADFORMAT "u: %s/%s "
- "[domain:%s,referral:%u,restart:%u,qrysent:%u,"
- "timeout:%u,lame:%u,neterr:%u,badresp:%u,"
- "adberr:%u,findfail:%u,valfail:%u]",
- __FILE__, fctx->exitline, fctx->info,
- fctx->duration / US_PER_SEC,
- fctx->duration % US_PER_SEC,
- isc_result_totext(fctx->result),
- isc_result_totext(fctx->vresult), domainbuf,
- fctx->referrals, fctx->restarts,
- fctx->querysent, fctx->timeouts, fctx->lamecount,
- fctx->neterr, fctx->badresp, fctx->adberr,
- fctx->findfail, fctx->valfail);
- fctx->logged = ISC_TRUE;
- }
-
- UNLOCK(&res->buckets[fctx->bucketnum].lock);
-}
-
-dns_dispatchmgr_t *
-dns_resolver_dispatchmgr(dns_resolver_t *resolver) {
- REQUIRE(VALID_RESOLVER(resolver));
- return (resolver->dispatchmgr);
-}
-
-dns_dispatch_t *
-dns_resolver_dispatchv4(dns_resolver_t *resolver) {
- REQUIRE(VALID_RESOLVER(resolver));
- return (dns_dispatchset_get(resolver->dispatches4));
-}
-
-dns_dispatch_t *
-dns_resolver_dispatchv6(dns_resolver_t *resolver) {
- REQUIRE(VALID_RESOLVER(resolver));
- return (dns_dispatchset_get(resolver->dispatches6));
-}
-
-isc_socketmgr_t *
-dns_resolver_socketmgr(dns_resolver_t *resolver) {
- REQUIRE(VALID_RESOLVER(resolver));
- return (resolver->socketmgr);
-}
-
-isc_taskmgr_t *
-dns_resolver_taskmgr(dns_resolver_t *resolver) {
- REQUIRE(VALID_RESOLVER(resolver));
- return (resolver->taskmgr);
-}
-
-isc_uint32_t
-dns_resolver_getlamettl(dns_resolver_t *resolver) {
- REQUIRE(VALID_RESOLVER(resolver));
- return (resolver->lame_ttl);
-}
-
-void
-dns_resolver_setlamettl(dns_resolver_t *resolver, isc_uint32_t lame_ttl) {
- REQUIRE(VALID_RESOLVER(resolver));
- resolver->lame_ttl = lame_ttl;
-}
-
-unsigned int
-dns_resolver_nrunning(dns_resolver_t *resolver) {
- unsigned int n;
- LOCK(&resolver->nlock);
- n = resolver->nfctx;
- UNLOCK(&resolver->nlock);
- return (n);
-}
-
-isc_result_t
-dns_resolver_addalternate(dns_resolver_t *resolver, isc_sockaddr_t *alt,
- dns_name_t *name, in_port_t port) {
- alternate_t *a;
- isc_result_t result;
-
- REQUIRE(VALID_RESOLVER(resolver));
- REQUIRE(!resolver->frozen);
- REQUIRE((alt == NULL) ^ (name == NULL));
-
- a = isc_mem_get(resolver->mctx, sizeof(*a));
- if (a == NULL)
- return (ISC_R_NOMEMORY);
- if (alt != NULL) {
- a->isaddress = ISC_TRUE;
- a->_u.addr = *alt;
- } else {
- a->isaddress = ISC_FALSE;
- a->_u._n.port = port;
- dns_name_init(&a->_u._n.name, NULL);
- result = dns_name_dup(name, resolver->mctx, &a->_u._n.name);
- if (result != ISC_R_SUCCESS) {
- isc_mem_put(resolver->mctx, a, sizeof(*a));
- return (result);
- }
- }
- ISC_LINK_INIT(a, link);
- ISC_LIST_APPEND(resolver->alternates, a, link);
-
- return (ISC_R_SUCCESS);
-}
-
-void
-dns_resolver_setudpsize(dns_resolver_t *resolver, isc_uint16_t udpsize) {
- REQUIRE(VALID_RESOLVER(resolver));
- resolver->udpsize = udpsize;
-}
-
-isc_uint16_t
-dns_resolver_getudpsize(dns_resolver_t *resolver) {
- REQUIRE(VALID_RESOLVER(resolver));
- return (resolver->udpsize);
-}
-
-void
-dns_resolver_flushbadcache(dns_resolver_t *resolver, dns_name_t *name) {
- unsigned int i;
- dns_badcache_t *bad, *prev, *next;
-
- REQUIRE(VALID_RESOLVER(resolver));
-
- LOCK(&resolver->lock);
- if (resolver->badcache == NULL)
- goto unlock;
-
- if (name != NULL) {
- isc_time_t now;
- isc_result_t result;
- result = isc_time_now(&now);
- if (result != ISC_R_SUCCESS)
- isc_time_settoepoch(&now);
- i = dns_name_hash(name, ISC_FALSE) % resolver->badhash;
- prev = NULL;
- for (bad = resolver->badcache[i]; bad != NULL; bad = next) {
- int n;
- next = bad->next;
- n = isc_time_compare(&bad->expire, &now);
- if (n < 0 || dns_name_equal(name, &bad->name)) {
- if (prev == NULL)
- resolver->badcache[i] = bad->next;
- else
- prev->next = bad->next;
- isc_mem_put(resolver->mctx, bad, sizeof(*bad) +
- bad->name.length);
- resolver->badcount--;
- } else
- prev = bad;
- }
- } else
- destroy_badcache(resolver);
-
- unlock:
- UNLOCK(&resolver->lock);
-
-}
-
-static void
-resizehash(dns_resolver_t *resolver, isc_time_t *now, isc_boolean_t grow) {
- unsigned int newsize;
- dns_badcache_t **new, *bad, *next;
- unsigned int i;
-
- if (grow)
- newsize = resolver->badhash * 2 + 1;
- else
- newsize = (resolver->badhash - 1) / 2;
-
- new = isc_mem_get(resolver->mctx,
- sizeof(*resolver->badcache) * newsize);
- if (new == NULL)
- return;
- memset(new, 0, sizeof(*resolver->badcache) * newsize);
- for (i = 0; i < resolver->badhash; i++) {
- for (bad = resolver->badcache[i]; bad != NULL; bad = next) {
- next = bad->next;
- if (isc_time_compare(&bad->expire, now) < 0) {
- isc_mem_put(resolver->mctx, bad, sizeof(*bad) +
- bad->name.length);
- resolver->badcount--;
- } else {
- bad->next = new[bad->hashval % newsize];
- new[bad->hashval % newsize] = bad;
- }
- }
- }
- isc_mem_put(resolver->mctx, resolver->badcache,
- sizeof(*resolver->badcache) * resolver->badhash);
- resolver->badhash = newsize;
- resolver->badcache = new;
-}
-
-void
-dns_resolver_addbadcache(dns_resolver_t *resolver, dns_name_t *name,
- dns_rdatatype_t type, isc_time_t *expire)
-{
- isc_time_t now;
- isc_result_t result = ISC_R_SUCCESS;
- unsigned int i, hashval;
- dns_badcache_t *bad, *prev, *next;
-
- REQUIRE(VALID_RESOLVER(resolver));
-
- LOCK(&resolver->lock);
- if (resolver->badcache == NULL) {
- resolver->badcache = isc_mem_get(resolver->mctx,
- sizeof(*resolver->badcache) *
- DNS_BADCACHE_SIZE);
- if (resolver->badcache == NULL)
- goto cleanup;
- resolver->badhash = DNS_BADCACHE_SIZE;
- memset(resolver->badcache, 0, sizeof(*resolver->badcache) *
- resolver->badhash);
- }
-
- result = isc_time_now(&now);
- if (result != ISC_R_SUCCESS)
- isc_time_settoepoch(&now);
- hashval = dns_name_hash(name, ISC_FALSE);
- i = hashval % resolver->badhash;
- prev = NULL;
- for (bad = resolver->badcache[i]; bad != NULL; bad = next) {
- next = bad->next;
- if (bad->type == type && dns_name_equal(name, &bad->name))
- break;
- if (isc_time_compare(&bad->expire, &now) < 0) {
- if (prev == NULL)
- resolver->badcache[i] = bad->next;
- else
- prev->next = bad->next;
- isc_mem_put(resolver->mctx, bad, sizeof(*bad) +
- bad->name.length);
- resolver->badcount--;
- } else
- prev = bad;
- }
- if (bad == NULL) {
- isc_buffer_t buffer;
- bad = isc_mem_get(resolver->mctx, sizeof(*bad) + name->length);
- if (bad == NULL)
- goto cleanup;
- bad->type = type;
- bad->hashval = hashval;
- bad->expire = *expire;
- isc_buffer_init(&buffer, bad + 1, name->length);
- dns_name_init(&bad->name, NULL);
- dns_name_copy(name, &bad->name, &buffer);
- bad->next = resolver->badcache[i];
- resolver->badcache[i] = bad;
- resolver->badcount++;
- if (resolver->badcount > resolver->badhash * 8)
- resizehash(resolver, &now, ISC_TRUE);
- if (resolver->badcount < resolver->badhash * 2 &&
- resolver->badhash > DNS_BADCACHE_SIZE)
- resizehash(resolver, &now, ISC_FALSE);
- } else
- bad->expire = *expire;
- cleanup:
- UNLOCK(&resolver->lock);
-}
-
-isc_boolean_t
-dns_resolver_getbadcache(dns_resolver_t *resolver, dns_name_t *name,
- dns_rdatatype_t type, isc_time_t *now)
-{
- dns_badcache_t *bad, *prev, *next;
- isc_boolean_t answer = ISC_FALSE;
- unsigned int i;
-
- REQUIRE(VALID_RESOLVER(resolver));
-
- LOCK(&resolver->lock);
- if (resolver->badcache == NULL)
- goto unlock;
-
- i = dns_name_hash(name, ISC_FALSE) % resolver->badhash;
- prev = NULL;
- for (bad = resolver->badcache[i]; bad != NULL; bad = next) {
- next = bad->next;
- /*
- * Search the hash list. Clean out expired records as we go.
- */
- if (isc_time_compare(&bad->expire, now) < 0) {
- if (prev != NULL)
- prev->next = bad->next;
- else
- resolver->badcache[i] = bad->next;
- isc_mem_put(resolver->mctx, bad, sizeof(*bad) +
- bad->name.length);
- resolver->badcount--;
- continue;
- }
- if (bad->type == type && dns_name_equal(name, &bad->name)) {
- answer = ISC_TRUE;
- break;
- }
- prev = bad;
- }
-
- /*
- * Slow sweep to clean out stale records.
- */
- i = resolver->badsweep++ % resolver->badhash;
- bad = resolver->badcache[i];
- if (bad != NULL && isc_time_compare(&bad->expire, now) < 0) {
- resolver->badcache[i] = bad->next;
- isc_mem_put(resolver->mctx, bad, sizeof(*bad) +
- bad->name.length);
- resolver->badcount--;
- }
-
- unlock:
- UNLOCK(&resolver->lock);
- return (answer);
-}
-
-void
-dns_resolver_printbadcache(dns_resolver_t *resolver, FILE *fp) {
- char namebuf[DNS_NAME_FORMATSIZE];
- char typebuf[DNS_RDATATYPE_FORMATSIZE];
- dns_badcache_t *bad, *next, *prev;
- isc_time_t now;
- unsigned int i;
- isc_uint64_t t;
-
- LOCK(&resolver->lock);
- fprintf(fp, ";\n; Bad cache\n;\n");
-
- if (resolver->badcache == NULL)
- goto unlock;
-
- TIME_NOW(&now);
- for (i = 0; i < resolver->badhash; i++) {
- prev = NULL;
- for (bad = resolver->badcache[i]; bad != NULL; bad = next) {
- next = bad->next;
- if (isc_time_compare(&bad->expire, &now) < 0) {
- if (prev != NULL)
- prev->next = bad->next;
- else
- resolver->badcache[i] = bad->next;
- isc_mem_put(resolver->mctx, bad, sizeof(*bad) +
- bad->name.length);
- resolver->badcount--;
- continue;
- }
- prev = bad;
- dns_name_format(&bad->name, namebuf, sizeof(namebuf));
- dns_rdatatype_format(bad->type, typebuf,
- sizeof(typebuf));
- t = isc_time_microdiff(&bad->expire, &now);
- t /= 1000;
- fprintf(fp, "; %s/%s [ttl "
- "%" ISC_PLATFORM_QUADFORMAT "u]\n",
- namebuf, typebuf, t);
- }
- }
-
- unlock:
- UNLOCK(&resolver->lock);
-}
-
-static void
-free_algorithm(void *node, void *arg) {
- unsigned char *algorithms = node;
- isc_mem_t *mctx = arg;
-
- isc_mem_put(mctx, algorithms, *algorithms);
-}
-
-void
-dns_resolver_reset_algorithms(dns_resolver_t *resolver) {
-
- REQUIRE(VALID_RESOLVER(resolver));
-
-#if USE_ALGLOCK
- RWLOCK(&resolver->alglock, isc_rwlocktype_write);
-#endif
- if (resolver->algorithms != NULL)
- dns_rbt_destroy(&resolver->algorithms);
-#if USE_ALGLOCK
- RWUNLOCK(&resolver->alglock, isc_rwlocktype_write);
-#endif
-}
-
-isc_result_t
-dns_resolver_disable_algorithm(dns_resolver_t *resolver, dns_name_t *name,
- unsigned int alg)
-{
- unsigned int len, mask;
- unsigned char *new;
- unsigned char *algorithms;
- isc_result_t result;
- dns_rbtnode_t *node = NULL;
-
- REQUIRE(VALID_RESOLVER(resolver));
- if (alg > 255)
- return (ISC_R_RANGE);
-
-#if USE_ALGLOCK
- RWLOCK(&resolver->alglock, isc_rwlocktype_write);
-#endif
- if (resolver->algorithms == NULL) {
- result = dns_rbt_create(resolver->mctx, free_algorithm,
- resolver->mctx, &resolver->algorithms);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- }
-
- len = alg/8 + 2;
- mask = 1 << (alg%8);
-
- result = dns_rbt_addnode(resolver->algorithms, name, &node);
-
- if (result == ISC_R_SUCCESS || result == ISC_R_EXISTS) {
- algorithms = node->data;
- if (algorithms == NULL || len > *algorithms) {
- new = isc_mem_get(resolver->mctx, len);
- if (new == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup;
- }
- memset(new, 0, len);
- if (algorithms != NULL)
- memcpy(new, algorithms, *algorithms);
- new[len-1] |= mask;
- *new = len;
- node->data = new;
- if (algorithms != NULL)
- isc_mem_put(resolver->mctx, algorithms,
- *algorithms);
- } else
- algorithms[len-1] |= mask;
- }
- result = ISC_R_SUCCESS;
- cleanup:
-#if USE_ALGLOCK
- RWUNLOCK(&resolver->alglock, isc_rwlocktype_write);
-#endif
- return (result);
-}
-
-isc_boolean_t
-dns_resolver_algorithm_supported(dns_resolver_t *resolver, dns_name_t *name,
- unsigned int alg)
-{
- unsigned int len, mask;
- unsigned char *algorithms;
- void *data = NULL;
- isc_result_t result;
- isc_boolean_t found = ISC_FALSE;
-
- REQUIRE(VALID_RESOLVER(resolver));
-
-#if USE_ALGLOCK
- RWLOCK(&resolver->alglock, isc_rwlocktype_read);
-#endif
- if (resolver->algorithms == NULL)
- goto unlock;
- result = dns_rbt_findname(resolver->algorithms, name, 0, NULL, &data);
- if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
- len = alg/8 + 2;
- mask = 1 << (alg%8);
- algorithms = data;
- if (len <= *algorithms && (algorithms[len-1] & mask) != 0)
- found = ISC_TRUE;
- }
- unlock:
-#if USE_ALGLOCK
- RWUNLOCK(&resolver->alglock, isc_rwlocktype_read);
-#endif
- if (found)
- return (ISC_FALSE);
- return (dst_algorithm_supported(alg));
-}
-
-isc_boolean_t
-dns_resolver_digest_supported(dns_resolver_t *resolver, unsigned int digest) {
-
- UNUSED(resolver);
- return (dns_ds_digest_supported(digest));
-}
-
-void
-dns_resolver_resetmustbesecure(dns_resolver_t *resolver) {
-
- REQUIRE(VALID_RESOLVER(resolver));
-
-#if USE_MBSLOCK
- RWLOCK(&resolver->mbslock, isc_rwlocktype_write);
-#endif
- if (resolver->mustbesecure != NULL)
- dns_rbt_destroy(&resolver->mustbesecure);
-#if USE_MBSLOCK
- RWUNLOCK(&resolver->mbslock, isc_rwlocktype_write);
-#endif
-}
-
-static isc_boolean_t yes = ISC_TRUE, no = ISC_FALSE;
-
-isc_result_t
-dns_resolver_setmustbesecure(dns_resolver_t *resolver, dns_name_t *name,
- isc_boolean_t value)
-{
- isc_result_t result;
-
- REQUIRE(VALID_RESOLVER(resolver));
-
-#if USE_MBSLOCK
- RWLOCK(&resolver->mbslock, isc_rwlocktype_write);
-#endif
- if (resolver->mustbesecure == NULL) {
- result = dns_rbt_create(resolver->mctx, NULL, NULL,
- &resolver->mustbesecure);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- }
- result = dns_rbt_addname(resolver->mustbesecure, name,
- value ? &yes : &no);
- cleanup:
-#if USE_MBSLOCK
- RWUNLOCK(&resolver->mbslock, isc_rwlocktype_write);
-#endif
- return (result);
-}
-
-isc_boolean_t
-dns_resolver_getmustbesecure(dns_resolver_t *resolver, dns_name_t *name) {
- void *data = NULL;
- isc_boolean_t value = ISC_FALSE;
- isc_result_t result;
-
- REQUIRE(VALID_RESOLVER(resolver));
-
-#if USE_MBSLOCK
- RWLOCK(&resolver->mbslock, isc_rwlocktype_read);
-#endif
- if (resolver->mustbesecure == NULL)
- goto unlock;
- result = dns_rbt_findname(resolver->mustbesecure, name, 0, NULL, &data);
- if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH)
- value = *(isc_boolean_t*)data;
- unlock:
-#if USE_MBSLOCK
- RWUNLOCK(&resolver->mbslock, isc_rwlocktype_read);
-#endif
- return (value);
-}
-
-void
-dns_resolver_getclientsperquery(dns_resolver_t *resolver, isc_uint32_t *cur,
- isc_uint32_t *min, isc_uint32_t *max)
-{
- REQUIRE(VALID_RESOLVER(resolver));
-
- LOCK(&resolver->lock);
- if (cur != NULL)
- *cur = resolver->spillat;
- if (min != NULL)
- *min = resolver->spillatmin;
- if (max != NULL)
- *max = resolver->spillatmax;
- UNLOCK(&resolver->lock);
-}
-
-void
-dns_resolver_setclientsperquery(dns_resolver_t *resolver, isc_uint32_t min,
- isc_uint32_t max)
-{
- REQUIRE(VALID_RESOLVER(resolver));
-
- LOCK(&resolver->lock);
- resolver->spillatmin = resolver->spillat = min;
- resolver->spillatmax = max;
- UNLOCK(&resolver->lock);
-}
-
-isc_boolean_t
-dns_resolver_getzeronosoattl(dns_resolver_t *resolver) {
- REQUIRE(VALID_RESOLVER(resolver));
-
- return (resolver->zero_no_soa_ttl);
-}
-
-void
-dns_resolver_setzeronosoattl(dns_resolver_t *resolver, isc_boolean_t state) {
- REQUIRE(VALID_RESOLVER(resolver));
-
- resolver->zero_no_soa_ttl = state;
-}
-
-unsigned int
-dns_resolver_getoptions(dns_resolver_t *resolver) {
- REQUIRE(VALID_RESOLVER(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;
- if (seconds < MINIMUM_QUERY_TIMEOUT)
- seconds = MINIMUM_QUERY_TIMEOUT;
-
- resolver->query_timeout = seconds;
-}
diff --git a/contrib/bind9/lib/dns/result.c b/contrib/bind9/lib/dns/result.c
deleted file mode 100644
index 39879532d485..000000000000
--- a/contrib/bind9/lib/dns/result.c
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007-2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <isc/once.h>
-#include <isc/util.h>
-
-#include <dns/result.h>
-#include <dns/lib.h>
-
-static const char *text[DNS_R_NRESULTS] = {
- "label too long", /*%< 0 DNS_R_LABELTOOLONG */
- "bad escape", /*%< 1 DNS_R_BADESCAPE */
- /*!
- * Note that DNS_R_BADBITSTRING and DNS_R_BITSTRINGTOOLONG are
- * deprecated.
- */
- "bad bitstring", /*%< 2 DNS_R_BADBITSTRING */
- "bitstring too long", /*%< 3 DNS_R_BITSTRINGTOOLONG */
- "empty label", /*%< 4 DNS_R_EMPTYLABEL */
-
- "bad dotted quad", /*%< 5 DNS_R_BADDOTTEDQUAD */
- "invalid NS owner name (wildcard)", /*%< 6 DNS_R_INVALIDNS */
- "unknown class/type", /*%< 7 DNS_R_UNKNOWN */
- "bad label type", /*%< 8 DNS_R_BADLABELTYPE */
- "bad compression pointer", /*%< 9 DNS_R_BADPOINTER */
-
- "too many hops", /*%< 10 DNS_R_TOOMANYHOPS */
- "disallowed (by application policy)", /*%< 11 DNS_R_DISALLOWED */
- "extra input text", /*%< 12 DNS_R_EXTRATOKEN */
- "extra input data", /*%< 13 DNS_R_EXTRADATA */
- "text too long", /*%< 14 DNS_R_TEXTTOOLONG */
-
- "not at top of zone", /*%< 15 DNS_R_NOTZONETOP */
- "syntax error", /*%< 16 DNS_R_SYNTAX */
- "bad checksum", /*%< 17 DNS_R_BADCKSUM */
- "bad IPv6 address", /*%< 18 DNS_R_BADAAAA */
- "no owner", /*%< 19 DNS_R_NOOWNER */
-
- "no ttl", /*%< 20 DNS_R_NOTTL */
- "bad class", /*%< 21 DNS_R_BADCLASS */
- "name too long", /*%< 22 DNS_R_NAMETOOLONG */
- "partial match", /*%< 23 DNS_R_PARTIALMATCH */
- "new origin", /*%< 24 DNS_R_NEWORIGIN */
-
- "unchanged", /*%< 25 DNS_R_UNCHANGED */
- "bad ttl", /*%< 26 DNS_R_BADTTL */
- "more data needed/to be rendered", /*%< 27 DNS_R_NOREDATA */
- "continue", /*%< 28 DNS_R_CONTINUE */
- "delegation", /*%< 29 DNS_R_DELEGATION */
-
- "glue", /*%< 30 DNS_R_GLUE */
- "dname", /*%< 31 DNS_R_DNAME */
- "cname", /*%< 32 DNS_R_CNAME */
- "bad database", /*%< 33 DNS_R_BADDB */
- "zonecut", /*%< 34 DNS_R_ZONECUT */
-
- "bad zone", /*%< 35 DNS_R_BADZONE */
- "more data", /*%< 36 DNS_R_MOREDATA */
- "up to date", /*%< 37 DNS_R_UPTODATE */
- "tsig verify failure", /*%< 38 DNS_R_TSIGVERIFYFAILURE */
- "tsig indicates error", /*%< 39 DNS_R_TSIGERRORSET */
-
- "RRSIG failed to verify", /*%< 40 DNS_R_SIGINVALID */
- "RRSIG has expired", /*%< 41 DNS_R_SIGEXPIRED */
- "RRSIG validity period has not begun", /*%< 42 DNS_R_SIGFUTURE */
- "key is unauthorized to sign data", /*%< 43 DNS_R_KEYUNAUTHORIZED */
- "invalid time", /*%< 44 DNS_R_INVALIDTIME */
-
- "expected a TSIG or SIG(0)", /*%< 45 DNS_R_EXPECTEDTSIG */
- "did not expect a TSIG or SIG(0)", /*%< 46 DNS_R_UNEXPECTEDTSIG */
- "TKEY is unacceptable", /*%< 47 DNS_R_INVALIDTKEY */
- "hint", /*%< 48 DNS_R_HINT */
- "drop", /*%< 49 DNS_R_DROP */
-
- "zone not loaded", /*%< 50 DNS_R_NOTLOADED */
- "ncache nxdomain", /*%< 51 DNS_R_NCACHENXDOMAIN */
- "ncache nxrrset", /*%< 52 DNS_R_NCACHENXRRSET */
- "wait", /*%< 53 DNS_R_WAIT */
- "not verified yet", /*%< 54 DNS_R_NOTVERIFIEDYET */
-
- "no identity", /*%< 55 DNS_R_NOIDENTITY */
- "no journal", /*%< 56 DNS_R_NOJOURNAL */
- "alias", /*%< 57 DNS_R_ALIAS */
- "use TCP", /*%< 58 DNS_R_USETCP */
- "no valid RRSIG", /*%< 59 DNS_R_NOVALIDSIG */
-
- "no valid NSEC", /*%< 60 DNS_R_NOVALIDNSEC */
- "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 */
-
- "unexpected message id", /*%< 65 DNS_R_UNEXPECTEDID */
- "seen include file", /*%< 66 DNS_R_SEENINCLUDE */
- "not exact", /*%< 67 DNS_R_NOTEXACT */
- "address blackholed", /*%< 68 DNS_R_BLACKHOLED */
- "bad algorithm", /*%< 69 DNS_R_BADALG */
-
- "invalid use of a meta type", /*%< 70 DNS_R_METATYPE */
- "CNAME and other data", /*%< 71 DNS_R_CNAMEANDOTHER */
- "multiple RRs of singleton type", /*%< 72 DNS_R_SINGLETON */
- "hint nxrrset", /*%< 73 DNS_R_HINTNXRRSET */
- "no master file configured", /*%< 74 DNS_R_NOMASTERFILE */
-
- "unknown protocol", /*%< 75 DNS_R_UNKNOWNPROTO */
- "clocks are unsynchronized", /*%< 76 DNS_R_CLOCKSKEW */
- "IXFR failed", /*%< 77 DNS_R_BADIXFR */
- "not authoritative", /*%< 78 DNS_R_NOTAUTHORITATIVE */
- "no valid KEY", /*%< 79 DNS_R_NOVALIDKEY */
-
- "obsolete", /*%< 80 DNS_R_OBSOLETE */
- "already frozen", /*%< 81 DNS_R_FROZEN */
- "unknown flag", /*%< 82 DNS_R_UNKNOWNFLAG */
- "expected a response", /*%< 83 DNS_R_EXPECTEDRESPONSE */
- "no valid DS", /*%< 84 DNS_R_NOVALIDDS */
-
- "NS is an address", /*%< 85 DNS_R_NSISADDRESS */
- "received FORMERR", /*%< 86 DNS_R_REMOTEFORMERR */
- "truncated TCP response", /*%< 87 DNS_R_TRUNCATEDTCP */
- "lame server detected", /*%< 88 DNS_R_LAME */
- "unexpected RCODE", /*%< 89 DNS_R_UNEXPECTEDRCODE */
-
- "unexpected OPCODE", /*%< 90 DNS_R_UNEXPECTEDOPCODE */
- "chase DS servers", /*%< 91 DNS_R_CHASEDSSERVERS */
- "empty name", /*%< 92 DNS_R_EMPTYNAME */
- "empty wild", /*%< 93 DNS_R_EMPTYWILD */
- "bad bitmap", /*%< 94 DNS_R_BADBITMAP */
-
- "from wildcard", /*%< 95 DNS_R_FROMWILDCARD */
- "bad owner name (check-names)", /*%< 96 DNS_R_BADOWNERNAME */
- "bad name (check-names)", /*%< 97 DNS_R_BADNAME */
- "dynamic zone", /*%< 98 DNS_R_DYNAMIC */
- "unknown command", /*%< 99 DNS_R_UNKNOWNCOMMAND */
-
- "must-be-secure", /*%< 100 DNS_R_MUSTBESECURE */
- "covering NSEC record returned", /*%< 101 DNS_R_COVERINGNSEC */
- "MX is an address", /*%< 102 DNS_R_MXISADDRESS */
- "duplicate query", /*%< 103 DNS_R_DUPLICATE */
- "invalid NSEC3 owner name (wildcard)", /*%< 104 DNS_R_INVALIDNSEC3 */
-
- "not master", /*%< 105 DNS_R_NOTMASTER */
- "broken trust chain", /*%< 106 DNS_R_BROKENCHAIN */
- "expired", /*%< 107 DNS_R_EXPIRED */
- "not dynamic", /*%< 108 DNS_R_NOTDYNAMIC */
- "bad EUI" /*%< 109 DNS_R_BADEUI */
-};
-
-static const char *rcode_text[DNS_R_NRCODERESULTS] = {
- "NOERROR", /*%< 0 DNS_R_NOEROR */
- "FORMERR", /*%< 1 DNS_R_FORMERR */
- "SERVFAIL", /*%< 2 DNS_R_SERVFAIL */
- "NXDOMAIN", /*%< 3 DNS_R_NXDOMAIN */
- "NOTIMP", /*%< 4 DNS_R_NOTIMP */
-
- "REFUSED", /*%< 5 DNS_R_REFUSED */
- "YXDOMAIN", /*%< 6 DNS_R_YXDOMAIN */
- "YXRRSET", /*%< 7 DNS_R_YXRRSET */
- "NXRRSET", /*%< 8 DNS_R_NXRRSET */
- "NOTAUTH", /*%< 9 DNS_R_NOTAUTH */
-
- "NOTZONE", /*%< 10 DNS_R_NOTZONE */
- "<rcode 11>", /*%< 11 has no macro */
- "<rcode 12>", /*%< 12 has no macro */
- "<rcode 13>", /*%< 13 has no macro */
- "<rcode 14>", /*%< 14 has no macro */
-
- "<rcode 15>", /*%< 15 has no macro */
- "BADVERS", /*%< 16 DNS_R_BADVERS */
-};
-
-#define DNS_RESULT_RESULTSET 2
-#define DNS_RESULT_RCODERESULTSET 3
-
-static isc_once_t once = ISC_ONCE_INIT;
-
-static void
-initialize_action(void) {
- isc_result_t result;
-
- result = isc_result_register(ISC_RESULTCLASS_DNS, DNS_R_NRESULTS,
- text, dns_msgcat, DNS_RESULT_RESULTSET);
- if (result == ISC_R_SUCCESS)
- result = isc_result_register(ISC_RESULTCLASS_DNSRCODE,
- DNS_R_NRCODERESULTS,
- rcode_text, dns_msgcat,
- DNS_RESULT_RCODERESULTSET);
- if (result != ISC_R_SUCCESS)
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_result_register() failed: %u", result);
-}
-
-static void
-initialize(void) {
- dns_lib_initmsgcat();
- RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
-}
-
-const char *
-dns_result_totext(isc_result_t result) {
- initialize();
-
- return (isc_result_totext(result));
-}
-
-void
-dns_result_register(void) {
- initialize();
-}
-
-dns_rcode_t
-dns_result_torcode(isc_result_t result) {
- dns_rcode_t rcode = dns_rcode_servfail;
-
- if (DNS_RESULT_ISRCODE(result)) {
- /*
- * Rcodes can't be bigger than 12 bits, which is why we
- * AND with 0xFFF instead of 0xFFFF.
- */
- return ((dns_rcode_t)((result) & 0xFFF));
- }
- /*
- * Try to supply an appropriate rcode.
- */
- switch (result) {
- case ISC_R_SUCCESS:
- rcode = dns_rcode_noerror;
- break;
- case ISC_R_BADBASE64:
- case ISC_R_NOSPACE:
- case ISC_R_RANGE:
- case ISC_R_UNEXPECTEDEND:
- case DNS_R_BADAAAA:
- /* case DNS_R_BADBITSTRING: deprecated */
- case DNS_R_BADCKSUM:
- case DNS_R_BADCLASS:
- case DNS_R_BADLABELTYPE:
- case DNS_R_BADPOINTER:
- case DNS_R_BADTTL:
- case DNS_R_BADZONE:
- /* case DNS_R_BITSTRINGTOOLONG: deprecated */
- case DNS_R_EXTRADATA:
- case DNS_R_LABELTOOLONG:
- case DNS_R_NOREDATA:
- case DNS_R_SYNTAX:
- case DNS_R_TEXTTOOLONG:
- case DNS_R_TOOMANYHOPS:
- case DNS_R_TSIGERRORSET:
- case DNS_R_UNKNOWN:
- case DNS_R_NAMETOOLONG:
- rcode = dns_rcode_formerr;
- break;
- case DNS_R_DISALLOWED:
- rcode = dns_rcode_refused;
- break;
- case DNS_R_TSIGVERIFYFAILURE:
- case DNS_R_CLOCKSKEW:
- rcode = dns_rcode_notauth;
- break;
- default:
- rcode = dns_rcode_servfail;
- }
-
- return (rcode);
-}
diff --git a/contrib/bind9/lib/dns/rootns.c b/contrib/bind9/lib/dns/rootns.c
deleted file mode 100644
index 3502022c2ae1..000000000000
--- a/contrib/bind9/lib/dns/rootns.c
+++ /dev/null
@@ -1,528 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007, 2008, 2010, 2012, 2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2002 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: rootns.c,v 1.40 2010/06/18 05:36:24 marka Exp $ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <isc/buffer.h>
-#include <isc/string.h> /* Required for HP/UX (and others?) */
-#include <isc/util.h>
-
-#include <dns/callbacks.h>
-#include <dns/db.h>
-#include <dns/dbiterator.h>
-#include <dns/fixedname.h>
-#include <dns/log.h>
-#include <dns/master.h>
-#include <dns/rdata.h>
-#include <dns/rdata.h>
-#include <dns/rdataset.h>
-#include <dns/rdatasetiter.h>
-#include <dns/rdatastruct.h>
-#include <dns/rdatatype.h>
-#include <dns/result.h>
-#include <dns/rootns.h>
-#include <dns/view.h>
-
-static char root_ns[] =
-";\n"
-"; Internet Root Nameservers\n"
-";\n"
-"$TTL 518400\n"
-". 518400 IN NS A.ROOT-SERVERS.NET.\n"
-". 518400 IN NS B.ROOT-SERVERS.NET.\n"
-". 518400 IN NS C.ROOT-SERVERS.NET.\n"
-". 518400 IN NS D.ROOT-SERVERS.NET.\n"
-". 518400 IN NS E.ROOT-SERVERS.NET.\n"
-". 518400 IN NS F.ROOT-SERVERS.NET.\n"
-". 518400 IN NS G.ROOT-SERVERS.NET.\n"
-". 518400 IN NS H.ROOT-SERVERS.NET.\n"
-". 518400 IN NS I.ROOT-SERVERS.NET.\n"
-". 518400 IN NS J.ROOT-SERVERS.NET.\n"
-". 518400 IN NS K.ROOT-SERVERS.NET.\n"
-". 518400 IN NS L.ROOT-SERVERS.NET.\n"
-". 518400 IN NS M.ROOT-SERVERS.NET.\n"
-"A.ROOT-SERVERS.NET. 3600000 IN A 198.41.0.4\n"
-"A.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:503:BA3E::2:30\n"
-"B.ROOT-SERVERS.NET. 3600000 IN A 192.228.79.201\n"
-"C.ROOT-SERVERS.NET. 3600000 IN A 192.33.4.12\n"
-"D.ROOT-SERVERS.NET. 3600000 IN A 199.7.91.13\n"
-"D.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:500:2d::d\n"
-"E.ROOT-SERVERS.NET. 3600000 IN A 192.203.230.10\n"
-"F.ROOT-SERVERS.NET. 3600000 IN A 192.5.5.241\n"
-"F.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:500:2F::F\n"
-"G.ROOT-SERVERS.NET. 3600000 IN A 192.112.36.4\n"
-"H.ROOT-SERVERS.NET. 3600000 IN A 128.63.2.53\n"
-"H.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:500:1::803F:235\n"
-"I.ROOT-SERVERS.NET. 3600000 IN A 192.36.148.17\n"
-"I.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:7fe::53\n"
-"J.ROOT-SERVERS.NET. 3600000 IN A 192.58.128.30\n"
-"J.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:503:C27::2:30\n"
-"K.ROOT-SERVERS.NET. 3600000 IN A 193.0.14.129\n"
-"K.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:7FD::1\n"
-"L.ROOT-SERVERS.NET. 3600000 IN A 199.7.83.42\n"
-"L.ROOT-SERVERS.NET. 604800 IN AAAA 2001:500:3::42\n"
-"M.ROOT-SERVERS.NET. 3600000 IN A 202.12.27.33\n"
-"M.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:DC3::35\n";
-
-static isc_result_t
-in_rootns(dns_rdataset_t *rootns, dns_name_t *name) {
- isc_result_t result;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdata_ns_t ns;
-
- if (!dns_rdataset_isassociated(rootns))
- return (ISC_R_NOTFOUND);
-
- result = dns_rdataset_first(rootns);
- while (result == ISC_R_SUCCESS) {
- dns_rdataset_current(rootns, &rdata);
- result = dns_rdata_tostruct(&rdata, &ns, NULL);
- if (result != ISC_R_SUCCESS)
- return (result);
- if (dns_name_compare(name, &ns.name) == 0)
- return (ISC_R_SUCCESS);
- result = dns_rdataset_next(rootns);
- dns_rdata_reset(&rdata);
- }
- if (result == ISC_R_NOMORE)
- result = ISC_R_NOTFOUND;
- return (result);
-}
-
-static isc_result_t
-check_node(dns_rdataset_t *rootns, dns_name_t *name,
- dns_rdatasetiter_t *rdsiter) {
- isc_result_t result;
- dns_rdataset_t rdataset;
-
- dns_rdataset_init(&rdataset);
- result = dns_rdatasetiter_first(rdsiter);
- while (result == ISC_R_SUCCESS) {
- dns_rdatasetiter_current(rdsiter, &rdataset);
- switch (rdataset.type) {
- case dns_rdatatype_a:
- case dns_rdatatype_aaaa:
- result = in_rootns(rootns, name);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- break;
- case dns_rdatatype_ns:
- if (dns_name_compare(name, dns_rootname) == 0)
- break;
- /*FALLTHROUGH*/
- default:
- result = ISC_R_FAILURE;
- goto cleanup;
- }
- dns_rdataset_disassociate(&rdataset);
- result = dns_rdatasetiter_next(rdsiter);
- }
- if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
- cleanup:
- if (dns_rdataset_isassociated(&rdataset))
- dns_rdataset_disassociate(&rdataset);
- return (result);
-}
-
-static isc_result_t
-check_hints(dns_db_t *db) {
- isc_result_t result;
- dns_rdataset_t rootns;
- dns_dbiterator_t *dbiter = NULL;
- dns_dbnode_t *node = NULL;
- isc_stdtime_t now;
- dns_fixedname_t fixname;
- dns_name_t *name;
- dns_rdatasetiter_t *rdsiter = NULL;
-
- isc_stdtime_get(&now);
-
- dns_fixedname_init(&fixname);
- name = dns_fixedname_name(&fixname);
-
- dns_rdataset_init(&rootns);
- (void)dns_db_find(db, dns_rootname, NULL, dns_rdatatype_ns, 0,
- now, NULL, name, &rootns, NULL);
- result = dns_db_createiterator(db, 0, &dbiter);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- result = dns_dbiterator_first(dbiter);
- while (result == ISC_R_SUCCESS) {
- result = dns_dbiterator_current(dbiter, &node, name);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- result = dns_db_allrdatasets(db, node, NULL, now, &rdsiter);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- result = check_node(&rootns, name, rdsiter);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- dns_rdatasetiter_destroy(&rdsiter);
- dns_db_detachnode(db, &node);
- result = dns_dbiterator_next(dbiter);
- }
- if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
-
- cleanup:
- if (dns_rdataset_isassociated(&rootns))
- dns_rdataset_disassociate(&rootns);
- if (rdsiter != NULL)
- dns_rdatasetiter_destroy(&rdsiter);
- if (node != NULL)
- dns_db_detachnode(db, &node);
- if (dbiter != NULL)
- dns_dbiterator_destroy(&dbiter);
- return (result);
-}
-
-isc_result_t
-dns_rootns_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
- const char *filename, dns_db_t **target)
-{
- isc_result_t result, eresult;
- isc_buffer_t source;
- size_t len;
- dns_rdatacallbacks_t callbacks;
- dns_db_t *db = NULL;
-
- REQUIRE(target != NULL && *target == NULL);
-
- result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone,
- rdclass, 0, NULL, &db);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- dns_rdatacallbacks_init(&callbacks);
-
- len = strlen(root_ns);
- isc_buffer_init(&source, root_ns, len);
- isc_buffer_add(&source, len);
-
- result = dns_db_beginload(db, &callbacks.add,
- &callbacks.add_private);
- if (result != ISC_R_SUCCESS)
- return (result);
- if (filename != NULL) {
- /*
- * Load the hints from the specified filename.
- */
- result = dns_master_loadfile(filename, &db->origin,
- &db->origin, db->rdclass,
- DNS_MASTER_HINT,
- &callbacks, db->mctx);
- } else if (rdclass == dns_rdataclass_in) {
- /*
- * Default to using the Internet root servers.
- */
- result = dns_master_loadbuffer(&source, &db->origin,
- &db->origin, db->rdclass,
- DNS_MASTER_HINT,
- &callbacks, db->mctx);
- } else
- result = ISC_R_NOTFOUND;
- eresult = dns_db_endload(db, &callbacks.add_private);
- if (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE)
- result = eresult;
- if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE)
- goto db_detach;
- if (check_hints(db) != ISC_R_SUCCESS)
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
- DNS_LOGMODULE_HINTS, ISC_LOG_WARNING,
- "extra data in root hints '%s'",
- (filename != NULL) ? filename : "<BUILT-IN>");
- *target = db;
- return (ISC_R_SUCCESS);
-
- db_detach:
- dns_db_detach(&db);
-
- return (result);
-}
-
-static void
-report(dns_view_t *view, dns_name_t *name, isc_boolean_t missing,
- dns_rdata_t *rdata)
-{
- const char *viewname = "", *sep = "";
- char namebuf[DNS_NAME_FORMATSIZE];
- char typebuf[DNS_RDATATYPE_FORMATSIZE];
- char databuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:123.123.123.123")];
- isc_buffer_t buffer;
- isc_result_t result;
-
- if (strcmp(view->name, "_bind") != 0 &&
- strcmp(view->name, "_default") != 0) {
- viewname = view->name;
- sep = ": view ";
- }
-
- dns_name_format(name, namebuf, sizeof(namebuf));
- dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
- isc_buffer_init(&buffer, databuf, sizeof(databuf) - 1);
- result = dns_rdata_totext(rdata, NULL, &buffer);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- databuf[isc_buffer_usedlength(&buffer)] = '\0';
-
- if (missing)
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
- DNS_LOGMODULE_HINTS, ISC_LOG_WARNING,
- "checkhints%s%s: %s/%s (%s) missing from hints",
- sep, viewname, namebuf, typebuf, databuf);
- else
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
- DNS_LOGMODULE_HINTS, ISC_LOG_WARNING,
- "checkhints%s%s: %s/%s (%s) extra record "
- "in hints", sep, viewname, namebuf, typebuf,
- databuf);
-}
-
-static isc_boolean_t
-inrrset(dns_rdataset_t *rrset, dns_rdata_t *rdata) {
- isc_result_t result;
- dns_rdata_t current = DNS_RDATA_INIT;
-
- result = dns_rdataset_first(rrset);
- while (result == ISC_R_SUCCESS) {
- dns_rdataset_current(rrset, &current);
- if (dns_rdata_compare(rdata, &current) == 0)
- return (ISC_TRUE);
- dns_rdata_reset(&current);
- result = dns_rdataset_next(rrset);
- }
- return (ISC_FALSE);
-}
-
-/*
- * Check that the address RRsets match.
- *
- * Note we don't complain about missing glue records.
- */
-
-static void
-check_address_records(dns_view_t *view, dns_db_t *hints, dns_db_t *db,
- dns_name_t *name, isc_stdtime_t now)
-{
- isc_result_t hresult, rresult, result;
- dns_rdataset_t hintrrset, rootrrset;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_name_t *foundname;
- dns_fixedname_t fixed;
-
- dns_rdataset_init(&hintrrset);
- dns_rdataset_init(&rootrrset);
- dns_fixedname_init(&fixed);
- foundname = dns_fixedname_name(&fixed);
-
- hresult = dns_db_find(hints, name, NULL, dns_rdatatype_a, 0,
- now, NULL, foundname, &hintrrset, NULL);
- rresult = dns_db_find(db, name, NULL, dns_rdatatype_a,
- DNS_DBFIND_GLUEOK, now, NULL, foundname,
- &rootrrset, NULL);
- if (hresult == ISC_R_SUCCESS &&
- (rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) {
- result = dns_rdataset_first(&rootrrset);
- while (result == ISC_R_SUCCESS) {
- dns_rdata_reset(&rdata);
- dns_rdataset_current(&rootrrset, &rdata);
- if (!inrrset(&hintrrset, &rdata))
- report(view, name, ISC_TRUE, &rdata);
- result = dns_rdataset_next(&rootrrset);
- }
- result = dns_rdataset_first(&hintrrset);
- while (result == ISC_R_SUCCESS) {
- dns_rdata_reset(&rdata);
- dns_rdataset_current(&hintrrset, &rdata);
- if (!inrrset(&rootrrset, &rdata))
- report(view, name, ISC_FALSE, &rdata);
- result = dns_rdataset_next(&hintrrset);
- }
- }
- if (hresult == ISC_R_NOTFOUND &&
- (rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) {
- result = dns_rdataset_first(&rootrrset);
- while (result == ISC_R_SUCCESS) {
- dns_rdata_reset(&rdata);
- dns_rdataset_current(&rootrrset, &rdata);
- report(view, name, ISC_TRUE, &rdata);
- result = dns_rdataset_next(&rootrrset);
- }
- }
- if (dns_rdataset_isassociated(&rootrrset))
- dns_rdataset_disassociate(&rootrrset);
- if (dns_rdataset_isassociated(&hintrrset))
- dns_rdataset_disassociate(&hintrrset);
-
- /*
- * Check AAAA records.
- */
- hresult = dns_db_find(hints, name, NULL, dns_rdatatype_aaaa, 0,
- now, NULL, foundname, &hintrrset, NULL);
- rresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
- DNS_DBFIND_GLUEOK, now, NULL, foundname,
- &rootrrset, NULL);
- if (hresult == ISC_R_SUCCESS &&
- (rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) {
- result = dns_rdataset_first(&rootrrset);
- while (result == ISC_R_SUCCESS) {
- dns_rdata_reset(&rdata);
- dns_rdataset_current(&rootrrset, &rdata);
- if (!inrrset(&hintrrset, &rdata))
- report(view, name, ISC_TRUE, &rdata);
- dns_rdata_reset(&rdata);
- result = dns_rdataset_next(&rootrrset);
- }
- result = dns_rdataset_first(&hintrrset);
- while (result == ISC_R_SUCCESS) {
- dns_rdata_reset(&rdata);
- dns_rdataset_current(&hintrrset, &rdata);
- if (!inrrset(&rootrrset, &rdata))
- report(view, name, ISC_FALSE, &rdata);
- dns_rdata_reset(&rdata);
- result = dns_rdataset_next(&hintrrset);
- }
- }
- if (hresult == ISC_R_NOTFOUND &&
- (rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) {
- result = dns_rdataset_first(&rootrrset);
- while (result == ISC_R_SUCCESS) {
- dns_rdata_reset(&rdata);
- dns_rdataset_current(&rootrrset, &rdata);
- report(view, name, ISC_TRUE, &rdata);
- dns_rdata_reset(&rdata);
- result = dns_rdataset_next(&rootrrset);
- }
- }
- if (dns_rdataset_isassociated(&rootrrset))
- dns_rdataset_disassociate(&rootrrset);
- if (dns_rdataset_isassociated(&hintrrset))
- dns_rdataset_disassociate(&hintrrset);
-}
-
-void
-dns_root_checkhints(dns_view_t *view, dns_db_t *hints, dns_db_t *db) {
- isc_result_t result;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdata_ns_t ns;
- dns_rdataset_t hintns, rootns;
- const char *viewname = "", *sep = "";
- isc_stdtime_t now;
- dns_name_t *name;
- dns_fixedname_t fixed;
-
- REQUIRE(hints != NULL);
- REQUIRE(db != NULL);
- REQUIRE(view != NULL);
-
- isc_stdtime_get(&now);
-
- if (strcmp(view->name, "_bind") != 0 &&
- strcmp(view->name, "_default") != 0) {
- viewname = view->name;
- sep = ": view ";
- }
-
- dns_rdataset_init(&hintns);
- dns_rdataset_init(&rootns);
- dns_fixedname_init(&fixed);
- name = dns_fixedname_name(&fixed);
-
- result = dns_db_find(hints, dns_rootname, NULL, dns_rdatatype_ns, 0,
- now, NULL, name, &hintns, NULL);
- if (result != ISC_R_SUCCESS) {
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
- DNS_LOGMODULE_HINTS, ISC_LOG_WARNING,
- "checkhints%s%s: unable to get root NS rrset "
- "from hints: %s", sep, viewname,
- dns_result_totext(result));
- goto cleanup;
- }
-
- result = dns_db_find(db, dns_rootname, NULL, dns_rdatatype_ns, 0,
- now, NULL, name, &rootns, NULL);
- if (result != ISC_R_SUCCESS) {
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
- DNS_LOGMODULE_HINTS, ISC_LOG_WARNING,
- "checkhints%s%s: unable to get root NS rrset "
- "from cache: %s", sep, viewname,
- dns_result_totext(result));
- goto cleanup;
- }
-
- /*
- * Look for missing root NS names.
- */
- result = dns_rdataset_first(&rootns);
- while (result == ISC_R_SUCCESS) {
- dns_rdataset_current(&rootns, &rdata);
- result = dns_rdata_tostruct(&rdata, &ns, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- result = in_rootns(&hintns, &ns.name);
- if (result != ISC_R_SUCCESS) {
- char namebuf[DNS_NAME_FORMATSIZE];
- /* missing from hints */
- dns_name_format(&ns.name, namebuf, sizeof(namebuf));
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
- DNS_LOGMODULE_HINTS, ISC_LOG_WARNING,
- "checkhints%s%s: unable to find root "
- "NS '%s' in hints", sep, viewname,
- namebuf);
- } else
- check_address_records(view, hints, db, &ns.name, now);
- dns_rdata_reset(&rdata);
- result = dns_rdataset_next(&rootns);
- }
- if (result != ISC_R_NOMORE) {
- goto cleanup;
- }
-
- /*
- * Look for extra root NS names.
- */
- result = dns_rdataset_first(&hintns);
- while (result == ISC_R_SUCCESS) {
- dns_rdataset_current(&hintns, &rdata);
- result = dns_rdata_tostruct(&rdata, &ns, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- result = in_rootns(&rootns, &ns.name);
- if (result != ISC_R_SUCCESS) {
- char namebuf[DNS_NAME_FORMATSIZE];
- /* extra entry in hints */
- dns_name_format(&ns.name, namebuf, sizeof(namebuf));
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
- DNS_LOGMODULE_HINTS, ISC_LOG_WARNING,
- "checkhints%s%s: extra NS '%s' in hints",
- sep, viewname, namebuf);
- }
- dns_rdata_reset(&rdata);
- result = dns_rdataset_next(&hintns);
- }
- if (result != ISC_R_NOMORE) {
- goto cleanup;
- }
-
- cleanup:
- if (dns_rdataset_isassociated(&rootns))
- dns_rdataset_disassociate(&rootns);
- if (dns_rdataset_isassociated(&hintns))
- dns_rdataset_disassociate(&hintns);
-}
diff --git a/contrib/bind9/lib/dns/rpz.c b/contrib/bind9/lib/dns/rpz.c
deleted file mode 100644
index 2d689e7ba128..000000000000
--- a/contrib/bind9/lib/dns/rpz.c
+++ /dev/null
@@ -1,1192 +0,0 @@
-/*
- * Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-
-/*! \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 have_nsdname; /* zone has NSDNAME record */
- dns_rpz_cidr_node_t *root;
- dns_name_t ip_name; /* RPZ_IP_ZONE.origin. */
- dns_name_t nsip_name; /* RPZ_NSIP_ZONE.origin. */
- dns_name_t nsdname_name; /* RPZ_NSDNAME_ZONE.origin */
-};
-
-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 rpz 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, "disabled"))
- return (DNS_RPZ_POLICY_DISABLED);
- if (!strcasecmp(str, "passthru"))
- return (DNS_RPZ_POLICY_PASSTHRU);
- 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);
- /*
- * Obsolete
- */
- if (!strcasecmp(str, "no-op"))
- return (DNS_RPZ_POLICY_PASSTHRU);
- return (DNS_RPZ_POLICY_ERROR);
-}
-
-const char *
-dns_rpz_policy2str(dns_rpz_policy_t policy) {
- const char *str;
-
- switch (policy) {
- case DNS_RPZ_POLICY_PASSTHRU:
- str = "PASSTHRU";
- break;
- case DNS_RPZ_POLICY_NXDOMAIN:
- str = "NXDOMAIN";
- break;
- case DNS_RPZ_POLICY_NODATA:
- str = "NODATA";
- break;
- case DNS_RPZ_POLICY_RECORD:
- str = "Local-Data";
- break;
- case DNS_RPZ_POLICY_CNAME:
- case DNS_RPZ_POLICY_WILDCNAME:
- str = "CNAME";
- break;
- default:
- str = "";
- POST(str);
- INSIST(0);
- }
- return (str);
-}
-
-/*
- * 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->passthru))
- dns_name_free(&zone->passthru, 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));
- }
-}
-
-/*
- * 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);
-
- 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_get(dns_rpz_cidr_t *cidr, dns_rpz_st_t *st) {
- if (cidr == NULL)
- return;
- 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->have_nsdname)
- st->state |= DNS_RPZ_HAVE_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 *str1, const char *str2) {
- char printname[DNS_NAME_FORMATSIZE];
-
- /*
- * bin/tests/system/rpz/tests.sh looks for "invalid rpz".
- */
- if (level < DNS_RPZ_DEBUG_QUIET
- && isc_log_wouldlog(dns_lctx, level)) {
- dns_name_format(name, printname, sizeof(printname));
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
- DNS_LOGMODULE_RBTDB, level,
- "invalid rpz IP address \"%s\"%s%s",
- printname, str1, str2);
- }
-}
-
-/*
- * 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_result_t result;
- dns_fixedname_t fname;
- dns_name_t *ipname;
- char ipstr[DNS_NAME_FORMATSIZE];
- const char *prefix_str, *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
- */
- dns_fixedname_init(&fname);
- ipname = dns_fixedname_name(&fname);
- dns_name_split(src_name, dns_name_countlabels(&cidr->ip_name),
- ipname, NULL);
- dns_name_format(ipname, ipstr, sizeof(ipstr));
- end = &ipstr[strlen(ipstr)+1];
- prefix_str = ipstr;
-
- prefix = strtoul(prefix_str, &cp2, 10);
- if (*cp2 != '.') {
- badname(level, src_name,
- "; invalid leading prefix length", "");
- return (ISC_R_FAILURE);
- }
- *cp2 = '\0';
- if (prefix < 1U || prefix > 128U) {
- badname(level, src_name,
- "; invalid prefix length of ", prefix_str);
- return (ISC_R_FAILURE);
- }
- cp = cp2+1;
-
- 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,
- "; invalid IPv4 prefix length of ", prefix_str);
- 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')) {
- if (*cp2 == '.')
- *cp2 = '\0';
- badname(level, src_name,
- "; invalid IPv4 octet ", cp);
- 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')) {
- if (*cp2 == '.')
- *cp2 = '\0';
- badname(level, src_name,
- "; invalid IPv6 word ", cp);
- 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,
- "; too small prefix length of ", prefix_str);
- return (ISC_R_FAILURE);
- }
- bits -= i;
- bits += DNS_RPZ_CIDR_WORD_BITS;
- }
-
- /*
- * Convert the address back to a canonical policy domain name
- * to ensure that it is in canonical form.
- */
- result = ip2name(cidr, tgt_ip, (dns_rpz_cidr_bits_t) prefix,
- type, NULL, ipname);
- if (result != ISC_R_SUCCESS || !dns_name_equal(src_name, ipname)) {
- 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;
-
- bit = DNS_RPZ_CIDR_WORD_BITS-1;
- if ((w & 0xffff0000) != 0) {
- w >>= 16;
- bit -= 16;
- }
- if ((w & 0xff00) != 0) {
- w >>= 8;
- bit -= 8;
- }
- if ((w & 0xf0) != 0) {
- w >>= 4;
- bit -= 4;
- }
- if ((w & 0xc) != 0) {
- w >>= 2;
- bit -= 2;
- }
- if ((w & 2) != 0)
- --bit;
- 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) {
- isc_result_t result;
- dns_rpz_cidr_key_t tgt_ip;
- dns_rpz_cidr_bits_t tgt_prefix;
- dns_rpz_type_t type;
-
- REQUIRE(cidr != NULL);
-
- /*
- * 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->have_nsdname = ISC_TRUE;
- return;
- case DNS_RPZ_TYPE_QNAME:
- case DNS_RPZ_TYPE_BAD:
- return;
- }
- result = name2ipkey(cidr, DNS_RPZ_ERROR_LEVEL, name,
- type, &tgt_ip, &tgt_prefix);
- if (result != ISC_R_SUCCESS)
- return;
-
- result = search(cidr, &tgt_ip, tgt_prefix, type, ISC_TRUE, NULL);
- if (result == ISC_R_EXISTS &&
- isc_log_wouldlog(dns_lctx, DNS_RPZ_ERROR_LEVEL))
- {
- char printname[DNS_NAME_FORMATSIZE];
-
- /*
- * bin/tests/system/rpz/tests.sh looks for "rpz.*failed".
- */
- dns_name_format(name, printname, sizeof(printname));
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
- DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL,
- "rpz add failed; \"%s\" is a duplicate name",
- 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) {
- isc_result_t result;
- 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.
- */
- result = name2ipkey(cidr, DNS_RPZ_DEBUG_QUIET, name,
- type, &tgt_ip, &tgt_prefix);
- if (result != ISC_R_SUCCESS)
- return;
-
- result = search(cidr, &tgt_ip, tgt_prefix, type, ISC_FALSE, &tgt);
- if (result != ISC_R_SUCCESS) {
- badname(DNS_RPZ_ERROR_LEVEL, name, "; missing rpz node", "");
- 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_rpz_zone_t *rpz, 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);
-
- if (dns_name_iswildcard(&cname.cname)) {
- /*
- * CNAME *. means NODATA
- */
- if (dns_name_countlabels(&cname.cname) == 2)
- return (DNS_RPZ_POLICY_NODATA);
-
- /*
- * A qname of www.evil.com and a policy of
- * *.evil.com CNAME *.garden.net
- * gives a result of
- * evil.com CNAME evil.com.garden.net
- */
- if (dns_name_countlabels(&cname.cname) > 2)
- return (DNS_RPZ_POLICY_WILDCNAME);
- }
-
- /*
- * CNAME PASSTHRU.origin means "do not rewrite.
- */
- if (dns_name_equal(&cname.cname, &rpz->passthru))
- return (DNS_RPZ_POLICY_PASSTHRU);
-
- /*
- * 128.1.0.127.rpz-ip CNAME 128.1.0.0.127. is obsolete PASSTHRU
- */
- if (selfname != NULL && dns_name_equal(&cname.cname, selfname))
- return (DNS_RPZ_POLICY_PASSTHRU);
-
- /*
- * Any other rdata gives a response consisting of the rdata.
- */
- return (DNS_RPZ_POLICY_RECORD);
-}
diff --git a/contrib/bind9/lib/dns/rriterator.c b/contrib/bind9/lib/dns/rriterator.c
deleted file mode 100644
index 509fb42270f3..000000000000
--- a/contrib/bind9/lib/dns/rriterator.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (C) 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/*! \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);
- REQUIRE(rdataset == NULL || *rdataset == NULL);
- REQUIRE(rdata == NULL || *rdata == NULL);
-
- *name = dns_fixedname_name(&it->fixedname);
- *ttl = it->rdataset.ttl;
-
- dns_rdata_reset(&it->rdata);
- dns_rdataset_current(&it->rdataset, &it->rdata);
-
- if (rdataset != NULL)
- *rdataset = &it->rdataset;
-
- if (rdata != NULL)
- *rdata = &it->rdata;
-}
diff --git a/contrib/bind9/lib/dns/sdb.c b/contrib/bind9/lib/dns/sdb.c
deleted file mode 100644
index 191fda219f46..000000000000
--- a/contrib/bind9/lib/dns/sdb.c
+++ /dev/null
@@ -1,1596 +0,0 @@
-/*
- * Copyright (C) 2004-2012 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <string.h>
-
-#include <isc/buffer.h>
-#include <isc/lex.h>
-#include <isc/log.h>
-#include <isc/magic.h>
-#include <isc/mem.h>
-#include <isc/once.h>
-#include <isc/print.h>
-#include <isc/region.h>
-#include <isc/util.h>
-
-#include <dns/callbacks.h>
-#include <dns/db.h>
-#include <dns/dbiterator.h>
-#include <dns/fixedname.h>
-#include <dns/log.h>
-#include <dns/rdata.h>
-#include <dns/rdatalist.h>
-#include <dns/rdataset.h>
-#include <dns/rdatasetiter.h>
-#include <dns/rdatatype.h>
-#include <dns/result.h>
-#include <dns/sdb.h>
-#include <dns/types.h>
-
-#include "rdatalist_p.h"
-
-struct dns_sdbimplementation {
- const dns_sdbmethods_t *methods;
- void *driverdata;
- unsigned int flags;
- isc_mem_t *mctx;
- isc_mutex_t driverlock;
- dns_dbimplementation_t *dbimp;
-};
-
-struct dns_sdb {
- /* Unlocked */
- dns_db_t common;
- char *zone;
- dns_sdbimplementation_t *implementation;
- void *dbdata;
- isc_mutex_t lock;
- /* Locked */
- unsigned int references;
-};
-
-struct dns_sdblookup {
- /* Unlocked */
- unsigned int magic;
- dns_sdb_t *sdb;
- ISC_LIST(dns_rdatalist_t) lists;
- ISC_LIST(isc_buffer_t) buffers;
- dns_name_t *name;
- ISC_LINK(dns_sdblookup_t) link;
- isc_mutex_t lock;
- dns_rdatacallbacks_t callbacks;
- /* Locked */
- unsigned int references;
-};
-
-typedef struct dns_sdblookup dns_sdbnode_t;
-
-struct dns_sdballnodes {
- dns_dbiterator_t common;
- ISC_LIST(dns_sdbnode_t) nodelist;
- dns_sdbnode_t *current;
- dns_sdbnode_t *origin;
-};
-
-typedef dns_sdballnodes_t sdb_dbiterator_t;
-
-typedef struct sdb_rdatasetiter {
- dns_rdatasetiter_t common;
- dns_rdatalist_t *current;
-} sdb_rdatasetiter_t;
-
-#define SDB_MAGIC ISC_MAGIC('S', 'D', 'B', '-')
-
-/*%
- * Note that "impmagic" is not the first four bytes of the struct, so
- * ISC_MAGIC_VALID cannot be used.
- */
-#define VALID_SDB(sdb) ((sdb) != NULL && \
- (sdb)->common.impmagic == SDB_MAGIC)
-
-#define SDBLOOKUP_MAGIC ISC_MAGIC('S','D','B','L')
-#define VALID_SDBLOOKUP(sdbl) ISC_MAGIC_VALID(sdbl, SDBLOOKUP_MAGIC)
-#define VALID_SDBNODE(sdbn) VALID_SDBLOOKUP(sdbn)
-
-/* These values are taken from RFC1537 */
-#define SDB_DEFAULT_REFRESH (60 * 60 * 8)
-#define SDB_DEFAULT_RETRY (60 * 60 * 2)
-#define SDB_DEFAULT_EXPIRE (60 * 60 * 24 * 7)
-#define SDB_DEFAULT_MINIMUM (60 * 60 * 24)
-
-/* This is a reasonable value */
-#define SDB_DEFAULT_TTL (60 * 60 * 24)
-
-#ifdef __COVERITY__
-#define MAYBE_LOCK(sdb) LOCK(&sdb->implementation->driverlock)
-#define MAYBE_UNLOCK(sdb) UNLOCK(&sdb->implementation->driverlock)
-#else
-#define MAYBE_LOCK(sdb) \
- do { \
- unsigned int flags = sdb->implementation->flags; \
- if ((flags & DNS_SDBFLAG_THREADSAFE) == 0) \
- LOCK(&sdb->implementation->driverlock); \
- } while (0)
-
-#define MAYBE_UNLOCK(sdb) \
- do { \
- unsigned int flags = sdb->implementation->flags; \
- if ((flags & DNS_SDBFLAG_THREADSAFE) == 0) \
- UNLOCK(&sdb->implementation->driverlock); \
- } while (0)
-#endif
-
-static int dummy;
-
-static isc_result_t dns_sdb_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 isc_result_t findrdataset(dns_db_t *db, dns_dbnode_t *node,
- dns_dbversion_t *version,
- dns_rdatatype_t type, dns_rdatatype_t covers,
- isc_stdtime_t now, dns_rdataset_t *rdataset,
- dns_rdataset_t *sigrdataset);
-
-static isc_result_t createnode(dns_sdb_t *sdb, dns_sdbnode_t **nodep);
-
-static void destroynode(dns_sdbnode_t *node);
-
-static void detachnode(dns_db_t *db, dns_dbnode_t **targetp);
-
-
-static void list_tordataset(dns_rdatalist_t *rdatalist,
- dns_db_t *db, dns_dbnode_t *node,
- dns_rdataset_t *rdataset);
-
-static void dbiterator_destroy(dns_dbiterator_t **iteratorp);
-static isc_result_t dbiterator_first(dns_dbiterator_t *iterator);
-static isc_result_t dbiterator_last(dns_dbiterator_t *iterator);
-static isc_result_t dbiterator_seek(dns_dbiterator_t *iterator,
- dns_name_t *name);
-static isc_result_t dbiterator_prev(dns_dbiterator_t *iterator);
-static isc_result_t dbiterator_next(dns_dbiterator_t *iterator);
-static isc_result_t dbiterator_current(dns_dbiterator_t *iterator,
- dns_dbnode_t **nodep,
- dns_name_t *name);
-static isc_result_t dbiterator_pause(dns_dbiterator_t *iterator);
-static isc_result_t dbiterator_origin(dns_dbiterator_t *iterator,
- dns_name_t *name);
-
-static dns_dbiteratormethods_t dbiterator_methods = {
- dbiterator_destroy,
- dbiterator_first,
- dbiterator_last,
- dbiterator_seek,
- dbiterator_prev,
- dbiterator_next,
- dbiterator_current,
- dbiterator_pause,
- dbiterator_origin
-};
-
-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
-};
-
-/*
- * Functions used by implementors of simple databases
- */
-isc_result_t
-dns_sdb_register(const char *drivername, const dns_sdbmethods_t *methods,
- void *driverdata, unsigned int flags, isc_mem_t *mctx,
- dns_sdbimplementation_t **sdbimp)
-{
- dns_sdbimplementation_t *imp;
- isc_result_t result;
-
- REQUIRE(drivername != NULL);
- REQUIRE(methods != NULL);
- REQUIRE(methods->lookup != NULL || methods->lookup2 != NULL);
- REQUIRE(mctx != NULL);
- REQUIRE(sdbimp != NULL && *sdbimp == NULL);
- REQUIRE((flags & ~(DNS_SDBFLAG_RELATIVEOWNER |
- DNS_SDBFLAG_RELATIVERDATA |
- DNS_SDBFLAG_THREADSAFE|
- DNS_SDBFLAG_DNS64)) == 0);
-
- imp = isc_mem_get(mctx, sizeof(dns_sdbimplementation_t));
- if (imp == NULL)
- return (ISC_R_NOMEMORY);
- imp->methods = methods;
- imp->driverdata = driverdata;
- imp->flags = flags;
- imp->mctx = NULL;
- isc_mem_attach(mctx, &imp->mctx);
- result = isc_mutex_init(&imp->driverlock);
- if (result != ISC_R_SUCCESS)
- goto cleanup_mctx;
-
- imp->dbimp = NULL;
- result = dns_db_register(drivername, dns_sdb_create, imp, mctx,
- &imp->dbimp);
- if (result != ISC_R_SUCCESS)
- goto cleanup_mutex;
- *sdbimp = imp;
-
- return (ISC_R_SUCCESS);
-
- cleanup_mutex:
- DESTROYLOCK(&imp->driverlock);
- cleanup_mctx:
- isc_mem_put(mctx, imp, sizeof(dns_sdbimplementation_t));
- return (result);
-}
-
-void
-dns_sdb_unregister(dns_sdbimplementation_t **sdbimp) {
- dns_sdbimplementation_t *imp;
- isc_mem_t *mctx;
-
- REQUIRE(sdbimp != NULL && *sdbimp != NULL);
-
- imp = *sdbimp;
- dns_db_unregister(&imp->dbimp);
- DESTROYLOCK(&imp->driverlock);
-
- mctx = imp->mctx;
- isc_mem_put(mctx, imp, sizeof(dns_sdbimplementation_t));
- isc_mem_detach(&mctx);
-
- *sdbimp = NULL;
-}
-
-static inline unsigned int
-initial_size(unsigned int len) {
- unsigned int size;
-
- for (size = 1024; size < (64 * 1024); size *= 2)
- if (len < size)
- return (size);
- return (65535);
-}
-
-isc_result_t
-dns_sdb_putrdata(dns_sdblookup_t *lookup, dns_rdatatype_t typeval,
- dns_ttl_t ttl, const unsigned char *rdatap,
- unsigned int rdlen)
-{
- dns_rdatalist_t *rdatalist;
- dns_rdata_t *rdata;
- isc_buffer_t *rdatabuf = NULL;
- isc_result_t result;
- isc_mem_t *mctx;
- isc_region_t region;
-
- mctx = lookup->sdb->common.mctx;
-
- rdatalist = ISC_LIST_HEAD(lookup->lists);
- while (rdatalist != NULL) {
- if (rdatalist->type == typeval)
- break;
- rdatalist = ISC_LIST_NEXT(rdatalist, link);
- }
-
- if (rdatalist == NULL) {
- rdatalist = isc_mem_get(mctx, sizeof(dns_rdatalist_t));
- if (rdatalist == NULL)
- return (ISC_R_NOMEMORY);
- rdatalist->rdclass = lookup->sdb->common.rdclass;
- rdatalist->type = typeval;
- rdatalist->covers = 0;
- rdatalist->ttl = ttl;
- ISC_LIST_INIT(rdatalist->rdata);
- ISC_LINK_INIT(rdatalist, link);
- ISC_LIST_APPEND(lookup->lists, rdatalist, link);
- } else
- if (rdatalist->ttl != ttl)
- return (DNS_R_BADTTL);
-
- rdata = isc_mem_get(mctx, sizeof(dns_rdata_t));
- if (rdata == NULL)
- return (ISC_R_NOMEMORY);
-
- result = isc_buffer_allocate(mctx, &rdatabuf, rdlen);
- if (result != ISC_R_SUCCESS)
- goto failure;
- DE_CONST(rdatap, region.base);
- region.length = rdlen;
- isc_buffer_copyregion(rdatabuf, &region);
- isc_buffer_usedregion(rdatabuf, &region);
- dns_rdata_init(rdata);
- dns_rdata_fromregion(rdata, rdatalist->rdclass, rdatalist->type,
- &region);
- ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
- ISC_LIST_APPEND(lookup->buffers, rdatabuf, link);
- rdata = NULL;
-
- failure:
- if (rdata != NULL)
- isc_mem_put(mctx, rdata, sizeof(dns_rdata_t));
- return (result);
-}
-
-isc_result_t
-dns_sdb_putrr(dns_sdblookup_t *lookup, const char *type, dns_ttl_t ttl,
- const char *data)
-{
- unsigned int datalen;
- dns_rdatatype_t typeval;
- isc_textregion_t r;
- isc_lex_t *lex = NULL;
- isc_result_t result;
- unsigned char *p = NULL;
- unsigned int size = 0; /* Init to suppress compiler warning */
- isc_mem_t *mctx;
- dns_sdbimplementation_t *imp;
- dns_name_t *origin;
- isc_buffer_t b;
- isc_buffer_t rb;
-
- REQUIRE(VALID_SDBLOOKUP(lookup));
- REQUIRE(type != NULL);
- REQUIRE(data != NULL);
-
- mctx = lookup->sdb->common.mctx;
-
- DE_CONST(type, r.base);
- r.length = strlen(type);
- result = dns_rdatatype_fromtext(&typeval, &r);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- imp = lookup->sdb->implementation;
- if ((imp->flags & DNS_SDBFLAG_RELATIVERDATA) != 0)
- origin = &lookup->sdb->common.origin;
- else
- origin = dns_rootname;
-
- result = isc_lex_create(mctx, 64, &lex);
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- datalen = strlen(data);
- size = initial_size(datalen);
- do {
- isc_buffer_constinit(&b, data, datalen);
- isc_buffer_add(&b, datalen);
- result = isc_lex_openbuffer(lex, &b);
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- if (size >= 65535)
- size = 65535;
- p = isc_mem_get(mctx, size);
- if (p == NULL) {
- result = ISC_R_NOMEMORY;
- goto failure;
- }
- isc_buffer_init(&rb, p, size);
- result = dns_rdata_fromtext(NULL,
- lookup->sdb->common.rdclass,
- typeval, lex,
- origin, 0,
- mctx, &rb,
- &lookup->callbacks);
- if (result != ISC_R_NOSPACE)
- break;
-
- /*
- * Is the RR too big?
- */
- if (size >= 65535)
- break;
- isc_mem_put(mctx, p, size);
- p = NULL;
- size *= 2;
- } while (result == ISC_R_NOSPACE);
-
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- result = dns_sdb_putrdata(lookup, typeval, ttl,
- isc_buffer_base(&rb),
- isc_buffer_usedlength(&rb));
- failure:
- if (p != NULL)
- isc_mem_put(mctx, p, size);
- if (lex != NULL)
- isc_lex_destroy(&lex);
-
- return (result);
-}
-
-static isc_result_t
-getnode(dns_sdballnodes_t *allnodes, const char *name, dns_sdbnode_t **nodep) {
- dns_name_t *newname, *origin;
- dns_fixedname_t fnewname;
- dns_sdb_t *sdb = (dns_sdb_t *)allnodes->common.db;
- dns_sdbimplementation_t *imp = sdb->implementation;
- dns_sdbnode_t *sdbnode;
- isc_mem_t *mctx = sdb->common.mctx;
- isc_buffer_t b;
- isc_result_t result;
-
- dns_fixedname_init(&fnewname);
- newname = dns_fixedname_name(&fnewname);
-
- if ((imp->flags & DNS_SDBFLAG_RELATIVERDATA) != 0)
- origin = &sdb->common.origin;
- else
- origin = dns_rootname;
- isc_buffer_constinit(&b, name, strlen(name));
- isc_buffer_add(&b, strlen(name));
-
- result = dns_name_fromtext(newname, &b, origin, 0, NULL);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- if (allnodes->common.relative_names) {
- /* All names are relative to the root */
- unsigned int nlabels = dns_name_countlabels(newname);
- dns_name_getlabelsequence(newname, 0, nlabels - 1, newname);
- }
-
- sdbnode = ISC_LIST_HEAD(allnodes->nodelist);
- if (sdbnode == NULL || !dns_name_equal(sdbnode->name, newname)) {
- sdbnode = NULL;
- result = createnode(sdb, &sdbnode);
- if (result != ISC_R_SUCCESS)
- return (result);
- sdbnode->name = isc_mem_get(mctx, sizeof(dns_name_t));
- if (sdbnode->name == NULL) {
- destroynode(sdbnode);
- return (ISC_R_NOMEMORY);
- }
- dns_name_init(sdbnode->name, NULL);
- result = dns_name_dup(newname, mctx, sdbnode->name);
- if (result != ISC_R_SUCCESS) {
- isc_mem_put(mctx, sdbnode->name, sizeof(dns_name_t));
- destroynode(sdbnode);
- return (result);
- }
- ISC_LIST_PREPEND(allnodes->nodelist, sdbnode, link);
- if (allnodes->origin == NULL &&
- dns_name_equal(newname, &sdb->common.origin))
- allnodes->origin = sdbnode;
- }
- *nodep = sdbnode;
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_sdb_putnamedrr(dns_sdballnodes_t *allnodes, const char *name,
- const char *type, dns_ttl_t ttl, const char *data)
-{
- isc_result_t result;
- dns_sdbnode_t *sdbnode = NULL;
- result = getnode(allnodes, name, &sdbnode);
- if (result != ISC_R_SUCCESS)
- return (result);
- return (dns_sdb_putrr(sdbnode, type, ttl, data));
-}
-
-isc_result_t
-dns_sdb_putnamedrdata(dns_sdballnodes_t *allnodes, const char *name,
- dns_rdatatype_t type, dns_ttl_t ttl,
- const void *rdata, unsigned int rdlen)
-{
- isc_result_t result;
- dns_sdbnode_t *sdbnode = NULL;
- result = getnode(allnodes, name, &sdbnode);
- if (result != ISC_R_SUCCESS)
- return (result);
- return (dns_sdb_putrdata(sdbnode, type, ttl, rdata, rdlen));
-}
-
-isc_result_t
-dns_sdb_putsoa(dns_sdblookup_t *lookup, const char *mname, const char *rname,
- isc_uint32_t serial)
-{
- char str[2 * DNS_NAME_MAXTEXT + 5 * (sizeof("2147483647")) + 7];
- int n;
-
- REQUIRE(mname != NULL);
- REQUIRE(rname != NULL);
-
- n = snprintf(str, sizeof(str), "%s %s %u %u %u %u %u",
- mname, rname, serial,
- SDB_DEFAULT_REFRESH, SDB_DEFAULT_RETRY,
- SDB_DEFAULT_EXPIRE, SDB_DEFAULT_MINIMUM);
- if (n >= (int)sizeof(str) || n < 0)
- return (ISC_R_NOSPACE);
- return (dns_sdb_putrr(lookup, "SOA", SDB_DEFAULT_TTL, str));
-}
-
-/*
- * DB routines
- */
-
-static void
-attach(dns_db_t *source, dns_db_t **targetp) {
- dns_sdb_t *sdb = (dns_sdb_t *) source;
-
- REQUIRE(VALID_SDB(sdb));
-
- LOCK(&sdb->lock);
- REQUIRE(sdb->references > 0);
- sdb->references++;
- UNLOCK(&sdb->lock);
-
- *targetp = source;
-}
-
-static void
-destroy(dns_sdb_t *sdb) {
- isc_mem_t *mctx;
- dns_sdbimplementation_t *imp = sdb->implementation;
-
- mctx = sdb->common.mctx;
-
- if (imp->methods->destroy != NULL) {
- MAYBE_LOCK(sdb);
- imp->methods->destroy(sdb->zone, imp->driverdata,
- &sdb->dbdata);
- MAYBE_UNLOCK(sdb);
- }
-
- isc_mem_free(mctx, sdb->zone);
- DESTROYLOCK(&sdb->lock);
-
- sdb->common.magic = 0;
- sdb->common.impmagic = 0;
-
- dns_name_free(&sdb->common.origin, mctx);
-
- isc_mem_put(mctx, sdb, sizeof(dns_sdb_t));
- isc_mem_detach(&mctx);
-}
-
-static void
-detach(dns_db_t **dbp) {
- dns_sdb_t *sdb = (dns_sdb_t *)(*dbp);
- isc_boolean_t need_destroy = ISC_FALSE;
-
- REQUIRE(VALID_SDB(sdb));
- LOCK(&sdb->lock);
- REQUIRE(sdb->references > 0);
- sdb->references--;
- if (sdb->references == 0)
- need_destroy = ISC_TRUE;
- UNLOCK(&sdb->lock);
-
- if (need_destroy)
- destroy(sdb);
-
- *dbp = NULL;
-}
-
-static isc_result_t
-beginload(dns_db_t *db, dns_addrdatasetfunc_t *addp, dns_dbload_t **dbloadp) {
- UNUSED(db);
- UNUSED(addp);
- UNUSED(dbloadp);
- return (ISC_R_NOTIMPLEMENTED);
-}
-
-static isc_result_t
-endload(dns_db_t *db, dns_dbload_t **dbloadp) {
- UNUSED(db);
- UNUSED(dbloadp);
- return (ISC_R_NOTIMPLEMENTED);
-}
-
-static isc_result_t
-dump(dns_db_t *db, dns_dbversion_t *version, const char *filename,
- dns_masterformat_t masterformat) {
- UNUSED(db);
- UNUSED(version);
- UNUSED(filename);
- UNUSED(masterformat);
- return (ISC_R_NOTIMPLEMENTED);
-}
-
-static void
-currentversion(dns_db_t *db, dns_dbversion_t **versionp) {
- REQUIRE(versionp != NULL && *versionp == NULL);
-
- UNUSED(db);
-
- *versionp = (void *) &dummy;
- return;
-}
-
-static isc_result_t
-newversion(dns_db_t *db, dns_dbversion_t **versionp) {
- UNUSED(db);
- UNUSED(versionp);
-
- return (ISC_R_NOTIMPLEMENTED);
-}
-
-static void
-attachversion(dns_db_t *db, dns_dbversion_t *source,
- dns_dbversion_t **targetp)
-{
- REQUIRE(source != NULL && source == (void *) &dummy);
- REQUIRE(targetp != NULL && *targetp == NULL);
-
- UNUSED(db);
- *targetp = source;
- return;
-}
-
-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);
-
- UNUSED(db);
- UNUSED(commit);
-
- *versionp = NULL;
-}
-
-static isc_result_t
-createnode(dns_sdb_t *sdb, dns_sdbnode_t **nodep) {
- dns_sdbnode_t *node;
- isc_result_t result;
-
- node = isc_mem_get(sdb->common.mctx, sizeof(dns_sdbnode_t));
- if (node == NULL)
- return (ISC_R_NOMEMORY);
-
- node->sdb = NULL;
- attach((dns_db_t *)sdb, (dns_db_t **)&node->sdb);
- ISC_LIST_INIT(node->lists);
- ISC_LIST_INIT(node->buffers);
- ISC_LINK_INIT(node, link);
- node->name = NULL;
- result = isc_mutex_init(&node->lock);
- if (result != ISC_R_SUCCESS) {
- isc_mem_put(sdb->common.mctx, node, sizeof(dns_sdbnode_t));
- return (result);
- }
- dns_rdatacallbacks_init(&node->callbacks);
- node->references = 1;
- node->magic = SDBLOOKUP_MAGIC;
-
- *nodep = node;
- return (ISC_R_SUCCESS);
-}
-
-static void
-destroynode(dns_sdbnode_t *node) {
- dns_rdatalist_t *list;
- dns_rdata_t *rdata;
- isc_buffer_t *b;
- dns_sdb_t *sdb;
- isc_mem_t *mctx;
-
- sdb = node->sdb;
- mctx = sdb->common.mctx;
-
- while (!ISC_LIST_EMPTY(node->lists)) {
- list = ISC_LIST_HEAD(node->lists);
- while (!ISC_LIST_EMPTY(list->rdata)) {
- rdata = ISC_LIST_HEAD(list->rdata);
- ISC_LIST_UNLINK(list->rdata, rdata, link);
- isc_mem_put(mctx, rdata, sizeof(dns_rdata_t));
- }
- ISC_LIST_UNLINK(node->lists, list, link);
- isc_mem_put(mctx, list, sizeof(dns_rdatalist_t));
- }
-
- while (!ISC_LIST_EMPTY(node->buffers)) {
- b = ISC_LIST_HEAD(node->buffers);
- ISC_LIST_UNLINK(node->buffers, b, link);
- isc_buffer_free(&b);
- }
-
- if (node->name != NULL) {
- dns_name_free(node->name, mctx);
- isc_mem_put(mctx, node->name, sizeof(dns_name_t));
- }
- DESTROYLOCK(&node->lock);
- node->magic = 0;
- isc_mem_put(mctx, node, sizeof(dns_sdbnode_t));
- detach((dns_db_t **) (void *)&sdb);
-}
-
-static isc_result_t
-findnodeext(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
- dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo,
- dns_dbnode_t **nodep)
-{
- dns_sdb_t *sdb = (dns_sdb_t *)db;
- dns_sdbnode_t *node = NULL;
- isc_result_t result;
- isc_buffer_t b;
- char namestr[DNS_NAME_MAXTEXT + 1];
- isc_boolean_t isorigin;
- dns_sdbimplementation_t *imp;
- dns_name_t relname;
- unsigned int labels;
-
- REQUIRE(VALID_SDB(sdb));
- REQUIRE(create == ISC_FALSE);
- REQUIRE(nodep != NULL && *nodep == NULL);
-
- UNUSED(name);
- UNUSED(create);
-
- imp = sdb->implementation;
-
- isorigin = dns_name_equal(name, &sdb->common.origin);
-
- if (imp->methods->lookup2 != NULL) {
- if ((imp->flags & DNS_SDBFLAG_RELATIVEOWNER) != 0) {
- labels = dns_name_countlabels(name) -
- dns_name_countlabels(&db->origin);
- dns_name_init(&relname, NULL);
- dns_name_getlabelsequence(name, 0, labels, &relname);
- name = &relname;
- }
- } else {
- isc_buffer_init(&b, namestr, sizeof(namestr));
- if ((imp->flags & DNS_SDBFLAG_RELATIVEOWNER) != 0) {
-
- labels = dns_name_countlabels(name) -
- dns_name_countlabels(&db->origin);
- dns_name_init(&relname, NULL);
- dns_name_getlabelsequence(name, 0, labels, &relname);
- result = dns_name_totext(&relname, ISC_TRUE, &b);
- if (result != ISC_R_SUCCESS)
- return (result);
- } else {
- result = dns_name_totext(name, ISC_TRUE, &b);
- if (result != ISC_R_SUCCESS)
- return (result);
- }
- isc_buffer_putuint8(&b, 0);
- }
-
- result = createnode(sdb, &node);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- MAYBE_LOCK(sdb);
- if (imp->methods->lookup2 != NULL)
- result = imp->methods->lookup2(&sdb->common.origin, name,
- sdb->dbdata, node, methods,
- clientinfo);
- else
- result = imp->methods->lookup(sdb->zone, namestr, sdb->dbdata,
- node, methods, clientinfo);
- MAYBE_UNLOCK(sdb);
- if (result != ISC_R_SUCCESS &&
- !(result == ISC_R_NOTFOUND &&
- isorigin && imp->methods->authority != NULL))
- {
- destroynode(node);
- return (result);
- }
-
- if (isorigin && imp->methods->authority != NULL) {
- MAYBE_LOCK(sdb);
- result = imp->methods->authority(sdb->zone, sdb->dbdata, node);
- MAYBE_UNLOCK(sdb);
- if (result != ISC_R_SUCCESS) {
- destroynode(node);
- return (result);
- }
- }
-
- *nodep = node;
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
- dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
- dns_dbnode_t **nodep, dns_name_t *foundname,
- dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo,
- dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
-{
- dns_sdb_t *sdb = (dns_sdb_t *)db;
- dns_dbnode_t *node = NULL;
- dns_fixedname_t fname;
- dns_rdataset_t xrdataset;
- dns_name_t *xname;
- unsigned int nlabels, olabels;
- isc_result_t result;
- unsigned int i;
- unsigned int flags;
-
- REQUIRE(VALID_SDB(sdb));
- REQUIRE(nodep == NULL || *nodep == NULL);
- REQUIRE(version == NULL || version == (void *) &dummy);
-
- UNUSED(options);
-
- if (!dns_name_issubdomain(name, &db->origin))
- return (DNS_R_NXDOMAIN);
-
- olabels = dns_name_countlabels(&db->origin);
- nlabels = dns_name_countlabels(name);
-
- dns_fixedname_init(&fname);
- xname = dns_fixedname_name(&fname);
-
- if (rdataset == NULL) {
- dns_rdataset_init(&xrdataset);
- rdataset = &xrdataset;
- }
-
- result = DNS_R_NXDOMAIN;
- flags = sdb->implementation->flags;
- i = (flags & DNS_SDBFLAG_DNS64) != 0 ? nlabels : olabels;
- for (; i <= nlabels; i++) {
- /*
- * Look up the next label.
- */
- dns_name_getlabelsequence(name, nlabels - i, i, xname);
- result = findnodeext(db, xname, ISC_FALSE, methods,
- clientinfo, &node);
- if (result == ISC_R_NOTFOUND) {
- /*
- * No data at zone apex?
- */
- if (i == olabels)
- return (DNS_R_BADDB);
- result = DNS_R_NXDOMAIN;
- continue;
- }
- if (result != ISC_R_SUCCESS)
- return (result);
-
- /*
- * DNS64 zone's don't have DNAME or NS records.
- */
- if ((flags & DNS_SDBFLAG_DNS64) != 0)
- goto skip;
-
- /*
- * DNS64 zone's don't have DNAME or NS records.
- */
- if ((flags & DNS_SDBFLAG_DNS64) != 0)
- goto skip;
-
- /*
- * Look for a DNAME at the current label, unless this is
- * the qname.
- */
- if (i < nlabels) {
- result = findrdataset(db, node, version,
- dns_rdatatype_dname,
- 0, now, rdataset, sigrdataset);
- if (result == ISC_R_SUCCESS) {
- result = DNS_R_DNAME;
- break;
- }
- }
-
- /*
- * Look for an NS at the current label, unless this is the
- * origin or glue is ok.
- */
- if (i != olabels && (options & DNS_DBFIND_GLUEOK) == 0) {
- result = findrdataset(db, node, version,
- dns_rdatatype_ns,
- 0, now, rdataset, sigrdataset);
- if (result == ISC_R_SUCCESS) {
- if (i == nlabels && type == dns_rdatatype_any)
- {
- result = DNS_R_ZONECUT;
- dns_rdataset_disassociate(rdataset);
- if (sigrdataset != NULL &&
- dns_rdataset_isassociated
- (sigrdataset)) {
- dns_rdataset_disassociate
- (sigrdataset);
- }
- } else
- result = DNS_R_DELEGATION;
- break;
- }
- }
-
- /*
- * If the current name is not the qname, add another label
- * and try again.
- */
- if (i < nlabels) {
- destroynode(node);
- node = NULL;
- continue;
- }
-
- skip:
- /*
- * If we're looking for ANY, we're done.
- */
- if (type == dns_rdatatype_any) {
- result = ISC_R_SUCCESS;
- break;
- }
-
- /*
- * Look for the qtype.
- */
- result = findrdataset(db, node, version, type,
- 0, now, rdataset, sigrdataset);
- if (result == ISC_R_SUCCESS)
- break;
-
- /*
- * Look for a CNAME
- */
- if (type != dns_rdatatype_cname) {
- result = findrdataset(db, node, version,
- dns_rdatatype_cname,
- 0, now, rdataset, sigrdataset);
- if (result == ISC_R_SUCCESS) {
- result = DNS_R_CNAME;
- break;
- }
- }
-
- result = DNS_R_NXRRSET;
- break;
- }
-
- if (rdataset == &xrdataset && dns_rdataset_isassociated(rdataset))
- dns_rdataset_disassociate(rdataset);
-
- if (foundname != NULL) {
- isc_result_t xresult;
-
- xresult = dns_name_copy(xname, foundname, NULL);
- if (xresult != ISC_R_SUCCESS) {
- if (node != NULL)
- destroynode(node);
- if (dns_rdataset_isassociated(rdataset))
- dns_rdataset_disassociate(rdataset);
- return (DNS_R_BADDB);
- }
- }
-
- if (nodep != NULL)
- *nodep = node;
- else if (node != NULL)
- detachnode(db, &node);
-
- return (result);
-}
-
-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)
-{
- UNUSED(db);
- UNUSED(name);
- UNUSED(options);
- UNUSED(now);
- UNUSED(nodep);
- UNUSED(foundname);
- UNUSED(rdataset);
- UNUSED(sigrdataset);
-
- return (ISC_R_NOTIMPLEMENTED);
-}
-
-static void
-attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) {
- dns_sdb_t *sdb = (dns_sdb_t *)db;
- dns_sdbnode_t *node = (dns_sdbnode_t *)source;
-
- REQUIRE(VALID_SDB(sdb));
-
- UNUSED(sdb);
-
- LOCK(&node->lock);
- INSIST(node->references > 0);
- node->references++;
- INSIST(node->references != 0); /* Catch overflow. */
- UNLOCK(&node->lock);
-
- *targetp = source;
-}
-
-static void
-detachnode(dns_db_t *db, dns_dbnode_t **targetp) {
- dns_sdb_t *sdb = (dns_sdb_t *)db;
- dns_sdbnode_t *node;
- isc_boolean_t need_destroy = ISC_FALSE;
-
- REQUIRE(VALID_SDB(sdb));
- REQUIRE(targetp != NULL && *targetp != NULL);
-
- UNUSED(sdb);
-
- node = (dns_sdbnode_t *)(*targetp);
-
- 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);
-
- *targetp = NULL;
-}
-
-static isc_result_t
-expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) {
- UNUSED(db);
- UNUSED(node);
- UNUSED(now);
- INSIST(0);
- return (ISC_R_UNEXPECTED);
-}
-
-static void
-printnode(dns_db_t *db, dns_dbnode_t *node, FILE *out) {
- UNUSED(db);
- UNUSED(node);
- UNUSED(out);
- return;
-}
-
-static isc_result_t
-createiterator(dns_db_t *db, unsigned int options, dns_dbiterator_t **iteratorp)
-{
- dns_sdb_t *sdb = (dns_sdb_t *)db;
- sdb_dbiterator_t *sdbiter;
- dns_sdbimplementation_t *imp = sdb->implementation;
- isc_result_t result;
-
- REQUIRE(VALID_SDB(sdb));
-
- if (imp->methods->allnodes == NULL)
- return (ISC_R_NOTIMPLEMENTED);
-
- if ((options & DNS_DB_NSEC3ONLY) != 0 ||
- (options & DNS_DB_NONSEC3) != 0)
- return (ISC_R_NOTIMPLEMENTED);
-
- sdbiter = isc_mem_get(sdb->common.mctx, sizeof(sdb_dbiterator_t));
- if (sdbiter == NULL)
- return (ISC_R_NOMEMORY);
-
- sdbiter->common.methods = &dbiterator_methods;
- sdbiter->common.db = NULL;
- dns_db_attach(db, &sdbiter->common.db);
- sdbiter->common.relative_names = ISC_TF(options & DNS_DB_RELATIVENAMES);
- sdbiter->common.magic = DNS_DBITERATOR_MAGIC;
- ISC_LIST_INIT(sdbiter->nodelist);
- sdbiter->current = NULL;
- sdbiter->origin = NULL;
-
- MAYBE_LOCK(sdb);
- result = imp->methods->allnodes(sdb->zone, sdb->dbdata, sdbiter);
- MAYBE_UNLOCK(sdb);
- if (result != ISC_R_SUCCESS) {
- dbiterator_destroy((dns_dbiterator_t **) (void *)&sdbiter);
- return (result);
- }
-
- if (sdbiter->origin != NULL) {
- ISC_LIST_UNLINK(sdbiter->nodelist, sdbiter->origin, link);
- ISC_LIST_PREPEND(sdbiter->nodelist, sdbiter->origin, link);
- }
-
- *iteratorp = (dns_dbiterator_t *)sdbiter;
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
- dns_rdatatype_t type, dns_rdatatype_t covers,
- isc_stdtime_t now, dns_rdataset_t *rdataset,
- dns_rdataset_t *sigrdataset)
-{
- dns_rdatalist_t *list;
- dns_sdbnode_t *sdbnode = (dns_sdbnode_t *)node;
-
- REQUIRE(VALID_SDBNODE(node));
-
- UNUSED(db);
- UNUSED(version);
- UNUSED(covers);
- UNUSED(now);
- UNUSED(sigrdataset);
-
- if (type == dns_rdatatype_rrsig)
- return (ISC_R_NOTIMPLEMENTED);
-
- list = ISC_LIST_HEAD(sdbnode->lists);
- while (list != NULL) {
- if (list->type == type)
- break;
- list = ISC_LIST_NEXT(list, link);
- }
- if (list == NULL)
- return (ISC_R_NOTFOUND);
-
- list_tordataset(list, db, node, rdataset);
-
- return (ISC_R_SUCCESS);
-}
-
-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)
-{
- sdb_rdatasetiter_t *iterator;
-
- REQUIRE(version == NULL || version == &dummy);
-
- UNUSED(version);
- UNUSED(now);
-
- iterator = isc_mem_get(db->mctx, sizeof(sdb_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 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);
- UNUSED(now);
- UNUSED(rdataset);
- UNUSED(options);
- UNUSED(addedrdataset);
-
- return (ISC_R_NOTIMPLEMENTED);
-}
-
-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);
- UNUSED(newrdataset);
-
- return (ISC_R_NOTIMPLEMENTED);
-}
-
-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_boolean_t
-issecure(dns_db_t *db) {
- UNUSED(db);
-
- return (ISC_FALSE);
-}
-
-static unsigned int
-nodecount(dns_db_t *db) {
- UNUSED(db);
-
- return (0);
-}
-
-static isc_boolean_t
-ispersistent(dns_db_t *db) {
- UNUSED(db);
- return (ISC_TRUE);
-}
-
-static void
-overmem(dns_db_t *db, isc_boolean_t overmem) {
- UNUSED(db);
- UNUSED(overmem);
-}
-
-static void
-settask(dns_db_t *db, isc_task_t *task) {
- UNUSED(db);
- UNUSED(task);
-}
-
-
-static dns_dbmethods_t sdb_methods = {
- attach,
- detach,
- beginload,
- endload,
- dump,
- currentversion,
- newversion,
- attachversion,
- closeversion,
- NULL,
- NULL,
- findzonecut,
- attachnode,
- detachnode,
- expirenode,
- printnode,
- createiterator,
- findrdataset,
- allrdatasets,
- addrdataset,
- subtractrdataset,
- deleterdataset,
- issecure,
- nodecount,
- ispersistent,
- overmem,
- 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 */
- findnodeext,
- findext
-};
-
-static isc_result_t
-dns_sdb_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_sdb_t *sdb;
- isc_result_t result;
- char zonestr[DNS_NAME_MAXTEXT + 1];
- isc_buffer_t b;
- dns_sdbimplementation_t *imp;
-
- REQUIRE(driverarg != NULL);
-
- imp = driverarg;
-
- if (type != dns_dbtype_zone)
- return (ISC_R_NOTIMPLEMENTED);
-
- sdb = isc_mem_get(mctx, sizeof(dns_sdb_t));
- if (sdb == NULL)
- return (ISC_R_NOMEMORY);
- memset(sdb, 0, sizeof(dns_sdb_t));
-
- dns_name_init(&sdb->common.origin, NULL);
- sdb->common.attributes = 0;
- sdb->common.methods = &sdb_methods;
- sdb->common.rdclass = rdclass;
- sdb->common.mctx = NULL;
- sdb->implementation = imp;
-
- isc_mem_attach(mctx, &sdb->common.mctx);
-
- result = isc_mutex_init(&sdb->lock);
- if (result != ISC_R_SUCCESS)
- goto cleanup_mctx;
-
- result = dns_name_dupwithoffsets(origin, mctx, &sdb->common.origin);
- if (result != ISC_R_SUCCESS)
- goto cleanup_lock;
-
- isc_buffer_init(&b, zonestr, sizeof(zonestr));
- result = dns_name_totext(origin, ISC_TRUE, &b);
- if (result != ISC_R_SUCCESS)
- goto cleanup_origin;
- isc_buffer_putuint8(&b, 0);
-
- sdb->zone = isc_mem_strdup(mctx, zonestr);
- if (sdb->zone == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup_origin;
- }
-
- sdb->dbdata = NULL;
- if (imp->methods->create != NULL) {
- MAYBE_LOCK(sdb);
- result = imp->methods->create(sdb->zone, argc, argv,
- imp->driverdata, &sdb->dbdata);
- MAYBE_UNLOCK(sdb);
- if (result != ISC_R_SUCCESS)
- goto cleanup_zonestr;
- }
-
- sdb->references = 1;
-
- sdb->common.magic = DNS_DB_MAGIC;
- sdb->common.impmagic = SDB_MAGIC;
-
- *dbp = (dns_db_t *)sdb;
-
- return (ISC_R_SUCCESS);
-
- cleanup_zonestr:
- isc_mem_free(mctx, sdb->zone);
- cleanup_origin:
- dns_name_free(&sdb->common.origin, mctx);
- cleanup_lock:
- (void)isc_mutex_destroy(&sdb->lock);
- cleanup_mctx:
- isc_mem_put(mctx, sdb, sizeof(dns_sdb_t));
- isc_mem_detach(&mctx);
-
- return (result);
-}
-
-
-/*
- * Rdataset Methods
- */
-
-static void
-disassociate(dns_rdataset_t *rdataset) {
- dns_dbnode_t *node = rdataset->private5;
- dns_sdbnode_t *sdbnode = (dns_sdbnode_t *) node;
- dns_db_t *db = (dns_db_t *) sdbnode->sdb;
-
- detachnode(db, &node);
- isc__rdatalist_disassociate(rdataset);
-}
-
-static void
-rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
- dns_dbnode_t *node = source->private5;
- dns_sdbnode_t *sdbnode = (dns_sdbnode_t *) node;
- dns_db_t *db = (dns_db_t *) sdbnode->sdb;
- dns_dbnode_t *tempdb = NULL;
-
- isc__rdatalist_clone(source, target);
- attachnode(db, node, &tempdb);
- source->private5 = tempdb;
-}
-
-static dns_rdatasetmethods_t methods = {
- disassociate,
- isc__rdatalist_first,
- isc__rdatalist_next,
- isc__rdatalist_current,
- rdataset_clone,
- isc__rdatalist_count,
- isc__rdatalist_addnoqname,
- isc__rdatalist_getnoqname,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-static void
-list_tordataset(dns_rdatalist_t *rdatalist,
- dns_db_t *db, dns_dbnode_t *node,
- dns_rdataset_t *rdataset)
-{
- /*
- * The sdb rdataset is an rdatalist with some additions.
- * - private1 & private2 are used by the rdatalist.
- * - private3 & private 4 are unused.
- * - private5 is the node.
- */
-
- /* This should never fail. */
- RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) ==
- ISC_R_SUCCESS);
-
- rdataset->methods = &methods;
- dns_db_attachnode(db, node, &rdataset->private5);
-}
-
-/*
- * Database Iterator Methods
- */
-static void
-dbiterator_destroy(dns_dbiterator_t **iteratorp) {
- sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)(*iteratorp);
- dns_sdb_t *sdb = (dns_sdb_t *)sdbiter->common.db;
-
- while (!ISC_LIST_EMPTY(sdbiter->nodelist)) {
- dns_sdbnode_t *node;
- node = ISC_LIST_HEAD(sdbiter->nodelist);
- ISC_LIST_UNLINK(sdbiter->nodelist, node, link);
- destroynode(node);
- }
-
- dns_db_detach(&sdbiter->common.db);
- isc_mem_put(sdb->common.mctx, sdbiter, sizeof(sdb_dbiterator_t));
-
- *iteratorp = NULL;
-}
-
-static isc_result_t
-dbiterator_first(dns_dbiterator_t *iterator) {
- sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator;
-
- sdbiter->current = ISC_LIST_HEAD(sdbiter->nodelist);
- if (sdbiter->current == NULL)
- return (ISC_R_NOMORE);
- else
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-dbiterator_last(dns_dbiterator_t *iterator) {
- sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator;
-
- sdbiter->current = ISC_LIST_TAIL(sdbiter->nodelist);
- if (sdbiter->current == NULL)
- return (ISC_R_NOMORE);
- else
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name) {
- sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator;
-
- sdbiter->current = ISC_LIST_HEAD(sdbiter->nodelist);
- while (sdbiter->current != NULL) {
- if (dns_name_equal(sdbiter->current->name, name))
- return (ISC_R_SUCCESS);
- sdbiter->current = ISC_LIST_NEXT(sdbiter->current, link);
- }
- return (ISC_R_NOTFOUND);
-}
-
-static isc_result_t
-dbiterator_prev(dns_dbiterator_t *iterator) {
- sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator;
-
- sdbiter->current = ISC_LIST_PREV(sdbiter->current, link);
- if (sdbiter->current == NULL)
- return (ISC_R_NOMORE);
- else
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-dbiterator_next(dns_dbiterator_t *iterator) {
- sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator;
-
- sdbiter->current = ISC_LIST_NEXT(sdbiter->current, link);
- if (sdbiter->current == NULL)
- return (ISC_R_NOMORE);
- else
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep,
- dns_name_t *name)
-{
- sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator;
-
- attachnode(iterator->db, sdbiter->current, nodep);
- if (name != NULL)
- return (dns_name_copy(sdbiter->current->name, name, NULL));
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-dbiterator_pause(dns_dbiterator_t *iterator) {
- UNUSED(iterator);
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-dbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name) {
- UNUSED(iterator);
- return (dns_name_copy(dns_rootname, name, NULL));
-}
-
-/*
- * Rdataset Iterator Methods
- */
-
-static void
-rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp) {
- sdb_rdatasetiter_t *sdbiterator = (sdb_rdatasetiter_t *)(*iteratorp);
- detachnode(sdbiterator->common.db, &sdbiterator->common.node);
- isc_mem_put(sdbiterator->common.db->mctx, sdbiterator,
- sizeof(sdb_rdatasetiter_t));
- *iteratorp = NULL;
-}
-
-static isc_result_t
-rdatasetiter_first(dns_rdatasetiter_t *iterator) {
- sdb_rdatasetiter_t *sdbiterator = (sdb_rdatasetiter_t *)iterator;
- dns_sdbnode_t *sdbnode = (dns_sdbnode_t *)iterator->node;
-
- if (ISC_LIST_EMPTY(sdbnode->lists))
- return (ISC_R_NOMORE);
- sdbiterator->current = ISC_LIST_HEAD(sdbnode->lists);
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-rdatasetiter_next(dns_rdatasetiter_t *iterator) {
- sdb_rdatasetiter_t *sdbiterator = (sdb_rdatasetiter_t *)iterator;
-
- sdbiterator->current = ISC_LIST_NEXT(sdbiterator->current, link);
- if (sdbiterator->current == NULL)
- return (ISC_R_NOMORE);
- else
- return (ISC_R_SUCCESS);
-}
-
-static void
-rdatasetiter_current(dns_rdatasetiter_t *iterator, dns_rdataset_t *rdataset) {
- sdb_rdatasetiter_t *sdbiterator = (sdb_rdatasetiter_t *)iterator;
-
- list_tordataset(sdbiterator->current, iterator->db, iterator->node,
- rdataset);
-}
diff --git a/contrib/bind9/lib/dns/sdlz.c b/contrib/bind9/lib/dns/sdlz.c
deleted file mode 100644
index 9d4e615802fa..000000000000
--- a/contrib/bind9/lib/dns/sdlz.c
+++ /dev/null
@@ -1,2103 +0,0 @@
-/*
- * Portions Copyright (C) 2005-2012 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * Copyright (C) 2002 Stichting NLnet, Netherlands, stichting@nlnet.nl.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the
- * above copyright notice and this permission notice appear in all
- * copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND STICHTING NLNET
- * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
- * STICHTING NLNET BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
- * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
- * USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * The development of Dynamically Loadable Zones (DLZ) for Bind 9 was
- * conceived and contributed by Rob Butler.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the
- * above copyright notice and this permission notice appear in all
- * copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ROB BUTLER
- * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
- * ROB BUTLER BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
- * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
- * USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/*! \file */
-
-#include <config.h>
-#include <string.h>
-
-#include <isc/buffer.h>
-#include <isc/lex.h>
-#include <isc/log.h>
-#include <isc/rwlock.h>
-#include <isc/string.h>
-#include <isc/util.h>
-#include <isc/magic.h>
-#include <isc/mem.h>
-#include <isc/once.h>
-#include <isc/print.h>
-#include <isc/region.h>
-
-#include <dns/callbacks.h>
-#include <dns/db.h>
-#include <dns/dbiterator.h>
-#include <dns/dlz.h>
-#include <dns/fixedname.h>
-#include <dns/log.h>
-#include <dns/rdata.h>
-#include <dns/rdatalist.h>
-#include <dns/rdataset.h>
-#include <dns/rdatasetiter.h>
-#include <dns/rdatatype.h>
-#include <dns/result.h>
-#include <dns/master.h>
-#include <dns/sdlz.h>
-#include <dns/types.h>
-
-#include "rdatalist_p.h"
-
-/*
- * Private Types
- */
-
-struct dns_sdlzimplementation {
- const dns_sdlzmethods_t *methods;
- isc_mem_t *mctx;
- void *driverarg;
- unsigned int flags;
- isc_mutex_t driverlock;
- dns_dlzimplementation_t *dlz_imp;
-};
-
-struct dns_sdlz_db {
- /* Unlocked */
- dns_db_t common;
- void *dbdata;
- dns_sdlzimplementation_t *dlzimp;
- isc_mutex_t refcnt_lock;
- /* Locked */
- unsigned int references;
- dns_dbversion_t *future_version;
- int dummy_version;
-};
-
-struct dns_sdlzlookup {
- /* Unlocked */
- unsigned int magic;
- dns_sdlz_db_t *sdlz;
- ISC_LIST(dns_rdatalist_t) lists;
- ISC_LIST(isc_buffer_t) buffers;
- dns_name_t *name;
- ISC_LINK(dns_sdlzlookup_t) link;
- isc_mutex_t lock;
- dns_rdatacallbacks_t callbacks;
- /* Locked */
- unsigned int references;
-};
-
-typedef struct dns_sdlzlookup dns_sdlznode_t;
-
-struct dns_sdlzallnodes {
- dns_dbiterator_t common;
- ISC_LIST(dns_sdlznode_t) nodelist;
- dns_sdlznode_t *current;
- dns_sdlznode_t *origin;
-};
-
-typedef dns_sdlzallnodes_t sdlz_dbiterator_t;
-
-typedef struct sdlz_rdatasetiter {
- dns_rdatasetiter_t common;
- dns_rdatalist_t *current;
-} sdlz_rdatasetiter_t;
-
-
-#define SDLZDB_MAGIC ISC_MAGIC('D', 'L', 'Z', 'S')
-
-/*
- * Note that "impmagic" is not the first four bytes of the struct, so
- * ISC_MAGIC_VALID cannot be used.
- */
-
-#define VALID_SDLZDB(sdlzdb) ((sdlzdb) != NULL && \
- (sdlzdb)->common.impmagic == SDLZDB_MAGIC)
-
-#define SDLZLOOKUP_MAGIC ISC_MAGIC('D','L','Z','L')
-#define VALID_SDLZLOOKUP(sdlzl) ISC_MAGIC_VALID(sdlzl, SDLZLOOKUP_MAGIC)
-#define VALID_SDLZNODE(sdlzn) VALID_SDLZLOOKUP(sdlzn)
-
-/* These values are taken from RFC 1537 */
-#define SDLZ_DEFAULT_REFRESH (60 * 60 * 8)
-#define SDLZ_DEFAULT_RETRY (60 * 60 * 2)
-#define SDLZ_DEFAULT_EXPIRE (60 * 60 * 24 * 7)
-#define SDLZ_DEFAULT_MINIMUM (60 * 60 * 24)
-
-/* This is a reasonable value */
-#define SDLZ_DEFAULT_TTL (60 * 60 * 24)
-
-#ifdef __COVERITY__
-#define MAYBE_LOCK(imp) LOCK(&imp->driverlock)
-#define MAYBE_UNLOCK(imp) UNLOCK(&imp->driverlock)
-#else
-#define MAYBE_LOCK(imp) \
- do { \
- unsigned int flags = imp->flags; \
- if ((flags & DNS_SDLZFLAG_THREADSAFE) == 0) \
- LOCK(&imp->driverlock); \
- } while (0)
-
-#define MAYBE_UNLOCK(imp) \
- do { \
- unsigned int flags = imp->flags; \
- if ((flags & DNS_SDLZFLAG_THREADSAFE) == 0) \
- UNLOCK(&imp->driverlock); \
- } while (0)
-#endif
-
-/*
- * Forward references. Try to keep these to a minimum.
- */
-
-static void list_tordataset(dns_rdatalist_t *rdatalist,
- dns_db_t *db, dns_dbnode_t *node,
- dns_rdataset_t *rdataset);
-
-static void detachnode(dns_db_t *db, dns_dbnode_t **targetp);
-
-static void dbiterator_destroy(dns_dbiterator_t **iteratorp);
-static isc_result_t dbiterator_first(dns_dbiterator_t *iterator);
-static isc_result_t dbiterator_last(dns_dbiterator_t *iterator);
-static isc_result_t dbiterator_seek(dns_dbiterator_t *iterator,
- dns_name_t *name);
-static isc_result_t dbiterator_prev(dns_dbiterator_t *iterator);
-static isc_result_t dbiterator_next(dns_dbiterator_t *iterator);
-static isc_result_t dbiterator_current(dns_dbiterator_t *iterator,
- dns_dbnode_t **nodep,
- dns_name_t *name);
-static isc_result_t dbiterator_pause(dns_dbiterator_t *iterator);
-static isc_result_t dbiterator_origin(dns_dbiterator_t *iterator,
- dns_name_t *name);
-
-static dns_dbiteratormethods_t dbiterator_methods = {
- dbiterator_destroy,
- dbiterator_first,
- dbiterator_last,
- dbiterator_seek,
- dbiterator_prev,
- dbiterator_next,
- dbiterator_current,
- dbiterator_pause,
- dbiterator_origin
-};
-
-/*
- * Utility functions
- */
-
-/*
- * 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;
-
- for (i = 0; i < len; i++) {
- if (str[i] >= 'A' && str[i] <= 'Z')
- str[i] += 32;
- }
-}
-
-static inline unsigned int
-initial_size(const char *data) {
- unsigned int len = (strlen(data) / 64) + 1;
- return (len * 64 + 64);
-}
-
-/*
- * Rdataset Iterator Methods. These methods were "borrowed" from the SDB
- * driver interface. See the SDB driver interface documentation for more info.
- */
-
-static void
-rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp) {
- sdlz_rdatasetiter_t *sdlziterator =
- (sdlz_rdatasetiter_t *)(*iteratorp);
-
- detachnode(sdlziterator->common.db, &sdlziterator->common.node);
- isc_mem_put(sdlziterator->common.db->mctx, sdlziterator,
- sizeof(sdlz_rdatasetiter_t));
- *iteratorp = NULL;
-}
-
-static isc_result_t
-rdatasetiter_first(dns_rdatasetiter_t *iterator) {
- sdlz_rdatasetiter_t *sdlziterator = (sdlz_rdatasetiter_t *)iterator;
- dns_sdlznode_t *sdlznode = (dns_sdlznode_t *)iterator->node;
-
- if (ISC_LIST_EMPTY(sdlznode->lists))
- return (ISC_R_NOMORE);
- sdlziterator->current = ISC_LIST_HEAD(sdlznode->lists);
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-rdatasetiter_next(dns_rdatasetiter_t *iterator) {
- sdlz_rdatasetiter_t *sdlziterator = (sdlz_rdatasetiter_t *)iterator;
-
- sdlziterator->current = ISC_LIST_NEXT(sdlziterator->current, link);
- if (sdlziterator->current == NULL)
- return (ISC_R_NOMORE);
- else
- return (ISC_R_SUCCESS);
-}
-
-static void
-rdatasetiter_current(dns_rdatasetiter_t *iterator, dns_rdataset_t *rdataset) {
- sdlz_rdatasetiter_t *sdlziterator = (sdlz_rdatasetiter_t *)iterator;
-
- list_tordataset(sdlziterator->current, iterator->db, iterator->node,
- rdataset);
-}
-
-static dns_rdatasetitermethods_t rdatasetiter_methods = {
- rdatasetiter_destroy,
- rdatasetiter_first,
- rdatasetiter_next,
- rdatasetiter_current
-};
-
-/*
- * DB routines. These methods were "borrowed" from the SDB driver interface.
- * See the SDB driver interface documentation for more info.
- */
-
-static void
-attach(dns_db_t *source, dns_db_t **targetp) {
- dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *) source;
-
- REQUIRE(VALID_SDLZDB(sdlz));
-
- LOCK(&sdlz->refcnt_lock);
- REQUIRE(sdlz->references > 0);
- sdlz->references++;
- UNLOCK(&sdlz->refcnt_lock);
-
- *targetp = source;
-}
-
-static void
-destroy(dns_sdlz_db_t *sdlz) {
- isc_mem_t *mctx;
- mctx = sdlz->common.mctx;
-
- sdlz->common.magic = 0;
- sdlz->common.impmagic = 0;
-
- (void)isc_mutex_destroy(&sdlz->refcnt_lock);
-
- dns_name_free(&sdlz->common.origin, mctx);
-
- isc_mem_put(mctx, sdlz, sizeof(dns_sdlz_db_t));
- isc_mem_detach(&mctx);
-}
-
-static void
-detach(dns_db_t **dbp) {
- dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)(*dbp);
- isc_boolean_t need_destroy = ISC_FALSE;
-
- REQUIRE(VALID_SDLZDB(sdlz));
- LOCK(&sdlz->refcnt_lock);
- REQUIRE(sdlz->references > 0);
- sdlz->references--;
- if (sdlz->references == 0)
- need_destroy = ISC_TRUE;
- UNLOCK(&sdlz->refcnt_lock);
-
- if (need_destroy)
- destroy(sdlz);
-
- *dbp = NULL;
-}
-
-static isc_result_t
-beginload(dns_db_t *db, dns_addrdatasetfunc_t *addp, dns_dbload_t **dbloadp) {
- UNUSED(db);
- UNUSED(addp);
- UNUSED(dbloadp);
- return (ISC_R_NOTIMPLEMENTED);
-}
-
-static isc_result_t
-endload(dns_db_t *db, dns_dbload_t **dbloadp) {
- UNUSED(db);
- UNUSED(dbloadp);
- return (ISC_R_NOTIMPLEMENTED);
-}
-
-static isc_result_t
-dump(dns_db_t *db, dns_dbversion_t *version, const char *filename,
- dns_masterformat_t masterformat)
-{
- UNUSED(db);
- UNUSED(version);
- UNUSED(filename);
- UNUSED(masterformat);
- return (ISC_R_NOTIMPLEMENTED);
-}
-
-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);
-
- *versionp = (void *) &sdlz->dummy_version;
- return;
-}
-
-static isc_result_t
-newversion(dns_db_t *db, dns_dbversion_t **versionp) {
- dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
- char origin[DNS_NAME_MAXTEXT + 1];
- isc_result_t result;
-
- 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)
-{
- dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
-
- REQUIRE(VALID_SDLZDB(sdlz));
- REQUIRE(source != NULL && source == (void *)&sdlz->dummy_version);
-
- *targetp = source;
-}
-
-static void
-closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) {
- dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
- char origin[DNS_NAME_MAXTEXT + 1];
-
- 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));
-
- 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
-createnode(dns_sdlz_db_t *sdlz, dns_sdlznode_t **nodep) {
- dns_sdlznode_t *node;
- isc_result_t result;
-
- node = isc_mem_get(sdlz->common.mctx, sizeof(dns_sdlznode_t));
- if (node == NULL)
- return (ISC_R_NOMEMORY);
-
- node->sdlz = NULL;
- attach((dns_db_t *)sdlz, (dns_db_t **)&node->sdlz);
- ISC_LIST_INIT(node->lists);
- ISC_LIST_INIT(node->buffers);
- ISC_LINK_INIT(node, link);
- node->name = NULL;
- 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(sdlz->common.mctx, node, sizeof(dns_sdlznode_t));
- return (ISC_R_UNEXPECTED);
- }
- dns_rdatacallbacks_init(&node->callbacks);
- node->references = 1;
- node->magic = SDLZLOOKUP_MAGIC;
-
- *nodep = node;
- return (ISC_R_SUCCESS);
-}
-
-static void
-destroynode(dns_sdlznode_t *node) {
- dns_rdatalist_t *list;
- dns_rdata_t *rdata;
- isc_buffer_t *b;
- dns_sdlz_db_t *sdlz;
- dns_db_t *db;
- isc_mem_t *mctx;
-
- sdlz = node->sdlz;
- mctx = sdlz->common.mctx;
-
- while (!ISC_LIST_EMPTY(node->lists)) {
- list = ISC_LIST_HEAD(node->lists);
- while (!ISC_LIST_EMPTY(list->rdata)) {
- rdata = ISC_LIST_HEAD(list->rdata);
- ISC_LIST_UNLINK(list->rdata, rdata, link);
- isc_mem_put(mctx, rdata, sizeof(dns_rdata_t));
- }
- ISC_LIST_UNLINK(node->lists, list, link);
- isc_mem_put(mctx, list, sizeof(dns_rdatalist_t));
- }
-
- while (!ISC_LIST_EMPTY(node->buffers)) {
- b = ISC_LIST_HEAD(node->buffers);
- ISC_LIST_UNLINK(node->buffers, b, link);
- isc_buffer_free(&b);
- }
-
- if (node->name != NULL) {
- dns_name_free(node->name, mctx);
- isc_mem_put(mctx, node->name, sizeof(dns_name_t));
- }
- DESTROYLOCK(&node->lock);
- node->magic = 0;
- isc_mem_put(mctx, node, sizeof(dns_sdlznode_t));
- db = &sdlz->common;
- detach(&db);
-}
-
-static isc_result_t
-findnodeext(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
- dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo,
- dns_dbnode_t **nodep)
-{
- dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
- dns_sdlznode_t *node = NULL;
- isc_result_t result;
- isc_buffer_t b;
- char namestr[DNS_NAME_MAXTEXT + 1];
- isc_buffer_t b2;
- char zonestr[DNS_NAME_MAXTEXT + 1];
- isc_boolean_t isorigin;
- dns_sdlzauthorityfunc_t authority;
-
- REQUIRE(VALID_SDLZDB(sdlz));
- REQUIRE(nodep != NULL && *nodep == NULL);
-
- 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) {
- dns_name_t relname;
- unsigned int labels;
-
- labels = dns_name_countlabels(name) -
- dns_name_countlabels(&db->origin);
- dns_name_init(&relname, NULL);
- dns_name_getlabelsequence(name, 0, labels, &relname);
- result = dns_name_totext(&relname, ISC_TRUE, &b);
- if (result != ISC_R_SUCCESS)
- return (result);
- } else {
- result = dns_name_totext(name, ISC_TRUE, &b);
- if (result != ISC_R_SUCCESS)
- return (result);
- }
- isc_buffer_putuint8(&b, 0);
-
- isc_buffer_init(&b2, zonestr, sizeof(zonestr));
- result = dns_name_totext(&sdlz->common.origin, ISC_TRUE, &b2);
- if (result != ISC_R_SUCCESS)
- return (result);
- isc_buffer_putuint8(&b2, 0);
-
- result = createnode(sdlz, &node);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- isorigin = dns_name_equal(name, &sdlz->common.origin);
-
- /* make sure strings are always lowercase */
- dns_sdlz_tolower(zonestr);
- dns_sdlz_tolower(namestr);
-
- MAYBE_LOCK(sdlz->dlzimp);
-
- /* try to lookup the host (namestr) */
- result = sdlz->dlzimp->methods->lookup(zonestr, namestr,
- sdlz->dlzimp->driverarg,
- sdlz->dbdata, node,
- methods, clientinfo);
-
- /*
- * if the host (namestr) was not found, try to lookup a
- * "wildcard" host.
- */
- if (result != ISC_R_SUCCESS && !create)
- result = sdlz->dlzimp->methods->lookup(zonestr, "*",
- sdlz->dlzimp->driverarg,
- sdlz->dbdata, node,
- methods, clientinfo);
-
- MAYBE_UNLOCK(sdlz->dlzimp);
-
- if (result != ISC_R_SUCCESS && !isorigin && !create) {
- destroynode(node);
- return (result);
- }
-
- if (isorigin && sdlz->dlzimp->methods->authority != NULL) {
- MAYBE_LOCK(sdlz->dlzimp);
- authority = sdlz->dlzimp->methods->authority;
- result = (*authority)(zonestr, sdlz->dlzimp->driverarg,
- sdlz->dbdata, node);
- MAYBE_UNLOCK(sdlz->dlzimp);
- if (result != ISC_R_SUCCESS &&
- result != ISC_R_NOTIMPLEMENTED) {
- destroynode(node);
- return (result);
- }
- }
-
- 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);
-}
-
-static isc_result_t
-findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
- dns_dbnode_t **nodep)
-{
- return (findnodeext(db, name, create, NULL, NULL, nodep));
-}
-
-static isc_result_t
-findzonecut(dns_db_t *db, dns_name_t *name, unsigned int options,
- isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname,
- dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
-{
- UNUSED(db);
- UNUSED(name);
- UNUSED(options);
- UNUSED(now);
- UNUSED(nodep);
- UNUSED(foundname);
- UNUSED(rdataset);
- UNUSED(sigrdataset);
-
- return (ISC_R_NOTIMPLEMENTED);
-}
-
-static void
-attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) {
- dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
- dns_sdlznode_t *node = (dns_sdlznode_t *)source;
-
- REQUIRE(VALID_SDLZDB(sdlz));
-
- UNUSED(sdlz);
-
- LOCK(&node->lock);
- INSIST(node->references > 0);
- node->references++;
- INSIST(node->references != 0); /* Catch overflow. */
- UNLOCK(&node->lock);
-
- *targetp = source;
-}
-
-static void
-detachnode(dns_db_t *db, dns_dbnode_t **targetp) {
- dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
- dns_sdlznode_t *node;
- isc_boolean_t need_destroy = ISC_FALSE;
-
- REQUIRE(VALID_SDLZDB(sdlz));
- REQUIRE(targetp != NULL && *targetp != NULL);
-
- UNUSED(sdlz);
-
- node = (dns_sdlznode_t *)(*targetp);
-
- 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);
-
- *targetp = NULL;
-}
-
-static isc_result_t
-expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) {
- UNUSED(db);
- UNUSED(node);
- UNUSED(now);
- INSIST(0);
- return (ISC_R_UNEXPECTED);
-}
-
-static void
-printnode(dns_db_t *db, dns_dbnode_t *node, FILE *out) {
- UNUSED(db);
- UNUSED(node);
- UNUSED(out);
- return;
-}
-
-static isc_result_t
-createiterator(dns_db_t *db, unsigned int options, dns_dbiterator_t **iteratorp)
-{
- dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
- sdlz_dbiterator_t *sdlziter;
- isc_result_t result;
- isc_buffer_t b;
- char zonestr[DNS_NAME_MAXTEXT + 1];
-
- REQUIRE(VALID_SDLZDB(sdlz));
-
- if (sdlz->dlzimp->methods->allnodes == NULL)
- return (ISC_R_NOTIMPLEMENTED);
-
- if ((options & DNS_DB_NSEC3ONLY) != 0 ||
- (options & DNS_DB_NONSEC3) != 0)
- return (ISC_R_NOTIMPLEMENTED);
-
- isc_buffer_init(&b, zonestr, sizeof(zonestr));
- result = dns_name_totext(&sdlz->common.origin, ISC_TRUE, &b);
- if (result != ISC_R_SUCCESS)
- return (result);
- isc_buffer_putuint8(&b, 0);
-
- sdlziter = isc_mem_get(sdlz->common.mctx, sizeof(sdlz_dbiterator_t));
- if (sdlziter == NULL)
- return (ISC_R_NOMEMORY);
-
- sdlziter->common.methods = &dbiterator_methods;
- sdlziter->common.db = NULL;
- dns_db_attach(db, &sdlziter->common.db);
- sdlziter->common.relative_names = ISC_TF(options & DNS_DB_RELATIVENAMES);
- sdlziter->common.magic = DNS_DBITERATOR_MAGIC;
- ISC_LIST_INIT(sdlziter->nodelist);
- sdlziter->current = NULL;
- sdlziter->origin = NULL;
-
- /* make sure strings are always lowercase */
- dns_sdlz_tolower(zonestr);
-
- MAYBE_LOCK(sdlz->dlzimp);
- result = sdlz->dlzimp->methods->allnodes(zonestr,
- sdlz->dlzimp->driverarg,
- sdlz->dbdata, sdlziter);
- MAYBE_UNLOCK(sdlz->dlzimp);
- if (result != ISC_R_SUCCESS) {
- dns_dbiterator_t *iter = &sdlziter->common;
- dbiterator_destroy(&iter);
- return (result);
- }
-
- if (sdlziter->origin != NULL) {
- ISC_LIST_UNLINK(sdlziter->nodelist, sdlziter->origin, link);
- ISC_LIST_PREPEND(sdlziter->nodelist, sdlziter->origin, link);
- }
-
- *iteratorp = (dns_dbiterator_t *)sdlziter;
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
- dns_rdatatype_t type, dns_rdatatype_t covers,
- isc_stdtime_t now, dns_rdataset_t *rdataset,
- dns_rdataset_t *sigrdataset)
-{
- dns_rdatalist_t *list;
- dns_sdlznode_t *sdlznode = (dns_sdlznode_t *)node;
-
- REQUIRE(VALID_SDLZNODE(node));
-
- UNUSED(db);
- UNUSED(version);
- UNUSED(covers);
- UNUSED(now);
- UNUSED(sigrdataset);
-
- if (type == dns_rdatatype_sig || type == dns_rdatatype_rrsig)
- return (ISC_R_NOTIMPLEMENTED);
-
- list = ISC_LIST_HEAD(sdlznode->lists);
- while (list != NULL) {
- if (list->type == type)
- break;
- list = ISC_LIST_NEXT(list, link);
- }
- if (list == NULL)
- return (ISC_R_NOTFOUND);
-
- list_tordataset(list, db, node, rdataset);
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
- dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
- dns_dbnode_t **nodep, dns_name_t *foundname,
- dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo,
- dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
-{
- dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
- dns_dbnode_t *node = NULL;
- dns_fixedname_t fname;
- dns_rdataset_t xrdataset;
- dns_name_t *xname;
- unsigned int nlabels, olabels;
- isc_result_t result;
- unsigned int i;
-
- REQUIRE(VALID_SDLZDB(sdlz));
- REQUIRE(nodep == NULL || *nodep == NULL);
- REQUIRE(version == NULL || version == (void*)&sdlz->dummy_version);
-
- UNUSED(options);
- UNUSED(sdlz);
-
- if (!dns_name_issubdomain(name, &db->origin))
- return (DNS_R_NXDOMAIN);
-
- olabels = dns_name_countlabels(&db->origin);
- nlabels = dns_name_countlabels(name);
-
- dns_fixedname_init(&fname);
- xname = dns_fixedname_name(&fname);
-
- if (rdataset == NULL) {
- dns_rdataset_init(&xrdataset);
- rdataset = &xrdataset;
- }
-
- result = DNS_R_NXDOMAIN;
-
- for (i = olabels; i <= nlabels; i++) {
- /*
- * Look up the next label.
- */
- dns_name_getlabelsequence(name, nlabels - i, i, xname);
- result = findnodeext(db, xname, ISC_FALSE,
- methods, clientinfo, &node);
- if (result != ISC_R_SUCCESS) {
- result = DNS_R_NXDOMAIN;
- continue;
- }
-
- /*
- * Look for a DNAME at the current label, unless this is
- * the qname.
- */
- if (i < nlabels) {
- result = findrdataset(db, node, version,
- dns_rdatatype_dname, 0, now,
- rdataset, sigrdataset);
- if (result == ISC_R_SUCCESS) {
- result = DNS_R_DNAME;
- break;
- }
- }
-
- /*
- * Look for an NS at the current label, unless this is the
- * origin or glue is ok.
- */
- if (i != olabels && (options & DNS_DBFIND_GLUEOK) == 0) {
- result = findrdataset(db, node, version,
- dns_rdatatype_ns, 0, now,
- rdataset, sigrdataset);
- if (result == ISC_R_SUCCESS) {
- if (i == nlabels && type == dns_rdatatype_any)
- {
- result = DNS_R_ZONECUT;
- dns_rdataset_disassociate(rdataset);
- if (sigrdataset != NULL &&
- dns_rdataset_isassociated
- (sigrdataset)) {
- dns_rdataset_disassociate
- (sigrdataset);
- }
- } else
- result = DNS_R_DELEGATION;
- break;
- }
- }
-
- /*
- * If the current name is not the qname, add another label
- * and try again.
- */
- if (i < nlabels) {
- destroynode(node);
- node = NULL;
- continue;
- }
-
- /*
- * If we're looking for ANY, we're done.
- */
- if (type == dns_rdatatype_any) {
- result = ISC_R_SUCCESS;
- break;
- }
-
- /*
- * Look for the qtype.
- */
- result = findrdataset(db, node, version, type, 0, now,
- rdataset, sigrdataset);
- if (result == ISC_R_SUCCESS)
- break;
-
- /*
- * Look for a CNAME
- */
- if (type != dns_rdatatype_cname) {
- result = findrdataset(db, node, version,
- dns_rdatatype_cname, 0, now,
- rdataset, sigrdataset);
- if (result == ISC_R_SUCCESS) {
- result = DNS_R_CNAME;
- break;
- }
- }
-
- result = DNS_R_NXRRSET;
- break;
- }
-
- if (rdataset == &xrdataset && dns_rdataset_isassociated(rdataset))
- dns_rdataset_disassociate(rdataset);
-
- if (foundname != NULL) {
- isc_result_t xresult;
-
- xresult = dns_name_copy(xname, foundname, NULL);
- if (xresult != ISC_R_SUCCESS) {
- if (node != NULL)
- destroynode(node);
- if (dns_rdataset_isassociated(rdataset))
- dns_rdataset_disassociate(rdataset);
- return (DNS_R_BADDB);
- }
- }
-
- if (nodep != NULL)
- *nodep = node;
- else if (node != NULL)
- detachnode(db, &node);
-
- return (result);
-}
-
-static isc_result_t
-find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
- dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
- dns_dbnode_t **nodep, dns_name_t *foundname,
- dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
-{
- return (findext(db, name, version, type, options, now, nodep,
- foundname, NULL, NULL, rdataset, sigrdataset));
-}
-
-static isc_result_t
-allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
- isc_stdtime_t now, dns_rdatasetiter_t **iteratorp)
-{
- dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *) db;
- sdlz_rdatasetiter_t *iterator;
-
- REQUIRE(VALID_SDLZDB(sdlz));
-
- REQUIRE(version == NULL ||
- version == (void*)&sdlz->dummy_version ||
- version == sdlz->future_version);
-
- UNUSED(version);
- UNUSED(now);
-
- iterator = isc_mem_get(db->mctx, sizeof(sdlz_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 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)
-{
- dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
- isc_result_t result;
-
- UNUSED(now);
- UNUSED(addedrdataset);
- REQUIRE(VALID_SDLZDB(sdlz));
-
- 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)
-{
- dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
- isc_result_t result;
-
- UNUSED(newrdataset);
- REQUIRE(VALID_SDLZDB(sdlz));
-
- 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)
-{
- 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);
-
- 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
-issecure(dns_db_t *db) {
- UNUSED(db);
-
- return (ISC_FALSE);
-}
-
-static unsigned int
-nodecount(dns_db_t *db) {
- UNUSED(db);
-
- return (0);
-}
-
-static isc_boolean_t
-ispersistent(dns_db_t *db) {
- UNUSED(db);
- return (ISC_TRUE);
-}
-
-static void
-overmem(dns_db_t *db, isc_boolean_t overmem) {
- UNUSED(db);
- UNUSED(overmem);
-}
-
-static void
-settask(dns_db_t *db, isc_task_t *task) {
- UNUSED(db);
- UNUSED(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 = findnodeext(db, &sdlz->common.origin, ISC_FALSE,
- NULL, NULL, nodep);
- if (result != ISC_R_SUCCESS)
- sdlz_log(ISC_LOG_ERROR, "sdlz getoriginnode failed : %s",
- isc_result_totext(result));
- return (result);
-}
-
-static dns_dbmethods_t sdlzdb_methods = {
- attach,
- detach,
- beginload,
- endload,
- dump,
- currentversion,
- newversion,
- attachversion,
- closeversion,
- findnode,
- find,
- findzonecut,
- attachnode,
- detachnode,
- expirenode,
- printnode,
- createiterator,
- findrdataset,
- allrdatasets,
- addrdataset,
- subtractrdataset,
- deleterdataset,
- issecure,
- nodecount,
- ispersistent,
- overmem,
- settask,
- getoriginnode,
- NULL, /* transfernode */
- NULL, /* getnsec3parameters */
- NULL, /* findnsec3node */
- NULL, /* setsigningtime */
- NULL, /* getsigningtime */
- NULL, /* resigned */
- NULL, /* isdnssec */
- NULL, /* getrrsetstats */
- NULL, /* rpz_enabled */
- NULL, /* rpz_findips */
- findnodeext,
- findext
-};
-
-/*
- * Database Iterator Methods. These methods were "borrowed" from the SDB
- * driver interface. See the SDB driver interface documentation for more info.
- */
-
-static void
-dbiterator_destroy(dns_dbiterator_t **iteratorp) {
- sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)(*iteratorp);
- dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)sdlziter->common.db;
-
- while (!ISC_LIST_EMPTY(sdlziter->nodelist)) {
- dns_sdlznode_t *node;
- node = ISC_LIST_HEAD(sdlziter->nodelist);
- ISC_LIST_UNLINK(sdlziter->nodelist, node, link);
- destroynode(node);
- }
-
- dns_db_detach(&sdlziter->common.db);
- isc_mem_put(sdlz->common.mctx, sdlziter, sizeof(sdlz_dbiterator_t));
-
- *iteratorp = NULL;
-}
-
-static isc_result_t
-dbiterator_first(dns_dbiterator_t *iterator) {
- sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator;
-
- sdlziter->current = ISC_LIST_HEAD(sdlziter->nodelist);
- if (sdlziter->current == NULL)
- return (ISC_R_NOMORE);
- else
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-dbiterator_last(dns_dbiterator_t *iterator) {
- sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator;
-
- sdlziter->current = ISC_LIST_TAIL(sdlziter->nodelist);
- if (sdlziter->current == NULL)
- return (ISC_R_NOMORE);
- else
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name) {
- sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator;
-
- sdlziter->current = ISC_LIST_HEAD(sdlziter->nodelist);
- while (sdlziter->current != NULL) {
- if (dns_name_equal(sdlziter->current->name, name))
- return (ISC_R_SUCCESS);
- sdlziter->current = ISC_LIST_NEXT(sdlziter->current, link);
- }
- return (ISC_R_NOTFOUND);
-}
-
-static isc_result_t
-dbiterator_prev(dns_dbiterator_t *iterator) {
- sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator;
-
- sdlziter->current = ISC_LIST_PREV(sdlziter->current, link);
- if (sdlziter->current == NULL)
- return (ISC_R_NOMORE);
- else
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-dbiterator_next(dns_dbiterator_t *iterator) {
- sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator;
-
- sdlziter->current = ISC_LIST_NEXT(sdlziter->current, link);
- if (sdlziter->current == NULL)
- return (ISC_R_NOMORE);
- else
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep,
- dns_name_t *name)
-{
- sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator;
-
- attachnode(iterator->db, sdlziter->current, nodep);
- if (name != NULL)
- return (dns_name_copy(sdlziter->current->name, name, NULL));
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-dbiterator_pause(dns_dbiterator_t *iterator) {
- UNUSED(iterator);
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-dbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name) {
- UNUSED(iterator);
- return (dns_name_copy(dns_rootname, name, NULL));
-}
-
-/*
- * Rdataset Methods. These methods were "borrowed" from the SDB driver
- * interface. See the SDB driver interface documentation for more info.
- */
-
-static void
-disassociate(dns_rdataset_t *rdataset) {
- dns_dbnode_t *node = rdataset->private5;
- dns_sdlznode_t *sdlznode = (dns_sdlznode_t *) node;
- dns_db_t *db = (dns_db_t *) sdlznode->sdlz;
-
- detachnode(db, &node);
- isc__rdatalist_disassociate(rdataset);
-}
-
-static void
-rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
- dns_dbnode_t *node = source->private5;
- dns_sdlznode_t *sdlznode = (dns_sdlznode_t *) node;
- dns_db_t *db = (dns_db_t *) sdlznode->sdlz;
- dns_dbnode_t *tempdb = NULL;
-
- isc__rdatalist_clone(source, target);
- attachnode(db, node, &tempdb);
- source->private5 = tempdb;
-}
-
-static dns_rdatasetmethods_t rdataset_methods = {
- disassociate,
- isc__rdatalist_first,
- isc__rdatalist_next,
- isc__rdatalist_current,
- rdataset_clone,
- isc__rdatalist_count,
- isc__rdatalist_addnoqname,
- isc__rdatalist_getnoqname,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-static void
-list_tordataset(dns_rdatalist_t *rdatalist,
- dns_db_t *db, dns_dbnode_t *node,
- dns_rdataset_t *rdataset)
-{
- /*
- * The sdlz rdataset is an rdatalist with some additions.
- * - private1 & private2 are used by the rdatalist.
- * - private3 & private 4 are unused.
- * - private5 is the node.
- */
-
- /* This should never fail. */
- RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) ==
- ISC_R_SUCCESS);
-
- rdataset->methods = &rdataset_methods;
- dns_db_attachnode(db, node, &rdataset->private5);
-}
-
-/*
- * SDLZ core methods. This is the core of the new DLZ functionality.
- */
-
-/*%
- * Build a 'bind' database driver structure to be returned by
- * either the find zone or the allow zone transfer method.
- * This method is only available in this source file, it is
- * not made available anywhere else.
- */
-
-static isc_result_t
-dns_sdlzcreateDBP(isc_mem_t *mctx, void *driverarg, void *dbdata,
- dns_name_t *name, dns_rdataclass_t rdclass, dns_db_t **dbp)
-{
- isc_result_t result;
- dns_sdlz_db_t *sdlzdb;
- dns_sdlzimplementation_t *imp;
-
- /* check that things are as we expect */
- REQUIRE(dbp != NULL && *dbp == NULL);
- REQUIRE(name != NULL);
-
- imp = (dns_sdlzimplementation_t *) driverarg;
-
- /* allocate and zero memory for driver structure */
- sdlzdb = isc_mem_get(mctx, sizeof(dns_sdlz_db_t));
- if (sdlzdb == NULL)
- return (ISC_R_NOMEMORY);
- memset(sdlzdb, 0, sizeof(dns_sdlz_db_t));
-
- /* initialize and set origin */
- dns_name_init(&sdlzdb->common.origin, NULL);
- result = dns_name_dupwithoffsets(name, mctx, &sdlzdb->common.origin);
- if (result != ISC_R_SUCCESS)
- goto mem_cleanup;
-
- /* initialize the reference count mutex */
- result = isc_mutex_init(&sdlzdb->refcnt_lock);
- if (result != ISC_R_SUCCESS)
- goto name_cleanup;
-
- /* set the rest of the database structure attributes */
- sdlzdb->dlzimp = imp;
- sdlzdb->common.methods = &sdlzdb_methods;
- sdlzdb->common.attributes = 0;
- sdlzdb->common.rdclass = rdclass;
- sdlzdb->common.mctx = NULL;
- sdlzdb->dbdata = dbdata;
- sdlzdb->references = 1;
-
- /* attach to the memory context */
- isc_mem_attach(mctx, &sdlzdb->common.mctx);
-
- /* mark structure as valid */
- sdlzdb->common.magic = DNS_DB_MAGIC;
- sdlzdb->common.impmagic = SDLZDB_MAGIC;
- *dbp = (dns_db_t *) sdlzdb;
-
- return (result);
-
- /*
- * reference count mutex could not be initialized, clean up
- * name memory
- */
- name_cleanup:
- dns_name_free(&sdlzdb->common.origin, mctx);
- mem_cleanup:
- isc_mem_put(mctx, sdlzdb, sizeof(dns_sdlz_db_t));
- return (result);
-}
-
-static isc_result_t
-dns_sdlzallowzonexfr(void *driverarg, void *dbdata, isc_mem_t *mctx,
- dns_rdataclass_t rdclass, dns_name_t *name,
- isc_sockaddr_t *clientaddr, dns_db_t **dbp)
-{
- isc_buffer_t b;
- isc_buffer_t b2;
- char namestr[DNS_NAME_MAXTEXT + 1];
- char clientstr[(sizeof "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")
- + 1];
- isc_netaddr_t netaddr;
- isc_result_t result;
- dns_sdlzimplementation_t *imp;
-
- /*
- * Perform checks to make sure data is as we expect it to be.
- */
- REQUIRE(driverarg != NULL);
- REQUIRE(name != NULL);
- REQUIRE(clientaddr != NULL);
- REQUIRE(dbp != NULL && *dbp == NULL);
-
- imp = (dns_sdlzimplementation_t *) driverarg;
-
- /* Convert DNS name to ascii text */
- isc_buffer_init(&b, namestr, sizeof(namestr));
- result = dns_name_totext(name, ISC_TRUE, &b);
- if (result != ISC_R_SUCCESS)
- return (result);
- isc_buffer_putuint8(&b, 0);
-
- /* convert client address to ascii text */
- isc_buffer_init(&b2, clientstr, sizeof(clientstr));
- isc_netaddr_fromsockaddr(&netaddr, clientaddr);
- result = isc_netaddr_totext(&netaddr, &b2);
- if (result != ISC_R_SUCCESS)
- return (result);
- isc_buffer_putuint8(&b2, 0);
-
- /* make sure strings are always lowercase */
- dns_sdlz_tolower(namestr);
- dns_sdlz_tolower(clientstr);
-
- /* Call SDLZ driver's find zone method */
- if (imp->methods->allowzonexfr != NULL) {
- MAYBE_LOCK(imp);
- result = imp->methods->allowzonexfr(imp->driverarg, dbdata,
- namestr, clientstr);
- MAYBE_UNLOCK(imp);
- /*
- * if zone is supported and transfers allowed build a 'bind'
- * database driver
- */
- if (result == ISC_R_SUCCESS)
- result = dns_sdlzcreateDBP(mctx, driverarg, dbdata,
- name, rdclass, dbp);
- return (result);
- }
-
- return (ISC_R_NOTIMPLEMENTED);
-}
-
-static isc_result_t
-dns_sdlzcreate(isc_mem_t *mctx, const char *dlzname, unsigned int argc,
- char *argv[], void *driverarg, void **dbdata)
-{
- dns_sdlzimplementation_t *imp;
- isc_result_t result = ISC_R_NOTFOUND;
-
- /* Write debugging message to log */
- sdlz_log(ISC_LOG_DEBUG(2), "Loading SDLZ driver.");
-
- /*
- * Performs checks to make sure data is as we expect it to be.
- */
- REQUIRE(driverarg != NULL);
- REQUIRE(dlzname != NULL);
- REQUIRE(dbdata != NULL);
- UNUSED(mctx);
-
- imp = driverarg;
-
- /* If the create method exists, call it. */
- if (imp->methods->create != NULL) {
- MAYBE_LOCK(imp);
- result = imp->methods->create(dlzname, argc, argv,
- imp->driverarg, dbdata);
- MAYBE_UNLOCK(imp);
- }
-
- /* Write debugging message to log */
- if (result == ISC_R_SUCCESS) {
- sdlz_log(ISC_LOG_DEBUG(2), "SDLZ driver loaded successfully.");
- } else {
- sdlz_log(ISC_LOG_ERROR, "SDLZ driver failed to load.");
- }
-
- return (result);
-}
-
-static void
-dns_sdlzdestroy(void *driverdata, void **dbdata)
-{
-
- dns_sdlzimplementation_t *imp;
-
- /* Write debugging message to log */
- sdlz_log(ISC_LOG_DEBUG(2), "Unloading SDLZ driver.");
-
- imp = driverdata;
-
- /* If the destroy method exists, call it. */
- if (imp->methods->destroy != NULL) {
- MAYBE_LOCK(imp);
- imp->methods->destroy(imp->driverarg, dbdata);
- MAYBE_UNLOCK(imp);
- }
-}
-
-static isc_result_t
-dns_sdlzfindzone(void *driverarg, void *dbdata, isc_mem_t *mctx,
- dns_rdataclass_t rdclass, dns_name_t *name, dns_db_t **dbp)
-{
- isc_buffer_t b;
- char namestr[DNS_NAME_MAXTEXT + 1];
- isc_result_t result;
- dns_sdlzimplementation_t *imp;
-
- /*
- * Perform checks to make sure data is as we expect it to be.
- */
- REQUIRE(driverarg != NULL);
- REQUIRE(name != NULL);
- REQUIRE(dbp != NULL && *dbp == NULL);
-
- imp = (dns_sdlzimplementation_t *) driverarg;
-
- /* Convert DNS name to ascii text */
- isc_buffer_init(&b, namestr, sizeof(namestr));
- result = dns_name_totext(name, ISC_TRUE, &b);
- if (result != ISC_R_SUCCESS)
- return (result);
- isc_buffer_putuint8(&b, 0);
-
- /* make sure strings are always lowercase */
- dns_sdlz_tolower(namestr);
-
- /* Call SDLZ driver's find zone method */
- MAYBE_LOCK(imp);
- result = imp->methods->findzone(imp->driverarg, dbdata, namestr);
- MAYBE_UNLOCK(imp);
-
- /*
- * if zone is supported build a 'bind' database driver
- * structure to return
- */
- if (result == ISC_R_SUCCESS)
- result = dns_sdlzcreateDBP(mctx, driverarg, dbdata, name,
- rdclass, dbp);
-
- 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 = NULL;
- 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 != NULL)
- 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 != NULL)
- 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 != NULL) {
- dst_key_format(key, b_key, sizeof(b_key));
- tkey_token = dst_key_tkeytoken(key);
- } else
- b_key[0] = 0;
-
- if (tkey_token != NULL) {
- 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 != 0 ? 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_sdlzconfigure,
- dns_sdlzssumatch
-};
-
-/*
- * Public functions.
- */
-
-isc_result_t
-dns_sdlz_putrr(dns_sdlzlookup_t *lookup, const char *type, dns_ttl_t ttl,
- const char *data)
-{
- dns_rdatalist_t *rdatalist;
- dns_rdata_t *rdata;
- dns_rdatatype_t typeval;
- isc_consttextregion_t r;
- isc_buffer_t b;
- isc_buffer_t *rdatabuf = NULL;
- isc_lex_t *lex;
- isc_result_t result;
- unsigned int size;
- isc_mem_t *mctx;
- dns_name_t *origin;
-
- REQUIRE(VALID_SDLZLOOKUP(lookup));
- REQUIRE(type != NULL);
- REQUIRE(data != NULL);
-
- mctx = lookup->sdlz->common.mctx;
-
- r.base = type;
- r.length = strlen(type);
- result = dns_rdatatype_fromtext(&typeval, (void *) &r);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- rdatalist = ISC_LIST_HEAD(lookup->lists);
- while (rdatalist != NULL) {
- if (rdatalist->type == typeval)
- break;
- rdatalist = ISC_LIST_NEXT(rdatalist, link);
- }
-
- if (rdatalist == NULL) {
- rdatalist = isc_mem_get(mctx, sizeof(dns_rdatalist_t));
- if (rdatalist == NULL)
- return (ISC_R_NOMEMORY);
- rdatalist->rdclass = lookup->sdlz->common.rdclass;
- rdatalist->type = typeval;
- rdatalist->covers = 0;
- rdatalist->ttl = ttl;
- ISC_LIST_INIT(rdatalist->rdata);
- ISC_LINK_INIT(rdatalist, link);
- ISC_LIST_APPEND(lookup->lists, rdatalist, link);
- } else
- 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)
- return (ISC_R_NOMEMORY);
- dns_rdata_init(rdata);
-
- if ((lookup->sdlz->dlzimp->flags & DNS_SDLZFLAG_RELATIVERDATA) != 0)
- origin = &lookup->sdlz->common.origin;
- else
- origin = dns_rootname;
-
- lex = NULL;
- result = isc_lex_create(mctx, 64, &lex);
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- size = initial_size(data);
- do {
- isc_buffer_constinit(&b, data, strlen(data));
- isc_buffer_add(&b, strlen(data));
-
- result = isc_lex_openbuffer(lex, &b);
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- rdatabuf = NULL;
- result = isc_buffer_allocate(mctx, &rdatabuf, size);
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- result = dns_rdata_fromtext(rdata, rdatalist->rdclass,
- rdatalist->type, lex,
- origin, ISC_FALSE,
- mctx, rdatabuf,
- &lookup->callbacks);
- if (result != ISC_R_SUCCESS)
- isc_buffer_free(&rdatabuf);
- if (size >= 65535)
- break;
- size *= 2;
- if (size >= 65535)
- size = 65535;
- } while (result == ISC_R_NOSPACE);
-
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
- ISC_LIST_APPEND(lookup->buffers, rdatabuf, link);
-
- if (lex != NULL)
- isc_lex_destroy(&lex);
-
- return (ISC_R_SUCCESS);
-
- failure:
- if (rdatabuf != NULL)
- isc_buffer_free(&rdatabuf);
- if (lex != NULL)
- isc_lex_destroy(&lex);
- isc_mem_put(mctx, rdata, sizeof(dns_rdata_t));
-
- return (result);
-}
-
-isc_result_t
-dns_sdlz_putnamedrr(dns_sdlzallnodes_t *allnodes, const char *name,
- const char *type, dns_ttl_t ttl, const char *data)
-{
- dns_name_t *newname, *origin;
- dns_fixedname_t fnewname;
- dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)allnodes->common.db;
- dns_sdlznode_t *sdlznode;
- isc_mem_t *mctx = sdlz->common.mctx;
- isc_buffer_t b;
- isc_result_t result;
-
- dns_fixedname_init(&fnewname);
- newname = dns_fixedname_name(&fnewname);
-
- if ((sdlz->dlzimp->flags & DNS_SDLZFLAG_RELATIVERDATA) != 0)
- origin = &sdlz->common.origin;
- else
- origin = dns_rootname;
- isc_buffer_constinit(&b, name, strlen(name));
- isc_buffer_add(&b, strlen(name));
-
- result = dns_name_fromtext(newname, &b, origin, 0, NULL);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- if (allnodes->common.relative_names) {
- /* All names are relative to the root */
- unsigned int nlabels = dns_name_countlabels(newname);
- dns_name_getlabelsequence(newname, 0, nlabels - 1, newname);
- }
-
- sdlznode = ISC_LIST_HEAD(allnodes->nodelist);
- if (sdlznode == NULL || !dns_name_equal(sdlznode->name, newname)) {
- sdlznode = NULL;
- result = createnode(sdlz, &sdlznode);
- if (result != ISC_R_SUCCESS)
- return (result);
- sdlznode->name = isc_mem_get(mctx, sizeof(dns_name_t));
- if (sdlznode->name == NULL) {
- destroynode(sdlznode);
- return (ISC_R_NOMEMORY);
- }
- dns_name_init(sdlznode->name, NULL);
- result = dns_name_dup(newname, mctx, sdlznode->name);
- if (result != ISC_R_SUCCESS) {
- isc_mem_put(mctx, sdlznode->name, sizeof(dns_name_t));
- destroynode(sdlznode);
- return (result);
- }
- ISC_LIST_PREPEND(allnodes->nodelist, sdlznode, link);
- if (allnodes->origin == NULL &&
- dns_name_equal(newname, &sdlz->common.origin))
- allnodes->origin = sdlznode;
- }
- return (dns_sdlz_putrr(sdlznode, type, ttl, data));
-
-}
-
-isc_result_t
-dns_sdlz_putsoa(dns_sdlzlookup_t *lookup, const char *mname, const char *rname,
- isc_uint32_t serial)
-{
- char str[2 * DNS_NAME_MAXTEXT + 5 * (sizeof("2147483647")) + 7];
- int n;
-
- REQUIRE(mname != NULL);
- REQUIRE(rname != NULL);
-
- n = snprintf(str, sizeof str, "%s %s %u %u %u %u %u",
- mname, rname, serial,
- SDLZ_DEFAULT_REFRESH, SDLZ_DEFAULT_RETRY,
- SDLZ_DEFAULT_EXPIRE, SDLZ_DEFAULT_MINIMUM);
- if (n >= (int)sizeof(str) || n < 0)
- return (ISC_R_NOSPACE);
- return (dns_sdlz_putrr(lookup, "SOA", SDLZ_DEFAULT_TTL, str));
-}
-
-isc_result_t
-dns_sdlzregister(const char *drivername, const dns_sdlzmethods_t *methods,
- void *driverarg, unsigned int flags, isc_mem_t *mctx,
- dns_sdlzimplementation_t **sdlzimp)
-{
-
- dns_sdlzimplementation_t *imp;
- isc_result_t result;
-
- /*
- * Performs checks to make sure data is as we expect it to be.
- */
- REQUIRE(drivername != NULL);
- REQUIRE(methods != NULL);
- REQUIRE(methods->findzone != NULL);
- REQUIRE(methods->lookup != NULL);
- REQUIRE(mctx != NULL);
- REQUIRE(sdlzimp != NULL && *sdlzimp == NULL);
- REQUIRE((flags & ~(DNS_SDLZFLAG_RELATIVEOWNER |
- DNS_SDLZFLAG_RELATIVERDATA |
- DNS_SDLZFLAG_THREADSAFE)) == 0);
-
- /* Write debugging message to log */
- sdlz_log(ISC_LOG_DEBUG(2), "Registering SDLZ driver '%s'", drivername);
-
- /*
- * Allocate memory for a sdlz_implementation object. Error if
- * we cannot.
- */
- imp = isc_mem_get(mctx, sizeof(dns_sdlzimplementation_t));
- if (imp == NULL)
- return (ISC_R_NOMEMORY);
-
- /* Make sure memory region is set to all 0's */
- memset(imp, 0, sizeof(dns_sdlzimplementation_t));
-
- /* Store the data passed into this method */
- imp->methods = methods;
- imp->driverarg = driverarg;
- imp->flags = flags;
- imp->mctx = NULL;
-
- /* attach the new sdlz_implementation object to a memory context */
- isc_mem_attach(mctx, &imp->mctx);
-
- /*
- * initialize the driver lock, error if we cannot
- * (used if a driver does not support multiple threads)
- */
- result = isc_mutex_init(&imp->driverlock);
- if (result != ISC_R_SUCCESS) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_mutex_init() failed: %s",
- isc_result_totext(result));
- goto cleanup_mctx;
- }
-
- imp->dlz_imp = NULL;
-
- /*
- * register the DLZ driver. Pass in our "extra" sdlz information as
- * a driverarg. (that's why we stored the passed in driver arg in our
- * sdlz_implementation structure) Also, store the dlz_implementation
- * structure in our sdlz_implementation.
- */
- result = dns_dlzregister(drivername, &sdlzmethods, imp, mctx,
- &imp->dlz_imp);
-
- /* if registration fails, cleanup and get outta here. */
- if (result != ISC_R_SUCCESS)
- goto cleanup_mutex;
-
- *sdlzimp = imp;
-
- return (ISC_R_SUCCESS);
-
- cleanup_mutex:
- /* destroy the driver lock, we don't need it anymore */
- DESTROYLOCK(&imp->driverlock);
-
- cleanup_mctx:
- /*
- * return the memory back to the available memory pool and
- * remove it from the memory context.
- */
- isc_mem_put(mctx, imp, sizeof(dns_sdlzimplementation_t));
- isc_mem_detach(&mctx);
- return (result);
-}
-
-void
-dns_sdlzunregister(dns_sdlzimplementation_t **sdlzimp) {
- dns_sdlzimplementation_t *imp;
- isc_mem_t *mctx;
-
- /* Write debugging message to log */
- sdlz_log(ISC_LOG_DEBUG(2), "Unregistering SDLZ driver.");
-
- /*
- * Performs checks to make sure data is as we expect it to be.
- */
- REQUIRE(sdlzimp != NULL && *sdlzimp != NULL);
-
- imp = *sdlzimp;
-
- /* Unregister the DLZ driver implementation */
- dns_dlzunregister(&imp->dlz_imp);
-
- /* destroy the driver lock, we don't need it anymore */
- DESTROYLOCK(&imp->driverlock);
-
- mctx = imp->mctx;
-
- /*
- * return the memory back to the available memory pool and
- * remove it from the memory context.
- */
- isc_mem_put(mctx, imp, sizeof(dns_sdlzimplementation_t));
- isc_mem_detach(&mctx);
-
- *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/contrib/bind9/lib/dns/soa.c b/contrib/bind9/lib/dns/soa.c
deleted file mode 100644
index 1b58bfec12d5..000000000000
--- a/contrib/bind9/lib/dns/soa.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $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
-decode_uint32(unsigned char *p) {
- return ((p[0] << 24) +
- (p[1] << 16) +
- (p[2] << 8) +
- (p[3] << 0));
-}
-
-static inline void
-encode_uint32(isc_uint32_t val, unsigned char *p) {
- p[0] = (isc_uint8_t)(val >> 24);
- p[1] = (isc_uint8_t)(val >> 16);
- p[2] = (isc_uint8_t)(val >> 8);
- p[3] = (isc_uint8_t)(val >> 0);
-}
-
-static isc_uint32_t
-soa_get(dns_rdata_t *rdata, int offset) {
- INSIST(rdata->type == dns_rdatatype_soa);
- /*
- * Locate the field within the SOA RDATA based
- * on its position relative to the end of the data.
- *
- * This is a bit of a kludge, but the alternative approach of
- * using dns_rdata_tostruct() and dns_rdata_fromstruct() would
- * involve a lot of unnecessary work (like building domain
- * names and allocating temporary memory) when all we really
- * want to do is to get 32 bits of fixed-sized data.
- */
- INSIST(rdata->length >= 20);
- INSIST(offset >= 0 && offset <= 16);
- 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);
-}
-isc_uint32_t
-dns_soa_getrefresh(dns_rdata_t *rdata) {
- return soa_get(rdata, 4);
-}
-isc_uint32_t
-dns_soa_getretry(dns_rdata_t *rdata) {
- return soa_get(rdata, 8);
-}
-isc_uint32_t
-dns_soa_getexpire(dns_rdata_t *rdata) {
- return soa_get(rdata, 12);
-}
-isc_uint32_t
-dns_soa_getminimum(dns_rdata_t *rdata) {
- return soa_get(rdata, 16);
-}
-
-static void
-soa_set(dns_rdata_t *rdata, isc_uint32_t val, int offset) {
- INSIST(rdata->type == dns_rdatatype_soa);
- INSIST(rdata->length >= 20);
- INSIST(offset >= 0 && offset <= 16);
- encode_uint32(val, rdata->data + rdata->length - 20 + offset);
-}
-
-void
-dns_soa_setserial(isc_uint32_t val, dns_rdata_t *rdata) {
- soa_set(rdata, val, 0);
-}
-void
-dns_soa_setrefresh(isc_uint32_t val, dns_rdata_t *rdata) {
- soa_set(rdata, val, 4);
-}
-void
-dns_soa_setretry(isc_uint32_t val, dns_rdata_t *rdata) {
- soa_set(rdata, val, 8);
-}
-void
-dns_soa_setexpire(isc_uint32_t val, dns_rdata_t *rdata) {
- soa_set(rdata, val, 12);
-}
-void
-dns_soa_setminimum(isc_uint32_t val, dns_rdata_t *rdata) {
- soa_set(rdata, val, 16);
-}
diff --git a/contrib/bind9/lib/dns/spnego.asn1 b/contrib/bind9/lib/dns/spnego.asn1
deleted file mode 100644
index 43d152bd4fca..000000000000
--- a/contrib/bind9/lib/dns/spnego.asn1
+++ /dev/null
@@ -1,52 +0,0 @@
--- Copyright (C) The Internet Society 2005. This version of
--- this module is part of RFC 4178; see the RFC itself for
--- full legal notices.
-
--- (The above copyright notice is per RFC 3978 5.6 (a), q.v.)
-
--- $Id: spnego.asn1,v 1.2 2006/12/04 01:52:46 marka Exp $
-
--- This is the SPNEGO ASN.1 module from RFC 4178, tweaked
--- to get the Heimdal ASN.1 compiler to accept it.
-
-SPNEGOASNOneSpec DEFINITIONS ::= BEGIN
-
-MechType ::= OBJECT IDENTIFIER
-
-MechTypeList ::= SEQUENCE OF MechType
-
-ContextFlags ::= BIT STRING {
- delegFlag (0),
- mutualFlag (1),
- replayFlag (2),
- sequenceFlag (3),
- anonFlag (4),
- confFlag (5),
- integFlag (6)
-}
-
-NegTokenInit ::= SEQUENCE {
- mechTypes [0] MechTypeList,
- reqFlags [1] ContextFlags OPTIONAL,
- mechToken [2] OCTET STRING OPTIONAL,
- mechListMIC [3] OCTET STRING OPTIONAL
-}
-
-NegTokenResp ::= SEQUENCE {
- negState [0] ENUMERATED {
- accept-completed (0),
- accept-incomplete (1),
- reject (2),
- request-mic (3)
- } OPTIONAL,
- supportedMech [1] MechType OPTIONAL,
- responseToken [2] OCTET STRING OPTIONAL,
- mechListMIC [3] OCTET STRING OPTIONAL
-}
-
-NegotiationToken ::= CHOICE {
- negTokenInit [0] NegTokenInit,
- negTokenResp [1] NegTokenResp
-}
-
-END
diff --git a/contrib/bind9/lib/dns/spnego.c b/contrib/bind9/lib/dns/spnego.c
deleted file mode 100644
index 0c1c8583650d..000000000000
--- a/contrib/bind9/lib/dns/spnego.c
+++ /dev/null
@@ -1,1820 +0,0 @@
-/*
- * Copyright (C) 2006-2013 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/*! \file
- * \brief
- * Portable SPNEGO implementation.
- *
- * This is part of a portable implementation of the SPNEGO protocol
- * (RFCs 2478 and 4178). This implementation uses the RFC 4178 ASN.1
- * module but is not a full implementation of the RFC 4178 protocol;
- * at the moment, we only support GSS-TSIG with Kerberos
- * authentication, so we only need enough of the SPNEGO protocol to
- * support that.
- *
- * The files that make up this portable SPNEGO implementation are:
- * \li spnego.c (this file)
- * \li spnego.h (API SPNEGO exports to the rest of lib/dns)
- * \li spnego.asn1 (SPNEGO ASN.1 module)
- * \li spnego_asn1.c (routines generated from spngo.asn1)
- * \li spnego_asn1.pl (perl script to generate spnego_asn1.c)
- *
- * Everything but the functions exported in spnego.h is static, to
- * avoid possible conflicts with other libraries (particularly Heimdal,
- * since much of this code comes from Heimdal by way of mod_auth_kerb).
- *
- * spnego_asn1.c is shipped as part of lib/dns because generating it
- * requires both Perl and the Heimdal ASN.1 compiler. See
- * spnego_asn1.pl for further details. We've tried to eliminate all
- * compiler warnings from the generated code, but you may see a few
- * when using a compiler version we haven't tested yet.
- */
-
-/*
- * Portions of this code were derived from mod_auth_kerb and Heimdal.
- * These packages are available from:
- *
- * http://modauthkerb.sourceforge.net/
- * http://www.pdc.kth.se/heimdal/
- *
- * and were released under the following licenses:
- *
- * ----------------------------------------------------------------
- *
- * Copyright (c) 2004 Masarykova universita
- * (Masaryk University, Brno, Czech Republic)
- * 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 University 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
- *
- * ----------------------------------------------------------------
- *
- * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * 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 Institute 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 INSTITUTE 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 INSTITUTE 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.
- */
-
-/*
- * XXXSRA We should omit this file entirely in Makefile.in via autoconf,
- * but this will keep it from generating errors until that's written.
- */
-
-#ifdef GSSAPI
-
-/*
- * XXXSRA Some of the following files are almost certainly unnecessary,
- * but using this list (borrowed from gssapictx.c) gets rid of some
- * whacky compilation errors when building with MSVC and should be
- * harmless in any case.
- */
-
-#include <config.h>
-
-#include <stdlib.h>
-#include <errno.h>
-
-#include <isc/buffer.h>
-#include <isc/dir.h>
-#include <isc/entropy.h>
-#include <isc/lex.h>
-#include <isc/mem.h>
-#include <isc/once.h>
-#include <isc/random.h>
-#include <isc/string.h>
-#include <isc/time.h>
-#include <isc/util.h>
-
-#include <dns/fixedname.h>
-#include <dns/name.h>
-#include <dns/rdata.h>
-#include <dns/rdataclass.h>
-#include <dns/result.h>
-#include <dns/types.h>
-#include <dns/keyvalues.h>
-#include <dns/log.h>
-
-#include <dst/gssapi.h>
-#include <dst/result.h>
-
-#include "dst_internal.h"
-
-/*
- * The API we export
- */
-#include "spnego.h"
-
-/* 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,
- ASN1_MISPLACED_FIELD = 1859794434,
- ASN1_TYPE_MISMATCH = 1859794435,
- ASN1_OVERFLOW = 1859794436,
- ASN1_OVERRUN = 1859794437,
- ASN1_BAD_ID = 1859794438,
- ASN1_BAD_LENGTH = 1859794439,
- ASN1_BAD_FORMAT = 1859794440,
- ASN1_PARSE_ERROR = 1859794441
-} asn1_error_number;
-
-#define ERROR_TABLE_BASE_asn1 1859794432
-#endif
-
-#define __asn1_common_definitions__
-
-typedef struct octet_string {
- size_t length;
- void *data;
-} octet_string;
-
-typedef char *general_string;
-
-typedef char *utf8_string;
-
-typedef struct oid {
- size_t length;
- unsigned *components;
-} oid;
-
-/* der.h */
-
-typedef enum {
- ASN1_C_UNIV = 0, ASN1_C_APPL = 1,
- ASN1_C_CONTEXT = 2, ASN1_C_PRIVATE = 3
-} Der_class;
-
-typedef enum {
- PRIM = 0, CONS = 1
-} Der_type;
-
-/* Universal tags */
-
-enum {
- UT_Boolean = 1,
- UT_Integer = 2,
- UT_BitString = 3,
- UT_OctetString = 4,
- UT_Null = 5,
- UT_OID = 6,
- UT_Enumerated = 10,
- UT_Sequence = 16,
- UT_Set = 17,
- UT_PrintableString = 19,
- UT_IA5String = 22,
- UT_UTCTime = 23,
- UT_GeneralizedTime = 24,
- UT_VisibleString = 26,
- UT_GeneralString = 27
-};
-
-#define ASN1_INDEFINITE 0xdce0deed
-
-static int
-der_get_length(const unsigned char *p, size_t len,
- size_t * val, size_t * size);
-
-static int
-der_get_octet_string(const unsigned char *p, size_t len,
- octet_string * data, size_t * size);
-static int
-der_get_oid(const unsigned char *p, size_t len,
- oid * data, size_t * size);
-static int
-der_get_tag(const unsigned char *p, size_t len,
- Der_class * class, Der_type * type,
- int *tag, size_t * size);
-
-static int
-der_match_tag(const unsigned char *p, size_t len,
- Der_class class, Der_type type,
- int tag, size_t * size);
-static int
-der_match_tag_and_length(const unsigned char *p, size_t len,
- Der_class class, Der_type type, int tag,
- size_t * length_ret, size_t * size);
-
-static int
-decode_oid(const unsigned char *p, size_t len,
- oid * k, size_t * size);
-
-static int
-decode_enumerated(const unsigned char *p, size_t len, void *num, size_t *size);
-
-static int
-decode_octet_string(const unsigned char *, size_t, octet_string *, size_t *);
-
-static int
-der_put_int(unsigned char *p, size_t len, int val, size_t *);
-
-static int
-der_put_length(unsigned char *p, size_t len, size_t val, size_t *);
-
-static int
-der_put_octet_string(unsigned char *p, size_t len,
- const octet_string * data, size_t *);
-static int
-der_put_oid(unsigned char *p, size_t len,
- const oid * data, size_t * size);
-static int
-der_put_tag(unsigned char *p, size_t len, Der_class class, Der_type type,
- int tag, size_t *);
-static int
-der_put_length_and_tag(unsigned char *, size_t, size_t,
- Der_class, Der_type, int, size_t *);
-
-static int
-encode_enumerated(unsigned char *p, size_t len, const void *data, size_t *);
-
-static int
-encode_octet_string(unsigned char *p, size_t len,
- const octet_string * k, size_t *);
-static int
-encode_oid(unsigned char *p, size_t len,
- const oid * k, size_t *);
-
-static void
-free_octet_string(octet_string * k);
-
-static void
-free_oid (oid * k);
-
-static size_t
-length_len(size_t len);
-
-static int
-fix_dce(size_t reallen, size_t * len);
-
-/*
- * Include stuff generated by the ASN.1 compiler.
- */
-
-#include "spnego_asn1.c"
-
-static unsigned char gss_krb5_mech_oid_bytes[] = {
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02
-};
-
-static gss_OID_desc gss_krb5_mech_oid_desc = {
- sizeof(gss_krb5_mech_oid_bytes),
- gss_krb5_mech_oid_bytes
-};
-
-static gss_OID GSS_KRB5_MECH = &gss_krb5_mech_oid_desc;
-
-static unsigned char gss_mskrb5_mech_oid_bytes[] = {
- 0x2a, 0x86, 0x48, 0x82, 0xf7, 0x12, 0x01, 0x02, 0x02
-};
-
-static gss_OID_desc gss_mskrb5_mech_oid_desc = {
- sizeof(gss_mskrb5_mech_oid_bytes),
- gss_mskrb5_mech_oid_bytes
-};
-
-static gss_OID GSS_MSKRB5_MECH = &gss_mskrb5_mech_oid_desc;
-
-static unsigned char gss_spnego_mech_oid_bytes[] = {
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x02
-};
-
-static gss_OID_desc gss_spnego_mech_oid_desc = {
- sizeof(gss_spnego_mech_oid_bytes),
- gss_spnego_mech_oid_bytes
-};
-
-static gss_OID GSS_SPNEGO_MECH = &gss_spnego_mech_oid_desc;
-
-/* spnegokrb5_locl.h */
-
-static OM_uint32
-gssapi_spnego_encapsulate(OM_uint32 *,
- unsigned char *,
- size_t,
- gss_buffer_t,
- const gss_OID);
-
-static OM_uint32
-gssapi_spnego_decapsulate(OM_uint32 *,
- gss_buffer_t,
- unsigned char **,
- size_t *,
- const gss_OID);
-
-/* mod_auth_kerb.c */
-
-static int
-cmp_gss_type(gss_buffer_t token, gss_OID oid)
-{
- unsigned char *p;
- size_t len;
-
- if (token->length == 0U)
- return (GSS_S_DEFECTIVE_TOKEN);
-
- p = token->value;
- if (*p++ != 0x60)
- return (GSS_S_DEFECTIVE_TOKEN);
- len = *p++;
- if (len & 0x80) {
- if ((len & 0x7f) > 4U)
- return (GSS_S_DEFECTIVE_TOKEN);
- p += len & 0x7f;
- }
- if (*p++ != 0x06)
- return (GSS_S_DEFECTIVE_TOKEN);
-
- if (((OM_uint32) *p++) != oid->length)
- return (GSS_S_DEFECTIVE_TOKEN);
-
- return (memcmp(p, oid->elements, oid->length));
-}
-
-/* accept_sec_context.c */
-/*
- * SPNEGO wrapper for Kerberos5 GSS-API kouril@ics.muni.cz, 2003 (mostly
- * based on Heimdal code)
- */
-
-static OM_uint32
-code_NegTokenArg(OM_uint32 * minor_status,
- const NegTokenResp * resp,
- unsigned char **outbuf,
- size_t * outbuf_size)
-{
- OM_uint32 ret;
- u_char *buf;
- size_t buf_size, buf_len = 0;
-
- buf_size = 1024;
- buf = malloc(buf_size);
- if (buf == NULL) {
- *minor_status = ENOMEM;
- return (GSS_S_FAILURE);
- }
- do {
- ret = encode_NegTokenResp(buf + buf_size - 1,
- buf_size,
- resp, &buf_len);
- if (ret == 0) {
- size_t tmp;
-
- ret = der_put_length_and_tag(buf + buf_size - buf_len - 1,
- buf_size - buf_len,
- buf_len,
- ASN1_C_CONTEXT,
- CONS,
- 1,
- &tmp);
- if (ret == 0)
- buf_len += tmp;
- }
- if (ret) {
- if (ret == ASN1_OVERFLOW) {
- u_char *tmp;
-
- buf_size *= 2;
- tmp = realloc(buf, buf_size);
- if (tmp == NULL) {
- *minor_status = ENOMEM;
- free(buf);
- return (GSS_S_FAILURE);
- }
- buf = tmp;
- } else {
- *minor_status = ret;
- free(buf);
- return (GSS_S_FAILURE);
- }
- }
- } while (ret == ASN1_OVERFLOW);
-
- *outbuf = malloc(buf_len);
- if (*outbuf == NULL) {
- *minor_status = ENOMEM;
- free(buf);
- return (GSS_S_FAILURE);
- }
- memcpy(*outbuf, buf + buf_size - buf_len, buf_len);
- *outbuf_size = buf_len;
-
- free(buf);
-
- return (GSS_S_COMPLETE);
-}
-
-static OM_uint32
-send_reject(OM_uint32 * minor_status,
- gss_buffer_t output_token)
-{
- NegTokenResp resp;
- OM_uint32 ret;
-
- resp.negState = malloc(sizeof(*resp.negState));
- if (resp.negState == NULL) {
- *minor_status = ENOMEM;
- return (GSS_S_FAILURE);
- }
- *(resp.negState) = reject;
-
- resp.supportedMech = NULL;
- resp.responseToken = NULL;
- resp.mechListMIC = NULL;
-
- ret = code_NegTokenArg(minor_status, &resp,
- (unsigned char **)&output_token->value,
- &output_token->length);
- free_NegTokenResp(&resp);
- if (ret)
- return (ret);
-
- return (GSS_S_BAD_MECH);
-}
-
-static OM_uint32
-send_accept(OM_uint32 * minor_status,
- gss_buffer_t output_token,
- gss_buffer_t mech_token,
- const gss_OID pref)
-{
- NegTokenResp resp;
- OM_uint32 ret;
-
- memset(&resp, 0, sizeof(resp));
- resp.negState = malloc(sizeof(*resp.negState));
- if (resp.negState == NULL) {
- *minor_status = ENOMEM;
- return (GSS_S_FAILURE);
- }
- *(resp.negState) = accept_completed;
-
- resp.supportedMech = malloc(sizeof(*resp.supportedMech));
- if (resp.supportedMech == NULL) {
- free_NegTokenResp(&resp);
- *minor_status = ENOMEM;
- return (GSS_S_FAILURE);
- }
- ret = der_get_oid(pref->elements,
- pref->length,
- resp.supportedMech,
- NULL);
- if (ret) {
- free_NegTokenResp(&resp);
- *minor_status = ENOMEM;
- return (GSS_S_FAILURE);
- }
- if (mech_token != NULL && mech_token->length != 0U) {
- resp.responseToken = malloc(sizeof(*resp.responseToken));
- if (resp.responseToken == NULL) {
- free_NegTokenResp(&resp);
- *minor_status = ENOMEM;
- return (GSS_S_FAILURE);
- }
- resp.responseToken->length = mech_token->length;
- resp.responseToken->data = mech_token->value;
- }
-
- ret = code_NegTokenArg(minor_status, &resp,
- (unsigned char **)&output_token->value,
- &output_token->length);
- if (resp.responseToken != NULL) {
- free(resp.responseToken);
- resp.responseToken = NULL;
- }
- free_NegTokenResp(&resp);
- if (ret)
- return (ret);
-
- return (GSS_S_COMPLETE);
-}
-
-OM_uint32
-gss_accept_sec_context_spnego(OM_uint32 *minor_status,
- gss_ctx_id_t *context_handle,
- const gss_cred_id_t acceptor_cred_handle,
- const gss_buffer_t input_token_buffer,
- const gss_channel_bindings_t input_chan_bindings,
- gss_name_t *src_name,
- gss_OID *mech_type,
- gss_buffer_t output_token,
- OM_uint32 *ret_flags,
- OM_uint32 *time_rec,
- gss_cred_id_t *delegated_cred_handle)
-{
- NegTokenInit init_token;
- OM_uint32 major_status;
- OM_uint32 minor_status2;
- gss_buffer_desc ibuf, obuf;
- gss_buffer_t ot = NULL;
- gss_OID pref = GSS_KRB5_MECH;
- unsigned char *buf;
- size_t buf_size;
- size_t len, taglen, ni_len;
- int found = 0;
- int ret;
- unsigned i;
-
- /*
- * Before doing anything else, see whether this is a SPNEGO
- * PDU. If not, dispatch to the GSSAPI library and get out.
- */
-
- if (cmp_gss_type(input_token_buffer, GSS_SPNEGO_MECH))
- return (gss_accept_sec_context(minor_status,
- context_handle,
- acceptor_cred_handle,
- input_token_buffer,
- input_chan_bindings,
- src_name,
- mech_type,
- output_token,
- ret_flags,
- time_rec,
- delegated_cred_handle));
-
- /*
- * If we get here, it's SPNEGO.
- */
-
- memset(&init_token, 0, sizeof(init_token));
-
- ret = gssapi_spnego_decapsulate(minor_status, input_token_buffer,
- &buf, &buf_size, GSS_SPNEGO_MECH);
- if (ret)
- return (ret);
-
- ret = der_match_tag_and_length(buf, buf_size, ASN1_C_CONTEXT, CONS,
- 0, &len, &taglen);
- if (ret)
- return (ret);
-
- ret = decode_NegTokenInit(buf + taglen, len, &init_token, &ni_len);
- if (ret) {
- *minor_status = EINVAL; /* XXX */
- return (GSS_S_DEFECTIVE_TOKEN);
- }
-
- for (i = 0; !found && i < init_token.mechTypes.len; ++i) {
- unsigned char mechbuf[17];
- size_t mech_len;
-
- ret = der_put_oid(mechbuf + sizeof(mechbuf) - 1,
- sizeof(mechbuf),
- &init_token.mechTypes.val[i],
- &mech_len);
- if (ret) {
- free_NegTokenInit(&init_token);
- return (GSS_S_DEFECTIVE_TOKEN);
- }
- if (mech_len == GSS_KRB5_MECH->length &&
- memcmp(GSS_KRB5_MECH->elements,
- mechbuf + sizeof(mechbuf) - mech_len,
- mech_len) == 0) {
- found = 1;
- break;
- }
- if (mech_len == GSS_MSKRB5_MECH->length &&
- memcmp(GSS_MSKRB5_MECH->elements,
- mechbuf + sizeof(mechbuf) - mech_len,
- mech_len) == 0) {
- found = 1;
- if (i == 0)
- pref = GSS_MSKRB5_MECH;
- break;
- }
- }
-
- if (!found) {
- free_NegTokenInit(&init_token);
- return (send_reject(minor_status, output_token));
- }
-
- if (i == 0 && init_token.mechToken != NULL) {
- ibuf.length = init_token.mechToken->length;
- ibuf.value = init_token.mechToken->data;
-
- major_status = gss_accept_sec_context(minor_status,
- context_handle,
- acceptor_cred_handle,
- &ibuf,
- input_chan_bindings,
- src_name,
- mech_type,
- &obuf,
- ret_flags,
- time_rec,
- delegated_cred_handle);
- if (GSS_ERROR(major_status)) {
- free_NegTokenInit(&init_token);
- send_reject(&minor_status2, output_token);
- return (major_status);
- }
- ot = &obuf;
- }
- ret = send_accept(&minor_status2, output_token, ot, pref);
- free_NegTokenInit(&init_token);
- if (ot != NULL && ot->length != 0U)
- gss_release_buffer(&minor_status2, ot);
-
- return (ret);
-}
-
-/* decapsulate.c */
-
-static OM_uint32
-gssapi_verify_mech_header(u_char ** str,
- size_t total_len,
- const gss_OID mech)
-{
- size_t len, len_len, mech_len, foo;
- int e;
- u_char *p = *str;
-
- if (total_len < 1U)
- return (GSS_S_DEFECTIVE_TOKEN);
- if (*p++ != 0x60)
- return (GSS_S_DEFECTIVE_TOKEN);
- e = der_get_length(p, total_len - 1, &len, &len_len);
- if (e || 1 + len_len + len != total_len)
- return (GSS_S_DEFECTIVE_TOKEN);
- p += len_len;
- if (*p++ != 0x06)
- return (GSS_S_DEFECTIVE_TOKEN);
- e = der_get_length(p, total_len - 1 - len_len - 1,
- &mech_len, &foo);
- if (e)
- return (GSS_S_DEFECTIVE_TOKEN);
- p += foo;
- if (mech_len != mech->length)
- return (GSS_S_BAD_MECH);
- if (memcmp(p, mech->elements, mech->length) != 0)
- return (GSS_S_BAD_MECH);
- p += mech_len;
- *str = p;
- return (GSS_S_COMPLETE);
-}
-
-/*
- * Remove the GSS-API wrapping from `in_token' giving `buf and buf_size' Does
- * not copy data, so just free `in_token'.
- */
-
-static OM_uint32
-gssapi_spnego_decapsulate(OM_uint32 *minor_status,
- gss_buffer_t input_token_buffer,
- unsigned char **buf,
- size_t *buf_len,
- const gss_OID mech)
-{
- u_char *p;
- OM_uint32 ret;
-
- p = input_token_buffer->value;
- ret = gssapi_verify_mech_header(&p,
- input_token_buffer->length,
- mech);
- if (ret) {
- *minor_status = ret;
- return (GSS_S_FAILURE);
- }
- *buf_len = input_token_buffer->length -
- (p - (u_char *) input_token_buffer->value);
- *buf = p;
- return (GSS_S_COMPLETE);
-}
-
-/* der_free.c */
-
-static void
-free_octet_string(octet_string *k)
-{
- free(k->data);
- k->data = NULL;
-}
-
-static void
-free_oid(oid *k)
-{
- free(k->components);
- k->components = NULL;
-}
-
-/* der_get.c */
-
-/*
- * All decoding functions take a pointer `p' to first position in which to
- * read, from the left, `len' which means the maximum number of characters we
- * are able to read, `ret' were the value will be returned and `size' where
- * the number of used bytes is stored. Either 0 or an error code is returned.
- */
-
-static int
-der_get_unsigned(const unsigned char *p, size_t len,
- unsigned *ret, size_t *size)
-{
- unsigned val = 0;
- size_t oldlen = len;
-
- while (len--)
- val = val * 256 + *p++;
- *ret = val;
- if (size)
- *size = oldlen;
- return (0);
-}
-
-static int
-der_get_int(const unsigned char *p, size_t len,
- int *ret, size_t *size)
-{
- int val = 0;
- size_t oldlen = len;
-
- if (len > 0U) {
- val = (signed char)*p++;
- while (--len)
- val = val * 256 + *p++;
- }
- *ret = val;
- if (size)
- *size = oldlen;
- return (0);
-}
-
-static int
-der_get_length(const unsigned char *p, size_t len,
- size_t *val, size_t *size)
-{
- size_t v;
-
- if (len <= 0U)
- return (ASN1_OVERRUN);
- --len;
- v = *p++;
- if (v < 128U) {
- *val = v;
- if (size)
- *size = 1;
- } else {
- int e;
- size_t l;
- unsigned tmp;
-
- if (v == 0x80U) {
- *val = ASN1_INDEFINITE;
- if (size)
- *size = 1;
- return (0);
- }
- v &= 0x7F;
- if (len < v)
- return (ASN1_OVERRUN);
- e = der_get_unsigned(p, v, &tmp, &l);
- if (e)
- return (e);
- *val = tmp;
- if (size)
- *size = l + 1;
- }
- return (0);
-}
-
-static int
-der_get_octet_string(const unsigned char *p, size_t len,
- octet_string *data, size_t *size)
-{
- data->length = len;
- if (len != 0U) {
- data->data = malloc(len);
- if (data->data == NULL)
- return (ENOMEM);
- memcpy(data->data, p, len);
- } else
- data->data = NULL;
- if (size)
- *size = len;
- return (0);
-}
-
-static int
-der_get_oid(const unsigned char *p, size_t len,
- oid *data, size_t *size)
-{
- int n;
- size_t oldlen = len;
-
- data->components = NULL;
- data->length = 0;
- if (len < 1U)
- return (ASN1_OVERRUN);
-
- data->components = malloc(len * sizeof(*data->components));
- if (data->components == NULL && len != 0U)
- return (ENOMEM);
- data->components[0] = (*p) / 40;
- data->components[1] = (*p) % 40;
- --len;
- ++p;
- for (n = 2; len > 0U; ++n) {
- unsigned u = 0;
-
- do {
- --len;
- u = u * 128 + (*p++ % 128);
- } while (len > 0U && p[-1] & 0x80);
- data->components[n] = u;
- }
- if (p[-1] & 0x80) {
- free_oid(data);
- return (ASN1_OVERRUN);
- }
- data->length = n;
- if (size)
- *size = oldlen;
- return (0);
-}
-
-static int
-der_get_tag(const unsigned char *p, size_t len,
- Der_class *class, Der_type *type,
- int *tag, size_t *size)
-{
- if (len < 1U)
- return (ASN1_OVERRUN);
- *class = (Der_class) (((*p) >> 6) & 0x03);
- *type = (Der_type) (((*p) >> 5) & 0x01);
- *tag = (*p) & 0x1F;
- if (size)
- *size = 1;
- return (0);
-}
-
-static int
-der_match_tag(const unsigned char *p, size_t len,
- Der_class class, Der_type type,
- int tag, size_t *size)
-{
- size_t l;
- Der_class thisclass;
- Der_type thistype;
- int thistag;
- int e;
-
- e = der_get_tag(p, len, &thisclass, &thistype, &thistag, &l);
- if (e)
- return (e);
- if (class != thisclass || type != thistype)
- return (ASN1_BAD_ID);
- if (tag > thistag)
- return (ASN1_MISPLACED_FIELD);
- if (tag < thistag)
- return (ASN1_MISSING_FIELD);
- if (size)
- *size = l;
- return (0);
-}
-
-static int
-der_match_tag_and_length(const unsigned char *p, size_t len,
- Der_class class, Der_type type, int tag,
- size_t *length_ret, size_t *size)
-{
- size_t l, ret = 0;
- int e;
-
- e = der_match_tag(p, len, class, type, tag, &l);
- if (e)
- return (e);
- p += l;
- len -= l;
- ret += l;
- e = der_get_length(p, len, length_ret, &l);
- if (e)
- return (e);
- /* p += l; */
- len -= l;
- POST(len);
- ret += l;
- if (size)
- *size = ret;
- return (0);
-}
-
-static int
-decode_enumerated(const unsigned char *p, size_t len, void *num, size_t *size)
-{
- size_t ret = 0;
- size_t l, reallen;
- int e;
-
- e = der_match_tag(p, len, ASN1_C_UNIV, PRIM, UT_Enumerated, &l);
- if (e)
- return (e);
- p += l;
- len -= l;
- ret += l;
- e = der_get_length(p, len, &reallen, &l);
- if (e)
- return (e);
- p += l;
- len -= l;
- ret += l;
- e = der_get_int(p, reallen, num, &l);
- if (e)
- return (e);
- p += l;
- len -= l;
- POST(p); POST(len);
- ret += l;
- if (size)
- *size = ret;
- return (0);
-}
-
-static int
-decode_octet_string(const unsigned char *p, size_t len,
- octet_string *k, size_t *size)
-{
- size_t ret = 0;
- size_t l;
- int e;
- size_t slen;
-
- k->data = NULL;
- k->length = 0;
-
- e = der_match_tag(p, len, ASN1_C_UNIV, PRIM, UT_OctetString, &l);
- if (e)
- return (e);
- p += l;
- len -= l;
- ret += l;
-
- e = der_get_length(p, len, &slen, &l);
- if (e)
- return (e);
- p += l;
- len -= l;
- ret += l;
- if (len < slen)
- return (ASN1_OVERRUN);
-
- e = der_get_octet_string(p, slen, k, &l);
- if (e)
- return (e);
- p += l;
- len -= l;
- POST(p); POST(len);
- ret += l;
- if (size)
- *size = ret;
- return (0);
-}
-
-static int
-decode_oid(const unsigned char *p, size_t len,
- oid *k, size_t *size)
-{
- size_t ret = 0;
- size_t l;
- int e;
- size_t slen;
-
- e = der_match_tag(p, len, ASN1_C_UNIV, PRIM, UT_OID, &l);
- if (e)
- return (e);
- p += l;
- len -= l;
- ret += l;
-
- e = der_get_length(p, len, &slen, &l);
- if (e)
- return (e);
- p += l;
- len -= l;
- ret += l;
- if (len < slen)
- return (ASN1_OVERRUN);
-
- e = der_get_oid(p, slen, k, &l);
- if (e)
- return (e);
- p += l;
- len -= l;
- POST(p); POST(len);
- ret += l;
- if (size)
- *size = ret;
- return (0);
-}
-
-static int
-fix_dce(size_t reallen, size_t *len)
-{
- if (reallen == ASN1_INDEFINITE)
- return (1);
- if (*len < reallen)
- return (-1);
- *len = reallen;
- return (0);
-}
-
-/* der_length.c */
-
-static size_t
-len_unsigned(unsigned val)
-{
- size_t ret = 0;
-
- do {
- ++ret;
- val /= 256;
- } while (val);
- return (ret);
-}
-
-static size_t
-length_len(size_t len)
-{
- if (len < 128U)
- return (1);
- else
- return (len_unsigned(len) + 1);
-}
-
-
-/* der_put.c */
-
-/*
- * All encoding functions take a pointer `p' to first position in which to
- * write, from the right, `len' which means the maximum number of characters
- * we are able to write. The function returns the number of characters
- * written in `size' (if non-NULL). The return value is 0 or an error.
- */
-
-static int
-der_put_unsigned(unsigned char *p, size_t len, unsigned val, size_t *size)
-{
- unsigned char *base = p;
-
- if (val) {
- while (len > 0U && val) {
- *p-- = val % 256;
- val /= 256;
- --len;
- }
- if (val != 0)
- return (ASN1_OVERFLOW);
- else {
- *size = base - p;
- return (0);
- }
- } else if (len < 1U)
- return (ASN1_OVERFLOW);
- else {
- *p = 0;
- *size = 1;
- return (0);
- }
-}
-
-static int
-der_put_int(unsigned char *p, size_t len, int val, size_t *size)
-{
- unsigned char *base = p;
-
- if (val >= 0) {
- do {
- if (len < 1U)
- return (ASN1_OVERFLOW);
- *p-- = val % 256;
- len--;
- val /= 256;
- } while (val);
- if (p[1] >= 128) {
- if (len < 1U)
- return (ASN1_OVERFLOW);
- *p-- = 0;
- len--;
- }
- } else {
- val = ~val;
- do {
- if (len < 1U)
- return (ASN1_OVERFLOW);
- *p-- = ~(val % 256);
- len--;
- val /= 256;
- } while (val);
- if (p[1] < 128) {
- if (len < 1U)
- return (ASN1_OVERFLOW);
- *p-- = 0xff;
- len--;
- }
- }
- *size = base - p;
- return (0);
-}
-
-static int
-der_put_length(unsigned char *p, size_t len, size_t val, size_t *size)
-{
- if (len < 1U)
- return (ASN1_OVERFLOW);
- if (val < 128U) {
- *p = val;
- *size = 1;
- return (0);
- } else {
- size_t l;
- int e;
-
- e = der_put_unsigned(p, len - 1, val, &l);
- if (e)
- return (e);
- p -= l;
- *p = 0x80 | l;
- *size = l + 1;
- return (0);
- }
-}
-
-static int
-der_put_octet_string(unsigned char *p, size_t len,
- const octet_string *data, size_t *size)
-{
- if (len < data->length)
- return (ASN1_OVERFLOW);
- p -= data->length;
- len -= data->length;
- POST(len);
- memcpy(p + 1, data->data, data->length);
- *size = data->length;
- return (0);
-}
-
-static int
-der_put_oid(unsigned char *p, size_t len,
- const oid *data, size_t *size)
-{
- unsigned char *base = p;
- int n;
-
- for (n = data->length - 1; n >= 2; --n) {
- unsigned u = data->components[n];
-
- if (len < 1U)
- return (ASN1_OVERFLOW);
- *p-- = u % 128;
- u /= 128;
- --len;
- while (u > 0) {
- if (len < 1U)
- return (ASN1_OVERFLOW);
- *p-- = 128 + u % 128;
- u /= 128;
- --len;
- }
- }
- if (len < 1U)
- return (ASN1_OVERFLOW);
- *p-- = 40 * data->components[0] + data->components[1];
- *size = base - p;
- return (0);
-}
-
-static int
-der_put_tag(unsigned char *p, size_t len, Der_class class, Der_type type,
- int tag, size_t *size)
-{
- if (len < 1U)
- return (ASN1_OVERFLOW);
- *p = (class << 6) | (type << 5) | tag; /* XXX */
- *size = 1;
- return (0);
-}
-
-static int
-der_put_length_and_tag(unsigned char *p, size_t len, size_t len_val,
- Der_class class, Der_type type, int tag, size_t *size)
-{
- size_t ret = 0;
- size_t l;
- int e;
-
- e = der_put_length(p, len, len_val, &l);
- if (e)
- return (e);
- p -= l;
- len -= l;
- ret += l;
- e = der_put_tag(p, len, class, type, tag, &l);
- if (e)
- return (e);
- p -= l;
- len -= l;
- POST(p); POST(len);
- ret += l;
- *size = ret;
- return (0);
-}
-
-static int
-encode_enumerated(unsigned char *p, size_t len, const void *data, size_t *size)
-{
- unsigned num = *(const unsigned *)data;
- size_t ret = 0;
- size_t l;
- int e;
-
- e = der_put_int(p, len, num, &l);
- if (e)
- return (e);
- p -= l;
- len -= l;
- ret += l;
- e = der_put_length_and_tag(p, len, l, ASN1_C_UNIV, PRIM, UT_Enumerated, &l);
- if (e)
- return (e);
- p -= l;
- len -= l;
- POST(p); POST(len);
- ret += l;
- *size = ret;
- return (0);
-}
-
-static int
-encode_octet_string(unsigned char *p, size_t len,
- const octet_string *k, size_t *size)
-{
- size_t ret = 0;
- size_t l;
- int e;
-
- e = der_put_octet_string(p, len, k, &l);
- if (e)
- return (e);
- p -= l;
- len -= l;
- ret += l;
- e = der_put_length_and_tag(p, len, l, ASN1_C_UNIV, PRIM, UT_OctetString, &l);
- if (e)
- return (e);
- p -= l;
- len -= l;
- POST(p); POST(len);
- ret += l;
- *size = ret;
- return (0);
-}
-
-static int
-encode_oid(unsigned char *p, size_t len,
- const oid *k, size_t *size)
-{
- size_t ret = 0;
- size_t l;
- int e;
-
- e = der_put_oid(p, len, k, &l);
- if (e)
- return (e);
- p -= l;
- len -= l;
- ret += l;
- e = der_put_length_and_tag(p, len, l, ASN1_C_UNIV, PRIM, UT_OID, &l);
- if (e)
- return (e);
- p -= l;
- len -= l;
- POST(p); POST(len);
- ret += l;
- *size = ret;
- return (0);
-}
-
-
-/* encapsulate.c */
-
-static void
-gssapi_encap_length(size_t data_len,
- size_t *len,
- size_t *total_len,
- const gss_OID mech)
-{
- size_t len_len;
-
- *len = 1 + 1 + mech->length + data_len;
-
- len_len = length_len(*len);
-
- *total_len = 1 + len_len + *len;
-}
-
-static u_char *
-gssapi_mech_make_header(u_char *p,
- size_t len,
- const gss_OID mech)
-{
- int e;
- size_t len_len, foo;
-
- *p++ = 0x60;
- len_len = length_len(len);
- e = der_put_length(p + len_len - 1, len_len, len, &foo);
- if (e || foo != len_len)
- return (NULL);
- p += len_len;
- *p++ = 0x06;
- *p++ = mech->length;
- memcpy(p, mech->elements, mech->length);
- p += mech->length;
- return (p);
-}
-
-/*
- * Give it a krb5_data and it will encapsulate with extra GSS-API wrappings.
- */
-
-static OM_uint32
-gssapi_spnego_encapsulate(OM_uint32 * minor_status,
- unsigned char *buf,
- size_t buf_size,
- gss_buffer_t output_token,
- const gss_OID mech)
-{
- size_t len, outer_len;
- u_char *p;
-
- gssapi_encap_length(buf_size, &len, &outer_len, mech);
-
- output_token->length = outer_len;
- output_token->value = malloc(outer_len);
- if (output_token->value == NULL) {
- *minor_status = ENOMEM;
- return (GSS_S_FAILURE);
- }
- p = gssapi_mech_make_header(output_token->value, len, mech);
- if (p == NULL) {
- if (output_token->length != 0U)
- gss_release_buffer(minor_status, output_token);
- return (GSS_S_FAILURE);
- }
- memcpy(p, buf, buf_size);
- return (GSS_S_COMPLETE);
-}
-
-/* init_sec_context.c */
-/*
- * SPNEGO wrapper for Kerberos5 GSS-API kouril@ics.muni.cz, 2003 (mostly
- * based on Heimdal code)
- */
-
-static int
-add_mech(MechTypeList * mech_list, gss_OID mech)
-{
- MechType *tmp;
- int ret;
-
- tmp = realloc(mech_list->val, (mech_list->len + 1) * sizeof(*tmp));
- if (tmp == NULL)
- return (ENOMEM);
- mech_list->val = tmp;
-
- ret = der_get_oid(mech->elements, mech->length,
- &mech_list->val[mech_list->len], NULL);
- if (ret)
- return (ret);
-
- mech_list->len++;
- return (0);
-}
-
-/*
- * return the length of the mechanism in token or -1
- * (which implies that the token was bad - GSS_S_DEFECTIVE_TOKEN
- */
-
-static ssize_t
-gssapi_krb5_get_mech(const u_char *ptr,
- size_t total_len,
- const u_char **mech_ret)
-{
- size_t len, len_len, mech_len, foo;
- const u_char *p = ptr;
- int e;
-
- if (total_len < 1U)
- return (-1);
- if (*p++ != 0x60)
- return (-1);
- e = der_get_length (p, total_len - 1, &len, &len_len);
- if (e || 1 + len_len + len != total_len)
- return (-1);
- p += len_len;
- if (*p++ != 0x06)
- return (-1);
- e = der_get_length (p, total_len - 1 - len_len - 1,
- &mech_len, &foo);
- if (e)
- return (-1);
- p += foo;
- *mech_ret = p;
- return (mech_len);
-}
-
-static OM_uint32
-spnego_initial(OM_uint32 *minor_status,
- const gss_cred_id_t initiator_cred_handle,
- gss_ctx_id_t *context_handle,
- const gss_name_t target_name,
- const gss_OID mech_type,
- OM_uint32 req_flags,
- OM_uint32 time_req,
- const gss_channel_bindings_t input_chan_bindings,
- const gss_buffer_t input_token,
- gss_OID *actual_mech_type,
- gss_buffer_t output_token,
- OM_uint32 *ret_flags,
- OM_uint32 *time_rec)
-{
- NegTokenInit token_init;
- OM_uint32 major_status, minor_status2;
- gss_buffer_desc krb5_output_token = GSS_C_EMPTY_BUFFER;
- unsigned char *buf = NULL;
- size_t buf_size;
- size_t len;
- int ret;
-
- (void)mech_type;
-
- memset(&token_init, 0, sizeof(token_init));
-
- ret = add_mech(&token_init.mechTypes, GSS_KRB5_MECH);
- if (ret) {
- *minor_status = ret;
- ret = GSS_S_FAILURE;
- goto end;
- }
-
- major_status = gss_init_sec_context(minor_status,
- initiator_cred_handle,
- context_handle,
- target_name,
- GSS_KRB5_MECH,
- req_flags,
- time_req,
- input_chan_bindings,
- input_token,
- actual_mech_type,
- &krb5_output_token,
- ret_flags,
- time_rec);
- if (GSS_ERROR(major_status)) {
- ret = major_status;
- goto end;
- }
- if (krb5_output_token.length > 0U) {
- token_init.mechToken = malloc(sizeof(*token_init.mechToken));
- if (token_init.mechToken == NULL) {
- *minor_status = ENOMEM;
- ret = GSS_S_FAILURE;
- goto end;
- }
- token_init.mechToken->data = krb5_output_token.value;
- token_init.mechToken->length = krb5_output_token.length;
- }
- /*
- * The MS implementation of SPNEGO seems to not like the mechListMIC
- * field, so we omit it (it's optional anyway)
- */
-
- buf_size = 1024;
- buf = malloc(buf_size);
- if (buf == NULL) {
- *minor_status = ENOMEM;
- ret = GSS_S_FAILURE;
- goto end;
- }
-
- do {
- ret = encode_NegTokenInit(buf + buf_size - 1,
- buf_size,
- &token_init, &len);
- if (ret == 0) {
- size_t tmp;
-
- ret = der_put_length_and_tag(buf + buf_size - len - 1,
- buf_size - len,
- len,
- ASN1_C_CONTEXT,
- CONS,
- 0,
- &tmp);
- if (ret == 0)
- len += tmp;
- }
- if (ret) {
- if (ret == ASN1_OVERFLOW) {
- u_char *tmp;
-
- buf_size *= 2;
- tmp = realloc(buf, buf_size);
- if (tmp == NULL) {
- *minor_status = ENOMEM;
- ret = GSS_S_FAILURE;
- goto end;
- }
- buf = tmp;
- } else {
- *minor_status = ret;
- ret = GSS_S_FAILURE;
- goto end;
- }
- }
- } while (ret == ASN1_OVERFLOW);
-
- ret = gssapi_spnego_encapsulate(minor_status,
- buf + buf_size - len, len,
- output_token, GSS_SPNEGO_MECH);
- if (ret == GSS_S_COMPLETE)
- ret = major_status;
-
-end:
- if (token_init.mechToken != NULL) {
- free(token_init.mechToken);
- token_init.mechToken = NULL;
- }
- free_NegTokenInit(&token_init);
- if (krb5_output_token.length != 0U)
- gss_release_buffer(&minor_status2, &krb5_output_token);
- if (buf)
- free(buf);
-
- return (ret);
-}
-
-static OM_uint32
-spnego_reply(OM_uint32 *minor_status,
- const gss_cred_id_t initiator_cred_handle,
- gss_ctx_id_t *context_handle,
- const gss_name_t target_name,
- const gss_OID mech_type,
- OM_uint32 req_flags,
- OM_uint32 time_req,
- const gss_channel_bindings_t input_chan_bindings,
- const gss_buffer_t input_token,
- gss_OID *actual_mech_type,
- gss_buffer_t output_token,
- OM_uint32 *ret_flags,
- OM_uint32 *time_rec)
-{
- OM_uint32 ret;
- NegTokenResp resp;
- unsigned char *buf;
- size_t buf_size;
- u_char oidbuf[17];
- size_t oidlen;
- gss_buffer_desc sub_token;
- ssize_t mech_len;
- const u_char *p;
- size_t len, taglen;
-
- (void)mech_type;
-
- output_token->length = 0;
- output_token->value = NULL;
-
- /*
- * SPNEGO doesn't include gss wrapping on SubsequentContextToken
- * like the Kerberos 5 mech does. But lets check for it anyway.
- */
-
- mech_len = gssapi_krb5_get_mech(input_token->value,
- input_token->length,
- &p);
-
- if (mech_len < 0) {
- buf = input_token->value;
- buf_size = input_token->length;
- } else if ((size_t)mech_len == GSS_KRB5_MECH->length &&
- memcmp(GSS_KRB5_MECH->elements, p, mech_len) == 0)
- return (gss_init_sec_context(minor_status,
- initiator_cred_handle,
- context_handle,
- target_name,
- GSS_KRB5_MECH,
- req_flags,
- time_req,
- input_chan_bindings,
- input_token,
- actual_mech_type,
- output_token,
- ret_flags,
- time_rec));
- else if ((size_t)mech_len == GSS_SPNEGO_MECH->length &&
- memcmp(GSS_SPNEGO_MECH->elements, p, mech_len) == 0) {
- ret = gssapi_spnego_decapsulate(minor_status,
- input_token,
- &buf,
- &buf_size,
- GSS_SPNEGO_MECH);
- if (ret)
- return (ret);
- } else
- return (GSS_S_BAD_MECH);
-
- ret = der_match_tag_and_length(buf, buf_size,
- ASN1_C_CONTEXT, CONS, 1, &len, &taglen);
- if (ret)
- return (ret);
-
- if(len > buf_size - taglen)
- return (ASN1_OVERRUN);
-
- ret = decode_NegTokenResp(buf + taglen, len, &resp, NULL);
- if (ret) {
- free_NegTokenResp(&resp);
- *minor_status = ENOMEM;
- return (GSS_S_FAILURE);
- }
-
- if (resp.negState == NULL ||
- *(resp.negState) == reject ||
- resp.supportedMech == NULL) {
- free_NegTokenResp(&resp);
- return (GSS_S_BAD_MECH);
- }
-
- ret = der_put_oid(oidbuf + sizeof(oidbuf) - 1,
- sizeof(oidbuf),
- resp.supportedMech,
- &oidlen);
- if (ret || oidlen != GSS_KRB5_MECH->length ||
- memcmp(oidbuf + sizeof(oidbuf) - oidlen,
- GSS_KRB5_MECH->elements,
- oidlen) != 0) {
- free_NegTokenResp(&resp);
- return GSS_S_BAD_MECH;
- }
-
- if (resp.responseToken != NULL) {
- sub_token.length = resp.responseToken->length;
- sub_token.value = resp.responseToken->data;
- } else {
- sub_token.length = 0;
- sub_token.value = NULL;
- }
-
- ret = gss_init_sec_context(minor_status,
- initiator_cred_handle,
- context_handle,
- target_name,
- GSS_KRB5_MECH,
- req_flags,
- time_req,
- input_chan_bindings,
- &sub_token,
- actual_mech_type,
- output_token,
- ret_flags,
- time_rec);
- if (ret) {
- free_NegTokenResp(&resp);
- return (ret);
- }
-
- /*
- * XXXSRA I don't think this limited implementation ever needs
- * to check the MIC -- our preferred mechanism (Kerberos)
- * authenticates its own messages and is the only mechanism
- * we'll accept, so if the mechanism negotiation completes
- * successfully, we don't need the MIC. See RFC 4178.
- */
-
- free_NegTokenResp(&resp);
- return (ret);
-}
-
-
-
-OM_uint32
-gss_init_sec_context_spnego(OM_uint32 *minor_status,
- const gss_cred_id_t initiator_cred_handle,
- gss_ctx_id_t *context_handle,
- const gss_name_t target_name,
- const gss_OID mech_type,
- OM_uint32 req_flags,
- OM_uint32 time_req,
- const gss_channel_bindings_t input_chan_bindings,
- const gss_buffer_t input_token,
- gss_OID *actual_mech_type,
- gss_buffer_t output_token,
- OM_uint32 *ret_flags,
- OM_uint32 *time_rec)
-{
- /* Dirty trick to suppress compiler warnings */
-
- /* Figure out whether we're starting over or processing a reply */
-
- if (input_token == GSS_C_NO_BUFFER || input_token->length == 0U)
- return (spnego_initial(minor_status,
- initiator_cred_handle,
- context_handle,
- target_name,
- mech_type,
- req_flags,
- time_req,
- input_chan_bindings,
- input_token,
- actual_mech_type,
- output_token,
- ret_flags,
- time_rec));
- else
- return (spnego_reply(minor_status,
- initiator_cred_handle,
- context_handle,
- target_name,
- mech_type,
- req_flags,
- time_req,
- input_chan_bindings,
- input_token,
- actual_mech_type,
- output_token,
- ret_flags,
- time_rec));
-}
-
-#endif /* GSSAPI */
diff --git a/contrib/bind9/lib/dns/spnego.h b/contrib/bind9/lib/dns/spnego.h
deleted file mode 100644
index c44614b43bed..000000000000
--- a/contrib/bind9/lib/dns/spnego.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2006, 2007 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: spnego.h,v 1.4 2007/06/19 23:47:16 tbox Exp $ */
-
-/*! \file
- * \brief
- * Entry points into portable SPNEGO implementation.
- * See spnego.c for information on the SPNEGO implementation itself.
- */
-
-#ifndef _SPNEGO_H_
-#define _SPNEGO_H_
-
-/*%
- * Wrapper for GSSAPI gss_init_sec_context(), using portable SPNEGO
- * implementation instead of the one that's part of the GSSAPI
- * library. Takes arguments identical to the standard GSSAPI
- * function, uses standard gss_init_sec_context() to handle
- * everything inside the SPNEGO wrapper.
- */
-OM_uint32
-gss_init_sec_context_spnego(OM_uint32 *,
- const gss_cred_id_t,
- gss_ctx_id_t *,
- const gss_name_t,
- const gss_OID,
- OM_uint32,
- OM_uint32,
- const gss_channel_bindings_t,
- const gss_buffer_t,
- gss_OID *,
- gss_buffer_t,
- OM_uint32 *,
- OM_uint32 *);
-
-/*%
- * Wrapper for GSSAPI gss_accept_sec_context(), using portable SPNEGO
- * implementation instead of the one that's part of the GSSAPI
- * library. Takes arguments identical to the standard GSSAPI
- * function. Checks the OID of the input token to see if it's SPNEGO;
- * if so, processes it, otherwise hands the call off to the standard
- * gss_accept_sec_context() function.
- */
-OM_uint32 gss_accept_sec_context_spnego(OM_uint32 *,
- gss_ctx_id_t *,
- const gss_cred_id_t,
- const gss_buffer_t,
- const gss_channel_bindings_t,
- gss_name_t *,
- gss_OID *,
- gss_buffer_t,
- OM_uint32 *,
- OM_uint32 *,
- gss_cred_id_t *);
-
-
-#endif
diff --git a/contrib/bind9/lib/dns/spnego_asn1.c b/contrib/bind9/lib/dns/spnego_asn1.c
deleted file mode 100644
index b50605456693..000000000000
--- a/contrib/bind9/lib/dns/spnego_asn1.c
+++ /dev/null
@@ -1,867 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2012, 2013 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: spnego_asn1.c,v 1.4 2007/06/19 23:47:16 tbox Exp $ */
-
-/*! \file
- * \brief Method routines generated from SPNEGO ASN.1 module.
- * See spnego_asn1.pl for details. Do not edit.
- */
-
-/* Generated from spnego.asn1 */
-/* Do not edit */
-
-#ifndef __asn1_h__
-#define __asn1_h__
-
-
-#ifndef __asn1_common_definitions__
-#define __asn1_common_definitions__
-
-typedef struct octet_string {
- size_t length;
- void *data;
-} octet_string;
-
-typedef char *general_string;
-
-typedef char *utf8_string;
-
-typedef struct oid {
- size_t length;
- unsigned *components;
-} oid;
-
-#define ASN1_MALLOC_ENCODE(T, B, BL, S, L, R) \
- do { \
- (BL) = length_##T((S)); \
- (B) = malloc((BL)); \
- if((B) == NULL) { \
- (R) = ENOMEM; \
- } else { \
- (R) = encode_##T(((unsigned char*)(B)) + (BL) - 1, (BL), \
- (S), (L)); \
- if((R) != 0) { \
- free((B)); \
- (B) = NULL; \
- } \
- } \
- } while (0)
-
-#endif
-
-/*
- * MechType ::= OBJECT IDENTIFIER
- */
-
-typedef oid MechType;
-
-static int encode_MechType(unsigned char *, size_t, const MechType *, size_t *);
-static int decode_MechType(const unsigned char *, size_t, MechType *, size_t *);
-static void free_MechType(MechType *);
-/* unused declaration: length_MechType */
-/* unused declaration: copy_MechType */
-
-
-/*
- * MechTypeList ::= SEQUENCE OF MechType
- */
-
-typedef struct MechTypeList {
- unsigned int len;
- MechType *val;
-} MechTypeList;
-
-static int encode_MechTypeList(unsigned char *, size_t, const MechTypeList *, size_t *);
-static int decode_MechTypeList(const unsigned char *, size_t, MechTypeList *, size_t *);
-static void free_MechTypeList(MechTypeList *);
-/* unused declaration: length_MechTypeList */
-/* unused declaration: copy_MechTypeList */
-
-
-/*
- * ContextFlags ::= BIT STRING { delegFlag(0), mutualFlag(1), replayFlag(2),
- * sequenceFlag(3), anonFlag(4), confFlag(5), integFlag(6) }
- */
-
-typedef struct ContextFlags {
- unsigned int delegFlag:1;
- unsigned int mutualFlag:1;
- unsigned int replayFlag:1;
- unsigned int sequenceFlag:1;
- unsigned int anonFlag:1;
- unsigned int confFlag:1;
- unsigned int integFlag:1;
-} ContextFlags;
-
-
-static int encode_ContextFlags(unsigned char *, size_t, const ContextFlags *, size_t *);
-static int decode_ContextFlags(const unsigned char *, size_t, ContextFlags *, size_t *);
-static void free_ContextFlags(ContextFlags *);
-/* unused declaration: length_ContextFlags */
-/* unused declaration: copy_ContextFlags */
-/* unused declaration: ContextFlags2int */
-/* unused declaration: int2ContextFlags */
-/* unused declaration: asn1_ContextFlags_units */
-
-/*
- * NegTokenInit ::= SEQUENCE { mechTypes[0] MechTypeList, reqFlags[1]
- * ContextFlags OPTIONAL, mechToken[2] OCTET STRING OPTIONAL,
- * mechListMIC[3] OCTET STRING OPTIONAL }
- */
-
-typedef struct NegTokenInit {
- MechTypeList mechTypes;
- ContextFlags *reqFlags;
- octet_string *mechToken;
- octet_string *mechListMIC;
-} NegTokenInit;
-
-static int encode_NegTokenInit(unsigned char *, size_t, const NegTokenInit *, size_t *);
-static int decode_NegTokenInit(const unsigned char *, size_t, NegTokenInit *, size_t *);
-static void free_NegTokenInit(NegTokenInit *);
-/* unused declaration: length_NegTokenInit */
-/* unused declaration: copy_NegTokenInit */
-
-
-/*
- * NegTokenResp ::= SEQUENCE { negState[0] ENUMERATED {
- * accept-completed(0), accept-incomplete(1), reject(2), request-mic(3) }
- * OPTIONAL, supportedMech[1] MechType OPTIONAL, responseToken[2] OCTET
- * STRING OPTIONAL, mechListMIC[3] OCTET STRING OPTIONAL }
- */
-
-typedef struct NegTokenResp {
- enum {
- accept_completed = 0,
- accept_incomplete = 1,
- reject = 2,
- request_mic = 3
- } *negState;
-
- MechType *supportedMech;
- octet_string *responseToken;
- octet_string *mechListMIC;
-} NegTokenResp;
-
-static int encode_NegTokenResp(unsigned char *, size_t, const NegTokenResp *, size_t *);
-static int decode_NegTokenResp(const unsigned char *, size_t, NegTokenResp *, size_t *);
-static void free_NegTokenResp(NegTokenResp *);
-/* unused declaration: length_NegTokenResp */
-/* unused declaration: copy_NegTokenResp */
-
-
-
-
-#endif /* __asn1_h__ */
-/* Generated from spnego.asn1 */
-/* Do not edit */
-
-
-#define BACK if (e) return e; p -= l; len -= l; ret += l; POST(p); POST(len); POST(ret)
-
-static int
-encode_MechType(unsigned char *p, size_t len, const MechType * data, size_t * size)
-{
- size_t ret = 0;
- size_t l;
- int e;
-
- e = encode_oid(p, len, data, &l);
- BACK;
- *size = ret;
- return 0;
-}
-
-#define FORW if(e) goto fail; p += l; len -= l; ret += l; POST(p); POST(len); POST(ret)
-
-static int
-decode_MechType(const unsigned char *p, size_t len, MechType * data, size_t * size)
-{
- size_t ret = 0;
- size_t l;
- int e;
-
- memset(data, 0, sizeof(*data));
- e = decode_oid(p, len, data, &l);
- FORW;
- if (size)
- *size = ret;
- return 0;
-fail:
- free_MechType(data);
- return e;
-}
-
-static void
-free_MechType(MechType * data)
-{
- free_oid(data);
-}
-
-/* unused function: length_MechType */
-
-
-/* unused function: copy_MechType */
-
-/* Generated from spnego.asn1 */
-/* Do not edit */
-
-
-static int
-encode_MechTypeList(unsigned char *p, size_t len, const MechTypeList * data, size_t * size)
-{
- size_t ret = 0;
- size_t l;
- int i, e;
-
- for (i = (data)->len - 1; i >= 0; --i) {
- int oldret = ret;
- ret = 0;
- e = encode_MechType(p, len, &(data)->val[i], &l);
- BACK;
- ret += oldret;
- }
- e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l);
- BACK;
- *size = ret;
- return 0;
-}
-
-static int
-decode_MechTypeList(const unsigned char *p, size_t len, MechTypeList * data, size_t * size)
-{
- size_t ret = 0, reallen;
- size_t l;
- int e;
-
- memset(data, 0, sizeof(*data));
- reallen = 0;
- e = der_match_tag_and_length(p, len, ASN1_C_UNIV, CONS, UT_Sequence, &reallen, &l);
- FORW;
- if (len < reallen)
- return ASN1_OVERRUN;
- len = reallen;
- {
- size_t origlen = len;
- int oldret = ret;
- ret = 0;
- (data)->len = 0;
- (data)->val = NULL;
- while (ret < origlen) {
- void *old = (data)->val;
- (data)->len++;
- (data)->val = realloc((data)->val, sizeof(*((data)->val)) * (data)->len);
- if ((data)->val == NULL) {
- (data)->val = old;
- (data)->len--;
- return ENOMEM;
- }
- e = decode_MechType(p, len, &(data)->val[(data)->len - 1], &l);
- FORW;
- len = origlen - ret;
- }
- ret += oldret;
- }
- if (size)
- *size = ret;
- return 0;
-fail:
- free_MechTypeList(data);
- return e;
-}
-
-static void
-free_MechTypeList(MechTypeList * data)
-{
- while ((data)->len) {
- free_MechType(&(data)->val[(data)->len - 1]);
- (data)->len--;
- }
- free((data)->val);
- (data)->val = NULL;
-}
-
-/* unused function: length_MechTypeList */
-
-
-/* unused function: copy_MechTypeList */
-
-/* Generated from spnego.asn1 */
-/* Do not edit */
-
-
-static int
-encode_ContextFlags(unsigned char *p, size_t len, const ContextFlags * data, size_t * size)
-{
- size_t ret = 0;
- size_t l;
- int e;
-
- {
- unsigned char c = 0;
- *p-- = c;
- len--;
- ret++;
- c = 0;
- *p-- = c;
- len--;
- ret++;
- c = 0;
- *p-- = c;
- len--;
- ret++;
- c = 0;
- if (data->integFlag)
- c |= 1 << 1;
- if (data->confFlag)
- c |= 1 << 2;
- if (data->anonFlag)
- c |= 1 << 3;
- if (data->sequenceFlag)
- c |= 1 << 4;
- if (data->replayFlag)
- c |= 1 << 5;
- if (data->mutualFlag)
- c |= 1 << 6;
- if (data->delegFlag)
- c |= 1 << 7;
- *p-- = c;
- *p-- = 0;
- len -= 2;
- ret += 2;
- }
-
- e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, PRIM, UT_BitString, &l);
- BACK;
- *size = ret;
- return 0;
-}
-
-static int
-decode_ContextFlags(const unsigned char *p, size_t len, ContextFlags * data, size_t * size)
-{
- size_t ret = 0, reallen;
- size_t l;
- int e;
-
- memset(data, 0, sizeof(*data));
- reallen = 0;
- e = der_match_tag_and_length(p, len, ASN1_C_UNIV, PRIM, UT_BitString, &reallen, &l);
- FORW;
- if (len < reallen)
- return ASN1_OVERRUN;
- p++;
- len--;
- reallen--;
- ret++;
- data->delegFlag = (*p >> 7) & 1;
- data->mutualFlag = (*p >> 6) & 1;
- data->replayFlag = (*p >> 5) & 1;
- data->sequenceFlag = (*p >> 4) & 1;
- data->anonFlag = (*p >> 3) & 1;
- data->confFlag = (*p >> 2) & 1;
- data->integFlag = (*p >> 1) & 1;
- ret += reallen;
- if (size)
- *size = ret;
- return 0;
-fail:
- free_ContextFlags(data);
- return e;
-}
-
-static void
-free_ContextFlags(ContextFlags * data)
-{
- (void)data;
-}
-
-/* unused function: length_ContextFlags */
-
-
-/* unused function: copy_ContextFlags */
-
-
-/* unused function: ContextFlags2int */
-
-
-/* unused function: int2ContextFlags */
-
-
-/* unused variable: ContextFlags_units */
-
-/* unused function: asn1_ContextFlags_units */
-
-/* Generated from spnego.asn1 */
-/* Do not edit */
-
-
-static int
-encode_NegTokenInit(unsigned char *p, size_t len, const NegTokenInit * data, size_t * size)
-{
- size_t ret = 0;
- size_t l;
- int e;
-
- if ((data)->mechListMIC) {
- int oldret = ret;
- ret = 0;
- e = encode_octet_string(p, len, (data)->mechListMIC, &l);
- BACK;
- e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 3, &l);
- BACK;
- ret += oldret;
- }
- if ((data)->mechToken) {
- int oldret = ret;
- ret = 0;
- e = encode_octet_string(p, len, (data)->mechToken, &l);
- BACK;
- e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 2, &l);
- BACK;
- ret += oldret;
- }
- if ((data)->reqFlags) {
- int oldret = ret;
- ret = 0;
- e = encode_ContextFlags(p, len, (data)->reqFlags, &l);
- BACK;
- e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 1, &l);
- BACK;
- ret += oldret;
- } {
- int oldret = ret;
- ret = 0;
- e = encode_MechTypeList(p, len, &(data)->mechTypes, &l);
- BACK;
- e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 0, &l);
- BACK;
- ret += oldret;
- }
- e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l);
- BACK;
- *size = ret;
- return 0;
-}
-
-static int
-decode_NegTokenInit(const unsigned char *p, size_t len, NegTokenInit * data, size_t * size)
-{
- size_t ret = 0, reallen;
- size_t l;
- int e;
-
- memset(data, 0, sizeof(*data));
- reallen = 0;
- e = der_match_tag_and_length(p, len, ASN1_C_UNIV, CONS, UT_Sequence, &reallen, &l);
- FORW;
- {
- int dce_fix;
- if ((dce_fix = fix_dce(reallen, &len)) < 0)
- return ASN1_BAD_FORMAT;
- {
- size_t newlen, oldlen;
-
- e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 0, &l);
- if (e)
- return e;
- else {
- p += l;
- len -= l;
- ret += l;
- e = der_get_length(p, len, &newlen, &l);
- FORW;
- {
- int dce_fix;
- oldlen = len;
- if ((dce_fix = fix_dce(newlen, &len)) < 0)
- return ASN1_BAD_FORMAT;
- e = decode_MechTypeList(p, len, &(data)->mechTypes, &l);
- FORW;
- if (dce_fix) {
- e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
- FORW;
- } else
- len = oldlen - newlen;
- }
- }
- }
- {
- size_t newlen, oldlen;
-
- e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 1, &l);
- if (e)
- (data)->reqFlags = NULL;
- else {
- p += l;
- len -= l;
- ret += l;
- e = der_get_length(p, len, &newlen, &l);
- FORW;
- {
- int dce_fix;
- oldlen = len;
- if ((dce_fix = fix_dce(newlen, &len)) < 0)
- return ASN1_BAD_FORMAT;
- (data)->reqFlags = malloc(sizeof(*(data)->reqFlags));
- if ((data)->reqFlags == NULL)
- return ENOMEM;
- e = decode_ContextFlags(p, len, (data)->reqFlags, &l);
- FORW;
- if (dce_fix) {
- e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
- FORW;
- } else
- len = oldlen - newlen;
- }
- }
- }
- {
- size_t newlen, oldlen;
-
- e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 2, &l);
- if (e)
- (data)->mechToken = NULL;
- else {
- p += l;
- len -= l;
- ret += l;
- e = der_get_length(p, len, &newlen, &l);
- FORW;
- {
- int dce_fix;
- oldlen = len;
- if ((dce_fix = fix_dce(newlen, &len)) < 0)
- return ASN1_BAD_FORMAT;
- (data)->mechToken = malloc(sizeof(*(data)->mechToken));
- if ((data)->mechToken == NULL)
- return ENOMEM;
- e = decode_octet_string(p, len, (data)->mechToken, &l);
- FORW;
- if (dce_fix) {
- e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
- FORW;
- } else
- len = oldlen - newlen;
- }
- }
- }
- {
- size_t newlen, oldlen;
-
- e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 3, &l);
- if (e)
- (data)->mechListMIC = NULL;
- else {
- p += l;
- len -= l;
- ret += l;
- e = der_get_length(p, len, &newlen, &l);
- FORW;
- {
- int dce_fix;
- oldlen = len;
- if ((dce_fix = fix_dce(newlen, &len)) < 0)
- return ASN1_BAD_FORMAT;
- (data)->mechListMIC = malloc(sizeof(*(data)->mechListMIC));
- if ((data)->mechListMIC == NULL)
- return ENOMEM;
- e = decode_octet_string(p, len, (data)->mechListMIC, &l);
- FORW;
- if (dce_fix) {
- e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
- FORW;
- } else
- len = oldlen - newlen;
- }
- }
- }
- if (dce_fix) {
- e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
- FORW;
- }
- }
- if (size)
- *size = ret;
- return 0;
-fail:
- free_NegTokenInit(data);
- return e;
-}
-
-static void
-free_NegTokenInit(NegTokenInit * data)
-{
- free_MechTypeList(&(data)->mechTypes);
- if ((data)->reqFlags) {
- free_ContextFlags((data)->reqFlags);
- free((data)->reqFlags);
- (data)->reqFlags = NULL;
- }
- if ((data)->mechToken) {
- free_octet_string((data)->mechToken);
- free((data)->mechToken);
- (data)->mechToken = NULL;
- }
- if ((data)->mechListMIC) {
- free_octet_string((data)->mechListMIC);
- free((data)->mechListMIC);
- (data)->mechListMIC = NULL;
- }
-}
-
-/* unused function: length_NegTokenInit */
-
-
-/* unused function: copy_NegTokenInit */
-
-/* Generated from spnego.asn1 */
-/* Do not edit */
-
-
-static int
-encode_NegTokenResp(unsigned char *p, size_t len, const NegTokenResp * data, size_t * size)
-{
- size_t ret = 0;
- size_t l;
- int e;
-
- if ((data)->mechListMIC) {
- int oldret = ret;
- ret = 0;
- e = encode_octet_string(p, len, (data)->mechListMIC, &l);
- BACK;
- e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 3, &l);
- BACK;
- ret += oldret;
- }
- if ((data)->responseToken) {
- int oldret = ret;
- ret = 0;
- e = encode_octet_string(p, len, (data)->responseToken, &l);
- BACK;
- e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 2, &l);
- BACK;
- ret += oldret;
- }
- if ((data)->supportedMech) {
- int oldret = ret;
- ret = 0;
- e = encode_MechType(p, len, (data)->supportedMech, &l);
- BACK;
- e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 1, &l);
- BACK;
- ret += oldret;
- }
- if ((data)->negState) {
- int oldret = ret;
- ret = 0;
- e = encode_enumerated(p, len, (data)->negState, &l);
- BACK;
- e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 0, &l);
- BACK;
- ret += oldret;
- }
- e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l);
- BACK;
- *size = ret;
- return 0;
-}
-
-static int
-decode_NegTokenResp(const unsigned char *p, size_t len, NegTokenResp * data, size_t * size)
-{
- size_t ret = 0, reallen;
- size_t l;
- int e;
-
- memset(data, 0, sizeof(*data));
- reallen = 0;
- e = der_match_tag_and_length(p, len, ASN1_C_UNIV, CONS, UT_Sequence, &reallen, &l);
- FORW;
- {
- int dce_fix;
- if ((dce_fix = fix_dce(reallen, &len)) < 0)
- return ASN1_BAD_FORMAT;
- {
- size_t newlen, oldlen;
-
- e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 0, &l);
- if (e)
- (data)->negState = NULL;
- else {
- p += l;
- len -= l;
- ret += l;
- e = der_get_length(p, len, &newlen, &l);
- FORW;
- {
- int dce_fix;
- oldlen = len;
- if ((dce_fix = fix_dce(newlen, &len)) < 0)
- return ASN1_BAD_FORMAT;
- (data)->negState = malloc(sizeof(*(data)->negState));
- if ((data)->negState == NULL)
- return ENOMEM;
- e = decode_enumerated(p, len, (data)->negState, &l);
- FORW;
- if (dce_fix) {
- e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
- FORW;
- } else
- len = oldlen - newlen;
- }
- }
- }
- {
- size_t newlen, oldlen;
-
- e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 1, &l);
- if (e)
- (data)->supportedMech = NULL;
- else {
- p += l;
- len -= l;
- ret += l;
- e = der_get_length(p, len, &newlen, &l);
- FORW;
- {
- int dce_fix;
- oldlen = len;
- if ((dce_fix = fix_dce(newlen, &len)) < 0)
- return ASN1_BAD_FORMAT;
- (data)->supportedMech = malloc(sizeof(*(data)->supportedMech));
- if ((data)->supportedMech == NULL)
- return ENOMEM;
- e = decode_MechType(p, len, (data)->supportedMech, &l);
- FORW;
- if (dce_fix) {
- e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
- FORW;
- } else
- len = oldlen - newlen;
- }
- }
- }
- {
- size_t newlen, oldlen;
-
- e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 2, &l);
- if (e)
- (data)->responseToken = NULL;
- else {
- p += l;
- len -= l;
- ret += l;
- e = der_get_length(p, len, &newlen, &l);
- FORW;
- {
- int dce_fix;
- oldlen = len;
- if ((dce_fix = fix_dce(newlen, &len)) < 0)
- return ASN1_BAD_FORMAT;
- (data)->responseToken = malloc(sizeof(*(data)->responseToken));
- if ((data)->responseToken == NULL)
- return ENOMEM;
- e = decode_octet_string(p, len, (data)->responseToken, &l);
- FORW;
- if (dce_fix) {
- e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
- FORW;
- } else
- len = oldlen - newlen;
- }
- }
- }
- {
- size_t newlen, oldlen;
-
- e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 3, &l);
- if (e)
- (data)->mechListMIC = NULL;
- else {
- p += l;
- len -= l;
- ret += l;
- e = der_get_length(p, len, &newlen, &l);
- FORW;
- {
- int dce_fix;
- oldlen = len;
- if ((dce_fix = fix_dce(newlen, &len)) < 0)
- return ASN1_BAD_FORMAT;
- (data)->mechListMIC = malloc(sizeof(*(data)->mechListMIC));
- if ((data)->mechListMIC == NULL)
- return ENOMEM;
- e = decode_octet_string(p, len, (data)->mechListMIC, &l);
- FORW;
- if (dce_fix) {
- e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
- FORW;
- } else
- len = oldlen - newlen;
- }
- }
- }
- if (dce_fix) {
- e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
- FORW;
- }
- }
- if (size)
- *size = ret;
- return 0;
-fail:
- free_NegTokenResp(data);
- return e;
-}
-
-static void
-free_NegTokenResp(NegTokenResp * data)
-{
- if ((data)->negState) {
- free((data)->negState);
- (data)->negState = NULL;
- }
- if ((data)->supportedMech) {
- free_MechType((data)->supportedMech);
- free((data)->supportedMech);
- (data)->supportedMech = NULL;
- }
- if ((data)->responseToken) {
- free_octet_string((data)->responseToken);
- free((data)->responseToken);
- (data)->responseToken = NULL;
- }
- if ((data)->mechListMIC) {
- free_octet_string((data)->mechListMIC);
- free((data)->mechListMIC);
- (data)->mechListMIC = NULL;
- }
-}
-
-/* unused function: length_NegTokenResp */
-
-
-/* unused function: copy_NegTokenResp */
-
-/* Generated from spnego.asn1 */
-/* Do not edit */
-
-
-/* CHOICE */
-/* unused variable: asn1_NegotiationToken_dummy_holder */
diff --git a/contrib/bind9/lib/dns/spnego_asn1.pl b/contrib/bind9/lib/dns/spnego_asn1.pl
deleted file mode 100755
index 0aaa57fa549e..000000000000
--- a/contrib/bind9/lib/dns/spnego_asn1.pl
+++ /dev/null
@@ -1,200 +0,0 @@
-#!/bin/bin/perl -w
-#
-# Copyright (C) 2006, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
-#
-# Permission to use, copy, modify, and/or distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-# PERFORMANCE OF THIS SOFTWARE.
-
-# $Id: spnego_asn1.pl,v 1.4 2007/06/19 23:47:16 tbox Exp $
-
-# Our SPNEGO implementation uses some functions generated by the
-# Heimdal ASN.1 compiler, which this script then whacks a bit to make
-# them work properly in this stripped down implementation. We don't
-# want to require our users to have a copy of the compiler, so we ship
-# the output of this script, but we need to keep the script around in
-# any case to cope with future changes to the SPNEGO ASN.1 code, so we
-# might as well supply the script for users who want it.
-
-# Overall plan: run the ASN.1 compiler, run each of its output files
-# through indent, fix up symbols and whack everything to be static.
-# We use indent for two reasons: (1) to whack the Heimdal compiler's
-# output into something closer to ISC's coding standard, and (2) to
-# make it easier for this script to parse the result.
-
-# Output from this script is C code which we expect to be #included
-# into another C file, which is why everything generated by this
-# script is marked "static". The intent is to minimize the number of
-# extern symbols exported by the SPNEGO implementation, to avoid
-# potential conflicts with the GSSAPI libraries.
-
-###
-
-# Filename of the ASN.1 specification. Hardcoded for the moment
-# since this script is intended for compiling exactly one module.
-
-my $asn1_source = $ENV{ASN1_SOURCE} || "spnego.asn1";
-
-# Heimdal ASN.1 compiler. This script was written using the version
-# from Heimdal 0.7.1. To build this, download a copy of
-# heimdal-0.7.1.tar.gz, configure and build with the default options,
-# then look for the compiler in heimdal-0.7.1/lib/asn1/asn1_compile.
-
-my $asn1_compile = $ENV{ASN1_COMPILE} || "asn1_compile";
-
-# BSD indent program. This script was written using the version of
-# indent that comes with FreeBSD 4.11-STABLE. The GNU project, as
-# usual, couldn't resist the temptation to monkey with indent's
-# command line syntax, so this probably won't work with GNU indent.
-
-my $indent = $ENV{INDENT} || "indent";
-
-###
-
-# Step 1: run the compiler. Input is the ASN.1 file. Outputs are a
-# header file (name specified on command line without the .h suffix),
-# a file called "asn1_files" listing the names of the other output
-# files, and a set of files containing C code generated by the
-# compiler for each data type that the compiler found.
-
-if (! -r $asn1_source || system($asn1_compile, $asn1_source, "asn1")) {
- die("Couldn't compile ASN.1 source file $asn1_source\n");
-}
-
-my @files = ("asn1.h");
-
-open(F, "asn1_files")
- or die("Couldn't open asn1_files: $!\n");
-push(@files, split)
- while (<F>);
-close(F);
-
-unlink("asn1_files");
-
-###
-
-# Step 2: generate header block.
-
-print(q~/*
- * Copyright (C) 2006 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: spnego_asn1.pl,v 1.4 2007/06/19 23:47:16 tbox Exp $ */
-
-/*! \file
- * \brief Method routines generated from SPNEGO ASN.1 module.
- * See spnego_asn1.pl for details. Do not edit.
- */
-
-~);
-
-###
-
-# Step 3: read and process each generated file, then delete it.
-
-my $output;
-
-for my $file (@files) {
-
- my $is_static = 0;
-
- system($indent, "-di1", "-ldi1", $file) == 0
- or die("Couldn't indent $file");
-
- unlink("$file.BAK");
-
- open(F, $file)
- or die("Couldn't open $file: $!");
-
- while (<F>) {
-
- # Symbol name fixups
-
- s/heim_general_string/general_string/g;
- s/heim_octet_string/octet_string/g;
- s/heim_oid/oid/g;
- s/heim_utf8_string/utf8_string/g;
-
- # Convert all externs to statics
-
- if (/^static/) {
- $is_static = 1;
- }
-
- if (!/^typedef/ &&
- !$is_static &&
- /^[A-Za-z_][0-9A-Za-z_]*[ \t]*($|[^:0-9A-Za-z_])/) {
- $_ = "static " . $_;
- $is_static = 1;
- }
-
- if (/[{};]/) {
- $is_static = 0;
- }
-
- # Suppress file inclusion, pass anything else through
-
- if (!/#include/) {
- $output .= $_;
- }
- }
-
- close(F);
- unlink($file);
-}
-
-# Step 4: Delete unused stuff to avoid code bloat and compiler warnings.
-
-my @unused_functions = qw(ContextFlags2int
- int2ContextFlags
- asn1_ContextFlags_units
- length_NegTokenInit
- copy_NegTokenInit
- length_NegTokenResp
- copy_NegTokenResp
- length_MechTypeList
- length_MechType
- copy_MechTypeList
- length_ContextFlags
- copy_ContextFlags
- copy_MechType);
-
-$output =~ s<^static [^\n]+\n$_\(.+?^}></* unused function: $_ */\n>ms
- foreach (@unused_functions);
-
-$output =~ s<^static .+$_\(.*\);$></* unused declaration: $_ */>m
- foreach (@unused_functions);
-
-$output =~ s<^static struct units ContextFlags_units\[\].+?^};>
- </* unused variable: ContextFlags_units */>ms;
-
-$output =~ s<^static int asn1_NegotiationToken_dummy_holder = 1;>
- </* unused variable: asn1_NegotiationToken_dummy_holder */>ms;
-
-$output =~ s<^static void\nfree_ContextFlags\(ContextFlags \* data\)\n{\n>
- <$&\t(void)data;\n>ms;
-
-# Step 5: Write the result.
-
-print($output);
-
diff --git a/contrib/bind9/lib/dns/ssu.c b/contrib/bind9/lib/dns/ssu.c
deleted file mode 100644
index 49a777a6447e..000000000000
--- a/contrib/bind9/lib/dns/ssu.c
+++ /dev/null
@@ -1,613 +0,0 @@
-/*
- * Copyright (C) 2004-2008, 2010, 2011, 2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*! \file */
-/*
- * $Id: ssu.c,v 1.38 2011/01/06 23:47:00 tbox Exp $
- * Principal Author: Brian Wellington
- */
-
-#include <config.h>
-
-#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 <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)
-
-#define SSURULEMAGIC ISC_MAGIC('S', 'S', 'U', 'R')
-#define VALID_SSURULE(table) ISC_MAGIC_VALID(table, SSURULEMAGIC)
-
-struct dns_ssurule {
- unsigned int magic;
- isc_boolean_t grant; /*%< is this a grant or a deny? */
- unsigned int matchtype; /*%< which type of pattern match? */
- dns_name_t *identity; /*%< the identity to match */
- dns_name_t *name; /*%< the name being updated */
- unsigned int ntypes; /*%< number of data types covered */
- dns_rdatatype_t *types; /*%< the data types. Can include ANY, */
- /*%< defaults to all but SIG,SOA,NS if NULL */
- ISC_LINK(dns_ssurule_t) link;
-};
-
-struct dns_ssutable {
- unsigned int magic;
- isc_mem_t *mctx;
- unsigned int references;
- isc_mutex_t lock;
- dns_dlzdb_t *dlzdatabase;
- ISC_LIST(dns_ssurule_t) rules;
-};
-
-isc_result_t
-dns_ssutable_create(isc_mem_t *mctx, dns_ssutable_t **tablep) {
- isc_result_t result;
- dns_ssutable_t *table;
-
- REQUIRE(tablep != NULL && *tablep == NULL);
- REQUIRE(mctx != NULL);
-
- table = isc_mem_get(mctx, sizeof(dns_ssutable_t));
- if (table == NULL)
- return (ISC_R_NOMEMORY);
- result = isc_mutex_init(&table->lock);
- if (result != ISC_R_SUCCESS) {
- isc_mem_put(mctx, table, sizeof(dns_ssutable_t));
- return (result);
- }
- table->references = 1;
- table->mctx = NULL;
- isc_mem_attach(mctx, &table->mctx);
- ISC_LIST_INIT(table->rules);
- table->magic = SSUTABLEMAGIC;
- *tablep = table;
- return (ISC_R_SUCCESS);
-}
-
-static inline void
-destroy(dns_ssutable_t *table) {
- isc_mem_t *mctx;
-
- REQUIRE(VALID_SSUTABLE(table));
-
- mctx = table->mctx;
- while (!ISC_LIST_EMPTY(table->rules)) {
- dns_ssurule_t *rule = ISC_LIST_HEAD(table->rules);
- if (rule->identity != NULL) {
- dns_name_free(rule->identity, mctx);
- isc_mem_put(mctx, rule->identity, sizeof(dns_name_t));
- }
- if (rule->name != NULL) {
- dns_name_free(rule->name, mctx);
- isc_mem_put(mctx, rule->name, sizeof(dns_name_t));
- }
- if (rule->types != NULL)
- isc_mem_put(mctx, rule->types,
- rule->ntypes * sizeof(dns_rdatatype_t));
- ISC_LIST_UNLINK(table->rules, rule, link);
- rule->magic = 0;
- isc_mem_put(mctx, rule, sizeof(dns_ssurule_t));
- }
- DESTROYLOCK(&table->lock);
- table->magic = 0;
- isc_mem_putanddetach(&table->mctx, table, sizeof(dns_ssutable_t));
-}
-
-void
-dns_ssutable_attach(dns_ssutable_t *source, dns_ssutable_t **targetp) {
- REQUIRE(VALID_SSUTABLE(source));
- REQUIRE(targetp != NULL && *targetp == NULL);
-
- LOCK(&source->lock);
-
- INSIST(source->references > 0);
- source->references++;
- INSIST(source->references != 0);
-
- UNLOCK(&source->lock);
-
- *targetp = source;
-}
-
-void
-dns_ssutable_detach(dns_ssutable_t **tablep) {
- dns_ssutable_t *table;
- isc_boolean_t done = ISC_FALSE;
-
- REQUIRE(tablep != NULL);
- table = *tablep;
- REQUIRE(VALID_SSUTABLE(table));
-
- LOCK(&table->lock);
-
- INSIST(table->references > 0);
- if (--table->references == 0)
- done = ISC_TRUE;
- UNLOCK(&table->lock);
-
- *tablep = NULL;
-
- if (done)
- destroy(table);
-}
-
-isc_result_t
-dns_ssutable_addrule(dns_ssutable_t *table, isc_boolean_t grant,
- dns_name_t *identity, unsigned int matchtype,
- dns_name_t *name, unsigned int ntypes,
- dns_rdatatype_t *types)
-{
- dns_ssurule_t *rule;
- isc_mem_t *mctx;
- isc_result_t result;
-
- REQUIRE(VALID_SSUTABLE(table));
- REQUIRE(dns_name_isabsolute(identity));
- REQUIRE(dns_name_isabsolute(name));
- REQUIRE(matchtype <= DNS_SSUMATCHTYPE_MAX);
- if (matchtype == DNS_SSUMATCHTYPE_WILDCARD)
- REQUIRE(dns_name_iswildcard(name));
- if (ntypes > 0)
- REQUIRE(types != NULL);
-
- mctx = table->mctx;
- rule = isc_mem_get(mctx, sizeof(dns_ssurule_t));
- if (rule == NULL)
- return (ISC_R_NOMEMORY);
-
- rule->identity = NULL;
- rule->name = NULL;
- rule->types = NULL;
-
- rule->grant = grant;
-
- rule->identity = isc_mem_get(mctx, sizeof(dns_name_t));
- if (rule->identity == NULL) {
- result = ISC_R_NOMEMORY;
- goto failure;
- }
- dns_name_init(rule->identity, NULL);
- result = dns_name_dup(identity, mctx, rule->identity);
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- rule->name = isc_mem_get(mctx, sizeof(dns_name_t));
- if (rule->name == NULL) {
- result = ISC_R_NOMEMORY;
- goto failure;
- }
- dns_name_init(rule->name, NULL);
- result = dns_name_dup(name, mctx, rule->name);
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- rule->matchtype = matchtype;
-
- rule->ntypes = ntypes;
- if (ntypes > 0) {
- rule->types = isc_mem_get(mctx,
- ntypes * sizeof(dns_rdatatype_t));
- if (rule->types == NULL) {
- result = ISC_R_NOMEMORY;
- goto failure;
- }
- memcpy(rule->types, types, ntypes * sizeof(dns_rdatatype_t));
- } else
- rule->types = NULL;
-
- rule->magic = SSURULEMAGIC;
- ISC_LIST_INITANDAPPEND(table->rules, rule, link);
-
- return (ISC_R_SUCCESS);
-
- failure:
- if (rule->identity != NULL) {
- if (dns_name_dynamic(rule->identity))
- dns_name_free(rule->identity, mctx);
- isc_mem_put(mctx, rule->identity, sizeof(dns_name_t));
- }
- if (rule->name != NULL) {
- if (dns_name_dynamic(rule->name))
- dns_name_free(rule->name, mctx);
- isc_mem_put(mctx, rule->name, sizeof(dns_name_t));
- }
- if (rule->types != NULL)
- isc_mem_put(mctx, rule->types,
- ntypes * sizeof(dns_rdatatype_t));
- isc_mem_put(mctx, rule, sizeof(dns_ssurule_t));
-
- return (result);
-}
-
-static inline isc_boolean_t
-isusertype(dns_rdatatype_t type) {
- return (ISC_TF(type != dns_rdatatype_ns &&
- type != dns_rdatatype_soa &&
- type != dns_rdatatype_rrsig));
-}
-
-static void
-reverse_from_address(dns_name_t *tcpself, isc_netaddr_t *tcpaddr) {
- char buf[16 * 4 + sizeof("IP6.ARPA.")];
- isc_result_t result;
- unsigned char *ap;
- isc_buffer_t b;
- unsigned long l;
-
- switch (tcpaddr->family) {
- case AF_INET:
- l = ntohl(tcpaddr->type.in.s_addr);
- result = isc_string_printf(buf, sizeof(buf),
- "%lu.%lu.%lu.%lu.IN-ADDR.ARPA.",
- (l >> 0) & 0xff, (l >> 8) & 0xff,
- (l >> 16) & 0xff, (l >> 24) & 0xff);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- break;
- case AF_INET6:
- ap = tcpaddr->type.in6.s6_addr;
- result = isc_string_printf(buf, sizeof(buf),
- "%x.%x.%x.%x.%x.%x.%x.%x."
- "%x.%x.%x.%x.%x.%x.%x.%x."
- "%x.%x.%x.%x.%x.%x.%x.%x."
- "%x.%x.%x.%x.%x.%x.%x.%x."
- "IP6.ARPA.",
- ap[15] & 0x0f, (ap[15] >> 4) & 0x0f,
- ap[14] & 0x0f, (ap[14] >> 4) & 0x0f,
- ap[13] & 0x0f, (ap[13] >> 4) & 0x0f,
- ap[12] & 0x0f, (ap[12] >> 4) & 0x0f,
- ap[11] & 0x0f, (ap[11] >> 4) & 0x0f,
- ap[10] & 0x0f, (ap[10] >> 4) & 0x0f,
- ap[9] & 0x0f, (ap[9] >> 4) & 0x0f,
- ap[8] & 0x0f, (ap[8] >> 4) & 0x0f,
- ap[7] & 0x0f, (ap[7] >> 4) & 0x0f,
- ap[6] & 0x0f, (ap[6] >> 4) & 0x0f,
- ap[5] & 0x0f, (ap[5] >> 4) & 0x0f,
- ap[4] & 0x0f, (ap[4] >> 4) & 0x0f,
- ap[3] & 0x0f, (ap[3] >> 4) & 0x0f,
- ap[2] & 0x0f, (ap[2] >> 4) & 0x0f,
- ap[1] & 0x0f, (ap[1] >> 4) & 0x0f,
- ap[0] & 0x0f, (ap[0] >> 4) & 0x0f);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- break;
- default:
- INSIST(0);
- }
- isc_buffer_init(&b, buf, strlen(buf));
- isc_buffer_add(&b, strlen(buf));
- result = dns_name_fromtext(tcpself, &b, dns_rootname, 0, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
-}
-
-static void
-stf_from_address(dns_name_t *stfself, isc_netaddr_t *tcpaddr) {
- char buf[sizeof("X.X.X.X.Y.Y.Y.Y.2.0.0.2.IP6.ARPA.")];
- isc_result_t result;
- unsigned char *ap;
- isc_buffer_t b;
- unsigned long l;
-
- switch(tcpaddr->family) {
- case AF_INET:
- l = ntohl(tcpaddr->type.in.s_addr);
- result = isc_string_printf(buf, sizeof(buf),
- "%lx.%lx.%lx.%lx.%lx.%lx.%lx.%lx"
- "2.0.0.2.IP6.ARPA.",
- l & 0xf, (l >> 4) & 0xf,
- (l >> 8) & 0xf, (l >> 12) & 0xf,
- (l >> 16) & 0xf, (l >> 20) & 0xf,
- (l >> 24) & 0xf, (l >> 28) & 0xf);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- break;
- case AF_INET6:
- ap = tcpaddr->type.in6.s6_addr;
- result = isc_string_printf(buf, sizeof(buf),
- "%x.%x.%x.%x.%x.%x.%x.%x."
- "%x.%x.%x.%x.IP6.ARPA.",
- ap[5] & 0x0f, (ap[5] >> 4) & 0x0f,
- ap[4] & 0x0f, (ap[4] >> 4) & 0x0f,
- ap[3] & 0x0f, (ap[3] >> 4) & 0x0f,
- ap[2] & 0x0f, (ap[2] >> 4) & 0x0f,
- ap[1] & 0x0f, (ap[1] >> 4) & 0x0f,
- ap[0] & 0x0f, (ap[0] >> 4) & 0x0f);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- break;
- default:
- INSIST(0);
- }
- isc_buffer_init(&b, buf, strlen(buf));
- isc_buffer_add(&b, strlen(buf));
- result = dns_name_fromtext(stfself, &b, dns_rootname, 0, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
-}
-
-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,
- const dst_key_t *key)
-{
- dns_ssurule_t *rule;
- unsigned int i;
- dns_fixedname_t fixed;
- dns_name_t *wildcard;
- dns_name_t *tcpself;
- dns_name_t *stfself;
- isc_result_t result;
-
- REQUIRE(VALID_SSUTABLE(table));
- REQUIRE(signer == NULL || dns_name_isabsolute(signer));
- REQUIRE(dns_name_isabsolute(name));
-
- if (signer == NULL && tcpaddr == NULL)
- return (ISC_FALSE);
-
- for (rule = ISC_LIST_HEAD(table->rules);
- rule != NULL;
- rule = ISC_LIST_NEXT(rule, link))
- {
- switch (rule->matchtype) {
- case DNS_SSUMATCHTYPE_NAME:
- case DNS_SSUMATCHTYPE_SUBDOMAIN:
- case DNS_SSUMATCHTYPE_WILDCARD:
- case DNS_SSUMATCHTYPE_SELF:
- case DNS_SSUMATCHTYPE_SELFSUB:
- case DNS_SSUMATCHTYPE_SELFWILD:
- if (signer == NULL)
- continue;
- if (dns_name_iswildcard(rule->identity)) {
- if (!dns_name_matcheswildcard(signer,
- rule->identity))
- continue;
- } else {
- if (!dns_name_equal(signer, rule->identity))
- continue;
- }
- break;
- case DNS_SSUMATCHTYPE_SELFKRB5:
- case DNS_SSUMATCHTYPE_SELFMS:
- case DNS_SSUMATCHTYPE_SUBDOMAINKRB5:
- case DNS_SSUMATCHTYPE_SUBDOMAINMS:
- if (signer == NULL)
- continue;
- break;
- case DNS_SSUMATCHTYPE_TCPSELF:
- case DNS_SSUMATCHTYPE_6TO4SELF:
- if (tcpaddr == NULL)
- continue;
- break;
- }
-
- switch (rule->matchtype) {
- case DNS_SSUMATCHTYPE_NAME:
- if (!dns_name_equal(name, rule->name))
- continue;
- break;
- case DNS_SSUMATCHTYPE_SUBDOMAIN:
- if (!dns_name_issubdomain(name, rule->name))
- continue;
- break;
- case DNS_SSUMATCHTYPE_WILDCARD:
- if (!dns_name_matcheswildcard(name, rule->name))
- continue;
- break;
- case DNS_SSUMATCHTYPE_SELF:
- if (!dns_name_equal(signer, name))
- continue;
- break;
- case DNS_SSUMATCHTYPE_SELFSUB:
- if (!dns_name_issubdomain(name, signer))
- continue;
- break;
- case DNS_SSUMATCHTYPE_SELFWILD:
- dns_fixedname_init(&fixed);
- wildcard = dns_fixedname_name(&fixed);
- result = dns_name_concatenate(dns_wildcardname, signer,
- wildcard, NULL);
- if (result != ISC_R_SUCCESS)
- continue;
- if (!dns_name_matcheswildcard(name, wildcard))
- continue;
- break;
- case DNS_SSUMATCHTYPE_SELFKRB5:
- if (!dst_gssapi_identitymatchesrealmkrb5(signer, name,
- rule->identity))
- continue;
- break;
- case DNS_SSUMATCHTYPE_SELFMS:
- if (!dst_gssapi_identitymatchesrealmms(signer, name,
- rule->identity))
- continue;
- break;
- case DNS_SSUMATCHTYPE_SUBDOMAINKRB5:
- if (!dns_name_issubdomain(name, rule->name))
- continue;
- if (!dst_gssapi_identitymatchesrealmkrb5(signer, NULL,
- rule->identity))
- continue;
- break;
- case DNS_SSUMATCHTYPE_SUBDOMAINMS:
- if (!dns_name_issubdomain(name, rule->name))
- continue;
- if (!dst_gssapi_identitymatchesrealmms(signer, NULL,
- rule->identity))
- continue;
- break;
- case DNS_SSUMATCHTYPE_TCPSELF:
- dns_fixedname_init(&fixed);
- tcpself = dns_fixedname_name(&fixed);
- reverse_from_address(tcpself, tcpaddr);
- if (dns_name_iswildcard(rule->identity)) {
- if (!dns_name_matcheswildcard(tcpself,
- rule->identity))
- continue;
- } else {
- if (!dns_name_equal(tcpself, rule->identity))
- continue;
- }
- if (!dns_name_equal(tcpself, name))
- continue;
- break;
- case DNS_SSUMATCHTYPE_6TO4SELF:
- dns_fixedname_init(&fixed);
- stfself = dns_fixedname_name(&fixed);
- stf_from_address(stfself, tcpaddr);
- if (dns_name_iswildcard(rule->identity)) {
- if (!dns_name_matcheswildcard(stfself,
- rule->identity))
- continue;
- } else {
- if (!dns_name_equal(stfself, rule->identity))
- continue;
- }
- 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 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++) {
- if (rule->types[i] == dns_rdatatype_any ||
- rule->types[i] == type)
- break;
- }
- if (i == rule->ntypes)
- continue;
- }
- return (rule->grant);
- }
-
- return (ISC_FALSE);
-}
-
-isc_boolean_t
-dns_ssurule_isgrant(const dns_ssurule_t *rule) {
- REQUIRE(VALID_SSURULE(rule));
- return (rule->grant);
-}
-
-dns_name_t *
-dns_ssurule_identity(const dns_ssurule_t *rule) {
- REQUIRE(VALID_SSURULE(rule));
- return (rule->identity);
-}
-
-unsigned int
-dns_ssurule_matchtype(const dns_ssurule_t *rule) {
- REQUIRE(VALID_SSURULE(rule));
- return (rule->matchtype);
-}
-
-dns_name_t *
-dns_ssurule_name(const dns_ssurule_t *rule) {
- REQUIRE(VALID_SSURULE(rule));
- return (rule->name);
-}
-
-unsigned int
-dns_ssurule_types(const dns_ssurule_t *rule, dns_rdatatype_t **types) {
- REQUIRE(VALID_SSURULE(rule));
- REQUIRE(types != NULL && *types != NULL);
- *types = rule->types;
- return (rule->ntypes);
-}
-
-isc_result_t
-dns_ssutable_firstrule(const dns_ssutable_t *table, dns_ssurule_t **rule) {
- REQUIRE(VALID_SSUTABLE(table));
- REQUIRE(rule != NULL && *rule == NULL);
- *rule = ISC_LIST_HEAD(table->rules);
- return (*rule != NULL ? ISC_R_SUCCESS : ISC_R_NOMORE);
-}
-
-isc_result_t
-dns_ssutable_nextrule(dns_ssurule_t *rule, dns_ssurule_t **nextrule) {
- REQUIRE(VALID_SSURULE(rule));
- REQUIRE(nextrule != NULL && *nextrule == NULL);
- *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/contrib/bind9/lib/dns/ssu_external.c b/contrib/bind9/lib/dns/ssu_external.c
deleted file mode 100644
index 43d231d63eb0..000000000000
--- a/contrib/bind9/lib/dns/ssu_external.c
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/*
- * 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;
- strlcpy(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 = NULL;
- 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);
-
- if (key != NULL) {
- dst_key_format(key, b_key, sizeof(b_key));
- tkey_token = dst_key_tkeytoken(key);
- } else
- b_key[0] = 0;
-
- if (tkey_token != NULL) {
- isc_buffer_region(tkey_token, &token_region);
- token_len = token_region.length;
- }
-
- /* Format the request elements */
- if (signer != NULL)
- 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 != NULL)
- isc_netaddr_format(tcpaddr, b_addr, sizeof(b_addr));
- else
- b_addr[0] = 0;
-
- dns_rdatatype_format(type, b_type, sizeof(b_type));
-
- /* 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/contrib/bind9/lib/dns/stats.c b/contrib/bind9/lib/dns/stats.c
deleted file mode 100644
index a59dde633217..000000000000
--- a/contrib/bind9/lib/dns/stats.c
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- * 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
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: stats.c,v 1.18 2009/01/27 23:47:54 tbox Exp $ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <isc/magic.h>
-#include <isc/mem.h>
-#include <isc/stats.h>
-#include <isc/util.h>
-
-#include <dns/opcode.h>
-#include <dns/rdatatype.h>
-#include <dns/stats.h>
-
-#define DNS_STATS_MAGIC ISC_MAGIC('D', 's', 't', 't')
-#define DNS_STATS_VALID(x) ISC_MAGIC_VALID(x, DNS_STATS_MAGIC)
-
-/*%
- * Statistics types.
- */
-typedef enum {
- dns_statstype_general = 0,
- dns_statstype_rdtype = 1,
- dns_statstype_rdataset = 2,
- dns_statstype_opcode = 3
-} dns_statstype_t;
-
-/*%
- * It doesn't make sense to have 2^16 counters for all possible types since
- * most of them won't be used. We have counters for the first 256 types and
- * those explicitly supported in the rdata implementation.
- * XXXJT: this introduces tight coupling with the rdata implementation.
- * Ideally, we should have rdata handle this type of details.
- */
-enum {
- /* For 0-255, we use the rdtype value as counter indices */
- rdtypecounter_dlv = 256, /* for dns_rdatatype_dlv */
- rdtypecounter_others = 257, /* anything else */
- rdtypecounter_max = 258,
- /* The following are used for rdataset */
- rdtypenxcounter_max = rdtypecounter_max * 2,
- rdtypecounter_nxdomain = rdtypenxcounter_max,
- rdatasettypecounter_max = rdtypecounter_nxdomain + 1
-};
-
-struct dns_stats {
- /*% Unlocked */
- unsigned int magic;
- dns_statstype_t type;
- isc_mem_t *mctx;
- isc_mutex_t lock;
- isc_stats_t *counters;
-
- /*% Locked by lock */
- unsigned int references;
-};
-
-typedef struct rdatadumparg {
- dns_rdatatypestats_dumper_t fn;
- void *arg;
-} rdatadumparg_t;
-
-typedef struct opcodedumparg {
- dns_opcodestats_dumper_t fn;
- void *arg;
-} opcodedumparg_t;
-
-void
-dns_stats_attach(dns_stats_t *stats, dns_stats_t **statsp) {
- REQUIRE(DNS_STATS_VALID(stats));
- REQUIRE(statsp != NULL && *statsp == NULL);
-
- LOCK(&stats->lock);
- stats->references++;
- UNLOCK(&stats->lock);
-
- *statsp = stats;
-}
-
-void
-dns_stats_detach(dns_stats_t **statsp) {
- dns_stats_t *stats;
-
- REQUIRE(statsp != NULL && DNS_STATS_VALID(*statsp));
-
- stats = *statsp;
- *statsp = NULL;
-
- LOCK(&stats->lock);
- stats->references--;
- UNLOCK(&stats->lock);
-
- if (stats->references == 0) {
- isc_stats_detach(&stats->counters);
- DESTROYLOCK(&stats->lock);
- isc_mem_putanddetach(&stats->mctx, stats, sizeof(*stats));
- }
-}
-
-/*%
- * Create methods
- */
-static isc_result_t
-create_stats(isc_mem_t *mctx, dns_statstype_t type, int ncounters,
- dns_stats_t **statsp)
-{
- dns_stats_t *stats;
- isc_result_t result;
-
- stats = isc_mem_get(mctx, sizeof(*stats));
- if (stats == NULL)
- return (ISC_R_NOMEMORY);
-
- stats->counters = NULL;
- stats->references = 1;
-
- result = isc_mutex_init(&stats->lock);
- if (result != ISC_R_SUCCESS)
- goto clean_stats;
-
- result = isc_stats_create(mctx, &stats->counters, ncounters);
- if (result != ISC_R_SUCCESS)
- goto clean_mutex;
-
- stats->magic = DNS_STATS_MAGIC;
- stats->type = type;
- stats->mctx = NULL;
- isc_mem_attach(mctx, &stats->mctx);
- *statsp = stats;
-
- return (ISC_R_SUCCESS);
-
- clean_mutex:
- DESTROYLOCK(&stats->lock);
- clean_stats:
- isc_mem_put(mctx, stats, sizeof(*stats));
-
- return (result);
-}
-
-isc_result_t
-dns_generalstats_create(isc_mem_t *mctx, dns_stats_t **statsp, int ncounters) {
- REQUIRE(statsp != NULL && *statsp == NULL);
-
- return (create_stats(mctx, dns_statstype_general, ncounters, statsp));
-}
-
-isc_result_t
-dns_rdatatypestats_create(isc_mem_t *mctx, dns_stats_t **statsp) {
- REQUIRE(statsp != NULL && *statsp == NULL);
-
- return (create_stats(mctx, dns_statstype_rdtype, rdtypecounter_max,
- statsp));
-}
-
-isc_result_t
-dns_rdatasetstats_create(isc_mem_t *mctx, dns_stats_t **statsp) {
- REQUIRE(statsp != NULL && *statsp == NULL);
-
- return (create_stats(mctx, dns_statstype_rdataset,
- (rdtypecounter_max * 2) + 1, statsp));
-}
-
-isc_result_t
-dns_opcodestats_create(isc_mem_t *mctx, dns_stats_t **statsp) {
- REQUIRE(statsp != NULL && *statsp == NULL);
-
- return (create_stats(mctx, dns_statstype_opcode, 16, statsp));
-}
-
-/*%
- * Increment/Decrement methods
- */
-void
-dns_generalstats_increment(dns_stats_t *stats, isc_statscounter_t counter) {
- REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_general);
-
- isc_stats_increment(stats->counters, counter);
-}
-
-void
-dns_rdatatypestats_increment(dns_stats_t *stats, dns_rdatatype_t type) {
- int counter;
-
- REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_rdtype);
-
- if (type == dns_rdatatype_dlv)
- counter = rdtypecounter_dlv;
- else if (type > dns_rdatatype_any)
- counter = rdtypecounter_others;
- else
- counter = (int)type;
-
- isc_stats_increment(stats->counters, (isc_statscounter_t)counter);
-}
-
-static inline void
-update_rdatasetstats(dns_stats_t *stats, dns_rdatastatstype_t rrsettype,
- isc_boolean_t increment)
-{
- int counter;
- dns_rdatatype_t rdtype;
-
- if ((DNS_RDATASTATSTYPE_ATTR(rrsettype) &
- DNS_RDATASTATSTYPE_ATTR_NXDOMAIN) != 0) {
- counter = rdtypecounter_nxdomain;
- } else {
- rdtype = DNS_RDATASTATSTYPE_BASE(rrsettype);
- if (rdtype == dns_rdatatype_dlv)
- counter = (int)rdtypecounter_dlv;
- else if (rdtype > dns_rdatatype_any)
- counter = (int)rdtypecounter_others;
- else
- counter = (int)rdtype;
-
- if ((DNS_RDATASTATSTYPE_ATTR(rrsettype) &
- DNS_RDATASTATSTYPE_ATTR_NXRRSET) != 0)
- counter += rdtypecounter_max;
- }
-
- if (increment)
- isc_stats_increment(stats->counters, counter);
- else
- isc_stats_decrement(stats->counters, counter);
-}
-
-void
-dns_rdatasetstats_increment(dns_stats_t *stats, dns_rdatastatstype_t rrsettype)
-{
- REQUIRE(DNS_STATS_VALID(stats) &&
- stats->type == dns_statstype_rdataset);
-
- update_rdatasetstats(stats, rrsettype, ISC_TRUE);
-}
-
-void
-dns_rdatasetstats_decrement(dns_stats_t *stats, dns_rdatastatstype_t rrsettype)
-{
- REQUIRE(DNS_STATS_VALID(stats) &&
- stats->type == dns_statstype_rdataset);
-
- update_rdatasetstats(stats, rrsettype, ISC_FALSE);
-}
-void
-dns_opcodestats_increment(dns_stats_t *stats, dns_opcode_t code) {
- REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_opcode);
-
- isc_stats_increment(stats->counters, (isc_statscounter_t)code);
-}
-
-/*%
- * Dump methods
- */
-void
-dns_generalstats_dump(dns_stats_t *stats, dns_generalstats_dumper_t dump_fn,
- void *arg, unsigned int options)
-{
- REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_general);
-
- isc_stats_dump(stats->counters, (isc_stats_dumper_t)dump_fn,
- arg, options);
-}
-
-static void
-dump_rdentry(int rdcounter, isc_uint64_t value, dns_rdatastatstype_t attributes,
- dns_rdatatypestats_dumper_t dump_fn, void * arg)
-{
- dns_rdatatype_t rdtype = dns_rdatatype_none; /* sentinel */
- dns_rdatastatstype_t type;
-
- if (rdcounter == rdtypecounter_others)
- attributes |= DNS_RDATASTATSTYPE_ATTR_OTHERTYPE;
- else {
- if (rdcounter == rdtypecounter_dlv)
- rdtype = dns_rdatatype_dlv;
- else
- rdtype = (dns_rdatatype_t)rdcounter;
- }
- type = DNS_RDATASTATSTYPE_VALUE((dns_rdatastatstype_t)rdtype,
- attributes);
- dump_fn(type, value, arg);
-}
-
-static void
-rdatatype_dumpcb(isc_statscounter_t counter, isc_uint64_t value, void *arg) {
- rdatadumparg_t *rdatadumparg = arg;
-
- dump_rdentry(counter, value, 0, rdatadumparg->fn, rdatadumparg->arg);
-}
-
-void
-dns_rdatatypestats_dump(dns_stats_t *stats, dns_rdatatypestats_dumper_t dump_fn,
- void *arg0, unsigned int options)
-{
- rdatadumparg_t arg;
- REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_rdtype);
-
- arg.fn = dump_fn;
- arg.arg = arg0;
- isc_stats_dump(stats->counters, rdatatype_dumpcb, &arg, options);
-}
-
-static void
-rdataset_dumpcb(isc_statscounter_t counter, isc_uint64_t value, void *arg) {
- rdatadumparg_t *rdatadumparg = arg;
-
- if (counter < rdtypecounter_max) {
- dump_rdentry(counter, value, 0, rdatadumparg->fn,
- rdatadumparg->arg);
- } else if (counter < rdtypenxcounter_max) {
- dump_rdentry(counter - rdtypecounter_max, value,
- DNS_RDATASTATSTYPE_ATTR_NXRRSET,
- rdatadumparg->fn, rdatadumparg->arg);
- } else {
- dump_rdentry(0, value, DNS_RDATASTATSTYPE_ATTR_NXDOMAIN,
- rdatadumparg->fn, rdatadumparg->arg);
- }
-}
-
-void
-dns_rdatasetstats_dump(dns_stats_t *stats, dns_rdatatypestats_dumper_t dump_fn,
- void *arg0, unsigned int options)
-{
- rdatadumparg_t arg;
-
- REQUIRE(DNS_STATS_VALID(stats) &&
- stats->type == dns_statstype_rdataset);
-
- arg.fn = dump_fn;
- arg.arg = arg0;
- isc_stats_dump(stats->counters, rdataset_dumpcb, &arg, options);
-}
-
-static void
-opcode_dumpcb(isc_statscounter_t counter, isc_uint64_t value, void *arg) {
- opcodedumparg_t *opcodearg = arg;
-
- opcodearg->fn((dns_opcode_t)counter, value, opcodearg->arg);
-}
-
-void
-dns_opcodestats_dump(dns_stats_t *stats, dns_opcodestats_dumper_t dump_fn,
- void *arg0, unsigned int options)
-{
- opcodedumparg_t arg;
-
- REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_opcode);
-
- arg.fn = dump_fn;
- arg.arg = arg0;
- isc_stats_dump(stats->counters, opcode_dumpcb, &arg, options);
-}
-
-/***
- *** Obsolete variables and functions follow:
- ***/
-LIBDNS_EXTERNAL_DATA const char *dns_statscounter_names[DNS_STATS_NCOUNTERS] =
- {
- "success",
- "referral",
- "nxrrset",
- "nxdomain",
- "recursion",
- "failure",
- "duplicate",
- "dropped"
- };
-
-isc_result_t
-dns_stats_alloccounters(isc_mem_t *mctx, isc_uint64_t **ctrp) {
- int i;
- isc_uint64_t *p =
- isc_mem_get(mctx, DNS_STATS_NCOUNTERS * sizeof(isc_uint64_t));
- if (p == NULL)
- return (ISC_R_NOMEMORY);
- for (i = 0; i < DNS_STATS_NCOUNTERS; i++)
- p[i] = 0;
- *ctrp = p;
- return (ISC_R_SUCCESS);
-}
-
-void
-dns_stats_freecounters(isc_mem_t *mctx, isc_uint64_t **ctrp) {
- isc_mem_put(mctx, *ctrp, DNS_STATS_NCOUNTERS * sizeof(isc_uint64_t));
- *ctrp = NULL;
-}
diff --git a/contrib/bind9/lib/dns/tcpmsg.c b/contrib/bind9/lib/dns/tcpmsg.c
deleted file mode 100644
index 49add56f37a6..000000000000
--- a/contrib/bind9/lib/dns/tcpmsg.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: tcpmsg.c,v 1.31 2007/06/19 23:47:16 tbox Exp $ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <isc/mem.h>
-#include <isc/task.h>
-#include <isc/util.h>
-
-#include <dns/events.h>
-#include <dns/result.h>
-#include <dns/tcpmsg.h>
-
-#ifdef TCPMSG_DEBUG
-#include <stdio.h> /* Required for printf. */
-#define XDEBUG(x) printf x
-#else
-#define XDEBUG(x)
-#endif
-
-#define TCPMSG_MAGIC ISC_MAGIC('T', 'C', 'P', 'm')
-#define VALID_TCPMSG(foo) ISC_MAGIC_VALID(foo, TCPMSG_MAGIC)
-
-static void recv_length(isc_task_t *, isc_event_t *);
-static void recv_message(isc_task_t *, isc_event_t *);
-
-
-static void
-recv_length(isc_task_t *task, isc_event_t *ev_in) {
- isc_socketevent_t *ev = (isc_socketevent_t *)ev_in;
- isc_event_t *dev;
- dns_tcpmsg_t *tcpmsg = ev_in->ev_arg;
- isc_region_t region;
- isc_result_t result;
-
- INSIST(VALID_TCPMSG(tcpmsg));
-
- dev = &tcpmsg->event;
- tcpmsg->address = ev->address;
-
- if (ev->result != ISC_R_SUCCESS) {
- tcpmsg->result = ev->result;
- goto send_and_free;
- }
-
- /*
- * Success.
- */
- tcpmsg->size = ntohs(tcpmsg->size);
- if (tcpmsg->size == 0) {
- tcpmsg->result = ISC_R_UNEXPECTEDEND;
- goto send_and_free;
- }
- if (tcpmsg->size > tcpmsg->maxsize) {
- tcpmsg->result = ISC_R_RANGE;
- goto send_and_free;
- }
-
- region.base = isc_mem_get(tcpmsg->mctx, tcpmsg->size);
- region.length = tcpmsg->size;
- if (region.base == NULL) {
- tcpmsg->result = ISC_R_NOMEMORY;
- goto send_and_free;
- }
- XDEBUG(("Allocated %d bytes\n", tcpmsg->size));
-
- isc_buffer_init(&tcpmsg->buffer, region.base, region.length);
- result = isc_socket_recv(tcpmsg->sock, &region, 0,
- task, recv_message, tcpmsg);
- if (result != ISC_R_SUCCESS) {
- tcpmsg->result = result;
- goto send_and_free;
- }
-
- isc_event_free(&ev_in);
- return;
-
- send_and_free:
- isc_task_send(tcpmsg->task, &dev);
- tcpmsg->task = NULL;
- isc_event_free(&ev_in);
- return;
-}
-
-static void
-recv_message(isc_task_t *task, isc_event_t *ev_in) {
- isc_socketevent_t *ev = (isc_socketevent_t *)ev_in;
- isc_event_t *dev;
- dns_tcpmsg_t *tcpmsg = ev_in->ev_arg;
-
- (void)task;
-
- INSIST(VALID_TCPMSG(tcpmsg));
-
- dev = &tcpmsg->event;
- tcpmsg->address = ev->address;
-
- if (ev->result != ISC_R_SUCCESS) {
- tcpmsg->result = ev->result;
- goto send_and_free;
- }
-
- tcpmsg->result = ISC_R_SUCCESS;
- isc_buffer_add(&tcpmsg->buffer, ev->n);
-
- XDEBUG(("Received %d bytes (of %d)\n", ev->n, tcpmsg->size));
-
- send_and_free:
- isc_task_send(tcpmsg->task, &dev);
- tcpmsg->task = NULL;
- isc_event_free(&ev_in);
-}
-
-void
-dns_tcpmsg_init(isc_mem_t *mctx, isc_socket_t *sock, dns_tcpmsg_t *tcpmsg) {
- REQUIRE(mctx != NULL);
- REQUIRE(sock != NULL);
- REQUIRE(tcpmsg != NULL);
-
- tcpmsg->magic = TCPMSG_MAGIC;
- tcpmsg->size = 0;
- tcpmsg->buffer.base = NULL;
- tcpmsg->buffer.length = 0;
- tcpmsg->maxsize = 65535; /* Largest message possible. */
- tcpmsg->mctx = mctx;
- tcpmsg->sock = sock;
- tcpmsg->task = NULL; /* None yet. */
- tcpmsg->result = ISC_R_UNEXPECTED; /* None yet. */
- /*
- * Should probably initialize the event here, but it can wait.
- */
-}
-
-
-void
-dns_tcpmsg_setmaxsize(dns_tcpmsg_t *tcpmsg, unsigned int maxsize) {
- REQUIRE(VALID_TCPMSG(tcpmsg));
- REQUIRE(maxsize < 65536);
-
- tcpmsg->maxsize = maxsize;
-}
-
-
-isc_result_t
-dns_tcpmsg_readmessage(dns_tcpmsg_t *tcpmsg,
- isc_task_t *task, isc_taskaction_t action, void *arg)
-{
- isc_result_t result;
- isc_region_t region;
-
- REQUIRE(VALID_TCPMSG(tcpmsg));
- REQUIRE(task != NULL);
- REQUIRE(tcpmsg->task == NULL); /* not currently in use */
-
- if (tcpmsg->buffer.base != NULL) {
- isc_mem_put(tcpmsg->mctx, tcpmsg->buffer.base,
- tcpmsg->buffer.length);
- tcpmsg->buffer.base = NULL;
- tcpmsg->buffer.length = 0;
- }
-
- tcpmsg->task = task;
- tcpmsg->action = action;
- tcpmsg->arg = arg;
- tcpmsg->result = ISC_R_UNEXPECTED; /* unknown right now */
-
- ISC_EVENT_INIT(&tcpmsg->event, sizeof(isc_event_t), 0, 0,
- DNS_EVENT_TCPMSG, action, arg, tcpmsg,
- NULL, NULL);
-
- region.base = (unsigned char *)&tcpmsg->size;
- region.length = 2; /* isc_uint16_t */
- result = isc_socket_recv(tcpmsg->sock, &region, 0,
- tcpmsg->task, recv_length, tcpmsg);
-
- if (result != ISC_R_SUCCESS)
- tcpmsg->task = NULL;
-
- return (result);
-}
-
-void
-dns_tcpmsg_cancelread(dns_tcpmsg_t *tcpmsg) {
- REQUIRE(VALID_TCPMSG(tcpmsg));
-
- isc_socket_cancel(tcpmsg->sock, NULL, ISC_SOCKCANCEL_RECV);
-}
-
-void
-dns_tcpmsg_keepbuffer(dns_tcpmsg_t *tcpmsg, isc_buffer_t *buffer) {
- REQUIRE(VALID_TCPMSG(tcpmsg));
- REQUIRE(buffer != NULL);
-
- *buffer = tcpmsg->buffer;
- tcpmsg->buffer.base = NULL;
- tcpmsg->buffer.length = 0;
-}
-
-#if 0
-void
-dns_tcpmsg_freebuffer(dns_tcpmsg_t *tcpmsg) {
- REQUIRE(VALID_TCPMSG(tcpmsg));
-
- if (tcpmsg->buffer.base == NULL)
- return;
-
- isc_mem_put(tcpmsg->mctx, tcpmsg->buffer.base, tcpmsg->buffer.length);
- tcpmsg->buffer.base = NULL;
- tcpmsg->buffer.length = 0;
-}
-#endif
-
-void
-dns_tcpmsg_invalidate(dns_tcpmsg_t *tcpmsg) {
- REQUIRE(VALID_TCPMSG(tcpmsg));
-
- tcpmsg->magic = 0;
-
- if (tcpmsg->buffer.base != NULL) {
- isc_mem_put(tcpmsg->mctx, tcpmsg->buffer.base,
- tcpmsg->buffer.length);
- tcpmsg->buffer.base = NULL;
- tcpmsg->buffer.length = 0;
- }
-}
diff --git a/contrib/bind9/lib/dns/time.c b/contrib/bind9/lib/dns/time.c
deleted file mode 100644
index 0f245a246a9d..000000000000
--- a/contrib/bind9/lib/dns/time.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007, 2009-2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <stdio.h>
-#include <isc/string.h> /* Required for HP/UX (and others?) */
-#include <time.h>
-#include <ctype.h>
-
-#include <isc/print.h>
-#include <isc/region.h>
-#include <isc/serial.h>
-#include <isc/stdtime.h>
-#include <isc/util.h>
-
-#include <dns/result.h>
-#include <dns/time.h>
-
-static int days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
-
-isc_result_t
-dns_time64_totext(isc_int64_t t, isc_buffer_t *target) {
- struct tm tm;
- char buf[sizeof("YYYYMMDDHHMMSS")];
- int secs;
- unsigned int l;
- isc_region_t region;
-
-/*
- * Warning. Do NOT use arguments with side effects with these macros.
- */
-#define is_leap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
-#define year_secs(y) ((is_leap(y) ? 366 : 365 ) * 86400)
-#define month_secs(m,y) ((days[m] + ((m == 1 && is_leap(y)) ? 1 : 0 )) * 86400)
-
- tm.tm_year = 70;
- while (t < 0) {
- if (tm.tm_year == 0)
- return (ISC_R_RANGE);
- tm.tm_year--;
- secs = year_secs(tm.tm_year + 1900);
- t += secs;
- }
- while ((secs = year_secs(tm.tm_year + 1900)) <= t) {
- t -= secs;
- tm.tm_year++;
- if (tm.tm_year + 1900 > 9999)
- return (ISC_R_RANGE);
- }
- tm.tm_mon = 0;
- while ((secs = month_secs(tm.tm_mon, tm.tm_year + 1900)) <= t) {
- t -= secs;
- tm.tm_mon++;
- }
- tm.tm_mday = 1;
- while (86400 <= t) {
- t -= 86400;
- tm.tm_mday++;
- }
- tm.tm_hour = 0;
- while (3600 <= t) {
- t -= 3600;
- tm.tm_hour++;
- }
- tm.tm_min = 0;
- while (60 <= t) {
- t -= 60;
- tm.tm_min++;
- }
- tm.tm_sec = (int)t;
- /* yyyy mm dd HH MM SS */
- snprintf(buf, sizeof(buf), "%04d%02d%02d%02d%02d%02d",
- tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
- tm.tm_hour, tm.tm_min, tm.tm_sec);
-
- isc_buffer_availableregion(target, &region);
- l = strlen(buf);
-
- if (l > region.length)
- return (ISC_R_NOSPACE);
-
- memcpy(region.base, buf, l);
- isc_buffer_add(target, l);
- return (ISC_R_SUCCESS);
-}
-
-isc_int64_t
-dns_time64_from32(isc_uint32_t value) {
- isc_stdtime_t now;
- isc_int64_t start;
- isc_int64_t t;
-
- /*
- * Adjust the time to the closest epoch. This should be changed
- * to use a 64-bit counterpart to isc_stdtime_get() if one ever
- * is defined, but even the current code is good until the year
- * 2106.
- */
- isc_stdtime_get(&now);
- start = (isc_int64_t) now;
- if (isc_serial_gt(value, now))
- t = start + (value - now);
- else
- t = start - (now - value);
-
- return (t);
-}
-
-isc_result_t
-dns_time32_totext(isc_uint32_t value, isc_buffer_t *target) {
- return (dns_time64_totext(dns_time64_from32(value), target));
-}
-
-isc_result_t
-dns_time64_fromtext(const char *source, isc_int64_t *target) {
- int year, month, day, hour, minute, second;
- isc_int64_t value;
- int secs;
- int i;
-
-#define RANGE(min, max, value) \
- do { \
- if (value < (min) || value > (max)) \
- return (ISC_R_RANGE); \
- } while (0)
-
- if (strlen(source) != 14U)
- return (DNS_R_SYNTAX);
- /*
- * Confirm the source only consists digits. sscanf() allows some
- * minor exceptions.
- */
- for (i = 0; i < 14; i++) {
- if (!isdigit((unsigned char)source[i]))
- return (DNS_R_SYNTAX);
- }
- if (sscanf(source, "%4d%2d%2d%2d%2d%2d",
- &year, &month, &day, &hour, &minute, &second) != 6)
- return (DNS_R_SYNTAX);
-
- RANGE(0, 9999, year);
- RANGE(1, 12, month);
- RANGE(1, days[month - 1] +
- ((month == 2 && is_leap(year)) ? 1 : 0), day);
- RANGE(0, 23, hour);
- RANGE(0, 59, minute);
- RANGE(0, 60, second); /* 60 == leap second. */
-
- /*
- * Calculate seconds from epoch.
- * Note: this uses a idealized calendar.
- */
- value = second + (60 * minute) + (3600 * hour) + ((day - 1) * 86400);
- for (i = 0; i < (month - 1); i++)
- value += days[i] * 86400;
- if (is_leap(year) && month > 2)
- value += 86400;
- if (year < 1970) {
- for (i = 1969; i >= year; i--) {
- secs = (is_leap(i) ? 366 : 365) * 86400;
- value -= secs;
- }
- } else {
- for (i = 1970; i < year; i++) {
- secs = (is_leap(i) ? 366 : 365) * 86400;
- value += secs;
- }
- }
-
- *target = value;
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_time32_fromtext(const char *source, isc_uint32_t *target) {
- isc_int64_t value64;
- isc_result_t result;
- result = dns_time64_fromtext(source, &value64);
- if (result != ISC_R_SUCCESS)
- return (result);
- *target = (isc_uint32_t)value64;
-
- return (ISC_R_SUCCESS);
-}
diff --git a/contrib/bind9/lib/dns/timer.c b/contrib/bind9/lib/dns/timer.c
deleted file mode 100644
index 39e45514ea93..000000000000
--- a/contrib/bind9/lib/dns/timer.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2000, 2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/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.c,v 1.7 2007/06/19 23:47:16 tbox Exp $ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <isc/result.h>
-#include <isc/time.h>
-#include <isc/timer.h>
-
-#include <dns/types.h>
-#include <dns/timer.h>
-
-#define CHECK(op) \
- do { result = (op); \
- if (result != ISC_R_SUCCESS) goto failure; \
- } while (0)
-
-isc_result_t
-dns_timer_setidle(isc_timer_t *timer, unsigned int maxtime,
- unsigned int idletime, isc_boolean_t purge)
-{
- isc_result_t result;
- isc_interval_t maxinterval, idleinterval;
- isc_time_t expires;
-
- /* Compute the time of expiry. */
- isc_interval_set(&maxinterval, maxtime, 0);
- CHECK(isc_time_nowplusinterval(&expires, &maxinterval));
-
- /*
- * Compute the idle interval, and add a spare nanosecond to
- * work around the silly limitation of the ISC timer interface
- * that you cannot specify an idle interval of zero.
- */
- isc_interval_set(&idleinterval, idletime, 1);
-
- CHECK(isc_timer_reset(timer, isc_timertype_once,
- &expires, &idleinterval,
- purge));
- failure:
- return (result);
-}
diff --git a/contrib/bind9/lib/dns/tkey.c b/contrib/bind9/lib/dns/tkey.c
deleted file mode 100644
index 161c18808ef4..000000000000
--- a/contrib/bind9/lib/dns/tkey.c
+++ /dev/null
@@ -1,1460 +0,0 @@
-/*
- * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001, 2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * $Id$
- */
-/*! \file */
-#include <config.h>
-
-#include <isc/buffer.h>
-#include <isc/entropy.h>
-#include <isc/md5.h>
-#include <isc/mem.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>
-#include <dns/message.h>
-#include <dns/name.h>
-#include <dns/rdata.h>
-#include <dns/rdatalist.h>
-#include <dns/rdataset.h>
-#include <dns/rdatastruct.h>
-#include <dns/result.h>
-#include <dns/tkey.h>
-#include <dns/tsig.h>
-
-#include <dst/dst.h>
-#include <dst/gssapi.h>
-
-#define TKEY_RANDOM_AMOUNT 16
-
-#define RETERR(x) do { \
- result = (x); \
- if (result != ISC_R_SUCCESS) \
- goto failure; \
- } while (0)
-
-static void
-tkey_log(const char *fmt, ...) ISC_FORMAT_PRINTF(1, 2);
-
-static void
-tkey_log(const char *fmt, ...) {
- va_list ap;
-
- va_start(ap, fmt);
- isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL,
- DNS_LOGMODULE_REQUEST, ISC_LOG_DEBUG(4), fmt, ap);
- va_end(ap);
-}
-
-static void
-_dns_tkey_dumpmessage(dns_message_t *msg) {
- isc_buffer_t outbuf;
- unsigned char output[4096];
- isc_result_t result;
-
- isc_buffer_init(&outbuf, output, sizeof(output));
- result = dns_message_totext(msg, &dns_master_style_debug, 0,
- &outbuf);
- if (result != ISC_R_SUCCESS)
- fprintf(stderr, "Warning: dns_message_totext returned: %s\n",
- dns_result_totext(result));
- fprintf(stderr, "%.*s\n", (int)isc_buffer_usedlength(&outbuf),
- (char *)isc_buffer_base(&outbuf));
-}
-
-isc_result_t
-dns_tkeyctx_create(isc_mem_t *mctx, isc_entropy_t *ectx, dns_tkeyctx_t **tctxp)
-{
- dns_tkeyctx_t *tctx;
-
- REQUIRE(mctx != NULL);
- REQUIRE(ectx != NULL);
- REQUIRE(tctxp != NULL && *tctxp == NULL);
-
- tctx = isc_mem_get(mctx, sizeof(dns_tkeyctx_t));
- if (tctx == NULL)
- return (ISC_R_NOMEMORY);
- tctx->mctx = NULL;
- isc_mem_attach(mctx, &tctx->mctx);
- tctx->ectx = NULL;
- isc_entropy_attach(ectx, &tctx->ectx);
- tctx->dhkey = NULL;
- tctx->domain = NULL;
- tctx->gsscred = NULL;
- tctx->gssapi_keytab = NULL;
-
- *tctxp = tctx;
- return (ISC_R_SUCCESS);
-}
-
-void
-dns_tkeyctx_destroy(dns_tkeyctx_t **tctxp) {
- isc_mem_t *mctx;
- dns_tkeyctx_t *tctx;
-
- REQUIRE(tctxp != NULL && *tctxp != NULL);
-
- tctx = *tctxp;
- mctx = tctx->mctx;
-
- if (tctx->dhkey != NULL)
- dst_key_free(&tctx->dhkey);
- if (tctx->domain != NULL) {
- if (dns_name_dynamic(tctx->domain))
- 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);
- isc_mem_put(mctx, tctx, sizeof(dns_tkeyctx_t));
- isc_mem_detach(&mctx);
- *tctxp = NULL;
-}
-
-static isc_result_t
-add_rdata_to_list(dns_message_t *msg, dns_name_t *name, dns_rdata_t *rdata,
- isc_uint32_t ttl, dns_namelist_t *namelist)
-{
- isc_result_t result;
- isc_region_t r, newr;
- dns_rdata_t *newrdata = NULL;
- dns_name_t *newname = NULL;
- dns_rdatalist_t *newlist = NULL;
- dns_rdataset_t *newset = NULL;
- isc_buffer_t *tmprdatabuf = NULL;
-
- RETERR(dns_message_gettemprdata(msg, &newrdata));
-
- dns_rdata_toregion(rdata, &r);
- RETERR(isc_buffer_allocate(msg->mctx, &tmprdatabuf, r.length));
- isc_buffer_availableregion(tmprdatabuf, &newr);
- memcpy(newr.base, r.base, r.length);
- dns_rdata_fromregion(newrdata, rdata->rdclass, rdata->type, &newr);
- dns_message_takebuffer(msg, &tmprdatabuf);
-
- RETERR(dns_message_gettempname(msg, &newname));
- dns_name_init(newname, NULL);
- RETERR(dns_name_dup(name, msg->mctx, newname));
-
- RETERR(dns_message_gettemprdatalist(msg, &newlist));
- newlist->rdclass = newrdata->rdclass;
- newlist->type = newrdata->type;
- newlist->covers = 0;
- newlist->ttl = ttl;
- ISC_LIST_INIT(newlist->rdata);
- ISC_LIST_APPEND(newlist->rdata, newrdata, link);
-
- RETERR(dns_message_gettemprdataset(msg, &newset));
- dns_rdataset_init(newset);
- RETERR(dns_rdatalist_tordataset(newlist, newset));
-
- ISC_LIST_INIT(newname->list);
- ISC_LIST_APPEND(newname->list, newset, link);
-
- ISC_LIST_APPEND(*namelist, newname, link);
-
- return (ISC_R_SUCCESS);
-
- failure:
- if (newrdata != NULL) {
- if (ISC_LINK_LINKED(newrdata, link)) {
- INSIST(newlist != NULL);
- ISC_LIST_UNLINK(newlist->rdata, newrdata, link);
- }
- dns_message_puttemprdata(msg, &newrdata);
- }
- if (newname != NULL)
- dns_message_puttempname(msg, &newname);
- if (newset != NULL) {
- dns_rdataset_disassociate(newset);
- dns_message_puttemprdataset(msg, &newset);
- }
- if (newlist != NULL)
- dns_message_puttemprdatalist(msg, &newlist);
- return (result);
-}
-
-static void
-free_namelist(dns_message_t *msg, dns_namelist_t *namelist) {
- dns_name_t *name;
- dns_rdataset_t *set;
-
- while (!ISC_LIST_EMPTY(*namelist)) {
- name = ISC_LIST_HEAD(*namelist);
- ISC_LIST_UNLINK(*namelist, name, link);
- while (!ISC_LIST_EMPTY(name->list)) {
- set = ISC_LIST_HEAD(name->list);
- ISC_LIST_UNLINK(name->list, set, link);
- dns_message_puttemprdataset(msg, &set);
- }
- dns_message_puttempname(msg, &name);
- }
-}
-
-static isc_result_t
-compute_secret(isc_buffer_t *shared, isc_region_t *queryrandomness,
- isc_region_t *serverrandomness, isc_buffer_t *secret)
-{
- isc_md5_t md5ctx;
- isc_region_t r, r2;
- unsigned char digests[32];
- unsigned int i;
-
- isc_buffer_usedregion(shared, &r);
-
- /*
- * MD5 ( query data | DH value ).
- */
- isc_md5_init(&md5ctx);
- isc_md5_update(&md5ctx, queryrandomness->base,
- queryrandomness->length);
- isc_md5_update(&md5ctx, r.base, r.length);
- isc_md5_final(&md5ctx, digests);
-
- /*
- * MD5 ( server data | DH value ).
- */
- isc_md5_init(&md5ctx);
- isc_md5_update(&md5ctx, serverrandomness->base,
- serverrandomness->length);
- isc_md5_update(&md5ctx, r.base, r.length);
- isc_md5_final(&md5ctx, &digests[ISC_MD5_DIGESTLENGTH]);
-
- /*
- * XOR ( DH value, MD5-1 | MD5-2).
- */
- isc_buffer_availableregion(secret, &r);
- isc_buffer_usedregion(shared, &r2);
- if (r.length < sizeof(digests) || r.length < r2.length)
- return (ISC_R_NOSPACE);
- if (r2.length > sizeof(digests)) {
- memcpy(r.base, r2.base, r2.length);
- for (i = 0; i < sizeof(digests); i++)
- r.base[i] ^= digests[i];
- isc_buffer_add(secret, r2.length);
- } else {
- memcpy(r.base, digests, sizeof(digests));
- for (i = 0; i < r2.length; i++)
- r.base[i] ^= r2.base[i];
- isc_buffer_add(secret, sizeof(digests));
- }
- return (ISC_R_SUCCESS);
-
-}
-
-static isc_result_t
-process_dhtkey(dns_message_t *msg, dns_name_t *signer, dns_name_t *name,
- dns_rdata_tkey_t *tkeyin, dns_tkeyctx_t *tctx,
- dns_rdata_tkey_t *tkeyout,
- dns_tsig_keyring_t *ring, dns_namelist_t *namelist)
-{
- isc_result_t result = ISC_R_SUCCESS;
- dns_name_t *keyname, ourname;
- dns_rdataset_t *keyset = NULL;
- dns_rdata_t keyrdata = DNS_RDATA_INIT, ourkeyrdata = DNS_RDATA_INIT;
- isc_boolean_t found_key = ISC_FALSE, found_incompatible = ISC_FALSE;
- dst_key_t *pubkey = NULL;
- isc_buffer_t ourkeybuf, *shared = NULL;
- isc_region_t r, r2, ourkeyr;
- unsigned char keydata[DST_KEY_MAXSIZE];
- unsigned int sharedsize;
- isc_buffer_t secret;
- unsigned char *randomdata = NULL, secretdata[256];
- dns_ttl_t ttl = 0;
-
- if (tctx->dhkey == NULL) {
- tkey_log("process_dhtkey: tkey-dhkey not defined");
- tkeyout->error = dns_tsigerror_badalg;
- return (DNS_R_REFUSED);
- }
-
- if (!dns_name_equal(&tkeyin->algorithm, DNS_TSIG_HMACMD5_NAME)) {
- tkey_log("process_dhtkey: algorithms other than "
- "hmac-md5 are not supported");
- tkeyout->error = dns_tsigerror_badalg;
- return (ISC_R_SUCCESS);
- }
-
- /*
- * Look for a DH KEY record that will work with ours.
- */
- for (result = dns_message_firstname(msg, DNS_SECTION_ADDITIONAL);
- result == ISC_R_SUCCESS && !found_key;
- result = dns_message_nextname(msg, DNS_SECTION_ADDITIONAL)) {
- keyname = NULL;
- dns_message_currentname(msg, DNS_SECTION_ADDITIONAL, &keyname);
- keyset = NULL;
- result = dns_message_findtype(keyname, dns_rdatatype_key, 0,
- &keyset);
- if (result != ISC_R_SUCCESS)
- continue;
-
- for (result = dns_rdataset_first(keyset);
- result == ISC_R_SUCCESS && !found_key;
- result = dns_rdataset_next(keyset)) {
- dns_rdataset_current(keyset, &keyrdata);
- pubkey = NULL;
- result = dns_dnssec_keyfromrdata(keyname, &keyrdata,
- msg->mctx, &pubkey);
- if (result != ISC_R_SUCCESS) {
- dns_rdata_reset(&keyrdata);
- continue;
- }
- if (dst_key_alg(pubkey) == DNS_KEYALG_DH) {
- if (dst_key_paramcompare(pubkey, tctx->dhkey))
- {
- found_key = ISC_TRUE;
- ttl = keyset->ttl;
- break;
- } else
- found_incompatible = ISC_TRUE;
- }
- dst_key_free(&pubkey);
- dns_rdata_reset(&keyrdata);
- }
- }
-
- if (!found_key) {
- if (found_incompatible) {
- tkey_log("process_dhtkey: found an incompatible key");
- tkeyout->error = dns_tsigerror_badkey;
- return (ISC_R_SUCCESS);
- } else {
- tkey_log("process_dhtkey: failed to find a key");
- return (DNS_R_FORMERR);
- }
- }
-
- RETERR(add_rdata_to_list(msg, keyname, &keyrdata, ttl, namelist));
-
- isc_buffer_init(&ourkeybuf, keydata, sizeof(keydata));
- RETERR(dst_key_todns(tctx->dhkey, &ourkeybuf));
- isc_buffer_usedregion(&ourkeybuf, &ourkeyr);
- dns_rdata_fromregion(&ourkeyrdata, dns_rdataclass_any,
- dns_rdatatype_key, &ourkeyr);
-
- dns_name_init(&ourname, NULL);
- dns_name_clone(dst_key_name(tctx->dhkey), &ourname);
-
- /*
- * XXXBEW The TTL should be obtained from the database, if it exists.
- */
- RETERR(add_rdata_to_list(msg, &ourname, &ourkeyrdata, 0, namelist));
-
- RETERR(dst_key_secretsize(tctx->dhkey, &sharedsize));
- RETERR(isc_buffer_allocate(msg->mctx, &shared, sharedsize));
-
- result = dst_key_computesecret(pubkey, tctx->dhkey, shared);
- if (result != ISC_R_SUCCESS) {
- tkey_log("process_dhtkey: failed to compute shared secret: %s",
- isc_result_totext(result));
- goto failure;
- }
- dst_key_free(&pubkey);
-
- isc_buffer_init(&secret, secretdata, sizeof(secretdata));
-
- randomdata = isc_mem_get(tkeyout->mctx, TKEY_RANDOM_AMOUNT);
- if (randomdata == NULL)
- goto failure;
-
- result = isc_entropy_getdata(tctx->ectx, randomdata,
- TKEY_RANDOM_AMOUNT, NULL, 0);
- if (result != ISC_R_SUCCESS) {
- tkey_log("process_dhtkey: failed to obtain entropy: %s",
- isc_result_totext(result));
- goto failure;
- }
-
- r.base = randomdata;
- r.length = TKEY_RANDOM_AMOUNT;
- r2.base = tkeyin->key;
- r2.length = tkeyin->keylen;
- RETERR(compute_secret(shared, &r2, &r, &secret));
- isc_buffer_free(&shared);
-
- RETERR(dns_tsigkey_create(name, &tkeyin->algorithm,
- isc_buffer_base(&secret),
- isc_buffer_usedlength(&secret),
- ISC_TRUE, signer, tkeyin->inception,
- tkeyin->expire, ring->mctx, ring, NULL));
-
- /* This key is good for a long time */
- tkeyout->inception = tkeyin->inception;
- tkeyout->expire = tkeyin->expire;
-
- tkeyout->key = randomdata;
- tkeyout->keylen = TKEY_RANDOM_AMOUNT;
-
- return (ISC_R_SUCCESS);
-
- failure:
- if (!ISC_LIST_EMPTY(*namelist))
- free_namelist(msg, namelist);
- if (shared != NULL)
- isc_buffer_free(&shared);
- if (pubkey != NULL)
- dst_key_free(&pubkey);
- if (randomdata != NULL)
- isc_mem_put(tkeyout->mctx, randomdata, TKEY_RANDOM_AMOUNT);
- return (result);
-}
-
-static isc_result_t
-process_gsstkey(dns_name_t *name, dns_rdata_tkey_t *tkeyin,
- dns_tkeyctx_t *tctx, dns_rdata_tkey_t *tkeyout,
- dns_tsig_keyring_t *ring)
-{
- isc_result_t result = ISC_R_SUCCESS;
- dst_key_t *dstkey = NULL;
- dns_tsigkey_t *tsigkey = NULL;
- dns_fixedname_t principal;
- isc_stdtime_t now;
- isc_region_t intoken;
- isc_buffer_t *outtoken = NULL;
- gss_ctx_id_t gss_ctx = 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)) {
- tkeyout->error = dns_tsigerror_badalg;
- tkey_log("process_gsstkey(): dns_tsigerror_badalg"); /* XXXSRA */
- return (ISC_R_SUCCESS);
- }
-
- /*
- * XXXDCL need to check for key expiry per 4.1.1
- * XXXDCL need a way to check fully established, perhaps w/key_flags
- */
-
- intoken.base = tkeyin->key;
- intoken.length = tkeyin->keylen;
-
- result = dns_tsigkey_find(&tsigkey, name, &tkeyin->algorithm, ring);
- if (result == ISC_R_SUCCESS)
- gss_ctx = dst_key_getgssctx(tsigkey->key);
-
- dns_fixedname_init(&principal);
-
- /*
- * 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);
- if (result == DNS_R_INVALIDTKEY) {
- if (tsigkey != NULL)
- dns_tsigkey_detach(&tsigkey);
- tkeyout->error = dns_tsigerror_badkey;
- tkey_log("process_gsstkey(): dns_tsigerror_badkey"); /* XXXSRA */
- return (ISC_R_SUCCESS);
- }
- if (result != DNS_R_CONTINUE && result != ISC_R_SUCCESS)
- goto failure;
- /*
- * XXXDCL Section 4.1.3: Limit GSS_S_CONTINUE_NEEDED to 10 times.
- */
-
- isc_stdtime_get(&now);
-
- if (tsigkey == NULL) {
-#ifdef GSSAPI
- OM_uint32 gret, minor, lifetime;
-#endif
- isc_uint32_t expire;
-
- RETERR(dst_key_fromgssapi(name, gss_ctx, ring->mctx,
- &dstkey, &intoken));
- /*
- * Limit keys to 1 hour or the context's lifetime whichever
- * is smaller.
- */
- expire = now + 3600;
-#ifdef GSSAPI
- gret = gss_context_time(&minor, gss_ctx, &lifetime);
- if (gret == GSS_S_COMPLETE && now + lifetime < expire)
- expire = now + lifetime;
-#endif
- RETERR(dns_tsigkey_createfromkey(name, &tkeyin->algorithm,
- dstkey, ISC_TRUE,
- dns_fixedname_name(&principal),
- now, expire, ring->mctx, ring,
- NULL));
- dst_key_free(&dstkey);
- tkeyout->inception = now;
- tkeyout->expire = expire;
- } else {
- tkeyout->inception = tsigkey->inception;
- tkeyout->expire = tsigkey->expire;
- dns_tsigkey_detach(&tsigkey);
- }
-
- if (outtoken) {
- tkeyout->key = isc_mem_get(tkeyout->mctx,
- isc_buffer_usedlength(outtoken));
- if (tkeyout->key == NULL) {
- result = ISC_R_NOMEMORY;
- goto failure;
- }
- tkeyout->keylen = isc_buffer_usedlength(outtoken);
- memcpy(tkeyout->key, isc_buffer_base(outtoken),
- isc_buffer_usedlength(outtoken));
- isc_buffer_free(&outtoken);
- } else {
- tkeyout->key = isc_mem_get(tkeyout->mctx, tkeyin->keylen);
- if (tkeyout->key == NULL) {
- result = ISC_R_NOMEMORY;
- goto failure;
- }
- tkeyout->keylen = tkeyin->keylen;
- memcpy(tkeyout->key, tkeyin->key, tkeyin->keylen);
- }
-
- tkeyout->error = dns_rcode_noerror;
-
- tkey_log("process_gsstkey(): dns_tsigerror_noerror"); /* XXXSRA */
-
- return (ISC_R_SUCCESS);
-
-failure:
- if (tsigkey != NULL)
- dns_tsigkey_detach(&tsigkey);
-
- if (dstkey != NULL)
- dst_key_free(&dstkey);
-
- if (outtoken != NULL)
- isc_buffer_free(&outtoken);
-
- tkey_log("process_gsstkey(): %s",
- isc_result_totext(result)); /* XXXSRA */
-
- return (result);
-}
-
-static isc_result_t
-process_deletetkey(dns_name_t *signer, dns_name_t *name,
- dns_rdata_tkey_t *tkeyin, dns_rdata_tkey_t *tkeyout,
- dns_tsig_keyring_t *ring)
-{
- isc_result_t result;
- dns_tsigkey_t *tsigkey = NULL;
- dns_name_t *identity;
-
- result = dns_tsigkey_find(&tsigkey, name, &tkeyin->algorithm, ring);
- if (result != ISC_R_SUCCESS) {
- tkeyout->error = dns_tsigerror_badname;
- return (ISC_R_SUCCESS);
- }
-
- /*
- * Only allow a delete if the identity that created the key is the
- * same as the identity that signed the message.
- */
- identity = dns_tsigkey_identity(tsigkey);
- if (identity == NULL || !dns_name_equal(identity, signer)) {
- dns_tsigkey_detach(&tsigkey);
- return (DNS_R_REFUSED);
- }
-
- /*
- * Set the key to be deleted when no references are left. If the key
- * was not generated with TKEY and is in the config file, it may be
- * reloaded later.
- */
- dns_tsigkey_setdeleted(tsigkey);
-
- /* Release the reference */
- dns_tsigkey_detach(&tsigkey);
-
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_tkey_processquery(dns_message_t *msg, dns_tkeyctx_t *tctx,
- dns_tsig_keyring_t *ring)
-{
- isc_result_t result = ISC_R_SUCCESS;
- dns_rdata_tkey_t tkeyin, tkeyout;
- isc_boolean_t freetkeyin = ISC_FALSE;
- dns_name_t *qname, *name, *keyname, *signer, tsigner;
- dns_fixedname_t fkeyname;
- dns_rdataset_t *tkeyset;
- dns_rdata_t rdata;
- dns_namelist_t namelist;
- char tkeyoutdata[512];
- isc_buffer_t tkeyoutbuf;
-
- REQUIRE(msg != NULL);
- REQUIRE(tctx != NULL);
- REQUIRE(ring != NULL);
-
- ISC_LIST_INIT(namelist);
-
- /*
- * Interpret the question section.
- */
- result = dns_message_firstname(msg, DNS_SECTION_QUESTION);
- if (result != ISC_R_SUCCESS)
- return (DNS_R_FORMERR);
-
- qname = NULL;
- dns_message_currentname(msg, DNS_SECTION_QUESTION, &qname);
-
- /*
- * Look for a TKEY record that matches the question.
- */
- tkeyset = NULL;
- name = NULL;
- result = dns_message_findname(msg, DNS_SECTION_ADDITIONAL, qname,
- dns_rdatatype_tkey, 0, &name, &tkeyset);
- if (result != ISC_R_SUCCESS) {
- /*
- * Try the answer section, since that's where Win2000
- * puts it.
- */
- if (dns_message_findname(msg, DNS_SECTION_ANSWER, qname,
- dns_rdatatype_tkey, 0, &name,
- &tkeyset) != ISC_R_SUCCESS) {
- result = DNS_R_FORMERR;
- tkey_log("dns_tkey_processquery: couldn't find a TKEY "
- "matching the question");
- goto failure;
- }
- }
- result = dns_rdataset_first(tkeyset);
- if (result != ISC_R_SUCCESS) {
- result = DNS_R_FORMERR;
- goto failure;
- }
- dns_rdata_init(&rdata);
- dns_rdataset_current(tkeyset, &rdata);
-
- RETERR(dns_rdata_tostruct(&rdata, &tkeyin, NULL));
- freetkeyin = ISC_TRUE;
-
- if (tkeyin.error != dns_rcode_noerror) {
- result = DNS_R_FORMERR;
- goto failure;
- }
-
- /*
- * Before we go any farther, verify that the message was signed.
- * GSSAPI TKEY doesn't require a signature, the rest do.
- */
- dns_name_init(&tsigner, NULL);
- result = dns_message_signer(msg, &tsigner);
- if (result != ISC_R_SUCCESS) {
- if (tkeyin.mode == DNS_TKEYMODE_GSSAPI &&
- result == ISC_R_NOTFOUND)
- signer = NULL;
- else {
- tkey_log("dns_tkey_processquery: query was not "
- "properly signed - rejecting");
- result = DNS_R_FORMERR;
- goto failure;
- }
- } else
- signer = &tsigner;
-
- tkeyout.common.rdclass = tkeyin.common.rdclass;
- tkeyout.common.rdtype = tkeyin.common.rdtype;
- ISC_LINK_INIT(&tkeyout.common, link);
- tkeyout.mctx = msg->mctx;
-
- dns_name_init(&tkeyout.algorithm, NULL);
- dns_name_clone(&tkeyin.algorithm, &tkeyout.algorithm);
-
- tkeyout.inception = tkeyout.expire = 0;
- tkeyout.mode = tkeyin.mode;
- tkeyout.error = 0;
- tkeyout.keylen = tkeyout.otherlen = 0;
- tkeyout.key = tkeyout.other = NULL;
-
- /*
- * A delete operation must have a fully specified key name. If this
- * is not a delete, we do the following:
- * if (qname != ".")
- * keyname = qname + defaultdomain
- * else
- * keyname = <random hex> + defaultdomain
- */
- if (tkeyin.mode != DNS_TKEYMODE_DELETE) {
- dns_tsigkey_t *tsigkey = NULL;
-
- if (tctx->domain == NULL && tkeyin.mode != DNS_TKEYMODE_GSSAPI) {
- tkey_log("dns_tkey_processquery: tkey-domain not set");
- result = DNS_R_REFUSED;
- goto failure;
- }
-
- dns_fixedname_init(&fkeyname);
- keyname = dns_fixedname_name(&fkeyname);
-
- if (!dns_name_equal(qname, dns_rootname)) {
- unsigned int n = dns_name_countlabels(qname);
- RUNTIME_CHECK(dns_name_copy(qname, keyname, NULL)
- == ISC_R_SUCCESS);
- dns_name_getlabelsequence(keyname, 0, n - 1, keyname);
- } else {
- static char hexdigits[16] = {
- '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
- unsigned char randomdata[16];
- char randomtext[32];
- isc_buffer_t b;
- unsigned int i, j;
-
- result = isc_entropy_getdata(tctx->ectx,
- randomdata,
- sizeof(randomdata),
- NULL, 0);
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- for (i = 0, j = 0; i < sizeof(randomdata); i++) {
- unsigned char val = randomdata[i];
- randomtext[j++] = hexdigits[val >> 4];
- randomtext[j++] = hexdigits[val & 0xF];
- }
- isc_buffer_init(&b, randomtext, sizeof(randomtext));
- isc_buffer_add(&b, sizeof(randomtext));
- result = dns_name_fromtext(keyname, &b, NULL, 0, NULL);
- if (result != ISC_R_SUCCESS)
- goto failure;
- }
-
- if (tkeyin.mode == DNS_TKEYMODE_GSSAPI) {
- /* Yup. This is a hack */
- result = dns_name_concatenate(keyname, dns_rootname,
- keyname, NULL);
- if (result != ISC_R_SUCCESS)
- goto failure;
- } else {
- result = dns_name_concatenate(keyname, tctx->domain,
- keyname, NULL);
- if (result != ISC_R_SUCCESS)
- goto failure;
- }
-
- result = dns_tsigkey_find(&tsigkey, keyname, NULL, ring);
-
- if (result == ISC_R_SUCCESS) {
- tkeyout.error = dns_tsigerror_badname;
- dns_tsigkey_detach(&tsigkey);
- goto failure_with_tkey;
- } else if (result != ISC_R_NOTFOUND)
- goto failure;
- } else
- keyname = qname;
-
- switch (tkeyin.mode) {
- case DNS_TKEYMODE_DIFFIEHELLMAN:
- tkeyout.error = dns_rcode_noerror;
- RETERR(process_dhtkey(msg, signer, keyname, &tkeyin,
- tctx, &tkeyout, ring,
- &namelist));
- break;
- case DNS_TKEYMODE_GSSAPI:
- tkeyout.error = dns_rcode_noerror;
- RETERR(process_gsstkey(keyname, &tkeyin, tctx,
- &tkeyout, ring));
- break;
- case DNS_TKEYMODE_DELETE:
- tkeyout.error = dns_rcode_noerror;
- RETERR(process_deletetkey(signer, keyname, &tkeyin,
- &tkeyout, ring));
- break;
- case DNS_TKEYMODE_SERVERASSIGNED:
- case DNS_TKEYMODE_RESOLVERASSIGNED:
- result = DNS_R_NOTIMP;
- goto failure;
- default:
- tkeyout.error = dns_tsigerror_badmode;
- }
-
- failure_with_tkey:
- dns_rdata_init(&rdata);
- isc_buffer_init(&tkeyoutbuf, tkeyoutdata, sizeof(tkeyoutdata));
- result = dns_rdata_fromstruct(&rdata, tkeyout.common.rdclass,
- tkeyout.common.rdtype, &tkeyout,
- &tkeyoutbuf);
-
- if (freetkeyin) {
- dns_rdata_freestruct(&tkeyin);
- freetkeyin = ISC_FALSE;
- }
-
- if (tkeyout.key != NULL)
- isc_mem_put(tkeyout.mctx, tkeyout.key, tkeyout.keylen);
- if (tkeyout.other != NULL)
- isc_mem_put(tkeyout.mctx, tkeyout.other, tkeyout.otherlen);
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- RETERR(add_rdata_to_list(msg, keyname, &rdata, 0, &namelist));
-
- RETERR(dns_message_reply(msg, ISC_TRUE));
-
- name = ISC_LIST_HEAD(namelist);
- while (name != NULL) {
- dns_name_t *next = ISC_LIST_NEXT(name, link);
- ISC_LIST_UNLINK(namelist, name, link);
- dns_message_addname(msg, name, DNS_SECTION_ANSWER);
- name = next;
- }
-
- return (ISC_R_SUCCESS);
-
- failure:
- if (freetkeyin)
- dns_rdata_freestruct(&tkeyin);
- if (!ISC_LIST_EMPTY(namelist))
- free_namelist(msg, &namelist);
- return (result);
-}
-
-static isc_result_t
-buildquery(dns_message_t *msg, dns_name_t *name,
- dns_rdata_tkey_t *tkey, isc_boolean_t win2k)
-{
- dns_name_t *qname = NULL, *aname = NULL;
- dns_rdataset_t *question = NULL, *tkeyset = NULL;
- dns_rdatalist_t *tkeylist = NULL;
- dns_rdata_t *rdata = NULL;
- isc_buffer_t *dynbuf = NULL;
- isc_result_t result;
-
- REQUIRE(msg != NULL);
- REQUIRE(name != NULL);
- REQUIRE(tkey != NULL);
-
- RETERR(dns_message_gettempname(msg, &qname));
- RETERR(dns_message_gettempname(msg, &aname));
-
- RETERR(dns_message_gettemprdataset(msg, &question));
- dns_rdataset_init(question);
- dns_rdataset_makequestion(question, dns_rdataclass_any,
- dns_rdatatype_tkey);
-
- RETERR(isc_buffer_allocate(msg->mctx, &dynbuf, 4096));
- RETERR(dns_message_gettemprdata(msg, &rdata));
-
- RETERR(dns_rdata_fromstruct(rdata, dns_rdataclass_any,
- dns_rdatatype_tkey, tkey, dynbuf));
- dns_message_takebuffer(msg, &dynbuf);
-
- RETERR(dns_message_gettemprdatalist(msg, &tkeylist));
- tkeylist->rdclass = dns_rdataclass_any;
- tkeylist->type = dns_rdatatype_tkey;
- tkeylist->covers = 0;
- tkeylist->ttl = 0;
- ISC_LIST_INIT(tkeylist->rdata);
- ISC_LIST_APPEND(tkeylist->rdata, rdata, link);
-
- RETERR(dns_message_gettemprdataset(msg, &tkeyset));
- dns_rdataset_init(tkeyset);
- RETERR(dns_rdatalist_tordataset(tkeylist, tkeyset));
-
- dns_name_init(qname, NULL);
- dns_name_clone(name, qname);
-
- dns_name_init(aname, NULL);
- dns_name_clone(name, aname);
-
- ISC_LIST_APPEND(qname->list, question, link);
- ISC_LIST_APPEND(aname->list, tkeyset, link);
-
- dns_message_addname(msg, qname, DNS_SECTION_QUESTION);
-
- /*
- * Windows 2000 needs this in the answer section, not the additional
- * section where the RFC specifies.
- */
- if (win2k)
- dns_message_addname(msg, aname, DNS_SECTION_ANSWER);
- else
- dns_message_addname(msg, aname, DNS_SECTION_ADDITIONAL);
-
- return (ISC_R_SUCCESS);
-
- failure:
- if (qname != NULL)
- dns_message_puttempname(msg, &qname);
- if (aname != NULL)
- dns_message_puttempname(msg, &aname);
- if (question != NULL) {
- dns_rdataset_disassociate(question);
- dns_message_puttemprdataset(msg, &question);
- }
- if (dynbuf != NULL)
- isc_buffer_free(&dynbuf);
- printf("buildquery error\n");
- return (result);
-}
-
-isc_result_t
-dns_tkey_builddhquery(dns_message_t *msg, dst_key_t *key, dns_name_t *name,
- dns_name_t *algorithm, isc_buffer_t *nonce,
- isc_uint32_t lifetime)
-{
- dns_rdata_tkey_t tkey;
- dns_rdata_t *rdata = NULL;
- isc_buffer_t *dynbuf = NULL;
- isc_region_t r;
- dns_name_t keyname;
- dns_namelist_t namelist;
- isc_result_t result;
- isc_stdtime_t now;
-
- REQUIRE(msg != NULL);
- REQUIRE(key != NULL);
- REQUIRE(dst_key_alg(key) == DNS_KEYALG_DH);
- REQUIRE(dst_key_isprivate(key));
- REQUIRE(name != NULL);
- REQUIRE(algorithm != NULL);
-
- tkey.common.rdclass = dns_rdataclass_any;
- tkey.common.rdtype = dns_rdatatype_tkey;
- ISC_LINK_INIT(&tkey.common, link);
- tkey.mctx = msg->mctx;
- dns_name_init(&tkey.algorithm, NULL);
- dns_name_clone(algorithm, &tkey.algorithm);
- isc_stdtime_get(&now);
- tkey.inception = now;
- tkey.expire = now + lifetime;
- tkey.mode = DNS_TKEYMODE_DIFFIEHELLMAN;
- if (nonce != NULL)
- isc_buffer_usedregion(nonce, &r);
- else {
- r.base = isc_mem_get(msg->mctx, 0);
- r.length = 0;
- }
- tkey.error = 0;
- tkey.key = r.base;
- tkey.keylen = r.length;
- tkey.other = NULL;
- tkey.otherlen = 0;
-
- RETERR(buildquery(msg, name, &tkey, ISC_FALSE));
-
- if (nonce == NULL)
- isc_mem_put(msg->mctx, r.base, 0);
-
- RETERR(dns_message_gettemprdata(msg, &rdata));
- RETERR(isc_buffer_allocate(msg->mctx, &dynbuf, 1024));
- RETERR(dst_key_todns(key, dynbuf));
- isc_buffer_usedregion(dynbuf, &r);
- dns_rdata_fromregion(rdata, dns_rdataclass_any,
- dns_rdatatype_key, &r);
- dns_message_takebuffer(msg, &dynbuf);
-
- dns_name_init(&keyname, NULL);
- dns_name_clone(dst_key_name(key), &keyname);
-
- ISC_LIST_INIT(namelist);
- RETERR(add_rdata_to_list(msg, &keyname, rdata, 0, &namelist));
- name = ISC_LIST_HEAD(namelist);
- while (name != NULL) {
- dns_name_t *next = ISC_LIST_NEXT(name, link);
- ISC_LIST_UNLINK(namelist, name, link);
- dns_message_addname(msg, name, DNS_SECTION_ADDITIONAL);
- name = next;
- }
-
- return (ISC_R_SUCCESS);
-
- failure:
-
- if (dynbuf != NULL)
- isc_buffer_free(&dynbuf);
- return (result);
-}
-
-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,
- isc_mem_t *mctx, char **err_message)
-{
- dns_rdata_tkey_t tkey;
- isc_result_t result;
- isc_stdtime_t now;
- isc_buffer_t token;
- unsigned char array[4096];
-
- UNUSED(intoken);
-
- REQUIRE(msg != NULL);
- 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,
- mctx, err_message);
- if (result != DNS_R_CONTINUE && result != ISC_R_SUCCESS)
- return (result);
-
- tkey.common.rdclass = dns_rdataclass_any;
- tkey.common.rdtype = dns_rdatatype_tkey;
- ISC_LINK_INIT(&tkey.common, link);
- tkey.mctx = NULL;
- dns_name_init(&tkey.algorithm, NULL);
-
- if (win2k)
- dns_name_clone(DNS_TSIG_GSSAPIMS_NAME, &tkey.algorithm);
- else
- dns_name_clone(DNS_TSIG_GSSAPI_NAME, &tkey.algorithm);
-
- isc_stdtime_get(&now);
- tkey.inception = now;
- tkey.expire = now + lifetime;
- tkey.mode = DNS_TKEYMODE_GSSAPI;
- tkey.error = 0;
- tkey.key = isc_buffer_base(&token);
- tkey.keylen = isc_buffer_usedlength(&token);
- tkey.other = NULL;
- tkey.otherlen = 0;
-
- RETERR(buildquery(msg, name, &tkey, win2k));
-
- return (ISC_R_SUCCESS);
-
- failure:
- return (result);
-}
-
-isc_result_t
-dns_tkey_builddeletequery(dns_message_t *msg, dns_tsigkey_t *key) {
- dns_rdata_tkey_t tkey;
-
- REQUIRE(msg != NULL);
- REQUIRE(key != NULL);
-
- tkey.common.rdclass = dns_rdataclass_any;
- tkey.common.rdtype = dns_rdatatype_tkey;
- ISC_LINK_INIT(&tkey.common, link);
- tkey.mctx = msg->mctx;
- dns_name_init(&tkey.algorithm, NULL);
- dns_name_clone(key->algorithm, &tkey.algorithm);
- tkey.inception = tkey.expire = 0;
- tkey.mode = DNS_TKEYMODE_DELETE;
- tkey.error = 0;
- tkey.keylen = tkey.otherlen = 0;
- tkey.key = tkey.other = NULL;
-
- return (buildquery(msg, &key->name, &tkey, ISC_FALSE));
-}
-
-static isc_result_t
-find_tkey(dns_message_t *msg, dns_name_t **name, dns_rdata_t *rdata,
- int section)
-{
- dns_rdataset_t *tkeyset;
- isc_result_t result;
-
- result = dns_message_firstname(msg, section);
- while (result == ISC_R_SUCCESS) {
- *name = NULL;
- dns_message_currentname(msg, section, name);
- tkeyset = NULL;
- result = dns_message_findtype(*name, dns_rdatatype_tkey, 0,
- &tkeyset);
- if (result == ISC_R_SUCCESS) {
- result = dns_rdataset_first(tkeyset);
- if (result != ISC_R_SUCCESS)
- return (result);
- dns_rdataset_current(tkeyset, rdata);
- return (ISC_R_SUCCESS);
- }
- result = dns_message_nextname(msg, section);
- }
- if (result == ISC_R_NOMORE)
- return (ISC_R_NOTFOUND);
- return (result);
-}
-
-isc_result_t
-dns_tkey_processdhresponse(dns_message_t *qmsg, dns_message_t *rmsg,
- dst_key_t *key, isc_buffer_t *nonce,
- dns_tsigkey_t **outkey, dns_tsig_keyring_t *ring)
-{
- dns_rdata_t qtkeyrdata = DNS_RDATA_INIT, rtkeyrdata = DNS_RDATA_INIT;
- dns_name_t keyname, *tkeyname, *theirkeyname, *ourkeyname, *tempname;
- dns_rdataset_t *theirkeyset = NULL, *ourkeyset = NULL;
- dns_rdata_t theirkeyrdata = DNS_RDATA_INIT;
- dst_key_t *theirkey = NULL;
- dns_rdata_tkey_t qtkey, rtkey;
- unsigned char secretdata[256];
- unsigned int sharedsize;
- isc_buffer_t *shared = NULL, secret;
- isc_region_t r, r2;
- isc_result_t result;
- isc_boolean_t freertkey = ISC_FALSE;
-
- REQUIRE(qmsg != NULL);
- REQUIRE(rmsg != NULL);
- REQUIRE(key != NULL);
- REQUIRE(dst_key_alg(key) == DNS_KEYALG_DH);
- REQUIRE(dst_key_isprivate(key));
- if (outkey != NULL)
- REQUIRE(*outkey == NULL);
-
- if (rmsg->rcode != dns_rcode_noerror)
- return (ISC_RESULTCLASS_DNSRCODE + rmsg->rcode);
- RETERR(find_tkey(rmsg, &tkeyname, &rtkeyrdata, DNS_SECTION_ANSWER));
- RETERR(dns_rdata_tostruct(&rtkeyrdata, &rtkey, NULL));
- freertkey = ISC_TRUE;
-
- RETERR(find_tkey(qmsg, &tempname, &qtkeyrdata,
- DNS_SECTION_ADDITIONAL));
- RETERR(dns_rdata_tostruct(&qtkeyrdata, &qtkey, NULL));
-
- if (rtkey.error != dns_rcode_noerror ||
- rtkey.mode != DNS_TKEYMODE_DIFFIEHELLMAN ||
- rtkey.mode != qtkey.mode ||
- !dns_name_equal(&rtkey.algorithm, &qtkey.algorithm) ||
- rmsg->rcode != dns_rcode_noerror) {
- tkey_log("dns_tkey_processdhresponse: tkey mode invalid "
- "or error set(1)");
- result = DNS_R_INVALIDTKEY;
- dns_rdata_freestruct(&qtkey);
- goto failure;
- }
-
- dns_rdata_freestruct(&qtkey);
-
- dns_name_init(&keyname, NULL);
- dns_name_clone(dst_key_name(key), &keyname);
-
- ourkeyname = NULL;
- ourkeyset = NULL;
- RETERR(dns_message_findname(rmsg, DNS_SECTION_ANSWER, &keyname,
- dns_rdatatype_key, 0, &ourkeyname,
- &ourkeyset));
-
- result = dns_message_firstname(rmsg, DNS_SECTION_ANSWER);
- while (result == ISC_R_SUCCESS) {
- theirkeyname = NULL;
- dns_message_currentname(rmsg, DNS_SECTION_ANSWER,
- &theirkeyname);
- if (dns_name_equal(theirkeyname, ourkeyname))
- goto next;
- theirkeyset = NULL;
- result = dns_message_findtype(theirkeyname, dns_rdatatype_key,
- 0, &theirkeyset);
- if (result == ISC_R_SUCCESS) {
- RETERR(dns_rdataset_first(theirkeyset));
- break;
- }
- next:
- result = dns_message_nextname(rmsg, DNS_SECTION_ANSWER);
- }
-
- if (theirkeyset == NULL) {
- tkey_log("dns_tkey_processdhresponse: failed to find server "
- "key");
- result = ISC_R_NOTFOUND;
- goto failure;
- }
-
- dns_rdataset_current(theirkeyset, &theirkeyrdata);
- RETERR(dns_dnssec_keyfromrdata(theirkeyname, &theirkeyrdata,
- rmsg->mctx, &theirkey));
-
- RETERR(dst_key_secretsize(key, &sharedsize));
- RETERR(isc_buffer_allocate(rmsg->mctx, &shared, sharedsize));
-
- RETERR(dst_key_computesecret(theirkey, key, shared));
-
- isc_buffer_init(&secret, secretdata, sizeof(secretdata));
-
- r.base = rtkey.key;
- r.length = rtkey.keylen;
- if (nonce != NULL)
- isc_buffer_usedregion(nonce, &r2);
- else {
- r2.base = isc_mem_get(rmsg->mctx, 0);
- r2.length = 0;
- }
- RETERR(compute_secret(shared, &r2, &r, &secret));
- if (nonce == NULL)
- isc_mem_put(rmsg->mctx, r2.base, 0);
-
- isc_buffer_usedregion(&secret, &r);
- result = dns_tsigkey_create(tkeyname, &rtkey.algorithm,
- r.base, r.length, ISC_TRUE,
- NULL, rtkey.inception, rtkey.expire,
- rmsg->mctx, ring, outkey);
- isc_buffer_free(&shared);
- dns_rdata_freestruct(&rtkey);
- dst_key_free(&theirkey);
- return (result);
-
- failure:
- if (shared != NULL)
- isc_buffer_free(&shared);
-
- if (theirkey != NULL)
- dst_key_free(&theirkey);
-
- if (freertkey)
- dns_rdata_freestruct(&rtkey);
-
- return (result);
-}
-
-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, char **err_message)
-{
- dns_rdata_t rtkeyrdata = DNS_RDATA_INIT, qtkeyrdata = DNS_RDATA_INIT;
- dns_name_t *tkeyname;
- dns_rdata_tkey_t rtkey, qtkey;
- dst_key_t *dstkey = NULL;
- isc_buffer_t intoken;
- isc_result_t result;
- unsigned char array[1024];
-
- REQUIRE(outtoken != NULL);
- REQUIRE(qmsg != NULL);
- REQUIRE(rmsg != NULL);
- REQUIRE(gname != NULL);
- REQUIRE(ring != NULL);
- if (outkey != NULL)
- REQUIRE(*outkey == NULL);
-
- if (rmsg->rcode != dns_rcode_noerror)
- return (ISC_RESULTCLASS_DNSRCODE + rmsg->rcode);
- RETERR(find_tkey(rmsg, &tkeyname, &rtkeyrdata, DNS_SECTION_ANSWER));
- RETERR(dns_rdata_tostruct(&rtkeyrdata, &rtkey, NULL));
-
- /*
- * Win2k puts the item in the ANSWER section, while the RFC
- * specifies it should be in the ADDITIONAL section. Check first
- * where it should be, and then where it may be.
- */
- result = find_tkey(qmsg, &tkeyname, &qtkeyrdata,
- DNS_SECTION_ADDITIONAL);
- if (result == ISC_R_NOTFOUND)
- result = find_tkey(qmsg, &tkeyname, &qtkeyrdata,
- DNS_SECTION_ANSWER);
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- RETERR(dns_rdata_tostruct(&qtkeyrdata, &qtkey, NULL));
-
- if (rtkey.error != dns_rcode_noerror ||
- rtkey.mode != DNS_TKEYMODE_GSSAPI ||
- !dns_name_equal(&rtkey.algorithm, &qtkey.algorithm)) {
- tkey_log("dns_tkey_processgssresponse: tkey mode invalid "
- "or error set(2) %d", rtkey.error);
- _dns_tkey_dumpmessage(qmsg);
- _dns_tkey_dumpmessage(rmsg);
- result = DNS_R_INVALIDTKEY;
- goto failure;
- }
-
- isc_buffer_init(outtoken, array, sizeof(array));
- isc_buffer_init(&intoken, rtkey.key, rtkey.keylen);
- RETERR(dst_gssapi_initctx(gname, &intoken, outtoken, context,
- ring->mctx, err_message));
-
- RETERR(dst_key_fromgssapi(dns_rootname, *context, rmsg->mctx,
- &dstkey, NULL));
-
- RETERR(dns_tsigkey_createfromkey(tkeyname, DNS_TSIG_GSSAPI_NAME,
- dstkey, ISC_FALSE, NULL,
- rtkey.inception, rtkey.expire,
- ring->mctx, ring, outkey));
- dst_key_free(&dstkey);
- dns_rdata_freestruct(&rtkey);
- return (result);
-
- failure:
- /*
- * XXXSRA This probably leaks memory from rtkey and qtkey.
- */
- if (dstkey != NULL)
- dst_key_free(&dstkey);
- return (result);
-}
-
-isc_result_t
-dns_tkey_processdeleteresponse(dns_message_t *qmsg, dns_message_t *rmsg,
- dns_tsig_keyring_t *ring)
-{
- dns_rdata_t qtkeyrdata = DNS_RDATA_INIT, rtkeyrdata = DNS_RDATA_INIT;
- dns_name_t *tkeyname, *tempname;
- dns_rdata_tkey_t qtkey, rtkey;
- dns_tsigkey_t *tsigkey = NULL;
- isc_result_t result;
-
- REQUIRE(qmsg != NULL);
- REQUIRE(rmsg != NULL);
-
- if (rmsg->rcode != dns_rcode_noerror)
- return(ISC_RESULTCLASS_DNSRCODE + rmsg->rcode);
-
- RETERR(find_tkey(rmsg, &tkeyname, &rtkeyrdata, DNS_SECTION_ANSWER));
- RETERR(dns_rdata_tostruct(&rtkeyrdata, &rtkey, NULL));
-
- RETERR(find_tkey(qmsg, &tempname, &qtkeyrdata,
- DNS_SECTION_ADDITIONAL));
- RETERR(dns_rdata_tostruct(&qtkeyrdata, &qtkey, NULL));
-
- if (rtkey.error != dns_rcode_noerror ||
- rtkey.mode != DNS_TKEYMODE_DELETE ||
- rtkey.mode != qtkey.mode ||
- !dns_name_equal(&rtkey.algorithm, &qtkey.algorithm) ||
- rmsg->rcode != dns_rcode_noerror) {
- tkey_log("dns_tkey_processdeleteresponse: tkey mode invalid "
- "or error set(3)");
- result = DNS_R_INVALIDTKEY;
- dns_rdata_freestruct(&qtkey);
- dns_rdata_freestruct(&rtkey);
- goto failure;
- }
-
- dns_rdata_freestruct(&qtkey);
-
- RETERR(dns_tsigkey_find(&tsigkey, tkeyname, &rtkey.algorithm, ring));
-
- dns_rdata_freestruct(&rtkey);
-
- /*
- * Mark the key as deleted.
- */
- dns_tsigkey_setdeleted(tsigkey);
- /*
- * Release the reference.
- */
- dns_tsigkey_detach(&tsigkey);
-
- failure:
- return (result);
-}
-
-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, char **err_message)
-{
- dns_rdata_t rtkeyrdata = DNS_RDATA_INIT, qtkeyrdata = DNS_RDATA_INIT;
- dns_name_t *tkeyname;
- dns_rdata_tkey_t rtkey, qtkey;
- isc_buffer_t intoken, outtoken;
- dst_key_t *dstkey = NULL;
- isc_result_t result;
- unsigned char array[1024];
-
- REQUIRE(qmsg != NULL);
- REQUIRE(rmsg != NULL);
- REQUIRE(server != NULL);
- if (outkey != NULL)
- REQUIRE(*outkey == NULL);
-
- if (rmsg->rcode != dns_rcode_noerror)
- return (ISC_RESULTCLASS_DNSRCODE + rmsg->rcode);
-
- RETERR(find_tkey(rmsg, &tkeyname, &rtkeyrdata, DNS_SECTION_ANSWER));
- RETERR(dns_rdata_tostruct(&rtkeyrdata, &rtkey, NULL));
-
- if (win2k == ISC_TRUE)
- RETERR(find_tkey(qmsg, &tkeyname, &qtkeyrdata,
- DNS_SECTION_ANSWER));
- else
- RETERR(find_tkey(qmsg, &tkeyname, &qtkeyrdata,
- DNS_SECTION_ADDITIONAL));
-
- RETERR(dns_rdata_tostruct(&qtkeyrdata, &qtkey, NULL));
-
- if (rtkey.error != dns_rcode_noerror ||
- rtkey.mode != DNS_TKEYMODE_GSSAPI ||
- !dns_name_equal(&rtkey.algorithm, &qtkey.algorithm))
- {
- tkey_log("dns_tkey_processdhresponse: tkey mode invalid "
- "or error set(4)");
- result = DNS_R_INVALIDTKEY;
- goto failure;
- }
-
- isc_buffer_init(&intoken, rtkey.key, rtkey.keylen);
- isc_buffer_init(&outtoken, array, sizeof(array));
-
- 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, NULL));
-
- /*
- * XXXSRA This seems confused. If we got CONTINUE from initctx,
- * the GSS negotiation hasn't completed yet, so we can't sign
- * anything yet.
- */
-
- RETERR(dns_tsigkey_createfromkey(tkeyname,
- (win2k
- ? DNS_TSIG_GSSAPIMS_NAME
- : DNS_TSIG_GSSAPI_NAME),
- dstkey, ISC_TRUE, NULL,
- rtkey.inception, rtkey.expire,
- ring->mctx, ring, outkey));
- dst_key_free(&dstkey);
- dns_rdata_freestruct(&rtkey);
- return (result);
-
- failure:
- /*
- * XXXSRA This probably leaks memory from qtkey.
- */
- dns_rdata_freestruct(&rtkey);
- if (dstkey != NULL)
- dst_key_free(&dstkey);
- return (result);
-}
diff --git a/contrib/bind9/lib/dns/tsec.c b/contrib/bind9/lib/dns/tsec.c
deleted file mode 100644
index bfa6195d0d89..000000000000
--- a/contrib/bind9/lib/dns/tsec.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * 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/contrib/bind9/lib/dns/tsig.c b/contrib/bind9/lib/dns/tsig.c
deleted file mode 100644
index c7768f4c788a..000000000000
--- a/contrib/bind9/lib/dns/tsig.c
+++ /dev/null
@@ -1,1883 +0,0 @@
-/*
- * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2002 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * $Id$
- */
-/*! \file */
-#include <config.h>
-#include <stdlib.h>
-
-#include <isc/buffer.h>
-#include <isc/mem.h>
-#include <isc/print.h>
-#include <isc/refcount.h>
-#include <isc/serial.h>
-#include <isc/string.h> /* Required for HP/UX (and others?) */
-#include <isc/util.h>
-#include <isc/time.h>
-
-#include <dns/keyvalues.h>
-#include <dns/log.h>
-#include <dns/message.h>
-#include <dns/fixedname.h>
-#include <dns/rbt.h>
-#include <dns/rdata.h>
-#include <dns/rdatalist.h>
-#include <dns/rdataset.h>
-#include <dns/rdatastruct.h>
-#include <dns/result.h>
-#include <dns/tsig.h>
-
-#include <dst/result.h>
-
-#define TSIG_MAGIC ISC_MAGIC('T', 'S', 'I', 'G')
-#define VALID_TSIG_KEY(x) ISC_MAGIC_VALID(x, TSIG_MAGIC)
-
-#ifndef DNS_TSIG_MAXGENERATEDKEYS
-#define DNS_TSIG_MAXGENERATEDKEYS 4096
-#endif
-
-#define is_response(msg) (msg->flags & DNS_MESSAGEFLAG_QR)
-#define algname_is_allocated(algname) \
- ((algname) != dns_tsig_hmacmd5_name && \
- (algname) != dns_tsig_hmacsha1_name && \
- (algname) != dns_tsig_hmacsha224_name && \
- (algname) != dns_tsig_hmacsha256_name && \
- (algname) != dns_tsig_hmacsha384_name && \
- (algname) != dns_tsig_hmacsha512_name && \
- (algname) != dns_tsig_gssapi_name && \
- (algname) != dns_tsig_gssapims_name)
-
-#define BADTIMELEN 6
-
-static unsigned char hmacmd5_ndata[] = "\010hmac-md5\007sig-alg\003reg\003int";
-static unsigned char hmacmd5_offsets[] = { 0, 9, 17, 21, 25 };
-
-static dns_name_t hmacmd5 = {
- DNS_NAME_MAGIC,
- hmacmd5_ndata, 26, 5,
- DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE,
- hmacmd5_offsets, NULL,
- {(void *)-1, (void *)-1},
- {NULL, NULL}
-};
-
-dns_name_t *dns_tsig_hmacmd5_name = &hmacmd5;
-
-static unsigned char gsstsig_ndata[] = "\010gss-tsig";
-static unsigned char gsstsig_offsets[] = { 0, 9 };
-static dns_name_t gsstsig = {
- DNS_NAME_MAGIC,
- gsstsig_ndata, 10, 2,
- DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE,
- gsstsig_offsets, NULL,
- {(void *)-1, (void *)-1},
- {NULL, NULL}
-};
-LIBDNS_EXTERNAL_DATA dns_name_t *dns_tsig_gssapi_name = &gsstsig;
-
-/*
- * Since Microsoft doesn't follow its own standard, we will use this
- * alternate name as a second guess.
- */
-static unsigned char gsstsigms_ndata[] = "\003gss\011microsoft\003com";
-static unsigned char gsstsigms_offsets[] = { 0, 4, 14, 18 };
-static dns_name_t gsstsigms = {
- DNS_NAME_MAGIC,
- gsstsigms_ndata, 19, 4,
- DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE,
- gsstsigms_offsets, NULL,
- {(void *)-1, (void *)-1},
- {NULL, NULL}
-};
-LIBDNS_EXTERNAL_DATA dns_name_t *dns_tsig_gssapims_name = &gsstsigms;
-
-static unsigned char hmacsha1_ndata[] = "\011hmac-sha1";
-static unsigned char hmacsha1_offsets[] = { 0, 10 };
-
-static dns_name_t hmacsha1 = {
- DNS_NAME_MAGIC,
- hmacsha1_ndata, 11, 2,
- DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE,
- hmacsha1_offsets, NULL,
- {(void *)-1, (void *)-1},
- {NULL, NULL}
-};
-
-LIBDNS_EXTERNAL_DATA dns_name_t *dns_tsig_hmacsha1_name = &hmacsha1;
-
-static unsigned char hmacsha224_ndata[] = "\013hmac-sha224";
-static unsigned char hmacsha224_offsets[] = { 0, 12 };
-
-static dns_name_t hmacsha224 = {
- DNS_NAME_MAGIC,
- hmacsha224_ndata, 13, 2,
- DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE,
- hmacsha224_offsets, NULL,
- {(void *)-1, (void *)-1},
- {NULL, NULL}
-};
-
-LIBDNS_EXTERNAL_DATA dns_name_t *dns_tsig_hmacsha224_name = &hmacsha224;
-
-static unsigned char hmacsha256_ndata[] = "\013hmac-sha256";
-static unsigned char hmacsha256_offsets[] = { 0, 12 };
-
-static dns_name_t hmacsha256 = {
- DNS_NAME_MAGIC,
- hmacsha256_ndata, 13, 2,
- DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE,
- hmacsha256_offsets, NULL,
- {(void *)-1, (void *)-1},
- {NULL, NULL}
-};
-
-LIBDNS_EXTERNAL_DATA dns_name_t *dns_tsig_hmacsha256_name = &hmacsha256;
-
-static unsigned char hmacsha384_ndata[] = "\013hmac-sha384";
-static unsigned char hmacsha384_offsets[] = { 0, 12 };
-
-static dns_name_t hmacsha384 = {
- DNS_NAME_MAGIC,
- hmacsha384_ndata, 13, 2,
- DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE,
- hmacsha384_offsets, NULL,
- {(void *)-1, (void *)-1},
- {NULL, NULL}
-};
-
-LIBDNS_EXTERNAL_DATA dns_name_t *dns_tsig_hmacsha384_name = &hmacsha384;
-
-static unsigned char hmacsha512_ndata[] = "\013hmac-sha512";
-static unsigned char hmacsha512_offsets[] = { 0, 12 };
-
-static dns_name_t hmacsha512 = {
- DNS_NAME_MAGIC,
- hmacsha512_ndata, 13, 2,
- DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE,
- hmacsha512_offsets, NULL,
- {(void *)-1, (void *)-1},
- {NULL, NULL}
-};
-
-LIBDNS_EXTERNAL_DATA dns_name_t *dns_tsig_hmacsha512_name = &hmacsha512;
-
-static isc_result_t
-tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg);
-
-static void
-tsig_log(dns_tsigkey_t *key, int level, const char *fmt, ...)
- ISC_FORMAT_PRINTF(3, 4);
-
-static void
-cleanup_ring(dns_tsig_keyring_t *ring);
-static void
-tsigkey_free(dns_tsigkey_t *key);
-
-static void
-tsig_log(dns_tsigkey_t *key, int level, const char *fmt, ...) {
- va_list ap;
- char message[4096];
- char namestr[DNS_NAME_FORMATSIZE];
- char creatorstr[DNS_NAME_FORMATSIZE];
-
- if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
- return;
- if (key != NULL)
- dns_name_format(&key->name, namestr, sizeof(namestr));
- else
- strcpy(namestr, "<null>");
-
- 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);
- va_end(ap);
- if (key != NULL && key->generated)
- isc_log_write(dns_lctx,
- DNS_LOGCATEGORY_DNSSEC, DNS_LOGMODULE_TSIG,
- level, "tsig key '%s' (%s): %s",
- namestr, creatorstr, message);
- else
- isc_log_write(dns_lctx,
- DNS_LOGCATEGORY_DNSSEC, DNS_LOGMODULE_TSIG,
- 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) &&
- tkey->ring->lru.tail != tkey)
- {
- 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,
- dns_name_t *creator, isc_stdtime_t inception,
- isc_stdtime_t expire, isc_mem_t *mctx,
- dns_tsig_keyring_t *ring, dns_tsigkey_t **key)
-{
- dns_tsigkey_t *tkey;
- isc_result_t ret;
- unsigned int refs = 0;
-
- REQUIRE(key == NULL || *key == NULL);
- REQUIRE(name != NULL);
- REQUIRE(algorithm != NULL);
- REQUIRE(mctx != NULL);
- REQUIRE(key != NULL || ring != NULL);
-
- tkey = (dns_tsigkey_t *) isc_mem_get(mctx, sizeof(dns_tsigkey_t));
- if (tkey == NULL)
- return (ISC_R_NOMEMORY);
-
- dns_name_init(&tkey->name, NULL);
- ret = dns_name_dup(name, mctx, &tkey->name);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_key;
- (void)dns_name_downcase(&tkey->name, &tkey->name, NULL);
-
- if (dns_name_equal(algorithm, DNS_TSIG_HMACMD5_NAME)) {
- tkey->algorithm = DNS_TSIG_HMACMD5_NAME;
- if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_HMACMD5) {
- ret = DNS_R_BADALG;
- goto cleanup_name;
- }
- } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA1_NAME)) {
- tkey->algorithm = DNS_TSIG_HMACSHA1_NAME;
- if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_HMACSHA1) {
- ret = DNS_R_BADALG;
- goto cleanup_name;
- }
- } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA224_NAME)) {
- tkey->algorithm = DNS_TSIG_HMACSHA224_NAME;
- if (dstkey != NULL &&
- dst_key_alg(dstkey) != DST_ALG_HMACSHA224) {
- ret = DNS_R_BADALG;
- goto cleanup_name;
- }
- } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA256_NAME)) {
- tkey->algorithm = DNS_TSIG_HMACSHA256_NAME;
- if (dstkey != NULL &&
- dst_key_alg(dstkey) != DST_ALG_HMACSHA256) {
- ret = DNS_R_BADALG;
- goto cleanup_name;
- }
- } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA384_NAME)) {
- tkey->algorithm = DNS_TSIG_HMACSHA384_NAME;
- if (dstkey != NULL &&
- dst_key_alg(dstkey) != DST_ALG_HMACSHA384) {
- ret = DNS_R_BADALG;
- goto cleanup_name;
- }
- } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA512_NAME)) {
- tkey->algorithm = DNS_TSIG_HMACSHA512_NAME;
- if (dstkey != NULL &&
- dst_key_alg(dstkey) != DST_ALG_HMACSHA512) {
- ret = DNS_R_BADALG;
- goto cleanup_name;
- }
- } else if (dns_name_equal(algorithm, DNS_TSIG_GSSAPI_NAME)) {
- tkey->algorithm = DNS_TSIG_GSSAPI_NAME;
- if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_GSSAPI) {
- ret = DNS_R_BADALG;
- goto cleanup_name;
- }
- } else if (dns_name_equal(algorithm, DNS_TSIG_GSSAPIMS_NAME)) {
- tkey->algorithm = DNS_TSIG_GSSAPIMS_NAME;
- if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_GSSAPI) {
- ret = DNS_R_BADALG;
- goto cleanup_name;
- }
- } else {
- if (dstkey != NULL) {
- ret = DNS_R_BADALG;
- goto cleanup_name;
- }
- tkey->algorithm = isc_mem_get(mctx, sizeof(dns_name_t));
- if (tkey->algorithm == NULL) {
- ret = ISC_R_NOMEMORY;
- goto cleanup_name;
- }
- dns_name_init(tkey->algorithm, NULL);
- ret = dns_name_dup(algorithm, mctx, tkey->algorithm);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_algorithm;
- (void)dns_name_downcase(tkey->algorithm, tkey->algorithm,
- NULL);
- }
-
- if (creator != NULL) {
- tkey->creator = isc_mem_get(mctx, sizeof(dns_name_t));
- if (tkey->creator == NULL) {
- ret = ISC_R_NOMEMORY;
- goto cleanup_algorithm;
- }
- dns_name_init(tkey->creator, NULL);
- ret = dns_name_dup(creator, mctx, tkey->creator);
- if (ret != ISC_R_SUCCESS) {
- isc_mem_put(mctx, tkey->creator, sizeof(dns_name_t));
- goto cleanup_algorithm;
- }
- } else
- tkey->creator = NULL;
-
- tkey->key = NULL;
- if (dstkey != NULL)
- dst_key_attach(dstkey, &tkey->key);
- tkey->ring = ring;
-
- if (key != NULL)
- refs = 1;
- if (ring != NULL)
- refs++;
- ret = isc_refcount_init(&tkey->refs, refs);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_creator;
-
- tkey->generated = generated;
- tkey->inception = inception;
- tkey->expire = expire;
- tkey->mctx = NULL;
- isc_mem_attach(mctx, &tkey->mctx);
-
- tkey->magic = TSIG_MAGIC;
-
- if (ring != NULL) {
- ret = keyring_add(ring, name, tkey);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_refs;
- }
-
- /*
- * Ignore this if it's a GSS key, since the key size is meaningless.
- */
- if (dstkey != NULL && dst_key_size(dstkey) < 64 &&
- !dns_name_equal(algorithm, DNS_TSIG_GSSAPI_NAME) &&
- !dns_name_equal(algorithm, DNS_TSIG_GSSAPIMS_NAME)) {
- char namestr[DNS_NAME_FORMATSIZE];
- dns_name_format(name, namestr, sizeof(namestr));
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC,
- DNS_LOGMODULE_TSIG, ISC_LOG_INFO,
- "the key '%s' is too short to be secure",
- namestr);
- }
-
- if (key != NULL)
- *key = tkey;
-
- return (ISC_R_SUCCESS);
-
- cleanup_refs:
- tkey->magic = 0;
- while (refs-- > 0)
- isc_refcount_decrement(&tkey->refs, NULL);
- isc_refcount_destroy(&tkey->refs);
- cleanup_creator:
- if (tkey->key != NULL)
- dst_key_free(&tkey->key);
- if (tkey->creator != NULL) {
- dns_name_free(tkey->creator, mctx);
- isc_mem_put(mctx, tkey->creator, sizeof(dns_name_t));
- }
- cleanup_algorithm:
- if (algname_is_allocated(tkey->algorithm)) {
- if (dns_name_dynamic(tkey->algorithm))
- dns_name_free(tkey->algorithm, mctx);
- isc_mem_put(mctx, tkey->algorithm, sizeof(dns_name_t));
- }
- cleanup_name:
- dns_name_free(&tkey->name, mctx);
- cleanup_key:
- isc_mem_put(mctx, tkey, sizeof(dns_tsigkey_t));
-
- return (ret);
-}
-
-/*
- * Find a few nodes to destroy if possible.
- */
-static void
-cleanup_ring(dns_tsig_keyring_t *ring)
-{
- 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;
-
- /*
- * Start up a new iterator each time.
- */
- isc_stdtime_get(&now);
- dns_name_init(&foundname, NULL);
- dns_fixedname_init(&fixedorigin);
- origin = dns_fixedname_name(&fixedorigin);
-
- again:
- 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);
- return;
- }
-
- for (;;) {
- node = NULL;
- dns_rbtnodechain_current(&chain, &foundname, origin, &node);
- tkey = node->data;
- if (tkey != NULL) {
- if (tkey->generated
- && isc_refcount_current(&tkey->refs) == 1
- && tkey->inception != tkey->expire
- && tkey->expire < now) {
- tsig_log(tkey, 2, "tsig expire: deleting");
- /* delete the key */
- dns_rbtnodechain_invalidate(&chain);
- remove_fromring(tkey);
- goto again;
- }
- }
- result = dns_rbtnodechain_next(&chain, &foundname,
- origin);
- if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
- dns_rbtnodechain_invalidate(&chain);
- return;
- }
- }
-}
-
-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 (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;
-
- REQUIRE(tkey != NULL);
- REQUIRE(fp != NULL);
-
- 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,
- dns_name_t *creator, isc_stdtime_t inception,
- isc_stdtime_t expire, isc_mem_t *mctx,
- dns_tsig_keyring_t *ring, dns_tsigkey_t **key)
-{
- dst_key_t *dstkey = NULL;
- isc_result_t result;
-
- REQUIRE(length >= 0);
- if (length > 0)
- REQUIRE(secret != NULL);
-
- if (dns_name_equal(algorithm, DNS_TSIG_HMACMD5_NAME)) {
- if (secret != NULL) {
- isc_buffer_t b;
-
- isc_buffer_init(&b, secret, length);
- isc_buffer_add(&b, length);
- result = dst_key_frombuffer(name, DST_ALG_HMACMD5,
- DNS_KEYOWNER_ENTITY,
- DNS_KEYPROTO_DNSSEC,
- dns_rdataclass_in,
- &b, mctx, &dstkey);
- if (result != ISC_R_SUCCESS)
- return (result);
- }
- } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA1_NAME)) {
- if (secret != NULL) {
- isc_buffer_t b;
-
- isc_buffer_init(&b, secret, length);
- isc_buffer_add(&b, length);
- result = dst_key_frombuffer(name, DST_ALG_HMACSHA1,
- DNS_KEYOWNER_ENTITY,
- DNS_KEYPROTO_DNSSEC,
- dns_rdataclass_in,
- &b, mctx, &dstkey);
- if (result != ISC_R_SUCCESS)
- return (result);
- }
- } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA224_NAME)) {
- if (secret != NULL) {
- isc_buffer_t b;
-
- isc_buffer_init(&b, secret, length);
- isc_buffer_add(&b, length);
- result = dst_key_frombuffer(name, DST_ALG_HMACSHA224,
- DNS_KEYOWNER_ENTITY,
- DNS_KEYPROTO_DNSSEC,
- dns_rdataclass_in,
- &b, mctx, &dstkey);
- if (result != ISC_R_SUCCESS)
- return (result);
- }
- } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA256_NAME)) {
- if (secret != NULL) {
- isc_buffer_t b;
-
- isc_buffer_init(&b, secret, length);
- isc_buffer_add(&b, length);
- result = dst_key_frombuffer(name, DST_ALG_HMACSHA256,
- DNS_KEYOWNER_ENTITY,
- DNS_KEYPROTO_DNSSEC,
- dns_rdataclass_in,
- &b, mctx, &dstkey);
- if (result != ISC_R_SUCCESS)
- return (result);
- }
- } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA384_NAME)) {
- if (secret != NULL) {
- isc_buffer_t b;
-
- isc_buffer_init(&b, secret, length);
- isc_buffer_add(&b, length);
- result = dst_key_frombuffer(name, DST_ALG_HMACSHA384,
- DNS_KEYOWNER_ENTITY,
- DNS_KEYPROTO_DNSSEC,
- dns_rdataclass_in,
- &b, mctx, &dstkey);
- if (result != ISC_R_SUCCESS)
- return (result);
- }
- } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA512_NAME)) {
- if (secret != NULL) {
- isc_buffer_t b;
-
- isc_buffer_init(&b, secret, length);
- isc_buffer_add(&b, length);
- result = dst_key_frombuffer(name, DST_ALG_HMACSHA512,
- DNS_KEYOWNER_ENTITY,
- DNS_KEYPROTO_DNSSEC,
- dns_rdataclass_in,
- &b, mctx, &dstkey);
- if (result != ISC_R_SUCCESS)
- return (result);
- }
- } else if (length > 0)
- return (DNS_R_BADALG);
-
- result = dns_tsigkey_createfromkey(name, algorithm, dstkey,
- generated, creator,
- inception, expire, mctx, ring, key);
- if (dstkey != NULL)
- dst_key_free(&dstkey);
- return (result);
-}
-
-void
-dns_tsigkey_attach(dns_tsigkey_t *source, dns_tsigkey_t **targetp) {
- REQUIRE(VALID_TSIG_KEY(source));
- REQUIRE(targetp != NULL && *targetp == NULL);
-
- isc_refcount_increment(&source->refs, NULL);
- *targetp = source;
-}
-
-static void
-tsigkey_free(dns_tsigkey_t *key) {
- REQUIRE(VALID_TSIG_KEY(key));
-
- key->magic = 0;
- dns_name_free(&key->name, key->mctx);
- if (algname_is_allocated(key->algorithm)) {
- dns_name_free(key->algorithm, key->mctx);
- isc_mem_put(key->mctx, key->algorithm, sizeof(dns_name_t));
- }
- if (key->key != NULL)
- dst_key_free(&key->key);
- if (key->creator != NULL) {
- dns_name_free(key->creator, key->mctx);
- isc_mem_put(key->mctx, key->creator, sizeof(dns_name_t));
- }
- isc_refcount_destroy(&key->refs);
- isc_mem_putanddetach(&key->mctx, key, sizeof(dns_tsigkey_t));
-}
-
-void
-dns_tsigkey_detach(dns_tsigkey_t **keyp) {
- dns_tsigkey_t *key;
- unsigned int refs;
-
- REQUIRE(keyp != NULL);
- REQUIRE(VALID_TSIG_KEY(*keyp));
-
- key = *keyp;
- isc_refcount_decrement(&key->refs, &refs);
-
- if (refs == 0)
- tsigkey_free(key);
-
- *keyp = NULL;
-}
-
-void
-dns_tsigkey_setdeleted(dns_tsigkey_t *key) {
- REQUIRE(VALID_TSIG_KEY(key));
- REQUIRE(key->ring != NULL);
-
- RWLOCK(&key->ring->lock, isc_rwlocktype_write);
- remove_fromring(key);
- RWUNLOCK(&key->ring->lock, isc_rwlocktype_write);
-}
-
-isc_result_t
-dns_tsig_sign(dns_message_t *msg) {
- dns_tsigkey_t *key;
- dns_rdata_any_tsig_t tsig, querytsig;
- unsigned char data[128];
- isc_buffer_t databuf, sigbuf;
- isc_buffer_t *dynbuf;
- dns_name_t *owner;
- dns_rdata_t *rdata = NULL;
- dns_rdatalist_t *datalist;
- dns_rdataset_t *dataset;
- isc_region_t r;
- isc_stdtime_t now;
- isc_mem_t *mctx;
- dst_context_t *ctx = NULL;
- isc_result_t ret;
- unsigned char badtimedata[BADTIMELEN];
- unsigned int sigsize = 0;
- isc_boolean_t response = is_response(msg);
-
- REQUIRE(msg != NULL);
- REQUIRE(VALID_TSIG_KEY(dns_message_gettsigkey(msg)));
-
- /*
- * If this is a response, there should be a query tsig.
- */
- if (response && msg->querytsig == NULL)
- return (DNS_R_EXPECTEDTSIG);
-
- dynbuf = NULL;
-
- mctx = msg->mctx;
- key = dns_message_gettsigkey(msg);
-
- tsig.mctx = mctx;
- tsig.common.rdclass = dns_rdataclass_any;
- tsig.common.rdtype = dns_rdatatype_tsig;
- ISC_LINK_INIT(&tsig.common, link);
- dns_name_init(&tsig.algorithm, NULL);
- dns_name_clone(key->algorithm, &tsig.algorithm);
-
- isc_stdtime_get(&now);
- tsig.timesigned = now + msg->timeadjust;
- tsig.fudge = DNS_TSIG_FUDGE;
-
- tsig.originalid = msg->id;
-
- isc_buffer_init(&databuf, data, sizeof(data));
-
- if (response)
- tsig.error = msg->querytsigstatus;
- else
- tsig.error = dns_rcode_noerror;
-
- if (tsig.error != dns_tsigerror_badtime) {
- tsig.otherlen = 0;
- tsig.other = NULL;
- } else {
- isc_buffer_t otherbuf;
-
- tsig.otherlen = BADTIMELEN;
- tsig.other = badtimedata;
- isc_buffer_init(&otherbuf, tsig.other, tsig.otherlen);
- isc_buffer_putuint48(&otherbuf, tsig.timesigned);
- }
-
- if (key->key != NULL && tsig.error != dns_tsigerror_badsig) {
- unsigned char header[DNS_MESSAGE_HEADERLEN];
- isc_buffer_t headerbuf;
- isc_uint16_t digestbits;
-
- ret = dst_context_create2(key->key, mctx,
- DNS_LOGCATEGORY_DNSSEC, &ctx);
- if (ret != ISC_R_SUCCESS)
- return (ret);
-
- /*
- * If this is a response, digest the query signature.
- */
- if (response) {
- dns_rdata_t querytsigrdata = DNS_RDATA_INIT;
-
- ret = dns_rdataset_first(msg->querytsig);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_context;
- dns_rdataset_current(msg->querytsig, &querytsigrdata);
- ret = dns_rdata_tostruct(&querytsigrdata, &querytsig,
- NULL);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_context;
- isc_buffer_putuint16(&databuf, querytsig.siglen);
- if (isc_buffer_availablelength(&databuf) <
- querytsig.siglen) {
- ret = ISC_R_NOSPACE;
- goto cleanup_context;
- }
- isc_buffer_putmem(&databuf, querytsig.signature,
- querytsig.siglen);
- isc_buffer_usedregion(&databuf, &r);
- ret = dst_context_adddata(ctx, &r);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_context;
- }
-#if defined(__clang__) && \
- ( __clang_major__ < 3 || \
- (__clang_major__ == 3 && __clang_minor__ < 2) || \
- (__clang_major__ == 4 && __clang_minor__ < 2))
- /* false positive: http://llvm.org/bugs/show_bug.cgi?id=14461 */
- else memset(&querytsig, 0, sizeof(querytsig));
-#endif
-
- /*
- * Digest the header.
- */
- isc_buffer_init(&headerbuf, header, sizeof(header));
- dns_message_renderheader(msg, &headerbuf);
- isc_buffer_usedregion(&headerbuf, &r);
- ret = dst_context_adddata(ctx, &r);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_context;
-
- /*
- * Digest the remainder of the message.
- */
- isc_buffer_usedregion(msg->buffer, &r);
- isc_region_consume(&r, DNS_MESSAGE_HEADERLEN);
- ret = dst_context_adddata(ctx, &r);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_context;
-
- if (msg->tcp_continuation == 0) {
- /*
- * Digest the name, class, ttl, alg.
- */
- dns_name_toregion(&key->name, &r);
- ret = dst_context_adddata(ctx, &r);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_context;
-
- isc_buffer_clear(&databuf);
- isc_buffer_putuint16(&databuf, dns_rdataclass_any);
- isc_buffer_putuint32(&databuf, 0); /* ttl */
- isc_buffer_usedregion(&databuf, &r);
- ret = dst_context_adddata(ctx, &r);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_context;
-
- dns_name_toregion(&tsig.algorithm, &r);
- ret = dst_context_adddata(ctx, &r);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_context;
-
- }
- /* Digest the timesigned and fudge */
- isc_buffer_clear(&databuf);
- if (tsig.error == dns_tsigerror_badtime) {
- INSIST(response);
- tsig.timesigned = querytsig.timesigned;
- }
- isc_buffer_putuint48(&databuf, tsig.timesigned);
- isc_buffer_putuint16(&databuf, tsig.fudge);
- isc_buffer_usedregion(&databuf, &r);
- ret = dst_context_adddata(ctx, &r);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_context;
-
- if (msg->tcp_continuation == 0) {
- /*
- * Digest the error and other data length.
- */
- isc_buffer_clear(&databuf);
- isc_buffer_putuint16(&databuf, tsig.error);
- isc_buffer_putuint16(&databuf, tsig.otherlen);
-
- isc_buffer_usedregion(&databuf, &r);
- ret = dst_context_adddata(ctx, &r);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_context;
-
- /*
- * Digest other data.
- */
- if (tsig.otherlen > 0) {
- r.length = tsig.otherlen;
- r.base = tsig.other;
- ret = dst_context_adddata(ctx, &r);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_context;
- }
- }
-
- ret = dst_key_sigsize(key->key, &sigsize);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_context;
- tsig.signature = (unsigned char *) isc_mem_get(mctx, sigsize);
- if (tsig.signature == NULL) {
- ret = ISC_R_NOMEMORY;
- goto cleanup_context;
- }
-
- isc_buffer_init(&sigbuf, tsig.signature, sigsize);
- ret = dst_context_sign(ctx, &sigbuf);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_signature;
- dst_context_destroy(&ctx);
- digestbits = dst_key_getbits(key->key);
- if (digestbits != 0) {
- unsigned int bytes = (digestbits + 1) / 8;
- if (response && bytes < querytsig.siglen)
- bytes = querytsig.siglen;
- if (bytes > isc_buffer_usedlength(&sigbuf))
- bytes = isc_buffer_usedlength(&sigbuf);
- tsig.siglen = bytes;
- } else
- tsig.siglen = isc_buffer_usedlength(&sigbuf);
- } else {
- tsig.siglen = 0;
- tsig.signature = NULL;
- }
-
- ret = dns_message_gettemprdata(msg, &rdata);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_signature;
- ret = isc_buffer_allocate(msg->mctx, &dynbuf, 512);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_rdata;
- ret = dns_rdata_fromstruct(rdata, dns_rdataclass_any,
- dns_rdatatype_tsig, &tsig, dynbuf);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_dynbuf;
-
- dns_message_takebuffer(msg, &dynbuf);
-
- if (tsig.signature != NULL) {
- isc_mem_put(mctx, tsig.signature, sigsize);
- tsig.signature = NULL;
- }
-
- owner = NULL;
- ret = dns_message_gettempname(msg, &owner);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_rdata;
- dns_name_init(owner, NULL);
- ret = dns_name_dup(&key->name, msg->mctx, owner);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_owner;
-
- datalist = NULL;
- ret = dns_message_gettemprdatalist(msg, &datalist);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_owner;
- dataset = NULL;
- ret = dns_message_gettemprdataset(msg, &dataset);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_rdatalist;
- datalist->rdclass = dns_rdataclass_any;
- datalist->type = dns_rdatatype_tsig;
- datalist->covers = 0;
- datalist->ttl = 0;
- ISC_LIST_INIT(datalist->rdata);
- ISC_LIST_APPEND(datalist->rdata, rdata, link);
- dns_rdataset_init(dataset);
- RUNTIME_CHECK(dns_rdatalist_tordataset(datalist, dataset)
- == ISC_R_SUCCESS);
- msg->tsig = dataset;
- msg->tsigname = owner;
-
- /* Windows does not like the tsig name being compressed. */
- msg->tsigname->attributes |= DNS_NAMEATTR_NOCOMPRESS;
-
- return (ISC_R_SUCCESS);
-
- cleanup_rdatalist:
- dns_message_puttemprdatalist(msg, &datalist);
- cleanup_owner:
- dns_message_puttempname(msg, &owner);
- goto cleanup_rdata;
- cleanup_dynbuf:
- isc_buffer_free(&dynbuf);
- cleanup_rdata:
- dns_message_puttemprdata(msg, &rdata);
- cleanup_signature:
- if (tsig.signature != NULL)
- isc_mem_put(mctx, tsig.signature, sigsize);
- cleanup_context:
- if (ctx != NULL)
- dst_context_destroy(&ctx);
- return (ret);
-}
-
-isc_result_t
-dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
- dns_tsig_keyring_t *ring1, dns_tsig_keyring_t *ring2)
-{
- dns_rdata_any_tsig_t tsig, querytsig;
- isc_region_t r, source_r, header_r, sig_r;
- isc_buffer_t databuf;
- unsigned char data[32];
- dns_name_t *keyname;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- isc_stdtime_t now;
- isc_result_t ret;
- dns_tsigkey_t *tsigkey;
- dst_key_t *key = NULL;
- unsigned char header[DNS_MESSAGE_HEADERLEN];
- dst_context_t *ctx = NULL;
- isc_mem_t *mctx;
- isc_uint16_t addcount, id;
- unsigned int siglen;
- unsigned int alg;
- isc_boolean_t response;
-
- REQUIRE(source != NULL);
- REQUIRE(DNS_MESSAGE_VALID(msg));
- tsigkey = dns_message_gettsigkey(msg);
- response = is_response(msg);
-
- REQUIRE(tsigkey == NULL || VALID_TSIG_KEY(tsigkey));
-
- msg->verify_attempted = 1;
-
- if (msg->tcp_continuation) {
- if (tsigkey == NULL || msg->querytsig == NULL)
- return (DNS_R_UNEXPECTEDTSIG);
- return (tsig_verify_tcp(source, msg));
- }
-
- /*
- * There should be a TSIG record...
- */
- if (msg->tsig == NULL)
- return (DNS_R_EXPECTEDTSIG);
-
- /*
- * If this is a response and there's no key or query TSIG, there
- * shouldn't be one on the response.
- */
- if (response && (tsigkey == NULL || msg->querytsig == NULL))
- return (DNS_R_UNEXPECTEDTSIG);
-
- mctx = msg->mctx;
-
- /*
- * If we're here, we know the message is well formed and contains a
- * TSIG record.
- */
-
- keyname = msg->tsigname;
- ret = dns_rdataset_first(msg->tsig);
- if (ret != ISC_R_SUCCESS)
- return (ret);
- dns_rdataset_current(msg->tsig, &rdata);
- ret = dns_rdata_tostruct(&rdata, &tsig, NULL);
- if (ret != ISC_R_SUCCESS)
- return (ret);
- dns_rdata_reset(&rdata);
- if (response) {
- ret = dns_rdataset_first(msg->querytsig);
- if (ret != ISC_R_SUCCESS)
- return (ret);
- dns_rdataset_current(msg->querytsig, &rdata);
- ret = dns_rdata_tostruct(&rdata, &querytsig, NULL);
- if (ret != ISC_R_SUCCESS)
- return (ret);
- }
-#if defined(__clang__) && \
- ( __clang_major__ < 3 || \
- (__clang_major__ == 3 && __clang_minor__ < 2) || \
- (__clang_major__ == 4 && __clang_minor__ < 2))
- /* false positive: http://llvm.org/bugs/show_bug.cgi?id=14461 */
- else memset(&querytsig, 0, sizeof(querytsig));
-#endif
-
- /*
- * Do the key name and algorithm match that of the query?
- */
- if (response &&
- (!dns_name_equal(keyname, &tsigkey->name) ||
- !dns_name_equal(&tsig.algorithm, &querytsig.algorithm))) {
- msg->tsigstatus = dns_tsigerror_badkey;
- tsig_log(msg->tsigkey, 2,
- "key name and algorithm do not match");
- return (DNS_R_TSIGVERIFYFAILURE);
- }
-
- /*
- * Get the current time.
- */
- isc_stdtime_get(&now);
-
- /*
- * Find dns_tsigkey_t based on keyname.
- */
- if (tsigkey == NULL) {
- ret = ISC_R_NOTFOUND;
- if (ring1 != NULL)
- ret = dns_tsigkey_find(&tsigkey, keyname,
- &tsig.algorithm, ring1);
- if (ret == ISC_R_NOTFOUND && ring2 != NULL)
- ret = dns_tsigkey_find(&tsigkey, keyname,
- &tsig.algorithm, ring2);
- if (ret != ISC_R_SUCCESS) {
- msg->tsigstatus = dns_tsigerror_badkey;
- ret = dns_tsigkey_create(keyname, &tsig.algorithm,
- NULL, 0, ISC_FALSE, NULL,
- now, now,
- mctx, NULL, &msg->tsigkey);
- if (ret != ISC_R_SUCCESS)
- return (ret);
- tsig_log(msg->tsigkey, 2, "unknown key");
- return (DNS_R_TSIGVERIFYFAILURE);
- }
- msg->tsigkey = tsigkey;
- }
-
- key = tsigkey->key;
-
- /*
- * Is the time ok?
- */
- if (now + msg->timeadjust > tsig.timesigned + tsig.fudge) {
- msg->tsigstatus = dns_tsigerror_badtime;
- tsig_log(msg->tsigkey, 2, "signature has expired");
- return (DNS_R_CLOCKSKEW);
- } else if (now + msg->timeadjust < tsig.timesigned - tsig.fudge) {
- msg->tsigstatus = dns_tsigerror_badtime;
- tsig_log(msg->tsigkey, 2, "signature is in the future");
- return (DNS_R_CLOCKSKEW);
- }
-
- /*
- * Check digest length.
- */
- alg = dst_key_alg(key);
- ret = dst_key_sigsize(key, &siglen);
- if (ret != ISC_R_SUCCESS)
- return (ret);
- if (alg == DST_ALG_HMACMD5 || alg == DST_ALG_HMACSHA1 ||
- alg == DST_ALG_HMACSHA224 || alg == DST_ALG_HMACSHA256 ||
- alg == DST_ALG_HMACSHA384 || alg == DST_ALG_HMACSHA512) {
- isc_uint16_t digestbits = dst_key_getbits(key);
- if (tsig.siglen > siglen) {
- tsig_log(msg->tsigkey, 2, "signature length to big");
- return (DNS_R_FORMERR);
- }
- if (tsig.siglen > 0 &&
- (tsig.siglen < 10 || tsig.siglen < ((siglen + 1) / 2))) {
- tsig_log(msg->tsigkey, 2,
- "signature length below minimum");
- return (DNS_R_FORMERR);
- }
- if (tsig.siglen > 0 && digestbits != 0 &&
- tsig.siglen < ((digestbits + 1) / 8)) {
- msg->tsigstatus = dns_tsigerror_badtrunc;
- tsig_log(msg->tsigkey, 2,
- "truncated signature length too small");
- return (DNS_R_TSIGVERIFYFAILURE);
- }
- if (tsig.siglen > 0 && digestbits == 0 &&
- tsig.siglen < siglen) {
- msg->tsigstatus = dns_tsigerror_badtrunc;
- tsig_log(msg->tsigkey, 2, "signature length too small");
- return (DNS_R_TSIGVERIFYFAILURE);
- }
- }
-
- if (tsig.siglen > 0) {
- sig_r.base = tsig.signature;
- sig_r.length = tsig.siglen;
-
- ret = dst_context_create2(key, mctx,
- DNS_LOGCATEGORY_DNSSEC, &ctx);
- if (ret != ISC_R_SUCCESS)
- return (ret);
-
- if (response) {
- isc_buffer_init(&databuf, data, sizeof(data));
- isc_buffer_putuint16(&databuf, querytsig.siglen);
- isc_buffer_usedregion(&databuf, &r);
- ret = dst_context_adddata(ctx, &r);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_context;
- if (querytsig.siglen > 0) {
- r.length = querytsig.siglen;
- r.base = querytsig.signature;
- ret = dst_context_adddata(ctx, &r);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_context;
- }
- }
-
- /*
- * Extract the header.
- */
- isc_buffer_usedregion(source, &r);
- memcpy(header, r.base, DNS_MESSAGE_HEADERLEN);
- isc_region_consume(&r, DNS_MESSAGE_HEADERLEN);
-
- /*
- * Decrement the additional field counter.
- */
- memcpy(&addcount, &header[DNS_MESSAGE_HEADERLEN - 2], 2);
- addcount = htons((isc_uint16_t)(ntohs(addcount) - 1));
- memcpy(&header[DNS_MESSAGE_HEADERLEN - 2], &addcount, 2);
-
- /*
- * Put in the original id.
- */
- id = htons(tsig.originalid);
- memcpy(&header[0], &id, 2);
-
- /*
- * Digest the modified header.
- */
- header_r.base = (unsigned char *) header;
- header_r.length = DNS_MESSAGE_HEADERLEN;
- ret = dst_context_adddata(ctx, &header_r);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_context;
-
- /*
- * Digest all non-TSIG records.
- */
- isc_buffer_usedregion(source, &source_r);
- r.base = source_r.base + DNS_MESSAGE_HEADERLEN;
- r.length = msg->sigstart - DNS_MESSAGE_HEADERLEN;
- ret = dst_context_adddata(ctx, &r);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_context;
-
- /*
- * Digest the key name.
- */
- dns_name_toregion(&tsigkey->name, &r);
- ret = dst_context_adddata(ctx, &r);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_context;
-
- isc_buffer_init(&databuf, data, sizeof(data));
- isc_buffer_putuint16(&databuf, tsig.common.rdclass);
- isc_buffer_putuint32(&databuf, msg->tsig->ttl);
- isc_buffer_usedregion(&databuf, &r);
- ret = dst_context_adddata(ctx, &r);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_context;
-
- /*
- * Digest the key algorithm.
- */
- dns_name_toregion(tsigkey->algorithm, &r);
- ret = dst_context_adddata(ctx, &r);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_context;
-
- isc_buffer_clear(&databuf);
- isc_buffer_putuint48(&databuf, tsig.timesigned);
- isc_buffer_putuint16(&databuf, tsig.fudge);
- isc_buffer_putuint16(&databuf, tsig.error);
- isc_buffer_putuint16(&databuf, tsig.otherlen);
- isc_buffer_usedregion(&databuf, &r);
- ret = dst_context_adddata(ctx, &r);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_context;
-
- if (tsig.otherlen > 0) {
- r.base = tsig.other;
- r.length = tsig.otherlen;
- ret = dst_context_adddata(ctx, &r);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_context;
- }
-
- ret = dst_context_verify(ctx, &sig_r);
- if (ret == DST_R_VERIFYFAILURE) {
- msg->tsigstatus = dns_tsigerror_badsig;
- ret = DNS_R_TSIGVERIFYFAILURE;
- tsig_log(msg->tsigkey, 2,
- "signature failed to verify(1)");
- goto cleanup_context;
- } else if (ret != ISC_R_SUCCESS)
- goto cleanup_context;
-
- dst_context_destroy(&ctx);
- } else if (tsig.error != dns_tsigerror_badsig &&
- tsig.error != dns_tsigerror_badkey) {
- msg->tsigstatus = dns_tsigerror_badsig;
- tsig_log(msg->tsigkey, 2, "signature was empty");
- return (DNS_R_TSIGVERIFYFAILURE);
- }
-
- msg->tsigstatus = dns_rcode_noerror;
-
- if (tsig.error != dns_rcode_noerror) {
- if (tsig.error == dns_tsigerror_badtime)
- return (DNS_R_CLOCKSKEW);
- else
- return (DNS_R_TSIGERRORSET);
- }
-
- msg->verified_sig = 1;
-
- return (ISC_R_SUCCESS);
-
-cleanup_context:
- if (ctx != NULL)
- dst_context_destroy(&ctx);
-
- return (ret);
-}
-
-static isc_result_t
-tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg) {
- dns_rdata_any_tsig_t tsig, querytsig;
- isc_region_t r, source_r, header_r, sig_r;
- isc_buffer_t databuf;
- unsigned char data[32];
- dns_name_t *keyname;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- isc_stdtime_t now;
- isc_result_t ret;
- dns_tsigkey_t *tsigkey;
- dst_key_t *key = NULL;
- unsigned char header[DNS_MESSAGE_HEADERLEN];
- isc_uint16_t addcount, id;
- isc_boolean_t has_tsig = ISC_FALSE;
- isc_mem_t *mctx;
-
- REQUIRE(source != NULL);
- REQUIRE(msg != NULL);
- REQUIRE(dns_message_gettsigkey(msg) != NULL);
- REQUIRE(msg->tcp_continuation == 1);
- REQUIRE(msg->querytsig != NULL);
-
- if (!is_response(msg))
- return (DNS_R_EXPECTEDRESPONSE);
-
- mctx = msg->mctx;
-
- tsigkey = dns_message_gettsigkey(msg);
-
- /*
- * Extract and parse the previous TSIG
- */
- ret = dns_rdataset_first(msg->querytsig);
- if (ret != ISC_R_SUCCESS)
- return (ret);
- dns_rdataset_current(msg->querytsig, &rdata);
- ret = dns_rdata_tostruct(&rdata, &querytsig, NULL);
- if (ret != ISC_R_SUCCESS)
- return (ret);
- dns_rdata_reset(&rdata);
-
- /*
- * If there is a TSIG in this message, do some checks.
- */
- if (msg->tsig != NULL) {
- has_tsig = ISC_TRUE;
-
- keyname = msg->tsigname;
- ret = dns_rdataset_first(msg->tsig);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_querystruct;
- dns_rdataset_current(msg->tsig, &rdata);
- ret = dns_rdata_tostruct(&rdata, &tsig, NULL);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_querystruct;
-
- /*
- * Do the key name and algorithm match that of the query?
- */
- if (!dns_name_equal(keyname, &tsigkey->name) ||
- !dns_name_equal(&tsig.algorithm, &querytsig.algorithm)) {
- msg->tsigstatus = dns_tsigerror_badkey;
- ret = DNS_R_TSIGVERIFYFAILURE;
- tsig_log(msg->tsigkey, 2,
- "key name and algorithm do not match");
- goto cleanup_querystruct;
- }
-
- /*
- * Is the time ok?
- */
- isc_stdtime_get(&now);
-
- if (now + msg->timeadjust > tsig.timesigned + tsig.fudge) {
- msg->tsigstatus = dns_tsigerror_badtime;
- tsig_log(msg->tsigkey, 2, "signature has expired");
- ret = DNS_R_CLOCKSKEW;
- goto cleanup_querystruct;
- } else if (now + msg->timeadjust <
- tsig.timesigned - tsig.fudge) {
- msg->tsigstatus = dns_tsigerror_badtime;
- tsig_log(msg->tsigkey, 2,
- "signature is in the future");
- ret = DNS_R_CLOCKSKEW;
- goto cleanup_querystruct;
- }
- }
-
- key = tsigkey->key;
-
- if (msg->tsigctx == NULL) {
- ret = dst_context_create2(key, mctx,
- DNS_LOGCATEGORY_DNSSEC,
- &msg->tsigctx);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_querystruct;
-
- /*
- * Digest the length of the query signature
- */
- isc_buffer_init(&databuf, data, sizeof(data));
- isc_buffer_putuint16(&databuf, querytsig.siglen);
- isc_buffer_usedregion(&databuf, &r);
- ret = dst_context_adddata(msg->tsigctx, &r);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_context;
-
- /*
- * Digest the data of the query signature
- */
- if (querytsig.siglen > 0) {
- r.length = querytsig.siglen;
- r.base = querytsig.signature;
- ret = dst_context_adddata(msg->tsigctx, &r);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_context;
- }
- }
-
- /*
- * Extract the header.
- */
- isc_buffer_usedregion(source, &r);
- memcpy(header, r.base, DNS_MESSAGE_HEADERLEN);
- isc_region_consume(&r, DNS_MESSAGE_HEADERLEN);
-
- /*
- * Decrement the additional field counter if necessary.
- */
- if (has_tsig) {
- memcpy(&addcount, &header[DNS_MESSAGE_HEADERLEN - 2], 2);
- addcount = htons((isc_uint16_t)(ntohs(addcount) - 1));
- memcpy(&header[DNS_MESSAGE_HEADERLEN - 2], &addcount, 2);
- }
-
- /*
- * Put in the original id.
- */
- /* XXX Can TCP transfers be forwarded? How would that work? */
- if (has_tsig) {
- id = htons(tsig.originalid);
- memcpy(&header[0], &id, 2);
- }
-
- /*
- * Digest the modified header.
- */
- header_r.base = (unsigned char *) header;
- header_r.length = DNS_MESSAGE_HEADERLEN;
- ret = dst_context_adddata(msg->tsigctx, &header_r);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_context;
-
- /*
- * Digest all non-TSIG records.
- */
- isc_buffer_usedregion(source, &source_r);
- r.base = source_r.base + DNS_MESSAGE_HEADERLEN;
- if (has_tsig)
- r.length = msg->sigstart - DNS_MESSAGE_HEADERLEN;
- else
- r.length = source_r.length - DNS_MESSAGE_HEADERLEN;
- ret = dst_context_adddata(msg->tsigctx, &r);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_context;
-
- /*
- * Digest the time signed and fudge.
- */
- if (has_tsig) {
- isc_buffer_init(&databuf, data, sizeof(data));
- isc_buffer_putuint48(&databuf, tsig.timesigned);
- isc_buffer_putuint16(&databuf, tsig.fudge);
- isc_buffer_usedregion(&databuf, &r);
- ret = dst_context_adddata(msg->tsigctx, &r);
- if (ret != ISC_R_SUCCESS)
- goto cleanup_context;
-
- sig_r.base = tsig.signature;
- sig_r.length = tsig.siglen;
- if (tsig.siglen == 0) {
- if (tsig.error != dns_rcode_noerror) {
- if (tsig.error == dns_tsigerror_badtime)
- ret = DNS_R_CLOCKSKEW;
- else
- ret = DNS_R_TSIGERRORSET;
- } else {
- tsig_log(msg->tsigkey, 2,
- "signature is empty");
- ret = DNS_R_TSIGVERIFYFAILURE;
- }
- goto cleanup_context;
- }
-
- ret = dst_context_verify(msg->tsigctx, &sig_r);
- if (ret == DST_R_VERIFYFAILURE) {
- msg->tsigstatus = dns_tsigerror_badsig;
- tsig_log(msg->tsigkey, 2,
- "signature failed to verify(2)");
- ret = DNS_R_TSIGVERIFYFAILURE;
- goto cleanup_context;
- }
- else if (ret != ISC_R_SUCCESS)
- goto cleanup_context;
-
- dst_context_destroy(&msg->tsigctx);
- }
-
- msg->tsigstatus = dns_rcode_noerror;
- return (ISC_R_SUCCESS);
-
- cleanup_context:
- dst_context_destroy(&msg->tsigctx);
-
- cleanup_querystruct:
- dns_rdata_freestruct(&querytsig);
-
- return (ret);
-
-}
-
-isc_result_t
-dns_tsigkey_find(dns_tsigkey_t **tsigkey, dns_name_t *name,
- dns_name_t *algorithm, dns_tsig_keyring_t *ring)
-{
- dns_tsigkey_t *key;
- isc_stdtime_t now;
- isc_result_t result;
-
- REQUIRE(tsigkey != NULL);
- REQUIRE(*tsigkey == NULL);
- REQUIRE(name != NULL);
- REQUIRE(ring != NULL);
-
- RWLOCK(&ring->lock, isc_rwlocktype_write);
- cleanup_ring(ring);
- RWUNLOCK(&ring->lock, isc_rwlocktype_write);
-
- isc_stdtime_get(&now);
- RWLOCK(&ring->lock, isc_rwlocktype_read);
- key = NULL;
- result = dns_rbt_findname(ring->keys, name, 0, NULL, (void *)&key);
- if (result == DNS_R_PARTIALMATCH || result == ISC_R_NOTFOUND) {
- RWUNLOCK(&ring->lock, isc_rwlocktype_read);
- return (ISC_R_NOTFOUND);
- }
- if (algorithm != NULL && !dns_name_equal(key->algorithm, algorithm)) {
- RWUNLOCK(&ring->lock, isc_rwlocktype_read);
- return (ISC_R_NOTFOUND);
- }
- if (key->inception != key->expire && isc_serial_lt(key->expire, now)) {
- /*
- * The key has expired.
- */
- RWUNLOCK(&ring->lock, isc_rwlocktype_read);
- RWLOCK(&ring->lock, isc_rwlocktype_write);
- remove_fromring(key);
- RWUNLOCK(&ring->lock, isc_rwlocktype_write);
- return (ISC_R_NOTFOUND);
- }
-#if 0
- /*
- * MPAXXX We really should look at the inception time.
- */
- if (key->inception != key->expire &&
- isc_serial_lt(key->inception, now)) {
- RWUNLOCK(&ring->lock, isc_rwlocktype_read);
- adjust_lru(key);
- return (ISC_R_NOTFOUND);
- }
-#endif
- isc_refcount_increment(&key->refs, NULL);
- RWUNLOCK(&ring->lock, isc_rwlocktype_read);
- adjust_lru(key);
- *tsigkey = key;
- return (ISC_R_SUCCESS);
-}
-
-static void
-free_tsignode(void *node, void *_unused) {
- dns_tsigkey_t *key;
-
- REQUIRE(node != NULL);
-
- UNUSED(_unused);
-
- key = node;
- if (key->generated) {
- if (ISC_LINK_LINKED(key, link))
- ISC_LIST_UNLINK(key->ring->lru, key, link);
- }
- dns_tsigkey_detach(&key);
-}
-
-isc_result_t
-dns_tsigkeyring_create(isc_mem_t *mctx, dns_tsig_keyring_t **ringp) {
- isc_result_t result;
- dns_tsig_keyring_t *ring;
-
- REQUIRE(mctx != NULL);
- REQUIRE(ringp != NULL);
- REQUIRE(*ringp == NULL);
-
- ring = isc_mem_get(mctx, sizeof(dns_tsig_keyring_t));
- if (ring == NULL)
- return (ISC_R_NOMEMORY);
-
- result = isc_rwlock_init(&ring->lock, 0, 0);
- if (result != ISC_R_SUCCESS) {
- isc_mem_put(mctx, ring, sizeof(dns_tsig_keyring_t));
- return (result);
- }
-
- ring->keys = NULL;
- result = dns_rbt_create(mctx, free_tsignode, NULL, &ring->keys);
- if (result != ISC_R_SUCCESS) {
- isc_rwlock_destroy(&ring->lock);
- isc_mem_put(mctx, ring, sizeof(dns_tsig_keyring_t));
- return (result);
- }
-
- ring->writecount = 0;
- ring->mctx = NULL;
- ring->generated = 0;
- 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_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);
-
- 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)
- 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/contrib/bind9/lib/dns/ttl.c b/contrib/bind9/lib/dns/ttl.c
deleted file mode 100644
index d3cf024138db..000000000000
--- a/contrib/bind9/lib/dns/ttl.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <ctype.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <isc/buffer.h>
-#include <isc/parseint.h>
-#include <isc/print.h>
-#include <isc/region.h>
-#include <isc/string.h>
-#include <isc/util.h>
-
-#include <dns/result.h>
-#include <dns/ttl.h>
-
-#define RETERR(x) do { \
- isc_result_t _r = (x); \
- if (_r != ISC_R_SUCCESS) \
- return (_r); \
- } while (0)
-
-
-static isc_result_t bind_ttl(isc_textregion_t *source, isc_uint32_t *ttl);
-
-/*
- * Helper for dns_ttl_totext().
- */
-static isc_result_t
-ttlfmt(unsigned int t, const char *s, isc_boolean_t verbose,
- isc_boolean_t space, isc_buffer_t *target)
-{
- char tmp[60];
- size_t len;
- isc_region_t region;
-
- if (verbose)
- len = snprintf(tmp, sizeof(tmp), "%s%u %s%s",
- space ? " " : "",
- t, s,
- t == 1 ? "" : "s");
- else
- len = snprintf(tmp, sizeof(tmp), "%u%c", t, s[0]);
-
- INSIST(len + 1 <= sizeof(tmp));
- isc_buffer_availableregion(target, &region);
- if (len > region.length)
- return (ISC_R_NOSPACE);
- memcpy(region.base, tmp, len);
- isc_buffer_add(target, len);
-
- return (ISC_R_SUCCESS);
-}
-
-/*
- * Derived from bind8 ns_format_ttl().
- */
-isc_result_t
-dns_ttl_totext(isc_uint32_t src, isc_boolean_t verbose, isc_buffer_t *target) {
- unsigned secs, mins, hours, days, weeks, x;
-
- secs = src % 60; src /= 60;
- mins = src % 60; src /= 60;
- hours = src % 24; src /= 24;
- days = src % 7; src /= 7;
- weeks = src; src = 0;
- POST(src);
-
- x = 0;
- if (weeks != 0) {
- RETERR(ttlfmt(weeks, "week", verbose, ISC_TF(x > 0), target));
- x++;
- }
- if (days != 0) {
- RETERR(ttlfmt(days, "day", verbose, ISC_TF(x > 0), target));
- x++;
- }
- if (hours != 0) {
- RETERR(ttlfmt(hours, "hour", verbose, ISC_TF(x > 0), target));
- x++;
- }
- if (mins != 0) {
- RETERR(ttlfmt(mins, "minute", verbose, ISC_TF(x > 0), target));
- x++;
- }
- if (secs != 0 ||
- (weeks == 0 && days == 0 && hours == 0 && mins == 0)) {
- RETERR(ttlfmt(secs, "second", verbose, ISC_TF(x > 0), target));
- x++;
- }
- INSIST (x > 0);
- /*
- * If only a single unit letter is printed, print it
- * in upper case. (Why? Because BIND 8 does that.
- * Presumably it has a reason.)
- */
- if (x == 1 && !verbose) {
- isc_region_t region;
- /*
- * The unit letter is the last character in the
- * used region of the buffer.
- *
- * toupper() does not need its argument to be masked of cast
- * here because region.base is type unsigned char *.
- */
- isc_buffer_usedregion(target, &region);
- region.base[region.length - 1] =
- toupper(region.base[region.length - 1]);
- }
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_counter_fromtext(isc_textregion_t *source, isc_uint32_t *ttl) {
- return (bind_ttl(source, ttl));
-}
-
-isc_result_t
-dns_ttl_fromtext(isc_textregion_t *source, isc_uint32_t *ttl) {
- isc_result_t result;
-
- result = bind_ttl(source, ttl);
- if (result != ISC_R_SUCCESS)
- result = DNS_R_BADTTL;
- return (result);
-}
-
-static isc_result_t
-bind_ttl(isc_textregion_t *source, isc_uint32_t *ttl) {
- isc_uint32_t tmp = 0;
- isc_uint32_t n;
- char *s;
- char buf[64];
- char nbuf[64]; /* Number buffer */
-
- /*
- * Copy the buffer as it may not be NULL terminated.
- * No legal counter / ttl is longer that 63 characters.
- */
- if (source->length > sizeof(buf) - 1)
- return (DNS_R_SYNTAX);
- strncpy(buf, source->base, source->length);
- buf[source->length] = '\0';
- s = buf;
-
- do {
- isc_result_t result;
-
- char *np = nbuf;
- while (*s != '\0' && isdigit((unsigned char)*s))
- *np++ = *s++;
- *np++ = '\0';
- INSIST(np - nbuf <= (int)sizeof(nbuf));
- result = isc_parse_uint32(&n, nbuf, 10);
- if (result != ISC_R_SUCCESS)
- return (DNS_R_SYNTAX);
- switch (*s) {
- case 'w':
- case 'W':
- tmp += n * 7 * 24 * 3600;
- s++;
- break;
- case 'd':
- case 'D':
- tmp += n * 24 * 3600;
- s++;
- break;
- case 'h':
- case 'H':
- tmp += n * 3600;
- s++;
- break;
- case 'm':
- case 'M':
- tmp += n * 60;
- s++;
- break;
- case 's':
- case 'S':
- tmp += n;
- s++;
- break;
- case '\0':
- /* Plain number? */
- if (tmp != 0)
- return (DNS_R_SYNTAX);
- tmp = n;
- break;
- default:
- return (DNS_R_SYNTAX);
- }
- } while (*s != '\0');
- *ttl = tmp;
- return (ISC_R_SUCCESS);
-}
diff --git a/contrib/bind9/lib/dns/update.c b/contrib/bind9/lib/dns/update.c
deleted file mode 100644
index 14ffcc2234d8..000000000000
--- a/contrib/bind9/lib/dns/update.c
+++ /dev/null
@@ -1,1865 +0,0 @@
-/*
- * Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-#include <config.h>
-
-#include <isc/log.h>
-#include <isc/netaddr.h>
-#include <isc/print.h>
-#include <isc/serial.h>
-#include <isc/stats.h>
-#include <isc/stdtime.h>
-#include <isc/string.h>
-#include <isc/taskpool.h>
-#include <isc/util.h>
-
-#include <dns/db.h>
-#include <dns/dbiterator.h>
-#include <dns/diff.h>
-#include <dns/dnssec.h>
-#include <dns/events.h>
-#include <dns/fixedname.h>
-#include <dns/journal.h>
-#include <dns/keyvalues.h>
-#include <dns/log.h>
-#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>
-#include <dns/rdatastruct.h>
-#include <dns/rdatatype.h>
-#include <dns/result.h>
-#include <dns/soa.h>
-#include <dns/ssu.h>
-#include <dns/tsig.h>
-#include <dns/update.h>
-#include <dns/view.h>
-#include <dns/zone.h>
-#include <dns/zt.h>
-
-
-/**************************************************************************/
-
-/*%
- * Log level for tracing dynamic update protocol requests.
- */
-#define LOGLEVEL_PROTOCOL ISC_LOG_INFO
-
-/*%
- * Log level for low-level debug tracing.
- */
-#define LOGLEVEL_DEBUG ISC_LOG_DEBUG(8)
-
-/*%
- * Check an operation for failure. These macros all assume that
- * the function using them has a 'result' variable and a 'failure'
- * label.
- */
-#define CHECK(op) \
- do { result = (op); \
- if (result != ISC_R_SUCCESS) goto failure; \
- } while (0)
-
-/*%
- * Fail unconditionally with result 'code', which must not
- * be ISC_R_SUCCESS. The reason for failure presumably has
- * been logged already.
- *
- * The test against ISC_R_SUCCESS is there to keep the Solaris compiler
- * from complaining about "end-of-loop code not reached".
- */
-
-#define FAIL(code) \
- do { \
- result = (code); \
- if (result != ISC_R_SUCCESS) goto failure; \
- } while (0)
-
-/*%
- * Fail unconditionally and log as a client error.
- * The test against ISC_R_SUCCESS is there to keep the Solaris compiler
- * from complaining about "end-of-loop code not reached".
- */
-#define FAILC(code, msg) \
- do { \
- const char *_what = "failed"; \
- result = (code); \
- switch (result) { \
- case DNS_R_NXDOMAIN: \
- case DNS_R_YXDOMAIN: \
- case DNS_R_YXRRSET: \
- case DNS_R_NXRRSET: \
- _what = "unsuccessful"; \
- } \
- update_log(log, zone, LOGLEVEL_PROTOCOL, \
- "update %s: %s (%s)", _what, \
- msg, isc_result_totext(result)); \
- if (result != ISC_R_SUCCESS) goto failure; \
- } while (0)
-
-#define FAILN(code, name, msg) \
- do { \
- const char *_what = "failed"; \
- result = (code); \
- switch (result) { \
- case DNS_R_NXDOMAIN: \
- case DNS_R_YXDOMAIN: \
- case DNS_R_YXRRSET: \
- case DNS_R_NXRRSET: \
- _what = "unsuccessful"; \
- } \
- if (isc_log_wouldlog(dns_lctx, LOGLEVEL_PROTOCOL)) { \
- char _nbuf[DNS_NAME_FORMATSIZE]; \
- dns_name_format(name, _nbuf, sizeof(_nbuf)); \
- update_log(log, zone, LOGLEVEL_PROTOCOL, \
- "update %s: %s: %s (%s)", _what, _nbuf, \
- msg, isc_result_totext(result)); \
- } \
- if (result != ISC_R_SUCCESS) goto failure; \
- } while (0)
-
-#define FAILNT(code, name, type, msg) \
- do { \
- const char *_what = "failed"; \
- result = (code); \
- switch (result) { \
- case DNS_R_NXDOMAIN: \
- case DNS_R_YXDOMAIN: \
- case DNS_R_YXRRSET: \
- case DNS_R_NXRRSET: \
- _what = "unsuccessful"; \
- } \
- if (isc_log_wouldlog(dns_lctx, LOGLEVEL_PROTOCOL)) { \
- char _nbuf[DNS_NAME_FORMATSIZE]; \
- char _tbuf[DNS_RDATATYPE_FORMATSIZE]; \
- dns_name_format(name, _nbuf, sizeof(_nbuf)); \
- dns_rdatatype_format(type, _tbuf, sizeof(_tbuf)); \
- update_log(log, zone, LOGLEVEL_PROTOCOL, \
- "update %s: %s/%s: %s (%s)", \
- _what, _nbuf, _tbuf, msg, \
- isc_result_totext(result)); \
- } \
- if (result != ISC_R_SUCCESS) goto failure; \
- } while (0)
-
-/*%
- * Fail unconditionally and log as a server error.
- * The test against ISC_R_SUCCESS is there to keep the Solaris compiler
- * from complaining about "end-of-loop code not reached".
- */
-#define FAILS(code, msg) \
- do { \
- result = (code); \
- update_log(log, zone, LOGLEVEL_PROTOCOL, \
- "error: %s: %s", \
- msg, isc_result_totext(result)); \
- if (result != ISC_R_SUCCESS) goto failure; \
- } while (0)
-
-/**************************************************************************/
-
-typedef struct rr rr_t;
-
-struct rr {
- /* dns_name_t name; */
- isc_uint32_t ttl;
- dns_rdata_t rdata;
-};
-
-typedef struct update_event update_event_t;
-
-/**************************************************************************/
-
-static void
-update_log(dns_update_log_t *callback, dns_zone_t *zone,
- int level, const char *fmt, ...) ISC_FORMAT_PRINTF(4, 5);
-
-static void
-update_log(dns_update_log_t *callback, dns_zone_t *zone,
- int level, const char *fmt, ...)
-{
- va_list ap;
- char message[4096];
-
- if (callback == NULL)
- return;
-
- if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
- return;
-
-
- va_start(ap, fmt);
- vsnprintf(message, sizeof(message), fmt, ap);
- va_end(ap);
-
- (callback->func)(callback->arg, zone, level, message);
-}
-
-/*%
- * Update a single RR in version 'ver' of 'db' and log the
- * update in 'diff'.
- *
- * Ensures:
- * \li '*tuple' == NULL. Either the tuple is freed, or its
- * ownership has been transferred to the diff.
- */
-static isc_result_t
-do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
- dns_diff_t *diff)
-{
- dns_diff_t temp_diff;
- isc_result_t result;
-
- /*
- * Create a singleton diff.
- */
- dns_diff_init(diff->mctx, &temp_diff);
- 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));
-}
-
-/**************************************************************************/
-/*
- * Callback-style iteration over rdatasets and rdatas.
- *
- * foreach_rrset() can be used to iterate over the RRsets
- * of a name and call a callback function with each
- * one. Similarly, foreach_rr() can be used to iterate
- * over the individual RRs at name, optionally restricted
- * to RRs of a given type.
- *
- * The callback functions are called "actions" and take
- * two arguments: a void pointer for passing arbitrary
- * context information, and a pointer to the current RRset
- * or RR. By convention, their names end in "_action".
- */
-
-/*
- * XXXRTH We might want to make this public somewhere in libdns.
- */
-
-/*%
- * Function type for foreach_rrset() iterator actions.
- */
-typedef isc_result_t rrset_func(void *data, dns_rdataset_t *rrset);
-
-/*%
- * Function type for foreach_rr() iterator actions.
- */
-typedef isc_result_t rr_func(void *data, rr_t *rr);
-
-/*%
- * Internal context struct for foreach_node_rr().
- */
-typedef struct {
- rr_func * rr_action;
- void * rr_action_data;
-} foreach_node_rr_ctx_t;
-
-/*%
- * Internal helper function for foreach_node_rr().
- */
-static isc_result_t
-foreach_node_rr_action(void *data, dns_rdataset_t *rdataset) {
- isc_result_t result;
- foreach_node_rr_ctx_t *ctx = data;
- for (result = dns_rdataset_first(rdataset);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(rdataset))
- {
- rr_t rr = { 0, DNS_RDATA_INIT };
-
- dns_rdataset_current(rdataset, &rr.rdata);
- rr.ttl = rdataset->ttl;
- result = (*ctx->rr_action)(ctx->rr_action_data, &rr);
- if (result != ISC_R_SUCCESS)
- return (result);
- }
- if (result != ISC_R_NOMORE)
- return (result);
- return (ISC_R_SUCCESS);
-}
-
-/*%
- * For each rdataset of 'name' in 'ver' of 'db', call 'action'
- * with the rdataset and 'action_data' as arguments. If the name
- * does not exist, do nothing.
- *
- * If 'action' returns an error, abort iteration and return the error.
- */
-static isc_result_t
-foreach_rrset(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
- rrset_func *action, void *action_data)
-{
- isc_result_t result;
- dns_dbnode_t *node;
- dns_rdatasetiter_t *iter;
-
- node = NULL;
- result = dns_db_findnode(db, name, ISC_FALSE, &node);
- if (result == ISC_R_NOTFOUND)
- return (ISC_R_SUCCESS);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- iter = NULL;
- result = dns_db_allrdatasets(db, node, ver,
- (isc_stdtime_t) 0, &iter);
- if (result != ISC_R_SUCCESS)
- goto cleanup_node;
-
- for (result = dns_rdatasetiter_first(iter);
- result == ISC_R_SUCCESS;
- result = dns_rdatasetiter_next(iter))
- {
- dns_rdataset_t rdataset;
-
- dns_rdataset_init(&rdataset);
- dns_rdatasetiter_current(iter, &rdataset);
-
- result = (*action)(action_data, &rdataset);
-
- dns_rdataset_disassociate(&rdataset);
- if (result != ISC_R_SUCCESS)
- goto cleanup_iterator;
- }
- if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
-
- cleanup_iterator:
- dns_rdatasetiter_destroy(&iter);
-
- cleanup_node:
- dns_db_detachnode(db, &node);
-
- return (result);
-}
-
-/*%
- * For each RR of 'name' in 'ver' of 'db', call 'action'
- * with the RR and 'action_data' as arguments. If the name
- * does not exist, do nothing.
- *
- * If 'action' returns an error, abort iteration
- * and return the error.
- */
-static isc_result_t
-foreach_node_rr(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
- rr_func *rr_action, void *rr_action_data)
-{
- foreach_node_rr_ctx_t ctx;
- ctx.rr_action = rr_action;
- ctx.rr_action_data = rr_action_data;
- return (foreach_rrset(db, ver, name,
- foreach_node_rr_action, &ctx));
-}
-
-
-/*%
- * For each of the RRs specified by 'db', 'ver', 'name', 'type',
- * (which can be dns_rdatatype_any to match any type), and 'covers', call
- * 'action' with the RR and 'action_data' as arguments. If the name
- * does not exist, or if no RRset of the given type exists at the name,
- * do nothing.
- *
- * If 'action' returns an error, abort iteration and return the error.
- */
-static isc_result_t
-foreach_rr(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
- dns_rdatatype_t type, dns_rdatatype_t covers, rr_func *rr_action,
- void *rr_action_data)
-{
-
- isc_result_t result;
- dns_dbnode_t *node;
- dns_rdataset_t rdataset;
-
- if (type == dns_rdatatype_any)
- return (foreach_node_rr(db, ver, name,
- rr_action, rr_action_data));
-
- node = NULL;
- if (type == dns_rdatatype_nsec3 ||
- (type == dns_rdatatype_rrsig && covers == dns_rdatatype_nsec3))
- result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
- else
- result = dns_db_findnode(db, name, ISC_FALSE, &node);
- if (result == ISC_R_NOTFOUND)
- return (ISC_R_SUCCESS);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- dns_rdataset_init(&rdataset);
- result = dns_db_findrdataset(db, node, ver, type, covers,
- (isc_stdtime_t) 0, &rdataset, NULL);
- if (result == ISC_R_NOTFOUND) {
- result = ISC_R_SUCCESS;
- goto cleanup_node;
- }
- if (result != ISC_R_SUCCESS)
- goto cleanup_node;
-
- for (result = dns_rdataset_first(&rdataset);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(&rdataset))
- {
- rr_t rr = { 0, DNS_RDATA_INIT };
- dns_rdataset_current(&rdataset, &rr.rdata);
- rr.ttl = rdataset.ttl;
- result = (*rr_action)(rr_action_data, &rr);
- if (result != ISC_R_SUCCESS)
- goto cleanup_rdataset;
- }
- if (result != ISC_R_NOMORE)
- goto cleanup_rdataset;
- result = ISC_R_SUCCESS;
-
- cleanup_rdataset:
- dns_rdataset_disassociate(&rdataset);
- cleanup_node:
- dns_db_detachnode(db, &node);
-
- return (result);
-}
-
-/**************************************************************************/
-/*
- * Various tests on the database contents (for prerequisites, etc).
- */
-
-/*%
- * Function type for predicate functions that compare a database RR 'db_rr'
- * against an update RR 'update_rr'.
- */
-typedef isc_boolean_t rr_predicate(dns_rdata_t *update_rr, dns_rdata_t *db_rr);
-
-/*%
- * Helper function for rrset_exists().
- */
-static isc_result_t
-rrset_exists_action(void *data, rr_t *rr) {
- UNUSED(data);
- UNUSED(rr);
- return (ISC_R_EXISTS);
-}
-
-/*%
- * Utility macro for RR existence checking functions.
- *
- * If the variable 'result' has the value ISC_R_EXISTS or
- * ISC_R_SUCCESS, set *exists to ISC_TRUE or ISC_FALSE,
- * respectively, and return success.
- *
- * If 'result' has any other value, there was a failure.
- * Return the failure result code and do not set *exists.
- *
- * This would be more readable as "do { if ... } while(0)",
- * but that form generates tons of warnings on Solaris 2.6.
- */
-#define RETURN_EXISTENCE_FLAG \
- return ((result == ISC_R_EXISTS) ? \
- (*exists = ISC_TRUE, ISC_R_SUCCESS) : \
- ((result == ISC_R_SUCCESS) ? \
- (*exists = ISC_FALSE, ISC_R_SUCCESS) : \
- result))
-
-/*%
- * Set '*exists' to true iff an rrset of the given type exists,
- * to false otherwise.
- */
-static isc_result_t
-rrset_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
- dns_rdatatype_t type, dns_rdatatype_t covers,
- isc_boolean_t *exists)
-{
- isc_result_t result;
- result = foreach_rr(db, ver, name, type, covers,
- rrset_exists_action, NULL);
- RETURN_EXISTENCE_FLAG;
-}
-
-/*%
- * Set '*visible' to true if the RRset exists and is part of the
- * visible zone. Otherwise '*visible' is set to false unless a
- * error occurs.
- */
-static isc_result_t
-rrset_visible(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
- dns_rdatatype_t type, isc_boolean_t *visible)
-{
- isc_result_t result;
- dns_fixedname_t fixed;
-
- dns_fixedname_init(&fixed);
- result = dns_db_find(db, name, ver, type, DNS_DBFIND_NOWILD,
- (isc_stdtime_t) 0, NULL,
- dns_fixedname_name(&fixed), NULL, NULL);
- switch (result) {
- case ISC_R_SUCCESS:
- *visible = ISC_TRUE;
- break;
- /*
- * Glue, obscured, deleted or replaced records.
- */
- case DNS_R_DELEGATION:
- case DNS_R_DNAME:
- case DNS_R_CNAME:
- case DNS_R_NXDOMAIN:
- case DNS_R_NXRRSET:
- case DNS_R_EMPTYNAME:
- case DNS_R_COVERINGNSEC:
- *visible = ISC_FALSE;
- result = ISC_R_SUCCESS;
- break;
- default:
- break;
- }
- return (result);
-}
-
-/*%
- * Context struct and helper function for name_exists().
- */
-
-static isc_result_t
-name_exists_action(void *data, dns_rdataset_t *rrset) {
- UNUSED(data);
- UNUSED(rrset);
- return (ISC_R_EXISTS);
-}
-
-/*%
- * Set '*exists' to true iff the given name exists, to false otherwise.
- */
-static isc_result_t
-name_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
- isc_boolean_t *exists)
-{
- isc_result_t result;
- result = foreach_rrset(db, ver, name,
- name_exists_action, NULL);
- RETURN_EXISTENCE_FLAG;
-}
-
-/**************************************************************************/
-/*
- * Checking of "RRset exists (value dependent)" prerequisites.
- *
- * In the RFC2136 section 3.2.5, this is the pseudocode involving
- * a variable called "temp", a mapping of <name, type> tuples to rrsets.
- *
- * Here, we represent the "temp" data structure as (non-minimal) "dns_diff_t"
- * where each tuple has op==DNS_DIFFOP_EXISTS.
- */
-
-/*%
- * A comparison function defining the sorting order for the entries
- * in the "temp" data structure. The major sort key is the owner name,
- * followed by the type and rdata.
- */
-static int
-temp_order(const void *av, const void *bv) {
- dns_difftuple_t const * const *ap = av;
- dns_difftuple_t const * const *bp = bv;
- dns_difftuple_t const *a = *ap;
- dns_difftuple_t const *b = *bp;
- int r;
- r = dns_name_compare(&a->name, &b->name);
- if (r != 0)
- return (r);
- r = (b->rdata.type - a->rdata.type);
- if (r != 0)
- return (r);
- r = dns_rdata_casecompare(&a->rdata, &b->rdata);
- return (r);
-}
-
-/**************************************************************************/
-/*
- * Conditional deletion of RRs.
- */
-
-/*%
- * Context structure for delete_if().
- */
-
-typedef struct {
- rr_predicate *predicate;
- dns_db_t *db;
- dns_dbversion_t *ver;
- dns_diff_t *diff;
- dns_name_t *name;
- dns_rdata_t *update_rr;
-} conditional_delete_ctx_t;
-
-/*%
- * Predicate functions for delete_if().
- */
-
-/*%
- * Return true always.
- */
-static isc_boolean_t
-true_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) {
- UNUSED(update_rr);
- UNUSED(db_rr);
- return (ISC_TRUE);
-}
-
-/*%
- * Return true if the record is a RRSIG.
- */
-static isc_boolean_t
-rrsig_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) {
- UNUSED(update_rr);
- return ((db_rr->type == dns_rdatatype_rrsig) ?
- ISC_TRUE : ISC_FALSE);
-}
-
-/*%
- * Internal helper function for delete_if().
- */
-static isc_result_t
-delete_if_action(void *data, rr_t *rr) {
- conditional_delete_ctx_t *ctx = data;
- if ((*ctx->predicate)(ctx->update_rr, &rr->rdata)) {
- isc_result_t result;
- result = update_one_rr(ctx->db, ctx->ver, ctx->diff,
- DNS_DIFFOP_DEL, ctx->name,
- rr->ttl, &rr->rdata);
- return (result);
- } else {
- return (ISC_R_SUCCESS);
- }
-}
-
-/*%
- * Conditionally delete RRs. Apply 'predicate' to the RRs
- * specified by 'db', 'ver', 'name', and 'type' (which can
- * be dns_rdatatype_any to match any type). Delete those
- * RRs for which the predicate returns true, and log the
- * deletions in 'diff'.
- */
-static isc_result_t
-delete_if(rr_predicate *predicate, dns_db_t *db, dns_dbversion_t *ver,
- dns_name_t *name, dns_rdatatype_t type, dns_rdatatype_t covers,
- dns_rdata_t *update_rr, dns_diff_t *diff)
-{
- conditional_delete_ctx_t ctx;
- ctx.predicate = predicate;
- ctx.db = db;
- ctx.ver = ver;
- ctx.diff = diff;
- ctx.name = name;
- ctx.update_rr = update_rr;
- return (foreach_rr(db, ver, name, type, covers,
- delete_if_action, &ctx));
-}
-
-/**************************************************************************/
-/*
- * Incremental updating of NSECs and RRSIGs.
- */
-
-/*%
- * We abuse the dns_diff_t type to represent a set of domain names
- * affected by the update.
- */
-static isc_result_t
-namelist_append_name(dns_diff_t *list, dns_name_t *name) {
- isc_result_t result;
- dns_difftuple_t *tuple = NULL;
- static dns_rdata_t dummy_rdata = DNS_RDATA_INIT;
-
- CHECK(dns_difftuple_create(list->mctx, DNS_DIFFOP_EXISTS, name, 0,
- &dummy_rdata, &tuple));
- dns_diff_append(list, &tuple);
- failure:
- return (result);
-}
-
-static isc_result_t
-namelist_append_subdomain(dns_db_t *db, dns_name_t *name, dns_diff_t *affected)
-{
- isc_result_t result;
- dns_fixedname_t fixedname;
- dns_name_t *child;
- dns_dbiterator_t *dbit = NULL;
-
- dns_fixedname_init(&fixedname);
- child = dns_fixedname_name(&fixedname);
-
- CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit));
-
- for (result = dns_dbiterator_seek(dbit, name);
- result == ISC_R_SUCCESS;
- result = dns_dbiterator_next(dbit))
- {
- dns_dbnode_t *node = NULL;
- CHECK(dns_dbiterator_current(dbit, &node, child));
- dns_db_detachnode(db, &node);
- if (! dns_name_issubdomain(child, name))
- break;
- CHECK(namelist_append_name(affected, child));
- }
- if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
- failure:
- if (dbit != NULL)
- dns_dbiterator_destroy(&dbit);
- return (result);
-}
-
-
-
-/*%
- * Helper function for non_nsec_rrset_exists().
- */
-static isc_result_t
-is_non_nsec_action(void *data, dns_rdataset_t *rrset) {
- UNUSED(data);
- if (!(rrset->type == dns_rdatatype_nsec ||
- rrset->type == dns_rdatatype_nsec3 ||
- (rrset->type == dns_rdatatype_rrsig &&
- (rrset->covers == dns_rdatatype_nsec ||
- rrset->covers == dns_rdatatype_nsec3))))
- return (ISC_R_EXISTS);
- return (ISC_R_SUCCESS);
-}
-
-/*%
- * Check whether there is an rrset other than a NSEC or RRSIG NSEC,
- * i.e., anything that justifies the continued existence of a name
- * after a secure update.
- *
- * If such an rrset exists, set '*exists' to ISC_TRUE.
- * Otherwise, set it to ISC_FALSE.
- */
-static isc_result_t
-non_nsec_rrset_exists(dns_db_t *db, dns_dbversion_t *ver,
- dns_name_t *name, isc_boolean_t *exists)
-{
- isc_result_t result;
- result = foreach_rrset(db, ver, name, is_non_nsec_action, NULL);
- RETURN_EXISTENCE_FLAG;
-}
-
-/*%
- * A comparison function for sorting dns_diff_t:s by name.
- */
-static int
-name_order(const void *av, const void *bv) {
- dns_difftuple_t const * const *ap = av;
- dns_difftuple_t const * const *bp = bv;
- dns_difftuple_t const *a = *ap;
- dns_difftuple_t const *b = *bp;
- return (dns_name_compare(&a->name, &b->name));
-}
-
-static isc_result_t
-uniqify_name_list(dns_diff_t *list) {
- isc_result_t result;
- dns_difftuple_t *p, *q;
-
- CHECK(dns_diff_sort(list, name_order));
-
- p = ISC_LIST_HEAD(list->tuples);
- while (p != NULL) {
- do {
- q = ISC_LIST_NEXT(p, link);
- if (q == NULL || ! dns_name_equal(&p->name, &q->name))
- break;
- ISC_LIST_UNLINK(list->tuples, q, link);
- dns_difftuple_free(&q);
- } while (1);
- p = ISC_LIST_NEXT(p, link);
- }
- failure:
- return (result);
-}
-
-static isc_result_t
-is_active(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
- isc_boolean_t *flag, isc_boolean_t *cut, isc_boolean_t *unsecure)
-{
- isc_result_t result;
- dns_fixedname_t foundname;
- dns_fixedname_init(&foundname);
- result = dns_db_find(db, name, ver, dns_rdatatype_any,
- DNS_DBFIND_GLUEOK | DNS_DBFIND_NOWILD,
- (isc_stdtime_t) 0, NULL,
- dns_fixedname_name(&foundname),
- NULL, NULL);
- if (result == ISC_R_SUCCESS || result == DNS_R_EMPTYNAME) {
- *flag = ISC_TRUE;
- *cut = ISC_FALSE;
- if (unsecure != NULL)
- *unsecure = ISC_FALSE;
- return (ISC_R_SUCCESS);
- } else if (result == DNS_R_ZONECUT) {
- *flag = ISC_TRUE;
- *cut = ISC_TRUE;
- if (unsecure != NULL) {
- /*
- * We are at the zonecut. Check to see if there
- * is a DS RRset.
- */
- if (dns_db_find(db, name, ver, dns_rdatatype_ds, 0,
- (isc_stdtime_t) 0, NULL,
- dns_fixedname_name(&foundname),
- NULL, NULL) == DNS_R_NXRRSET)
- *unsecure = ISC_TRUE;
- else
- *unsecure = ISC_FALSE;
- }
- return (ISC_R_SUCCESS);
- } else if (result == DNS_R_GLUE || result == DNS_R_DNAME ||
- result == DNS_R_DELEGATION || result == DNS_R_NXDOMAIN) {
- *flag = ISC_FALSE;
- *cut = ISC_FALSE;
- if (unsecure != NULL)
- *unsecure = ISC_FALSE;
- return (ISC_R_SUCCESS);
- } else {
- /*
- * Silence compiler.
- */
- *flag = ISC_FALSE;
- *cut = ISC_FALSE;
- if (unsecure != NULL)
- *unsecure = ISC_FALSE;
- return (result);
- }
-}
-
-/*%
- * Find the next/previous name that has a NSEC record.
- * In other words, skip empty database nodes and names that
- * have had their NSECs removed because they are obscured by
- * a zone cut.
- */
-static isc_result_t
-next_active(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db,
- dns_dbversion_t *ver, dns_name_t *oldname, dns_name_t *newname,
- isc_boolean_t forward)
-{
- isc_result_t result;
- dns_dbiterator_t *dbit = NULL;
- isc_boolean_t has_nsec = ISC_FALSE;
- unsigned int wraps = 0;
- isc_boolean_t secure = dns_db_issecure(db);
-
- CHECK(dns_db_createiterator(db, 0, &dbit));
-
- CHECK(dns_dbiterator_seek(dbit, oldname));
- do {
- dns_dbnode_t *node = NULL;
-
- if (forward)
- result = dns_dbiterator_next(dbit);
- else
- result = dns_dbiterator_prev(dbit);
- if (result == ISC_R_NOMORE) {
- /*
- * Wrap around.
- */
- if (forward)
- CHECK(dns_dbiterator_first(dbit));
- else
- CHECK(dns_dbiterator_last(dbit));
- wraps++;
- if (wraps == 2) {
- update_log(log, zone, ISC_LOG_ERROR,
- "secure zone with no NSECs");
- result = DNS_R_BADZONE;
- goto failure;
- }
- }
- CHECK(dns_dbiterator_current(dbit, &node, newname));
- dns_db_detachnode(db, &node);
-
- /*
- * The iterator may hold the tree lock, and
- * rrset_exists() calls dns_db_findnode() which
- * may try to reacquire it. To avoid deadlock
- * we must pause the iterator first.
- */
- CHECK(dns_dbiterator_pause(dbit));
- if (secure) {
- CHECK(rrset_exists(db, ver, newname,
- dns_rdatatype_nsec, 0, &has_nsec));
- } else {
- dns_fixedname_t ffound;
- dns_name_t *found;
- dns_fixedname_init(&ffound);
- found = dns_fixedname_name(&ffound);
- result = dns_db_find(db, newname, ver,
- dns_rdatatype_soa,
- DNS_DBFIND_NOWILD, 0, NULL, found,
- NULL, NULL);
- if (result == ISC_R_SUCCESS ||
- result == DNS_R_EMPTYNAME ||
- result == DNS_R_NXRRSET ||
- result == DNS_R_CNAME ||
- (result == DNS_R_DELEGATION &&
- dns_name_equal(newname, found))) {
- has_nsec = ISC_TRUE;
- result = ISC_R_SUCCESS;
- } else if (result != DNS_R_NXDOMAIN)
- break;
- }
- } while (! has_nsec);
- failure:
- if (dbit != NULL)
- dns_dbiterator_destroy(&dbit);
-
- return (result);
-}
-
-/*%
- * Add a NSEC record for "name", recording the change in "diff".
- * The existing NSEC is removed.
- */
-static isc_result_t
-add_nsec(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db,
- dns_dbversion_t *ver, dns_name_t *name, dns_ttl_t nsecttl,
- dns_diff_t *diff)
-{
- isc_result_t result;
- dns_dbnode_t *node = NULL;
- unsigned char buffer[DNS_NSEC_BUFFERSIZE];
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_difftuple_t *tuple = NULL;
- dns_fixedname_t fixedname;
- dns_name_t *target;
-
- dns_fixedname_init(&fixedname);
- target = dns_fixedname_name(&fixedname);
-
- /*
- * Find the successor name, aka NSEC target.
- */
- CHECK(next_active(log, zone, db, ver, name, target, ISC_TRUE));
-
- /*
- * Create the NSEC RDATA.
- */
- CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
- dns_rdata_init(&rdata);
- CHECK(dns_nsec_buildrdata(db, ver, node, target, buffer, &rdata));
- dns_db_detachnode(db, &node);
-
- /*
- * Delete the old NSEC and record the change.
- */
- CHECK(delete_if(true_p, db, ver, name, dns_rdatatype_nsec, 0,
- NULL, diff));
- /*
- * Add the new NSEC and record the change.
- */
- CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, name,
- nsecttl, &rdata, &tuple));
- CHECK(do_one_tuple(&tuple, db, ver, diff));
- INSIST(tuple == NULL);
-
- failure:
- if (node != NULL)
- dns_db_detachnode(db, &node);
- return (result);
-}
-
-/*%
- * Add a placeholder NSEC record for "name", recording the change in "diff".
- */
-static isc_result_t
-add_placeholder_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
- dns_diff_t *diff)
-{
- isc_result_t result;
- dns_difftuple_t *tuple = NULL;
- isc_region_t r;
- unsigned char data[1] = { 0 }; /* The root domain, no bits. */
- dns_rdata_t rdata = DNS_RDATA_INIT;
-
- r.base = data;
- r.length = sizeof(data);
- dns_rdata_fromregion(&rdata, dns_db_class(db), dns_rdatatype_nsec, &r);
- CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, name, 0,
- &rdata, &tuple));
- CHECK(do_one_tuple(&tuple, db, ver, diff));
- failure:
- return (result);
-}
-
-static isc_result_t
-find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
- isc_mem_t *mctx, unsigned int maxkeys,
- dst_key_t **keys, unsigned int *nkeys)
-{
- isc_result_t result;
- dns_dbnode_t *node = NULL;
- const char *directory = dns_zone_getkeydirectory(zone);
- CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node));
- CHECK(dns_dnssec_findzonekeys2(db, ver, node, dns_db_origin(db),
- directory, mctx, maxkeys, keys, nkeys));
- failure:
- if (node != NULL)
- dns_db_detachnode(db, &node);
- return (result);
-}
-
-/*%
- * Add RRSIG records for an RRset, recording the change in "diff".
- */
-static isc_result_t
-add_sigs(dns_update_log_t *log, 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 keyset_kskonly)
-{
- isc_result_t result;
- dns_dbnode_t *node = NULL;
- dns_rdataset_t rdataset;
- dns_rdata_t sig_rdata = DNS_RDATA_INIT;
- isc_buffer_t buffer;
- unsigned char data[1024]; /* XXX */
- unsigned int i, j;
- isc_boolean_t added_sig = ISC_FALSE;
- isc_mem_t *mctx = diff->mctx;
-
- dns_rdataset_init(&rdataset);
- isc_buffer_init(&buffer, data, sizeof(data));
-
- /* Get the rdataset to sign. */
- if (type == dns_rdatatype_nsec3)
- CHECK(dns_db_findnsec3node(db, name, ISC_FALSE, &node));
- else
- CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
- CHECK(dns_db_findrdataset(db, node, ver, type, 0,
- (isc_stdtime_t) 0, &rdataset, NULL));
- dns_db_detachnode(db, &node);
-
-#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 (!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. */
- CHECK(dns_dnssec_sign(name, &rdataset, keys[i],
- &inception, &expire,
- mctx, &buffer, &sig_rdata));
-
- /* Update the database and journal with the RRSIG. */
- /* XXX inefficient - will cause dataset merging */
- CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN, name,
- rdataset.ttl, &sig_rdata));
- dns_rdata_reset(&sig_rdata);
- isc_buffer_init(&buffer, data, sizeof(data));
- added_sig = ISC_TRUE;
- }
- if (!added_sig) {
- update_log(log, zone, ISC_LOG_ERROR,
- "found no active private keys, "
- "unable to generate any signatures");
- result = ISC_R_NOTFOUND;
- }
-
- failure:
- if (dns_rdataset_isassociated(&rdataset))
- dns_rdataset_disassociate(&rdataset);
- if (node != NULL)
- dns_db_detachnode(db, &node);
- return (result);
-}
-
-/*
- * Delete expired RRsigs and any RRsigs we are about to re-sign.
- * See also zone.c:del_sigs().
- */
-static isc_result_t
-del_keysigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
- dns_diff_t *diff, dst_key_t **keys, unsigned int nkeys)
-{
- isc_result_t result;
- dns_dbnode_t *node = NULL;
- dns_rdataset_t rdataset;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- unsigned int i;
- dns_rdata_rrsig_t rrsig;
- isc_boolean_t found;
-
- dns_rdataset_init(&rdataset);
-
- result = dns_db_findnode(db, name, ISC_FALSE, &node);
- if (result == ISC_R_NOTFOUND)
- return (ISC_R_SUCCESS);
- if (result != ISC_R_SUCCESS)
- goto failure;
- result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig,
- dns_rdatatype_dnskey, (isc_stdtime_t) 0,
- &rdataset, NULL);
- dns_db_detachnode(db, &node);
-
- if (result == ISC_R_NOTFOUND)
- return (ISC_R_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);
- result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- found = ISC_FALSE;
- for (i = 0; i < nkeys; i++) {
- if (rrsig.keyid == dst_key_id(keys[i])) {
- found = ISC_TRUE;
- if (!dst_key_isprivate(keys[i])) {
- /*
- * The re-signing code in zone.c
- * will mark this as offline.
- * Just skip the record for now.
- */
- break;
- }
- result = update_one_rr(db, ver, diff,
- DNS_DIFFOP_DEL, name,
- rdataset.ttl, &rdata);
- break;
- }
- }
- /*
- * If there is not a matching DNSKEY then delete the RRSIG.
- */
- if (!found)
- result = update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
- name, rdataset.ttl, &rdata);
- dns_rdata_reset(&rdata);
- if (result != ISC_R_SUCCESS)
- break;
- }
- dns_rdataset_disassociate(&rdataset);
- if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
-failure:
- if (node != NULL)
- dns_db_detachnode(db, &node);
- return (result);
-}
-
-static isc_result_t
-add_exposed_sigs(dns_update_log_t *log, 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 keyset_kskonly)
-{
- isc_result_t result;
- dns_dbnode_t *node;
- dns_rdatasetiter_t *iter;
-
- node = NULL;
- result = dns_db_findnode(db, name, ISC_FALSE, &node);
- if (result == ISC_R_NOTFOUND)
- return (ISC_R_SUCCESS);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- iter = NULL;
- result = dns_db_allrdatasets(db, node, ver,
- (isc_stdtime_t) 0, &iter);
- if (result != ISC_R_SUCCESS)
- goto cleanup_node;
-
- for (result = dns_rdatasetiter_first(iter);
- result == ISC_R_SUCCESS;
- result = dns_rdatasetiter_next(iter))
- {
- dns_rdataset_t rdataset;
- dns_rdatatype_t type;
- isc_boolean_t flag;
-
- dns_rdataset_init(&rdataset);
- dns_rdatasetiter_current(iter, &rdataset);
- type = rdataset.type;
- dns_rdataset_disassociate(&rdataset);
-
- /*
- * We don't need to sign unsigned NSEC records at the cut
- * as they are handled elsewhere.
- */
- if ((type == dns_rdatatype_rrsig) ||
- (cut && type != dns_rdatatype_ds))
- continue;
- result = rrset_exists(db, ver, name, dns_rdatatype_rrsig,
- type, &flag);
- if (result != ISC_R_SUCCESS)
- goto cleanup_iterator;
- if (flag)
- continue;;
- result = add_sigs(log, zone, db, ver, name, type, diff,
- keys, nkeys, inception, expire,
- check_ksk, keyset_kskonly);
- if (result != ISC_R_SUCCESS)
- goto cleanup_iterator;
- }
- if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
-
- cleanup_iterator:
- dns_rdatasetiter_destroy(&iter);
-
- cleanup_node:
- dns_db_detachnode(db, &node);
-
- return (result);
-}
-
-/*%
- * Update RRSIG, NSEC and NSEC3 records affected by an update. The original
- * update, including the SOA serial update but excluding the RRSIG & NSEC
- * changes, is in "diff" and has already been applied to "newver" of "db".
- * The database version prior to the update is "oldver".
- *
- * The necessary RRSIG, NSEC and NSEC3 changes will be applied to "newver"
- * and added (as a minimal diff) to "diff".
- *
- * The RRSIGs generated will be valid for 'sigvalidityinterval' seconds.
- */
-isc_result_t
-dns_update_signatures(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db,
- dns_dbversion_t *oldver, dns_dbversion_t *newver,
- dns_diff_t *diff, isc_uint32_t sigvalidityinterval)
-{
- isc_result_t result;
- dns_difftuple_t *t;
- dns_diff_t diffnames;
- dns_diff_t affected;
- dns_diff_t sig_diff;
- dns_diff_t nsec_diff;
- dns_diff_t nsec_mindiff;
- isc_boolean_t flag, build_nsec, build_nsec3;
- dst_key_t *zone_keys[DNS_MAXZONEKEYS];
- unsigned int nkeys = 0;
- unsigned int i;
- isc_stdtime_t now, inception, expire;
- dns_ttl_t nsecttl;
- dns_rdata_soa_t soa;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdataset_t rdataset;
- dns_dbnode_t *node = NULL;
- isc_boolean_t check_ksk, keyset_kskonly;
- isc_boolean_t unsecure;
- isc_boolean_t cut;
- dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
-
- dns_diff_init(diff->mctx, &diffnames);
- dns_diff_init(diff->mctx, &affected);
-
- dns_diff_init(diff->mctx, &sig_diff);
- sig_diff.resign = dns_zone_getsigresigninginterval(zone);
- dns_diff_init(diff->mctx, &nsec_diff);
- dns_diff_init(diff->mctx, &nsec_mindiff);
-
- result = find_zone_keys(zone, db, newver, diff->mctx,
- DNS_MAXZONEKEYS, zone_keys, &nkeys);
- if (result != ISC_R_SUCCESS) {
- update_log(log, zone, ISC_LOG_ERROR,
- "could not get zone keys for secure dynamic update");
- goto failure;
- }
-
- isc_stdtime_get(&now);
- inception = now - 3600; /* Allow for some clock skew. */
- expire = now + sigvalidityinterval;
-
- /*
- * Do we look at the KSK flag on the DNSKEY to determining which
- * keys sign which RRsets? First check the zone option then
- * check the keys flags to make sure at least one has a ksk set
- * and one doesn't.
- */
- check_ksk = ISC_TF((dns_zone_getoptions(zone) &
- DNS_ZONEOPT_UPDATECHECKKSK) != 0);
- keyset_kskonly = ISC_TF((dns_zone_getoptions(zone) &
- DNS_ZONEOPT_DNSKEYKSKONLY) != 0);
-
- /*
- * Get the NSEC/NSEC3 TTL from the SOA MINIMUM field.
- */
- CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node));
- dns_rdataset_init(&rdataset);
- CHECK(dns_db_findrdataset(db, node, newver, dns_rdatatype_soa, 0,
- (isc_stdtime_t) 0, &rdataset, NULL));
- CHECK(dns_rdataset_first(&rdataset));
- dns_rdataset_current(&rdataset, &rdata);
- CHECK(dns_rdata_tostruct(&rdata, &soa, NULL));
- nsecttl = soa.minimum;
- dns_rdataset_disassociate(&rdataset);
- dns_db_detachnode(db, &node);
-
- /*
- * Find all RRsets directly affected by the update, and
- * update their RRSIGs. Also build a list of names affected
- * by the update in "diffnames".
- */
- CHECK(dns_diff_sort(diff, temp_order));
-
- t = ISC_LIST_HEAD(diff->tuples);
- while (t != NULL) {
- dns_name_t *name = &t->name;
- /* Now "name" is a new, unique name affected by the update. */
-
- CHECK(namelist_append_name(&diffnames, name));
-
- while (t != NULL && dns_name_equal(&t->name, name)) {
- dns_rdatatype_t type;
- type = t->rdata.type;
-
- /*
- * Now "name" and "type" denote a new unique RRset
- * affected by the update.
- */
-
- /* Don't sign RRSIGs. */
- if (type == dns_rdatatype_rrsig)
- goto skip;
-
- /*
- * Delete all old RRSIGs covering this type, since they
- * are all invalid when the signed RRset has changed.
- * We may not be able to recreate all of them - tough.
- * Special case changes to the zone's DNSKEY records
- * to support offline KSKs.
- */
- if (type == dns_rdatatype_dnskey)
- del_keysigs(db, newver, name, &sig_diff,
- zone_keys, nkeys);
- else
- CHECK(delete_if(true_p, db, newver, name,
- dns_rdatatype_rrsig, type,
- NULL, &sig_diff));
-
- /*
- * If this RRset is still visible after the update,
- * add a new signature for it.
- */
- CHECK(rrset_visible(db, newver, name, type, &flag));
- if (flag) {
- CHECK(add_sigs(log, zone, db, newver, name,
- type, &sig_diff, zone_keys,
- nkeys, inception, expire,
- check_ksk, keyset_kskonly));
- }
- skip:
- /* Skip any other updates to the same RRset. */
- while (t != NULL &&
- dns_name_equal(&t->name, name) &&
- t->rdata.type == type)
- {
- t = ISC_LIST_NEXT(t, link);
- }
- }
- }
- update_log(log, zone, ISC_LOG_DEBUG(3), "updated data signatures");
-
- /* Remove orphaned NSECs and RRSIG NSECs. */
- for (t = ISC_LIST_HEAD(diffnames.tuples);
- t != NULL;
- t = ISC_LIST_NEXT(t, link))
- {
- CHECK(non_nsec_rrset_exists(db, newver, &t->name, &flag));
- if (! flag) {
- CHECK(delete_if(true_p, db, newver, &t->name,
- dns_rdatatype_any, 0,
- NULL, &sig_diff));
- }
- }
- update_log(log, zone, ISC_LOG_DEBUG(3),
- "removed any orphaned NSEC records");
-
- /*
- * See if we need to build NSEC or NSEC3 chains.
- */
- CHECK(dns_private_chains(db, newver, privatetype, &build_nsec,
- &build_nsec3));
- if (!build_nsec)
- goto update_nsec3;
-
- update_log(log, zone, ISC_LOG_DEBUG(3), "rebuilding NSEC chain");
-
- /*
- * When a name is created or deleted, its predecessor needs to
- * have its NSEC updated.
- */
- for (t = ISC_LIST_HEAD(diffnames.tuples);
- t != NULL;
- t = ISC_LIST_NEXT(t, link))
- {
- isc_boolean_t existed, exists;
- dns_fixedname_t fixedname;
- dns_name_t *prevname;
-
- dns_fixedname_init(&fixedname);
- prevname = dns_fixedname_name(&fixedname);
-
- if (oldver != NULL)
- CHECK(name_exists(db, oldver, &t->name, &existed));
- else
- existed = ISC_FALSE;
- CHECK(name_exists(db, newver, &t->name, &exists));
- if (exists == existed)
- continue;
-
- /*
- * Find the predecessor.
- * When names become obscured or unobscured in this update
- * transaction, we may find the wrong predecessor because
- * the NSECs have not yet been updated to reflect the delegation
- * change. This should not matter because in this case,
- * the correct predecessor is either the delegation node or
- * a newly unobscured node, and those nodes are on the
- * "affected" list in any case.
- */
- CHECK(next_active(log, zone, db, newver,
- &t->name, prevname, ISC_FALSE));
- CHECK(namelist_append_name(&affected, prevname));
- }
-
- /*
- * Find names potentially affected by delegation changes
- * (obscured by adding an NS or DNAME, or unobscured by
- * removing one).
- */
- for (t = ISC_LIST_HEAD(diffnames.tuples);
- t != NULL;
- t = ISC_LIST_NEXT(t, link))
- {
- isc_boolean_t ns_existed, dname_existed;
- isc_boolean_t ns_exists, dname_exists;
-
- if (oldver != NULL)
- CHECK(rrset_exists(db, oldver, &t->name,
- dns_rdatatype_ns, 0, &ns_existed));
- else
- ns_existed = ISC_FALSE;
- if (oldver != NULL)
- CHECK(rrset_exists(db, oldver, &t->name,
- dns_rdatatype_dname, 0,
- &dname_existed));
- else
- dname_existed = ISC_FALSE;
- CHECK(rrset_exists(db, newver, &t->name, dns_rdatatype_ns, 0,
- &ns_exists));
- CHECK(rrset_exists(db, newver, &t->name, dns_rdatatype_dname, 0,
- &dname_exists));
- if ((ns_exists || dname_exists) == (ns_existed || dname_existed))
- continue;
- /*
- * There was a delegation change. Mark all subdomains
- * of t->name as potentially needing a NSEC update.
- */
- CHECK(namelist_append_subdomain(db, &t->name, &affected));
- }
-
- ISC_LIST_APPENDLIST(affected.tuples, diffnames.tuples, link);
- INSIST(ISC_LIST_EMPTY(diffnames.tuples));
-
- CHECK(uniqify_name_list(&affected));
-
- /*
- * Determine which names should have NSECs, and delete/create
- * NSECs to make it so. We don't know the final NSEC targets yet,
- * so we just create placeholder NSECs with arbitrary contents
- * to indicate that their respective owner names should be part of
- * the NSEC chain.
- */
- for (t = ISC_LIST_HEAD(affected.tuples);
- t != NULL;
- t = ISC_LIST_NEXT(t, link))
- {
- isc_boolean_t exists;
- dns_name_t *name = &t->name;
-
- CHECK(name_exists(db, newver, name, &exists));
- if (! exists)
- continue;
- CHECK(is_active(db, newver, name, &flag, &cut, NULL));
- if (!flag) {
- /*
- * This name is obscured. Delete any
- * existing NSEC record.
- */
- CHECK(delete_if(true_p, db, newver, name,
- dns_rdatatype_nsec, 0,
- NULL, &nsec_diff));
- CHECK(delete_if(rrsig_p, db, newver, name,
- dns_rdatatype_any, 0, NULL, diff));
- } else {
- /*
- * 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.
- */
- 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(log, zone, db, newver, name,
- cut, &sig_diff, zone_keys, nkeys,
- inception, expire, check_ksk,
- keyset_kskonly));
- }
- }
-
- /*
- * Now we know which names are part of the NSEC chain.
- * Make them all point at their correct targets.
- */
- for (t = ISC_LIST_HEAD(affected.tuples);
- t != NULL;
- t = ISC_LIST_NEXT(t, link))
- {
- CHECK(rrset_exists(db, newver, &t->name,
- dns_rdatatype_nsec, 0, &flag));
- if (flag) {
- /*
- * There is a NSEC, but we don't know if it is correct.
- * Delete it and create a correct one to be sure.
- * If the update was unnecessary, the diff minimization
- * will take care of eliminating it from the journal,
- * IXFRs, etc.
- *
- * The RRSIG bit should always be set in the NSECs
- * we generate, because they will all get RRSIG NSECs.
- * (XXX what if the zone keys are missing?).
- * Because the RRSIG NSECs have not necessarily been
- * created yet, the correctness of the bit mask relies
- * on the assumption that NSECs are only created if
- * there is other data, and if there is other data,
- * there are other RRSIGs.
- */
- CHECK(add_nsec(log, zone, db, newver, &t->name,
- nsecttl, &nsec_diff));
- }
- }
-
- /*
- * Minimize the set of NSEC updates so that we don't
- * have to regenerate the RRSIG NSECs for NSECs that were
- * replaced with identical ones.
- */
- while ((t = ISC_LIST_HEAD(nsec_diff.tuples)) != NULL) {
- ISC_LIST_UNLINK(nsec_diff.tuples, t, link);
- dns_diff_appendminimal(&nsec_mindiff, &t);
- }
-
- update_log(log, zone, ISC_LOG_DEBUG(3), "signing rebuilt NSEC chain");
-
- /* Update RRSIG NSECs. */
- for (t = ISC_LIST_HEAD(nsec_mindiff.tuples);
- t != NULL;
- t = ISC_LIST_NEXT(t, link))
- {
- if (t->op == DNS_DIFFOP_DEL) {
- CHECK(delete_if(true_p, db, newver, &t->name,
- dns_rdatatype_rrsig, dns_rdatatype_nsec,
- NULL, &sig_diff));
- } else if (t->op == DNS_DIFFOP_ADD) {
- CHECK(add_sigs(log, zone, db, newver, &t->name,
- dns_rdatatype_nsec, &sig_diff,
- zone_keys, nkeys, inception, expire,
- check_ksk, keyset_kskonly));
- } else {
- INSIST(0);
- }
- }
-
- update_nsec3:
-
- /* Record our changes for the journal. */
- while ((t = ISC_LIST_HEAD(sig_diff.tuples)) != NULL) {
- ISC_LIST_UNLINK(sig_diff.tuples, t, link);
- dns_diff_appendminimal(diff, &t);
- }
- while ((t = ISC_LIST_HEAD(nsec_mindiff.tuples)) != NULL) {
- ISC_LIST_UNLINK(nsec_mindiff.tuples, t, link);
- dns_diff_appendminimal(diff, &t);
- }
-
- INSIST(ISC_LIST_EMPTY(sig_diff.tuples));
- INSIST(ISC_LIST_EMPTY(nsec_diff.tuples));
- INSIST(ISC_LIST_EMPTY(nsec_mindiff.tuples));
-
- if (!build_nsec3) {
- update_log(log, zone, ISC_LOG_DEBUG(3),
- "no NSEC3 chains to rebuild");
- goto failure;
- }
-
- update_log(log, zone, ISC_LOG_DEBUG(3), "rebuilding NSEC3 chains");
-
- dns_diff_clear(&diffnames);
- dns_diff_clear(&affected);
-
- CHECK(dns_diff_sort(diff, temp_order));
-
- /*
- * Find names potentially affected by delegation changes
- * (obscured by adding an NS or DNAME, or unobscured by
- * removing one).
- */
- t = ISC_LIST_HEAD(diff->tuples);
- while (t != NULL) {
- dns_name_t *name = &t->name;
-
- 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) {
- t = ISC_LIST_NEXT(t, link);
- continue;
- }
-
- CHECK(namelist_append_name(&affected, name));
-
- if (oldver != NULL)
- CHECK(rrset_exists(db, oldver, name, dns_rdatatype_ns,
- 0, &ns_existed));
- else
- ns_existed = ISC_FALSE;
- if (oldver != NULL)
- CHECK(rrset_exists(db, oldver, name,
- dns_rdatatype_dname, 0,
- &dname_existed));
- else
- dname_existed = ISC_FALSE;
- CHECK(rrset_exists(db, newver, name, dns_rdatatype_ns, 0,
- &ns_exists));
- CHECK(rrset_exists(db, newver, name, dns_rdatatype_dname, 0,
- &dname_exists));
-
- exists = ns_exists || dname_exists;
- existed = ns_existed || dname_existed;
- if (exists == existed)
- goto nextname;
- /*
- * There was a delegation change. Mark all subdomains
- * of t->name as potentially needing a NSEC3 update.
- */
- CHECK(namelist_append_subdomain(db, name, &affected));
-
- nextname:
- while (t != NULL && dns_name_equal(&t->name, name))
- t = ISC_LIST_NEXT(t, link);
- }
-
- for (t = ISC_LIST_HEAD(affected.tuples);
- t != NULL;
- t = ISC_LIST_NEXT(t, link)) {
- dns_name_t *name = &t->name;
-
- unsecure = ISC_FALSE; /* Silence compiler warning. */
- CHECK(is_active(db, newver, name, &flag, &cut, &unsecure));
-
- if (!flag) {
- CHECK(delete_if(rrsig_p, db, newver, name,
- dns_rdatatype_any, 0, NULL, diff));
- CHECK(dns_nsec3_delnsec3sx(db, newver, name,
- privatetype, &nsec_diff));
- } else {
- CHECK(add_exposed_sigs(log, zone, db, newver, name,
- cut, &sig_diff, zone_keys, nkeys,
- inception, expire, check_ksk,
- keyset_kskonly));
- CHECK(dns_nsec3_addnsec3sx(db, newver, name, nsecttl,
- unsecure, privatetype,
- &nsec_diff));
- }
- }
-
- /*
- * Minimize the set of NSEC3 updates so that we don't
- * have to regenerate the RRSIG NSEC3s for NSEC3s that were
- * replaced with identical ones.
- */
- while ((t = ISC_LIST_HEAD(nsec_diff.tuples)) != NULL) {
- ISC_LIST_UNLINK(nsec_diff.tuples, t, link);
- dns_diff_appendminimal(&nsec_mindiff, &t);
- }
-
- update_log(log, zone, ISC_LOG_DEBUG(3),
- "signing rebuilt NSEC3 chain");
-
- /* Update RRSIG NSEC3s. */
- for (t = ISC_LIST_HEAD(nsec_mindiff.tuples);
- t != NULL;
- t = ISC_LIST_NEXT(t, link))
- {
- if (t->op == DNS_DIFFOP_DEL) {
- CHECK(delete_if(true_p, db, newver, &t->name,
- dns_rdatatype_rrsig,
- dns_rdatatype_nsec3,
- NULL, &sig_diff));
- } else if (t->op == DNS_DIFFOP_ADD) {
- CHECK(add_sigs(log, zone, db, newver, &t->name,
- dns_rdatatype_nsec3,
- &sig_diff, zone_keys, nkeys,
- inception, expire, check_ksk,
- keyset_kskonly));
- } else {
- INSIST(0);
- }
- }
-
- /* Record our changes for the journal. */
- while ((t = ISC_LIST_HEAD(sig_diff.tuples)) != NULL) {
- ISC_LIST_UNLINK(sig_diff.tuples, t, link);
- dns_diff_appendminimal(diff, &t);
- }
- while ((t = ISC_LIST_HEAD(nsec_mindiff.tuples)) != NULL) {
- ISC_LIST_UNLINK(nsec_mindiff.tuples, t, link);
- dns_diff_appendminimal(diff, &t);
- }
-
- INSIST(ISC_LIST_EMPTY(sig_diff.tuples));
- INSIST(ISC_LIST_EMPTY(nsec_diff.tuples));
- INSIST(ISC_LIST_EMPTY(nsec_mindiff.tuples));
-
- failure:
- dns_diff_clear(&sig_diff);
- dns_diff_clear(&nsec_diff);
- dns_diff_clear(&nsec_mindiff);
-
- dns_diff_clear(&affected);
- dns_diff_clear(&diffnames);
-
- for (i = 0; i < nkeys; i++)
- dst_key_free(&zone_keys[i]);
-
- return (result);
-}
-
-isc_uint32_t
-dns_update_soaserial(isc_uint32_t serial, dns_updatemethod_t method) {
- isc_stdtime_t now;
-
- if (method == dns_updatemethod_unixtime) {
- isc_stdtime_get(&now);
- if (now != 0 && isc_serial_gt(now, serial))
- return (now);
- }
-
- /* RFC1982 */
- serial = (serial + 1) & 0xFFFFFFFF;
- if (serial == 0)
- serial = 1;
-
- return (serial);
-}
diff --git a/contrib/bind9/lib/dns/validator.c b/contrib/bind9/lib/dns/validator.c
deleted file mode 100644
index 8cf7f665ec88..000000000000
--- a/contrib/bind9/lib/dns/validator.c
+++ /dev/null
@@ -1,3960 +0,0 @@
-/*
- * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2000-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-#include <config.h>
-
-#include <isc/base32.h>
-#include <isc/mem.h>
-#include <isc/print.h>
-#include <isc/sha2.h>
-#include <isc/string.h>
-#include <isc/task.h>
-#include <isc/util.h>
-
-#include <dns/db.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/rdataset.h>
-#include <dns/rdatatype.h>
-#include <dns/resolver.h>
-#include <dns/result.h>
-#include <dns/validator.h>
-#include <dns/view.h>
-
-/*! \file
- * \brief
- * Basic processing sequences.
- *
- * \li When called with rdataset and sigrdataset:
- * validator_start -> validate -> proveunsecure -> startfinddlvsep ->
- * dlv_validator_start -> validator_start -> validate -> proveunsecure
- *
- * validator_start -> validate -> nsecvalidate (secure wildcard answer)
- *
- * \li When called with rdataset, sigrdataset and with DNS_VALIDATOR_DLV:
- * validator_start -> startfinddlvsep -> dlv_validator_start ->
- * validator_start -> validate -> proveunsecure
- *
- * \li When called with rdataset:
- * validator_start -> proveunsecure -> startfinddlvsep ->
- * dlv_validator_start -> validator_start -> proveunsecure
- *
- * \li When called with rdataset and with DNS_VALIDATOR_DLV:
- * validator_start -> startfinddlvsep -> dlv_validator_start ->
- * validator_start -> proveunsecure
- *
- * \li When called without a rdataset:
- * validator_start -> nsecvalidate -> proveunsecure -> startfinddlvsep ->
- * dlv_validator_start -> validator_start -> nsecvalidate -> proveunsecure
- *
- * Note: there isn't a case for DNS_VALIDATOR_DLV here as we want nsecvalidate()
- * to always validate the authority section even when it does not contain
- * signatures.
- *
- * validator_start: determines what type of validation to do.
- * validate: attempts to perform a positive validation.
- * proveunsecure: attempts to prove the answer comes from a unsecure zone.
- * nsecvalidate: attempts to prove a negative response.
- * startfinddlvsep: starts the DLV record lookup.
- * dlv_validator_start: resets state and restarts the lookup using the
- * DLV RRset found by startfinddlvsep.
- */
-
-#define VALIDATOR_MAGIC ISC_MAGIC('V', 'a', 'l', '?')
-#define VALID_VALIDATOR(v) ISC_MAGIC_VALID(v, VALIDATOR_MAGIC)
-
-#define VALATTR_SHUTDOWN 0x0001 /*%< Shutting down. */
-#define VALATTR_CANCELED 0x0002 /*%< Canceled. */
-#define VALATTR_TRIEDVERIFY 0x0004 /*%< We have found a key and
- * have attempted a verify. */
-#define VALATTR_INSECURITY 0x0010 /*%< Attempting proveunsecure. */
-#define VALATTR_DLVTRIED 0x0020 /*%< Looked for a DLV record. */
-
-/*!
- * NSEC proofs to be looked for.
- */
-#define VALATTR_NEEDNOQNAME 0x00000100
-#define VALATTR_NEEDNOWILDCARD 0x00000200
-#define VALATTR_NEEDNODATA 0x00000400
-
-/*!
- * NSEC proofs that have been found.
- */
-#define VALATTR_FOUNDNOQNAME 0x00001000
-#define VALATTR_FOUNDNOWILDCARD 0x00002000
-#define VALATTR_FOUNDNODATA 0x00004000
-#define VALATTR_FOUNDCLOSEST 0x00008000
-
-/*
- *
- */
-#define VALATTR_FOUNDOPTOUT 0x00010000
-#define VALATTR_FOUNDUNKNOWN 0x00020000
-
-#define NEEDNODATA(val) ((val->attributes & VALATTR_NEEDNODATA) != 0)
-#define NEEDNOQNAME(val) ((val->attributes & VALATTR_NEEDNOQNAME) != 0)
-#define NEEDNOWILDCARD(val) ((val->attributes & VALATTR_NEEDNOWILDCARD) != 0)
-#define DLVTRIED(val) ((val->attributes & VALATTR_DLVTRIED) != 0)
-#define FOUNDNODATA(val) ((val->attributes & VALATTR_FOUNDNODATA) != 0)
-#define FOUNDNOQNAME(val) ((val->attributes & VALATTR_FOUNDNOQNAME) != 0)
-#define FOUNDNOWILDCARD(val) ((val->attributes & VALATTR_FOUNDNOWILDCARD) != 0)
-#define FOUNDCLOSEST(val) ((val->attributes & VALATTR_FOUNDCLOSEST) != 0)
-#define FOUNDOPTOUT(val) ((val->attributes & VALATTR_FOUNDOPTOUT) != 0)
-
-#define SHUTDOWN(v) (((v)->attributes & VALATTR_SHUTDOWN) != 0)
-#define CANCELED(v) (((v)->attributes & VALATTR_CANCELED) != 0)
-
-#define NEGATIVE(r) (((r)->attributes & DNS_RDATASETATTR_NEGATIVE) != 0)
-
-static void
-destroy(dns_validator_t *val);
-
-static isc_result_t
-get_dst_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo,
- dns_rdataset_t *rdataset);
-
-static isc_result_t
-validate(dns_validator_t *val, isc_boolean_t resume);
-
-static isc_result_t
-validatezonekey(dns_validator_t *val);
-
-static isc_result_t
-nsecvalidate(dns_validator_t *val, isc_boolean_t resume);
-
-static isc_result_t
-proveunsecure(dns_validator_t *val, isc_boolean_t have_ds,
- isc_boolean_t resume);
-
-static void
-validator_logv(dns_validator_t *val, isc_logcategory_t *category,
- isc_logmodule_t *module, int level, const char *fmt, va_list ap)
- ISC_FORMAT_PRINTF(5, 0);
-
-static void
-validator_log(void *val, int level, const char *fmt, ...)
- ISC_FORMAT_PRINTF(3, 4);
-
-static void
-validator_logcreate(dns_validator_t *val,
- dns_name_t *name, dns_rdatatype_t type,
- const char *caller, const char *operation);
-
-static isc_result_t
-dlv_validatezonekey(dns_validator_t *val);
-
-static void
-dlv_validator_start(dns_validator_t *val);
-
-static isc_result_t
-finddlvsep(dns_validator_t *val, isc_boolean_t resume);
-
-static isc_result_t
-startfinddlvsep(dns_validator_t *val, dns_name_t *unsecure);
-
-/*%
- * Mark the RRsets as a answer.
- */
-static inline void
-markanswer(dns_validator_t *val, const char *where) {
- validator_log(val, ISC_LOG_DEBUG(3), "marking as answer (%s)", where);
- if (val->event->rdataset != NULL)
- dns_rdataset_settrust(val->event->rdataset, dns_trust_answer);
- if (val->event->sigrdataset != NULL)
- dns_rdataset_settrust(val->event->sigrdataset,
- dns_trust_answer);
-}
-
-static inline void
-marksecure(dns_validatorevent_t *event) {
- dns_rdataset_settrust(event->rdataset, dns_trust_secure);
- if (event->sigrdataset != NULL)
- dns_rdataset_settrust(event->sigrdataset, dns_trust_secure);
- event->secure = ISC_TRUE;
-}
-
-static void
-validator_done(dns_validator_t *val, isc_result_t result) {
- isc_task_t *task;
-
- if (val->event == NULL)
- return;
-
- /*
- * Caller must be holding the lock.
- */
-
- val->event->result = result;
- task = val->event->ev_sender;
- val->event->ev_sender = val;
- val->event->ev_type = DNS_EVENT_VALIDATORDONE;
- val->event->ev_action = val->action;
- val->event->ev_arg = val->arg;
- isc_task_sendanddetach(&task, (isc_event_t **)&val->event);
-}
-
-static inline isc_boolean_t
-exit_check(dns_validator_t *val) {
- /*
- * Caller must be holding the lock.
- */
- if (!SHUTDOWN(val))
- return (ISC_FALSE);
-
- INSIST(val->event == NULL);
-
- if (val->fetch != NULL || val->subvalidator != NULL)
- return (ISC_FALSE);
-
- return (ISC_TRUE);
-}
-
-/*
- * Check that we have atleast one supported algorithm in the DLV RRset.
- */
-static inline isc_boolean_t
-dlv_algorithm_supported(dns_validator_t *val) {
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdata_dlv_t dlv;
- isc_result_t result;
-
- for (result = dns_rdataset_first(&val->dlv);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(&val->dlv)) {
- dns_rdata_reset(&rdata);
- dns_rdataset_current(&val->dlv, &rdata);
- result = dns_rdata_tostruct(&rdata, &dlv, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
-
- if (!dns_resolver_algorithm_supported(val->view->resolver,
- val->event->name,
- 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);
- }
- return (ISC_FALSE);
-}
-
-/*%
- * Look in the NSEC record returned from a DS query to see if there is
- * a NS RRset at this name. If it is found we are at a delegation point.
- */
-static isc_boolean_t
-isdelegation(dns_name_t *name, dns_rdataset_t *rdataset,
- isc_result_t dbresult)
-{
- dns_fixedname_t fixed;
- dns_label_t hashlabel;
- dns_name_t nsec3name;
- dns_rdata_nsec3_t nsec3;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdataset_t set;
- int order;
- int scope;
- isc_boolean_t found;
- isc_buffer_t buffer;
- isc_result_t result;
- unsigned char hash[NSEC3_MAX_HASH_LENGTH];
- unsigned char owner[NSEC3_MAX_HASH_LENGTH];
- unsigned int length;
-
- REQUIRE(dbresult == DNS_R_NXRRSET || dbresult == DNS_R_NCACHENXRRSET);
-
- dns_rdataset_init(&set);
- if (dbresult == DNS_R_NXRRSET)
- dns_rdataset_clone(rdataset, &set);
- else {
- result = dns_ncache_getrdataset(rdataset, name,
- dns_rdatatype_nsec, &set);
- if (result == ISC_R_NOTFOUND)
- goto trynsec3;
- if (result != ISC_R_SUCCESS)
- return (ISC_FALSE);
- }
-
- INSIST(set.type == dns_rdatatype_nsec);
-
- found = ISC_FALSE;
- result = dns_rdataset_first(&set);
- if (result == ISC_R_SUCCESS) {
- dns_rdataset_current(&set, &rdata);
- found = dns_nsec_typepresent(&rdata, dns_rdatatype_ns);
- dns_rdata_reset(&rdata);
- }
- dns_rdataset_disassociate(&set);
- return (found);
-
- trynsec3:
- /*
- * Iterate over the ncache entry.
- */
- found = ISC_FALSE;
- dns_name_init(&nsec3name, NULL);
- dns_fixedname_init(&fixed);
- dns_name_downcase(name, dns_fixedname_name(&fixed), NULL);
- name = dns_fixedname_name(&fixed);
- for (result = dns_rdataset_first(rdataset);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(rdataset))
- {
- dns_ncache_current(rdataset, &nsec3name, &set);
- if (set.type != dns_rdatatype_nsec3) {
- dns_rdataset_disassociate(&set);
- continue;
- }
- dns_name_getlabel(&nsec3name, 0, &hashlabel);
- isc_region_consume(&hashlabel, 1);
- isc_buffer_init(&buffer, owner, sizeof(owner));
- result = isc_base32hex_decoderegion(&hashlabel, &buffer);
- if (result != ISC_R_SUCCESS) {
- dns_rdataset_disassociate(&set);
- continue;
- }
- for (result = dns_rdataset_first(&set);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(&set))
- {
- dns_rdata_reset(&rdata);
- dns_rdataset_current(&set, &rdata);
- (void)dns_rdata_tostruct(&rdata, &nsec3, NULL);
- if (nsec3.hash != 1)
- continue;
- length = isc_iterated_hash(hash, nsec3.hash,
- nsec3.iterations, nsec3.salt,
- nsec3.salt_length,
- name->ndata, name->length);
- if (length != isc_buffer_usedlength(&buffer))
- continue;
- order = memcmp(hash, owner, length);
- if (order == 0) {
- found = dns_nsec3_typepresent(&rdata,
- dns_rdatatype_ns);
- dns_rdataset_disassociate(&set);
- return (found);
- }
- if ((nsec3.flags & DNS_NSEC3FLAG_OPTOUT) == 0)
- continue;
- /*
- * Does this optout span cover the name?
- */
- scope = memcmp(owner, nsec3.next, nsec3.next_length);
- if ((scope < 0 && order > 0 &&
- memcmp(hash, nsec3.next, length) < 0) ||
- (scope >= 0 && (order > 0 ||
- memcmp(hash, nsec3.next, length) < 0)))
- {
- dns_rdataset_disassociate(&set);
- return (ISC_TRUE);
- }
- }
- dns_rdataset_disassociate(&set);
- }
- return (found);
-}
-
-/*%
- * We have been asked to look for a key.
- * If found resume the validation process.
- * If not found fail the validation process.
- */
-static void
-fetch_callback_validator(isc_task_t *task, isc_event_t *event) {
- dns_fetchevent_t *devent;
- dns_validator_t *val;
- dns_rdataset_t *rdataset;
- isc_boolean_t want_destroy;
- isc_result_t result;
- isc_result_t eresult;
- isc_result_t saved_result;
- dns_fetch_t *fetch;
-
- UNUSED(task);
- INSIST(event->ev_type == DNS_EVENT_FETCHDONE);
- devent = (dns_fetchevent_t *)event;
- val = devent->ev_arg;
- rdataset = &val->frdataset;
- 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);
- if (dns_rdataset_isassociated(&val->fsigrdataset))
- dns_rdataset_disassociate(&val->fsigrdataset);
- isc_event_free(&event);
-
- INSIST(val->event != NULL);
-
- validator_log(val, ISC_LOG_DEBUG(3), "in fetch_callback_validator");
- LOCK(&val->lock);
- fetch = val->fetch;
- val->fetch = NULL;
- if (CANCELED(val)) {
- validator_done(val, ISC_R_CANCELED);
- } else if (eresult == ISC_R_SUCCESS) {
- validator_log(val, ISC_LOG_DEBUG(3),
- "keyset with trust %s",
- dns_trust_totext(rdataset->trust));
- /*
- * Only extract the dst key if the keyset is secure.
- */
- if (rdataset->trust >= dns_trust_secure) {
- result = get_dst_key(val, val->siginfo, rdataset);
- if (result == ISC_R_SUCCESS)
- val->keyset = &val->frdataset;
- }
- result = validate(val, ISC_TRUE);
- if (result == DNS_R_NOVALIDSIG &&
- (val->attributes & VALATTR_TRIEDVERIFY) == 0)
- {
- saved_result = result;
- validator_log(val, ISC_LOG_DEBUG(3),
- "falling back to insecurity proof");
- val->attributes |= VALATTR_INSECURITY;
- result = proveunsecure(val, ISC_FALSE, ISC_FALSE);
- if (result == DNS_R_NOTINSECURE)
- result = saved_result;
- }
- if (result != DNS_R_WAIT)
- validator_done(val, result);
- } else {
- validator_log(val, ISC_LOG_DEBUG(3),
- "fetch_callback_validator: got %s",
- isc_result_totext(eresult));
- if (eresult == ISC_R_CANCELED)
- validator_done(val, eresult);
- else
- validator_done(val, DNS_R_BROKENCHAIN);
- }
- want_destroy = exit_check(val);
- UNLOCK(&val->lock);
- if (fetch != NULL)
- dns_resolver_destroyfetch(&fetch);
- if (want_destroy)
- destroy(val);
-}
-
-/*%
- * We were asked to look for a DS record as part of following a key chain
- * upwards. If found resume the validation process. If not found fail the
- * validation process.
- */
-static void
-dsfetched(isc_task_t *task, isc_event_t *event) {
- dns_fetchevent_t *devent;
- dns_validator_t *val;
- dns_rdataset_t *rdataset;
- isc_boolean_t want_destroy;
- isc_result_t result;
- isc_result_t eresult;
- dns_fetch_t *fetch;
-
- UNUSED(task);
- INSIST(event->ev_type == DNS_EVENT_FETCHDONE);
- devent = (dns_fetchevent_t *)event;
- val = devent->ev_arg;
- rdataset = &val->frdataset;
- 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);
- if (dns_rdataset_isassociated(&val->fsigrdataset))
- dns_rdataset_disassociate(&val->fsigrdataset);
- isc_event_free(&event);
-
- INSIST(val->event != NULL);
-
- validator_log(val, ISC_LOG_DEBUG(3), "in dsfetched");
- LOCK(&val->lock);
- fetch = val->fetch;
- val->fetch = NULL;
- if (CANCELED(val)) {
- validator_done(val, ISC_R_CANCELED);
- } else if (eresult == ISC_R_SUCCESS) {
- validator_log(val, ISC_LOG_DEBUG(3),
- "dsset with trust %s",
- dns_trust_totext(rdataset->trust));
- val->dsset = &val->frdataset;
- result = validatezonekey(val);
- if (result != DNS_R_WAIT)
- validator_done(val, result);
- } else if (eresult == DNS_R_CNAME ||
- eresult == DNS_R_NXRRSET ||
- eresult == DNS_R_NCACHENXRRSET ||
- eresult == DNS_R_SERVFAIL) /* RFC 1034 parent? */
- {
- validator_log(val, ISC_LOG_DEBUG(3),
- "falling back to insecurity proof (%s)",
- dns_result_totext(eresult));
- val->attributes |= VALATTR_INSECURITY;
- result = proveunsecure(val, ISC_FALSE, ISC_FALSE);
- if (result != DNS_R_WAIT)
- validator_done(val, result);
- } else {
- validator_log(val, ISC_LOG_DEBUG(3),
- "dsfetched: got %s",
- isc_result_totext(eresult));
- if (eresult == ISC_R_CANCELED)
- validator_done(val, eresult);
- else
- validator_done(val, DNS_R_BROKENCHAIN);
- }
- want_destroy = exit_check(val);
- UNLOCK(&val->lock);
- if (fetch != NULL)
- dns_resolver_destroyfetch(&fetch);
- if (want_destroy)
- destroy(val);
-}
-
-/*%
- * We were asked to look for the DS record as part of proving that a
- * name is unsecure.
- *
- * If the DS record doesn't exist and the query name corresponds to
- * a delegation point we are transitioning from a secure zone to a
- * unsecure zone.
- *
- * If the DS record exists it will be secure. We can continue looking
- * for the break point in the chain of trust.
- */
-static void
-dsfetched2(isc_task_t *task, isc_event_t *event) {
- dns_fetchevent_t *devent;
- dns_validator_t *val;
- dns_name_t *tname;
- isc_boolean_t want_destroy;
- isc_result_t result;
- isc_result_t eresult;
- dns_fetch_t *fetch;
-
- UNUSED(task);
- INSIST(event->ev_type == DNS_EVENT_FETCHDONE);
- devent = (dns_fetchevent_t *)event;
- val = devent->ev_arg;
- 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);
- if (dns_rdataset_isassociated(&val->fsigrdataset))
- dns_rdataset_disassociate(&val->fsigrdataset);
-
- INSIST(val->event != NULL);
-
- validator_log(val, ISC_LOG_DEBUG(3), "in dsfetched2: %s",
- dns_result_totext(eresult));
- LOCK(&val->lock);
- fetch = val->fetch;
- val->fetch = NULL;
- if (CANCELED(val)) {
- validator_done(val, ISC_R_CANCELED);
- } else if (eresult == DNS_R_CNAME ||
- eresult == DNS_R_NXRRSET ||
- eresult == DNS_R_NCACHENXRRSET)
- {
- /*
- * There is no DS. If this is a delegation, we're done.
- */
- tname = dns_fixedname_name(&devent->foundname);
- if (eresult != DNS_R_CNAME &&
- isdelegation(tname, &val->frdataset, eresult)) {
- if (val->mustbesecure) {
- validator_log(val, ISC_LOG_WARNING,
- "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");
- validator_done(val, ISC_R_SUCCESS);
- } else {
- result = startfinddlvsep(val, tname);
- if (result != DNS_R_WAIT)
- validator_done(val, result);
- }
- } else {
- result = proveunsecure(val, ISC_FALSE, ISC_TRUE);
- if (result != DNS_R_WAIT)
- validator_done(val, result);
- }
- } else if (eresult == ISC_R_SUCCESS ||
- eresult == DNS_R_NXDOMAIN ||
- eresult == DNS_R_NCACHENXDOMAIN)
- {
- /*
- * There is a DS which may or may not be a zone cut.
- * In either case we are still in a secure zone resume
- * validation.
- */
- result = proveunsecure(val, ISC_TF(eresult == ISC_R_SUCCESS),
- ISC_TRUE);
- if (result != DNS_R_WAIT)
- validator_done(val, result);
- } else {
- if (eresult == ISC_R_CANCELED)
- validator_done(val, eresult);
- else
- validator_done(val, DNS_R_NOVALIDDS);
- }
- isc_event_free(&event);
- want_destroy = exit_check(val);
- UNLOCK(&val->lock);
- if (fetch != NULL)
- dns_resolver_destroyfetch(&fetch);
- if (want_destroy)
- destroy(val);
-}
-
-/*%
- * Callback from when a DNSKEY RRset has been validated.
- *
- * Resumes the stalled validation process.
- */
-static void
-keyvalidated(isc_task_t *task, isc_event_t *event) {
- dns_validatorevent_t *devent;
- dns_validator_t *val;
- isc_boolean_t want_destroy;
- isc_result_t result;
- isc_result_t eresult;
- isc_result_t saved_result;
-
- UNUSED(task);
- INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
-
- devent = (dns_validatorevent_t *)event;
- val = devent->ev_arg;
- eresult = devent->result;
-
- isc_event_free(&event);
- dns_validator_destroy(&val->subvalidator);
-
- INSIST(val->event != NULL);
-
- validator_log(val, ISC_LOG_DEBUG(3), "in keyvalidated");
- LOCK(&val->lock);
- if (CANCELED(val)) {
- validator_done(val, ISC_R_CANCELED);
- } else if (eresult == ISC_R_SUCCESS) {
- validator_log(val, ISC_LOG_DEBUG(3),
- "keyset with trust %s",
- dns_trust_totext(val->frdataset.trust));
- /*
- * Only extract the dst key if the keyset is secure.
- */
- if (val->frdataset.trust >= dns_trust_secure)
- (void) get_dst_key(val, val->siginfo, &val->frdataset);
- result = validate(val, ISC_TRUE);
- if (result == DNS_R_NOVALIDSIG &&
- (val->attributes & VALATTR_TRIEDVERIFY) == 0)
- {
- saved_result = result;
- validator_log(val, ISC_LOG_DEBUG(3),
- "falling back to insecurity proof");
- val->attributes |= VALATTR_INSECURITY;
- result = proveunsecure(val, ISC_FALSE, ISC_FALSE);
- if (result == DNS_R_NOTINSECURE)
- result = saved_result;
- }
- if (result != DNS_R_WAIT)
- validator_done(val, result);
- } else {
- if (eresult != DNS_R_BROKENCHAIN) {
- if (dns_rdataset_isassociated(&val->frdataset))
- dns_rdataset_expire(&val->frdataset);
- if (dns_rdataset_isassociated(&val->fsigrdataset))
- dns_rdataset_expire(&val->fsigrdataset);
- }
- validator_log(val, ISC_LOG_DEBUG(3),
- "keyvalidated: got %s",
- isc_result_totext(eresult));
- validator_done(val, DNS_R_BROKENCHAIN);
- }
- want_destroy = exit_check(val);
- UNLOCK(&val->lock);
- if (want_destroy)
- destroy(val);
-}
-
-/*%
- * Callback when the DS record has been validated.
- *
- * Resumes validation of the zone key or the unsecure zone proof.
- */
-static void
-dsvalidated(isc_task_t *task, isc_event_t *event) {
- dns_validatorevent_t *devent;
- dns_validator_t *val;
- isc_boolean_t want_destroy;
- isc_result_t result;
- isc_result_t eresult;
-
- UNUSED(task);
- INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
-
- devent = (dns_validatorevent_t *)event;
- val = devent->ev_arg;
- eresult = devent->result;
-
- isc_event_free(&event);
- dns_validator_destroy(&val->subvalidator);
-
- INSIST(val->event != NULL);
-
- validator_log(val, ISC_LOG_DEBUG(3), "in dsvalidated");
- LOCK(&val->lock);
- if (CANCELED(val)) {
- validator_done(val, ISC_R_CANCELED);
- } else if (eresult == ISC_R_SUCCESS) {
- isc_boolean_t have_dsset;
- dns_name_t *name;
- validator_log(val, ISC_LOG_DEBUG(3),
- "%s with trust %s",
- val->frdataset.type == dns_rdatatype_ds ?
- "dsset" : "ds non-existance",
- dns_trust_totext(val->frdataset.trust));
- have_dsset = ISC_TF(val->frdataset.type == dns_rdatatype_ds);
- name = dns_fixedname_name(&val->fname);
- if ((val->attributes & VALATTR_INSECURITY) != 0 &&
- val->frdataset.covers == dns_rdatatype_ds &&
- NEGATIVE(&val->frdataset) &&
- isdelegation(name, &val->frdataset, DNS_R_NCACHENXRRSET)) {
- if (val->mustbesecure) {
- validator_log(val, ISC_LOG_WARNING,
- "must be secure failure, no DS "
- "and this is a delegation");
- result = DNS_R_MUSTBESECURE;
- } else if (val->view->dlv == NULL || DLVTRIED(val)) {
- markanswer(val, "dsvalidated");
- result = ISC_R_SUCCESS;;
- } else
- result = startfinddlvsep(val, name);
- } else if ((val->attributes & VALATTR_INSECURITY) != 0) {
- result = proveunsecure(val, have_dsset, ISC_TRUE);
- } else
- result = validatezonekey(val);
- if (result != DNS_R_WAIT)
- validator_done(val, result);
- } else {
- if (eresult != DNS_R_BROKENCHAIN) {
- if (dns_rdataset_isassociated(&val->frdataset))
- dns_rdataset_expire(&val->frdataset);
- if (dns_rdataset_isassociated(&val->fsigrdataset))
- dns_rdataset_expire(&val->fsigrdataset);
- }
- validator_log(val, ISC_LOG_DEBUG(3),
- "dsvalidated: got %s",
- isc_result_totext(eresult));
- validator_done(val, DNS_R_BROKENCHAIN);
- }
- want_destroy = exit_check(val);
- UNLOCK(&val->lock);
- if (want_destroy)
- destroy(val);
-}
-
-/*%
- * Callback when the CNAME record has been validated.
- *
- * Resumes validation of the unsecure zone proof.
- */
-static void
-cnamevalidated(isc_task_t *task, isc_event_t *event) {
- dns_validatorevent_t *devent;
- dns_validator_t *val;
- isc_boolean_t want_destroy;
- isc_result_t result;
- isc_result_t eresult;
-
- UNUSED(task);
- INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
-
- devent = (dns_validatorevent_t *)event;
- val = devent->ev_arg;
- eresult = devent->result;
-
- isc_event_free(&event);
- dns_validator_destroy(&val->subvalidator);
-
- INSIST(val->event != NULL);
- INSIST((val->attributes & VALATTR_INSECURITY) != 0);
-
- validator_log(val, ISC_LOG_DEBUG(3), "in cnamevalidated");
- LOCK(&val->lock);
- if (CANCELED(val)) {
- validator_done(val, ISC_R_CANCELED);
- } else if (eresult == ISC_R_SUCCESS) {
- validator_log(val, ISC_LOG_DEBUG(3), "cname with trust %s",
- dns_trust_totext(val->frdataset.trust));
- result = proveunsecure(val, ISC_FALSE, ISC_TRUE);
- if (result != DNS_R_WAIT)
- validator_done(val, result);
- } else {
- if (eresult != DNS_R_BROKENCHAIN) {
- if (dns_rdataset_isassociated(&val->frdataset))
- dns_rdataset_expire(&val->frdataset);
- if (dns_rdataset_isassociated(&val->fsigrdataset))
- dns_rdataset_expire(&val->fsigrdataset);
- }
- validator_log(val, ISC_LOG_DEBUG(3),
- "cnamevalidated: got %s",
- isc_result_totext(eresult));
- validator_done(val, DNS_R_BROKENCHAIN);
- }
- want_destroy = exit_check(val);
- UNLOCK(&val->lock);
- if (want_destroy)
- destroy(val);
-}
-
-/*%
- * Callback for when NSEC records have been validated.
- *
- * Looks for NOQNAME, NODATA and OPTOUT proofs.
- *
- * Resumes nsecvalidate.
- */
-static void
-authvalidated(isc_task_t *task, isc_event_t *event) {
- dns_validatorevent_t *devent;
- dns_validator_t *val;
- dns_rdataset_t *rdataset;
- isc_boolean_t want_destroy;
- isc_result_t result;
- isc_boolean_t exists, data;
-
- UNUSED(task);
- INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
-
- devent = (dns_validatorevent_t *)event;
- rdataset = devent->rdataset;
- val = devent->ev_arg;
- result = devent->result;
- dns_validator_destroy(&val->subvalidator);
-
- INSIST(val->event != NULL);
-
- validator_log(val, ISC_LOG_DEBUG(3), "in authvalidated");
- LOCK(&val->lock);
- if (CANCELED(val)) {
- validator_done(val, ISC_R_CANCELED);
- } else if (result != ISC_R_SUCCESS) {
- validator_log(val, ISC_LOG_DEBUG(3),
- "authvalidated: got %s",
- isc_result_totext(result));
- if (result == DNS_R_BROKENCHAIN)
- val->authfail++;
- if (result == ISC_R_CANCELED)
- validator_done(val, result);
- else {
- result = nsecvalidate(val, ISC_TRUE);
- if (result != DNS_R_WAIT)
- validator_done(val, result);
- }
- } else {
- dns_name_t **proofs = val->event->proofs;
- dns_name_t *wild = dns_fixedname_name(&val->wild);
-
- if (rdataset->trust == dns_trust_secure)
- val->seensig = ISC_TRUE;
-
- if (rdataset->type == dns_rdatatype_nsec &&
- rdataset->trust == dns_trust_secure &&
- (NEEDNODATA(val) || NEEDNOQNAME(val)) &&
- !FOUNDNODATA(val) && !FOUNDNOQNAME(val) &&
- dns_nsec_noexistnodata(val->event->type, val->event->name,
- devent->name, rdataset, &exists,
- &data, wild, validator_log, val)
- == ISC_R_SUCCESS)
- {
- if (exists && !data) {
- val->attributes |= VALATTR_FOUNDNODATA;
- if (NEEDNODATA(val))
- proofs[DNS_VALIDATOR_NODATAPROOF] =
- devent->name;
- }
- if (!exists) {
- val->attributes |= VALATTR_FOUNDNOQNAME;
- val->attributes |= VALATTR_FOUNDCLOSEST;
- /*
- * The NSEC noqname proof also contains
- * the closest encloser.
-
- */
- if (NEEDNOQNAME(val))
- proofs[DNS_VALIDATOR_NOQNAMEPROOF] =
- devent->name;
- }
- }
-
- result = nsecvalidate(val, ISC_TRUE);
- if (result != DNS_R_WAIT)
- validator_done(val, result);
- }
- want_destroy = exit_check(val);
- UNLOCK(&val->lock);
- if (want_destroy)
- destroy(val);
-
- /*
- * Free stuff from the event.
- */
- isc_event_free(&event);
-}
-
-/*%
- * Looks for the requested name and type in the view (zones and cache).
- *
- * When looking for a DLV record also checks to make sure the NSEC record
- * returns covers the query name as part of aggressive negative caching.
- *
- * Returns:
- * \li ISC_R_SUCCESS
- * \li ISC_R_NOTFOUND
- * \li DNS_R_NCACHENXDOMAIN
- * \li DNS_R_NCACHENXRRSET
- * \li DNS_R_NXRRSET
- * \li DNS_R_NXDOMAIN
- * \li DNS_R_BROKENCHAIN
- */
-static inline isc_result_t
-view_find(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) {
- dns_fixedname_t fixedname;
- dns_name_t *foundname;
- dns_rdata_nsec_t nsec;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- isc_result_t result;
- unsigned int options;
- isc_time_t now;
- char buf1[DNS_NAME_FORMATSIZE];
- char buf2[DNS_NAME_FORMATSIZE];
- char buf3[DNS_NAME_FORMATSIZE];
- char namebuf[DNS_NAME_FORMATSIZE];
- char typebuf[DNS_RDATATYPE_FORMATSIZE];
-
- if (dns_rdataset_isassociated(&val->frdataset))
- dns_rdataset_disassociate(&val->frdataset);
- if (dns_rdataset_isassociated(&val->fsigrdataset))
- dns_rdataset_disassociate(&val->fsigrdataset);
-
- if (isc_time_now(&now) == ISC_R_SUCCESS &&
- dns_resolver_getbadcache(val->view->resolver, name, type, &now)) {
-
- dns_name_format(name, namebuf, sizeof(namebuf));
- dns_rdatatype_format(type, typebuf, sizeof(typebuf));
- validator_log(val, ISC_LOG_INFO, "bad cache hit (%s/%s)",
- namebuf, typebuf);
- return (DNS_R_BROKENCHAIN);
- }
-
- options = DNS_DBFIND_PENDINGOK;
- if (type == dns_rdatatype_dlv)
- options |= DNS_DBFIND_COVERINGNSEC;
- dns_fixedname_init(&fixedname);
- foundname = dns_fixedname_name(&fixedname);
- result = dns_view_find(val->view, name, type, 0, options,
- ISC_FALSE, NULL, NULL, foundname,
- &val->frdataset, &val->fsigrdataset);
-
- if (result == DNS_R_NXDOMAIN) {
- if (dns_rdataset_isassociated(&val->frdataset))
- dns_rdataset_disassociate(&val->frdataset);
- if (dns_rdataset_isassociated(&val->fsigrdataset))
- dns_rdataset_disassociate(&val->fsigrdataset);
- } else if (result == DNS_R_COVERINGNSEC) {
- validator_log(val, ISC_LOG_DEBUG(3), "DNS_R_COVERINGNSEC");
- /*
- * Check if the returned NSEC covers the name.
- */
- INSIST(type == dns_rdatatype_dlv);
- if (val->frdataset.trust != dns_trust_secure) {
- validator_log(val, ISC_LOG_DEBUG(3),
- "covering nsec: trust %s",
- dns_trust_totext(val->frdataset.trust));
- goto notfound;
- }
- result = dns_rdataset_first(&val->frdataset);
- if (result != ISC_R_SUCCESS)
- goto notfound;
- dns_rdataset_current(&val->frdataset, &rdata);
- if (dns_nsec_typepresent(&rdata, dns_rdatatype_ns) &&
- !dns_nsec_typepresent(&rdata, dns_rdatatype_soa)) {
- /* Parent NSEC record. */
- if (dns_name_issubdomain(name, foundname)) {
- validator_log(val, ISC_LOG_DEBUG(3),
- "covering nsec: for parent");
- goto notfound;
- }
- }
- result = dns_rdata_tostruct(&rdata, &nsec, NULL);
- if (result != ISC_R_SUCCESS)
- goto notfound;
- if (dns_name_compare(foundname, &nsec.next) >= 0) {
- /* End of zone chain. */
- if (!dns_name_issubdomain(name, &nsec.next)) {
- /*
- * XXXMPA We could look for a parent NSEC
- * at nsec.next and if found retest with
- * this NSEC.
- */
- dns_rdata_freestruct(&nsec);
- validator_log(val, ISC_LOG_DEBUG(3),
- "covering nsec: not in zone");
- goto notfound;
- }
- } else if (dns_name_compare(name, &nsec.next) >= 0) {
- /*
- * XXXMPA We could check if this NSEC is at a zone
- * apex and if the qname is not below it and look for
- * a parent NSEC with the same name. This requires
- * that we can cache both NSEC records which we
- * currently don't support.
- */
- dns_rdata_freestruct(&nsec);
- validator_log(val, ISC_LOG_DEBUG(3),
- "covering nsec: not in range");
- goto notfound;
- }
- if (isc_log_wouldlog(dns_lctx,ISC_LOG_DEBUG(3))) {
- dns_name_format(name, buf1, sizeof buf1);
- dns_name_format(foundname, buf2, sizeof buf2);
- dns_name_format(&nsec.next, buf3, sizeof buf3);
- validator_log(val, ISC_LOG_DEBUG(3),
- "covering nsec found: '%s' '%s' '%s'",
- buf1, buf2, buf3);
- }
- if (dns_rdataset_isassociated(&val->frdataset))
- dns_rdataset_disassociate(&val->frdataset);
- if (dns_rdataset_isassociated(&val->fsigrdataset))
- dns_rdataset_disassociate(&val->fsigrdataset);
- dns_rdata_freestruct(&nsec);
- result = DNS_R_NCACHENXDOMAIN;
- } else if (result != ISC_R_SUCCESS &&
- result != DNS_R_NCACHENXDOMAIN &&
- result != DNS_R_NCACHENXRRSET &&
- result != DNS_R_EMPTYNAME &&
- result != DNS_R_NXRRSET &&
- result != ISC_R_NOTFOUND) {
- goto notfound;
- }
- return (result);
-
- notfound:
- if (dns_rdataset_isassociated(&val->frdataset))
- dns_rdataset_disassociate(&val->frdataset);
- if (dns_rdataset_isassociated(&val->fsigrdataset))
- dns_rdataset_disassociate(&val->fsigrdataset);
- return (ISC_R_NOTFOUND);
-}
-
-/*%
- * Checks to make sure we are not going to loop. As we use a SHARED fetch
- * the validation process will stall if looping was to occur.
- */
-static inline isc_boolean_t
-check_deadlock(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,
- dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
-{
- dns_validator_t *parent;
-
- for (parent = val; parent != NULL; parent = parent->parent) {
- if (parent->event != NULL &&
- parent->event->type == type &&
- dns_name_equal(parent->event->name, name) &&
- /*
- * As NSEC3 records are meta data you sometimes
- * need to prove a NSEC3 record which says that
- * itself doesn't exist.
- */
- (parent->event->type != dns_rdatatype_nsec3 ||
- rdataset == NULL || sigrdataset == NULL ||
- parent->event->message == NULL ||
- parent->event->rdataset != NULL ||
- parent->event->sigrdataset != NULL))
- {
- validator_log(val, ISC_LOG_DEBUG(3),
- "continuing validation would lead to "
- "deadlock: aborting validation");
- return (ISC_TRUE);
- }
- }
- return (ISC_FALSE);
-}
-
-/*%
- * Start a fetch for the requested name and type.
- */
-static inline isc_result_t
-create_fetch(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,
- isc_taskaction_t callback, const char *caller)
-{
- if (dns_rdataset_isassociated(&val->frdataset))
- dns_rdataset_disassociate(&val->frdataset);
- if (dns_rdataset_isassociated(&val->fsigrdataset))
- dns_rdataset_disassociate(&val->fsigrdataset);
-
- 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,
- NULL, NULL, NULL, 0,
- val->event->ev_sender,
- callback, val,
- &val->frdataset,
- &val->fsigrdataset,
- &val->fetch));
-}
-
-/*%
- * Start a subvalidation process.
- */
-static inline isc_result_t
-create_validator(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,
- dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
- isc_taskaction_t action, const char *caller)
-{
- isc_result_t result;
-
- 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,
- rdataset, sigrdataset, NULL, 0,
- val->task, action, val,
- &val->subvalidator);
- if (result == ISC_R_SUCCESS) {
- val->subvalidator->parent = val;
- val->subvalidator->depth = val->depth + 1;
- }
- return (result);
-}
-
-/*%
- * Try to find a key that could have signed 'siginfo' among those
- * in 'rdataset'. If found, build a dst_key_t for it and point
- * val->key at it.
- *
- * If val->key is non-NULL, this returns the next matching key.
- */
-static isc_result_t
-get_dst_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo,
- dns_rdataset_t *rdataset)
-{
- isc_result_t result;
- isc_buffer_t b;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dst_key_t *oldkey = val->key;
- isc_boolean_t foundold;
-
- if (oldkey == NULL)
- foundold = ISC_TRUE;
- else {
- foundold = ISC_FALSE;
- val->key = NULL;
- }
-
- result = dns_rdataset_first(rdataset);
- if (result != ISC_R_SUCCESS)
- goto failure;
- do {
- dns_rdataset_current(rdataset, &rdata);
-
- isc_buffer_init(&b, rdata.data, rdata.length);
- isc_buffer_add(&b, rdata.length);
- INSIST(val->key == NULL);
- result = dst_key_fromdns(&siginfo->signer, rdata.rdclass, &b,
- val->view->mctx, &val->key);
- if (result != ISC_R_SUCCESS)
- goto failure;
- if (siginfo->algorithm ==
- (dns_secalg_t)dst_key_alg(val->key) &&
- siginfo->keyid ==
- (dns_keytag_t)dst_key_id(val->key) &&
- dst_key_iszonekey(val->key))
- {
- if (foundold)
- /*
- * This is the key we're looking for.
- */
- return (ISC_R_SUCCESS);
- else if (dst_key_compare(oldkey, val->key) == ISC_TRUE)
- {
- foundold = ISC_TRUE;
- dst_key_free(&oldkey);
- }
- }
- dst_key_free(&val->key);
- dns_rdata_reset(&rdata);
- result = dns_rdataset_next(rdataset);
- } while (result == ISC_R_SUCCESS);
- if (result == ISC_R_NOMORE)
- result = ISC_R_NOTFOUND;
-
- failure:
- if (oldkey != NULL)
- dst_key_free(&oldkey);
-
- return (result);
-}
-
-/*%
- * Get the key that generated this signature.
- */
-static isc_result_t
-get_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo) {
- isc_result_t result;
- unsigned int nlabels;
- int order;
- dns_namereln_t namereln;
-
- /*
- * Is the signer name appropriate for this signature?
- *
- * The signer name must be at the same level as the owner name
- * or closer to the DNS root.
- */
- namereln = dns_name_fullcompare(val->event->name, &siginfo->signer,
- &order, &nlabels);
- if (namereln != dns_namereln_subdomain &&
- namereln != dns_namereln_equal)
- return (DNS_R_CONTINUE);
-
- if (namereln == dns_namereln_equal) {
- /*
- * If this is a self-signed keyset, it must not be a zone key
- * (since get_key is not called from validatezonekey).
- */
- if (val->event->rdataset->type == dns_rdatatype_dnskey)
- return (DNS_R_CONTINUE);
-
- /*
- * Records appearing in the parent zone at delegation
- * points cannot be self-signed.
- */
- if (dns_rdatatype_atparent(val->event->rdataset->type))
- return (DNS_R_CONTINUE);
- } else {
- /*
- * SOA and NS RRsets can only be signed by a key with
- * the same name.
- */
- if (val->event->rdataset->type == dns_rdatatype_soa ||
- val->event->rdataset->type == dns_rdatatype_ns) {
- const char *typename;
-
- if (val->event->rdataset->type == dns_rdatatype_soa)
- typename = "SOA";
- else
- typename = "NS";
- validator_log(val, ISC_LOG_DEBUG(3),
- "%s signer mismatch", typename);
- return (DNS_R_CONTINUE);
- }
- }
-
- /*
- * Do we know about this key?
- */
- result = view_find(val, &siginfo->signer, dns_rdatatype_dnskey);
- if (result == ISC_R_SUCCESS) {
- /*
- * We have an rrset for the given keyname.
- */
- val->keyset = &val->frdataset;
- if ((DNS_TRUST_PENDING(val->frdataset.trust) ||
- DNS_TRUST_ANSWER(val->frdataset.trust)) &&
- dns_rdataset_isassociated(&val->fsigrdataset))
- {
- /*
- * We know the key but haven't validated it yet or
- * we have a key of trust answer but a DS/DLV
- * record for the zone may have been added.
- */
- result = create_validator(val, &siginfo->signer,
- dns_rdatatype_dnskey,
- &val->frdataset,
- &val->fsigrdataset,
- keyvalidated,
- "get_key");
- if (result != ISC_R_SUCCESS)
- return (result);
- return (DNS_R_WAIT);
- } else if (DNS_TRUST_PENDING(val->frdataset.trust)) {
- /*
- * Having a pending key with no signature means that
- * something is broken.
- */
- result = DNS_R_CONTINUE;
- } else if (val->frdataset.trust < dns_trust_secure) {
- /*
- * The key is legitimately insecure. There's no
- * point in even attempting verification.
- */
- val->key = NULL;
- result = ISC_R_SUCCESS;
- } else {
- /*
- * See if we've got the key used in the signature.
- */
- validator_log(val, ISC_LOG_DEBUG(3),
- "keyset with trust %s",
- dns_trust_totext(val->frdataset.trust));
- result = get_dst_key(val, siginfo, val->keyset);
- if (result != ISC_R_SUCCESS) {
- /*
- * Either the key we're looking for is not
- * in the rrset, or something bad happened.
- * Give up.
- */
- result = DNS_R_CONTINUE;
- }
- }
- } else if (result == ISC_R_NOTFOUND) {
- /*
- * We don't know anything about this key.
- */
- result = create_fetch(val, &siginfo->signer,
- dns_rdatatype_dnskey,
- fetch_callback_validator, "get_key");
- if (result != ISC_R_SUCCESS)
- return (result);
- return (DNS_R_WAIT);
- } else if (result == DNS_R_NCACHENXDOMAIN ||
- result == DNS_R_NCACHENXRRSET ||
- result == DNS_R_EMPTYNAME ||
- result == DNS_R_NXDOMAIN ||
- result == DNS_R_NXRRSET)
- {
- /*
- * This key doesn't exist.
- */
- result = DNS_R_CONTINUE;
- } else if (result == DNS_R_BROKENCHAIN)
- return (result);
-
- if (dns_rdataset_isassociated(&val->frdataset) &&
- val->keyset != &val->frdataset)
- dns_rdataset_disassociate(&val->frdataset);
- if (dns_rdataset_isassociated(&val->fsigrdataset))
- dns_rdataset_disassociate(&val->fsigrdataset);
-
- return (result);
-}
-
-static dns_keytag_t
-compute_keytag(dns_rdata_t *rdata, dns_rdata_dnskey_t *key) {
- isc_region_t r;
-
- dns_rdata_toregion(rdata, &r);
- return (dst_region_computeid(&r, key->algorithm));
-}
-
-/*%
- * Is this keyset self-signed?
- */
-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;
-
- if (rdataset->type == dns_rdatatype_cname ||
- rdataset->type == dns_rdatatype_dname)
- return (answer);
-
- INSIST(rdataset->type == dns_rdatatype_dnskey);
-
- for (result = dns_rdataset_first(rdataset);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(rdataset))
- {
- dns_rdata_reset(&rdata);
- dns_rdataset_current(rdataset, &rdata);
- result = dns_rdata_tostruct(&rdata, &key, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- keytag = compute_keytag(&rdata, &key);
- for (result = dns_rdataset_first(sigrdataset);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(sigrdataset))
- {
- dns_rdata_reset(&sigrdata);
- dns_rdataset_current(sigrdataset, &sigrdata);
- result = dns_rdata_tostruct(&sigrdata, &sig, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
-
- 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_verify3(name, rdataset, dstkey,
- ISC_TRUE,
- val->view->maxbits,
- 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 (answer);
-}
-
-/*%
- * Attempt to verify the rdataset using the given key and rdata (RRSIG).
- * The signature was good and from a wildcard record and the QNAME does
- * not match the wildcard we need to look for a NOQNAME proof.
- *
- * Returns:
- * \li ISC_R_SUCCESS if the verification succeeds.
- * \li Others if the verification fails.
- */
-static isc_result_t
-verify(dns_validator_t *val, dst_key_t *key, dns_rdata_t *rdata,
- isc_uint16_t keyid)
-{
- isc_result_t result;
- dns_fixedname_t fixed;
- isc_boolean_t ignore = ISC_FALSE;
- dns_name_t *wild;
-
- val->attributes |= VALATTR_TRIEDVERIFY;
- dns_fixedname_init(&fixed);
- wild = dns_fixedname_name(&fixed);
- again:
- result = dns_dnssec_verify3(val->event->name, val->event->rdataset,
- key, ignore, val->view->maxbits,
- val->view->mctx, rdata, wild);
- if ((result == DNS_R_SIGEXPIRED || result == DNS_R_SIGFUTURE) &&
- val->view->acceptexpired)
- {
- ignore = ISC_TRUE;
- goto again;
- }
- if (ignore && (result == ISC_R_SUCCESS || result == DNS_R_FROMWILDCARD))
- validator_log(val, ISC_LOG_INFO,
- "accepted expired %sRRSIG (keyid=%u)",
- (result == DNS_R_FROMWILDCARD) ?
- "wildcard " : "", keyid);
- else if (result == DNS_R_SIGEXPIRED || result == DNS_R_SIGFUTURE)
- validator_log(val, ISC_LOG_INFO,
- "verify failed due to bad signature (keyid=%u): "
- "%s", keyid, isc_result_totext(result));
- else
- validator_log(val, ISC_LOG_DEBUG(3),
- "verify rdataset (keyid=%u): %s",
- keyid, isc_result_totext(result));
- if (result == DNS_R_FROMWILDCARD) {
- if (!dns_name_equal(val->event->name, wild)) {
- dns_name_t *closest;
- unsigned int labels;
-
- /*
- * Compute the closest encloser in case we need it
- * for the NSEC3 NOQNAME proof.
- */
- closest = dns_fixedname_name(&val->closest);
- dns_name_copy(wild, closest, NULL);
- labels = dns_name_countlabels(closest) - 1;
- dns_name_getlabelsequence(closest, 1, labels, closest);
- val->attributes |= VALATTR_NEEDNOQNAME;
- }
- result = ISC_R_SUCCESS;
- }
- return (result);
-}
-
-/*%
- * Attempts positive response validation of a normal RRset.
- *
- * Returns:
- * \li ISC_R_SUCCESS Validation completed successfully
- * \li DNS_R_WAIT Validation has started but is waiting
- * for an event.
- * \li Other return codes are possible and all indicate failure.
- */
-static isc_result_t
-validate(dns_validator_t *val, isc_boolean_t resume) {
- isc_result_t result;
- dns_validatorevent_t *event;
- dns_rdata_t rdata = DNS_RDATA_INIT;
-
- /*
- * Caller must be holding the validator lock.
- */
-
- event = val->event;
-
- if (resume) {
- /*
- * We already have a sigrdataset.
- */
- result = ISC_R_SUCCESS;
- validator_log(val, ISC_LOG_DEBUG(3), "resuming validate");
- } else {
- result = dns_rdataset_first(event->sigrdataset);
- }
-
- for (;
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(event->sigrdataset))
- {
- dns_rdata_reset(&rdata);
- dns_rdataset_current(event->sigrdataset, &rdata);
- if (val->siginfo == NULL) {
- val->siginfo = isc_mem_get(val->view->mctx,
- sizeof(*val->siginfo));
- if (val->siginfo == NULL)
- return (ISC_R_NOMEMORY);
- }
- result = dns_rdata_tostruct(&rdata, val->siginfo, NULL);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- /*
- * At this point we could check that the signature algorithm
- * was known and "sufficiently good".
- */
- if (!dns_resolver_algorithm_supported(val->view->resolver,
- event->name,
- val->siginfo->algorithm)) {
- resume = ISC_FALSE;
- continue;
- }
-
- if (!resume) {
- result = get_key(val, val->siginfo);
- if (result == DNS_R_CONTINUE)
- continue; /* Try the next SIG RR. */
- if (result != ISC_R_SUCCESS)
- return (result);
- }
-
- /*
- * There isn't a secure DNSKEY for this signature so move
- * onto the next RRSIG.
- */
- if (val->key == NULL) {
- resume = ISC_FALSE;
- continue;
- }
-
- do {
- result = verify(val, val->key, &rdata,
- val->siginfo->keyid);
- if (result == ISC_R_SUCCESS)
- break;
- if (val->keynode != NULL) {
- dns_keynode_t *nextnode = NULL;
- result = dns_keytable_findnextkeynode(
- val->keytable,
- val->keynode,
- &nextnode);
- dns_keytable_detachkeynode(val->keytable,
- &val->keynode);
- val->keynode = nextnode;
- if (result != ISC_R_SUCCESS) {
- val->key = NULL;
- 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)
- break;
- }
- } while (1);
- if (result != ISC_R_SUCCESS)
- validator_log(val, ISC_LOG_DEBUG(3),
- "failed to verify rdataset");
- else {
- isc_stdtime_t now;
-
- isc_stdtime_get(&now);
- dns_rdataset_trimttl(event->rdataset,
- event->sigrdataset,
- val->siginfo, now,
- val->view->acceptexpired);
- }
-
- if (val->keynode != NULL)
- dns_keytable_detachkeynode(val->keytable,
- &val->keynode);
- else {
- if (val->key != NULL)
- dst_key_free(&val->key);
- if (val->keyset != NULL) {
- dns_rdataset_disassociate(val->keyset);
- val->keyset = NULL;
- }
- }
- val->key = NULL;
- if (NEEDNOQNAME(val)) {
- if (val->event->message == NULL) {
- validator_log(val, ISC_LOG_DEBUG(3),
- "no message available for noqname proof");
- return (DNS_R_NOVALIDSIG);
- }
- validator_log(val, ISC_LOG_DEBUG(3),
- "looking for noqname proof");
- return (nsecvalidate(val, ISC_FALSE));
- } else if (result == ISC_R_SUCCESS) {
- marksecure(event);
- validator_log(val, ISC_LOG_DEBUG(3),
- "marking as secure, "
- "noqname proof not needed");
- return (result);
- } else {
- validator_log(val, ISC_LOG_DEBUG(3),
- "verify failure: %s",
- isc_result_totext(result));
- resume = ISC_FALSE;
- }
- }
- if (result != ISC_R_NOMORE) {
- validator_log(val, ISC_LOG_DEBUG(3),
- "failed to iterate signatures: %s",
- isc_result_totext(result));
- return (result);
- }
-
- validator_log(val, ISC_LOG_INFO, "no valid signature found");
- return (DNS_R_NOVALIDSIG);
-}
-
-/*%
- * 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_rdata_dlv_t dlv;
- dns_rdata_t dlvrdata = DNS_RDATA_INIT;
- dns_rdata_t keyrdata = DNS_RDATA_INIT;
- dns_rdataset_t trdataset;
- isc_boolean_t supported_algorithm;
- isc_result_t result;
- char digest_types[256];
-
- validator_log(val, ISC_LOG_DEBUG(3), "dlv_validatezonekey");
-
- /*
- * Look through the DLV record and find the keys that can sign the
- * key set and the matching signature. For each such key, attempt
- * verification.
- */
- supported_algorithm = ISC_FALSE;
-
- /*
- * If DNS_DSDIGEST_SHA256 is present we are required to prefer
- * it over DNS_DSDIGEST_SHA1. This in practice means that we
- * need to ignore DNS_DSDIGEST_SHA1 if a DNS_DSDIGEST_SHA256
- * is present.
- */
- memset(digest_types, 1, sizeof(digest_types));
- for (result = dns_rdataset_first(&val->dlv);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(&val->dlv)) {
- dns_rdata_reset(&dlvrdata);
- dns_rdataset_current(&val->dlv, &dlvrdata);
- result = dns_rdata_tostruct(&dlvrdata, &dlv, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
-
- if (!dns_resolver_algorithm_supported(val->view->resolver,
- val->event->name,
- dlv.algorithm))
- continue;
-
- if (dlv.digest_type == DNS_DSDIGEST_SHA256 &&
- dlv.length == ISC_SHA256_DIGESTLENGTH) {
- digest_types[DNS_DSDIGEST_SHA1] = 0;
- break;
- }
- }
-
- for (result = dns_rdataset_first(&val->dlv);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(&val->dlv))
- {
- dns_rdata_reset(&dlvrdata);
- dns_rdataset_current(&val->dlv, &dlvrdata);
- result = dns_rdata_tostruct(&dlvrdata, &dlv, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
-
- if (!dns_resolver_digest_supported(val->view->resolver,
- dlv.digest_type))
- continue;
-
- if (digest_types[dlv.digest_type] == 0)
- continue;
-
- if (!dns_resolver_algorithm_supported(val->view->resolver,
- val->event->name,
- dlv.algorithm))
- continue;
-
- supported_algorithm = ISC_TRUE;
-
- dns_rdataset_init(&trdataset);
- dns_rdataset_clone(val->event->rdataset, &trdataset);
-
- /*
- * 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);
-
- dns_rdataset_disassociate(&trdataset);
- if (result == ISC_R_SUCCESS)
- break;
- validator_log(val, ISC_LOG_DEBUG(3),
- "no RRSIG matching DLV key");
- }
- if (result == ISC_R_SUCCESS) {
- marksecure(val->event);
- 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,"
- "no supported algorithm/digest (dlv)");
- return (DNS_R_MUSTBESECURE);
- }
- validator_log(val, ISC_LOG_DEBUG(3),
- "no supported algorithm/digest (dlv)");
- markanswer(val, "dlv_validatezonekey (2)");
- return (ISC_R_SUCCESS);
- } else
- return (DNS_R_NOVALIDSIG);
-}
-
-/*%
- * Attempts positive response validation of an RRset containing zone keys
- * (i.e. a DNSKEY rrset).
- *
- * Returns:
- * \li ISC_R_SUCCESS Validation completed successfully
- * \li DNS_R_WAIT Validation has started but is waiting
- * for an event.
- * \li Other return codes are possible and all indicate failure.
- */
-static isc_result_t
-validatezonekey(dns_validator_t *val) {
- isc_result_t result;
- dns_validatorevent_t *event;
- dns_rdataset_t trdataset;
- dns_rdata_t dsrdata = DNS_RDATA_INIT;
- dns_rdata_t keyrdata = DNS_RDATA_INIT;
- dns_rdata_t sigrdata = DNS_RDATA_INIT;
- char namebuf[DNS_NAME_FORMATSIZE];
- dns_rdata_ds_t ds;
- dns_rdata_rrsig_t sig;
- dst_key_t *dstkey;
- isc_boolean_t supported_algorithm;
- isc_boolean_t atsep = ISC_FALSE;
- char digest_types[256];
-
- /*
- * Caller must be holding the validator lock.
- */
-
- event = val->event;
-
- if (val->havedlvsep && val->dlv.trust >= dns_trust_secure &&
- dns_name_equal(event->name, dns_fixedname_name(&val->dlvsep)))
- return (dlv_validatezonekey(val));
-
- if (val->dsset == NULL) {
-
- /*
- * We have a dlv sep. Skip looking up the SEP from
- * {trusted,managed}-keys. If the dlv sep is for the
- * root then it will have been handled above so we don't
- * need to check whether val->event->name is "." prior to
- * looking up the DS.
- */
- if (val->havedlvsep)
- goto find_ds;
-
- /*
- * First, see if this key was signed by a trusted key.
- */
- for (result = dns_rdataset_first(val->event->sigrdataset);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(val->event->sigrdataset))
- {
- dns_keynode_t *keynode = NULL;
- dns_fixedname_t fixed;
- dns_name_t *found;
-
- dns_fixedname_init(&fixed);
- found = dns_fixedname_name(&fixed);
- 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 (!dns_name_equal(val->event->name, &sig.signer))
- continue;
-
- result = dns_keytable_findkeynode(val->keytable,
- val->event->name,
- sig.algorithm,
- sig.keyid, &keynode);
- if (result == ISC_R_NOTFOUND &&
- dns_keytable_finddeepestmatch(val->keytable,
- val->event->name, found) != ISC_R_SUCCESS) {
- if (val->mustbesecure) {
- validator_log(val, ISC_LOG_WARNING,
- "must be secure failure, "
- "not beneath secure root");
- return (DNS_R_MUSTBESECURE);
- } else
- validator_log(val, ISC_LOG_DEBUG(3),
- "not beneath secure root");
- if (val->view->dlv == NULL) {
- markanswer(val, "validatezonekey (1)");
- return (ISC_R_SUCCESS);
- }
- return (startfinddlvsep(val, dns_rootname));
- }
- if (result == DNS_R_PARTIALMATCH ||
- result == ISC_R_SUCCESS)
- atsep = ISC_TRUE;
- 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);
- break;
- }
- result = dns_keytable_findnextkeynode(
- val->keytable,
- keynode,
- &nextnode);
- dns_keytable_detachkeynode(val->keytable,
- &keynode);
- keynode = nextnode;
- }
- if (result == ISC_R_SUCCESS) {
- marksecure(event);
- validator_log(val, ISC_LOG_DEBUG(3),
- "signed by trusted key; "
- "marking as secure");
- return (result);
- }
- }
-
- if (atsep) {
- /*
- * We have not found a key to verify this DNSKEY
- * RRset. As this is a SEP we have to assume that
- * the RRset is invalid.
- */
- dns_name_format(val->event->name, namebuf,
- sizeof(namebuf));
- validator_log(val, ISC_LOG_NOTICE,
- "unable to find a DNSKEY which verifies "
- "the DNSKEY RRset and also matches a "
- "trusted key for '%s'",
- namebuf);
- validator_log(val, ISC_LOG_NOTICE,
- "please check the 'trusted-keys' for "
- "'%s' in named.conf.", namebuf);
- return (DNS_R_NOVALIDKEY);
- }
-
- /*
- * If this is the root name and there was no trusted key,
- * give up, since there's no DS at the root.
- */
- if (dns_name_equal(event->name, dns_rootname)) {
- if ((val->attributes & VALATTR_TRIEDVERIFY) != 0) {
- validator_log(val, ISC_LOG_DEBUG(3),
- "root key failed to validate");
- return (DNS_R_NOVALIDSIG);
- } else {
- validator_log(val, ISC_LOG_DEBUG(3),
- "no trusted root key");
- return (DNS_R_NOVALIDDS);
- }
- }
- find_ds:
- /*
- * Otherwise, try to find the DS record.
- */
- result = view_find(val, val->event->name, dns_rdatatype_ds);
- if (result == ISC_R_SUCCESS) {
- /*
- * We have DS records.
- */
- val->dsset = &val->frdataset;
- if ((DNS_TRUST_PENDING(val->frdataset.trust) ||
- DNS_TRUST_ANSWER(val->frdataset.trust)) &&
- dns_rdataset_isassociated(&val->fsigrdataset))
- {
- result = create_validator(val,
- val->event->name,
- dns_rdatatype_ds,
- &val->frdataset,
- &val->fsigrdataset,
- dsvalidated,
- "validatezonekey");
- if (result != ISC_R_SUCCESS)
- return (result);
- return (DNS_R_WAIT);
- } else if (DNS_TRUST_PENDING(val->frdataset.trust)) {
- /*
- * There should never be an unsigned DS.
- */
- dns_rdataset_disassociate(&val->frdataset);
- validator_log(val, ISC_LOG_DEBUG(2),
- "unsigned DS record");
- return (DNS_R_NOVALIDSIG);
- } else {
- result = ISC_R_SUCCESS;
- POST(result);
- }
- } else if (result == ISC_R_NOTFOUND) {
- /*
- * We don't have the DS. Find it.
- */
- result = create_fetch(val, val->event->name,
- dns_rdatatype_ds, dsfetched,
- "validatezonekey");
- if (result != ISC_R_SUCCESS)
- return (result);
- return (DNS_R_WAIT);
- } else if (result == DNS_R_NCACHENXDOMAIN ||
- result == DNS_R_NCACHENXRRSET ||
- result == DNS_R_EMPTYNAME ||
- result == DNS_R_NXDOMAIN ||
- result == DNS_R_NXRRSET ||
- result == DNS_R_CNAME)
- {
- /*
- * The DS does not exist.
- */
- if (dns_rdataset_isassociated(&val->frdataset))
- dns_rdataset_disassociate(&val->frdataset);
- if (dns_rdataset_isassociated(&val->fsigrdataset))
- dns_rdataset_disassociate(&val->fsigrdataset);
- validator_log(val, ISC_LOG_DEBUG(2), "no DS record");
- return (DNS_R_NOVALIDSIG);
- } else if (result == DNS_R_BROKENCHAIN)
- return (result);
- }
-
- /*
- * We have a DS set.
- */
- INSIST(val->dsset != NULL);
-
- if (val->dsset->trust < dns_trust_secure) {
- if (val->mustbesecure) {
- validator_log(val, ISC_LOG_WARNING,
- "must be secure failure,"
- " insecure DS");
- return (DNS_R_MUSTBESECURE);
- }
- if (val->view->dlv == NULL || DLVTRIED(val)) {
- markanswer(val, "validatezonekey (2)");
- return (ISC_R_SUCCESS);
- }
- return (startfinddlvsep(val, val->event->name));
- }
-
- /*
- * Look through the DS record and find the keys that can sign the
- * key set and the matching signature. For each such key, attempt
- * verification.
- */
-
- supported_algorithm = ISC_FALSE;
-
- /*
- * If DNS_DSDIGEST_SHA256 is present we are required to prefer
- * it over DNS_DSDIGEST_SHA1. This in practice means that we
- * need to ignore DNS_DSDIGEST_SHA1 if a DNS_DSDIGEST_SHA256
- * is present.
- */
- memset(digest_types, 1, sizeof(digest_types));
- for (result = dns_rdataset_first(val->dsset);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(val->dsset)) {
- dns_rdata_reset(&dsrdata);
- dns_rdataset_current(val->dsset, &dsrdata);
- result = dns_rdata_tostruct(&dsrdata, &ds, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
-
- if (!dns_resolver_algorithm_supported(val->view->resolver,
- val->event->name,
- ds.algorithm))
- continue;
-
- if (ds.digest_type == DNS_DSDIGEST_SHA256 &&
- ds.length == ISC_SHA256_DIGESTLENGTH) {
- digest_types[DNS_DSDIGEST_SHA1] = 0;
- break;
- }
- }
-
- for (result = dns_rdataset_first(val->dsset);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(val->dsset))
- {
- dns_rdata_reset(&dsrdata);
- dns_rdataset_current(val->dsset, &dsrdata);
- result = dns_rdata_tostruct(&dsrdata, &ds, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
-
- if (!dns_resolver_digest_supported(val->view->resolver,
- ds.digest_type))
- continue;
-
- if (digest_types[ds.digest_type] == 0)
- continue;
-
- if (!dns_resolver_algorithm_supported(val->view->resolver,
- val->event->name,
- ds.algorithm))
- continue;
-
- supported_algorithm = ISC_TRUE;
-
- dns_rdataset_init(&trdataset);
- dns_rdataset_clone(val->event->rdataset, &trdataset);
-
- /*
- * Find matching DNSKEY from DS.
- */
- 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),
- "no DNSKEY matching DS");
- continue;
- }
-
- /*
- * 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;
- validator_log(val, ISC_LOG_DEBUG(3),
- "no RRSIG matching DS key");
- }
- if (result == ISC_R_SUCCESS) {
- marksecure(event);
- 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, "
- "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 {
- validator_log(val, ISC_LOG_INFO,
- "no valid signature found (DS)");
- return (DNS_R_NOVALIDSIG);
- }
-}
-
-/*%
- * Starts a positive response validation.
- *
- * Returns:
- * \li ISC_R_SUCCESS Validation completed successfully
- * \li DNS_R_WAIT Validation has started but is waiting
- * for an event.
- * \li Other return codes are possible and all indicate failure.
- */
-static isc_result_t
-start_positive_validation(dns_validator_t *val) {
- /*
- * If this is not a key, go straight into validate().
- */
- if (val->event->type != dns_rdatatype_dnskey || !isselfsigned(val))
- return (validate(val, ISC_FALSE));
-
- return (validatezonekey(val));
-}
-
-/*%
- * val_rdataset_first and val_rdataset_next provide iteration methods
- * that hide whether we are iterating across a message or a negative
- * cache rdataset.
- */
-static isc_result_t
-val_rdataset_first(dns_validator_t *val, dns_name_t **namep,
- dns_rdataset_t **rdatasetp)
-{
- dns_message_t *message = val->event->message;
- isc_result_t result;
-
- REQUIRE(rdatasetp != NULL);
- REQUIRE(namep != NULL);
- if (message == NULL) {
- REQUIRE(*rdatasetp != NULL);
- REQUIRE(*namep != NULL);
- } else {
- REQUIRE(*rdatasetp == NULL);
- REQUIRE(*namep == NULL);
- }
-
- if (message != NULL) {
- result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
- if (result != ISC_R_SUCCESS)
- return (result);
- dns_message_currentname(message, DNS_SECTION_AUTHORITY, namep);
- *rdatasetp = ISC_LIST_HEAD((*namep)->list);
- INSIST(*rdatasetp != NULL);
- } else {
- result = dns_rdataset_first(val->event->rdataset);
- if (result == ISC_R_SUCCESS)
- dns_ncache_current(val->event->rdataset, *namep,
- *rdatasetp);
- }
- return (result);
-}
-
-static isc_result_t
-val_rdataset_next(dns_validator_t *val, dns_name_t **namep,
- dns_rdataset_t **rdatasetp)
-{
- dns_message_t *message = val->event->message;
- isc_result_t result = ISC_R_SUCCESS;
-
- REQUIRE(rdatasetp != NULL && *rdatasetp != NULL);
- REQUIRE(namep != NULL && *namep != NULL);
-
- if (message != NULL) {
- dns_rdataset_t *rdataset = *rdatasetp;
- rdataset = ISC_LIST_NEXT(rdataset, link);
- if (rdataset == NULL) {
- *namep = NULL;
- result = dns_message_nextname(message,
- DNS_SECTION_AUTHORITY);
- if (result == ISC_R_SUCCESS) {
- dns_message_currentname(message,
- DNS_SECTION_AUTHORITY,
- namep);
- rdataset = ISC_LIST_HEAD((*namep)->list);
- INSIST(rdataset != NULL);
- }
- }
- *rdatasetp = rdataset;
- } else {
- dns_rdataset_disassociate(*rdatasetp);
- result = dns_rdataset_next(val->event->rdataset);
- if (result == ISC_R_SUCCESS)
- dns_ncache_current(val->event->rdataset, *namep,
- *rdatasetp);
- }
- return (result);
-}
-
-/*%
- * Look for NODATA at the wildcard and NOWILDCARD proofs in the
- * previously validated NSEC records. As these proofs are mutually
- * exclusive we stop when one is found.
- *
- * Returns
- * \li ISC_R_SUCCESS
- */
-static isc_result_t
-checkwildcard(dns_validator_t *val, dns_rdatatype_t type, dns_name_t *zonename)
-{
- dns_name_t *name, *wild, tname;
- isc_result_t result;
- isc_boolean_t exists, data;
- char namebuf[DNS_NAME_FORMATSIZE];
- dns_rdataset_t *rdataset, trdataset;
-
- dns_name_init(&tname, NULL);
- dns_rdataset_init(&trdataset);
- wild = dns_fixedname_name(&val->wild);
-
- if (dns_name_countlabels(wild) == 0) {
- validator_log(val, ISC_LOG_DEBUG(3),
- "in checkwildcard: no wildcard to check");
- return (ISC_R_SUCCESS);
- }
-
- dns_name_format(wild, namebuf, sizeof(namebuf));
- validator_log(val, ISC_LOG_DEBUG(3), "in checkwildcard: %s", namebuf);
-
- if (val->event->message == NULL) {
- name = &tname;
- rdataset = &trdataset;
- } else {
- name = NULL;
- rdataset = NULL;
- }
-
- for (result = val_rdataset_first(val, &name, &rdataset);
- result == ISC_R_SUCCESS;
- result = val_rdataset_next(val, &name, &rdataset))
- {
- if (rdataset->type != type ||
- rdataset->trust != dns_trust_secure)
- continue;
-
- if (rdataset->type == dns_rdatatype_nsec &&
- (NEEDNODATA(val) || NEEDNOWILDCARD(val)) &&
- !FOUNDNODATA(val) && !FOUNDNOWILDCARD(val) &&
- dns_nsec_noexistnodata(val->event->type, wild, name,
- rdataset, &exists, &data, NULL,
- validator_log, val)
- == ISC_R_SUCCESS)
- {
- dns_name_t **proofs = val->event->proofs;
- if (exists && !data)
- val->attributes |= VALATTR_FOUNDNODATA;
- if (exists && !data && NEEDNODATA(val))
- proofs[DNS_VALIDATOR_NODATAPROOF] =
- name;
- if (!exists)
- val->attributes |=
- VALATTR_FOUNDNOWILDCARD;
- if (!exists && NEEDNOQNAME(val))
- proofs[DNS_VALIDATOR_NOWILDCARDPROOF] =
- name;
- if (dns_rdataset_isassociated(&trdataset))
- dns_rdataset_disassociate(&trdataset);
- return (ISC_R_SUCCESS);
- }
-
- if (rdataset->type == dns_rdatatype_nsec3 &&
- (NEEDNODATA(val) || NEEDNOWILDCARD(val)) &&
- !FOUNDNODATA(val) && !FOUNDNOWILDCARD(val) &&
- dns_nsec3_noexistnodata(val->event->type, wild, name,
- rdataset, zonename, &exists, &data,
- NULL, NULL, NULL, NULL, NULL, NULL,
- validator_log, val)
- == ISC_R_SUCCESS)
- {
- dns_name_t **proofs = val->event->proofs;
- if (exists && !data)
- val->attributes |= VALATTR_FOUNDNODATA;
- if (exists && !data && NEEDNODATA(val))
- proofs[DNS_VALIDATOR_NODATAPROOF] =
- name;
- if (!exists)
- val->attributes |=
- VALATTR_FOUNDNOWILDCARD;
- if (!exists && NEEDNOQNAME(val))
- proofs[DNS_VALIDATOR_NOWILDCARDPROOF] =
- name;
- if (dns_rdataset_isassociated(&trdataset))
- dns_rdataset_disassociate(&trdataset);
- return (ISC_R_SUCCESS);
- }
- }
- if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
- if (dns_rdataset_isassociated(&trdataset))
- dns_rdataset_disassociate(&trdataset);
- return (result);
-}
-
-static isc_result_t
-findnsec3proofs(dns_validator_t *val) {
- dns_name_t *name, tname;
- isc_result_t result;
- isc_boolean_t exists, data, optout, unknown;
- isc_boolean_t setclosest, setnearest, *setclosestp;
- dns_fixedname_t fclosest, fnearest, fzonename;
- dns_name_t *closest, *nearest, *zonename, *closestp;
- dns_name_t **proofs = val->event->proofs;
- dns_rdataset_t *rdataset, trdataset;
-
- dns_name_init(&tname, NULL);
- dns_rdataset_init(&trdataset);
- dns_fixedname_init(&fclosest);
- dns_fixedname_init(&fnearest);
- dns_fixedname_init(&fzonename);
- closest = dns_fixedname_name(&fclosest);
- nearest = dns_fixedname_name(&fnearest);
- zonename = dns_fixedname_name(&fzonename);
-
- if (val->event->message == NULL) {
- name = &tname;
- rdataset = &trdataset;
- } else {
- name = NULL;
- rdataset = NULL;
- }
-
- for (result = val_rdataset_first(val, &name, &rdataset);
- result == ISC_R_SUCCESS;
- result = val_rdataset_next(val, &name, &rdataset))
- {
- if (rdataset->type != dns_rdatatype_nsec3 ||
- rdataset->trust != dns_trust_secure)
- continue;
-
- result = dns_nsec3_noexistnodata(val->event->type,
- val->event->name, name,
- rdataset, zonename, NULL,
- NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, validator_log,
- val);
- if (result != ISC_R_IGNORE && result != ISC_R_SUCCESS) {
- if (dns_rdataset_isassociated(&trdataset))
- dns_rdataset_disassociate(&trdataset);
- return (result);
- }
- }
- if (result != ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
- POST(result);
-
- if (dns_name_countlabels(zonename) == 0)
- return (ISC_R_SUCCESS);
-
- /*
- * If the val->closest is set then we want to use it otherwise
- * we need to discover it.
- */
- if (dns_name_countlabels(dns_fixedname_name(&val->closest)) != 0) {
- char namebuf[DNS_NAME_FORMATSIZE];
-
- dns_name_format(dns_fixedname_name(&val->closest),
- namebuf, sizeof(namebuf));
- validator_log(val, ISC_LOG_DEBUG(3), "closest encloser from "
- "wildcard signature '%s'", namebuf);
- dns_name_copy(dns_fixedname_name(&val->closest), closest, NULL);
- closestp = NULL;
- setclosestp = NULL;
- } else {
- closestp = closest;
- setclosestp = &setclosest;
- }
-
- for (result = val_rdataset_first(val, &name, &rdataset);
- result == ISC_R_SUCCESS;
- result = val_rdataset_next(val, &name, &rdataset))
- {
- if (rdataset->type != dns_rdatatype_nsec3 ||
- rdataset->trust != dns_trust_secure)
- continue;
-
- /*
- * We process all NSEC3 records to find the closest
- * encloser and nearest name to the closest encloser.
- */
- setclosest = setnearest = ISC_FALSE;
- optout = ISC_FALSE;
- unknown = ISC_FALSE;
- result = dns_nsec3_noexistnodata(val->event->type,
- val->event->name,
- name, rdataset, zonename,
- &exists, &data, &optout,
- &unknown, setclosestp,
- &setnearest, closestp,
- nearest, validator_log, val);
- if (unknown)
- val->attributes |= VALATTR_FOUNDUNKNOWN;
- if (result != ISC_R_SUCCESS)
- continue;
- if (setclosest)
- proofs[DNS_VALIDATOR_CLOSESTENCLOSER] = name;
- if (exists && !data && NEEDNODATA(val)) {
- val->attributes |= VALATTR_FOUNDNODATA;
- proofs[DNS_VALIDATOR_NODATAPROOF] = name;
- }
- if (!exists && setnearest) {
- val->attributes |= VALATTR_FOUNDNOQNAME;
- proofs[DNS_VALIDATOR_NOQNAMEPROOF] = name;
- if (optout)
- val->attributes |= VALATTR_FOUNDOPTOUT;
- }
- }
- if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
-
- /*
- * To know we have a valid noqname and optout proofs we need to also
- * have a valid closest encloser. Otherwise we could still be looking
- * at proofs from the parent zone.
- */
- if (dns_name_countlabels(closest) > 0 &&
- dns_name_countlabels(nearest) ==
- dns_name_countlabels(closest) + 1 &&
- dns_name_issubdomain(nearest, closest))
- {
- val->attributes |= VALATTR_FOUNDCLOSEST;
- result = dns_name_concatenate(dns_wildcardname, closest,
- dns_fixedname_name(&val->wild),
- NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- } else {
- val->attributes &= ~VALATTR_FOUNDNOQNAME;
- val->attributes &= ~VALATTR_FOUNDOPTOUT;
- proofs[DNS_VALIDATOR_NOQNAMEPROOF] = NULL;
- }
-
- /*
- * Do we need to check for the wildcard?
- */
- if (FOUNDNOQNAME(val) && FOUNDCLOSEST(val) &&
- ((NEEDNODATA(val) && !FOUNDNODATA(val)) || NEEDNOWILDCARD(val))) {
- result = checkwildcard(val, dns_rdatatype_nsec3, zonename);
- if (result != ISC_R_SUCCESS)
- return (result);
- }
- return (result);
-}
-
-/*%
- * Validate the authority section records.
- */
-static isc_result_t
-validate_authority(dns_validator_t *val, isc_boolean_t resume) {
- dns_name_t *name;
- dns_message_t *message = val->event->message;
- isc_result_t result;
-
- if (!resume)
- result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
- else
- result = ISC_R_SUCCESS;
-
- for (;
- result == ISC_R_SUCCESS;
- result = dns_message_nextname(message, DNS_SECTION_AUTHORITY))
- {
- dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL;
-
- name = NULL;
- dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name);
- if (resume) {
- rdataset = ISC_LIST_NEXT(val->currentset, link);
- val->currentset = NULL;
- resume = ISC_FALSE;
- } else
- rdataset = ISC_LIST_HEAD(name->list);
-
- for (;
- rdataset != NULL;
- rdataset = ISC_LIST_NEXT(rdataset, link))
- {
- if (rdataset->type == dns_rdatatype_rrsig)
- continue;
-
- for (sigrdataset = ISC_LIST_HEAD(name->list);
- sigrdataset != NULL;
- sigrdataset = ISC_LIST_NEXT(sigrdataset,
- link))
- {
- if (sigrdataset->type == dns_rdatatype_rrsig &&
- sigrdataset->covers == rdataset->type)
- break;
- }
- /*
- * If a signed zone is missing the zone key, bad
- * things could happen. A query for data in the zone
- * would lead to a query for the zone key, which
- * would return a negative answer, which would contain
- * an SOA and an NSEC signed by the missing key, which
- * would trigger another query for the DNSKEY (since
- * the first one is still in progress), and go into an
- * infinite loop. Avoid that.
- */
- if (val->event->type == dns_rdatatype_dnskey &&
- rdataset->type == dns_rdatatype_nsec &&
- dns_name_equal(name, val->event->name))
- {
- dns_rdata_t nsec = DNS_RDATA_INIT;
-
- result = dns_rdataset_first(rdataset);
- if (result != ISC_R_SUCCESS)
- return (result);
- dns_rdataset_current(rdataset, &nsec);
- if (dns_nsec_typepresent(&nsec,
- dns_rdatatype_soa))
- continue;
- }
- val->currentset = rdataset;
- result = create_validator(val, name, rdataset->type,
- rdataset, sigrdataset,
- authvalidated,
- "validate_authority");
- if (result != ISC_R_SUCCESS)
- return (result);
- val->authcount++;
- return (DNS_R_WAIT);
- }
- }
- if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
- return (result);
-}
-
-/*%
- * Validate the ncache elements.
- */
-static isc_result_t
-validate_ncache(dns_validator_t *val, isc_boolean_t resume) {
- dns_name_t *name;
- isc_result_t result;
-
- if (!resume)
- result = dns_rdataset_first(val->event->rdataset);
- else
- result = dns_rdataset_next(val->event->rdataset);
-
- for (;
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(val->event->rdataset))
- {
- dns_rdataset_t *rdataset, *sigrdataset = NULL;
-
- if (dns_rdataset_isassociated(&val->frdataset))
- dns_rdataset_disassociate(&val->frdataset);
- if (dns_rdataset_isassociated(&val->fsigrdataset))
- dns_rdataset_disassociate(&val->fsigrdataset);
-
- dns_fixedname_init(&val->fname);
- name = dns_fixedname_name(&val->fname);
- rdataset = &val->frdataset;
- dns_ncache_current(val->event->rdataset, name, rdataset);
-
- if (val->frdataset.type == dns_rdatatype_rrsig)
- continue;
-
- result = dns_ncache_getsigrdataset(val->event->rdataset, name,
- rdataset->type,
- &val->fsigrdataset);
- if (result == ISC_R_SUCCESS)
- sigrdataset = &val->fsigrdataset;
-
- /*
- * If a signed zone is missing the zone key, bad
- * things could happen. A query for data in the zone
- * would lead to a query for the zone key, which
- * would return a negative answer, which would contain
- * an SOA and an NSEC signed by the missing key, which
- * would trigger another query for the DNSKEY (since
- * the first one is still in progress), and go into an
- * infinite loop. Avoid that.
- */
- if (val->event->type == dns_rdatatype_dnskey &&
- rdataset->type == dns_rdatatype_nsec &&
- dns_name_equal(name, val->event->name))
- {
- dns_rdata_t nsec = DNS_RDATA_INIT;
-
- result = dns_rdataset_first(rdataset);
- if (result != ISC_R_SUCCESS)
- return (result);
- dns_rdataset_current(rdataset, &nsec);
- if (dns_nsec_typepresent(&nsec,
- dns_rdatatype_soa))
- continue;
- }
- val->currentset = rdataset;
- result = create_validator(val, name, rdataset->type,
- rdataset, sigrdataset,
- authvalidated,
- "validate_ncache");
- if (result != ISC_R_SUCCESS)
- return (result);
- val->authcount++;
- return (DNS_R_WAIT);
- }
- if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
- return (result);
-}
-
-/*%
- * Prove a negative answer is good or that there is a NOQNAME when the
- * answer is from a wildcard.
- *
- * Loop through the authority section looking for NODATA, NOWILDCARD
- * and NOQNAME proofs in the NSEC records by calling authvalidated().
- *
- * If the required proofs are found we are done.
- *
- * If the proofs are not found attempt to prove this is a unsecure
- * response.
- */
-static isc_result_t
-nsecvalidate(dns_validator_t *val, isc_boolean_t resume) {
- isc_result_t result;
-
- if (resume)
- validator_log(val, ISC_LOG_DEBUG(3), "resuming nsecvalidate");
-
- if (val->event->message == NULL)
- result = validate_ncache(val, resume);
- else
- result = validate_authority(val, resume);
-
- if (result != ISC_R_SUCCESS)
- return (result);
-
- /*
- * Do we only need to check for NOQNAME? To get here we must have
- * had a secure wildcard answer.
- */
- if (!NEEDNODATA(val) && !NEEDNOWILDCARD(val) && NEEDNOQNAME(val)) {
- if (!FOUNDNOQNAME(val))
- findnsec3proofs(val);
- if (FOUNDNOQNAME(val) && FOUNDCLOSEST(val)) {
- validator_log(val, ISC_LOG_DEBUG(3),
- "marking as secure, noqname proof found");
- marksecure(val->event);
- return (ISC_R_SUCCESS);
- } else if (FOUNDOPTOUT(val) &&
- dns_name_countlabels(dns_fixedname_name(&val->wild))
- != 0) {
- validator_log(val, ISC_LOG_DEBUG(3),
- "optout proof found");
- val->event->optout = ISC_TRUE;
- markanswer(val, "nsecvalidate (1)");
- return (ISC_R_SUCCESS);
- } else if ((val->attributes & VALATTR_FOUNDUNKNOWN) != 0) {
- validator_log(val, ISC_LOG_DEBUG(3),
- "unknown NSEC3 hash algorithm found");
- markanswer(val, "nsecvalidate (2)");
- return (ISC_R_SUCCESS);
- }
- validator_log(val, ISC_LOG_DEBUG(3),
- "noqname proof not found");
- return (DNS_R_NOVALIDNSEC);
- }
-
- if (!FOUNDNOQNAME(val) && !FOUNDNODATA(val))
- findnsec3proofs(val);
-
- /*
- * Do we need to check for the wildcard?
- */
- if (FOUNDNOQNAME(val) && FOUNDCLOSEST(val) &&
- ((NEEDNODATA(val) && !FOUNDNODATA(val)) || NEEDNOWILDCARD(val))) {
- result = checkwildcard(val, dns_rdatatype_nsec, NULL);
- if (result != ISC_R_SUCCESS)
- return (result);
- }
-
- if ((NEEDNODATA(val) && (FOUNDNODATA(val) || FOUNDOPTOUT(val))) ||
- (NEEDNOQNAME(val) && FOUNDNOQNAME(val) &&
- NEEDNOWILDCARD(val) && FOUNDNOWILDCARD(val) &&
- FOUNDCLOSEST(val))) {
- if ((val->attributes & VALATTR_FOUNDOPTOUT) != 0)
- val->event->optout = ISC_TRUE;
- validator_log(val, ISC_LOG_DEBUG(3),
- "nonexistence proof(s) found");
- if (val->event->message == NULL)
- marksecure(val->event);
- else
- val->event->secure = ISC_TRUE;
- return (ISC_R_SUCCESS);
- }
-
- if (val->authfail != 0 && val->authcount == val->authfail)
- return (DNS_R_BROKENCHAIN);
- validator_log(val, ISC_LOG_DEBUG(3),
- "nonexistence proof(s) not found");
- val->attributes |= VALATTR_INSECURITY;
- return (proveunsecure(val, ISC_FALSE, ISC_FALSE));
-}
-
-static isc_boolean_t
-check_ds(dns_validator_t *val, dns_name_t *name, dns_rdataset_t *rdataset) {
- dns_rdata_t dsrdata = DNS_RDATA_INIT;
- dns_rdata_ds_t ds;
- isc_result_t result;
-
- for (result = dns_rdataset_first(rdataset);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(rdataset)) {
- dns_rdataset_current(rdataset, &dsrdata);
- result = dns_rdata_tostruct(&dsrdata, &ds, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
-
- if (dns_resolver_digest_supported(val->view->resolver,
- ds.digest_type) &&
- dns_resolver_algorithm_supported(val->view->resolver,
- name, ds.algorithm)) {
- dns_rdata_reset(&dsrdata);
- return (ISC_TRUE);
- }
- dns_rdata_reset(&dsrdata);
- }
- return (ISC_FALSE);
-}
-
-static void
-dlvvalidated(isc_task_t *task, isc_event_t *event) {
- dns_validatorevent_t *devent;
- dns_validator_t *val;
- isc_result_t eresult;
- isc_boolean_t want_destroy;
-
- UNUSED(task);
- INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
-
- devent = (dns_validatorevent_t *)event;
- val = devent->ev_arg;
- eresult = devent->result;
-
- isc_event_free(&event);
- dns_validator_destroy(&val->subvalidator);
-
- INSIST(val->event != NULL);
-
- validator_log(val, ISC_LOG_DEBUG(3), "in dlvvalidated");
- LOCK(&val->lock);
- if (CANCELED(val)) {
- validator_done(val, ISC_R_CANCELED);
- } else if (eresult == ISC_R_SUCCESS) {
- validator_log(val, ISC_LOG_DEBUG(3),
- "dlvset with trust %s",
- dns_trust_totext(val->frdataset.trust));
- dns_rdataset_clone(&val->frdataset, &val->dlv);
- val->havedlvsep = ISC_TRUE;
- if (dlv_algorithm_supported(val))
- dlv_validator_start(val);
- else {
- markanswer(val, "dlvvalidated");
- validator_done(val, ISC_R_SUCCESS);
- }
- } else {
- if (eresult != DNS_R_BROKENCHAIN) {
- if (dns_rdataset_isassociated(&val->frdataset))
- dns_rdataset_expire(&val->frdataset);
- if (dns_rdataset_isassociated(&val->fsigrdataset))
- dns_rdataset_expire(&val->fsigrdataset);
- }
- validator_log(val, ISC_LOG_DEBUG(3),
- "dlvvalidated: got %s",
- isc_result_totext(eresult));
- validator_done(val, DNS_R_BROKENCHAIN);
- }
- want_destroy = exit_check(val);
- UNLOCK(&val->lock);
- if (want_destroy)
- destroy(val);
-}
-
-/*%
- * Callback from fetching a DLV record.
- *
- * Resumes the DLV lookup process.
- */
-static void
-dlvfetched(isc_task_t *task, isc_event_t *event) {
- char namebuf[DNS_NAME_FORMATSIZE];
- dns_fetchevent_t *devent;
- dns_validator_t *val;
- isc_boolean_t want_destroy;
- isc_result_t eresult;
- isc_result_t result;
- dns_fetch_t *fetch;
-
- UNUSED(task);
- INSIST(event->ev_type == DNS_EVENT_FETCHDONE);
- devent = (dns_fetchevent_t *)event;
- val = devent->ev_arg;
- 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);
- if (dns_rdataset_isassociated(&val->fsigrdataset))
- dns_rdataset_disassociate(&val->fsigrdataset);
- isc_event_free(&event);
-
- INSIST(val->event != NULL);
- validator_log(val, ISC_LOG_DEBUG(3), "in dlvfetched: %s",
- dns_result_totext(eresult));
-
- LOCK(&val->lock);
- fetch = val->fetch;
- val->fetch = NULL;
- if (eresult == ISC_R_SUCCESS) {
- dns_name_format(dns_fixedname_name(&val->dlvsep), namebuf,
- sizeof(namebuf));
- dns_rdataset_clone(&val->frdataset, &val->dlv);
- val->havedlvsep = ISC_TRUE;
- if (dlv_algorithm_supported(val)) {
- validator_log(val, ISC_LOG_DEBUG(3), "DLV %s found",
- namebuf);
- dlv_validator_start(val);
- } else {
- validator_log(val, ISC_LOG_DEBUG(3),
- "DLV %s found with no supported algorithms",
- namebuf);
- markanswer(val, "dlvfetched (1)");
- validator_done(val, ISC_R_SUCCESS);
- }
- } else if (eresult == DNS_R_NXRRSET ||
- eresult == DNS_R_NXDOMAIN ||
- eresult == DNS_R_NCACHENXRRSET ||
- eresult == DNS_R_NCACHENXDOMAIN) {
- result = finddlvsep(val, ISC_TRUE);
- if (result == ISC_R_SUCCESS) {
- if (dlv_algorithm_supported(val)) {
- dns_name_format(dns_fixedname_name(&val->dlvsep),
- namebuf, sizeof(namebuf));
- validator_log(val, ISC_LOG_DEBUG(3),
- "DLV %s found", namebuf);
- dlv_validator_start(val);
- } else {
- validator_log(val, ISC_LOG_DEBUG(3),
- "DLV %s found with no supported "
- "algorithms", namebuf);
- markanswer(val, "dlvfetched (2)");
- validator_done(val, ISC_R_SUCCESS);
- }
- } else if (result == ISC_R_NOTFOUND) {
- validator_log(val, ISC_LOG_DEBUG(3), "DLV not found");
- markanswer(val, "dlvfetched (3)");
- validator_done(val, ISC_R_SUCCESS);
- } else {
- validator_log(val, ISC_LOG_DEBUG(3), "DLV lookup: %s",
- dns_result_totext(result));
- if (result != DNS_R_WAIT)
- validator_done(val, result);
- }
- } else {
- validator_log(val, ISC_LOG_DEBUG(3), "DLV lookup: %s",
- dns_result_totext(eresult));
- validator_done(val, eresult);
- }
- want_destroy = exit_check(val);
- UNLOCK(&val->lock);
- if (fetch != NULL)
- dns_resolver_destroyfetch(&fetch);
- if (want_destroy)
- destroy(val);
-}
-
-/*%
- * Start the DLV lookup process.
- *
- * Returns
- * \li ISC_R_SUCCESS
- * \li DNS_R_WAIT
- * \li Others on validation failures.
- */
-static isc_result_t
-startfinddlvsep(dns_validator_t *val, dns_name_t *unsecure) {
- char namebuf[DNS_NAME_FORMATSIZE];
- isc_result_t result;
-
- INSIST(!DLVTRIED(val));
-
- val->attributes |= VALATTR_DLVTRIED;
-
- dns_name_format(unsecure, namebuf, sizeof(namebuf));
- validator_log(val, ISC_LOG_DEBUG(3),
- "plain DNSSEC returns unsecure (%s): looking for DLV",
- namebuf);
-
- if (dns_name_issubdomain(val->event->name, val->view->dlv)) {
- validator_log(val, ISC_LOG_WARNING, "must be secure failure, "
- " %s is under DLV (startfinddlvsep)", namebuf);
- return (DNS_R_MUSTBESECURE);
- }
-
- val->dlvlabels = dns_name_countlabels(unsecure) - 1;
- result = finddlvsep(val, ISC_FALSE);
- if (result == ISC_R_NOTFOUND) {
- validator_log(val, ISC_LOG_DEBUG(3), "DLV not found");
- markanswer(val, "startfinddlvsep (1)");
- return (ISC_R_SUCCESS);
- }
- if (result != ISC_R_SUCCESS) {
- validator_log(val, ISC_LOG_DEBUG(3), "DLV lookup: %s",
- dns_result_totext(result));
- return (result);
- }
- dns_name_format(dns_fixedname_name(&val->dlvsep), namebuf,
- sizeof(namebuf));
- if (dlv_algorithm_supported(val)) {
- validator_log(val, ISC_LOG_DEBUG(3), "DLV %s found", namebuf);
- dlv_validator_start(val);
- return (DNS_R_WAIT);
- }
- validator_log(val, ISC_LOG_DEBUG(3), "DLV %s found with no supported "
- "algorithms", namebuf);
- markanswer(val, "startfinddlvsep (2)");
- validator_done(val, ISC_R_SUCCESS);
- return (ISC_R_SUCCESS);
-}
-
-/*%
- * Continue the DLV lookup process.
- *
- * Returns
- * \li ISC_R_SUCCESS
- * \li ISC_R_NOTFOUND
- * \li DNS_R_WAIT
- * \li Others on validation failure.
- */
-static isc_result_t
-finddlvsep(dns_validator_t *val, isc_boolean_t resume) {
- char namebuf[DNS_NAME_FORMATSIZE];
- dns_fixedname_t dlvfixed;
- dns_name_t *dlvname;
- dns_name_t *dlvsep;
- dns_name_t noroot;
- isc_result_t result;
- unsigned int labels;
-
- 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, "
- "%s is under DLV (finddlvsep)", namebuf);
- return (DNS_R_MUSTBESECURE);
- }
-
- dns_fixedname_init(&val->dlvsep);
- dlvsep = dns_fixedname_name(&val->dlvsep);
- dns_name_copy(val->event->name, dlvsep, NULL);
- /*
- * If this is a response to a DS query, we need to look in
- * the parent zone for the trust anchor.
- */
- if (val->event->type == dns_rdatatype_ds) {
- labels = dns_name_countlabels(dlvsep);
- if (labels == 0)
- return (ISC_R_NOTFOUND);
- dns_name_getlabelsequence(dlvsep, 1, labels - 1,
- dlvsep);
- }
- } else {
- dlvsep = dns_fixedname_name(&val->dlvsep);
- labels = dns_name_countlabels(dlvsep);
- dns_name_getlabelsequence(dlvsep, 1, labels - 1, dlvsep);
- }
- dns_name_init(&noroot, NULL);
- dns_fixedname_init(&dlvfixed);
- dlvname = dns_fixedname_name(&dlvfixed);
- labels = dns_name_countlabels(dlvsep);
- if (labels == 0)
- return (ISC_R_NOTFOUND);
- dns_name_getlabelsequence(dlvsep, 0, labels - 1, &noroot);
- result = dns_name_concatenate(&noroot, val->view->dlv, dlvname, NULL);
- while (result == ISC_R_NOSPACE) {
- labels = dns_name_countlabels(dlvsep);
- dns_name_getlabelsequence(dlvsep, 1, labels - 1, dlvsep);
- dns_name_getlabelsequence(dlvsep, 0, labels - 2, &noroot);
- result = dns_name_concatenate(&noroot, val->view->dlv,
- dlvname, NULL);
- }
- if (result != ISC_R_SUCCESS) {
- validator_log(val, ISC_LOG_DEBUG(2), "DLV concatenate failed");
- return (DNS_R_NOVALIDSIG);
- }
-
- while (dns_name_countlabels(dlvname) >=
- dns_name_countlabels(val->view->dlv) + val->dlvlabels) {
- dns_name_format(dlvname, namebuf, sizeof(namebuf));
- validator_log(val, ISC_LOG_DEBUG(3), "looking for DLV %s",
- namebuf);
- result = view_find(val, dlvname, dns_rdatatype_dlv);
- if (result == ISC_R_SUCCESS) {
- if (DNS_TRUST_PENDING(val->frdataset.trust) &&
- dns_rdataset_isassociated(&val->fsigrdataset))
- {
- dns_fixedname_init(&val->fname);
- dns_name_copy(dlvname,
- dns_fixedname_name(&val->fname),
- NULL);
- result = create_validator(val,
- dns_fixedname_name(&val->fname),
- dns_rdatatype_dlv,
- &val->frdataset,
- &val->fsigrdataset,
- dlvvalidated,
- "finddlvsep");
- if (result != ISC_R_SUCCESS)
- return (result);
- return (DNS_R_WAIT);
- }
- 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);
- }
- if (result == ISC_R_NOTFOUND) {
- result = create_fetch(val, dlvname, dns_rdatatype_dlv,
- dlvfetched, "finddlvsep");
- if (result != ISC_R_SUCCESS)
- return (result);
- return (DNS_R_WAIT);
- }
- if (result != DNS_R_NXRRSET &&
- result != DNS_R_NXDOMAIN &&
- result != DNS_R_EMPTYNAME &&
- result != DNS_R_NCACHENXRRSET &&
- result != DNS_R_NCACHENXDOMAIN)
- return (result);
- /*
- * Strip first labels from both dlvsep and dlvname.
- */
- labels = dns_name_countlabels(dlvsep);
- if (labels == 0)
- break;
- dns_name_getlabelsequence(dlvsep, 1, labels - 1, dlvsep);
- labels = dns_name_countlabels(dlvname);
- dns_name_getlabelsequence(dlvname, 1, labels - 1, dlvname);
- }
- return (ISC_R_NOTFOUND);
-}
-
-/*%
- * proveunsecure walks down from the SEP looking for a break in the
- * chain of trust. That occurs when we can prove the DS record does
- * not exist at a delegation point or the DS exists at a delegation
- * but we don't support the algorithm/digest.
- *
- * If DLV is active and we look for a DLV record at or below the
- * point we go insecure. If found we restart the validation process.
- * If not found or DLV isn't active we mark the response as a answer.
- *
- * Returns:
- * \li ISC_R_SUCCESS val->event->name is in a unsecure zone
- * \li DNS_R_WAIT validation is in progress.
- * \li DNS_R_MUSTBESECURE val->event->name is supposed to be secure
- * (policy) but we proved that it is unsecure.
- * \li DNS_R_NOVALIDSIG
- * \li DNS_R_NOVALIDNSEC
- * \li DNS_R_NOTINSECURE
- * \li DNS_R_BROKENCHAIN
- */
-static isc_result_t
-proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
-{
- isc_result_t result;
- dns_fixedname_t fixedsecroot;
- dns_name_t *secroot;
- dns_name_t *tname;
- char namebuf[DNS_NAME_FORMATSIZE];
- dns_name_t *found;
- dns_fixedname_t fixedfound;
-
- dns_fixedname_init(&fixedsecroot);
- secroot = dns_fixedname_name(&fixedsecroot);
- dns_fixedname_init(&fixedfound);
- found = dns_fixedname_name(&fixedfound);
- if (val->havedlvsep)
- dns_name_copy(dns_fixedname_name(&val->dlvsep), secroot, NULL);
- else {
- unsigned int labels;
- dns_name_copy(val->event->name, secroot, NULL);
- /*
- * If this is a response to a DS query, we need to look in
- * the parent zone for the trust anchor.
- */
-
- labels = dns_name_countlabels(secroot);
- if (val->event->type == dns_rdatatype_ds && labels > 1U)
- dns_name_getlabelsequence(secroot, 1, labels - 1,
- secroot);
- result = dns_keytable_finddeepestmatch(val->keytable,
- secroot, secroot);
- if (result == ISC_R_NOTFOUND) {
- if (val->mustbesecure) {
- validator_log(val, ISC_LOG_WARNING,
- "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);
- }
- return (startfinddlvsep(val, dns_rootname));
- } else if (result != ISC_R_SUCCESS)
- return (result);
- }
-
- if (!resume) {
- /*
- * We are looking for breaks below the SEP so add a label.
- */
- val->labels = dns_name_countlabels(secroot) + 1;
- } else {
- validator_log(val, ISC_LOG_DEBUG(3), "resuming proveunsecure");
- /*
- * 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 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 &&
- !check_ds(val, dns_fixedname_name(&val->fname),
- &val->frdataset)) {
- dns_name_format(dns_fixedname_name(&val->fname),
- namebuf, sizeof(namebuf));
- if ((val->view->dlv == NULL || DLVTRIED(val)) &&
- val->mustbesecure) {
- validator_log(val, ISC_LOG_WARNING,
- "must be secure failure at '%s', "
- "can't fall back to DLV",
- namebuf);
- result = DNS_R_MUSTBESECURE;
- goto out;
- }
- validator_log(val, ISC_LOG_DEBUG(3),
- "no supported algorithm/digest (%s/DS)",
- namebuf);
- if (val->view->dlv == NULL || DLVTRIED(val)) {
- markanswer(val, "proveunsecure (2)");
- result = ISC_R_SUCCESS;
- goto out;
- }
- return(startfinddlvsep(val,
- dns_fixedname_name(&val->fname)));
- }
- val->labels++;
- }
-
- for (;
- val->labels <= dns_name_countlabels(val->event->name);
- val->labels++)
- {
-
- dns_fixedname_init(&val->fname);
- tname = dns_fixedname_name(&val->fname);
- if (val->labels == dns_name_countlabels(val->event->name))
- dns_name_copy(val->event->name, tname, NULL);
- else
- dns_name_split(val->event->name, val->labels,
- NULL, tname);
-
- dns_name_format(tname, namebuf, sizeof(namebuf));
- validator_log(val, ISC_LOG_DEBUG(3),
- "checking existence of DS at '%s'",
- namebuf);
-
- result = view_find(val, tname, dns_rdatatype_ds);
- if (result == DNS_R_NXRRSET || result == DNS_R_NCACHENXRRSET) {
- /*
- * There is no DS. If this is a delegation,
- * we may be done.
- */
- /*
- * If we have "trust == answer" then this namespace
- * has switched from insecure to should be secure.
- */
- if (DNS_TRUST_PENDING(val->frdataset.trust) ||
- DNS_TRUST_ANSWER(val->frdataset.trust)) {
- result = create_validator(val, tname,
- dns_rdatatype_ds,
- &val->frdataset,
- NULL, dsvalidated,
- "proveunsecure");
- if (result != ISC_R_SUCCESS)
- goto out;
- return (DNS_R_WAIT);
- }
- /*
- * Zones using NSEC3 don't return a NSEC RRset so
- * we need to use dns_view_findzonecut2 to find
- * the zone cut.
- */
- 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 &&
- dns_name_equal(tname, found)) {
- if (val->mustbesecure) {
- validator_log(val, ISC_LOG_WARNING,
- "must be secure failure, "
- "no DS at zone cut");
- return (DNS_R_MUSTBESECURE);
- }
- if (val->view->dlv == NULL || DLVTRIED(val)) {
- markanswer(val, "proveunsecure (3)");
- return (ISC_R_SUCCESS);
- }
- return (startfinddlvsep(val, tname));
- }
- if (val->frdataset.trust < dns_trust_secure) {
- /*
- * This shouldn't happen, since the negative
- * response should have been validated. Since
- * 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, "
- "%s is a delegation",
- namebuf);
- return (DNS_R_MUSTBESECURE);
- }
- if (val->view->dlv == NULL || DLVTRIED(val)) {
- markanswer(val, "proveunsecure (4)");
- return (ISC_R_SUCCESS);
- }
- return (startfinddlvsep(val, tname));
- }
- continue;
- } else if (result == DNS_R_CNAME) {
- if (DNS_TRUST_PENDING(val->frdataset.trust) ||
- DNS_TRUST_ANSWER(val->frdataset.trust)) {
- result = create_validator(val, tname,
- dns_rdatatype_cname,
- &val->frdataset,
- NULL, cnamevalidated,
- "proveunsecure "
- "(cname)");
- if (result != ISC_R_SUCCESS)
- goto out;
- return (DNS_R_WAIT);
- }
- continue;
- } else if (result == ISC_R_SUCCESS) {
- /*
- * There is a DS here. Verify that it's secure and
- * continue.
- */
- if (val->frdataset.trust >= dns_trust_secure) {
- if (!check_ds(val, tname, &val->frdataset)) {
- validator_log(val, ISC_LOG_DEBUG(3),
- "no supported algorithm/"
- "digest (%s/DS)", namebuf);
- if (val->mustbesecure) {
- validator_log(val,
- ISC_LOG_WARNING,
- "must be secure failure, "
- "no supported algorithm/"
- "digest (%s/DS)",
- namebuf);
- result = DNS_R_MUSTBESECURE;
- goto out;
- }
- if (val->view->dlv == NULL ||
- DLVTRIED(val)) {
- markanswer(val,
- "proveunsecure (5)");
- result = ISC_R_SUCCESS;
- goto out;
- }
- return(startfinddlvsep(val, tname));
- }
- continue;
- }
- else if (!dns_rdataset_isassociated(&val->fsigrdataset))
- {
- validator_log(val, ISC_LOG_DEBUG(3),
- "DS is unsigned");
- result = DNS_R_NOVALIDSIG;
- goto out;
- }
- /*
- * Validate / re-validate answer.
- */
- result = create_validator(val, tname, dns_rdatatype_ds,
- &val->frdataset,
- &val->fsigrdataset,
- dsvalidated,
- "proveunsecure");
- if (result != ISC_R_SUCCESS)
- goto out;
- return (DNS_R_WAIT);
- } else if (result == DNS_R_NXDOMAIN ||
- result == DNS_R_NCACHENXDOMAIN) {
- /*
- * This is not a zone cut. Assuming things are
- * as expected, continue.
- */
- if (!dns_rdataset_isassociated(&val->frdataset)) {
- /*
- * There should be an NSEC here, since we
- * are still in a secure zone.
- */
- result = DNS_R_NOVALIDNSEC;
- goto out;
- } else if (DNS_TRUST_PENDING(val->frdataset.trust) ||
- DNS_TRUST_ANSWER(val->frdataset.trust)) {
- /*
- * If we have "trust == answer" then this namespace
- * has switched from insecure to should be secure.
- */
- result = create_validator(val, tname,
- dns_rdatatype_ds,
- &val->frdataset,
- NULL, dsvalidated,
- "proveunsecure");
- if (result != ISC_R_SUCCESS)
- goto out;
- return (DNS_R_WAIT);
- } else if (val->frdataset.trust < dns_trust_secure) {
- /*
- * This shouldn't happen, since the negative
- * response should have been validated. Since
- * 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;
- }
- continue;
- } else if (result == ISC_R_NOTFOUND) {
- /*
- * We don't know anything about the DS. Find it.
- */
- result = create_fetch(val, tname, dns_rdatatype_ds,
- dsfetched2, "proveunsecure");
- if (result != ISC_R_SUCCESS)
- goto out;
- return (DNS_R_WAIT);
- } else if (result == DNS_R_BROKENCHAIN)
- return (result);
- }
-
- /* Couldn't complete insecurity proof */
- validator_log(val, ISC_LOG_DEBUG(3), "insecurity proof failed");
- return (DNS_R_NOTINSECURE);
-
- out:
- if (dns_rdataset_isassociated(&val->frdataset))
- dns_rdataset_disassociate(&val->frdataset);
- if (dns_rdataset_isassociated(&val->fsigrdataset))
- dns_rdataset_disassociate(&val->fsigrdataset);
- return (result);
-}
-
-/*%
- * Reset state and revalidate the answer using DLV.
- */
-static void
-dlv_validator_start(dns_validator_t *val) {
- isc_event_t *event;
-
- validator_log(val, ISC_LOG_DEBUG(3), "dlv_validator_start");
-
- /*
- * Reset state and try again.
- */
- val->attributes &= VALATTR_DLVTRIED;
- val->options &= ~DNS_VALIDATOR_DLV;
-
- event = (isc_event_t *)val->event;
- isc_task_send(val->task, &event);
-}
-
-/*%
- * Start the validation process.
- *
- * Attempt to validate the answer based on the category it appears to
- * fall in.
- * \li 1. secure positive answer.
- * \li 2. unsecure positive answer.
- * \li 3. a negative answer (secure or unsecure).
- *
- * Note a answer that appears to be a secure positive answer may actually
- * be an unsecure positive answer.
- */
-static void
-validator_start(isc_task_t *task, isc_event_t *event) {
- dns_validator_t *val;
- dns_validatorevent_t *vevent;
- isc_boolean_t want_destroy = ISC_FALSE;
- isc_result_t result = ISC_R_FAILURE;
-
- UNUSED(task);
- REQUIRE(event->ev_type == DNS_EVENT_VALIDATORSTART);
- vevent = (dns_validatorevent_t *)event;
- val = vevent->validator;
-
- /* If the validator has been canceled, val->event == NULL */
- if (val->event == NULL)
- return;
-
- if (DLVTRIED(val))
- validator_log(val, ISC_LOG_DEBUG(3), "restarting using DLV");
- else
- validator_log(val, ISC_LOG_DEBUG(3), "starting");
-
- LOCK(&val->lock);
-
- if ((val->options & DNS_VALIDATOR_DLV) != 0 &&
- val->event->rdataset != NULL) {
- validator_log(val, ISC_LOG_DEBUG(3), "looking for DLV");
- result = startfinddlvsep(val, dns_rootname);
- } else if (val->event->rdataset != NULL &&
- val->event->sigrdataset != NULL) {
- isc_result_t saved_result;
-
- /*
- * This looks like a simple validation. We say "looks like"
- * because it might end up requiring an insecurity proof.
- */
- validator_log(val, ISC_LOG_DEBUG(3),
- "attempting positive response validation");
-
- INSIST(dns_rdataset_isassociated(val->event->rdataset));
- INSIST(dns_rdataset_isassociated(val->event->sigrdataset));
- result = start_positive_validation(val);
- if (result == DNS_R_NOVALIDSIG &&
- (val->attributes & VALATTR_TRIEDVERIFY) == 0)
- {
- saved_result = result;
- validator_log(val, ISC_LOG_DEBUG(3),
- "falling back to insecurity proof");
- val->attributes |= VALATTR_INSECURITY;
- result = proveunsecure(val, ISC_FALSE, ISC_FALSE);
- if (result == DNS_R_NOTINSECURE)
- result = saved_result;
- }
- } else if (val->event->rdataset != NULL &&
- val->event->rdataset->type != 0) {
- /*
- * This is either an unsecure subdomain or a response from
- * a broken server.
- */
- INSIST(dns_rdataset_isassociated(val->event->rdataset));
- validator_log(val, ISC_LOG_DEBUG(3),
- "attempting insecurity proof");
-
- 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)
- {
- /*
- * This is a nonexistence validation.
- */
- validator_log(val, ISC_LOG_DEBUG(3),
- "attempting negative response validation");
-
- if (val->event->message->rcode == dns_rcode_nxdomain) {
- val->attributes |= VALATTR_NEEDNOQNAME;
- val->attributes |= VALATTR_NEEDNOWILDCARD;
- } else
- val->attributes |= VALATTR_NEEDNODATA;
- result = nsecvalidate(val, ISC_FALSE);
- } else if (val->event->rdataset != NULL &&
- NEGATIVE(val->event->rdataset))
- {
- /*
- * This is a nonexistence validation.
- */
- validator_log(val, ISC_LOG_DEBUG(3),
- "attempting negative response validation");
-
- if (val->event->rdataset->covers == dns_rdatatype_any) {
- val->attributes |= VALATTR_NEEDNOQNAME;
- val->attributes |= VALATTR_NEEDNOWILDCARD;
- } else
- val->attributes |= VALATTR_NEEDNODATA;
- result = nsecvalidate(val, ISC_FALSE);
- } else {
- /*
- * This shouldn't happen.
- */
- INSIST(0);
- }
-
- if (result != DNS_R_WAIT) {
- want_destroy = exit_check(val);
- validator_done(val, result);
- }
-
- UNLOCK(&val->lock);
- if (want_destroy)
- destroy(val);
-}
-
-isc_result_t
-dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
- dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
- dns_message_t *message, unsigned int options,
- isc_task_t *task, isc_taskaction_t action, void *arg,
- dns_validator_t **validatorp)
-{
- isc_result_t result = ISC_R_FAILURE;
- dns_validator_t *val;
- isc_task_t *tclone = NULL;
- dns_validatorevent_t *event;
-
- REQUIRE(name != NULL);
- REQUIRE(rdataset != NULL ||
- (rdataset == NULL && sigrdataset == NULL && message != NULL));
- REQUIRE(validatorp != NULL && *validatorp == NULL);
-
- val = isc_mem_get(view->mctx, sizeof(*val));
- if (val == NULL)
- 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,
- validator_start, NULL,
- sizeof(dns_validatorevent_t));
- if (event == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup_val;
- }
- isc_task_attach(task, &tclone);
- event->validator = val;
- event->result = ISC_R_FAILURE;
- event->name = name;
- event->type = type;
- event->rdataset = rdataset;
- event->sigrdataset = sigrdataset;
- event->message = message;
- memset(event->proofs, 0, sizeof(event->proofs));
- event->optout = ISC_FALSE;
- event->secure = ISC_FALSE;
- result = isc_mutex_init(&val->lock);
- if (result != ISC_R_SUCCESS)
- goto cleanup_event;
- val->event = event;
- val->options = options;
- val->attributes = 0;
- val->fetch = NULL;
- val->subvalidator = NULL;
- val->parent = NULL;
-
- val->keytable = NULL;
- result = dns_view_getsecroots(val->view, &val->keytable);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- val->keynode = NULL;
- val->key = NULL;
- val->siginfo = NULL;
- val->task = task;
- val->action = action;
- val->arg = arg;
- val->labels = 0;
- val->currentset = NULL;
- val->keyset = NULL;
- val->dsset = NULL;
- dns_rdataset_init(&val->dlv);
- val->seensig = ISC_FALSE;
- val->havedlvsep = ISC_FALSE;
- val->depth = 0;
- val->authcount = 0;
- val->authfail = 0;
- val->mustbesecure = dns_resolver_getmustbesecure(view->resolver, name);
- dns_rdataset_init(&val->frdataset);
- dns_rdataset_init(&val->fsigrdataset);
- dns_fixedname_init(&val->wild);
- dns_fixedname_init(&val->nearest);
- dns_fixedname_init(&val->closest);
- ISC_LINK_INIT(val, link);
- val->magic = VALIDATOR_MAGIC;
-
- if ((options & DNS_VALIDATOR_DEFER) == 0)
- isc_task_send(task, ISC_EVENT_PTR(&event));
-
- *validatorp = val;
-
- return (ISC_R_SUCCESS);
-
- cleanup_event:
- isc_task_detach(&tclone);
- isc_event_free(ISC_EVENT_PTR(&event));
-
- cleanup_val:
- dns_view_weakdetach(&val->view);
- isc_mem_put(view->mctx, val, sizeof(*val));
-
- return (result);
-}
-
-void
-dns_validator_send(dns_validator_t *validator) {
- isc_event_t *event;
- REQUIRE(VALID_VALIDATOR(validator));
-
- LOCK(&validator->lock);
-
- INSIST((validator->options & DNS_VALIDATOR_DEFER) != 0);
- event = (isc_event_t *)validator->event;
- validator->options &= ~DNS_VALIDATOR_DEFER;
- UNLOCK(&validator->lock);
-
- isc_task_send(validator->task, ISC_EVENT_PTR(&event));
-}
-
-void
-dns_validator_cancel(dns_validator_t *validator) {
- dns_fetch_t *fetch = NULL;
-
- REQUIRE(VALID_VALIDATOR(validator));
-
- LOCK(&validator->lock);
-
- validator_log(validator, ISC_LOG_DEBUG(3), "dns_validator_cancel");
-
- if ((validator->attributes & VALATTR_CANCELED) == 0) {
- validator->attributes |= VALATTR_CANCELED;
- if (validator->event != NULL) {
- fetch = validator->fetch;
- validator->fetch = NULL;
-
- if (validator->subvalidator != NULL)
- dns_validator_cancel(validator->subvalidator);
- if ((validator->options & DNS_VALIDATOR_DEFER) != 0) {
- validator->options &= ~DNS_VALIDATOR_DEFER;
- validator_done(validator, ISC_R_CANCELED);
- }
- }
- }
- UNLOCK(&validator->lock);
-
- /* Need to cancel and destroy the fetch outside validator lock */
- if (fetch != NULL) {
- dns_resolver_cancelfetch(fetch);
- dns_resolver_destroyfetch(&fetch);
- }
-}
-
-static void
-destroy(dns_validator_t *val) {
- isc_mem_t *mctx;
-
- REQUIRE(SHUTDOWN(val));
- REQUIRE(val->event == NULL);
- REQUIRE(val->fetch == NULL);
-
- if (val->keynode != NULL)
- dns_keytable_detachkeynode(val->keytable, &val->keynode);
- else if (val->key != NULL)
- dst_key_free(&val->key);
- if (val->keytable != NULL)
- dns_keytable_detach(&val->keytable);
- if (val->subvalidator != NULL)
- dns_validator_destroy(&val->subvalidator);
- if (val->havedlvsep)
- dns_rdataset_disassociate(&val->dlv);
- if (dns_rdataset_isassociated(&val->frdataset))
- dns_rdataset_disassociate(&val->frdataset);
- if (dns_rdataset_isassociated(&val->fsigrdataset))
- dns_rdataset_disassociate(&val->fsigrdataset);
- mctx = val->view->mctx;
- if (val->siginfo != NULL)
- isc_mem_put(mctx, val->siginfo, sizeof(*val->siginfo));
- DESTROYLOCK(&val->lock);
- dns_view_weakdetach(&val->view);
- val->magic = 0;
- isc_mem_put(mctx, val, sizeof(*val));
-}
-
-void
-dns_validator_destroy(dns_validator_t **validatorp) {
- dns_validator_t *val;
- isc_boolean_t want_destroy = ISC_FALSE;
-
- REQUIRE(validatorp != NULL);
- val = *validatorp;
- REQUIRE(VALID_VALIDATOR(val));
-
- LOCK(&val->lock);
-
- val->attributes |= VALATTR_SHUTDOWN;
- validator_log(val, ISC_LOG_DEBUG(3), "dns_validator_destroy");
-
- want_destroy = exit_check(val);
-
- UNLOCK(&val->lock);
-
- if (want_destroy)
- destroy(val);
-
- *validatorp = NULL;
-}
-
-static void
-validator_logv(dns_validator_t *val, isc_logcategory_t *category,
- isc_logmodule_t *module, int level, const char *fmt, va_list ap)
-{
- char msgbuf[2048];
- static const char spaces[] = " *";
- int depth = val->depth * 2;
-
- vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
-
- if ((unsigned int) depth >= sizeof spaces)
- depth = sizeof spaces - 1;
-
- if (val->event != NULL && val->event->name != NULL) {
- char namebuf[DNS_NAME_FORMATSIZE];
- char typebuf[DNS_RDATATYPE_FORMATSIZE];
-
- dns_name_format(val->event->name, namebuf, sizeof(namebuf));
- dns_rdatatype_format(val->event->type, typebuf,
- sizeof(typebuf));
- isc_log_write(dns_lctx, category, module, level,
- "%.*svalidating @%p: %s %s: %s", depth, spaces,
- val, namebuf, typebuf, msgbuf);
- } else {
- isc_log_write(dns_lctx, category, module, level,
- "%.*svalidator @%p: %s", depth, spaces,
- val, msgbuf);
- }
-}
-
-static void
-validator_log(void *val, int level, const char *fmt, ...) {
- va_list ap;
-
- if (! isc_log_wouldlog(dns_lctx, level))
- return;
-
- va_start(ap, fmt);
-
- validator_logv(val, DNS_LOGCATEGORY_DNSSEC,
- DNS_LOGMODULE_VALIDATOR, level, fmt, ap);
- va_end(ap);
-}
-
-static void
-validator_logcreate(dns_validator_t *val,
- dns_name_t *name, dns_rdatatype_t type,
- const char *caller, const char *operation)
-{
- char namestr[DNS_NAME_FORMATSIZE];
- char typestr[DNS_RDATATYPE_FORMATSIZE];
-
- dns_name_format(name, namestr, sizeof(namestr));
- dns_rdatatype_format(type, typestr, sizeof(typestr));
- validator_log(val, ISC_LOG_DEBUG(9), "%s: creating %s for %s %s",
- caller, operation, namestr, typestr);
-}
diff --git a/contrib/bind9/lib/dns/version.c b/contrib/bind9/lib/dns/version.c
deleted file mode 100644
index fbc8889bd565..000000000000
--- a/contrib/bind9/lib/dns/version.c
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-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: version.c,v 1.15 2007/06/19 23:47:16 tbox Exp $ */
-
-/*! \file */
-
-#include <dns/version.h>
-
-const char dns_version[] = VERSION;
-
-const unsigned int dns_libinterface = LIBINTERFACE;
-const unsigned int dns_librevision = LIBREVISION;
-const unsigned int dns_libage = LIBAGE;
diff --git a/contrib/bind9/lib/dns/view.c b/contrib/bind9/lib/dns/view.c
deleted file mode 100644
index 9c1a201a8bd9..000000000000
--- a/contrib/bind9/lib/dns/view.c
+++ /dev/null
@@ -1,1845 +0,0 @@
-/*
- * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/*! \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>
-#include <isc/util.h>
-
-#include <dns/acache.h>
-#include <dns/acl.h>
-#include <dns/adb.h>
-#include <dns/cache.h>
-#include <dns/db.h>
-#include <dns/dispatch.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>
-#include <dns/zt.h>
-
-#define RESSHUTDOWN(v) (((v)->attributes & DNS_VIEWATTR_RESSHUTDOWN) != 0)
-#define ADBSHUTDOWN(v) (((v)->attributes & DNS_VIEWATTR_ADBSHUTDOWN) != 0)
-#define REQSHUTDOWN(v) (((v)->attributes & DNS_VIEWATTR_REQSHUTDOWN) != 0)
-
-#define DNS_VIEW_DELONLYHASH 111
-
-static void resolver_shutdown(isc_task_t *task, isc_event_t *event);
-static void adb_shutdown(isc_task_t *task, isc_event_t *event);
-static void req_shutdown(isc_task_t *task, isc_event_t *event);
-
-isc_result_t
-dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
- const char *name, dns_view_t **viewp)
-{
- dns_view_t *view;
- isc_result_t result;
-
- /*
- * Create a view.
- */
-
- REQUIRE(name != NULL);
- REQUIRE(viewp != NULL && *viewp == NULL);
-
- view = isc_mem_get(mctx, sizeof(*view));
- if (view == NULL)
- return (ISC_R_NOMEMORY);
-
- view->mctx = NULL;
- isc_mem_attach(mctx, &view->mctx);
- view->name = isc_mem_strdup(mctx, name);
- if (view->name == NULL) {
- result = ISC_R_NOMEMORY;
- goto cleanup_view;
- }
- result = isc_mutex_init(&view->lock);
- if (result != ISC_R_SUCCESS)
- goto cleanup_name;
-
- view->zonetable = NULL;
-#ifdef BIND9
- result = dns_zt_create(mctx, rdclass, &view->zonetable);
- if (result != ISC_R_SUCCESS) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "dns_zt_create() failed: %s",
- isc_result_totext(result));
- result = ISC_R_UNEXPECTED;
- goto cleanup_mutex;
- }
-#endif
- view->secroots_priv = NULL;
- view->fwdtable = NULL;
- result = dns_fwdtable_create(mctx, &view->fwdtable);
- if (result != ISC_R_SUCCESS) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "dns_fwdtable_create() failed: %s",
- isc_result_totext(result));
- result = ISC_R_UNEXPECTED;
- goto cleanup_zt;
- }
-
- view->acache = NULL;
- view->cache = NULL;
- view->cachedb = NULL;
- view->dlzdatabase = NULL;
- view->hints = NULL;
- view->resolver = NULL;
- view->adb = NULL;
- view->requestmgr = NULL;
- view->rdclass = rdclass;
- view->frozen = ISC_FALSE;
- view->task = NULL;
- result = isc_refcount_init(&view->references, 1);
- if (result != ISC_R_SUCCESS)
- goto cleanup_fwdtable;
- view->weakrefs = 0;
- view->attributes = (DNS_VIEWATTR_RESSHUTDOWN|DNS_VIEWATTR_ADBSHUTDOWN|
- DNS_VIEWATTR_REQSHUTDOWN);
- view->statickeys = NULL;
- view->dynamickeys = NULL;
- view->matchclients = NULL;
- view->matchdestinations = NULL;
- view->matchrecursiveonly = ISC_FALSE;
- result = dns_tsigkeyring_create(view->mctx, &view->dynamickeys);
- if (result != ISC_R_SUCCESS)
- goto cleanup_references;
- view->peers = NULL;
- view->order = NULL;
- view->delonly = NULL;
- view->rootdelonly = ISC_FALSE;
- 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.
- */
- view->recursion = ISC_TRUE;
- view->auth_nxdomain = ISC_FALSE; /* Was true in BIND 8 */
- view->additionalfromcache = ISC_TRUE;
- view->additionalfromauth = ISC_TRUE;
- view->enablednssec = ISC_TRUE;
- view->enablevalidation = ISC_TRUE;
- view->acceptexpired = ISC_FALSE;
- view->minimalresponses = ISC_FALSE;
- view->transfer_format = dns_one_answer;
- view->cacheacl = NULL;
- view->cacheonacl = NULL;
- view->queryacl = NULL;
- view->queryonacl = NULL;
- view->recursionacl = NULL;
- view->recursiononacl = NULL;
- view->sortlist = NULL;
- view->transferacl = NULL;
- view->notifyacl = NULL;
- view->updateacl = NULL;
- view->upfwdacl = NULL;
- view->denyansweracl = NULL;
- view->answeracl_exclude = NULL;
- view->denyanswernames = NULL;
- view->answernames_exclude = NULL;
- view->provideixfr = ISC_TRUE;
- view->maxcachettl = 7 * 24 * 3600;
- view->maxncachettl = 3 * 3600;
- view->dstport = 53;
- view->preferred_glue = 0;
- view->flush = ISC_FALSE;
- view->dlv = NULL;
- view->maxudp = 0;
- view->maxbits = 0;
- view->v4_aaaa = dns_v4_aaaa_ok;
- view->v4_aaaa_acl = NULL;
- ISC_LIST_INIT(view->rpz_zones);
- view->rpz_recursive_only = ISC_TRUE;
- view->rpz_break_dnssec = ISC_FALSE;
- dns_fixedname_init(&view->dlv_fixed);
- view->managed_keys = NULL;
- view->redirect = NULL;
-#ifdef BIND9
- view->new_zone_file = NULL;
- view->new_zone_config = NULL;
- 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)
- goto cleanup_order;
-
- result = dns_aclenv_init(view->mctx, &view->aclenv);
- if (result != ISC_R_SUCCESS)
- goto cleanup_peerlist;
-
- ISC_LINK_INIT(view, link);
- ISC_EVENT_INIT(&view->resevent, sizeof(view->resevent), 0, NULL,
- DNS_EVENT_VIEWRESSHUTDOWN, resolver_shutdown,
- view, NULL, NULL, NULL);
- ISC_EVENT_INIT(&view->adbevent, sizeof(view->adbevent), 0, NULL,
- DNS_EVENT_VIEWADBSHUTDOWN, adb_shutdown,
- view, NULL, NULL, NULL);
- ISC_EVENT_INIT(&view->reqevent, sizeof(view->reqevent), 0, NULL,
- DNS_EVENT_VIEWREQSHUTDOWN, req_shutdown,
- view, NULL, NULL, NULL);
- view->viewlist = NULL;
- view->magic = DNS_VIEW_MAGIC;
-
- *viewp = view;
-
- return (ISC_R_SUCCESS);
-
- cleanup_peerlist:
- dns_peerlist_detach(&view->peers);
-
- cleanup_order:
-#ifdef BIND9
- dns_order_detach(&view->order);
-
- cleanup_dynkeys:
-#endif
- dns_tsigkeyring_detach(&view->dynamickeys);
-
- cleanup_references:
- isc_refcount_destroy(&view->references);
-
- cleanup_fwdtable:
- dns_fwdtable_destroy(&view->fwdtable);
-
- cleanup_zt:
-#ifdef BIND9
- dns_zt_detach(&view->zonetable);
-
- cleanup_mutex:
-#endif
- DESTROYLOCK(&view->lock);
-
- cleanup_name:
- isc_mem_free(mctx, view->name);
-
- cleanup_view:
- isc_mem_putanddetach(&view->mctx, view, sizeof(*view));
-
- return (result);
-}
-
-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);
- REQUIRE(RESSHUTDOWN(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) {
- 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_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)
- isc_task_detach(&view->task);
- if (view->hints != NULL)
- dns_db_detach(&view->hints);
- if (view->dlzdatabase != NULL)
- dns_dlzdestroy(&view->dlzdatabase);
- if (view->cachedb != NULL)
- dns_db_detach(&view->cachedb);
- if (view->cache != NULL)
- dns_cache_detach(&view->cache);
- if (view->matchclients != NULL)
- dns_acl_detach(&view->matchclients);
- if (view->matchdestinations != NULL)
- dns_acl_detach(&view->matchdestinations);
- if (view->cacheacl != NULL)
- dns_acl_detach(&view->cacheacl);
- if (view->cacheonacl != NULL)
- dns_acl_detach(&view->cacheonacl);
- if (view->queryacl != NULL)
- dns_acl_detach(&view->queryacl);
- if (view->queryonacl != NULL)
- dns_acl_detach(&view->queryonacl);
- if (view->recursionacl != NULL)
- dns_acl_detach(&view->recursionacl);
- if (view->recursiononacl != NULL)
- dns_acl_detach(&view->recursiononacl);
- if (view->sortlist != NULL)
- dns_acl_detach(&view->sortlist);
- if (view->transferacl != NULL)
- dns_acl_detach(&view->transferacl);
- if (view->notifyacl != NULL)
- dns_acl_detach(&view->notifyacl);
- if (view->updateacl != NULL)
- 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;
-
- for (i = 0; i < DNS_VIEW_DELONLYHASH; i++) {
- name = ISC_LIST_HEAD(view->delonly[i]);
- while (name != NULL) {
- ISC_LIST_UNLINK(view->delonly[i], name, link);
- dns_name_free(name, view->mctx);
- isc_mem_put(view->mctx, name, sizeof(*name));
- name = ISC_LIST_HEAD(view->delonly[i]);
- }
- }
- isc_mem_put(view->mctx, view->delonly, sizeof(dns_namelist_t) *
- DNS_VIEW_DELONLYHASH);
- view->delonly = NULL;
- }
- if (view->rootexclude != NULL) {
- dns_name_t *name;
- int i;
-
- for (i = 0; i < DNS_VIEW_DELONLYHASH; i++) {
- name = ISC_LIST_HEAD(view->rootexclude[i]);
- while (name != NULL) {
- ISC_LIST_UNLINK(view->rootexclude[i],
- name, link);
- dns_name_free(name, view->mctx);
- isc_mem_put(view->mctx, name, sizeof(*name));
- name = ISC_LIST_HEAD(view->rootexclude[i]);
- }
- }
- isc_mem_put(view->mctx, view->rootexclude,
- sizeof(dns_namelist_t) * DNS_VIEW_DELONLYHASH);
- view->rootexclude = NULL;
- }
- if (view->resstats != NULL)
- isc_stats_detach(&view->resstats);
- if (view->resquerystats != NULL)
- dns_stats_detach(&view->resquerystats);
- 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);
- if (view->redirect != NULL)
- dns_zone_detach(&view->redirect);
- dns_view_setnewzones(view, ISC_FALSE, NULL, NULL);
-#endif
- dns_fwdtable_destroy(&view->fwdtable);
- dns_aclenv_destroy(&view->aclenv);
- DESTROYLOCK(&view->lock);
- isc_refcount_destroy(&view->references);
- isc_mem_free(view->mctx, view->name);
- isc_mem_putanddetach(&view->mctx, view, sizeof(*view));
-}
-
-/*
- * Return true iff 'view' may be freed.
- * The caller must be holding the view lock.
- */
-static isc_boolean_t
-all_done(dns_view_t *view) {
-
- if (isc_refcount_current(&view->references) == 0 &&
- view->weakrefs == 0 &&
- RESSHUTDOWN(view) && ADBSHUTDOWN(view) && REQSHUTDOWN(view))
- return (ISC_TRUE);
-
- return (ISC_FALSE);
-}
-
-void
-dns_view_attach(dns_view_t *source, dns_view_t **targetp) {
-
- REQUIRE(DNS_VIEW_VALID(source));
- REQUIRE(targetp != NULL && *targetp == NULL);
-
- isc_refcount_increment(&source->references, NULL);
-
- *targetp = source;
-}
-
-static void
-view_flushanddetach(dns_view_t **viewp, isc_boolean_t flush) {
- dns_view_t *view;
- unsigned int refs;
- isc_boolean_t done = ISC_FALSE;
-
- REQUIRE(viewp != NULL);
- view = *viewp;
- REQUIRE(DNS_VIEW_VALID(view));
-
- if (flush)
- view->flush = ISC_TRUE;
- isc_refcount_decrement(&view->references, &refs);
- if (refs == 0) {
-#ifdef BIND9
- dns_zone_t *mkzone = NULL, *rdzone = NULL;
-#endif
-
- LOCK(&view->lock);
- if (!RESSHUTDOWN(view))
- dns_resolver_shutdown(view->resolver);
- if (!ADBSHUTDOWN(view))
- 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) {
- mkzone = view->managed_keys;
- view->managed_keys = NULL;
- if (view->flush)
- dns_zone_flush(mkzone);
- }
- if (view->redirect != NULL) {
- rdzone = view->redirect;
- view->redirect = NULL;
- if (view->flush)
- dns_zone_flush(rdzone);
- }
-#endif
- done = all_done(view);
- UNLOCK(&view->lock);
-
-#ifdef BIND9
- /* Need to detach zones outside view lock */
- if (mkzone != NULL)
- dns_zone_detach(&mkzone);
-
- if (rdzone != NULL)
- dns_zone_detach(&rdzone);
-#endif
- }
-
- *viewp = NULL;
-
- if (done)
- destroy(view);
-}
-
-void
-dns_view_flushanddetach(dns_view_t **viewp) {
- view_flushanddetach(viewp, ISC_TRUE);
-}
-
-void
-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);
- dns_zone_dialup(zone);
- return (ISC_R_SUCCESS);
-}
-
-void
-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) {
-
- REQUIRE(DNS_VIEW_VALID(source));
- REQUIRE(targetp != NULL && *targetp == NULL);
-
- LOCK(&source->lock);
- source->weakrefs++;
- UNLOCK(&source->lock);
-
- *targetp = source;
-}
-
-void
-dns_view_weakdetach(dns_view_t **viewp) {
- dns_view_t *view;
- isc_boolean_t done = ISC_FALSE;
-
- REQUIRE(viewp != NULL);
- view = *viewp;
- REQUIRE(DNS_VIEW_VALID(view));
-
- LOCK(&view->lock);
-
- INSIST(view->weakrefs > 0);
- view->weakrefs--;
- done = all_done(view);
-
- UNLOCK(&view->lock);
-
- *viewp = NULL;
-
- if (done)
- destroy(view);
-}
-
-static void
-resolver_shutdown(isc_task_t *task, isc_event_t *event) {
- dns_view_t *view = event->ev_arg;
- isc_boolean_t done;
-
- REQUIRE(event->ev_type == DNS_EVENT_VIEWRESSHUTDOWN);
- REQUIRE(DNS_VIEW_VALID(view));
- REQUIRE(view->task == task);
-
- UNUSED(task);
-
- LOCK(&view->lock);
-
- view->attributes |= DNS_VIEWATTR_RESSHUTDOWN;
- done = all_done(view);
-
- UNLOCK(&view->lock);
-
- isc_event_free(&event);
-
- if (done)
- destroy(view);
-}
-
-static void
-adb_shutdown(isc_task_t *task, isc_event_t *event) {
- dns_view_t *view = event->ev_arg;
- isc_boolean_t done;
-
- REQUIRE(event->ev_type == DNS_EVENT_VIEWADBSHUTDOWN);
- REQUIRE(DNS_VIEW_VALID(view));
- REQUIRE(view->task == task);
-
- UNUSED(task);
-
- LOCK(&view->lock);
-
- view->attributes |= DNS_VIEWATTR_ADBSHUTDOWN;
- done = all_done(view);
-
- UNLOCK(&view->lock);
-
- isc_event_free(&event);
-
- if (done)
- destroy(view);
-}
-
-static void
-req_shutdown(isc_task_t *task, isc_event_t *event) {
- dns_view_t *view = event->ev_arg;
- isc_boolean_t done;
-
- REQUIRE(event->ev_type == DNS_EVENT_VIEWREQSHUTDOWN);
- REQUIRE(DNS_VIEW_VALID(view));
- REQUIRE(view->task == task);
-
- UNUSED(task);
-
- LOCK(&view->lock);
-
- view->attributes |= DNS_VIEWATTR_REQSHUTDOWN;
- done = all_done(view);
-
- UNLOCK(&view->lock);
-
- isc_event_free(&event);
-
- if (done)
- destroy(view);
-}
-
-isc_result_t
-dns_view_createresolver(dns_view_t *view,
- isc_taskmgr_t *taskmgr,
- unsigned int ntasks, unsigned int ndisp,
- isc_socketmgr_t *socketmgr,
- isc_timermgr_t *timermgr,
- unsigned int options,
- dns_dispatchmgr_t *dispatchmgr,
- dns_dispatch_t *dispatchv4,
- dns_dispatch_t *dispatchv6)
-{
- isc_result_t result;
- isc_event_t *event;
- isc_mem_t *mctx = NULL;
-
- REQUIRE(DNS_VIEW_VALID(view));
- REQUIRE(!view->frozen);
- REQUIRE(view->resolver == NULL);
-
- result = isc_task_create(taskmgr, 0, &view->task);
- if (result != ISC_R_SUCCESS)
- return (result);
- isc_task_setname(view->task, "view", view);
-
- result = dns_resolver_create(view, taskmgr, ntasks, ndisp, socketmgr,
- timermgr, options, dispatchmgr,
- dispatchv4, dispatchv6,
- &view->resolver);
- if (result != ISC_R_SUCCESS) {
- isc_task_detach(&view->task);
- return (result);
- }
- event = &view->resevent;
- dns_resolver_whenshutdown(view->resolver, view->task, &event);
- view->attributes &= ~DNS_VIEWATTR_RESSHUTDOWN;
-
- result = isc_mem_create(0, 0, &mctx);
- if (result != ISC_R_SUCCESS) {
- dns_resolver_shutdown(view->resolver);
- return (result);
- }
-
- result = dns_adb_create(mctx, view, timermgr, taskmgr, &view->adb);
- isc_mem_setname(mctx, "ADB", NULL);
- isc_mem_detach(&mctx);
- if (result != ISC_R_SUCCESS) {
- dns_resolver_shutdown(view->resolver);
- return (result);
- }
- event = &view->adbevent;
- dns_adb_whenshutdown(view->adb, view->task, &event);
- view->attributes &= ~DNS_VIEWATTR_ADBSHUTDOWN;
-
- result = dns_requestmgr_create(view->mctx, timermgr, socketmgr,
- dns_resolver_taskmgr(view->resolver),
- dns_resolver_dispatchmgr(view->resolver),
- dispatchv4, dispatchv6,
- &view->requestmgr);
- if (result != ISC_R_SUCCESS) {
- dns_adb_shutdown(view->adb);
- dns_resolver_shutdown(view->resolver);
- return (result);
- }
- event = &view->reqevent;
- dns_requestmgr_whenshutdown(view->requestmgr, view->task, &event);
- view->attributes &= ~DNS_VIEWATTR_REQSHUTDOWN;
-
- return (ISC_R_SUCCESS);
-}
-
-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);
- }
- dns_cache_attach(cache, &view->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
-dns_view_sethints(dns_view_t *view, dns_db_t *hints) {
- REQUIRE(DNS_VIEW_VALID(view));
- REQUIRE(!view->frozen);
- REQUIRE(view->hints == NULL);
- REQUIRE(dns_db_iszone(hints));
-
- dns_db_attach(hints, &view->hints);
-}
-
-void
-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_detach(&view->statickeys);
- dns_tsigkeyring_attach(ring, &view->statickeys);
-}
-
-void
-dns_view_setdynamickeyring(dns_view_t *view, dns_tsig_keyring_t *ring) {
- REQUIRE(DNS_VIEW_VALID(view));
- REQUIRE(ring != NULL);
- if (view->dynamickeys != NULL)
- dns_tsigkeyring_detach(&view->dynamickeys);
- dns_tsigkeyring_attach(ring, &view->dynamickeys);
-}
-
-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));
-
- 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);
- }
- }
- }
-}
-
-void
-dns_view_setdstport(dns_view_t *view, in_port_t dstport) {
- REQUIRE(DNS_VIEW_VALID(view));
- view->dstport = dstport;
-}
-
-void
-dns_view_freeze(dns_view_t *view) {
- REQUIRE(DNS_VIEW_VALID(view));
- REQUIRE(!view->frozen);
-
- if (view->resolver != NULL) {
- INSIST(view->cachedb != NULL);
- dns_resolver_freeze(view->resolver);
- }
- 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;
-
- REQUIRE(DNS_VIEW_VALID(view));
-
- if (view->zonetable != NULL) {
- result = dns_zt_find(view->zonetable, name, 0, NULL, zonep);
- if (result == DNS_R_PARTIALMATCH) {
- dns_zone_detach(zonep);
- result = ISC_R_NOTFOUND;
- }
- } else
- result = ISC_R_NOTFOUND;
-
- 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) {
- 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, is_staticstub_zone;
- dns_rdataset_t zrdataset, zsigrdataset;
- dns_zone_t *zone;
-
-#ifndef BIND9
- UNUSED(use_hints);
- UNUSED(use_static_stub);
- UNUSED(zone);
-#endif
-
- /*
- * Find an rdataset whose owner name is 'name', and whose type is
- * 'type'.
- */
-
- REQUIRE(DNS_VIEW_VALID(view));
- REQUIRE(view->frozen);
- REQUIRE(type != dns_rdatatype_rrsig);
- REQUIRE(rdataset != NULL); /* XXXBEW - remove this */
- REQUIRE(nodep == NULL || *nodep == NULL);
-
- /*
- * Initialize.
- */
- dns_rdataset_init(&zrdataset);
- dns_rdataset_init(&zsigrdataset);
- zdb = NULL;
- znode = NULL;
-
- /*
- * Find a database to answer the query.
- */
- db = NULL;
- node = NULL;
- is_staticstub_zone = ISC_FALSE;
-#ifdef BIND9
- zone = NULL;
- 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;
-
- is_cache = dns_db_iscache(db);
-
- db_find:
- /*
- * Now look for an answer in the database.
- */
- result = dns_db_find(db, name, NULL, type, options,
- now, &node, foundname, rdataset, sigrdataset);
-
- if (result == DNS_R_DELEGATION || result == ISC_R_NOTFOUND) {
- if (dns_rdataset_isassociated(rdataset))
- dns_rdataset_disassociate(rdataset);
- if (sigrdataset != NULL &&
- dns_rdataset_isassociated(sigrdataset))
- dns_rdataset_disassociate(sigrdataset);
- if (node != NULL)
- dns_db_detachnode(db, &node);
- if (!is_cache) {
- dns_db_detach(&db);
- 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);
- goto db_find;
- }
- } else {
- /*
- * We don't have the data in the cache. If we've got
- * glue from the zone, use it.
- */
- if (dns_rdataset_isassociated(&zrdataset)) {
- dns_rdataset_clone(&zrdataset, rdataset);
- if (sigrdataset != NULL &&
- dns_rdataset_isassociated(&zsigrdataset))
- dns_rdataset_clone(&zsigrdataset,
- sigrdataset);
- result = DNS_R_GLUE;
- if (db != NULL)
- dns_db_detach(&db);
- dns_db_attach(zdb, &db);
- dns_db_attachnode(db, znode, &node);
- goto cleanup;
- }
- }
- /*
- * We don't know the answer.
- */
- result = ISC_R_NOTFOUND;
- } else if (result == DNS_R_GLUE) {
- 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.
- */
- is_cache = ISC_TRUE;
- dns_rdataset_clone(rdataset, &zrdataset);
- dns_rdataset_disassociate(rdataset);
- if (sigrdataset != NULL &&
- dns_rdataset_isassociated(sigrdataset)) {
- dns_rdataset_clone(sigrdataset, &zsigrdataset);
- dns_rdataset_disassociate(sigrdataset);
- }
- dns_db_attach(db, &zdb);
- dns_db_attachnode(zdb, node, &znode);
- dns_db_detachnode(db, &node);
- dns_db_detach(&db);
- dns_db_attach(view->cachedb, &db);
- goto db_find;
- }
- /*
- * Otherwise, the glue is the best answer.
- */
- 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);
- if (sigrdataset != NULL &&
- dns_rdataset_isassociated(sigrdataset))
- dns_rdataset_disassociate(sigrdataset);
- if (db != NULL) {
- if (node != NULL)
- dns_db_detachnode(db, &node);
- dns_db_detach(&db);
- }
- result = dns_db_find(view->hints, name, NULL, type, options,
- now, &node, foundname,
- rdataset, sigrdataset);
- if (result == ISC_R_SUCCESS || result == DNS_R_GLUE) {
- /*
- * We just used a hint. Let the resolver know it
- * should consider priming.
- */
- dns_resolver_prime(view->resolver);
- dns_db_attach(view->hints, &db);
- result = DNS_R_HINT;
- } else if (result == DNS_R_NXRRSET) {
- dns_db_attach(view->hints, &db);
- result = DNS_R_HINTNXRRSET;
- } else if (result == DNS_R_NXDOMAIN)
- result = ISC_R_NOTFOUND;
-
- /*
- * Cleanup if non-standard hints are used.
- */
- if (db == NULL && node != NULL)
- dns_db_detachnode(view->hints, &node);
- }
-#endif /* BIND9 */
-
- cleanup:
- if (dns_rdataset_isassociated(&zrdataset)) {
- dns_rdataset_disassociate(&zrdataset);
- if (dns_rdataset_isassociated(&zsigrdataset))
- dns_rdataset_disassociate(&zsigrdataset);
- }
-
- if (zdb != NULL) {
- if (znode != NULL)
- dns_db_detachnode(zdb, &znode);
- dns_db_detach(&zdb);
- }
-
- if (db != NULL) {
- if (node != NULL) {
- if (nodep != NULL)
- *nodep = node;
- else
- dns_db_detachnode(db, &node);
- }
- if (dbp != NULL)
- *dbp = db;
- else
- dns_db_detach(&db);
- } else
- INSIST(node == NULL);
-
-#ifdef BIND9
- if (zone != NULL)
- dns_zone_detach(&zone);
-#endif
-
- return (result);
-}
-
-isc_result_t
-dns_view_simplefind(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_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
-{
- isc_result_t result;
- dns_fixedname_t foundname;
-
- dns_fixedname_init(&foundname);
- result = dns_view_find(view, name, type, now, options, use_hints,
- NULL, NULL, dns_fixedname_name(&foundname),
- rdataset, sigrdataset);
- if (result == DNS_R_NXDOMAIN) {
- /*
- * The rdataset and sigrdataset of the relevant NSEC record
- * may be returned, but the caller cannot use them because
- * foundname is not returned by this simplified API. We
- * disassociate them here to prevent any misuse by the caller.
- */
- if (dns_rdataset_isassociated(rdataset))
- dns_rdataset_disassociate(rdataset);
- if (sigrdataset != NULL &&
- dns_rdataset_isassociated(sigrdataset))
- dns_rdataset_disassociate(sigrdataset);
- } else if (result != ISC_R_SUCCESS &&
- result != DNS_R_GLUE &&
- result != DNS_R_HINT &&
- result != DNS_R_NCACHENXDOMAIN &&
- result != DNS_R_NCACHENXRRSET &&
- result != DNS_R_NXRRSET &&
- result != DNS_R_HINTNXRRSET &&
- result != ISC_R_NOTFOUND) {
- if (dns_rdataset_isassociated(rdataset))
- dns_rdataset_disassociate(rdataset);
- if (sigrdataset != NULL &&
- dns_rdataset_isassociated(sigrdataset))
- dns_rdataset_disassociate(sigrdataset);
- result = ISC_R_NOTFOUND;
- }
-
- return (result);
-}
-
-isc_result_t
-dns_view_findzonecut(dns_view_t *view, dns_name_t *name, dns_name_t *fname,
- isc_stdtime_t now, unsigned int options,
- isc_boolean_t use_hints,
- dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
-{
- return(dns_view_findzonecut2(view, name, fname, now, options,
- use_hints, ISC_TRUE,
- rdataset, sigrdataset));
-}
-
-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,
- 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;
- dns_zone_t *zone;
- dns_name_t *zfname;
- dns_rdataset_t zrdataset, zsigrdataset;
- dns_fixedname_t zfixedname;
-
-#ifndef BIND9
- UNUSED(zone);
-#endif
-
- REQUIRE(DNS_VIEW_VALID(view));
- REQUIRE(view->frozen);
-
- db = NULL;
- use_zone = ISC_FALSE;
- try_hints = ISC_FALSE;
- zfname = NULL;
-
- /*
- * Initialize.
- */
- dns_fixedname_init(&zfixedname);
- dns_rdataset_init(&zrdataset);
- dns_rdataset_init(&zsigrdataset);
-
- /*
- * Find the right database.
- */
-#ifdef BIND9
- zone = NULL;
- result = dns_zt_find(view->zonetable, name, 0, NULL, &zone);
- if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH)
- result = dns_zone_getdb(zone, &db);
-#else
- result = ISC_R_NOTFOUND;
-#endif
- if (result == ISC_R_NOTFOUND) {
- /*
- * We're not directly authoritative for this query name, nor
- * is it a subdomain of any zone for which we're
- * authoritative.
- */
- if (use_cache && view->cachedb != NULL) {
- /*
- * We have a cache; try it.
- */
- dns_db_attach(view->cachedb, &db);
- } else {
- /*
- * Maybe we have hints...
- */
- try_hints = ISC_TRUE;
- goto finish;
- }
- } else if (result != ISC_R_SUCCESS) {
- /*
- * Something is broken.
- */
- goto cleanup;
- }
- is_cache = dns_db_iscache(db);
-
- db_find:
- /*
- * Look for the zonecut.
- */
- if (!is_cache) {
- result = dns_db_find(db, name, NULL, dns_rdatatype_ns, options,
- now, NULL, fname, rdataset, sigrdataset);
- if (result == DNS_R_DELEGATION)
- result = ISC_R_SUCCESS;
- else if (result != ISC_R_SUCCESS)
- goto cleanup;
- if (use_cache && view->cachedb != NULL && db != view->hints) {
- /*
- * We found an answer, but the cache may be better.
- */
- zfname = dns_fixedname_name(&zfixedname);
- result = dns_name_copy(fname, zfname, NULL);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- dns_rdataset_clone(rdataset, &zrdataset);
- dns_rdataset_disassociate(rdataset);
- if (sigrdataset != NULL &&
- dns_rdataset_isassociated(sigrdataset)) {
- dns_rdataset_clone(sigrdataset, &zsigrdataset);
- dns_rdataset_disassociate(sigrdataset);
- }
- dns_db_detach(&db);
- dns_db_attach(view->cachedb, &db);
- is_cache = ISC_TRUE;
- goto db_find;
- }
- } else {
- result = dns_db_findzonecut(db, name, options, now, NULL,
- fname, rdataset, sigrdataset);
- if (result == ISC_R_SUCCESS) {
- if (zfname != NULL &&
- (!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.
- */
- use_zone = ISC_TRUE;
- }
- } else if (result == ISC_R_NOTFOUND) {
- if (zfname != NULL) {
- /*
- * We didn't find anything in the cache, but we
- * have a zone delegation, so use it.
- */
- use_zone = ISC_TRUE;
- } else {
- /*
- * Maybe we have hints...
- */
- try_hints = ISC_TRUE;
- }
- } else {
- /*
- * Something bad happened.
- */
- goto cleanup;
- }
- }
-
- finish:
- if (use_zone) {
- if (dns_rdataset_isassociated(rdataset)) {
- dns_rdataset_disassociate(rdataset);
- if (sigrdataset != NULL &&
- dns_rdataset_isassociated(sigrdataset))
- dns_rdataset_disassociate(sigrdataset);
- }
- result = dns_name_copy(zfname, fname, NULL);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- dns_rdataset_clone(&zrdataset, rdataset);
- if (sigrdataset != NULL &&
- dns_rdataset_isassociated(&zrdataset))
- dns_rdataset_clone(&zsigrdataset, sigrdataset);
- } else if (try_hints && use_hints && view->hints != NULL) {
- /*
- * We've found nothing so far, but we have hints.
- */
- result = dns_db_find(view->hints, dns_rootname, NULL,
- dns_rdatatype_ns, 0, now, NULL, fname,
- rdataset, NULL);
- if (result != ISC_R_SUCCESS) {
- /*
- * We can't even find the hints for the root
- * nameservers!
- */
- if (dns_rdataset_isassociated(rdataset))
- dns_rdataset_disassociate(rdataset);
- result = ISC_R_NOTFOUND;
- }
- }
-
- cleanup:
- if (dns_rdataset_isassociated(&zrdataset)) {
- dns_rdataset_disassociate(&zrdataset);
- if (dns_rdataset_isassociated(&zsigrdataset))
- dns_rdataset_disassociate(&zsigrdataset);
- }
- if (db != NULL)
- dns_db_detach(&db);
-#ifdef BIND9
- if (zone != NULL)
- dns_zone_detach(&zone);
-#endif
-
- return (result);
-}
-
-isc_result_t
-dns_viewlist_find(dns_viewlist_t *list, const char *name,
- dns_rdataclass_t rdclass, dns_view_t **viewp)
-{
- dns_view_t *view;
-
- REQUIRE(list != NULL);
-
- for (view = ISC_LIST_HEAD(*list);
- view != NULL;
- view = ISC_LIST_NEXT(view, link)) {
- if (strcmp(view->name, name) == 0 && view->rdclass == rdclass)
- break;
- }
- if (view == NULL)
- return (ISC_R_NOTFOUND);
-
- dns_view_attach(view, viewp);
-
- 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,
- dns_zone_t **zonep)
-{
- dns_view_t *view;
- isc_result_t result;
- dns_zone_t *zone1 = NULL, *zone2 = NULL;
- dns_zone_t **zp = NULL;;
-
- REQUIRE(list != NULL);
- for (view = ISC_LIST_HEAD(*list);
- view != NULL;
- view = ISC_LIST_NEXT(view, link)) {
- if (allclasses == ISC_FALSE && view->rdclass != rdclass)
- continue;
-
- /*
- * If the zone is defined in more than one view,
- * treat it as not found.
- */
- zp = (zone1 == NULL) ? &zone1 : &zone2;
- result = dns_zt_find(view->zonetable, name, 0, NULL, zp);
- INSIST(result == ISC_R_SUCCESS ||
- result == ISC_R_NOTFOUND ||
- result == DNS_R_PARTIALMATCH);
-
- /* Treat a partial match as no match */
- if (result == DNS_R_PARTIALMATCH) {
- dns_zone_detach(zp);
- result = ISC_R_NOTFOUND;
- POST(result);
- }
-
- if (zone2 != NULL) {
- dns_zone_detach(&zone1);
- dns_zone_detach(&zone2);
- return (ISC_R_NOTFOUND);
- }
- }
-
- if (zone1 != NULL) {
- dns_zone_attach(zone1, zonep);
- dns_zone_detach(&zone1);
- return (ISC_R_SUCCESS);
- }
-
- return (ISC_R_NOTFOUND);
-}
-
-isc_result_t
-dns_view_load(dns_view_t *view, isc_boolean_t stop) {
-
- REQUIRE(DNS_VIEW_VALID(view));
- REQUIRE(view->zonetable != NULL);
-
- return (dns_zt_load(view->zonetable, stop));
-}
-
-isc_result_t
-dns_view_loadnew(dns_view_t *view, isc_boolean_t stop) {
-
- REQUIRE(DNS_VIEW_VALID(view));
- REQUIRE(view->zonetable != NULL);
-
- return (dns_zt_loadnew(view->zonetable, stop));
-}
-
-isc_result_t
-dns_view_asyncload(dns_view_t *view, dns_zt_allloaded_t callback, void *arg) {
- REQUIRE(DNS_VIEW_VALID(view));
- REQUIRE(view->zonetable != NULL);
-
- return (dns_zt_asyncload(view->zonetable, callback, arg));
-}
-
-
-#endif /* BIND9 */
-
-isc_result_t
-dns_view_gettsig(dns_view_t *view, dns_name_t *keyname, dns_tsigkey_t **keyp)
-{
- isc_result_t result;
- REQUIRE(keyp != NULL && *keyp == NULL);
-
- result = dns_tsigkey_find(keyp, keyname, NULL,
- view->statickeys);
- if (result == ISC_R_NOTFOUND)
- result = dns_tsigkey_find(keyp, keyname, NULL,
- view->dynamickeys);
- return (result);
-}
-
-isc_result_t
-dns_view_getpeertsig(dns_view_t *view, isc_netaddr_t *peeraddr,
- dns_tsigkey_t **keyp)
-{
- isc_result_t result;
- dns_name_t *keyname = NULL;
- dns_peer_t *peer = NULL;
-
- result = dns_peerlist_peerbyaddr(view->peers, peeraddr, &peer);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- result = dns_peer_getkey(peer, &keyname);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- result = dns_view_gettsig(view, keyname, keyp);
- return ((result == ISC_R_NOTFOUND) ? ISC_R_FAILURE : result);
-}
-
-isc_result_t
-dns_view_checksig(dns_view_t *view, isc_buffer_t *source, dns_message_t *msg) {
- REQUIRE(DNS_VIEW_VALID(view));
- REQUIRE(source != NULL);
-
- return (dns_tsig_verify(source, msg, view->statickeys,
- view->dynamickeys));
-}
-
-#ifdef BIND9
-isc_result_t
-dns_view_dumpdbtostream(dns_view_t *view, FILE *fp) {
- isc_result_t result;
-
- REQUIRE(DNS_VIEW_VALID(view));
-
- (void)fprintf(fp, ";\n; Cache dump of view '%s'\n;\n", view->name);
- result = dns_master_dumptostream(view->mctx, view->cachedb, NULL,
- &dns_master_style_cache, fp);
- if (result != ISC_R_SUCCESS)
- return (result);
- dns_adb_dump(view->adb, 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);
- 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);
-}
-
-isc_result_t
-dns_view_flushname(dns_view_t *view, dns_name_t *name) {
- return (dns_view_flushnode(view, name, ISC_FALSE));
-}
-
-isc_result_t
-dns_view_flushnode(dns_view_t *view, dns_name_t *name, isc_boolean_t tree) {
-
- REQUIRE(DNS_VIEW_VALID(view));
-
- if (!tree) {
- if (view->adb != NULL)
- dns_adb_flushname(view->adb, name);
- if (view->cache == NULL)
- return (ISC_R_SUCCESS);
- if (view->resolver != NULL)
- dns_resolver_flushbadcache(view->resolver, name);
- }
- return (dns_cache_flushnode(view->cache, name, tree));
-}
-
-isc_result_t
-dns_view_adddelegationonly(dns_view_t *view, dns_name_t *name) {
- isc_result_t result;
- dns_name_t *new;
- isc_uint32_t hash;
-
- REQUIRE(DNS_VIEW_VALID(view));
-
- if (view->delonly == NULL) {
- view->delonly = isc_mem_get(view->mctx,
- sizeof(dns_namelist_t) *
- DNS_VIEW_DELONLYHASH);
- if (view->delonly == NULL)
- return (ISC_R_NOMEMORY);
- for (hash = 0; hash < DNS_VIEW_DELONLYHASH; hash++)
- ISC_LIST_INIT(view->delonly[hash]);
- }
- hash = dns_name_hash(name, ISC_FALSE) % DNS_VIEW_DELONLYHASH;
- new = ISC_LIST_HEAD(view->delonly[hash]);
- while (new != NULL && !dns_name_equal(new, name))
- new = ISC_LIST_NEXT(new, link);
- if (new != NULL)
- return (ISC_R_SUCCESS);
- new = isc_mem_get(view->mctx, sizeof(*new));
- if (new == NULL)
- return (ISC_R_NOMEMORY);
- dns_name_init(new, NULL);
- result = dns_name_dup(name, view->mctx, new);
- if (result == ISC_R_SUCCESS)
- ISC_LIST_APPEND(view->delonly[hash], new, link);
- else
- isc_mem_put(view->mctx, new, sizeof(*new));
- return (result);
-}
-
-isc_result_t
-dns_view_excludedelegationonly(dns_view_t *view, dns_name_t *name) {
- isc_result_t result;
- dns_name_t *new;
- isc_uint32_t hash;
-
- REQUIRE(DNS_VIEW_VALID(view));
-
- if (view->rootexclude == NULL) {
- view->rootexclude = isc_mem_get(view->mctx,
- sizeof(dns_namelist_t) *
- DNS_VIEW_DELONLYHASH);
- if (view->rootexclude == NULL)
- return (ISC_R_NOMEMORY);
- for (hash = 0; hash < DNS_VIEW_DELONLYHASH; hash++)
- ISC_LIST_INIT(view->rootexclude[hash]);
- }
- hash = dns_name_hash(name, ISC_FALSE) % DNS_VIEW_DELONLYHASH;
- new = ISC_LIST_HEAD(view->rootexclude[hash]);
- while (new != NULL && !dns_name_equal(new, name))
- new = ISC_LIST_NEXT(new, link);
- if (new != NULL)
- return (ISC_R_SUCCESS);
- new = isc_mem_get(view->mctx, sizeof(*new));
- if (new == NULL)
- return (ISC_R_NOMEMORY);
- dns_name_init(new, NULL);
- result = dns_name_dup(name, view->mctx, new);
- if (result == ISC_R_SUCCESS)
- ISC_LIST_APPEND(view->rootexclude[hash], new, link);
- else
- isc_mem_put(view->mctx, new, sizeof(*new));
- return (result);
-}
-
-isc_boolean_t
-dns_view_isdelegationonly(dns_view_t *view, dns_name_t *name) {
- dns_name_t *new;
- isc_uint32_t hash;
-
- REQUIRE(DNS_VIEW_VALID(view));
-
- if (!view->rootdelonly && view->delonly == NULL)
- return (ISC_FALSE);
-
- hash = dns_name_hash(name, ISC_FALSE) % DNS_VIEW_DELONLYHASH;
- if (view->rootdelonly && dns_name_countlabels(name) <= 2) {
- if (view->rootexclude == NULL)
- return (ISC_TRUE);
- new = ISC_LIST_HEAD(view->rootexclude[hash]);
- while (new != NULL && !dns_name_equal(new, name))
- new = ISC_LIST_NEXT(new, link);
- if (new == NULL)
- return (ISC_TRUE);
- }
-
- if (view->delonly == NULL)
- return (ISC_FALSE);
-
- new = ISC_LIST_HEAD(view->delonly[hash]);
- while (new != NULL && !dns_name_equal(new, name))
- new = ISC_LIST_NEXT(new, link);
- if (new == NULL)
- return (ISC_FALSE);
- return (ISC_TRUE);
-}
-
-void
-dns_view_setrootdelonly(dns_view_t *view, isc_boolean_t value) {
- REQUIRE(DNS_VIEW_VALID(view));
- view->rootdelonly = value;
-}
-
-isc_boolean_t
-dns_view_getrootdelonly(dns_view_t *view) {
- REQUIRE(DNS_VIEW_VALID(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) {
- REQUIRE(DNS_VIEW_VALID(view));
- REQUIRE(!view->frozen);
- REQUIRE(view->resstats == NULL);
-
- isc_stats_attach(stats, &view->resstats);
-}
-
-void
-dns_view_getresstats(dns_view_t *view, isc_stats_t **statsp) {
- REQUIRE(DNS_VIEW_VALID(view));
- REQUIRE(statsp != NULL && *statsp == NULL);
-
- if (view->resstats != NULL)
- isc_stats_attach(view->resstats, statsp);
-}
-
-void
-dns_view_setresquerystats(dns_view_t *view, dns_stats_t *stats) {
- REQUIRE(DNS_VIEW_VALID(view));
- REQUIRE(!view->frozen);
- REQUIRE(view->resquerystats == NULL);
-
- dns_stats_attach(stats, &view->resquerystats);
-}
-
-void
-dns_view_getresquerystats(dns_view_t *view, dns_stats_t **statsp) {
- REQUIRE(DNS_VIEW_VALID(view));
- REQUIRE(statsp != NULL && *statsp == NULL);
-
- 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));
-
- if (view->secroots_priv == NULL)
- return (ISC_R_NOTFOUND);
- 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/contrib/bind9/lib/dns/xfrin.c b/contrib/bind9/lib/dns/xfrin.c
deleted file mode 100644
index 813f616e6fa0..000000000000
--- a/contrib/bind9/lib/dns/xfrin.c
+++ /dev/null
@@ -1,1556 +0,0 @@
-/*
- * Copyright (C) 2004-2008, 2011-2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <isc/mem.h>
-#include <isc/print.h>
-#include <isc/random.h>
-#include <isc/string.h> /* Required for HP/UX (and others?) */
-#include <isc/task.h>
-#include <isc/timer.h>
-#include <isc/util.h>
-
-#include <dns/db.h>
-#include <dns/diff.h>
-#include <dns/events.h>
-#include <dns/journal.h>
-#include <dns/log.h>
-#include <dns/message.h>
-#include <dns/rdataclass.h>
-#include <dns/rdatalist.h>
-#include <dns/rdataset.h>
-#include <dns/result.h>
-#include <dns/soa.h>
-#include <dns/tcpmsg.h>
-#include <dns/timer.h>
-#include <dns/tsig.h>
-#include <dns/view.h>
-#include <dns/xfrin.h>
-#include <dns/zone.h>
-
-#include <dst/dst.h>
-
-/*
- * Incoming AXFR and IXFR.
- */
-
-/*%
- * It would be non-sensical (or at least obtuse) to use FAIL() with an
- * ISC_R_SUCCESS code, but the test is there to keep the Solaris compiler
- * from complaining about "end-of-loop code not reached".
- */
-#define FAIL(code) \
- do { result = (code); \
- if (result != ISC_R_SUCCESS) goto failure; \
- } while (0)
-
-#define CHECK(op) \
- do { result = (op); \
- if (result != ISC_R_SUCCESS) goto failure; \
- } while (0)
-
-/*%
- * The states of the *XFR state machine. We handle both IXFR and AXFR
- * with a single integrated state machine because they cannot be distinguished
- * immediately - an AXFR response to an IXFR request can only be detected
- * when the first two (2) response RRs have already been received.
- */
-typedef enum {
- XFRST_SOAQUERY,
- XFRST_GOTSOA,
- XFRST_INITIALSOA,
- XFRST_FIRSTDATA,
- XFRST_IXFR_DELSOA,
- XFRST_IXFR_DEL,
- XFRST_IXFR_ADDSOA,
- XFRST_IXFR_ADD,
- XFRST_IXFR_END,
- XFRST_AXFR,
- XFRST_AXFR_END
-} xfrin_state_t;
-
-/*%
- * Incoming zone transfer context.
- */
-
-struct dns_xfrin_ctx {
- unsigned int magic;
- isc_mem_t *mctx;
- dns_zone_t *zone;
-
- int refcount;
-
- isc_task_t *task;
- isc_timer_t *timer;
- isc_socketmgr_t *socketmgr;
-
- int connects; /*%< Connect in progress */
- int sends; /*%< Send in progress */
- int recvs; /*%< Receive in progress */
- isc_boolean_t shuttingdown;
-
- dns_name_t name; /*%< Name of zone to transfer */
- dns_rdataclass_t rdclass;
-
- isc_boolean_t checkid;
- dns_messageid_t id;
-
- /*%
- * Requested transfer type (dns_rdatatype_axfr or
- * dns_rdatatype_ixfr). The actual transfer type
- * may differ due to IXFR->AXFR fallback.
- */
- dns_rdatatype_t reqtype;
-
- isc_sockaddr_t masteraddr;
- isc_sockaddr_t sourceaddr;
- isc_socket_t *socket;
-
- /*% Buffer for IXFR/AXFR request message */
- isc_buffer_t qbuffer;
- unsigned char qbuffer_data[512];
-
- /*% Incoming reply TCP message */
- dns_tcpmsg_t tcpmsg;
- isc_boolean_t tcpmsg_valid;
-
- dns_db_t *db;
- dns_dbversion_t *ver;
- dns_diff_t diff; /*%< Pending database changes */
- int difflen; /*%< Number of pending tuples */
-
- xfrin_state_t state;
- isc_uint32_t end_serial;
- isc_boolean_t is_ixfr;
-
- unsigned int nmsg; /*%< Number of messages recvd */
- unsigned int nrecs; /*%< Number of records recvd */
- isc_uint64_t nbytes; /*%< Number of bytes received */
-
- isc_time_t start; /*%< Start time of the transfer */
- isc_time_t end; /*%< End time of the transfer */
-
- dns_tsigkey_t *tsigkey; /*%< Key used to create TSIG */
- isc_buffer_t *lasttsig; /*%< The last TSIG */
- dst_context_t *tsigctx; /*%< TSIG verification context */
- unsigned int sincetsig; /*%< recvd since the last TSIG */
- dns_xfrindone_t done;
-
- /*%
- * AXFR- and IXFR-specific data. Only one is used at a time
- * according to the is_ixfr flag, so this could be a union,
- * but keeping them separate makes it a bit simpler to clean
- * things up when destroying the context.
- */
- struct {
- dns_addrdatasetfunc_t add_func;
- dns_dbload_t *add_private;
- } axfr;
-
- struct {
- isc_uint32_t request_serial;
- isc_uint32_t current_serial;
- dns_journal_t *journal;
-
- } ixfr;
-};
-
-#define XFRIN_MAGIC ISC_MAGIC('X', 'f', 'r', 'I')
-#define VALID_XFRIN(x) ISC_MAGIC_VALID(x, XFRIN_MAGIC)
-
-/**************************************************************************/
-/*
- * Forward declarations.
- */
-
-static isc_result_t
-xfrin_create(isc_mem_t *mctx,
- dns_zone_t *zone,
- dns_db_t *db,
- isc_task_t *task,
- isc_timermgr_t *timermgr,
- isc_socketmgr_t *socketmgr,
- dns_name_t *zonename,
- dns_rdataclass_t rdclass,
- dns_rdatatype_t reqtype,
- isc_sockaddr_t *masteraddr,
- isc_sockaddr_t *sourceaddr,
- dns_tsigkey_t *tsigkey,
- dns_xfrin_ctx_t **xfrp);
-
-static isc_result_t axfr_init(dns_xfrin_ctx_t *xfr);
-static isc_result_t axfr_makedb(dns_xfrin_ctx_t *xfr, dns_db_t **dbp);
-static isc_result_t axfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op,
- dns_name_t *name, dns_ttl_t ttl,
- 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);
-static isc_result_t ixfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op,
- dns_name_t *name, dns_ttl_t ttl,
- dns_rdata_t *rdata);
-static isc_result_t ixfr_commit(dns_xfrin_ctx_t *xfr);
-
-static isc_result_t xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name,
- isc_uint32_t ttl, dns_rdata_t *rdata);
-
-static isc_result_t xfrin_start(dns_xfrin_ctx_t *xfr);
-
-static void xfrin_connect_done(isc_task_t *task, isc_event_t *event);
-static isc_result_t xfrin_send_request(dns_xfrin_ctx_t *xfr);
-static void xfrin_send_done(isc_task_t *task, isc_event_t *event);
-static void xfrin_sendlen_done(isc_task_t *task, isc_event_t *event);
-static void xfrin_recv_done(isc_task_t *task, isc_event_t *event);
-static void xfrin_timeout(isc_task_t *task, isc_event_t *event);
-
-static void maybe_free(dns_xfrin_ctx_t *xfr);
-
-static void
-xfrin_fail(dns_xfrin_ctx_t *xfr, isc_result_t result, const char *msg);
-static isc_result_t
-render(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t *buf);
-
-static void
-xfrin_logv(int level, const char *zonetext, isc_sockaddr_t *masteraddr,
- const char *fmt, va_list ap)
- ISC_FORMAT_PRINTF(4, 0);
-
-static void
-xfrin_log1(int level, const char *zonetext, isc_sockaddr_t *masteraddr,
- const char *fmt, ...)
- ISC_FORMAT_PRINTF(4, 5);
-
-static void
-xfrin_log(dns_xfrin_ctx_t *xfr, int level, const char *fmt, ...)
- ISC_FORMAT_PRINTF(3, 4);
-
-/**************************************************************************/
-/*
- * AXFR handling
- */
-
-static isc_result_t
-axfr_init(dns_xfrin_ctx_t *xfr) {
- isc_result_t result;
-
- xfr->is_ixfr = ISC_FALSE;
-
- if (xfr->db != NULL)
- dns_db_detach(&xfr->db);
-
- CHECK(axfr_makedb(xfr, &xfr->db));
- CHECK(dns_db_beginload(xfr->db, &xfr->axfr.add_func,
- &xfr->axfr.add_private));
- result = ISC_R_SUCCESS;
- failure:
- return (result);
-}
-
-static isc_result_t
-axfr_makedb(dns_xfrin_ctx_t *xfr, dns_db_t **dbp) {
- return (dns_db_create(xfr->mctx, /* XXX */
- "rbt", /* XXX guess */
- &xfr->name,
- dns_dbtype_zone,
- xfr->rdclass,
- 0, NULL, /* XXX guess */
- dbp));
-}
-
-static isc_result_t
-axfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op,
- dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata)
-{
- isc_result_t result;
-
- dns_difftuple_t *tuple = NULL;
-
- CHECK(dns_zone_checknames(xfr->zone, name, rdata));
- CHECK(dns_difftuple_create(xfr->diff.mctx, op,
- name, ttl, rdata, &tuple));
- dns_diff_append(&xfr->diff, &tuple);
- if (++xfr->difflen > 100)
- CHECK(axfr_apply(xfr));
- result = ISC_R_SUCCESS;
- failure:
- return (result);
-}
-
-/*
- * Store a set of AXFR RRs in the database.
- */
-static isc_result_t
-axfr_apply(dns_xfrin_ctx_t *xfr) {
- isc_result_t result;
-
- CHECK(dns_diff_load(&xfr->diff,
- xfr->axfr.add_func, xfr->axfr.add_private));
- xfr->difflen = 0;
- dns_diff_clear(&xfr->diff);
- result = ISC_R_SUCCESS;
- failure:
- return (result);
-}
-
-static isc_result_t
-axfr_commit(dns_xfrin_ctx_t *xfr) {
- isc_result_t result;
-
- 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;
- failure:
- return (result);
-}
-
-/**************************************************************************/
-/*
- * IXFR handling
- */
-
-static isc_result_t
-ixfr_init(dns_xfrin_ctx_t *xfr) {
- isc_result_t result;
- char *journalfile;
-
- if (xfr->reqtype != dns_rdatatype_ixfr) {
- xfrin_log(xfr, ISC_LOG_ERROR,
- "got incremental response to AXFR request");
- return (DNS_R_FORMERR);
- }
-
- xfr->is_ixfr = ISC_TRUE;
- INSIST(xfr->db != NULL);
- xfr->difflen = 0;
-
- journalfile = dns_zone_getjournal(xfr->zone);
- if (journalfile != NULL)
- CHECK(dns_journal_open(xfr->mctx, journalfile,
- DNS_JOURNAL_CREATE, &xfr->ixfr.journal));
-
- result = ISC_R_SUCCESS;
- failure:
- return (result);
-}
-
-static isc_result_t
-ixfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op,
- dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata)
-{
- isc_result_t result;
-
- dns_difftuple_t *tuple = NULL;
- if (op == DNS_DIFFOP_ADD)
- CHECK(dns_zone_checknames(xfr->zone, name, rdata));
- CHECK(dns_difftuple_create(xfr->diff.mctx, op,
- name, ttl, rdata, &tuple));
- dns_diff_append(&xfr->diff, &tuple);
- if (++xfr->difflen > 100)
- CHECK(ixfr_apply(xfr));
- result = ISC_R_SUCCESS;
- failure:
- return (result);
-}
-
-/*
- * Apply a set of IXFR changes to the database.
- */
-static isc_result_t
-ixfr_apply(dns_xfrin_ctx_t *xfr) {
- isc_result_t result;
-
- if (xfr->ver == NULL) {
- CHECK(dns_db_newversion(xfr->db, &xfr->ver));
- if (xfr->ixfr.journal != NULL)
- CHECK(dns_journal_begin_transaction(xfr->ixfr.journal));
- }
- CHECK(dns_diff_apply(&xfr->diff, xfr->db, xfr->ver));
- if (xfr->ixfr.journal != NULL) {
- result = dns_journal_writediff(xfr->ixfr.journal, &xfr->diff);
- if (result != ISC_R_SUCCESS)
- goto failure;
- }
- dns_diff_clear(&xfr->diff);
- xfr->difflen = 0;
- result = ISC_R_SUCCESS;
- failure:
- return (result);
-}
-
-static isc_result_t
-ixfr_commit(dns_xfrin_ctx_t *xfr) {
- isc_result_t result;
-
- CHECK(ixfr_apply(xfr));
- if (xfr->ver != NULL) {
- /* XXX enter ready-to-commit state here */
- if (xfr->ixfr.journal != NULL)
- CHECK(dns_journal_commit(xfr->ixfr.journal));
- dns_db_closeversion(xfr->db, &xfr->ver, ISC_TRUE);
- dns_zone_markdirty(xfr->zone);
- }
- result = ISC_R_SUCCESS;
- failure:
- return (result);
-}
-
-/**************************************************************************/
-/*
- * Common AXFR/IXFR protocol code
- */
-
-/*
- * Handle a single incoming resource record according to the current
- * state.
- */
-static isc_result_t
-xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name, isc_uint32_t ttl,
- dns_rdata_t *rdata)
-{
- isc_result_t result;
-
- xfr->nrecs++;
-
- if (rdata->type == dns_rdatatype_none ||
- dns_rdatatype_ismeta(rdata->type))
- FAIL(DNS_R_FORMERR);
-
- redo:
- switch (xfr->state) {
- case XFRST_SOAQUERY:
- if (rdata->type != dns_rdatatype_soa) {
- xfrin_log(xfr, ISC_LOG_ERROR,
- "non-SOA response to SOA query");
- FAIL(DNS_R_FORMERR);
- }
- xfr->end_serial = dns_soa_getserial(rdata);
- if (!DNS_SERIAL_GT(xfr->end_serial, xfr->ixfr.request_serial) &&
- !dns_zone_isforced(xfr->zone)) {
- xfrin_log(xfr, ISC_LOG_DEBUG(3),
- "requested serial %u, "
- "master has %u, not updating",
- xfr->ixfr.request_serial, xfr->end_serial);
- FAIL(DNS_R_UPTODATE);
- }
- xfr->state = XFRST_GOTSOA;
- break;
-
- case XFRST_GOTSOA:
- /*
- * Skip other records in the answer section.
- */
- break;
-
- case XFRST_INITIALSOA:
- if (rdata->type != dns_rdatatype_soa) {
- xfrin_log(xfr, ISC_LOG_ERROR,
- "first RR in zone transfer must be SOA");
- FAIL(DNS_R_FORMERR);
- }
- /*
- * Remember the serial number in the initial SOA.
- * We need it to recognize the end of an IXFR.
- */
- xfr->end_serial = dns_soa_getserial(rdata);
- if (xfr->reqtype == dns_rdatatype_ixfr &&
- ! DNS_SERIAL_GT(xfr->end_serial, xfr->ixfr.request_serial)
- && !dns_zone_isforced(xfr->zone))
- {
- /*
- * This must be the single SOA record that is
- * sent when the current version on the master
- * is not newer than the version in the request.
- */
- xfrin_log(xfr, ISC_LOG_DEBUG(3),
- "requested serial %u, "
- "master has %u, not updating",
- xfr->ixfr.request_serial, xfr->end_serial);
- FAIL(DNS_R_UPTODATE);
- }
- if (xfr->reqtype == dns_rdatatype_axfr)
- xfr->checkid = ISC_FALSE;
- xfr->state = XFRST_FIRSTDATA;
- break;
-
- case XFRST_FIRSTDATA:
- /*
- * If the transfer begins with one SOA record, it is an AXFR,
- * if it begins with two SOAs, it is an IXFR.
- */
- if (xfr->reqtype == dns_rdatatype_ixfr &&
- rdata->type == dns_rdatatype_soa &&
- xfr->ixfr.request_serial == dns_soa_getserial(rdata)) {
- xfrin_log(xfr, ISC_LOG_DEBUG(3),
- "got incremental response");
- CHECK(ixfr_init(xfr));
- xfr->state = XFRST_IXFR_DELSOA;
- } else {
- xfrin_log(xfr, ISC_LOG_DEBUG(3),
- "got nonincremental response");
- CHECK(axfr_init(xfr));
- xfr->state = XFRST_AXFR;
- }
- goto redo;
-
- case XFRST_IXFR_DELSOA:
- INSIST(rdata->type == dns_rdatatype_soa);
- CHECK(ixfr_putdata(xfr, DNS_DIFFOP_DEL, name, ttl, rdata));
- xfr->state = XFRST_IXFR_DEL;
- break;
-
- case XFRST_IXFR_DEL:
- if (rdata->type == dns_rdatatype_soa) {
- isc_uint32_t soa_serial = dns_soa_getserial(rdata);
- xfr->state = XFRST_IXFR_ADDSOA;
- xfr->ixfr.current_serial = soa_serial;
- goto redo;
- }
- CHECK(ixfr_putdata(xfr, DNS_DIFFOP_DEL, name, ttl, rdata));
- break;
-
- case XFRST_IXFR_ADDSOA:
- INSIST(rdata->type == dns_rdatatype_soa);
- CHECK(ixfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
- xfr->state = XFRST_IXFR_ADD;
- break;
-
- case XFRST_IXFR_ADD:
- if (rdata->type == dns_rdatatype_soa) {
- isc_uint32_t soa_serial = dns_soa_getserial(rdata);
- if (soa_serial == xfr->end_serial) {
- CHECK(ixfr_commit(xfr));
- xfr->state = XFRST_IXFR_END;
- break;
- } else if (soa_serial != xfr->ixfr.current_serial) {
- xfrin_log(xfr, ISC_LOG_ERROR,
- "IXFR out of sync: "
- "expected serial %u, got %u",
- xfr->ixfr.current_serial, soa_serial);
- FAIL(DNS_R_FORMERR);
- } else {
- CHECK(ixfr_commit(xfr));
- xfr->state = XFRST_IXFR_DELSOA;
- goto redo;
- }
- }
- if (rdata->type == dns_rdatatype_ns &&
- dns_name_iswildcard(name))
- FAIL(DNS_R_INVALIDNS);
- CHECK(ixfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
- break;
-
- case XFRST_AXFR:
- /*
- * Old BINDs sent cross class A records for non IN classes.
- */
- if (rdata->type == dns_rdatatype_a &&
- rdata->rdclass != xfr->rdclass &&
- xfr->rdclass != dns_rdataclass_in)
- break;
- CHECK(axfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
- if (rdata->type == dns_rdatatype_soa) {
- CHECK(axfr_commit(xfr));
- xfr->state = XFRST_AXFR_END;
- break;
- }
- break;
- case XFRST_AXFR_END:
- case XFRST_IXFR_END:
- FAIL(DNS_R_EXTRADATA);
- /* NOTREACHED */
- default:
- INSIST(0);
- break;
- }
- result = ISC_R_SUCCESS;
- failure:
- return (result);
-}
-
-isc_result_t
-dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype,
- isc_sockaddr_t *masteraddr, dns_tsigkey_t *tsigkey,
- isc_mem_t *mctx, isc_timermgr_t *timermgr,
- isc_socketmgr_t *socketmgr, isc_task_t *task,
- dns_xfrindone_t done, dns_xfrin_ctx_t **xfrp)
-{
- isc_sockaddr_t sourceaddr;
-
- switch (isc_sockaddr_pf(masteraddr)) {
- case PF_INET:
- sourceaddr = *dns_zone_getxfrsource4(zone);
- break;
- case PF_INET6:
- sourceaddr = *dns_zone_getxfrsource6(zone);
- break;
- default:
- INSIST(0);
- }
-
- return(dns_xfrin_create2(zone, xfrtype, masteraddr, &sourceaddr,
- tsigkey, mctx, timermgr, socketmgr,
- task, done, xfrp));
-}
-
-isc_result_t
-dns_xfrin_create2(dns_zone_t *zone, dns_rdatatype_t xfrtype,
- isc_sockaddr_t *masteraddr, isc_sockaddr_t *sourceaddr,
- dns_tsigkey_t *tsigkey, isc_mem_t *mctx,
- isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
- isc_task_t *task, dns_xfrindone_t done,
- dns_xfrin_ctx_t **xfrp)
-{
- dns_name_t *zonename = dns_zone_getorigin(zone);
- dns_xfrin_ctx_t *xfr = NULL;
- isc_result_t result;
- dns_db_t *db = NULL;
-
- REQUIRE(xfrp != NULL && *xfrp == NULL);
-
- (void)dns_zone_getdb(zone, &db);
-
- if (xfrtype == dns_rdatatype_soa || xfrtype == dns_rdatatype_ixfr)
- REQUIRE(db != NULL);
-
- CHECK(xfrin_create(mctx, zone, db, task, timermgr, socketmgr, zonename,
- dns_zone_getclass(zone), xfrtype, masteraddr,
- sourceaddr, tsigkey, &xfr));
-
- CHECK(xfrin_start(xfr));
-
- xfr->done = done;
- xfr->refcount++;
- *xfrp = xfr;
-
- failure:
- if (db != NULL)
- dns_db_detach(&db);
- if (result != ISC_R_SUCCESS) {
- char zonetext[DNS_NAME_MAXTEXT+32];
- dns_zone_name(zone, zonetext, sizeof(zonetext));
- xfrin_log1(ISC_LOG_ERROR, zonetext, masteraddr,
- "zone transfer setup failed");
- }
- return (result);
-}
-
-void
-dns_xfrin_shutdown(dns_xfrin_ctx_t *xfr) {
- if (! xfr->shuttingdown)
- xfrin_fail(xfr, ISC_R_CANCELED, "shut down");
-}
-
-void
-dns_xfrin_attach(dns_xfrin_ctx_t *source, dns_xfrin_ctx_t **target) {
- REQUIRE(target != NULL && *target == NULL);
- source->refcount++;
- *target = source;
-}
-
-void
-dns_xfrin_detach(dns_xfrin_ctx_t **xfrp) {
- dns_xfrin_ctx_t *xfr = *xfrp;
- INSIST(xfr->refcount > 0);
- xfr->refcount--;
- maybe_free(xfr);
- *xfrp = NULL;
-}
-
-static void
-xfrin_cancelio(dns_xfrin_ctx_t *xfr) {
- if (xfr->connects > 0) {
- isc_socket_cancel(xfr->socket, xfr->task,
- ISC_SOCKCANCEL_CONNECT);
- } else if (xfr->recvs > 0) {
- dns_tcpmsg_cancelread(&xfr->tcpmsg);
- } else if (xfr->sends > 0) {
- isc_socket_cancel(xfr->socket, xfr->task,
- ISC_SOCKCANCEL_SEND);
- }
-}
-
-static void
-xfrin_reset(dns_xfrin_ctx_t *xfr) {
- REQUIRE(VALID_XFRIN(xfr));
-
- xfrin_log(xfr, ISC_LOG_INFO, "resetting");
-
- xfrin_cancelio(xfr);
-
- if (xfr->socket != NULL)
- isc_socket_detach(&xfr->socket);
-
- if (xfr->lasttsig != NULL)
- isc_buffer_free(&xfr->lasttsig);
-
- dns_diff_clear(&xfr->diff);
- xfr->difflen = 0;
-
- if (xfr->ixfr.journal != NULL)
- dns_journal_destroy(&xfr->ixfr.journal);
-
- if (xfr->axfr.add_private != NULL) {
- (void)dns_db_endload(xfr->db, &xfr->axfr.add_private);
- xfr->axfr.add_func = NULL;
- }
-
- if (xfr->tcpmsg_valid) {
- dns_tcpmsg_invalidate(&xfr->tcpmsg);
- xfr->tcpmsg_valid = ISC_FALSE;
- }
-
- if (xfr->ver != NULL)
- dns_db_closeversion(xfr->db, &xfr->ver, ISC_FALSE);
-}
-
-
-static void
-xfrin_fail(dns_xfrin_ctx_t *xfr, isc_result_t result, const char *msg) {
- if (result != DNS_R_UPTODATE) {
- xfrin_log(xfr, ISC_LOG_ERROR, "%s: %s",
- msg, isc_result_totext(result));
- if (xfr->is_ixfr)
- /* Pass special result code to force AXFR retry */
- result = DNS_R_BADIXFR;
- }
- xfrin_cancelio(xfr);
- /*
- * Close the journal.
- */
- if (xfr->ixfr.journal != NULL)
- dns_journal_destroy(&xfr->ixfr.journal);
- if (xfr->done != NULL) {
- (xfr->done)(xfr->zone, result);
- xfr->done = NULL;
- }
- xfr->shuttingdown = ISC_TRUE;
- maybe_free(xfr);
-}
-
-static isc_result_t
-xfrin_create(isc_mem_t *mctx,
- dns_zone_t *zone,
- dns_db_t *db,
- isc_task_t *task,
- isc_timermgr_t *timermgr,
- isc_socketmgr_t *socketmgr,
- dns_name_t *zonename,
- dns_rdataclass_t rdclass,
- dns_rdatatype_t reqtype,
- isc_sockaddr_t *masteraddr,
- isc_sockaddr_t *sourceaddr,
- dns_tsigkey_t *tsigkey,
- dns_xfrin_ctx_t **xfrp)
-{
- dns_xfrin_ctx_t *xfr = NULL;
- isc_result_t result;
- isc_uint32_t tmp;
-
- xfr = isc_mem_get(mctx, sizeof(*xfr));
- if (xfr == NULL)
- return (ISC_R_NOMEMORY);
- xfr->mctx = NULL;
- isc_mem_attach(mctx, &xfr->mctx);
- xfr->refcount = 0;
- xfr->zone = NULL;
- dns_zone_iattach(zone, &xfr->zone);
- xfr->task = NULL;
- isc_task_attach(task, &xfr->task);
- xfr->timer = NULL;
- xfr->socketmgr = socketmgr;
- xfr->done = NULL;
-
- xfr->connects = 0;
- xfr->sends = 0;
- xfr->recvs = 0;
- xfr->shuttingdown = ISC_FALSE;
-
- dns_name_init(&xfr->name, NULL);
- xfr->rdclass = rdclass;
- isc_random_get(&tmp);
- xfr->checkid = ISC_TRUE;
- xfr->id = (isc_uint16_t)(tmp & 0xffff);
- xfr->reqtype = reqtype;
-
- /* sockaddr */
- xfr->socket = NULL;
- /* qbuffer */
- /* qbuffer_data */
- /* tcpmsg */
- xfr->tcpmsg_valid = ISC_FALSE;
-
- xfr->db = NULL;
- if (db != NULL)
- dns_db_attach(db, &xfr->db);
- xfr->ver = NULL;
- dns_diff_init(xfr->mctx, &xfr->diff);
- xfr->difflen = 0;
-
- if (reqtype == dns_rdatatype_soa)
- xfr->state = XFRST_SOAQUERY;
- else
- xfr->state = XFRST_INITIALSOA;
- /* end_serial */
-
- xfr->nmsg = 0;
- xfr->nrecs = 0;
- xfr->nbytes = 0;
- isc_time_now(&xfr->start);
-
- xfr->tsigkey = NULL;
- if (tsigkey != NULL)
- dns_tsigkey_attach(tsigkey, &xfr->tsigkey);
- xfr->lasttsig = NULL;
- xfr->tsigctx = NULL;
- xfr->sincetsig = 0;
- xfr->is_ixfr = ISC_FALSE;
-
- /* ixfr.request_serial */
- /* ixfr.current_serial */
- xfr->ixfr.journal = NULL;
-
- xfr->axfr.add_func = NULL;
- xfr->axfr.add_private = NULL;
-
- CHECK(dns_name_dup(zonename, mctx, &xfr->name));
-
- CHECK(isc_timer_create(timermgr, isc_timertype_inactive, NULL, NULL,
- task, xfrin_timeout, xfr, &xfr->timer));
- CHECK(dns_timer_setidle(xfr->timer,
- dns_zone_getmaxxfrin(xfr->zone),
- dns_zone_getidlein(xfr->zone),
- ISC_FALSE));
-
- xfr->masteraddr = *masteraddr;
-
- INSIST(isc_sockaddr_pf(masteraddr) == isc_sockaddr_pf(sourceaddr));
- xfr->sourceaddr = *sourceaddr;
- isc_sockaddr_setport(&xfr->sourceaddr, 0);
-
- isc_buffer_init(&xfr->qbuffer, xfr->qbuffer_data,
- sizeof(xfr->qbuffer_data));
-
- xfr->magic = XFRIN_MAGIC;
- *xfrp = xfr;
- return (ISC_R_SUCCESS);
-
- failure:
- if (xfr->timer != NULL)
- isc_timer_detach(&xfr->timer);
- if (dns_name_dynamic(&xfr->name))
- dns_name_free(&xfr->name, xfr->mctx);
- if (xfr->tsigkey != NULL)
- dns_tsigkey_detach(&xfr->tsigkey);
- if (xfr->db != NULL)
- dns_db_detach(&xfr->db);
- isc_task_detach(&xfr->task);
- dns_zone_idetach(&xfr->zone);
- isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr));
-
- return (result);
-}
-
-static isc_result_t
-xfrin_start(dns_xfrin_ctx_t *xfr) {
- isc_result_t result;
- CHECK(isc_socket_create(xfr->socketmgr,
- isc_sockaddr_pf(&xfr->sourceaddr),
- isc_sockettype_tcp,
- &xfr->socket));
- isc_socket_setname(xfr->socket, "xfrin", NULL);
-#ifndef BROKEN_TCP_BIND_BEFORE_CONNECT
- CHECK(isc_socket_bind(xfr->socket, &xfr->sourceaddr,
- ISC_SOCKET_REUSEADDRESS));
-#endif
- CHECK(isc_socket_connect(xfr->socket, &xfr->masteraddr, xfr->task,
- xfrin_connect_done, xfr));
- xfr->connects++;
- return (ISC_R_SUCCESS);
- failure:
- xfrin_fail(xfr, result, "failed setting up socket");
- return (result);
-}
-
-/* XXX the resolver could use this, too */
-
-static isc_result_t
-render(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t *buf) {
- dns_compress_t cctx;
- isc_boolean_t cleanup_cctx = ISC_FALSE;
- isc_result_t result;
-
- CHECK(dns_compress_init(&cctx, -1, mctx));
- cleanup_cctx = ISC_TRUE;
- CHECK(dns_message_renderbegin(msg, &cctx, buf));
- CHECK(dns_message_rendersection(msg, DNS_SECTION_QUESTION, 0));
- CHECK(dns_message_rendersection(msg, DNS_SECTION_ANSWER, 0));
- CHECK(dns_message_rendersection(msg, DNS_SECTION_AUTHORITY, 0));
- CHECK(dns_message_rendersection(msg, DNS_SECTION_ADDITIONAL, 0));
- CHECK(dns_message_renderend(msg));
- result = ISC_R_SUCCESS;
- failure:
- if (cleanup_cctx)
- dns_compress_invalidate(&cctx);
- return (result);
-}
-
-/*
- * A connection has been established.
- */
-static void
-xfrin_connect_done(isc_task_t *task, isc_event_t *event) {
- isc_socket_connev_t *cev = (isc_socket_connev_t *) event;
- dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg;
- isc_result_t result = cev->result;
- char sourcetext[ISC_SOCKADDR_FORMATSIZE];
- isc_sockaddr_t sockaddr;
-
- REQUIRE(VALID_XFRIN(xfr));
-
- UNUSED(task);
-
- INSIST(event->ev_type == ISC_SOCKEVENT_CONNECT);
- isc_event_free(&event);
-
- xfr->connects--;
- if (xfr->shuttingdown) {
- maybe_free(xfr);
- return;
- }
-
- if (result != ISC_R_SUCCESS) {
- dns_zonemgr_t * zmgr = dns_zone_getmgr(xfr->zone);
- isc_time_t now;
-
- if (zmgr != NULL) {
- TIME_NOW(&now);
- dns_zonemgr_unreachableadd(zmgr, &xfr->masteraddr,
- &xfr->sourceaddr, &now);
- }
- goto failure;
- }
-
- result = isc_socket_getsockname(xfr->socket, &sockaddr);
- if (result == ISC_R_SUCCESS) {
- isc_sockaddr_format(&sockaddr, sourcetext, sizeof(sourcetext));
- } else
- strcpy(sourcetext, "<UNKNOWN>");
- xfrin_log(xfr, ISC_LOG_INFO, "connected using %s", sourcetext);
-
- dns_tcpmsg_init(xfr->mctx, xfr->socket, &xfr->tcpmsg);
- xfr->tcpmsg_valid = ISC_TRUE;
-
- CHECK(xfrin_send_request(xfr));
- failure:
- if (result != ISC_R_SUCCESS)
- xfrin_fail(xfr, result, "failed to connect");
-}
-
-/*
- * Convert a tuple into a dns_name_t suitable for inserting
- * into the given dns_message_t.
- */
-static isc_result_t
-tuple2msgname(dns_difftuple_t *tuple, dns_message_t *msg, dns_name_t **target)
-{
- isc_result_t result;
- dns_rdata_t *rdata = NULL;
- dns_rdatalist_t *rdl = NULL;
- dns_rdataset_t *rds = NULL;
- dns_name_t *name = NULL;
-
- REQUIRE(target != NULL && *target == NULL);
-
- CHECK(dns_message_gettemprdata(msg, &rdata));
- dns_rdata_init(rdata);
- dns_rdata_clone(&tuple->rdata, rdata);
-
- CHECK(dns_message_gettemprdatalist(msg, &rdl));
- dns_rdatalist_init(rdl);
- rdl->type = tuple->rdata.type;
- rdl->rdclass = tuple->rdata.rdclass;
- rdl->ttl = tuple->ttl;
- ISC_LIST_APPEND(rdl->rdata, rdata, link);
-
- CHECK(dns_message_gettemprdataset(msg, &rds));
- dns_rdataset_init(rds);
- CHECK(dns_rdatalist_tordataset(rdl, rds));
-
- CHECK(dns_message_gettempname(msg, &name));
- dns_name_init(name, NULL);
- dns_name_clone(&tuple->name, name);
- ISC_LIST_APPEND(name->list, rds, link);
-
- *target = name;
- return (ISC_R_SUCCESS);
-
- failure:
-
- if (rds != NULL) {
- dns_rdataset_disassociate(rds);
- dns_message_puttemprdataset(msg, &rds);
- }
- if (rdl != NULL) {
- ISC_LIST_UNLINK(rdl->rdata, rdata, link);
- dns_message_puttemprdatalist(msg, &rdl);
- }
- if (rdata != NULL)
- dns_message_puttemprdata(msg, &rdata);
-
- return (result);
-}
-
-
-/*
- * Build an *XFR request and send its length prefix.
- */
-static isc_result_t
-xfrin_send_request(dns_xfrin_ctx_t *xfr) {
- isc_result_t result;
- isc_region_t region;
- isc_region_t lregion;
- dns_rdataset_t *qrdataset = NULL;
- dns_message_t *msg = NULL;
- unsigned char length[2];
- dns_difftuple_t *soatuple = NULL;
- dns_name_t *qname = NULL;
- dns_dbversion_t *ver = NULL;
- dns_name_t *msgsoaname = NULL;
-
- /* Create the request message */
- CHECK(dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTRENDER, &msg));
- CHECK(dns_message_settsigkey(msg, xfr->tsigkey));
-
- /* Create a name for the question section. */
- CHECK(dns_message_gettempname(msg, &qname));
- dns_name_init(qname, NULL);
- dns_name_clone(&xfr->name, qname);
-
- /* Formulate the question and attach it to the question name. */
- CHECK(dns_message_gettemprdataset(msg, &qrdataset));
- dns_rdataset_init(qrdataset);
- dns_rdataset_makequestion(qrdataset, xfr->rdclass, xfr->reqtype);
- ISC_LIST_APPEND(qname->list, qrdataset, link);
- qrdataset = NULL;
-
- dns_message_addname(msg, qname, DNS_SECTION_QUESTION);
- qname = NULL;
-
- if (xfr->reqtype == dns_rdatatype_ixfr) {
- /* Get the SOA and add it to the authority section. */
- /* XXX is using the current version the right thing? */
- dns_db_currentversion(xfr->db, &ver);
- CHECK(dns_db_createsoatuple(xfr->db, ver, xfr->mctx,
- DNS_DIFFOP_EXISTS, &soatuple));
- xfr->ixfr.request_serial = dns_soa_getserial(&soatuple->rdata);
- xfr->ixfr.current_serial = xfr->ixfr.request_serial;
- xfrin_log(xfr, ISC_LOG_DEBUG(3),
- "requesting IXFR for serial %u",
- xfr->ixfr.request_serial);
-
- CHECK(tuple2msgname(soatuple, msg, &msgsoaname));
- dns_message_addname(msg, msgsoaname, DNS_SECTION_AUTHORITY);
- } else if (xfr->reqtype == dns_rdatatype_soa)
- CHECK(dns_db_getsoaserial(xfr->db, NULL,
- &xfr->ixfr.request_serial));
-
- xfr->checkid = ISC_TRUE;
- xfr->id++;
- xfr->nmsg = 0;
- xfr->nrecs = 0;
- xfr->nbytes = 0;
- isc_time_now(&xfr->start);
- msg->id = xfr->id;
- if (xfr->tsigctx != NULL)
- dst_context_destroy(&xfr->tsigctx);
-
- CHECK(render(msg, xfr->mctx, &xfr->qbuffer));
-
- /*
- * Free the last tsig, if there is one.
- */
- if (xfr->lasttsig != NULL)
- isc_buffer_free(&xfr->lasttsig);
-
- /*
- * Save the query TSIG and don't let message_destroy free it.
- */
- CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig));
-
- isc_buffer_usedregion(&xfr->qbuffer, &region);
- INSIST(region.length <= 65535);
-
- length[0] = region.length >> 8;
- length[1] = region.length & 0xFF;
- lregion.base = length;
- lregion.length = 2;
- CHECK(isc_socket_send(xfr->socket, &lregion, xfr->task,
- xfrin_sendlen_done, xfr));
- xfr->sends++;
-
- failure:
- if (qname != NULL)
- dns_message_puttempname(msg, &qname);
- if (qrdataset != NULL)
- dns_message_puttemprdataset(msg, &qrdataset);
- if (msg != NULL)
- dns_message_destroy(&msg);
- if (soatuple != NULL)
- dns_difftuple_free(&soatuple);
- if (ver != NULL)
- dns_db_closeversion(xfr->db, &ver, ISC_FALSE);
- return (result);
-}
-
-/* XXX there should be library support for sending DNS TCP messages */
-
-static void
-xfrin_sendlen_done(isc_task_t *task, isc_event_t *event) {
- isc_socketevent_t *sev = (isc_socketevent_t *) event;
- dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg;
- isc_result_t evresult = sev->result;
- isc_result_t result;
- isc_region_t region;
-
- REQUIRE(VALID_XFRIN(xfr));
-
- UNUSED(task);
-
- INSIST(event->ev_type == ISC_SOCKEVENT_SENDDONE);
- isc_event_free(&event);
-
- xfr->sends--;
- if (xfr->shuttingdown) {
- maybe_free(xfr);
- return;
- }
-
- xfrin_log(xfr, ISC_LOG_DEBUG(3), "sent request length prefix");
- CHECK(evresult);
-
- isc_buffer_usedregion(&xfr->qbuffer, &region);
- CHECK(isc_socket_send(xfr->socket, &region, xfr->task,
- xfrin_send_done, xfr));
- xfr->sends++;
- failure:
- if (result != ISC_R_SUCCESS)
- xfrin_fail(xfr, result, "failed sending request length prefix");
-}
-
-
-static void
-xfrin_send_done(isc_task_t *task, isc_event_t *event) {
- isc_socketevent_t *sev = (isc_socketevent_t *) event;
- dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg;
- isc_result_t result;
-
- REQUIRE(VALID_XFRIN(xfr));
-
- UNUSED(task);
-
- INSIST(event->ev_type == ISC_SOCKEVENT_SENDDONE);
-
- xfr->sends--;
- xfrin_log(xfr, ISC_LOG_DEBUG(3), "sent request data");
- CHECK(sev->result);
-
- CHECK(dns_tcpmsg_readmessage(&xfr->tcpmsg, xfr->task,
- xfrin_recv_done, xfr));
- xfr->recvs++;
- failure:
- isc_event_free(&event);
- if (result != ISC_R_SUCCESS)
- xfrin_fail(xfr, result, "failed sending request data");
-}
-
-
-static void
-xfrin_recv_done(isc_task_t *task, isc_event_t *ev) {
- dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) ev->ev_arg;
- isc_result_t result;
- dns_message_t *msg = NULL;
- dns_name_t *name;
- dns_tcpmsg_t *tcpmsg;
- dns_name_t *tsigowner = NULL;
-
- REQUIRE(VALID_XFRIN(xfr));
-
- UNUSED(task);
-
- INSIST(ev->ev_type == DNS_EVENT_TCPMSG);
- tcpmsg = ev->ev_sender;
- isc_event_free(&ev);
-
- xfr->recvs--;
- if (xfr->shuttingdown) {
- maybe_free(xfr);
- return;
- }
-
- CHECK(tcpmsg->result);
-
- xfrin_log(xfr, ISC_LOG_DEBUG(7), "received %u bytes",
- tcpmsg->buffer.used);
-
- CHECK(isc_timer_touch(xfr->timer));
-
- CHECK(dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTPARSE, &msg));
-
- CHECK(dns_message_settsigkey(msg, xfr->tsigkey));
- CHECK(dns_message_setquerytsig(msg, xfr->lasttsig));
-
- msg->tsigctx = xfr->tsigctx;
- xfr->tsigctx = NULL;
-
- if (xfr->nmsg > 0)
- msg->tcp_continuation = 1;
-
- result = dns_message_parse(msg, &tcpmsg->buffer,
- DNS_MESSAGEPARSE_PRESERVEORDER);
-
- if (result != ISC_R_SUCCESS || msg->rcode != dns_rcode_noerror ||
- (xfr->checkid && msg->id != xfr->id)) {
- if (result == ISC_R_SUCCESS)
- result = ISC_RESULTCLASS_DNSRCODE + msg->rcode; /*XXX*/
- if (result == ISC_R_SUCCESS || result == DNS_R_NOERROR)
- result = DNS_R_UNEXPECTEDID;
- if (xfr->reqtype == dns_rdatatype_axfr ||
- xfr->reqtype == dns_rdatatype_soa)
- goto failure;
- xfrin_log(xfr, ISC_LOG_DEBUG(3), "got %s, retrying with AXFR",
- isc_result_totext(result));
- try_axfr:
- dns_message_destroy(&msg);
- xfrin_reset(xfr);
- xfr->reqtype = dns_rdatatype_soa;
- xfr->state = XFRST_SOAQUERY;
- (void)xfrin_start(xfr);
- return;
- }
-
- /*
- * Does the server know about IXFR? If it doesn't we will get
- * a message with a empty answer section or a potentially a CNAME /
- * DNAME, the later is handled by xfr_rr() which will return FORMERR
- * if the first RR in the answer section is not a SOA record.
- */
- if (xfr->reqtype == dns_rdatatype_ixfr &&
- xfr->state == XFRST_INITIALSOA &&
- msg->counts[DNS_SECTION_ANSWER] == 0) {
- xfrin_log(xfr, ISC_LOG_DEBUG(3),
- "empty answer section, retrying with AXFR");
- goto try_axfr;
- }
-
- if (xfr->reqtype == dns_rdatatype_soa &&
- (msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
- FAIL(DNS_R_NOTAUTHORITATIVE);
- }
-
-
- result = dns_message_checksig(msg, dns_zone_getview(xfr->zone));
- if (result != ISC_R_SUCCESS) {
- xfrin_log(xfr, ISC_LOG_DEBUG(3), "TSIG check failed: %s",
- isc_result_totext(result));
- goto failure;
- }
-
- for (result = dns_message_firstname(msg, DNS_SECTION_ANSWER);
- result == ISC_R_SUCCESS;
- result = dns_message_nextname(msg, DNS_SECTION_ANSWER))
- {
- dns_rdataset_t *rds;
-
- name = NULL;
- dns_message_currentname(msg, DNS_SECTION_ANSWER, &name);
- for (rds = ISC_LIST_HEAD(name->list);
- rds != NULL;
- rds = ISC_LIST_NEXT(rds, link))
- {
- for (result = dns_rdataset_first(rds);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(rds))
- {
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdataset_current(rds, &rdata);
- CHECK(xfr_rr(xfr, name, rds->ttl, &rdata));
- }
- }
- }
- if (result != ISC_R_NOMORE)
- goto failure;
-
- if (dns_message_gettsig(msg, &tsigowner) != NULL) {
- /*
- * Reset the counter.
- */
- xfr->sincetsig = 0;
-
- /*
- * Free the last tsig, if there is one.
- */
- if (xfr->lasttsig != NULL)
- isc_buffer_free(&xfr->lasttsig);
-
- /*
- * Update the last tsig pointer.
- */
- CHECK(dns_message_getquerytsig(msg, xfr->mctx,
- &xfr->lasttsig));
-
- } else if (dns_message_gettsigkey(msg) != NULL) {
- xfr->sincetsig++;
- if (xfr->sincetsig > 100 || xfr->nmsg == 0 ||
- xfr->state == XFRST_AXFR_END ||
- xfr->state == XFRST_IXFR_END)
- {
- result = DNS_R_EXPECTEDTSIG;
- goto failure;
- }
- }
-
- /*
- * Update the number of messages received.
- */
- xfr->nmsg++;
-
- /*
- * Update the number of bytes received.
- */
- xfr->nbytes += tcpmsg->buffer.used;
-
- /*
- * Take the context back.
- */
- INSIST(xfr->tsigctx == NULL);
- xfr->tsigctx = msg->tsigctx;
- msg->tsigctx = NULL;
-
- dns_message_destroy(&msg);
-
- switch (xfr->state) {
- case XFRST_GOTSOA:
- xfr->reqtype = dns_rdatatype_axfr;
- xfr->state = XFRST_INITIALSOA;
- CHECK(xfrin_send_request(xfr));
- 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.
- */
- if (xfr->done != NULL) {
- (xfr->done)(xfr->zone, ISC_R_SUCCESS);
- xfr->done = NULL;
- }
- /*
- * We should have no outstanding events at this
- * point, thus maybe_free() should succeed.
- */
- xfr->shuttingdown = ISC_TRUE;
- maybe_free(xfr);
- break;
- default:
- /*
- * Read the next message.
- */
- CHECK(dns_tcpmsg_readmessage(&xfr->tcpmsg, xfr->task,
- xfrin_recv_done, xfr));
- xfr->recvs++;
- }
- return;
-
- failure:
- if (msg != NULL)
- dns_message_destroy(&msg);
- if (result != ISC_R_SUCCESS)
- xfrin_fail(xfr, result, "failed while receiving responses");
-}
-
-static void
-xfrin_timeout(isc_task_t *task, isc_event_t *event) {
- dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg;
-
- REQUIRE(VALID_XFRIN(xfr));
-
- UNUSED(task);
-
- isc_event_free(&event);
- /*
- * This will log "giving up: timeout".
- */
- xfrin_fail(xfr, ISC_R_TIMEDOUT, "giving up");
-}
-
-static void
-maybe_free(dns_xfrin_ctx_t *xfr) {
- isc_uint64_t msecs;
- isc_uint64_t persec;
-
- REQUIRE(VALID_XFRIN(xfr));
-
- if (! xfr->shuttingdown || xfr->refcount != 0 ||
- xfr->connects != 0 || xfr->sends != 0 ||
- xfr->recvs != 0)
- return;
-
- /*
- * Calculate the length of time the transfer took,
- * and print a log message with the bytes and rate.
- */
- isc_time_now(&xfr->end);
- msecs = isc_time_microdiff(&xfr->end, &xfr->start) / 1000;
- if (msecs == 0)
- msecs = 1;
- persec = (xfr->nbytes * 1000) / msecs;
- xfrin_log(xfr, ISC_LOG_INFO,
- "Transfer completed: %d messages, %d records, "
- "%" ISC_PRINT_QUADFORMAT "u bytes, "
- "%u.%03u secs (%u bytes/sec)",
- xfr->nmsg, xfr->nrecs, xfr->nbytes,
- (unsigned int) (msecs / 1000), (unsigned int) (msecs % 1000),
- (unsigned int) persec);
-
- if (xfr->socket != NULL)
- isc_socket_detach(&xfr->socket);
-
- if (xfr->timer != NULL)
- isc_timer_detach(&xfr->timer);
-
- if (xfr->task != NULL)
- isc_task_detach(&xfr->task);
-
- if (xfr->tsigkey != NULL)
- dns_tsigkey_detach(&xfr->tsigkey);
-
- if (xfr->lasttsig != NULL)
- isc_buffer_free(&xfr->lasttsig);
-
- dns_diff_clear(&xfr->diff);
-
- if (xfr->ixfr.journal != NULL)
- dns_journal_destroy(&xfr->ixfr.journal);
-
- if (xfr->axfr.add_private != NULL)
- (void)dns_db_endload(xfr->db, &xfr->axfr.add_private);
-
- if (xfr->tcpmsg_valid)
- dns_tcpmsg_invalidate(&xfr->tcpmsg);
-
- if (xfr->tsigctx != NULL)
- dst_context_destroy(&xfr->tsigctx);
-
- if ((xfr->name.attributes & DNS_NAMEATTR_DYNAMIC) != 0)
- dns_name_free(&xfr->name, xfr->mctx);
-
- if (xfr->ver != NULL)
- dns_db_closeversion(xfr->db, &xfr->ver, ISC_FALSE);
-
- if (xfr->db != NULL)
- dns_db_detach(&xfr->db);
-
- if (xfr->zone != NULL)
- dns_zone_idetach(&xfr->zone);
-
- isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr));
-}
-
-/*
- * Log incoming zone transfer messages in a format like
- * transfer of <zone> from <address>: <message>
- */
-static void
-xfrin_logv(int level, const char *zonetext, isc_sockaddr_t *masteraddr,
- const char *fmt, va_list ap)
-{
- char mastertext[ISC_SOCKADDR_FORMATSIZE];
- char msgtext[2048];
-
- isc_sockaddr_format(masteraddr, mastertext, sizeof(mastertext));
- vsnprintf(msgtext, sizeof(msgtext), fmt, ap);
-
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_XFER_IN,
- DNS_LOGMODULE_XFER_IN, level,
- "transfer of '%s' from %s: %s",
- zonetext, mastertext, msgtext);
-}
-
-/*
- * Logging function for use when a xfrin_ctx_t has not yet been created.
- */
-
-static void
-xfrin_log1(int level, const char *zonetext, isc_sockaddr_t *masteraddr,
- const char *fmt, ...)
-{
- va_list ap;
-
- if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
- return;
-
- va_start(ap, fmt);
- xfrin_logv(level, zonetext, masteraddr, fmt, ap);
- va_end(ap);
-}
-
-/*
- * Logging function for use when there is a xfrin_ctx_t.
- */
-
-static void
-xfrin_log(dns_xfrin_ctx_t *xfr, int level, const char *fmt, ...)
-{
- va_list ap;
- char zonetext[DNS_NAME_MAXTEXT+32];
-
- if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
- return;
-
- dns_zone_name(xfr->zone, zonetext, sizeof(zonetext));
-
- va_start(ap, fmt);
- xfrin_logv(level, zonetext, &xfr->masteraddr, fmt, ap);
- va_end(ap);
-}
diff --git a/contrib/bind9/lib/dns/zone.c b/contrib/bind9/lib/dns/zone.c
deleted file mode 100644
index 10ba807c52f1..000000000000
--- a/contrib/bind9/lib/dns/zone.c
+++ /dev/null
@@ -1,16753 +0,0 @@
-/*
- * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/*! \file */
-
-#include <config.h>
-#include <errno.h>
-
-#include <isc/file.h>
-#include <isc/hex.h>
-#include <isc/mutex.h>
-#include <isc/pool.h>
-#include <isc/print.h>
-#include <isc/random.h>
-#include <isc/ratelimiter.h>
-#include <isc/refcount.h>
-#include <isc/rwlock.h>
-#include <isc/serial.h>
-#include <isc/stats.h>
-#include <isc/stdtime.h>
-#include <isc/strerror.h>
-#include <isc/string.h>
-#include <isc/taskpool.h>
-#include <isc/timer.h>
-#include <isc/util.h>
-
-#include <dns/acache.h>
-#include <dns/acl.h>
-#include <dns/adb.h>
-#include <dns/callbacks.h>
-#include <dns/db.h>
-#include <dns/dbiterator.h>
-#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>
-#include <dns/masterdump.h>
-#include <dns/message.h>
-#include <dns/name.h>
-#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/rdata.h>
-#include <dns/rdataclass.h>
-#include <dns/rdatalist.h>
-#include <dns/rdataset.h>
-#include <dns/rdatasetiter.h>
-#include <dns/rdatastruct.h>
-#include <dns/rdatatype.h>
-#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>
-#include <dns/time.h>
-#include <dns/tsig.h>
-#include <dns/update.h>
-#include <dns/xfrin.h>
-#include <dns/zone.h>
-#include <dns/zt.h>
-
-#include <dst/dst.h>
-
-#define ZONE_MAGIC ISC_MAGIC('Z', 'O', 'N', 'E')
-#define DNS_ZONE_VALID(zone) ISC_MAGIC_VALID(zone, ZONE_MAGIC)
-
-#define NOTIFY_MAGIC ISC_MAGIC('N', 't', 'f', 'y')
-#define DNS_NOTIFY_VALID(notify) ISC_MAGIC_VALID(notify, NOTIFY_MAGIC)
-
-#define STUB_MAGIC ISC_MAGIC('S', 't', 'u', 'b')
-#define DNS_STUB_VALID(stub) ISC_MAGIC_VALID(stub, STUB_MAGIC)
-
-#define ZONEMGR_MAGIC ISC_MAGIC('Z', 'm', 'g', 'r')
-#define DNS_ZONEMGR_VALID(stub) ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC)
-
-#define LOAD_MAGIC ISC_MAGIC('L', 'o', 'a', 'd')
-#define DNS_LOAD_VALID(load) ISC_MAGIC_VALID(load, LOAD_MAGIC)
-
-#define FORWARD_MAGIC ISC_MAGIC('F', 'o', 'r', 'w')
-#define DNS_FORWARD_VALID(load) ISC_MAGIC_VALID(load, FORWARD_MAGIC)
-
-#define IO_MAGIC ISC_MAGIC('Z', 'm', 'I', 'O')
-#define DNS_IO_VALID(load) ISC_MAGIC_VALID(load, IO_MAGIC)
-
-/*%
- * Ensure 'a' is at least 'min' but not more than 'max'.
- */
-#define RANGE(a, min, max) \
- (((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max)))
-
-#define NSEC3REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
-
-/*%
- * Key flags
- */
-#define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0)
-#define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0)
-#define ALG(x) dst_key_alg(x)
-
-/*
- * Default values.
- */
-#define DNS_DEFAULT_IDLEIN 3600 /*%< 1 hour */
-#define DNS_DEFAULT_IDLEOUT 3600 /*%< 1 hour */
-#define MAX_XFER_TIME (2*3600) /*%< Documented default is 2 hours */
-#define RESIGN_DELAY 3600 /*%< 1 hour */
-
-#ifndef DNS_MAX_EXPIRE
-#define DNS_MAX_EXPIRE 14515200 /*%< 24 weeks */
-#endif
-
-#ifndef DNS_DUMP_DELAY
-#define DNS_DUMP_DELAY 900 /*%< 15 minutes */
-#endif
-
-typedef struct dns_notify dns_notify_t;
-typedef struct dns_stub dns_stub_t;
-typedef struct dns_load dns_load_t;
-typedef struct dns_forward dns_forward_t;
-typedef ISC_LIST(dns_forward_t) dns_forwardlist_t;
-typedef struct dns_io dns_io_t;
-typedef ISC_LIST(dns_io_t) dns_iolist_t;
-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;
-typedef struct dns_asyncload dns_asyncload_t;
-
-#define DNS_ZONE_CHECKLOCK
-#ifdef DNS_ZONE_CHECKLOCK
-#define LOCK_ZONE(z) \
- do { LOCK(&(z)->lock); \
- INSIST((z)->locked == ISC_FALSE); \
- (z)->locked = ISC_TRUE; \
- } while (0)
-#define UNLOCK_ZONE(z) \
- do { (z)->locked = ISC_FALSE; UNLOCK(&(z)->lock); } while (0)
-#define LOCKED_ZONE(z) ((z)->locked)
-#else
-#define LOCK_ZONE(z) LOCK(&(z)->lock)
-#define UNLOCK_ZONE(z) UNLOCK(&(z)->lock)
-#define LOCKED_ZONE(z) ISC_TRUE
-#endif
-
-#ifdef ISC_RWLOCK_USEATOMIC
-#define ZONEDB_INITLOCK(l) isc_rwlock_init((l), 0, 0)
-#define ZONEDB_DESTROYLOCK(l) isc_rwlock_destroy(l)
-#define ZONEDB_LOCK(l, t) RWLOCK((l), (t))
-#define ZONEDB_UNLOCK(l, t) RWUNLOCK((l), (t))
-#else
-#define ZONEDB_INITLOCK(l) isc_mutex_init(l)
-#define ZONEDB_DESTROYLOCK(l) DESTROYLOCK(l)
-#define ZONEDB_LOCK(l, t) LOCK(l)
-#define ZONEDB_UNLOCK(l, t) UNLOCK(l)
-#endif
-
-struct dns_zone {
- /* Unlocked */
- unsigned int magic;
- isc_mutex_t lock;
-#ifdef DNS_ZONE_CHECKLOCK
- isc_boolean_t locked;
-#endif
- isc_mem_t *mctx;
- isc_refcount_t erefs;
-
-#ifdef ISC_RWLOCK_USEATOMIC
- isc_rwlock_t dblock;
-#else
- isc_mutex_t dblock;
-#endif
- dns_db_t *db; /* Locked by dblock */
-
- /* Locked */
- dns_zonemgr_t *zmgr;
- ISC_LINK(dns_zone_t) link; /* Used by zmgr. */
- isc_timer_t *timer;
- unsigned int irefs;
- dns_name_t origin;
- char *masterfile;
- dns_masterformat_t masterformat;
- char *journal;
- isc_int32_t journalsize;
- dns_rdataclass_t rdclass;
- dns_zonetype_t type;
- unsigned int flags;
- unsigned int options;
- unsigned int db_argc;
- char **db_argv;
- isc_time_t expiretime;
- isc_time_t refreshtime;
- isc_time_t dumptime;
- isc_time_t loadtime;
- isc_time_t notifytime;
- isc_time_t resigntime;
- isc_time_t keywarntime;
- isc_time_t signingtime;
- isc_time_t nsec3chaintime;
- isc_time_t refreshkeytime;
- isc_uint32_t refreshkeyinterval;
- isc_uint32_t refreshkeycount;
- isc_uint32_t refresh;
- isc_uint32_t retry;
- isc_uint32_t expire;
- isc_uint32_t minimum;
- isc_stdtime_t key_expiry;
- isc_stdtime_t log_key_expired_timer;
- char *keydirectory;
-
- isc_uint32_t maxrefresh;
- isc_uint32_t minrefresh;
- isc_uint32_t maxretry;
- isc_uint32_t minretry;
-
- isc_sockaddr_t *masters;
- dns_name_t **masterkeynames;
- isc_boolean_t *mastersok;
- unsigned int masterscnt;
- unsigned int curmaster;
- isc_sockaddr_t masteraddr;
- dns_notifytype_t notifytype;
- isc_sockaddr_t *notify;
- dns_name_t **notifykeynames;
- unsigned int notifycnt;
- isc_sockaddr_t notifyfrom;
- isc_task_t *task;
- isc_task_t *loadtask;
- isc_sockaddr_t notifysrc4;
- isc_sockaddr_t notifysrc6;
- isc_sockaddr_t xfrsource4;
- isc_sockaddr_t xfrsource6;
- isc_sockaddr_t altxfrsource4;
- isc_sockaddr_t altxfrsource6;
- isc_sockaddr_t sourceaddr;
- dns_xfrin_ctx_t *xfr; /* task locked */
- dns_tsigkey_t *tsigkey; /* key used for xfr */
- /* Access Control Lists */
- dns_acl_t *update_acl;
- dns_acl_t *forward_acl;
- dns_acl_t *notify_acl;
- dns_acl_t *query_acl;
- dns_acl_t *queryon_acl;
- dns_acl_t *xfr_acl;
- isc_boolean_t update_disabled;
- isc_boolean_t zero_no_soa_ttl;
- dns_severity_t check_names;
- ISC_LIST(dns_notify_t) notifies;
- dns_request_t *request;
- dns_loadctx_t *lctx;
- dns_io_t *readio;
- dns_dumpctx_t *dctx;
- dns_io_t *writeio;
- isc_uint32_t maxxfrin;
- isc_uint32_t maxxfrout;
- isc_uint32_t idlein;
- isc_uint32_t idleout;
- isc_event_t ctlevent;
- dns_ssutable_t *ssutable;
- isc_uint32_t sigvalidityinterval;
- isc_uint32_t sigresigninginterval;
- dns_view_t *view;
- dns_acache_t *acache;
- dns_checkmxfunc_t checkmx;
- dns_checksrvfunc_t checksrv;
- dns_checknsfunc_t checkns;
- /*%
- * Zones in certain states such as "waiting for zone transfer"
- * or "zone transfer in progress" are kept on per-state linked lists
- * in the zone manager using the 'statelink' field. The 'statelist'
- * field points at the list the zone is currently on. It the zone
- * is not on any such list, statelist is NULL.
- */
- ISC_LINK(dns_zone_t) statelink;
- dns_zonelist_t *statelist;
- /*%
- * Statistics counters about zone management.
- */
- isc_stats_t *stats;
- /*%
- * Optional per-zone statistics counters. Counted outside of this
- * module.
- */
- dns_zonestat_level_t statlevel;
- isc_boolean_t requeststats_on;
- isc_stats_t *requeststats;
- dns_stats_t *rcvquerystats;
- isc_uint32_t notifydelay;
- dns_isselffunc_t isself;
- void *isselfarg;
-
- char * strnamerd;
- char * strname;
- char * strrdclass;
- char * strviewname;
-
- /*%
- * Serial number for deferred journal compaction.
- */
- isc_uint32_t compact_serial;
- /*%
- * Keys that are signing the zone for the first time.
- */
- dns_signinglist_t signing;
- dns_nsec3chainlist_t nsec3chain;
- /*%
- * Signing / re-signing quantum stopping parameters.
- */
- 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 this is a response policy zone
- */
- isc_boolean_t is_rpz;
-
- /*%
- * Serial number update method.
- */
- dns_updatemethod_t updatemethod;
-
- /*%
- * whether ixfr is requested
- */
- isc_boolean_t requestixfr;
-
- /*%
- * Outstanding forwarded UPDATE requests.
- */
- dns_forwardlist_t forwards;
-
- dns_zone_t *raw;
- dns_zone_t *secure;
-
- isc_boolean_t sourceserialset;
- isc_uint32_t sourceserial;
-};
-
-typedef struct {
- dns_diff_t *diff;
- isc_boolean_t offline;
-} zonediff_t;
-
-#define zonediff_init(z, d) \
- do { \
- zonediff_t *_z = (z); \
- (_z)->diff = (d); \
- (_z)->offline = ISC_FALSE; \
- } while (0)
-
-#define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0))
-#define DNS_ZONE_SETFLAG(z,f) do { \
- INSIST(LOCKED_ZONE(z)); \
- (z)->flags |= (f); \
- } while (0)
-#define DNS_ZONE_CLRFLAG(z,f) do { \
- INSIST(LOCKED_ZONE(z)); \
- (z)->flags &= ~(f); \
- } while (0)
- /* XXX MPA these may need to go back into zone.h */
-#define DNS_ZONEFLG_REFRESH 0x00000001U /*%< refresh check in progress */
-#define DNS_ZONEFLG_NEEDDUMP 0x00000002U /*%< zone need consolidation */
-#define DNS_ZONEFLG_USEVC 0x00000004U /*%< use tcp for refresh query */
-#define DNS_ZONEFLG_DUMPING 0x00000008U /*%< a dump is in progress */
-#define DNS_ZONEFLG_HASINCLUDE 0x00000010U /*%< $INCLUDE in zone file */
-#define DNS_ZONEFLG_LOADED 0x00000020U /*%< database has loaded */
-#define DNS_ZONEFLG_EXITING 0x00000040U /*%< zone is being destroyed */
-#define DNS_ZONEFLG_EXPIRED 0x00000080U /*%< zone has expired */
-#define DNS_ZONEFLG_NEEDREFRESH 0x00000100U /*%< refresh check needed */
-#define DNS_ZONEFLG_UPTODATE 0x00000200U /*%< zone contents are
- * uptodate */
-#define DNS_ZONEFLG_NEEDNOTIFY 0x00000400U /*%< need to send out notify
- * messages */
-#define DNS_ZONEFLG_DIFFONRELOAD 0x00000800U /*%< generate a journal diff on
- * reload */
-#define DNS_ZONEFLG_NOMASTERS 0x00001000U /*%< an attempt to refresh a
- * zone with no masters
- * occurred */
-#define DNS_ZONEFLG_LOADING 0x00002000U /*%< load from disk in progress*/
-#define DNS_ZONEFLG_HAVETIMERS 0x00004000U /*%< timer values have been set
- * from SOA (if not set, we
- * are still using
- * default timer values) */
-#define DNS_ZONEFLG_FORCEXFER 0x00008000U /*%< Force a zone xfer */
-#define DNS_ZONEFLG_NOREFRESH 0x00010000U
-#define DNS_ZONEFLG_DIALNOTIFY 0x00020000U
-#define DNS_ZONEFLG_DIALREFRESH 0x00040000U
-#define DNS_ZONEFLG_SHUTDOWN 0x00080000U
-#define DNS_ZONEFLAG_NOIXFR 0x00100000U /*%< IXFR failed, force AXFR */
-#define DNS_ZONEFLG_FLUSH 0x00200000U
-#define DNS_ZONEFLG_NOEDNS 0x00400000U
-#define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U
-#define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U
-#define DNS_ZONEFLG_NEEDCOMPACT 0x02000000U
-#define DNS_ZONEFLG_REFRESHING 0x04000000U /*%< Refreshing keydata */
-#define DNS_ZONEFLG_THAW 0x08000000U
-#define DNS_ZONEFLG_LOADPENDING 0x10000000U /*%< Loading scheduled */
-#define DNS_ZONEFLG_NODELAY 0x20000000U
-#define DNS_ZONEFLG_SENDSECURE 0x40000000U
-
-#define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
-#define DNS_ZONEKEY_OPTION(z,o) (((z)->keyopts & (o)) != 0)
-
-/* Flags for zone_load() */
-#define DNS_ZONELOADFLAG_NOSTAT 0x00000001U /* Do not stat() master files */
-#define DNS_ZONELOADFLAG_THAW 0x00000002U /* Thaw the zone on successful
- load. */
-
-#define UNREACH_CHACHE_SIZE 10U
-#define UNREACH_HOLD_TIME 600 /* 10 minutes */
-
-#define CHECK(op) \
- do { result = (op); \
- if (result != ISC_R_SUCCESS) goto failure; \
- } while (0)
-
-struct dns_unreachable {
- isc_sockaddr_t remote;
- isc_sockaddr_t local;
- isc_uint32_t expire;
- isc_uint32_t last;
-};
-
-struct dns_zonemgr {
- unsigned int magic;
- isc_mem_t * mctx;
- int refs; /* Locked by rwlock */
- isc_taskmgr_t * taskmgr;
- isc_timermgr_t * timermgr;
- isc_socketmgr_t * socketmgr;
- isc_taskpool_t * zonetasks;
- isc_taskpool_t * loadtasks;
- isc_task_t * task;
- isc_pool_t * mctxpool;
- isc_ratelimiter_t * rl;
- isc_rwlock_t rwlock;
- isc_mutex_t iolock;
- isc_rwlock_t urlock;
-
- /* Locked by rwlock. */
- dns_zonelist_t zones;
- dns_zonelist_t waiting_for_xfrin;
- dns_zonelist_t xfrin_in_progress;
-
- /* Configuration data. */
- isc_uint32_t transfersin;
- isc_uint32_t transfersperns;
- unsigned int serialqueryrate;
-
- /* Locked by iolock */
- isc_uint32_t iolimit;
- isc_uint32_t ioactive;
- dns_iolist_t high;
- dns_iolist_t low;
-
- /* Locked by urlock. */
- /* LRU cache */
- struct dns_unreachable unreachable[UNREACH_CHACHE_SIZE];
-};
-
-/*%
- * Hold notify state.
- */
-struct dns_notify {
- unsigned int magic;
- unsigned int flags;
- isc_mem_t *mctx;
- dns_zone_t *zone;
- dns_adbfind_t *find;
- dns_request_t *request;
- dns_name_t ns;
- isc_sockaddr_t dst;
- dns_tsigkey_t *key;
- ISC_LINK(dns_notify_t) link;
-};
-
-#define DNS_NOTIFY_NOSOA 0x0001U
-
-/*%
- * dns_stub holds state while performing a 'stub' transfer.
- * 'db' is the zone's 'db' or a new one if this is the initial
- * transfer.
- */
-
-struct dns_stub {
- unsigned int magic;
- isc_mem_t *mctx;
- dns_zone_t *zone;
- dns_db_t *db;
- dns_dbversion_t *version;
-};
-
-/*%
- * Hold load state.
- */
-struct dns_load {
- unsigned int magic;
- isc_mem_t *mctx;
- dns_zone_t *zone;
- dns_db_t *db;
- isc_time_t loadtime;
- dns_rdatacallbacks_t callbacks;
-};
-
-/*%
- * Hold forward state.
- */
-struct dns_forward {
- unsigned int magic;
- isc_mem_t *mctx;
- dns_zone_t *zone;
- isc_buffer_t *msgbuf;
- dns_request_t *request;
- isc_uint32_t which;
- isc_sockaddr_t addr;
- dns_updatecallback_t callback;
- void *callback_arg;
- ISC_LINK(dns_forward_t) link;
-};
-
-/*%
- * Hold IO request state.
- */
-struct dns_io {
- unsigned int magic;
- dns_zonemgr_t *zmgr;
- isc_boolean_t high;
- isc_task_t *task;
- ISC_LINK(dns_io_t) link;
- isc_event_t *event;
-};
-
-/*%
- * Hold state for when we are signing a zone with a new
- * DNSKEY as result of an update.
- */
-struct dns_signing {
- unsigned int magic;
- dns_db_t *db;
- dns_dbiterator_t *dbiterator;
- dns_secalg_t algorithm;
- isc_uint16_t keyid;
- isc_boolean_t delete;
- isc_boolean_t done;
- ISC_LINK(dns_signing_t) link;
-};
-
-struct dns_nsec3chain {
- 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_LINK(dns_nsec3chain_t) link;
-};
-/*%<
- * 'dbiterator' contains a iterator for the database. If we are creating
- * a NSEC3 chain only the non-NSEC3 nodes will be iterated. If we are
- * removing a NSEC3 chain then both NSEC3 and non-NSEC3 nodes will be
- * iterated.
- *
- * 'nsec3param' contains the parameters of the NSEC3 chain being created
- * or removed.
- *
- * 'salt' is buffer space and is referenced via 'nsec3param.salt'.
- *
- * 'seen_nsec' will be set to true if, while iterating the zone to create a
- * NSEC3 chain, a NSEC record is seen.
- *
- * 'delete_nsec' will be set to true if, at the completion of the creation
- * of a NSEC3 chain, 'seen_nsec' is true. If 'delete_nsec' is true then we
- * are in the process of deleting the NSEC chain.
- *
- * 'save_delete_nsec' is used to store the initial state of 'delete_nsec'
- * so it can be recovered in the event of a error.
- */
-
-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;
-};
-
-/*%
- * Hold state for an asynchronous load
- */
-struct dns_asyncload {
- dns_zone_t *zone;
- dns_zt_zoneloaded_t loaded;
- void *loaded_arg;
-};
-
-#define HOUR 3600
-#define DAY (24*HOUR)
-#define MONTH (30*DAY)
-
-#define SEND_BUFFER_SIZE 2048
-
-static void zone_settimer(dns_zone_t *, isc_time_t *);
-static void cancel_refresh(dns_zone_t *);
-static void zone_debuglog(dns_zone_t *zone, const char *, int debuglevel,
- const char *msg, ...) ISC_FORMAT_PRINTF(4, 5);
-static void notify_log(dns_zone_t *zone, int level, const char *fmt, ...)
- ISC_FORMAT_PRINTF(3, 4);
-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);
-static void zone_idetach(dns_zone_t **zonep);
-static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db,
- isc_boolean_t dump);
-static inline void zone_attachdb(dns_zone_t *zone, dns_db_t *db);
-static inline void zone_detachdb(dns_zone_t *zone);
-static isc_result_t default_journal(dns_zone_t *zone);
-static void zone_xfrdone(dns_zone_t *zone, isc_result_t result);
-static isc_result_t zone_postload(dns_zone_t *zone, dns_db_t *db,
- isc_time_t loadtime, isc_result_t result);
-static void zone_needdump(dns_zone_t *zone, unsigned int delay);
-static void zone_shutdown(isc_task_t *, isc_event_t *);
-static void zone_loaddone(void *arg, isc_result_t result);
-static isc_result_t zone_startload(dns_db_t *db, dns_zone_t *zone,
- isc_time_t loadtime);
-static void zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length);
-static void zone_name_tostr(dns_zone_t *zone, char *buf, size_t length);
-static void zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length);
-static void zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length);
-static isc_result_t zone_send_secureserial(dns_zone_t *zone,
- isc_boolean_t secure_locked,
- isc_uint32_t serial);
-
-#if 0
-/* ondestroy example */
-static void dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event);
-#endif
-
-static void refresh_callback(isc_task_t *, isc_event_t *);
-static void stub_callback(isc_task_t *, isc_event_t *);
-static void queue_soa_query(dns_zone_t *zone);
-static void soa_query(isc_task_t *, isc_event_t *);
-static void ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset,
- dns_stub_t *stub);
-static int message_count(dns_message_t *msg, dns_section_t section,
- dns_rdatatype_t type);
-static void notify_cancel(dns_zone_t *zone);
-static void notify_find_address(dns_notify_t *notify);
-static void notify_send(dns_notify_t *notify);
-static isc_result_t notify_createmessage(dns_zone_t *zone,
- unsigned int flags,
- dns_message_t **messagep);
-static void notify_done(isc_task_t *task, isc_event_t *event);
-static void notify_send_toaddr(isc_task_t *task, isc_event_t *event);
-static isc_result_t zone_dump(dns_zone_t *, isc_boolean_t);
-static void got_transfer_quota(isc_task_t *task, isc_event_t *event);
-static isc_result_t zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr,
- dns_zone_t *zone);
-static void zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi);
-static void zonemgr_free(dns_zonemgr_t *zmgr);
-static isc_result_t zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
- isc_task_t *task, isc_taskaction_t action,
- void *arg, dns_io_t **iop);
-static void zonemgr_putio(dns_io_t **iop);
-static void zonemgr_cancelio(dns_io_t *io);
-
-static isc_result_t
-zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
- unsigned int *soacount, isc_uint32_t *serial,
- isc_uint32_t *refresh, isc_uint32_t *retry,
- isc_uint32_t *expire, isc_uint32_t *minimum,
- unsigned int *errors);
-
-static void zone_freedbargs(dns_zone_t *zone);
-static void forward_callback(isc_task_t *task, isc_event_t *event);
-static void zone_saveunique(dns_zone_t *zone, const char *path,
- const char *templat);
-static void zone_maintenance(dns_zone_t *zone);
-static void zone_notify(dns_zone_t *zone, isc_time_t *now);
-static void dump_done(void *arg, isc_result_t result);
-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);
-static isc_boolean_t delsig_ok(dns_rdata_rrsig_t *rrsig_ptr,
- dst_key_t **keys, unsigned int nkeys);
-static isc_result_t zone_send_securedb(dns_zone_t *zone, isc_boolean_t locked,
- dns_db_t *db);
-
-#define ENTER zone_debuglog(zone, me, 1, "enter")
-
-static const unsigned int dbargc_default = 1;
-static const char *dbargv_default[] = { "rbt" };
-
-#define DNS_ZONE_JITTER_ADD(a, b, c) \
- do { \
- isc_interval_t _i; \
- isc_uint32_t _j; \
- _j = isc_random_jitter((b), (b)/4); \
- isc_interval_set(&_i, _j, 0); \
- if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
- dns_zone_log(zone, ISC_LOG_WARNING, \
- "epoch approaching: upgrade required: " \
- "now + %s failed", #b); \
- isc_interval_set(&_i, _j/2, 0); \
- (void)isc_time_add((a), &_i, (c)); \
- } \
- } while (0)
-
-#define DNS_ZONE_TIME_ADD(a, b, c) \
- do { \
- isc_interval_t _i; \
- isc_interval_set(&_i, (b), 0); \
- if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
- dns_zone_log(zone, ISC_LOG_WARNING, \
- "epoch approaching: upgrade required: " \
- "now + %s failed", #b); \
- isc_interval_set(&_i, (b)/2, 0); \
- (void)isc_time_add((a), &_i, (c)); \
- } \
- } while (0)
-
-/*%
- * Increment resolver-related statistics counters. Zone must be locked.
- */
-static inline void
-inc_stats(dns_zone_t *zone, isc_statscounter_t counter) {
- if (zone->stats != NULL)
- isc_stats_increment(zone->stats, counter);
-}
-
-/***
- *** Public functions.
- ***/
-
-isc_result_t
-dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
- isc_result_t result;
- dns_zone_t *zone;
- isc_time_t now;
-
- REQUIRE(zonep != NULL && *zonep == NULL);
- REQUIRE(mctx != NULL);
-
- TIME_NOW(&now);
- zone = isc_mem_get(mctx, sizeof(*zone));
- if (zone == NULL)
- return (ISC_R_NOMEMORY);
-
- zone->mctx = NULL;
- isc_mem_attach(mctx, &zone->mctx);
-
- result = isc_mutex_init(&zone->lock);
- if (result != ISC_R_SUCCESS)
- goto free_zone;
-
- result = ZONEDB_INITLOCK(&zone->dblock);
- if (result != ISC_R_SUCCESS)
- goto free_mutex;
-
- /* XXX MPA check that all elements are initialised */
-#ifdef DNS_ZONE_CHECKLOCK
- zone->locked = ISC_FALSE;
-#endif
- zone->db = NULL;
- zone->zmgr = NULL;
- ISC_LINK_INIT(zone, link);
- result = isc_refcount_init(&zone->erefs, 1); /* Implicit attach. */
- if (result != ISC_R_SUCCESS)
- goto free_dblock;
- zone->irefs = 0;
- dns_name_init(&zone->origin, NULL);
- zone->strnamerd = NULL;
- zone->strname = NULL;
- zone->strrdclass = NULL;
- zone->strviewname = NULL;
- zone->masterfile = NULL;
- zone->masterformat = dns_masterformat_none;
- zone->keydirectory = NULL;
- zone->journalsize = -1;
- zone->journal = NULL;
- zone->rdclass = dns_rdataclass_none;
- 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);
- isc_time_settoepoch(&zone->refreshtime);
- isc_time_settoepoch(&zone->dumptime);
- isc_time_settoepoch(&zone->loadtime);
- zone->notifytime = now;
- isc_time_settoepoch(&zone->resigntime);
- isc_time_settoepoch(&zone->keywarntime);
- isc_time_settoepoch(&zone->signingtime);
- isc_time_settoepoch(&zone->nsec3chaintime);
- isc_time_settoepoch(&zone->refreshkeytime);
- zone->refreshkeyinterval = 0;
- zone->refreshkeycount = 0;
- zone->refresh = DNS_ZONE_DEFAULTREFRESH;
- zone->retry = DNS_ZONE_DEFAULTRETRY;
- zone->expire = 0;
- zone->minimum = 0;
- zone->maxrefresh = DNS_ZONE_MAXREFRESH;
- zone->minrefresh = DNS_ZONE_MINREFRESH;
- zone->maxretry = DNS_ZONE_MAXRETRY;
- zone->minretry = DNS_ZONE_MINRETRY;
- zone->masters = NULL;
- zone->masterkeynames = NULL;
- zone->mastersok = NULL;
- zone->masterscnt = 0;
- zone->curmaster = 0;
- zone->notify = NULL;
- zone->notifykeynames = NULL;
- zone->notifytype = dns_notifytype_yes;
- zone->notifycnt = 0;
- zone->task = NULL;
- zone->loadtask = NULL;
- zone->update_acl = NULL;
- zone->forward_acl = NULL;
- zone->notify_acl = NULL;
- zone->query_acl = NULL;
- zone->queryon_acl = NULL;
- zone->xfr_acl = NULL;
- zone->update_disabled = ISC_FALSE;
- zone->zero_no_soa_ttl = ISC_TRUE;
- zone->check_names = dns_severity_ignore;
- zone->request = NULL;
- zone->lctx = NULL;
- zone->readio = NULL;
- zone->dctx = NULL;
- zone->writeio = NULL;
- zone->timer = NULL;
- zone->idlein = DNS_DEFAULT_IDLEIN;
- zone->idleout = DNS_DEFAULT_IDLEOUT;
- zone->log_key_expired_timer = 0;
- ISC_LIST_INIT(zone->notifies);
- isc_sockaddr_any(&zone->notifysrc4);
- isc_sockaddr_any6(&zone->notifysrc6);
- isc_sockaddr_any(&zone->xfrsource4);
- isc_sockaddr_any6(&zone->xfrsource6);
- isc_sockaddr_any(&zone->altxfrsource4);
- isc_sockaddr_any6(&zone->altxfrsource6);
- zone->xfr = NULL;
- zone->tsigkey = NULL;
- zone->maxxfrin = MAX_XFER_TIME;
- zone->maxxfrout = MAX_XFER_TIME;
- zone->ssutable = NULL;
- zone->sigvalidityinterval = 30 * 24 * 3600;
- zone->sigresigninginterval = 7 * 24 * 3600;
- zone->view = NULL;
- zone->acache = NULL;
- zone->checkmx = NULL;
- zone->checksrv = NULL;
- zone->checkns = NULL;
- ISC_LINK_INIT(zone, statelink);
- zone->statelist = NULL;
- zone->stats = NULL;
- zone->requeststats_on = ISC_FALSE;
- zone->statlevel = dns_zonestat_none;
- zone->requeststats = NULL;
- zone->rcvquerystats = NULL;
- zone->notifydelay = 5;
- zone->isself = NULL;
- zone->isselfarg = NULL;
- ISC_LIST_INIT(zone->signing);
- ISC_LIST_INIT(zone->nsec3chain);
- zone->signatures = 10;
- zone->nodes = 100;
- zone->privatetype = (dns_rdatatype_t)0xffffU;
- zone->added = ISC_FALSE;
- zone->is_rpz = ISC_FALSE;
- ISC_LIST_INIT(zone->forwards);
- zone->raw = NULL;
- zone->secure = NULL;
- zone->sourceserial = 0;
- zone->sourceserialset = ISC_FALSE;
-
- zone->magic = ZONE_MAGIC;
-
- /* Must be after magic is set. */
- result = dns_zone_setdbtype(zone, dbargc_default, dbargv_default);
- if (result != ISC_R_SUCCESS)
- goto free_erefs;
-
- ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL,
- DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone,
- NULL, NULL);
- *zonep = zone;
- return (ISC_R_SUCCESS);
-
- free_erefs:
- isc_refcount_decrement(&zone->erefs, NULL);
- isc_refcount_destroy(&zone->erefs);
-
- free_dblock:
- ZONEDB_DESTROYLOCK(&zone->dblock);
-
- free_mutex:
- DESTROYLOCK(&zone->lock);
-
- free_zone:
- isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone));
- return (result);
-}
-
-/*
- * Free a zone. Because we require that there be no more
- * outstanding events or references, no locking is necessary.
- */
-static void
-zone_free(dns_zone_t *zone) {
- isc_mem_t *mctx = NULL;
- dns_signing_t *signing;
- dns_nsec3chain_t *nsec3chain;
-
- REQUIRE(DNS_ZONE_VALID(zone));
- REQUIRE(isc_refcount_current(&zone->erefs) == 0);
- REQUIRE(zone->irefs == 0);
- REQUIRE(!LOCKED_ZONE(zone));
- REQUIRE(zone->timer == NULL);
-
- /*
- * Managed objects. Order is important.
- */
- if (zone->request != NULL)
- dns_request_destroy(&zone->request); /* XXXMPA */
- INSIST(zone->readio == NULL);
- INSIST(zone->statelist == NULL);
- INSIST(zone->writeio == NULL);
-
- if (zone->task != NULL)
- isc_task_detach(&zone->task);
- if (zone->loadtask != NULL)
- isc_task_detach(&zone->loadtask);
- if (zone->zmgr != NULL)
- dns_zonemgr_releasezone(zone->zmgr, zone);
-
- /* Unmanaged objects */
- for (signing = ISC_LIST_HEAD(zone->signing);
- signing != NULL;
- signing = ISC_LIST_HEAD(zone->signing)) {
- ISC_LIST_UNLINK(zone->signing, signing, link);
- dns_db_detach(&signing->db);
- dns_dbiterator_destroy(&signing->dbiterator);
- isc_mem_put(zone->mctx, signing, sizeof *signing);
- }
- for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
- nsec3chain != NULL;
- nsec3chain = ISC_LIST_HEAD(zone->nsec3chain)) {
- ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
- dns_db_detach(&nsec3chain->db);
- dns_dbiterator_destroy(&nsec3chain->dbiterator);
- isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
- }
- if (zone->masterfile != NULL)
- isc_mem_free(zone->mctx, zone->masterfile);
- zone->masterfile = NULL;
- if (zone->keydirectory != NULL)
- isc_mem_free(zone->mctx, zone->keydirectory);
- zone->keydirectory = NULL;
- zone->journalsize = -1;
- if (zone->journal != NULL)
- isc_mem_free(zone->mctx, zone->journal);
- zone->journal = NULL;
- if (zone->stats != NULL)
- isc_stats_detach(&zone->stats);
- if (zone->requeststats != NULL)
- isc_stats_detach(&zone->requeststats);
- if(zone->rcvquerystats != NULL )
- dns_stats_detach(&zone->rcvquerystats);
- if (zone->db != NULL)
- zone_detachdb(zone);
- if (zone->acache != NULL)
- dns_acache_detach(&zone->acache);
- zone_freedbargs(zone);
- RUNTIME_CHECK(dns_zone_setmasterswithkeys(zone, NULL, NULL, 0)
- == ISC_R_SUCCESS);
- RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, 0)
- == ISC_R_SUCCESS);
- zone->check_names = dns_severity_ignore;
- if (zone->update_acl != NULL)
- dns_acl_detach(&zone->update_acl);
- if (zone->forward_acl != NULL)
- dns_acl_detach(&zone->forward_acl);
- if (zone->notify_acl != NULL)
- dns_acl_detach(&zone->notify_acl);
- if (zone->query_acl != NULL)
- dns_acl_detach(&zone->query_acl);
- if (zone->queryon_acl != NULL)
- dns_acl_detach(&zone->queryon_acl);
- if (zone->xfr_acl != NULL)
- dns_acl_detach(&zone->xfr_acl);
- if (dns_name_dynamic(&zone->origin))
- dns_name_free(&zone->origin, zone->mctx);
- if (zone->strnamerd != NULL)
- isc_mem_free(zone->mctx, zone->strnamerd);
- if (zone->strname != NULL)
- isc_mem_free(zone->mctx, zone->strname);
- if (zone->strrdclass != NULL)
- isc_mem_free(zone->mctx, zone->strrdclass);
- if (zone->strviewname != NULL)
- isc_mem_free(zone->mctx, zone->strviewname);
- if (zone->ssutable != NULL)
- dns_ssutable_detach(&zone->ssutable);
-
- /* last stuff */
- ZONEDB_DESTROYLOCK(&zone->dblock);
- DESTROYLOCK(&zone->lock);
- isc_refcount_destroy(&zone->erefs);
- zone->magic = 0;
- mctx = zone->mctx;
- isc_mem_put(mctx, zone, sizeof(*zone));
- isc_mem_detach(&mctx);
-}
-
-/*
- * Returns ISC_TRUE iff this the signed side of an inline-signing zone.
- * Caller should hold zone lock.
- */
-static inline isc_boolean_t
-inline_secure(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
- if (zone->raw != NULL)
- return (ISC_TRUE);
- return (ISC_FALSE);
-}
-
-/*
- * Returns ISC_TRUE iff this the unsigned side of an inline-signing zone
- * Caller should hold zone lock.
- */
-static inline isc_boolean_t
-inline_raw(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
- if (zone->secure != NULL)
- return (ISC_TRUE);
- return (ISC_FALSE);
-}
-
-/*
- * Single shot.
- */
-void
-dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) {
- char namebuf[1024];
-
- REQUIRE(DNS_ZONE_VALID(zone));
- REQUIRE(rdclass != dns_rdataclass_none);
-
- /*
- * Test and set.
- */
- LOCK_ZONE(zone);
- REQUIRE(zone->rdclass == dns_rdataclass_none ||
- zone->rdclass == rdclass);
- zone->rdclass = rdclass;
-
- if (zone->strnamerd != NULL)
- isc_mem_free(zone->mctx, zone->strnamerd);
- if (zone->strrdclass != NULL)
- isc_mem_free(zone->mctx, zone->strrdclass);
-
- zone_namerd_tostr(zone, namebuf, sizeof namebuf);
- zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
- zone_rdclass_tostr(zone, namebuf, sizeof namebuf);
- zone->strrdclass = isc_mem_strdup(zone->mctx, namebuf);
-
- if (inline_secure(zone))
- dns_zone_setclass(zone->raw, rdclass);
- UNLOCK_ZONE(zone);
-}
-
-dns_rdataclass_t
-dns_zone_getclass(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- return (zone->rdclass);
-}
-
-void
-dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- zone->notifytype = notifytype;
- UNLOCK_ZONE(zone);
-}
-
-isc_result_t
-dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp) {
- isc_result_t result;
- unsigned int soacount;
-
- REQUIRE(DNS_ZONE_VALID(zone));
- REQUIRE(serialp != NULL);
-
- LOCK_ZONE(zone);
- ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
- if (zone->db != NULL) {
- result = zone_get_from_db(zone, zone->db, NULL, &soacount,
- serialp, NULL, NULL, NULL, NULL,
- NULL);
- if (result == ISC_R_SUCCESS && soacount == 0)
- result = ISC_R_FAILURE;
- } else
- result = DNS_R_NOTLOADED;
- ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
- UNLOCK_ZONE(zone);
-
- return (result);
-}
-
-isc_uint32_t
-dns_zone_getserial(dns_zone_t *zone) {
- isc_result_t result;
- isc_uint32_t serial;
-
- result = dns_zone_getserial2(zone, &serial);
- if (result != ISC_R_SUCCESS)
- serial = 0; /* XXX: not really correct, but no other choice */
-
- return (serial);
-}
-
-/*
- * Single shot.
- */
-void
-dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) {
- char namebuf[1024];
-
- REQUIRE(DNS_ZONE_VALID(zone));
- REQUIRE(type != dns_zone_none);
-
- /*
- * Test and set.
- */
- LOCK_ZONE(zone);
- REQUIRE(zone->type == dns_zone_none || zone->type == type);
- zone->type = type;
-
- if (zone->strnamerd != NULL)
- isc_mem_free(zone->mctx, zone->strnamerd);
-
- zone_namerd_tostr(zone, namebuf, sizeof namebuf);
- zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
- UNLOCK_ZONE(zone);
-}
-
-static void
-zone_freedbargs(dns_zone_t *zone) {
- unsigned int i;
-
- /* Free the old database argument list. */
- if (zone->db_argv != NULL) {
- for (i = 0; i < zone->db_argc; i++)
- isc_mem_free(zone->mctx, zone->db_argv[i]);
- isc_mem_put(zone->mctx, zone->db_argv,
- zone->db_argc * sizeof(*zone->db_argv));
- }
- zone->db_argc = 0;
- zone->db_argv = NULL;
-}
-
-isc_result_t
-dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) {
- size_t size = 0;
- unsigned int i;
- isc_result_t result = ISC_R_SUCCESS;
- void *mem;
- char **tmp, *tmp2;
-
- REQUIRE(DNS_ZONE_VALID(zone));
- REQUIRE(argv != NULL && *argv == NULL);
-
- LOCK_ZONE(zone);
- size = (zone->db_argc + 1) * sizeof(char *);
- for (i = 0; i < zone->db_argc; i++)
- size += strlen(zone->db_argv[i]) + 1;
- mem = isc_mem_allocate(mctx, size);
- if (mem != NULL) {
- tmp = mem;
- tmp2 = mem;
- tmp2 += (zone->db_argc + 1) * sizeof(char *);
- for (i = 0; i < zone->db_argc; i++) {
- *tmp++ = tmp2;
- strcpy(tmp2, zone->db_argv[i]);
- tmp2 += strlen(tmp2) + 1;
- }
- *tmp = NULL;
- } else
- result = ISC_R_NOMEMORY;
- UNLOCK_ZONE(zone);
- *argv = mem;
- return (result);
-}
-
-isc_result_t
-dns_zone_setdbtype(dns_zone_t *zone,
- unsigned int dbargc, const char * const *dbargv) {
- isc_result_t result = ISC_R_SUCCESS;
- char **new = NULL;
- unsigned int i;
-
- REQUIRE(DNS_ZONE_VALID(zone));
- REQUIRE(dbargc >= 1);
- REQUIRE(dbargv != NULL);
-
- LOCK_ZONE(zone);
-
- /* Set up a new database argument list. */
- new = isc_mem_get(zone->mctx, dbargc * sizeof(*new));
- if (new == NULL)
- goto nomem;
- for (i = 0; i < dbargc; i++)
- new[i] = NULL;
- for (i = 0; i < dbargc; i++) {
- new[i] = isc_mem_strdup(zone->mctx, dbargv[i]);
- if (new[i] == NULL)
- goto nomem;
- }
-
- /* Free the old list. */
- zone_freedbargs(zone);
-
- zone->db_argc = dbargc;
- zone->db_argv = new;
- result = ISC_R_SUCCESS;
- goto unlock;
-
- nomem:
- if (new != NULL) {
- for (i = 0; i < dbargc; i++)
- if (new[i] != NULL)
- isc_mem_free(zone->mctx, new[i]);
- isc_mem_put(zone->mctx, new, dbargc * sizeof(*new));
- }
- result = ISC_R_NOMEMORY;
-
- unlock:
- UNLOCK_ZONE(zone);
- return (result);
-}
-
-void
-dns_zone_setview(dns_zone_t *zone, dns_view_t *view) {
- char namebuf[1024];
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- if (zone->view != NULL)
- dns_view_weakdetach(&zone->view);
- dns_view_weakattach(view, &zone->view);
-
- if (zone->strviewname != NULL)
- isc_mem_free(zone->mctx, zone->strviewname);
- if (zone->strnamerd != NULL)
- isc_mem_free(zone->mctx, zone->strnamerd);
-
- zone_namerd_tostr(zone, namebuf, sizeof namebuf);
- zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
- zone_viewname_tostr(zone, namebuf, sizeof namebuf);
- zone->strviewname = isc_mem_strdup(zone->mctx, namebuf);
-
- if (inline_secure(zone))
- dns_zone_setview(zone->raw, view);
-
- UNLOCK_ZONE(zone);
-}
-
-dns_view_t *
-dns_zone_getview(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- return (zone->view);
-}
-
-
-isc_result_t
-dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) {
- isc_result_t result;
- char namebuf[1024];
-
- REQUIRE(DNS_ZONE_VALID(zone));
- REQUIRE(origin != NULL);
-
- LOCK_ZONE(zone);
- if (dns_name_dynamic(&zone->origin)) {
- dns_name_free(&zone->origin, zone->mctx);
- dns_name_init(&zone->origin, NULL);
- }
- result = dns_name_dup(origin, zone->mctx, &zone->origin);
-
- if (zone->strnamerd != NULL)
- isc_mem_free(zone->mctx, zone->strnamerd);
- if (zone->strname != NULL)
- isc_mem_free(zone->mctx, zone->strname);
-
- zone_namerd_tostr(zone, namebuf, sizeof namebuf);
- zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
- zone_name_tostr(zone, namebuf, sizeof namebuf);
- zone->strname = isc_mem_strdup(zone->mctx, namebuf);
-
- if (result == ISC_R_SUCCESS && inline_secure(zone))
- result = dns_zone_setorigin(zone->raw, origin);
- UNLOCK_ZONE(zone);
- return (result);
-}
-
-void
-dns_zone_setacache(dns_zone_t *zone, dns_acache_t *acache) {
- REQUIRE(DNS_ZONE_VALID(zone));
- REQUIRE(acache != NULL);
-
- LOCK_ZONE(zone);
- if (zone->acache != NULL)
- dns_acache_detach(&zone->acache);
- dns_acache_attach(acache, &zone->acache);
- ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
- if (zone->db != NULL) {
- isc_result_t result;
-
- /*
- * If the zone reuses an existing DB, the DB needs to be
- * set in the acache explicitly. We can safely ignore the
- * case where the DB is already set. If other error happens,
- * the acache will not work effectively.
- */
- result = dns_acache_setdb(acache, zone->db);
- if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "dns_acache_setdb() failed: %s",
- isc_result_totext(result));
- }
- }
- ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
- UNLOCK_ZONE(zone);
-}
-
-static isc_result_t
-dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) {
- char *copy;
-
- if (value != NULL) {
- copy = isc_mem_strdup(zone->mctx, value);
- if (copy == NULL)
- return (ISC_R_NOMEMORY);
- } else {
- copy = NULL;
- }
-
- if (*field != NULL)
- isc_mem_free(zone->mctx, *field);
-
- *field = copy;
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_zone_setfile(dns_zone_t *zone, const char *file) {
- return (dns_zone_setfile2(zone, file, dns_masterformat_text));
-}
-
-isc_result_t
-dns_zone_setfile2(dns_zone_t *zone, const char *file,
- dns_masterformat_t format) {
- isc_result_t result = ISC_R_SUCCESS;
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- result = dns_zone_setstring(zone, &zone->masterfile, file);
- if (result == ISC_R_SUCCESS) {
- zone->masterformat = format;
- result = default_journal(zone);
- }
- UNLOCK_ZONE(zone);
-
- return (result);
-}
-
-const char *
-dns_zone_getfile(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- return (zone->masterfile);
-}
-
-static isc_result_t
-default_journal(dns_zone_t *zone) {
- isc_result_t result;
- char *journal;
-
- REQUIRE(DNS_ZONE_VALID(zone));
- REQUIRE(LOCKED_ZONE(zone));
-
- if (zone->masterfile != NULL) {
- /* Calculate string length including '\0'. */
- int len = strlen(zone->masterfile) + sizeof(".jnl");
- journal = isc_mem_allocate(zone->mctx, len);
- if (journal == NULL)
- return (ISC_R_NOMEMORY);
- strcpy(journal, zone->masterfile);
- strcat(journal, ".jnl");
- } else {
- journal = NULL;
- }
- result = dns_zone_setstring(zone, &zone->journal, journal);
- if (journal != NULL)
- isc_mem_free(zone->mctx, journal);
- return (result);
-}
-
-isc_result_t
-dns_zone_setjournal(dns_zone_t *zone, const char *journal) {
- isc_result_t result = ISC_R_SUCCESS;
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- result = dns_zone_setstring(zone, &zone->journal, journal);
- UNLOCK_ZONE(zone);
-
- return (result);
-}
-
-char *
-dns_zone_getjournal(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- return (zone->journal);
-}
-
-/*
- * Return true iff the zone is "dynamic", in the sense that the zone's
- * master file (if any) is written by the server, rather than being
- * updated manually and read by the server.
- *
- * This is true for slave zones, stub zones, key zones, and zones that
- * allow dynamic updates either by having an update policy ("ssutable")
- * or an "allow-update" ACL with a value other than exactly "{ none; }".
- */
-isc_boolean_t
-dns_zone_isdynamic(dns_zone_t *zone, isc_boolean_t ignore_freeze) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- if (zone->type == dns_zone_slave || zone->type == dns_zone_stub ||
- zone->type == dns_zone_key ||
- (zone->type == dns_zone_redirect && zone->masters != NULL))
- return (ISC_TRUE);
-
- /* If !ignore_freeze, we need check whether updates are disabled. */
- if (zone->type == dns_zone_master &&
- (!zone->update_disabled || ignore_freeze) &&
- ((zone->ssutable != NULL) ||
- (zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl))))
- return (ISC_TRUE);
-
- return (ISC_FALSE);
-
-}
-
-/*
- * Set the response policy index and information for a zone.
- */
-isc_result_t
-dns_zone_rpz_enable(dns_zone_t *zone) {
- /*
- * Only RBTDB zones can be used for response policy zones,
- * because only they have the code to load the create the summary data.
- * Only zones that are loaded instead of mmap()ed create the
- * summary data and so can be policy zones.
- */
- if (strcmp(zone->db_argv[0], "rbt") != 0 &&
- strcmp(zone->db_argv[0], "rbt64") != 0)
- return (ISC_R_NOTIMPLEMENTED);
-
- zone->is_rpz = ISC_TRUE;
-
- return (ISC_R_SUCCESS);
-}
-
-isc_boolean_t
-dns_zone_get_rpz(dns_zone_t *zone) {
- return (zone->is_rpz);
-}
-
-static isc_result_t
-zone_load(dns_zone_t *zone, unsigned int flags) {
- isc_result_t result;
- isc_time_t now;
- isc_time_t loadtime, filetime;
- dns_db_t *db = NULL;
- isc_boolean_t rbt, hasraw;
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- hasraw = inline_secure(zone);
- if (hasraw) {
- result = zone_load(zone->raw, flags);
- if (result != ISC_R_SUCCESS) {
- UNLOCK_ZONE(zone);
- return(result);
- }
- LOCK_ZONE(zone->raw);
- }
-
- TIME_NOW(&now);
-
- INSIST(zone->type != dns_zone_none);
-
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
- if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
- result = DNS_R_CONTINUE;
- goto cleanup;
- }
-
- INSIST(zone->db_argc >= 1);
-
- rbt = strcmp(zone->db_argv[0], "rbt") == 0 ||
- strcmp(zone->db_argv[0], "rbt64") == 0;
-
- if (zone->db != NULL && zone->masterfile == NULL && rbt) {
- /*
- * The zone has no master file configured.
- */
- result = ISC_R_SUCCESS;
- goto cleanup;
- }
-
- if (zone->db != NULL && dns_zone_isdynamic(zone, ISC_FALSE)) {
- /*
- * This is a slave, stub, or dynamically updated
- * zone being reloaded. Do nothing - the database
- * we already have is guaranteed to be up-to-date.
- */
- if (zone->type == dns_zone_master)
- result = DNS_R_DYNAMIC;
- else
- result = ISC_R_SUCCESS;
- goto cleanup;
- }
-
- /*
- * Store the current time before the zone is loaded, so that if the
- * file changes between the time of the load and the time that
- * zone->loadtime is set, then the file will still be reloaded
- * the next time dns_zone_load is called.
- */
- TIME_NOW(&loadtime);
-
- /*
- * Don't do the load if the file that stores the zone is older
- * than the last time the zone was loaded. If the zone has not
- * been loaded yet, zone->loadtime will be the epoch.
- */
- if (zone->masterfile != NULL) {
- /*
- * 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) {
- result = ISC_R_SUCCESS;
- goto cleanup;
- }
-
- result = isc_file_getmodtime(zone->masterfile, &filetime);
- 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) {
- dns_zone_log(zone, ISC_LOG_DEBUG(1),
- "skipping load: master file "
- "older than last load");
- result = DNS_R_UPTODATE;
- goto cleanup;
- }
- loadtime = filetime;
- }
- }
-
- /*
- * Built in zones (with the exception of empty zones) don't need
- * to be reloaded.
- */
- if (zone->type == dns_zone_master &&
- strcmp(zone->db_argv[0], "_builtin") == 0 &&
- (zone->db_argc < 2 || strcmp(zone->db_argv[1], "empty") != 0) &&
- DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
- result = ISC_R_SUCCESS;
- goto cleanup;
- }
-
- if ((zone->type == dns_zone_slave || zone->type == dns_zone_stub ||
- (zone->type == dns_zone_redirect && zone->masters != NULL)) &&
- rbt) {
- if (zone->masterfile == NULL ||
- !isc_file_exists(zone->masterfile)) {
- if (zone->masterfile != NULL) {
- dns_zone_log(zone, ISC_LOG_DEBUG(1),
- "no master file");
- }
- zone->refreshtime = now;
- if (zone->task != NULL)
- zone_settimer(zone, &now);
- result = ISC_R_SUCCESS;
- goto cleanup;
- }
- }
-
- dns_zone_log(zone, ISC_LOG_DEBUG(1), "starting load");
-
- result = dns_db_create(zone->mctx, zone->db_argv[0],
- &zone->origin, (zone->type == dns_zone_stub) ?
- dns_dbtype_stub : dns_dbtype_zone,
- zone->rdclass,
- zone->db_argc - 1, zone->db_argv + 1,
- &db);
-
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "loading zone: creating database: %s",
- isc_result_totext(result));
- goto cleanup;
- }
- dns_db_settask(db, zone->task);
-
- if (! dns_db_ispersistent(db)) {
- if (zone->masterfile != NULL) {
- result = zone_startload(db, zone, loadtime);
- } else {
- result = DNS_R_NOMASTERFILE;
- if (zone->type == dns_zone_master ||
- (zone->type == dns_zone_redirect &&
- zone->masters == NULL)) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "loading zone: "
- "no master file configured");
- goto cleanup;
- }
- dns_zone_log(zone, ISC_LOG_INFO, "loading zone: "
- "no master file configured: continuing");
- }
- }
-
- if (result == DNS_R_CONTINUE) {
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING);
- if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
- goto cleanup;
- }
-
- result = zone_postload(zone, db, loadtime, result);
-
- cleanup:
- if (hasraw)
- UNLOCK_ZONE(zone->raw);
- UNLOCK_ZONE(zone);
- if (db != NULL)
- dns_db_detach(&db);
- return (result);
-}
-
-isc_result_t
-dns_zone_load(dns_zone_t *zone) {
- return (zone_load(zone, 0));
-}
-
-isc_result_t
-dns_zone_loadnew(dns_zone_t *zone) {
- return (zone_load(zone, DNS_ZONELOADFLAG_NOSTAT));
-}
-
-static void
-zone_asyncload(isc_task_t *task, isc_event_t *event) {
- dns_asyncload_t *asl = event->ev_arg;
- dns_zone_t *zone = asl->zone;
- isc_result_t result = ISC_R_SUCCESS;
-
- UNUSED(task);
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
- result = ISC_R_CANCELED;
- isc_event_free(&event);
- if (result == ISC_R_CANCELED ||
- !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING))
- goto cleanup;
-
- zone_load(zone, 0);
-
- LOCK_ZONE(zone);
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING);
- UNLOCK_ZONE(zone);
-
- /* Inform the zone table we've finished loading */
- if (asl->loaded != NULL)
- (asl->loaded)(asl->loaded_arg, zone, task);
-
- cleanup:
- isc_mem_put(zone->mctx, asl, sizeof (*asl));
- dns_zone_idetach(&zone);
-}
-
-isc_result_t
-dns_zone_asyncload(dns_zone_t *zone, dns_zt_zoneloaded_t done, void *arg) {
- isc_event_t *e;
- dns_asyncload_t *asl = NULL;
- isc_result_t result = ISC_R_SUCCESS;
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- if (zone->zmgr == NULL)
- return (ISC_R_FAILURE);
-
- asl = isc_mem_get(zone->mctx, sizeof (*asl));
- if (asl == NULL)
- CHECK(ISC_R_NOMEMORY);
-
- asl->zone = NULL;
- asl->loaded = done;
- asl->loaded_arg = arg;
-
- e = isc_event_allocate(zone->zmgr->mctx, zone->zmgr,
- DNS_EVENT_ZONELOAD,
- zone_asyncload, asl,
- sizeof(isc_event_t));
- if (e == NULL)
- CHECK(ISC_R_NOMEMORY);
-
- LOCK_ZONE(zone);
- zone_iattach(zone, &asl->zone);
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADPENDING);
- isc_task_send(zone->loadtask, &e);
- UNLOCK_ZONE(zone);
-
- return (ISC_R_SUCCESS);
-
- failure:
- if (asl != NULL)
- isc_mem_put(zone->mctx, asl, sizeof (*asl));
- return (result);
-}
-
-isc_boolean_t
-dns__zone_loadpending(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- return (ISC_TF(DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING)));
-}
-
-isc_result_t
-dns_zone_loadandthaw(dns_zone_t *zone) {
- isc_result_t result;
-
- if (inline_raw(zone))
- result = zone_load(zone->secure, DNS_ZONELOADFLAG_THAW);
- else
- result = zone_load(zone, DNS_ZONELOADFLAG_THAW);
-
- switch (result) {
- case DNS_R_CONTINUE:
- /* Deferred thaw. */
- break;
- case DNS_R_UPTODATE:
- case ISC_R_SUCCESS:
- case DNS_R_SEENINCLUDE:
- zone->update_disabled = ISC_FALSE;
- break;
- case DNS_R_NOMASTERFILE:
- zone->update_disabled = ISC_FALSE;
- break;
- default:
- /* Error, remain in disabled state. */
- break;
- }
- return (result);
-}
-
-static unsigned int
-get_master_options(dns_zone_t *zone) {
- unsigned int options;
-
- options = DNS_MASTER_ZONE;
- if (zone->type == dns_zone_slave ||
- (zone->type == dns_zone_redirect && zone->masters == NULL))
- options |= DNS_MASTER_SLAVE;
- if (zone->type == dns_zone_key)
- options |= DNS_MASTER_KEY;
- if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS))
- options |= DNS_MASTER_CHECKNS;
- if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS))
- options |= DNS_MASTER_FATALNS;
- if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
- options |= DNS_MASTER_CHECKNAMES;
- if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL))
- options |= DNS_MASTER_CHECKNAMESFAIL;
- if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX))
- options |= DNS_MASTER_CHECKMX;
- if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL))
- options |= DNS_MASTER_CHECKMXFAIL;
- if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD))
- options |= DNS_MASTER_CHECKWILDCARD;
- if (inline_secure(zone) || (zone->type == dns_zone_master &&
- ((zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl)) ||
- zone->ssutable != NULL)))
- options |= DNS_MASTER_RESIGN;
- return (options);
-}
-
-static void
-zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
- dns_load_t *load = event->ev_arg;
- isc_result_t result = ISC_R_SUCCESS;
- unsigned int options;
-
- REQUIRE(DNS_LOAD_VALID(load));
-
- if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
- result = ISC_R_CANCELED;
- isc_event_free(&event);
- if (result == ISC_R_CANCELED)
- goto fail;
-
- options = get_master_options(load->zone);
-
- result = dns_master_loadfileinc3(load->zone->masterfile,
- dns_db_origin(load->db),
- dns_db_origin(load->db),
- load->zone->rdclass, options,
- load->zone->sigresigninginterval,
- &load->callbacks, task,
- zone_loaddone, load,
- &load->zone->lctx, load->zone->mctx,
- load->zone->masterformat);
- if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE &&
- result != DNS_R_SEENINCLUDE)
- goto fail;
- return;
-
- fail:
- zone_loaddone(load, result);
-}
-
-static void
-get_raw_serial(dns_zone_t *raw, dns_masterrawheader_t *rawdata) {
- isc_result_t result;
- unsigned int soacount;
-
- LOCK(&raw->lock);
- if (raw->db != NULL) {
- result = zone_get_from_db(raw, raw->db, NULL, &soacount,
- &rawdata->sourceserial,
- NULL, NULL, NULL, NULL,
- NULL);
- if (result == ISC_R_SUCCESS && soacount > 0U)
- rawdata->flags |= DNS_MASTERRAW_SOURCESERIALSET;
- }
- UNLOCK(&raw->lock);
-}
-
-static void
-zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
- const char me[] = "zone_gotwritehandle";
- dns_zone_t *zone = event->ev_arg;
- isc_result_t result = ISC_R_SUCCESS;
- dns_dbversion_t *version = NULL;
- dns_masterrawheader_t rawdata;
-
- REQUIRE(DNS_ZONE_VALID(zone));
- INSIST(task == zone->task);
- ENTER;
-
- if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
- result = ISC_R_CANCELED;
- isc_event_free(&event);
- if (result == ISC_R_CANCELED)
- goto fail;
-
- LOCK_ZONE(zone);
- ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
- if (zone->db != NULL) {
- dns_db_currentversion(zone->db, &version);
- dns_master_initrawheader(&rawdata);
- if (inline_secure(zone))
- get_raw_serial(zone->raw, &rawdata);
- result = dns_master_dumpinc3(zone->mctx, zone->db, version,
- &dns_master_style_default,
- zone->masterfile, zone->task,
- dump_done, zone, &zone->dctx,
- zone->masterformat, &rawdata);
- dns_db_closeversion(zone->db, &version, ISC_FALSE);
- } else
- result = ISC_R_CANCELED;
- ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
- UNLOCK_ZONE(zone);
- if (result != DNS_R_CONTINUE)
- goto fail;
- return;
-
- fail:
- dump_done(zone, result);
-}
-
-/*
- * Save the raw serial number for inline-signing zones.
- * (XXX: Other information from the header will be used
- * for other purposes in the future, but for now this is
- * all we're interested in.)
- */
-static void
-zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) {
- if ((header->flags & DNS_MASTERRAW_SOURCESERIALSET) == 0)
- return;
-
- zone->sourceserial = header->sourceserial;
- zone->sourceserialset = ISC_TRUE;
-}
-
-void
-dns_zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) {
- if (zone == NULL)
- return;
-
- LOCK_ZONE(zone);
- zone_setrawdata(zone, header);
- UNLOCK_ZONE(zone);
-}
-
-static isc_result_t
-zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
- dns_load_t *load;
- isc_result_t result;
- isc_result_t tresult;
- unsigned int options;
-
-#ifdef BIND9
- if (zone->is_rpz) {
- result = dns_db_rpz_enabled(db, NULL);
- if (result != ISC_R_SUCCESS)
- return (result);
- }
-#endif
-
- options = get_master_options(zone);
- if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS))
- options |= DNS_MASTER_MANYERRORS;
-
- if (zone->zmgr != NULL && zone->db != NULL && zone->loadtask != NULL) {
- load = isc_mem_get(zone->mctx, sizeof(*load));
- if (load == NULL)
- return (ISC_R_NOMEMORY);
-
- load->mctx = NULL;
- load->zone = NULL;
- load->db = NULL;
- load->loadtime = loadtime;
- load->magic = LOAD_MAGIC;
-
- isc_mem_attach(zone->mctx, &load->mctx);
- zone_iattach(zone, &load->zone);
- dns_db_attach(db, &load->db);
- dns_rdatacallbacks_init(&load->callbacks);
- load->callbacks.rawdata = zone_setrawdata;
- zone_iattach(zone, &load->callbacks.zone);
- result = dns_db_beginload(db, &load->callbacks.add,
- &load->callbacks.add_private);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- result = zonemgr_getio(zone->zmgr, ISC_TRUE, zone->loadtask,
- zone_gotreadhandle, load,
- &zone->readio);
- if (result != ISC_R_SUCCESS) {
- /*
- * We can't report multiple errors so ignore
- * the result of dns_db_endload().
- */
- (void)dns_db_endload(load->db,
- &load->callbacks.add_private);
- goto cleanup;
- } else
- result = DNS_R_CONTINUE;
- } else {
- dns_rdatacallbacks_t callbacks;
-
- dns_rdatacallbacks_init(&callbacks);
- callbacks.rawdata = zone_setrawdata;
- zone_iattach(zone, &callbacks.zone);
- result = dns_db_beginload(db, &callbacks.add,
- &callbacks.add_private);
- if (result != ISC_R_SUCCESS) {
- zone_idetach(&callbacks.zone);
- return (result);
- }
- result = dns_master_loadfile3(zone->masterfile,
- &zone->origin, &zone->origin,
- zone->rdclass, options,
- zone->sigresigninginterval,
- &callbacks, zone->mctx,
- zone->masterformat);
- tresult = dns_db_endload(db, &callbacks.add_private);
- if (result == ISC_R_SUCCESS)
- result = tresult;
- zone_idetach(&callbacks.zone);
- }
-
- return (result);
-
- cleanup:
- load->magic = 0;
- dns_db_detach(&load->db);
- zone_idetach(&load->zone);
- zone_idetach(&load->callbacks.zone);
- isc_mem_detach(&load->mctx);
- isc_mem_put(zone->mctx, load, sizeof(*load));
- return (result);
-}
-
-static isc_boolean_t
-zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
- dns_name_t *owner)
-{
- isc_result_t result;
- char ownerbuf[DNS_NAME_FORMATSIZE];
- char namebuf[DNS_NAME_FORMATSIZE];
- char altbuf[DNS_NAME_FORMATSIZE];
- dns_fixedname_t fixed;
- dns_name_t *foundname;
- int level;
-
- /*
- * "." means the services does not exist.
- */
- if (dns_name_equal(name, dns_rootname))
- return (ISC_TRUE);
-
- /*
- * Outside of zone.
- */
- if (!dns_name_issubdomain(name, &zone->origin)) {
- if (zone->checkmx != NULL)
- return ((zone->checkmx)(zone, name, owner));
- return (ISC_TRUE);
- }
-
- if (zone->type == dns_zone_master)
- level = ISC_LOG_ERROR;
- else
- level = ISC_LOG_WARNING;
-
- dns_fixedname_init(&fixed);
- foundname = dns_fixedname_name(&fixed);
-
- result = dns_db_find(db, name, NULL, 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,
- 0, 0, NULL, foundname, NULL, NULL);
- if (result == ISC_R_SUCCESS)
- return (ISC_TRUE);
- }
-
- dns_name_format(owner, ownerbuf, sizeof ownerbuf);
- 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);
- return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
- }
-
- if (result == DNS_R_CNAME) {
- if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
- DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
- level = ISC_LOG_WARNING;
- if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
- dns_zone_log(zone, level,
- "%s/MX '%s' is a CNAME (illegal)",
- ownerbuf, namebuf);
- return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
- }
-
- if (result == DNS_R_DNAME) {
- if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
- DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
- level = ISC_LOG_WARNING;
- if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) {
- dns_name_format(foundname, altbuf, sizeof altbuf);
- dns_zone_log(zone, level, "%s/MX '%s' is below a DNAME"
- " '%s' (illegal)", ownerbuf, namebuf,
- altbuf);
- }
- return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
- }
-
- if (zone->checkmx != NULL && result == DNS_R_DELEGATION)
- return ((zone->checkmx)(zone, name, owner));
-
- return (ISC_TRUE);
-}
-
-static isc_boolean_t
-zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
- dns_name_t *owner)
-{
- isc_result_t result;
- char ownerbuf[DNS_NAME_FORMATSIZE];
- char namebuf[DNS_NAME_FORMATSIZE];
- char altbuf[DNS_NAME_FORMATSIZE];
- dns_fixedname_t fixed;
- dns_name_t *foundname;
- int level;
-
- /*
- * "." means the services does not exist.
- */
- if (dns_name_equal(name, dns_rootname))
- return (ISC_TRUE);
-
- /*
- * Outside of zone.
- */
- if (!dns_name_issubdomain(name, &zone->origin)) {
- if (zone->checksrv != NULL)
- return ((zone->checksrv)(zone, name, owner));
- return (ISC_TRUE);
- }
-
- if (zone->type == dns_zone_master)
- level = ISC_LOG_ERROR;
- else
- level = ISC_LOG_WARNING;
-
- dns_fixedname_init(&fixed);
- foundname = dns_fixedname_name(&fixed);
-
- result = dns_db_find(db, name, NULL, 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,
- 0, 0, NULL, foundname, NULL, NULL);
- if (result == ISC_R_SUCCESS)
- return (ISC_TRUE);
- }
-
- dns_name_format(owner, ownerbuf, sizeof ownerbuf);
- 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,
- "%s/SRV '%s' has no address records (A or AAAA)",
- ownerbuf, namebuf);
- /* XXX950 make fatal for 9.5.0. */
- return (ISC_TRUE);
- }
-
- if (result == DNS_R_CNAME) {
- if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
- DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
- level = ISC_LOG_WARNING;
- if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
- dns_zone_log(zone, level,
- "%s/SRV '%s' is a CNAME (illegal)",
- ownerbuf, namebuf);
- return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
- }
-
- if (result == DNS_R_DNAME) {
- if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
- DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
- level = ISC_LOG_WARNING;
- if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) {
- dns_name_format(foundname, altbuf, sizeof altbuf);
- dns_zone_log(zone, level, "%s/SRV '%s' is below a "
- "DNAME '%s' (illegal)", ownerbuf, namebuf,
- altbuf);
- }
- return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
- }
-
- if (zone->checksrv != NULL && result == DNS_R_DELEGATION)
- return ((zone->checksrv)(zone, name, owner));
-
- return (ISC_TRUE);
-}
-
-static isc_boolean_t
-zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
- dns_name_t *owner)
-{
- isc_boolean_t answer = ISC_TRUE;
- isc_result_t result, tresult;
- char ownerbuf[DNS_NAME_FORMATSIZE];
- char namebuf[DNS_NAME_FORMATSIZE];
- char altbuf[DNS_NAME_FORMATSIZE];
- dns_fixedname_t fixed;
- dns_name_t *foundname;
- dns_rdataset_t a;
- dns_rdataset_t aaaa;
- int level;
-
- /*
- * Outside of zone.
- */
- if (!dns_name_issubdomain(name, &zone->origin)) {
- if (zone->checkns != NULL)
- return ((zone->checkns)(zone, name, owner, NULL, NULL));
- return (ISC_TRUE);
- }
-
- if (zone->type == dns_zone_master)
- level = ISC_LOG_ERROR;
- else
- level = ISC_LOG_WARNING;
-
- dns_fixedname_init(&fixed);
- foundname = dns_fixedname_name(&fixed);
- dns_rdataset_init(&a);
- dns_rdataset_init(&aaaa);
-
- result = dns_db_find(db, name, NULL, dns_rdatatype_a,
- DNS_DBFIND_GLUEOK, 0, NULL,
- foundname, &a, NULL);
-
- if (result == ISC_R_SUCCESS) {
- dns_rdataset_disassociate(&a);
- return (ISC_TRUE);
- } else if (result == DNS_R_DELEGATION)
- dns_rdataset_disassociate(&a);
-
- if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION ||
- result == DNS_R_GLUE) {
- tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
- DNS_DBFIND_GLUEOK, 0, NULL,
- foundname, &aaaa, NULL);
- if (tresult == ISC_R_SUCCESS) {
- dns_rdataset_disassociate(&aaaa);
- return (ISC_TRUE);
- }
- if (tresult == DNS_R_DELEGATION)
- dns_rdataset_disassociate(&aaaa);
- if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) {
- /*
- * Check glue against child zone.
- */
- if (zone->checkns != NULL)
- answer = (zone->checkns)(zone, name, owner,
- &a, &aaaa);
- if (dns_rdataset_isassociated(&a))
- dns_rdataset_disassociate(&a);
- if (dns_rdataset_isassociated(&aaaa))
- dns_rdataset_disassociate(&aaaa);
- return (answer);
- }
- }
-
- dns_name_format(owner, ownerbuf, sizeof ownerbuf);
- dns_name_format(name, namebuf, sizeof namebuf);
- if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
- result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION) {
- const char *what;
- isc_boolean_t required = ISC_FALSE;
- if (dns_name_issubdomain(name, owner)) {
- what = "REQUIRED GLUE ";
- required = ISC_TRUE;
- } else if (result == DNS_R_DELEGATION)
- what = "SIBLING GLUE ";
- else
- what = "";
-
- if (result != DNS_R_DELEGATION || required ||
- DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING)) {
- dns_zone_log(zone, level, "%s/NS '%s' has no %s"
- "address records (A or AAAA)",
- ownerbuf, namebuf, what);
- /*
- * Log missing address record.
- */
- if (result == DNS_R_DELEGATION && zone->checkns != NULL)
- (void)(zone->checkns)(zone, name, owner,
- &a, &aaaa);
- /* XXX950 make fatal for 9.5.0. */
- /* answer = ISC_FALSE; */
- }
- } else if (result == DNS_R_CNAME) {
- dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)",
- ownerbuf, namebuf);
- /* XXX950 make fatal for 9.5.0. */
- /* answer = ISC_FALSE; */
- } else if (result == DNS_R_DNAME) {
- dns_name_format(foundname, altbuf, sizeof altbuf);
- dns_zone_log(zone, level,
- "%s/NS '%s' is below a DNAME '%s' (illegal)",
- ownerbuf, namebuf, altbuf);
- /* XXX950 make fatal for 9.5.0. */
- /* answer = ISC_FALSE; */
- }
-
- if (dns_rdataset_isassociated(&a))
- dns_rdataset_disassociate(&a);
- if (dns_rdataset_isassociated(&aaaa))
- dns_rdataset_disassociate(&aaaa);
- return (answer);
-}
-
-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
-isspf(const dns_rdata_t *rdata) {
- char buf[1024];
- const unsigned char *data = rdata->data;
- unsigned int rdl = rdata->length, i = 0, tl, len;
-
- while (rdl > 0U) {
- len = tl = *data;
- ++data;
- --rdl;
- INSIST(tl <= rdl);
- if (len > sizeof(buf) - i - 1)
- len = sizeof(buf) - i - 1;
- memcpy(buf + i, data, len);
- i += len;
- data += tl;
- rdl -= tl;
- }
-
- if (i < 6U)
- return(ISC_FALSE);
-
- buf[i] = 0;
- if (strncmp(buf, "v=spf1", 6) == 0 && (buf[6] == 0 || buf[6] == ' '))
- return (ISC_TRUE);
- return (ISC_FALSE);
-}
-
-static isc_boolean_t
-integrity_checks(dns_zone_t *zone, dns_db_t *db) {
- dns_dbiterator_t *dbiterator = NULL;
- dns_dbnode_t *node = NULL;
- dns_rdataset_t rdataset;
- dns_fixedname_t fixed;
- dns_fixedname_t fixedbottom;
- dns_rdata_mx_t mx;
- dns_rdata_ns_t ns;
- dns_rdata_in_srv_t srv;
- dns_rdata_t rdata;
- dns_name_t *name;
- dns_name_t *bottom;
- isc_result_t result;
- isc_boolean_t ok = ISC_TRUE, have_spf, have_txt;
-
- dns_fixedname_init(&fixed);
- name = dns_fixedname_name(&fixed);
- dns_fixedname_init(&fixedbottom);
- bottom = dns_fixedname_name(&fixedbottom);
- dns_rdataset_init(&rdataset);
- dns_rdata_init(&rdata);
-
- result = dns_db_createiterator(db, 0, &dbiterator);
- if (result != ISC_R_SUCCESS)
- return (ISC_TRUE);
-
- result = dns_dbiterator_first(dbiterator);
- while (result == ISC_R_SUCCESS) {
- result = dns_dbiterator_current(dbiterator, &node, name);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- /*
- * Is this name visible in the zone?
- */
- if (!dns_name_issubdomain(name, &zone->origin) ||
- (dns_name_countlabels(bottom) > 0 &&
- dns_name_issubdomain(name, bottom)))
- goto next;
-
- /*
- * Don't check the NS records at the origin.
- */
- if (dns_name_equal(name, &zone->origin))
- goto checkmx;
-
- result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns,
- 0, 0, &rdataset, NULL);
- if (result != ISC_R_SUCCESS)
- goto checkmx;
- /*
- * Remember bottom of zone.
- */
- dns_name_copy(name, bottom, NULL);
-
- result = dns_rdataset_first(&rdataset);
- while (result == ISC_R_SUCCESS) {
- dns_rdataset_current(&rdataset, &rdata);
- result = dns_rdata_tostruct(&rdata, &ns, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- if (!zone_check_glue(zone, db, &ns.name, name))
- ok = ISC_FALSE;
- dns_rdata_reset(&rdata);
- result = dns_rdataset_next(&rdataset);
- }
- dns_rdataset_disassociate(&rdataset);
- goto next;
-
- checkmx:
- result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx,
- 0, 0, &rdataset, NULL);
- if (result != ISC_R_SUCCESS)
- goto checksrv;
- result = dns_rdataset_first(&rdataset);
- while (result == ISC_R_SUCCESS) {
- dns_rdataset_current(&rdataset, &rdata);
- result = dns_rdata_tostruct(&rdata, &mx, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- if (!zone_check_mx(zone, db, &mx.mx, name))
- ok = ISC_FALSE;
- dns_rdata_reset(&rdata);
- result = dns_rdataset_next(&rdataset);
- }
- dns_rdataset_disassociate(&rdataset);
-
- checksrv:
- if (zone->rdclass != dns_rdataclass_in)
- goto next;
- result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv,
- 0, 0, &rdataset, NULL);
- if (result != ISC_R_SUCCESS)
- goto checkspf;
- result = dns_rdataset_first(&rdataset);
- while (result == ISC_R_SUCCESS) {
- dns_rdataset_current(&rdataset, &rdata);
- result = dns_rdata_tostruct(&rdata, &srv, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- if (!zone_check_srv(zone, db, &srv.target, name))
- ok = ISC_FALSE;
- dns_rdata_reset(&rdata);
- result = dns_rdataset_next(&rdataset);
- }
- dns_rdataset_disassociate(&rdataset);
-
- checkspf:
- /*
- * Check if there is a type TXT spf record without a type SPF
- * RRset being present.
- */
- if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSPF))
- goto next;
- if (zone->rdclass != dns_rdataclass_in)
- goto next;
- have_spf = have_txt = ISC_FALSE;
- result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_spf,
- 0, 0, &rdataset, NULL);
- if (result == ISC_R_SUCCESS) {
- dns_rdataset_disassociate(&rdataset);
- have_spf = ISC_TRUE;
- }
- result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_txt,
- 0, 0, &rdataset, NULL);
- if (result != ISC_R_SUCCESS)
- goto notxt;
- result = dns_rdataset_first(&rdataset);
- while (result == ISC_R_SUCCESS) {
- dns_rdataset_current(&rdataset, &rdata);
- have_txt = isspf(&rdata);
- dns_rdata_reset(&rdata);
- if (have_txt)
- break;
- result = dns_rdataset_next(&rdataset);
- }
- dns_rdataset_disassociate(&rdataset);
-
- notxt:
- if (have_spf != have_txt) {
- char namebuf[DNS_NAME_FORMATSIZE];
- const char *found = have_txt ? "TXT" : "SPF";
- const char *need = have_txt ? "SPF" : "TXT";
-
- dns_name_format(name, namebuf, sizeof(namebuf));
- dns_zone_log(zone, ISC_LOG_WARNING, "'%s' found SPF/%s "
- "record but no SPF/%s record found, add "
- "matching type %s record", namebuf, found,
- need, need);
- }
-
- next:
- dns_db_detachnode(db, &node);
- result = dns_dbiterator_next(dbiterator);
- }
-
- cleanup:
- if (node != NULL)
- dns_db_detachnode(db, &node);
- dns_dbiterator_destroy(&dbiterator);
-
- return (ok);
-}
-
-/*
- * 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
- * if they are in use.
- */
-static void
-zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) {
- dns_dbnode_t *node = NULL;
- dns_dbversion_t *version = NULL;
- dns_rdata_dnskey_t dnskey;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdataset_t rdataset;
- isc_result_t result;
- isc_boolean_t logit, foundrsa = ISC_FALSE, foundmd5 = ISC_FALSE;
- const char *algorithm;
-
- result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- dns_db_currentversion(db, &version);
- dns_rdataset_init(&rdataset);
- result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
- dns_rdatatype_none, 0, &rdataset, NULL);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- 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, &dnskey, NULL);
- INSIST(result == ISC_R_SUCCESS);
-
- if ((dnskey.algorithm == DST_ALG_RSASHA1 ||
- dnskey.algorithm == DST_ALG_RSAMD5) &&
- dnskey.datalen > 1 && dnskey.data[0] == 1 &&
- dnskey.data[1] == 3)
- {
- if (dnskey.algorithm == DST_ALG_RSASHA1) {
- logit = !foundrsa;
- foundrsa = ISC_TRUE;
- algorithm = "RSASHA1";
- } else {
- logit = !foundmd5;
- foundmd5 = ISC_TRUE;
- algorithm = "RSAMD5";
- }
- if (logit)
- dns_zone_log(zone, ISC_LOG_WARNING,
- "weak %s (%u) key found "
- "(exponent=3)", algorithm,
- dnskey.algorithm);
- if (foundrsa && foundmd5)
- break;
- }
- dns_rdata_reset(&rdata);
- }
- dns_rdataset_disassociate(&rdataset);
-
- cleanup:
- if (node != NULL)
- dns_db_detachnode(db, &node);
- if (version != NULL)
- dns_db_closeversion(db, &version, ISC_FALSE);
-}
-
-static void
-resume_signingwithkey(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;
-
- result = dns_db_findnode(zone->db, &zone->origin, ISC_FALSE, &node);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- dns_db_currentversion(zone->db, &version);
- dns_rdataset_init(&rdataset);
- result = dns_db_findrdataset(zone->db, node, version,
- 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);
- if (rdata.length != 5 ||
- rdata.data[0] == 0 || rdata.data[4] != 0) {
- dns_rdata_reset(&rdata);
- continue;
- }
-
- result = zone_signwithkey(zone, rdata.data[0],
- (rdata.data[1] << 8) | rdata.data[2],
- ISC_TF(rdata.data[3]));
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_signwithkey failed: %s",
- dns_result_totext(result));
- }
- dns_rdata_reset(&rdata);
- }
- dns_rdataset_disassociate(&rdataset);
-
- cleanup:
- if (node != NULL)
- dns_db_detachnode(zone->db, &node);
- if (version != NULL)
- dns_db_closeversion(zone->db, &version, ISC_FALSE);
-}
-
-static isc_result_t
-zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
- dns_nsec3chain_t *nsec3chain, *current;
- dns_dbversion_t *version = NULL;
- isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE;
- isc_result_t result;
- isc_time_t now;
- unsigned int options = 0;
- char saltbuf[255*2+1];
- char flags[sizeof("INITIAL|REMOVE|CREATE|NONSEC|OPTOUT")];
- int i;
-
- dns_db_currentversion(zone->db, &version);
- result = dns_nsec_nseconly(zone->db, version, &nseconly);
- nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
- dns_db_closeversion(zone->db, &version, ISC_FALSE);
- if (!nsec3ok && (nsec3param->flags & DNS_NSEC3FLAG_REMOVE) == 0)
- return (ISC_R_SUCCESS);
-
- nsec3chain = isc_mem_get(zone->mctx, sizeof *nsec3chain);
- if (nsec3chain == NULL)
- return (ISC_R_NOMEMORY);
-
- nsec3chain->magic = 0;
- nsec3chain->done = ISC_FALSE;
- nsec3chain->db = NULL;
- nsec3chain->dbiterator = NULL;
- nsec3chain->nsec3param.common.rdclass = nsec3param->common.rdclass;
- nsec3chain->nsec3param.common.rdtype = nsec3param->common.rdtype;
- nsec3chain->nsec3param.hash = nsec3param->hash;
- nsec3chain->nsec3param.iterations = nsec3param->iterations;
- nsec3chain->nsec3param.flags = nsec3param->flags;
- nsec3chain->nsec3param.salt_length = nsec3param->salt_length;
- memcpy(nsec3chain->salt, nsec3param->salt, nsec3param->salt_length);
- nsec3chain->nsec3param.salt = nsec3chain->salt;
- nsec3chain->seen_nsec = ISC_FALSE;
- 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_INITIAL) {
- if (flags[0] == '\0')
- strlcpy(flags, "INITIAL", sizeof(flags));
- else
- strlcat(flags, "|INITIAL", sizeof(flags));
- }
- if (nsec3param->flags & DNS_NSEC3FLAG_CREATE) {
- if (flags[0] == '\0')
- strlcpy(flags, "CREATE", sizeof(flags));
- 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)) {
- if (current->db == zone->db &&
- current->nsec3param.hash == nsec3param->hash &&
- current->nsec3param.iterations == nsec3param->iterations &&
- current->nsec3param.salt_length == nsec3param->salt_length
- && !memcmp(current->nsec3param.salt, nsec3param->salt,
- nsec3param->salt_length))
- current->done = ISC_TRUE;
- }
-
- if (zone->db != NULL) {
- dns_db_attach(zone->db, &nsec3chain->db);
- if ((nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0)
- options = DNS_DB_NONSEC3;
- result = dns_db_createiterator(nsec3chain->db, options,
- &nsec3chain->dbiterator);
- if (result == ISC_R_SUCCESS)
- dns_dbiterator_first(nsec3chain->dbiterator);
- if (result == ISC_R_SUCCESS) {
- dns_dbiterator_pause(nsec3chain->dbiterator);
- ISC_LIST_INITANDAPPEND(zone->nsec3chain,
- nsec3chain, link);
- nsec3chain = NULL;
- if (isc_time_isepoch(&zone->nsec3chaintime)) {
- TIME_NOW(&now);
- zone->nsec3chaintime = now;
- if (zone->task != NULL)
- zone_settimer(zone, &now);
- }
- }
- } else
- result = ISC_R_NOTFOUND;
-
- if (nsec3chain != NULL) {
- if (nsec3chain->db != NULL)
- dns_db_detach(&nsec3chain->db);
- if (nsec3chain->dbiterator != NULL)
- dns_dbiterator_destroy(&nsec3chain->dbiterator);
- isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
- }
- return (result);
-}
-
-static void
-resume_addnsec3chain(dns_zone_t *zone) {
- dns_dbnode_t *node = NULL;
- dns_dbversion_t *version = NULL;
- dns_rdataset_t rdataset;
- isc_result_t result;
- dns_rdata_nsec3param_t nsec3param;
- isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE;
-
- if (zone->privatetype == 0)
- return;
-
- result = dns_db_findnode(zone->db, &zone->origin, ISC_FALSE, &node);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- dns_db_currentversion(zone->db, &version);
-
- result = dns_nsec_nseconly(zone->db, version, &nseconly);
- nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
-
- dns_rdataset_init(&rdataset);
- result = dns_db_findrdataset(zone->db, node, version,
- zone->privatetype, dns_rdatatype_none,
- 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))
- {
- 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_REMOVE) != 0) ||
- ((nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0 && nsec3ok))
- {
- result = zone_addnsec3chain(zone, &nsec3param);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_addnsec3chain failed: %s",
- dns_result_totext(result));
- }
- }
- }
- dns_rdataset_disassociate(&rdataset);
- cleanup:
- if (node != NULL)
- dns_db_detachnode(zone->db, &node);
- if (version != NULL)
- dns_db_closeversion(zone->db, &version, ISC_FALSE);
-}
-
-static void
-set_resigntime(dns_zone_t *zone) {
- dns_rdataset_t rdataset;
- dns_fixedname_t fixed;
- unsigned int resign;
- isc_result_t result;
- isc_uint32_t nanosecs;
-
- dns_rdataset_init(&rdataset);
- dns_fixedname_init(&fixed);
- result = dns_db_getsigningtime(zone->db, &rdataset,
- dns_fixedname_name(&fixed));
- if (result != ISC_R_SUCCESS) {
- isc_time_settoepoch(&zone->resigntime);
- return;
- }
- resign = rdataset.resign;
- dns_rdataset_disassociate(&rdataset);
- isc_random_get(&nanosecs);
- nanosecs %= 1000000000;
- isc_time_set(&zone->resigntime, resign, nanosecs);
-}
-
-static isc_result_t
-check_nsec3param(dns_zone_t *zone, dns_db_t *db) {
- dns_dbnode_t *node = NULL;
- dns_rdataset_t rdataset;
- dns_dbversion_t *version = NULL;
- dns_rdata_nsec3param_t nsec3param;
- isc_boolean_t ok = ISC_FALSE;
- isc_result_t result;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- isc_boolean_t dynamic = (zone->type == dns_zone_master) ?
- dns_zone_isdynamic(zone, ISC_FALSE) : ISC_FALSE;
-
- dns_rdataset_init(&rdataset);
- result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "nsec3param lookup failure: %s",
- dns_result_totext(result));
- return (result);
- }
- dns_db_currentversion(db, &version);
-
- result = dns_db_findrdataset(db, node, version,
- 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));
- goto cleanup;
- }
-
- /*
- * For dynamic zones we must support every algorithm so we can
- * regenerate all the NSEC3 chains.
- * For non-dynamic zones we only need to find a supported algorithm.
- */
- 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, &nsec3param, NULL);
- dns_rdata_reset(&rdata);
- INSIST(result == ISC_R_SUCCESS);
- if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NSEC3TESTZONE) &&
- nsec3param.hash == DNS_NSEC3_UNKNOWNALG && !dynamic)
- {
- dns_zone_log(zone, ISC_LOG_WARNING,
- "nsec3 test \"unknown\" hash algorithm found: %u",
- nsec3param.hash);
- ok = ISC_TRUE;
- } else if (!dns_nsec3_supportedhash(nsec3param.hash)) {
- if (dynamic) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "unsupported nsec3 hash algorithm"
- " in dynamic zone: %u",
- nsec3param.hash);
- result = DNS_R_BADZONE;
- /* Stop second error message. */
- ok = ISC_TRUE;
- break;
- } else
- dns_zone_log(zone, ISC_LOG_WARNING,
- "unsupported nsec3 hash algorithm: %u",
- nsec3param.hash);
- } else
- ok = ISC_TRUE;
- }
- if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
-
- if (!ok) {
- result = DNS_R_BADZONE;
- dns_zone_log(zone, ISC_LOG_ERROR,
- "no supported nsec3 hash algorithm");
- }
-
- cleanup:
- if (dns_rdataset_isassociated(&rdataset))
- dns_rdataset_disassociate(&rdataset);
- dns_db_closeversion(db, &version, ISC_FALSE);
- dns_db_detachnode(db, &node);
- 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;
- /* Refresh new keys from the zone apex as soon as possible. */
- set_refreshkeytimer(zone, &keydata, now);
-
- skip:
- result = dns_keytable_nextkeynode(keytable, keynode, &nextnode);
- if (result != ISC_R_NOTFOUND) {
- dns_keytable_detachkeynode(keytable, &keynode);
- keynode = nextnode;
- }
- }
-
- 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.
- */
-static void
-trust_key(dns_zone_t *zone, 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_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);
-
- result = dns_view_getsecroots(zone->view, &sr);
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- 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;
-}
-
-/*
- * Add a null key to the security roots for so that all queries
- * to the zone will fail.
- */
-static void
-fail_secure(dns_zone_t *zone, dns_name_t *keyname) {
- isc_result_t result;
- dns_keytable_t *sr = NULL;
-
- result = dns_view_getsecroots(zone->view, &sr);
- if (result == ISC_R_SUCCESS) {
- 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.
- */
-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;
- int trusted = 0, revoked = 0, pending = 0;
- isc_stdtime_t now;
- dns_keytable_t *sr = NULL;
-
- isc_stdtime_get(&now);
-
- result = dns_view_getsecroots(zone->view, &sr);
- if (result == ISC_R_SUCCESS) {
- 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. */
- result = dns_rdata_tostruct(&rdata, &keydata, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
-
- /* 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(zone, 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(zone, 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
-update_soa_serial(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
- isc_mem_t *mctx, dns_updatemethod_t method) {
- dns_difftuple_t *deltuple = NULL;
- dns_difftuple_t *addtuple = NULL;
- isc_uint32_t serial;
- 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);
- serial = dns_update_soaserial(serial, method);
- dns_soa_setserial(serial, &addtuple->rdata);
- CHECK(do_one_tuple(&deltuple, db, ver, diff));
- CHECK(do_one_tuple(&addtuple, db, ver, diff));
- 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, isc_uint32_t *sourceserial,
- const char *caller)
-{
- const char me[] = "zone_journal";
- const char *journalfile;
- isc_result_t result = ISC_R_SUCCESS;
- dns_journal_t *journal = NULL;
- unsigned int mode = DNS_JOURNAL_CREATE|DNS_JOURNAL_WRITE;
-
- ENTER;
- journalfile = dns_zone_getjournal(zone);
- if (journalfile != NULL) {
- result = dns_journal_open(zone->mctx, journalfile, mode,
- &journal);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "%s:dns_journal_open -> %s",
- caller, dns_result_totext(result));
- return (result);
- }
-
- if (sourceserial != NULL)
- dns_journal_set_sourceserial(journal, *sourceserial);
-
- result = dns_journal_write_transaction(journal, diff);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "%s:dns_journal_write_transaction -> %s",
- caller, dns_result_totext(result));
- }
- dns_journal_destroy(&journal);
- }
-
- 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",
- 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",
- 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;
- isc_boolean_t commit = 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",
- 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 = NULL;
- 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. */
- CHECK(update_soa_serial(db, ver, &diff, zone->mctx,
- zone->updatemethod));
- CHECK(zone_journal(zone, &diff, NULL, "sync_keyzone"));
-
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
- zone_needdump(zone, 30);
- commit = ISC_TRUE;
- }
-
- failure:
- if (result != ISC_R_SUCCESS &&
- !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "unable to synchronize managed keys: %s",
- dns_result_totext(result));
- isc_time_settoepoch(&zone->refreshkeytime);
- }
- if (keynode != NULL)
- dns_keytable_detachkeynode(sr, &keynode);
- if (sr != NULL)
- dns_keytable_detach(&sr);
- if (ver != NULL)
- dns_db_closeversion(db, &ver, commit);
- dns_diff_clear(&diff);
-
- return (result);
-}
-
-isc_result_t
-dns_zone_synckeyzone(dns_zone_t *zone) {
- isc_result_t result;
- dns_db_t *db = NULL;
-
- if (zone->type != dns_zone_key)
- return (DNS_R_BADZONE);
-
- CHECK(dns_zone_getdb(zone, &db));
-
- LOCK_ZONE(zone);
- result = sync_keyzone(zone, db);
- UNLOCK_ZONE(zone);
-
- failure:
- if (db != NULL)
- dns_db_detach(&db);
- return (result);
-}
-
-static void
-maybe_send_secure(dns_zone_t *zone) {
- isc_result_t result;
-
- /*
- * We've finished loading, or else failed to load, an inline-signing
- * 'secure' zone. We now need information about the status of the
- * 'raw' zone. If we failed to load, then we need it to send a
- * copy of its database; if we succeeded, we need it to send its
- * serial number so that we can sync with it. If it has not yet
- * loaded, we set a flag so that it will send the necessary
- * information when it has finished loading.
- */
- if (zone->raw->db != NULL) {
- if (zone->db != NULL) {
- isc_uint32_t serial;
- unsigned int soacount;
-
- result = zone_get_from_db(zone->raw, zone->raw->db,
- NULL, &soacount, &serial, NULL,
- NULL, NULL, NULL, NULL);
- if (result == ISC_R_SUCCESS && soacount > 0U)
- zone_send_secureserial(zone->raw, ISC_TRUE, serial);
- } else
- zone_send_securedb(zone->raw, ISC_TRUE, zone->raw->db);
-
- } else
- DNS_ZONE_SETFLAG(zone->raw, DNS_ZONEFLG_SENDSECURE);
-}
-
-static isc_boolean_t
-zone_unchanged(dns_db_t *db1, dns_db_t *db2, isc_mem_t *mctx) {
- isc_result_t result;
- isc_boolean_t answer = ISC_FALSE;
- dns_diff_t diff;
-
- dns_diff_init(mctx, &diff);
- result = dns_db_diffx(&diff, db1, NULL, db2, NULL, NULL);
- if (result == ISC_R_SUCCESS && ISC_LIST_EMPTY(diff.tuples))
- answer = ISC_TRUE;
- dns_diff_clear(&diff);
- return (answer);
-}
-
-/*
- * The zone is presumed to be locked.
- */
-static isc_result_t
-zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
- isc_result_t result)
-{
- unsigned int soacount = 0;
- unsigned int nscount = 0;
- unsigned int errors = 0;
- isc_uint32_t serial, oldserial, refresh, retry, expire, minimum;
- 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);
-
- /*
- * Initiate zone transfer? We may need a error code that
- * indicates that the "permanent" form does not exist.
- * XXX better error feedback to log.
- */
- if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) {
- if (zone->type == dns_zone_slave ||
- zone->type == dns_zone_stub ||
- (zone->type == dns_zone_redirect &&
- zone->masters == NULL)) {
- if (result == ISC_R_FILENOTFOUND)
- dns_zone_log(zone, ISC_LOG_DEBUG(1),
- "no master file");
- else if (result != DNS_R_NOMASTERFILE)
- dns_zone_log(zone, ISC_LOG_ERROR,
- "loading from master file %s "
- "failed: %s",
- zone->masterfile,
- dns_result_totext(result));
- } else if (zone->type == dns_zone_master &&
- inline_secure(zone) && result == ISC_R_FILENOTFOUND)
- {
- dns_zone_log(zone, ISC_LOG_DEBUG(1),
- "no master file, requesting db");
- maybe_send_secure(zone);
- } else {
- int level = ISC_LOG_ERROR;
- if (zone->type == dns_zone_key &&
- result == ISC_R_FILENOTFOUND)
- level = ISC_LOG_DEBUG(1);
- dns_zone_log(zone, level,
- "loading from master file %s failed: %s",
- zone->masterfile,
- dns_result_totext(result));
- nomaster = ISC_TRUE;
- }
-
- if (zone->type != dns_zone_key)
- goto cleanup;
- }
-
- dns_zone_log(zone, ISC_LOG_DEBUG(2),
- "number of nodes in database: %u",
- dns_db_nodecount(db));
-
- if (result == DNS_R_SEENINCLUDE)
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
- else
- 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 &&
- ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) &&
- ! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
- {
- if (zone->type == dns_zone_master &&
- (zone->update_acl != NULL || zone->ssutable != NULL))
- options = DNS_JOURNALOPT_RESIGN;
- else
- options = 0;
- result = dns_journal_rollforward2(zone->mctx, db, options,
- zone->sigresigninginterval,
- zone->journal);
- if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND &&
- result != DNS_R_UPTODATE && result != DNS_R_NOJOURNAL &&
- result != ISC_R_RANGE) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "journal rollforward failed: %s",
- dns_result_totext(result));
- goto cleanup;
-
-
- }
- if (result == ISC_R_NOTFOUND || result == ISC_R_RANGE) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "journal rollforward failed: "
- "journal out of sync with zone");
- goto cleanup;
- }
- dns_zone_log(zone, ISC_LOG_DEBUG(1),
- "journal rollforward completed "
- "successfully: %s",
- dns_result_totext(result));
- if (result == ISC_R_SUCCESS)
- needdump = ISC_TRUE;
- }
-
- /*
- * Obtain ns, soa and cname counts for top of zone.
- */
- INSIST(db != NULL);
- result = zone_get_from_db(zone, db, &nscount, &soacount, &serial,
- &refresh, &retry, &expire, &minimum,
- &errors);
- 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");
- }
-
- /*
- * Check to make sure the journal is up to date, and remove the
- * journal file if it isn't, as we wouldn't be able to apply
- * updates otherwise.
- */
- if (zone->journal != NULL && dns_zone_isdynamic(zone, ISC_TRUE) &&
- ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS)) {
- isc_uint32_t jserial;
- dns_journal_t *journal = NULL;
-
- result = dns_journal_open(zone->mctx, zone->journal,
- DNS_JOURNAL_READ, &journal);
- if (result == ISC_R_SUCCESS) {
- jserial = dns_journal_last_serial(journal);
- dns_journal_destroy(&journal);
- } else {
- jserial = serial;
- result = ISC_R_SUCCESS;
- }
-
- if (jserial != serial) {
- dns_zone_log(zone, ISC_LOG_INFO,
- "journal file is out of date: "
- "removing journal file");
- if (remove(zone->journal) < 0 && errno != ENOENT) {
- char strbuf[ISC_STRERRORSIZE];
- isc__strerror(errno, strbuf, sizeof(strbuf));
- isc_log_write(dns_lctx,
- DNS_LOGCATEGORY_GENERAL,
- DNS_LOGMODULE_ZONE,
- ISC_LOG_WARNING,
- "unable to remove journal "
- "'%s': '%s'",
- zone->journal, strbuf);
- }
- }
- }
-
- dns_zone_log(zone, ISC_LOG_DEBUG(1), "loaded; checking validity");
-
- /*
- * Master / Slave / Stub zones require both NS and SOA records at
- * the top of the zone.
- */
-
- switch (zone->type) {
- case dns_zone_dlz:
- case dns_zone_master:
- case dns_zone_slave:
- case dns_zone_stub:
- case dns_zone_redirect:
- if (soacount != 1) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "has %d SOA records", soacount);
- result = DNS_R_BADZONE;
- }
- if (nscount == 0) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "has no NS records");
- result = DNS_R_BADZONE;
- }
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- if (zone->type == dns_zone_master && errors != 0) {
- result = DNS_R_BADZONE;
- goto cleanup;
- }
- if (zone->type != dns_zone_stub &&
- zone->type != dns_zone_redirect) {
- result = check_nsec3param(zone, db);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- }
- if (zone->type == dns_zone_master &&
- DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) &&
- !integrity_checks(zone, db)) {
- result = DNS_R_BADZONE;
- 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) {
- unsigned int oldsoacount;
-
- /*
- * This is checked in zone_replacedb() for slave zones
- * as they don't reload from disk.
- */
- result = zone_get_from_db(zone, zone->db, NULL,
- &oldsoacount, &oldserial,
- NULL, NULL, NULL, NULL,
- NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- RUNTIME_CHECK(soacount > 0U);
- if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
- !isc_serial_gt(serial, oldserial)) {
- isc_uint32_t serialmin, serialmax;
-
- INSIST(zone->type == dns_zone_master);
-
- if (serial == oldserial &&
- zone_unchanged(zone->db, db, zone->mctx)) {
- dns_zone_log(zone, ISC_LOG_INFO,
- "ixfr-from-differences: "
- "unchanged");
- return(ISC_R_SUCCESS);
- }
-
- serialmin = (oldserial + 1) & 0xffffffffU;
- serialmax = (oldserial + 0x7fffffffU) &
- 0xffffffffU;
- dns_zone_log(zone, ISC_LOG_ERROR,
- "ixfr-from-differences: "
- "new serial (%u) out of range "
- "[%u - %u]", serial, serialmin,
- serialmax);
- result = DNS_R_BADZONE;
- goto cleanup;
- } else if (!isc_serial_ge(serial, oldserial))
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone serial (%u/%u) has gone "
- "backwards", serial, oldserial);
- else if (serial == oldserial && !hasinclude &&
- strcmp(zone->db_argv[0], "_builtin") != 0)
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone serial (%u) unchanged. "
- "zone may fail to transfer "
- "to slaves.", serial);
- }
-
- if (zone->type == dns_zone_master &&
- (zone->update_acl != NULL || zone->ssutable != NULL) &&
- zone->sigresigninginterval < (3 * refresh) &&
- dns_db_issecure(db))
- {
- dns_zone_log(zone, ISC_LOG_WARNING,
- "sig-re-signing-interval less than "
- "3 * refresh.");
- }
-
- zone->refresh = RANGE(refresh,
- zone->minrefresh, zone->maxrefresh);
- zone->retry = RANGE(retry,
- zone->minretry, zone->maxretry);
- zone->expire = RANGE(expire, zone->refresh + zone->retry,
- DNS_MAX_EXPIRE);
- zone->minimum = minimum;
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
-
- if (zone->type == dns_zone_slave ||
- zone->type == dns_zone_stub ||
- (zone->type == dns_zone_redirect &&
- zone->masters != NULL)) {
- isc_time_t t;
- isc_uint32_t delay;
-
- result = isc_file_getmodtime(zone->journal, &t);
- if (result != ISC_R_SUCCESS)
- result = isc_file_getmodtime(zone->masterfile,
- &t);
- if (result == ISC_R_SUCCESS)
- DNS_ZONE_TIME_ADD(&t, zone->expire,
- &zone->expiretime);
- else
- DNS_ZONE_TIME_ADD(&now, zone->retry,
- &zone->expiretime);
-
- delay = isc_random_jitter(zone->retry,
- (zone->retry * 3) / 4);
- DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime);
- if (isc_time_compare(&zone->refreshtime,
- &zone->expiretime) >= 0)
- 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);
- result = ISC_R_UNEXPECTED;
- goto cleanup;
- }
-
- /*
- * Check for weak DNSKEY's.
- */
- 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. */
- {
- isc_event_t *e = isc_event_allocate(zone->mctx, NULL,
- DNS_EVENT_DBDESTROYED,
- dns_zonemgr_dbdestroyed,
- zone,
- sizeof(isc_event_t));
- dns_db_ondestroy(db, zone->task, &e);
- }
-#endif
-
- ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
- if (zone->db != NULL) {
- result = zone_replacedb(zone, db, ISC_FALSE);
- ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- } else {
- zone_attachdb(zone, db);
- ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
- DNS_ZONE_SETFLAG(zone,
- DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SENDSECURE) &&
- inline_raw(zone))
- {
- if (zone->secure->db == NULL)
- zone_send_securedb(zone, ISC_FALSE, db);
- else
- zone_send_secureserial(zone, ISC_FALSE, serial);
- }
- }
-
- /*
- * Finished loading inline-signing zone; need to get status
- * from the raw side now.
- */
- if (zone->type == dns_zone_master && inline_secure(zone))
- maybe_send_secure(zone);
-
-
- result = ISC_R_SUCCESS;
-
- if (needdump) {
- 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);
- resume_signingwithkey(zone);
- resume_addnsec3chain(zone);
- }
-
- if (zone->type == dns_zone_master &&
- !DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN) &&
- dns_zone_isdynamic(zone, ISC_FALSE) &&
- dns_db_issecure(db)) {
- dns_name_t *name;
- dns_fixedname_t fixed;
- dns_rdataset_t next;
-
- dns_rdataset_init(&next);
- dns_fixedname_init(&fixed);
- name = dns_fixedname_name(&fixed);
-
- result = dns_db_getsigningtime(db, &next, name);
- if (result == ISC_R_SUCCESS) {
- isc_stdtime_t timenow;
- char namebuf[DNS_NAME_FORMATSIZE];
- char typebuf[DNS_RDATATYPE_FORMATSIZE];
-
- isc_stdtime_get(&timenow);
- dns_name_format(name, namebuf, sizeof(namebuf));
- dns_rdatatype_format(next.covers,
- typebuf, sizeof(typebuf));
- dns_zone_log(zone, ISC_LOG_DEBUG(3),
- "next resign: %s/%s in %d seconds",
- namebuf, typebuf,
- next.resign - timenow);
- dns_rdataset_disassociate(&next);
- } else
- dns_zone_log(zone, ISC_LOG_WARNING,
- "signed dynamic zone has no "
- "resign event scheduled");
- }
-
- zone_settimer(zone, &now);
- }
-
- if (! dns_db_ispersistent(db))
- dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u%s", serial,
- dns_db_issecure(db) ? " (DNSSEC signed)" : "");
-
- zone->loadtime = loadtime;
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING);
- return (result);
-
- cleanup:
- if (zone->type == dns_zone_slave ||
- zone->type == dns_zone_stub ||
- zone->type == dns_zone_key ||
- (zone->type == dns_zone_redirect && zone->masters != NULL)) {
- if (zone->journal != NULL)
- zone_saveunique(zone, zone->journal, "jn-XXXXXXXX");
- if (zone->masterfile != NULL)
- zone_saveunique(zone, zone->masterfile, "db-XXXXXXXX");
-
- /* Mark the zone for immediate refresh. */
- zone->refreshtime = now;
- if (zone->task != NULL)
- zone_settimer(zone, &now);
- result = ISC_R_SUCCESS;
- } else if (zone->type == dns_zone_master ||
- zone->type == dns_zone_redirect) {
- if (!(inline_secure(zone) && result == ISC_R_FILENOTFOUND))
- dns_zone_log(zone, ISC_LOG_ERROR,
- "not loaded due to errors.");
- else if (zone->type == dns_zone_master)
- result = ISC_R_SUCCESS;
- }
-
- return (result);
-}
-
-static isc_boolean_t
-exit_check(dns_zone_t *zone) {
-
- REQUIRE(LOCKED_ZONE(zone));
-
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) &&
- zone->irefs == 0)
- {
- /*
- * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0.
- */
- INSIST(isc_refcount_current(&zone->erefs) == 0);
- return (ISC_TRUE);
- }
- return (ISC_FALSE);
-}
-
-static isc_boolean_t
-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];
- dns_fixedname_t fixed;
- dns_name_t *foundname;
- int level;
-
- if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS))
- return (ISC_TRUE);
-
- if (zone->type == dns_zone_master)
- level = ISC_LOG_ERROR;
- else
- level = ISC_LOG_WARNING;
-
- dns_fixedname_init(&fixed);
- foundname = dns_fixedname_name(&fixed);
-
- 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, version, dns_rdatatype_aaaa,
- 0, 0, NULL, foundname, NULL, NULL);
- if (result == ISC_R_SUCCESS)
- return (ISC_TRUE);
- }
-
- if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
- result == DNS_R_EMPTYNAME) {
- 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) {
- 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) {
- 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);
-}
-
-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, isc_boolean_t logit)
-{
- isc_result_t result;
- unsigned int count = 0;
- unsigned int ecount = 0;
- dns_rdataset_t rdataset;
- dns_rdata_t rdata;
- dns_rdata_ns_t ns;
-
- 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) {
- INSIST(!dns_rdataset_isassociated(&rdataset));
- goto success;
- }
- if (result != ISC_R_SUCCESS) {
- INSIST(!dns_rdataset_isassociated(&rdataset));
- goto invalidate_rdataset;
- }
-
- result = dns_rdataset_first(&rdataset);
- while (result == ISC_R_SUCCESS) {
- if (errors != NULL && zone->rdclass == dns_rdataclass_in &&
- (zone->type == dns_zone_master ||
- zone->type == dns_zone_slave)) {
- dns_rdata_init(&rdata);
- dns_rdataset_current(&rdataset, &rdata);
- 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, version, &ns.name, logit))
- ecount++;
- }
- count++;
- result = dns_rdataset_next(&rdataset);
- }
- dns_rdataset_disassociate(&rdataset);
-
- success:
- if (nscount != NULL)
- *nscount = count;
- if (errors != NULL)
- *errors = ecount;
-
- result = ISC_R_SUCCESS;
-
- invalidate_rdataset:
- dns_rdataset_invalidate(&rdataset);
-
- return (result);
-}
-
-static isc_result_t
-zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
- unsigned int *soacount,
- isc_uint32_t *serial, isc_uint32_t *refresh,
- isc_uint32_t *retry, isc_uint32_t *expire,
- isc_uint32_t *minimum)
-{
- isc_result_t result;
- unsigned int count;
- dns_rdataset_t rdataset;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdata_soa_t soa;
-
- dns_rdataset_init(&rdataset);
- 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)
- *serial = 0;
- if (refresh != NULL)
- *refresh = 0;
- if (retry != NULL)
- *retry = 0;
- if (expire != NULL)
- *expire = 0;
- if (minimum != NULL)
- *minimum = 0;
- result = ISC_R_SUCCESS;
- goto invalidate_rdataset;
- }
- if (result != ISC_R_SUCCESS) {
- INSIST(!dns_rdataset_isassociated(&rdataset));
- goto invalidate_rdataset;
- }
-
- count = 0;
- result = dns_rdataset_first(&rdataset);
- while (result == ISC_R_SUCCESS) {
- dns_rdata_init(&rdata);
- dns_rdataset_current(&rdataset, &rdata);
- count++;
- if (count == 1) {
- result = dns_rdata_tostruct(&rdata, &soa, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- }
-
- result = dns_rdataset_next(&rdataset);
- dns_rdata_reset(&rdata);
- }
- dns_rdataset_disassociate(&rdataset);
-
- if (soacount != NULL)
- *soacount = count;
-
- if (count > 0) {
- if (serial != NULL)
- *serial = soa.serial;
- if (refresh != NULL)
- *refresh = soa.refresh;
- if (retry != NULL)
- *retry = soa.retry;
- if (expire != NULL)
- *expire = soa.expire;
- if (minimum != NULL)
- *minimum = soa.minimum;
- } else {
- if (soacount != NULL)
- *soacount = 0;
- if (serial != NULL)
- *serial = 0;
- if (refresh != NULL)
- *refresh = 0;
- if (retry != NULL)
- *retry = 0;
- if (expire != NULL)
- *expire = 0;
- if (minimum != NULL)
- *minimum = 0;
- }
-
- result = ISC_R_SUCCESS;
-
- invalidate_rdataset:
- dns_rdataset_invalidate(&rdataset);
-
- return (result);
-}
-
-/*
- * zone must be locked.
- */
-static isc_result_t
-zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
- unsigned int *soacount, isc_uint32_t *serial,
- isc_uint32_t *refresh, isc_uint32_t *retry,
- isc_uint32_t *expire, isc_uint32_t *minimum,
- unsigned int *errors)
-{
- 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);
-
- dns_db_currentversion(db, &version);
-
- node = NULL;
- result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
- if (result != ISC_R_SUCCESS) {
- answer = result;
- goto closeversion;
- }
-
- if (nscount != NULL || errors != NULL) {
- result = zone_count_ns_rr(zone, db, node, version,
- nscount, errors, ISC_TRUE);
- if (result != ISC_R_SUCCESS)
- answer = result;
- }
-
- if (soacount != NULL || serial != NULL || refresh != NULL
- || retry != NULL || expire != NULL || minimum != NULL) {
- result = zone_load_soa_rr(db, node, version, soacount,
- serial, refresh, retry, expire,
- minimum);
- if (result != ISC_R_SUCCESS)
- answer = result;
- }
-
- dns_db_detachnode(db, &node);
- closeversion:
- dns_db_closeversion(db, &version, ISC_FALSE);
-
- return (answer);
-}
-
-void
-dns_zone_attach(dns_zone_t *source, dns_zone_t **target) {
- REQUIRE(DNS_ZONE_VALID(source));
- REQUIRE(target != NULL && *target == NULL);
- isc_refcount_increment(&source->erefs, NULL);
- *target = source;
-}
-
-void
-dns_zone_detach(dns_zone_t **zonep) {
- dns_zone_t *zone;
- dns_zone_t *raw = NULL;
- dns_zone_t *secure = NULL;
- unsigned int refs;
- isc_boolean_t free_now = ISC_FALSE;
-
- REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
-
- zone = *zonep;
-
- isc_refcount_decrement(&zone->erefs, &refs);
-
- if (refs == 0) {
- LOCK_ZONE(zone);
- /*
- * We just detached the last external reference.
- */
- if (zone->task != NULL) {
- /*
- * This zone is being managed. Post
- * its control event and let it clean
- * up synchronously in the context of
- * its task.
- */
- isc_event_t *ev = &zone->ctlevent;
- isc_task_send(zone->task, &ev);
- } else {
- /*
- * This zone is not being managed; it has
- * no task and can have no outstanding
- * events. Free it immediately.
- */
- /*
- * Unmanaged zones should not have non-null views;
- * we have no way of detaching from the view here
- * without causing deadlock because this code is called
- * with the view already locked.
- */
- INSIST(zone->view == NULL);
- free_now = ISC_TRUE;
- raw = zone->raw;
- zone->raw = NULL;
- secure = zone->secure;
- zone->secure = NULL;
- }
- UNLOCK_ZONE(zone);
- }
- *zonep = NULL;
- if (free_now) {
- if (raw != NULL)
- dns_zone_detach(&raw);
- if (secure != NULL)
- dns_zone_idetach(&secure);
- zone_free(zone);
- }
-}
-
-void
-dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) {
- REQUIRE(DNS_ZONE_VALID(source));
- REQUIRE(target != NULL && *target == NULL);
- LOCK_ZONE(source);
- zone_iattach(source, target);
- UNLOCK_ZONE(source);
-}
-
-static void
-zone_iattach(dns_zone_t *source, dns_zone_t **target) {
-
- /*
- * 'source' locked by caller.
- */
- REQUIRE(LOCKED_ZONE(source));
- REQUIRE(DNS_ZONE_VALID(source));
- REQUIRE(target != NULL && *target == NULL);
- INSIST(source->irefs + isc_refcount_current(&source->erefs) > 0);
- source->irefs++;
- INSIST(source->irefs != 0);
- *target = source;
-}
-
-static void
-zone_idetach(dns_zone_t **zonep) {
- dns_zone_t *zone;
-
- /*
- * 'zone' locked by caller.
- */
- REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
- zone = *zonep;
- REQUIRE(LOCKED_ZONE(*zonep));
- *zonep = NULL;
-
- INSIST(zone->irefs > 0);
- zone->irefs--;
- INSIST(zone->irefs + isc_refcount_current(&zone->erefs) > 0);
-}
-
-void
-dns_zone_idetach(dns_zone_t **zonep) {
- dns_zone_t *zone;
- isc_boolean_t free_needed;
-
- REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
- zone = *zonep;
- *zonep = NULL;
-
- LOCK_ZONE(zone);
- INSIST(zone->irefs > 0);
- zone->irefs--;
- free_needed = exit_check(zone);
- UNLOCK_ZONE(zone);
- if (free_needed)
- zone_free(zone);
-}
-
-isc_mem_t *
-dns_zone_getmctx(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- return (zone->mctx);
-}
-
-dns_zonemgr_t *
-dns_zone_getmgr(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- return (zone->zmgr);
-}
-
-void
-dns_zone_setflag(dns_zone_t *zone, unsigned int flags, isc_boolean_t value) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- if (value)
- DNS_ZONE_SETFLAG(zone, flags);
- else
- DNS_ZONE_CLRFLAG(zone, flags);
- UNLOCK_ZONE(zone);
-}
-
-void
-dns_zone_setoption(dns_zone_t *zone, unsigned int option, isc_boolean_t value)
-{
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- if (value)
- zone->options |= option;
- else
- zone->options &= ~option;
- UNLOCK_ZONE(zone);
-}
-
-unsigned int
-dns_zone_getoptions(dns_zone_t *zone) {
-
- REQUIRE(DNS_ZONE_VALID(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));
-
- LOCK_ZONE(zone);
- zone->xfrsource4 = *xfrsource;
- UNLOCK_ZONE(zone);
-
- return (ISC_R_SUCCESS);
-}
-
-isc_sockaddr_t *
-dns_zone_getxfrsource4(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
- return (&zone->xfrsource4);
-}
-
-isc_result_t
-dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- zone->xfrsource6 = *xfrsource;
- UNLOCK_ZONE(zone);
-
- return (ISC_R_SUCCESS);
-}
-
-isc_sockaddr_t *
-dns_zone_getxfrsource6(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
- return (&zone->xfrsource6);
-}
-
-isc_result_t
-dns_zone_setaltxfrsource4(dns_zone_t *zone,
- const isc_sockaddr_t *altxfrsource)
-{
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- zone->altxfrsource4 = *altxfrsource;
- UNLOCK_ZONE(zone);
-
- return (ISC_R_SUCCESS);
-}
-
-isc_sockaddr_t *
-dns_zone_getaltxfrsource4(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
- return (&zone->altxfrsource4);
-}
-
-isc_result_t
-dns_zone_setaltxfrsource6(dns_zone_t *zone,
- const isc_sockaddr_t *altxfrsource)
-{
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- zone->altxfrsource6 = *altxfrsource;
- UNLOCK_ZONE(zone);
-
- return (ISC_R_SUCCESS);
-}
-
-isc_sockaddr_t *
-dns_zone_getaltxfrsource6(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
- return (&zone->altxfrsource6);
-}
-
-isc_result_t
-dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- zone->notifysrc4 = *notifysrc;
- UNLOCK_ZONE(zone);
-
- return (ISC_R_SUCCESS);
-}
-
-isc_sockaddr_t *
-dns_zone_getnotifysrc4(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
- return (&zone->notifysrc4);
-}
-
-isc_result_t
-dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- zone->notifysrc6 = *notifysrc;
- UNLOCK_ZONE(zone);
-
- return (ISC_R_SUCCESS);
-}
-
-isc_sockaddr_t *
-dns_zone_getnotifysrc6(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
- return (&zone->notifysrc6);
-}
-
-static isc_boolean_t
-same_addrs(const isc_sockaddr_t *old, const isc_sockaddr_t *new,
- isc_uint32_t count)
-{
- unsigned int i;
-
- for (i = 0; i < count; i++)
- if (!isc_sockaddr_equal(&old[i], &new[i]))
- return (ISC_FALSE);
- return (ISC_TRUE);
-}
-
-static isc_boolean_t
-same_keynames(dns_name_t **old, dns_name_t **new, isc_uint32_t count) {
- unsigned int i;
-
- if (old == NULL && new == NULL)
- return (ISC_TRUE);
- if (old == NULL || new == NULL)
- return (ISC_FALSE);
-
- for (i = 0; i < count; i++) {
- if (old[i] == NULL && new[i] == NULL)
- continue;
- if (old[i] == NULL || new[i] == NULL ||
- !dns_name_equal(old[i], new[i]))
- return (ISC_FALSE);
- }
- return (ISC_TRUE);
-}
-
-static void
-clear_addresskeylist(isc_sockaddr_t **addrsp, dns_name_t ***keynamesp,
- unsigned int *countp, isc_mem_t *mctx)
-{
- unsigned int count;
- isc_sockaddr_t *addrs;
- dns_name_t **keynames;
-
- REQUIRE(countp != NULL && addrsp != NULL && keynamesp != NULL);
-
- count = *countp;
- *countp = 0;
- addrs = *addrsp;
- *addrsp = NULL;
- keynames = *keynamesp;
- *keynamesp = NULL;
-
- if (addrs != NULL)
- isc_mem_put(mctx, addrs, count * sizeof(isc_sockaddr_t));
-
- if (keynames != NULL) {
- unsigned int i;
- for (i = 0; i < count; i++) {
- if (keynames[i] != NULL) {
- dns_name_free(keynames[i], mctx);
- isc_mem_put(mctx, keynames[i],
- sizeof(dns_name_t));
- keynames[i] = NULL;
- }
- }
- isc_mem_put(mctx, keynames, count * sizeof(dns_name_t *));
- }
-}
-
-static isc_result_t
-set_addrkeylist(unsigned int count,
- const isc_sockaddr_t *addrs, isc_sockaddr_t **newaddrsp,
- dns_name_t **names, dns_name_t ***newnamesp,
- isc_mem_t *mctx)
-{
- isc_result_t result;
- isc_sockaddr_t *newaddrs = NULL;
- dns_name_t **newnames = NULL;
- unsigned int i;
-
- REQUIRE(newaddrsp != NULL && *newaddrsp == NULL);
- REQUIRE(newnamesp != NULL && *newnamesp == NULL);
-
- newaddrs = isc_mem_get(mctx, count * sizeof(*newaddrs));
- if (newaddrs == NULL)
- return (ISC_R_NOMEMORY);
- memcpy(newaddrs, addrs, count * sizeof(*newaddrs));
-
- newnames = NULL;
- if (names != NULL) {
- newnames = isc_mem_get(mctx, count * sizeof(*newnames));
- if (newnames == NULL) {
- isc_mem_put(mctx, newaddrs, count * sizeof(*newaddrs));
- return (ISC_R_NOMEMORY);
- }
- for (i = 0; i < count; i++)
- newnames[i] = NULL;
- for (i = 0; i < count; i++) {
- if (names[i] != NULL) {
- newnames[i] = isc_mem_get(mctx,
- sizeof(dns_name_t));
- if (newnames[i] == NULL)
- goto allocfail;
- dns_name_init(newnames[i], NULL);
- result = dns_name_dup(names[i], mctx,
- newnames[i]);
- if (result != ISC_R_SUCCESS) {
- allocfail:
- for (i = 0; i < count; i++)
- if (newnames[i] != NULL)
- dns_name_free(
- newnames[i],
- mctx);
- isc_mem_put(mctx, newaddrs,
- count * sizeof(*newaddrs));
- isc_mem_put(mctx, newnames,
- count * sizeof(*newnames));
- return (ISC_R_NOMEMORY);
- }
- }
- }
- }
-
- *newaddrsp = newaddrs;
- *newnamesp = newnames;
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
- isc_uint32_t count)
-{
- return (dns_zone_setalsonotifywithkeys(zone, notify, NULL, count));
-}
-
-isc_result_t
-dns_zone_setalsonotifywithkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
- dns_name_t **keynames, isc_uint32_t count)
-{
- isc_result_t result;
- isc_sockaddr_t *newaddrs = NULL;
- dns_name_t **newnames = NULL;
-
- REQUIRE(DNS_ZONE_VALID(zone));
- REQUIRE(count == 0 || notify != NULL);
- if (keynames != NULL)
- REQUIRE(count != 0);
-
- LOCK_ZONE(zone);
-
- if (count == zone->notifycnt &&
- same_addrs(zone->notify, notify, count) &&
- same_keynames(zone->notifykeynames, keynames, count))
- goto unlock;
-
- clear_addresskeylist(&zone->notify, &zone->notifykeynames,
- &zone->notifycnt, zone->mctx);
-
- if (count == 0)
- goto unlock;
-
- /*
- * Set up the notify and notifykey lists
- */
- result = set_addrkeylist(count, notify, &newaddrs,
- keynames, &newnames, zone->mctx);
- if (result != ISC_R_SUCCESS)
- goto unlock;
-
- /*
- * Everything is ok so attach to the zone.
- */
- zone->notify = newaddrs;
- zone->notifykeynames = newnames;
- zone->notifycnt = count;
- unlock:
- UNLOCK_ZONE(zone);
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters,
- isc_uint32_t count)
-{
- isc_result_t result;
-
- result = dns_zone_setmasterswithkeys(zone, masters, NULL, count);
- return (result);
-}
-
-isc_result_t
-dns_zone_setmasterswithkeys(dns_zone_t *zone,
- const isc_sockaddr_t *masters,
- dns_name_t **keynames,
- isc_uint32_t count)
-{
- isc_result_t result = ISC_R_SUCCESS;
- isc_sockaddr_t *newaddrs = NULL;
- dns_name_t **newnames = NULL;
- isc_boolean_t *newok;
- unsigned int i;
-
- REQUIRE(DNS_ZONE_VALID(zone));
- REQUIRE(count == 0 || masters != NULL);
- if (keynames != NULL) {
- REQUIRE(count != 0);
- }
-
- LOCK_ZONE(zone);
- /*
- * The refresh code assumes that 'masters' wouldn't change under it.
- * If it will change then kill off any current refresh in progress
- * and update the masters info. If it won't change then we can just
- * unlock and exit.
- */
- if (count != zone->masterscnt ||
- !same_addrs(zone->masters, masters, count) ||
- !same_keynames(zone->masterkeynames, keynames, count)) {
- if (zone->request != NULL)
- dns_request_cancel(zone->request);
- } else
- goto unlock;
-
- /*
- * This needs to happen before clear_addresskeylist() sets
- * zone->masterscnt to 0:
- */
- if (zone->mastersok != NULL) {
- isc_mem_put(zone->mctx, zone->mastersok,
- zone->masterscnt * sizeof(isc_boolean_t));
- zone->mastersok = NULL;
- }
- clear_addresskeylist(&zone->masters, &zone->masterkeynames,
- &zone->masterscnt, zone->mctx);
- /*
- * If count == 0, don't allocate any space for masters, mastersok or
- * keynames so internally, those pointers are NULL if count == 0
- */
- if (count == 0)
- goto unlock;
-
- /*
- * mastersok must contain count elements
- */
- newok = isc_mem_get(zone->mctx, count * sizeof(*newok));
- if (newok == NULL) {
- result = ISC_R_NOMEMORY;
- isc_mem_put(zone->mctx, newaddrs, count * sizeof(*newaddrs));
- goto unlock;
- };
- for (i = 0; i < count; i++)
- newok[i] = ISC_FALSE;
-
- /*
- * Now set up the masters and masterkey lists
- */
- result = set_addrkeylist(count, masters, &newaddrs,
- keynames, &newnames, zone->mctx);
- if (result != ISC_R_SUCCESS) {
- isc_mem_put(zone->mctx, newok, count * sizeof(*newok));
- goto unlock;
- }
-
- /*
- * Everything is ok so attach to the zone.
- */
- zone->curmaster = 0;
- zone->mastersok = newok;
- zone->masters = newaddrs;
- zone->masterkeynames = newnames;
- zone->masterscnt = count;
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS);
-
- unlock:
- UNLOCK_ZONE(zone);
- return (result);
-}
-
-isc_result_t
-dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) {
- isc_result_t result = ISC_R_SUCCESS;
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
- if (zone->db == NULL)
- result = DNS_R_NOTLOADED;
- else
- dns_db_attach(zone->db, dpb);
- ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
-
- 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.
- */
-
-void
-dns_zone_maintenance(dns_zone_t *zone) {
- const char me[] = "dns_zone_maintenance";
- isc_time_t now;
-
- REQUIRE(DNS_ZONE_VALID(zone));
- ENTER;
-
- LOCK_ZONE(zone);
- TIME_NOW(&now);
- zone_settimer(zone, &now);
- UNLOCK_ZONE(zone);
-}
-
-static inline isc_boolean_t
-was_dumping(dns_zone_t *zone) {
- isc_boolean_t dumping;
-
- REQUIRE(LOCKED_ZONE(zone));
-
- dumping = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING);
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
- if (!dumping) {
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
- isc_time_settoepoch(&zone->dumptime);
- }
- return (dumping);
-}
-
-static isc_result_t
-find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
- isc_mem_t *mctx, unsigned int maxkeys,
- dst_key_t **keys, unsigned int *nkeys)
-{
- isc_result_t result;
- dns_dbnode_t *node = NULL;
- const char *directory = dns_zone_getkeydirectory(zone);
-
- CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node));
- result = dns_dnssec_findzonekeys2(db, ver, node, dns_db_origin(db),
- directory, mctx, maxkeys, keys,
- nkeys);
- if (result == ISC_R_NOTFOUND)
- result = ISC_R_SUCCESS;
- failure:
- if (node != NULL)
- dns_db_detachnode(db, &node);
- return (result);
-}
-
-static isc_result_t
-offline(dns_db_t *db, dns_dbversion_t *ver, zonediff_t *zonediff,
- dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata)
-{
- isc_result_t result;
-
- if ((rdata->flags & DNS_RDATA_OFFLINE) != 0)
- return (ISC_R_SUCCESS);
- result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN,
- name, ttl, rdata);
- if (result != ISC_R_SUCCESS)
- return (result);
- rdata->flags |= DNS_RDATA_OFFLINE;
- result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_ADDRESIGN,
- name, ttl, rdata);
- zonediff->offline = ISC_TRUE;
- return (result);
-}
-
-static void
-set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when, isc_stdtime_t now)
-{
- unsigned int delta;
- char timebuf[80];
-
- zone->key_expiry = when;
- if (when <= now) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "DNSKEY RRSIG(s) have expired");
- isc_time_settoepoch(&zone->keywarntime);
- } else if (when < now + 7 * 24 * 3600) {
- isc_time_t t;
- isc_time_set(&t, when, 0);
- isc_time_formattimestamp(&t, timebuf, 80);
- dns_zone_log(zone, ISC_LOG_WARNING,
- "DNSKEY RRSIG(s) will expire within 7 days: %s",
- timebuf);
- delta = when - now;
- delta--; /* loop prevention */
- delta /= 24 * 3600; /* to whole days */
- delta *= 24 * 3600; /* to seconds */
- isc_time_set(&zone->keywarntime, when - delta, 0);
- } else {
- isc_time_set(&zone->keywarntime, when - 7 * 24 * 3600, 0);
- isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
- dns_zone_log(zone, ISC_LOG_NOTICE,
- "setting keywarntime to %s", timebuf);
- }
-}
-
-/*
- * Helper function to del_sigs(). We don't want to delete RRSIGs that
- * have no new key.
- */
-static isc_boolean_t
-delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys) {
- unsigned int i = 0;
-
- /*
- * It's okay to delete a signature if there is an active ZSK
- * with the same algorithm
- */
- for (i = 0; i < nkeys; i++) {
- if (rrsig_ptr->algorithm == dst_key_alg(keys[i]) &&
- (dst_key_isprivate(keys[i])) && !KSK(keys[i]))
- return (ISC_TRUE);
- }
-
- /*
- * Failing that, it is *not* okay to delete a signature
- * if the associated public key is still in the DNSKEY RRset
- */
- for (i = 0; i < nkeys; i++) {
- if ((rrsig_ptr->algorithm == dst_key_alg(keys[i])) &&
- (rrsig_ptr->keyid == dst_key_id(keys[i])))
- return (ISC_FALSE);
- }
-
- /*
- * But if the key is gone, then go ahead.
- */
- return (ISC_TRUE);
-}
-
-/*
- * Delete expired RRsigs and any RRsigs we are about to re-sign.
- * See also update.c:del_keysigs().
- */
-static isc_result_t
-del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
- dns_rdatatype_t type, zonediff_t *zonediff, dst_key_t **keys,
- unsigned int nkeys, isc_stdtime_t now, isc_boolean_t incremental)
-{
- isc_result_t result;
- dns_dbnode_t *node = NULL;
- dns_rdataset_t rdataset;
- unsigned int i;
- dns_rdata_rrsig_t rrsig;
- isc_boolean_t found, changed;
- isc_int64_t warn = 0, maybe = 0;
-
- dns_rdataset_init(&rdataset);
-
- if (type == dns_rdatatype_nsec3)
- result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
- else
- result = dns_db_findnode(db, name, ISC_FALSE, &node);
- if (result == ISC_R_NOTFOUND)
- return (ISC_R_SUCCESS);
- if (result != ISC_R_SUCCESS)
- goto failure;
- result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig, type,
- (isc_stdtime_t) 0, &rdataset, NULL);
- dns_db_detachnode(db, &node);
-
- if (result == ISC_R_NOTFOUND) {
- INSIST(!dns_rdataset_isassociated(&rdataset));
- return (ISC_R_SUCCESS);
- }
- if (result != ISC_R_SUCCESS) {
- INSIST(!dns_rdataset_isassociated(&rdataset));
- goto failure;
- }
-
- changed = ISC_FALSE;
- 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, &rrsig, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
-
- if (type != dns_rdatatype_dnskey) {
- if (delsig_ok(&rrsig, keys, nkeys)) {
- result = update_one_rr(db, ver, zonediff->diff,
- DNS_DIFFOP_DELRESIGN, name,
- rdataset.ttl, &rdata);
- if (incremental)
- changed = ISC_TRUE;
- if (result != ISC_R_SUCCESS)
- break;
- } else {
- /*
- * At this point, we've got an RRSIG,
- * which is signed by an inactive key.
- * An administrator needs to provide a new
- * key/alg, but until that time, we want to
- * keep the old RRSIG. Marking the key as
- * offline will prevent us spinning waiting
- * for the private part.
- */
- if (incremental) {
- result = offline(db, ver, zonediff,
- name, rdataset.ttl,
- &rdata);
- changed = ISC_TRUE;
- if (result != ISC_R_SUCCESS)
- break;
- }
-
- /*
- * Log the key id and algorithm of
- * the inactive key with no replacement
- */
- if (zone->log_key_expired_timer <= now) {
- char origin[DNS_NAME_FORMATSIZE];
- char algbuf[DNS_NAME_FORMATSIZE];
- dns_name_format(&zone->origin, origin,
- sizeof(origin));
- dns_secalg_format(rrsig.algorithm,
- algbuf,
- sizeof(algbuf));
- dns_zone_log(zone, ISC_LOG_WARNING,
- "Key %s/%s/%d "
- "missing or inactive "
- "and has no replacement: "
- "retaining signatures.",
- origin, algbuf,
- rrsig.keyid);
- zone->log_key_expired_timer = now +
- 3600;
- }
- }
- continue;
- }
-
- /*
- * RRSIG(DNSKEY) requires special processing.
- */
- found = ISC_FALSE;
- for (i = 0; i < nkeys; i++) {
- if (rrsig.algorithm == dst_key_alg(keys[i]) &&
- rrsig.keyid == dst_key_id(keys[i])) {
- found = ISC_TRUE;
- /*
- * Mark offline RRSIG(DNSKEY).
- * We want the earliest offline expire time
- * iff there is a new offline signature.
- */
- if (!dst_key_isprivate(keys[i])) {
- isc_int64_t timeexpire =
- dns_time64_from32(rrsig.timeexpire);
- if (warn != 0 && warn > timeexpire)
- warn = timeexpire;
- if (rdata.flags & DNS_RDATA_OFFLINE) {
- if (maybe == 0 ||
- maybe > timeexpire)
- maybe = timeexpire;
- break;
- }
- if (warn == 0)
- warn = maybe;
- if (warn == 0 || warn > timeexpire)
- warn = timeexpire;
- result = offline(db, ver, zonediff,
- name, rdataset.ttl,
- &rdata);
- break;
- }
- result = update_one_rr(db, ver, zonediff->diff,
- DNS_DIFFOP_DELRESIGN,
- name, rdataset.ttl,
- &rdata);
- break;
- }
- }
-
- /*
- * If there is not a matching DNSKEY then
- * delete the RRSIG.
- */
- if (!found)
- result = update_one_rr(db, ver, zonediff->diff,
- DNS_DIFFOP_DELRESIGN, name,
- rdataset.ttl, &rdata);
- if (result != ISC_R_SUCCESS)
- break;
- }
-
- if (changed && (rdataset.attributes & DNS_RDATASETATTR_RESIGN) != 0)
- dns_db_resigned(db, &rdataset, ver);
-
- dns_rdataset_disassociate(&rdataset);
- if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
- if (warn > 0) {
-#if defined(STDTIME_ON_32BITS)
- isc_stdtime_t stdwarn = (isc_stdtime_t)warn;
- if (warn == stdwarn)
-#endif
- set_key_expiry_warning(zone, (isc_stdtime_t)warn, now);
-#if defined(STDTIME_ON_32BITS)
- else
- dns_zone_log(zone, ISC_LOG_ERROR,
- "key expiry warning time out of range");
-#endif
- }
- failure:
- if (node != NULL)
- dns_db_detachnode(db, &node);
- return (result);
-}
-
-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_boolean_t keyset_kskonly)
-{
- isc_result_t result;
- dns_dbnode_t *node = NULL;
- dns_rdataset_t rdataset;
- dns_rdata_t sig_rdata = DNS_RDATA_INIT;
- unsigned char data[1024]; /* XXX */
- isc_buffer_t buffer;
- unsigned int i, j;
-
- dns_rdataset_init(&rdataset);
- isc_buffer_init(&buffer, data, sizeof(data));
-
- if (type == dns_rdatatype_nsec3)
- result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
- else
- result = dns_db_findnode(db, name, ISC_FALSE, &node);
- if (result == ISC_R_NOTFOUND)
- return (ISC_R_SUCCESS);
- if (result != ISC_R_SUCCESS)
- goto failure;
- 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) {
- INSIST(!dns_rdataset_isassociated(&rdataset));
- return (ISC_R_SUCCESS);
- }
- if (result != ISC_R_SUCCESS) {
- INSIST(!dns_rdataset_isassociated(&rdataset));
- goto failure;
- }
-
- for (i = 0; i < nkeys; i++) {
- 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));
- /* Update the database and journal with the RRSIG. */
- /* XXX inefficient - will cause dataset merging */
- CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN,
- name, rdataset.ttl, &sig_rdata));
- dns_rdata_reset(&sig_rdata);
- isc_buffer_init(&buffer, data, sizeof(data));
- }
-
- failure:
- if (dns_rdataset_isassociated(&rdataset))
- dns_rdataset_disassociate(&rdataset);
- if (node != NULL)
- dns_db_detachnode(db, &node);
- return (result);
-}
-
-static void
-zone_resigninc(dns_zone_t *zone) {
- const char *me = "zone_resigninc";
- dns_db_t *db = NULL;
- dns_dbversion_t *version = NULL;
- dns_diff_t _sig_diff;
- zonediff_t zonediff;
- dns_fixedname_t fixed;
- dns_name_t *name;
- dns_rdataset_t rdataset;
- dns_rdatatype_t covers;
- dst_key_t *zone_keys[DNS_MAXZONEKEYS];
- 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;
- unsigned int i;
- unsigned int nkeys = 0;
- unsigned int resign;
-
- ENTER;
-
- dns_rdataset_init(&rdataset);
- dns_fixedname_init(&fixed);
- dns_diff_init(zone->mctx, &_sig_diff);
- _sig_diff.resign = zone->sigresigninginterval;
- zonediff_init(&zonediff, &_sig_diff);
-
- /*
- * Zone is frozen or automatic resigning is disabled.
- * Pause for 5 minutes.
- */
- if (zone->update_disabled ||
- DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN))
- {
- result = ISC_R_FAILURE;
- goto failure;
- }
-
- ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
- dns_db_attach(zone->db, &db);
- ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
-
- result = dns_db_newversion(db, &version);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_resigninc:dns_db_newversion -> %s",
- dns_result_totext(result));
- goto failure;
- }
-
- result = find_zone_keys(zone, db, version, zone->mctx, DNS_MAXZONEKEYS,
- zone_keys, &nkeys);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_resigninc:find_zone_keys -> %s",
- dns_result_totext(result));
- goto failure;
- }
-
- isc_stdtime_get(&now);
- inception = now - 3600; /* Allow for clock skew. */
- soaexpire = now + dns_zone_getsigvalidityinterval(zone);
- /*
- * Spread out signatures over time if they happen to be
- * clumped. We don't do this for each add_sigs() call as
- * we still want some clustering to occur.
- */
- isc_random_get(&jitter);
- expire = soaexpire - jitter % 3600;
- stop = now + 5;
-
- check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
- keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
-
- name = dns_fixedname_name(&fixed);
- result = dns_db_getsigningtime(db, &rdataset, name);
- if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_resigninc:dns_db_getsigningtime -> %s",
- dns_result_totext(result));
- }
-
- i = 0;
- while (result == ISC_R_SUCCESS) {
- resign = rdataset.resign;
- covers = rdataset.covers;
- dns_rdataset_disassociate(&rdataset);
-
- /*
- * Stop if we hit the SOA as that means we have walked the
- * entire zone. The SOA record should always be the most
- * recent signature.
- */
- /* XXXMPA increase number of RRsets signed pre call */
- if (covers == dns_rdatatype_soa || i++ > zone->signatures ||
- resign > stop)
- break;
-
- result = del_sigs(zone, db, version, name, covers, &zonediff,
- zone_keys, nkeys, now, ISC_TRUE);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_resigninc:del_sigs -> %s",
- dns_result_totext(result));
- break;
- }
-
- result = add_sigs(db, version, name, covers, zonediff.diff,
- zone_keys, nkeys, zone->mctx, inception,
- expire, check_ksk, keyset_kskonly);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_resigninc:add_sigs -> %s",
- dns_result_totext(result));
- break;
- }
- result = dns_db_getsigningtime(db, &rdataset,
- dns_fixedname_name(&fixed));
- if (nkeys == 0 && result == ISC_R_NOTFOUND) {
- result = ISC_R_SUCCESS;
- break;
- }
- if (result != ISC_R_SUCCESS)
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_resigninc:dns_db_getsigningtime -> %s",
- dns_result_totext(result));
- }
-
- if (result != ISC_R_NOMORE && result != ISC_R_SUCCESS)
- goto failure;
-
- result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
- &zonediff, zone_keys, nkeys, now, ISC_TRUE);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_resigninc:del_sigs -> %s",
- dns_result_totext(result));
- goto failure;
- }
-
- /*
- * Did we change anything in the zone?
- */
- if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
- /*
- * Commit the changes if any key has been marked as offline. */
- if (zonediff.offline)
- dns_db_closeversion(db, &version, ISC_TRUE);
- goto failure;
- }
-
- /* Increment SOA serial if we have made changes */
- result = update_soa_serial(db, version, zonediff.diff, zone->mctx,
- zone->updatemethod);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_resigninc:update_soa_serial -> %s",
- dns_result_totext(result));
- goto failure;
- }
-
- /*
- * Generate maximum life time signatures so that the above loop
- * termination is sensible.
- */
- result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
- zonediff.diff, zone_keys, nkeys, zone->mctx,
- inception, soaexpire, check_ksk, keyset_kskonly);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_resigninc:add_sigs -> %s",
- dns_result_totext(result));
- goto failure;
- }
-
- /* Write changes to journal file. */
- CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_resigninc"));
-
- /* Everything has succeeded. Commit the changes. */
- dns_db_closeversion(db, &version, ISC_TRUE);
-
- failure:
- dns_diff_clear(&_sig_diff);
- for (i = 0; i < nkeys; i++)
- dst_key_free(&zone_keys[i]);
- if (version != NULL) {
- dns_db_closeversion(zone->db, &version, ISC_FALSE);
- dns_db_detach(&db);
- } else if (db != NULL)
- dns_db_detach(&db);
- if (result == ISC_R_SUCCESS) {
- set_resigntime(zone);
- LOCK_ZONE(zone);
- zone_needdump(zone, DNS_DUMP_DELAY);
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
- UNLOCK_ZONE(zone);
- } else {
- /*
- * Something failed. Retry in 5 minutes.
- */
- isc_interval_t ival;
- isc_interval_set(&ival, 300, 0);
- isc_time_nowplusinterval(&zone->resigntime, &ival);
- }
-}
-
-static isc_result_t
-next_active(dns_db_t *db, dns_dbversion_t *version, dns_name_t *oldname,
- dns_name_t *newname, isc_boolean_t bottom)
-{
- isc_result_t result;
- dns_dbiterator_t *dbit = NULL;
- dns_rdatasetiter_t *rdsit = NULL;
- dns_dbnode_t *node = NULL;
-
- CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit));
- CHECK(dns_dbiterator_seek(dbit, oldname));
- do {
- result = dns_dbiterator_next(dbit);
- if (result == ISC_R_NOMORE)
- CHECK(dns_dbiterator_first(dbit));
- CHECK(dns_dbiterator_current(dbit, &node, newname));
- if (bottom && dns_name_issubdomain(newname, oldname) &&
- !dns_name_equal(newname, oldname)) {
- dns_db_detachnode(db, &node);
- continue;
- }
- /*
- * Is this node empty?
- */
- CHECK(dns_db_allrdatasets(db, node, version, 0, &rdsit));
- result = dns_rdatasetiter_first(rdsit);
- dns_db_detachnode(db, &node);
- dns_rdatasetiter_destroy(&rdsit);
- if (result != ISC_R_NOMORE)
- break;
- } while (1);
- failure:
- if (node != NULL)
- dns_db_detachnode(db, &node);
- if (dbit != NULL)
- dns_dbiterator_destroy(&dbit);
- return (result);
-}
-
-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)
-{
- isc_result_t result;
- dns_rdataset_t rdataset;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdata_rrsig_t rrsig;
-
- dns_rdataset_init(&rdataset);
- result = dns_db_findrdataset(db, node, version, dns_rdatatype_rrsig,
- type, 0, &rdataset, NULL);
- 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)) {
- dns_rdataset_current(&rdataset, &rdata);
- result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
- INSIST(result == ISC_R_SUCCESS);
- if (rrsig.algorithm == dst_key_alg(key) &&
- rrsig.keyid == dst_key_id(key)) {
- dns_rdataset_disassociate(&rdataset);
- return (ISC_TRUE);
- }
- dns_rdata_reset(&rdata);
- }
- dns_rdataset_disassociate(&rdataset);
- return (ISC_FALSE);
-}
-
-static isc_result_t
-add_nsec(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
- dns_dbnode_t *node, dns_ttl_t ttl, isc_boolean_t bottom,
- dns_diff_t *diff)
-{
- dns_fixedname_t fixed;
- dns_name_t *next;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- isc_result_t result;
- unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE];
-
- dns_fixedname_init(&fixed);
- next = dns_fixedname_name(&fixed);
-
- CHECK(next_active(db, version, name, next, bottom));
- CHECK(dns_nsec_buildrdata(db, version, node, next, nsecbuffer,
- &rdata));
- CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, ttl,
- &rdata));
- failure:
- return (result);
-}
-
-static isc_result_t
-sign_a_node(dns_db_t *db, dns_name_t *name, dns_dbnode_t *node,
- dns_dbversion_t *version, isc_boolean_t build_nsec3,
- 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 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;
- dns_rdataset_t rdataset;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- isc_buffer_t buffer;
- unsigned char data[1024];
- isc_boolean_t seen_soa, seen_ns, seen_rr, seen_dname, seen_nsec,
- seen_nsec3, seen_ds;
- isc_boolean_t bottom;
-
- result = dns_db_allrdatasets(db, node, version, 0, &iterator);
- if (result != ISC_R_SUCCESS) {
- if (result == ISC_R_NOTFOUND)
- 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 =
- seen_nsec3 = seen_ds = ISC_FALSE;
- 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_soa)
- seen_soa = ISC_TRUE;
- else if (rdataset.type == dns_rdatatype_ns)
- seen_ns = ISC_TRUE;
- else if (rdataset.type == dns_rdatatype_ds)
- seen_ds = ISC_TRUE;
- else if (rdataset.type == dns_rdatatype_dname)
- seen_dname = ISC_TRUE;
- else if (rdataset.type == dns_rdatatype_nsec)
- seen_nsec = ISC_TRUE;
- else if (rdataset.type == dns_rdatatype_nsec3)
- seen_nsec3 = ISC_TRUE;
- if (rdataset.type != dns_rdatatype_rrsig)
- seen_rr = ISC_TRUE;
- dns_rdataset_disassociate(&rdataset);
- }
- if (result != ISC_R_NOMORE)
- goto failure;
- if (seen_ns && !seen_soa)
- *delegation = ISC_TRUE;
- /*
- * Going from insecure to NSEC3.
- * Don't generate NSEC3 records for NSEC3 records.
- */
- if (build_nsec3 && !seen_nsec3 && seen_rr) {
- isc_boolean_t unsecure = !seen_ds && seen_ns && !seen_soa;
- CHECK(dns_nsec3_addnsec3s(db, version, name, minimum,
- unsecure, diff));
- (*signatures)--;
- }
- /*
- * Going from insecure to NSEC.
- * Don't generate NSEC records for NSEC3 records.
- */
- if (build_nsec && !seen_nsec3 && !seen_nsec && seen_rr) {
- /* Build and add NSEC. */
- bottom = (seen_ns && !seen_soa) || seen_dname;
- /*
- * 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) {
- dns_rdatasetiter_current(iterator, &rdataset);
- if (rdataset.type == dns_rdatatype_soa ||
- rdataset.type == dns_rdatatype_rrsig)
- goto next_rdataset;
- 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 &&
- rdataset.type != dns_rdatatype_nsec)
- goto next_rdataset;
- 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. */
- /* XXX inefficient - will cause dataset merging */
- CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADDRESIGN,
- name, rdataset.ttl, &rdata));
- dns_rdata_reset(&rdata);
- (*signatures)--;
- next_rdataset:
- dns_rdataset_disassociate(&rdataset);
- result = dns_rdatasetiter_next(iterator);
- }
- if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
- if (seen_dname)
- *delegation = ISC_TRUE;
- failure:
- if (dns_rdataset_isassociated(&rdataset))
- dns_rdataset_disassociate(&rdataset);
- if (iterator != NULL)
- dns_rdatasetiter_destroy(&iterator);
- 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 update_only, dns_diff_t *diff)
-{
- isc_result_t result;
- dns_rdataset_t rdataset;
- dns_dbnode_t *node = NULL;
-
- CHECK(dns_db_getoriginnode(db, &node));
- 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);
- return (result);
-}
-
-static isc_result_t
-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;
- dns_rdataset_t rdataset;
- 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,
- 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) {
- 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;
- }
- /*
- * 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;
- have_rr = ISC_TRUE;
- } else
- CHECK(update_one_rr(signing->db, version, diff,
- 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;
- data[3] = 0;
- data[4] = 1;
- rdata.length = sizeof(data);
- rdata.data = data;
- rdata.type = zone->privatetype;
- rdata.rdclass = dns_db_class(signing->db);
- CHECK(update_one_rr(signing->db, version, diff, DNS_DIFFOP_ADD,
- &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);
- if (node != NULL)
- dns_db_detachnode(signing->db, &node);
- 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_rdatatype_t privatetype,
- dns_diff_t *diff)
-{
- dns_dbnode_t *node = NULL;
- dns_name_t *name = dns_db_origin(db);
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdataset_t rdataset;
- dns_rdata_nsec3param_t nsec3param;
- isc_result_t result;
- isc_buffer_t buffer;
- unsigned char parambuf[DNS_NSEC3PARAM_BUFFERSIZE];
- dns_ttl_t ttl = 0;
- isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE;
-
- dns_rdataset_init(&rdataset);
-
- result = dns_db_getoriginnode(db, &node);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
- 0, 0, &rdataset, NULL);
- if (result == ISC_R_NOTFOUND)
- goto try_private;
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- /*
- * Preserve the existing ttl.
- */
- ttl = rdataset.ttl;
-
- /*
- * Delete all NSEC3PARAM records which match that in nsec3chain.
- */
- for (result = dns_rdataset_first(&rdataset);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(&rdataset)) {
-
- dns_rdataset_current(&rdataset, &rdata);
- CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
-
- if (nsec3param.hash != chain->nsec3param.hash ||
- (active && nsec3param.flags != 0) ||
- 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, &rdata));
- dns_rdata_reset(&rdata);
- }
- if (result != ISC_R_NOMORE)
- goto failure;
-
- dns_rdataset_disassociate(&rdataset);
-
- try_private:
-
- if (active)
- goto add;
-
- result = dns_nsec_nseconly(db, ver, &nseconly);
- nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
-
- /*
- * Delete all private records which match that in nsec3chain.
- */
- 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 ((!nsec3ok &&
- (nsec3param.flags & DNS_NSEC3FLAG_INITIAL) != 0) ||
- nsec3param.hash != chain->nsec3param.hash ||
- nsec3param.iterations != chain->nsec3param.iterations ||
- nsec3param.salt_length != chain->nsec3param.salt_length ||
- memcmp(nsec3param.salt, chain->nsec3param.salt,
- 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;
- goto failure;
- }
-
- /*
- * Add a NSEC3PARAM record which matches that in nsec3chain but
- * with all flags bits cleared.
- *
- * Note: we do not clear chain->nsec3param.flags as this change
- * may be reversed.
- */
- isc_buffer_init(&buffer, &parambuf, sizeof(parambuf));
- CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db),
- dns_rdatatype_nsec3param,
- &chain->nsec3param, &buffer));
- rdata.data[1] = 0; /* Clear flag bits. */
- CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name, ttl, &rdata));
-
- failure:
- dns_db_detachnode(db, &node);
- if (dns_rdataset_isassociated(&rdataset))
- dns_rdataset_disassociate(&rdataset);
- return (result);
-}
-
-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)
-{
- dns_rdataset_t rdataset;
- isc_result_t result;
-
- dns_rdataset_init(&rdataset);
-
- result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
- 0, 0, &rdataset, NULL);
- if (result == ISC_R_NOTFOUND)
- 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_rdataset_current(&rdataset, &rdata);
- CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
- rdataset.ttl, &rdata));
- }
- if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
- failure:
- dns_rdataset_disassociate(&rdataset);
- return (result);
-}
-
-static isc_result_t
-deletematchingnsec3(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
- dns_name_t *name, const dns_rdata_nsec3param_t *param,
- dns_diff_t *diff)
-{
- dns_rdataset_t rdataset;
- dns_rdata_nsec3_t nsec3;
- isc_result_t result;
-
- dns_rdataset_init(&rdataset);
- result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3,
- 0, 0, &rdataset, NULL);
- if (result == ISC_R_NOTFOUND)
- 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_rdataset_current(&rdataset, &rdata);
- CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL));
- if (nsec3.hash != param->hash ||
- nsec3.iterations != param->iterations ||
- nsec3.salt_length != param->salt_length ||
- memcmp(nsec3.salt, param->salt, nsec3.salt_length))
- continue;
- CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
- rdataset.ttl, &rdata));
- }
- if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
- failure:
- dns_rdataset_disassociate(&rdataset);
- return (result);
-}
-
-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)
-{
- dns_dbnode_t *node = NULL;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdata_nsec3param_t myparam;
- dns_rdataset_t rdataset;
- isc_result_t result;
-
- *answer = ISC_FALSE;
-
- result = dns_db_getoriginnode(db, &node);
- 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_SUCCESS) {
- dns_rdataset_disassociate(&rdataset);
- dns_db_detachnode(db, &node);
- return (result);
- }
- if (result != ISC_R_NOTFOUND) {
- dns_db_detachnode(db, &node);
- return (result);
- }
-
- result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
- 0, 0, &rdataset, NULL);
- if (result == ISC_R_NOTFOUND) {
- *answer = ISC_TRUE;
- dns_db_detachnode(db, &node);
- return (ISC_R_SUCCESS);
- }
- 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_rdataset_current(&rdataset, &rdata);
- CHECK(dns_rdata_tostruct(&rdata, &myparam, NULL));
- dns_rdata_reset(&rdata);
- /*
- * Ignore any NSEC3PARAM removals.
- */
- if (NSEC3REMOVE(myparam.flags))
- continue;
- /*
- * Ignore the chain that we are in the process of deleting.
- */
- if (myparam.hash == param->hash &&
- myparam.iterations == param->iterations &&
- myparam.salt_length == param->salt_length &&
- !memcmp(myparam.salt, param->salt, myparam.salt_length))
- continue;
- /*
- * Found an active NSEC3 chain.
- */
- break;
- }
- if (result == ISC_R_NOMORE) {
- *answer = ISC_TRUE;
- result = ISC_R_SUCCESS;
- }
-
- failure:
- if (dns_rdataset_isassociated(&rdataset))
- dns_rdataset_disassociate(&rdataset);
- dns_db_detachnode(db, &node);
- 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,
- zonediff_t *zonediff)
-{
- 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, zonediff,
- zone_keys, nkeys, now, ISC_FALSE);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "update_sigs:del_sigs -> %s",
- dns_result_totext(result));
- return (result);
- }
- result = add_sigs(db, version, &tuple->name,
- tuple->rdata.type, zonediff->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",
- 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(zonediff->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 *me = "zone_nsec3chain";
- dns_db_t *db = NULL;
- dns_dbnode_t *node = NULL;
- dns_dbversion_t *version = NULL;
- dns_diff_t _sig_diff;
- dns_diff_t nsec_diff;
- dns_diff_t nsec3_diff;
- dns_diff_t param_diff;
- zonediff_t zonediff;
- dns_fixedname_t fixed;
- dns_fixedname_t nextfixed;
- dns_name_t *name, *nextname;
- dns_rdataset_t rdataset;
- dns_nsec3chain_t *nsec3chain = NULL, *nextnsec3chain;
- dns_nsec3chainlist_t cleanup;
- dst_key_t *zone_keys[DNS_MAXZONEKEYS];
- isc_int32_t signatures;
- isc_boolean_t check_ksk, keyset_kskonly;
- isc_boolean_t delegation;
- isc_boolean_t first;
- isc_result_t result;
- isc_stdtime_t now, inception, soaexpire, expire;
- isc_uint32_t jitter;
- unsigned int i;
- unsigned int nkeys = 0;
- isc_uint32_t nodes;
- isc_boolean_t unsecure = ISC_FALSE;
- 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;
- isc_boolean_t buildnsecchain;
- isc_boolean_t updatensec = ISC_FALSE;
- dns_rdatatype_t privatetype = zone->privatetype;
-
- ENTER;
-
- dns_rdataset_init(&rdataset);
- dns_fixedname_init(&fixed);
- name = dns_fixedname_name(&fixed);
- dns_fixedname_init(&nextfixed);
- nextname = dns_fixedname_name(&nextfixed);
- dns_diff_init(zone->mctx, &param_diff);
- dns_diff_init(zone->mctx, &nsec3_diff);
- dns_diff_init(zone->mctx, &nsec_diff);
- dns_diff_init(zone->mctx, &_sig_diff);
- _sig_diff.resign = zone->sigresigninginterval;
- zonediff_init(&zonediff, &_sig_diff);
- ISC_LIST_INIT(cleanup);
-
- /*
- * Updates are disabled. Pause for 5 minutes.
- */
- if (zone->update_disabled) {
- result = ISC_R_FAILURE;
- goto failure;
- }
-
- ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
- dns_db_attach(zone->db, &db);
- ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
-
- result = dns_db_newversion(db, &version);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_nsec3chain:dns_db_newversion -> %s",
- dns_result_totext(result));
- goto failure;
- }
-
- result = find_zone_keys(zone, db, version, zone->mctx,
- DNS_MAXZONEKEYS, zone_keys, &nkeys);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_nsec3chain:find_zone_keys -> %s",
- dns_result_totext(result));
- goto failure;
- }
-
- isc_stdtime_get(&now);
- inception = now - 3600; /* Allow for clock skew. */
- soaexpire = now + dns_zone_getsigvalidityinterval(zone);
-
- /*
- * Spread out signatures over time if they happen to be
- * clumped. We don't do this for each add_sigs() call as
- * we still want some clustering to occur.
- */
- isc_random_get(&jitter);
- expire = soaexpire - jitter % 3600;
-
- check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
- keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
-
- /*
- * We keep pulling nodes off each iterator in turn until
- * we have no more nodes to pull off or we reach the limits
- * for this quantum.
- */
- nodes = zone->nodes;
- signatures = zone->signatures;
- LOCK_ZONE(zone);
- nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
- UNLOCK_ZONE(zone);
- first = ISC_TRUE;
-
- if (nsec3chain != NULL)
- nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
- /*
- * Generate new NSEC3 chains first.
- */
- while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
- LOCK_ZONE(zone);
- nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
-
- ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
- if (nsec3chain->done || nsec3chain->db != zone->db) {
- ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
- ISC_LIST_APPEND(cleanup, nsec3chain, link);
- }
- ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
- UNLOCK_ZONE(zone);
- if (ISC_LIST_TAIL(cleanup) == nsec3chain)
- goto next_addchain;
-
- /*
- * Possible future db.
- */
- if (nsec3chain->db != db) {
- goto next_addchain;
- }
-
- if (NSEC3REMOVE(nsec3chain->nsec3param.flags))
- goto next_addchain;
-
- dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
-
- if (nsec3chain->delete_nsec) {
- delegation = ISC_FALSE;
- dns_dbiterator_pause(nsec3chain->dbiterator);
- CHECK(delete_nsec(db, version, node, name, &nsec_diff));
- goto next_addnode;
- }
- /*
- * On the first pass we need to check if the current node
- * has not been obscured.
- */
- delegation = ISC_FALSE;
- unsecure = ISC_FALSE;
- if (first) {
- dns_fixedname_t ffound;
- dns_name_t *found;
- dns_fixedname_init(&ffound);
- found = dns_fixedname_name(&ffound);
- result = dns_db_find(db, name, version,
- dns_rdatatype_soa,
- DNS_DBFIND_NOWILD, 0, NULL, found,
- NULL, NULL);
- if ((result == DNS_R_DELEGATION ||
- result == DNS_R_DNAME) &&
- !dns_name_equal(name, found)) {
- /*
- * Remember the obscuring name so that
- * we skip all obscured names.
- */
- dns_name_copy(found, name, NULL);
- delegation = ISC_TRUE;
- goto next_addnode;
- }
- }
-
- /*
- * Check to see if this is a bottom of zone node.
- */
- result = dns_db_allrdatasets(db, node, version, 0, &iterator);
- if (result == ISC_R_NOTFOUND) /* Empty node? */
- goto next_addnode;
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- seen_soa = seen_ns = seen_dname = seen_ds = seen_nsec =
- ISC_FALSE;
- for (result = dns_rdatasetiter_first(iterator);
- result == ISC_R_SUCCESS;
- result = dns_rdatasetiter_next(iterator)) {
- dns_rdatasetiter_current(iterator, &rdataset);
- INSIST(rdataset.type != dns_rdatatype_nsec3);
- if (rdataset.type == dns_rdatatype_soa)
- seen_soa = ISC_TRUE;
- else if (rdataset.type == dns_rdatatype_ns)
- seen_ns = ISC_TRUE;
- else if (rdataset.type == dns_rdatatype_dname)
- seen_dname = ISC_TRUE;
- else if (rdataset.type == dns_rdatatype_ds)
- seen_ds = ISC_TRUE;
- else if (rdataset.type == dns_rdatatype_nsec)
- seen_nsec = ISC_TRUE;
- dns_rdataset_disassociate(&rdataset);
- }
- dns_rdatasetiter_destroy(&iterator);
- /*
- * Is there a NSEC chain than needs to be cleaned up?
- */
- if (seen_nsec)
- nsec3chain->seen_nsec = ISC_TRUE;
- if (seen_ns && !seen_soa && !seen_ds)
- unsecure = ISC_TRUE;
- if ((seen_ns && !seen_soa) || seen_dname)
- delegation = ISC_TRUE;
-
- /*
- * Process one node.
- */
- dns_dbiterator_pause(nsec3chain->dbiterator);
- 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",
- 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
- * two signature generated below.
- *
- * If we are only changing the optout flag the cost is half
- * that of the cost of generating a completely new chain.
- */
- signatures -= 4;
-
- /*
- * Go onto next node.
- */
- next_addnode:
- first = ISC_FALSE;
- dns_db_detachnode(db, &node);
- do {
- result = dns_dbiterator_next(nsec3chain->dbiterator);
-
- if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) {
- dns_dbiterator_pause(nsec3chain->dbiterator);
- CHECK(fixup_nsec3param(db, version, nsec3chain,
- ISC_FALSE, privatetype,
- &param_diff));
- LOCK_ZONE(zone);
- ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
- link);
- UNLOCK_ZONE(zone);
- ISC_LIST_APPEND(cleanup, nsec3chain, link);
- goto next_addchain;
- }
- if (result == ISC_R_NOMORE) {
- dns_dbiterator_pause(nsec3chain->dbiterator);
- if (nsec3chain->seen_nsec) {
- 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, privatetype,
- &param_diff));
- LOCK_ZONE(zone);
- ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
- link);
- UNLOCK_ZONE(zone);
- ISC_LIST_APPEND(cleanup, nsec3chain, link);
- goto next_addchain;
- } else if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_nsec3chain:"
- "dns_dbiterator_next -> %s",
- dns_result_totext(result));
- goto failure;
- } else if (delegation) {
- dns_dbiterator_current(nsec3chain->dbiterator,
- &node, nextname);
- dns_db_detachnode(db, &node);
- if (!dns_name_issubdomain(nextname, name))
- break;
- } else
- break;
- } while (1);
- continue;
-
- same_addchain:
- CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
- first = ISC_TRUE;
- continue;
-
- next_addchain:
- dns_dbiterator_pause(nsec3chain->dbiterator);
- nsec3chain = nextnsec3chain;
- first = ISC_TRUE;
- if (nsec3chain != NULL)
- nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
- }
-
- /*
- * Process removals.
- */
- LOCK_ZONE(zone);
- nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
- UNLOCK_ZONE(zone);
- first = ISC_TRUE;
- buildnsecchain = ISC_FALSE;
- while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
- LOCK_ZONE(zone);
- nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
- UNLOCK_ZONE(zone);
-
- if (nsec3chain->db != db)
- goto next_removechain;
-
- if (!NSEC3REMOVE(nsec3chain->nsec3param.flags))
- goto next_removechain;
-
- /*
- * Work out if we need to build a NSEC chain as a consequence
- * of removing this NSEC3 chain.
- */
- if (first && !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",
- 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;
-
- if (!buildnsecchain) {
- /*
- * Delete the NSECPARAM record that matches this chain.
- */
- 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",
- dns_result_totext(result));
- goto failure;
- }
- }
-
- /*
- * Delete the NSEC3 records.
- */
- 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",
- dns_result_totext(result));
- goto failure;
- }
- goto next_removenode;
- }
-
- if (first) {
- dns_fixedname_t ffound;
- dns_name_t *found;
- dns_fixedname_init(&ffound);
- found = dns_fixedname_name(&ffound);
- result = dns_db_find(db, name, version,
- dns_rdatatype_soa,
- DNS_DBFIND_NOWILD, 0, NULL, found,
- NULL, NULL);
- if ((result == DNS_R_DELEGATION ||
- result == DNS_R_DNAME) &&
- !dns_name_equal(name, found)) {
- /*
- * Remember the obscuring name so that
- * we skip all obscured names.
- */
- dns_name_copy(found, name, NULL);
- delegation = ISC_TRUE;
- goto next_removenode;
- }
- }
-
- /*
- * Check to see if this is a bottom of zone node.
- */
- result = dns_db_allrdatasets(db, node, version, 0, &iterator);
- if (result == ISC_R_NOTFOUND) /* Empty node? */
- goto next_removenode;
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- seen_soa = seen_ns = seen_dname = seen_nsec3 = seen_nsec =
- seen_rr = ISC_FALSE;
- 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_soa)
- seen_soa = ISC_TRUE;
- else if (rdataset.type == dns_rdatatype_ns)
- seen_ns = ISC_TRUE;
- else if (rdataset.type == dns_rdatatype_dname)
- seen_dname = ISC_TRUE;
- else if (rdataset.type == dns_rdatatype_nsec)
- seen_nsec = ISC_TRUE;
- else if (rdataset.type == dns_rdatatype_nsec3)
- seen_nsec3 = ISC_TRUE;
- if (rdataset.type != dns_rdatatype_rrsig)
- seen_rr = ISC_TRUE;
- dns_rdataset_disassociate(&rdataset);
- }
- dns_rdatasetiter_destroy(&iterator);
-
- if (!seen_rr || seen_nsec3 || seen_nsec)
- goto next_removenode;
- if ((seen_ns && !seen_soa) || seen_dname)
- delegation = ISC_TRUE;
-
- /*
- * 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;
- dns_db_detachnode(db, &node);
- do {
- result = dns_dbiterator_next(nsec3chain->dbiterator);
- if (result == ISC_R_NOMORE && buildnsecchain) {
- /*
- * The NSEC chain should now be built.
- * We can now remove the NSEC3 chain.
- */
- updatensec = ISC_TRUE;
- goto same_removechain;
- }
- if (result == ISC_R_NOMORE) {
- LOCK_ZONE(zone);
- ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
- link);
- UNLOCK_ZONE(zone);
- ISC_LIST_APPEND(cleanup, nsec3chain, link);
- dns_dbiterator_pause(nsec3chain->dbiterator);
- 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",
- dns_result_totext(result));
- goto failure;
- }
- goto next_removechain;
- } else if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_nsec3chain:"
- "dns_dbiterator_next -> %s",
- dns_result_totext(result));
- goto failure;
- } else if (delegation) {
- dns_dbiterator_current(nsec3chain->dbiterator,
- &node, nextname);
- dns_db_detachnode(db, &node);
- if (!dns_name_issubdomain(nextname, name))
- break;
- } else
- break;
- } while (1);
- continue;
-
- same_removechain:
- CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
- buildnsecchain = ISC_FALSE;
- first = ISC_TRUE;
- continue;
-
- next_removechain:
- dns_dbiterator_pause(nsec3chain->dbiterator);
- nsec3chain = nextnsec3chain;
- first = ISC_TRUE;
- }
-
- /*
- * We may need to update the NSEC/NSEC3 records for the zone apex.
- */
- 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);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
- "dns_db_allrdatasets -> %s",
- dns_result_totext(result));
- goto failure;
- }
- 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);
-
- 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",
- dns_result_totext(result));
- goto failure;
- }
- }
-
- if (rebuild_nsec3) {
- if (nsec3chain != NULL)
- dns_dbiterator_pause(nsec3chain->dbiterator);
-
- 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",
- dns_result_totext(result));
- goto failure;
- }
- }
- }
-
- if (nsec3chain != NULL)
- dns_dbiterator_pause(nsec3chain->dbiterator);
-
- /*
- * Add / update signatures for the NSEC3 records.
- */
- if (nsec3chain != NULL)
- dns_dbiterator_pause(nsec3chain->dbiterator);
- result = update_sigs(&nsec3_diff, db, version, zone_keys,
- nkeys, zone, inception, expire, now,
- check_ksk, keyset_kskonly, &zonediff);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
- "update_sigs -> %s", dns_result_totext(result));
- goto failure;
- }
-
- /*
- * 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, &zonediff);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
- "update_sigs -> %s", dns_result_totext(result));
- goto failure;
- }
-
- if (updatensec) {
- 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:"
- "updatesecure -> %s",
- dns_result_totext(result));
- goto failure;
- }
- }
-
- result = update_sigs(&nsec_diff, db, version, zone_keys,
- nkeys, zone, inception, expire, now,
- check_ksk, keyset_kskonly, &zonediff);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
- "update_sigs -> %s", dns_result_totext(result));
- goto failure;
- }
-
- /*
- * If we made no effective changes to the zone then we can just
- * cleanup otherwise we need to increment the serial.
- */
- if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
- /*
- * No need to call dns_db_closeversion() here as it is
- * called with commit = ISC_TRUE below.
- */
- goto done;
- }
-
- result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
- &zonediff, zone_keys, nkeys, now, ISC_FALSE);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
- "del_sigs -> %s", dns_result_totext(result));
- goto failure;
- }
-
- result = update_soa_serial(db, version, zonediff.diff, zone->mctx,
- zone->updatemethod);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
- "update_soa_serial -> %s",
- dns_result_totext(result));
- goto failure;
- }
-
- result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
- zonediff.diff, zone_keys, nkeys, zone->mctx,
- inception, soaexpire, check_ksk, keyset_kskonly);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
- "add_sigs -> %s", dns_result_totext(result));
- goto failure;
- }
-
- /* Write changes to journal file. */
- CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_nsec3chain"));
-
- LOCK_ZONE(zone);
- zone_needdump(zone, DNS_DUMP_DELAY);
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
- UNLOCK_ZONE(zone);
-
- done:
- /*
- * Pause all iterators so that dns_db_closeversion() can succeed.
- */
- LOCK_ZONE(zone);
- for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
- nsec3chain != NULL;
- nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
- dns_dbiterator_pause(nsec3chain->dbiterator);
- UNLOCK_ZONE(zone);
-
- /*
- * Everything has succeeded. Commit the changes.
- * Unconditionally commit as zonediff.offline not checked above.
- */
- dns_db_closeversion(db, &version, ISC_TRUE);
-
- /*
- * Everything succeeded so we can clean these up now.
- */
- nsec3chain = ISC_LIST_HEAD(cleanup);
- while (nsec3chain != NULL) {
- ISC_LIST_UNLINK(cleanup, nsec3chain, link);
- dns_db_detach(&nsec3chain->db);
- dns_dbiterator_destroy(&nsec3chain->dbiterator);
- isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
- nsec3chain = ISC_LIST_HEAD(cleanup);
- }
-
- set_resigntime(zone);
-
- failure:
- if (result != ISC_R_SUCCESS)
- dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain: %s",
- dns_result_totext(result));
- /*
- * On error roll back the current nsec3chain.
- */
- if (result != ISC_R_SUCCESS && nsec3chain != NULL) {
- if (nsec3chain->done) {
- dns_db_detach(&nsec3chain->db);
- dns_dbiterator_destroy(&nsec3chain->dbiterator);
- isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
- } else {
- result = dns_dbiterator_first(nsec3chain->dbiterator);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- dns_dbiterator_pause(nsec3chain->dbiterator);
- nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
- }
- }
-
- /*
- * Rollback the cleanup list.
- */
- nsec3chain = ISC_LIST_TAIL(cleanup);
- while (nsec3chain != NULL) {
- ISC_LIST_UNLINK(cleanup, nsec3chain, link);
- if (nsec3chain->done) {
- dns_db_detach(&nsec3chain->db);
- dns_dbiterator_destroy(&nsec3chain->dbiterator);
- isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
- } else {
- LOCK_ZONE(zone);
- ISC_LIST_PREPEND(zone->nsec3chain, nsec3chain, link);
- UNLOCK_ZONE(zone);
- result = dns_dbiterator_first(nsec3chain->dbiterator);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- dns_dbiterator_pause(nsec3chain->dbiterator);
- nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
- }
- nsec3chain = ISC_LIST_TAIL(cleanup);
- }
-
- LOCK_ZONE(zone);
- for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
- nsec3chain != NULL;
- nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
- dns_dbiterator_pause(nsec3chain->dbiterator);
- UNLOCK_ZONE(zone);
-
- dns_diff_clear(&param_diff);
- dns_diff_clear(&nsec3_diff);
- dns_diff_clear(&nsec_diff);
- dns_diff_clear(&_sig_diff);
-
- if (iterator != NULL)
- dns_rdatasetiter_destroy(&iterator);
-
- 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);
- } else if (db != NULL)
- dns_db_detach(&db);
-
- LOCK_ZONE(zone);
- if (ISC_LIST_HEAD(zone->nsec3chain) != NULL) {
- isc_interval_t i;
- if (zone->update_disabled || result != ISC_R_SUCCESS)
- isc_interval_set(&i, 60, 0); /* 1 minute */
- else
- isc_interval_set(&i, 0, 10000000); /* 10 ms */
- isc_time_nowplusinterval(&zone->nsec3chaintime, &i);
- } else
- isc_time_settoepoch(&zone->nsec3chaintime);
- UNLOCK_ZONE(zone);
-}
-
-static isc_result_t
-del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
- dns_dbnode_t *node, unsigned int nkeys, dns_secalg_t algorithm,
- isc_uint16_t keyid, dns_diff_t *diff)
-{
- dns_rdata_rrsig_t rrsig;
- dns_rdataset_t rdataset;
- dns_rdatasetiter_t *iterator = NULL;
- isc_result_t result;
-
- result = dns_db_allrdatasets(db, node, version, 0, &iterator);
- if (result != ISC_R_SUCCESS) {
- if (result == ISC_R_NOTFOUND)
- result = ISC_R_SUCCESS;
- return (result);
- }
-
- dns_rdataset_init(&rdataset);
- for (result = dns_rdatasetiter_first(iterator);
- result == ISC_R_SUCCESS;
- result = dns_rdatasetiter_next(iterator)) {
- dns_rdatasetiter_current(iterator, &rdataset);
- if (nkeys == 0 && rdataset.type == dns_rdatatype_nsec) {
- 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(update_one_rr(db, version, diff,
- DNS_DIFFOP_DEL, name,
- rdataset.ttl, &rdata));
- }
- if (result != ISC_R_NOMORE)
- goto failure;
- dns_rdataset_disassociate(&rdataset);
- continue;
- }
- if (rdataset.type != dns_rdatatype_rrsig) {
- dns_rdataset_disassociate(&rdataset);
- continue;
- }
- 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, &rrsig, NULL));
- if (rrsig.algorithm != algorithm ||
- rrsig.keyid != keyid)
- continue;
- CHECK(update_one_rr(db, version, diff,
- DNS_DIFFOP_DELRESIGN, name,
- rdataset.ttl, &rdata));
- }
- dns_rdataset_disassociate(&rdataset);
- if (result != ISC_R_NOMORE)
- break;
- }
- if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
- failure:
- if (dns_rdataset_isassociated(&rdataset))
- dns_rdataset_disassociate(&rdataset);
- dns_rdatasetiter_destroy(&iterator);
- return (result);
-}
-
-/*
- * Incrementally sign the zone using the keys requested.
- * Builds the NSEC chain if required.
- */
-static void
-zone_sign(dns_zone_t *zone) {
- const char *me = "zone_sign";
- 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;
- zonediff_t zonediff;
- dns_fixedname_t fixed;
- dns_fixedname_t nextfixed;
- dns_name_t *name, *nextname;
- dns_rdataset_t rdataset;
- dns_signing_t *signing, *nextsigning;
- dns_signinglist_t cleanup;
- dst_key_t *zone_keys[DNS_MAXZONEKEYS];
- isc_int32_t signatures;
- isc_boolean_t check_ksk, keyset_kskonly, is_ksk;
- isc_boolean_t commit = ISC_FALSE;
- isc_boolean_t delegation;
- 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;
- isc_uint32_t jitter;
- unsigned int i, j;
- unsigned int nkeys = 0;
- isc_uint32_t nodes;
-
- ENTER;
-
- dns_rdataset_init(&rdataset);
- dns_fixedname_init(&fixed);
- name = dns_fixedname_name(&fixed);
- dns_fixedname_init(&nextfixed);
- nextname = dns_fixedname_name(&nextfixed);
- dns_diff_init(zone->mctx, &_sig_diff);
- _sig_diff.resign = zone->sigresigninginterval;
- dns_diff_init(zone->mctx, &post_diff);
- zonediff_init(&zonediff, &_sig_diff);
- ISC_LIST_INIT(cleanup);
-
- /*
- * Updates are disabled. Pause for 5 minutes.
- */
- if (zone->update_disabled) {
- result = ISC_R_FAILURE;
- goto failure;
- }
-
- ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
- dns_db_attach(zone->db, &db);
- ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
-
- result = dns_db_newversion(db, &version);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_sign:dns_db_newversion -> %s",
- dns_result_totext(result));
- goto failure;
- }
-
- result = find_zone_keys(zone, db, version, zone->mctx,
- DNS_MAXZONEKEYS, zone_keys, &nkeys);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_sign:find_zone_keys -> %s",
- dns_result_totext(result));
- goto failure;
- }
-
- isc_stdtime_get(&now);
- inception = now - 3600; /* Allow for clock skew. */
- soaexpire = now + dns_zone_getsigvalidityinterval(zone);
-
- /*
- * Spread out signatures over time if they happen to be
- * clumped. We don't do this for each add_sigs() call as
- * we still want some clustering to occur.
- */
- isc_random_get(&jitter);
- expire = soaexpire - jitter % 3600;
-
- /*
- * We keep pulling nodes off each iterator in turn until
- * we have no more nodes to pull off or we reach the limits
- * for this quantum.
- */
- nodes = zone->nodes;
- signatures = zone->signatures;
- signing = ISC_LIST_HEAD(zone->signing);
- first = ISC_TRUE;
-
- 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;
-
- while (signing != NULL && nodes-- > 0 && signatures > 0) {
- nextsigning = ISC_LIST_NEXT(signing, link);
-
- ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
- if (signing->done || signing->db != zone->db) {
- /*
- * The zone has been reloaded. We will have
- * created new signings as part of the reload
- * process so we can destroy this one.
- */
- ISC_LIST_UNLINK(zone->signing, signing, link);
- ISC_LIST_APPEND(cleanup, signing, link);
- ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
- goto next_signing;
- }
- ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
-
- if (signing->db != db)
- goto next_signing;
-
- delegation = 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) {
- dns_dbiterator_pause(signing->dbiterator);
- CHECK(del_sig(db, version, name, node, nkeys,
- signing->algorithm, signing->keyid,
- zonediff.diff));
- }
-
- /*
- * On the first pass we need to check if the current node
- * has not been obscured.
- */
- if (first) {
- dns_fixedname_t ffound;
- dns_name_t *found;
- dns_fixedname_init(&ffound);
- found = dns_fixedname_name(&ffound);
- result = dns_db_find(db, name, version,
- dns_rdatatype_soa,
- DNS_DBFIND_NOWILD, 0, NULL, found,
- NULL, NULL);
- if ((result == DNS_R_DELEGATION ||
- result == DNS_R_DNAME) &&
- !dns_name_equal(name, found)) {
- /*
- * Remember the obscuring name so that
- * we skip all obscured names.
- */
- dns_name_copy(found, name, NULL);
- delegation = ISC_TRUE;
- goto next_node;
- }
- }
-
- /*
- * Process one node.
- */
- 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;
-
- /*
- * When deleting make sure we are properly signed
- * with the algorithm that was being removed.
- */
- if (signing->delete &&
- ALG(zone_keys[i]) != signing->algorithm)
- continue;
-
- /*
- * Do we do KSK processing?
- */
- 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,
- ISC_TF(both && keyset_kskonly),
- &delegation, zonediff.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.
- */
- next_node:
- first = ISC_FALSE;
- dns_db_detachnode(db, &node);
- do {
- result = dns_dbiterator_next(signing->dbiterator);
- if (result == ISC_R_NOMORE) {
- ISC_LIST_UNLINK(zone->signing, signing, link);
- ISC_LIST_APPEND(cleanup, signing, link);
- dns_dbiterator_pause(signing->dbiterator);
- if (nkeys != 0 && build_nsec) {
- /*
- * We have finished regenerating the
- * zone with a zone signing key.
- * The NSEC chain is now complete and
- * there is a full set of signatures
- * for the zone. We can now clear the
- * OPT bit from the NSEC record.
- */
- result = updatesecure(db, version,
- &zone->origin,
- zone->minimum,
- ISC_FALSE,
- &post_diff);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone,
- ISC_LOG_ERROR,
- "updatesecure -> %s",
- dns_result_totext(result));
- goto failure;
- }
- }
- 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",
- 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,
- "zone_sign:dns_dbiterator_next -> %s",
- dns_result_totext(result));
- goto failure;
- } else if (delegation) {
- dns_dbiterator_current(signing->dbiterator,
- &node, nextname);
- dns_db_detachnode(db, &node);
- if (!dns_name_issubdomain(nextname, name))
- break;
- } else
- break;
- } while (1);
- continue;
-
- next_signing:
- dns_dbiterator_pause(signing->dbiterator);
- signing = nextsigning;
- first = ISC_TRUE;
- }
-
- 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, &zonediff);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:"
- "update_sigs -> %s",
- dns_result_totext(result));
- goto failure;
- }
- }
-
- /*
- * Have we changed anything?
- */
- if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
- if (zonediff.offline)
- commit = ISC_TRUE;
- result = ISC_R_SUCCESS;
- goto pauseall;
- }
-
- commit = ISC_TRUE;
-
- result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
- &zonediff, zone_keys, nkeys, now, ISC_FALSE);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_sign:del_sigs -> %s",
- dns_result_totext(result));
- goto failure;
- }
-
- result = update_soa_serial(db, version, zonediff.diff, zone->mctx,
- zone->updatemethod);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_sign:update_soa_serial -> %s",
- dns_result_totext(result));
- goto failure;
- }
-
- /*
- * Generate maximum life time signatures so that the above loop
- * termination is sensible.
- */
- result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
- zonediff.diff, zone_keys, nkeys, zone->mctx,
- inception, soaexpire, check_ksk, keyset_kskonly);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_sign:add_sigs -> %s",
- dns_result_totext(result));
- goto failure;
- }
-
- /*
- * Write changes to journal file.
- */
- CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_sign"));
-
- pauseall:
- /*
- * Pause all iterators so that dns_db_closeversion() can succeed.
- */
- for (signing = ISC_LIST_HEAD(zone->signing);
- signing != NULL;
- signing = ISC_LIST_NEXT(signing, link))
- dns_dbiterator_pause(signing->dbiterator);
-
- for (signing = ISC_LIST_HEAD(cleanup);
- signing != NULL;
- signing = ISC_LIST_NEXT(signing, link))
- dns_dbiterator_pause(signing->dbiterator);
-
- /*
- * Everything has succeeded. Commit the changes.
- */
- dns_db_closeversion(db, &version, commit);
-
- /*
- * Everything succeeded so we can clean these up now.
- */
- signing = ISC_LIST_HEAD(cleanup);
- while (signing != NULL) {
- ISC_LIST_UNLINK(cleanup, signing, link);
- dns_db_detach(&signing->db);
- dns_dbiterator_destroy(&signing->dbiterator);
- isc_mem_put(zone->mctx, signing, sizeof *signing);
- signing = ISC_LIST_HEAD(cleanup);
- }
-
- set_resigntime(zone);
-
- if (commit) {
- LOCK_ZONE(zone);
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
- zone_needdump(zone, DNS_DUMP_DELAY);
- UNLOCK_ZONE(zone);
- }
-
- failure:
- /*
- * Rollback the cleanup list.
- */
- signing = ISC_LIST_HEAD(cleanup);
- while (signing != NULL) {
- ISC_LIST_UNLINK(cleanup, signing, link);
- ISC_LIST_PREPEND(zone->signing, signing, link);
- dns_dbiterator_first(signing->dbiterator);
- dns_dbiterator_pause(signing->dbiterator);
- signing = ISC_LIST_HEAD(cleanup);
- }
-
- for (signing = ISC_LIST_HEAD(zone->signing);
- signing != NULL;
- signing = ISC_LIST_NEXT(signing, link))
- dns_dbiterator_pause(signing->dbiterator);
-
- dns_diff_clear(&_sig_diff);
-
- 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);
- } else if (db != NULL)
- dns_db_detach(&db);
-
- if (ISC_LIST_HEAD(zone->signing) != NULL) {
- isc_interval_t i;
- if (zone->update_disabled || result != ISC_R_SUCCESS)
- isc_interval_set(&i, 60, 0); /* 1 minute */
- else
- isc_interval_set(&i, 0, 10000000); /* 10 ms */
- isc_time_nowplusinterval(&zone->signingtime, &i);
- } else
- isc_time_settoepoch(&zone->signingtime);
-}
-
-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;
- isc_result_t result;
-
- dns_rdata_reset(target);
- isc_buffer_init(&buf, data, size);
-
- switch (rr->type) {
- case dns_rdatatype_dnskey:
- result = dns_rdata_tostruct(rr, &dnskey, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- dnskey.flags &= ~DNS_KEYFLAG_REVOKE;
- dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
- &dnskey, &buf);
- break;
- case dns_rdatatype_keydata:
- result = dns_rdata_tostruct(rr, &keydata, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- 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);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
-
- 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 ||
- dst_key_rid(dstkey) == sig.keyid)) {
- 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 alldone = ISC_FALSE;
- isc_boolean_t commit = 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;
- isc_boolean_t free_needed;
-
- 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);
-
- LOCK_ZONE(zone);
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || zone->view == NULL)
- goto cleanup;
-
- isc_stdtime_get(&now);
- dns_name_format(keyname, namebuf, sizeof(namebuf));
-
- result = dns_view_getsecroots(zone->view, &secroots);
- INSIST(result == ISC_R_SUCCESS);
-
- dns_diff_init(mctx, &diff);
- diff.resign = zone->sigresigninginterval;
-
- CHECK(dns_db_newversion(kfetch->db, &ver));
-
- 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));
- goto done;
- }
-
- /* 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));
- goto done;
- }
-
- /*
- * 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);
- result = dns_rdata_tostruct(&keydatarr, &keydata, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
-
- /*
- * 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));
- }
-
- 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));
-
- 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);
- result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
-
- /* 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);
- result = dns_rdata_tostruct(&keydatarr, &keydata, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
-
- 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 */
- dns_view_untrust(zone->view, keyname,
- &dnskey, mctx);
-
- /* 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));
-
- 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));
- } else if (newkey) {
- /* Convert DNSKEY to KEYDATA */
- result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- 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));
- }
-
- if (trustkey) {
- /* Trust this key. */
- result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- trust_key(zone, 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, keyname);
-
- done:
-
- if (!ISC_LIST_EMPTY(diff.tuples)) {
- /* Write changes to journal file. */
- CHECK(update_soa_serial(kfetch->db, ver, &diff, mctx,
- zone->updatemethod));
- CHECK(zone_journal(zone, &diff, NULL, "keyfetch_done"));
- commit = ISC_TRUE;
-
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
- zone_needdump(zone, 30);
- }
-
- failure:
-
- dns_diff_clear(&diff);
- if (ver != NULL)
- dns_db_closeversion(kfetch->db, &ver, commit);
-
- cleanup:
- dns_db_detach(&kfetch->db);
-
- INSIST(zone->irefs > 0);
- zone->irefs--;
- kfetch->zone = NULL;
-
- 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);
-
- free_needed = exit_check(zone);
- UNLOCK_ZONE(zone);
- if (free_needed)
- zone_free(zone);
-}
-
-/*
- * 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;
- isc_boolean_t fetching = ISC_FALSE, fetch_err = ISC_FALSE;
-
- ENTER;
- REQUIRE(zone->db != NULL);
-
- isc_stdtime_get(&now);
-
- LOCK_ZONE(zone);
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
- isc_time_settoepoch(&zone->refreshkeytime);
- UNLOCK_ZONE(zone);
- return;
- }
-
- ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
- dns_db_attach(zone->db, &db);
- ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
-
- dns_diff_init(zone->mctx, &diff);
-
- CHECK(dns_db_newversion(db, &ver));
-
- 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_name_t *name = NULL, *kname = NULL;
- dns_rdataset_t *kdset = NULL;
- dns_keyfetch_t *kfetch;
- isc_uint32_t ttl;
-
- dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL);
- if (kdset == NULL || kdset->type != dns_rdatatype_keydata ||
- !dns_rdataset_isassociated(kdset))
- 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;
-
- kfetch = isc_mem_get(zone->mctx, sizeof(dns_keyfetch_t));
- if (kfetch == NULL) {
- fetch_err = ISC_TRUE;
- goto failure;
- }
-
- zone->refreshkeycount++;
- kfetch->zone = zone;
- zone->irefs++;
- INSIST(zone->irefs != 0);
- dns_fixedname_init(&kfetch->name);
- kname = dns_fixedname_name(&kfetch->name);
- dns_name_dup(name, zone->mctx, kname);
- 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;
-
- result = dns_resolver_createfetch(zone->view->resolver,
- kname, dns_rdatatype_dnskey,
- NULL, NULL, NULL,
- DNS_FETCHOPT_NOVALIDATE,
- zone->task,
- keyfetch_done, kfetch,
- &kfetch->dnskeyset,
- &kfetch->dnskeysigset,
- &kfetch->fetch);
- if (result == ISC_R_SUCCESS)
- fetching = ISC_TRUE;
- else {
- zone->refreshkeycount--;
- zone->irefs--;
- dns_db_detach(&kfetch->db);
- dns_rdataset_disassociate(&kfetch->keydataset);
- dns_name_free(kname, zone->mctx);
- isc_mem_put(zone->mctx, kfetch, sizeof(dns_keyfetch_t));
- dns_zone_log(zone, ISC_LOG_WARNING,
- "Failed to create fetch for "
- "DNSKEY update");
- fetch_err = ISC_TRUE;
- }
- }
- if (!ISC_LIST_EMPTY(diff.tuples)) {
- CHECK(update_soa_serial(db, ver, &diff, zone->mctx,
- zone->updatemethod));
- CHECK(zone_journal(zone, &diff, NULL, "zone_refreshkeys"));
- commit = ISC_TRUE;
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
- zone_needdump(zone, 30);
- }
-
- failure:
- if (fetch_err) {
- /*
- * Error during a key fetch; retry in an hour.
- */
- isc_time_t timenow, timethen;
- char timebuf[80];
-
- TIME_NOW(&timenow);
- DNS_ZONE_TIME_ADD(&timenow, HOUR, &timethen);
- zone->refreshkeytime = timethen;
- zone_settimer(zone, &timenow);
-
- isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
- dns_zone_log(zone, ISC_LOG_DEBUG(1), "retry key refresh: %s",
- timebuf);
-
- if (!fetching)
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
- }
-
- UNLOCK_ZONE(zone);
-
- dns_diff_clear(&diff);
- if (ver != NULL) {
- dns_rriterator_destroy(&rrit);
- 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;
- isc_result_t result;
- isc_boolean_t dumping;
-
- REQUIRE(DNS_ZONE_VALID(zone));
- ENTER;
-
- /*
- * Are we pending load/reload?
- */
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING))
- return;
-
- /*
- * Configuring the view of this zone may have
- * failed, for example because the config file
- * had a syntax error. In that case, the view
- * adb or resolver will be NULL, and we had better not try
- * to do further maintenance on it.
- */
- if (zone->view == NULL || zone->view->adb == NULL)
- return;
-
- TIME_NOW(&now);
-
- /*
- * Expire check.
- */
- switch (zone->type) {
- case dns_zone_redirect:
- if (zone->masters == NULL)
- break;
- case dns_zone_slave:
- case dns_zone_stub:
- LOCK_ZONE(zone);
- if (isc_time_compare(&now, &zone->expiretime) >= 0 &&
- DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
- zone_expire(zone);
- zone->refreshtime = now;
- }
- UNLOCK_ZONE(zone);
- break;
- default:
- break;
- }
-
- /*
- * Up to date check.
- */
- switch (zone->type) {
- case dns_zone_redirect:
- if (zone->masters == NULL)
- break;
- case dns_zone_slave:
- case dns_zone_stub:
- if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) &&
- isc_time_compare(&now, &zone->refreshtime) >= 0)
- dns_zone_refresh(zone);
- break;
- default:
- break;
- }
-
- /*
- * Slaves send notifies before backing up to disk, masters after.
- */
- if (zone->type == dns_zone_slave &&
- DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) &&
- isc_time_compare(&now, &zone->notifytime) >= 0)
- zone_notify(zone, &now);
-
- /*
- * Do we need to consolidate the backing store?
- */
- switch (zone->type) {
- case dns_zone_master:
- case dns_zone_slave:
- case dns_zone_key:
- case dns_zone_redirect:
- case dns_zone_stub:
- LOCK_ZONE(zone);
- if (zone->masterfile != NULL &&
- isc_time_compare(&now, &zone->dumptime) >= 0 &&
- DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
- DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) {
- dumping = was_dumping(zone);
- } else
- dumping = ISC_TRUE;
- UNLOCK_ZONE(zone);
- if (!dumping) {
- result = zone_dump(zone, ISC_TRUE); /* task locked */
- if (result != ISC_R_SUCCESS)
- dns_zone_log(zone, ISC_LOG_WARNING,
- "dump failed: %s",
- dns_result_totext(result));
- }
- break;
- default:
- break;
- }
-
- /*
- * Master/redirect zones send notifies now, if needed
- */
- switch (zone->type) {
- case dns_zone_master:
- case dns_zone_redirect:
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) &&
- isc_time_compare(&now, &zone->notifytime) >= 0)
- zone_notify(zone, &now);
- default:
- break;
- }
-
- /*
- * Do we need to refresh keys?
- */
- switch (zone->type) {
- case dns_zone_key:
- if (isc_time_compare(&now, &zone->refreshkeytime) >= 0) {
- if (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_redirect:
- case dns_zone_slave:
- /*
- * Do we need to sign/resign some RRsets?
- */
- if (!isc_time_isepoch(&zone->signingtime) &&
- isc_time_compare(&now, &zone->signingtime) >= 0)
- zone_sign(zone);
- else if (!isc_time_isepoch(&zone->resigntime) &&
- isc_time_compare(&now, &zone->resigntime) >= 0)
- zone_resigninc(zone);
- else if (!isc_time_isepoch(&zone->nsec3chaintime) &&
- isc_time_compare(&now, &zone->nsec3chaintime) >= 0)
- zone_nsec3chain(zone);
- /*
- * Do we need to issue a key expiry warning?
- */
- if (!isc_time_isepoch(&zone->keywarntime) &&
- isc_time_compare(&now, &zone->keywarntime) >= 0)
- set_key_expiry_warning(zone, zone->key_expiry,
- isc_time_seconds(&now));
- break;
-
- default:
- break;
- }
- zone_settimer(zone, &now);
-}
-
-void
-dns_zone_markdirty(dns_zone_t *zone) {
- isc_uint32_t serial;
- isc_result_t result = ISC_R_SUCCESS;
-
- LOCK_ZONE(zone);
- if (zone->type == dns_zone_master) {
- if (inline_raw(zone)) {
- unsigned int soacount;
-
- ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
- if (zone->db != NULL) {
- result = zone_get_from_db(zone, zone->db, NULL,
- &soacount, &serial,
- NULL, NULL, NULL,
- NULL, NULL);
- } else
- result = DNS_R_NOTLOADED;
- ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
- if (result == ISC_R_SUCCESS && soacount > 0U)
- zone_send_secureserial(zone, ISC_FALSE, serial);
- }
-
- /* XXXMPA make separate call back */
- if (result == ISC_R_SUCCESS)
- set_resigntime(zone);
- }
- zone_needdump(zone, DNS_DUMP_DELAY);
- UNLOCK_ZONE(zone);
-}
-
-void
-dns_zone_expire(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- zone_expire(zone);
- UNLOCK_ZONE(zone);
-}
-
-static void
-zone_expire(dns_zone_t *zone) {
- /*
- * 'zone' locked by caller.
- */
-
- REQUIRE(LOCKED_ZONE(zone));
-
- dns_zone_log(zone, ISC_LOG_WARNING, "expired");
-
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED);
- zone->refresh = DNS_ZONE_DEFAULTREFRESH;
- zone->retry = DNS_ZONE_DEFAULTRETRY;
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
- zone_unload(zone);
-}
-
-void
-dns_zone_refresh(dns_zone_t *zone) {
- isc_interval_t i;
- isc_uint32_t oldflags;
- unsigned int j;
- isc_result_t result;
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
- return;
-
- /*
- * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation
- * in progress at a time.
- */
-
- LOCK_ZONE(zone);
- oldflags = zone->flags;
- if (zone->masterscnt == 0) {
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOMASTERS);
- if ((oldflags & DNS_ZONEFLG_NOMASTERS) == 0)
- dns_zone_log(zone, ISC_LOG_ERROR,
- "cannot refresh: no masters");
- goto unlock;
- }
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
- if ((oldflags & (DNS_ZONEFLG_REFRESH|DNS_ZONEFLG_LOADING)) != 0)
- goto unlock;
-
- /*
- * Set the next refresh time as if refresh check has failed.
- * Setting this to the retry time will do that. XXXMLG
- * If we are successful it will be reset using zone->refresh.
- */
- isc_interval_set(&i, isc_random_jitter(zone->retry, zone->retry / 4),
- 0);
- result = isc_time_nowplusinterval(&zone->refreshtime, &i);
- if (result != ISC_R_SUCCESS)
- dns_zone_log(zone, ISC_LOG_WARNING,
- "isc_time_nowplusinterval() failed: %s",
- dns_result_totext(result));
-
- /*
- * When lacking user-specified timer values from the SOA,
- * do exponential backoff of the retry time up to a
- * maximum of six hours.
- */
- if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS))
- zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600);
-
- zone->curmaster = 0;
- for (j = 0; j < zone->masterscnt; j++)
- zone->mastersok[j] = ISC_FALSE;
- /* initiate soa query */
- queue_soa_query(zone);
- unlock:
- UNLOCK_ZONE(zone);
-}
-
-isc_result_t
-dns_zone_flush(dns_zone_t *zone) {
- isc_result_t result = ISC_R_SUCCESS;
- isc_boolean_t dumping;
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH);
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
- zone->masterfile != NULL) {
- result = ISC_R_ALREADYRUNNING;
- dumping = was_dumping(zone);
- } else
- dumping = ISC_TRUE;
- UNLOCK_ZONE(zone);
- if (!dumping)
- result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
- return (result);
-}
-
-isc_result_t
-dns_zone_dump(dns_zone_t *zone) {
- isc_result_t result = ISC_R_ALREADYRUNNING;
- isc_boolean_t dumping;
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- dumping = was_dumping(zone);
- UNLOCK_ZONE(zone);
- if (!dumping)
- result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
- return (result);
-}
-
-static void
-zone_needdump(dns_zone_t *zone, unsigned int delay) {
- const char me[] = "zone_needdump";
- isc_time_t dumptime;
- isc_time_t now;
-
- /*
- * 'zone' locked by caller
- */
-
- REQUIRE(DNS_ZONE_VALID(zone));
- REQUIRE(LOCKED_ZONE(zone));
- ENTER;
-
- /*
- * Do we have a place to dump to and are we loaded?
- */
- if (zone->masterfile == NULL ||
- DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
- return;
-
- TIME_NOW(&now);
- /* add some noise */
- DNS_ZONE_JITTER_ADD(&now, delay, &dumptime);
-
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
- if (isc_time_isepoch(&zone->dumptime) ||
- isc_time_compare(&zone->dumptime, &dumptime) > 0)
- zone->dumptime = dumptime;
- if (zone->task != NULL)
- zone_settimer(zone, &now);
-}
-
-static void
-dump_done(void *arg, isc_result_t result) {
- const char me[] = "dump_done";
- dns_zone_t *zone = arg;
- dns_db_t *db;
- dns_dbversion_t *version;
- isc_boolean_t again = ISC_FALSE;
- isc_boolean_t compact = ISC_FALSE;
- isc_uint32_t serial;
- isc_result_t tresult;
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- ENTER;
-
- if (result == ISC_R_SUCCESS && zone->journal != NULL &&
- zone->journalsize != -1) {
-
- /*
- * We don't own these, zone->dctx must stay valid.
- */
- db = dns_dumpctx_db(zone->dctx);
- version = dns_dumpctx_version(zone->dctx);
-
- tresult = dns_db_getsoaserial(db, version, &serial);
- /*
- * If there is a secure version of this zone
- * use its serial if it is less than ours.
- */
- if (tresult == ISC_R_SUCCESS && inline_raw(zone) &&
- zone->secure->db != NULL)
- {
- isc_uint32_t sserial;
- isc_result_t mresult;
-
- mresult = dns_db_getsoaserial(zone->secure->db,
- NULL, &sserial);
- if (mresult == ISC_R_SUCCESS &&
- isc_serial_lt(sserial, serial))
- serial = sserial;
- }
- /*
- * Note: we are task locked here so we can test
- * zone->xfr safely.
- */
- if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) {
- tresult = dns_journal_compact(zone->mctx,
- zone->journal,
- serial,
- zone->journalsize);
- switch (tresult) {
- case ISC_R_SUCCESS:
- case ISC_R_NOSPACE:
- case ISC_R_NOTFOUND:
- dns_zone_log(zone, ISC_LOG_DEBUG(3),
- "dns_journal_compact: %s",
- dns_result_totext(tresult));
- break;
- default:
- dns_zone_log(zone, ISC_LOG_ERROR,
- "dns_journal_compact failed: %s",
- dns_result_totext(tresult));
- break;
- }
- } else if (tresult == ISC_R_SUCCESS) {
- compact = ISC_TRUE;
- zone->compact_serial = serial;
- }
- }
-
- LOCK_ZONE(zone);
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
- if (compact)
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
- if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) {
- /*
- * Try again in a short while.
- */
- zone_needdump(zone, DNS_DUMP_DELAY);
- } else if (result == ISC_R_SUCCESS &&
- DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
- DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
- DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
- isc_time_settoepoch(&zone->dumptime);
- again = ISC_TRUE;
- } else if (result == ISC_R_SUCCESS)
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
-
- if (zone->dctx != NULL)
- dns_dumpctx_detach(&zone->dctx);
- zonemgr_putio(&zone->writeio);
- UNLOCK_ZONE(zone);
- if (again)
- (void)zone_dump(zone, ISC_FALSE);
- dns_zone_idetach(&zone);
-}
-
-static isc_result_t
-zone_dump(dns_zone_t *zone, isc_boolean_t compact) {
- const char me[] = "zone_dump";
- isc_result_t result;
- dns_dbversion_t *version = NULL;
- isc_boolean_t again;
- dns_db_t *db = NULL;
- char *masterfile = NULL;
- dns_masterformat_t masterformat = dns_masterformat_none;
-
-/*
- * 'compact' MUST only be set if we are task locked.
- */
-
- REQUIRE(DNS_ZONE_VALID(zone));
- ENTER;
-
- redo:
- ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
- if (zone->db != NULL)
- dns_db_attach(zone->db, &db);
- ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
- LOCK_ZONE(zone);
- if (zone->masterfile != NULL) {
- masterfile = isc_mem_strdup(zone->mctx, zone->masterfile);
- masterformat = zone->masterformat;
- }
- UNLOCK_ZONE(zone);
- if (db == NULL) {
- result = DNS_R_NOTLOADED;
- goto fail;
- }
- if (masterfile == NULL) {
- result = DNS_R_NOMASTERFILE;
- goto fail;
- }
-
- if (compact && zone->type != dns_zone_stub) {
- dns_zone_t *dummy = NULL;
- LOCK_ZONE(zone);
- zone_iattach(zone, &dummy);
- result = zonemgr_getio(zone->zmgr, ISC_FALSE, zone->task,
- zone_gotwritehandle, zone,
- &zone->writeio);
- if (result != ISC_R_SUCCESS)
- zone_idetach(&dummy);
- else
- result = DNS_R_CONTINUE;
- UNLOCK_ZONE(zone);
- } else {
- dns_masterrawheader_t rawdata;
- dns_db_currentversion(db, &version);
- dns_master_initrawheader(&rawdata);
- if (inline_secure(zone))
- get_raw_serial(zone->raw, &rawdata);
- result = dns_master_dump3(zone->mctx, db, version,
- &dns_master_style_default,
- masterfile, masterformat,
- &rawdata);
- dns_db_closeversion(db, &version, ISC_FALSE);
- }
- fail:
- if (db != NULL)
- dns_db_detach(&db);
- if (masterfile != NULL)
- isc_mem_free(zone->mctx, masterfile);
- masterfile = NULL;
-
- if (result == DNS_R_CONTINUE)
- return (ISC_R_SUCCESS); /* XXXMPA */
-
- again = ISC_FALSE;
- LOCK_ZONE(zone);
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
- if (result != ISC_R_SUCCESS) {
- /*
- * Try again in a short while.
- */
- zone_needdump(zone, DNS_DUMP_DELAY);
- } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
- DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
- DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
- isc_time_settoepoch(&zone->dumptime);
- again = ISC_TRUE;
- } else
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
- UNLOCK_ZONE(zone);
- if (again)
- goto redo;
-
- return (result);
-}
-
-static isc_result_t
-dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style,
- dns_masterformat_t format, const isc_uint32_t rawversion)
-{
- isc_result_t result;
- dns_dbversion_t *version = NULL;
- dns_db_t *db = NULL;
- dns_masterrawheader_t rawdata;
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
- if (zone->db != NULL)
- dns_db_attach(zone->db, &db);
- ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
- if (db == NULL)
- return (DNS_R_NOTLOADED);
-
- dns_db_currentversion(db, &version);
- dns_master_initrawheader(&rawdata);
- if (rawversion == 0)
- rawdata.flags |= DNS_MASTERRAW_COMPAT;
- else if (inline_secure(zone))
- get_raw_serial(zone->raw, &rawdata);
- else if (zone->sourceserialset) {
- rawdata.flags = DNS_MASTERRAW_SOURCESERIALSET;
- rawdata.sourceserial = zone->sourceserial;
- }
- result = dns_master_dumptostream3(zone->mctx, db, version, style,
- format, &rawdata, fd);
- dns_db_closeversion(db, &version, ISC_FALSE);
- dns_db_detach(&db);
- return (result);
-}
-
-isc_result_t
-dns_zone_dumptostream3(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
- const dns_master_style_t *style,
- const isc_uint32_t rawversion)
-{
- return (dumptostream(zone, fd, style, format, rawversion));
-}
-
-isc_result_t
-dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
- const dns_master_style_t *style) {
- return (dumptostream(zone, fd, style, format, DNS_RAWFORMAT_VERSION));
-}
-
-isc_result_t
-dns_zone_dumptostream(dns_zone_t *zone, FILE *fd) {
- return (dumptostream(zone, fd, &dns_master_style_default,
- dns_masterformat_text, 0));
-}
-
-isc_result_t
-dns_zone_fulldumptostream(dns_zone_t *zone, FILE *fd) {
- return (dumptostream(zone, fd, &dns_master_style_full,
- dns_masterformat_text, 0));
-}
-
-void
-dns_zone_unload(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- zone_unload(zone);
- UNLOCK_ZONE(zone);
-}
-
-static void
-notify_cancel(dns_zone_t *zone) {
- dns_notify_t *notify;
-
- /*
- * 'zone' locked by caller.
- */
-
- REQUIRE(LOCKED_ZONE(zone));
-
- for (notify = ISC_LIST_HEAD(zone->notifies);
- notify != NULL;
- notify = ISC_LIST_NEXT(notify, link)) {
- if (notify->find != NULL)
- dns_adb_cancelfind(notify->find);
- if (notify->request != NULL)
- dns_request_cancel(notify->request);
- }
-}
-
-static void
-forward_cancel(dns_zone_t *zone) {
- dns_forward_t *forward;
-
- /*
- * 'zone' locked by caller.
- */
-
- REQUIRE(LOCKED_ZONE(zone));
-
- for (forward = ISC_LIST_HEAD(zone->forwards);
- forward != NULL;
- forward = ISC_LIST_NEXT(forward, link)) {
- if (forward->request != NULL)
- dns_request_cancel(forward->request);
- }
-}
-
-static void
-zone_unload(dns_zone_t *zone) {
-
- /*
- * 'zone' locked by caller.
- */
-
- REQUIRE(LOCKED_ZONE(zone));
-
- if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
- !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
- if (zone->writeio != NULL)
- zonemgr_cancelio(zone->writeio);
-
- if (zone->dctx != NULL)
- dns_dumpctx_cancel(zone->dctx);
- }
- ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
- zone_detachdb(zone);
- ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED);
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
-}
-
-void
-dns_zone_setminrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
- REQUIRE(DNS_ZONE_VALID(zone));
- REQUIRE(val > 0);
-
- zone->minrefresh = val;
-}
-
-void
-dns_zone_setmaxrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
- REQUIRE(DNS_ZONE_VALID(zone));
- REQUIRE(val > 0);
-
- zone->maxrefresh = val;
-}
-
-void
-dns_zone_setminretrytime(dns_zone_t *zone, isc_uint32_t val) {
- REQUIRE(DNS_ZONE_VALID(zone));
- REQUIRE(val > 0);
-
- zone->minretry = val;
-}
-
-void
-dns_zone_setmaxretrytime(dns_zone_t *zone, isc_uint32_t val) {
- REQUIRE(DNS_ZONE_VALID(zone));
- REQUIRE(val > 0);
-
- zone->maxretry = val;
-}
-
-static isc_boolean_t
-notify_isqueued(dns_zone_t *zone, dns_name_t *name, isc_sockaddr_t *addr) {
- dns_notify_t *notify;
-
- for (notify = ISC_LIST_HEAD(zone->notifies);
- notify != NULL;
- notify = ISC_LIST_NEXT(notify, link)) {
- if (notify->request != NULL)
- continue;
- if (name != NULL && dns_name_dynamic(&notify->ns) &&
- dns_name_equal(name, &notify->ns))
- return (ISC_TRUE);
- if (addr != NULL && isc_sockaddr_equal(addr, &notify->dst))
- return (ISC_TRUE);
- }
- return (ISC_FALSE);
-}
-
-static isc_boolean_t
-notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) {
- dns_tsigkey_t *key = NULL;
- isc_sockaddr_t src;
- isc_sockaddr_t any;
- isc_boolean_t isself;
- isc_netaddr_t dstaddr;
- isc_result_t result;
-
- if (zone->view == NULL || zone->isself == NULL)
- return (ISC_FALSE);
-
- switch (isc_sockaddr_pf(dst)) {
- case PF_INET:
- src = zone->notifysrc4;
- isc_sockaddr_any(&any);
- break;
- case PF_INET6:
- src = zone->notifysrc6;
- isc_sockaddr_any6(&any);
- break;
- default:
- return (ISC_FALSE);
- }
-
- /*
- * When sending from any the kernel will assign a source address
- * that matches the destination address.
- */
- if (isc_sockaddr_eqaddr(&any, &src))
- src = *dst;
-
- isc_netaddr_fromsockaddr(&dstaddr, dst);
- result = dns_view_getpeertsig(zone->view, &dstaddr, &key);
- if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
- return (ISC_FALSE);
- isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass,
- zone->isselfarg);
- if (key != NULL)
- dns_tsigkey_detach(&key);
- return (isself);
-}
-
-static void
-notify_destroy(dns_notify_t *notify, isc_boolean_t locked) {
- isc_mem_t *mctx;
-
- /*
- * Caller holds zone lock.
- */
- REQUIRE(DNS_NOTIFY_VALID(notify));
-
- if (notify->zone != NULL) {
- if (!locked)
- LOCK_ZONE(notify->zone);
- REQUIRE(LOCKED_ZONE(notify->zone));
- if (ISC_LINK_LINKED(notify, link))
- ISC_LIST_UNLINK(notify->zone->notifies, notify, link);
- if (!locked)
- UNLOCK_ZONE(notify->zone);
- if (locked)
- zone_idetach(&notify->zone);
- else
- dns_zone_idetach(&notify->zone);
- }
- if (notify->find != NULL)
- dns_adb_destroyfind(&notify->find);
- if (notify->request != NULL)
- dns_request_destroy(&notify->request);
- if (dns_name_dynamic(&notify->ns))
- dns_name_free(&notify->ns, notify->mctx);
- if (notify->key != NULL)
- dns_tsigkey_detach(&notify->key);
- mctx = notify->mctx;
- isc_mem_put(notify->mctx, notify, sizeof(*notify));
- isc_mem_detach(&mctx);
-}
-
-static isc_result_t
-notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) {
- dns_notify_t *notify;
-
- REQUIRE(notifyp != NULL && *notifyp == NULL);
-
- notify = isc_mem_get(mctx, sizeof(*notify));
- if (notify == NULL)
- return (ISC_R_NOMEMORY);
-
- notify->mctx = NULL;
- isc_mem_attach(mctx, &notify->mctx);
- notify->flags = flags;
- notify->zone = NULL;
- notify->find = NULL;
- notify->request = NULL;
- notify->key = NULL;
- isc_sockaddr_any(&notify->dst);
- dns_name_init(&notify->ns, NULL);
- ISC_LINK_INIT(notify, link);
- notify->magic = NOTIFY_MAGIC;
- *notifyp = notify;
- return (ISC_R_SUCCESS);
-}
-
-/*
- * XXXAG should check for DNS_ZONEFLG_EXITING
- */
-static void
-process_adb_event(isc_task_t *task, isc_event_t *ev) {
- dns_notify_t *notify;
- isc_eventtype_t result;
-
- UNUSED(task);
-
- notify = ev->ev_arg;
- REQUIRE(DNS_NOTIFY_VALID(notify));
- INSIST(task == notify->zone->task);
- result = ev->ev_type;
- isc_event_free(&ev);
- if (result == DNS_EVENT_ADBMOREADDRESSES) {
- dns_adb_destroyfind(&notify->find);
- notify_find_address(notify);
- return;
- }
- if (result == DNS_EVENT_ADBNOMOREADDRESSES) {
- LOCK_ZONE(notify->zone);
- notify_send(notify);
- UNLOCK_ZONE(notify->zone);
- }
- notify_destroy(notify, ISC_FALSE);
-}
-
-static void
-notify_find_address(dns_notify_t *notify) {
- isc_result_t result;
- unsigned int options;
-
- REQUIRE(DNS_NOTIFY_VALID(notify));
- options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET |
- DNS_ADBFIND_INET6 | DNS_ADBFIND_RETURNLAME;
-
- if (notify->zone->view->adb == NULL)
- goto destroy;
-
- result = dns_adb_createfind(notify->zone->view->adb,
- notify->zone->task,
- process_adb_event, notify,
- &notify->ns, dns_rootname, 0,
- options, 0, NULL,
- notify->zone->view->dstport,
- &notify->find);
-
- /* Something failed? */
- if (result != ISC_R_SUCCESS)
- goto destroy;
-
- /* More addresses pending? */
- if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0)
- return;
-
- /* We have as many addresses as we can get. */
- LOCK_ZONE(notify->zone);
- notify_send(notify);
- UNLOCK_ZONE(notify->zone);
-
- destroy:
- notify_destroy(notify, ISC_FALSE);
-}
-
-
-static isc_result_t
-notify_send_queue(dns_notify_t *notify) {
- isc_event_t *e;
- isc_result_t result;
-
- e = isc_event_allocate(notify->mctx, NULL,
- DNS_EVENT_NOTIFYSENDTOADDR,
- notify_send_toaddr,
- notify, sizeof(isc_event_t));
- if (e == NULL)
- return (ISC_R_NOMEMORY);
- e->ev_arg = notify;
- e->ev_sender = NULL;
- result = isc_ratelimiter_enqueue(notify->zone->zmgr->rl,
- notify->zone->task, &e);
- if (result != ISC_R_SUCCESS)
- isc_event_free(&e);
- return (result);
-}
-
-static void
-notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
- dns_notify_t *notify;
- isc_result_t result;
- dns_message_t *message = NULL;
- isc_netaddr_t dstip;
- dns_tsigkey_t *key = NULL;
- char addrbuf[ISC_SOCKADDR_FORMATSIZE];
- isc_sockaddr_t src;
- int timeout;
- isc_boolean_t have_notifysource = ISC_FALSE;
-
- notify = event->ev_arg;
- REQUIRE(DNS_NOTIFY_VALID(notify));
-
- UNUSED(task);
-
- LOCK_ZONE(notify->zone);
-
- if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) {
- result = ISC_R_CANCELED;
- goto cleanup;
- }
-
- if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 ||
- DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) ||
- notify->zone->view->requestmgr == NULL ||
- notify->zone->db == NULL) {
- result = ISC_R_CANCELED;
- goto cleanup;
- }
-
- /*
- * The raw IPv4 address should also exist. Don't send to the
- * mapped form.
- */
- if (isc_sockaddr_pf(&notify->dst) == PF_INET6 &&
- IN6_IS_ADDR_V4MAPPED(&notify->dst.type.sin6.sin6_addr)) {
- isc_sockaddr_format(&notify->dst, addrbuf, sizeof(addrbuf));
- notify_log(notify->zone, ISC_LOG_DEBUG(3),
- "notify: ignoring IPv6 mapped IPV4 address: %s",
- addrbuf);
- result = ISC_R_CANCELED;
- goto cleanup;
- }
-
- result = notify_createmessage(notify->zone, notify->flags, &message);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- if (notify->key != NULL) {
- /* Transfer ownership of key */
- key = notify->key;
- notify->key = NULL;
- } else {
- isc_netaddr_fromsockaddr(&dstip, &notify->dst);
- isc_sockaddr_format(&notify->dst, addrbuf, sizeof(addrbuf));
- result = dns_view_getpeertsig(notify->zone->view, &dstip, &key);
- if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
- notify_log(notify->zone, ISC_LOG_ERROR,
- "NOTIFY to %s not sent. "
- "Peer TSIG key lookup failure.", addrbuf);
- goto cleanup_message;
- }
- }
-
- /* XXX: should we log the tsig key too? */
- notify_log(notify->zone, ISC_LOG_DEBUG(3), "sending notify to %s",
- addrbuf);
- if (notify->zone->view->peers != NULL) {
- dns_peer_t *peer = NULL;
- result = dns_peerlist_peerbyaddr(notify->zone->view->peers,
- &dstip, &peer);
- if (result == ISC_R_SUCCESS) {
- result = dns_peer_getnotifysource(peer, &src);
- if (result == ISC_R_SUCCESS)
- have_notifysource = ISC_TRUE;
- }
- }
- switch (isc_sockaddr_pf(&notify->dst)) {
- case PF_INET:
- if (!have_notifysource)
- src = notify->zone->notifysrc4;
- break;
- case PF_INET6:
- if (!have_notifysource)
- src = notify->zone->notifysrc6;
- break;
- default:
- result = ISC_R_NOTIMPLEMENTED;
- goto cleanup_key;
- }
- timeout = 15;
- if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY))
- timeout = 30;
- result = dns_request_createvia2(notify->zone->view->requestmgr,
- message, &src, &notify->dst, 0, key,
- timeout * 3, timeout,
- notify->zone->task, notify_done,
- notify, &notify->request);
- if (result == ISC_R_SUCCESS) {
- if (isc_sockaddr_pf(&notify->dst) == AF_INET) {
- inc_stats(notify->zone,
- dns_zonestatscounter_notifyoutv4);
- } else {
- inc_stats(notify->zone,
- dns_zonestatscounter_notifyoutv6);
- }
- }
-
- cleanup_key:
- if (key != NULL)
- dns_tsigkey_detach(&key);
- cleanup_message:
- dns_message_destroy(&message);
- cleanup:
- UNLOCK_ZONE(notify->zone);
- isc_event_free(&event);
- if (result != ISC_R_SUCCESS)
- notify_destroy(notify, ISC_FALSE);
-}
-
-static void
-notify_send(dns_notify_t *notify) {
- dns_adbaddrinfo_t *ai;
- isc_sockaddr_t dst;
- isc_result_t result;
- dns_notify_t *new = NULL;
-
- /*
- * Zone lock held by caller.
- */
- REQUIRE(DNS_NOTIFY_VALID(notify));
- REQUIRE(LOCKED_ZONE(notify->zone));
-
- for (ai = ISC_LIST_HEAD(notify->find->list);
- ai != NULL;
- ai = ISC_LIST_NEXT(ai, publink)) {
- dst = ai->sockaddr;
- if (notify_isqueued(notify->zone, NULL, &dst))
- continue;
- if (notify_isself(notify->zone, &dst))
- continue;
- new = NULL;
- result = notify_create(notify->mctx,
- (notify->flags & DNS_NOTIFY_NOSOA),
- &new);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- zone_iattach(notify->zone, &new->zone);
- ISC_LIST_APPEND(new->zone->notifies, new, link);
- new->dst = dst;
- result = notify_send_queue(new);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- new = NULL;
- }
-
- cleanup:
- if (new != NULL)
- notify_destroy(new, ISC_TRUE);
-}
-
-void
-dns_zone_notify(dns_zone_t *zone) {
- isc_time_t now;
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
-
- TIME_NOW(&now);
- zone_settimer(zone, &now);
- UNLOCK_ZONE(zone);
-}
-
-static void
-zone_notify(dns_zone_t *zone, isc_time_t *now) {
- dns_dbnode_t *node = NULL;
- dns_db_t *zonedb = NULL;
- dns_dbversion_t *version = NULL;
- dns_name_t *origin = NULL;
- dns_name_t master;
- dns_rdata_ns_t ns;
- dns_rdata_soa_t soa;
- isc_uint32_t serial;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdataset_t nsrdset;
- dns_rdataset_t soardset;
- isc_result_t result;
- dns_notify_t *notify = NULL;
- unsigned int i;
- isc_sockaddr_t dst;
- isc_boolean_t isqueued;
- dns_notifytype_t notifytype;
- unsigned int flags = 0;
- isc_boolean_t loggednotify = ISC_FALSE;
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
- notifytype = zone->notifytype;
- DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime);
- UNLOCK_ZONE(zone);
-
- if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
- return;
-
- if (notifytype == dns_notifytype_no)
- return;
-
- if (notifytype == dns_notifytype_masteronly &&
- zone->type != dns_zone_master)
- return;
-
- origin = &zone->origin;
-
- /*
- * If the zone is dialup we are done as we don't want to send
- * the current soa so as to force a refresh query.
- */
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
- flags |= DNS_NOTIFY_NOSOA;
-
- /*
- * Get SOA RRset.
- */
- ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
- if (zone->db != NULL)
- dns_db_attach(zone->db, &zonedb);
- ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
- if (zonedb == NULL)
- return;
- dns_db_currentversion(zonedb, &version);
- result = dns_db_findnode(zonedb, origin, ISC_FALSE, &node);
- if (result != ISC_R_SUCCESS)
- goto cleanup1;
-
- dns_rdataset_init(&soardset);
- result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa,
- dns_rdatatype_none, 0, &soardset, NULL);
- if (result != ISC_R_SUCCESS)
- goto cleanup2;
-
- /*
- * Find serial and master server's name.
- */
- dns_name_init(&master, NULL);
- result = dns_rdataset_first(&soardset);
- if (result != ISC_R_SUCCESS)
- goto cleanup3;
- dns_rdataset_current(&soardset, &rdata);
- result = dns_rdata_tostruct(&rdata, &soa, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- dns_rdata_reset(&rdata);
- result = dns_name_dup(&soa.origin, zone->mctx, &master);
- serial = soa.serial;
- dns_rdataset_disassociate(&soardset);
- if (result != ISC_R_SUCCESS)
- goto cleanup3;
-
- /*
- * Enqueue notify requests for 'also-notify' servers.
- */
- LOCK_ZONE(zone);
- for (i = 0; i < zone->notifycnt; i++) {
- dns_tsigkey_t *key = NULL;
-
- dst = zone->notify[i];
- if (notify_isqueued(zone, NULL, &dst))
- continue;
-
- result = notify_create(zone->mctx, flags, &notify);
- if (result != ISC_R_SUCCESS)
- continue;
-
- zone_iattach(zone, &notify->zone);
- notify->dst = dst;
-
- if ((zone->notifykeynames != NULL) &&
- (zone->notifykeynames[i] != NULL)) {
- dns_view_t *view = dns_zone_getview(zone);
- dns_name_t *keyname = zone->notifykeynames[i];
- result = dns_view_gettsig(view, keyname, &key);
- if (result == ISC_R_SUCCESS) {
- notify->key = key;
- key = NULL;
- }
- }
-
- ISC_LIST_APPEND(zone->notifies, notify, link);
- result = notify_send_queue(notify);
- if (result != ISC_R_SUCCESS)
- notify_destroy(notify, ISC_TRUE);
- if (!loggednotify) {
- notify_log(zone, ISC_LOG_INFO,
- "sending notifies (serial %u)",
- serial);
- loggednotify = ISC_TRUE;
- }
- notify = NULL;
- }
- UNLOCK_ZONE(zone);
-
- if (notifytype == dns_notifytype_explicit)
- goto cleanup3;
-
- /*
- * Process NS RRset to generate notifies.
- */
-
- dns_rdataset_init(&nsrdset);
- result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns,
- dns_rdatatype_none, 0, &nsrdset, NULL);
- if (result != ISC_R_SUCCESS)
- goto cleanup3;
-
- result = dns_rdataset_first(&nsrdset);
- while (result == ISC_R_SUCCESS) {
- dns_rdataset_current(&nsrdset, &rdata);
- result = dns_rdata_tostruct(&rdata, &ns, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- dns_rdata_reset(&rdata);
- /*
- * Don't notify the master server unless explicitly
- * configured to do so.
- */
- if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOTIFYTOSOA) &&
- dns_name_compare(&master, &ns.name) == 0) {
- result = dns_rdataset_next(&nsrdset);
- continue;
- }
-
- if (!loggednotify) {
- notify_log(zone, ISC_LOG_INFO,
- "sending notifies (serial %u)",
- serial);
- loggednotify = ISC_TRUE;
- }
-
- LOCK_ZONE(zone);
- isqueued = notify_isqueued(zone, &ns.name, NULL);
- UNLOCK_ZONE(zone);
- if (isqueued) {
- result = dns_rdataset_next(&nsrdset);
- continue;
- }
- result = notify_create(zone->mctx, flags, &notify);
- if (result != ISC_R_SUCCESS)
- continue;
- dns_zone_iattach(zone, &notify->zone);
- result = dns_name_dup(&ns.name, zone->mctx, &notify->ns);
- if (result != ISC_R_SUCCESS) {
- LOCK_ZONE(zone);
- notify_destroy(notify, ISC_TRUE);
- UNLOCK_ZONE(zone);
- continue;
- }
- LOCK_ZONE(zone);
- ISC_LIST_APPEND(zone->notifies, notify, link);
- UNLOCK_ZONE(zone);
- notify_find_address(notify);
- notify = NULL;
- result = dns_rdataset_next(&nsrdset);
- }
- dns_rdataset_disassociate(&nsrdset);
-
- cleanup3:
- if (dns_name_dynamic(&master))
- dns_name_free(&master, zone->mctx);
- cleanup2:
- dns_db_detachnode(zonedb, &node);
- cleanup1:
- dns_db_closeversion(zonedb, &version, ISC_FALSE);
- dns_db_detach(&zonedb);
-}
-
-/***
- *** Private
- ***/
-
-static inline isc_result_t
-save_nsrrset(dns_message_t *message, dns_name_t *name,
- dns_db_t *db, dns_dbversion_t *version)
-{
- dns_rdataset_t *nsrdataset = NULL;
- dns_rdataset_t *rdataset = NULL;
- dns_dbnode_t *node = NULL;
- dns_rdata_ns_t ns;
- isc_result_t result;
- dns_rdata_t rdata = DNS_RDATA_INIT;
-
- /*
- * Extract NS RRset from message.
- */
- result = dns_message_findname(message, DNS_SECTION_ANSWER, name,
- dns_rdatatype_ns, dns_rdatatype_none,
- NULL, &nsrdataset);
- if (result != ISC_R_SUCCESS)
- goto fail;
-
- /*
- * Add NS rdataset.
- */
- result = dns_db_findnode(db, name, ISC_TRUE, &node);
- if (result != ISC_R_SUCCESS)
- goto fail;
- result = dns_db_addrdataset(db, node, version, 0,
- nsrdataset, 0, NULL);
- dns_db_detachnode(db, &node);
- if (result != ISC_R_SUCCESS)
- goto fail;
- /*
- * Add glue rdatasets.
- */
- for (result = dns_rdataset_first(nsrdataset);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(nsrdataset)) {
- dns_rdataset_current(nsrdataset, &rdata);
- result = dns_rdata_tostruct(&rdata, &ns, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- dns_rdata_reset(&rdata);
- if (!dns_name_issubdomain(&ns.name, name))
- continue;
- rdataset = NULL;
- result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
- &ns.name, dns_rdatatype_aaaa,
- dns_rdatatype_none, NULL,
- &rdataset);
- if (result == ISC_R_SUCCESS) {
- result = dns_db_findnode(db, &ns.name,
- ISC_TRUE, &node);
- if (result != ISC_R_SUCCESS)
- goto fail;
- result = dns_db_addrdataset(db, node, version, 0,
- rdataset, 0, NULL);
- dns_db_detachnode(db, &node);
- if (result != ISC_R_SUCCESS)
- goto fail;
- }
- rdataset = NULL;
- result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
- &ns.name, dns_rdatatype_a,
- dns_rdatatype_none, NULL,
- &rdataset);
- if (result == ISC_R_SUCCESS) {
- result = dns_db_findnode(db, &ns.name,
- ISC_TRUE, &node);
- if (result != ISC_R_SUCCESS)
- goto fail;
- result = dns_db_addrdataset(db, node, version, 0,
- rdataset, 0, NULL);
- dns_db_detachnode(db, &node);
- if (result != ISC_R_SUCCESS)
- goto fail;
- }
- }
- if (result != ISC_R_NOMORE)
- goto fail;
-
- return (ISC_R_SUCCESS);
-
-fail:
- return (result);
-}
-
-static void
-stub_callback(isc_task_t *task, isc_event_t *event) {
- const char me[] = "stub_callback";
- dns_requestevent_t *revent = (dns_requestevent_t *)event;
- dns_stub_t *stub = NULL;
- dns_message_t *msg = NULL;
- dns_zone_t *zone = NULL;
- char master[ISC_SOCKADDR_FORMATSIZE];
- char source[ISC_SOCKADDR_FORMATSIZE];
- isc_uint32_t nscnt, cnamecnt, refresh, retry, expire;
- isc_result_t result;
- isc_time_t now;
- isc_boolean_t exiting = ISC_FALSE;
- isc_interval_t i;
- unsigned int j, soacount;
-
- stub = revent->ev_arg;
- INSIST(DNS_STUB_VALID(stub));
-
- UNUSED(task);
-
- zone = stub->zone;
-
- ENTER;
-
- TIME_NOW(&now);
-
- LOCK_ZONE(zone);
-
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
- zone_debuglog(zone, me, 1, "exiting");
- exiting = ISC_TRUE;
- goto next_master;
- }
-
- isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
- isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
-
- if (revent->result != ISC_R_SUCCESS) {
- if (revent->result == ISC_R_TIMEDOUT &&
- !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
- dns_zone_log(zone, ISC_LOG_DEBUG(1),
- "refreshing stub: timeout retrying "
- " without EDNS master %s (source %s)",
- master, source);
- goto same_master;
- }
- dns_zonemgr_unreachableadd(zone->zmgr, &zone->masteraddr,
- &zone->sourceaddr, &now);
- dns_zone_log(zone, ISC_LOG_INFO,
- "could not refresh stub from master %s"
- " (source %s): %s", master, source,
- dns_result_totext(revent->result));
- goto next_master;
- }
-
- result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
- if (result != ISC_R_SUCCESS)
- goto next_master;
-
- result = dns_request_getresponse(revent->request, msg, 0);
- if (result != ISC_R_SUCCESS)
- goto next_master;
-
- /*
- * Unexpected rcode.
- */
- if (msg->rcode != dns_rcode_noerror) {
- char rcode[128];
- isc_buffer_t rb;
-
- isc_buffer_init(&rb, rcode, sizeof(rcode));
- (void)dns_rcode_totext(msg->rcode, &rb);
-
- if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
- (msg->rcode == dns_rcode_servfail ||
- msg->rcode == dns_rcode_notimp ||
- msg->rcode == dns_rcode_formerr)) {
- dns_zone_log(zone, ISC_LOG_DEBUG(1),
- "refreshing stub: rcode (%.*s) retrying "
- "without EDNS master %s (source %s)",
- (int)rb.used, rcode, master, source);
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
- goto same_master;
- }
-
- dns_zone_log(zone, ISC_LOG_INFO,
- "refreshing stub: "
- "unexpected rcode (%.*s) from %s (source %s)",
- (int)rb.used, rcode, master, source);
- goto next_master;
- }
-
- /*
- * We need complete messages.
- */
- if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
- if (dns_request_usedtcp(revent->request)) {
- dns_zone_log(zone, ISC_LOG_INFO,
- "refreshing stub: truncated TCP "
- "response from master %s (source %s)",
- master, source);
- goto next_master;
- }
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
- goto same_master;
- }
-
- /*
- * If non-auth log and next master.
- */
- if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
- dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
- "non-authoritative answer from "
- "master %s (source %s)", master, source);
- goto next_master;
- }
-
- /*
- * Sanity checks.
- */
- cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
- nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns);
-
- if (cnamecnt != 0) {
- dns_zone_log(zone, ISC_LOG_INFO,
- "refreshing stub: unexpected CNAME response "
- "from master %s (source %s)", master, source);
- goto next_master;
- }
-
- if (nscnt == 0) {
- dns_zone_log(zone, ISC_LOG_INFO,
- "refreshing stub: no NS records in response "
- "from master %s (source %s)", master, source);
- goto next_master;
- }
-
- /*
- * Save answer.
- */
- result = save_nsrrset(msg, &zone->origin, stub->db, stub->version);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_INFO,
- "refreshing stub: unable to save NS records "
- "from master %s (source %s)", master, source);
- goto next_master;
- }
-
- /*
- * Tidy up.
- */
- dns_db_closeversion(stub->db, &stub->version, ISC_TRUE);
- ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
- if (zone->db == NULL)
- zone_attachdb(zone, stub->db);
- result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL,
- &refresh, &retry, &expire, NULL, NULL);
- if (result == ISC_R_SUCCESS && soacount > 0U) {
- zone->refresh = RANGE(refresh, zone->minrefresh,
- zone->maxrefresh);
- zone->retry = RANGE(retry, zone->minretry, zone->maxretry);
- zone->expire = RANGE(expire, zone->refresh + zone->retry,
- DNS_MAX_EXPIRE);
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
- }
- ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
- dns_db_detach(&stub->db);
-
- dns_message_destroy(&msg);
- isc_event_free(&event);
- dns_request_destroy(&zone->request);
-
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
- DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
- isc_interval_set(&i, zone->expire, 0);
- DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
-
- if (zone->masterfile != NULL)
- zone_needdump(zone, 0);
-
- zone_settimer(zone, &now);
- goto free_stub;
-
- next_master:
- if (stub->version != NULL)
- dns_db_closeversion(stub->db, &stub->version, ISC_FALSE);
- if (stub->db != NULL)
- dns_db_detach(&stub->db);
- if (msg != NULL)
- dns_message_destroy(&msg);
- isc_event_free(&event);
- dns_request_destroy(&zone->request);
- /*
- * Skip to next failed / untried master.
- */
- do {
- zone->curmaster++;
- } while (zone->curmaster < zone->masterscnt &&
- zone->mastersok[zone->curmaster]);
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
- if (exiting || zone->curmaster >= zone->masterscnt) {
- isc_boolean_t done = ISC_TRUE;
- if (!exiting &&
- DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
- !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
- /*
- * Did we get a good answer from all the masters?
- */
- for (j = 0; j < zone->masterscnt; j++)
- if (zone->mastersok[j] == ISC_FALSE) {
- done = ISC_FALSE;
- break;
- }
- } else
- done = ISC_TRUE;
- if (!done) {
- zone->curmaster = 0;
- /*
- * Find the next failed master.
- */
- while (zone->curmaster < zone->masterscnt &&
- zone->mastersok[zone->curmaster])
- zone->curmaster++;
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
- } else {
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
-
- zone_settimer(zone, &now);
- goto free_stub;
- }
- }
- queue_soa_query(zone);
- goto free_stub;
-
- same_master:
- if (msg != NULL)
- dns_message_destroy(&msg);
- isc_event_free(&event);
- dns_request_destroy(&zone->request);
- ns_query(zone, NULL, stub);
- UNLOCK_ZONE(zone);
- goto done;
-
- free_stub:
- UNLOCK_ZONE(zone);
- stub->magic = 0;
- dns_zone_idetach(&stub->zone);
- INSIST(stub->db == NULL);
- INSIST(stub->version == NULL);
- isc_mem_put(stub->mctx, stub, sizeof(*stub));
-
- done:
- INSIST(event == NULL);
- return;
-}
-
-/*
- * An SOA query has finished (successfully or not).
- */
-static void
-refresh_callback(isc_task_t *task, isc_event_t *event) {
- const char me[] = "refresh_callback";
- dns_requestevent_t *revent = (dns_requestevent_t *)event;
- dns_zone_t *zone;
- dns_message_t *msg = NULL;
- isc_uint32_t soacnt, cnamecnt, soacount, nscount;
- isc_time_t now;
- char master[ISC_SOCKADDR_FORMATSIZE];
- char source[ISC_SOCKADDR_FORMATSIZE];
- dns_rdataset_t *rdataset = NULL;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdata_soa_t soa;
- isc_result_t result;
- isc_uint32_t serial, oldserial = 0;
- unsigned int j;
- isc_boolean_t do_queue_xfrin = ISC_FALSE;
-
- zone = revent->ev_arg;
- INSIST(DNS_ZONE_VALID(zone));
-
- UNUSED(task);
-
- ENTER;
-
- TIME_NOW(&now);
-
- LOCK_ZONE(zone);
-
- /*
- * if timeout log and next master;
- */
-
- isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
- isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
-
- if (revent->result != ISC_R_SUCCESS) {
- if (revent->result == ISC_R_TIMEDOUT &&
- !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
- dns_zone_log(zone, ISC_LOG_DEBUG(1),
- "refresh: timeout retrying without EDNS "
- "master %s (source %s)", master, source);
- goto same_master;
- }
- if (revent->result == ISC_R_TIMEDOUT &&
- !dns_request_usedtcp(revent->request)) {
- dns_zone_log(zone, ISC_LOG_INFO,
- "refresh: retry limit for "
- "master %s exceeded (source %s)",
- master, source);
- /* Try with slave with TCP. */
- if ((zone->type == dns_zone_slave ||
- zone->type == dns_zone_redirect) &&
- DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH)) {
- if (!dns_zonemgr_unreachable(zone->zmgr,
- &zone->masteraddr,
- &zone->sourceaddr,
- &now))
- {
- DNS_ZONE_SETFLAG(zone,
- DNS_ZONEFLG_SOABEFOREAXFR);
- goto tcp_transfer;
- }
- dns_zone_log(zone, ISC_LOG_DEBUG(1),
- "refresh: skipped tcp fallback "
- "as master %s (source %s) is "
- "unreachable (cached)",
- master, source);
- }
- } else
- dns_zone_log(zone, ISC_LOG_INFO,
- "refresh: failure trying master "
- "%s (source %s): %s", master, source,
- dns_result_totext(revent->result));
- goto next_master;
- }
-
- result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
- if (result != ISC_R_SUCCESS)
- goto next_master;
- result = dns_request_getresponse(revent->request, msg, 0);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_INFO,
- "refresh: failure trying master "
- "%s (source %s): %s", master, source,
- dns_result_totext(result));
- goto next_master;
- }
-
- /*
- * Unexpected rcode.
- */
- if (msg->rcode != dns_rcode_noerror) {
- char rcode[128];
- isc_buffer_t rb;
-
- isc_buffer_init(&rb, rcode, sizeof(rcode));
- (void)dns_rcode_totext(msg->rcode, &rb);
-
- if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
- (msg->rcode == dns_rcode_servfail ||
- msg->rcode == dns_rcode_notimp ||
- msg->rcode == dns_rcode_formerr)) {
- dns_zone_log(zone, ISC_LOG_DEBUG(1),
- "refresh: rcode (%.*s) retrying without "
- "EDNS master %s (source %s)",
- (int)rb.used, rcode, master, source);
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
- goto same_master;
- }
- dns_zone_log(zone, ISC_LOG_INFO,
- "refresh: unexpected rcode (%.*s) from "
- "master %s (source %s)", (int)rb.used, rcode,
- master, source);
- /*
- * Perhaps AXFR/IXFR is allowed even if SOA queries aren't.
- */
- if (msg->rcode == dns_rcode_refused &&
- (zone->type == dns_zone_slave ||
- zone->type == dns_zone_redirect))
- goto tcp_transfer;
- goto next_master;
- }
-
- /*
- * If truncated punt to zone transfer which will query again.
- */
- if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
- if (zone->type == dns_zone_slave ||
- zone->type == dns_zone_redirect) {
- dns_zone_log(zone, ISC_LOG_INFO,
- "refresh: truncated UDP answer, "
- "initiating TCP zone xfer "
- "for master %s (source %s)",
- master, source);
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
- goto tcp_transfer;
- } else {
- INSIST(zone->type == dns_zone_stub);
- if (dns_request_usedtcp(revent->request)) {
- dns_zone_log(zone, ISC_LOG_INFO,
- "refresh: truncated TCP response "
- "from master %s (source %s)",
- master, source);
- goto next_master;
- }
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
- goto same_master;
- }
- }
-
- /*
- * if non-auth log and next master;
- */
- if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
- dns_zone_log(zone, ISC_LOG_INFO,
- "refresh: non-authoritative answer from "
- "master %s (source %s)", master, source);
- goto next_master;
- }
-
- cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
- soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa);
- nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns);
- soacount = message_count(msg, DNS_SECTION_AUTHORITY,
- dns_rdatatype_soa);
-
- /*
- * There should not be a CNAME record at top of zone.
- */
- if (cnamecnt != 0) {
- dns_zone_log(zone, ISC_LOG_INFO,
- "refresh: CNAME at top of zone "
- "in master %s (source %s)", master, source);
- goto next_master;
- }
-
- /*
- * if referral log and next master;
- */
- if (soacnt == 0 && soacount == 0 && nscount != 0) {
- dns_zone_log(zone, ISC_LOG_INFO,
- "refresh: referral response "
- "from master %s (source %s)", master, source);
- goto next_master;
- }
-
- /*
- * if nodata log and next master;
- */
- if (soacnt == 0 && (nscount == 0 || soacount != 0)) {
- dns_zone_log(zone, ISC_LOG_INFO,
- "refresh: NODATA response "
- "from master %s (source %s)", master, source);
- goto next_master;
- }
-
- /*
- * Only one soa at top of zone.
- */
- if (soacnt != 1) {
- dns_zone_log(zone, ISC_LOG_INFO,
- "refresh: answer SOA count (%d) != 1 "
- "from master %s (source %s)",
- soacnt, master, source);
- goto next_master;
- }
-
- /*
- * Extract serial
- */
- rdataset = NULL;
- result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin,
- dns_rdatatype_soa, dns_rdatatype_none,
- NULL, &rdataset);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_INFO,
- "refresh: unable to get SOA record "
- "from master %s (source %s)", master, source);
- goto next_master;
- }
-
- result = dns_rdataset_first(rdataset);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_INFO,
- "refresh: dns_rdataset_first() failed");
- goto next_master;
- }
-
- dns_rdataset_current(rdataset, &rdata);
- result = dns_rdata_tostruct(&rdata, &soa, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
-
- serial = soa.serial;
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
- unsigned int soacount;
- result = zone_get_from_db(zone, zone->db, NULL, &soacount,
- &oldserial, NULL, NULL, NULL, NULL,
- NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- RUNTIME_CHECK(soacount > 0U);
- zone_debuglog(zone, me, 1, "serial: new %u, old %u",
- serial, oldserial);
- } else
- zone_debuglog(zone, me, 1, "serial: new %u, old not loaded",
- serial);
-
- if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) ||
- DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) ||
- isc_serial_gt(serial, oldserial)) {
- if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
- &zone->sourceaddr, &now))
- {
- dns_zone_log(zone, ISC_LOG_INFO,
- "refresh: skipping %s as master %s "
- "(source %s) is unreachable (cached)",
- (zone->type == dns_zone_slave ||
- zone->type == dns_zone_redirect) ?
- "zone transfer" : "NS query",
- master, source);
- goto next_master;
- }
- tcp_transfer:
- isc_event_free(&event);
- dns_request_destroy(&zone->request);
- if (zone->type == dns_zone_slave ||
- zone->type == dns_zone_redirect) {
- do_queue_xfrin = ISC_TRUE;
- } else {
- INSIST(zone->type == dns_zone_stub);
- ns_query(zone, rdataset, NULL);
- }
- if (msg != NULL)
- dns_message_destroy(&msg);
- } else if (isc_serial_eq(soa.serial, oldserial)) {
- if (zone->masterfile != NULL) {
- result = ISC_R_FAILURE;
- if (zone->journal != NULL)
- result = isc_file_settime(zone->journal, &now);
- if (result == ISC_R_SUCCESS &&
- !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
- !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
- result = isc_file_settime(zone->masterfile,
- &now);
- } else if (result != ISC_R_SUCCESS)
- result = isc_file_settime(zone->masterfile,
- &now);
- /* Someone removed the file from underneath us! */
- if (result == ISC_R_FILENOTFOUND) {
- zone_needdump(zone, DNS_DUMP_DELAY);
- } else if (result != ISC_R_SUCCESS)
- dns_zone_log(zone, ISC_LOG_ERROR,
- "refresh: could not set file "
- "modification time of '%s': %s",
- zone->masterfile,
- dns_result_totext(result));
- }
- DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
- DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
- zone->mastersok[zone->curmaster] = ISC_TRUE;
- goto next_master;
- } else {
- if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER))
- dns_zone_log(zone, ISC_LOG_INFO, "serial number (%u) "
- "received from master %s < ours (%u)",
- soa.serial, master, oldserial);
- else
- zone_debuglog(zone, me, 1, "ahead");
- zone->mastersok[zone->curmaster] = ISC_TRUE;
- goto next_master;
- }
- if (msg != NULL)
- dns_message_destroy(&msg);
- goto detach;
-
- next_master:
- if (msg != NULL)
- dns_message_destroy(&msg);
- isc_event_free(&event);
- dns_request_destroy(&zone->request);
- /*
- * Skip to next failed / untried master.
- */
- do {
- zone->curmaster++;
- } while (zone->curmaster < zone->masterscnt &&
- zone->mastersok[zone->curmaster]);
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
- if (zone->curmaster >= zone->masterscnt) {
- isc_boolean_t done = ISC_TRUE;
- if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
- !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
- /*
- * Did we get a good answer from all the masters?
- */
- for (j = 0; j < zone->masterscnt; j++)
- if (zone->mastersok[j] == ISC_FALSE) {
- done = ISC_FALSE;
- break;
- }
- } else
- done = ISC_TRUE;
- if (!done) {
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
- zone->curmaster = 0;
- /*
- * Find the next failed master.
- */
- while (zone->curmaster < zone->masterscnt &&
- zone->mastersok[zone->curmaster])
- zone->curmaster++;
- goto requeue;
- }
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
- zone->refreshtime = now;
- }
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
- zone_settimer(zone, &now);
- goto detach;
- }
-
- requeue:
- queue_soa_query(zone);
- goto detach;
-
- same_master:
- if (msg != NULL)
- dns_message_destroy(&msg);
- isc_event_free(&event);
- dns_request_destroy(&zone->request);
- queue_soa_query(zone);
-
- detach:
- UNLOCK_ZONE(zone);
- if (do_queue_xfrin)
- queue_xfrin(zone);
- dns_zone_idetach(&zone);
- return;
-}
-
-static void
-queue_soa_query(dns_zone_t *zone) {
- const char me[] = "queue_soa_query";
- isc_event_t *e;
- dns_zone_t *dummy = NULL;
- isc_result_t result;
-
- ENTER;
- /*
- * Locked by caller
- */
- REQUIRE(LOCKED_ZONE(zone));
-
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
- cancel_refresh(zone);
- return;
- }
-
- e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE,
- soa_query, zone, sizeof(isc_event_t));
- if (e == NULL) {
- cancel_refresh(zone);
- return;
- }
-
- /*
- * Attach so that we won't clean up
- * until the event is delivered.
- */
- zone_iattach(zone, &dummy);
-
- e->ev_arg = zone;
- e->ev_sender = NULL;
- result = isc_ratelimiter_enqueue(zone->zmgr->rl, zone->task, &e);
- if (result != ISC_R_SUCCESS) {
- zone_idetach(&dummy);
- isc_event_free(&e);
- cancel_refresh(zone);
- }
-}
-
-static inline isc_result_t
-create_query(dns_zone_t *zone, dns_rdatatype_t rdtype,
- dns_message_t **messagep)
-{
- dns_message_t *message = NULL;
- dns_name_t *qname = NULL;
- dns_rdataset_t *qrdataset = NULL;
- isc_result_t result;
-
- result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
- &message);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- message->opcode = dns_opcode_query;
- message->rdclass = zone->rdclass;
-
- 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;
-
- /*
- * Make question.
- */
- dns_name_init(qname, NULL);
- dns_name_clone(&zone->origin, qname);
- dns_rdataset_init(qrdataset);
- dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype);
- ISC_LIST_APPEND(qname->list, qrdataset, link);
- dns_message_addname(message, qname, DNS_SECTION_QUESTION);
-
- *messagep = message;
- 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 isc_result_t
-add_opt(dns_message_t *message, isc_uint16_t udpsize, isc_boolean_t reqnsid) {
- dns_rdataset_t *rdataset = NULL;
- dns_rdatalist_t *rdatalist = NULL;
- dns_rdata_t *rdata = NULL;
- isc_result_t result;
-
- result = dns_message_gettemprdatalist(message, &rdatalist);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- result = dns_message_gettemprdata(message, &rdata);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- result = dns_message_gettemprdataset(message, &rdataset);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- dns_rdataset_init(rdataset);
-
- rdatalist->type = dns_rdatatype_opt;
- rdatalist->covers = 0;
-
- /*
- * Set Maximum UDP buffer size.
- */
- rdatalist->rdclass = udpsize;
-
- /*
- * Set EXTENDED-RCODE, VERSION, DO and Z to 0.
- */
- rdatalist->ttl = 0;
-
- /* Set EDNS options if applicable */
- if (reqnsid) {
- unsigned char data[4];
- isc_buffer_t buf;
-
- isc_buffer_init(&buf, data, sizeof(data));
- isc_buffer_putuint16(&buf, DNS_OPT_NSID);
- isc_buffer_putuint16(&buf, 0);
- rdata->data = data;
- rdata->length = sizeof(data);
- } else {
- rdata->data = NULL;
- rdata->length = 0;
- }
-
- rdata->rdclass = rdatalist->rdclass;
- rdata->type = rdatalist->type;
- rdata->flags = 0;
-
- ISC_LIST_INIT(rdatalist->rdata);
- ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
- RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset)
- == ISC_R_SUCCESS);
-
- return (dns_message_setopt(message, rdataset));
-
- cleanup:
- if (rdatalist != NULL)
- dns_message_puttemprdatalist(message, &rdatalist);
- if (rdataset != NULL)
- dns_message_puttemprdataset(message, &rdataset);
- if (rdata != NULL)
- dns_message_puttemprdata(message, &rdata);
-
- return (result);
-}
-
-static void
-soa_query(isc_task_t *task, isc_event_t *event) {
- const char me[] = "soa_query";
- isc_result_t result = ISC_R_FAILURE;
- dns_message_t *message = NULL;
- dns_zone_t *zone = event->ev_arg;
- dns_zone_t *dummy = NULL;
- isc_netaddr_t masterip;
- dns_tsigkey_t *key = NULL;
- isc_uint32_t options;
- isc_boolean_t cancel = ISC_TRUE;
- int timeout;
- isc_boolean_t have_xfrsource, reqnsid;
- isc_uint16_t udpsize = SEND_BUFFER_SIZE;
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- UNUSED(task);
-
- ENTER;
-
- LOCK_ZONE(zone);
- if (((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) ||
- DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
- zone->view->requestmgr == NULL) {
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
- cancel = ISC_FALSE;
- goto cleanup;
- }
-
- /*
- * XXX Optimisation: Create message when zone is setup and reuse.
- */
- result = create_query(zone, dns_rdatatype_soa, &message);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- again:
- INSIST(zone->masterscnt > 0);
- INSIST(zone->curmaster < zone->masterscnt);
-
- zone->masteraddr = zone->masters[zone->curmaster];
-
- isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
- /*
- * First, look for a tsig key in the master statement, then
- * try for a server key.
- */
- if ((zone->masterkeynames != NULL) &&
- (zone->masterkeynames[zone->curmaster] != NULL)) {
- dns_view_t *view = dns_zone_getview(zone);
- dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
- result = dns_view_gettsig(view, keyname, &key);
- if (result != ISC_R_SUCCESS) {
- char namebuf[DNS_NAME_FORMATSIZE];
- dns_name_format(keyname, namebuf, sizeof(namebuf));
- dns_zone_log(zone, ISC_LOG_ERROR,
- "unable to find key: %s", namebuf);
- goto skip_master;
- }
- }
- if (key == NULL) {
- result = dns_view_getpeertsig(zone->view, &masterip, &key);
- if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
- char addrbuf[ISC_NETADDR_FORMATSIZE];
- isc_netaddr_format(&masterip, addrbuf, sizeof(addrbuf));
- dns_zone_log(zone, ISC_LOG_ERROR,
- "unable to find TSIG key for %s", addrbuf);
- goto skip_master;
- }
- }
-
- have_xfrsource = ISC_FALSE;
- reqnsid = zone->view->requestnsid;
- if (zone->view->peers != NULL) {
- dns_peer_t *peer = NULL;
- isc_boolean_t edns;
- result = dns_peerlist_peerbyaddr(zone->view->peers,
- &masterip, &peer);
- if (result == ISC_R_SUCCESS) {
- result = dns_peer_getsupportedns(peer, &edns);
- if (result == ISC_R_SUCCESS && !edns)
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
- result = dns_peer_gettransfersource(peer,
- &zone->sourceaddr);
- if (result == ISC_R_SUCCESS)
- have_xfrsource = ISC_TRUE;
- if (zone->view->resolver != NULL)
- udpsize =
- dns_resolver_getudpsize(zone->view->resolver);
- (void)dns_peer_getudpsize(peer, &udpsize);
- (void)dns_peer_getrequestnsid(peer, &reqnsid);
- }
- }
-
- switch (isc_sockaddr_pf(&zone->masteraddr)) {
- case PF_INET:
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
- if (isc_sockaddr_equal(&zone->altxfrsource4,
- &zone->xfrsource4))
- goto skip_master;
- zone->sourceaddr = zone->altxfrsource4;
- } else if (!have_xfrsource)
- zone->sourceaddr = zone->xfrsource4;
- break;
- case PF_INET6:
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
- if (isc_sockaddr_equal(&zone->altxfrsource6,
- &zone->xfrsource6))
- goto skip_master;
- zone->sourceaddr = zone->altxfrsource6;
- } else if (!have_xfrsource)
- zone->sourceaddr = zone->xfrsource6;
- break;
- default:
- result = ISC_R_NOTIMPLEMENTED;
- goto cleanup;
- }
-
- options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ?
- DNS_REQUESTOPT_TCP : 0;
-
- if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
- result = add_opt(message, udpsize, reqnsid);
- if (result != ISC_R_SUCCESS)
- zone_debuglog(zone, me, 1,
- "unable to add opt record: %s",
- dns_result_totext(result));
- }
-
- zone_iattach(zone, &dummy);
- timeout = 15;
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
- timeout = 30;
- result = dns_request_createvia2(zone->view->requestmgr, message,
- &zone->sourceaddr, &zone->masteraddr,
- options, key, timeout * 3, timeout,
- zone->task, refresh_callback, zone,
- &zone->request);
- if (result != ISC_R_SUCCESS) {
- zone_idetach(&dummy);
- zone_debuglog(zone, me, 1,
- "dns_request_createvia2() failed: %s",
- dns_result_totext(result));
- goto cleanup;
- } else {
- if (isc_sockaddr_pf(&zone->masteraddr) == PF_INET)
- inc_stats(zone, dns_zonestatscounter_soaoutv4);
- else
- inc_stats(zone, dns_zonestatscounter_soaoutv6);
- }
- cancel = ISC_FALSE;
-
- cleanup:
- if (key != NULL)
- dns_tsigkey_detach(&key);
- if (result != ISC_R_SUCCESS)
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
- if (message != NULL)
- dns_message_destroy(&message);
- if (cancel)
- cancel_refresh(zone);
- isc_event_free(&event);
- UNLOCK_ZONE(zone);
- dns_zone_idetach(&zone);
- return;
-
- skip_master:
- if (key != NULL)
- dns_tsigkey_detach(&key);
- /*
- * Skip to next failed / untried master.
- */
- do {
- zone->curmaster++;
- } while (zone->curmaster < zone->masterscnt &&
- zone->mastersok[zone->curmaster]);
- if (zone->curmaster < zone->masterscnt)
- goto again;
- zone->curmaster = 0;
- goto cleanup;
-}
-
-static void
-ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
- const char me[] = "ns_query";
- isc_result_t result;
- dns_message_t *message = NULL;
- isc_netaddr_t masterip;
- dns_tsigkey_t *key = NULL;
- dns_dbnode_t *node = NULL;
- int timeout;
- isc_boolean_t have_xfrsource = ISC_FALSE, reqnsid;
- isc_uint16_t udpsize = SEND_BUFFER_SIZE;
-
- REQUIRE(DNS_ZONE_VALID(zone));
- REQUIRE(LOCKED_ZONE(zone));
- REQUIRE((soardataset != NULL && stub == NULL) ||
- (soardataset == NULL && stub != NULL));
- REQUIRE(stub == NULL || DNS_STUB_VALID(stub));
-
- ENTER;
-
- if (stub == NULL) {
- stub = isc_mem_get(zone->mctx, sizeof(*stub));
- if (stub == NULL)
- goto cleanup;
- stub->magic = STUB_MAGIC;
- stub->mctx = zone->mctx;
- stub->zone = NULL;
- stub->db = NULL;
- stub->version = NULL;
-
- /*
- * Attach so that the zone won't disappear from under us.
- */
- zone_iattach(zone, &stub->zone);
-
- /*
- * If a db exists we will update it, otherwise we create a
- * new one and attach it to the zone once we have the NS
- * RRset and glue.
- */
- ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
- if (zone->db != NULL) {
- dns_db_attach(zone->db, &stub->db);
- ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
- } else {
- ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
-
- INSIST(zone->db_argc >= 1);
- result = dns_db_create(zone->mctx, zone->db_argv[0],
- &zone->origin, dns_dbtype_stub,
- zone->rdclass,
- zone->db_argc - 1,
- zone->db_argv + 1,
- &stub->db);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "refreshing stub: "
- "could not create "
- "database: %s",
- dns_result_totext(result));
- goto cleanup;
- }
- dns_db_settask(stub->db, zone->task);
- }
-
- result = dns_db_newversion(stub->db, &stub->version);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
- "dns_db_newversion() failed: %s",
- dns_result_totext(result));
- goto cleanup;
- }
-
- /*
- * Update SOA record.
- */
- result = dns_db_findnode(stub->db, &zone->origin, ISC_TRUE,
- &node);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
- "dns_db_findnode() failed: %s",
- dns_result_totext(result));
- goto cleanup;
- }
-
- result = dns_db_addrdataset(stub->db, node, stub->version, 0,
- soardataset, 0, NULL);
- dns_db_detachnode(stub->db, &node);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_INFO,
- "refreshing stub: "
- "dns_db_addrdataset() failed: %s",
- dns_result_totext(result));
- goto cleanup;
- }
- }
-
- /*
- * XXX Optimisation: Create message when zone is setup and reuse.
- */
- result = create_query(zone, dns_rdatatype_ns, &message);
- INSIST(result == ISC_R_SUCCESS);
-
- INSIST(zone->masterscnt > 0);
- INSIST(zone->curmaster < zone->masterscnt);
- zone->masteraddr = zone->masters[zone->curmaster];
-
- isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
- /*
- * First, look for a tsig key in the master statement, then
- * try for a server key.
- */
- if ((zone->masterkeynames != NULL) &&
- (zone->masterkeynames[zone->curmaster] != NULL)) {
- dns_view_t *view = dns_zone_getview(zone);
- dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
- result = dns_view_gettsig(view, keyname, &key);
- if (result != ISC_R_SUCCESS) {
- char namebuf[DNS_NAME_FORMATSIZE];
- dns_name_format(keyname, namebuf, sizeof(namebuf));
- dns_zone_log(zone, ISC_LOG_ERROR,
- "unable to find key: %s", namebuf);
- }
- }
- if (key == NULL)
- (void)dns_view_getpeertsig(zone->view, &masterip, &key);
-
- reqnsid = zone->view->requestnsid;
- if (zone->view->peers != NULL) {
- dns_peer_t *peer = NULL;
- isc_boolean_t edns;
- result = dns_peerlist_peerbyaddr(zone->view->peers,
- &masterip, &peer);
- if (result == ISC_R_SUCCESS) {
- result = dns_peer_getsupportedns(peer, &edns);
- if (result == ISC_R_SUCCESS && !edns)
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
- result = dns_peer_gettransfersource(peer,
- &zone->sourceaddr);
- if (result == ISC_R_SUCCESS)
- have_xfrsource = ISC_TRUE;
- if (zone->view->resolver != NULL)
- udpsize =
- dns_resolver_getudpsize(zone->view->resolver);
- (void)dns_peer_getudpsize(peer, &udpsize);
- (void)dns_peer_getrequestnsid(peer, &reqnsid);
- }
-
- }
- if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
- result = add_opt(message, udpsize, reqnsid);
- if (result != ISC_R_SUCCESS)
- zone_debuglog(zone, me, 1,
- "unable to add opt record: %s",
- dns_result_totext(result));
- }
-
- /*
- * Always use TCP so that we shouldn't truncate in additional section.
- */
- switch (isc_sockaddr_pf(&zone->masteraddr)) {
- case PF_INET:
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
- zone->sourceaddr = zone->altxfrsource4;
- else if (!have_xfrsource)
- zone->sourceaddr = zone->xfrsource4;
- break;
- case PF_INET6:
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
- zone->sourceaddr = zone->altxfrsource6;
- else if (!have_xfrsource)
- zone->sourceaddr = zone->xfrsource6;
- break;
- default:
- result = ISC_R_NOTIMPLEMENTED;
- POST(result);
- goto cleanup;
- }
- timeout = 15;
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
- timeout = 30;
- result = dns_request_createvia2(zone->view->requestmgr, message,
- &zone->sourceaddr, &zone->masteraddr,
- DNS_REQUESTOPT_TCP, key, timeout * 3,
- timeout, zone->task, stub_callback,
- stub, &zone->request);
- if (result != ISC_R_SUCCESS) {
- zone_debuglog(zone, me, 1,
- "dns_request_createvia() failed: %s",
- dns_result_totext(result));
- goto cleanup;
- }
- dns_message_destroy(&message);
- goto unlock;
-
- cleanup:
- cancel_refresh(zone);
- if (stub != NULL) {
- stub->magic = 0;
- if (stub->version != NULL)
- dns_db_closeversion(stub->db, &stub->version,
- ISC_FALSE);
- if (stub->db != NULL)
- dns_db_detach(&stub->db);
- if (stub->zone != NULL)
- zone_idetach(&stub->zone);
- isc_mem_put(stub->mctx, stub, sizeof(*stub));
- }
- if (message != NULL)
- dns_message_destroy(&message);
- unlock:
- if (key != NULL)
- dns_tsigkey_detach(&key);
- return;
-}
-
-/*
- * Handle the control event. Note that although this event causes the zone
- * to shut down, it is not a shutdown event in the sense of the task library.
- */
-static void
-zone_shutdown(isc_task_t *task, isc_event_t *event) {
- dns_zone_t *zone = (dns_zone_t *) event->ev_arg;
- isc_boolean_t free_needed, linked = ISC_FALSE;
- dns_zone_t *raw = NULL, *secure = NULL;
-
- UNUSED(task);
- REQUIRE(DNS_ZONE_VALID(zone));
- INSIST(event->ev_type == DNS_EVENT_ZONECONTROL);
- INSIST(isc_refcount_current(&zone->erefs) == 0);
-
- zone_debuglog(zone, "zone_shutdown", 3, "shutting down");
-
- /*
- * Stop things being restarted after we cancel them below.
- */
- LOCK_ZONE(zone);
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING);
- UNLOCK_ZONE(zone);
-
- /*
- * If we were waiting for xfrin quota, step out of
- * the queue.
- * If there's no zone manager, we can't be waiting for the
- * xfrin quota
- */
- if (zone->zmgr != NULL) {
- RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
- if (zone->statelist == &zone->zmgr->waiting_for_xfrin) {
- ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone,
- statelink);
- linked = ISC_TRUE;
- zone->statelist = NULL;
- }
- RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
- }
-
- /*
- * In task context, no locking required. See zone_xfrdone().
- */
- if (zone->xfr != NULL)
- dns_xfrin_shutdown(zone->xfr);
-
- LOCK_ZONE(zone);
- if (linked) {
- INSIST(zone->irefs > 0);
- zone->irefs--;
- }
- if (zone->request != NULL) {
- dns_request_cancel(zone->request);
- }
-
- if (zone->readio != NULL)
- zonemgr_cancelio(zone->readio);
-
- if (zone->lctx != NULL)
- dns_loadctx_cancel(zone->lctx);
-
- if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
- !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
- if (zone->writeio != NULL)
- zonemgr_cancelio(zone->writeio);
-
- if (zone->dctx != NULL)
- dns_dumpctx_cancel(zone->dctx);
- }
-
- notify_cancel(zone);
-
- forward_cancel(zone);
-
- if (zone->timer != NULL) {
- isc_timer_detach(&zone->timer);
- INSIST(zone->irefs > 0);
- zone->irefs--;
- }
-
- if (zone->view != NULL)
- dns_view_weakdetach(&zone->view);
-
- /*
- * We have now canceled everything set the flag to allow exit_check()
- * to succeed. We must not unlock between setting this flag and
- * calling exit_check().
- */
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN);
- free_needed = exit_check(zone);
- if (inline_secure(zone)) {
- raw = zone->raw;
- zone->raw = NULL;
- }
- if (inline_raw(zone)) {
- secure = zone->secure;
- zone->secure = NULL;
- }
- UNLOCK_ZONE(zone);
- if (raw != NULL)
- dns_zone_detach(&raw);
- if (secure != NULL)
- dns_zone_idetach(&secure);
- if (free_needed)
- zone_free(zone);
-}
-
-static void
-zone_timer(isc_task_t *task, isc_event_t *event) {
- const char me[] = "zone_timer";
- dns_zone_t *zone = (dns_zone_t *)event->ev_arg;
-
- UNUSED(task);
- REQUIRE(DNS_ZONE_VALID(zone));
-
- ENTER;
-
- zone_maintenance(zone);
-
- isc_event_free(&event);
-}
-
-static void
-zone_settimer(dns_zone_t *zone, isc_time_t *now) {
- const char me[] = "zone_settimer";
- isc_time_t next;
- isc_result_t result;
-
- ENTER;
- REQUIRE(DNS_ZONE_VALID(zone));
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
- return;
-
- isc_time_settoepoch(&next);
-
- switch (zone->type) {
- case dns_zone_redirect:
- if (zone->masters != NULL)
- goto treat_as_slave;
- /* FALLTHROUGH */
-
- case dns_zone_master:
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
- next = zone->notifytime;
- 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 (zone->type == dns_zone_redirect)
- break;
- 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)
- next = zone->resigntime;
- }
- if (!isc_time_isepoch(&zone->keywarntime)) {
- if (isc_time_isepoch(&next) ||
- isc_time_compare(&zone->keywarntime, &next) < 0)
- next = zone->keywarntime;
- }
- if (!isc_time_isepoch(&zone->signingtime)) {
- if (isc_time_isepoch(&next) ||
- isc_time_compare(&zone->signingtime, &next) < 0)
- next = zone->signingtime;
- }
- if (!isc_time_isepoch(&zone->nsec3chaintime)) {
- if (isc_time_isepoch(&next) ||
- isc_time_compare(&zone->nsec3chaintime, &next) < 0)
- next = zone->nsec3chaintime;
- }
- break;
-
- case dns_zone_slave:
- treat_as_slave:
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
- next = zone->notifytime;
- /* FALLTHROUGH */
-
- case dns_zone_stub:
- if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) &&
- !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOMASTERS) &&
- !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) &&
- !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
- INSIST(!isc_time_isepoch(&zone->refreshtime));
- if (isc_time_isepoch(&next) ||
- isc_time_compare(&zone->refreshtime, &next) < 0)
- next = zone->refreshtime;
- }
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
- INSIST(!isc_time_isepoch(&zone->expiretime));
- if (isc_time_isepoch(&next) ||
- isc_time_compare(&zone->expiretime, &next) < 0)
- next = zone->expiretime;
- }
- 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;
- }
- 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;
- }
-
- if (isc_time_isepoch(&next)) {
- zone_debuglog(zone, me, 10, "settimer inactive");
- result = isc_timer_reset(zone->timer, isc_timertype_inactive,
- NULL, NULL, ISC_TRUE);
- if (result != ISC_R_SUCCESS)
- dns_zone_log(zone, ISC_LOG_ERROR,
- "could not deactivate zone timer: %s",
- isc_result_totext(result));
- } else {
- if (isc_time_compare(&next, now) <= 0)
- next = *now;
- result = isc_timer_reset(zone->timer, isc_timertype_once,
- &next, NULL, ISC_TRUE);
- if (result != ISC_R_SUCCESS)
- dns_zone_log(zone, ISC_LOG_ERROR,
- "could not reset zone timer: %s",
- isc_result_totext(result));
- }
-}
-
-static void
-cancel_refresh(dns_zone_t *zone) {
- const char me[] = "cancel_refresh";
- isc_time_t now;
-
- /*
- * 'zone' locked by caller.
- */
-
- REQUIRE(DNS_ZONE_VALID(zone));
- REQUIRE(LOCKED_ZONE(zone));
-
- ENTER;
-
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
- TIME_NOW(&now);
- zone_settimer(zone, &now);
-}
-
-static isc_result_t
-notify_createmessage(dns_zone_t *zone, unsigned int flags,
- dns_message_t **messagep)
-{
- dns_db_t *zonedb = NULL;
- dns_dbnode_t *node = NULL;
- dns_dbversion_t *version = NULL;
- dns_message_t *message = NULL;
- dns_rdataset_t rdataset;
- dns_rdata_t rdata = DNS_RDATA_INIT;
-
- dns_name_t *tempname = NULL;
- dns_rdata_t *temprdata = NULL;
- dns_rdatalist_t *temprdatalist = NULL;
- dns_rdataset_t *temprdataset = NULL;
-
- isc_result_t result;
- isc_region_t r;
- isc_buffer_t *b = NULL;
-
- REQUIRE(DNS_ZONE_VALID(zone));
- REQUIRE(messagep != NULL && *messagep == NULL);
-
- result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
- &message);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- message->opcode = dns_opcode_notify;
- message->flags |= DNS_MESSAGEFLAG_AA;
- message->rdclass = zone->rdclass;
-
- result = dns_message_gettempname(message, &tempname);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- result = dns_message_gettemprdataset(message, &temprdataset);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- /*
- * Make question.
- */
- dns_name_init(tempname, NULL);
- dns_name_clone(&zone->origin, tempname);
- dns_rdataset_init(temprdataset);
- dns_rdataset_makequestion(temprdataset, zone->rdclass,
- dns_rdatatype_soa);
- ISC_LIST_APPEND(tempname->list, temprdataset, link);
- dns_message_addname(message, tempname, DNS_SECTION_QUESTION);
- tempname = NULL;
- temprdataset = NULL;
-
- if ((flags & DNS_NOTIFY_NOSOA) != 0)
- goto done;
-
- result = dns_message_gettempname(message, &tempname);
- if (result != ISC_R_SUCCESS)
- goto soa_cleanup;
- result = dns_message_gettemprdata(message, &temprdata);
- if (result != ISC_R_SUCCESS)
- goto soa_cleanup;
- result = dns_message_gettemprdataset(message, &temprdataset);
- if (result != ISC_R_SUCCESS)
- goto soa_cleanup;
- result = dns_message_gettemprdatalist(message, &temprdatalist);
- if (result != ISC_R_SUCCESS)
- goto soa_cleanup;
-
- ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
- INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */
- dns_db_attach(zone->db, &zonedb);
- ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
-
- dns_name_init(tempname, NULL);
- dns_name_clone(&zone->origin, tempname);
- dns_db_currentversion(zonedb, &version);
- result = dns_db_findnode(zonedb, tempname, ISC_FALSE, &node);
- if (result != ISC_R_SUCCESS)
- goto soa_cleanup;
-
- dns_rdataset_init(&rdataset);
- result = dns_db_findrdataset(zonedb, node, version,
- dns_rdatatype_soa,
- dns_rdatatype_none, 0, &rdataset,
- NULL);
- if (result != ISC_R_SUCCESS)
- goto soa_cleanup;
- result = dns_rdataset_first(&rdataset);
- if (result != ISC_R_SUCCESS)
- goto soa_cleanup;
- dns_rdataset_current(&rdataset, &rdata);
- dns_rdata_toregion(&rdata, &r);
- result = isc_buffer_allocate(zone->mctx, &b, r.length);
- if (result != ISC_R_SUCCESS)
- goto soa_cleanup;
- isc_buffer_putmem(b, r.base, r.length);
- isc_buffer_usedregion(b, &r);
- dns_rdata_init(temprdata);
- dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r);
- dns_message_takebuffer(message, &b);
- result = dns_rdataset_next(&rdataset);
- dns_rdataset_disassociate(&rdataset);
- if (result != ISC_R_NOMORE)
- goto soa_cleanup;
- temprdatalist->rdclass = rdata.rdclass;
- temprdatalist->type = rdata.type;
- temprdatalist->covers = 0;
- temprdatalist->ttl = rdataset.ttl;
- ISC_LIST_INIT(temprdatalist->rdata);
- ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link);
-
- dns_rdataset_init(temprdataset);
- result = dns_rdatalist_tordataset(temprdatalist, temprdataset);
- if (result != ISC_R_SUCCESS)
- goto soa_cleanup;
-
- ISC_LIST_APPEND(tempname->list, temprdataset, link);
- dns_message_addname(message, tempname, DNS_SECTION_ANSWER);
- temprdatalist = NULL;
- temprdataset = NULL;
- temprdata = NULL;
- tempname = NULL;
-
- soa_cleanup:
- if (node != NULL)
- dns_db_detachnode(zonedb, &node);
- if (version != NULL)
- dns_db_closeversion(zonedb, &version, ISC_FALSE);
- if (zonedb != NULL)
- dns_db_detach(&zonedb);
- if (tempname != NULL)
- dns_message_puttempname(message, &tempname);
- if (temprdata != NULL)
- dns_message_puttemprdata(message, &temprdata);
- if (temprdataset != NULL)
- dns_message_puttemprdataset(message, &temprdataset);
- if (temprdatalist != NULL)
- dns_message_puttemprdatalist(message, &temprdatalist);
-
- done:
- *messagep = message;
- return (ISC_R_SUCCESS);
-
- cleanup:
- if (tempname != NULL)
- dns_message_puttempname(message, &tempname);
- if (temprdataset != NULL)
- dns_message_puttemprdataset(message, &temprdataset);
- dns_message_destroy(&message);
- return (result);
-}
-
-isc_result_t
-dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
- dns_message_t *msg)
-{
- unsigned int i;
- dns_rdata_soa_t soa;
- dns_rdataset_t *rdataset = NULL;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- isc_result_t result;
- char fromtext[ISC_SOCKADDR_FORMATSIZE];
- int match = 0;
- isc_netaddr_t netaddr;
- isc_sockaddr_t local, remote;
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- /*
- * If type != T_SOA return DNS_R_NOTIMP. We don't yet support
- * ROLLOVER.
- *
- * SOA: RFC1996
- * Check that 'from' is a valid notify source, (zone->masters).
- * Return DNS_R_REFUSED if not.
- *
- * If the notify message contains a serial number check it
- * against the zones serial and return if <= current serial
- *
- * If a refresh check is progress, if so just record the
- * fact we received a NOTIFY and from where and return.
- * We will perform a new refresh check when the current one
- * completes. Return ISC_R_SUCCESS.
- *
- * Otherwise initiate a refresh check using 'from' as the
- * first address to check. Return ISC_R_SUCCESS.
- */
-
- isc_sockaddr_format(from, fromtext, sizeof(fromtext));
-
- /*
- * Notify messages are processed by the raw zone.
- */
- LOCK_ZONE(zone);
- if (inline_secure(zone)) {
- result = dns_zone_notifyreceive(zone->raw, from, msg);
- UNLOCK_ZONE(zone);
- return (result);
- }
- /*
- * We only handle NOTIFY (SOA) at the present.
- */
- if (isc_sockaddr_pf(from) == PF_INET)
- inc_stats(zone, dns_zonestatscounter_notifyinv4);
- else
- inc_stats(zone, dns_zonestatscounter_notifyinv6);
- if (msg->counts[DNS_SECTION_QUESTION] == 0 ||
- dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin,
- dns_rdatatype_soa, dns_rdatatype_none,
- NULL, NULL) != ISC_R_SUCCESS) {
- UNLOCK_ZONE(zone);
- if (msg->counts[DNS_SECTION_QUESTION] == 0) {
- dns_zone_log(zone, ISC_LOG_NOTICE,
- "NOTIFY with no "
- "question section from: %s", fromtext);
- return (DNS_R_FORMERR);
- }
- dns_zone_log(zone, ISC_LOG_NOTICE,
- "NOTIFY zone does not match");
- return (DNS_R_NOTIMP);
- }
-
- /*
- * If we are a master zone just succeed.
- */
- if (zone->type == dns_zone_master) {
- UNLOCK_ZONE(zone);
- return (ISC_R_SUCCESS);
- }
-
- isc_netaddr_fromsockaddr(&netaddr, from);
- for (i = 0; i < zone->masterscnt; i++) {
- if (isc_sockaddr_eqaddr(from, &zone->masters[i]))
- break;
- if (zone->view->aclenv.match_mapped &&
- IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) &&
- isc_sockaddr_pf(&zone->masters[i]) == AF_INET) {
- isc_netaddr_t na1, na2;
- isc_netaddr_fromv4mapped(&na1, &netaddr);
- isc_netaddr_fromsockaddr(&na2, &zone->masters[i]);
- if (isc_netaddr_equal(&na1, &na2))
- break;
- }
- }
-
- /*
- * Accept notify requests from non masters if they are on
- * 'zone->notify_acl'.
- */
- if (i >= zone->masterscnt && zone->notify_acl != NULL &&
- dns_acl_match(&netaddr, NULL, zone->notify_acl,
- &zone->view->aclenv,
- &match, NULL) == ISC_R_SUCCESS &&
- match > 0)
- {
- /* Accept notify. */
- } else if (i >= zone->masterscnt) {
- UNLOCK_ZONE(zone);
- dns_zone_log(zone, ISC_LOG_INFO,
- "refused notify from non-master: %s", fromtext);
- inc_stats(zone, dns_zonestatscounter_notifyrej);
- return (DNS_R_REFUSED);
- }
-
- /*
- * If the zone is loaded and there are answers check the serial
- * to see if we need to do a refresh. Do not worry about this
- * check if we are a dialup zone as we use the notify request
- * to trigger a refresh check.
- */
- if (msg->counts[DNS_SECTION_ANSWER] > 0 &&
- DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
- !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH)) {
- result = dns_message_findname(msg, DNS_SECTION_ANSWER,
- &zone->origin,
- dns_rdatatype_soa,
- dns_rdatatype_none, NULL,
- &rdataset);
- if (result == ISC_R_SUCCESS)
- result = dns_rdataset_first(rdataset);
- if (result == ISC_R_SUCCESS) {
- isc_uint32_t serial = 0, oldserial;
- unsigned int soacount;
-
- dns_rdataset_current(rdataset, &rdata);
- result = dns_rdata_tostruct(&rdata, &soa, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- serial = soa.serial;
- /*
- * The following should safely be performed without DB
- * lock and succeed in this context.
- */
- result = zone_get_from_db(zone, zone->db, NULL,
- &soacount, &oldserial, NULL,
- NULL, NULL, NULL, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- RUNTIME_CHECK(soacount > 0U);
- if (isc_serial_le(serial, oldserial)) {
- dns_zone_log(zone,
- ISC_LOG_INFO,
- "notify from %s: "
- "zone is up to date",
- fromtext);
- UNLOCK_ZONE(zone);
- return (ISC_R_SUCCESS);
- }
- }
- }
-
- /*
- * If we got this far and there was a refresh in progress just
- * let it complete. Record where we got the notify from so we
- * can perform a refresh check when the current one completes
- */
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) {
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
- zone->notifyfrom = *from;
- UNLOCK_ZONE(zone);
- dns_zone_log(zone, ISC_LOG_INFO,
- "notify from %s: refresh in progress, "
- "refresh check queued",
- fromtext);
- return (ISC_R_SUCCESS);
- }
- zone->notifyfrom = *from;
- local = zone->masteraddr;
- remote = zone->sourceaddr;
- UNLOCK_ZONE(zone);
- dns_zonemgr_unreachabledel(zone->zmgr, &local, &remote);
- dns_zone_refresh(zone);
- return (ISC_R_SUCCESS);
-}
-
-void
-dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) {
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- if (zone->notify_acl != NULL)
- dns_acl_detach(&zone->notify_acl);
- dns_acl_attach(acl, &zone->notify_acl);
- UNLOCK_ZONE(zone);
-}
-
-void
-dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) {
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- if (zone->query_acl != NULL)
- dns_acl_detach(&zone->query_acl);
- dns_acl_attach(acl, &zone->query_acl);
- UNLOCK_ZONE(zone);
-}
-
-void
-dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl) {
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- if (zone->queryon_acl != NULL)
- dns_acl_detach(&zone->queryon_acl);
- dns_acl_attach(acl, &zone->queryon_acl);
- UNLOCK_ZONE(zone);
-}
-
-void
-dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) {
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- if (zone->update_acl != NULL)
- dns_acl_detach(&zone->update_acl);
- dns_acl_attach(acl, &zone->update_acl);
- UNLOCK_ZONE(zone);
-}
-
-void
-dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) {
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- if (zone->forward_acl != NULL)
- dns_acl_detach(&zone->forward_acl);
- dns_acl_attach(acl, &zone->forward_acl);
- UNLOCK_ZONE(zone);
-}
-
-void
-dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) {
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- if (zone->xfr_acl != NULL)
- dns_acl_detach(&zone->xfr_acl);
- dns_acl_attach(acl, &zone->xfr_acl);
- UNLOCK_ZONE(zone);
-}
-
-dns_acl_t *
-dns_zone_getnotifyacl(dns_zone_t *zone) {
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- return (zone->notify_acl);
-}
-
-dns_acl_t *
-dns_zone_getqueryacl(dns_zone_t *zone) {
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- return (zone->query_acl);
-}
-
-dns_acl_t *
-dns_zone_getqueryonacl(dns_zone_t *zone) {
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- return (zone->queryon_acl);
-}
-
-dns_acl_t *
-dns_zone_getupdateacl(dns_zone_t *zone) {
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- return (zone->update_acl);
-}
-
-dns_acl_t *
-dns_zone_getforwardacl(dns_zone_t *zone) {
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- return (zone->forward_acl);
-}
-
-dns_acl_t *
-dns_zone_getxfracl(dns_zone_t *zone) {
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- return (zone->xfr_acl);
-}
-
-void
-dns_zone_clearupdateacl(dns_zone_t *zone) {
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- if (zone->update_acl != NULL)
- dns_acl_detach(&zone->update_acl);
- UNLOCK_ZONE(zone);
-}
-
-void
-dns_zone_clearforwardacl(dns_zone_t *zone) {
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- if (zone->forward_acl != NULL)
- dns_acl_detach(&zone->forward_acl);
- UNLOCK_ZONE(zone);
-}
-
-void
-dns_zone_clearnotifyacl(dns_zone_t *zone) {
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- if (zone->notify_acl != NULL)
- dns_acl_detach(&zone->notify_acl);
- UNLOCK_ZONE(zone);
-}
-
-void
-dns_zone_clearqueryacl(dns_zone_t *zone) {
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- if (zone->query_acl != NULL)
- dns_acl_detach(&zone->query_acl);
- UNLOCK_ZONE(zone);
-}
-
-void
-dns_zone_clearqueryonacl(dns_zone_t *zone) {
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- if (zone->queryon_acl != NULL)
- dns_acl_detach(&zone->queryon_acl);
- UNLOCK_ZONE(zone);
-}
-
-void
-dns_zone_clearxfracl(dns_zone_t *zone) {
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- if (zone->xfr_acl != NULL)
- dns_acl_detach(&zone->xfr_acl);
- UNLOCK_ZONE(zone);
-}
-
-isc_boolean_t
-dns_zone_getupdatedisabled(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
- return (zone->update_disabled);
-
-}
-
-void
-dns_zone_setupdatedisabled(dns_zone_t *zone, isc_boolean_t state) {
- REQUIRE(DNS_ZONE_VALID(zone));
- zone->update_disabled = state;
-}
-
-isc_boolean_t
-dns_zone_getzeronosoattl(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
- return (zone->zero_no_soa_ttl);
-
-}
-
-void
-dns_zone_setzeronosoattl(dns_zone_t *zone, isc_boolean_t state) {
- REQUIRE(DNS_ZONE_VALID(zone));
- zone->zero_no_soa_ttl = state;
-}
-
-void
-dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) {
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- zone->check_names = severity;
-}
-
-dns_severity_t
-dns_zone_getchecknames(dns_zone_t *zone) {
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- return (zone->check_names);
-}
-
-void
-dns_zone_setjournalsize(dns_zone_t *zone, isc_int32_t size) {
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- zone->journalsize = size;
-}
-
-isc_int32_t
-dns_zone_getjournalsize(dns_zone_t *zone) {
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- return (zone->journalsize);
-}
-
-static void
-zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) {
- isc_result_t result = ISC_R_FAILURE;
- isc_buffer_t buffer;
-
- REQUIRE(buf != NULL);
- REQUIRE(length > 1U);
-
- /*
- * Leave space for terminating '\0'.
- */
- isc_buffer_init(&buffer, buf, length - 1);
- if (zone->type != dns_zone_redirect && zone->type != dns_zone_key) {
- if (dns_name_dynamic(&zone->origin))
- result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
- if (result != ISC_R_SUCCESS &&
- isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
- isc_buffer_putstr(&buffer, "<UNKNOWN>");
-
- if (isc_buffer_availablelength(&buffer) > 0)
- isc_buffer_putstr(&buffer, "/");
- (void)dns_rdataclass_totext(zone->rdclass, &buffer);
- }
-
- if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 &&
- strcmp(zone->view->name, "_default") != 0 &&
- strlen(zone->view->name) < isc_buffer_availablelength(&buffer)) {
- isc_buffer_putstr(&buffer, "/");
- isc_buffer_putstr(&buffer, zone->view->name);
- }
- if (inline_secure(zone) && 9U < isc_buffer_availablelength(&buffer))
- isc_buffer_putstr(&buffer, " (signed)");
- if (inline_raw(zone) && 11U < isc_buffer_availablelength(&buffer))
- isc_buffer_putstr(&buffer, " (unsigned)");
-
- buf[isc_buffer_usedlength(&buffer)] = '\0';
-}
-
-static void
-zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) {
- isc_result_t result = ISC_R_FAILURE;
- isc_buffer_t buffer;
-
- REQUIRE(buf != NULL);
- REQUIRE(length > 1U);
-
- /*
- * Leave space for terminating '\0'.
- */
- isc_buffer_init(&buffer, buf, length - 1);
- if (dns_name_dynamic(&zone->origin))
- result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
- if (result != ISC_R_SUCCESS &&
- isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
- isc_buffer_putstr(&buffer, "<UNKNOWN>");
-
- buf[isc_buffer_usedlength(&buffer)] = '\0';
-}
-
-static void
-zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) {
- isc_buffer_t buffer;
-
- REQUIRE(buf != NULL);
- REQUIRE(length > 1U);
-
- /*
- * Leave space for terminating '\0'.
- */
- isc_buffer_init(&buffer, buf, length - 1);
- (void)dns_rdataclass_totext(zone->rdclass, &buffer);
-
- buf[isc_buffer_usedlength(&buffer)] = '\0';
-}
-
-static void
-zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length) {
- isc_buffer_t buffer;
-
- REQUIRE(buf != NULL);
- REQUIRE(length > 1U);
-
-
- /*
- * Leave space for terminating '\0'.
- */
- isc_buffer_init(&buffer, buf, length - 1);
-
- if (zone->view == NULL) {
- isc_buffer_putstr(&buffer, "_none");
- } else if (strlen(zone->view->name)
- < isc_buffer_availablelength(&buffer)) {
- isc_buffer_putstr(&buffer, zone->view->name);
- } else {
- isc_buffer_putstr(&buffer, "_toolong");
- }
-
- buf[isc_buffer_usedlength(&buffer)] = '\0';
-}
-
-void
-dns_zone_name(dns_zone_t *zone, char *buf, size_t length) {
- REQUIRE(DNS_ZONE_VALID(zone));
- REQUIRE(buf != NULL);
- zone_namerd_tostr(zone, buf, length);
-}
-
-static void
-notify_log(dns_zone_t *zone, int level, const char *fmt, ...) {
- va_list ap;
- char message[4096];
-
- if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
- return;
-
- va_start(ap, fmt);
- vsnprintf(message, sizeof(message), fmt, ap);
- va_end(ap);
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY, DNS_LOGMODULE_ZONE,
- level, "zone %s: %s", zone->strnamerd, message);
-}
-
-void
-dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category,
- int level, const char *fmt, ...) {
- va_list ap;
- char message[4096];
-
- if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
- return;
-
- va_start(ap, fmt);
- vsnprintf(message, sizeof(message), fmt, ap);
- va_end(ap);
- isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE,
- level, "%s%s: %s", (zone->type == dns_zone_key) ?
- "managed-keys-zone" : (zone->type == dns_zone_redirect) ?
- "redirect-zone" : "zone ", zone->strnamerd, message);
-}
-
-void
-dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) {
- va_list ap;
- char message[4096];
-
- if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
- return;
-
- va_start(ap, fmt);
- vsnprintf(message, sizeof(message), fmt, ap);
- va_end(ap);
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
- level, "%s%s: %s", (zone->type == dns_zone_key) ?
- "managed-keys-zone" : (zone->type == dns_zone_redirect) ?
- "redirect-zone" : "zone ", zone->strnamerd, message);
-}
-
-static void
-zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel,
- const char *fmt, ...)
-{
- va_list ap;
- char message[4096];
- int level = ISC_LOG_DEBUG(debuglevel);
- const char *zstr;
-
- if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
- return;
-
- va_start(ap, fmt);
- vsnprintf(message, sizeof(message), fmt, ap);
- va_end(ap);
-
- switch (zone->type) {
- case dns_zone_key:
- zstr = "managed-keys-zone";
- break;
- case dns_zone_redirect:
- zstr = "redirect-zone";
- break;
- default:
- zstr = "zone";
- }
-
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
- level, "%s: %s %s: %s", me, zstr, zone->strnamerd,
- message);
-}
-
-static int
-message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type)
-{
- isc_result_t result;
- dns_name_t *name;
- dns_rdataset_t *curr;
- int count = 0;
-
- result = dns_message_firstname(msg, section);
- while (result == ISC_R_SUCCESS) {
- name = NULL;
- dns_message_currentname(msg, section, &name);
-
- for (curr = ISC_LIST_TAIL(name->list); curr != NULL;
- curr = ISC_LIST_PREV(curr, link)) {
- if (curr->type == type)
- count++;
- }
- result = dns_message_nextname(msg, section);
- }
-
- return (count);
-}
-
-void
-dns_zone_setmaxxfrin(dns_zone_t *zone, isc_uint32_t maxxfrin) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- zone->maxxfrin = maxxfrin;
-}
-
-isc_uint32_t
-dns_zone_getmaxxfrin(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- return (zone->maxxfrin);
-}
-
-void
-dns_zone_setmaxxfrout(dns_zone_t *zone, isc_uint32_t maxxfrout) {
- REQUIRE(DNS_ZONE_VALID(zone));
- zone->maxxfrout = maxxfrout;
-}
-
-isc_uint32_t
-dns_zone_getmaxxfrout(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- return (zone->maxxfrout);
-}
-
-dns_zonetype_t
-dns_zone_gettype(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- return (zone->type);
-}
-
-dns_name_t *
-dns_zone_getorigin(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- return (&zone->origin);
-}
-
-void
-dns_zone_settask(dns_zone_t *zone, isc_task_t *task) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- if (zone->task != NULL)
- isc_task_detach(&zone->task);
- isc_task_attach(task, &zone->task);
- ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
- if (zone->db != NULL)
- dns_db_settask(zone->db, zone->task);
- ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
- UNLOCK_ZONE(zone);
-}
-
-void
-dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) {
- REQUIRE(DNS_ZONE_VALID(zone));
- isc_task_attach(zone->task, target);
-}
-
-void
-dns_zone_setidlein(dns_zone_t *zone, isc_uint32_t idlein) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- if (idlein == 0)
- idlein = DNS_DEFAULT_IDLEIN;
- zone->idlein = idlein;
-}
-
-isc_uint32_t
-dns_zone_getidlein(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- return (zone->idlein);
-}
-
-void
-dns_zone_setidleout(dns_zone_t *zone, isc_uint32_t idleout) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- zone->idleout = idleout;
-}
-
-isc_uint32_t
-dns_zone_getidleout(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- return (zone->idleout);
-}
-
-static void
-notify_done(isc_task_t *task, isc_event_t *event) {
- dns_requestevent_t *revent = (dns_requestevent_t *)event;
- dns_notify_t *notify;
- isc_result_t result;
- dns_message_t *message = NULL;
- isc_buffer_t buf;
- char rcode[128];
- char addrbuf[ISC_SOCKADDR_FORMATSIZE];
-
- UNUSED(task);
-
- notify = event->ev_arg;
- REQUIRE(DNS_NOTIFY_VALID(notify));
- INSIST(task == notify->zone->task);
-
- isc_buffer_init(&buf, rcode, sizeof(rcode));
- isc_sockaddr_format(&notify->dst, addrbuf, sizeof(addrbuf));
-
- result = revent->result;
- if (result == ISC_R_SUCCESS)
- result = dns_message_create(notify->zone->mctx,
- DNS_MESSAGE_INTENTPARSE, &message);
- if (result == ISC_R_SUCCESS)
- result = dns_request_getresponse(revent->request, message,
- DNS_MESSAGEPARSE_PRESERVEORDER);
- if (result == ISC_R_SUCCESS)
- result = dns_rcode_totext(message->rcode, &buf);
- if (result == ISC_R_SUCCESS)
- notify_log(notify->zone, ISC_LOG_DEBUG(3),
- "notify response from %s: %.*s",
- addrbuf, (int)buf.used, rcode);
- else
- notify_log(notify->zone, ISC_LOG_DEBUG(2),
- "notify to %s failed: %s", addrbuf,
- dns_result_totext(result));
-
- /*
- * 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);
- if (message != NULL && message->rcode == dns_rcode_formerr &&
- (notify->flags & DNS_NOTIFY_NOSOA) == 0) {
- notify->flags |= DNS_NOTIFY_NOSOA;
- dns_request_destroy(&notify->request);
- result = notify_send_queue(notify);
- if (result != ISC_R_SUCCESS)
- notify_destroy(notify, ISC_FALSE);
- } else {
- if (result == ISC_R_TIMEDOUT)
- notify_log(notify->zone, ISC_LOG_DEBUG(1),
- "notify to %s: retries exceeded", addrbuf);
- notify_destroy(notify, ISC_FALSE);
- }
- if (message != NULL)
- dns_message_destroy(&message);
-}
-
-struct secure_event {
- isc_event_t e;
- dns_db_t *db;
- isc_uint32_t serial;
-};
-
-static void
-update_log_cb(void *arg, dns_zone_t *zone, int level, const char *message) {
- UNUSED(arg);
- dns_zone_log(zone, level, "%s", message);
-}
-
-static isc_result_t
-sync_secure_journal(dns_zone_t *zone, dns_journal_t *journal,
- isc_uint32_t start, isc_uint32_t end,
- dns_difftuple_t **soatuplep, dns_diff_t *diff)
-{
- isc_result_t result;
- dns_difftuple_t *tuple = NULL;
- dns_diffop_t op = DNS_DIFFOP_ADD;
- int n_soa = 0;
-
- REQUIRE(soatuplep != NULL);
-
- if (start == end)
- return (DNS_R_UNCHANGED);
-
- CHECK(dns_journal_iter_init(journal, start, end));
- for (result = dns_journal_first_rr(journal);
- result == ISC_R_SUCCESS;
- result = dns_journal_next_rr(journal))
- {
- dns_name_t *name = NULL;
- isc_uint32_t ttl;
- dns_rdata_t *rdata = NULL;
- dns_journal_current_rr(journal, &name, &ttl, &rdata);
-
- if (rdata->type == dns_rdatatype_soa) {
- n_soa++;
- if (n_soa == 2) {
- /*
- * Save the latest raw SOA record.
- */
- if (*soatuplep != NULL)
- dns_difftuple_free(soatuplep);
- CHECK(dns_difftuple_create(diff->mctx,
- DNS_DIFFOP_ADD,
- name, ttl, rdata,
- soatuplep));
- }
- if (n_soa == 3)
- n_soa = 1;
- continue;
- }
-
- /* Sanity. */
- if (n_soa == 0) {
- dns_zone_log(zone->raw, ISC_LOG_ERROR,
- "corrupt journal file: '%s'\n",
- zone->raw->journal);
- return (ISC_R_FAILURE);
- }
-
- if (zone->privatetype != 0 &&
- rdata->type == zone->privatetype)
- continue;
-
- if (rdata->type == dns_rdatatype_nsec ||
- rdata->type == dns_rdatatype_rrsig ||
- rdata->type == dns_rdatatype_nsec3 ||
- rdata->type == dns_rdatatype_dnskey ||
- rdata->type == dns_rdatatype_nsec3param)
- continue;
-
- op = (n_soa == 1) ? DNS_DIFFOP_DEL : DNS_DIFFOP_ADD;
-
- CHECK(dns_difftuple_create(diff->mctx, op, name, ttl, rdata,
- &tuple));
- dns_diff_appendminimal(diff, &tuple);
- }
- if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
-
- failure:
- return(result);
-}
-
-static isc_result_t
-sync_secure_db(dns_zone_t *seczone, dns_db_t *secdb,
- dns_dbversion_t *secver, dns_difftuple_t **soatuple,
- dns_diff_t *diff)
-{
- isc_result_t result;
- dns_db_t *rawdb = NULL;
- dns_dbversion_t *rawver = NULL;
- dns_difftuple_t *tuple = NULL, *next;
- dns_difftuple_t *oldtuple = NULL, *newtuple = NULL;
- dns_rdata_soa_t oldsoa, newsoa;
-
- REQUIRE(DNS_ZONE_VALID(seczone));
- REQUIRE(inline_secure(seczone));
- REQUIRE(soatuple != NULL && *soatuple == NULL);
-
- if (!seczone->sourceserialset)
- return (DNS_R_UNCHANGED);
-
- dns_db_attach(seczone->raw->db, &rawdb);
- dns_db_currentversion(rawdb, &rawver);
- result = dns_db_diffx(diff, rawdb, rawver, secdb, secver, NULL);
- dns_db_closeversion(rawdb, &rawver, ISC_FALSE);
- dns_db_detach(&rawdb);
-
- if (result != ISC_R_SUCCESS)
- return (result);
-
- for (tuple = ISC_LIST_HEAD(diff->tuples);
- tuple != NULL;
- tuple = next)
- {
- next = ISC_LIST_NEXT(tuple, link);
- if (tuple->rdata.type == dns_rdatatype_nsec ||
- tuple->rdata.type == dns_rdatatype_rrsig ||
- tuple->rdata.type == dns_rdatatype_dnskey ||
- tuple->rdata.type == dns_rdatatype_nsec3 ||
- tuple->rdata.type == dns_rdatatype_nsec3param)
- {
- ISC_LIST_UNLINK(diff->tuples, tuple, link);
- dns_difftuple_free(&tuple);
- continue;
- }
- if (tuple->rdata.type == dns_rdatatype_soa) {
- if (tuple->op == DNS_DIFFOP_DEL) {
- INSIST(oldtuple == NULL);
- oldtuple = tuple;
- }
- if (tuple->op == DNS_DIFFOP_ADD) {
- INSIST(newtuple == NULL);
- newtuple = tuple;
- }
- }
- }
-
- if (oldtuple != NULL && newtuple != NULL) {
-
- result = dns_rdata_tostruct(&oldtuple->rdata, &oldsoa, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
-
- result = dns_rdata_tostruct(&newtuple->rdata, &newsoa, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
-
- /*
- * If the SOA records are the same except for the serial
- * remove them from the diff.
- */
- if (oldsoa.refresh == newsoa.refresh &&
- oldsoa.retry == newsoa.retry &&
- oldsoa.minimum == newsoa.minimum &&
- oldsoa.expire == newsoa.expire &&
- dns_name_equal(&oldsoa.origin, &newsoa.origin) &&
- dns_name_equal(&oldsoa.contact, &newsoa.contact)) {
- ISC_LIST_UNLINK(diff->tuples, oldtuple, link);
- dns_difftuple_free(&oldtuple);
- ISC_LIST_UNLINK(diff->tuples, newtuple, link);
- dns_difftuple_free(&newtuple);
- }
- }
-
- if (ISC_LIST_EMPTY(diff->tuples))
- return (DNS_R_UNCHANGED);
-
- /*
- * If there are still SOA records in the diff they can now be removed
- * saving the new SOA record.
- */
- if (oldtuple != NULL) {
- ISC_LIST_UNLINK(diff->tuples, oldtuple, link);
- dns_difftuple_free(&oldtuple);
- }
-
- if (newtuple != NULL) {
- ISC_LIST_UNLINK(diff->tuples, newtuple, link);
- *soatuple = newtuple;
- }
-
- return (ISC_R_SUCCESS);
-}
-
-static void
-receive_secure_serial(isc_task_t *task, isc_event_t *event) {
- isc_result_t result;
- dns_journal_t *rjournal = NULL;
- isc_uint32_t start, end;
- dns_zone_t *zone;
- dns_db_t *db = NULL;
- dns_dbversion_t *newver = NULL, *oldver = NULL;
- dns_diff_t diff;
- dns_difftuple_t *tuple = NULL, *soatuple = NULL;
- dns_update_log_t log = { update_log_cb, NULL };
- isc_time_t timenow;
-
- zone = event->ev_arg;
- end = ((struct secure_event *)event)->serial;
- isc_event_free(&event);
-
- LOCK_ZONE(zone);
-
- dns_diff_init(zone->mctx, &diff);
-
- UNUSED(task);
-
- /*
- * zone->db may be NULL if the load from disk failed.
- */
- if (zone->db == NULL || !inline_secure(zone)) {
- result = ISC_R_FAILURE;
- goto failure;
- }
-
- /*
- * We first attempt to sync the raw zone to the secure zone
- * by using the raw zone's journal, applying all the deltas
- * from the latest source-serial of the secure zone up to
- * the current serial number of the raw zone.
- *
- * If that fails, then we'll fall back to a direct comparison
- * between raw and secure zones.
- */
- result = dns_journal_open(zone->raw->mctx, zone->raw->journal,
- DNS_JOURNAL_WRITE, &rjournal);
- if (result != ISC_R_SUCCESS)
- goto failure;
- else {
- dns_journal_t *sjournal = NULL;
-
- result = dns_journal_open(zone->mctx, zone->journal,
- DNS_JOURNAL_READ, &sjournal);
- if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
- goto failure;
-
- if (!dns_journal_get_sourceserial(rjournal, &start)) {
- start = dns_journal_first_serial(rjournal);
- dns_journal_set_sourceserial(rjournal, start);
- }
- if (sjournal != NULL) {
- isc_uint32_t serial;
- /*
- * We read the secure journal first, if that exists
- * use its value provided it is greater that from the
- * raw journal.
- */
- if (dns_journal_get_sourceserial(sjournal, &serial)) {
- if (isc_serial_gt(serial, start))
- start = serial;
- }
- dns_journal_destroy(&sjournal);
- }
- }
-
- dns_db_attach(zone->db, &db);
- dns_db_currentversion(db, &oldver);
- CHECK(dns_db_newversion(db, &newver));
-
- /*
- * Try to apply diffs from the raw zone's journal to the secure
- * zone. If that fails, we recover by syncing up the databases
- * directly.
- */
- result = sync_secure_journal(zone, rjournal, start, end,
- &soatuple, &diff);
- if (result == DNS_R_UNCHANGED)
- goto failure;
- else if (result != ISC_R_SUCCESS)
- CHECK(sync_secure_db(zone, db, oldver, &soatuple, &diff));
-
- CHECK(dns_diff_apply(&diff, db, newver));
-
- if (soatuple != NULL) {
- isc_uint32_t oldserial, newserial, desired;
-
- CHECK(dns_db_createsoatuple(db, oldver, diff.mctx,
- DNS_DIFFOP_DEL, &tuple));
- oldserial = dns_soa_getserial(&tuple->rdata);
- newserial = desired = dns_soa_getserial(&soatuple->rdata);
- if (!isc_serial_gt(newserial, oldserial)) {
- newserial = oldserial + 1;
- if (newserial == 0)
- newserial++;
- dns_soa_setserial(newserial, &soatuple->rdata);
- }
- CHECK(do_one_tuple(&tuple, db, newver, &diff));
- CHECK(do_one_tuple(&soatuple, db, newver, &diff));
- dns_zone_log(zone, ISC_LOG_INFO, "serial %u (unsigned %u)",
- newserial, desired);
- } else
- CHECK(update_soa_serial(db, newver, &diff, zone->mctx,
- zone->updatemethod));
-
- CHECK(dns_update_signatures(&log, zone, db, oldver, newver,
- &diff, zone->sigvalidityinterval));
-
- CHECK(zone_journal(zone, &diff, &end, "receive_secure_serial"));
-
- dns_journal_set_sourceserial(rjournal, end);
- dns_journal_commit(rjournal);
-
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
-
- zone->sourceserial = end;
- zone->sourceserialset = ISC_TRUE;
- zone_needdump(zone, DNS_DUMP_DELAY);
-
- TIME_NOW(&timenow);
- zone_settimer(zone, &timenow);
-
- dns_db_closeversion(db, &oldver, ISC_FALSE);
- dns_db_closeversion(db, &newver, ISC_TRUE);
-
- failure:
- UNLOCK_ZONE(zone);
- if (result != ISC_R_SUCCESS)
- dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_serial: %s",
- dns_result_totext(result));
- if (tuple != NULL)
- dns_difftuple_free(&tuple);
- if (soatuple != NULL)
- dns_difftuple_free(&soatuple);
- if (db != NULL) {
- if (oldver != NULL)
- dns_db_closeversion(db, &oldver, ISC_FALSE);
- if (newver != NULL)
- dns_db_closeversion(db, &newver, ISC_FALSE);
- dns_db_detach(&db);
- }
- if (rjournal != NULL)
- dns_journal_destroy(&rjournal);
- dns_diff_clear(&diff);
- dns_zone_idetach(&zone);
-}
-
-static isc_result_t
-zone_send_secureserial(dns_zone_t *zone, isc_boolean_t locked,
- isc_uint32_t serial)
-{
- isc_event_t *e;
- dns_zone_t *dummy = NULL;
-
- e = isc_event_allocate(zone->secure->mctx, zone,
- DNS_EVENT_ZONESECURESERIAL,
- receive_secure_serial, zone->secure,
- sizeof(struct secure_event));
- if (e == NULL)
- return (ISC_R_NOMEMORY);
- ((struct secure_event *)e)->serial = serial;
- if (locked)
- zone_iattach(zone->secure, &dummy);
- else
- dns_zone_iattach(zone->secure, &dummy);
- isc_task_send(zone->secure->task, &e);
-
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE);
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-checkandaddsoa(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
- dns_rdataset_t *rdataset, isc_uint32_t oldserial)
-{
- dns_rdata_soa_t soa;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdatalist_t temprdatalist;
- dns_rdataset_t temprdataset;
- isc_buffer_t b;
- isc_result_t result;
- unsigned char buf[DNS_SOA_BUFFERSIZE];
-
- result = dns_rdataset_first(rdataset);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- dns_rdataset_current(rdataset, &rdata);
- result = dns_rdata_tostruct(&rdata, &soa, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
-
- if (isc_serial_gt(soa.serial, oldserial))
- return (dns_db_addrdataset(db, node, version, 0, rdataset, 0,
- NULL));
- /*
- * Always bump the serial.
- */
- oldserial++;
- if (oldserial == 0)
- oldserial++;
- soa.serial = oldserial;
-
- /*
- * Construct a replacement rdataset.
- */
- dns_rdata_reset(&rdata);
- isc_buffer_init(&b, buf, sizeof(buf));
- result = dns_rdata_fromstruct(&rdata, rdataset->rdclass,
- dns_rdatatype_soa, &soa, &b);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- temprdatalist.rdclass = rdata.rdclass;
- temprdatalist.type = rdata.type;
- temprdatalist.covers = 0;
- temprdatalist.ttl = rdataset->ttl;
- ISC_LIST_INIT(temprdatalist.rdata);
- ISC_LIST_APPEND(temprdatalist.rdata, &rdata, link);
-
- dns_rdataset_init(&temprdataset);
- result = dns_rdatalist_tordataset(&temprdatalist, &temprdataset);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- return (dns_db_addrdataset(db, node, version, 0, &temprdataset,
- 0, NULL));
-}
-
-static void
-receive_secure_db(isc_task_t *task, isc_event_t *event) {
- isc_result_t result;
- dns_zone_t *zone;
- dns_db_t *rawdb, *db = NULL;
- dns_dbnode_t *rawnode = NULL, *node = NULL;
- dns_fixedname_t fname;
- dns_name_t *name;
- dns_dbiterator_t *dbiterator = NULL;
- dns_rdatasetiter_t *rdsit = NULL;
- dns_rdataset_t rdataset;
- dns_dbversion_t *version = NULL;
- isc_time_t loadtime;
- unsigned int oldserial = 0;
- isc_boolean_t have_oldserial = ISC_FALSE;
-
- UNUSED(task);
-
- zone = event->ev_arg;
- rawdb = ((struct secure_event *)event)->db;
- isc_event_free(&event);
-
- REQUIRE(inline_secure(zone));
-
- dns_fixedname_init(&fname);
- name = dns_fixedname_name(&fname);
- dns_rdataset_init(&rdataset);
-
- TIME_NOW(&loadtime);
- if (zone->db != NULL) {
- result = dns_db_getsoaserial(zone->db, NULL, &oldserial);
- if (result == ISC_R_SUCCESS)
- have_oldserial = ISC_TRUE;
- }
-
- result = dns_db_create(zone->mctx, zone->db_argv[0],
- &zone->origin, dns_dbtype_zone, zone->rdclass,
- zone->db_argc - 1, zone->db_argv + 1, &db);
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- result = dns_db_newversion(db, &version);
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- result = dns_db_createiterator(rawdb, 0, &dbiterator);
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- for (result = dns_dbiterator_first(dbiterator);
- result == ISC_R_SUCCESS;
- result = dns_dbiterator_next(dbiterator)) {
- result = dns_dbiterator_current(dbiterator, &rawnode, name);
- if (result != ISC_R_SUCCESS)
- continue;
-
- result = dns_db_findnode(db, name, ISC_TRUE, &node);
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- result = dns_db_allrdatasets(rawdb, rawnode, NULL, 0, &rdsit);
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- for (result = dns_rdatasetiter_first(rdsit);
- result == ISC_R_SUCCESS;
- result = dns_rdatasetiter_next(rdsit)) {
- dns_rdatasetiter_current(rdsit, &rdataset);
- if (rdataset.type == dns_rdatatype_nsec ||
- rdataset.type == dns_rdatatype_rrsig ||
- rdataset.type == dns_rdatatype_nsec3 ||
- rdataset.type == dns_rdatatype_dnskey ||
- rdataset.type == dns_rdatatype_nsec3param) {
- dns_rdataset_disassociate(&rdataset);
- continue;
- }
- if (rdataset.type == dns_rdatatype_soa &&
- have_oldserial) {
- result = checkandaddsoa(db, node, version,
- &rdataset, oldserial);
- } else
- result = dns_db_addrdataset(db, node, version,
- 0, &rdataset, 0,
- NULL);
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- dns_rdataset_disassociate(&rdataset);
- }
- dns_rdatasetiter_destroy(&rdsit);
- dns_db_detachnode(rawdb, &rawnode);
- dns_db_detachnode(db, &node);
- }
-
- dns_db_closeversion(db, &version, ISC_TRUE);
- /*
- * Lock hierarchy: zmgr, zone, raw.
- */
- LOCK_ZONE(zone);
- if (inline_secure(zone))
- LOCK_ZONE(zone->raw);
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
- result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);
- zone_needdump(zone, 0); /* XXXMPA */
- if (inline_secure(zone))
- UNLOCK_ZONE(zone->raw);
- UNLOCK_ZONE(zone);
-
- failure:
- if (result != ISC_R_SUCCESS)
- dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_db: %s",
- dns_result_totext(result));
-
- if (dns_rdataset_isassociated(&rdataset))
- dns_rdataset_disassociate(&rdataset);
- if (db != NULL) {
- if (node != NULL)
- dns_db_detachnode(db, &node);
- dns_db_detach(&db);
- }
- if (rawnode != NULL)
- dns_db_detachnode(rawdb, &rawnode);
- dns_db_detach(&rawdb);
- if (dbiterator != NULL)
- dns_dbiterator_destroy(&dbiterator);
- dns_zone_idetach(&zone);
-}
-
-static isc_result_t
-zone_send_securedb(dns_zone_t *zone, isc_boolean_t locked, dns_db_t *db) {
- isc_event_t *e;
- dns_db_t *dummy = NULL;
- dns_zone_t *secure = NULL;
-
- e = isc_event_allocate(zone->secure->mctx, zone,
- DNS_EVENT_ZONESECUREDB,
- receive_secure_db, zone->secure,
- sizeof(struct secure_event));
- if (e == NULL)
- return (ISC_R_NOMEMORY);
- dns_db_attach(db, &dummy);
- ((struct secure_event *)e)->db = dummy;
- if (locked)
- zone_iattach(zone->secure, &secure);
- else
- dns_zone_iattach(zone->secure, &secure);
-
- isc_task_send(zone->secure->task, &e);
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE);
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
- isc_result_t result;
-
- REQUIRE(DNS_ZONE_VALID(zone));
- LOCK_ZONE(zone);
- ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
- result = zone_replacedb(zone, db, dump);
- ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
- UNLOCK_ZONE(zone);
- return (result);
-}
-
-static isc_result_t
-zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
- dns_dbversion_t *ver;
- isc_result_t result;
- unsigned int soacount = 0;
- unsigned int nscount = 0;
-
- /*
- * 'zone' and 'zonedb' locked by caller.
- */
- REQUIRE(DNS_ZONE_VALID(zone));
- REQUIRE(LOCKED_ZONE(zone));
-
- result = zone_get_from_db(zone, db, &nscount, &soacount,
- NULL, NULL, NULL, NULL, NULL, NULL);
- if (result == ISC_R_SUCCESS) {
- if (soacount != 1) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "has %d SOA records", soacount);
- result = DNS_R_BADZONE;
- }
- if (nscount == 0 && zone->type != dns_zone_key) {
- dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records");
- result = DNS_R_BADZONE;
- }
- if (result != ISC_R_SUCCESS)
- return (result);
- } else {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "retrieving SOA and NS records failed: %s",
- dns_result_totext(result));
- return (result);
- }
-
- result = check_nsec3param(zone, db);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- ver = NULL;
- dns_db_currentversion(db, &ver);
-
- /*
- * The initial version of a slave zone is always dumped;
- * subsequent versions may be journaled instead if this
- * is enabled in the configuration.
- */
- if (zone->db != NULL && zone->journal != NULL &&
- DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
- !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER))
- {
- isc_uint32_t serial, oldserial;
- unsigned int soacount;
-
- dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs");
-
- result = dns_db_getsoaserial(db, ver, &serial);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "ixfr-from-differences: unable to get "
- "new serial");
- goto fail;
- }
-
- /*
- * This is checked in zone_postload() for master zones.
- */
- result = zone_get_from_db(zone, zone->db, NULL, &soacount,
- &oldserial, NULL, NULL, NULL, NULL,
- NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- RUNTIME_CHECK(soacount > 0U);
- if ((zone->type == dns_zone_slave ||
- (zone->type == dns_zone_redirect &&
- zone->masters != NULL))
- && !isc_serial_gt(serial, oldserial)) {
- isc_uint32_t serialmin, serialmax;
- serialmin = (oldserial + 1) & 0xffffffffU;
- serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU;
- dns_zone_log(zone, ISC_LOG_ERROR,
- "ixfr-from-differences: failed: "
- "new serial (%u) out of range [%u - %u]",
- serial, serialmin, serialmax);
- result = ISC_R_RANGE;
- goto fail;
- }
-
- result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL,
- zone->journal);
- if (result != ISC_R_SUCCESS)
- goto fail;
- if (dump)
- zone_needdump(zone, DNS_DUMP_DELAY);
- else if (zone->journalsize != -1) {
- result = dns_journal_compact(zone->mctx, zone->journal,
- serial, zone->journalsize);
- switch (result) {
- case ISC_R_SUCCESS:
- case ISC_R_NOSPACE:
- case ISC_R_NOTFOUND:
- dns_zone_log(zone, ISC_LOG_DEBUG(3),
- "dns_journal_compact: %s",
- dns_result_totext(result));
- break;
- default:
- dns_zone_log(zone, ISC_LOG_ERROR,
- "dns_journal_compact failed: %s",
- dns_result_totext(result));
- break;
- }
- }
- if (zone->type == dns_zone_master && inline_raw(zone))
- zone_send_secureserial(zone, ISC_FALSE, serial);
- } else {
- if (dump && zone->masterfile != NULL) {
- /*
- * If DNS_ZONEFLG_FORCEXFER was set we don't want
- * to keep the old masterfile.
- */
- 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
- * because 'dump' is set, it didn't change by
- * 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
- * no longer be used to bring the zone
- * up-to-date, it is useless and should be
- * removed.
- */
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
- DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
- "removing journal file");
- if (remove(zone->journal) < 0 && errno != ENOENT) {
- char strbuf[ISC_STRERRORSIZE];
- isc__strerror(errno, strbuf, sizeof(strbuf));
- isc_log_write(dns_lctx,
- DNS_LOGCATEGORY_GENERAL,
- DNS_LOGMODULE_ZONE,
- ISC_LOG_WARNING,
- "unable to remove journal "
- "'%s': '%s'",
- zone->journal, strbuf);
- }
- }
-
- if (inline_raw(zone))
- zone_send_securedb(zone, ISC_FALSE, db);
- }
-
- dns_db_closeversion(db, &ver, ISC_FALSE);
-
- dns_zone_log(zone, ISC_LOG_DEBUG(3), "replacing zone database");
-
- if (zone->db != NULL)
- zone_detachdb(zone);
- zone_attachdb(zone, db);
- dns_db_settask(zone->db, zone->task);
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
- return (ISC_R_SUCCESS);
-
- fail:
- dns_db_closeversion(db, &ver, ISC_FALSE);
- return (result);
-}
-
-/* The caller must hold the dblock as a writer. */
-static inline void
-zone_attachdb(dns_zone_t *zone, dns_db_t *db) {
- REQUIRE(zone->db == NULL && db != NULL);
-
- dns_db_attach(db, &zone->db);
- if (zone->acache != NULL) {
- isc_result_t result;
- result = dns_acache_setdb(zone->acache, db);
- if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "dns_acache_setdb() failed: %s",
- isc_result_totext(result));
- }
- }
-}
-
-/* The caller must hold the dblock as a writer. */
-static inline void
-zone_detachdb(dns_zone_t *zone) {
- REQUIRE(zone->db != NULL);
-
- if (zone->acache != NULL)
- (void)dns_acache_putdb(zone->acache, zone->db);
- dns_db_detach(&zone->db);
-}
-
-static void
-zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
- isc_time_t now;
- isc_boolean_t again = ISC_FALSE;
- unsigned int soacount;
- unsigned int nscount;
- isc_uint32_t serial, refresh, retry, expire, minimum;
- isc_result_t xfrresult = result;
- isc_boolean_t free_needed;
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- dns_zone_log(zone, ISC_LOG_DEBUG(1),
- "zone transfer finished: %s", dns_result_totext(result));
-
- LOCK_ZONE(zone);
- INSIST((zone->flags & DNS_ZONEFLG_REFRESH) != 0);
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
-
- TIME_NOW(&now);
- switch (result) {
- case ISC_R_SUCCESS:
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
- /*FALLTHROUGH*/
- case DNS_R_UPTODATE:
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER);
- /*
- * Has the zone expired underneath us?
- */
- ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
- if (zone->db == NULL) {
- ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
- goto same_master;
- }
-
- /*
- * Update the zone structure's data from the actual
- * SOA received.
- */
- nscount = 0;
- soacount = 0;
- INSIST(zone->db != NULL);
- result = zone_get_from_db(zone, zone->db, &nscount,
- &soacount, &serial, &refresh,
- &retry, &expire, &minimum, NULL);
- ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
- if (result == ISC_R_SUCCESS) {
- if (soacount != 1)
- dns_zone_log(zone, ISC_LOG_ERROR,
- "transferred zone "
- "has %d SOA record%s", soacount,
- (soacount != 0) ? "s" : "");
- if (nscount == 0) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "transferred zone "
- "has no NS records");
- if (DNS_ZONE_FLAG(zone,
- DNS_ZONEFLG_HAVETIMERS)) {
- zone->refresh = DNS_ZONE_DEFAULTREFRESH;
- zone->retry = DNS_ZONE_DEFAULTRETRY;
- }
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
- zone_unload(zone);
- goto next_master;
- }
- zone->refresh = RANGE(refresh, zone->minrefresh,
- zone->maxrefresh);
- zone->retry = RANGE(retry, zone->minretry,
- zone->maxretry);
- zone->expire = RANGE(expire,
- zone->refresh + zone->retry,
- DNS_MAX_EXPIRE);
- zone->minimum = minimum;
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
- }
-
- /*
- * Set our next update/expire times.
- */
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
- zone->refreshtime = now;
- DNS_ZONE_TIME_ADD(&now, zone->expire,
- &zone->expiretime);
- } else {
- DNS_ZONE_JITTER_ADD(&now, zone->refresh,
- &zone->refreshtime);
- DNS_ZONE_TIME_ADD(&now, zone->expire,
- &zone->expiretime);
- }
- if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) {
- char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")];
- if (zone->tsigkey != NULL) {
- char namebuf[DNS_NAME_FORMATSIZE];
- dns_name_format(&zone->tsigkey->name, namebuf,
- sizeof(namebuf));
- snprintf(buf, sizeof(buf), ": TSIG '%s'",
- namebuf);
- } else
- buf[0] = '\0';
- dns_zone_log(zone, ISC_LOG_INFO,
- "transferred serial %u%s",
- serial, buf);
- if (inline_raw(zone))
- zone_send_secureserial(zone, ISC_FALSE, serial);
- }
-
- /*
- * This is not necessary if we just performed a AXFR
- * however it is necessary for an IXFR / UPTODATE and
- * won't hurt with an AXFR.
- */
- if (zone->masterfile != NULL || zone->journal != NULL) {
- unsigned int delay = DNS_DUMP_DELAY;
-
- result = ISC_R_FAILURE;
- if (zone->journal != NULL)
- result = isc_file_settime(zone->journal, &now);
- if (result != ISC_R_SUCCESS &&
- zone->masterfile != NULL)
- result = isc_file_settime(zone->masterfile,
- &now);
-
- if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY) != 0) ||
- result == ISC_R_FILENOTFOUND)
- delay = 0;
-
- if ((result == ISC_R_SUCCESS ||
- result == ISC_R_FILENOTFOUND) &&
- zone->masterfile != NULL)
- 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;
-
- case DNS_R_BADIXFR:
- /* Force retry with AXFR. */
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLAG_NOIXFR);
- goto same_master;
-
- default:
- next_master:
- /*
- * Skip to next failed / untried master.
- */
- do {
- zone->curmaster++;
- } while (zone->curmaster < zone->masterscnt &&
- zone->mastersok[zone->curmaster]);
- /* FALLTHROUGH */
- same_master:
- if (zone->curmaster >= zone->masterscnt) {
- zone->curmaster = 0;
- if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
- !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
- while (zone->curmaster < zone->masterscnt &&
- zone->mastersok[zone->curmaster])
- zone->curmaster++;
- again = ISC_TRUE;
- } else
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
- } else {
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
- again = ISC_TRUE;
- }
- inc_stats(zone, dns_zonestatscounter_xfrfail);
- break;
- }
- zone_settimer(zone, &now);
-
- /*
- * If creating the transfer object failed, zone->xfr is NULL.
- * Otherwise, we are called as the done callback of a zone
- * transfer object that just entered its shutting-down
- * state. Since we are no longer responsible for shutting
- * it down, we can detach our reference.
- */
- if (zone->xfr != NULL)
- dns_xfrin_detach(&zone->xfr);
-
- if (zone->tsigkey != NULL)
- dns_tsigkey_detach(&zone->tsigkey);
-
- /*
- * Handle any deferred journal compaction.
- */
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) {
- result = dns_journal_compact(zone->mctx, zone->journal,
- zone->compact_serial,
- zone->journalsize);
- switch (result) {
- case ISC_R_SUCCESS:
- case ISC_R_NOSPACE:
- case ISC_R_NOTFOUND:
- dns_zone_log(zone, ISC_LOG_DEBUG(3),
- "dns_journal_compact: %s",
- dns_result_totext(result));
- break;
- default:
- dns_zone_log(zone, ISC_LOG_ERROR,
- "dns_journal_compact failed: %s",
- dns_result_totext(result));
- break;
- }
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
- }
-
- /*
- * This transfer finishing freed up a transfer quota slot.
- * Let any other zones waiting for quota have it.
- */
- UNLOCK_ZONE(zone);
- RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
- ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink);
- zone->statelist = NULL;
- zmgr_resume_xfrs(zone->zmgr, ISC_FALSE);
- RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
- LOCK_ZONE(zone);
-
- /*
- * Retry with a different server if necessary.
- */
- if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
- queue_soa_query(zone);
-
- INSIST(zone->irefs > 0);
- zone->irefs--;
- free_needed = exit_check(zone);
- UNLOCK_ZONE(zone);
- if (free_needed)
- zone_free(zone);
-}
-
-static void
-zone_loaddone(void *arg, isc_result_t result) {
- static char me[] = "zone_loaddone";
- dns_load_t *load = arg;
- dns_zone_t *zone;
- isc_result_t tresult;
-
- REQUIRE(DNS_LOAD_VALID(load));
- zone = load->zone;
-
- ENTER;
-
- tresult = dns_db_endload(load->db, &load->callbacks.add_private);
- if (tresult != ISC_R_SUCCESS &&
- (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE))
- result = tresult;
-
- /*
- * Lock hierarchy: zmgr, zone, raw.
- */
- LOCK_ZONE(zone);
- if (inline_secure(zone))
- LOCK_ZONE(zone->raw);
- (void)zone_postload(zone, load->db, load->loadtime, result);
- zonemgr_putio(&zone->readio);
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADING);
- zone_idetach(&load->callbacks.zone);
- /*
- * Leave the zone frozen if the reload fails.
- */
- if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) &&
- DNS_ZONE_FLAG(zone, DNS_ZONEFLG_THAW))
- zone->update_disabled = ISC_FALSE;
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_THAW);
- if (inline_secure(zone))
- UNLOCK_ZONE(zone->raw);
- UNLOCK_ZONE(zone);
-
- load->magic = 0;
- dns_db_detach(&load->db);
- if (load->zone->lctx != NULL)
- dns_loadctx_detach(&load->zone->lctx);
- dns_zone_idetach(&load->zone);
- isc_mem_putanddetach(&load->mctx, load, sizeof(*load));
-}
-
-void
-dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) {
- REQUIRE(DNS_ZONE_VALID(zone));
- REQUIRE(table != NULL);
- REQUIRE(*table == NULL);
-
- LOCK_ZONE(zone);
- if (zone->ssutable != NULL)
- dns_ssutable_attach(zone->ssutable, table);
- UNLOCK_ZONE(zone);
-}
-
-void
-dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- if (zone->ssutable != NULL)
- dns_ssutable_detach(&zone->ssutable);
- if (table != NULL)
- dns_ssutable_attach(table, &zone->ssutable);
- UNLOCK_ZONE(zone);
-}
-
-void
-dns_zone_setsigvalidityinterval(dns_zone_t *zone, isc_uint32_t interval) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- zone->sigvalidityinterval = interval;
-}
-
-isc_uint32_t
-dns_zone_getsigvalidityinterval(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- return (zone->sigvalidityinterval);
-}
-
-void
-dns_zone_setsigresigninginterval(dns_zone_t *zone, isc_uint32_t interval) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- zone->sigresigninginterval = interval;
-}
-
-isc_uint32_t
-dns_zone_getsigresigninginterval(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- return (zone->sigresigninginterval);
-}
-
-static void
-queue_xfrin(dns_zone_t *zone) {
- const char me[] = "queue_xfrin";
- isc_result_t result;
- dns_zonemgr_t *zmgr = zone->zmgr;
-
- ENTER;
-
- INSIST(zone->statelist == NULL);
-
- RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
- ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink);
- LOCK_ZONE(zone);
- zone->irefs++;
- UNLOCK_ZONE(zone);
- zone->statelist = &zmgr->waiting_for_xfrin;
- result = zmgr_start_xfrin_ifquota(zmgr, zone);
- RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
-
- if (result == ISC_R_QUOTA) {
- dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
- "zone transfer deferred due to quota");
- } else if (result != ISC_R_SUCCESS) {
- dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
- "starting zone transfer: %s",
- isc_result_totext(result));
- }
-}
-
-/*
- * This event callback is called when a zone has received
- * any necessary zone transfer quota. This is the time
- * to go ahead and start the transfer.
- */
-static void
-got_transfer_quota(isc_task_t *task, isc_event_t *event) {
- isc_result_t result = ISC_R_SUCCESS;
- dns_peer_t *peer = NULL;
- char master[ISC_SOCKADDR_FORMATSIZE];
- char source[ISC_SOCKADDR_FORMATSIZE];
- dns_rdatatype_t xfrtype;
- dns_zone_t *zone = event->ev_arg;
- isc_netaddr_t masterip;
- isc_sockaddr_t sourceaddr;
- isc_sockaddr_t masteraddr;
- isc_time_t now;
- const char *soa_before = "";
-
- UNUSED(task);
-
- INSIST(task == zone->task);
-
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
- result = ISC_R_CANCELED;
- goto cleanup;
- }
-
- TIME_NOW(&now);
-
- isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
- if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
- &zone->sourceaddr, &now))
- {
- isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
- dns_zone_log(zone, ISC_LOG_INFO,
- "got_transfer_quota: skipping zone transfer as "
- "master %s (source %s) is unreachable (cached)",
- master, source);
- result = ISC_R_CANCELED;
- goto cleanup;
- }
-
- isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
- (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
-
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
- soa_before = "SOA before ";
- /*
- * Decide whether we should request IXFR or AXFR.
- */
- if (zone->db == NULL) {
- dns_zone_log(zone, ISC_LOG_DEBUG(1),
- "no database exists yet, requesting AXFR of "
- "initial version from %s", master);
- xfrtype = dns_rdatatype_axfr;
- } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
- dns_zone_log(zone, ISC_LOG_DEBUG(1),
- "forced reload, requesting AXFR of "
- "initial version from %s", master);
- xfrtype = dns_rdatatype_axfr;
- } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLAG_NOIXFR)) {
- dns_zone_log(zone, ISC_LOG_DEBUG(1),
- "retrying with AXFR from %s due to "
- "previous IXFR failure", master);
- xfrtype = dns_rdatatype_axfr;
- LOCK_ZONE(zone);
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLAG_NOIXFR);
- UNLOCK_ZONE(zone);
- } else {
- isc_boolean_t use_ixfr = ISC_TRUE;
- if (peer != NULL)
- result = dns_peer_getrequestixfr(peer, &use_ixfr);
- if (peer == NULL || result != ISC_R_SUCCESS)
- use_ixfr = zone->requestixfr;
- if (use_ixfr == ISC_FALSE) {
- dns_zone_log(zone, ISC_LOG_DEBUG(1),
- "IXFR disabled, requesting %sAXFR from %s",
- soa_before, master);
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
- xfrtype = dns_rdatatype_soa;
- else
- xfrtype = dns_rdatatype_axfr;
- } else {
- dns_zone_log(zone, ISC_LOG_DEBUG(1),
- "requesting IXFR from %s", master);
- xfrtype = dns_rdatatype_ixfr;
- }
- }
-
- /*
- * Determine if we should attempt to sign the request with TSIG.
- */
- result = ISC_R_NOTFOUND;
- /*
- * First, look for a tsig key in the master statement, then
- * try for a server key.
- */
- if ((zone->masterkeynames != NULL) &&
- (zone->masterkeynames[zone->curmaster] != NULL)) {
- dns_view_t *view = dns_zone_getview(zone);
- dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
- result = dns_view_gettsig(view, keyname, &zone->tsigkey);
- }
- if (zone->tsigkey == NULL)
- result = dns_view_getpeertsig(zone->view, &masterip,
- &zone->tsigkey);
-
- if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "could not get TSIG key for zone transfer: %s",
- isc_result_totext(result));
- }
-
- LOCK_ZONE(zone);
- masteraddr = zone->masteraddr;
- sourceaddr = zone->sourceaddr;
- UNLOCK_ZONE(zone);
- INSIST(isc_sockaddr_pf(&masteraddr) == isc_sockaddr_pf(&sourceaddr));
- result = dns_xfrin_create2(zone, xfrtype, &masteraddr, &sourceaddr,
- zone->tsigkey, zone->mctx,
- zone->zmgr->timermgr, zone->zmgr->socketmgr,
- zone->task, zone_xfrdone, &zone->xfr);
- if (result == ISC_R_SUCCESS) {
- LOCK_ZONE(zone);
- if (xfrtype == dns_rdatatype_axfr) {
- if (isc_sockaddr_pf(&masteraddr) == PF_INET)
- inc_stats(zone, dns_zonestatscounter_axfrreqv4);
- else
- inc_stats(zone, dns_zonestatscounter_axfrreqv6);
- } else if (xfrtype == dns_rdatatype_ixfr) {
- if (isc_sockaddr_pf(&masteraddr) == PF_INET)
- inc_stats(zone, dns_zonestatscounter_ixfrreqv4);
- else
- inc_stats(zone, dns_zonestatscounter_ixfrreqv6);
- }
- UNLOCK_ZONE(zone);
- }
- cleanup:
- /*
- * Any failure in this function is handled like a failed
- * zone transfer. This ensures that we get removed from
- * zmgr->xfrin_in_progress.
- */
- if (result != ISC_R_SUCCESS)
- zone_xfrdone(zone, result);
-
- isc_event_free(&event);
-}
-
-/*
- * Update forwarding support.
- */
-
-static void
-forward_destroy(dns_forward_t *forward) {
-
- forward->magic = 0;
- if (forward->request != NULL)
- dns_request_destroy(&forward->request);
- if (forward->msgbuf != NULL)
- isc_buffer_free(&forward->msgbuf);
- if (forward->zone != NULL) {
- LOCK(&forward->zone->lock);
- if (ISC_LINK_LINKED(forward, link))
- ISC_LIST_UNLINK(forward->zone->forwards, forward, link);
- UNLOCK(&forward->zone->lock);
- dns_zone_idetach(&forward->zone);
- }
- isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward));
-}
-
-static isc_result_t
-sendtomaster(dns_forward_t *forward) {
- isc_result_t result;
- isc_sockaddr_t src;
-
- LOCK_ZONE(forward->zone);
-
- if (DNS_ZONE_FLAG(forward->zone, DNS_ZONEFLG_EXITING)) {
- UNLOCK_ZONE(forward->zone);
- return (ISC_R_CANCELED);
- }
-
- if (forward->which >= forward->zone->masterscnt) {
- UNLOCK_ZONE(forward->zone);
- return (ISC_R_NOMORE);
- }
-
- forward->addr = forward->zone->masters[forward->which];
- /*
- * Always use TCP regardless of whether the original update
- * used TCP.
- * XXX The timeout may but a bit small if we are far down a
- * transfer graph and the master has to try several masters.
- */
- switch (isc_sockaddr_pf(&forward->addr)) {
- case PF_INET:
- src = forward->zone->xfrsource4;
- break;
- case PF_INET6:
- src = forward->zone->xfrsource6;
- break;
- default:
- result = ISC_R_NOTIMPLEMENTED;
- goto unlock;
- }
- result = dns_request_createraw(forward->zone->view->requestmgr,
- forward->msgbuf,
- &src, &forward->addr,
- DNS_REQUESTOPT_TCP, 15 /* XXX */,
- forward->zone->task,
- forward_callback, forward,
- &forward->request);
- if (result == ISC_R_SUCCESS) {
- if (!ISC_LINK_LINKED(forward, link))
- ISC_LIST_APPEND(forward->zone->forwards, forward, link);
- }
-
- unlock:
- UNLOCK_ZONE(forward->zone);
- return (result);
-}
-
-static void
-forward_callback(isc_task_t *task, isc_event_t *event) {
- const char me[] = "forward_callback";
- dns_requestevent_t *revent = (dns_requestevent_t *)event;
- dns_message_t *msg = NULL;
- char master[ISC_SOCKADDR_FORMATSIZE];
- isc_result_t result;
- dns_forward_t *forward;
- dns_zone_t *zone;
-
- UNUSED(task);
-
- forward = revent->ev_arg;
- INSIST(DNS_FORWARD_VALID(forward));
- zone = forward->zone;
- INSIST(DNS_ZONE_VALID(zone));
-
- ENTER;
-
- isc_sockaddr_format(&forward->addr, master, sizeof(master));
-
- if (revent->result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_INFO,
- "could not forward dynamic update to %s: %s",
- master, dns_result_totext(revent->result));
- goto next_master;
- }
-
- result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
- if (result != ISC_R_SUCCESS)
- goto next_master;
-
- result = dns_request_getresponse(revent->request, msg,
- DNS_MESSAGEPARSE_PRESERVEORDER |
- DNS_MESSAGEPARSE_CLONEBUFFER);
- if (result != ISC_R_SUCCESS)
- goto next_master;
-
- switch (msg->rcode) {
- /*
- * Pass these rcodes back to client.
- */
- case dns_rcode_noerror:
- case dns_rcode_yxdomain:
- case dns_rcode_yxrrset:
- case dns_rcode_nxrrset:
- case dns_rcode_refused:
- case dns_rcode_nxdomain:
- break;
-
- /* These should not occur if the masters/zone are valid. */
- case dns_rcode_notzone:
- case dns_rcode_notauth: {
- char rcode[128];
- isc_buffer_t rb;
-
- isc_buffer_init(&rb, rcode, sizeof(rcode));
- (void)dns_rcode_totext(msg->rcode, &rb);
- dns_zone_log(zone, ISC_LOG_WARNING,
- "forwarding dynamic update: "
- "unexpected response: master %s returned: %.*s",
- master, (int)rb.used, rcode);
- goto next_master;
- }
-
- /* Try another server for these rcodes. */
- case dns_rcode_formerr:
- case dns_rcode_servfail:
- case dns_rcode_notimp:
- case dns_rcode_badvers:
- default:
- goto next_master;
- }
-
- /* call callback */
- (forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg);
- msg = NULL;
- dns_request_destroy(&forward->request);
- forward_destroy(forward);
- isc_event_free(&event);
- return;
-
- next_master:
- if (msg != NULL)
- dns_message_destroy(&msg);
- isc_event_free(&event);
- forward->which++;
- dns_request_destroy(&forward->request);
- result = sendtomaster(forward);
- if (result != ISC_R_SUCCESS) {
- /* call callback */
- dns_zone_log(zone, ISC_LOG_DEBUG(3),
- "exhausted dynamic update forwarder list");
- (forward->callback)(forward->callback_arg, result, NULL);
- forward_destroy(forward);
- }
-}
-
-isc_result_t
-dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg,
- dns_updatecallback_t callback, void *callback_arg)
-{
- dns_forward_t *forward;
- isc_result_t result;
- isc_region_t *mr;
-
- REQUIRE(DNS_ZONE_VALID(zone));
- REQUIRE(msg != NULL);
- REQUIRE(callback != NULL);
-
- forward = isc_mem_get(zone->mctx, sizeof(*forward));
- if (forward == NULL)
- return (ISC_R_NOMEMORY);
-
- forward->request = NULL;
- forward->zone = NULL;
- forward->msgbuf = NULL;
- forward->which = 0;
- forward->mctx = 0;
- forward->callback = callback;
- forward->callback_arg = callback_arg;
- ISC_LINK_INIT(forward, link);
- forward->magic = FORWARD_MAGIC;
-
- mr = dns_message_getrawmessage(msg);
- if (mr == NULL) {
- result = ISC_R_UNEXPECTEDEND;
- goto cleanup;
- }
-
- result = isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- result = isc_buffer_copyregion(forward->msgbuf, mr);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- isc_mem_attach(zone->mctx, &forward->mctx);
- dns_zone_iattach(zone, &forward->zone);
- result = sendtomaster(forward);
-
- cleanup:
- if (result != ISC_R_SUCCESS) {
- forward_destroy(forward);
- }
- return (result);
-}
-
-isc_result_t
-dns_zone_next(dns_zone_t *zone, dns_zone_t **next) {
- REQUIRE(DNS_ZONE_VALID(zone));
- REQUIRE(next != NULL && *next == NULL);
-
- *next = ISC_LIST_NEXT(zone, link);
- if (*next == NULL)
- return (ISC_R_NOMORE);
- else
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) {
- REQUIRE(DNS_ZONEMGR_VALID(zmgr));
- REQUIRE(first != NULL && *first == NULL);
-
- *first = ISC_LIST_HEAD(zmgr->zones);
- if (*first == NULL)
- return (ISC_R_NOMORE);
- else
- return (ISC_R_SUCCESS);
-}
-
-/***
- *** Zone manager.
- ***/
-
-isc_result_t
-dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
- isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
- dns_zonemgr_t **zmgrp)
-{
- dns_zonemgr_t *zmgr;
- isc_result_t result;
- isc_interval_t interval;
-
- zmgr = isc_mem_get(mctx, sizeof(*zmgr));
- if (zmgr == NULL)
- return (ISC_R_NOMEMORY);
- zmgr->mctx = NULL;
- zmgr->refs = 1;
- isc_mem_attach(mctx, &zmgr->mctx);
- zmgr->taskmgr = taskmgr;
- zmgr->timermgr = timermgr;
- zmgr->socketmgr = socketmgr;
- zmgr->zonetasks = NULL;
- zmgr->loadtasks = NULL;
- zmgr->mctxpool = NULL;
- zmgr->task = NULL;
- zmgr->rl = NULL;
- ISC_LIST_INIT(zmgr->zones);
- ISC_LIST_INIT(zmgr->waiting_for_xfrin);
- ISC_LIST_INIT(zmgr->xfrin_in_progress);
- memset(zmgr->unreachable, 0, sizeof(zmgr->unreachable));
- result = isc_rwlock_init(&zmgr->rwlock, 0, 0);
- if (result != ISC_R_SUCCESS)
- goto free_mem;
-
- zmgr->transfersin = 10;
- zmgr->transfersperns = 2;
-
- /* Unreachable lock. */
- result = isc_rwlock_init(&zmgr->urlock, 0, 0);
- if (result != ISC_R_SUCCESS)
- goto free_rwlock;
-
- /* Create a single task for queueing of SOA queries. */
- result = isc_task_create(taskmgr, 1, &zmgr->task);
- if (result != ISC_R_SUCCESS)
- goto free_urlock;
-
- isc_task_setname(zmgr->task, "zmgr", zmgr);
- result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
- &zmgr->rl);
- if (result != ISC_R_SUCCESS)
- goto free_task;
-
- /* default to 20 refresh queries / notifies per second. */
- isc_interval_set(&interval, 0, 1000000000/2);
- result = isc_ratelimiter_setinterval(zmgr->rl, &interval);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- isc_ratelimiter_setpertic(zmgr->rl, 10);
-
- zmgr->iolimit = 1;
- zmgr->ioactive = 0;
- ISC_LIST_INIT(zmgr->high);
- ISC_LIST_INIT(zmgr->low);
-
- result = isc_mutex_init(&zmgr->iolock);
- if (result != ISC_R_SUCCESS)
- goto free_rl;
-
- zmgr->magic = ZONEMGR_MAGIC;
-
- *zmgrp = zmgr;
- return (ISC_R_SUCCESS);
-
-#if 0
- free_iolock:
- DESTROYLOCK(&zmgr->iolock);
-#endif
- free_rl:
- isc_ratelimiter_detach(&zmgr->rl);
- free_task:
- isc_task_detach(&zmgr->task);
- free_urlock:
- isc_rwlock_destroy(&zmgr->urlock);
- free_rwlock:
- isc_rwlock_destroy(&zmgr->rwlock);
- free_mem:
- isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
- isc_mem_detach(&mctx);
- return (result);
-}
-
-isc_result_t
-dns_zonemgr_createzone(dns_zonemgr_t *zmgr, dns_zone_t **zonep) {
- isc_result_t result;
- isc_mem_t *mctx = NULL;
- dns_zone_t *zone = NULL;
- void *item;
-
- REQUIRE(DNS_ZONEMGR_VALID(zmgr));
- REQUIRE(zonep != NULL && *zonep == NULL);
-
- if (zmgr->mctxpool == NULL)
- return (ISC_R_FAILURE);
-
- item = isc_pool_get(zmgr->mctxpool);
- if (item == NULL)
- return (ISC_R_FAILURE);
-
- isc_mem_attach((isc_mem_t *) item, &mctx);
- result = dns_zone_create(&zone, mctx);
- isc_mem_detach(&mctx);
-
- if (result == ISC_R_SUCCESS)
- *zonep = zone;
-
- return (result);
-}
-
-isc_result_t
-dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
- isc_result_t result;
-
- REQUIRE(DNS_ZONE_VALID(zone));
- REQUIRE(DNS_ZONEMGR_VALID(zmgr));
-
- if (zmgr->zonetasks == NULL)
- return (ISC_R_FAILURE);
-
- RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
- LOCK_ZONE(zone);
- REQUIRE(zone->task == NULL);
- REQUIRE(zone->timer == NULL);
- REQUIRE(zone->zmgr == NULL);
-
- isc_taskpool_gettask(zmgr->zonetasks, &zone->task);
- isc_taskpool_gettask(zmgr->loadtasks, &zone->loadtask);
-
- /*
- * Set the task name. The tag will arbitrarily point to one
- * of the zones sharing the task (in practice, the one
- * to be managed last).
- */
- isc_task_setname(zone->task, "zone", zone);
- isc_task_setname(zone->loadtask, "loadzone", zone);
-
- result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
- NULL, NULL,
- zone->task, zone_timer, zone,
- &zone->timer);
-
- if (result != ISC_R_SUCCESS)
- goto cleanup_tasks;
-
- /*
- * The timer "holds" a iref.
- */
- zone->irefs++;
- INSIST(zone->irefs != 0);
-
- ISC_LIST_APPEND(zmgr->zones, zone, link);
- zone->zmgr = zmgr;
- zmgr->refs++;
-
- goto unlock;
-
- cleanup_tasks:
- isc_task_detach(&zone->loadtask);
- isc_task_detach(&zone->task);
-
- unlock:
- UNLOCK_ZONE(zone);
- RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
- return (result);
-}
-
-void
-dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
- isc_boolean_t free_now = ISC_FALSE;
-
- REQUIRE(DNS_ZONE_VALID(zone));
- REQUIRE(DNS_ZONEMGR_VALID(zmgr));
- REQUIRE(zone->zmgr == zmgr);
-
- RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
- LOCK_ZONE(zone);
-
- ISC_LIST_UNLINK(zmgr->zones, zone, link);
- zone->zmgr = NULL;
- zmgr->refs--;
- if (zmgr->refs == 0)
- free_now = ISC_TRUE;
-
- UNLOCK_ZONE(zone);
- RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
-
- if (free_now)
- zonemgr_free(zmgr);
- ENSURE(zone->zmgr == NULL);
-}
-
-void
-dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) {
- REQUIRE(DNS_ZONEMGR_VALID(source));
- REQUIRE(target != NULL && *target == NULL);
-
- RWLOCK(&source->rwlock, isc_rwlocktype_write);
- REQUIRE(source->refs > 0);
- source->refs++;
- INSIST(source->refs > 0);
- RWUNLOCK(&source->rwlock, isc_rwlocktype_write);
- *target = source;
-}
-
-void
-dns_zonemgr_detach(dns_zonemgr_t **zmgrp) {
- dns_zonemgr_t *zmgr;
- isc_boolean_t free_now = ISC_FALSE;
-
- REQUIRE(zmgrp != NULL);
- zmgr = *zmgrp;
- REQUIRE(DNS_ZONEMGR_VALID(zmgr));
-
- RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
- zmgr->refs--;
- if (zmgr->refs == 0)
- free_now = ISC_TRUE;
- RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
-
- if (free_now)
- zonemgr_free(zmgr);
- *zmgrp = NULL;
-}
-
-isc_result_t
-dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) {
- dns_zone_t *p;
-
- REQUIRE(DNS_ZONEMGR_VALID(zmgr));
-
- RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
- for (p = ISC_LIST_HEAD(zmgr->zones);
- p != NULL;
- p = ISC_LIST_NEXT(p, link))
- {
- dns_zone_maintenance(p);
- }
- RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
-
- /*
- * Recent configuration changes may have increased the
- * amount of available transfers quota. Make sure any
- * transfers currently blocked on quota get started if
- * possible.
- */
- RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
- zmgr_resume_xfrs(zmgr, ISC_TRUE);
- RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
- return (ISC_R_SUCCESS);
-}
-
-void
-dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) {
-
- REQUIRE(DNS_ZONEMGR_VALID(zmgr));
-
- RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
- zmgr_resume_xfrs(zmgr, ISC_TRUE);
- RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
-}
-
-void
-dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
- dns_zone_t *zone;
-
- REQUIRE(DNS_ZONEMGR_VALID(zmgr));
-
- isc_ratelimiter_shutdown(zmgr->rl);
-
- if (zmgr->task != NULL)
- isc_task_destroy(&zmgr->task);
- if (zmgr->zonetasks != NULL)
- isc_taskpool_destroy(&zmgr->zonetasks);
- if (zmgr->loadtasks != NULL)
- isc_taskpool_destroy(&zmgr->loadtasks);
- if (zmgr->mctxpool != NULL)
- isc_pool_destroy(&zmgr->mctxpool);
-
- RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
- for (zone = ISC_LIST_HEAD(zmgr->zones);
- zone != NULL;
- zone = ISC_LIST_NEXT(zone, link))
- {
- LOCK_ZONE(zone);
- forward_cancel(zone);
- UNLOCK_ZONE(zone);
- }
- RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
-}
-
-static isc_result_t
-mctxinit(void **target, void *arg) {
- isc_result_t result;
- isc_mem_t *mctx = NULL;
-
- UNUSED(arg);
-
- REQUIRE(target != NULL && *target == NULL);
-
- result = isc_mem_create(0, 0, &mctx);
- if (result != ISC_R_SUCCESS)
- return (result);
- isc_mem_setname(mctx, "zonemgr-pool", NULL);
-
- *target = mctx;
- return (ISC_R_SUCCESS);
-}
-
-static void
-mctxfree(void **target) {
- isc_mem_t *mctx = *(isc_mem_t **) target;
- isc_mem_detach(&mctx);
- *target = NULL;
-}
-
-#define ZONES_PER_TASK 100
-#define ZONES_PER_MCTX 1000
-
-isc_result_t
-dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones) {
- isc_result_t result;
- int ntasks = num_zones / ZONES_PER_TASK;
- int nmctx = num_zones / ZONES_PER_MCTX;
- isc_taskpool_t *pool = NULL;
- isc_pool_t *mctxpool = NULL;
-
- REQUIRE(DNS_ZONEMGR_VALID(zmgr));
-
- /*
- * For anything fewer than 1000 zones we use 10 tasks in
- * the task pools. More than that, and we'll scale at one
- * task per 100 zones. Similarly, for anything smaller than
- * 2000 zones we use 2 memory contexts, then scale at 1:1000.
- */
- if (ntasks < 10)
- ntasks = 10;
- if (nmctx < 2)
- nmctx = 2;
-
- /* Create or resize the zone task pools. */
- if (zmgr->zonetasks == NULL)
- result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx,
- ntasks, 2, &pool);
- else
- result = isc_taskpool_expand(&zmgr->zonetasks, ntasks, &pool);
-
- if (result == ISC_R_SUCCESS)
- zmgr->zonetasks = pool;
-
- pool = NULL;
- if (zmgr->loadtasks == NULL)
- result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx,
- ntasks, 2, &pool);
- else
- result = isc_taskpool_expand(&zmgr->loadtasks, ntasks, &pool);
-
- if (result == ISC_R_SUCCESS)
- zmgr->loadtasks = pool;
-
-#ifdef BIND9
- /*
- * We always set all tasks in the zone-load task pool to
- * privileged. This prevents other tasks in the system from
- * running while the server task manager is in privileged
- * mode.
- *
- * NOTE: If we start using task privileges for any other
- * part of the system than zone tasks, then this will need to be
- * revisted. In that case we'd want to turn on privileges for
- * zone tasks only when we were loading, and turn them off the
- * rest of the time. For now, however, it's okay to just
- * set it and forget it.
- */
- isc_taskpool_setprivilege(zmgr->loadtasks, ISC_TRUE);
-#endif
-
- /* Create or resize the zone memory context pool. */
- if (zmgr->mctxpool == NULL)
- result = isc_pool_create(zmgr->mctx, nmctx, mctxfree,
- mctxinit, NULL, &mctxpool);
- else
- result = isc_pool_expand(&zmgr->mctxpool, nmctx, &mctxpool);
-
- if (result == ISC_R_SUCCESS)
- zmgr->mctxpool = mctxpool;
-
- return (result);
-}
-
-static void
-zonemgr_free(dns_zonemgr_t *zmgr) {
- isc_mem_t *mctx;
-
- INSIST(zmgr->refs == 0);
- INSIST(ISC_LIST_EMPTY(zmgr->zones));
-
- zmgr->magic = 0;
-
- DESTROYLOCK(&zmgr->iolock);
- isc_ratelimiter_detach(&zmgr->rl);
-
- isc_rwlock_destroy(&zmgr->urlock);
- isc_rwlock_destroy(&zmgr->rwlock);
- mctx = zmgr->mctx;
- isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
- isc_mem_detach(&mctx);
-}
-
-void
-dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, isc_uint32_t value) {
- REQUIRE(DNS_ZONEMGR_VALID(zmgr));
-
- zmgr->transfersin = value;
-}
-
-isc_uint32_t
-dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr) {
- REQUIRE(DNS_ZONEMGR_VALID(zmgr));
-
- return (zmgr->transfersin);
-}
-
-void
-dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, isc_uint32_t value) {
- REQUIRE(DNS_ZONEMGR_VALID(zmgr));
-
- zmgr->transfersperns = value;
-}
-
-isc_uint32_t
-dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr) {
- REQUIRE(DNS_ZONEMGR_VALID(zmgr));
-
- return (zmgr->transfersperns);
-}
-
-/*
- * Try to start a new incoming zone transfer to fill a quota
- * slot that was just vacated.
- *
- * Requires:
- * The zone manager is locked by the caller.
- */
-static void
-zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi) {
- dns_zone_t *zone;
- dns_zone_t *next;
-
- for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
- zone != NULL;
- zone = next)
- {
- isc_result_t result;
- next = ISC_LIST_NEXT(zone, statelink);
- result = zmgr_start_xfrin_ifquota(zmgr, zone);
- if (result == ISC_R_SUCCESS) {
- if (multi)
- continue;
- /*
- * We successfully filled the slot. We're done.
- */
- break;
- } else if (result == ISC_R_QUOTA) {
- /*
- * Not enough quota. This is probably the per-server
- * quota, because we usually get called when a unit of
- * global quota has just been freed. Try the next
- * zone, it may succeed if it uses another master.
- */
- continue;
- } else {
- dns_zone_log(zone, ISC_LOG_DEBUG(1),
- "starting zone transfer: %s",
- isc_result_totext(result));
- break;
- }
- }
-}
-
-/*
- * Try to start an incoming zone transfer for 'zone', quota permitting.
- *
- * Requires:
- * The zone manager is locked by the caller.
- *
- * Returns:
- * ISC_R_SUCCESS There was enough quota and we attempted to
- * start a transfer. zone_xfrdone() has been or will
- * be called.
- * ISC_R_QUOTA Not enough quota.
- * Others Failure.
- */
-static isc_result_t
-zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
- dns_peer_t *peer = NULL;
- isc_netaddr_t masterip;
- isc_uint32_t nxfrsin, nxfrsperns;
- dns_zone_t *x;
- isc_uint32_t maxtransfersin, maxtransfersperns;
- isc_event_t *e;
-
- /*
- * If we are exiting just pretend we got quota so the zone will
- * be cleaned up in the zone's task context.
- */
- LOCK_ZONE(zone);
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
- UNLOCK_ZONE(zone);
- goto gotquota;
- }
-
- /*
- * Find any configured information about the server we'd
- * like to transfer this zone from.
- */
- isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
- (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
- UNLOCK_ZONE(zone);
-
- /*
- * Determine the total maximum number of simultaneous
- * transfers allowed, and the maximum for this specific
- * master.
- */
- maxtransfersin = zmgr->transfersin;
- maxtransfersperns = zmgr->transfersperns;
- if (peer != NULL)
- (void)dns_peer_gettransfers(peer, &maxtransfersperns);
-
- /*
- * Count the total number of transfers that are in progress,
- * and the number of transfers in progress from this master.
- * We linearly scan a list of all transfers; if this turns
- * out to be too slow, we could hash on the master address.
- */
- nxfrsin = nxfrsperns = 0;
- for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
- x != NULL;
- x = ISC_LIST_NEXT(x, statelink))
- {
- isc_netaddr_t xip;
-
- LOCK_ZONE(x);
- isc_netaddr_fromsockaddr(&xip, &x->masteraddr);
- UNLOCK_ZONE(x);
-
- nxfrsin++;
- if (isc_netaddr_equal(&xip, &masterip))
- nxfrsperns++;
- }
-
- /* Enforce quota. */
- if (nxfrsin >= maxtransfersin)
- return (ISC_R_QUOTA);
-
- if (nxfrsperns >= maxtransfersperns)
- return (ISC_R_QUOTA);
-
- gotquota:
- /*
- * We have sufficient quota. Move the zone to the "xfrin_in_progress"
- * list and send it an event to let it start the actual transfer in the
- * context of its own task.
- */
- e = isc_event_allocate(zmgr->mctx, zmgr, DNS_EVENT_ZONESTARTXFRIN,
- got_transfer_quota, zone, sizeof(isc_event_t));
- if (e == NULL)
- return (ISC_R_NOMEMORY);
-
- LOCK_ZONE(zone);
- INSIST(zone->statelist == &zmgr->waiting_for_xfrin);
- ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink);
- ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink);
- zone->statelist = &zmgr->xfrin_in_progress;
- isc_task_send(zone->task, &e);
- dns_zone_log(zone, ISC_LOG_INFO, "Transfer started.");
- UNLOCK_ZONE(zone);
-
- return (ISC_R_SUCCESS);
-}
-
-void
-dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, isc_uint32_t iolimit) {
-
- REQUIRE(DNS_ZONEMGR_VALID(zmgr));
- REQUIRE(iolimit > 0);
-
- zmgr->iolimit = iolimit;
-}
-
-isc_uint32_t
-dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr) {
-
- REQUIRE(DNS_ZONEMGR_VALID(zmgr));
-
- return (zmgr->iolimit);
-}
-
-/*
- * Get permission to request a file handle from the OS.
- * An event will be sent to action when one is available.
- * There are two queues available (high and low), the high
- * queue will be serviced before the low one.
- *
- * zonemgr_putio() must be called after the event is delivered to
- * 'action'.
- */
-
-static isc_result_t
-zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
- isc_task_t *task, isc_taskaction_t action, void *arg,
- dns_io_t **iop)
-{
- dns_io_t *io;
- isc_boolean_t queue;
-
- REQUIRE(DNS_ZONEMGR_VALID(zmgr));
- REQUIRE(iop != NULL && *iop == NULL);
-
- io = isc_mem_get(zmgr->mctx, sizeof(*io));
- if (io == NULL)
- return (ISC_R_NOMEMORY);
-
- io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY,
- action, arg, sizeof(*io->event));
- if (io->event == NULL) {
- isc_mem_put(zmgr->mctx, io, sizeof(*io));
- return (ISC_R_NOMEMORY);
- }
-
- io->zmgr = zmgr;
- io->high = high;
- io->task = NULL;
- isc_task_attach(task, &io->task);
- ISC_LINK_INIT(io, link);
- io->magic = IO_MAGIC;
-
- LOCK(&zmgr->iolock);
- zmgr->ioactive++;
- queue = ISC_TF(zmgr->ioactive > zmgr->iolimit);
- if (queue) {
- if (io->high)
- ISC_LIST_APPEND(zmgr->high, io, link);
- else
- ISC_LIST_APPEND(zmgr->low, io, link);
- }
- UNLOCK(&zmgr->iolock);
- *iop = io;
-
- if (!queue)
- isc_task_send(io->task, &io->event);
- return (ISC_R_SUCCESS);
-}
-
-static void
-zonemgr_putio(dns_io_t **iop) {
- dns_io_t *io;
- dns_io_t *next;
- dns_zonemgr_t *zmgr;
-
- REQUIRE(iop != NULL);
- io = *iop;
- REQUIRE(DNS_IO_VALID(io));
-
- *iop = NULL;
-
- INSIST(!ISC_LINK_LINKED(io, link));
- INSIST(io->event == NULL);
-
- zmgr = io->zmgr;
- isc_task_detach(&io->task);
- io->magic = 0;
- isc_mem_put(zmgr->mctx, io, sizeof(*io));
-
- LOCK(&zmgr->iolock);
- INSIST(zmgr->ioactive > 0);
- zmgr->ioactive--;
- next = HEAD(zmgr->high);
- if (next == NULL)
- next = HEAD(zmgr->low);
- if (next != NULL) {
- if (next->high)
- ISC_LIST_UNLINK(zmgr->high, next, link);
- else
- ISC_LIST_UNLINK(zmgr->low, next, link);
- INSIST(next->event != NULL);
- }
- UNLOCK(&zmgr->iolock);
- if (next != NULL)
- isc_task_send(next->task, &next->event);
-}
-
-static void
-zonemgr_cancelio(dns_io_t *io) {
- isc_boolean_t send_event = ISC_FALSE;
-
- REQUIRE(DNS_IO_VALID(io));
-
- /*
- * If we are queued to be run then dequeue.
- */
- LOCK(&io->zmgr->iolock);
- if (ISC_LINK_LINKED(io, link)) {
- if (io->high)
- ISC_LIST_UNLINK(io->zmgr->high, io, link);
- else
- ISC_LIST_UNLINK(io->zmgr->low, io, link);
-
- send_event = ISC_TRUE;
- INSIST(io->event != NULL);
- }
- UNLOCK(&io->zmgr->iolock);
- if (send_event) {
- io->event->ev_attributes |= ISC_EVENTATTR_CANCELED;
- isc_task_send(io->task, &io->event);
- }
-}
-
-static void
-zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) {
- char *buf;
- int buflen;
- isc_result_t result;
-
- buflen = strlen(path) + strlen(templat) + 2;
-
- buf = isc_mem_get(zone->mctx, buflen);
- if (buf == NULL)
- return;
-
- result = isc_file_template(path, templat, buf, buflen);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- result = isc_file_renameunique(path, buf);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- dns_zone_log(zone, ISC_LOG_WARNING, "unable to load from '%s'; "
- "renaming file to '%s' for failure analysis and "
- "retransferring.", path, buf);
-
- cleanup:
- isc_mem_put(zone->mctx, buf, buflen);
-}
-
-#if 0
-/* Hook for ondestroy notification from a database. */
-
-static void
-dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event) {
- dns_db_t *db = event->sender;
- UNUSED(task);
-
- isc_event_free(&event);
-
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
- DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
- "database (%p) destroyed", (void*) db);
-}
-#endif
-
-void
-dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) {
- isc_interval_t interval;
- isc_uint32_t s, ns;
- isc_uint32_t pertic;
- isc_result_t result;
-
- REQUIRE(DNS_ZONEMGR_VALID(zmgr));
-
- if (value == 0)
- value = 1;
-
- if (value == 1) {
- s = 1;
- ns = 0;
- pertic = 1;
- } else if (value <= 10) {
- s = 0;
- ns = 1000000000 / value;
- pertic = 1;
- } else {
- s = 0;
- ns = (1000000000 / value) * 10;
- pertic = 10;
- }
-
- isc_interval_set(&interval, s, ns);
- result = isc_ratelimiter_setinterval(zmgr->rl, &interval);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- isc_ratelimiter_setpertic(zmgr->rl, pertic);
-
- zmgr->serialqueryrate = value;
-}
-
-unsigned int
-dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) {
- REQUIRE(DNS_ZONEMGR_VALID(zmgr));
-
- return (zmgr->serialqueryrate);
-}
-
-isc_boolean_t
-dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
- isc_sockaddr_t *local, isc_time_t *now)
-{
- unsigned int i;
- isc_rwlocktype_t locktype;
- isc_result_t result;
- isc_uint32_t seconds = isc_time_seconds(now);
-
- REQUIRE(DNS_ZONEMGR_VALID(zmgr));
-
- locktype = isc_rwlocktype_read;
- RWLOCK(&zmgr->urlock, locktype);
- for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
- if (zmgr->unreachable[i].expire >= seconds &&
- isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
- isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
- result = isc_rwlock_tryupgrade(&zmgr->urlock);
- if (result == ISC_R_SUCCESS) {
- locktype = isc_rwlocktype_write;
- zmgr->unreachable[i].last = seconds;
- }
- break;
- }
- }
- RWUNLOCK(&zmgr->urlock, locktype);
- return (ISC_TF(i < UNREACH_CHACHE_SIZE));
-}
-
-void
-dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
- isc_sockaddr_t *local)
-{
- unsigned int i;
- isc_rwlocktype_t locktype;
- isc_result_t result;
-
- char master[ISC_SOCKADDR_FORMATSIZE];
- char source[ISC_SOCKADDR_FORMATSIZE];
-
- isc_sockaddr_format(remote, master, sizeof(master));
- isc_sockaddr_format(local, source, sizeof(source));
-
- REQUIRE(DNS_ZONEMGR_VALID(zmgr));
-
- locktype = isc_rwlocktype_read;
- RWLOCK(&zmgr->urlock, locktype);
- for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
- if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
- isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
- if (zmgr->unreachable[i].expire == 0)
- break;
- result = isc_rwlock_tryupgrade(&zmgr->urlock);
- if (result == ISC_R_SUCCESS) {
- locktype = isc_rwlocktype_write;
- zmgr->unreachable[i].expire = 0;
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
- DNS_LOGMODULE_ZONE, ISC_LOG_INFO,
- "master %s (source %s) deleted "
- "from unreachable cache",
- master, source);
- }
- break;
- }
- }
- RWUNLOCK(&zmgr->urlock, locktype);
-}
-
-void
-dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
- isc_sockaddr_t *local, isc_time_t *now)
-{
- isc_uint32_t seconds = isc_time_seconds(now);
- isc_uint32_t last = seconds;
- unsigned int i, slot = UNREACH_CHACHE_SIZE, oldest = 0;
-
- REQUIRE(DNS_ZONEMGR_VALID(zmgr));
-
- RWLOCK(&zmgr->urlock, isc_rwlocktype_write);
- for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
- /* Existing entry? */
- if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
- isc_sockaddr_equal(&zmgr->unreachable[i].local, local))
- break;
- /* Empty slot? */
- if (zmgr->unreachable[i].expire < seconds)
- slot = i;
- /* Least recently used slot? */
- if (zmgr->unreachable[i].last < last) {
- last = zmgr->unreachable[i].last;
- oldest = i;
- }
- }
- if (i < UNREACH_CHACHE_SIZE) {
- /*
- * Found a existing entry. Update the expire timer and
- * last usage timestamps.
- */
- zmgr->unreachable[i].expire = seconds + UNREACH_HOLD_TIME;
- zmgr->unreachable[i].last = seconds;
- } else if (slot != UNREACH_CHACHE_SIZE) {
- /*
- * Found a empty slot. Add a new entry to the cache.
- */
- zmgr->unreachable[slot].expire = seconds + UNREACH_HOLD_TIME;
- zmgr->unreachable[slot].last = seconds;
- zmgr->unreachable[slot].remote = *remote;
- zmgr->unreachable[slot].local = *local;
- } else {
- /*
- * Replace the least recently used entry in the cache.
- */
- zmgr->unreachable[oldest].expire = seconds + UNREACH_HOLD_TIME;
- zmgr->unreachable[oldest].last = seconds;
- zmgr->unreachable[oldest].remote = *remote;
- zmgr->unreachable[oldest].local = *local;
- }
- RWUNLOCK(&zmgr->urlock, isc_rwlocktype_write);
-}
-
-void
-dns_zone_forcereload(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- if (zone->type == dns_zone_master ||
- (zone->type == dns_zone_redirect && zone->masters == NULL))
- return;
-
- LOCK_ZONE(zone);
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER);
- UNLOCK_ZONE(zone);
- dns_zone_refresh(zone);
-}
-
-isc_boolean_t
-dns_zone_isforced(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER));
-}
-
-isc_result_t
-dns_zone_setstatistics(dns_zone_t *zone, isc_boolean_t on) {
- /*
- * This function is obsoleted.
- */
- UNUSED(zone);
- UNUSED(on);
- return (ISC_R_NOTIMPLEMENTED);
-}
-
-isc_uint64_t *
-dns_zone_getstatscounters(dns_zone_t *zone) {
- /*
- * This function is obsoleted.
- */
- UNUSED(zone);
- return (NULL);
-}
-
-void
-dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) {
- REQUIRE(DNS_ZONE_VALID(zone));
- REQUIRE(zone->stats == NULL);
-
- LOCK_ZONE(zone);
- zone->stats = NULL;
- isc_stats_attach(stats, &zone->stats);
- UNLOCK_ZONE(zone);
-}
-
-void
-dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) {
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- if (zone->requeststats_on && stats == NULL)
- zone->requeststats_on = ISC_FALSE;
- else if (!zone->requeststats_on && stats != NULL) {
- if (zone->requeststats == NULL) {
- isc_stats_attach(stats, &zone->requeststats);
- zone->requeststats_on = ISC_TRUE;
- }
- }
- UNLOCK_ZONE(zone);
-}
-
-#ifdef NEWSTATS
-void
-dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats) {
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- if (zone->requeststats_on && stats != NULL) {
- if (zone->rcvquerystats == NULL) {
- dns_stats_attach(stats, &zone->rcvquerystats);
- zone->requeststats_on = ISC_TRUE;
- }
- }
- UNLOCK_ZONE(zone);
-}
-#endif
-
-isc_stats_t *
-dns_zone_getrequeststats(dns_zone_t *zone) {
- /*
- * We don't lock zone for efficiency reason. This is not catastrophic
- * because requeststats must always be valid when requeststats_on is
- * true.
- * Some counters may be incremented while requeststats_on is becoming
- * false, or some cannot be incremented just after the statistics are
- * installed, but it shouldn't matter much in practice.
- */
- if (zone->requeststats_on)
- return (zone->requeststats);
- else
- return (NULL);
-}
-
-#ifdef NEWSTATS
-/*
- * Return the received query stats bucket
- * see note from dns_zone_getrequeststats()
- */
-dns_stats_t *
-dns_zone_getrcvquerystats(dns_zone_t *zone) {
- if (zone->requeststats_on)
- return (zone->rcvquerystats);
- else
- return (NULL);
-}
-#endif
-
-void
-dns_zone_dialup(dns_zone_t *zone) {
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- zone_debuglog(zone, "dns_zone_dialup", 3,
- "notify = %d, refresh = %d",
- DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY),
- DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH));
-
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
- dns_zone_notify(zone);
- if (zone->type != dns_zone_master && zone->masters != NULL &&
- DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
- dns_zone_refresh(zone);
-}
-
-void
-dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY |
- DNS_ZONEFLG_DIALREFRESH |
- DNS_ZONEFLG_NOREFRESH);
- switch (dialup) {
- case dns_dialuptype_no:
- break;
- case dns_dialuptype_yes:
- DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY |
- DNS_ZONEFLG_DIALREFRESH |
- DNS_ZONEFLG_NOREFRESH));
- break;
- case dns_dialuptype_notify:
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
- break;
- case dns_dialuptype_notifypassive:
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
- break;
- case dns_dialuptype_refresh:
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH);
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
- break;
- case dns_dialuptype_passive:
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
- break;
- default:
- INSIST(0);
- }
- UNLOCK_ZONE(zone);
-}
-
-isc_result_t
-dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) {
- isc_result_t result = ISC_R_SUCCESS;
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- result = dns_zone_setstring(zone, &zone->keydirectory, directory);
- UNLOCK_ZONE(zone);
-
- return (result);
-}
-
-const char *
-dns_zone_getkeydirectory(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- return (zone->keydirectory);
-}
-
-unsigned int
-dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) {
- dns_zone_t *zone;
- unsigned int count = 0;
-
- REQUIRE(DNS_ZONEMGR_VALID(zmgr));
-
- RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
- switch (state) {
- case DNS_ZONESTATE_XFERRUNNING:
- for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
- zone != NULL;
- zone = ISC_LIST_NEXT(zone, statelink))
- count++;
- break;
- case DNS_ZONESTATE_XFERDEFERRED:
- for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
- zone != NULL;
- zone = ISC_LIST_NEXT(zone, statelink))
- count++;
- break;
- case DNS_ZONESTATE_SOAQUERY:
- for (zone = ISC_LIST_HEAD(zmgr->zones);
- zone != NULL;
- zone = ISC_LIST_NEXT(zone, link))
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH))
- count++;
- break;
- case DNS_ZONESTATE_ANY:
- for (zone = ISC_LIST_HEAD(zmgr->zones);
- zone != NULL;
- zone = ISC_LIST_NEXT(zone, link)) {
- dns_view_t *view = zone->view;
- if (view != NULL && strcmp(view->name, "_bind") == 0)
- continue;
- count++;
- }
- break;
- default:
- INSIST(0);
- }
-
- RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
-
- return (count);
-}
-
-isc_result_t
-dns_zone_checknames(dns_zone_t *zone, dns_name_t *name, dns_rdata_t *rdata) {
- isc_boolean_t ok = ISC_TRUE;
- isc_boolean_t fail = ISC_FALSE;
- char namebuf[DNS_NAME_FORMATSIZE];
- char namebuf2[DNS_NAME_FORMATSIZE];
- char typebuf[DNS_RDATATYPE_FORMATSIZE];
- int level = ISC_LOG_WARNING;
- dns_name_t bad;
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
- return (ISC_R_SUCCESS);
-
- if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) {
- level = ISC_LOG_ERROR;
- fail = ISC_TRUE;
- }
-
- ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, ISC_TRUE);
- if (!ok) {
- dns_name_format(name, namebuf, sizeof(namebuf));
- dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
- dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf,
- dns_result_totext(DNS_R_BADOWNERNAME));
- if (fail)
- return (DNS_R_BADOWNERNAME);
- }
-
- dns_name_init(&bad, NULL);
- ok = dns_rdata_checknames(rdata, name, &bad);
- if (!ok) {
- dns_name_format(name, namebuf, sizeof(namebuf));
- dns_name_format(&bad, namebuf2, sizeof(namebuf2));
- dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
- dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf,
- namebuf2, dns_result_totext(DNS_R_BADNAME));
- if (fail)
- return (DNS_R_BADNAME);
- }
-
- return (ISC_R_SUCCESS);
-}
-
-void
-dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) {
- REQUIRE(DNS_ZONE_VALID(zone));
- zone->checkmx = checkmx;
-}
-
-void
-dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) {
- REQUIRE(DNS_ZONE_VALID(zone));
- zone->checksrv = checksrv;
-}
-
-void
-dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) {
- REQUIRE(DNS_ZONE_VALID(zone));
- zone->checkns = checkns;
-}
-
-void
-dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- zone->isself = isself;
- zone->isselfarg = arg;
- UNLOCK_ZONE(zone);
-}
-
-void
-dns_zone_setnotifydelay(dns_zone_t *zone, isc_uint32_t delay) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- zone->notifydelay = delay;
- UNLOCK_ZONE(zone);
-}
-
-isc_uint32_t
-dns_zone_getnotifydelay(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- return (zone->notifydelay);
-}
-
-isc_result_t
-dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
- isc_uint16_t keyid, isc_boolean_t delete)
-{
- isc_result_t result;
- REQUIRE(DNS_ZONE_VALID(zone));
-
- dns_zone_log(zone, ISC_LOG_NOTICE,
- "dns_zone_signwithkey(algorithm=%u, keyid=%u)",
- algorithm, keyid);
- LOCK_ZONE(zone);
- result = zone_signwithkey(zone, algorithm, keyid, delete);
- UNLOCK_ZONE(zone);
-
- return (result);
-}
-
-static const char *hex = "0123456789ABCDEF";
-
-isc_result_t
-dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
- isc_result_t result;
- char salt[255*2+1];
- unsigned int i, j;
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- if (nsec3param->salt_length != 0) {
- INSIST((nsec3param->salt_length * 2U) < sizeof(salt));
- for (i = 0, j = 0; i < nsec3param->salt_length; i++) {
- salt[j++] = hex[(nsec3param->salt[i] >> 4) & 0xf];
- salt[j++] = hex[nsec3param->salt[i] & 0xf];
- }
- salt[j] = '\0';
- } else
- strcpy(salt, "-");
- dns_zone_log(zone, ISC_LOG_NOTICE,
- "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)",
- nsec3param->hash, nsec3param->iterations,
- salt);
- LOCK_ZONE(zone);
- result = zone_addnsec3chain(zone, nsec3param);
- UNLOCK_ZONE(zone);
-
- return (result);
-}
-
-void
-dns_zone_setnodes(dns_zone_t *zone, isc_uint32_t nodes) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- if (nodes == 0)
- nodes = 1;
- zone->nodes = nodes;
-}
-
-void
-dns_zone_setsignatures(dns_zone_t *zone, isc_uint32_t signatures) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- /*
- * We treat signatures as a signed value so explicitly
- * limit its range here.
- */
- if (signatures > ISC_INT32_MAX)
- signatures = ISC_INT32_MAX;
- else if (signatures == 0)
- signatures = 1;
- zone->signatures = signatures;
-}
-
-void
-dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type) {
- REQUIRE(DNS_ZONE_VALID(zone));
- zone->privatetype = type;
-}
-
-dns_rdatatype_t
-dns_zone_getprivatetype(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
- return (zone->privatetype);
-}
-
-static isc_result_t
-zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid,
- isc_boolean_t delete)
-{
- dns_signing_t *signing;
- dns_signing_t *current;
- isc_result_t result = ISC_R_SUCCESS;
- isc_time_t now;
-
- signing = isc_mem_get(zone->mctx, sizeof *signing);
- if (signing == NULL)
- return (ISC_R_NOMEMORY);
-
- signing->magic = 0;
- signing->db = NULL;
- signing->dbiterator = NULL;
- signing->algorithm = algorithm;
- signing->keyid = keyid;
- signing->delete = delete;
- signing->done = ISC_FALSE;
-
- TIME_NOW(&now);
-
- for (current = ISC_LIST_HEAD(zone->signing);
- current != NULL;
- current = ISC_LIST_NEXT(current, link)) {
- if (current->db == zone->db &&
- current->algorithm == signing->algorithm &&
- current->keyid == signing->keyid) {
- if (current->delete != signing->delete)
- current->done = ISC_TRUE;
- else
- goto cleanup;
- }
- }
-
- if (zone->db != NULL) {
- dns_db_attach(zone->db, &signing->db);
- result = dns_db_createiterator(signing->db, 0,
- &signing->dbiterator);
-
- if (result == ISC_R_SUCCESS)
- result = dns_dbiterator_first(signing->dbiterator);
- if (result == ISC_R_SUCCESS) {
- dns_dbiterator_pause(signing->dbiterator);
- ISC_LIST_INITANDAPPEND(zone->signing, signing, link);
- signing = NULL;
- if (isc_time_isepoch(&zone->signingtime)) {
- zone->signingtime = now;
- if (zone->task != NULL)
- zone_settimer(zone, &now);
- }
- }
- } else
- result = ISC_R_NOTFOUND;
-
- cleanup:
- if (signing != NULL) {
- if (signing->db != NULL)
- dns_db_detach(&signing->db);
- if (signing->dbiterator != NULL)
- dns_dbiterator_destroy(&signing->dbiterator);
- isc_mem_put(zone->mctx, signing, sizeof *signing);
- }
- 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,
- isc_boolean_t sign_all)
-{
- 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;
-
- if (sign_all || tuple->op == DNS_DIFFOP_DEL) {
- 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, zonediff_t *zonediff)
-{
- isc_result_t result;
- isc_stdtime_t now, inception, soaexpire;
- isc_boolean_t check_ksk, keyset_kskonly;
- dst_key_t *zone_keys[DNS_MAXZONEKEYS];
- unsigned int nkeys = 0, i;
- dns_difftuple_t *tuple;
-
- result = find_zone_keys(zone, db, ver, zone->mctx, DNS_MAXZONEKEYS,
- zone_keys, &nkeys);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "sign_apex:find_zone_keys -> %s",
- 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, zonediff,
- zone_keys, nkeys, now, ISC_FALSE);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "sign_apex:del_sigs -> %s",
- dns_result_totext(result));
- goto failure;
- }
- result = add_sigs(db, ver, &zone->origin, dns_rdatatype_dnskey,
- zonediff->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",
- dns_result_totext(result));
- goto failure;
- }
- }
-
- result = update_sigs(diff, db, ver, zone_keys, nkeys, zone,
- inception, soaexpire, now, check_ksk,
- keyset_kskonly, zonediff);
-
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "sign_apex:update_sigs -> %s",
- 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) {
- result = dns_nsec_nseconly(db, ver, &nseconly);
- if (result == ISC_R_NOTFOUND)
- result = ISC_R_SUCCESS;
- CHECK(result);
- }
-
- /* Check existing DB for NSEC3 */
- if (!nsec3)
- 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, ISC_TRUE, 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;
- zonediff_t zonediff;
- isc_boolean_t commit = ISC_FALSE, newactive = ISC_FALSE;
- isc_boolean_t newalg = 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);
- _sig_diff.resign = zone->sigresigninginterval;
- zonediff_init(&zonediff, &_sig_diff);
-
- CHECK(dns_zone_getdb(zone, &db));
- CHECK(dns_db_newversion(db, &ver));
- CHECK(dns_db_getoriginnode(db, &node));
-
- TIME_NOW(&timenow);
- now = isc_time_seconds(&timenow);
-
- 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;
- CHECK(dns_dnssec_keylistfromrdataset(&zone->origin, dir,
- mctx, &keyset,
- &keysigs, &soasigs,
- ISC_FALSE, ISC_FALSE,
- &dnskeys));
- } 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 failure;
- }
-
- /*
- * See if any pre-existing keys have newly become active;
- * also, see if any new key is for a new algorithm, as in that
- * event, 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.)
- */
- for (key = ISC_LIST_HEAD(dnskeys);
- key != NULL;
- key = ISC_LIST_NEXT(key, link)) {
- if (!key->first_sign)
- continue;
-
- newactive = ISC_TRUE;
-
- if (!dns_rdataset_isassociated(&keysigs)) {
- newalg = ISC_TRUE;
- break;
- }
-
- if (signed_with_alg(&keysigs, dst_key_alg(key->key))) {
- /*
- * This isn't a new algorithm; clear
- * first_sign so we won't sign the
- * whole zone with this key later
- */
- key->first_sign = ISC_FALSE;
- } else {
- newalg = 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,
- ISC_TF(newalg || fullsign)));
- CHECK(update_soa_serial(db, ver, &diff, mctx,
- zone->updatemethod));
- CHECK(add_chains(zone, db, ver, &diff));
- CHECK(sign_apex(zone, db, ver, &diff, &zonediff));
- CHECK(zone_journal(zone, zonediff.diff, NULL,
- "zone_rekey"));
- commit = ISC_TRUE;
- }
- }
-
- dns_db_closeversion(db, &ver, ISC_TRUE);
-
- if (commit) {
- dns_difftuple_t *tuple;
-
- LOCK_ZONE(zone);
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
-
- zone_needdump(zone, DNS_DUMP_DELAY);
-
- zone_settimer(zone, &timenow);
-
- /* 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 newly active
- * keys.
- */
- for (key = ISC_LIST_HEAD(dnskeys);
- key != NULL;
- key = ISC_LIST_NEXT(key, link)) {
- if (!key->first_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));
- }
- }
- }
-
- /*
- * 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(zonediff.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));
- }
- }
-
- /*
- * Activate any NSEC3 chain updates that may have
- * been scheduled before this rekey.
- */
- if (fullsign || newalg)
- resume_addnsec3chain(zone);
-
- /*
- * Schedule the next resigning event
- */
- set_resigntime(zone);
- UNLOCK_ZONE(zone);
- }
-
- isc_time_settoepoch(&zone->refreshkeytime);
-
- /*
- * If we're doing key maintenance, set the key refresh timer to
- * the next scheduled key event or to 'dnssec-loadkeys-interval'
- * seconds in the future, whichever is sooner.
- */
- if (DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) {
- isc_time_t timethen;
- isc_stdtime_t then;
-
- LOCK_ZONE(zone);
- DNS_ZONE_TIME_ADD(&timenow, zone->refreshkeyinterval,
- &timethen);
- zone->refreshkeytime = timethen;
- UNLOCK_ZONE(zone);
-
- for (key = ISC_LIST_HEAD(dnskeys);
- key != NULL;
- key = ISC_LIST_NEXT(key, link)) {
- 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_compare(&timethen,
- &zone->refreshkeytime) < 0) {
- zone->refreshkeytime = timethen;
- }
- UNLOCK_ZONE(zone);
- }
-
- zone_settimer(zone, &timenow);
-
- isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
- dns_zone_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf);
- }
-
- done:
- 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;
-
- failure:
- /*
- * Something went wrong; try again in ten minutes or
- * after a key refresh interval, whichever is shorter.
- */
- isc_interval_set(&ival, ISC_MIN(zone->refreshkeyinterval, 600), 0);
- isc_time_nowplusinterval(&zone->refreshkeytime, &ival);
- goto done;
-}
-
-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 hierarchy: zmgr, zone, raw.
- */
- LOCK_ZONE(zone);
- if (inline_secure(zone))
- LOCK_ZONE(zone->raw);
- result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);
- if (inline_secure(zone))
- UNLOCK_ZONE(zone->raw);
- UNLOCK_ZONE(zone);
- return result;
-}
-
-isc_result_t
-dns_zone_setrefreshkeyinterval(dns_zone_t *zone, isc_uint32_t interval) {
- REQUIRE(DNS_ZONE_VALID(zone));
- if (interval == 0)
- return (ISC_R_RANGE);
- /* Maximum value: 24 hours (3600 minutes) */
- if (interval > (24 * 60))
- interval = (24 * 60);
- /* Multiply by 60 for seconds */
- zone->refreshkeyinterval = interval * 60;
- return (ISC_R_SUCCESS);
-}
-
-void
-dns_zone_setrequestixfr(dns_zone_t *zone, isc_boolean_t flag) {
- REQUIRE(DNS_ZONE_VALID(zone));
- zone->requestixfr = flag;
-}
-
-isc_boolean_t
-dns_zone_getrequestixfr(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
- return (zone->requestixfr);
-}
-
-void
-dns_zone_setserialupdatemethod(dns_zone_t *zone, dns_updatemethod_t method) {
- REQUIRE(DNS_ZONE_VALID(zone));
- zone->updatemethod = method;
-}
-
-dns_updatemethod_t
-dns_zone_getserialupdatemethod(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
- return(zone->updatemethod);
-}
-
-/*
- * Lock hierarchy: zmgr, zone, raw.
- */
-isc_result_t
-dns_zone_link(dns_zone_t *zone, dns_zone_t *raw) {
- isc_result_t result;
- dns_zonemgr_t *zmgr;
-
- REQUIRE(DNS_ZONE_VALID(zone));
- REQUIRE(zone->zmgr != NULL);
- REQUIRE(zone->task != NULL);
- REQUIRE(zone->loadtask != NULL);
- REQUIRE(zone->raw == NULL);
-
- REQUIRE(DNS_ZONE_VALID(raw));
- REQUIRE(raw->zmgr == NULL);
- REQUIRE(raw->task == NULL);
- REQUIRE(raw->loadtask == NULL);
- REQUIRE(raw->secure == NULL);
-
- /*
- * Lock hierarchy: zmgr, zone, raw.
- */
- zmgr = zone->zmgr;
- RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
- LOCK_ZONE(zone);
- LOCK_ZONE(raw);
-
- result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
- NULL, NULL, zone->task, zone_timer, raw,
- &raw->timer);
- if (result != ISC_R_SUCCESS)
- goto unlock;
-
- /*
- * The timer "holds" a iref.
- */
- raw->irefs++;
- INSIST(raw->irefs != 0);
-
-
- /* dns_zone_attach(raw, &zone->raw); */
- isc_refcount_increment(&raw->erefs, NULL);
- zone->raw = raw;
-
- /* dns_zone_iattach(zone, &raw->secure); */
- zone_iattach(zone, &raw->secure);
-
- isc_task_attach(zone->task, &raw->task);
- isc_task_attach(zone->loadtask, &raw->loadtask);
-
- ISC_LIST_APPEND(zmgr->zones, raw, link);
- raw->zmgr = zmgr;
- zmgr->refs++;
-
- unlock:
- UNLOCK_ZONE(raw);
- UNLOCK_ZONE(zone);
- RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
- return (result);
-}
-
-void
-dns_zone_getraw(dns_zone_t *zone, dns_zone_t **raw) {
- REQUIRE(DNS_ZONE_VALID(zone));
- REQUIRE(raw != NULL && *raw == NULL);
-
- LOCK(&zone->lock);
- if (zone->raw != NULL)
- dns_zone_attach(zone->raw, raw);
- UNLOCK(&zone->lock);
-}
-
-struct keydone {
- isc_event_t event;
- isc_boolean_t all;
- unsigned char data[5];
-};
-
-#define PENDINGFLAGS (DNS_NSEC3FLAG_CREATE|DNS_NSEC3FLAG_INITIAL)
-
-static void
-keydone(isc_task_t *task, isc_event_t *event) {
- const char *me = "keydone";
- isc_boolean_t commit = ISC_FALSE;
- isc_result_t result;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_dbversion_t *oldver = NULL, *newver = NULL;
- dns_zone_t *zone;
- dns_db_t *db = NULL;
- dns_dbnode_t *node = NULL;
- dns_rdataset_t rdataset;
- dns_diff_t diff;
- struct keydone *keydone = (struct keydone *)event;
- dns_update_log_t log = { update_log_cb, NULL };
- isc_boolean_t clear_pending = ISC_FALSE;
-
- UNUSED(task);
-
- zone = event->ev_arg;
- INSIST(DNS_ZONE_VALID(zone));
-
- ENTER;
-
- dns_rdataset_init(&rdataset);
- dns_diff_init(zone->mctx, &diff);
-
- ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
- if (zone->db != NULL) {
- dns_db_attach(zone->db, &db);
- dns_db_currentversion(db, &oldver);
- result = dns_db_newversion(db, &newver);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "keydone:dns_db_newversion -> %s",
- dns_result_totext(result));
- goto failure;
- }
- }
- ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
- if (db == NULL)
- goto failure;
-
- result = dns_db_getoriginnode(db, &node);
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- result = dns_db_findrdataset(db, node, newver, zone->privatetype,
- dns_rdatatype_none, 0, &rdataset, NULL);
- if (result == ISC_R_NOTFOUND) {
- INSIST(!dns_rdataset_isassociated(&rdataset));
- goto failure;
- }
- if (result != ISC_R_SUCCESS) {
- INSIST(!dns_rdataset_isassociated(&rdataset));
- goto failure;
- }
-
- for (result = dns_rdataset_first(&rdataset);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(&rdataset)) {
- isc_boolean_t found = ISC_FALSE;
-
- dns_rdataset_current(&rdataset, &rdata);
-
- if (keydone->all) {
- if (rdata.length == 5 && rdata.data[0] != 0 &&
- rdata.data[3] == 0 && rdata.data[4] == 1)
- found = ISC_TRUE;
- else if (rdata.data[0] == 0 &&
- (rdata.data[2] & PENDINGFLAGS) != 0) {
- found = ISC_TRUE;
- clear_pending = ISC_TRUE;
- }
- } else if (rdata.length == 5 &&
- memcmp(rdata.data, keydone->data, 5) == 0)
- found = ISC_TRUE;
-
- if (found)
- CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_DEL,
- &zone->origin, rdataset.ttl,
- &rdata));
- dns_rdata_reset(&rdata);
- }
-
- if (!ISC_LIST_EMPTY(diff.tuples)) {
- /* Write changes to journal file. */
- CHECK(update_soa_serial(db, newver, &diff, zone->mctx,
- zone->updatemethod));
-
- result = dns_update_signatures(&log, zone, db,
- oldver, newver, &diff,
- zone->sigvalidityinterval);
- if (!clear_pending)
- CHECK(result);
-
- CHECK(zone_journal(zone, &diff, NULL, "keydone"));
- commit = ISC_TRUE;
-
- LOCK_ZONE(zone);
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
- zone_needdump(zone, 30);
- UNLOCK_ZONE(zone);
- }
-
- failure:
- if (dns_rdataset_isassociated(&rdataset))
- dns_rdataset_disassociate(&rdataset);
- if (db != NULL) {
- if (node != NULL)
- dns_db_detachnode(db, &node);
- if (oldver != NULL)
- dns_db_closeversion(db, &oldver, ISC_FALSE);
- if (newver != NULL)
- dns_db_closeversion(db, &newver, commit);
- dns_db_detach(&db);
- }
- dns_diff_clear(&diff);
- isc_event_free(&event);
- dns_zone_idetach(&zone);
-}
-
-isc_result_t
-dns_zone_keydone(dns_zone_t *zone, const char *keystr) {
- isc_result_t result = ISC_R_SUCCESS;
- isc_event_t *e;
- isc_buffer_t b;
- dns_zone_t *dummy = NULL;
- struct keydone *kd;
-
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
-
- e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_KEYDONE, keydone,
- zone, sizeof(struct keydone));
- if (e == NULL) {
- result = ISC_R_NOMEMORY;
- goto failure;
- }
-
- kd = (struct keydone *) e;
- if (strcasecmp(keystr, "all") == 0)
- kd->all = ISC_TRUE;
- else {
- isc_textregion_t r;
- char *algstr;
- dns_keytag_t keyid;
- dns_secalg_t alg;
- size_t n;
-
- kd->all = ISC_FALSE;
-
- n = sscanf(keystr, "%hd/", &keyid);
- if (n == 0U)
- CHECK(ISC_R_FAILURE);
-
- algstr = strchr(keystr, '/');
- if (algstr != NULL)
- algstr++;
- else
- CHECK(ISC_R_FAILURE);
-
- n = sscanf(algstr, "%hhd", &alg);
- if (n == 0U) {
- DE_CONST(algstr, r.base);
- r.length = strlen(algstr);
- CHECK(dns_secalg_fromtext(&alg, &r));
- }
-
- /* construct a private-type rdata */
- isc_buffer_init(&b, kd->data, sizeof(kd->data));
- isc_buffer_putuint8(&b, alg);
- isc_buffer_putuint8(&b, (keyid & 0xff00) >> 8);
- isc_buffer_putuint8(&b, (keyid & 0xff));
- isc_buffer_putuint8(&b, 0);
- isc_buffer_putuint8(&b, 1);
- }
-
- zone_iattach(zone, &dummy);
- isc_task_send(zone->task, &e);
-
- failure:
- if (e != NULL)
- isc_event_free(&e);
- UNLOCK_ZONE(zone);
- return (result);
-}
-
-struct nsec3param {
- isc_event_t event;
- unsigned char data[DNS_NSEC3PARAM_BUFFERSIZE + 1];
- unsigned int length;
- isc_boolean_t nsec;
- isc_boolean_t replace;
-};
-
-static void
-setnsec3param(isc_task_t *task, isc_event_t *event) {
- const char *me = "setnsec3param";
- isc_boolean_t commit = ISC_FALSE;
- isc_result_t result;
- dns_dbversion_t *oldver = NULL, *newver = NULL;
- dns_zone_t *zone;
- dns_db_t *db = NULL;
- dns_dbnode_t *node = NULL;
- dns_rdataset_t prdataset, nrdataset;
- dns_diff_t diff;
- struct nsec3param *np = (struct nsec3param *)event;
- dns_update_log_t log = { update_log_cb, NULL };
- dns_rdata_t rdata;
- isc_boolean_t nseconly;
- isc_boolean_t exists = ISC_FALSE;
-
- UNUSED(task);
-
- zone = event->ev_arg;
- INSIST(DNS_ZONE_VALID(zone));
-
- ENTER;
-
- dns_rdataset_init(&prdataset);
- dns_rdataset_init(&nrdataset);
- dns_diff_init(zone->mctx, &diff);
-
- ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
- if (zone->db != NULL) {
- dns_db_attach(zone->db, &db);
- dns_db_currentversion(db, &oldver);
- result = dns_db_newversion(db, &newver);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "setnsec3param:dns_db_newversion -> %s",
- dns_result_totext(result));
- goto failure;
- }
- }
- ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
- if (db == NULL)
- goto failure;
-
- CHECK(dns_db_getoriginnode(db, &node));
-
- /*
- * Does a private-type record already exist for this chain?
- */
- result = dns_db_findrdataset(db, node, newver, zone->privatetype,
- dns_rdatatype_none, 0, &prdataset, NULL);
- if (result == ISC_R_SUCCESS) {
- for (result = dns_rdataset_first(&prdataset);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(&prdataset)) {
- dns_rdata_init(&rdata);
- dns_rdataset_current(&prdataset, &rdata);
-
- if (np->length == rdata.length &&
- memcmp(rdata.data, np->data, np->length) == 0) {
- exists = ISC_TRUE;
- break;
- }
- }
- } else if (result != ISC_R_NOTFOUND) {
- INSIST(!dns_rdataset_isassociated(&prdataset));
- goto failure;
- }
-
- /*
- * Does the chain already exist?
- */
- result = dns_db_findrdataset(db, node, newver,
- dns_rdatatype_nsec3param,
- dns_rdatatype_none, 0, &nrdataset, NULL);
- if (result == ISC_R_SUCCESS) {
- for (result = dns_rdataset_first(&nrdataset);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(&nrdataset)) {
- dns_rdata_init(&rdata);
- dns_rdataset_current(&nrdataset, &rdata);
-
- if (np->length == (rdata.length + 1) &&
- memcmp(rdata.data, np->data + 1,
- np->length - 1) == 0)
- {
- exists = ISC_TRUE;
- break;
- }
- }
- } else if (result != ISC_R_NOTFOUND) {
- INSIST(!dns_rdataset_isassociated(&nrdataset));
- goto failure;
- }
-
-
- /*
- * We need to remove any existing NSEC3 chains.
- */
- if (!exists && np->replace && (np->length != 0 || np->nsec))
- CHECK(dns_nsec3param_deletechains(db, newver, zone,
- !np->nsec, &diff));
-
- if (!exists && np->length != 0) {
- /*
- * We're creating an NSEC3 chain.
- *
- * If the zone is not currently capable of supporting
- * an NSEC3 chain, add the INITIAL flag, so these
- * parameters can be used later when NSEC3 becomes
- * available.
- */
- dns_rdata_init(&rdata);
-
- np->data[2] |= DNS_NSEC3FLAG_CREATE;
- result = dns_nsec_nseconly(db, newver, &nseconly);
- if (result == ISC_R_NOTFOUND || nseconly)
- np->data[2] |= DNS_NSEC3FLAG_INITIAL;
-
- rdata.length = np->length;
- rdata.data = np->data;
- rdata.type = zone->privatetype;
- rdata.rdclass = zone->rdclass;
- CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_ADD,
- &zone->origin, 0, &rdata));
- }
-
- if (!ISC_LIST_EMPTY(diff.tuples)) {
- /* Write changes to journal file. */
- CHECK(update_soa_serial(db, newver, &diff, zone->mctx,
- zone->updatemethod));
- result = dns_update_signatures(&log, zone, db,
- oldver, newver, &diff,
- zone->sigvalidityinterval);
- if (result != ISC_R_NOTFOUND)
- CHECK(result);
- CHECK(zone_journal(zone, &diff, NULL, "setnsec3param"));
- commit = ISC_TRUE;
-
- LOCK_ZONE(zone);
- DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
- zone_needdump(zone, 30);
- UNLOCK_ZONE(zone);
- }
-
- failure:
- if (dns_rdataset_isassociated(&prdataset))
- dns_rdataset_disassociate(&prdataset);
- if (dns_rdataset_isassociated(&nrdataset))
- dns_rdataset_disassociate(&nrdataset);
- if (node != NULL)
- dns_db_detachnode(db, &node);
- if (oldver != NULL)
- dns_db_closeversion(db, &oldver, ISC_FALSE);
- if (newver != NULL)
- dns_db_closeversion(db, &newver, commit);
- if (db != NULL)
- dns_db_detach(&db);
- if (commit)
- resume_addnsec3chain(zone);
- dns_diff_clear(&diff);
- isc_event_free(&event);
- dns_zone_idetach(&zone);
-}
-
-isc_result_t
-dns_zone_setnsec3param(dns_zone_t *zone, isc_uint8_t hash, isc_uint8_t flags,
- isc_uint16_t iter, isc_uint8_t saltlen,
- unsigned char *salt, isc_boolean_t replace)
-{
- isc_result_t result = ISC_R_SUCCESS;
- dns_rdata_nsec3param_t param;
- dns_rdata_t nrdata = DNS_RDATA_INIT;
- dns_rdata_t prdata = DNS_RDATA_INIT;
- unsigned char nbuf[DNS_NSEC3PARAM_BUFFERSIZE];
- struct nsec3param *np;
- dns_zone_t *dummy = NULL;
- isc_buffer_t b;
- isc_event_t *e;
-
- REQUIRE(DNS_ZONE_VALID(zone));
- REQUIRE(salt != NULL);
-
- LOCK_ZONE(zone);
-
- e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_SETNSEC3PARAM,
- setnsec3param, zone, sizeof(struct nsec3param));
- if (e == NULL) {
- result = ISC_R_NOMEMORY;
- goto failure;
- }
-
- np = (struct nsec3param *) e;
- np->replace = replace;
- if (hash == 0) {
- np->length = 0;
- np->nsec = ISC_TRUE;
- } else {
- param.common.rdclass = zone->rdclass;
- param.common.rdtype = dns_rdatatype_nsec3param;
- ISC_LINK_INIT(&param.common, link);
- param.mctx = NULL;
- param.hash = hash;
- param.flags = flags;
- param.iterations = iter;
- param.salt_length = saltlen;
- param.salt = salt;
- isc_buffer_init(&b, nbuf, sizeof(nbuf));
- CHECK(dns_rdata_fromstruct(&nrdata, zone->rdclass,
- dns_rdatatype_nsec3param,
- &param, &b));
- dns_nsec3param_toprivate(&nrdata, &prdata, zone->privatetype,
- np->data, sizeof(np->data));
- np->length = prdata.length;
- }
-
- zone_iattach(zone, &dummy);
- isc_task_send(zone->task, &e);
-
- failure:
- if (e != NULL)
- isc_event_free(&e);
- UNLOCK_ZONE(zone);
- return (result);
-}
-
-void
-dns_zone_setstatlevel(dns_zone_t *zone, dns_zonestat_level_t level) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- zone->statlevel = level;
-}
-
-dns_zonestat_level_t
-dns_zone_getstatlevel(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- return (zone->statlevel);
-}
diff --git a/contrib/bind9/lib/dns/zonekey.c b/contrib/bind9/lib/dns/zonekey.c
deleted file mode 100644
index bf7474b86c48..000000000000
--- a/contrib/bind9/lib/dns/zonekey.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2001, 2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/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: zonekey.c,v 1.9 2007/06/19 23:47:16 tbox Exp $ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <isc/result.h>
-#include <isc/types.h>
-#include <isc/util.h>
-
-#include <dns/keyvalues.h>
-#include <dns/rdata.h>
-#include <dns/rdatastruct.h>
-#include <dns/types.h>
-#include <dns/zonekey.h>
-
-isc_boolean_t
-dns_zonekey_iszonekey(dns_rdata_t *keyrdata) {
- isc_result_t result;
- dns_rdata_dnskey_t key;
- isc_boolean_t iszonekey = ISC_TRUE;
-
- REQUIRE(keyrdata != NULL);
-
- result = dns_rdata_tostruct(keyrdata, &key, NULL);
- if (result != ISC_R_SUCCESS)
- return (ISC_FALSE);
-
- if ((key.flags & DNS_KEYTYPE_NOAUTH) != 0)
- iszonekey = ISC_FALSE;
- if ((key.flags & DNS_KEYFLAG_OWNERMASK) != DNS_KEYOWNER_ZONE)
- iszonekey = ISC_FALSE;
- if (key.protocol != DNS_KEYPROTO_DNSSEC &&
- key.protocol != DNS_KEYPROTO_ANY)
- iszonekey = ISC_FALSE;
-
- return (iszonekey);
-}
diff --git a/contrib/bind9/lib/dns/zt.c b/contrib/bind9/lib/dns/zt.c
deleted file mode 100644
index eb1e42472475..000000000000
--- a/contrib/bind9/lib/dns/zt.c
+++ /dev/null
@@ -1,539 +0,0 @@
-/*
- * Copyright (C) 2004-2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1999-2002 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id$ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <isc/file.h>
-#include <isc/magic.h>
-#include <isc/mem.h>
-#include <isc/string.h>
-#include <isc/task.h>
-#include <isc/util.h>
-
-#include <dns/log.h>
-#include <dns/name.h>
-#include <dns/rbt.h>
-#include <dns/rdataclass.h>
-#include <dns/result.h>
-#include <dns/view.h>
-#include <dns/zone.h>
-#include <dns/zt.h>
-
-struct dns_zt {
- /* Unlocked. */
- unsigned int magic;
- isc_mem_t *mctx;
- dns_rdataclass_t rdclass;
- isc_rwlock_t rwlock;
- dns_zt_allloaded_t loaddone;
- void * loaddone_arg;
- /* Locked by lock. */
- isc_boolean_t flush;
- isc_uint32_t references;
- unsigned int loads_pending;
- dns_rbt_t *table;
-};
-
-#define ZTMAGIC ISC_MAGIC('Z', 'T', 'b', 'l')
-#define VALID_ZT(zt) ISC_MAGIC_VALID(zt, ZTMAGIC)
-
-static void
-auto_detach(void *, void *);
-
-static isc_result_t
-load(dns_zone_t *zone, void *uap);
-
-static isc_result_t
-asyncload(dns_zone_t *zone, void *callback);
-
-static isc_result_t
-loadnew(dns_zone_t *zone, void *uap);
-
-static isc_result_t
-freezezones(dns_zone_t *zone, void *uap);
-
-static isc_result_t
-doneloading(dns_zt_t *zt, dns_zone_t *zone, isc_task_t *task);
-
-isc_result_t
-dns_zt_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_zt_t **ztp)
-{
- dns_zt_t *zt;
- isc_result_t result;
-
- REQUIRE(ztp != NULL && *ztp == NULL);
-
- zt = isc_mem_get(mctx, sizeof(*zt));
- if (zt == NULL)
- return (ISC_R_NOMEMORY);
-
- zt->table = NULL;
- result = dns_rbt_create(mctx, auto_detach, zt, &zt->table);
- if (result != ISC_R_SUCCESS)
- goto cleanup_zt;
-
- result = isc_rwlock_init(&zt->rwlock, 0, 0);
- if (result != ISC_R_SUCCESS)
- goto cleanup_rbt;
-
- zt->mctx = NULL;
- isc_mem_attach(mctx, &zt->mctx);
- zt->references = 1;
- zt->flush = ISC_FALSE;
- zt->rdclass = rdclass;
- zt->magic = ZTMAGIC;
- zt->loaddone = NULL;
- zt->loaddone_arg = NULL;
- zt->loads_pending = 0;
- *ztp = zt;
-
- return (ISC_R_SUCCESS);
-
- cleanup_rbt:
- dns_rbt_destroy(&zt->table);
-
- cleanup_zt:
- isc_mem_put(mctx, zt, sizeof(*zt));
-
- return (result);
-}
-
-isc_result_t
-dns_zt_mount(dns_zt_t *zt, dns_zone_t *zone) {
- isc_result_t result;
- dns_zone_t *dummy = NULL;
- dns_name_t *name;
-
- REQUIRE(VALID_ZT(zt));
-
- name = dns_zone_getorigin(zone);
-
- RWLOCK(&zt->rwlock, isc_rwlocktype_write);
-
- result = dns_rbt_addname(zt->table, name, zone);
- if (result == ISC_R_SUCCESS)
- dns_zone_attach(zone, &dummy);
-
- RWUNLOCK(&zt->rwlock, isc_rwlocktype_write);
-
- return (result);
-}
-
-isc_result_t
-dns_zt_unmount(dns_zt_t *zt, dns_zone_t *zone) {
- isc_result_t result;
- dns_name_t *name;
-
- REQUIRE(VALID_ZT(zt));
-
- name = dns_zone_getorigin(zone);
-
- RWLOCK(&zt->rwlock, isc_rwlocktype_write);
-
- result = dns_rbt_deletename(zt->table, name, ISC_FALSE);
-
- RWUNLOCK(&zt->rwlock, isc_rwlocktype_write);
-
- return (result);
-}
-
-isc_result_t
-dns_zt_find(dns_zt_t *zt, dns_name_t *name, unsigned int options,
- dns_name_t *foundname, dns_zone_t **zonep)
-{
- isc_result_t result;
- dns_zone_t *dummy = NULL;
- unsigned int rbtoptions = 0;
-
- REQUIRE(VALID_ZT(zt));
-
- if ((options & DNS_ZTFIND_NOEXACT) != 0)
- rbtoptions |= DNS_RBTFIND_NOEXACT;
-
- RWLOCK(&zt->rwlock, isc_rwlocktype_read);
-
- result = dns_rbt_findname(zt->table, name, rbtoptions, foundname,
- (void **) (void*)&dummy);
- if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH)
- dns_zone_attach(dummy, zonep);
-
- RWUNLOCK(&zt->rwlock, isc_rwlocktype_read);
-
- return (result);
-}
-
-void
-dns_zt_attach(dns_zt_t *zt, dns_zt_t **ztp) {
-
- REQUIRE(VALID_ZT(zt));
- REQUIRE(ztp != NULL && *ztp == NULL);
-
- RWLOCK(&zt->rwlock, isc_rwlocktype_write);
-
- INSIST(zt->references > 0);
- zt->references++;
- INSIST(zt->references != 0);
-
- RWUNLOCK(&zt->rwlock, isc_rwlocktype_write);
-
- *ztp = zt;
-}
-
-static isc_result_t
-flush(dns_zone_t *zone, void *uap) {
- UNUSED(uap);
- return (dns_zone_flush(zone));
-}
-
-static void
-zt_destroy(dns_zt_t *zt) {
- if (zt->flush)
- (void)dns_zt_apply(zt, ISC_FALSE, flush, NULL);
- dns_rbt_destroy(&zt->table);
- isc_rwlock_destroy(&zt->rwlock);
- zt->magic = 0;
- isc_mem_putanddetach(&zt->mctx, zt, sizeof(*zt));
-}
-
-static void
-zt_flushanddetach(dns_zt_t **ztp, isc_boolean_t need_flush) {
- isc_boolean_t destroy = ISC_FALSE;
- dns_zt_t *zt;
-
- REQUIRE(ztp != NULL && VALID_ZT(*ztp));
-
- zt = *ztp;
-
- RWLOCK(&zt->rwlock, isc_rwlocktype_write);
-
- INSIST(zt->references > 0);
- zt->references--;
- if (zt->references == 0)
- destroy = ISC_TRUE;
- if (need_flush)
- zt->flush = ISC_TRUE;
-
- RWUNLOCK(&zt->rwlock, isc_rwlocktype_write);
-
- if (destroy)
- zt_destroy(zt);
-
- *ztp = NULL;
-}
-
-void
-dns_zt_flushanddetach(dns_zt_t **ztp) {
- zt_flushanddetach(ztp, ISC_TRUE);
-}
-
-void
-dns_zt_detach(dns_zt_t **ztp) {
- zt_flushanddetach(ztp, ISC_FALSE);
-}
-
-isc_result_t
-dns_zt_load(dns_zt_t *zt, isc_boolean_t stop) {
- isc_result_t result;
-
- REQUIRE(VALID_ZT(zt));
-
- RWLOCK(&zt->rwlock, isc_rwlocktype_read);
- result = dns_zt_apply(zt, stop, load, NULL);
- RWUNLOCK(&zt->rwlock, isc_rwlocktype_read);
- return (result);
-}
-
-static isc_result_t
-load(dns_zone_t *zone, void *uap) {
- isc_result_t result;
- UNUSED(uap);
-
- result = dns_zone_load(zone);
- if (result == DNS_R_CONTINUE || result == DNS_R_UPTODATE)
- result = ISC_R_SUCCESS;
-
- return (result);
-}
-
-isc_result_t
-dns_zt_asyncload(dns_zt_t *zt, dns_zt_allloaded_t alldone, void *arg) {
- isc_result_t result;
- static dns_zt_zoneloaded_t dl = doneloading;
- int pending;
-
- REQUIRE(VALID_ZT(zt));
-
- RWLOCK(&zt->rwlock, isc_rwlocktype_write);
-
- INSIST(zt->loads_pending == 0);
- result = dns_zt_apply2(zt, ISC_FALSE, NULL, asyncload, &dl);
-
- pending = zt->loads_pending;
- if (pending != 0) {
- zt->loaddone = alldone;
- zt->loaddone_arg = arg;
- }
-
- RWUNLOCK(&zt->rwlock, isc_rwlocktype_write);
-
- if (pending == 0)
- alldone(arg);
-
- return (result);
-}
-
-/*
- * Initiates asynchronous loading of zone 'zone'. 'callback' is a
- * pointer to a function which will be used to inform the caller when
- * the zone loading is complete.
- */
-static isc_result_t
-asyncload(dns_zone_t *zone, void *callback) {
- isc_result_t result;
- dns_zt_zoneloaded_t *loaded = callback;
- dns_zt_t *zt;
-
- REQUIRE(zone != NULL);
- zt = dns_zone_getview(zone)->zonetable;
- INSIST(VALID_ZT(zt));
-
- result = dns_zone_asyncload(zone, *loaded, zt);
- if (result == ISC_R_SUCCESS) {
- INSIST(zt->references > 0);
- zt->references++;
- INSIST(zt->references != 0);
- zt->loads_pending++;
- }
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-dns_zt_loadnew(dns_zt_t *zt, isc_boolean_t stop) {
- isc_result_t result;
-
- REQUIRE(VALID_ZT(zt));
-
- RWLOCK(&zt->rwlock, isc_rwlocktype_read);
- result = dns_zt_apply(zt, stop, loadnew, NULL);
- RWUNLOCK(&zt->rwlock, isc_rwlocktype_read);
- return (result);
-}
-
-static isc_result_t
-loadnew(dns_zone_t *zone, void *uap) {
- isc_result_t result;
- UNUSED(uap);
-
- result = dns_zone_loadnew(zone);
- if (result == DNS_R_CONTINUE || result == DNS_R_UPTODATE ||
- result == DNS_R_DYNAMIC)
- result = ISC_R_SUCCESS;
- return (result);
-}
-
-isc_result_t
-dns_zt_freezezones(dns_zt_t *zt, isc_boolean_t freeze) {
- isc_result_t result, tresult;
-
- REQUIRE(VALID_ZT(zt));
-
- RWLOCK(&zt->rwlock, isc_rwlocktype_read);
- result = dns_zt_apply2(zt, ISC_FALSE, &tresult, freezezones, &freeze);
- RWUNLOCK(&zt->rwlock, isc_rwlocktype_read);
- if (tresult == ISC_R_NOTFOUND)
- tresult = ISC_R_SUCCESS;
- return ((result == ISC_R_SUCCESS) ? tresult : result);
-}
-
-static isc_result_t
-freezezones(dns_zone_t *zone, void *uap) {
- isc_boolean_t freeze = *(isc_boolean_t *)uap;
- isc_boolean_t frozen;
- isc_result_t result = ISC_R_SUCCESS;
- char classstr[DNS_RDATACLASS_FORMATSIZE];
- char zonename[DNS_NAME_FORMATSIZE];
- dns_zone_t *raw = NULL;
- dns_view_t *view;
- const char *vname;
- const char *sep;
- int level;
-
- dns_zone_getraw(zone, &raw);
- if (raw != NULL)
- zone = raw;
- if (dns_zone_gettype(zone) != dns_zone_master) {
- if (raw != NULL)
- dns_zone_detach(&raw);
- return (ISC_R_SUCCESS);
- }
- if (!dns_zone_isdynamic(zone, ISC_TRUE)) {
- if (raw != NULL)
- dns_zone_detach(&raw);
- return (ISC_R_SUCCESS);
- }
-
- frozen = dns_zone_getupdatedisabled(zone);
- if (freeze) {
- if (frozen)
- result = DNS_R_FROZEN;
- if (result == ISC_R_SUCCESS)
- result = dns_zone_flush(zone);
- } else {
- if (frozen) {
- result = dns_zone_load(zone);
- if (result == DNS_R_CONTINUE ||
- result == DNS_R_UPTODATE)
- result = ISC_R_SUCCESS;
- }
- }
- if (result == ISC_R_SUCCESS)
- dns_zone_setupdatedisabled(zone, freeze);
- view = dns_zone_getview(zone);
- if (strcmp(view->name, "_bind") == 0 ||
- strcmp(view->name, "_default") == 0)
- {
- vname = "";
- sep = "";
- } else {
- vname = view->name;
- sep = " ";
- }
- dns_rdataclass_format(dns_zone_getclass(zone), classstr,
- sizeof(classstr));
- dns_name_format(dns_zone_getorigin(zone), zonename, sizeof(zonename));
- level = (result != ISC_R_SUCCESS) ? ISC_LOG_ERROR : ISC_LOG_DEBUG(1);
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
- level, "%s zone '%s/%s'%s%s: %s",
- freeze ? "freezing" : "thawing",
- zonename, classstr, sep, vname,
- isc_result_totext(result));
- if (raw != NULL)
- dns_zone_detach(&raw);
- return (result);
-}
-
-isc_result_t
-dns_zt_apply(dns_zt_t *zt, isc_boolean_t stop,
- isc_result_t (*action)(dns_zone_t *, void *), void *uap)
-{
- return (dns_zt_apply2(zt, stop, NULL, action, uap));
-}
-
-isc_result_t
-dns_zt_apply2(dns_zt_t *zt, isc_boolean_t stop, isc_result_t *sub,
- isc_result_t (*action)(dns_zone_t *, void *), void *uap)
-{
- dns_rbtnode_t *node;
- dns_rbtnodechain_t chain;
- isc_result_t result, tresult = ISC_R_SUCCESS;
- dns_zone_t *zone;
-
- REQUIRE(VALID_ZT(zt));
- REQUIRE(action != NULL);
-
- dns_rbtnodechain_init(&chain, zt->mctx);
- result = dns_rbtnodechain_first(&chain, zt->table, NULL, NULL);
- if (result == ISC_R_NOTFOUND) {
- /*
- * The tree is empty.
- */
- tresult = result;
- result = ISC_R_NOMORE;
- }
- while (result == DNS_R_NEWORIGIN || result == ISC_R_SUCCESS) {
- result = dns_rbtnodechain_current(&chain, NULL, NULL,
- &node);
- if (result == ISC_R_SUCCESS) {
- zone = node->data;
- if (zone != NULL)
- result = (action)(zone, uap);
- if (result != ISC_R_SUCCESS && stop) {
- tresult = result;
- goto cleanup; /* don't break */
- } else if (result != ISC_R_SUCCESS &&
- tresult == ISC_R_SUCCESS)
- tresult = result;
- }
- result = dns_rbtnodechain_next(&chain, NULL, NULL);
- }
- if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
-
- cleanup:
- dns_rbtnodechain_invalidate(&chain);
- if (sub != NULL)
- *sub = tresult;
-
- return (result);
-}
-
-/*
- * Decrement the loads_pending counter; when counter reaches
- * zero, call the loaddone callback that was initially set by
- * dns_zt_asyncload().
- */
-static isc_result_t
-doneloading(dns_zt_t *zt, dns_zone_t *zone, isc_task_t *task) {
- isc_boolean_t destroy = ISC_FALSE;
- dns_zt_allloaded_t alldone = NULL;
- void *arg = NULL;
-
- UNUSED(zone);
- UNUSED(task);
-
- REQUIRE(VALID_ZT(zt));
-
- RWLOCK(&zt->rwlock, isc_rwlocktype_write);
- INSIST(zt->loads_pending != 0);
- INSIST(zt->references != 0);
- zt->references--;
- if (zt->references == 0)
- destroy = ISC_TRUE;
- zt->loads_pending--;
- if (zt->loads_pending == 0) {
- alldone = zt->loaddone;
- arg = zt->loaddone_arg;
- zt->loaddone = NULL;
- zt->loaddone_arg = NULL;
- }
- RWUNLOCK(&zt->rwlock, isc_rwlocktype_write);
-
- if (alldone != NULL)
- alldone(arg);
-
- if (destroy)
- zt_destroy(zt);
-
- return (ISC_R_SUCCESS);
-}
-
-/***
- *** Private
- ***/
-
-static void
-auto_detach(void *data, void *arg) {
- dns_zone_t *zone = data;
-
- UNUSED(arg);
-
- dns_zone_detach(&zone);
-}