diff options
author | erwin <erwin@FreeBSD.org> | 2013-07-24 07:12:55 +0000 |
---|---|---|
committer | erwin <erwin@FreeBSD.org> | 2013-07-24 07:12:55 +0000 |
commit | dc235a59431db02e1a04d85de49af9e278510ac8 (patch) | |
tree | e392027bf54f7a1fd2a6f3a16ecb4487844b44e9 /lib | |
parent | 9ef4e0591273b7d40b98ef46084442638150b2fc (diff) | |
download | FreeBSD-src-dc235a59431db02e1a04d85de49af9e278510ac8.zip FreeBSD-src-dc235a59431db02e1a04d85de49af9e278510ac8.tar.gz |
Vendor import of Bind 9.8.5-P1
Approved by: delphij (mentor)
Sponsored by: DK Hostmaster A/S
Diffstat (limited to 'lib')
160 files changed, 5376 insertions, 1747 deletions
diff --git a/lib/Makefile.in b/lib/Makefile.in index e3f0bdb..8dc1d38 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2012, 2013 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 @@ -27,3 +27,8 @@ SUBDIRS = isc isccc dns isccfg bind9 lwres tests TARGETS = @BIND9_MAKE_RULES@ + +distclean:: + @echo "making $@ in `pwd`/irs"; \ + (cd irs; ${MAKE} ${MAKEDEFS} DESTDIR="${DESTDIR}" $@) || exit 1; + diff --git a/lib/bind9/Makefile.in b/lib/bind9/Makefile.in index 73285e1..b6633e5 100644 --- a/lib/bind9/Makefile.in +++ b/lib/bind9/Makefile.in @@ -69,7 +69,8 @@ libbind9.la: ${OBJS} ${ISCCFGDEPLIBS} ${ISCDEPLIBS} ${DNSDEPLIBS} ${LIBTOOL_MODE_LINK} \ ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libbind9.la -rpath ${libdir} \ -version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \ - ${OBJS} ${DNSLIBS} ${ISCCFGLIBS} ${ISCLIBS} ${LIBS} + ${OBJS} ${DNSLIBS} ${ISCCFGLIBS} ${ISCLIBS} @DNS_CRYPTO_LIBS@ \ + ${LIBS} timestamp: libbind9.@A@ touch timestamp diff --git a/lib/bind9/api b/lib/bind9/api index 7e9b115..99f8d31 100644 --- a/lib/bind9/api +++ b/lib/bind9/api @@ -1,8 +1,9 @@ # LIBINTERFACE ranges # 9.6: 50-59, 110-119 # 9.7: 60-79 -# 9.8: 80-89 +# 9.8: 80-89, 120-129 # 9.9: 90-109 +# 9.9-sub: 130-139 LIBINTERFACE = 80 -LIBREVISION = 7 +LIBREVISION = 8 LIBAGE = 0 diff --git a/lib/bind9/check.c b/lib/bind9/check.c index f765604..7c975c9 100644 --- a/lib/bind9/check.c +++ b/lib/bind9/check.c @@ -100,7 +100,7 @@ check_orderent(const cfg_obj_t *ent, isc_log_t *logctx) { obj = cfg_tuple_get(ent, "name"); if (cfg_obj_isstring(obj)) { str = cfg_obj_asstring(obj); - isc_buffer_init(&b, str, strlen(str)); + isc_buffer_constinit(&b, str, strlen(str)); isc_buffer_add(&b, strlen(str)); tresult = dns_name_fromtext(dns_fixedname_name(&fixed), &b, dns_rootname, 0, NULL); @@ -197,7 +197,7 @@ check_dual_stack(const cfg_obj_t *options, isc_log_t *logctx) { continue; obj = cfg_tuple_get(value, "name"); str = cfg_obj_asstring(obj); - isc_buffer_init(&buffer, str, strlen(str)); + isc_buffer_constinit(&buffer, str, strlen(str)); isc_buffer_add(&buffer, strlen(str)); dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); @@ -263,7 +263,7 @@ disabled_algorithms(const cfg_obj_t *disabled, isc_log_t *logctx) { name = dns_fixedname_name(&fixed); obj = cfg_tuple_get(disabled, "name"); str = cfg_obj_asstring(obj); - isc_buffer_init(&b, str, strlen(str)); + isc_buffer_constinit(&b, str, strlen(str)); isc_buffer_add(&b, strlen(str)); tresult = dns_name_fromtext(name, &b, dns_rootname, 0, NULL); if (tresult != ISC_R_SUCCESS) { @@ -346,7 +346,7 @@ mustbesecure(const cfg_obj_t *secure, isc_symtab_t *symtab, isc_log_t *logctx, name = dns_fixedname_name(&fixed); obj = cfg_tuple_get(secure, "name"); str = cfg_obj_asstring(obj); - isc_buffer_init(&b, str, strlen(str)); + isc_buffer_constinit(&b, str, strlen(str)); isc_buffer_add(&b, strlen(str)); result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL); if (result != ISC_R_SUCCESS) { @@ -799,7 +799,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx, element = cfg_list_next(element)) { exclude = cfg_listelt_value(element); str = cfg_obj_asstring(exclude); - isc_buffer_init(&b, str, strlen(str)); + isc_buffer_constinit(&b, str, strlen(str)); isc_buffer_add(&b, strlen(str)); tresult = dns_name_fromtext(name, &b, dns_rootname, @@ -867,7 +867,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx, continue; } - isc_buffer_init(&b, dlv, strlen(dlv)); + isc_buffer_constinit(&b, dlv, strlen(dlv)); isc_buffer_add(&b, strlen(dlv)); tresult = dns_name_fromtext(name, &b, dns_rootname, 0, NULL); @@ -901,7 +901,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx, if (!cfg_obj_isvoid(anchor)) { dlv = cfg_obj_asstring(anchor); - isc_buffer_init(&b, dlv, strlen(dlv)); + isc_buffer_constinit(&b, dlv, strlen(dlv)); isc_buffer_add(&b, strlen(dlv)); tresult = dns_name_fromtext(name, &b, dns_rootname, @@ -975,7 +975,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx, (void)cfg_map_get(options, server_contact[i], &obj); if (obj != NULL) { str = cfg_obj_asstring(obj); - isc_buffer_init(&b, str, strlen(str)); + isc_buffer_constinit(&b, str, strlen(str)); isc_buffer_add(&b, strlen(str)); tresult = dns_name_fromtext(dns_fixedname_name(&fixed), &b, dns_rootname, 0, NULL); @@ -999,7 +999,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx, { obj = cfg_listelt_value(element); str = cfg_obj_asstring(obj); - isc_buffer_init(&b, str, strlen(str)); + isc_buffer_constinit(&b, str, strlen(str)); isc_buffer_add(&b, strlen(str)); tresult = dns_name_fromtext(dns_fixedname_name(&fixed), &b, dns_rootname, 0, NULL); @@ -1184,7 +1184,7 @@ check_update_policy(const cfg_obj_t *policy, isc_log_t *logctx) { dns_fixedname_init(&fixed); str = cfg_obj_asstring(identity); - isc_buffer_init(&b, str, strlen(str)); + isc_buffer_constinit(&b, str, strlen(str)); isc_buffer_add(&b, strlen(str)); tresult = dns_name_fromtext(dns_fixedname_name(&fixed), &b, dns_rootname, 0, NULL); @@ -1198,7 +1198,7 @@ check_update_policy(const cfg_obj_t *policy, isc_log_t *logctx) { strcasecmp(cfg_obj_asstring(matchtype), "zonesub") != 0) { dns_fixedname_init(&fixed); str = cfg_obj_asstring(dname); - isc_buffer_init(&b, str, strlen(str)); + isc_buffer_constinit(&b, str, strlen(str)); isc_buffer_add(&b, strlen(str)); tresult = dns_name_fromtext(dns_fixedname_name(&fixed), &b, dns_rootname, 0, NULL); @@ -1432,7 +1432,7 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions, * deals with strings. */ dns_fixedname_init(&fixedname); - isc_buffer_init(&b, znamestr, strlen(znamestr)); + isc_buffer_constinit(&b, znamestr, strlen(znamestr)); isc_buffer_add(&b, strlen(znamestr)); tresult = dns_name_fromtext(dns_fixedname_name(&fixedname), &b, dns_rootname, DNS_NAME_DOWNCASE, NULL); @@ -1680,7 +1680,7 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions, snamestr = cfg_obj_asstring(obj); dns_fixedname_init(&fixed_sname); - isc_buffer_init(&b2, snamestr, strlen(snamestr)); + isc_buffer_constinit(&b2, snamestr, strlen(snamestr)); isc_buffer_add(&b2, strlen(snamestr)); sname = dns_fixedname_name(&fixed_sname); tresult = dns_name_fromtext(sname, &b2, dns_rootname, @@ -1859,7 +1859,7 @@ check_keylist(const cfg_obj_t *keys, isc_symtab_t *symtab, isc_buffer_t b; char *keyname; - isc_buffer_init(&b, keyid, strlen(keyid)); + isc_buffer_constinit(&b, keyid, strlen(keyid)); isc_buffer_add(&b, strlen(keyid)); tresult = dns_name_fromtext(name, &b, dns_rootname, 0, NULL); @@ -2028,7 +2028,7 @@ check_servers(const cfg_obj_t *config, const cfg_obj_t *voptions, */ keyval = cfg_obj_asstring(keys); dns_fixedname_init(&fname); - isc_buffer_init(&b, keyval, strlen(keyval)); + isc_buffer_constinit(&b, keyval, strlen(keyval)); isc_buffer_add(&b, strlen(keyval)); keyname = dns_fixedname_name(&fname); tresult = dns_name_fromtext(keyname, &b, dns_rootname, @@ -2073,7 +2073,7 @@ check_trusted_key(const cfg_obj_t *key, isc_boolean_t managed, keyname = dns_fixedname_name(&fkeyname); keynamestr = cfg_obj_asstring(cfg_tuple_get(key, "name")); - isc_buffer_init(&b, keynamestr, strlen(keynamestr)); + isc_buffer_constinit(&b, keynamestr, strlen(keynamestr)); isc_buffer_add(&b, strlen(keynamestr)); result = dns_name_fromtext(keyname, &b, dns_rootname, 0, NULL); if (result != ISC_R_SUCCESS) { diff --git a/lib/dns/Makefile.in b/lib/dns/Makefile.in index a01bb41..51d6066 100644 --- a/lib/dns/Makefile.in +++ b/lib/dns/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") +# 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 @@ -46,8 +46,9 @@ LIBS = @LIBS@ # Alphabetically +OPENSSLGOSTLINKOBJS = opensslgost_link.@O@ OPENSSLLINKOBJS = openssl_link.@O@ openssldh_link.@O@ openssldsa_link.@O@ \ - opensslecdsa_link.@O@ opensslgost_link.@O@ \ + opensslecdsa_link.@O@ @OPENSSLGOSTLINKOBJS@ \ opensslrsa_link.@O@ DSTOBJS = @DST_EXTRA_OBJS@ @OPENSSLLINKOBJS@ \ @@ -76,8 +77,9 @@ DNSOBJS = acache.@O@ acl.@O@ adb.@O@ byaddr.@O@ \ OBJS= ${DNSOBJS} ${OTHEROBJS} ${DSTOBJS} # Alphabetically +OPENSSLGOSTLINKSRCS = opensslgost_link.c OPENSSLLINKSRCS = openssl_link.c openssldh_link.c openssldsa_link.c \ - opensslecdsa_link.c opensslgost_link.c opensslrsa_link.c + opensslecdsa_link.c @OPENSSLGOSTLINKSRCS@ opensslrsa_link.c DSTSRCS = @DST_EXTRA_SRCS@ @OPENSSLLINKSRCS@ \ dst_api.c dst_lib.c dst_parse.c \ diff --git a/lib/dns/acache.c b/lib/dns/acache.c index 2ad4981..863df35 100644 --- a/lib/dns/acache.c +++ b/lib/dns/acache.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -27,6 +27,7 @@ #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> @@ -72,10 +73,10 @@ * (XXX simply derived from definitions in cache.c There may be better * constants here.) */ -#define DNS_ACACHE_MINSIZE 2097152 /* Bytes. 2097152 = 2 MB */ -#define DNS_ACACHE_CLEANERINCREMENT 1000 /* Number of entries. */ +#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. */ +#define DEFAULT_ACACHE_ENTRY_LOCK_COUNT 1009 /*%< Should be prime. */ #if defined(ISC_RWLOCK_USEATOMIC) && defined(ISC_PLATFORM_HAVEATOMICSTORE) #define ACACHE_USE_RWLOCK 1 @@ -776,10 +777,14 @@ entry_stale(acache_cleaner_t *cleaner, dns_acacheentry_t *entry, * use and the cleaning interval. */ if (cleaner->overmem) { - unsigned int passed = - now32 - entry->lastused; /* <= interval */ + 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); @@ -825,8 +830,10 @@ acache_incremental_cleaning_action(isc_task_t *task, isc_event_t *event) { entry = cleaner->current_entry; isc_stdtime_convert32(cleaner->last_cleanup_time, &last32); - INSIST(now32 > last32); - interval = now32 - last32; + if (isc_serial_ge(now32, last32)) + interval = now32 - last32; + else + interval = 0; while (n_entries-- > 0) { isc_boolean_t is_stale = ISC_FALSE; @@ -861,7 +868,11 @@ acache_incremental_cleaning_action(isc_task_t *task, isc_event_t *event) { if (entry != NULL) { /* * If we are still in the overmem - * state, keep cleaning. + * 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, @@ -870,6 +881,7 @@ acache_incremental_cleaning_action(isc_task_t *task, isc_event_t *event) { "acache cleaner: " "still overmem, " "reset and try again"); + next = entry; continue; } } @@ -888,7 +900,7 @@ acache_incremental_cleaning_action(isc_task_t *task, isc_event_t *event) { * be the starting point in the next clean-up, and reschedule another * batch. If it fails, just try to continue anyway. */ - INSIST(next != NULL && next != cleaner->current_entry); + INSIST(next != NULL); dns_acache_detachentry(&cleaner->current_entry); dns_acache_attachentry(next, &cleaner->current_entry); @@ -1649,12 +1661,17 @@ dns_acache_setentry(dns_acache_t *acache, dns_acacheentry_t *entry, return (result); } -void +isc_boolean_t dns_acache_cancelentry(dns_acacheentry_t *entry) { - dns_acache_t *acache = entry->acache; + dns_acache_t *acache; + isc_boolean_t callback_active; REQUIRE(DNS_ACACHEENTRY_VALID(entry)); - INSIST(DNS_ACACHE_VALID(acache)); + + 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); @@ -1674,6 +1691,8 @@ dns_acache_cancelentry(dns_acacheentry_t *entry) { ACACHE_UNLOCK(&acache->entrylocks[entry->locknum], isc_rwlocktype_write); UNLOCK(&acache->lock); + + return (callback_active); } void @@ -1768,13 +1787,13 @@ dns_acache_setcachesize(dns_acache_t *acache, isc_uint32_t size) { REQUIRE(DNS_ACACHE_VALID(acache)); - if (size != 0 && size < DNS_ACACHE_MINSIZE) + if (size != 0U && size < DNS_ACACHE_MINSIZE) size = DNS_ACACHE_MINSIZE; hiwater = size - (size >> 3); lowater = size - (size >> 2); - if (size == 0 || hiwater == 0 || lowater == 0) + if (size == 0U || hiwater == 0U || lowater == 0U) isc_mem_setwater(acache->mctx, water, acache, 0, 0); else isc_mem_setwater(acache->mctx, water, acache, diff --git a/lib/dns/adb.c b/lib/dns/adb.c index 531d112..6aa5e5a 100644 --- a/lib/dns/adb.c +++ b/lib/dns/adb.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -89,7 +89,7 @@ #define DNS_ADB_INVALIDBUCKET (-1) /*%< invalid bucket address */ -#define DNS_ADB_MINADBSIZE (1024*1024) /*%< 1 Megabyte */ +#define DNS_ADB_MINADBSIZE (1024U*1024U) /*%< 1 Megabyte */ typedef ISC_LIST(dns_adbname_t) dns_adbnamelist_t; typedef struct dns_adbnamehook dns_adbnamehook_t; @@ -518,7 +518,9 @@ grow_entries(isc_task_t *task, isc_event_t *ev) { isc_event_free(&ev); - isc_task_beginexclusive(task); + result = isc_task_beginexclusive(task); + if (result != ISC_R_SUCCESS) + goto check_exit; i = 0; while (nbuckets[i] != 0 && adb->nentries >= nbuckets[i]) @@ -646,6 +648,7 @@ grow_entries(isc_task_t *task, isc_event_t *ev) { done: isc_task_endexclusive(task); + check_exit: LOCK(&adb->lock); if (dec_adb_irefcnt(adb)) check_exit(adb); @@ -670,7 +673,9 @@ grow_names(isc_task_t *task, isc_event_t *ev) { isc_event_free(&ev); - isc_task_beginexclusive(task); + result = isc_task_beginexclusive(task); + if (result != ISC_R_SUCCESS) + goto check_exit; i = 0; while (nbuckets[i] != 0 && adb->nnames >= nbuckets[i]) @@ -794,6 +799,7 @@ grow_names(isc_task_t *task, isc_event_t *ev) { done: isc_task_endexclusive(task); + check_exit: LOCK(&adb->lock); if (dec_adb_irefcnt(adb)) check_exit(adb); @@ -1280,6 +1286,7 @@ clean_namehooks(dns_adb_t *adb, dns_adbnamehooklist_t *namehooks) { 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]); } @@ -2075,6 +2082,7 @@ copy_namehook_lists(dns_adb_t *adb, dns_adbfind_t *find, dns_name_t *qname, while (namehook != NULL) { entry = namehook->entry; bucket = entry->lock_bucket; + INSIST(bucket != DNS_ADB_INVALIDBUCKET); LOCK(&adb->entrylocks[bucket]); if (!FIND_RETURNLAME(find) @@ -2105,6 +2113,7 @@ copy_namehook_lists(dns_adb_t *adb, dns_adbfind_t *find, dns_name_t *qname, while (namehook != NULL) { entry = namehook->entry; bucket = entry->lock_bucket; + INSIST(bucket != DNS_ADB_INVALIDBUCKET); LOCK(&adb->entrylocks[bucket]); if (!FIND_RETURNLAME(find) @@ -2331,7 +2340,8 @@ destroy(dns_adb_t *adb) { adb->magic = 0; isc_task_detach(&adb->task); - isc_task_detach(&adb->excl); + if (adb->excl != NULL) + isc_task_detach(&adb->excl); isc_mempool_destroy(&adb->nmp); isc_mempool_destroy(&adb->nhmp); @@ -4126,13 +4136,13 @@ dns_adb_setadbsize(dns_adb_t *adb, isc_uint32_t size) { INSIST(DNS_ADB_VALID(adb)); - if (size != 0 && size < DNS_ADB_MINADBSIZE) + 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 == 0 || hiwater == 0 || lowater == 0) + 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/lib/dns/api b/lib/dns/api index 325781a..5241a88 100644 --- a/lib/dns/api +++ b/lib/dns/api @@ -1,8 +1,9 @@ # LIBINTERFACE ranges # 9.6: 50-59, 110-119 # 9.7: 60-79 -# 9.8: 80-89 +# 9.8: 80-89, 120-129 # 9.9: 90-109 -LIBINTERFACE = 89 +# 9.9-sub: 130-139 +LIBINTERFACE = 122 LIBREVISION = 1 -LIBAGE = 1 +LIBAGE = 0 diff --git a/lib/dns/cache.c b/lib/dns/cache.c index 56bff8d..bced80e 100644 --- a/lib/dns/cache.c +++ b/lib/dns/cache.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -50,7 +50,7 @@ * DNS_CACHE_MINSIZE is how many bytes is the floor for dns_cache_setcachesize(). * See also DNS_CACHE_CLEANERINCREMENT */ -#define DNS_CACHE_MINSIZE 2097152 /*%< Bytes. 2097152 = 2 MB */ +#define DNS_CACHE_MINSIZE 2097152U /*%< Bytes. 2097152 = 2 MB */ /*! * Control incremental cleaning. * CLEANERINCREMENT is how many nodes are examined in one pass. @@ -1038,7 +1038,7 @@ dns_cache_setcachesize(dns_cache_t *cache, isc_uint32_t size) { * Impose a minimum cache size; pathological things happen if there * is too little room. */ - if (size != 0 && size < DNS_CACHE_MINSIZE) + if (size != 0U && size < DNS_CACHE_MINSIZE) size = DNS_CACHE_MINSIZE; LOCK(&cache->lock); @@ -1055,7 +1055,7 @@ dns_cache_setcachesize(dns_cache_t *cache, isc_uint32_t size) { * water(). */ - if (size == 0 || hiwater == 0 || lowater == 0) + if (size == 0U || hiwater == 0U || lowater == 0U) /* * Disable cache memory limiting. */ diff --git a/lib/dns/client.c b/lib/dns/client.c index 7b6d1640..c4780f7 100644 --- a/lib/dns/client.c +++ b/lib/dns/client.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -354,6 +354,12 @@ dns_client_create(dns_client_t **clientp, unsigned int options) { 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) @@ -373,7 +379,18 @@ dns_client_create(dns_client_t **clientp, unsigned int options) { 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) @@ -485,6 +502,7 @@ dns_client_createx(isc_mem_t *mctx, isc_appctx_t *actx, isc_taskmgr_t *taskmgr, 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; @@ -2000,8 +2018,9 @@ resolveaddr_done(isc_task_t *task, isc_event_t *event) { switch (family) { case AF_INET: dns_rdataset_current(rdataset, &rdata); - dns_rdata_tostruct(&rdata, &rdata_a, - NULL); + result = dns_rdata_tostruct(&rdata, &rdata_a, + NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); isc_sockaddr_fromin(sa, &rdata_a.in_addr, 53); @@ -2009,8 +2028,9 @@ resolveaddr_done(isc_task_t *task, isc_event_t *event) { break; case AF_INET6: dns_rdataset_current(rdataset, &rdata); - dns_rdata_tostruct(&rdata, &rdata_aaaa, - NULL); + result = dns_rdata_tostruct(&rdata, &rdata_aaaa, + NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); isc_sockaddr_fromin6(sa, &rdata_aaaa.in6_addr, 53); diff --git a/lib/dns/db.c b/lib/dns/db.c index 0cf2c27..77f82f1 100644 --- a/lib/dns/db.c +++ b/lib/dns/db.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -945,11 +945,12 @@ dns_db_resigned(dns_db_t *db, dns_rdataset_t *rdataset, (db->methods->resigned)(db, rdataset, version); } -void +isc_result_t dns_db_rpz_enabled(dns_db_t *db, dns_rpz_st_t *st) { if (db->methods->rpz_enabled != NULL) - (db->methods->rpz_enabled)(db, st); + return ((db->methods->rpz_enabled)(db, st)); + return (ISC_R_SUCCESS); } void diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c index 775d4f4..9848ac2 100644 --- a/lib/dns/dispatch.c +++ b/lib/dns/dispatch.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -2756,7 +2756,7 @@ get_udpsocket(dns_dispatchmgr_t *mgr, dns_dispatch_t *disp, * If no port is specified, we first try to pick up a random * port by ourselves. */ - if (isc_sockaddr_pf(&disp->local) == AF_INET) { + if (isc_sockaddr_pf(localaddr) == AF_INET) { nports = disp->mgr->nv4ports; ports = disp->mgr->v4ports; } else { @@ -2775,12 +2775,16 @@ get_udpsocket(dns_dispatchmgr_t *mgr, dns_dispatch_t *disp, isc_sockaddr_setport(&localaddr_bound, prt); result = open_socket(sockmgr, &localaddr_bound, 0, &sock); - if (result == ISC_R_SUCCESS || - result != ISC_R_ADDRINUSE) { - disp->localport = prt; - *sockp = sock; - return (result); - } + /* + * 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); } /* @@ -2805,8 +2809,6 @@ get_udpsocket(dns_dispatchmgr_t *mgr, dns_dispatch_t *disp, result = open_socket(sockmgr, localaddr, 0, &sock); if (result != ISC_R_SUCCESS) goto end; - else if (!anyport) - break; else if (portavailable(mgr, sock, NULL)) break; if (held[i] != NULL) diff --git a/lib/dns/dlz.c b/lib/dns/dlz.c index 8d1625a..19c600c 100644 --- a/lib/dns/dlz.c +++ b/lib/dns/dlz.c @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2005, 2007, 2009-2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -142,6 +142,7 @@ dns_dlzcreate(isc_mem_t *mctx, const char *dlzname, const char *drivername, { dns_dlzimplementation_t *impinfo; isc_result_t result; + dns_dlzdb_t *db = NULL; /* * initialize the dlz_implementations list, this is guaranteed @@ -180,30 +181,31 @@ dns_dlzcreate(isc_mem_t *mctx, const char *dlzname, const char *drivername, } /* Allocate memory to hold the DLZ database driver */ - (*dbp) = isc_mem_get(mctx, sizeof(dns_dlzdb_t)); - if ((*dbp) == NULL) { + 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((*dbp), 0, sizeof(dns_dlzdb_t)); + memset(db, 0, sizeof(dns_dlzdb_t)); - (*dbp)->implementation = impinfo; + db->implementation = impinfo; /* Create a new database using implementation 'drivername'. */ result = ((impinfo->methods->create)(mctx, dlzname, argc, argv, impinfo->driverarg, - &(*dbp)->dbdata)); + &db->dbdata)); /* mark the DLZ driver as valid */ if (result == ISC_R_SUCCESS) { RWUNLOCK(&dlz_implock, isc_rwlocktype_read); - (*dbp)->magic = DNS_DLZ_MAGIC; - isc_mem_attach(mctx, &(*dbp)->mctx); + 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, @@ -213,7 +215,7 @@ dns_dlzcreate(isc_mem_t *mctx, const char *dlzname, const char *drivername, /* impinfo->methods->create failed. */ RWUNLOCK(&dlz_implock, isc_rwlocktype_read); - isc_mem_put(mctx, (*dbp), sizeof(dns_dlzdb_t)); + isc_mem_put(mctx, db, sizeof(dns_dlzdb_t)); return (result); } @@ -543,7 +545,7 @@ dns_dlz_writeablezone(dns_view_t *view, const char *zone_name) { REQUIRE(dlzdatabase->configure_callback != NULL); - isc_buffer_init(&buffer, zone_name, strlen(zone_name)); + 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), diff --git a/lib/dns/dnssec.c b/lib/dns/dnssec.c index 3569ad7..587bd1c 100644 --- a/lib/dns/dnssec.c +++ b/lib/dns/dnssec.c @@ -275,7 +275,7 @@ dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, if (ret != ISC_R_SUCCESS) goto cleanup_databuf; - ret = dst_context_create(key, mctx, &ctx); + ret = dst_context_create2(key, mctx, DNS_LOGCATEGORY_DNSSEC, &ctx); if (ret != ISC_R_SUCCESS) goto cleanup_databuf; @@ -352,7 +352,6 @@ dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, ret = ISC_R_NOSPACE; goto cleanup_array; } - memcpy(sig.signature, r.base, sig.siglen); ret = dns_rdata_fromstruct(sigrdata, sig.common.rdclass, sig.common.rdtype, &sig, buffer); @@ -462,7 +461,7 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, } again: - ret = dst_context_create(key, mctx, &ctx); + ret = dst_context_create2(key, mctx, DNS_LOGCATEGORY_DNSSEC, &ctx); if (ret != ISC_R_SUCCESS) goto cleanup_struct; @@ -551,9 +550,9 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, 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_GENERAL, - DNS_LOGMODULE_DNSSEC, ISC_LOG_INFO, - "sucessfully validated after lower casing " + 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) @@ -854,7 +853,7 @@ dns_dnssec_signmessage(dns_message_t *msg, dst_key_t *key) { isc_buffer_init(&databuf, data, sizeof(data)); - RETERR(dst_context_create(key, mctx, &ctx)); + RETERR(dst_context_create2(key, mctx, DNS_LOGCATEGORY_DNSSEC, &ctx)); /* * Digest the fields of the SIG - we can cheat and use @@ -1004,7 +1003,7 @@ dns_dnssec_verifymessage(isc_buffer_t *source, dns_message_t *msg, goto failure; } - RETERR(dst_context_create(key, mctx, &ctx)); + RETERR(dst_context_create2(key, mctx, DNS_LOGCATEGORY_DNSSEC, &ctx)); /* * Digest the SIG(0) record, except for the signature. diff --git a/lib/dns/dst_api.c b/lib/dns/dst_api.c index f5dd89a..53978bc 100644 --- a/lib/dns/dst_api.c +++ b/lib/dns/dst_api.c @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -276,6 +276,13 @@ dst_algorithm_supported(unsigned int alg) { 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; @@ -294,6 +301,7 @@ dst_context_create(dst_key_t *key, isc_mem_t *mctx, dst_context_t **dctxp) { 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)); @@ -495,8 +503,7 @@ dst_key_fromnamedfile(const char *filename, const char *dirname, result = dst_key_read_public(newfilename, type, mctx, &pubkey); isc_mem_put(mctx, newfilename, newfilenamelen); newfilename = NULL; - if (result != ISC_R_SUCCESS) - return (result); + RETERR(result); if ((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) == DST_TYPE_PUBLIC || (pubkey->key_flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY) { @@ -560,7 +567,8 @@ dst_key_fromnamedfile(const char *filename, const char *dirname, isc_mem_put(mctx, newfilename, newfilenamelen); if (lex != NULL) isc_lex_destroy(&lex); - dst_key_free(&key); + if (key != NULL) + dst_key_free(&key); return (result); } @@ -1190,7 +1198,7 @@ dst_key_dump(dst_key_t *key, isc_mem_t *mctx, char **buffer, int *length) { REQUIRE(length != NULL && *length == 0); REQUIRE(VALID_KEY(key)); - if (key->func->isprivate == NULL) + if (key->func->dump == NULL) return (ISC_R_NOTIMPLEMENTED); return (key->func->dump(key, mctx, buffer, length)); } @@ -1247,24 +1255,24 @@ get_key_struct(dns_name_t *name, unsigned int alg, return (NULL); memset(key, 0, sizeof(dst_key_t)); - key->magic = KEY_MAGIC; - - result = isc_refcount_init(&key->refs, 1); - if (result != ISC_R_SUCCESS) { - isc_mem_put(mctx, key, sizeof(dst_key_t)); - return (NULL); - } key->key_name = isc_mem_get(mctx, sizeof(dns_name_t)); if (key->key_name == NULL) { - isc_refcount_destroy(&key->refs); 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_refcount_destroy(&key->refs); + 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); @@ -1283,6 +1291,7 @@ get_key_struct(dns_name_t *name, unsigned int alg, key->times[i] = 0; key->timeset[i] = ISC_FALSE; } + key->magic = KEY_MAGIC; return (key); } diff --git a/lib/dns/dst_internal.h b/lib/dns/dst_internal.h index 2f4f946..ee824f4 100644 --- a/lib/dns/dst_internal.h +++ b/lib/dns/dst_internal.h @@ -137,6 +137,7 @@ 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; diff --git a/lib/dns/dst_openssl.h b/lib/dns/dst_openssl.h index a30fd6a..e4d636e 100644 --- a/lib/dns/dst_openssl.h +++ b/lib/dns/dst_openssl.h @@ -21,6 +21,7 @@ #define DST_OPENSSL_H 1 #include <isc/lang.h> +#include <isc/log.h> #include <isc/result.h> #include <openssl/err.h> @@ -42,6 +43,10 @@ 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); diff --git a/lib/dns/ecdb.c b/lib/dns/ecdb.c index f1a833f..20da5b0 100644 --- a/lib/dns/ecdb.c +++ b/lib/dns/ecdb.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -80,8 +80,11 @@ typedef struct rdatasetheader { /* 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, @@ -406,6 +409,8 @@ bind_rdataset(dns_ecdb_t *ecdb, dns_ecdbnode_t *node, 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; @@ -469,6 +474,8 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 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); diff --git a/lib/dns/gen.c b/lib/dns/gen.c index a0b4df3..6b533dd 100644 --- a/lib/dns/gen.c +++ b/lib/dns/gen.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -15,8 +15,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: gen.c,v 1.85 2009/12/04 22:06:37 tbox Exp $ */ - /*! \file */ #ifdef WIN32 @@ -24,6 +22,10 @@ * 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> @@ -41,7 +43,12 @@ #include "gen-unix.h" #endif -#define TYPECLASSLEN 21 +#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" @@ -103,7 +110,7 @@ #define CHECKNAMESTYPE "rdata->type" #define CHECKNAMESDEF "result = ISC_TRUE" -const char copyright[] = +static const char copyright[] = "/*\n" " * Copyright (C) 2004%s Internet Systems Consortium, Inc. (\"ISC\")\n" " * Copyright (C) 1998-2003 Internet Software Consortium.\n" @@ -131,53 +138,59 @@ const char copyright[] = "/*! \\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 -struct cc { +static struct cc { struct cc *next; int rdclass; - char classname[TYPECLASSLEN]; + char classname[TYPECLASSBUF]; } *classes; -struct tt { +static struct tt { struct tt *next; int rdclass; int type; - char classname[TYPECLASSLEN]; - char typename[TYPECLASSLEN]; - char dirname[256]; /* XXX Should be max path length */ + char classname[TYPECLASSBUF]; + char typename[TYPECLASSBUF]; + char dirname[DIRNAMESIZE]; /* XXX Should be max path length */ } *types; -struct ttnam { - char typename[TYPECLASSLEN]; - char macroname[TYPECLASSLEN]; - char attr[256]; +static struct ttnam { + char typename[TYPECLASSBUF]; + char macroname[TYPECLASSBUF]; + char attr[ATTRIBUTESIZE]; unsigned int sorted; int type; } typenames[TYPENAMES]; -int maxtype = -1; +static int maxtype = -1; -char * +static char * upper(char *); -char * +static char * funname(const char *, char *); -void +static void doswitch(const char *, const char *, const char *, const char *, const char *, const char *); -void -dodecl(char *, char *, char *); -void +static void add(int, const char *, int, const char *, const char *); -void +static void sd(int, const char *, const char *, char); -void +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. */ -char * +static char * upper(char *s) { static int buf_to_use = 0; static char buf[10][256]; @@ -197,11 +210,12 @@ upper(char *s) { return (buf[buf_to_use]); } -char * +static char * funname(const char *s, char *buf) { char *b = buf; char c; + INSIST(strlen(s) < TYPECLASSBUF); while ((c = *s++)) { *b++ = (c == '-') ? '_' : c; } @@ -209,7 +223,7 @@ funname(const char *s, char *buf) { return (buf); } -void +static void doswitch(const char *name, const char *function, const char *args, const char *tsw, const char *csw, const char *res) { @@ -217,7 +231,7 @@ doswitch(const char *name, const char *function, const char *args, int first = 1; int lasttype = 0; int subswitch = 0; - char buf1[TYPECLASSLEN], buf2[TYPECLASSLEN]; + char buf1[TYPECLASSBUF], buf2[TYPECLASSBUF]; const char *result = " result ="; if (res == NULL) @@ -280,26 +294,6 @@ doswitch(const char *name, const char *function, const char *args, } } -void -dodecl(char *type, char *function, char *args) { - struct tt *tt; - char buf1[TYPECLASSLEN], buf2[TYPECLASSLEN]; - - fputs("\n", stdout); - for (tt = types; tt; tt = tt->next) - if (tt->rdclass) - fprintf(stdout, - "static inline %s %s_%s_%s(%s);\n", - type, function, - funname(tt->classname, buf1), - funname(tt->typename, buf2), args); - else - fprintf(stdout, - "static inline %s %s_%s(%s);\n", - type, function, - funname(tt->typename, buf1), args); -} - static struct ttnam * find_typename(int type) { int i; @@ -312,12 +306,13 @@ find_typename(int type) { return (NULL); } -void +static void insert_into_typenames(int type, const char *typename, const char *attr) { struct ttnam *ttn = NULL; - int c, i; + 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 && @@ -340,10 +335,10 @@ insert_into_typenames(int type, const char *typename, const char *attr) { typename); exit(1); } - strcpy(ttn->typename, typename); + strncpy(ttn->typename, typename, sizeof(ttn->typename)); ttn->type = type; - strcpy(ttn->macroname, ttn->typename); + strncpy(ttn->macroname, ttn->typename, sizeof(ttn->macroname)); c = strlen(ttn->macroname); while (c > 0) { if (ttn->macroname[c - 1] == '-') @@ -352,7 +347,9 @@ insert_into_typenames(int type, const char *typename, const char *attr) { } if (attr == NULL) { - sprintf(tmp, "RRTYPE_%s_ATTRIBUTES", upper(ttn->macroname)); + n = snprintf(tmp, sizeof(tmp), + "RRTYPE_%s_ATTRIBUTES", upper(ttn->macroname)); + INSIST(n > 0 && (unsigned)n < sizeof(tmp)); attr = tmp; } @@ -367,13 +364,13 @@ insert_into_typenames(int type, const char *typename, const char *attr) { attr, typename); exit(1); } - strcpy(ttn->attr, attr); + strncpy(ttn->attr, attr, sizeof(ttn->attr)); ttn->sorted = 0; if (maxtype < type) maxtype = type; } -void +static void add(int rdclass, const char *classname, int type, const char *typename, const char *dirname) { @@ -382,6 +379,10 @@ add(int rdclass, const char *classname, int type, const char *typename, 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) { @@ -392,11 +393,11 @@ add(int rdclass, const char *classname, int type, const char *typename, newtt->next = NULL; newtt->rdclass = rdclass; newtt->type = type; - strcpy(newtt->classname, classname); - strcpy(newtt->typename, typename); + strncpy(newtt->classname, classname, sizeof(newtt->classname)); + strncpy(newtt->typename, typename, sizeof(newtt->typename)); if (strncmp(dirname, "./", 2) == 0) dirname += 2; - strcpy(newtt->dirname, dirname); + strncpy(newtt->dirname, dirname, sizeof(newtt->dirname)); tt = types; oldtt = NULL; @@ -429,8 +430,12 @@ add(int rdclass, const char *classname, int type, const char *typename, return; newcc = (struct cc *)malloc(sizeof(*newcc)); + if (newcc == NULL) { + fprintf(stderr, "malloc() failed\n"); + exit(1); + } newcc->rdclass = rdclass; - strcpy(newcc->classname, classname); + strncpy(newcc->classname, classname, sizeof(newcc->classname)); cc = classes; oldcc = NULL; @@ -451,25 +456,25 @@ add(int rdclass, const char *classname, int type, const char *typename, classes = newcc; } -void +static void sd(int rdclass, const char *classname, const char *dirname, char filetype) { - char buf[sizeof("01234567890123456789_65535.h")]; - char fmt[sizeof("%20[-0-9a-z]_%d.h")]; - int type; - char typename[TYPECLASSLEN]; + char buf[TYPECLASSLEN + sizeof("_65535.h")]; + char typename[TYPECLASSBUF]; + int type, n; isc_dir_t dir; if (!start_directory(dirname, &dir)) return; - sprintf(fmt,"%s%c", "%20[-0-9a-z]_%d.", filetype); while (next_file(&dir)) { - if (sscanf(dir.filename, fmt, typename, &type) != 2) + if (sscanf(dir.filename, TYPECLASSFMT, typename, &type) != 2) continue; if ((type > 65535) || (type < 0)) continue; - sprintf(buf, "%s_%d.%c", typename, type, filetype); + 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); @@ -496,10 +501,10 @@ HASH(char *string) { int main(int argc, char **argv) { - char buf[256]; /* XXX Should be max path length */ - char srcdir[256]; /* XXX Should be max path length */ + char buf[DIRNAMESIZE]; /* XXX Should be max path length */ + char srcdir[DIRNAMESIZE]; /* XXX Should be max path length */ int rdclass; - char classname[TYPECLASSLEN]; + char classname[TYPECLASSBUF]; struct tt *tt; struct cc *cc; struct ttnam *ttn, *ttn2; @@ -513,8 +518,8 @@ main(int argc, char **argv) { int type_enum = 0; int structs = 0; int depend = 0; - int c, i, j; - char buf1[TYPECLASSLEN]; + int c, i, j, n; + char buf1[TYPECLASSBUF]; char filetype = 'c'; FILE *fd; char *prefix = NULL; @@ -561,7 +566,16 @@ main(int argc, char **argv) { filetype = 'h'; break; case 's': - sprintf(srcdir, "%s/", isc_commandline_argument); + 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; @@ -576,31 +590,37 @@ main(int argc, char **argv) { exit(1); } - sprintf(buf, "%srdata", srcdir); + 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, "%10[0-9a-z]_%d", - classname, &rdclass) != 2) + if (sscanf(dir.filename, TYPECLASSFMT, classname, + &rdclass) != 2) continue; if ((rdclass > 65535) || (rdclass < 0)) continue; - sprintf(buf, "%srdata/%s_%d", srcdir, classname, rdclass); + 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); - sprintf(buf, "%srdata/generic", srcdir); + 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) - sprintf(year, "-%d", tm->tm_year + 1900); - else + 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; @@ -862,7 +882,7 @@ main(int argc, char **argv) { } } for (tt = types; tt != NULL; tt = tt->next) { - sprintf(buf, "%s/%s_%d.h", + 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) diff --git a/lib/dns/gssapictx.c b/lib/dns/gssapictx.c index ee5be56..e4047d2 100644 --- a/lib/dns/gssapictx.c +++ b/lib/dns/gssapictx.c @@ -541,7 +541,7 @@ gss_err_message(isc_mem_t *mctx, isc_uint32_t major, isc_uint32_t minor, } estr = gss_error_tostring(major, minor, buf, sizeof(buf)); - if (estr) + if (estr != NULL) (*err_message) = isc_mem_strdup(mctx, estr); } #endif @@ -597,8 +597,12 @@ dst_gssapi_initctx(dns_name_t *name, isc_buffer_t *intoken, if (gret != GSS_S_COMPLETE && gret != GSS_S_CONTINUE_NEEDED) { gss_err_message(mctx, gret, minor, err_message); - gss_log(3, "Failure initiating security context: %s", - *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; } diff --git a/lib/dns/include/dns/acache.h b/lib/dns/include/dns/acache.h index 28990c2..c372ed9 100644 --- a/lib/dns/include/dns/acache.h +++ b/lib/dns/include/dns/acache.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006, 2007 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -25,7 +25,7 @@ /* * Acache - * + * * The Additional Cache Object * * This module manages internal caching entries that correspond to @@ -131,7 +131,7 @@ * - 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 + * * 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 @@ -387,7 +387,7 @@ dns_acache_setentry(dns_acache_t *acache, dns_acacheentry_t *entry, * ISC_R_NOTFOUND */ -void +isc_boolean_t dns_acache_cancelentry(dns_acacheentry_t *entry); /* * Cancel the use of the cache entry 'entry'. This function is supposed to @@ -398,6 +398,9 @@ dns_acache_cancelentry(dns_acacheentry_t *entry); * * Requires: * 'entry' is a valid additional cache entry. + * + * Returns: + * ISC_TRUE if the entry was active when canceled */ void @@ -415,7 +418,7 @@ dns_acache_attachentry(dns_acacheentry_t *source, dns_acacheentry_t **targetp); * * *targetp is attached to 'source'. */ - + void dns_acache_detachentry(dns_acacheentry_t **entryp); /* @@ -429,7 +432,7 @@ dns_acache_detachentry(dns_acacheentry_t **entryp); * * *entryp is NULL. * - * If '*entryp' is the last reference to the entry, + * 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. */ diff --git a/lib/dns/include/dns/db.h b/lib/dns/include/dns/db.h index fe268f4..ef090a2 100644 --- a/lib/dns/include/dns/db.h +++ b/lib/dns/include/dns/db.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -171,7 +171,7 @@ typedef struct dns_dbmethods { dns_dbversion_t *version); isc_boolean_t (*isdnssec)(dns_db_t *db); dns_stats_t *(*getrrsetstats)(dns_db_t *db); - void (*rpz_enabled)(dns_db_t *db, dns_rpz_st_t *st); + isc_result_t (*rpz_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, @@ -1500,11 +1500,11 @@ dns_db_getrrsetstats(dns_db_t *db); * dns_rdatasetstats_create(); otherwise NULL. */ -void +isc_result_t dns_db_rpz_enabled(dns_db_t *db, dns_rpz_st_t *st); /*%< - * See if a policy database has DNS_RPZ_TYPE_IP, DNS_RPZ_TYPE_NSIP, or - * DNS_RPZ_TYPE_NSDNAME records. + * Mark a database for response policy rewriting + * or find which RPZ data is available. */ void diff --git a/lib/dns/include/dns/message.h b/lib/dns/include/dns/message.h index 3bc734d..a6862fa 100644 --- a/lib/dns/include/dns/message.h +++ b/lib/dns/include/dns/message.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2010, 2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -251,6 +251,12 @@ struct dns_message { const void * order_arg; }; +struct dns_ednsopt { + isc_uint16_t code; + isc_uint16_t length; + unsigned char *value; +}; + /*** *** Functions ***/ @@ -1350,6 +1356,24 @@ dns_message_gettimeadjust(dns_message_t *msg); *\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/lib/dns/include/dns/name.h b/lib/dns/include/dns/name.h index bef8693..1a88e53 100644 --- a/lib/dns/include/dns/name.h +++ b/lib/dns/include/dns/name.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007, 2009-2011 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -1299,15 +1299,17 @@ ISC_LANG_ENDDECLS #define DNS_NAME_INIT(n, o) \ do { \ - (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); \ + 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) \ diff --git a/lib/dns/include/dns/ncache.h b/lib/dns/include/dns/ncache.h index 8d89879..337e834 100644 --- a/lib/dns/include/dns/ncache.h +++ b/lib/dns/include/dns/ncache.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -73,6 +73,11 @@ dns_ncache_addoptout(dns_message_t *message, dns_db_t *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. * diff --git a/lib/dns/include/dns/nsec.h b/lib/dns/include/dns/nsec.h index a18e138..510d96b 100644 --- a/lib/dns/include/dns/nsec.h +++ b/lib/dns/include/dns/nsec.h @@ -75,6 +75,19 @@ dns_nsec_nseconly(dns_db_t *db, dns_dbversion_t *version, * 'answer' to be non NULL. */ +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/lib/dns/include/dns/nsec3.h b/lib/dns/include/dns/nsec3.h index beb44f3..588dd05 100644 --- a/lib/dns/include/dns/nsec3.h +++ b/lib/dns/include/dns/nsec3.h @@ -247,6 +247,14 @@ dns_nsec3param_deletechains(dns_db_t *db, dns_dbversion_t *ver, * 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 diff --git a/lib/dns/include/dns/rdata.h b/lib/dns/include/dns/rdata.h index c3e7db6..2a67dc9 100644 --- a/lib/dns/include/dns/rdata.h +++ b/lib/dns/include/dns/rdata.h @@ -176,6 +176,7 @@ struct dns_rdata { #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 diff --git a/lib/dns/include/dns/result.h b/lib/dns/include/dns/result.h index 21388b2..9a7d2c2 100644 --- a/lib/dns/include/dns/result.h +++ b/lib/dns/include/dns/result.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -151,8 +151,10 @@ #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 108 /*%< Number of results */ +#define DNS_R_NRESULTS 110 /*%< Number of results */ /* * DNS wire format rcodes. diff --git a/lib/dns/include/dns/rpz.h b/lib/dns/include/dns/rpz.h index 4227dd4..ceea26d 100644 --- a/lib/dns/include/dns/rpz.h +++ b/lib/dns/include/dns/rpz.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -27,10 +27,11 @@ ISC_LANG_BEGINDECLS -#define DNS_RPZ_IP_ZONE "rpz-ip" -#define DNS_RPZ_NSIP_ZONE "rpz-nsip" -#define DNS_RPZ_NSDNAME_ZONE "rpz-nsdname" -#define DNS_RPZ_PASSTHRU_ZONE "rpz-passthru" +#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; @@ -75,6 +76,7 @@ struct dns_rpz_zone { 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; }; /* @@ -169,12 +171,6 @@ const char * dns_rpz_policy2str(dns_rpz_policy_t policy); void -dns_rpz_set_need(isc_boolean_t need); - -isc_boolean_t -dns_rpz_needed(void); - -void dns_rpz_cidr_free(dns_rpz_cidr_t **cidr); void @@ -184,7 +180,7 @@ isc_result_t dns_rpz_new_cidr(isc_mem_t *mctx, dns_name_t *origin, dns_rpz_cidr_t **rbtdb_cidr); void -dns_rpz_enabled(dns_rpz_cidr_t *cidr, dns_rpz_st_t *st); +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); diff --git a/lib/dns/include/dns/types.h b/lib/dns/include/dns/types.h index 921c76aa..a031825 100644 --- a/lib/dns/include/dns/types.h +++ b/lib/dns/include/dns/types.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2010, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010, 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 @@ -72,6 +72,7 @@ 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; @@ -373,4 +374,7 @@ 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/lib/dns/include/dns/validator.h b/lib/dns/include/dns/validator.h index 7d6ea7a..b3cfe99 100644 --- a/lib/dns/include/dns/validator.h +++ b/lib/dns/include/dns/validator.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -104,6 +104,10 @@ typedef struct dns_validatorevent { * Optout proof seen. */ isc_boolean_t optout; + /* + * Answer is secure. + */ + isc_boolean_t secure; } dns_validatorevent_t; #define DNS_VALIDATOR_NOQNAMEPROOF 0 diff --git a/lib/dns/include/dns/view.h b/lib/dns/include/dns/view.h index 4a04867..d999fa1 100644 --- a/lib/dns/include/dns/view.h +++ b/lib/dns/include/dns/view.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -164,6 +164,7 @@ struct dns_view { 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, diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h index 9db825c..6b9911d 100644 --- a/lib/dns/include/dns/zone.h +++ b/lib/dns/include/dns/zone.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -34,6 +34,7 @@ #include <dns/masterdump.h> #include <dns/rdatastruct.h> +#include <dns/rpz.h> #include <dns/types.h> typedef enum { @@ -77,6 +78,7 @@ typedef enum { #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 /* @@ -1898,6 +1900,15 @@ dns_zone_synckeyzone(dns_zone_t *zone); * 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); + ISC_LANG_ENDDECLS #endif /* DNS_ZONE_H */ diff --git a/lib/dns/include/dst/dst.h b/lib/dns/include/dst/dst.h index b0fa690..87d844b 100644 --- a/lib/dns/include/dst/dst.h +++ b/lib/dns/include/dst/dst.h @@ -26,6 +26,7 @@ #include <isc/stdtime.h> #include <dns/types.h> +#include <dns/log.h> #include <dns/name.h> #include <dns/secalg.h> @@ -169,6 +170,11 @@ dst_algorithm_supported(unsigned int alg); 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. * diff --git a/lib/dns/master.c b/lib/dns/master.c index 8304507..1b7460c 100644 --- a/lib/dns/master.c +++ b/lib/dns/master.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -156,6 +156,7 @@ struct dns_incctx { 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; @@ -568,6 +569,7 @@ loadctx_create(dns_masterformat_t format, isc_mem_t *mctx, goto cleanup_inc; lctx->keep_lex = ISC_FALSE; memset(specials, 0, sizeof(specials)); + specials[0] = 1; specials['('] = 1; specials[')'] = 1; specials['"'] = 1; @@ -770,7 +772,7 @@ static isc_result_t openfile_raw(dns_loadctx_t *lctx, const char *master_file) { isc_result_t result; - result = isc_stdio_open(master_file, "r", &lctx->f); + 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", @@ -1402,6 +1404,7 @@ load_text(dns_loadctx_t *lctx) { 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; @@ -1574,8 +1577,24 @@ load_text(dns_loadctx_t *lctx) { } 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) diff --git a/lib/dns/message.c b/lib/dns/message.c index 2b65f0e..d36edba 100644 --- a/lib/dns/message.c +++ b/lib/dns/message.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -1441,8 +1441,15 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, * the opcode is an update, or the type search is skipped. */ if (result == ISC_R_SUCCESS) { - if (dns_rdatatype_issingleton(rdtype)) - DO_FORMERR; + 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) { @@ -2112,6 +2119,30 @@ dns_message_renderend(dns_message_t *msg) { } /* + * 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) { @@ -2136,30 +2167,6 @@ dns_message_renderend(dns_message_t *msg) { } /* - * If we're adding a TSIG or SIG(0) to a truncated message, - * clear all rdatasets from the message except for the question - * before adding the TSIG or SIG(0). If the question doesn't fit, - * don't include it. - */ - if ((msg->tsigkey != NULL || msg->sig0key != NULL) && - (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're adding a TSIG record, generate and render it. */ if (msg->tsigkey != NULL) { @@ -2633,9 +2640,9 @@ dns_message_setopt(dns_message_t *msg, dns_rdataset_t *opt) { return (ISC_R_SUCCESS); cleanup: + dns_rdataset_disassociate(opt); dns_message_puttemprdataset(msg, &opt); return (result); - } dns_rdataset_t * @@ -3449,3 +3456,95 @@ dns_opcode_totext(dns_opcode_t opcode, isc_buffer_t *target) { 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/lib/dns/name.c b/lib/dns/name.c index fab1f33..7fb21e1 100644 --- a/lib/dns/name.c +++ b/lib/dns/name.c @@ -584,11 +584,13 @@ dns_name_fullcompare(const dns_name_t *name1, const dns_name_t *name2, nlabels = 0; l1 = name1->labels; l2 = name2->labels; - ldiff = (int)l1 - (int)l2; - if (ldiff < 0) + if (l2 > l1) { l = l1; - else + ldiff = 0 - (l2 - l1); + } else { l = l2; + ldiff = l1 - l2; + } while (l > 0) { l--; @@ -841,6 +843,10 @@ dns_name_matcheswildcard(const dns_name_t *name, const dns_name_t *wname) { 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) == @@ -1427,6 +1433,7 @@ dns_name_totext2(dns_name_t *name, unsigned int options, isc_buffer_t *target) case 0x24: /* '$' */ if ((options & DNS_NAME_MASTERFILE) == 0) goto no_escape; + /* FALLTHROUGH */ case 0x22: /* '"' */ case 0x28: /* '(' */ case 0x29: /* ')' */ @@ -1934,6 +1941,10 @@ dns_name_towire(const dns_name_t *name, dns_compress_t *cctx, * 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; @@ -2239,7 +2250,12 @@ dns_name_digest(dns_name_t *name, dns_digestfunc_t digest, void *arg) { 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); @@ -2404,7 +2420,7 @@ dns_name_fromstring2(dns_name_t *target, const char *src, REQUIRE(src != NULL); - isc_buffer_init(&buf, src, strlen(src)); + isc_buffer_constinit(&buf, src, strlen(src)); isc_buffer_add(&buf, strlen(src)); if (BINDABLE(target) && target->buffer != NULL) name = target; diff --git a/lib/dns/ncache.c b/lib/dns/ncache.c index c0e99d4..bcb3d05 100644 --- a/lib/dns/ncache.c +++ b/lib/dns/ncache.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2008, 2010-2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -47,6 +47,12 @@ * */ +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; @@ -96,8 +102,8 @@ 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 (dns_ncache_addoptout(message, cache, node, covers, now, maxttl, - ISC_FALSE, addedrdataset)); + return (addoptout(message, cache, node, covers, now, maxttl, + ISC_FALSE, ISC_FALSE, addedrdataset)); } isc_result_t @@ -106,6 +112,16 @@ dns_ncache_addoptout(dns_message_t *message, dns_db_t *cache, 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; @@ -242,6 +258,8 @@ dns_ncache_addoptout(dns_message_t *message, dns_db_t *cache, 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) diff --git a/lib/dns/nsec.c b/lib/dns/nsec.c index 72d1751..41b5dc3 100644 --- a/lib/dns/nsec.c +++ b/lib/dns/nsec.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -21,6 +21,7 @@ #include <config.h> +#include <isc/log.h> #include <isc/string.h> #include <isc/util.h> @@ -275,3 +276,161 @@ dns_nsec_nseconly(dns_db_t *db, dns_dbversion_t *version, } 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/lib/dns/nsec3.c b/lib/dns/nsec3.c index 123126d..7ec6b4c 100644 --- a/lib/dns/nsec3.c +++ b/lib/dns/nsec3.c @@ -22,6 +22,7 @@ #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> @@ -1132,7 +1133,11 @@ dns_nsec3param_deletechains(dns_db_t *db, dns_dbversion_t *ver, INSIST(rdata.length <= sizeof(buf)); memcpy(buf, rdata.data, rdata.length); - if (buf[0] != 0 || + /* + * 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 | DNS_NSEC3FLAG_NONSEC)) { dns_rdata_reset(&rdata); continue; @@ -1832,3 +1837,285 @@ dns_nsec3_maxiterations(dns_db_t *db, dns_dbversion_t *version, 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/lib/dns/openssl_link.c b/lib/dns/openssl_link.c index d186761..56465aa 100644 --- a/lib/dns/openssl_link.c +++ b/lib/dns/openssl_link.c @@ -286,46 +286,78 @@ dst__openssl_destroy() { } } -isc_result_t -dst__openssl_toresult(isc_result_t fallback) { +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 (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) { - isc_result_t result = fallback; - unsigned long err = ERR_peek_error(); + 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]; - switch (ERR_GET_REASON(err)) { - case ERR_R_MALLOC_FAILURE: - result = ISC_R_NOMEMORY; - goto done; - default: - break; - } - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, + result = toresult(fallback); + + isc_log_write(dns_lctx, category, DNS_LOGMODULE_CRYPTO, ISC_LOG_WARNING, - "%s failed", funcname); + "%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, DNS_LOGCATEGORY_GENERAL, + isc_log_write(dns_lctx, category, DNS_LOGMODULE_CRYPTO, ISC_LOG_INFO, "%s:%s:%d:%s", buf, file, line, (flags & ERR_TXT_STRING) ? data : ""); diff --git a/lib/dns/openssldsa_link.c b/lib/dns/openssldsa_link.c index e2cf8cd..66d47bb 100644 --- a/lib/dns/openssldsa_link.c +++ b/lib/dns/openssldsa_link.c @@ -168,7 +168,8 @@ openssldsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { if (!EVP_SignFinal(evp_md_ctx, sigbuf, &siglen, pkey)) { EVP_PKEY_free(pkey); free(sigbuf); - return (dst__openssl_toresult2("EVP_SignFinal", + return (dst__openssl_toresult3(dctx->category, + "EVP_SignFinal", ISC_R_FAILURE)); } INSIST(EVP_PKEY_size(pkey) >= (int) siglen); @@ -182,25 +183,30 @@ openssldsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { sb = sigbuf; if (d2i_DSA_SIG(&dsasig, &sb, (long) siglen) == NULL) { free(sigbuf); - return (dst__openssl_toresult2("d2i_DSA_SIG", ISC_R_FAILURE)); + 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_toresult2("EVP_DigestFinal_ex", + 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_toresult2("DSA_do_sign", + 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_toresult2("DSA_do_sign", + return (dst__openssl_toresult3(dctx->category, + "DSA_do_sign", DST_R_SIGNFAILURE)); #endif *r.base++ = (key->key_size - 512)/64; @@ -286,7 +292,8 @@ openssldsa_verify(dst_context_t *dctx, const isc_region_t *sig) { case 0: return (dst__openssl_toresult(DST_R_VERIFYFAILURE)); default: - return (dst__openssl_toresult2("DSA_do_verify", + return (dst__openssl_toresult3(dctx->category, + "DSA_do_verify", DST_R_VERIFYFAILURE)); } } diff --git a/lib/dns/opensslecdsa_link.c b/lib/dns/opensslecdsa_link.c index e6c9b67..1cf30f8 100644 --- a/lib/dns/opensslecdsa_link.c +++ b/lib/dns/opensslecdsa_link.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -73,7 +73,8 @@ opensslecdsa_createctx(dst_key_t *key, dst_context_t *dctx) { if (!EVP_DigestInit_ex(evp_md_ctx, type, NULL)) { EVP_MD_CTX_destroy(evp_md_ctx); - return (dst__openssl_toresult2("EVP_DigestInit_ex", + return (dst__openssl_toresult3(dctx->category, + "EVP_DigestInit_ex", ISC_R_FAILURE)); } @@ -103,7 +104,8 @@ opensslecdsa_adddata(dst_context_t *dctx, const isc_region_t *data) { dctx->key->key_alg == DST_ALG_ECDSA384); if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length)) - return (dst__openssl_toresult2("EVP_DigestUpdate", + return (dst__openssl_toresult3(dctx->category, + "EVP_DigestUpdate", ISC_R_FAILURE)); return (ISC_R_SUCCESS); @@ -147,12 +149,14 @@ opensslecdsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { DST_RET(ISC_R_NOSPACE); if (!EVP_DigestFinal(evp_md_ctx, digest, &dgstlen)) - DST_RET(dst__openssl_toresult2("EVP_DigestFinal", + 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_toresult2("ECDSA_do_sign", + 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; @@ -196,14 +200,19 @@ opensslecdsa_verify(dst_context_t *dctx, const isc_region_t *sig) { return (DST_R_VERIFYFAILURE); if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &dgstlen)) - DST_RET (dst__openssl_toresult2("EVP_DigestFinal_ex", + 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; */ @@ -216,7 +225,8 @@ opensslecdsa_verify(dst_context_t *dctx, const isc_region_t *sig) { ret = dst__openssl_toresult(DST_R_VERIFYFAILURE); break; default: - ret = dst__openssl_toresult2("ECDSA_do_verify", + ret = dst__openssl_toresult3(dctx->category, + "ECDSA_do_verify", DST_R_VERIFYFAILURE); break; } diff --git a/lib/dns/opensslgost_link.c b/lib/dns/opensslgost_link.c index 8a55a6b..098e312 100644 --- a/lib/dns/opensslgost_link.c +++ b/lib/dns/opensslgost_link.c @@ -127,7 +127,8 @@ opensslgost_verify(dst_context_t *dctx, const isc_region_t *sig) { case 0: return (dst__openssl_toresult(DST_R_VERIFYFAILURE)); default: - return (dst__openssl_toresult2("EVP_VerifyFinal", + return (dst__openssl_toresult3(dctx->category, + "EVP_VerifyFinal", DST_R_VERIFYFAILURE)); } } diff --git a/lib/dns/opensslrsa_link.c b/lib/dns/opensslrsa_link.c index 80c3f57..2430f24 100644 --- a/lib/dns/opensslrsa_link.c +++ b/lib/dns/opensslrsa_link.c @@ -156,7 +156,8 @@ opensslrsa_createctx(dst_key_t *key, dst_context_t *dctx) { if (!EVP_DigestInit_ex(evp_md_ctx, type, NULL)) { EVP_MD_CTX_destroy(evp_md_ctx); - return (dst__openssl_toresult2("EVP_DigestInit_ex", + return (dst__openssl_toresult3(dctx->category, + "EVP_DigestInit_ex", ISC_R_FAILURE)); } dctx->ctxdata.evp_md_ctx = evp_md_ctx; @@ -305,7 +306,8 @@ opensslrsa_adddata(dst_context_t *dctx, const isc_region_t *data) { #if USE_EVP if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length)) { - return (dst__openssl_toresult2("EVP_DigestUpdate", + return (dst__openssl_toresult3(dctx->category, + "EVP_DigestUpdate", ISC_R_FAILURE)); } #else @@ -395,7 +397,8 @@ opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { return (ISC_R_NOSPACE); if (!EVP_SignFinal(evp_md_ctx, r.base, &siglen, pkey)) { - return (dst__openssl_toresult2("EVP_SignFinal", + return (dst__openssl_toresult3(dctx->category, + "EVP_SignFinal", ISC_R_FAILURE)); } #else @@ -489,7 +492,8 @@ opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { status = RSA_sign(type, digest, digestlen, r.base, &siglen, rsa); #endif if (status == 0) - return (dst__openssl_toresult2("RSA_sign", + return (dst__openssl_toresult3(dctx->category, + "RSA_sign", DST_R_OPENSSLFAILURE)); #endif @@ -525,6 +529,16 @@ opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) { #if USE_EVP 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 switch (dctx->key->key_alg) { case DST_ALG_RSAMD5: @@ -610,7 +624,8 @@ opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) { original, rsa, RSA_PKCS1_PADDING); if (status <= 0) - return (dst__openssl_toresult2( + return (dst__openssl_toresult3( + dctx->category, "RSA_public_decrypt", DST_R_VERIFYFAILURE)); if (status != (int)(prefixlen + digestlen)) @@ -631,12 +646,10 @@ opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) { status = RSA_verify(type, digest, digestlen, sig->base, RSA_size(rsa), rsa); #endif -#endif if (status != 1) - return (dst__openssl_toresult2("RSA_verify", - DST_R_VERIFYFAILURE)); - + return (dst__openssl_toresult(DST_R_VERIFYFAILURE)); return (ISC_R_SUCCESS); +#endif } static isc_boolean_t diff --git a/lib/dns/peer.c b/lib/dns/peer.c index c55d73d..ec9e08c 100644 --- a/lib/dns/peer.c +++ b/lib/dns/peer.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -533,7 +533,7 @@ dns_peer_setkeybycharp(dns_peer_t *peer, const char *keyval) { isc_result_t result; dns_fixedname_init(&fname); - isc_buffer_init(&b, keyval, strlen(keyval)); + 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); diff --git a/lib/dns/rbt.c b/lib/dns/rbt.c index 4e033d6..eb95d14 100644 --- a/lib/dns/rbt.c +++ b/lib/dns/rbt.c @@ -1537,6 +1537,8 @@ rehash(dns_rbt_t *rbt) { return; } + INSIST(rbt->hashsize > 0); + for (i = 0; i < rbt->hashsize; i++) rbt->hashtable[i] = NULL; @@ -1947,6 +1949,7 @@ dns_rbt_deletefromlevel(dns_rbtnode_t *delete, dns_rbtnode_t **rootp) { COLOR(sibling) = COLOR(parent); MAKE_BLACK(parent); + INSIST(RIGHT(sibling) != NULL); MAKE_BLACK(RIGHT(sibling)); rotate_left(parent, rootp); child = *rootp; @@ -1984,6 +1987,7 @@ dns_rbt_deletefromlevel(dns_rbtnode_t *delete, dns_rbtnode_t **rootp) { COLOR(sibling) = COLOR(parent); MAKE_BLACK(parent); + INSIST(LEFT(sibling) != NULL); MAKE_BLACK(LEFT(sibling)); rotate_right(parent, rootp); child = *rootp; diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index ef721b8..f6f96ab 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -1550,15 +1550,16 @@ delete_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node) DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, ISC_LOG_WARNING, - "delete_nsecnode(): " + "delete_node(): " "dns_rbt_deletenode(nsecnode): %s", isc_result_totext(result)); } } - result = dns_rbt_deletenode(rbtdb->tree, node, ISC_FALSE); #ifdef BIND9 - dns_rpz_cidr_deleteip(rbtdb->rpz_cidr, name); + 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); @@ -1572,7 +1573,7 @@ delete_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node) DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, ISC_LOG_WARNING, - "delete_nsecnode(): " + "delete_cnode(): " "dns_rbt_deletenode: %s", isc_result_totext(result)); } @@ -4547,19 +4548,28 @@ find_coveringnsec(rbtdb_search_t *search, dns_dbnode_t **nodep, } /* - * Mark a database for response policy rewriting. + * Mark a database for response policy rewriting + * or find which RPZ data is available. */ #ifdef BIND9 -static void -get_rpz_enabled(dns_db_t *db, dns_rpz_st_t *st) -{ +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); - dns_rpz_enabled(rbtdb->rpz_cidr, st); + 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); } /* @@ -6224,6 +6234,7 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion, * 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); @@ -6357,7 +6368,8 @@ addnoqname(dns_rbtdb_t *rbtdb, rdatasetheader_t *newheader, cleanup: dns_rdataset_disassociate(&neg); dns_rdataset_disassociate(&negsig); - free_noqname(mctx, &noqname); + if (noqname != NULL) + free_noqname(mctx, &noqname); return(result); } @@ -6407,7 +6419,8 @@ addclosest(dns_rbtdb_t *rbtdb, rdatasetheader_t *newheader, cleanup: dns_rdataset_disassociate(&neg); dns_rdataset_disassociate(&negsig); - free_noqname(mctx, &closest); + if (closest != NULL) + free_noqname(mctx, &closest); return(result); } @@ -6860,7 +6873,7 @@ loadnode(dns_rbtdb_t *rbtdb, dns_name_t *name, dns_rbtnode_t **nodep, noderesult = dns_rbt_addnode(rbtdb->tree, name, nodep); #ifdef BIND9 - if (noderesult == ISC_R_SUCCESS) + if (noderesult == ISC_R_SUCCESS && rbtdb->rpz_cidr != NULL) dns_rpz_cidr_addip(rbtdb->rpz_cidr, name); #endif @@ -7447,8 +7460,8 @@ static dns_dbmethods_t zone_methods = { isdnssec, NULL, #ifdef BIND9 - get_rpz_enabled, - rpz_findips + rpz_enabled, + rpz_findips, #else NULL, NULL @@ -7681,24 +7694,6 @@ dns_rbtdb_create return (result); } -#ifdef BIND9 - /* - * Get ready for response policy IP address searching if at least one - * zone has been configured as a response policy zone and this - * is not a cache zone. - * It would be better to know that this database is for a policy - * zone named for a view, but that would require knowledge from - * above such as an argv[] set from data in the zone. - */ - if (type == dns_dbtype_zone && !dns_name_equal(origin, dns_rootname)) { - result = dns_rpz_new_cidr(mctx, origin, &rbtdb->rpz_cidr); - if (result != ISC_R_SUCCESS) { - free_rbtdb(rbtdb, ISC_FALSE, NULL); - return (result); - } - } -#endif - /* * In order to set the node callback bit correctly in zone databases, * we need to know if the node has the origin name of the zone. @@ -7977,7 +7972,9 @@ rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) { 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. @@ -8929,12 +8926,10 @@ acache_callback(dns_acacheentry_t *entry, void **arg) { if (acarray != NULL && acarray[count].entry == entry) { acarray[count].entry = NULL; INSIST(acarray[count].cbarg == cbarg); - isc_mem_put(rbtdb->common.mctx, cbarg, sizeof(acache_cbarg_t)); acarray[count].cbarg = NULL; - } else isc_mem_put(rbtdb->common.mctx, cbarg, sizeof(acache_cbarg_t)); - - dns_acache_detachentry(&entry); + dns_acache_detachentry(&entry); + } NODE_UNLOCK(nodelock, isc_rwlocktype_write); @@ -8958,9 +8953,10 @@ acache_cancelentry(isc_mem_t *mctx, dns_acacheentry_t *entry, cbarg = *cbargp; - dns_acache_cancelentry(entry); - dns_db_detachnode(cbarg->db, &cbarg->node); - dns_db_detach(&cbarg->db); + 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)); @@ -9027,6 +9023,7 @@ rdataset_setadditional(dns_rdataset_t *rdataset, dns_rdatasetadditional_t type, 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); diff --git a/lib/dns/rdata.c b/lib/dns/rdata.c index 60890e0..3865f42 100644 --- a/lib/dns/rdata.c +++ b/lib/dns/rdata.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -15,8 +15,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ - /*! \file */ #include <config.h> @@ -124,6 +122,15 @@ 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); @@ -212,6 +219,70 @@ 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) @@ -559,9 +630,9 @@ unknown_fromtext(dns_rdataclass_t rdclass, dns_rdatatype_t type, if (type == 0 || dns_rdatatype_ismeta(type)) return (DNS_R_METATYPE); - result = isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - ISC_FALSE); - if (result == ISC_R_SUCCESS && token.value.as_ulong > 65535U) + 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) @@ -611,6 +682,7 @@ dns_rdata_fromtext(dns_rdata_t *rdata, dns_rdataclass_t rdclass, 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) { @@ -638,13 +710,33 @@ dns_rdata_fromtext(dns_rdata_t *rdata, dns_rdataclass_t rdclass, return (result); } - if (strcmp(DNS_AS_STR(token), "\\#") == 0) - result = unknown_fromtext(rdclass, type, lexer, mctx, target); - else { + 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. @@ -1174,6 +1266,157 @@ txt_fromwire(isc_buffer_t *source, isc_buffer_t *target) { 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, ®ion); + 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); + + 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; diff --git a/lib/dns/rdata/any_255/tsig_250.c b/lib/dns/rdata/any_255/tsig_250.c index 338c5dd..0046ed0 100644 --- a/lib/dns/rdata/any_255/tsig_250.c +++ b/lib/dns/rdata/any_255/tsig_250.c @@ -133,7 +133,7 @@ static inline isc_result_t totext_any_tsig(ARGS_TOTEXT) { isc_region_t sr; isc_region_t sigr; - char buf[sizeof("281474976710655 ")]; + char buf[sizeof(" 281474976710655 ")]; char *bufp; dns_name_t name; dns_name_t prefix; @@ -223,19 +223,14 @@ totext_any_tsig(ARGS_TOTEXT) { */ 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, "%u ", n); - RETERR(str_totext(buf, target)); - } + RETERR(dns_tsigrcode_totext((dns_rcode_t)n, target)); /* * Other Size. */ n = uint16_fromregion(&sr); isc_region_consume(&sr, 2); - sprintf(buf, "%u ", n); + sprintf(buf, " %u ", n); RETERR(str_totext(buf, target)); /* diff --git a/lib/dns/rdata/generic/dlv_32769.c b/lib/dns/rdata/generic/dlv_32769.c index 4dbcb1e..97f37f7 100644 --- a/lib/dns/rdata/generic/dlv_32769.c +++ b/lib/dns/rdata/generic/dlv_32769.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006, 2007, 2009, 2010, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2006, 2007, 2009, 2010, 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 @@ -91,7 +91,7 @@ fromtext_dlv(ARGS_FROMTEXT) { length = -1; break; } - return (isc_hex_tobuffer(lexer, target, -1)); + return (isc_hex_tobuffer(lexer, target, length)); } static inline isc_result_t diff --git a/lib/dns/rdata/generic/eui48_108.c b/lib/dns/rdata/generic/eui48_108.c new file mode 100644 index 0000000..3e52fec --- /dev/null +++ b/lib/dns/rdata/generic/eui48_108.c @@ -0,0 +1,215 @@ +/* + * 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, ®ion1); + dns_rdata_toregion(rdata2, ®ion2); + return (isc_region_compare(®ion1, ®ion2)); +} + +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/lib/dns/rdata/generic/eui48_108.h b/lib/dns/rdata/generic/eui48_108.h new file mode 100644 index 0000000..508c61f --- /dev/null +++ b/lib/dns/rdata/generic/eui48_108.h @@ -0,0 +1,26 @@ +/* + * 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/lib/dns/rdata/generic/eui64_109.c b/lib/dns/rdata/generic/eui64_109.c new file mode 100644 index 0000000..245994f --- /dev/null +++ b/lib/dns/rdata/generic/eui64_109.c @@ -0,0 +1,220 @@ +/* + * 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, ®ion1); + dns_rdata_toregion(rdata2, ®ion2); + return (isc_region_compare(®ion1, ®ion2)); +} + +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/lib/dns/rdata/generic/eui64_109.h b/lib/dns/rdata/generic/eui64_109.h new file mode 100644 index 0000000..56996f8 --- /dev/null +++ b/lib/dns/rdata/generic/eui64_109.h @@ -0,0 +1,26 @@ +/* + * 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/lib/dns/rdata/generic/l32_105.c b/lib/dns/rdata/generic/l32_105.c new file mode 100644 index 0000000..763ddb9 --- /dev/null +++ b/lib/dns/rdata/generic/l32_105.c @@ -0,0 +1,233 @@ +/* + * 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, ®ion); + 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, ®ion); + num = uint16_fromregion(®ion); + isc_region_consume(®ion, 2); + sprintf(buf, "%u", num); + RETERR(str_totext(buf, target)); + + RETERR(str_totext(" ", target)); + + return (inet_totext(AF_INET, ®ion, 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, ®ion1); + dns_rdata_toregion(rdata2, ®ion2); + return (isc_region_compare(®ion1, ®ion2)); +} + +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, ®ion); + l32->pref = uint16_fromregion(®ion); + n = uint32_fromregion(®ion); + 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/lib/dns/rdata/generic/l32_105.h b/lib/dns/rdata/generic/l32_105.h new file mode 100644 index 0000000..f95db22 --- /dev/null +++ b/lib/dns/rdata/generic/l32_105.h @@ -0,0 +1,27 @@ +/* + * 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/lib/dns/rdata/generic/l64_106.c b/lib/dns/rdata/generic/l64_106.c new file mode 100644 index 0000000..ff20663 --- /dev/null +++ b/lib/dns/rdata/generic/l64_106.c @@ -0,0 +1,228 @@ +/* + * 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, ®ion); + num = uint16_fromregion(®ion); + isc_region_consume(®ion, 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, ®ion1); + dns_rdata_toregion(rdata2, ®ion2); + return (isc_region_compare(®ion1, ®ion2)); +} + +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, ®ion); + l64->pref = uint16_fromregion(®ion); + 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/lib/dns/rdata/generic/l64_106.h b/lib/dns/rdata/generic/l64_106.h new file mode 100644 index 0000000..8f93fc5 --- /dev/null +++ b/lib/dns/rdata/generic/l64_106.h @@ -0,0 +1,27 @@ +/* + * 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/lib/dns/rdata/generic/lp_107.c b/lib/dns/rdata/generic/lp_107.c new file mode 100644 index 0000000..732ef7f --- /dev/null +++ b/lib/dns/rdata/generic/lp_107.c @@ -0,0 +1,275 @@ +/* + * 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, ®ion); + num = uint16_fromregion(®ion); + isc_region_consume(®ion, 2); + sprintf(buf, "%u", num); + RETERR(str_totext(buf, target)); + + RETERR(str_totext(" ", target)); + + dns_name_fromregion(&name, ®ion); + 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, ®ion1); + dns_rdata_toregion(rdata2, ®ion2); + + return (isc_region_compare(®ion1, ®ion2)); +} + +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, ®ion); + return (isc_buffer_copyregion(target, ®ion)); +} + +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, ®ion); + lp->pref = uint16_fromregion(®ion); + isc_region_consume(®ion, 2); + dns_name_fromregion(&name, ®ion); + 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, ®ion); + isc_region_consume(®ion, 2); + dns_name_fromregion(&name, ®ion); + + 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, ®ion); + return ((digest)(arg, ®ion)); +} + +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, ®ion1); + dns_rdata_toregion(rdata2, ®ion2); + + isc_region_consume(®ion1, 2); + isc_region_consume(®ion2, 2); + + dns_name_fromregion(&name1, ®ion1); + dns_name_fromregion(&name2, ®ion2); + + return (dns_name_rdatacompare(&name1, &name2)); +} + +#endif /* RDATA_GENERIC_LP_107_C */ diff --git a/lib/dns/rdata/generic/lp_107.h b/lib/dns/rdata/generic/lp_107.h new file mode 100644 index 0000000..cbfee8a --- /dev/null +++ b/lib/dns/rdata/generic/lp_107.h @@ -0,0 +1,28 @@ +/* + * 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/lib/dns/rdata/generic/mx_15.c b/lib/dns/rdata/generic/mx_15.c index fd09e92..77eee15 100644 --- a/lib/dns/rdata/generic/mx_15.c +++ b/lib/dns/rdata/generic/mx_15.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -57,7 +57,6 @@ fromtext_mx(ARGS_FROMTEXT) { UNUSED(type); UNUSED(rdclass); - UNUSED(callbacks); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); diff --git a/lib/dns/rdata/generic/nid_104.c b/lib/dns/rdata/generic/nid_104.c new file mode 100644 index 0000000..c96b0bf --- /dev/null +++ b/lib/dns/rdata/generic/nid_104.c @@ -0,0 +1,228 @@ +/* + * 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, ®ion); + num = uint16_fromregion(®ion); + isc_region_consume(®ion, 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, ®ion1); + dns_rdata_toregion(rdata2, ®ion2); + return (isc_region_compare(®ion1, ®ion2)); +} + +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, ®ion); + nid->pref = uint16_fromregion(®ion); + 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/lib/dns/rdata/generic/nid_104.h b/lib/dns/rdata/generic/nid_104.h new file mode 100644 index 0000000..64a3ba4 --- /dev/null +++ b/lib/dns/rdata/generic/nid_104.h @@ -0,0 +1,27 @@ +/* + * 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/lib/dns/rdata/generic/sshfp_44.c b/lib/dns/rdata/generic/sshfp_44.c index c94c75c..03d5127 100644 --- a/lib/dns/rdata/generic/sshfp_44.c +++ b/lib/dns/rdata/generic/sshfp_44.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2006, 2007, 2009, 2012, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -53,7 +53,6 @@ fromtext_sshfp(ARGS_FROMTEXT) { if (token.value.as_ulong > 0xffU) RETTOK(ISC_R_RANGE); RETERR(uint8_tobuffer(token.value.as_ulong, target)); - type = (isc_uint16_t) token.value.as_ulong; /* * Digest. diff --git a/lib/dns/rdata/generic/txt_16.c b/lib/dns/rdata/generic/txt_16.c index c49864e..e1bce6a 100644 --- a/lib/dns/rdata/generic/txt_16.c +++ b/lib/dns/rdata/generic/txt_16.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2007-2009 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -38,6 +38,13 @@ fromtext_txt(ARGS_FROMTEXT) { 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, diff --git a/lib/dns/rdata/generic/uri_256.c b/lib/dns/rdata/generic/uri_256.c new file mode 100644 index 0000000..aa5b194 --- /dev/null +++ b/lib/dns/rdata/generic/uri_256.c @@ -0,0 +1,331 @@ +/* + * 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: uri_256.c,v 1.2 2011/03/03 14:10:27 fdupont Exp $ */ + +#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, ®ion); + + /* + * Priority + */ + priority = uint16_fromregion(®ion); + isc_region_consume(®ion, 2); + sprintf(buf, "%u ", priority); + RETERR(str_totext(buf, target)); + + /* + * Weight + */ + weight = uint16_fromregion(®ion); + isc_region_consume(®ion, 2); + sprintf(buf, "%u ", weight); + RETERR(str_totext(buf, target)); + + /* + * Target URI + */ + RETERR(multitxt_totext(®ion, 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, ®ion); + 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, ®ion); + 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(®ion); + isc_region_consume(®ion, 1); + if (region.length < len) + return (ISC_R_UNEXPECTEDEND); + isc_region_consume(®ion, 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/lib/dns/rdata/generic/uri_256.h b/lib/dns/rdata/generic/uri_256.h new file mode 100644 index 0000000..5061c03 --- /dev/null +++ b/lib/dns/rdata/generic/uri_256.h @@ -0,0 +1,31 @@ +/* + * 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. + */ + +#ifndef GENERIC_URI_256_H +#define GENERIC_URI_256_H 1 + +/* $Id: uri_256.h,v 1.2 2011/03/03 14:10:27 fdupont Exp $ */ + +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/lib/dns/rdata/in_1/naptr_35.c b/lib/dns/rdata/in_1/naptr_35.c index 71ba31e..e5df80b 100644 --- a/lib/dns/rdata/in_1/naptr_35.c +++ b/lib/dns/rdata/in_1/naptr_35.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007-2009, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007-2009, 2012, 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 @@ -25,9 +25,8 @@ #define RDATA_IN_1_NAPTR_35_C #define RRTYPE_NAPTR_ATTRIBUTES (0) -#ifdef HAVE_REGEX_H -#include <regex.h> -#endif + +#include <isc/regex.h> /* * Check the wire format of the Regexp field. @@ -35,18 +34,15 @@ */ static inline isc_result_t txt_valid_regex(const unsigned char *txt) { -#ifdef HAVE_REGEX_H - regex_t preg; - unsigned int regflags = REG_EXTENDED; unsigned int nsub = 0; char regex[256]; char *cp; -#endif isc_boolean_t flags = ISC_FALSE; isc_boolean_t replace = ISC_FALSE; unsigned char c; unsigned char delim; unsigned int len; + int n; len = *txt++; if (len == 0U) @@ -65,11 +61,7 @@ txt_valid_regex(const unsigned char *txt) { return (DNS_R_SYNTAX); } -#ifdef HAVE_REGEX_H - memset(&preg, 0, sizeof(preg)); cp = regex; -#endif - while (len-- > 0) { c = *txt++; if (c == 0) @@ -88,18 +80,13 @@ txt_valid_regex(const unsigned char *txt) { if (flags) { switch (c) { case 'i': -#ifdef HAVE_REGEX_H - regflags |= REG_ICASE; -#endif continue; default: return (DNS_R_SYNTAX); } } -#ifdef HAVE_REGEX_H if (!replace) *cp++ = c; -#endif if (c == '\\') { if (len == 0) return (DNS_R_SYNTAX); @@ -110,7 +97,6 @@ txt_valid_regex(const unsigned char *txt) { if (replace) switch (c) { case '0': return (DNS_R_SYNTAX); -#ifdef HAVE_REGEX_H case '1': if (nsub < 1) nsub = 1; break; case '2': if (nsub < 2) nsub = 2; break; case '3': if (nsub < 3) nsub = 3; break; @@ -120,30 +106,17 @@ txt_valid_regex(const unsigned char *txt) { case '7': if (nsub < 7) nsub = 7; break; case '8': if (nsub < 8) nsub = 8; break; case '9': if (nsub < 9) nsub = 9; break; -#endif } -#ifdef HAVE_REGEX_H if (!replace) *cp++ = c; -#endif } } if (!flags) return (DNS_R_SYNTAX); -#ifdef HAVE_REGEX_H *cp = '\0'; - if (regcomp(&preg, regex, regflags)) - return (DNS_R_SYNTAX); - /* - * Check that substitutions in the replacement string are consistant - * with the regular expression. - */ - if (preg.re_nsub < nsub) { - regfree(&preg); + n = isc_regex_validate(regex); + if (n < 0 || nsub > (unsigned int)n) return (DNS_R_SYNTAX); - } - regfree(&preg); -#endif return (ISC_R_SUCCESS); } diff --git a/lib/dns/rdata/in_1/nsap_22.c b/lib/dns/rdata/in_1/nsap_22.c index d762fe1..66129fe 100644 --- a/lib/dns/rdata/in_1/nsap_22.c +++ b/lib/dns/rdata/in_1/nsap_22.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -53,7 +53,6 @@ fromtext_in_nsap(ARGS_FROMTEXT) { RETTOK(DNS_R_SYNTAX); isc_textregion_consume(sr, 2); digits = 0; - n = 0; while (sr->length > 0) { if (sr->base[0] == '.') { isc_textregion_consume(sr, 1); diff --git a/lib/dns/request.c b/lib/dns/request.c index 58c0103..1316e69 100644 --- a/lib/dns/request.c +++ b/lib/dns/request.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -894,13 +894,15 @@ dns_request_createvia3(dns_requestmgr_t *requestmgr, dns_message_t *message, 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_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); diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 503f1d2..e21d97e 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -21,6 +21,7 @@ #include <config.h> +#include <isc/log.h> #include <isc/platform.h> #include <isc/print.h> #include <isc/string.h> @@ -42,6 +43,8 @@ #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> @@ -75,7 +78,7 @@ DNS_LOGCATEGORY_RESOLVER, \ DNS_LOGMODULE_RESOLVER, \ ISC_LOG_DEBUG(3), \ - "fctx %p(%s'): %s", fctx, fctx->info, (m)) + "fctx %p(%s): %s", fctx, fctx->info, (m)) #define FCTXTRACE2(m1, m2) \ isc_log_write(dns_lctx, \ DNS_LOGCATEGORY_RESOLVER, \ @@ -130,6 +133,7 @@ * 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 @@ -468,12 +472,16 @@ static isc_result_t ncache_adderesult(dns_message_t *message, 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. @@ -1270,67 +1278,15 @@ resquery_senddone(isc_task_t *task, isc_event_t *event) { static inline isc_result_t fctx_addopt(dns_message_t *message, unsigned int version, - isc_uint16_t udpsize, isc_boolean_t request_nsid) + isc_uint16_t udpsize, dns_ednsopt_t *ednsopts, size_t count) { - dns_rdataset_t *rdataset; - dns_rdatalist_t *rdatalist; - dns_rdata_t *rdata; + dns_rdataset_t *rdataset = NULL; isc_result_t result; - rdatalist = NULL; - result = dns_message_gettemprdatalist(message, &rdatalist); - if (result != ISC_R_SUCCESS) - return (result); - rdata = NULL; - result = dns_message_gettemprdata(message, &rdata); - if (result != ISC_R_SUCCESS) - return (result); - rdataset = NULL; - result = dns_message_gettemprdataset(message, &rdataset); + result = dns_message_buildopt(message, &rdataset, version, udpsize, + DNS_MESSAGEEXTFLAG_DO, ednsopts, count); if (result != ISC_R_SUCCESS) return (result); - 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, DO to 1. - */ - rdatalist->ttl = (version << 16); - rdatalist->ttl |= DNS_MESSAGEEXTFLAG_DO; - - /* - * Set EDNS options if applicable - */ - if (request_nsid) { - /* Send empty NSID option (RFC5001) */ - 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)); } @@ -1710,6 +1666,8 @@ resquery_send(resquery_t *query) { 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"); @@ -1892,8 +1850,15 @@ resquery_send(resquery_t *query) { /* 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, reqnsid); + udpsize, ednsopts, ednsopt); if (reqnsid && result == ISC_R_SUCCESS) { query->options |= DNS_FETCHOPT_WANTNSID; } else if (result != ISC_R_SUCCESS) { @@ -2478,7 +2443,7 @@ findname(fetchctx_t *fctx, dns_name_t *name, in_port_t port, isc_result_t result; res = fctx->res; - unshared = ISC_TF((fctx->options | DNS_FETCHOPT_UNSHARED) != 0); + 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 @@ -4227,7 +4192,7 @@ validated(isc_task_t *task, isc_event_t *event) { result = ncache_adderesult(fctx->rmessage, fctx->cache, node, covers, now, ttl, vevent->optout, - ardataset, &eresult); + vevent->secure, ardataset, &eresult); if (result != ISC_R_SUCCESS) goto noanswer_response; goto answer_response; @@ -4237,7 +4202,6 @@ validated(isc_task_t *task, isc_event_t *event) { 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); @@ -4248,6 +4212,18 @@ validated(isc_task_t *task, isc_event_t *event) { 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); + } } /* @@ -4367,6 +4343,14 @@ validated(isc_task_t *task, isc_event_t *event) { 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) @@ -4388,6 +4372,149 @@ validated(isc_task_t *task, isc_event_t *event) { 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) @@ -4521,6 +4648,17 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo, 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 @@ -4540,16 +4678,7 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo, */ if (rdataset->type == dns_rdatatype_rrsig) continue; - /* - * 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 (sigrdataset == NULL) { if (!ANSWER(rdataset) && need_validation) { /* @@ -4583,6 +4712,22 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo, 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, @@ -4710,6 +4855,21 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo, 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. */ @@ -4718,6 +4878,7 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo, rdataset, options, addedrdataset); + if (result == DNS_R_UNCHANGED) { if (ANSWER(rdataset) && ardataset != NULL && @@ -4813,8 +4974,8 @@ cache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, isc_stdtime_t now) 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, dns_rdataset_t *ardataset, - isc_result_t *eresultp) + isc_boolean_t optout, isc_boolean_t secure, + dns_rdataset_t *ardataset, isc_result_t *eresultp) { isc_result_t result; dns_rdataset_t rdataset; @@ -4823,8 +4984,12 @@ ncache_adderesult(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, dns_rdataset_init(&rdataset); ardataset = &rdataset; } - result = dns_ncache_addoptout(message, cache, node, covers, now, - maxttl, optout, ardataset); + 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 @@ -4991,7 +5156,7 @@ ncache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, result = ncache_adderesult(fctx->rmessage, fctx->cache, node, covers, now, ttl, ISC_FALSE, - ardataset, &eresult); + ISC_FALSE, ardataset, &eresult); if (result != ISC_R_SUCCESS) goto unlock; @@ -5387,10 +5552,10 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname, { isc_result_t result; dns_message_t *message; - dns_name_t *name, *qname, *ns_name, *soa_name, *ds_name; + 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; + dns_rdatatype_t type, save_type; dns_section_t section; FCTXTRACE("noanswer_response"); @@ -5457,6 +5622,8 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname, 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; @@ -5655,6 +5822,9 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname, 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) @@ -5690,7 +5860,27 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname, /* * The responder is insane. */ - log_formerr(fctx, "invalid response"); + 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); } } @@ -5899,12 +6089,12 @@ answer_response(fetchctx_t *fctx) { * but we found a CNAME. * * Getting a CNAME response for some - * query types is an error. + * query types is an error, see + * RFC 4035, Section 2.5. */ if (type == dns_rdatatype_rrsig || - type == dns_rdatatype_dnskey || - type == dns_rdatatype_nsec || - type == dns_rdatatype_nsec3) { + type == dns_rdatatype_key || + type == dns_rdatatype_nsec) { char buf[DNS_RDATATYPE_FORMATSIZE]; dns_rdatatype_format(fctx->type, buf, sizeof(buf)); @@ -6449,44 +6639,24 @@ checknames(dns_message_t *message) { /* * Log server NSID at log level 'level' */ -static isc_result_t -log_nsid(dns_rdataset_t *opt, resquery_t *query, int level, isc_mem_t *mctx) +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 optcode, nsid_len, buflen, i; - isc_result_t result; - isc_buffer_t nsidbuf; - dns_rdata_t rdata; + isc_uint16_t buflen, i; unsigned char *p, *buf, *nsid; - /* Extract rdata from OPT rdataset */ - result = dns_rdataset_first(opt); - if (result != ISC_R_SUCCESS) - return (ISC_R_FAILURE); - - dns_rdata_init(&rdata); - dns_rdataset_current(opt, &rdata); - if (rdata.length < 4) - return (ISC_R_FAILURE); - - /* Check for NSID */ - isc_buffer_init(&nsidbuf, rdata.data, rdata.length); - isc_buffer_add(&nsidbuf, rdata.length); - optcode = isc_buffer_getuint16(&nsidbuf); - nsid_len = isc_buffer_getuint16(&nsidbuf); - if (optcode != DNS_OPT_NSID || nsid_len == 0) - return (ISC_R_FAILURE); - /* Allocate buffer for storing hex version of the NSID */ buflen = nsid_len * 2 + 1; buf = isc_mem_get(mctx, buflen); if (buf == NULL) - return (ISC_R_NOSPACE); + return; /* Convert to hex */ p = buf; - nsid = rdata.data + 4; + nsid = isc_buffer_current(opt); for (i = 0; i < nsid_len; i++) { *p++ = hex[(nsid[0] >> 4) & 0xf]; *p++ = hex[nsid[0] & 0xf]; @@ -6502,7 +6672,7 @@ log_nsid(dns_rdataset_t *opt, resquery_t *query, int level, isc_mem_t *mctx) /* Clean up */ isc_mem_put(mctx, buf, buflen); - return (ISC_R_SUCCESS); + return; } static void @@ -6576,6 +6746,41 @@ betterreferral(fetchctx_t *fctx) { } 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; @@ -6650,13 +6855,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) { */ options |= DNS_FETCHOPT_NOEDNS0; resend = ISC_TRUE; - /* - * Remember that they don't like EDNS0. - */ - dns_adb_changeflags(fctx->adb, - query->addrinfo, - DNS_FETCHOPT_NOEDNS0, - DNS_FETCHOPT_NOEDNS0); + add_bad_edns(fctx, &query->addrinfo->sockaddr); } else { /* * There's no hope for this query. @@ -6723,14 +6922,8 @@ resquery_response(isc_task_t *task, isc_event_t *event) { */ options |= DNS_FETCHOPT_NOEDNS0; resend = ISC_TRUE; - /* - * Remember that they don't like EDNS0. - */ - dns_adb_changeflags( - fctx->adb, - query->addrinfo, - DNS_FETCHOPT_NOEDNS0, - DNS_FETCHOPT_NOEDNS0); + add_bad_edns(fctx, + &query->addrinfo->sockaddr); inc_stats(fctx->res, dns_resstatscounter_edns0fail); } else { @@ -6754,13 +6947,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) { */ options |= DNS_FETCHOPT_NOEDNS0; resend = ISC_TRUE; - /* - * Remember that they don't like EDNS0. - */ - dns_adb_changeflags(fctx->adb, - query->addrinfo, - DNS_FETCHOPT_NOEDNS0, - DNS_FETCHOPT_NOEDNS0); + add_bad_edns(fctx, &query->addrinfo->sockaddr); inc_stats(fctx->res, dns_resstatscounter_edns0fail); } else { @@ -6783,12 +6970,11 @@ resquery_response(isc_task_t *task, isc_event_t *event) { log_packet(message, ISC_LOG_DEBUG(10), fctx->res->mctx); /* - * Did we request NSID? If so, and if the response contains - * NSID data, log it at INFO level. + * Process receive opt record. */ opt = dns_message_getopt(message); - if (opt != NULL && (query->options & DNS_FETCHOPT_WANTNSID) != 0) - log_nsid(opt, query, ISC_LOG_INFO, fctx->res->mctx); + if (opt != NULL) + process_opt(query, opt); /* * If the message is signed, check the signature. If not, this diff --git a/lib/dns/result.c b/lib/dns/result.c index 0546d0f..3987953 100644 --- a/lib/dns/result.c +++ b/lib/dns/result.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007-2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -160,7 +160,9 @@ static const char *text[DNS_R_NRESULTS] = { "not master", /*%< 105 DNS_R_NOTMASTER */ "broken trust chain", /*%< 106 DNS_R_BROKENCHAIN */ - "expired", /*%< 106 DNS_R_EXPIRED */ + "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] = { @@ -264,6 +266,7 @@ dns_result_torcode(isc_result_t result) { 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: diff --git a/lib/dns/rootns.c b/lib/dns/rootns.c index 9b25369..3502022 100644 --- a/lib/dns/rootns.c +++ b/lib/dns/rootns.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2008, 2010 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -63,7 +63,8 @@ static char root_ns[] = "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 128.8.10.90\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" diff --git a/lib/dns/rpz.c b/lib/dns/rpz.c index 7865859..2d689e7 100644 --- a/lib/dns/rpz.c +++ b/lib/dns/rpz.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -16,6 +16,7 @@ /* $Id$ */ + /*! \file */ #include <config.h> @@ -123,8 +124,6 @@ struct dns_rpz_cidr { dns_name_t nsdname_name; /* RPZ_NSDNAME_ZONE.origin */ }; -static isc_boolean_t have_rpz_zones = ISC_FALSE; - const char * dns_rpz_type2str(dns_rpz_type_t type) { switch (type) { @@ -191,6 +190,7 @@ dns_rpz_policy2str(dns_rpz_policy_t policy) { break; default: str = ""; + POST(str); INSIST(0); } return (str); @@ -266,21 +266,6 @@ dns_rpz_view_destroy(dns_view_t *view) { } /* - * Note that we have at least one response policy zone. - * It would be better for something to tell the rbtdb code that the - * zone is in at least one view's list of policy zones. - */ -void -dns_rpz_set_need(isc_boolean_t need) { - have_rpz_zones = need; -} - -isc_boolean_t -dns_rpz_needed(void) { - return (have_rpz_zones); -} - -/* * Start a new radix tree for a response policy zone. */ isc_result_t @@ -292,12 +277,6 @@ dns_rpz_new_cidr(isc_mem_t *mctx, dns_name_t *origin, REQUIRE(rbtdb_cidr != NULL && *rbtdb_cidr == NULL); - /* - * Only if there is at least one response policy zone. - */ - if (!have_rpz_zones) - return (ISC_R_SUCCESS); - cidr = isc_mem_get(mctx, sizeof(*cidr)); if (cidr == NULL) return (ISC_R_NOMEMORY); @@ -339,7 +318,7 @@ dns_rpz_new_cidr(isc_mem_t *mctx, dns_name_t *origin, * See if a policy zone has IP, NSIP, or NSDNAME rules or records. */ void -dns_rpz_enabled(dns_rpz_cidr_t *cidr, dns_rpz_st_t *st) { +dns_rpz_enabled_get(dns_rpz_cidr_t *cidr, dns_rpz_st_t *st) { if (cidr == NULL) return; if (cidr->root != NULL && @@ -432,6 +411,9 @@ 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)); @@ -508,7 +490,7 @@ ip2name(dns_rpz_cidr_t *cidr, const dns_rpz_cidr_key_t *tgt_ip, while (i < DNS_RPZ_CIDR_WORDS * 2 && w[i] == 0) ++i; } - if (len > (int)sizeof(str)) + if (len >= (int)sizeof(str)) return (ISC_R_FAILURE); } } @@ -956,8 +938,7 @@ dns_rpz_cidr_addip(dns_rpz_cidr_t *cidr, dns_name_t *name) { dns_rpz_cidr_bits_t tgt_prefix; dns_rpz_type_t type; - if (cidr == NULL) - return; + REQUIRE(cidr != NULL); /* * No worries if the new name is not an IP address. @@ -985,6 +966,9 @@ dns_rpz_cidr_addip(dns_rpz_cidr_t *cidr, dns_name_t *name) { { 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, diff --git a/lib/dns/sdb.c b/lib/dns/sdb.c index 8092c5a..526ce87 100644 --- a/lib/dns/sdb.c +++ b/lib/dns/sdb.c @@ -382,7 +382,7 @@ dns_sdb_putrr(dns_sdblookup_t *lookup, const char *type, dns_ttl_t ttl, datalen = strlen(data); size = initial_size(datalen); do { - isc_buffer_init(&b, data, datalen); + isc_buffer_constinit(&b, data, datalen); isc_buffer_add(&b, datalen); result = isc_lex_openbuffer(lex, &b); if (result != ISC_R_SUCCESS) @@ -448,7 +448,7 @@ getnode(dns_sdballnodes_t *allnodes, const char *name, dns_sdbnode_t **nodep) { origin = &sdb->common.origin; else origin = dns_rootname; - isc_buffer_init(&b, name, strlen(name)); + isc_buffer_constinit(&b, name, strlen(name)); isc_buffer_add(&b, strlen(name)); result = dns_name_fromtext(newname, &b, origin, 0, NULL); diff --git a/lib/dns/sdlz.c b/lib/dns/sdlz.c index 870e981..6e518d1 100644 --- a/lib/dns/sdlz.c +++ b/lib/dns/sdlz.c @@ -1817,7 +1817,7 @@ dns_sdlz_putrr(dns_sdlzlookup_t *lookup, const char *type, dns_ttl_t ttl, size = initial_size(data); do { - isc_buffer_init(&b, data, strlen(data)); + isc_buffer_constinit(&b, data, strlen(data)); isc_buffer_add(&b, strlen(data)); result = isc_lex_openbuffer(lex, &b); @@ -1883,7 +1883,7 @@ dns_sdlz_putnamedrr(dns_sdlzallnodes_t *allnodes, const char *name, origin = &sdlz->common.origin; else origin = dns_rootname; - isc_buffer_init(&b, name, strlen(name)); + isc_buffer_constinit(&b, name, strlen(name)); isc_buffer_add(&b, strlen(name)); result = dns_name_fromtext(newname, &b, origin, 0, NULL); diff --git a/lib/dns/spnego.c b/lib/dns/spnego.c index 0486a72..0c1c858 100644 --- a/lib/dns/spnego.c +++ b/lib/dns/spnego.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -630,8 +630,10 @@ gss_accept_sec_context_spnego(OM_uint32 *minor_status, sizeof(mechbuf), &init_token.mechTypes.val[i], &mech_len); - if (ret) + 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, @@ -650,8 +652,10 @@ gss_accept_sec_context_spnego(OM_uint32 *minor_status, } } - if (!found) + 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; @@ -669,12 +673,14 @@ gss_accept_sec_context_spnego(OM_uint32 *minor_status, 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); @@ -846,10 +852,13 @@ der_get_octet_string(const unsigned char *p, size_t len, octet_string *data, size_t *size) { data->length = len; - data->data = malloc(len); - if (data->data == NULL && data->length != 0U) - return (ENOMEM); - memcpy(data->data, p, 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); @@ -862,6 +871,8 @@ der_get_oid(const unsigned char *p, size_t len, int n; size_t oldlen = len; + data->components = NULL; + data->length = 0; if (len < 1U) return (ASN1_OVERRUN); @@ -997,6 +1008,9 @@ decode_octet_string(const unsigned char *p, size_t len, 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); @@ -1547,6 +1561,11 @@ spnego_initial(OM_uint32 *minor_status, 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, @@ -1685,6 +1704,7 @@ spnego_reply(OM_uint32 *minor_status, ret = decode_NegTokenResp(buf + taglen, len, &resp, NULL); if (ret) { + free_NegTokenResp(&resp); *minor_status = ENOMEM; return (GSS_S_FAILURE); } diff --git a/lib/dns/spnego_asn1.c b/lib/dns/spnego_asn1.c index 75c2304..b506054 100644 --- a/lib/dns/spnego_asn1.c +++ b/lib/dns/spnego_asn1.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2007 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -53,10 +53,10 @@ typedef struct oid { (R) = ENOMEM; \ } else { \ (R) = encode_##T(((unsigned char*)(B)) + (BL) - 1, (BL), \ - (S), (L)); \ + (S), (L)); \ if((R) != 0) { \ - free((B)); \ - (B) = NULL; \ + free((B)); \ + (B) = NULL; \ } \ } \ } while (0) @@ -171,33 +171,31 @@ static void free_NegTokenResp(NegTokenResp *); /* Do not edit */ -#define BACK if (e) return e; p -= l; len -= l; ret += l +#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 i, e; + int e; - i = 0; e = encode_oid(p, len, data, &l); BACK; *size = ret; return 0; } -#define FORW if(e) goto fail; p += l; len -= l; ret += l +#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, reallen; + size_t ret = 0; size_t l; int e; memset(data, 0, sizeof(*data)); - reallen = 0; e = decode_oid(p, len, data, &l); FORW; if (size) @@ -223,8 +221,6 @@ free_MechType(MechType * data) /* Do not edit */ -#define BACK if (e) return e; p -= l; len -= l; ret += l - static int encode_MechTypeList(unsigned char *p, size_t len, const MechTypeList * data, size_t * size) { @@ -232,7 +228,6 @@ encode_MechTypeList(unsigned char *p, size_t len, const MechTypeList * data, siz size_t l; int i, e; - i = 0; for (i = (data)->len - 1; i >= 0; --i) { int oldret = ret; ret = 0; @@ -246,8 +241,6 @@ encode_MechTypeList(unsigned char *p, size_t len, const MechTypeList * data, siz return 0; } -#define FORW if(e) goto fail; p += l; len -= l; ret += l - static int decode_MechTypeList(const unsigned char *p, size_t len, MechTypeList * data, size_t * size) { @@ -269,8 +262,14 @@ decode_MechTypeList(const unsigned char *p, size_t len, MechTypeList * data, siz (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; @@ -305,16 +304,13 @@ free_MechTypeList(MechTypeList * data) /* Do not edit */ -#define BACK if (e) return e; p -= l; len -= l; ret += l - static int encode_ContextFlags(unsigned char *p, size_t len, const ContextFlags * data, size_t * size) { size_t ret = 0; size_t l; - int i, e; + int e; - i = 0; { unsigned char c = 0; *p-- = c; @@ -355,8 +351,6 @@ encode_ContextFlags(unsigned char *p, size_t len, const ContextFlags * data, siz return 0; } -#define FORW if(e) goto fail; p += l; len -= l; ret += l - static int decode_ContextFlags(const unsigned char *p, size_t len, ContextFlags * data, size_t * size) { @@ -381,8 +375,6 @@ decode_ContextFlags(const unsigned char *p, size_t len, ContextFlags * data, siz data->anonFlag = (*p >> 3) & 1; data->confFlag = (*p >> 2) & 1; data->integFlag = (*p >> 1) & 1; - p += reallen; - len -= reallen; ret += reallen; if (size) *size = ret; @@ -418,16 +410,13 @@ free_ContextFlags(ContextFlags * data) /* Do not edit */ -#define BACK if (e) return e; p -= l; len -= l; ret += l - static int encode_NegTokenInit(unsigned char *p, size_t len, const NegTokenInit * data, size_t * size) { size_t ret = 0; size_t l; - int i, e; + int e; - i = 0; if ((data)->mechListMIC) { int oldret = ret; ret = 0; @@ -469,8 +458,6 @@ encode_NegTokenInit(unsigned char *p, size_t len, const NegTokenInit * data, siz return 0; } -#define FORW if(e) goto fail; p += l; len -= l; ret += l - static int decode_NegTokenInit(const unsigned char *p, size_t len, NegTokenInit * data, size_t * size) { @@ -646,16 +633,13 @@ free_NegTokenInit(NegTokenInit * data) /* Do not edit */ -#define BACK if (e) return e; p -= l; len -= l; ret += l - static int encode_NegTokenResp(unsigned char *p, size_t len, const NegTokenResp * data, size_t * size) { size_t ret = 0; size_t l; - int i, e; + int e; - i = 0; if ((data)->mechListMIC) { int oldret = ret; ret = 0; @@ -698,8 +682,6 @@ encode_NegTokenResp(unsigned char *p, size_t len, const NegTokenResp * data, siz return 0; } -#define FORW if(e) goto fail; p += l; len -= l; ret += l - static int decode_NegTokenResp(const unsigned char *p, size_t len, NegTokenResp * data, size_t * size) { diff --git a/lib/dns/ssu.c b/lib/dns/ssu.c index 83aa679..49a777a 100644 --- a/lib/dns/ssu.c +++ b/lib/dns/ssu.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2008, 2010, 2011 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -82,7 +82,8 @@ dns_ssutable_create(isc_mem_t *mctx, dns_ssutable_t **tablep) { return (result); } table->references = 1; - table->mctx = mctx; + table->mctx = NULL; + isc_mem_attach(mctx, &table->mctx); ISC_LIST_INIT(table->rules); table->magic = SSUTABLEMAGIC; *tablep = table; @@ -115,7 +116,7 @@ destroy(dns_ssutable_t *table) { } DESTROYLOCK(&table->lock); table->magic = 0; - isc_mem_put(mctx, table, sizeof(dns_ssutable_t)); + isc_mem_putanddetach(&table->mctx, table, sizeof(dns_ssutable_t)); } void diff --git a/lib/dns/ssu_external.c b/lib/dns/ssu_external.c index 65ba1b5..43d231d 100644 --- a/lib/dns/ssu_external.c +++ b/lib/dns/ssu_external.c @@ -79,7 +79,7 @@ ux_socket_connect(const char *path) { memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; - strncpy(addr.sun_path, path, sizeof(addr.sun_path)); + strlcpy(addr.sun_path, path, sizeof(addr.sun_path)); fd = socket(AF_UNIX, SOCK_STREAM, 0); if (fd == -1) { diff --git a/lib/dns/tkey.c b/lib/dns/tkey.c index 0112f7e..161c188 100644 --- a/lib/dns/tkey.c +++ b/lib/dns/tkey.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -991,8 +991,13 @@ dns_tkey_builddhquery(dns_message_t *msg, dst_key_t *key, dns_name_t *name, ISC_LIST_INIT(namelist); RETERR(add_rdata_to_list(msg, &keyname, rdata, 0, &namelist)); - dns_message_addname(msg, ISC_LIST_HEAD(namelist), - DNS_SECTION_ADDITIONAL); + 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); diff --git a/lib/dns/tsig.c b/lib/dns/tsig.c index 76c239b..c7768f4 100644 --- a/lib/dns/tsig.c +++ b/lib/dns/tsig.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -239,7 +239,9 @@ adjust_lru(dns_tsigkey_t *tkey) { * 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)) { + 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); } @@ -625,8 +627,7 @@ restore_key(dns_tsig_keyring_t *ring, isc_stdtime_t now, FILE *fp) { } static void -dump_key(dns_tsigkey_t *tkey, FILE *fp) -{ +dump_key(dns_tsigkey_t *tkey, FILE *fp) { char *buffer = NULL; int length = 0; char namestr[DNS_NAME_FORMATSIZE]; @@ -634,6 +635,9 @@ dump_key(dns_tsigkey_t *tkey, FILE *fp) 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)); @@ -942,7 +946,8 @@ dns_tsig_sign(dns_message_t *msg) { isc_buffer_t headerbuf; isc_uint16_t digestbits; - ret = dst_context_create(key->key, mctx, &ctx); + ret = dst_context_create2(key->key, mctx, + DNS_LOGCATEGORY_DNSSEC, &ctx); if (ret != ISC_R_SUCCESS) return (ret); @@ -973,6 +978,13 @@ dns_tsig_sign(dns_message_t *msg) { 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. @@ -1228,6 +1240,13 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg, 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? @@ -1326,7 +1345,8 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg, sig_r.base = tsig.signature; sig_r.length = tsig.siglen; - ret = dst_context_create(key, mctx, &ctx); + ret = dst_context_create2(key, mctx, + DNS_LOGCATEGORY_DNSSEC, &ctx); if (ret != ISC_R_SUCCESS) return (ret); @@ -1557,7 +1577,9 @@ tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg) { key = tsigkey->key; if (msg->tsigctx == NULL) { - ret = dst_context_create(key, mctx, &msg->tsigctx); + ret = dst_context_create2(key, mctx, + DNS_LOGCATEGORY_DNSSEC, + &msg->tsigctx); if (ret != ISC_R_SUCCESS) goto cleanup_querystruct; @@ -1746,11 +1768,15 @@ static void free_tsignode(void *node, void *_unused) { dns_tsigkey_t *key; - UNUSED(_unused); - 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); } diff --git a/lib/dns/validator.c b/lib/dns/validator.c index 674675f..3d7518a 100644 --- a/lib/dns/validator.c +++ b/lib/dns/validator.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -157,7 +157,7 @@ validator_logv(dns_validator_t *val, isc_logcategory_t *category, ISC_FORMAT_PRINTF(5, 0); static void -validator_log(dns_validator_t *val, int level, const char *fmt, ...) +validator_log(void *val, int level, const char *fmt, ...) ISC_FORMAT_PRINTF(3, 4); static void @@ -195,6 +195,7 @@ 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 @@ -403,6 +404,7 @@ fetch_callback_validator(isc_task_t *task, isc_event_t *event) { 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); @@ -419,12 +421,13 @@ fetch_callback_validator(isc_task_t *task, isc_event_t *event) { if (dns_rdataset_isassociated(&val->fsigrdataset)) dns_rdataset_disassociate(&val->fsigrdataset); isc_event_free(&event); - dns_resolver_destroyfetch(&val->fetch); 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) { @@ -464,6 +467,8 @@ fetch_callback_validator(isc_task_t *task, isc_event_t *event) { } want_destroy = exit_check(val); UNLOCK(&val->lock); + if (fetch != NULL) + dns_resolver_destroyfetch(&fetch); if (want_destroy) destroy(val); } @@ -481,6 +486,7 @@ dsfetched(isc_task_t *task, isc_event_t *event) { 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); @@ -497,12 +503,13 @@ dsfetched(isc_task_t *task, isc_event_t *event) { if (dns_rdataset_isassociated(&val->fsigrdataset)) dns_rdataset_disassociate(&val->fsigrdataset); isc_event_free(&event); - dns_resolver_destroyfetch(&val->fetch); 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) { @@ -536,6 +543,8 @@ dsfetched(isc_task_t *task, isc_event_t *event) { } want_destroy = exit_check(val); UNLOCK(&val->lock); + if (fetch != NULL) + dns_resolver_destroyfetch(&fetch); if (want_destroy) destroy(val); } @@ -559,6 +568,7 @@ dsfetched2(isc_task_t *task, isc_event_t *event) { 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); @@ -573,13 +583,14 @@ dsfetched2(isc_task_t *task, isc_event_t *event) { dns_db_detach(&devent->db); if (dns_rdataset_isassociated(&val->fsigrdataset)) dns_rdataset_disassociate(&val->fsigrdataset); - dns_resolver_destroyfetch(&val->fetch); 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 || @@ -632,6 +643,8 @@ dsfetched2(isc_task_t *task, isc_event_t *event) { isc_event_free(&event); want_destroy = exit_check(val); UNLOCK(&val->lock); + if (fetch != NULL) + dns_resolver_destroyfetch(&fetch); if (want_destroy) destroy(val); } @@ -839,452 +852,6 @@ cnamevalidated(isc_task_t *task, isc_event_t *event) { } /*% - * 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. - */ -static isc_result_t -nsecnoexistnodata(dns_validator_t *val, dns_name_t *name, dns_name_t *nsecname, - dns_rdataset_t *nsecset, isc_boolean_t *exists, - isc_boolean_t *data, dns_name_t *wild) -{ - 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) { - validator_log(val, ISC_LOG_DEBUG(3), - "failure processing NSEC set"); - return (result); - } - dns_rdataset_current(nsecset, &rdata); - - validator_log(val, 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. - */ - validator_log(val, 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(val->event->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. - */ - validator_log(val, 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. - */ - validator_log(val, ISC_LOG_DEBUG(3), - "ignoring child nsec"); - return (ISC_R_IGNORE); - } - if (val->event->type == dns_rdatatype_cname || - val->event->type == dns_rdatatype_nxt || - val->event->type == dns_rdatatype_nsec || - val->event->type == dns_rdatatype_key || - !dns_nsec_typepresent(&rdata, dns_rdatatype_cname)) { - *exists = ISC_TRUE; - *data = dns_nsec_typepresent(&rdata, val->event->type); - validator_log(val, ISC_LOG_DEBUG(3), - "nsec proves name exists (owner) data=%d", - *data); - return (ISC_R_SUCCESS); - } - validator_log(val, 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. - */ - validator_log(val, 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); - validator_log(val, 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); - validator_log(val, ISC_LOG_DEBUG(3), - "ignoring nsec because name is past end of range"); - return (ISC_R_IGNORE); - } - - if (order > 0 && relation == dns_namereln_subdomain) { - validator_log(val, 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); - validator_log(val, ISC_LOG_DEBUG(3), - "failure generating wildcard name"); - return (result); - } - } - dns_rdata_freestruct(&nsec); - validator_log(val, ISC_LOG_DEBUG(3), "nsec range ok"); - *exists = ISC_FALSE; - return (ISC_R_SUCCESS); -} - -static isc_result_t -nsec3noexistnodata(dns_validator_t *val, 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) -{ - 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) { - validator_log(val, 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); - - validator_log(val, 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) { - validator_log(val, 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(val->event->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. - */ - validator_log(val, 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. - */ - validator_log(val, ISC_LOG_DEBUG(3), - "ignoring child NSEC3"); - return (ISC_R_IGNORE); - } - if (val->event->type == dns_rdatatype_cname || - val->event->type == dns_rdatatype_nxt || - val->event->type == dns_rdatatype_nsec || - val->event->type == dns_rdatatype_key || - !dns_nsec3_typepresent(&rdata, dns_rdatatype_cname)) { - *exists = ISC_TRUE; - *data = dns_nsec3_typepresent(&rdata, - val->event->type); - validator_log(val, ISC_LOG_DEBUG(3), - "NSEC3 proves name exists (owner) " - "data=%d", *data); - return (ISC_R_SUCCESS); - } - validator_log(val, 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. - */ - validator_log(val, 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)); - validator_log(val, 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)); - validator_log(val, 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)); - validator_log(val, 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) - validator_log(val, 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); -} - -/*% * Callback for when NSEC records have been validated. * * Looks for NOQNAME, NODATA and OPTOUT proofs. @@ -1339,8 +906,9 @@ authvalidated(isc_task_t *task, isc_event_t *event) { rdataset->trust == dns_trust_secure && (NEEDNODATA(val) || NEEDNOQNAME(val)) && !FOUNDNODATA(val) && !FOUNDNOQNAME(val) && - nsecnoexistnodata(val, val->event->name, devent->name, - rdataset, &exists, &data, wild) + dns_nsec_noexistnodata(val->event->type, val->event->name, + devent->name, rdataset, &exists, + &data, wild, validator_log, val) == ISC_R_SUCCESS) { if (exists && !data) { @@ -1413,9 +981,6 @@ view_find(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) { if (dns_rdataset_isassociated(&val->fsigrdataset)) dns_rdataset_disassociate(&val->fsigrdataset); - if (val->view->zonetable == NULL) - return (ISC_R_CANCELED); - if (isc_time_now(&now) == ISC_R_SUCCESS && dns_resolver_getbadcache(val->view->resolver, name, type, &now)) { @@ -1859,6 +1424,10 @@ isselfsigned(dns_validator_t *val) { 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); @@ -2831,8 +2400,9 @@ checkwildcard(dns_validator_t *val, dns_rdatatype_t type, dns_name_t *zonename) if (rdataset->type == dns_rdatatype_nsec && (NEEDNODATA(val) || NEEDNOWILDCARD(val)) && !FOUNDNODATA(val) && !FOUNDNOWILDCARD(val) && - nsecnoexistnodata(val, wild, name, rdataset, - &exists, &data, NULL) + 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; @@ -2855,10 +2425,11 @@ checkwildcard(dns_validator_t *val, dns_rdatatype_t type, dns_name_t *zonename) if (rdataset->type == dns_rdatatype_nsec3 && (NEEDNODATA(val) || NEEDNOWILDCARD(val)) && !FOUNDNODATA(val) && !FOUNDNOWILDCARD(val) && - nsec3noexistnodata(val, wild, name, rdataset, - zonename, &exists, &data, - NULL, NULL, NULL, NULL, NULL, - NULL) == ISC_R_SUCCESS) + 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) @@ -2920,11 +2491,12 @@ findnsec3proofs(dns_validator_t *val) { rdataset->trust != dns_trust_secure) continue; - result = nsec3noexistnodata(val, val->event->name, - name, rdataset, - zonename, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL); + 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); @@ -2972,16 +2544,19 @@ findnsec3proofs(dns_validator_t *val) { setclosest = setnearest = ISC_FALSE; optout = ISC_FALSE; unknown = ISC_FALSE; - (void)nsec3noexistnodata(val, val->event->name, name, rdataset, - zonename, &exists, &data, &optout, - &unknown, setclosestp, &setnearest, - closestp, nearest); - if (setclosest) - proofs[DNS_VALIDATOR_CLOSESTENCLOSER] = name; + 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; @@ -3272,6 +2847,8 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) { "nonexistence proof(s) found"); if (val->event->message == NULL) marksecure(val->event); + else + val->event->secure = ISC_TRUE; return (ISC_R_SUCCESS); } @@ -3374,6 +2951,7 @@ dlvfetched(isc_task_t *task, isc_event_t *event) { 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); @@ -3389,13 +2967,14 @@ dlvfetched(isc_task_t *task, isc_event_t *event) { if (dns_rdataset_isassociated(&val->fsigrdataset)) dns_rdataset_disassociate(&val->fsigrdataset); isc_event_free(&event); - dns_resolver_destroyfetch(&val->fetch); 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)); @@ -3448,6 +3027,8 @@ dlvfetched(isc_task_t *task, isc_event_t *event) { } want_destroy = exit_check(val); UNLOCK(&val->lock); + if (fetch != NULL) + dns_resolver_destroyfetch(&fetch); if (want_destroy) destroy(val); } @@ -4155,6 +3736,7 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, 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; @@ -4230,6 +3812,8 @@ dns_validator_send(dns_validator_t *validator) { void dns_validator_cancel(dns_validator_t *validator) { + dns_fetch_t *fetch = NULL; + REQUIRE(VALID_VALIDATOR(validator)); LOCK(&validator->lock); @@ -4239,8 +3823,8 @@ dns_validator_cancel(dns_validator_t *validator) { if ((validator->attributes & VALATTR_CANCELED) == 0) { validator->attributes |= VALATTR_CANCELED; if (validator->event != NULL) { - if (validator->fetch != NULL) - dns_resolver_cancelfetch(validator->fetch); + fetch = validator->fetch; + validator->fetch = NULL; if (validator->subvalidator != NULL) dns_validator_cancel(validator->subvalidator); @@ -4251,6 +3835,12 @@ dns_validator_cancel(dns_validator_t *validator) { } } 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 @@ -4339,7 +3929,7 @@ validator_logv(dns_validator_t *val, isc_logcategory_t *category, } static void -validator_log(dns_validator_t *val, int level, const char *fmt, ...) { +validator_log(void *val, int level, const char *fmt, ...) { va_list ap; if (! isc_log_wouldlog(dns_lctx, level)) diff --git a/lib/dns/view.c b/lib/dns/view.c index 6750058..5b6ad65 100644 --- a/lib/dns/view.c +++ b/lib/dns/view.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -86,6 +86,9 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, 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; @@ -95,8 +98,8 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, if (result != ISC_R_SUCCESS) goto cleanup_name; -#ifdef BIND9 view->zonetable = NULL; +#ifdef BIND9 result = dns_zt_create(mctx, rdclass, &view->zonetable); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, @@ -125,7 +128,6 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, view->resolver = NULL; view->adb = NULL; view->requestmgr = NULL; - view->mctx = mctx; view->rdclass = rdclass; view->frozen = ISC_FALSE; view->task = NULL; @@ -225,6 +227,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, 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; @@ -260,7 +263,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, isc_mem_free(mctx, view->name); cleanup_view: - isc_mem_put(mctx, view, sizeof(*view)); + isc_mem_putanddetach(&view->mctx, view, sizeof(*view)); return (result); } @@ -439,7 +442,7 @@ destroy(dns_view_t *view) { DESTROYLOCK(&view->lock); isc_refcount_destroy(&view->references); isc_mem_free(view->mctx, view->name); - isc_mem_put(view->mctx, view, sizeof(*view)); + isc_mem_putanddetach(&view->mctx, view, sizeof(*view)); } /* @@ -482,6 +485,10 @@ view_flushanddetach(dns_view_t **viewp, isc_boolean_t flush) { view->flush = ISC_TRUE; isc_refcount_decrement(&view->references, &refs); if (refs == 0) { +#ifdef BIND9 + dns_zone_t *mkzone = NULL; +#endif + LOCK(&view->lock); if (!RESSHUTDOWN(view)) dns_resolver_shutdown(view->resolver); @@ -497,13 +504,20 @@ view_flushanddetach(dns_view_t **viewp, isc_boolean_t flush) { 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(view->managed_keys); - dns_zone_detach(&view->managed_keys); + dns_zone_flush(mkzone); } #endif done = all_done(view); UNLOCK(&view->lock); + +#ifdef BIND9 + /* Need to detach zones outside view lock */ + if (mkzone != NULL) + dns_zone_detach(&mkzone); +#endif } *viewp = NULL; @@ -855,11 +869,14 @@ dns_view_findzone(dns_view_t *view, dns_name_t *name, dns_zone_t **zonep) { REQUIRE(DNS_VIEW_VALID(view)); - result = dns_zt_find(view->zonetable, name, 0, NULL, zonep); - if (result == DNS_R_PARTIALMATCH) { - dns_zone_detach(zonep); + 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); } @@ -892,6 +909,7 @@ dns_view_find2(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, #ifndef BIND9 UNUSED(use_hints); UNUSED(use_static_stub); + UNUSED(zone); #endif /* @@ -916,11 +934,11 @@ dns_view_find2(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, /* * Find a database to answer the query. */ - zone = NULL; 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) { @@ -1168,11 +1186,14 @@ dns_view_findzonecut2(dns_view_t *view, dns_name_t *name, dns_name_t *fname, dns_rdataset_t zrdataset, zsigrdataset; dns_fixedname_t zfixedname; +#ifndef BIND9 + UNUSED(zone); +#endif + REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(view->frozen); db = NULL; - zone = NULL; use_zone = ISC_FALSE; try_hints = ISC_FALSE; zfname = NULL; @@ -1188,6 +1209,7 @@ dns_view_findzonecut2(dns_view_t *view, dns_name_t *name, dns_name_t *fname, * 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); diff --git a/lib/dns/xfrin.c b/lib/dns/xfrin.c index eae39d9..3026af9 100644 --- a/lib/dns/xfrin.c +++ b/lib/dns/xfrin.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2008, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -591,6 +591,7 @@ xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name, isc_uint32_t ttl, case XFRST_AXFR_END: case XFRST_IXFR_END: FAIL(DNS_R_EXTRADATA); + /* NOTREACHED */ default: INSIST(0); break; @@ -781,7 +782,8 @@ xfrin_create(isc_mem_t *mctx, xfr = isc_mem_get(mctx, sizeof(*xfr)); if (xfr == NULL) return (ISC_R_NOMEMORY); - xfr->mctx = mctx; + xfr->mctx = NULL; + isc_mem_attach(mctx, &xfr->mctx); xfr->refcount = 0; xfr->zone = NULL; dns_zone_iattach(zone, &xfr->zone); @@ -876,7 +878,7 @@ xfrin_create(isc_mem_t *mctx, dns_db_detach(&xfr->db); isc_task_detach(&xfr->task); dns_zone_idetach(&xfr->zone); - isc_mem_put(mctx, xfr, sizeof(*xfr)); + isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr)); return (result); } @@ -1491,7 +1493,7 @@ maybe_free(dns_xfrin_ctx_t *xfr) { if (xfr->zone != NULL) dns_zone_idetach(&xfr->zone); - isc_mem_put(xfr->mctx, xfr, sizeof(*xfr)); + isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr)); } /* diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 22db239..c212bf6 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -335,9 +335,9 @@ struct dns_zone { isc_boolean_t added; /*% - * whether a rpz radix was needed when last loaded + * whether this is a response policy zone */ - isc_boolean_t rpz_zone; + isc_boolean_t is_rpz; /*% * Outstanding forwarded UPDATE requests. @@ -345,6 +345,18 @@ struct dns_zone { dns_forwardlist_t forwards; }; +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)); \ @@ -855,7 +867,7 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) { zone->nodes = 100; zone->privatetype = (dns_rdatatype_t)0xffffU; zone->added = ISC_FALSE; - zone->rpz_zone = ISC_FALSE; + zone->is_rpz = ISC_FALSE; ISC_LIST_INIT(zone->forwards); zone->magic = ZONE_MAGIC; @@ -1042,6 +1054,7 @@ dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) { 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); @@ -1049,8 +1062,11 @@ dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp) { LOCK_ZONE(zone); ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (zone->db != NULL) { - result = zone_get_from_db(zone, zone->db, NULL, NULL, serialp, - NULL, NULL, NULL, NULL, 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); @@ -1390,6 +1406,30 @@ zone_isdynamic(dns_zone_t *zone) { !dns_acl_isnone(zone->update_acl)))); } +/* + * 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) { @@ -1459,8 +1499,7 @@ zone_load(dns_zone_t *zone, unsigned int flags) { * "rndc reconfig", we are done. */ if (!isc_time_isepoch(&zone->loadtime) && - (flags & DNS_ZONELOADFLAG_NOSTAT) != 0 && - zone->rpz_zone == dns_rpz_needed()) { + (flags & DNS_ZONELOADFLAG_NOSTAT) != 0) { result = ISC_R_SUCCESS; goto cleanup; } @@ -1469,8 +1508,7 @@ zone_load(dns_zone_t *zone, unsigned int flags) { if (result == ISC_R_SUCCESS) { if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE) && - isc_time_compare(&filetime, &zone->loadtime) <= 0 && - zone->rpz_zone == dns_rpz_needed()) { + isc_time_compare(&filetime, &zone->loadtime) <= 0) { dns_zone_log(zone, ISC_LOG_DEBUG(1), "skipping load: master file " "older than last load"); @@ -1478,7 +1516,6 @@ zone_load(dns_zone_t *zone, unsigned int flags) { goto cleanup; } loadtime = filetime; - zone->rpz_zone = dns_rpz_needed(); } } @@ -1704,8 +1741,15 @@ zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) { isc_result_t tresult; unsigned int options; - options = get_master_options(zone); +#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; @@ -2174,6 +2218,34 @@ zone_check_dup(dns_zone_t *zone, dns_db_t *db) { } 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; @@ -2187,7 +2259,7 @@ integrity_checks(dns_zone_t *zone, dns_db_t *db) { dns_name_t *name; dns_name_t *bottom; isc_result_t result; - isc_boolean_t ok = ISC_TRUE; + isc_boolean_t ok = ISC_TRUE, have_spf, have_txt; dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); @@ -2265,7 +2337,7 @@ integrity_checks(dns_zone_t *zone, dns_db_t *db) { result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv, 0, 0, &rdataset, NULL); if (result != ISC_R_SUCCESS) - goto next; + goto checkspf; result = dns_rdataset_first(&rdataset); while (result == ISC_R_SUCCESS) { dns_rdataset_current(&rdataset, &rdata); @@ -2278,6 +2350,50 @@ integrity_checks(dns_zone_t *zone, dns_db_t *db) { } 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); @@ -2788,6 +2904,8 @@ create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 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); @@ -2797,10 +2915,6 @@ create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, } } - /* Refresh new keys from the zone apex as soon as possible. */ - if (*changed) - set_refreshkeytimer(zone, &keydata, now); - if (keynode != NULL) dns_keytable_detachkeynode(keytable, &keynode); *keynodep = NULL; @@ -2942,7 +3056,8 @@ load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) { dns_rdataset_current(rdataset, &rdata); /* Convert rdata to keydata. */ - dns_rdata_tostruct(&rdata, &keydata, NULL); + result = dns_rdata_tostruct(&rdata, &keydata, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); /* Set the key refresh timer. */ set_refreshkeytimer(zone, &keydata, now); @@ -3285,6 +3400,13 @@ sync_keyzone(dns_zone_t *zone, dns_db_t *db) { } 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) @@ -3462,14 +3584,18 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, } 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, NULL, - &oldserial, NULL, NULL, NULL, - NULL, NULL); + 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; @@ -3877,6 +4003,19 @@ zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, *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; @@ -4543,20 +4682,21 @@ find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, } static isc_result_t -offline(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, dns_name_t *name, - dns_ttl_t ttl, dns_rdata_t *rdata) +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, diff, DNS_DIFFOP_DELRESIGN, + 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, diff, DNS_DIFFOP_ADDRESIGN, + result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_ADDRESIGN, name, ttl, rdata); + zonediff->offline = ISC_TRUE; return (result); } @@ -4631,7 +4771,7 @@ delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys) { */ 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, dns_diff_t *diff, dst_key_t **keys, + 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; @@ -4677,7 +4817,7 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, if (type != dns_rdatatype_dnskey) { if (delsig_ok(&rrsig, keys, nkeys)) { - result = update_one_rr(db, ver, diff, + result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN, name, rdataset.ttl, &rdata); if (incremental) @@ -4695,8 +4835,9 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, * for the private part. */ if (incremental) { - result = offline(db, ver, diff, name, - rdataset.ttl, &rdata); + result = offline(db, ver, zonediff, + name, rdataset.ttl, + &rdata); changed = ISC_TRUE; if (result != ISC_R_SUCCESS) break; @@ -4756,11 +4897,12 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, warn = maybe; if (warn == 0 || warn > timeexpire) warn = timeexpire; - result = offline(db, ver, diff, name, - rdataset.ttl, &rdata); + result = offline(db, ver, zonediff, + name, rdataset.ttl, + &rdata); break; } - result = update_one_rr(db, ver, diff, + result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN, name, rdataset.ttl, &rdata); @@ -4773,7 +4915,7 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, * delete the RRSIG. */ if (!found) - result = update_one_rr(db, ver, diff, + result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN, name, rdataset.ttl, &rdata); if (result != ISC_R_SUCCESS) @@ -4903,9 +5045,11 @@ add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, 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; + dns_diff_t _sig_diff; + zonediff_t zonediff; dns_fixedname_t fixed; dns_name_t *name; dns_rdataset_t rdataset; @@ -4919,10 +5063,13 @@ zone_resigninc(dns_zone_t *zone) { 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; + dns_diff_init(zone->mctx, &_sig_diff); + _sig_diff.resign = zone->sigresigninginterval; + zonediff_init(&zonediff, &_sig_diff); /* * Updates are disabled. Pause for 5 minutes. @@ -4992,7 +5139,7 @@ zone_resigninc(dns_zone_t *zone) { resign > stop) break; - result = del_sigs(zone, db, version, name, covers, &sig_diff, + 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, @@ -5001,7 +5148,7 @@ zone_resigninc(dns_zone_t *zone) { break; } - result = add_sigs(db, version, name, covers, &sig_diff, + 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) { @@ -5026,7 +5173,7 @@ zone_resigninc(dns_zone_t *zone) { goto failure; result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, - &sig_diff, zone_keys, nkeys, now, ISC_TRUE); + &zonediff, zone_keys, nkeys, now, ISC_TRUE); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_resigninc:del_sigs -> %s", @@ -5037,11 +5184,17 @@ zone_resigninc(dns_zone_t *zone) { /* * Did we change anything in the zone? */ - if (ISC_LIST_EMPTY(sig_diff.tuples)) + 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 = increment_soa_serial(db, version, &sig_diff, zone->mctx); + result = increment_soa_serial(db, version, zonediff.diff, zone->mctx); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_resigninc:increment_soa_serial -> %s", @@ -5054,8 +5207,8 @@ zone_resigninc(dns_zone_t *zone) { * termination is sensible. */ result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa, - &sig_diff, zone_keys, nkeys, zone->mctx, inception, - soaexpire, check_ksk, keyset_kskonly); + 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", @@ -5064,13 +5217,13 @@ zone_resigninc(dns_zone_t *zone) { } /* Write changes to journal file. */ - CHECK(zone_journal(zone, &sig_diff, "zone_resigninc")); + CHECK(zone_journal(zone, zonediff.diff, "zone_resigninc")); /* Everything has succeeded. Commit the changes. */ dns_db_closeversion(db, &version, ISC_TRUE); failure: - dns_diff_clear(&sig_diff); + dns_diff_clear(&_sig_diff); for (i = 0; i < nkeys; i++) dst_key_free(&zone_keys[i]); if (version != NULL) { @@ -5740,7 +5893,7 @@ update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version, dst_key_t *zone_keys[], unsigned int nkeys, dns_zone_t *zone, isc_stdtime_t inception, isc_stdtime_t expire, isc_stdtime_t now, isc_boolean_t check_ksk, isc_boolean_t keyset_kskonly, - dns_diff_t *sig_diff) + zonediff_t *zonediff) { dns_difftuple_t *tuple; isc_result_t result; @@ -5749,7 +5902,7 @@ update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version, tuple != NULL; tuple = ISC_LIST_HEAD(diff->tuples)) { result = del_sigs(zone, db, version, &tuple->name, - tuple->rdata.type, sig_diff, + tuple->rdata.type, zonediff, zone_keys, nkeys, now, ISC_FALSE); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, @@ -5758,7 +5911,7 @@ update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version, return (result); } result = add_sigs(db, version, &tuple->name, - tuple->rdata.type, sig_diff, + tuple->rdata.type, zonediff->diff, zone_keys, nkeys, zone->mctx, inception, expire, check_ksk, keyset_kskonly); if (result != ISC_R_SUCCESS) { @@ -5775,7 +5928,7 @@ update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version, !dns_name_equal(&tuple->name, &next->name))) next = ISC_LIST_NEXT(next, link); ISC_LIST_UNLINK(diff->tuples, tuple, link); - dns_diff_appendminimal(sig_diff, &tuple); + dns_diff_appendminimal(zonediff->diff, &tuple); INSIST(tuple == NULL); tuple = next; } while (tuple != NULL); @@ -5789,13 +5942,15 @@ update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version, */ 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 _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; @@ -5821,6 +5976,8 @@ zone_nsec3chain(dns_zone_t *zone) { 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); @@ -5829,8 +5986,9 @@ zone_nsec3chain(dns_zone_t *zone) { dns_diff_init(zone->mctx, ¶m_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; + dns_diff_init(zone->mctx, &_sig_diff); + _sig_diff.resign = zone->sigresigninginterval; + zonediff_init(&zonediff, &_sig_diff); ISC_LIST_INIT(cleanup); /* @@ -6028,6 +6186,7 @@ zone_nsec3chain(dns_zone_t *zone) { 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, ¶m_diff)); @@ -6325,6 +6484,7 @@ zone_nsec3chain(dns_zone_t *zone) { if (rebuild_nsec) { if (nsec3chain != NULL) dns_dbiterator_pause(nsec3chain->dbiterator); + result = updatesecure(db, version, &zone->origin, zone->minimum, ISC_TRUE, &nsec_diff); @@ -6336,7 +6496,11 @@ zone_nsec3chain(dns_zone_t *zone) { 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, @@ -6351,12 +6515,17 @@ zone_nsec3chain(dns_zone_t *zone) { } } + 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, &sig_diff); + 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)); @@ -6369,7 +6538,7 @@ zone_nsec3chain(dns_zone_t *zone) { */ result = update_sigs(¶m_diff, db, version, zone_keys, nkeys, zone, inception, expire, now, - check_ksk, keyset_kskonly, &sig_diff); + 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)); @@ -6377,8 +6546,6 @@ zone_nsec3chain(dns_zone_t *zone) { } if (updatensec) { - if (nsec3chain != NULL) - dns_dbiterator_pause(nsec3chain->dbiterator); result = updatesecure(db, version, &zone->origin, zone->minimum, ISC_FALSE, &nsec_diff); if (result != ISC_R_SUCCESS) { @@ -6391,7 +6558,7 @@ zone_nsec3chain(dns_zone_t *zone) { result = update_sigs(&nsec_diff, db, version, zone_keys, nkeys, zone, inception, expire, now, - check_ksk, keyset_kskonly, &sig_diff); + 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)); @@ -6402,18 +6569,23 @@ zone_nsec3chain(dns_zone_t *zone) { * If we made no effective changes to the zone then we can just * cleanup otherwise we need to increment the serial. */ - if (ISC_LIST_HEAD(sig_diff.tuples) == NULL) + 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, - &sig_diff, zone_keys, nkeys, now, ISC_FALSE); + &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 = increment_soa_serial(db, version, &sig_diff, zone->mctx); + result = increment_soa_serial(db, version, zonediff.diff, zone->mctx); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" "increment_soa_serial -> %s", @@ -6422,8 +6594,8 @@ zone_nsec3chain(dns_zone_t *zone) { } result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa, - &sig_diff, zone_keys, nkeys, zone->mctx, inception, - soaexpire, check_ksk, keyset_kskonly); + 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)); @@ -6431,7 +6603,7 @@ zone_nsec3chain(dns_zone_t *zone) { } /* Write changes to journal file. */ - CHECK(zone_journal(zone, &sig_diff, "zone_nsec3chain")); + CHECK(zone_journal(zone, zonediff.diff, "zone_nsec3chain")); LOCK_ZONE(zone); zone_needdump(zone, DNS_DUMP_DELAY); @@ -6451,6 +6623,7 @@ zone_nsec3chain(dns_zone_t *zone) { /* * Everything has succeeded. Commit the changes. + * Unconditionally commit as zonediff.offline not checked above. */ dns_db_closeversion(db, &version, ISC_TRUE); @@ -6520,7 +6693,7 @@ zone_nsec3chain(dns_zone_t *zone) { dns_diff_clear(¶m_diff); dns_diff_clear(&nsec3_diff); dns_diff_clear(&nsec_diff); - dns_diff_clear(&sig_diff); + dns_diff_clear(&_sig_diff); if (iterator != NULL) dns_rdatasetiter_destroy(&iterator); @@ -6622,11 +6795,13 @@ del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, */ 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 _sig_diff; dns_diff_t post_diff; + zonediff_t zonediff; dns_fixedname_t fixed; dns_fixedname_t nextfixed; dns_name_t *name, *nextname; @@ -6648,14 +6823,17 @@ zone_sign(dns_zone_t *zone) { 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, &_sig_diff); + _sig_diff.resign = zone->sigresigninginterval; dns_diff_init(zone->mctx, &post_diff); + zonediff_init(&zonediff, &_sig_diff); ISC_LIST_INIT(cleanup); /* @@ -6769,7 +6947,7 @@ zone_sign(dns_zone_t *zone) { dns_dbiterator_pause(signing->dbiterator); CHECK(del_sig(db, version, name, node, nkeys, signing->algorithm, signing->keyid, - &sig_diff)); + zonediff.diff)); } /* @@ -6864,7 +7042,7 @@ zone_sign(dns_zone_t *zone) { build_nsec, zone_keys[i], inception, expire, zone->minimum, is_ksk, ISC_TF(both && keyset_kskonly), - &delegation, &sig_diff, + &delegation, zonediff.diff, &signatures, zone->mctx)); /* * If we are adding we are done. Look for other keys @@ -6946,7 +7124,7 @@ zone_sign(dns_zone_t *zone) { if (ISC_LIST_HEAD(post_diff.tuples) != NULL) { result = update_sigs(&post_diff, db, version, zone_keys, nkeys, zone, inception, expire, now, - check_ksk, keyset_kskonly, &sig_diff); + check_ksk, keyset_kskonly, &zonediff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:" "update_sigs -> %s", @@ -6958,7 +7136,9 @@ zone_sign(dns_zone_t *zone) { /* * Have we changed anything? */ - if (ISC_LIST_HEAD(sig_diff.tuples) == NULL) { + if (ISC_LIST_EMPTY(zonediff.diff->tuples)) { + if (zonediff.offline) + commit = ISC_TRUE; result = ISC_R_SUCCESS; goto pauseall; } @@ -6966,7 +7146,7 @@ zone_sign(dns_zone_t *zone) { commit = ISC_TRUE; result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, - &sig_diff, zone_keys, nkeys, now, ISC_FALSE); + &zonediff, zone_keys, nkeys, now, ISC_FALSE); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:del_sigs -> %s", @@ -6974,7 +7154,7 @@ zone_sign(dns_zone_t *zone) { goto failure; } - result = increment_soa_serial(db, version, &sig_diff, zone->mctx); + result = increment_soa_serial(db, version, zonediff.diff, zone->mctx); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:increment_soa_serial -> %s", @@ -6987,8 +7167,8 @@ zone_sign(dns_zone_t *zone) { * termination is sensible. */ result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa, - &sig_diff, zone_keys, nkeys, zone->mctx, inception, - soaexpire, check_ksk, keyset_kskonly); + 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", @@ -6999,7 +7179,7 @@ zone_sign(dns_zone_t *zone) { /* * Write changes to journal file. */ - CHECK(zone_journal(zone, &sig_diff, "zone_sign")); + CHECK(zone_journal(zone, zonediff.diff, "zone_sign")); pauseall: /* @@ -7059,7 +7239,7 @@ zone_sign(dns_zone_t *zone) { signing = ISC_LIST_NEXT(signing, link)) dns_dbiterator_pause(signing->dbiterator); - dns_diff_clear(&sig_diff); + dns_diff_clear(&_sig_diff); for (i = 0; i < nkeys; i++) dst_key_free(&zone_keys[i]); @@ -7090,19 +7270,22 @@ normalize_key(dns_rdata_t *rr, dns_rdata_t *target, 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: - dns_rdata_tostruct(rr, &dnskey, NULL); + 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: - dns_rdata_tostruct(rr, &keydata, NULL); + 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); @@ -7509,7 +7692,8 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) { result = dns_rdataset_next(&kfetch->keydataset)) { dns_rdata_reset(&keydatarr); dns_rdataset_current(&kfetch->keydataset, &keydatarr); - dns_rdata_tostruct(&keydatarr, &keydata, NULL); + result = dns_rdata_tostruct(&keydatarr, &keydata, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); /* * If any keydata record has a nonzero add holddown, then @@ -7599,7 +7783,8 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) { dns_rdata_reset(&dnskeyrr); dns_rdataset_current(&kfetch->dnskeyset, &dnskeyrr); - dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); + result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); /* Skip ZSK's */ if (!ISC_TF(dnskey.flags & DNS_KEYFLAG_KSK)) @@ -7610,7 +7795,8 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) { if (matchkey(&kfetch->keydataset, &dnskeyrr)) { dns_rdata_reset(&keydatarr); dns_rdataset_current(&kfetch->keydataset, &keydatarr); - dns_rdata_tostruct(&keydatarr, &keydata, NULL); + result = dns_rdata_tostruct(&keydatarr, &keydata, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); if (revoked && revocable(kfetch, &keydata)) { if (keydata.addhd > now) { @@ -7710,7 +7896,8 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) { &keydatarr)); } else if (newkey) { /* Convert DNSKEY to KEYDATA */ - dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); + 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; @@ -7729,7 +7916,8 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) { if (trustkey) { /* Trust this key. */ - dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); + result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); trust_key(zone, keyname, &dnskey, mctx); } @@ -8020,6 +8208,14 @@ zone_maintenance(dns_zone_t *zone) { } /* + * 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) { @@ -8049,14 +8245,28 @@ zone_maintenance(dns_zone_t *zone) { } /* + * Master/redirect zones send notifies now, if needed + */ + switch (zone->type) { + case dns_zone_master: + 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 && - DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && - !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) - zone_refreshkeys(zone); + 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) && @@ -8070,12 +8280,6 @@ zone_maintenance(dns_zone_t *zone) { case dns_zone_master: case dns_zone_slave: /* - * Do we need to send out notify messages? - */ - if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) && - isc_time_compare(&now, &zone->notifytime) >= 0) - zone_notify(zone, &now); - /* * Do we need to sign/resign some RRsets? */ if (!isc_time_isepoch(&zone->signingtime) && @@ -8088,7 +8292,7 @@ zone_maintenance(dns_zone_t *zone) { isc_time_compare(&now, &zone->nsec3chaintime) >= 0) zone_nsec3chain(zone); /* - * Do we need to issue a key expiry warning. + * Do we need to issue a key expiry warning? */ if (!isc_time_isepoch(&zone->keywarntime) && isc_time_compare(&now, &zone->keywarntime) >= 0) @@ -8237,6 +8441,7 @@ dns_zone_dump(dns_zone_t *zone) { static void zone_needdump(dns_zone_t *zone, unsigned int delay) { + const char me[] = "zone_needdump"; isc_time_t dumptime; isc_time_t now; @@ -8246,6 +8451,7 @@ zone_needdump(dns_zone_t *zone, unsigned int delay) { REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(LOCKED_ZONE(zone)); + ENTER; /* * Do we have a place to dump to and are we loaded? @@ -8898,9 +9104,9 @@ notify_send_toaddr(isc_task_t *task, isc_event_t *event) { dns_message_destroy(&message); cleanup: UNLOCK_ZONE(notify->zone); + isc_event_free(&event); if (result != ISC_R_SUCCESS) notify_destroy(notify, ISC_FALSE); - isc_event_free(&event); } static void @@ -9247,7 +9453,7 @@ stub_callback(isc_task_t *task, isc_event_t *event) { isc_time_t now; isc_boolean_t exiting = ISC_FALSE; isc_interval_t i; - unsigned int j; + unsigned int j, soacount; stub = revent->ev_arg; INSIST(DNS_STUB_VALID(stub)); @@ -9390,9 +9596,9 @@ stub_callback(isc_task_t *task, isc_event_t *event) { 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, NULL, NULL, &refresh, - &retry, &expire, NULL, NULL); - if (result == ISC_R_SUCCESS) { + 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); @@ -9728,10 +9934,12 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { serial = soa.serial; if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { - result = zone_get_from_db(zone, zone->db, NULL, NULL, + 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 @@ -10953,6 +11161,7 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from, 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); @@ -10962,10 +11171,11 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from, * The following should safely be performed without DB * lock and succeed in this context. */ - result = zone_get_from_db(zone, zone->db, NULL, NULL, - &oldserial, NULL, NULL, NULL, - NULL, NULL); + 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, @@ -11652,6 +11862,7 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) { 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"); @@ -11666,10 +11877,11 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) { /* * This is checked in zone_postload() for master zones. */ - result = zone_get_from_db(zone, zone->db, NULL, NULL, + 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 && !isc_serial_gt(serial, oldserial)) { isc_uint32_t serialmin, serialmax; @@ -11916,6 +12128,8 @@ zone_xfrdone(dns_zone_t *zone, isc_result_t result) { * 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); @@ -11923,14 +12137,16 @@ zone_xfrdone(dns_zone_t *zone, isc_result_t result) { zone->masterfile != NULL) result = isc_file_settime(zone->masterfile, &now); - /* Someone removed the file from underneath us! */ - if (result == ISC_R_FILENOTFOUND && - zone->masterfile != NULL) { - unsigned int delay = DNS_DUMP_DELAY; - if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY)) - delay = 0; + + 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) + else if (result != ISC_R_SUCCESS) dns_zone_log(zone, ISC_LOG_ERROR, "transfer: could not set file " "modification time of '%s': %s", @@ -13323,6 +13539,8 @@ dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, 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; @@ -13994,7 +14212,7 @@ add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype, static isc_result_t sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, - dns_diff_t *diff, dns_diff_t *sig_diff) + dns_diff_t *diff, zonediff_t *zonediff) { isc_result_t result; isc_stdtime_t now, inception, soaexpire; @@ -14034,7 +14252,7 @@ sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, if (tuple == NULL) { result = del_sigs(zone, db, ver, &zone->origin, - dns_rdatatype_dnskey, sig_diff, + dns_rdatatype_dnskey, zonediff, zone_keys, nkeys, now, ISC_FALSE); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, @@ -14043,7 +14261,7 @@ sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, goto failure; } result = add_sigs(db, ver, &zone->origin, dns_rdatatype_dnskey, - sig_diff, zone_keys, nkeys, zone->mctx, + zonediff->diff, zone_keys, nkeys, zone->mctx, inception, soaexpire, check_ksk, keyset_kskonly); if (result != ISC_R_SUCCESS) { @@ -14056,7 +14274,7 @@ sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, result = update_sigs(diff, db, ver, zone_keys, nkeys, zone, inception, soaexpire, now, check_ksk, - keyset_kskonly, sig_diff); + keyset_kskonly, zonediff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, @@ -14209,7 +14427,8 @@ zone_rekey(dns_zone_t *zone) { dns_rdataset_t soaset, soasigs, keyset, keysigs; dns_dnsseckeylist_t dnskeys, keys, rmkeys; dns_dnsseckey_t *key; - dns_diff_t diff, sig_diff; + 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; @@ -14233,8 +14452,9 @@ zone_rekey(dns_zone_t *zone) { dir = dns_zone_getkeydirectory(zone); mctx = zone->mctx; dns_diff_init(mctx, &diff); - dns_diff_init(mctx, &sig_diff); - sig_diff.resign = zone->sigresigninginterval; + 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)); @@ -14334,8 +14554,8 @@ zone_rekey(dns_zone_t *zone) { ISC_TF(newalg || fullsign))); CHECK(increment_soa_serial(db, ver, &diff, mctx)); CHECK(add_chains(zone, db, ver, &diff)); - CHECK(sign_apex(zone, db, ver, &diff, &sig_diff)); - CHECK(zone_journal(zone, &sig_diff, "zone_rekey")); + CHECK(sign_apex(zone, db, ver, &diff, &zonediff)); + CHECK(zone_journal(zone, zonediff.diff, "zone_rekey")); commit = ISC_TRUE; } } @@ -14425,7 +14645,7 @@ zone_rekey(dns_zone_t *zone) { * Cause the zone to add/delete NSEC3 chains for the * deferred NSEC3PARAM changes. */ - for (tuple = ISC_LIST_HEAD(sig_diff.tuples); + for (tuple = ISC_LIST_HEAD(zonediff.diff->tuples); tuple != NULL; tuple = ISC_LIST_NEXT(tuple, link)) { unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; @@ -14500,7 +14720,7 @@ zone_rekey(dns_zone_t *zone) { failure: dns_diff_clear(&diff); - dns_diff_clear(&sig_diff); + dns_diff_clear(&_sig_diff); clear_keylist(&dnskeys, mctx); clear_keylist(&keys, mctx); diff --git a/lib/export/dns/Makefile.in b/lib/export/dns/Makefile.in index 6df36fe..f575f86 100644 --- a/lib/export/dns/Makefile.in +++ b/lib/export/dns/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2012 Internet Systems Consortium, Inc. ("ISC") +# 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 @@ -43,8 +43,9 @@ LIBS = @LIBS@ # Alphabetically +OPENSSLGOSTLINKOBJS = opensslgost_link.@O@ OPENSSLLINKOBJS = openssl_link.@O@ openssldh_link.@O@ openssldsa_link.@O@ \ - opensslecdsa_link.@O@ opensslgost_link.@O@ opensslrsa_link.@O@ + opensslecdsa_link.@O@ @OPENSSLGOSTLINKOBJS@ opensslrsa_link.@O@ DSTOBJS = @OPENSSLLINKOBJS@ \ dst_api.@O@ dst_lib.@O@ dst_parse.@O@ dst_result.@O@ \ @@ -71,8 +72,9 @@ OBJS= ${DNSOBJS} ${OTHEROBJS} ${DSTOBJS} ${PORTDNSOBJS} # Alphabetically +OPENSSLGOSTLINKSRCS = opensslgost_link.c OPENSSLLINKSRCS = openssl_link.c openssldh_link.c openssldsa_link.c \ - opensslecdsa_link.c opensslgost_link.c opensslrsa_link.c + opensslecdsa_link.c @OPENSSLGOSTLINKSRCS@ opensslrsa_link.c DSTSRCS = @OPENSSLLINKSRCS@ \ dst_api.c dst_lib.c dst_parse.c \ diff --git a/lib/export/irs/Makefile.in b/lib/export/irs/Makefile.in index 2cbc0bb..b2520f9 100644 --- a/lib/export/irs/Makefile.in +++ b/lib/export/irs/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") +# 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 @@ -24,8 +24,9 @@ export_srcdir = @top_srcdir@/lib/export @BIND9_MAKE_INCLUDES@ -CINCLUDES = -I. -I./include -I${srcdir}/include \ +CINCLUDES = -I. -I./include -I${srcdir}/include -I ../../irs/include \ ${ISCCFG_INCLUDES} -I../dns/include ${DNS_INCLUDES} \ + -I../dns/include ${DNS_INCLUDES} \ -I${export_srcdir}/isc/include ${ISC_INCLUDES} CDEFINES = CWARNINGS = diff --git a/lib/export/isc/Makefile.in b/lib/export/isc/Makefile.in index 86726ab..c04a907 100644 --- a/lib/export/isc/Makefile.in +++ b/lib/export/isc/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2009, 2010, 2012 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2009, 2010, 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 @@ -67,12 +67,11 @@ OBJS = @ISC_EXTRA_OBJS@ \ error.@O@ event.@O@ \ hash.@O@ hex.@O@ hmacmd5.@O@ hmacsha.@O@ \ inet_aton.@O@ iterated_hash.@O@ lex.@O@ lfsr.@O@ log.@O@ \ - md5.@O@ mutexblock.@O@ \ - netaddr.@O@ netscope.@O@ \ - ondestroy.@O@ \ - parseint.@O@ portset.@O@ radix.@O@ \ - random.@O@ refcount.@O@ region.@O@ result.@O@ rwlock.@O@ \ - serial.@O@ sha1.@O@ sha2.@O@ sockaddr.@O@ stats.@O@ string.@O@ \ + md5.@O@ mutexblock.@O@ netaddr.@O@ netscope.@O@ \ + ondestroy.@O@ parseint.@O@ portset.@O@ radix.@O@ \ + random.@O@ refcount.@O@ region.@O@ regex.@O@ result.@O@ \ + rwlock.@O@ serial.@O@ sha1.@O@ sha2.@O@ sockaddr.@O@ \ + stats.@O@ string.@O@ \ symtab.@O@ \ version.@O@ \ ${APIOBJS} ${ISCDRIVEROBJS} \ @@ -94,7 +93,7 @@ SRCS = @ISC_EXTRA_SRCS@ \ netaddr.c netscope.c \ ondestroy.c \ parseint.c portset.c radix.c \ - random.c refcount.c region.c result.c rwlock.c \ + random.c refcount.c region.c regex.c result.c rwlock.c \ serial.c sha1.c sha2.c sockaddr.c stats.c string.c symtab.c \ version.c \ ${APISRCS} ${ISCDRIVERSRCS} diff --git a/lib/export/isc/include/isc/Makefile.in b/lib/export/isc/include/isc/Makefile.in index 91f538c..8c7eff8 100644 --- a/lib/export/isc/include/isc/Makefile.in +++ b/lib/export/isc/include/isc/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2009, 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 @@ -35,7 +35,7 @@ HEADERS = app.h assertions.h base64.h bitstring.h boolean.h \ magic.h md5.h mem.h msgcat.h msgs.h \ mutexblock.h namespace.h netaddr.h ondestroy.h os.h parseint.h \ print.h quota.h radix.h random.h ratelimiter.h \ - refcount.h region.h resource.h \ + refcount.h regex.h region.h resource.h \ result.h resultclass.h rwlock.h serial.h sha1.h sha2.h \ sockaddr.h socket.h stdio.h stdlib.h string.h \ symtab.h \ diff --git a/lib/export/isc/nls/Makefile.in b/lib/export/isc/nls/Makefile.in index 2515685..16a6a86 100644 --- a/lib/export/isc/nls/Makefile.in +++ b/lib/export/isc/nls/Makefile.in @@ -16,10 +16,12 @@ top_srcdir = @top_srcdir@ srcdir = @top_srcdir@/lib/isc/nls +export_srcdir = @top_srcdir@/lib/export @BIND9_MAKE_INCLUDES@ CINCLUDES = -I${srcdir}/unix/include \ + -I${export_srcdir}/isc/include \ ${ISC_INCLUDES} CDEFINES = diff --git a/lib/export/isc/nothreads/Makefile.in b/lib/export/isc/nothreads/Makefile.in index 994da63..4640993 100644 --- a/lib/export/isc/nothreads/Makefile.in +++ b/lib/export/isc/nothreads/Makefile.in @@ -16,11 +16,13 @@ top_srcdir = @top_srcdir@ srcdir = @top_srcdir@/lib/isc/nothreads +export_srcdir = @top_srcdir@/lib/export @BIND9_MAKE_INCLUDES@ CINCLUDES = -I${srcdir}/include \ -I${srcdir}/../unix/include \ + -I${export_srcdir}/isc/include \ -I../include \ -I${srcdir}/../include \ -I${srcdir}/.. diff --git a/lib/export/isc/pthreads/Makefile.in b/lib/export/isc/pthreads/Makefile.in index f08e5c6..80c5e3b 100644 --- a/lib/export/isc/pthreads/Makefile.in +++ b/lib/export/isc/pthreads/Makefile.in @@ -16,11 +16,13 @@ top_srcdir = @top_srcdir@ srcdir = @top_srcdir@/lib/isc/pthreads +export_srcdir = @top_srcdir@/lib/export @BIND9_MAKE_INCLUDES@ CINCLUDES = -I${srcdir}/include \ -I${srcdir}/../unix/include \ + -I${export_srcdir}/isc/include \ -I../include \ -I${srcdir}/../include \ -I${srcdir}/.. diff --git a/lib/export/isc/unix/Makefile.in b/lib/export/isc/unix/Makefile.in index f5cf7e8..1873202 100644 --- a/lib/export/isc/unix/Makefile.in +++ b/lib/export/isc/unix/Makefile.in @@ -16,11 +16,13 @@ top_srcdir = @top_srcdir@ srcdir = @top_srcdir@/lib/isc/unix +export_srcdir = @top_srcdir@/lib/export @BIND9_MAKE_INCLUDES@ CINCLUDES = -I${srcdir}/include \ -I${srcdir}/../@ISC_THREAD_DIR@/include \ + -I${export_srcdir}/isc/include \ -I../include \ -I${srcdir}/../include \ -I${srcdir}/.. diff --git a/lib/export/isccfg/Makefile.in b/lib/export/isccfg/Makefile.in index 907af50..2a791a4 100644 --- a/lib/export/isccfg/Makefile.in +++ b/lib/export/isccfg/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") +# 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 @@ -31,7 +31,7 @@ CDEFINES = CWARNINGS = ISCLIBS = ../isc/libisc.@A@ -DNSLIBS = ../dns/libdns.@A@ +DNSLIBS = ../dns/libdns.@A@ @DNS_CRYPTO_LIBS@ ISCDEPLIBS = ../../lib/isc/libisc.@A@ ISCCFGDEPLIBS = libisccfg.@A@ diff --git a/lib/export/samples/Makefile.in b/lib/export/samples/Makefile.in index cdc66b1..194aaeb 100644 --- a/lib/export/samples/Makefile.in +++ b/lib/export/samples/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2009, 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 @@ -25,7 +25,8 @@ export_srcdir = @top_srcdir@/lib/export CINCLUDES = -I${srcdir}/include -I../dns/include \ -I${export_srcdir}/isc/include \ ${DNS_INCLUDES} ${ISC_INCLUDES} \ - -I${top_srcdir}/lib/irs/include + -I${top_srcdir}/lib/irs/include \ + -I../../irs/include CDEFINES = CWARNINGS = diff --git a/lib/export/samples/nsprobe.c b/lib/export/samples/nsprobe.c index 869b194..1d7ed3b 100644 --- a/lib/export/samples/nsprobe.c +++ b/lib/export/samples/nsprobe.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -282,8 +282,6 @@ make_querymessage(dns_message_t *message, dns_name_t *qname0, dns_message_puttempname(message, &qname); if (qrdataset != NULL) dns_message_puttemprdataset(message, &qrdataset); - if (message != NULL) - dns_message_destroy(&message); return (result); } @@ -293,7 +291,7 @@ make_querymessage(dns_message_t *message, dns_name_t *qname0, static inline void increment_entry(unsigned long *entryp) { (*entryp)++; - INSIST(*entryp != 0); /* check overflow */ + INSIST(*entryp != 0U); /* check overflow */ } static void @@ -392,57 +390,57 @@ update_stat(struct probe_trans *trans) { } /* Update per domain statistics */ - if (local_stat.ignore > 0) { + if (local_stat.ignore > 0U) { if (verbose_level > 0) printf("%s:ignore\n", trans->domain); increment_entry(&domain_stat.ignore); err_count++; } - if (local_stat.nxdomain > 0) { + if (local_stat.nxdomain > 0U) { if (verbose_level > 0) printf("%s:nxdomain\n", trans->domain); increment_entry(&domain_stat.nxdomain); err_count++; } - if (local_stat.othererr > 0) { + if (local_stat.othererr > 0U) { if (verbose_level > 0) printf("%s:othererr\n", trans->domain); increment_entry(&domain_stat.othererr); err_count++; } - if (local_stat.multiplesoa > 0) { + if (local_stat.multiplesoa > 0U) { if (verbose_level > 0) printf("%s:multiplesoa\n", trans->domain); increment_entry(&domain_stat.multiplesoa); err_count++; } - if (local_stat.multiplecname > 0) { + if (local_stat.multiplecname > 0U) { if (verbose_level > 0) printf("%s:multiplecname\n", trans->domain); increment_entry(&domain_stat.multiplecname); err_count++; } - if (local_stat.brokenanswer > 0) { + if (local_stat.brokenanswer > 0U) { if (verbose_level > 0) printf("%s:brokenanswer\n", trans->domain); increment_entry(&domain_stat.brokenanswer); err_count++; } - if (local_stat.lame > 0) { + if (local_stat.lame > 0U) { if (verbose_level > 0) printf("%s:lame\n", trans->domain); increment_entry(&domain_stat.lame); err_count++; } - if (err_count > 1) + if (err_count > 1U) increment_entry(&multiple_error_domains); /* * We regard the domain as valid if and only if no authoritative server * has a problem and at least one server is known to be valid. */ - if (local_stat.valid > 0 && err_count == 0) { + if (local_stat.valid > 0U && err_count == 0U) { if (verbose_level > 1) printf("%s:valid\n", trans->domain); increment_entry(&domain_stat.valid); @@ -452,7 +450,7 @@ update_stat(struct probe_trans *trans) { * If the domain has no available server or all servers have the * 'unknown' result, the domain's result is also regarded as unknown. */ - if (local_stat.valid == 0 && err_count == 0) { + if (local_stat.valid == 0U && err_count == 0U) { if (verbose_level > 1) printf("%s:unknown\n", trans->domain); increment_entry(&domain_stat.unknown); @@ -1218,5 +1216,5 @@ main(int argc, char *argv[]) { isc_app_ctxfinish(actx); ctxs_destroy(&mctx, &actx, &taskmgr, &socketmgr, &timermgr); - exit(0); + return (0); } diff --git a/lib/export/samples/sample-async.c b/lib/export/samples/sample-async.c index e646e79..a70dd47 100644 --- a/lib/export/samples/sample-async.c +++ b/lib/export/samples/sample-async.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -398,5 +398,5 @@ main(int argc, char *argv[]) { isc_app_ctxfinish(query_actx); ctxs_destroy(&mctx, &query_actx, &taskmgr, &socketmgr, &timermgr); - exit(0); + return (0); } diff --git a/lib/export/samples/sample-gai.c b/lib/export/samples/sample-gai.c index 6dc4014..243d07a 100644 --- a/lib/export/samples/sample-gai.c +++ b/lib/export/samples/sample-gai.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2009, 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 @@ -61,7 +61,7 @@ do_gai(int family, char *hostname) { } } - freeaddrinfo(res); + freeaddrinfo(res0); } int @@ -73,5 +73,5 @@ main(int argc, char *argv[]) { do_gai(AF_INET6, argv[1]); do_gai(AF_UNSPEC, argv[1]); - exit(0); + return (0); } diff --git a/lib/export/samples/sample-request.c b/lib/export/samples/sample-request.c index d5d2312..07baf39 100644 --- a/lib/export/samples/sample-request.c +++ b/lib/export/samples/sample-request.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2009, 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 @@ -77,9 +77,12 @@ make_querymessage(dns_message_t *message, const char *namestr, isc_buffer_t b; size_t namelen; + REQUIRE(message != NULL); + REQUIRE(namestr != NULL); + /* Construct qname */ namelen = strlen(namestr); - isc_buffer_init(&b, namestr, namelen); + isc_buffer_constinit(&b, namestr, namelen); isc_buffer_add(&b, namelen); dns_fixedname_init(&fixedqname); qname0 = dns_fixedname_name(&fixedqname); @@ -115,8 +118,7 @@ make_querymessage(dns_message_t *message, const char *namestr, dns_message_puttempname(message, &qname); if (qrdataset != NULL) dns_message_puttemprdataset(message, &qrdataset); - if (message != NULL) - dns_message_destroy(&message); + dns_message_destroy(&message); return (result); } @@ -259,5 +261,5 @@ main(int argc, char *argv[]) { dns_client_destroy(&client); dns_lib_shutdown(); - exit(0); + return (0); } diff --git a/lib/export/samples/sample-update.c b/lib/export/samples/sample-update.c index e54d154..2c35baa 100644 --- a/lib/export/samples/sample-update.c +++ b/lib/export/samples/sample-update.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009, 2010 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2009, 2010, 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 @@ -305,7 +305,7 @@ main(int argc, char *argv[]) { dns_client_destroy(&client); dns_lib_shutdown(); - exit(0); + return (0); } /* @@ -372,7 +372,7 @@ parse_name(char **cmdlinep, dns_name_t *name) { isc_buffer_t source; word = nsu_strsep(cmdlinep, " \t\r\n"); - if (*word == 0) { + if (word == NULL || *word == 0) { fprintf(stderr, "could not read owner name\n"); exit(1); } diff --git a/lib/export/samples/sample.c b/lib/export/samples/sample.c index 7fc6a30..b121a0d 100644 --- a/lib/export/samples/sample.c +++ b/lib/export/samples/sample.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2009, 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 @@ -172,7 +172,9 @@ set_key(dns_client_t *client, char *keynamestr, char *keystr, } static void -addserver(dns_client_t *client, const char *addrstr, const char *namespace) { +addserver(dns_client_t *client, const char *addrstr, const char *port, + const char *namespace) +{ struct addrinfo hints, *res; int gai_error; isc_sockaddr_t sa; @@ -188,7 +190,7 @@ addserver(dns_client_t *client, const char *addrstr, const char *namespace) { hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; hints.ai_flags = AI_NUMERICHOST; - gai_error = getaddrinfo(addrstr, "53", &hints, &res); + gai_error = getaddrinfo(addrstr, port, &hints, &res); if (gai_error != 0) { fprintf(stderr, "getaddrinfo failed: %s\n", gai_strerror(gai_error)); @@ -196,15 +198,15 @@ addserver(dns_client_t *client, const char *addrstr, const char *namespace) { } INSIST(res->ai_addrlen <= sizeof(sa.type)); memcpy(&sa.type, res->ai_addr, res->ai_addrlen); - freeaddrinfo(res); sa.length = res->ai_addrlen; + freeaddrinfo(res); ISC_LINK_INIT(&sa, link); ISC_LIST_INIT(servers); ISC_LIST_APPEND(servers, &sa, link); if (namespace != NULL) { namelen = strlen(namespace); - isc_buffer_init(&b, namespace, namelen); + isc_buffer_constinit(&b, namespace, namelen); isc_buffer_add(&b, namelen); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); @@ -245,8 +247,9 @@ main(int argc, char *argv[]) { isc_mem_t *keymctx = NULL; unsigned int clientopt, resopt; isc_boolean_t is_sep = ISC_FALSE; + const char *port = "53"; - while ((ch = getopt(argc, argv, "a:es:t:k:K:")) != -1) { + while ((ch = getopt(argc, argv, "a:es:t:k:K:p:")) != -1) { switch (ch) { case 't': tr.base = optarg; @@ -279,6 +282,9 @@ main(int argc, char *argv[]) { case 'K': keystr = optarg; break; + case 'p': + port = optarg; + break; default: usage(); } @@ -318,11 +324,11 @@ main(int argc, char *argv[]) { } /* Set the nameserver */ - addserver(client, argv[0], NULL); + addserver(client, argv[0], port, NULL); /* Set the alternate nameserver (when specified) */ if (altserver != NULL) - addserver(client, altserveraddr, altservername); + addserver(client, altserveraddr, port, altservername); /* Install DNSSEC key (if given) */ if (keynamestr != NULL) { @@ -374,5 +380,5 @@ main(int argc, char *argv[]) { isc_mem_destroy(&keymctx); dns_lib_shutdown(); - exit(0); + return (0); } diff --git a/lib/irs/api b/lib/irs/api index ba19dd9..5c8dd5e 100644 --- a/lib/irs/api +++ b/lib/irs/api @@ -1,8 +1,9 @@ # LIBINTERFACE ranges # 9.6: 50-59, 110-119 # 9.7: 60-79 -# 9.8: 80-89 +# 9.8: 80-89, 120-129 # 9.9: 90-109 +# 9.9-sub: 130-139 LIBINTERFACE = 80 -LIBREVISION = 2 +LIBREVISION = 4 LIBAGE = 0 diff --git a/lib/irs/dnsconf.c b/lib/irs/dnsconf.c index 4a7d58b..529cebd 100644 --- a/lib/irs/dnsconf.c +++ b/lib/irs/dnsconf.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -144,8 +144,8 @@ configure_dnsseckeys(irs_dnsconf_t *conf, cfg_obj_t *cfgobj, /* Configure key name */ dns_fixedname_init(&fkeyname); keyname_base = dns_fixedname_name(&fkeyname); - isc_buffer_init(&namebuf, keynamestr, - strlen(keynamestr)); + isc_buffer_constinit(&namebuf, keynamestr, + strlen(keynamestr)); isc_buffer_add(&namebuf, strlen(keynamestr)); result = dns_name_fromtext(keyname_base, &namebuf, dns_rootname, 0, NULL); diff --git a/lib/irs/getaddrinfo.c b/lib/irs/getaddrinfo.c index 4b1f4a9..1de540f 100644 --- a/lib/irs/getaddrinfo.c +++ b/lib/irs/getaddrinfo.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2009, 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 @@ -136,6 +136,7 @@ #include <isc/lib.h> #include <isc/mem.h> #include <isc/sockaddr.h> +#include <isc/string.h> #include <isc/util.h> #include <dns/client.h> @@ -479,8 +480,10 @@ getaddrinfo(const char *hostname, const char *servname, err = (net_order[i])(hostname, flags, &ai_list, socktype, port); if (err != 0) { - if (ai_list != NULL) + if (ai_list != NULL) { freeaddrinfo(ai_list); + ai_list = NULL; + } break; } } @@ -549,7 +552,7 @@ make_resstate(isc_mem_t *mctx, gai_statehead_t *head, const char *hostname, /* Construct base domain name */ namelen = strlen(domain); - isc_buffer_init(&b, domain, namelen); + isc_buffer_constinit(&b, domain, namelen); isc_buffer_add(&b, namelen); dns_fixedname_init(&fixeddomain); qdomain = dns_fixedname_name(&fixeddomain); @@ -561,7 +564,7 @@ make_resstate(isc_mem_t *mctx, gai_statehead_t *head, const char *hostname, /* Construct query name */ namelen = strlen(hostname); - isc_buffer_init(&b, hostname, namelen); + isc_buffer_constinit(&b, hostname, namelen); isc_buffer_add(&b, namelen); dns_fixedname_init(&state->fixedname); state->qname = dns_fixedname_name(&state->fixedname); @@ -781,9 +784,9 @@ process_answer(isc_task_t *task, isc_event_t *event) { switch (family) { case AF_INET: dns_rdataset_current(rdataset, &rdata); - dns_rdata_tostruct(&rdata, &rdata_a, - NULL); - + result = dns_rdata_tostruct(&rdata, &rdata_a, + NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); SIN(ai->ai_addr)->sin_port = resstate->head->ai_port; memcpy(&SIN(ai->ai_addr)->sin_addr, @@ -792,8 +795,9 @@ process_answer(isc_task_t *task, isc_event_t *event) { break; case AF_INET6: dns_rdataset_current(rdataset, &rdata); - dns_rdata_tostruct(&rdata, &rdata_aaaa, - NULL); + result = dns_rdata_tostruct(&rdata, &rdata_aaaa, + NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); SIN6(ai->ai_addr)->sin6_port = resstate->head->ai_port; memcpy(&SIN6(ai->ai_addr)->sin6_addr, @@ -1143,10 +1147,8 @@ add_ipv6(const char *hostname, int flags, struct addrinfo **aip, UNUSED(flags); ai = ai_clone(*aip, AF_INET6); /* don't use ai_clone() */ - if (ai == NULL) { - freeaddrinfo(*aip); + if (ai == NULL) return (EAI_MEMORY); - } *aip = ai; ai->ai_socktype = socktype; @@ -1186,7 +1188,7 @@ get_local(const char *name, int socktype, struct addrinfo **res) { return (EAI_MEMORY); slocal = SLOCAL(ai->ai_addr); - strncpy(slocal->sun_path, name, sizeof(slocal->sun_path)); + strlcpy(slocal->sun_path, name, sizeof(slocal->sun_path)); ai->ai_socktype = socktype; /* diff --git a/lib/irs/getnameinfo.c b/lib/irs/getnameinfo.c index 80e3677..526ad09 100644 --- a/lib/irs/getnameinfo.c +++ b/lib/irs/getnameinfo.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -147,7 +147,7 @@ getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, IRS_GETNAMEINFO_BUFLEN_T hostlen, char *serv, IRS_GETNAMEINFO_BUFLEN_T servlen, IRS_GETNAMEINFO_FLAGS_T flags) { - struct afd *afd; + struct afd *afd = NULL; struct servent *sp; unsigned short port = 0; #ifdef IRS_PLATFORM_HAVESALEN @@ -328,6 +328,7 @@ getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, case DNS_R_NOVALIDDS: case DNS_R_NOVALIDSIG: ERR(EAI_INSECUREDATA); + break; default: ERR(EAI_FAIL); } diff --git a/lib/irs/resconf.c b/lib/irs/resconf.c index 18525e8..88bdac1 100644 --- a/lib/irs/resconf.c +++ b/lib/irs/resconf.c @@ -238,7 +238,7 @@ add_server(isc_mem_t *mctx, const char *address_str, goto cleanup; } address->length = res->ai_addrlen; - memcpy(&address->type.sa, res->ai_addr, res->ai_addrlen); + memcpy(&address->type.ss, res->ai_addr, res->ai_addrlen); ISC_LINK_INIT(address, link); ISC_LIST_APPEND(*nameservers, address, link); diff --git a/lib/isc/Makefile.in b/lib/isc/Makefile.in index ff500ff..2fa5633 100644 --- a/lib/isc/Makefile.in +++ b/lib/isc/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") +# 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 @@ -60,7 +60,8 @@ OBJS = @ISC_EXTRA_OBJS@ \ md5.@O@ mem.@O@ mutexblock.@O@ \ netaddr.@O@ netscope.@O@ ondestroy.@O@ \ parseint.@O@ portset.@O@ quota.@O@ radix.@O@ random.@O@ \ - ratelimiter.@O@ refcount.@O@ region.@O@ result.@O@ rwlock.@O@ \ + ratelimiter.@O@ refcount.@O@ region.@O@ regex.@O@ result.@O@ \ + rwlock.@O@ \ serial.@O@ sha1.@O@ sha2.@O@ sockaddr.@O@ stats.@O@ \ string.@O@ strtoul.@O@ symtab.@O@ task.@O@ taskpool.@O@ \ timer.@O@ version.@O@ ${UNIXOBJS} ${NLSOBJS} ${THREADOBJS} @@ -76,7 +77,7 @@ SRCS = @ISC_EXTRA_SRCS@ \ md5.c mem.c mutexblock.c \ netaddr.c netscope.c ondestroy.c \ parseint.c portset.c quota.c radix.c random.c \ - ratelimiter.c refcount.c region.c result.c rwlock.c \ + ratelimiter.c refcount.c region.c regex.c result.c rwlock.c \ serial.c sha1.c sha2.c sockaddr.c stats.c string.c strtoul.c \ symtab.c symtbl-empty.c task.c taskpool.c timer.c version.c diff --git a/lib/isc/api b/lib/isc/api index 18de29c..c7d2813 100644 --- a/lib/isc/api +++ b/lib/isc/api @@ -1,8 +1,9 @@ # LIBINTERFACE ranges # 9.6: 50-59, 110-119 # 9.7: 60-79 -# 9.8: 80-89 +# 9.8: 80-89, 120-129 # 9.9: 90-109 -LIBINTERFACE = 85 -LIBREVISION = 0 -LIBAGE = 1 +# 9.9-sub: 130-139 +LIBINTERFACE = 87 +LIBREVISION = 1 +LIBAGE = 3 diff --git a/lib/isc/buffer.c b/lib/isc/buffer.c index 1b59e65..e37af15 100644 --- a/lib/isc/buffer.c +++ b/lib/isc/buffer.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2008, 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 @@ -28,7 +28,7 @@ #include <isc/util.h> void -isc__buffer_init(isc_buffer_t *b, const void *base, unsigned int length) { +isc__buffer_init(isc_buffer_t *b, void *base, unsigned int length) { /* * Make 'b' refer to the 'length'-byte region starting at 'base'. * XXXDCL see the comment in buffer.h about base being const. diff --git a/lib/isc/include/isc/Makefile.in b/lib/isc/include/isc/Makefile.in index b8acdb5..8afcfa7 100644 --- a/lib/isc/include/isc/Makefile.in +++ b/lib/isc/include/isc/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004-2009, 2012 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004-2009, 2012, 2013 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 @@ -36,7 +36,7 @@ HEADERS = app.h assertions.h base64.h bind9.h bitstring.h boolean.h \ magic.h md5.h mem.h msgcat.h msgs.h mutexblock.h \ namespace.h netaddr.h ondestroy.h os.h parseint.h \ print.h quota.h radix.h random.h ratelimiter.h \ - refcount.h region.h resource.h \ + refcount.h regex.h region.h resource.h \ result.h resultclass.h rwlock.h serial.h sha1.h sha2.h \ sockaddr.h socket.h stdio.h stdlib.h string.h \ symtab.h \ diff --git a/lib/isc/include/isc/buffer.h b/lib/isc/include/isc/buffer.h index ae7e4c3..72b8560 100644 --- a/lib/isc/include/isc/buffer.h +++ b/lib/isc/include/isc/buffer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2008, 2010, 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 @@ -222,7 +222,7 @@ isc_buffer_free(isc_buffer_t **dynbuffer); */ void -isc__buffer_init(isc_buffer_t *b, const void *base, unsigned int length); +isc__buffer_init(isc_buffer_t *b, void *base, unsigned int length); /*!< * \brief Make 'b' refer to the 'length'-byte region starting at base. * @@ -681,12 +681,7 @@ ISC_LANG_ENDDECLS */ #define ISC__BUFFER_INIT(_b, _base, _length) \ do { \ - union { \ - const void * konst; \ - void * var; \ - } _u; \ - _u.konst = (_base); \ - (_b)->base = _u.var; \ + (_b)->base = _base; \ (_b)->length = (_length); \ (_b)->used = 0; \ (_b)->current = 0; \ @@ -896,6 +891,13 @@ ISC_LANG_ENDDECLS #define isc_buffer_putuint32 isc__buffer_putuint32 #endif +#define isc_buffer_constinit(_b, _d, _l) \ + do { \ + union { void *_var; const void *_const; } _deconst; \ + _deconst._const = (_d); \ + isc_buffer_init((_b), _deconst._var, (_l)); \ + } while (0) + /* * No inline method for this one (yet). */ diff --git a/lib/isc/include/isc/file.h b/lib/isc/include/isc/file.h index 38f78b7..92ea96e 100644 --- a/lib/isc/include/isc/file.h +++ b/lib/isc/include/isc/file.h @@ -115,8 +115,8 @@ isc_result_t isc_file_bopenuniquemode(char *templet, int mode, FILE **fp); /*!< * \brief Create and open a file with a unique name based on 'templet'. - * isc_file_bopen*() open the file in binary mode in Windows. - * isc_file_open*() open the file in text mode in Windows. + * isc_file_bopen*() open the file in binary mode in Windows. + * isc_file_open*() open the file in text mode in Windows. * * Notes: *\li 'template' is a reserved work in C++. If you want to complain @@ -217,6 +217,22 @@ isc_file_isplainfile(const char *name); * These occur when stat returns -1 and an errno. */ +isc_result_t +isc_file_isdirectory(const char *name); +/*!< + * \brief Check that 'name' exists and is a directory. + * + * Returns: + *\li #ISC_R_SUCCESS + * Success, file is a directory. + *\li #ISC_R_INVALIDFILE + * File is not a directory. + *\li #ISC_R_FILENOTFOUND + * File does not exist. + *\li #other ISC_R_* errors translated from errno + * These occur when stat returns -1 and an errno. + */ + isc_boolean_t isc_file_iscurrentdir(const char *filename); /*!< diff --git a/lib/isc/include/isc/list.h b/lib/isc/include/isc/list.h index 4056be2..2b174ec 100644 --- a/lib/isc/include/isc/list.h +++ b/lib/isc/include/isc/list.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2006, 2007, 2012, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1997-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -102,6 +102,8 @@ } \ (elt)->link.prev = (type *)(-1); \ (elt)->link.next = (type *)(-1); \ + ISC_INSIST((list).head != (elt)); \ + ISC_INSIST((list).tail != (elt)); \ } while (0) #define __ISC_LIST_UNLINKUNSAFE(list, elt, link) \ diff --git a/lib/isc/include/isc/mem.h b/lib/isc/include/isc/mem.h index c47ae55..317417f 100644 --- a/lib/isc/include/isc/mem.h +++ b/lib/isc/include/isc/mem.h @@ -40,15 +40,6 @@ typedef void * (*isc_memalloc_t)(void *, size_t); typedef void (*isc_memfree_t)(void *, void *); /*% - * Define ISC_MEM_DEBUG=1 to make all functions that free memory - * set the pointer being freed to NULL after being freed. - * This is the default; set ISC_MEM_DEBUG=0 to disable it. - */ -#ifndef ISC_MEM_DEBUG -#define ISC_MEM_DEBUG 1 -#endif - -/*% * Define ISC_MEM_TRACKLINES=1 to turn on detailed tracing of memory * allocation and freeing by file and line number. */ @@ -274,7 +265,6 @@ struct isc_mempool { #define ISCAPI_MPOOL_VALID(mp) ((mp) != NULL && \ (mp)->magic == ISCAPI_MPOOL_MAGIC) -#if ISC_MEM_DEBUG #define isc_mem_put(c, p, s) \ do { \ ISCMEMFUNC(put)((c), (p), (s) _ISC_MEM_FILELINE); \ @@ -295,13 +285,6 @@ struct isc_mempool { ISCMEMPOOLFUNC(put)((c), (p) _ISC_MEM_FILELINE); \ (p) = NULL; \ } while (0) -#else -#define isc_mem_put(c, p, s) ISCMEMFUNC(put)((c), (p), (s) _ISC_MEM_FILELINE) -#define isc_mem_putanddetach(c, p, s) \ - ISCMEMFUNC(putanddetach)((c), (p), (s) _ISC_MEM_FILELINE) -#define isc_mem_free(c, p) ISCMEMFUNC(free)((c), (p) _ISC_MEM_FILELINE) -#define isc_mempool_put(c, p) ISCMEMPOOLFUNC(put)((c), (p) _ISC_MEM_FILELINE) -#endif /*@{*/ isc_result_t @@ -548,7 +531,7 @@ isc_mem_gettag(isc_mem_t *ctx); */ #ifdef HAVE_LIBXML2 -void +int isc_mem_renderxml(xmlTextWriterPtr writer); /*%< * Render all contexts' statistics and status in XML for writer. diff --git a/lib/isc/include/isc/namespace.h b/lib/isc/include/isc/namespace.h index ae1801d..45b769c 100644 --- a/lib/isc/include/isc/namespace.h +++ b/lib/isc/include/isc/namespace.h @@ -70,6 +70,7 @@ #define isc_mem_isovermem isc__mem_isovermem #define isc_mem_setname isc__mem_setname #define isc_mem_setwater isc__mem_setwater +#define isc_mem_printactive isc__mem_printactive #define isc_mem_printallactive isc__mem_printallactive #define isc_mem_waterack isc__mem_waterack #define isc_mempool_create isc__mempool_create diff --git a/lib/isc/include/isc/regex.h b/lib/isc/include/isc/regex.h new file mode 100644 index 0000000..3cf6aa4 --- /dev/null +++ b/lib/isc/include/isc/regex.h @@ -0,0 +1,39 @@ +/* + * 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 ISC_REGEX_H +#define ISC_REGEX_H 1 + +/*! \file isc/regex.h */ + +#include <isc/types.h> +#include <isc/lang.h> + +ISC_LANG_BEGINDECLS + +int +isc_regex_validate(const char *expression); +/*%< + * Check a regular expression for syntactic correctness. + * + * Returns: + *\li -1 on error. + *\li the number of groups in the expression. + */ + +ISC_LANG_ENDDECLS + +#endif /* ISC_REGEX_H */ diff --git a/lib/isc/include/isc/region.h b/lib/isc/include/isc/region.h index 43d8f8f..ccca272 100644 --- a/lib/isc/include/isc/region.h +++ b/lib/isc/include/isc/region.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -23,6 +23,7 @@ /*! \file isc/region.h */ #include <isc/types.h> +#include <isc/lang.h> struct isc_region { unsigned char * base; @@ -81,12 +82,14 @@ struct isc_consttextregion { } while (0) /*@}*/ +ISC_LANG_BEGINDECLS + int isc_region_compare(isc_region_t *r1, isc_region_t *r2); /*%< - * Compares the contents of two regions + * Compares the contents of two regions * - * Requires: + * Requires: *\li 'r1' is a valid region *\li 'r2' is a valid region * @@ -96,4 +99,6 @@ isc_region_compare(isc_region_t *r1, isc_region_t *r2); *\li > 0 if r1 is lexicographically greater than r2 */ +ISC_LANG_ENDDECLS + #endif /* ISC_REGION_H */ diff --git a/lib/isc/include/isc/sockaddr.h b/lib/isc/include/isc/sockaddr.h index 1e69142..4d811dd 100644 --- a/lib/isc/include/isc/sockaddr.h +++ b/lib/isc/include/isc/sockaddr.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -34,6 +34,7 @@ struct isc_sockaddr { struct sockaddr sa; struct sockaddr_in sin; struct sockaddr_in6 sin6; + struct sockaddr_storage ss; #ifdef ISC_PLATFORM_HAVESYSUNH struct sockaddr_un sunix; #endif diff --git a/lib/isc/include/isc/socket.h b/lib/isc/include/isc/socket.h index 0df7d27..4111ec2 100644 --- a/lib/isc/include/isc/socket.h +++ b/lib/isc/include/isc/socket.h @@ -1116,7 +1116,7 @@ isc__socketmgr_maxudp(isc_socketmgr_t *mgr, int maxudp); #ifdef HAVE_LIBXML2 -void +int isc_socketmgr_renderxml(isc_socketmgr_t *mgr, xmlTextWriterPtr writer); /*%< * Render internal statistics and other state into the XML document. diff --git a/lib/isc/include/isc/task.h b/lib/isc/include/isc/task.h index 19d4783..ced7059 100644 --- a/lib/isc/include/isc/task.h +++ b/lib/isc/include/isc/task.h @@ -726,7 +726,7 @@ isc_taskmgr_excltask(isc_taskmgr_t *mgr, isc_task_t **taskp); #ifdef HAVE_LIBXML2 -void +int isc_taskmgr_renderxml(isc_taskmgr_t *mgr, xmlTextWriterPtr writer); #endif diff --git a/lib/isc/include/isc/timer.h b/lib/isc/include/isc/timer.h index fa9abb1..0598f79 100644 --- a/lib/isc/include/isc/timer.h +++ b/lib/isc/include/isc/timer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-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 @@ -108,8 +108,8 @@ typedef struct { void (*destroy)(isc_timermgr_t **managerp); isc_result_t (*timercreate)(isc_timermgr_t *manager, isc_timertype_t type, - isc_time_t *expires, - isc_interval_t *interval, + const isc_time_t *expires, + const isc_interval_t *interval, isc_task_t *task, isc_taskaction_t action, const void *arg, @@ -120,7 +120,8 @@ typedef struct { void (*attach)(isc_timer_t *timer, isc_timer_t **timerp); void (*detach)(isc_timer_t **timerp); isc_result_t (*reset)(isc_timer_t *timer, isc_timertype_t type, - isc_time_t *expires, isc_interval_t *interval, + const isc_time_t *expires, + const isc_interval_t *interval, isc_boolean_t purge); isc_result_t (*touch)(isc_timer_t *timer); } isc_timermethods_t; @@ -168,8 +169,8 @@ struct isc_timer { isc_result_t isc_timer_create(isc_timermgr_t *manager, isc_timertype_t type, - isc_time_t *expires, - isc_interval_t *interval, + const isc_time_t *expires, + const isc_interval_t *interval, isc_task_t *task, isc_taskaction_t action, const void *arg, @@ -232,8 +233,8 @@ isc_timer_create(isc_timermgr_t *manager, isc_result_t isc_timer_reset(isc_timer_t *timer, isc_timertype_t type, - isc_time_t *expires, - isc_interval_t *interval, + const isc_time_t *expires, + const isc_interval_t *interval, isc_boolean_t purge); /*%< * Change the timer's type, expires, and interval values to the given diff --git a/lib/isc/inet_aton.c b/lib/isc/inet_aton.c index 14b4887..66a108d 100644 --- a/lib/isc/inet_aton.c +++ b/lib/isc/inet_aton.c @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2004, 2005, 2007, 2008, 2012 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1996-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -91,7 +91,7 @@ static char rcsid[] = "$Id: inet_aton.c,v 1.23 2008/12/01 23:47:45 tbox Exp $"; */ int isc_net_aton(const char *cp, struct in_addr *addr) { - unsigned long val; + isc_uint32_t val; int base, n; unsigned char c; isc_uint8_t parts[4]; diff --git a/lib/isc/mem.c b/lib/isc/mem.c index 1964b7a..20fec46 100644 --- a/lib/isc/mem.c +++ b/lib/isc/mem.c @@ -202,6 +202,7 @@ struct isc__mempool { #if ! ISC_MEM_TRACKLINES #define ADD_TRACE(a, b, c, d, e) #define DELETE_TRACE(a, b, c, d, e) +#define ISC_MEMFUNC_SCOPE #else #define ADD_TRACE(a, b, c, d, e) \ do { \ @@ -321,6 +322,7 @@ isc__mem_checkdestroyed(FILE *file); ISC_MEMFUNC_SCOPE unsigned int isc__mem_references(isc_mem_t *ctx0); #endif +#endif /* ISC_MEM_TRACKLINES */ static struct isc__memmethods { isc_memmethods_t methods; @@ -389,6 +391,7 @@ static struct isc__mempoolmethods { #endif }; +#if ISC_MEM_TRACKLINES /*! * mctx must be locked. */ @@ -1478,7 +1481,12 @@ isc__mem_stats(isc_mem_t *ctx0, FILE *out) { } while (pool != NULL) { fprintf(out, "%15s %10lu %10u %10u %10u %10u %10u %10u %s\n", - pool->name, (unsigned long) pool->size, pool->maxalloc, +#if ISC_MEMPOOL_NAMES + pool->name, +#else + "(not tracked)", +#endif + (unsigned long) pool->size, pool->maxalloc, pool->allocated, pool->freecount, pool->freemax, pool->fillcount, pool->gets, (pool->lock == NULL ? "N" : "Y")); @@ -2260,16 +2268,16 @@ isc__mem_register() { #ifdef BIND9 ISC_MEMFUNC_SCOPE void isc__mem_printactive(isc_mem_t *ctx0, FILE *file) { +#if ISC_MEM_TRACKLINES isc__mem_t *ctx = (isc__mem_t *)ctx0; REQUIRE(VALID_CONTEXT(ctx)); REQUIRE(file != NULL); -#if !ISC_MEM_TRACKLINES - UNUSED(ctx); - UNUSED(file); -#else print_active(ctx, file); +#else + UNUSED(ctx0); + UNUSED(file); #endif } @@ -2295,6 +2303,9 @@ isc__mem_printallactive(FILE *file) { ISC_MEMFUNC_SCOPE void isc__mem_checkdestroyed(FILE *file) { +#if !ISC_MEM_TRACKLINES + UNUSED(file); +#endif RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS); @@ -2339,25 +2350,27 @@ typedef struct summarystat { isc_uint64_t contextsize; } summarystat_t; -static void +#define TRY0(a) do { xmlrc = (a); if (xmlrc < 0) goto error; } while(0) +static int renderctx(isc__mem_t *ctx, summarystat_t *summary, xmlTextWriterPtr writer) { + int xmlrc; + REQUIRE(VALID_CONTEXT(ctx)); - xmlTextWriterStartElement(writer, ISC_XMLCHAR "context"); + MCTXLOCK(ctx, &ctx->lock); + + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "context")); - xmlTextWriterStartElement(writer, ISC_XMLCHAR "id"); - xmlTextWriterWriteFormatString(writer, "%p", ctx); - xmlTextWriterEndElement(writer); /* id */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "id")); + TRY0(xmlTextWriterWriteFormatString(writer, "%p", ctx)); + TRY0(xmlTextWriterEndElement(writer)); /* id */ if (ctx->name[0] != 0) { - xmlTextWriterStartElement(writer, ISC_XMLCHAR "name"); - xmlTextWriterWriteFormatString(writer, "%s", ctx->name); - xmlTextWriterEndElement(writer); /* name */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name")); + TRY0(xmlTextWriterWriteFormatString(writer, "%s", ctx->name)); + TRY0(xmlTextWriterEndElement(writer)); /* name */ } - REQUIRE(VALID_CONTEXT(ctx)); - MCTXLOCK(ctx, &ctx->lock); - summary->contextsize += sizeof(*ctx) + (ctx->max_size + 1) * sizeof(struct stats) + ctx->max_size * sizeof(element *) + @@ -2369,70 +2382,79 @@ renderctx(isc__mem_t *ctx, summarystat_t *summary, xmlTextWriterPtr writer) { ctx->debuglistcnt * sizeof(debuglink_t); } #endif - xmlTextWriterStartElement(writer, ISC_XMLCHAR "references"); - xmlTextWriterWriteFormatString(writer, "%d", ctx->references); - xmlTextWriterEndElement(writer); /* references */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "references")); + TRY0(xmlTextWriterWriteFormatString(writer, "%d", ctx->references)); + TRY0(xmlTextWriterEndElement(writer)); /* references */ summary->total += ctx->total; - xmlTextWriterStartElement(writer, ISC_XMLCHAR "total"); - xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", - (isc_uint64_t)ctx->total); - xmlTextWriterEndElement(writer); /* total */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "total")); + TRY0(xmlTextWriterWriteFormatString(writer, + "%" ISC_PRINT_QUADFORMAT "u", + (isc_uint64_t)ctx->total)); + TRY0(xmlTextWriterEndElement(writer)); /* total */ summary->inuse += ctx->inuse; - xmlTextWriterStartElement(writer, ISC_XMLCHAR "inuse"); - xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", - (isc_uint64_t)ctx->inuse); - xmlTextWriterEndElement(writer); /* inuse */ - - xmlTextWriterStartElement(writer, ISC_XMLCHAR "maxinuse"); - xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", - (isc_uint64_t)ctx->maxinuse); - xmlTextWriterEndElement(writer); /* maxinuse */ - - xmlTextWriterStartElement(writer, ISC_XMLCHAR "blocksize"); + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "inuse")); + TRY0(xmlTextWriterWriteFormatString(writer, + "%" ISC_PRINT_QUADFORMAT "u", + (isc_uint64_t)ctx->inuse)); + TRY0(xmlTextWriterEndElement(writer)); /* inuse */ + + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "maxinuse")); + TRY0(xmlTextWriterWriteFormatString(writer, + "%" ISC_PRINT_QUADFORMAT "u", + (isc_uint64_t)ctx->maxinuse)); + TRY0(xmlTextWriterEndElement(writer)); /* maxinuse */ + + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "blocksize")); if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) { summary->blocksize += ctx->basic_table_count * NUM_BASIC_BLOCKS * ctx->mem_target; - xmlTextWriterWriteFormatString(writer, + TRY0(xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", (isc_uint64_t) ctx->basic_table_count * NUM_BASIC_BLOCKS * - ctx->mem_target); + ctx->mem_target)); } else - xmlTextWriterWriteFormatString(writer, "%s", "-"); - xmlTextWriterEndElement(writer); /* blocksize */ + TRY0(xmlTextWriterWriteFormatString(writer, "%s", "-")); + TRY0(xmlTextWriterEndElement(writer)); /* blocksize */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "pools"); - xmlTextWriterWriteFormatString(writer, "%u", ctx->poolcnt); - xmlTextWriterEndElement(writer); /* pools */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "pools")); + TRY0(xmlTextWriterWriteFormatString(writer, "%u", ctx->poolcnt)); + TRY0(xmlTextWriterEndElement(writer)); /* pools */ summary->contextsize += ctx->poolcnt * sizeof(isc_mempool_t); - xmlTextWriterStartElement(writer, ISC_XMLCHAR "hiwater"); - xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", - (isc_uint64_t)ctx->hi_water); - xmlTextWriterEndElement(writer); /* hiwater */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "hiwater")); + TRY0(xmlTextWriterWriteFormatString(writer, + "%" ISC_PRINT_QUADFORMAT "u", + (isc_uint64_t)ctx->hi_water)); + TRY0(xmlTextWriterEndElement(writer)); /* hiwater */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "lowater"); - xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", - (isc_uint64_t)ctx->lo_water); - xmlTextWriterEndElement(writer); /* lowater */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "lowater")); + TRY0(xmlTextWriterWriteFormatString(writer, + "%" ISC_PRINT_QUADFORMAT "u", + (isc_uint64_t)ctx->lo_water)); + TRY0(xmlTextWriterEndElement(writer)); /* lowater */ + TRY0(xmlTextWriterEndElement(writer)); /* context */ + + error: MCTXUNLOCK(ctx, &ctx->lock); - xmlTextWriterEndElement(writer); /* context */ + return (xmlrc); } -void +int isc_mem_renderxml(xmlTextWriterPtr writer) { isc__mem_t *ctx; summarystat_t summary; isc_uint64_t lost; + int xmlrc; memset(&summary, 0, sizeof(summary)); - xmlTextWriterStartElement(writer, ISC_XMLCHAR "contexts"); + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "contexts")); RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS); @@ -2441,40 +2463,51 @@ isc_mem_renderxml(xmlTextWriterPtr writer) { for (ctx = ISC_LIST_HEAD(contexts); ctx != NULL; ctx = ISC_LIST_NEXT(ctx, link)) { - renderctx(ctx, &summary, writer); + xmlrc = renderctx(ctx, &summary, writer); + if (xmlrc < 0) { + UNLOCK(&lock); + goto error; + } } UNLOCK(&lock); - xmlTextWriterEndElement(writer); /* contexts */ - - xmlTextWriterStartElement(writer, ISC_XMLCHAR "summary"); - - xmlTextWriterStartElement(writer, ISC_XMLCHAR "TotalUse"); - xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", - summary.total); - xmlTextWriterEndElement(writer); /* TotalUse */ - - xmlTextWriterStartElement(writer, ISC_XMLCHAR "InUse"); - xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", - summary.inuse); - xmlTextWriterEndElement(writer); /* InUse */ - - xmlTextWriterStartElement(writer, ISC_XMLCHAR "BlockSize"); - xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", - summary.blocksize); - xmlTextWriterEndElement(writer); /* BlockSize */ - - xmlTextWriterStartElement(writer, ISC_XMLCHAR "ContextSize"); - xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", - summary.contextsize); - xmlTextWriterEndElement(writer); /* ContextSize */ - - xmlTextWriterStartElement(writer, ISC_XMLCHAR "Lost"); - xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", - lost); - xmlTextWriterEndElement(writer); /* Lost */ - - xmlTextWriterEndElement(writer); /* summary */ + TRY0(xmlTextWriterEndElement(writer)); /* contexts */ + + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "summary")); + + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "TotalUse")); + TRY0(xmlTextWriterWriteFormatString(writer, + "%" ISC_PRINT_QUADFORMAT "u", + summary.total)); + TRY0(xmlTextWriterEndElement(writer)); /* TotalUse */ + + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "InUse")); + TRY0(xmlTextWriterWriteFormatString(writer, + "%" ISC_PRINT_QUADFORMAT "u", + summary.inuse)); + TRY0(xmlTextWriterEndElement(writer)); /* InUse */ + + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "BlockSize")); + TRY0(xmlTextWriterWriteFormatString(writer, + "%" ISC_PRINT_QUADFORMAT "u", + summary.blocksize)); + TRY0(xmlTextWriterEndElement(writer)); /* BlockSize */ + + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "ContextSize")); + TRY0(xmlTextWriterWriteFormatString(writer, + "%" ISC_PRINT_QUADFORMAT "u", + summary.contextsize)); + TRY0(xmlTextWriterEndElement(writer)); /* ContextSize */ + + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "Lost")); + TRY0(xmlTextWriterWriteFormatString(writer, + "%" ISC_PRINT_QUADFORMAT "u", + lost)); + TRY0(xmlTextWriterEndElement(writer)); /* Lost */ + + TRY0(xmlTextWriterEndElement(writer)); /* summary */ + error: + return (xmlrc); } #endif /* HAVE_LIBXML2 */ diff --git a/lib/isc/nothreads/Makefile.in b/lib/isc/nothreads/Makefile.in index 540b243..b8b5f98 100644 --- a/lib/isc/nothreads/Makefile.in +++ b/lib/isc/nothreads/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007, 2009, 2010, 2012 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2009, 2010, 2012, 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 @@ -16,8 +16,8 @@ # $Id: Makefile.in,v 1.12 2010/06/09 23:50:58 tbox Exp $ top_srcdir = @top_srcdir@ -srcdir = @top_srcdir@/lib/isc/nothreads -VPATH = @top_srcdir@/lib/isc/nothreads +srcdir = @srcdir@ +VPATH = @srcdir@ CINCLUDES = -I${srcdir}/include \ -I${srcdir}/../unix/include \ diff --git a/lib/isc/parseint.c b/lib/isc/parseint.c index 266d44c..f8ec389 100644 --- a/lib/isc/parseint.c +++ b/lib/isc/parseint.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -32,6 +32,7 @@ isc_result_t isc_parse_uint32(isc_uint32_t *uip, const char *string, int base) { unsigned long n; + isc_uint32_t r; char *e; if (! isalnum((unsigned char)(string[0]))) return (ISC_R_BADNUMBER); @@ -39,9 +40,15 @@ isc_parse_uint32(isc_uint32_t *uip, const char *string, int base) { n = strtoul(string, &e, base); if (*e != '\0') return (ISC_R_BADNUMBER); - if (n == ULONG_MAX && errno == ERANGE) + /* + * Where long is 64 bits we need to convert to 32 bits then test for + * equality. This is a no-op on 32 bit machines and a good compiler + * will optimise it away. + */ + r = (isc_uint32_t)n; + if ((n == ULONG_MAX && errno == ERANGE) || (n != (unsigned long)r)) return (ISC_R_RANGE); - *uip = n; + *uip = r; return (ISC_R_SUCCESS); } diff --git a/lib/isc/pthreads/thread.c b/lib/isc/pthreads/thread.c index 4b5b491..1b250fa 100644 --- a/lib/isc/pthreads/thread.c +++ b/lib/isc/pthreads/thread.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -25,7 +25,7 @@ #include <isc/util.h> #ifndef THREAD_MINSTACKSIZE -#define THREAD_MINSTACKSIZE (64U * 1024) +#define THREAD_MINSTACKSIZE (1024U * 1024) #endif isc_result_t diff --git a/lib/isc/ratelimiter.c b/lib/isc/ratelimiter.c index 07bcc7c..fc66e9f 100644 --- a/lib/isc/ratelimiter.c +++ b/lib/isc/ratelimiter.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 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 @@ -114,7 +114,7 @@ isc_ratelimiter_setinterval(isc_ratelimiter_t *rl, isc_interval_t *interval) { /* * If the timer is currently running, change its rate. */ - if (rl->state == isc_ratelimiter_ratelimited) { + if (rl->state == isc_ratelimiter_ratelimited) { result = isc_timer_reset(rl->timer, isc_timertype_ticker, NULL, &rl->interval, ISC_FALSE); } @@ -142,13 +142,13 @@ isc_ratelimiter_enqueue(isc_ratelimiter_t *rl, isc_task_t *task, REQUIRE(ev->ev_sender == NULL); LOCK(&rl->lock); - if (rl->state == isc_ratelimiter_ratelimited || + if (rl->state == isc_ratelimiter_ratelimited || rl->state == isc_ratelimiter_stalled) { isc_event_t *ev = *eventp; ev->ev_sender = task; - ISC_LIST_APPEND(rl->pending, ev, ev_link); + ISC_LIST_APPEND(rl->pending, ev, ev_link); *eventp = NULL; - } else if (rl->state == isc_ratelimiter_idle) { + } else if (rl->state == isc_ratelimiter_idle) { result = isc_timer_reset(rl->timer, isc_timertype_ticker, NULL, &rl->interval, ISC_FALSE); if (result == ISC_R_SUCCESS) { @@ -177,7 +177,7 @@ ratelimiter_tick(isc_task_t *task, isc_event_t *event) { isc_event_free(&event); pertic = rl->pertic; - while (pertic != 0) { + while (pertic != 0) { pertic--; LOCK(&rl->lock); p = ISC_LIST_HEAD(rl->pending); @@ -289,8 +289,9 @@ isc_ratelimiter_stall(isc_ratelimiter_t *rl) { break; case isc_ratelimiter_ratelimited: result = isc_timer_reset(rl->timer, isc_timertype_inactive, - NULL, NULL, ISC_FALSE); + NULL, NULL, ISC_FALSE); RUNTIME_CHECK(result == ISC_R_SUCCESS); + /* FALLTHROUGH */ case isc_ratelimiter_idle: case isc_ratelimiter_stalled: rl->state = isc_ratelimiter_stalled; @@ -316,7 +317,7 @@ isc_ratelimiter_release(isc_ratelimiter_t *rl) { &rl->interval, ISC_FALSE); if (result == ISC_R_SUCCESS) rl->state = isc_ratelimiter_ratelimited; - } else + } else rl->state = isc_ratelimiter_idle; break; case isc_ratelimiter_ratelimited: diff --git a/lib/isc/regex.c b/lib/isc/regex.c new file mode 100644 index 0000000..279bcdc --- /dev/null +++ b/lib/isc/regex.c @@ -0,0 +1,370 @@ +/* + * 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. + */ + +#include <config.h> + +#include <isc/file.h> +#include <isc/regex.h> +#include <isc/string.h> + +#if VALREGEX_REPORT_REASON +#define FAIL(x) do { reason = (x); goto error; } while(0) +#else +#define FAIL(x) goto error +#endif + +/* + * Validate the regular expression 'C' locale. + */ +int +isc_regex_validate(const char *c) { + enum { + none, parse_bracket, parse_bound, + parse_ce, parse_ec, parse_cc + } state = none; + /* Well known character classes. */ + const char *cc[] = { + ":alnum:", ":digit:", ":punct:", ":alpha:", ":graph:", + ":space:", ":blank:", ":lower:", ":upper:", ":cntrl:", + ":print:", ":xdigit:" + }; + isc_boolean_t seen_comma = ISC_FALSE; + isc_boolean_t seen_high = ISC_FALSE; + isc_boolean_t seen_char = ISC_FALSE; + isc_boolean_t seen_ec = ISC_FALSE; + isc_boolean_t seen_ce = ISC_FALSE; + isc_boolean_t have_atom = ISC_FALSE; + int group = 0; + int range = 0; + int sub = 0; + isc_boolean_t empty_ok = ISC_FALSE; + isc_boolean_t neg = ISC_FALSE; + isc_boolean_t was_multiple = ISC_FALSE; + unsigned int low = 0; + unsigned int high = 0; + const char *ccname = NULL; + int range_start = 0; +#if VALREGEX_REPORT_REASON + const char *reason = ""; +#endif + + if (c == NULL || *c == 0) + FAIL("empty string"); + + while (c != NULL && *c != 0) { + switch (state) { + case none: + switch (*c) { + case '\\': /* make literal */ + ++c; + switch (*c) { + case '1': case '2': case '3': + case '4': case '5': case '6': + case '7': case '8': case '9': + if ((*c - '0') > sub) + FAIL("bad back reference"); + have_atom = ISC_TRUE; + was_multiple = ISC_FALSE; + break; + case 0: + FAIL("escaped end-of-string"); + default: + goto literal; + } + ++c; + break; + case '[': /* bracket start */ + ++c; + neg = ISC_FALSE; + was_multiple = ISC_FALSE; + seen_char = ISC_FALSE; + state = parse_bracket; + break; + case '{': /* bound start */ + switch (c[1]) { + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + case '8': case '9': + if (!have_atom) + FAIL("no atom"); + if (was_multiple) + FAIL("was multiple"); + seen_comma = ISC_FALSE; + seen_high = ISC_FALSE; + low = high = 0; + state = parse_bound; + break; + default: + goto literal; + } + ++c; + have_atom = ISC_TRUE; + was_multiple = ISC_TRUE; + break; + case '}': + goto literal; + case '(': /* group start */ + have_atom = ISC_FALSE; + was_multiple = ISC_FALSE; + empty_ok = ISC_TRUE; + ++group; + ++sub; + ++c; + break; + case ')': /* group end */ + if (group && !have_atom && !empty_ok) + FAIL("empty alternative"); + have_atom = ISC_TRUE; + was_multiple = ISC_FALSE; + if (group != 0) + --group; + ++c; + break; + case '|': /* alternative seperator */ + if (!have_atom) + FAIL("no atom"); + have_atom = ISC_FALSE; + empty_ok = ISC_FALSE; + was_multiple = ISC_FALSE; + ++c; + break; + case '^': + case '$': + have_atom = ISC_TRUE; + was_multiple = ISC_TRUE; + ++c; + break; + case '+': + case '*': + case '?': + if (was_multiple) + FAIL("was multiple"); + if (!have_atom) + FAIL("no atom"); + have_atom = ISC_TRUE; + was_multiple = ISC_TRUE; + ++c; + break; + case '.': + default: + literal: + have_atom = ISC_TRUE; + was_multiple = ISC_FALSE; + ++c; + break; + } + break; + case parse_bound: + switch (*c) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + if (!seen_comma) { + low = low * 10 + *c - '0'; + if (low > 255) + FAIL("lower bound too big"); + } else { + seen_high = ISC_TRUE; + high = high * 10 + *c - '0'; + if (high > 255) + FAIL("upper bound too big"); + } + ++c; + break; + case ',': + if (seen_comma) + FAIL("multiple commas"); + seen_comma = ISC_TRUE; + ++c; + break; + default: + case '{': + FAIL("non digit/comma"); + case '}': + if (seen_high && low > high) + FAIL("bad parse bound"); + seen_comma = ISC_FALSE; + state = none; + ++c; + break; + } + break; + case parse_bracket: + switch (*c) { + case '^': + if (seen_char || neg) goto inside; + neg = ISC_TRUE; + ++c; + break; + case '-': + if (range == 2) goto inside; + if (!seen_char) goto inside; + if (range == 1) + FAIL("bad range"); + range = 2; + ++c; + break; + case '[': + ++c; + switch (*c) { + case '.': /* collating element */ + if (range) --range; + ++c; + state = parse_ce; + seen_ce = ISC_FALSE; + break; + case '=': /* equivalence class */ + if (range == 2) + FAIL("equivalence class in range"); + ++c; + state = parse_ec; + seen_ec = ISC_FALSE; + break; + case ':': /* character class */ + if (range == 2) + FAIL("character class in range"); + ccname = c; + ++c; + state = parse_cc; + break; + } + seen_char = ISC_TRUE; + break; + case ']': + if (!c[1] && !seen_char) + FAIL("unfinished brace"); + if (!seen_char) + goto inside; + ++c; + range = 0; + have_atom = ISC_TRUE; + state = none; + break; + default: + inside: + seen_char = ISC_TRUE; + if (range == 2 && *c < range_start) + FAIL("out of order range"); + if (range != 0) + --range; + range_start = *c; + ++c; + break; + }; + break; + case parse_ce: + switch (*c) { + case '.': + ++c; + switch (*c) { + case ']': + if (!seen_ce) + FAIL("empty ce"); + ++c; + state = parse_bracket; + break; + default: + if (seen_ce) + range_start = 256; + else + range_start = '.'; + seen_ce = ISC_TRUE; + break; + } + break; + default: + if (seen_ce) + range_start = 256; + else + range_start = *c; + seen_ce = ISC_TRUE; + ++c; + break; + } + break; + case parse_ec: + switch (*c) { + case '=': + ++c; + switch (*c) { + case ']': + if (!seen_ec) + FAIL("no ec"); + ++c; + state = parse_bracket; + break; + default: + seen_ec = ISC_TRUE; + break; + } + break; + default: + seen_ec = ISC_TRUE; + ++c; + break; + } + break; + case parse_cc: + switch (*c) { + case ':': + ++c; + switch (*c) { + case ']': { + unsigned int i; + isc_boolean_t found = ISC_FALSE; + for (i = 0; + i < sizeof(cc)/sizeof(*cc); + i++) + { + unsigned int len; + len = strlen(cc[i]); + if (len != + (unsigned int)(c - ccname)) + continue; + if (strncmp(cc[i], ccname, len)) + continue; + found = ISC_TRUE; + } + if (!found) + FAIL("unknown cc"); + ++c; + state = parse_bracket; + break; + } + default: + break; + } + break; + default: + ++c; + break; + } + break; + } + } + if (group != 0) + FAIL("group open"); + if (state != none) + FAIL("incomplete"); + if (!have_atom) + FAIL("no atom"); + return (sub); + + error: +#if VALREGEX_REPORT_REASON + fprintf(stderr, "%s\n", reason); +#endif + return (-1); +} diff --git a/lib/isc/sockaddr.c b/lib/isc/sockaddr.c index 7b43b8f..91a949b 100644 --- a/lib/isc/sockaddr.c +++ b/lib/isc/sockaddr.c @@ -219,13 +219,12 @@ isc_sockaddr_hash(const isc_sockaddr_t *sockaddr, isc_boolean_t address_only) { break; case AF_INET6: in6 = &sockaddr->type.sin6.sin6_addr; + s = (const unsigned char *)in6; if (IN6_IS_ADDR_V4MAPPED(in6)) { - s = (const unsigned char *)&in6[12]; + s += 12; length = sizeof(sockaddr->type.sin.sin_addr.s_addr); - } else { - s = (const unsigned char *)in6; + } else length = sizeof(sockaddr->type.sin6.sin6_addr); - } p = ntohs(sockaddr->type.sin6.sin6_port); break; default: diff --git a/lib/isc/sparc64/include/isc/atomic.h b/lib/isc/sparc64/include/isc/atomic.h index b920095..4b36661 100644 --- a/lib/isc/sparc64/include/isc/atomic.h +++ b/lib/isc/sparc64/include/isc/atomic.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005, 2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2005, 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 @@ -72,9 +72,9 @@ isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) { for (prev = *(volatile isc_int32_t *)p; ; prev = swapped) { swapped = prev + val; __asm__ volatile( - "casa [%1] %2, %3, %0" - : "+r"(swapped) - : "r"(p), "n"(ASI_P), "r"(prev)); + "casa [%2] %3, %4, %0" + : "+r"(swapped), "=m"(*p) + : "r"(p), "n"(ASI_P), "r"(prev), "m"(*p)); if (swapped == prev) break; } @@ -92,10 +92,9 @@ isc_atomic_store(isc_int32_t *p, isc_int32_t val) { for (prev = *(volatile isc_int32_t *)p; ; prev = swapped) { swapped = val; __asm__ volatile( - "casa [%1] %2, %3, %0" - : "+r"(swapped) - : "r"(p), "n"(ASI_P), "r"(prev) - : "memory"); + "casa [%2] %3, %4, %0" + : "+r"(swapped), "=m"(*p) + : "r"(p), "n"(ASI_P), "r"(prev), "m"(*p)); if (swapped == prev) break; } @@ -111,9 +110,9 @@ isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) { isc_int32_t temp = val; __asm__ volatile( - "casa [%1] %2, %3, %0" - : "+r"(temp) - : "r"(p), "n"(ASI_P), "r"(cmpval)); + "casa [%2] %3, %4, %0" + : "+r"(temp), "=m"(*p) + : "r"(p), "n"(ASI_P), "r"(cmpval), "m"(*p)); return (temp); } diff --git a/lib/isc/symtab.c b/lib/isc/symtab.c index d4c1dcc..1f294fb 100644 --- a/lib/isc/symtab.c +++ b/lib/isc/symtab.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2011-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1996-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -71,15 +71,17 @@ isc_symtab_create(isc_mem_t *mctx, unsigned int size, symtab = (isc_symtab_t *)isc_mem_get(mctx, sizeof(*symtab)); if (symtab == NULL) return (ISC_R_NOMEMORY); + + symtab->mctx = NULL; + isc_mem_attach(mctx, &symtab->mctx); symtab->table = (eltlist_t *)isc_mem_get(mctx, size * sizeof(eltlist_t)); if (symtab->table == NULL) { - isc_mem_put(mctx, symtab, sizeof(*symtab)); + isc_mem_putanddetach(&symtab->mctx, symtab, sizeof(*symtab)); return (ISC_R_NOMEMORY); } for (i = 0; i < size; i++) INIT_LIST(symtab->table[i]); - symtab->mctx = mctx; symtab->size = size; symtab->count = 0; symtab->maxload = size * 3 / 4; @@ -117,7 +119,7 @@ isc_symtab_destroy(isc_symtab_t **symtabp) { isc_mem_put(symtab->mctx, symtab->table, symtab->size * sizeof(eltlist_t)); symtab->magic = 0; - isc_mem_put(symtab->mctx, symtab, sizeof(*symtab)); + isc_mem_putanddetach(&symtab->mctx, symtab, sizeof(*symtab)); *symtabp = NULL; } diff --git a/lib/isc/task.c b/lib/isc/task.c index a5f6ef9..94f1c6d 100644 --- a/lib/isc/task.c +++ b/lib/isc/task.c @@ -1539,10 +1539,12 @@ isc_task_exiting(isc_task_t *t) { #if defined(HAVE_LIBXML2) && defined(BIND9) -void +#define TRY0(a) do { xmlrc = (a); if (xmlrc < 0) goto error; } while(0) +int isc_taskmgr_renderxml(isc_taskmgr_t *mgr0, xmlTextWriterPtr writer) { isc__taskmgr_t *mgr = (isc__taskmgr_t *)mgr0; - isc__task_t *task; + isc__task_t *task = NULL; + int xmlrc; LOCK(&mgr->lock); @@ -1550,72 +1552,82 @@ isc_taskmgr_renderxml(isc_taskmgr_t *mgr0, xmlTextWriterPtr writer) { * Write out the thread-model, and some details about each depending * on which type is enabled. */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "thread-model"); + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "thread-model")); #ifdef ISC_PLATFORM_USETHREADS - xmlTextWriterStartElement(writer, ISC_XMLCHAR "type"); - xmlTextWriterWriteString(writer, ISC_XMLCHAR "threaded"); - xmlTextWriterEndElement(writer); /* type */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "type")); + TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "threaded")); + TRY0(xmlTextWriterEndElement(writer)); /* type */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "worker-threads"); - xmlTextWriterWriteFormatString(writer, "%d", mgr->workers); - xmlTextWriterEndElement(writer); /* worker-threads */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "worker-threads")); + TRY0(xmlTextWriterWriteFormatString(writer, "%d", mgr->workers)); + TRY0(xmlTextWriterEndElement(writer)); /* worker-threads */ #else /* ISC_PLATFORM_USETHREADS */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "type"); - xmlTextWriterWriteString(writer, ISC_XMLCHAR "non-threaded"); - xmlTextWriterEndElement(writer); /* type */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "type")); + TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "non-threaded")); + TRY0(xmlTextWriterEndElement(writer)); /* type */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "references"); - xmlTextWriterWriteFormatString(writer, "%d", mgr->refs); - xmlTextWriterEndElement(writer); /* references */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "references")); + TRY0(xmlTextWriterWriteFormatString(writer, "%d", mgr->refs)); + TRY0(xmlTextWriterEndElement(writer)); /* references */ #endif /* ISC_PLATFORM_USETHREADS */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "default-quantum"); - xmlTextWriterWriteFormatString(writer, "%d", mgr->default_quantum); - xmlTextWriterEndElement(writer); /* default-quantum */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "default-quantum")); + TRY0(xmlTextWriterWriteFormatString(writer, "%d", + mgr->default_quantum)); + TRY0(xmlTextWriterEndElement(writer)); /* default-quantum */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks-running"); - xmlTextWriterWriteFormatString(writer, "%d", mgr->tasks_running); - xmlTextWriterEndElement(writer); /* tasks-running */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks-running")); + TRY0(xmlTextWriterWriteFormatString(writer, "%d", mgr->tasks_running)); + TRY0(xmlTextWriterEndElement(writer)); /* tasks-running */ - xmlTextWriterEndElement(writer); /* thread-model */ + TRY0(xmlTextWriterEndElement(writer)); /* thread-model */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks"); + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks")); task = ISC_LIST_HEAD(mgr->tasks); while (task != NULL) { LOCK(&task->lock); - xmlTextWriterStartElement(writer, ISC_XMLCHAR "task"); + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "task")); if (task->name[0] != 0) { - xmlTextWriterStartElement(writer, ISC_XMLCHAR "name"); - xmlTextWriterWriteFormatString(writer, "%s", - task->name); - xmlTextWriterEndElement(writer); /* name */ + TRY0(xmlTextWriterStartElement(writer, + ISC_XMLCHAR "name")); + TRY0(xmlTextWriterWriteFormatString(writer, "%s", + task->name)); + TRY0(xmlTextWriterEndElement(writer)); /* name */ } - xmlTextWriterStartElement(writer, ISC_XMLCHAR "references"); - xmlTextWriterWriteFormatString(writer, "%d", task->references); - xmlTextWriterEndElement(writer); /* references */ + TRY0(xmlTextWriterStartElement(writer, + ISC_XMLCHAR "references")); + TRY0(xmlTextWriterWriteFormatString(writer, "%d", + task->references)); + TRY0(xmlTextWriterEndElement(writer)); /* references */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "id"); - xmlTextWriterWriteFormatString(writer, "%p", task); - xmlTextWriterEndElement(writer); /* id */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "id")); + TRY0(xmlTextWriterWriteFormatString(writer, "%p", task)); + TRY0(xmlTextWriterEndElement(writer)); /* id */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "state"); - xmlTextWriterWriteFormatString(writer, "%s", - statenames[task->state]); - xmlTextWriterEndElement(writer); /* state */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "state")); + TRY0(xmlTextWriterWriteFormatString(writer, "%s", + statenames[task->state])); + TRY0(xmlTextWriterEndElement(writer)); /* state */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "quantum"); - xmlTextWriterWriteFormatString(writer, "%d", task->quantum); - xmlTextWriterEndElement(writer); /* quantum */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "quantum")); + TRY0(xmlTextWriterWriteFormatString(writer, "%d", + task->quantum)); + TRY0(xmlTextWriterEndElement(writer)); /* quantum */ - xmlTextWriterEndElement(writer); + TRY0(xmlTextWriterEndElement(writer)); UNLOCK(&task->lock); task = ISC_LIST_NEXT(task, link); } - xmlTextWriterEndElement(writer); /* tasks */ + TRY0(xmlTextWriterEndElement(writer)); /* tasks */ + error: + if (task != NULL) + UNLOCK(&task->lock); UNLOCK(&mgr->lock); + + return (xmlrc); } #endif /* HAVE_LIBXML2 && BIND9 */ diff --git a/lib/isc/taskpool.c b/lib/isc/taskpool.c index 936732c..7324cfa 100644 --- a/lib/isc/taskpool.c +++ b/lib/isc/taskpool.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 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 @@ -52,13 +52,15 @@ alloc_pool(isc_taskmgr_t *tmgr, isc_mem_t *mctx, unsigned int ntasks, pool = isc_mem_get(mctx, sizeof(*pool)); if (pool == NULL) return (ISC_R_NOMEMORY); - pool->mctx = mctx; + + pool->mctx = NULL; + isc_mem_attach(mctx, &pool->mctx); pool->ntasks = ntasks; pool->quantum = quantum; pool->tmgr = tmgr; pool->tasks = isc_mem_get(mctx, ntasks * sizeof(isc_task_t *)); if (pool->tasks == NULL) { - isc_mem_put(mctx, pool, sizeof(*pool)); + isc_mem_putanddetach(&pool->mctx, pool, sizeof(*pool)); return (ISC_R_NOMEMORY); } for (i = 0; i < ntasks; i++) @@ -169,7 +171,7 @@ isc_taskpool_destroy(isc_taskpool_t **poolp) { } isc_mem_put(pool->mctx, pool->tasks, pool->ntasks * sizeof(isc_task_t *)); - isc_mem_put(pool->mctx, pool, sizeof(*pool)); + isc_mem_putanddetach(&pool->mctx, pool, sizeof(*pool)); *poolp = NULL; } diff --git a/lib/isc/timer.c b/lib/isc/timer.c index 0da251f..23fcbbe 100644 --- a/lib/isc/timer.c +++ b/lib/isc/timer.c @@ -130,12 +130,12 @@ struct isc__timermgr { ISC_TIMERFUNC_SCOPE isc_result_t isc__timer_create(isc_timermgr_t *manager, isc_timertype_t type, - isc_time_t *expires, isc_interval_t *interval, + const isc_time_t *expires, const isc_interval_t *interval, isc_task_t *task, isc_taskaction_t action, const void *arg, isc_timer_t **timerp); ISC_TIMERFUNC_SCOPE isc_result_t isc__timer_reset(isc_timer_t *timer, isc_timertype_t type, - isc_time_t *expires, isc_interval_t *interval, + const isc_time_t *expires, const isc_interval_t *interval, isc_boolean_t purge); ISC_TIMERFUNC_SCOPE isc_timertype_t isc__timer_gettype(isc_timer_t *timer); @@ -392,7 +392,7 @@ destroy(isc__timer_t *timer) { ISC_TIMERFUNC_SCOPE isc_result_t isc__timer_create(isc_timermgr_t *manager0, isc_timertype_t type, - isc_time_t *expires, isc_interval_t *interval, + const isc_time_t *expires, const isc_interval_t *interval, isc_task_t *task, isc_taskaction_t action, const void *arg, isc_timer_t **timerp) { @@ -514,7 +514,7 @@ isc__timer_create(isc_timermgr_t *manager0, isc_timertype_t type, ISC_TIMERFUNC_SCOPE isc_result_t isc__timer_reset(isc_timer_t *timer0, isc_timertype_t type, - isc_time_t *expires, isc_interval_t *interval, + const isc_time_t *expires, const isc_interval_t *interval, isc_boolean_t purge) { isc__timer_t *timer = (isc__timer_t *)timer0; @@ -692,7 +692,7 @@ dispatch(isc__timermgr_t *manager, isc_time_t *now) { while (manager->nscheduled > 0 && !done) { timer = isc_heap_element(manager->heap, 1); - INSIST(timer->type != isc_timertype_inactive); + INSIST(timer != NULL && timer->type != isc_timertype_inactive); if (isc_time_compare(now, &timer->due) >= 0) { if (timer->type == isc_timertype_ticker) { type = ISC_TIMEREVENT_TICK; diff --git a/lib/isc/timer_api.c b/lib/isc/timer_api.c index 97e62b3..39b33e3 100644 --- a/lib/isc/timer_api.c +++ b/lib/isc/timer_api.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -96,7 +96,7 @@ isc_timermgr_destroy(isc_timermgr_t **managerp) { isc_result_t isc_timer_create(isc_timermgr_t *manager, isc_timertype_t type, - isc_time_t *expires, isc_interval_t *interval, + const isc_time_t *expires, const isc_interval_t *interval, isc_task_t *task, isc_taskaction_t action, const void *arg, isc_timer_t **timerp) { @@ -128,7 +128,7 @@ isc_timer_detach(isc_timer_t **timerp) { isc_result_t isc_timer_reset(isc_timer_t *timer, isc_timertype_t type, - isc_time_t *expires, isc_interval_t *interval, + const isc_time_t *expires, const isc_interval_t *interval, isc_boolean_t purge) { REQUIRE(ISCAPI_TIMER_VALID(timer)); diff --git a/lib/isc/unix/entropy.c b/lib/isc/unix/entropy.c index ab53faf..9c422b5 100644 --- a/lib/isc/unix/entropy.c +++ b/lib/isc/unix/entropy.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2008, 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 @@ -536,8 +536,7 @@ isc_entropy_createfilesource(isc_entropy_t *ent, const char *fname) { memset(&sname, 0, sizeof(sname)); sname.sun_family = AF_UNIX; - strncpy(sname.sun_path, fname, sizeof(sname.sun_path)); - sname.sun_path[sizeof(sname.sun_path)-1] = '0'; + strlcpy(sname.sun_path, fname, sizeof(sname.sun_path)); #ifdef ISC_PLATFORM_HAVESALEN #if !defined(SUN_LEN) #define SUN_LEN(su) \ diff --git a/lib/isc/unix/file.c b/lib/isc/unix/file.c index 99c02ec..7bb25d7 100644 --- a/lib/isc/unix/file.c +++ b/lib/isc/unix/file.c @@ -396,6 +396,24 @@ isc_file_isplainfile(const char *filename) { return(ISC_R_SUCCESS); } +isc_result_t +isc_file_isdirectory(const char *filename) { + /* + * This function returns success if filename exists and is a + * directory. + */ + struct stat filestat; + memset(&filestat,0,sizeof(struct stat)); + + if ((stat(filename, &filestat)) == -1) + return(isc__errno2result(errno)); + + if(! S_ISDIR(filestat.st_mode)) + return(ISC_R_INVALIDFILE); + + return(ISC_R_SUCCESS); +} + isc_boolean_t isc_file_isabsolute(const char *filename) { REQUIRE(filename != NULL); @@ -542,6 +560,9 @@ isc_file_splitpath(isc_mem_t *mctx, char *path, char **dirname, char **basename) { char *dir, *file, *slash; + if (path == NULL) + return (ISC_R_INVALIDFILE); + slash = strrchr(path, '/'); if (slash == path) { diff --git a/lib/isc/unix/include/isc/time.h b/lib/isc/unix/include/isc/time.h index dc1cef9..d81d854 100644 --- a/lib/isc/unix/include/isc/time.h +++ b/lib/isc/unix/include/isc/time.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2009, 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 @@ -41,7 +41,7 @@ struct isc_interval { unsigned int nanoseconds; }; -extern isc_interval_t *isc_interval_zero; +extern const isc_interval_t * const isc_interval_zero; ISC_LANG_BEGINDECLS @@ -85,7 +85,7 @@ struct isc_time { unsigned int nanoseconds; }; -extern isc_time_t *isc_time_epoch; +extern const isc_time_t * const isc_time_epoch; void isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds); diff --git a/lib/isc/unix/net.c b/lib/isc/unix/net.c index ea4a504..1fedbc4 100644 --- a/lib/isc/unix/net.c +++ b/lib/isc/unix/net.c @@ -301,8 +301,6 @@ try_ipv6only(void) { goto close; } - close(s); - ipv6only_result = ISC_R_SUCCESS; close: @@ -358,7 +356,6 @@ try_ipv6pktinfo(void) { goto close; } - close(s); ipv6pktinfo_result = ISC_R_SUCCESS; close: diff --git a/lib/isc/unix/socket.c b/lib/isc/unix/socket.c index 9d64a77..d007598 100644 --- a/lib/isc/unix/socket.c +++ b/lib/isc/unix/socket.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -613,7 +613,7 @@ enum { STATID_SENDFAIL = 8, STATID_RECVFAIL = 9 }; -static const isc_statscounter_t upd4statsindex[] = { +static const isc_statscounter_t udp4statsindex[] = { isc_sockstatscounter_udp4open, isc_sockstatscounter_udp4openfail, isc_sockstatscounter_udp4close, @@ -625,7 +625,7 @@ static const isc_statscounter_t upd4statsindex[] = { isc_sockstatscounter_udp4sendfail, isc_sockstatscounter_udp4recvfail }; -static const isc_statscounter_t upd6statsindex[] = { +static const isc_statscounter_t udp6statsindex[] = { isc_sockstatscounter_udp6open, isc_sockstatscounter_udp6openfail, isc_sockstatscounter_udp6close, @@ -1192,7 +1192,7 @@ process_cmsg(isc__socket_t *sock, struct msghdr *msg, isc_socketevent_t *dev) { struct in6_pktinfo *pktinfop; #endif #ifdef SO_TIMESTAMP - struct timeval *timevalp; + void *timevalp; #endif #endif @@ -1259,9 +1259,11 @@ process_cmsg(isc__socket_t *sock, struct msghdr *msg, isc_socketevent_t *dev) { #ifdef SO_TIMESTAMP if (cmsgp->cmsg_level == SOL_SOCKET && cmsgp->cmsg_type == SCM_TIMESTAMP) { - timevalp = (struct timeval *)CMSG_DATA(cmsgp); - dev->timestamp.seconds = timevalp->tv_sec; - dev->timestamp.nanoseconds = timevalp->tv_usec * 1000; + struct timeval tv; + timevalp = CMSG_DATA(cmsgp); + memcpy(&tv, timevalp, sizeof(tv)); + dev->timestamp.seconds = tv.tv_sec; + dev->timestamp.nanoseconds = tv.tv_usec * 1000; dev->attributes |= ISC_SOCKEVENTATTR_TIMESTAMP; goto next; } @@ -2052,7 +2054,7 @@ allocate_socket(isc__socketmgr_t *manager, isc_sockettype_t type, sock->sendcmsgbuf = NULL; /* - * set up cmsg buffers + * Set up cmsg buffers. */ cmsgbuflen = 0; #if defined(USE_CMSG) && defined(ISC_PLATFORM_HAVEIN6PKTINFO) @@ -2094,7 +2096,7 @@ allocate_socket(isc__socketmgr_t *manager, isc_sockettype_t type, sock->tag = NULL; /* - * set up list of readers and writers to be initially empty + * Set up list of readers and writers to be initially empty. */ ISC_LIST_INIT(sock->recv_list); ISC_LIST_INIT(sock->send_list); @@ -2109,7 +2111,7 @@ allocate_socket(isc__socketmgr_t *manager, isc_sockettype_t type, sock->bound = 0; /* - * initialize the lock + * Initialize the lock. */ result = isc_mutex_init(&sock->lock); if (result != ISC_R_SUCCESS) { @@ -2119,7 +2121,7 @@ allocate_socket(isc__socketmgr_t *manager, isc_sockettype_t type, } /* - * Initialize readable and writable events + * Initialize readable and writable events. */ ISC_EVENT_INIT(&sock->readable_ev, sizeof(intev_t), ISC_EVENTATTR_NOPURGE, NULL, ISC_SOCKEVENT_INTR, @@ -2223,13 +2225,38 @@ clear_bsdcompat(void) { } #endif +static void +use_min_mtu(isc__socket_t *sock) { +#if !defined(IPV6_USE_MIN_MTU) && !defined(IPV6_MTU) + UNUSED(sock); +#endif +#ifdef IPV6_USE_MIN_MTU + /* use minimum MTU */ + if (sock->pf == AF_INET6) { + int on = 1; + (void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_USE_MIN_MTU, + (void *)&on, sizeof(on)); + } +#endif +#if defined(IPV6_MTU) + /* + * Use minimum MTU on IPv6 sockets. + */ + if (sock->pf == AF_INET6) { + int mtu = 1280; + (void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_MTU, + &mtu, sizeof(mtu)); + } +#endif +} + static isc_result_t opensocket(isc__socketmgr_t *manager, isc__socket_t *sock) { isc_result_t result; char strbuf[ISC_STRERRORSIZE]; const char *err = "socket"; int tries = 0; -#if defined(USE_CMSG) || defined(SO_BSDCOMPAT) +#if defined(USE_CMSG) || defined(SO_BSDCOMPAT) || defined(SO_NOSIGPIPE) int on = 1; #endif #if defined(SO_RCVBUF) @@ -2367,6 +2394,11 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock) { } #endif + /* + * Use minimum mtu if possible. + */ + use_min_mtu(sock); + #if defined(USE_CMSG) || defined(SO_RCVBUF) if (sock->type == isc_sockettype_udp) { @@ -2431,32 +2463,6 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock) { } #endif /* IPV6_RECVPKTINFO */ #endif /* ISC_PLATFORM_HAVEIN6PKTINFO */ -#ifdef IPV6_USE_MIN_MTU /* RFC 3542, not too common yet*/ - /* use minimum MTU */ - if (sock->pf == AF_INET6 && - setsockopt(sock->fd, IPPROTO_IPV6, IPV6_USE_MIN_MTU, - (void *)&on, sizeof(on)) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "setsockopt(%d, IPV6_USE_MIN_MTU) " - "%s: %s", sock->fd, - isc_msgcat_get(isc_msgcat, - ISC_MSGSET_GENERAL, - ISC_MSG_FAILED, - "failed"), - strbuf); - } -#endif -#if defined(IPV6_MTU) - /* - * Use minimum MTU on IPv6 sockets. - */ - if (sock->pf == AF_INET6) { - int mtu = 1280; - (void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_MTU, - &mtu, sizeof(mtu)); - } -#endif #if defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DONT) /* * Turn off Path MTU discovery on IPv6/UDP sockets. @@ -2546,7 +2552,7 @@ isc__socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type, switch (sock->type) { case isc_sockettype_udp: sock->statsindex = - (pf == AF_INET) ? upd4statsindex : upd6statsindex; + (pf == AF_INET) ? udp4statsindex : udp6statsindex; break; case isc_sockettype_tcp: sock->statsindex = @@ -3209,23 +3215,27 @@ internal_accept(isc_task_t *me, isc_event_t *ev) { if (fd != -1) { int lockid = FDLOCK_ID(fd); - LOCK(&manager->fdlock[lockid]); - manager->fds[fd] = NEWCONNSOCK(dev); - manager->fdstate[fd] = MANAGED; - UNLOCK(&manager->fdlock[lockid]); - - LOCK(&manager->lock); - ISC_LIST_APPEND(manager->socklist, NEWCONNSOCK(dev), link); - NEWCONNSOCK(dev)->fd = fd; NEWCONNSOCK(dev)->bound = 1; NEWCONNSOCK(dev)->connected = 1; /* + * Use minimum mtu if possible. + */ + use_min_mtu(NEWCONNSOCK(dev)); + + /* * Save away the remote address */ dev->address = NEWCONNSOCK(dev)->peer_address; + LOCK(&manager->fdlock[lockid]); + manager->fds[fd] = NEWCONNSOCK(dev); + manager->fdstate[fd] = MANAGED; + UNLOCK(&manager->fdlock[lockid]); + + LOCK(&manager->lock); + #ifdef USE_SELECT if (manager->maxfd < fd) manager->maxfd = fd; @@ -3236,6 +3246,8 @@ internal_accept(isc_task_t *me, isc_event_t *ev) { "accepted connection, new socket %p", dev->newsocket); + ISC_LIST_APPEND(manager->socklist, NEWCONNSOCK(dev), link); + UNLOCK(&manager->lock); inc_stats(manager->stats, sock->statsindex[STATID_ACCEPT]); @@ -5851,94 +5863,112 @@ _socktype(isc_sockettype_t type) return ("not-initialized"); } -ISC_SOCKETFUNC_SCOPE void +#define TRY0(a) do { xmlrc = (a); if (xmlrc < 0) goto error; } while(0) +ISC_SOCKETFUNC_SCOPE int isc_socketmgr_renderxml(isc_socketmgr_t *mgr0, xmlTextWriterPtr writer) { isc__socketmgr_t *mgr = (isc__socketmgr_t *)mgr0; - isc__socket_t *sock; + isc__socket_t *sock = NULL; char peerbuf[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_t addr; ISC_SOCKADDR_LEN_T len; + int xmlrc; LOCK(&mgr->lock); #ifdef USE_SHARED_MANAGER - xmlTextWriterStartElement(writer, ISC_XMLCHAR "references"); - xmlTextWriterWriteFormatString(writer, "%d", mgr->refs); - xmlTextWriterEndElement(writer); + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "references")); + TRY0(xmlTextWriterWriteFormatString(writer, "%d", mgr->refs)); + TRY0(xmlTextWriterEndElement(writer)); #endif /* USE_SHARED_MANAGER */ - xmlTextWriterStartElement(writer, ISC_XMLCHAR "sockets"); + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "sockets")); sock = ISC_LIST_HEAD(mgr->socklist); while (sock != NULL) { LOCK(&sock->lock); - xmlTextWriterStartElement(writer, ISC_XMLCHAR "socket"); + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "socket")); - xmlTextWriterStartElement(writer, ISC_XMLCHAR "id"); - xmlTextWriterWriteFormatString(writer, "%p", sock); - xmlTextWriterEndElement(writer); + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "id")); + TRY0(xmlTextWriterWriteFormatString(writer, "%p", sock)); + TRY0(xmlTextWriterEndElement(writer)); if (sock->name[0] != 0) { - xmlTextWriterStartElement(writer, ISC_XMLCHAR "name"); - xmlTextWriterWriteFormatString(writer, "%s", - sock->name); - xmlTextWriterEndElement(writer); /* name */ + TRY0(xmlTextWriterStartElement(writer, + ISC_XMLCHAR "name")); + TRY0(xmlTextWriterWriteFormatString(writer, "%s", + sock->name)); + TRY0(xmlTextWriterEndElement(writer)); /* name */ } - xmlTextWriterStartElement(writer, ISC_XMLCHAR "references"); - xmlTextWriterWriteFormatString(writer, "%d", sock->references); - xmlTextWriterEndElement(writer); + TRY0(xmlTextWriterStartElement(writer, + ISC_XMLCHAR "references")); + TRY0(xmlTextWriterWriteFormatString(writer, "%d", + sock->references)); + TRY0(xmlTextWriterEndElement(writer)); - xmlTextWriterWriteElement(writer, ISC_XMLCHAR "type", - ISC_XMLCHAR _socktype(sock->type)); + TRY0(xmlTextWriterWriteElement(writer, ISC_XMLCHAR "type", + ISC_XMLCHAR _socktype(sock->type))); if (sock->connected) { isc_sockaddr_format(&sock->peer_address, peerbuf, sizeof(peerbuf)); - xmlTextWriterWriteElement(writer, + TRY0(xmlTextWriterWriteElement(writer, ISC_XMLCHAR "peer-address", - ISC_XMLCHAR peerbuf); + ISC_XMLCHAR peerbuf)); } len = sizeof(addr); if (getsockname(sock->fd, &addr.type.sa, (void *)&len) == 0) { isc_sockaddr_format(&addr, peerbuf, sizeof(peerbuf)); - xmlTextWriterWriteElement(writer, + TRY0(xmlTextWriterWriteElement(writer, ISC_XMLCHAR "local-address", - ISC_XMLCHAR peerbuf); + ISC_XMLCHAR peerbuf)); } - xmlTextWriterStartElement(writer, ISC_XMLCHAR "states"); + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "states")); if (sock->pending_recv) - xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state", - ISC_XMLCHAR "pending-receive"); + TRY0(xmlTextWriterWriteElement(writer, + ISC_XMLCHAR "state", + ISC_XMLCHAR "pending-receive")); if (sock->pending_send) - xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state", - ISC_XMLCHAR "pending-send"); + TRY0(xmlTextWriterWriteElement(writer, + ISC_XMLCHAR "state", + ISC_XMLCHAR "pending-send")); if (sock->pending_accept) - xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state", - ISC_XMLCHAR "pending_accept"); + TRY0(xmlTextWriterWriteElement(writer, + ISC_XMLCHAR "state", + ISC_XMLCHAR "pending_accept")); if (sock->listener) - xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state", - ISC_XMLCHAR "listener"); + TRY0(xmlTextWriterWriteElement(writer, + ISC_XMLCHAR "state", + ISC_XMLCHAR "listener")); if (sock->connected) - xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state", - ISC_XMLCHAR "connected"); + TRY0(xmlTextWriterWriteElement(writer, + ISC_XMLCHAR "state", + ISC_XMLCHAR "connected")); if (sock->connecting) - xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state", - ISC_XMLCHAR "connecting"); + TRY0(xmlTextWriterWriteElement(writer, + ISC_XMLCHAR "state", + ISC_XMLCHAR "connecting")); if (sock->bound) - xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state", - ISC_XMLCHAR "bound"); + TRY0(xmlTextWriterWriteElement(writer, + ISC_XMLCHAR "state", + ISC_XMLCHAR "bound")); - xmlTextWriterEndElement(writer); /* states */ + TRY0(xmlTextWriterEndElement(writer)); /* states */ - xmlTextWriterEndElement(writer); /* socket */ + TRY0(xmlTextWriterEndElement(writer)); /* socket */ UNLOCK(&sock->lock); sock = ISC_LIST_NEXT(sock, link); } - xmlTextWriterEndElement(writer); /* sockets */ + TRY0(xmlTextWriterEndElement(writer)); /* sockets */ + + error: + if (sock != NULL) + UNLOCK(&sock->lock); UNLOCK(&mgr->lock); + + return (xmlrc); } #endif /* HAVE_LIBXML2 */ diff --git a/lib/isc/unix/time.c b/lib/isc/unix/time.c index ac23ae0..e820afb 100644 --- a/lib/isc/unix/time.c +++ b/lib/isc/unix/time.c @@ -54,8 +54,8 @@ *** Intervals ***/ -static isc_interval_t zero_interval = { 0, 0 }; -isc_interval_t *isc_interval_zero = &zero_interval; +static const isc_interval_t zero_interval = { 0, 0 }; +const isc_interval_t * const isc_interval_zero = &zero_interval; #if ISC_FIX_TV_USEC static inline void @@ -110,8 +110,8 @@ isc_interval_iszero(const isc_interval_t *i) { *** Absolute Times ***/ -static isc_time_t epoch = { 0, 0 }; -isc_time_t *isc_time_epoch = &epoch; +static const isc_time_t epoch = { 0, 0 }; +const isc_time_t * const isc_time_epoch = &epoch; void isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds) { diff --git a/lib/isccc/api b/lib/isccc/api index ba19dd9..461b9ac 100644 --- a/lib/isccc/api +++ b/lib/isccc/api @@ -1,8 +1,9 @@ # LIBINTERFACE ranges # 9.6: 50-59, 110-119 # 9.7: 60-79 -# 9.8: 80-89 +# 9.8: 80-89, 120-129 # 9.9: 90-109 +# 9.9-sub: 130-139 LIBINTERFACE = 80 -LIBREVISION = 2 +LIBREVISION = 3 LIBAGE = 0 diff --git a/lib/isccc/cc.c b/lib/isccc/cc.c index 1ab9479..07f8157 100644 --- a/lib/isccc/cc.c +++ b/lib/isccc/cc.c @@ -561,8 +561,10 @@ isccc_cc_createack(isccc_sexpr_t *message, isc_boolean_t ok, return (result); _ctrl = isccc_alist_lookup(ack, "_ctrl"); - if (_ctrl == NULL) - return (ISC_R_FAILURE); + if (_ctrl == NULL) { + result = ISC_R_FAILURE; + goto bad; + } if (isccc_cc_definestring(ack, "_ack", (ok) ? "1" : "0") == NULL) { result = ISC_R_NOMEMORY; goto bad; @@ -608,7 +610,7 @@ isc_result_t isccc_cc_createresponse(isccc_sexpr_t *message, isccc_time_t now, isccc_time_t expires, isccc_sexpr_t **alistp) { - char *_frm, *_to, *type; + char *_frm, *_to, *type = NULL; isc_uint32_t serial; isccc_sexpr_t *alist, *_ctrl, *_data; isc_result_t result; @@ -617,8 +619,7 @@ isccc_cc_createresponse(isccc_sexpr_t *message, isccc_time_t now, _ctrl = isccc_alist_lookup(message, "_ctrl"); _data = isccc_alist_lookup(message, "_data"); - if (_ctrl == NULL || - _data == NULL || + if (_ctrl == NULL || _data == NULL || isccc_cc_lookupuint32(_ctrl, "_ser", &serial) != ISC_R_SUCCESS || isccc_cc_lookupstring(_data, "type", &type) != ISC_R_SUCCESS) return (ISC_R_FAILURE); @@ -637,21 +638,33 @@ isccc_cc_createresponse(isccc_sexpr_t *message, isccc_time_t now, &alist); if (result != ISC_R_SUCCESS) return (result); + _ctrl = isccc_alist_lookup(alist, "_ctrl"); - if (_ctrl == NULL) - return (ISC_R_FAILURE); + if (_ctrl == NULL) { + result = ISC_R_FAILURE; + goto bad; + } + _data = isccc_alist_lookup(alist, "_data"); - if (_data == NULL) - return (ISC_R_FAILURE); + if (_data == NULL) { + result = ISC_R_FAILURE; + goto bad; + } + if (isccc_cc_definestring(_ctrl, "_rpl", "1") == NULL || - isccc_cc_definestring(_data, "type", type) == NULL) { - isccc_sexpr_free(&alist); - return (ISC_R_NOMEMORY); + isccc_cc_definestring(_data, "type", type) == NULL) + { + result = ISC_R_NOMEMORY; + goto bad; } *alistp = alist; return (ISC_R_SUCCESS); + + bad: + isccc_sexpr_free(&alist); + return (result); } isccc_sexpr_t * @@ -687,6 +700,8 @@ isccc_cc_lookupstring(isccc_sexpr_t *alist, const char *key, char **strp) { isccc_sexpr_t *kv, *v; + REQUIRE(strp == NULL || *strp == NULL); + kv = isccc_alist_assq(alist, key); if (kv != NULL) { v = ISCCC_SEXPR_CDR(kv); @@ -785,7 +800,7 @@ isccc_cc_checkdup(isccc_symtab_t *symtab, isccc_sexpr_t *message, { const char *_frm; const char *_to; - char *_ser, *_tim, *tmp; + char *_ser = NULL, *_tim = NULL, *tmp; isc_result_t result; char *key; size_t len; @@ -797,13 +812,19 @@ isccc_cc_checkdup(isccc_symtab_t *symtab, isccc_sexpr_t *message, isccc_cc_lookupstring(_ctrl, "_ser", &_ser) != ISC_R_SUCCESS || isccc_cc_lookupstring(_ctrl, "_tim", &_tim) != ISC_R_SUCCESS) return (ISC_R_FAILURE); + + INSIST(_ser != NULL); + INSIST(_tim != NULL); + /* * _frm and _to are optional. */ + tmp = NULL; if (isccc_cc_lookupstring(_ctrl, "_frm", &tmp) != ISC_R_SUCCESS) _frm = ""; else _frm = tmp; + tmp = NULL; if (isccc_cc_lookupstring(_ctrl, "_to", &tmp) != ISC_R_SUCCESS) _to = ""; else diff --git a/lib/isccfg/Makefile.in b/lib/isccfg/Makefile.in index bc42880..19ec61e 100644 --- a/lib/isccfg/Makefile.in +++ b/lib/isccfg/Makefile.in @@ -68,7 +68,8 @@ libisccfg.la: ${OBJS} ${LIBTOOL_MODE_LINK} \ ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libisccfg.la -rpath ${libdir} \ -version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \ - ${OBJS} ${DNSLIBS} ${ISCCCLIBS} ${ISCLIBS} ${LIBS} + ${OBJS} ${DNSLIBS} ${ISCCCLIBS} ${ISCLIBS} @DNS_CRYPTO_LIBS@ \ + ${LIBS} timestamp: libisccfg.@A@ touch timestamp diff --git a/lib/isccfg/aclconf.c b/lib/isccfg/aclconf.c index 469989a..af56599 100644 --- a/lib/isccfg/aclconf.c +++ b/lib/isccfg/aclconf.c @@ -192,7 +192,7 @@ convert_keyname(const cfg_obj_t *keyobj, isc_log_t *lctx, isc_mem_t *mctx, const char *txtname = cfg_obj_asstring(keyobj); keylen = strlen(txtname); - isc_buffer_init(&buf, txtname, keylen); + isc_buffer_constinit(&buf, txtname, keylen); isc_buffer_add(&buf, keylen); dns_fixedname_init(&fixname); result = dns_name_fromtext(dns_fixedname_name(&fixname), &buf, diff --git a/lib/isccfg/api b/lib/isccfg/api index cde1e2f..39585b0 100644 --- a/lib/isccfg/api +++ b/lib/isccfg/api @@ -1,8 +1,9 @@ # LIBINTERFACE ranges # 9.6: 50-59, 110-119 # 9.7: 60-79 -# 9.8: 80-89 +# 9.8: 80-89, 120-129 # 9.9: 90-109 +# 9.9-sub: 130-139 LIBINTERFACE = 82 -LIBREVISION = 3 +LIBREVISION = 7 LIBAGE = 0 diff --git a/lib/isccfg/include/isccfg/cfg.h b/lib/isccfg/include/isccfg/cfg.h index f467768..b21a3d8 100644 --- a/lib/isccfg/include/isccfg/cfg.h +++ b/lib/isccfg/include/isccfg/cfg.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007, 2010 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2010, 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 @@ -411,6 +411,10 @@ cfg_obj_destroy(cfg_parser_t *pctx, cfg_obj_t **obj); /*%< * Delete a reference to a configuration object; destroy the object if * there are no more references. + * + * Require: + * \li '*obj' is a valid cfg_obj_t. + * \li 'pctx' is a valid cfg_parser_t. */ void diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index 4d09f11..287ce14 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2002, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -526,6 +526,12 @@ static cfg_type_t cfg_type_checkmode = { &cfg_rep_string, &checkmode_enums }; +static const char *warn_enums[] = { "warn", "ignore", NULL }; +static cfg_type_t cfg_type_warn = { + "warn", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, + &cfg_rep_string, &warn_enums +}; + static cfg_tuplefielddef_t checknames_fields[] = { { "type", &cfg_type_checktype, 0 }, { "mode", &cfg_type_checkmode, 0 }, @@ -1018,10 +1024,9 @@ static cfg_type_t cfg_type_masterformat = { * response-policy { * zone <string> [ policy (given|disabled|passthru| * nxdomain|nodata|cname <domain> ) ] - * [ recursive-only yes|no ] - * [ max-policy-ttl number ] ; - * } [ recursive-only yes|no ] [ break-dnssec yes|no ] - * [ max-policy-ttl number ] ; + * [ recursive-only yes|no ] [ max-policy-ttl number ] ; + * } [ recursive-only yes|no ] [ max-policy-ttl number ] ; + * [ break-dnssec yes|no ] [ min-ns-dots number ] ; */ static void @@ -1223,6 +1228,7 @@ static cfg_tuplefielddef_t rpz_fields[] = { { "recursive-only", &cfg_type_boolean, 0 }, { "break-dnssec", &cfg_type_boolean, 0 }, { "max-policy-ttl", &cfg_type_uint32, 0 }, + { "min-ns-dots", &cfg_type_uint32, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_rpz = { @@ -1461,6 +1467,7 @@ zone_clauses[] = { { "check-mx", &cfg_type_checkmode, 0 }, { "check-mx-cname", &cfg_type_checkmode, 0 }, { "check-sibling", &cfg_type_boolean, 0 }, + { "check-spf", &cfg_type_warn, 0 }, { "check-srv-cname", &cfg_type_checkmode, 0 }, { "check-wildcard", &cfg_type_boolean, 0 }, { "dialup", &cfg_type_dialuptype, 0 }, diff --git a/lib/isccfg/parser.c b/lib/isccfg/parser.c index ef20184..de0fa31 100644 --- a/lib/isccfg/parser.c +++ b/lib/isccfg/parser.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * 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 @@ -387,13 +387,15 @@ cfg_parser_create(isc_mem_t *mctx, isc_log_t *lctx, cfg_parser_t **ret) { if (pctx == NULL) return (ISC_R_NOMEMORY); + pctx->mctx = NULL; + isc_mem_attach(mctx, &pctx->mctx); + result = isc_refcount_init(&pctx->references, 1); if (result != ISC_R_SUCCESS) { - isc_mem_put(mctx, pctx, sizeof(*pctx)); + isc_mem_putanddetach(&pctx->mctx, pctx, sizeof(*pctx)); return (result); } - pctx->mctx = mctx; pctx->lctx = lctx; pctx->lexer = NULL; pctx->seen_eof = ISC_FALSE; @@ -434,7 +436,7 @@ cfg_parser_create(isc_mem_t *mctx, isc_log_t *lctx, cfg_parser_t **ret) { isc_lex_destroy(&pctx->lexer); CLEANUP_OBJ(pctx->open_files); CLEANUP_OBJ(pctx->closed_files); - isc_mem_put(mctx, pctx, sizeof(*pctx)); + isc_mem_putanddetach(&pctx->mctx, pctx, sizeof(*pctx)); return (result); } @@ -555,7 +557,7 @@ cfg_parser_destroy(cfg_parser_t **pctxp) { */ CLEANUP_OBJ(pctx->open_files); CLEANUP_OBJ(pctx->closed_files); - isc_mem_put(pctx->mctx, pctx, sizeof(*pctx)); + isc_mem_putanddetach(&pctx->mctx, pctx, sizeof(*pctx)); } *pctxp = NULL; } @@ -2426,9 +2428,14 @@ cfg_obj_istype(const cfg_obj_t *obj, const cfg_type_t *type) { */ void cfg_obj_destroy(cfg_parser_t *pctx, cfg_obj_t **objp) { - cfg_obj_t *obj = *objp; + cfg_obj_t *obj; unsigned int refs; + REQUIRE(objp != NULL && *objp != NULL); + REQUIRE(pctx != NULL); + + obj = *objp; + isc_refcount_decrement(&obj->references, &refs); if (refs == 0) { obj->type->rep->free(pctx, obj); diff --git a/lib/lwres/api b/lib/lwres/api index 1e51baa..2a5c388 100644 --- a/lib/lwres/api +++ b/lib/lwres/api @@ -1,8 +1,9 @@ # LIBINTERFACE ranges # 9.6: 50-59, 110-119 # 9.7: 60-79 -# 9.8: 80-89 +# 9.8: 80-89, 120-129 # 9.9: 90-109 +# 9.9-sub: 130-139 LIBINTERFACE = 80 -LIBREVISION = 3 +LIBREVISION = 6 LIBAGE = 0 diff --git a/lib/lwres/context.c b/lib/lwres/context.c index 64bdaa1..047707f 100644 --- a/lib/lwres/context.c +++ b/lib/lwres/context.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007-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 @@ -377,6 +377,7 @@ lwres_context_send(lwres_context_t *ctx, lwresult = context_connect(ctx); if (lwresult != LWRES_R_SUCCESS) return (lwresult); + INSIST(ctx->sock >= 0); } ret = sendto(ctx->sock, sendbase, sendlen, 0, NULL, 0); diff --git a/lib/lwres/getaddrinfo.c b/lib/lwres/getaddrinfo.c index 811a2fe..7d5f2fb 100644 --- a/lib/lwres/getaddrinfo.c +++ b/lib/lwres/getaddrinfo.c @@ -573,10 +573,8 @@ add_ipv4(const char *hostname, int flags, struct addrinfo **aip, (void) lwres_conf_parse(lwrctx, lwres_resolv_conf); if (hostname == NULL && (flags & AI_PASSIVE) == 0) { ai = ai_clone(*aip, AF_INET); - if (ai == NULL) { - lwres_freeaddrinfo(*aip); + if (ai == NULL) SETERROR(EAI_MEMORY); - } *aip = ai; ai->ai_socktype = socktype; @@ -594,10 +592,8 @@ add_ipv4(const char *hostname, int flags, struct addrinfo **aip, addr = LWRES_LIST_HEAD(by->addrs); while (addr != NULL) { ai = ai_clone(*aip, AF_INET); - if (ai == NULL) { - lwres_freeaddrinfo(*aip); + if (ai == NULL) SETERROR(EAI_MEMORY); - } *aip = ai; ai->ai_socktype = socktype; SIN(ai->ai_addr)->sin_port = port; @@ -641,10 +637,8 @@ add_ipv6(const char *hostname, int flags, struct addrinfo **aip, if (hostname == NULL && (flags & AI_PASSIVE) == 0) { ai = ai_clone(*aip, AF_INET6); - if (ai == NULL) { - lwres_freeaddrinfo(*aip); + if (ai == NULL) SETERROR(EAI_MEMORY); - } *aip = ai; ai->ai_socktype = socktype; @@ -662,10 +656,8 @@ add_ipv6(const char *hostname, int flags, struct addrinfo **aip, addr = LWRES_LIST_HEAD(by->addrs); while (addr != NULL) { ai = ai_clone(*aip, AF_INET6); - if (ai == NULL) { - lwres_freeaddrinfo(*aip); + if (ai == NULL) SETERROR(EAI_MEMORY); - } *aip = ai; ai->ai_socktype = socktype; SIN6(ai->ai_addr)->sin6_port = port; diff --git a/lib/lwres/getipnode.c b/lib/lwres/getipnode.c index 3bd8217..300376e 100644 --- a/lib/lwres/getipnode.c +++ b/lib/lwres/getipnode.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2009, 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 @@ -466,6 +466,9 @@ lwres_freehostent(struct hostent *he) { int names = 1; int addresses = 1; + if (he == NULL) + return; + free(he->h_name); cpp = he->h_addr_list; @@ -950,8 +953,9 @@ copyandmerge(struct hostent *he1, struct hostent *he2, int af, int *error_num) * Copy aliases. */ npp = he->h_aliases; - cpp = (he1 != NULL) ? he1->h_aliases : he2->h_aliases; - while (*cpp != NULL) { + cpp = (he1 != NULL) ? he1->h_aliases + : ((he2 != NULL) ? he2->h_aliases : NULL); + while (cpp != NULL && *cpp != NULL) { len = strlen (*cpp) + 1; *npp = malloc(len); if (*npp == NULL) @@ -1115,6 +1119,8 @@ hostfromname(lwres_gabnresponse_t *name, int af) { * Copy aliases. */ he->h_aliases = malloc(sizeof(char *) * (name->naliases + 1)); + if (he->h_aliases == NULL) + goto cleanup; for (i = 0; i < name->naliases; i++) { he->h_aliases[i] = strdup(name->aliases[i]); if (he->h_aliases[i] == NULL) @@ -1126,6 +1132,8 @@ hostfromname(lwres_gabnresponse_t *name, int af) { * Copy addresses. */ he->h_addr_list = malloc(sizeof(char *) * (name->naddrs + 1)); + if (he->h_addr_list == NULL) + goto cleanup; addr = LWRES_LIST_HEAD(name->addrs); i = 0; while (addr != NULL) { diff --git a/lib/lwres/getnameinfo.c b/lib/lwres/getnameinfo.c index 92a34a1..08ebf93 100644 --- a/lib/lwres/getnameinfo.c +++ b/lib/lwres/getnameinfo.c @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2004, 2005, 2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2004, 2005, 2007, 2011-2013 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -161,7 +161,7 @@ int lwres_getnameinfo(const struct sockaddr *sa, size_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags) { - struct afd *afd; + struct afd *afd = NULL; struct servent *sp; unsigned short port; #ifdef LWRES_PLATFORM_HAVESALEN diff --git a/lib/lwres/getrrset.c b/lib/lwres/getrrset.c index d8b6cc3..16af741 100644 --- a/lib/lwres/getrrset.c +++ b/lib/lwres/getrrset.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 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 @@ -21,12 +21,12 @@ /** * DESCRIPTION - * + * * lwres_getrrsetbyname() gets a set of resource records associated with * a hostname, class, and type. hostname is a pointer a to * null-terminated string. The flags field is currently unused and must * be zero. - * + * * After a successful call to lwres_getrrsetbyname(), *res is a pointer * to an #rrsetinfo structure, containing a list of one or more #rdatainfo * structures containing resource records and potentially another list of @@ -37,7 +37,7 @@ * in uncompressed DNS wire format. Properties of the rdataset are * represented in the #rri_flags bitfield. If the #RRSET_VALIDATED bit is * set, the data has been DNSSEC validated and the signatures verified. - * + * * All of the information returned by lwres_getrrsetbyname() is * dynamically allocated: the rrsetinfo and rdatainfo structures, and the * canonical host name strings pointed to by the rrsetinfostructure. @@ -45,15 +45,15 @@ * successful call to lwres_getrrsetbyname() is released by * lwres_freerrset(). rrset is a pointer to a struct rrset created by a * call to lwres_getrrsetbyname(). - * + * * The following structures are used: - * + * * \code * struct rdatainfo { * unsigned int rdi_length; // length of data * unsigned char *rdi_data; // record data * }; - * + * * struct rrsetinfo { * unsigned int rri_flags; // RRSET_VALIDATED... * unsigned int rri_rdclass; // class number @@ -66,23 +66,23 @@ * struct rdatainfo *rri_sigs; // individual signatures * }; * \endcode - * + * * \section getrrset_return Return Values - * + * * lwres_getrrsetbyname() returns zero on success, and one of the * following error codes if an error occurred: - * + * * \li #ERRSET_NONAME: the name does not exist - * + * * \li #ERRSET_NODATA: * the name exists, but does not have data of the desired type - * + * * \li #ERRSET_NOMEMORY: * memory could not be allocated - * + * * \li #ERRSET_INVAL: * a parameter is invalid - * + * * \li #ERRSET_FAIL: * other failure */ @@ -179,7 +179,7 @@ lwres_getrrsetbyname(const char *hostname, unsigned int rdclass, lwflags = 0; lwresult = lwres_getrdatabyname(lwrctx, hostname, - (lwres_uint16_t)rdclass, + (lwres_uint16_t)rdclass, (lwres_uint16_t)rdtype, lwflags, &response); if (lwresult != LWRES_R_SUCCESS) { @@ -271,18 +271,22 @@ lwres_getrrsetbyname(const char *hostname, unsigned int rdclass, void lwres_freerrset(struct rrsetinfo *rrset) { unsigned int i; - for (i = 0; i < rrset->rri_nrdatas; i++) { - if (rrset->rri_rdatas[i].rdi_data == NULL) - break; - free(rrset->rri_rdatas[i].rdi_data); + if (rrset->rri_rdatas != NULL) { + for (i = 0; i < rrset->rri_nrdatas; i++) { + if (rrset->rri_rdatas[i].rdi_data == NULL) + break; + free(rrset->rri_rdatas[i].rdi_data); + } + free(rrset->rri_rdatas); } - free(rrset->rri_rdatas); - for (i = 0; i < rrset->rri_nsigs; i++) { - if (rrset->rri_sigs[i].rdi_data == NULL) - break; - free(rrset->rri_sigs[i].rdi_data); + if (rrset->rri_sigs != NULL) { + for (i = 0; i < rrset->rri_nsigs; i++) { + if (rrset->rri_sigs[i].rdi_data == NULL) + break; + free(rrset->rri_sigs[i].rdi_data); + } + free(rrset->rri_sigs); } - free(rrset->rri_sigs); free(rrset->rri_name); free(rrset); } diff --git a/lib/lwres/lwinetaton.c b/lib/lwres/lwinetaton.c index e40c28f..5a0d85a 100644 --- a/lib/lwres/lwinetaton.c +++ b/lib/lwres/lwinetaton.c @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2004, 2005, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1996-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -95,7 +95,7 @@ static char rcsid[] = "$Id: lwinetaton.c,v 1.16 2007/06/19 23:47:22 tbox Exp $"; */ int lwres_net_aton(const char *cp, struct in_addr *addr) { - unsigned long val; + lwres_uint32_t val; int base, n; unsigned char c; lwres_uint8_t parts[4]; @@ -120,7 +120,7 @@ lwres_net_aton(const char *cp, struct in_addr *addr) { c = *++cp; if (c == 'x' || c == 'X') { base = 16; - c = *++cp; + c = *++cp; } else { base = 8; digit = 1; diff --git a/lib/lwres/print.c b/lib/lwres/print.c index 591ed36..87f3032 100644 --- a/lib/lwres/print.c +++ b/lib/lwres/print.c @@ -470,12 +470,16 @@ lwres__print_vsnprintf(char *str, size_t size, const char *format, va_list ap) { pad--; } break; + case 'D': /*deprecated*/ INSIST("use %ld instead of %D" == NULL); + break; case 'O': /*deprecated*/ INSIST("use %lo instead of %O" == NULL); + break; case 'U': /*deprecated*/ INSIST("use %lu instead of %U" == NULL); + break; case 'L': #ifdef HAVE_LONG_DOUBLE |