4 * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 2001-2003 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
20 /* Id: config.c,v 1.106 2009/12/04 21:09:32 marka Exp */
28 #include <isc/buffer.h>
31 #include <isc/parseint.h>
32 #include <isc/region.h>
33 #include <isc/result.h>
34 #include <isc/sockaddr.h>
35 #include <isc/string.h>
38 #include <isccfg/namedconf.h>
40 #include <dns/fixedname.h>
42 #include <dns/rdataclass.h>
43 #include <dns/rdatatype.h>
49 #include <named/config.h>
50 #include <named/globals.h>
52 #include "bind.keys.h"
54 /*% default configuration */
55 static char defaultconf
[] = "\
57 # blackhole {none;};\n"
59 " coresize default;\n\
64 "# session-keyfile \"" NS_LOCALSTATEDIR
"/run/named/session.key\";\n\
65 session-keyname local-ddns;\n\
66 session-keyalg hmac-sha256;\n\
67 deallocate-on-exit true;\n\
69 dump-file \"named_dump.db\";\n\
71 has-old-clients false;\n\
72 heartbeat-interval 60;\n\
73 host-statistics no;\n\
74 interface-interval 60;\n\
76 listen-on-v6 {none;};\n\
77 match-mapped-addresses no;\n\
78 memstatistics-file \"named.memstats\";\n\
79 multiple-cnames no;\n\
80 # named-xfer <obsolete>;\n\
81 # pid-file \"" NS_LOCALSTATEDIR
"/run/named/named.pid\"; /* or /lwresd.pid */\n\
82 bindkeys-file \"" NS_SYSCONFDIR
"/bind.keys\";\n\
84 recursing-file \"named.recursing\";\n\
88 random-device \"" PATH_RANDOMDEV
"\";\n\
92 recursive-clients 1000;\n\
93 rrset-order {type NS order random; order cyclic; };\n\
95 serial-query-rate 20;\n\
97 statistics-file \"named.stats\";\n\
98 statistics-interval 60;\n\
100 tcp-listen-queue 3;\n\
101 # tkey-dhkey <none>\n\
102 # tkey-gssapi-credential <none>\n\
103 # tkey-domain <none>\n\
104 transfers-per-ns 2;\n\
107 treat-cr-as-space true;\n\
110 edns-udp-size 4096;\n\
111 max-udp-size 4096;\n\
112 request-nsid false;\n\
113 reserved-sockets 512;\n\
116 dnssec-lookaside . trust-anchor dlv.isc.org;\n\
119 allow-notify {none;};\n\
120 allow-update-forwarding {none;};\n\
121 allow-query-cache { localnets; localhost; };\n\
122 allow-query-cache-on { any; };\n\
123 allow-recursion { localnets; localhost; };\n\
124 allow-recursion-on { any; };\n\
125 # allow-v6-synthesis <obsolete>;\n\
128 auth-nxdomain false;\n\
129 minimal-responses false;\n\
131 provide-ixfr true;\n\
132 request-ixfr true;\n\
135 additional-from-auth true;\n\
136 additional-from-cache true;\n\
137 query-source address *;\n\
138 query-source-v6 address *;\n\
140 notify-source-v6 *;\n\
141 cleaning-interval 0; /* now meaningless */\n\
144 max-ncache-ttl 10800; /* 3 hours */\n\
145 max-cache-ttl 604800; /* 1 week */\n\
146 transfer-format many-answers;\n\
148 check-names master fail;\n\
149 check-names slave warn;\n\
150 check-names response ignore;\n\
151 check-dup-records warn;\n\
154 acache-cleaning-interval 60;\n\
155 max-acache-size 16M;\n\
156 dnssec-enable yes;\n\
157 dnssec-validation yes; \n\
158 dnssec-accept-expired no;\n\
159 clients-per-query 10;\n\
160 max-clients-per-query 100;\n\
161 zero-no-soa-ttl-cache no;\n\
162 nsec3-test-zone no;\n\
164 #ifdef ALLOW_FILTER_AAAA_ON_V4
165 " filter-aaaa-on-v4 no;\n\
170 allow-query {any;};\n\
171 allow-query-on {any;};\n\
172 allow-transfer {any;};\n\
174 # also-notify <none>\n\
179 # forwarders <none>\n\
180 maintain-ixfr-base no;\n\
181 # max-ixfr-log-size <obsolete>\n\
182 transfer-source *;\n\
183 transfer-source-v6 *;\n\
184 alt-transfer-source *;\n\
185 alt-transfer-source-v6 *;\n\
186 max-transfer-time-in 120;\n\
187 max-transfer-time-out 120;\n\
188 max-transfer-idle-in 60;\n\
189 max-transfer-idle-out 60;\n\
190 max-retry-time 1209600; /* 2 weeks */\n\
191 min-retry-time 500;\n\
192 max-refresh-time 2419200; /* 4 weeks */\n\
193 min-refresh-time 300;\n\
195 dnssec-secure-to-insecure no;\n\
196 sig-validity-interval 30; /* days */\n\
197 sig-signing-nodes 100;\n\
198 sig-signing-signatures 10;\n\
199 sig-signing-type 65534;\n\
200 zone-statistics false;\n\
201 max-journal-size unlimited;\n\
202 ixfr-from-differences false;\n\
203 check-wildcard yes;\n\
204 check-sibling yes;\n\
205 check-integrity yes;\n\
206 check-mx-cname warn;\n\
207 check-srv-cname warn;\n\
208 zero-no-soa-ttl yes;\n\
209 update-check-ksk yes;\n\
210 dnssec-dnskey-kskonly no;\n\
211 try-tcp-refresh yes; /* BIND 8 compat */\n\
216 # Zones in the \"_bind\" view are NOT counted in the count of zones.\n\
218 view \"_bind\" chaos {\n\
222 zone \"version.bind\" chaos {\n\
224 database \"_builtin version\";\n\
227 zone \"hostname.bind\" chaos {\n\
229 database \"_builtin hostname\";\n\
232 zone \"authors.bind\" chaos {\n\
234 database \"_builtin authors\";\n\
237 zone \"id.server\" chaos {\n\
239 database \"_builtin id\";\n\
245 # The \"_meta\" view is for zones that are used to store internal\n\
246 # information for named, such as managed keys. The zones are defined\n\
249 view \"_meta\" in {\n\
256 # Default trusted key(s) for builtin DLV support\n\
257 # (used if \"dnssec-lookaside auto;\" is set and\n\
258 # sysconfdir/bind.keys doesn't exist).\n\
260 # BEGIN MANAGED KEYS\n"
262 /* Imported from bind.keys.h: */
265 "# END MANAGED KEYS\n\
269 ns_config_parsedefaults(cfg_parser_t
*parser
, cfg_obj_t
**conf
) {
272 isc_buffer_init(&b
, defaultconf
, sizeof(defaultconf
) - 1);
273 isc_buffer_add(&b
, sizeof(defaultconf
) - 1);
274 return (cfg_parse_buffer(parser
, &b
, &cfg_type_namedconf
, conf
));
278 ns_config_get(const cfg_obj_t
**maps
, const char *name
, const cfg_obj_t
**obj
) {
283 return (ISC_R_NOTFOUND
);
284 if (cfg_map_get(maps
[i
], name
, obj
) == ISC_R_SUCCESS
)
285 return (ISC_R_SUCCESS
);
290 ns_checknames_get(const cfg_obj_t
**maps
, const char *which
,
291 const cfg_obj_t
**obj
)
293 const cfg_listelt_t
*element
;
294 const cfg_obj_t
*checknames
;
295 const cfg_obj_t
*type
;
296 const cfg_obj_t
*value
;
301 return (ISC_R_NOTFOUND
);
303 if (cfg_map_get(maps
[i
], "check-names", &checknames
) == ISC_R_SUCCESS
) {
305 * Zone map entry is not a list.
307 if (checknames
!= NULL
&& !cfg_obj_islist(checknames
)) {
309 return (ISC_R_SUCCESS
);
311 for (element
= cfg_list_first(checknames
);
313 element
= cfg_list_next(element
)) {
314 value
= cfg_listelt_value(element
);
315 type
= cfg_tuple_get(value
, "type");
316 if (strcasecmp(cfg_obj_asstring(type
), which
) == 0) {
317 *obj
= cfg_tuple_get(value
, "mode");
318 return (ISC_R_SUCCESS
);
327 ns_config_listcount(const cfg_obj_t
*list
) {
328 const cfg_listelt_t
*e
;
331 for (e
= cfg_list_first(list
); e
!= NULL
; e
= cfg_list_next(e
))
338 ns_config_getclass(const cfg_obj_t
*classobj
, dns_rdataclass_t defclass
,
339 dns_rdataclass_t
*classp
) {
343 if (!cfg_obj_isstring(classobj
)) {
345 return (ISC_R_SUCCESS
);
347 DE_CONST(cfg_obj_asstring(classobj
), r
.base
);
348 r
.length
= strlen(r
.base
);
349 result
= dns_rdataclass_fromtext(classp
, &r
);
350 if (result
!= ISC_R_SUCCESS
)
351 cfg_obj_log(classobj
, ns_g_lctx
, ISC_LOG_ERROR
,
352 "unknown class '%s'", r
.base
);
357 ns_config_gettype(const cfg_obj_t
*typeobj
, dns_rdatatype_t deftype
,
358 dns_rdatatype_t
*typep
) {
362 if (!cfg_obj_isstring(typeobj
)) {
364 return (ISC_R_SUCCESS
);
366 DE_CONST(cfg_obj_asstring(typeobj
), r
.base
);
367 r
.length
= strlen(r
.base
);
368 result
= dns_rdatatype_fromtext(typep
, &r
);
369 if (result
!= ISC_R_SUCCESS
)
370 cfg_obj_log(typeobj
, ns_g_lctx
, ISC_LOG_ERROR
,
371 "unknown type '%s'", r
.base
);
376 ns_config_getzonetype(const cfg_obj_t
*zonetypeobj
) {
377 dns_zonetype_t ztype
= dns_zone_none
;
380 str
= cfg_obj_asstring(zonetypeobj
);
381 if (strcasecmp(str
, "master") == 0)
382 ztype
= dns_zone_master
;
383 else if (strcasecmp(str
, "slave") == 0)
384 ztype
= dns_zone_slave
;
385 else if (strcasecmp(str
, "stub") == 0)
386 ztype
= dns_zone_stub
;
393 ns_config_getiplist(const cfg_obj_t
*config
, const cfg_obj_t
*list
,
394 in_port_t defport
, isc_mem_t
*mctx
,
395 isc_sockaddr_t
**addrsp
, isc_uint32_t
*countp
)
398 const cfg_obj_t
*addrlist
;
399 const cfg_obj_t
*portobj
;
400 const cfg_listelt_t
*element
;
401 isc_sockaddr_t
*addrs
;
405 INSIST(addrsp
!= NULL
&& *addrsp
== NULL
);
406 INSIST(countp
!= NULL
);
408 addrlist
= cfg_tuple_get(list
, "addresses");
409 count
= ns_config_listcount(addrlist
);
411 portobj
= cfg_tuple_get(list
, "port");
412 if (cfg_obj_isuint32(portobj
)) {
413 isc_uint32_t val
= cfg_obj_asuint32(portobj
);
414 if (val
> ISC_UINT16_MAX
) {
415 cfg_obj_log(portobj
, ns_g_lctx
, ISC_LOG_ERROR
,
416 "port '%u' out of range", val
);
417 return (ISC_R_RANGE
);
419 port
= (in_port_t
) val
;
420 } else if (defport
!= 0)
423 result
= ns_config_getport(config
, &port
);
424 if (result
!= ISC_R_SUCCESS
)
428 addrs
= isc_mem_get(mctx
, count
* sizeof(isc_sockaddr_t
));
430 return (ISC_R_NOMEMORY
);
432 for (element
= cfg_list_first(addrlist
);
434 element
= cfg_list_next(element
), i
++)
437 addrs
[i
] = *cfg_obj_assockaddr(cfg_listelt_value(element
));
438 if (isc_sockaddr_getport(&addrs
[i
]) == 0)
439 isc_sockaddr_setport(&addrs
[i
], port
);
446 return (ISC_R_SUCCESS
);
450 ns_config_putiplist(isc_mem_t
*mctx
, isc_sockaddr_t
**addrsp
,
453 INSIST(addrsp
!= NULL
&& *addrsp
!= NULL
);
455 isc_mem_put(mctx
, *addrsp
, count
* sizeof(isc_sockaddr_t
));
460 get_masters_def(const cfg_obj_t
*cctx
, const char *name
,
461 const cfg_obj_t
**ret
)
464 const cfg_obj_t
*masters
= NULL
;
465 const cfg_listelt_t
*elt
;
467 result
= cfg_map_get(cctx
, "masters", &masters
);
468 if (result
!= ISC_R_SUCCESS
)
470 for (elt
= cfg_list_first(masters
);
472 elt
= cfg_list_next(elt
)) {
473 const cfg_obj_t
*list
;
474 const char *listname
;
476 list
= cfg_listelt_value(elt
);
477 listname
= cfg_obj_asstring(cfg_tuple_get(list
, "name"));
479 if (strcasecmp(listname
, name
) == 0) {
481 return (ISC_R_SUCCESS
);
484 return (ISC_R_NOTFOUND
);
488 ns_config_getipandkeylist(const cfg_obj_t
*config
, const cfg_obj_t
*list
,
489 isc_mem_t
*mctx
, isc_sockaddr_t
**addrsp
,
490 dns_name_t
***keysp
, isc_uint32_t
*countp
)
492 isc_uint32_t addrcount
= 0, keycount
= 0, i
= 0;
493 isc_uint32_t listcount
= 0, l
= 0, j
;
494 isc_uint32_t stackcount
= 0, pushed
= 0;
496 const cfg_listelt_t
*element
;
497 const cfg_obj_t
*addrlist
;
498 const cfg_obj_t
*portobj
;
500 dns_fixedname_t fname
;
501 isc_sockaddr_t
*addrs
= NULL
;
502 dns_name_t
**keys
= NULL
;
503 struct { const char *name
; } *lists
= NULL
;
505 const cfg_listelt_t
*element
;
509 REQUIRE(addrsp
!= NULL
&& *addrsp
== NULL
);
510 REQUIRE(keysp
!= NULL
&& *keysp
== NULL
);
511 REQUIRE(countp
!= NULL
);
514 addrlist
= cfg_tuple_get(list
, "addresses");
515 portobj
= cfg_tuple_get(list
, "port");
516 if (cfg_obj_isuint32(portobj
)) {
517 isc_uint32_t val
= cfg_obj_asuint32(portobj
);
518 if (val
> ISC_UINT16_MAX
) {
519 cfg_obj_log(portobj
, ns_g_lctx
, ISC_LOG_ERROR
,
520 "port '%u' out of range", val
);
521 result
= ISC_R_RANGE
;
524 port
= (in_port_t
) val
;
526 result
= ns_config_getport(config
, &port
);
527 if (result
!= ISC_R_SUCCESS
)
531 result
= ISC_R_NOMEMORY
;
533 element
= cfg_list_first(addrlist
);
537 element
= cfg_list_next(element
))
539 const cfg_obj_t
*addr
;
540 const cfg_obj_t
*key
;
544 addr
= cfg_tuple_get(cfg_listelt_value(element
),
546 key
= cfg_tuple_get(cfg_listelt_value(element
), "key");
548 if (!cfg_obj_issockaddr(addr
)) {
549 const char *listname
= cfg_obj_asstring(addr
);
550 isc_result_t tresult
;
553 if (listcount
== l
) {
555 isc_uint32_t newlen
= listcount
+ 16;
556 size_t newsize
, oldsize
;
558 newsize
= newlen
* sizeof(*lists
);
559 oldsize
= listcount
* sizeof(*lists
);
560 new = isc_mem_get(mctx
, newsize
);
563 if (listcount
!= 0) {
564 memcpy(new, lists
, oldsize
);
565 isc_mem_put(mctx
, lists
, oldsize
);
571 for (j
= 0; j
< l
; j
++)
572 if (strcasecmp(lists
[j
].name
, listname
) == 0)
576 tresult
= get_masters_def(config
, listname
, &list
);
577 if (tresult
== ISC_R_NOTFOUND
) {
578 cfg_obj_log(addr
, ns_g_lctx
, ISC_LOG_ERROR
,
579 "masters \"%s\" not found", listname
);
584 if (tresult
!= ISC_R_SUCCESS
)
586 lists
[l
++].name
= listname
;
588 if (stackcount
== pushed
) {
590 isc_uint32_t newlen
= stackcount
+ 16;
591 size_t newsize
, oldsize
;
593 newsize
= newlen
* sizeof(*stack
);
594 oldsize
= stackcount
* sizeof(*stack
);
595 new = isc_mem_get(mctx
, newsize
);
598 if (stackcount
!= 0) {
599 memcpy(new, stack
, oldsize
);
600 isc_mem_put(mctx
, stack
, oldsize
);
606 * We want to resume processing this list on the
609 stack
[pushed
].element
= cfg_list_next(element
);
610 stack
[pushed
].port
= port
;
615 if (i
== addrcount
) {
617 isc_uint32_t newlen
= addrcount
+ 16;
618 size_t newsize
, oldsize
;
620 newsize
= newlen
* sizeof(isc_sockaddr_t
);
621 oldsize
= addrcount
* sizeof(isc_sockaddr_t
);
622 new = isc_mem_get(mctx
, newsize
);
625 if (addrcount
!= 0) {
626 memcpy(new, addrs
, oldsize
);
627 isc_mem_put(mctx
, addrs
, oldsize
);
632 newsize
= newlen
* sizeof(dns_name_t
*);
633 oldsize
= keycount
* sizeof(dns_name_t
*);
634 new = isc_mem_get(mctx
, newsize
);
638 memcpy(new, keys
, oldsize
);
639 isc_mem_put(mctx
, keys
, oldsize
);
645 addrs
[i
] = *cfg_obj_assockaddr(addr
);
646 if (isc_sockaddr_getport(&addrs
[i
]) == 0)
647 isc_sockaddr_setport(&addrs
[i
], port
);
649 if (!cfg_obj_isstring(key
)) {
653 keys
[i
] = isc_mem_get(mctx
, sizeof(dns_name_t
));
656 dns_name_init(keys
[i
], NULL
);
658 keystr
= cfg_obj_asstring(key
);
659 isc_buffer_init(&b
, keystr
, strlen(keystr
));
660 isc_buffer_add(&b
, strlen(keystr
));
661 dns_fixedname_init(&fname
);
662 result
= dns_name_fromtext(dns_fixedname_name(&fname
), &b
,
663 dns_rootname
, 0, NULL
);
664 if (result
!= ISC_R_SUCCESS
)
666 result
= dns_name_dup(dns_fixedname_name(&fname
), mctx
,
668 if (result
!= ISC_R_SUCCESS
)
674 element
= stack
[pushed
].element
;
675 port
= stack
[pushed
].port
;
680 size_t newsize
, oldsize
;
682 newsize
= i
* sizeof(isc_sockaddr_t
);
683 oldsize
= addrcount
* sizeof(isc_sockaddr_t
);
685 new = isc_mem_get(mctx
, newsize
);
688 memcpy(new, addrs
, newsize
);
691 isc_mem_put(mctx
, addrs
, oldsize
);
695 newsize
= i
* sizeof(dns_name_t
*);
696 oldsize
= keycount
* sizeof(dns_name_t
*);
698 new = isc_mem_get(mctx
, newsize
);
701 memcpy(new, keys
, newsize
);
704 isc_mem_put(mctx
, keys
, oldsize
);
710 isc_mem_put(mctx
, lists
, listcount
* sizeof(*lists
));
712 isc_mem_put(mctx
, stack
, stackcount
* sizeof(*stack
));
714 INSIST(keycount
== addrcount
);
720 return (ISC_R_SUCCESS
);
724 isc_mem_put(mctx
, addrs
, addrcount
* sizeof(isc_sockaddr_t
));
726 for (j
= 0; j
<= i
; j
++) {
729 if (dns_name_dynamic(keys
[j
]))
730 dns_name_free(keys
[j
], mctx
);
731 isc_mem_put(mctx
, keys
[j
], sizeof(dns_name_t
));
733 isc_mem_put(mctx
, keys
, keycount
* sizeof(dns_name_t
*));
736 isc_mem_put(mctx
, lists
, listcount
* sizeof(*lists
));
738 isc_mem_put(mctx
, stack
, stackcount
* sizeof(*stack
));
743 ns_config_putipandkeylist(isc_mem_t
*mctx
, isc_sockaddr_t
**addrsp
,
744 dns_name_t
***keysp
, isc_uint32_t count
)
747 dns_name_t
**keys
= *keysp
;
749 INSIST(addrsp
!= NULL
&& *addrsp
!= NULL
);
751 isc_mem_put(mctx
, *addrsp
, count
* sizeof(isc_sockaddr_t
));
752 for (i
= 0; i
< count
; i
++) {
755 if (dns_name_dynamic(keys
[i
]))
756 dns_name_free(keys
[i
], mctx
);
757 isc_mem_put(mctx
, keys
[i
], sizeof(dns_name_t
));
759 isc_mem_put(mctx
, *keysp
, count
* sizeof(dns_name_t
*));
765 ns_config_getport(const cfg_obj_t
*config
, in_port_t
*portp
) {
766 const cfg_obj_t
*maps
[3];
767 const cfg_obj_t
*options
= NULL
;
768 const cfg_obj_t
*portobj
= NULL
;
772 (void)cfg_map_get(config
, "options", &options
);
776 maps
[i
++] = ns_g_defaults
;
779 result
= ns_config_get(maps
, "port", &portobj
);
780 INSIST(result
== ISC_R_SUCCESS
);
781 if (cfg_obj_asuint32(portobj
) >= ISC_UINT16_MAX
) {
782 cfg_obj_log(portobj
, ns_g_lctx
, ISC_LOG_ERROR
,
783 "port '%u' out of range",
784 cfg_obj_asuint32(portobj
));
785 return (ISC_R_RANGE
);
787 *portp
= (in_port_t
)cfg_obj_asuint32(portobj
);
788 return (ISC_R_SUCCESS
);
791 struct keyalgorithms
{
793 enum { hmacnone
, hmacmd5
, hmacsha1
, hmacsha224
,
794 hmacsha256
, hmacsha384
, hmacsha512
} hmac
;
798 { "hmac-md5", hmacmd5
, DST_ALG_HMACMD5
, 128 },
799 { "hmac-md5.sig-alg.reg.int", hmacmd5
, DST_ALG_HMACMD5
, 0 },
800 { "hmac-md5.sig-alg.reg.int.", hmacmd5
, DST_ALG_HMACMD5
, 0 },
801 { "hmac-sha1", hmacsha1
, DST_ALG_HMACSHA1
, 160 },
802 { "hmac-sha224", hmacsha224
, DST_ALG_HMACSHA224
, 224 },
803 { "hmac-sha256", hmacsha256
, DST_ALG_HMACSHA256
, 256 },
804 { "hmac-sha384", hmacsha384
, DST_ALG_HMACSHA384
, 384 },
805 { "hmac-sha512", hmacsha512
, DST_ALG_HMACSHA512
, 512 },
806 { NULL
, hmacnone
, DST_ALG_UNKNOWN
, 0 }
810 ns_config_getkeyalgorithm(const char *str
, dns_name_t
**name
,
811 isc_uint16_t
*digestbits
)
813 return (ns_config_getkeyalgorithm2(str
, name
, NULL
, digestbits
));
817 ns_config_getkeyalgorithm2(const char *str
, dns_name_t
**name
,
818 unsigned int *typep
, isc_uint16_t
*digestbits
)
825 for (i
= 0; algorithms
[i
].str
!= NULL
; i
++) {
826 len
= strlen(algorithms
[i
].str
);
827 if (strncasecmp(algorithms
[i
].str
, str
, len
) == 0 &&
829 (algorithms
[i
].size
!= 0 && str
[len
] == '-')))
832 if (algorithms
[i
].str
== NULL
)
833 return (ISC_R_NOTFOUND
);
834 if (str
[len
] == '-') {
835 result
= isc_parse_uint16(&bits
, str
+ len
+ 1, 10);
836 if (result
!= ISC_R_SUCCESS
)
838 if (bits
> algorithms
[i
].size
)
839 return (ISC_R_RANGE
);
840 } else if (algorithms
[i
].size
== 0)
843 bits
= algorithms
[i
].size
;
846 switch (algorithms
[i
].hmac
) {
847 case hmacmd5
: *name
= dns_tsig_hmacmd5_name
; break;
848 case hmacsha1
: *name
= dns_tsig_hmacsha1_name
; break;
849 case hmacsha224
: *name
= dns_tsig_hmacsha224_name
; break;
850 case hmacsha256
: *name
= dns_tsig_hmacsha256_name
; break;
851 case hmacsha384
: *name
= dns_tsig_hmacsha384_name
; break;
852 case hmacsha512
: *name
= dns_tsig_hmacsha512_name
; break;
858 *typep
= algorithms
[i
].type
;
859 if (digestbits
!= NULL
)
861 return (ISC_R_SUCCESS
);