aboutsummaryrefslogtreecommitdiff
path: root/external/unbound/testcode
diff options
context:
space:
mode:
authorErik de Castro Lopo <erikd@mega-nerd.com>2017-06-16 20:16:05 +1000
committerErik de Castro Lopo <erikd@mega-nerd.com>2017-06-17 23:04:00 +1000
commita85b5759f34c0c4110a479a8b5fa606f15ed9b23 (patch)
tree518cb8346249a42fd2aa8a78c09c3631e14db6aa /external/unbound/testcode
parentMerge pull request #2059 (diff)
downloadmonero-a85b5759f34c0c4110a479a8b5fa606f15ed9b23.tar.xz
Upgrade unbound library
These files were pulled from the 1.6.3 release tarball. This new version builds against OpenSSL version 1.1 which will be the default in the new Debian Stable which is due to be released RealSoonNow (tm).
Diffstat (limited to 'external/unbound/testcode')
-rw-r--r--external/unbound/testcode/asynclook.c11
-rw-r--r--external/unbound/testcode/checklocks.c2
-rw-r--r--external/unbound/testcode/checklocks.h10
-rw-r--r--external/unbound/testcode/delayer.c5
-rwxr-xr-xexternal/unbound/testcode/do-tests.sh2
-rw-r--r--external/unbound/testcode/fake_event.c50
-rw-r--r--external/unbound/testcode/lock_verify.c20
-rw-r--r--external/unbound/testcode/memstats.c17
-rw-r--r--external/unbound/testcode/perf.c1
-rw-r--r--external/unbound/testcode/petal.c30
-rw-r--r--external/unbound/testcode/replay.c26
-rw-r--r--external/unbound/testcode/replay.h20
-rw-r--r--external/unbound/testcode/signit.c2
-rw-r--r--external/unbound/testcode/streamtcp.c17
-rw-r--r--external/unbound/testcode/testbound.c26
-rw-r--r--external/unbound/testcode/testpkts.c308
-rw-r--r--external/unbound/testcode/testpkts.h22
-rw-r--r--external/unbound/testcode/unitecs.c284
-rw-r--r--external/unbound/testcode/unitlruhash.c76
-rw-r--r--external/unbound/testcode/unitmain.c310
-rw-r--r--external/unbound/testcode/unitmain.h4
-rw-r--r--external/unbound/testcode/unitneg.c4
-rw-r--r--external/unbound/testcode/unitslabhash.c62
-rw-r--r--external/unbound/testcode/unitverify.c16
24 files changed, 1144 insertions, 181 deletions
diff --git a/external/unbound/testcode/asynclook.c b/external/unbound/testcode/asynclook.c
index 534489735..a2bdb6213 100644
--- a/external/unbound/testcode/asynclook.c
+++ b/external/unbound/testcode/asynclook.c
@@ -64,7 +64,7 @@ struct track_id {
/** true if cancelled */
int cancel;
/** a lock on this structure for thread safety */
- lock_basic_t lock;
+ lock_basic_type lock;
};
/**
@@ -164,7 +164,7 @@ struct ext_thr_info {
/** thread num for debug */
int thread_num;
/** thread id */
- ub_thread_t tid;
+ ub_thread_type tid;
/** context */
struct ub_ctx* ctx;
/** size of array to query */
@@ -335,12 +335,17 @@ ext_thread(void* arg)
r = ub_wait(inf->ctx);
checkerr("ub_ctx_wait", r);
}
+ /* if these locks are destroyed, or if the async_ids is freed, then
+ a use-after-free happens in another thread.
+ The allocation is only part of this test, though. */
+ /*
if(async_ids) {
for(i=0; i<inf->numq; i++) {
lock_basic_destroy(&async_ids[i].lock);
}
}
free(async_ids);
+ */
return NULL;
}
@@ -465,7 +470,7 @@ int main(int argc, char** argv)
return 1;
}
- /* perform asyncronous calls */
+ /* perform asynchronous calls */
num_wait = argc;
for(i=0; i<argc; i++) {
lookups[i].name = argv[i];
diff --git a/external/unbound/testcode/checklocks.c b/external/unbound/testcode/checklocks.c
index dab98491e..7e6f0bb5d 100644
--- a/external/unbound/testcode/checklocks.c
+++ b/external/unbound/testcode/checklocks.c
@@ -61,7 +61,7 @@ static int key_created = 0;
/** if the key was deleted, i.e. we have quit */
static int key_deleted = 0;
/** we hide the thread debug info with this key. */
-static ub_thread_key_t thr_debug_key;
+static ub_thread_key_type thr_debug_key;
/** the list of threads, so all threads can be examined. NULL if unused. */
static struct thr_check* thread_infos[THRDEBUG_MAX_THREADS];
/** do we check locking order */
diff --git a/external/unbound/testcode/checklocks.h b/external/unbound/testcode/checklocks.h
index 936f28275..182a93858 100644
--- a/external/unbound/testcode/checklocks.h
+++ b/external/unbound/testcode/checklocks.h
@@ -307,7 +307,7 @@ struct checked_lock_mutex { struct checked_lock* c_m; };
struct checked_lock_spl { struct checked_lock* c_spl; };
/** debugging rwlock */
-typedef struct checked_lock_rw lock_rw_t;
+typedef struct checked_lock_rw lock_rw_type;
#define lock_rw_init(lock) checklock_init(check_lock_rwlock, &((lock)->c_rw), __func__, __FILE__, __LINE__)
#define lock_rw_destroy(lock) checklock_destroy(check_lock_rwlock, &((lock)->c_rw), __func__, __FILE__, __LINE__)
#define lock_rw_rdlock(lock) checklock_rdlock(check_lock_rwlock, (lock)->c_rw, __func__, __FILE__, __LINE__)
@@ -315,26 +315,26 @@ typedef struct checked_lock_rw lock_rw_t;
#define lock_rw_unlock(lock) checklock_unlock(check_lock_rwlock, (lock)->c_rw, __func__, __FILE__, __LINE__)
/** debugging mutex */
-typedef struct checked_lock_mutex lock_basic_t;
+typedef struct checked_lock_mutex lock_basic_type;
#define lock_basic_init(lock) checklock_init(check_lock_mutex, &((lock)->c_m), __func__, __FILE__, __LINE__)
#define lock_basic_destroy(lock) checklock_destroy(check_lock_mutex, &((lock)->c_m), __func__, __FILE__, __LINE__)
#define lock_basic_lock(lock) checklock_lock(check_lock_mutex, (lock)->c_m, __func__, __FILE__, __LINE__)
#define lock_basic_unlock(lock) checklock_unlock(check_lock_mutex, (lock)->c_m, __func__, __FILE__, __LINE__)
/** debugging spinlock */
-typedef struct checked_lock_spl lock_quick_t;
+typedef struct checked_lock_spl lock_quick_type;
#define lock_quick_init(lock) checklock_init(check_lock_spinlock, &((lock)->c_spl), __func__, __FILE__, __LINE__)
#define lock_quick_destroy(lock) checklock_destroy(check_lock_spinlock, &((lock)->c_spl), __func__, __FILE__, __LINE__)
#define lock_quick_lock(lock) checklock_lock(check_lock_spinlock, (lock)->c_spl, __func__, __FILE__, __LINE__)
#define lock_quick_unlock(lock) checklock_unlock(check_lock_spinlock, (lock)->c_spl, __func__, __FILE__, __LINE__)
/** we use the pthread id, our thr_check structure is kept behind the scenes */
-typedef pthread_t ub_thread_t;
+typedef pthread_t ub_thread_type;
#define ub_thread_create(thr, func, arg) checklock_thrcreate(thr, func, arg)
#define ub_thread_self() pthread_self()
#define ub_thread_join(thread) checklock_thrjoin(thread)
-typedef pthread_key_t ub_thread_key_t;
+typedef pthread_key_t ub_thread_key_type;
#define ub_thread_key_create(key, f) LOCKRET(pthread_key_create(key, f))
#define ub_thread_key_set(key, v) LOCKRET(pthread_setspecific(key, v))
#define ub_thread_key_get(key) pthread_getspecific(key)
diff --git a/external/unbound/testcode/delayer.c b/external/unbound/testcode/delayer.c
index 050cbd23e..5489b591e 100644
--- a/external/unbound/testcode/delayer.c
+++ b/external/unbound/testcode/delayer.c
@@ -1042,7 +1042,7 @@ service(const char* bind_str, int bindport, const char* serv_str,
}
i=0;
if(bindport == 0) {
- bindport = 1024 + random()%64000;
+ bindport = 1024 + arc4random()%64000;
i = 100;
}
while(1) {
@@ -1058,7 +1058,7 @@ service(const char* bind_str, int bindport, const char* serv_str,
#endif
if(i--==0)
fatal_exit("cannot bind any port");
- bindport = 1024 + random()%64000;
+ bindport = 1024 + arc4random()%64000;
} else break;
}
fd_set_nonblock(s);
@@ -1138,7 +1138,6 @@ int main(int argc, char** argv)
verbosity = 0;
log_init(0, 0, 0);
log_ident_set("delayer");
- srandom(time(NULL) ^ getpid());
if(argc == 1) usage(argv);
while( (c=getopt(argc, argv, "b:d:f:hm:p:")) != -1) {
switch(c) {
diff --git a/external/unbound/testcode/do-tests.sh b/external/unbound/testcode/do-tests.sh
index 6ea12cd2f..e356d4fc3 100755
--- a/external/unbound/testcode/do-tests.sh
+++ b/external/unbound/testcode/do-tests.sh
@@ -9,6 +9,7 @@ NEED_CURL='06-ianaports.tpkg root_anchor.tpkg'
NEED_WHOAMI='07-confroot.tpkg'
NEED_IPV6='fwd_ancil.tpkg fwd_tcp_tc6.tpkg stub_udp6.tpkg edns_cache.tpkg'
NEED_NOMINGW='tcp_sigpipe.tpkg 07-confroot.tpkg 08-host-lib.tpkg fwd_ancil.tpkg'
+NEED_DNSCRYPT_PROXY='dnscrypt_queries.tpkg'
# test if dig and ldns-testns are available.
test_tool_avail "dig"
@@ -39,6 +40,7 @@ for test in `ls *.tpkg`; do
skip_if_in_list $test "$NEED_XXD" "xxd"
skip_if_in_list $test "$NEED_NC" "nc"
skip_if_in_list $test "$NEED_WHOAMI" "whoami"
+ skip_if_in_list $test "$NEED_DNSCRYPT_PROXY" "dnscrypt-proxy"
if echo $NEED_IPV6 | grep $test >/dev/null; then
if test "$HAVE_IPV6" = no; then
diff --git a/external/unbound/testcode/fake_event.c b/external/unbound/testcode/fake_event.c
index e371cfdaa..154013a8c 100644
--- a/external/unbound/testcode/fake_event.c
+++ b/external/unbound/testcode/fake_event.c
@@ -318,7 +318,7 @@ answer_callback_from_entry(struct replay_runtime* runtime,
struct comm_point c;
struct comm_reply repinfo;
void* cb_arg = pend->cb_arg;
- comm_point_callback_t* cb = pend->callback;
+ comm_point_callback_type* cb = pend->callback;
memset(&c, 0, sizeof(c));
c.fd = -1;
@@ -422,7 +422,7 @@ fake_pending_callback(struct replay_runtime* runtime,
struct comm_reply repinfo;
struct comm_point c;
void* cb_arg;
- comm_point_callback_t* cb;
+ comm_point_callback_type* cb;
memset(&c, 0, sizeof(c));
if(!p) fatal_exit("No pending queries.");
@@ -735,7 +735,7 @@ struct listen_dnsport*
listen_create(struct comm_base* base, struct listen_port* ATTR_UNUSED(ports),
size_t bufsize, int ATTR_UNUSED(tcp_accept_count),
void* ATTR_UNUSED(sslctx), struct dt_env* ATTR_UNUSED(dtenv),
- comm_point_callback_t* cb, void* cb_arg)
+ comm_point_callback_type* cb, void* cb_arg)
{
struct replay_runtime* runtime = (struct replay_runtime*)base;
struct listen_dnsport* l= calloc(1, sizeof(struct listen_dnsport));
@@ -900,6 +900,7 @@ outside_network_create(struct comm_base* base, size_t bufsize,
struct ub_randstate* ATTR_UNUSED(rnd),
int ATTR_UNUSED(use_caps_for_id), int* ATTR_UNUSED(availports),
int ATTR_UNUSED(numavailports), size_t ATTR_UNUSED(unwanted_threshold),
+ int ATTR_UNUSED(outgoing_tcp_mss),
void (*unwanted_action)(void*), void* ATTR_UNUSED(unwanted_param),
int ATTR_UNUSED(do_udp), void* ATTR_UNUSED(sslctx),
int ATTR_UNUSED(delayclose), struct dt_env* ATTR_UNUSED(dtenv))
@@ -936,7 +937,7 @@ outside_network_quit_prepare(struct outside_network* ATTR_UNUSED(outnet))
struct pending*
pending_udp_query(struct serviced_query* sq, sldns_buffer* packet,
- int timeout, comm_point_callback_t* callback, void* callback_arg)
+ int timeout, comm_point_callback_type* callback, void* callback_arg)
{
struct replay_runtime* runtime = (struct replay_runtime*)
sq->outnet->base;
@@ -986,7 +987,7 @@ pending_udp_query(struct serviced_query* sq, sldns_buffer* packet,
struct waiting_tcp*
pending_tcp_query(struct serviced_query* sq, sldns_buffer* packet,
- int timeout, comm_point_callback_t* callback, void* callback_arg)
+ int timeout, comm_point_callback_type* callback, void* callback_arg)
{
struct replay_runtime* runtime = (struct replay_runtime*)
sq->outnet->base;
@@ -1035,13 +1036,13 @@ pending_tcp_query(struct serviced_query* sq, sldns_buffer* packet,
}
struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
- uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
- uint16_t flags, int dnssec, int ATTR_UNUSED(want_dnssec),
- int ATTR_UNUSED(nocaps), int ATTR_UNUSED(tcp_upstream),
- int ATTR_UNUSED(ssl_upstream), struct sockaddr_storage* addr,
- socklen_t addrlen, uint8_t* zone, size_t zonelen,
- comm_point_callback_t* callback, void* callback_arg,
- sldns_buffer* ATTR_UNUSED(buff))
+ struct query_info* qinfo, uint16_t flags, int dnssec,
+ int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps),
+ int ATTR_UNUSED(tcp_upstream), int ATTR_UNUSED(ssl_upstream),
+ struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
+ size_t zonelen, struct module_qstate* qstate,
+ comm_point_callback_type* callback, void* callback_arg,
+ sldns_buffer* ATTR_UNUSED(buff), struct module_env* ATTR_UNUSED(env))
{
struct replay_runtime* runtime = (struct replay_runtime*)outnet->base;
struct fake_pending* pend = (struct fake_pending*)calloc(1,
@@ -1049,7 +1050,7 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
char z[256];
log_assert(pend);
log_nametypeclass(VERB_OPS, "pending serviced query",
- qname, qtype, qclass);
+ qinfo->qname, qinfo->qtype, qinfo->qclass);
dname_str(zone, z);
verbose(VERB_OPS, "pending serviced query zone %s flags%s%s%s%s",
z, (flags&BIT_RD)?" RD":"", (flags&BIT_CD)?" CD":"",
@@ -1064,18 +1065,24 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
sldns_buffer_write_u16(pend->buffer, 0); /* ancount */
sldns_buffer_write_u16(pend->buffer, 0); /* nscount */
sldns_buffer_write_u16(pend->buffer, 0); /* arcount */
- sldns_buffer_write(pend->buffer, qname, qnamelen);
- sldns_buffer_write_u16(pend->buffer, qtype);
- sldns_buffer_write_u16(pend->buffer, qclass);
+ sldns_buffer_write(pend->buffer, qinfo->qname, qinfo->qname_len);
+ sldns_buffer_write_u16(pend->buffer, qinfo->qtype);
+ sldns_buffer_write_u16(pend->buffer, qinfo->qclass);
sldns_buffer_flip(pend->buffer);
if(1) {
- /* add edns */
struct edns_data edns;
+ if(!inplace_cb_query_call(env, qinfo, flags, addr, addrlen,
+ zone, zonelen, qstate, qstate->region)) {
+ free(pend);
+ return NULL;
+ }
+ /* add edns */
edns.edns_present = 1;
edns.ext_rcode = 0;
edns.edns_version = EDNS_ADVERTISED_VERSION;
edns.udp_size = EDNS_ADVERTISED_SIZE;
edns.bits = 0;
+ edns.opt_list = qstate->edns_opts_back_out;
if(dnssec)
edns.bits = EDNS_DO;
attach_edns_record(pend->buffer, &edns);
@@ -1084,7 +1091,7 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
pend->addrlen = addrlen;
pend->zone = memdup(zone, zonelen);
pend->zonelen = zonelen;
- pend->qtype = (int)qtype;
+ pend->qtype = (int)qinfo->qtype;
log_assert(pend->zone);
pend->callback = callback;
pend->cb_arg = callback_arg;
@@ -1128,6 +1135,7 @@ void outnet_serviced_query_stop(struct serviced_query* sq, void* cb_arg)
while(p) {
if(p == pend) {
log_assert(p->cb_arg == cb_arg);
+ (void)cb_arg;
log_info("serviced pending delete");
if(prev)
prev->next = p->next;
@@ -1157,7 +1165,7 @@ void listening_ports_free(struct listen_port* list)
struct comm_point* comm_point_create_local(struct comm_base* ATTR_UNUSED(base),
int ATTR_UNUSED(fd), size_t ATTR_UNUSED(bufsize),
- comm_point_callback_t* ATTR_UNUSED(callback),
+ comm_point_callback_type* ATTR_UNUSED(callback),
void* ATTR_UNUSED(callback_arg))
{
return calloc(1, 1);
@@ -1165,7 +1173,7 @@ struct comm_point* comm_point_create_local(struct comm_base* ATTR_UNUSED(base),
struct comm_point* comm_point_create_raw(struct comm_base* ATTR_UNUSED(base),
int ATTR_UNUSED(fd), int ATTR_UNUSED(writing),
- comm_point_callback_t* ATTR_UNUSED(callback),
+ comm_point_callback_type* ATTR_UNUSED(callback),
void* ATTR_UNUSED(callback_arg))
{
/* no pipe comm possible */
@@ -1386,7 +1394,7 @@ void comm_base_set_slow_accept_handlers(struct comm_base* ATTR_UNUSED(b),
(void)start_acc;
}
-struct event_base* comm_base_internal(struct comm_base* ATTR_UNUSED(b))
+struct ub_event_base* comm_base_internal(struct comm_base* ATTR_UNUSED(b))
{
/* no pipe comm possible in testbound */
return NULL;
diff --git a/external/unbound/testcode/lock_verify.c b/external/unbound/testcode/lock_verify.c
index 786d523c3..666a7029d 100644
--- a/external/unbound/testcode/lock_verify.c
+++ b/external/unbound/testcode/lock_verify.c
@@ -68,7 +68,7 @@ struct order_id {
/** a lock */
struct order_lock {
/** rbnode in all tree */
- rbnode_t node;
+ rbnode_type node;
/** lock id */
struct order_id id;
/** the creation file */
@@ -76,7 +76,7 @@ struct order_lock {
/** creation line */
int create_line;
/** set of all locks that are smaller than this one (locked earlier) */
- rbtree_t* smaller;
+ rbtree_type* smaller;
/** during depthfirstsearch, this is a linked list of the stack
* of locks. points to the next lock bigger than this one. */
struct lock_ref* dfs_next;
@@ -89,7 +89,7 @@ struct order_lock {
/** reference to a lock in a rbtree set */
struct lock_ref {
/** rbnode, key is an order_id ptr */
- rbnode_t node;
+ rbnode_type node;
/** the lock referenced */
struct order_lock* lock;
/** why is this ref */
@@ -105,7 +105,7 @@ static int verb = 0;
/** print program usage help */
static void
-usage()
+usage(void)
{
printf("lock_verify <trace files>\n");
}
@@ -181,7 +181,7 @@ static int readup_str(char** str, FILE* in)
}
/** read creation entry */
-static void read_create(rbtree_t* all, FILE* in)
+static void read_create(rbtree_type* all, FILE* in)
{
struct order_lock* o = calloc(1, sizeof(struct order_lock));
if(!o) fatal_exit("malloc failure");
@@ -210,7 +210,7 @@ static void read_create(rbtree_t* all, FILE* in)
/** insert lock entry (empty) into list */
static struct order_lock*
-insert_lock(rbtree_t* all, struct order_id* id)
+insert_lock(rbtree_type* all, struct order_id* id)
{
struct order_lock* o = calloc(1, sizeof(struct order_lock));
if(!o) fatal_exit("malloc failure");
@@ -223,7 +223,7 @@ insert_lock(rbtree_t* all, struct order_id* id)
}
/** read lock entry */
-static void read_lock(rbtree_t* all, FILE* in, int val)
+static void read_lock(rbtree_type* all, FILE* in, int val)
{
struct order_id prev_id, now_id;
struct lock_ref* ref;
@@ -256,7 +256,7 @@ static void read_lock(rbtree_t* all, FILE* in, int val)
}
/** read input file */
-static void readinput(rbtree_t* all, char* file)
+static void readinput(rbtree_type* all, char* file)
{
FILE *in = fopen(file, "r");
int fst;
@@ -367,7 +367,7 @@ static void check_order_lock(struct order_lock* lock)
}
/** Check ordering of locks */
-static void check_order(rbtree_t* all_locks)
+static void check_order(rbtree_type* all_locks)
{
/* check each lock */
struct order_lock* lock;
@@ -391,7 +391,7 @@ static void check_order(rbtree_t* all_locks)
int
main(int argc, char* argv[])
{
- rbtree_t* all_locks;
+ rbtree_type* all_locks;
int i;
time_t starttime = time(NULL);
#ifdef USE_THREAD_DEBUG
diff --git a/external/unbound/testcode/memstats.c b/external/unbound/testcode/memstats.c
index fc56c0d3c..dc29058ad 100644
--- a/external/unbound/testcode/memstats.c
+++ b/external/unbound/testcode/memstats.c
@@ -51,7 +51,7 @@
*/
struct codeline {
/** rbtree node */
- rbnode_t node;
+ rbnode_type node;
/** the name of the file:linenumber */
char* codeline;
/** the name of the function */
@@ -66,7 +66,7 @@ struct codeline {
/** print usage and exit */
static void
-usage()
+usage(void)
{
printf("usage: memstats <logfile>\n");
printf("statistics are printed on stdout.\n");
@@ -99,7 +99,7 @@ match(char* line)
/** find or alloc codeline in tree */
static struct codeline*
-get_codeline(rbtree_t* tree, char* key, char* func)
+get_codeline(rbtree_type* tree, char* key, char* func)
{
struct codeline* cl = (struct codeline*)rbtree_search(tree, key);
if(!cl) {
@@ -118,7 +118,7 @@ get_codeline(rbtree_t* tree, char* key, char* func)
/** read up the malloc stats */
static void
-read_malloc_stat(char* line, rbtree_t* tree)
+read_malloc_stat(char* line, rbtree_type* tree)
{
char codeline[10240];
char name[10240];
@@ -143,7 +143,7 @@ read_malloc_stat(char* line, rbtree_t* tree)
/** read up the calloc stats */
static void
-read_calloc_stat(char* line, rbtree_t* tree)
+read_calloc_stat(char* line, rbtree_type* tree)
{
char codeline[10240];
char name[10240];
@@ -180,7 +180,7 @@ get_file_size(const char* fname)
/** read the logfile */
static void
-readfile(rbtree_t* tree, const char* fname)
+readfile(rbtree_type* tree, const char* fname)
{
off_t total = get_file_size(fname);
off_t done = (off_t)0;
@@ -216,7 +216,7 @@ readfile(rbtree_t* tree, const char* fname)
/** print memory stats */
static void
-printstats(rbtree_t* tree)
+printstats(rbtree_type* tree)
{
struct codeline* cl;
uint64_t total = 0, tcalls = 0;
@@ -235,7 +235,8 @@ printstats(rbtree_t* tree)
/** main program */
int main(int argc, const char* argv[])
{
- rbtree_t* tree = 0;
+ rbtree_type* tree = 0;
+ log_init(NULL, 0, 0);
if(argc != 2) {
usage();
}
diff --git a/external/unbound/testcode/perf.c b/external/unbound/testcode/perf.c
index 320cbc933..d11357c4a 100644
--- a/external/unbound/testcode/perf.c
+++ b/external/unbound/testcode/perf.c
@@ -487,6 +487,7 @@ qlist_parse_line(sldns_buffer* buf, char* p)
qinfo.qname = sldns_str2wire_dname(nm, &qinfo.qname_len);
if(!qinfo.qname)
return 0;
+ qinfo.local_alias = NULL;
qinfo_query_encode(buf, &qinfo);
sldns_buffer_write_u16_at(buf, 0, 0); /* zero ID */
if(rec) LDNS_RD_SET(sldns_buffer_begin(buf));
diff --git a/external/unbound/testcode/petal.c b/external/unbound/testcode/petal.c
index a54181c37..b30549365 100644
--- a/external/unbound/testcode/petal.c
+++ b/external/unbound/testcode/petal.c
@@ -70,7 +70,7 @@ static int verb = 0;
/** Give petal usage, and exit (1). */
static void
-usage()
+usage(void)
{
printf("Usage: petal [opts]\n");
printf(" https daemon serves files from ./'host'/filename\n");
@@ -429,6 +429,7 @@ static void
provide_file_chunked(SSL* ssl, char* fname)
{
char buf[16384];
+ char* tmpbuf = NULL;
char* at = buf;
size_t avail = sizeof(buf);
size_t r;
@@ -471,9 +472,13 @@ provide_file_chunked(SSL* ssl, char* fname)
}
do {
- char tmpbuf[sizeof(buf)];
+ size_t red;
+ free(tmpbuf);
+ tmpbuf = malloc(avail-16);
+ if(!tmpbuf)
+ break;
/* read chunk; space-16 for xxxxCRLF..CRLF0CRLFCRLF (3 spare)*/
- size_t red = in?fread(tmpbuf, 1, avail-16, in):0;
+ red = in?fread(tmpbuf, 1, avail-16, in):0;
/* prepare chunk */
snprintf(at, avail, "%x\r\n", (unsigned)red);
r = strlen(at);
@@ -514,6 +519,7 @@ provide_file_chunked(SSL* ssl, char* fname)
avail = sizeof(buf);
} while(in && !feof(in) && !ferror(in));
+ free(tmpbuf);
if(in) fclose(in);
}
@@ -634,16 +640,30 @@ int main(int argc, char* argv[])
#ifdef SIGPIPE
(void)signal(SIGPIPE, SIG_IGN);
#endif
+#ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS
ERR_load_crypto_strings();
+#endif
ERR_load_SSL_strings();
+#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_CRYPTO)
OpenSSL_add_all_algorithms();
+#else
+ OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
+ | OPENSSL_INIT_ADD_ALL_DIGESTS
+ | OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
+#endif
+#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
(void)SSL_library_init();
+#else
+ (void)OPENSSL_init_ssl(0, NULL);
+#endif
do_service(addr, port, key, cert);
+#ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
CRYPTO_cleanup_all_ex_data();
- ERR_remove_state(0);
+#endif
+#ifdef HAVE_ERR_FREE_STRINGS
ERR_free_strings();
- RAND_cleanup();
+#endif
return 0;
}
diff --git a/external/unbound/testcode/replay.c b/external/unbound/testcode/replay.c
index 22670eb93..b45bde806 100644
--- a/external/unbound/testcode/replay.c
+++ b/external/unbound/testcode/replay.c
@@ -63,7 +63,7 @@
* done (successfully).
* @return expanded text, malloced. NULL on failure.
*/
-static char* macro_expand(rbtree_t* store,
+static char* macro_expand(rbtree_type* store,
struct replay_runtime* runtime, char** text);
/** compare of time values */
@@ -548,7 +548,7 @@ replay_var_compare(const void* a, const void* b)
return strcmp(x->name, y->name);
}
-rbtree_t*
+rbtree_type*
macro_store_create(void)
{
return rbtree_create(&replay_var_compare);
@@ -556,7 +556,7 @@ macro_store_create(void)
/** helper function to delete macro values */
static void
-del_macro(rbnode_t* x, void* ATTR_UNUSED(arg))
+del_macro(rbnode_type* x, void* ATTR_UNUSED(arg))
{
struct replay_var* v = (struct replay_var*)x;
free(v->name);
@@ -565,7 +565,7 @@ del_macro(rbnode_t* x, void* ATTR_UNUSED(arg))
}
void
-macro_store_delete(rbtree_t* store)
+macro_store_delete(rbtree_type* store)
{
if(!store)
return;
@@ -615,7 +615,7 @@ do_buf_insert(char* buf, size_t remain, char* after, char* inserted)
/** do macro recursion */
static char*
-do_macro_recursion(rbtree_t* store, struct replay_runtime* runtime,
+do_macro_recursion(rbtree_type* store, struct replay_runtime* runtime,
char* at, size_t remain)
{
char* after = at+2;
@@ -632,7 +632,7 @@ do_macro_recursion(rbtree_t* store, struct replay_runtime* runtime,
/** get var from store */
static struct replay_var*
-macro_getvar(rbtree_t* store, char* name)
+macro_getvar(rbtree_type* store, char* name)
{
struct replay_var k;
k.node.key = &k;
@@ -642,7 +642,7 @@ macro_getvar(rbtree_t* store, char* name)
/** do macro variable */
static char*
-do_macro_variable(rbtree_t* store, char* buf, size_t remain)
+do_macro_variable(rbtree_type* store, char* buf, size_t remain)
{
struct replay_var* v;
char* at = buf+1;
@@ -776,7 +776,7 @@ do_macro_range(char* buf)
}
static char*
-macro_expand(rbtree_t* store, struct replay_runtime* runtime, char** text)
+macro_expand(rbtree_type* store, struct replay_runtime* runtime, char** text)
{
char buf[10240];
char* at = *text;
@@ -844,7 +844,7 @@ macro_expand(rbtree_t* store, struct replay_runtime* runtime, char** text)
}
char*
-macro_process(rbtree_t* store, struct replay_runtime* runtime, char* text)
+macro_process(rbtree_type* store, struct replay_runtime* runtime, char* text)
{
char buf[10240];
char* next, *expand;
@@ -872,14 +872,14 @@ macro_process(rbtree_t* store, struct replay_runtime* runtime, char* text)
}
char*
-macro_lookup(rbtree_t* store, char* name)
+macro_lookup(rbtree_type* store, char* name)
{
struct replay_var* x = macro_getvar(store, name);
if(!x) return strdup("");
return strdup(x->value);
}
-void macro_print_debug(rbtree_t* store)
+void macro_print_debug(rbtree_type* store)
{
struct replay_var* x;
RBTREE_FOR(x, struct replay_var*, store) {
@@ -888,7 +888,7 @@ void macro_print_debug(rbtree_t* store)
}
int
-macro_assign(rbtree_t* store, char* name, char* value)
+macro_assign(rbtree_type* store, char* name, char* value)
{
struct replay_var* x = macro_getvar(store, name);
if(x) {
@@ -918,7 +918,7 @@ macro_assign(rbtree_t* store, char* name, char* value)
void testbound_selftest(void)
{
/* test the macro store */
- rbtree_t* store = macro_store_create();
+ rbtree_type* store = macro_store_create();
char* v;
int r;
int num_asserts = 0;
diff --git a/external/unbound/testcode/replay.h b/external/unbound/testcode/replay.h
index 05bd442f5..b33950304 100644
--- a/external/unbound/testcode/replay.h
+++ b/external/unbound/testcode/replay.h
@@ -280,7 +280,7 @@ struct replay_runtime {
struct fake_timer* timer_list;
/** callback to call for incoming queries */
- comm_point_callback_t* callback_query;
+ comm_point_callback_type* callback_query;
/** user argument for incoming query callback */
void *cb_arg;
@@ -305,7 +305,7 @@ struct replay_runtime {
/**
* Tree of macro values. Of type replay_var
*/
- rbtree_t* vars;
+ rbtree_type* vars;
};
/**
@@ -325,7 +325,7 @@ struct fake_pending {
/** qtype */
int qtype;
/** The callback function to call when answer arrives (or timeout) */
- comm_point_callback_t* callback;
+ comm_point_callback_type* callback;
/** callback user argument */
void* cb_arg;
/** original timeout in seconds from 'then' */
@@ -380,7 +380,7 @@ struct fake_timer {
*/
struct replay_var {
/** rbtree node. Key is this structure. Sorted by name. */
- rbnode_t node;
+ rbnode_type node;
/** the variable name */
char* name;
/** the variable value */
@@ -413,13 +413,13 @@ struct fake_timer* replay_get_oldest_timer(struct replay_runtime* runtime);
* Create variable storage
* @return new or NULL on failure.
*/
-rbtree_t* macro_store_create(void);
+rbtree_type* macro_store_create(void);
/**
* Delete variable storage
* @param store: the macro storage to free up.
*/
-void macro_store_delete(rbtree_t* store);
+void macro_store_delete(rbtree_type* store);
/**
* Apply macro substitution to string.
@@ -428,7 +428,7 @@ void macro_store_delete(rbtree_t* store);
* @param text: string to work on.
* @return newly malloced string with result.
*/
-char* macro_process(rbtree_t* store, struct replay_runtime* runtime,
+char* macro_process(rbtree_type* store, struct replay_runtime* runtime,
char* text);
/**
@@ -438,7 +438,7 @@ char* macro_process(rbtree_t* store, struct replay_runtime* runtime,
* @return newly malloced string with result or strdup("") if not found.
* or NULL on malloc failure.
*/
-char* macro_lookup(rbtree_t* store, char* name);
+char* macro_lookup(rbtree_type* store, char* name);
/**
* Set macro value.
@@ -447,10 +447,10 @@ char* macro_lookup(rbtree_t* store, char* name);
* @param value: text to set it to. Not expanded.
* @return false on failure.
*/
-int macro_assign(rbtree_t* store, char* name, char* value);
+int macro_assign(rbtree_type* store, char* name, char* value);
/** Print macro variables stored as debug info */
-void macro_print_debug(rbtree_t* store);
+void macro_print_debug(rbtree_type* store);
/** testbounds self test */
void testbound_selftest(void);
diff --git a/external/unbound/testcode/signit.c b/external/unbound/testcode/signit.c
index af4e0fe37..0eca0e088 100644
--- a/external/unbound/testcode/signit.c
+++ b/external/unbound/testcode/signit.c
@@ -63,7 +63,7 @@ struct keysets {
/** print usage and exit */
static void
-usage()
+usage(void)
{
printf("usage: signit expi ince keytag owner keyfile\n");
printf("present rrset data on stdin.\n");
diff --git a/external/unbound/testcode/streamtcp.c b/external/unbound/testcode/streamtcp.c
index c5919428a..34b5c0281 100644
--- a/external/unbound/testcode/streamtcp.c
+++ b/external/unbound/testcode/streamtcp.c
@@ -128,6 +128,9 @@ write_q(int fd, int udp, SSL* ssl, sldns_buffer* buf, uint16_t id,
qinfo.qtype = sldns_get_rr_type_by_name(strtype);
qinfo.qclass = sldns_get_rr_class_by_name(strclass);
+ /* clear local alias */
+ qinfo.local_alias = NULL;
+
/* make query */
qinfo_query_encode(buf, &qinfo);
sldns_buffer_write_u16_at(buf, 0, id);
@@ -265,7 +268,7 @@ static int get_random(void)
if (RAND_bytes((unsigned char*)&r, (int)sizeof(r)) == 1) {
return r;
}
- return (int)random();
+ return arc4random();
}
/** send the TCP queries and print answers */
@@ -406,8 +409,18 @@ int main(int argc, char** argv)
}
if(usessl) {
ERR_load_SSL_strings();
+#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_CRYPTO)
OpenSSL_add_all_algorithms();
- SSL_library_init();
+#else
+ OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
+ | OPENSSL_INIT_ADD_ALL_DIGESTS
+ | OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
+#endif
+#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
+ (void)SSL_library_init();
+#else
+ (void)OPENSSL_init_ssl(0, NULL);
+#endif
}
send_em(svr, udp, usessl, noanswer, argc, argv);
checklock_stop();
diff --git a/external/unbound/testcode/testbound.c b/external/unbound/testcode/testbound.c
index d908150a0..180b2c256 100644
--- a/external/unbound/testcode/testbound.c
+++ b/external/unbound/testcode/testbound.c
@@ -67,15 +67,17 @@ static struct config_strlist* cfgfiles = NULL;
/** give commandline usage for testbound. */
static void
-testbound_usage()
+testbound_usage(void)
{
printf("usage: testbound [options]\n");
printf("\ttest the unbound daemon.\n");
printf("-h this help\n");
printf("-p file playback text file\n");
+ printf("-1 detect SHA1 support (exit code 0 or 1)\n");
printf("-2 detect SHA256 support (exit code 0 or 1)\n");
printf("-g detect GOST support (exit code 0 or 1)\n");
printf("-e detect ECDSA support (exit code 0 or 1)\n");
+ printf("-c detect CLIENT_SUBNET support (exit code 0 or 1)\n");
printf("-s testbound self-test - unit test of testbound parts.\n");
printf("-o str unbound commandline options separated by spaces.\n");
printf("Version %s\n", PACKAGE_VERSION);
@@ -142,7 +144,7 @@ spool_auto_file(FILE* in, int* lineno, FILE* cfg, char* id)
/* find filename for new file */
while(isspace((unsigned char)*id))
id++;
- if(strlen(id)==0)
+ if(*id == '\0')
fatal_exit("AUTROTRUST_FILE must have id, line %d", *lineno);
id[strlen(id)-1]=0; /* remove newline */
fake_temp_file("_auto_", id, line, sizeof(line));
@@ -279,12 +281,21 @@ main(int argc, char* argv[])
pass_argc = 1;
pass_argv[0] = "unbound";
add_opts("-d", &pass_argc, pass_argv);
- while( (c=getopt(argc, argv, "2egho:p:s")) != -1) {
+ while( (c=getopt(argc, argv, "12egho:p:s")) != -1) {
switch(c) {
case 's':
free(pass_argv[1]);
testbound_selftest();
exit(0);
+ case '1':
+#ifdef USE_SHA1
+ printf("SHA1 supported\n");
+ exit(0);
+#else
+ printf("SHA1 not supported\n");
+ exit(1);
+#endif
+ break;
case '2':
#if (defined(HAVE_EVP_SHA256) || defined(HAVE_NSS) || defined(HAVE_NETTLE)) && defined(USE_SHA2)
printf("SHA256 supported\n");
@@ -317,6 +328,15 @@ main(int argc, char* argv[])
exit(1);
#endif
break;
+ case 'c':
+#ifdef CLIENT_SUBNET
+ printf("CLIENT_SUBNET supported\n");
+ exit(0);
+#else
+ printf("CLIENT_SUBNET not supported\n");
+ exit(1);
+#endif
+ break;
case 'p':
playback_file = optarg;
break;
diff --git a/external/unbound/testcode/testpkts.c b/external/unbound/testcode/testpkts.c
index d1960a410..e1a7768ab 100644
--- a/external/unbound/testcode/testpkts.c
+++ b/external/unbound/testcode/testpkts.c
@@ -98,6 +98,7 @@ entry_add_reply(struct entry* entry)
pkt->packet_sleep = 0;
pkt->reply_pkt = NULL;
pkt->reply_from_hex = NULL;
+ pkt->raw_ednsdata = NULL;
/* link at end */
while(*p)
p = &((*p)->next);
@@ -118,6 +119,12 @@ static void matchline(char* line, struct entry* e)
e->match_qtype = 1;
} else if(str_keyword(&parse, "qname")) {
e->match_qname = 1;
+ } else if(str_keyword(&parse, "rcode")) {
+ e->match_rcode = 1;
+ } else if(str_keyword(&parse, "question")) {
+ e->match_question = 1;
+ } else if(str_keyword(&parse, "answer")) {
+ e->match_answer = 1;
} else if(str_keyword(&parse, "subdomain")) {
e->match_subdomain = 1;
} else if(str_keyword(&parse, "all")) {
@@ -128,6 +135,8 @@ static void matchline(char* line, struct entry* e)
e->match_do = 1;
} else if(str_keyword(&parse, "noedns")) {
e->match_noedns = 1;
+ } else if(str_keyword(&parse, "ednsdata")) {
+ e->match_ednsdata_raw = 1;
} else if(str_keyword(&parse, "UDP")) {
e->match_transport = transport_udp;
} else if(str_keyword(&parse, "TCP")) {
@@ -224,6 +233,8 @@ static void adjustline(char* line, struct entry* e,
e->copy_id = 1;
} else if(str_keyword(&parse, "copy_query")) {
e->copy_query = 1;
+ } else if(str_keyword(&parse, "copy_ednsdata_assume_clientsubnet")) {
+ e->copy_ednsdata_assume_clientsubnet = 1;
} else if(str_keyword(&parse, "sleep=")) {
e->sleeptime = (unsigned int) strtol(parse, (char**)&parse, 10);
while(isspace((unsigned char)*parse))
@@ -239,7 +250,7 @@ static void adjustline(char* line, struct entry* e,
}
/** create new entry */
-static struct entry* new_entry()
+static struct entry* new_entry(void)
{
struct entry* e = (struct entry*)malloc(sizeof(struct entry));
if(!e) error("out of memory");
@@ -247,6 +258,9 @@ static struct entry* new_entry()
e->match_opcode = 0;
e->match_qtype = 0;
e->match_qname = 0;
+ e->match_rcode = 0;
+ e->match_question = 0;
+ e->match_answer = 0;
e->match_subdomain = 0;
e->match_all = 0;
e->match_ttl = 0;
@@ -258,6 +272,7 @@ static struct entry* new_entry()
e->reply_list = NULL;
e->copy_id = 0;
e->copy_query = 0;
+ e->copy_ednsdata_assume_clientsubnet = 0;
e->sleeptime = 0;
e->next = NULL;
return e;
@@ -475,25 +490,28 @@ static void add_rr(char* rrstr, uint8_t* pktbuf, size_t pktsize,
else error("internal error bad section %d", (int)add_section);
}
-/* add EDNS 4096 DO opt record */
+/* add EDNS 4096 opt record */
static void
-add_do_flag(uint8_t* pktbuf, size_t pktsize, size_t* pktlen)
+add_edns(uint8_t* pktbuf, size_t pktsize, int do_flag, uint8_t *ednsdata,
+ uint16_t ednslen, size_t* pktlen)
{
uint8_t edns[] = {0x00, /* root label */
0x00, LDNS_RR_TYPE_OPT, /* type */
0x10, 0x00, /* class is UDPSIZE 4096 */
0x00, /* TTL[0] is ext rcode */
0x00, /* TTL[1] is edns version */
- 0x80, 0x00, /* TTL[2-3] is edns flags, DO */
- 0x00, 0x00 /* rdatalength (0 options) */
+ (uint8_t)(do_flag?0x80:0x00), 0x00, /* TTL[2-3] is edns flags, DO */
+ (uint8_t)((ednslen >> 8) & 0xff),
+ (uint8_t)(ednslen & 0xff), /* rdatalength */
};
if(*pktlen < LDNS_HEADER_SIZE)
return;
- if(*pktlen + sizeof(edns) > pktsize)
+ if(*pktlen + sizeof(edns) + ednslen > pktsize)
error("not enough space for EDNS OPT record");
memmove(pktbuf+*pktlen, edns, sizeof(edns));
+ memmove(pktbuf+*pktlen+sizeof(edns), ednsdata, ednslen);
sldns_write_uint16(pktbuf+10, LDNS_ARCOUNT(pktbuf)+1);
- *pktlen += sizeof(edns);
+ *pktlen += (sizeof(edns) + ednslen);
}
/* Reads one entry from file. Returns entry or NULL on error. */
@@ -507,7 +525,9 @@ read_entry(FILE* in, const char* name, struct sldns_file_parse_state* pstate,
sldns_pkt_section add_section = LDNS_SECTION_QUESTION;
struct reply_packet *cur_reply = NULL;
int reading_hex = 0;
+ int reading_hex_ednsdata = 0;
sldns_buffer* hex_data_buffer = NULL;
+ sldns_buffer* hex_ednsdata_buffer = NULL;
uint8_t pktbuf[MAX_PACKETLEN];
size_t pktlen = LDNS_HEADER_SIZE;
int do_flag = 0; /* DO flag in EDNS */
@@ -574,21 +594,45 @@ read_entry(FILE* in, const char* name, struct sldns_file_parse_state* pstate,
cur_reply->reply_from_hex = hex_buffer2wire(hex_data_buffer);
sldns_buffer_free(hex_data_buffer);
hex_data_buffer = NULL;
+ } else if(reading_hex) {
+ sldns_buffer_printf(hex_data_buffer, "%s", line);
+ } else if(str_keyword(&parse, "HEX_EDNSDATA_BEGIN")) {
+ hex_ednsdata_buffer = sldns_buffer_new(MAX_PACKETLEN);
+ reading_hex_ednsdata = 1;
+ } else if(str_keyword(&parse, "HEX_EDNSDATA_END")) {
+ if (!reading_hex_ednsdata) {
+ error("%s line %d: HEX_EDNSDATA_END read but no"
+ "HEX_EDNSDATA_BEGIN keyword seen", name, pstate->lineno);
+ }
+ reading_hex_ednsdata = 0;
+ cur_reply->raw_ednsdata = hex_buffer2wire(hex_ednsdata_buffer);
+ sldns_buffer_free(hex_ednsdata_buffer);
+ hex_ednsdata_buffer = NULL;
+ } else if(reading_hex_ednsdata) {
+ sldns_buffer_printf(hex_ednsdata_buffer, "%s", line);
} else if(str_keyword(&parse, "ENTRY_END")) {
if(hex_data_buffer)
sldns_buffer_free(hex_data_buffer);
+ if(hex_ednsdata_buffer)
+ sldns_buffer_free(hex_ednsdata_buffer);
if(pktlen != 0) {
- if(do_flag)
- add_do_flag(pktbuf, sizeof(pktbuf),
- &pktlen);
+ if(do_flag || cur_reply->raw_ednsdata) {
+ if(cur_reply->raw_ednsdata &&
+ sldns_buffer_limit(cur_reply->raw_ednsdata))
+ add_edns(pktbuf, sizeof(pktbuf), do_flag,
+ sldns_buffer_begin(cur_reply->raw_ednsdata),
+ (uint16_t)sldns_buffer_limit(cur_reply->raw_ednsdata),
+ &pktlen);
+ else
+ add_edns(pktbuf, sizeof(pktbuf), do_flag,
+ NULL, 0, &pktlen);
+ }
cur_reply->reply_pkt = memdup(pktbuf, pktlen);
cur_reply->reply_len = pktlen;
if(!cur_reply->reply_pkt)
error("out of memory");
}
return current;
- } else if(reading_hex) {
- sldns_buffer_printf(hex_data_buffer, "%s", line);
} else {
add_rr(skip_whitespace?parse:line, pktbuf,
sizeof(pktbuf), &pktlen, pstate, add_section,
@@ -596,10 +640,14 @@ read_entry(FILE* in, const char* name, struct sldns_file_parse_state* pstate,
}
}
- if (reading_hex) {
+ if(reading_hex) {
error("%s: End of file reached while still reading hex, "
"missing HEX_ANSWER_END\n", name);
}
+ if(reading_hex_ednsdata) {
+ error("%s: End of file reached while still reading edns data, "
+ "missing HEX_EDNSDATA_END\n", name);
+ }
if(current) {
error("%s: End of file reached while reading entry. "
"missing ENTRY_END\n", name);
@@ -691,6 +739,14 @@ static int get_opcode(uint8_t* pkt, size_t pktlen)
return (int)LDNS_OPCODE_WIRE(pkt);
}
+/** returns rcode from packet */
+static int get_rcode(uint8_t* pkt, size_t pktlen)
+{
+ if(pktlen < LDNS_HEADER_SIZE)
+ return 0;
+ return (int)LDNS_RCODE_WIRE(pkt);
+}
+
/** get authority section SOA serial value */
static uint32_t get_serial(uint8_t* p, size_t plen)
{
@@ -761,16 +817,16 @@ pkt_find_edns_opt(uint8_t** p, size_t* plen)
wlen -= LDNS_HEADER_SIZE;
/* skip other records with wire2str_scan */
- for(i=0; i < LDNS_QDCOUNT(p); i++)
+ for(i=0; i < LDNS_QDCOUNT(*p); i++)
(void)sldns_wire2str_rrquestion_scan(&w, &wlen, &snull, &sl,
*p, *plen);
- for(i=0; i < LDNS_ANCOUNT(p); i++)
+ for(i=0; i < LDNS_ANCOUNT(*p); i++)
(void)sldns_wire2str_rr_scan(&w, &wlen, &snull, &sl, *p, *plen);
- for(i=0; i < LDNS_NSCOUNT(p); i++)
+ for(i=0; i < LDNS_NSCOUNT(*p); i++)
(void)sldns_wire2str_rr_scan(&w, &wlen, &snull, &sl, *p, *plen);
/* walk through additional section */
- for(i=0; i < LDNS_ARCOUNT(p); i++) {
+ for(i=0; i < LDNS_ARCOUNT(*p); i++) {
/* if this is OPT then done */
uint8_t* dstart = w;
size_t dlen = wlen;
@@ -802,8 +858,8 @@ get_do_flag(uint8_t* pkt, size_t len)
uint16_t edns_bits;
uint8_t* walk = pkt;
size_t walk_len = len;
- if(pkt_find_edns_opt(&walk, &walk_len)) {
- return 1;
+ if(!pkt_find_edns_opt(&walk, &walk_len)) {
+ return 0;
}
if(walk_len < 6)
return 0; /* malformed */
@@ -1086,6 +1142,138 @@ static void lowercase_pkt(uint8_t* pkt, size_t pktlen)
}
}
+/** match question section of packet */
+static int
+match_question(uint8_t* q, size_t qlen, uint8_t* p, size_t plen, int mttl)
+{
+ char* qstr, *pstr, *s, *qcmpstr, *pcmpstr;
+ uint8_t* qb = q, *pb = p;
+ int r;
+ /* zero TTLs */
+ qb = memdup(q, qlen);
+ pb = memdup(p, plen);
+ if(!qb || !pb) error("out of memory");
+ if(!mttl) {
+ zerottls(qb, qlen);
+ zerottls(pb, plen);
+ }
+ lowercase_pkt(qb, qlen);
+ lowercase_pkt(pb, plen);
+ qstr = sldns_wire2str_pkt(qb, qlen);
+ pstr = sldns_wire2str_pkt(pb, plen);
+ if(!qstr || !pstr) error("cannot pkt2string");
+
+ /* remove before ;; QUESTION */
+ s = strstr(qstr, ";; QUESTION SECTION");
+ qcmpstr = s;
+ s = strstr(pstr, ";; QUESTION SECTION");
+ pcmpstr = s;
+ if(!qcmpstr && !pcmpstr) {
+ free(qstr);
+ free(pstr);
+ free(qb);
+ free(pb);
+ return 1;
+ }
+ if(!qcmpstr || !pcmpstr) {
+ free(qstr);
+ free(pstr);
+ free(qb);
+ free(pb);
+ return 0;
+ }
+
+ /* remove after answer section, (;; AUTH, ;; ADD, ;; MSG size ..) */
+ s = strstr(qcmpstr, ";; ANSWER SECTION");
+ if(!s) s = strstr(qcmpstr, ";; AUTHORITY SECTION");
+ if(!s) s = strstr(qcmpstr, ";; ADDITIONAL SECTION");
+ if(!s) s = strstr(qcmpstr, ";; MSG SIZE");
+ if(s) *s = 0;
+ s = strstr(pcmpstr, ";; ANSWER SECTION");
+ if(!s) s = strstr(pcmpstr, ";; AUTHORITY SECTION");
+ if(!s) s = strstr(pcmpstr, ";; ADDITIONAL SECTION");
+ if(!s) s = strstr(pcmpstr, ";; MSG SIZE");
+ if(s) *s = 0;
+
+ r = (strcmp(qcmpstr, pcmpstr) == 0);
+
+ if(!r) {
+ verbose(3, "mismatch question section '%s' and '%s'",
+ qcmpstr, pcmpstr);
+ }
+
+ free(qstr);
+ free(pstr);
+ free(qb);
+ free(pb);
+ return r;
+}
+
+/** match answer section of packet */
+static int
+match_answer(uint8_t* q, size_t qlen, uint8_t* p, size_t plen, int mttl)
+{
+ char* qstr, *pstr, *s, *qcmpstr, *pcmpstr;
+ uint8_t* qb = q, *pb = p;
+ int r;
+ /* zero TTLs */
+ qb = memdup(q, qlen);
+ pb = memdup(p, plen);
+ if(!qb || !pb) error("out of memory");
+ if(!mttl) {
+ zerottls(qb, qlen);
+ zerottls(pb, plen);
+ }
+ lowercase_pkt(qb, qlen);
+ lowercase_pkt(pb, plen);
+ qstr = sldns_wire2str_pkt(qb, qlen);
+ pstr = sldns_wire2str_pkt(pb, plen);
+ if(!qstr || !pstr) error("cannot pkt2string");
+
+ /* remove before ;; ANSWER */
+ s = strstr(qstr, ";; ANSWER SECTION");
+ qcmpstr = s;
+ s = strstr(pstr, ";; ANSWER SECTION");
+ pcmpstr = s;
+ if(!qcmpstr && !pcmpstr) {
+ free(qstr);
+ free(pstr);
+ free(qb);
+ free(pb);
+ return 1;
+ }
+ if(!qcmpstr || !pcmpstr) {
+ free(qstr);
+ free(pstr);
+ free(qb);
+ free(pb);
+ return 0;
+ }
+
+ /* remove after answer section, (;; AUTH, ;; ADD, ;; MSG size ..) */
+ s = strstr(qcmpstr, ";; AUTHORITY SECTION");
+ if(!s) s = strstr(qcmpstr, ";; ADDITIONAL SECTION");
+ if(!s) s = strstr(qcmpstr, ";; MSG SIZE");
+ if(s) *s = 0;
+ s = strstr(pcmpstr, ";; AUTHORITY SECTION");
+ if(!s) s = strstr(pcmpstr, ";; ADDITIONAL SECTION");
+ if(!s) s = strstr(pcmpstr, ";; MSG SIZE");
+ if(s) *s = 0;
+
+ r = (strcmp(qcmpstr, pcmpstr) == 0);
+
+ if(!r) {
+ verbose(3, "mismatch answer section '%s' and '%s'",
+ qcmpstr, pcmpstr);
+ }
+
+ free(qstr);
+ free(pstr);
+ free(qb);
+ free(pb);
+ return r;
+}
+
/** match all of the packet */
int
match_all(uint8_t* q, size_t qlen, uint8_t* p, size_t plen, int mttl,
@@ -1128,6 +1316,9 @@ match_all(uint8_t* q, size_t qlen, uint8_t* p, size_t plen, int mttl,
/* check for reordered sections */
r = match_noloc(qstr, pstr, q, qlen, p, plen);
}
+ if(!r) {
+ verbose(3, "mismatch pkt '%s' and '%s'", qstr, pstr);
+ }
free(qstr);
free(pstr);
free(qb);
@@ -1186,6 +1377,31 @@ static int subdomain_dname(uint8_t* q, size_t qlen, uint8_t* p, size_t plen)
return 0;
}
+/** Match OPT RDATA (not the EDNS payload size or flags) */
+static int
+match_ednsdata(uint8_t* q, size_t qlen, uint8_t* p, size_t plen)
+{
+ uint8_t* walk_q = q;
+ size_t walk_qlen = qlen;
+ uint8_t* walk_p = p;
+ size_t walk_plen = plen;
+
+ if(!pkt_find_edns_opt(&walk_q, &walk_qlen))
+ walk_qlen = 0;
+ if(!pkt_find_edns_opt(&walk_p, &walk_plen))
+ walk_plen = 0;
+
+ /* class + ttl + rdlen = 8 */
+ if(walk_qlen <= 8 && walk_plen <= 8) {
+ verbose(3, "NO edns opt, move on");
+ return 1;
+ }
+ if(walk_qlen != walk_plen)
+ return 0;
+
+ return (memcmp(walk_p+8, walk_q+8, walk_qlen-8) == 0);
+}
+
/* finds entry in list, or returns NULL */
struct entry*
find_match(struct entry* entries, uint8_t* query_pkt, size_t len,
@@ -1214,6 +1430,31 @@ find_match(struct entry* entries, uint8_t* query_pkt, size_t len,
continue;
}
}
+ if(p->match_rcode) {
+ if(get_rcode(query_pkt, len) != get_rcode(reply, rlen)) {
+ char *r1 = sldns_wire2str_rcode(get_rcode(query_pkt, len));
+ char *r2 = sldns_wire2str_rcode(get_rcode(reply, rlen));
+ verbose(3, "bad rcode %s instead of %s\n",
+ r1, r2);
+ free(r1);
+ free(r2);
+ continue;
+ }
+ }
+ if(p->match_question) {
+ if(!match_question(query_pkt, len, reply, rlen,
+ (int)p->match_ttl)) {
+ verbose(3, "bad question section\n");
+ continue;
+ }
+ }
+ if(p->match_answer) {
+ if(!match_answer(query_pkt, len, reply, rlen,
+ (int)p->match_ttl)) {
+ verbose(3, "bad answer section\n");
+ continue;
+ }
+ }
if(p->match_subdomain) {
if(!subdomain_dname(query_pkt, len, reply, rlen)) {
verbose(3, "bad subdomain\n");
@@ -1232,6 +1473,11 @@ find_match(struct entry* entries, uint8_t* query_pkt, size_t len,
verbose(3, "bad; EDNS OPT present\n");
continue;
}
+ if(p->match_ednsdata_raw &&
+ !match_ednsdata(query_pkt, len, reply, rlen)) {
+ verbose(3, "bad EDNS data match.\n");
+ continue;
+ }
if(p->match_transport != transport_any && p->match_transport != transport) {
verbose(3, "bad transport\n");
continue;
@@ -1317,6 +1563,29 @@ adjust_packet(struct entry* match, uint8_t** answer_pkt, size_t *answer_len,
if(match->copy_id && reslen >= 1)
res[0] = orig[0];
+ if(match->copy_ednsdata_assume_clientsubnet) {
+ /** Assume there is only one EDNS option, which is ECS.
+ * Copy source mask from query to scope mask in reply. Assume
+ * rest of ECS data in response (eg address) matches the query.
+ */
+ uint8_t* walk_q = orig;
+ size_t walk_qlen = origlen;
+ uint8_t* walk_p = res;
+ size_t walk_plen = reslen;
+
+ if(!pkt_find_edns_opt(&walk_q, &walk_qlen)) {
+ walk_qlen = 0;
+ }
+ if(!pkt_find_edns_opt(&walk_p, &walk_plen)) {
+ walk_plen = 0;
+ }
+ /* class + ttl + rdlen + optcode + optlen + ecs fam + ecs source
+ * + ecs scope = index 15 */
+ if(walk_qlen >= 15 && walk_plen >= 15) {
+ walk_p[15] = walk_q[14];
+ }
+ }
+
if(match->sleeptime > 0) {
verbose(3, "sleeping for %d seconds\n", match->sleeptime);
#ifdef HAVE_SLEEP
@@ -1410,6 +1679,7 @@ void delete_replylist(struct reply_packet* replist)
np = p->next;
free(p->reply_pkt);
sldns_buffer_free(p->reply_from_hex);
+ sldns_buffer_free(p->raw_ednsdata);
free(p);
p=np;
}
diff --git a/external/unbound/testcode/testpkts.h b/external/unbound/testcode/testpkts.h
index 5c000546f..b175cab06 100644
--- a/external/unbound/testcode/testpkts.h
+++ b/external/unbound/testcode/testpkts.h
@@ -50,6 +50,10 @@ struct sldns_file_parse_state;
; 'ttl' used with all, rrs in packet must also have matching TTLs.
; 'DO' will match only queries with DO bit set.
; 'noedns' matches queries without EDNS OPT records.
+ ; 'rcode' makes the query match the rcode from the reply
+ ; 'question' makes the query match the question section
+ ; 'answer' makes the query match the answer section
+ ; 'ednsdata' matches queries to HEX_EDNS section.
MATCH [opcode] [qtype] [qname] [serial=<value>] [all] [ttl]
MATCH [UDP|TCP] DO
MATCH ...
@@ -84,6 +88,11 @@ struct sldns_file_parse_state;
; be parsed, ADJUST rules for the answer packet
; are ignored. Only copy_id is done.
HEX_ANSWER_END
+ HEX_EDNS_BEGIN ; follow with hex data.
+ ; Raw EDNS data to match against. It must be an
+ ; exact match (all options are matched) and will be
+ ; evaluated only when 'MATCH ednsdata' given.
+ HEX_EDNS_END
ENTRY_END
@@ -144,6 +153,8 @@ struct reply_packet {
uint8_t* reply_pkt;
/** length of reply pkt */
size_t reply_len;
+ /** Additional EDNS data for matching queries. */
+ struct sldns_buffer* raw_ednsdata;
/** or reply pkt in hex if not parsable */
struct sldns_buffer* reply_from_hex;
/** seconds to sleep before giving packet */
@@ -161,6 +172,12 @@ struct entry {
uint8_t match_qtype;
/** match qname with answer qname */
uint8_t match_qname;
+ /** match rcode with answer rcode */
+ uint8_t match_rcode;
+ /** match question section */
+ uint8_t match_question;
+ /** match answer section */
+ uint8_t match_answer;
/** match qname as subdomain of answer qname */
uint8_t match_subdomain;
/** match SOA serial number, from auth section */
@@ -173,6 +190,8 @@ struct entry {
uint8_t match_do;
/** match absence of EDNS OPT record in query */
uint8_t match_noedns;
+ /** match edns data field given in hex */
+ uint8_t match_ednsdata_raw;
/** match query serial with this value. */
uint32_t ixfr_soa_serial;
/** match on UDP/TCP */
@@ -186,6 +205,9 @@ struct entry {
uint8_t copy_id;
/** copy the query nametypeclass from query into the answer */
uint8_t copy_query;
+ /** copy ednsdata to reply, assume it is clientsubnet and
+ * adjust scopemask to match sourcemask */
+ uint8_t copy_ednsdata_assume_clientsubnet;
/** in seconds */
unsigned int sleeptime;
diff --git a/external/unbound/testcode/unitecs.c b/external/unbound/testcode/unitecs.c
new file mode 100644
index 000000000..3584b0f98
--- /dev/null
+++ b/external/unbound/testcode/unitecs.c
@@ -0,0 +1,284 @@
+/*
+ * testcode/unitecs.c - unit test for ecs routines.
+ *
+ * Copyright (c) 2013, NLnet Labs. All rights reserved.
+ *
+ * This software is open source.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NLNET LABS nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * \file
+ * Calls ecs related unit tests. Exits with code 1 on a failure.
+ */
+
+#include "config.h"
+
+#ifdef CLIENT_SUBNET
+
+#include "util/log.h"
+#include "util/module.h"
+#include "testcode/unitmain.h"
+#include "edns-subnet/addrtree.h"
+#include "edns-subnet/subnetmod.h"
+
+/*
+ void printkey(addrkey_t *k, addrlen_t bits)
+ {
+ int byte;
+ int bytes = bits/8 + ((bits%8)>0);
+ char msk = 0xFF;
+ for (byte = 0; byte < bytes; byte++) {
+ //~ if (byte+1 == bytes)
+ //~ msk = 0xFF<<(8-bits%8);
+ printf("%02x ", k[byte]&msk);
+ }
+ }
+
+ void print_tree(struct addrnode* node, int indent, int maxdepth)
+ {
+ struct addredge* edge;
+ int i, s, byte;
+ if (indent == 0) printf("-----Tree-----\n");
+ if (indent > maxdepth) {
+ printf("\n");
+ return;
+ }
+ printf("[node elem:%d] (%d)\n", node->elem != NULL, node);
+ for (i = 0; i<2; i++) {
+ if (node->edge[i]) {
+ for (s = 0; s < indent; s++) printf(" ");
+ printkey(node->edge[i]->str, node->edge[i]->len);
+ printf("(len %d bits, %d bytes) ", node->edge[i]->len,
+ node->edge[i]->len/8 + ((node->edge[i]->len%8)>0));
+ print_tree(node->edge[i]->node, indent+1, maxdepth);
+ }
+ }
+ if (indent == 0) printf("-----Tree-----");
+ }
+*/
+
+/* what should we check?
+ * X - is it balanced? (a node with 1 child shoudl not have
+ * a node with 1 child MUST have elem
+ * child must be sub of parent
+ * edge must be longer than parent edge
+ * */
+static int addrtree_inconsistent_subtree(struct addrtree* tree,
+ struct addredge* parent_edge, addrlen_t depth)
+{
+ struct addredge* edge;
+ struct addrnode* node = parent_edge->node;
+ int childcount, i, r;
+ if (depth > tree->max_depth) return 15;
+ childcount = (node->edge[0] != NULL) + (node->edge[1] != NULL);
+ /* Only nodes with 2 children should possibly have no element. */
+ if (childcount < 2 && !node->elem) return 10;
+ for (i = 0; i<2; i++) {
+ edge = node->edge[i];
+ if (!edge) continue;
+ if (!edge->node) return 11;
+ if (!edge->str) return 12;
+ if (edge->len <= parent_edge->len) return 13;
+ if (!unittest_wrapper_addrtree_issub(parent_edge->str,
+ parent_edge->len, edge->str, edge->len, 0))
+ return 14;
+ if ((r = addrtree_inconsistent_subtree(tree, edge, depth+1)) != 0)
+ return 100+r;
+ }
+ return 0;
+}
+
+static int addrtree_inconsistent(struct addrtree* tree)
+{
+ struct addredge* edge;
+ int i, r;
+
+ if (!tree) return 0;
+ if (!tree->root) return 1;
+
+ for (i = 0; i<2; i++) {
+ edge = tree->root->edge[i];
+ if (!edge) continue;
+ if (!edge->node) return 3;
+ if (!edge->str) return 4;
+ if ((r = addrtree_inconsistent_subtree(tree, edge, 1)) != 0)
+ return r;
+ }
+ return 0;
+}
+
+static addrlen_t randomkey(addrkey_t **k, int maxlen)
+{
+ int byte;
+ int bits = rand() % maxlen;
+ int bytes = bits/8 + (bits%8>0); /*ceil*/
+ *k = (addrkey_t *) malloc(bytes * sizeof(addrkey_t));
+ for (byte = 0; byte < bytes; byte++) {
+ (*k)[byte] = (addrkey_t)(rand() & 0xFF);
+ }
+ return (addrlen_t)bits;
+}
+
+static void elemfree(void *envptr, void *elemptr)
+{
+ struct reply_info *elem = (struct reply_info *)elemptr;
+ (void)envptr;
+ free(elem);
+}
+
+static void consistency_test(void)
+{
+ addrlen_t l;
+ time_t i;
+ unsigned int count;
+ addrkey_t *k;
+ struct addrtree* t;
+ struct module_env env;
+ struct reply_info *elem;
+ time_t timenow = 0;
+ unit_show_func("edns-subnet/addrtree.h", "Tree consistency check");
+ srand(9195); /* just some value for reproducibility */
+
+ t = addrtree_create(100, &elemfree, &unittest_wrapper_subnetmod_sizefunc, &env, 0);
+ count = t->node_count;
+ unit_assert(count == 0);
+ for (i = 0; i < 1000; i++) {
+ l = randomkey(&k, 128);
+ elem = (struct reply_info *) calloc(1, sizeof(struct reply_info));
+ addrtree_insert(t, k, l, 64, elem, timenow + 10, timenow);
+ /* This should always hold because no items ever expire. They
+ * could be overwritten, though. */
+ unit_assert( count <= t->node_count );
+ count = t->node_count;
+ free(k);
+ unit_assert( !addrtree_inconsistent(t) );
+ }
+ addrtree_delete(t);
+
+ unit_show_func("edns-subnet/addrtree.h", "Tree consistency with purge");
+ t = addrtree_create(8, &elemfree, &unittest_wrapper_subnetmod_sizefunc, &env, 0);
+ unit_assert(t->node_count == 0);
+ for (i = 0; i < 1000; i++) {
+ l = randomkey(&k, 128);
+ elem = (struct reply_info *) calloc(1, sizeof(struct reply_info));
+ addrtree_insert(t, k, l, 64, elem, i + 10, i);
+ free(k);
+ unit_assert( !addrtree_inconsistent(t) );
+ }
+ addrtree_delete(t);
+
+ unit_show_func("edns-subnet/addrtree.h", "Tree consistency with limit");
+ t = addrtree_create(8, &elemfree, &unittest_wrapper_subnetmod_sizefunc, &env, 27);
+ unit_assert(t->node_count == 0);
+ for (i = 0; i < 1000; i++) {
+ l = randomkey(&k, 128);
+ elem = (struct reply_info *) calloc(1, sizeof(struct reply_info));
+ addrtree_insert(t, k, l, 64, elem, i + 10, i);
+ unit_assert( t->node_count <= 27);
+ free(k);
+ unit_assert( !addrtree_inconsistent(t) );
+ }
+ addrtree_delete(t);
+}
+
+static void issub_test(void)
+{
+ addrkey_t k1[] = {0x55, 0x55, 0x5A};
+ addrkey_t k2[] = {0x55, 0x5D, 0x5A};
+ unit_show_func("edns-subnet/addrtree.h", "issub");
+ unit_assert( !unittest_wrapper_addrtree_issub(k1, 24, k2, 24, 0) );
+ unit_assert( unittest_wrapper_addrtree_issub(k1, 8, k2, 16, 0) );
+ unit_assert( unittest_wrapper_addrtree_issub(k2, 12, k1, 13, 0) );
+ unit_assert( !unittest_wrapper_addrtree_issub(k1, 16, k2, 12, 0) );
+ unit_assert( unittest_wrapper_addrtree_issub(k1, 12, k2, 12, 0) );
+ unit_assert( !unittest_wrapper_addrtree_issub(k1, 13, k2, 13, 0) );
+ unit_assert( unittest_wrapper_addrtree_issub(k1, 24, k2, 24, 13) );
+ unit_assert( !unittest_wrapper_addrtree_issub(k1, 24, k2, 20, 13) );
+ unit_assert( unittest_wrapper_addrtree_issub(k1, 20, k2, 24, 13) );
+}
+
+static void getbit_test(void)
+{
+ addrkey_t k1[] = {0x55, 0x55, 0x5A};
+ int i;
+ unit_show_func("edns-subnet/addrtree.h", "getbit");
+ for(i = 0; i<20; i++) {
+ unit_assert( unittest_wrapper_addrtree_getbit(k1, 20, (addrlen_t)i) == (i&1) );
+ }
+}
+
+static void bits_common_test(void)
+{
+ addrkey_t k1[] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0};
+ addrkey_t k2[] = {0,0,0,0,0,0,0,0};
+ addrlen_t i;
+
+ unit_show_func("edns-subnet/addrtree.h", "bits_common");
+ for(i = 0; i<64; i++) {
+ unit_assert( unittest_wrapper_addrtree_bits_common(k1, 64, k1, 64, i) == 64 );
+ }
+ for(i = 0; i<8; i++) {
+ k2[i] = k1[i]^(1<<i);
+ }
+ unit_assert( unittest_wrapper_addrtree_bits_common(k1, 64, k2, 64, 0) == 0*8+7 );
+ unit_assert( unittest_wrapper_addrtree_bits_common(k1, 64, k2, 64, 8) == 1*8+6 );
+ unit_assert( unittest_wrapper_addrtree_bits_common(k1, 64, k2, 64, 16) == 2*8+5 );
+ unit_assert( unittest_wrapper_addrtree_bits_common(k1, 64, k2, 64, 24) == 3*8+4 );
+ unit_assert( unittest_wrapper_addrtree_bits_common(k1, 64, k2, 64, 32) == 4*8+3 );
+ unit_assert( unittest_wrapper_addrtree_bits_common(k1, 64, k2, 64, 40) == 5*8+2 );
+ unit_assert( unittest_wrapper_addrtree_bits_common(k1, 64, k2, 64, 48) == 6*8+1 );
+ unit_assert( unittest_wrapper_addrtree_bits_common(k1, 64, k2, 64, 56) == 7*8+0 );
+}
+
+static void cmpbit_test(void)
+{
+ addrkey_t k1[] = {0xA5, 0x0F};
+ addrkey_t k2[] = {0x5A, 0xF0};
+ addrlen_t i;
+
+ unit_show_func("edns-subnet/addrtree.h", "cmpbit");
+ for(i = 0; i<16; i++) {
+ unit_assert( !unittest_wrapper_addrtree_cmpbit(k1,k1,i) );
+ unit_assert( unittest_wrapper_addrtree_cmpbit(k1,k2,i) );
+ }
+}
+
+void ecs_test(void)
+{
+ unit_show_feature("ecs");
+ cmpbit_test();
+ bits_common_test();
+ getbit_test();
+ issub_test();
+ consistency_test();
+}
+#endif /* CLIENT_SUBNET */
+
diff --git a/external/unbound/testcode/unitlruhash.c b/external/unbound/testcode/unitlruhash.c
index 28fc617f4..e196f0b63 100644
--- a/external/unbound/testcode/unitlruhash.c
+++ b/external/unbound/testcode/unitlruhash.c
@@ -45,9 +45,9 @@
#include "util/storage/slabhash.h" /* for the test structures */
/** use this type for the lruhash test key */
-typedef struct slabhash_testkey testkey_t;
+typedef struct slabhash_testkey testkey_type;
/** use this type for the lruhash test data */
-typedef struct slabhash_testdata testdata_t;
+typedef struct slabhash_testdata testdata_type;
/** delete key */
static void delkey(struct slabhash_testkey* k) {
@@ -56,10 +56,10 @@ static void delkey(struct slabhash_testkey* k) {
static void deldata(struct slabhash_testdata* d) {free(d);}
/** hash func, very bad to improve collisions */
-static hashvalue_t myhash(int id) {return (hashvalue_t)id & 0x0f;}
+static hashvalue_type myhash(int id) {return (hashvalue_type)id & 0x0f;}
/** allocate new key, fill in hash */
-static testkey_t* newkey(int id) {
- testkey_t* k = (testkey_t*)calloc(1, sizeof(testkey_t));
+static testkey_type* newkey(int id) {
+ testkey_type* k = (testkey_type*)calloc(1, sizeof(testkey_type));
if(!k) fatal_exit("out of memory");
k->id = id;
k->entry.hash = myhash(id);
@@ -68,9 +68,9 @@ static testkey_t* newkey(int id) {
return k;
}
/** new data el */
-static testdata_t* newdata(int val) {
- testdata_t* d = (testdata_t*)calloc(1,
- sizeof(testdata_t));
+static testdata_type* newdata(int val) {
+ testdata_type* d = (testdata_type*)calloc(1,
+ sizeof(testdata_type));
if(!d) fatal_exit("out of memory");
d->data = val;
return d;
@@ -80,12 +80,12 @@ static testdata_t* newdata(int val) {
static void
test_bin_find_entry(struct lruhash* table)
{
- testkey_t* k = newkey(12);
- testdata_t* d = newdata(128);
- testkey_t* k2 = newkey(12 + 1024);
- testkey_t* k3 = newkey(14);
- testkey_t* k4 = newkey(12 + 1024*2);
- hashvalue_t h = myhash(12);
+ testkey_type* k = newkey(12);
+ testdata_type* d = newdata(128);
+ testkey_type* k2 = newkey(12 + 1024);
+ testkey_type* k3 = newkey(14);
+ testkey_type* k4 = newkey(12 + 1024*2);
+ hashvalue_type h = myhash(12);
struct lruhash_bin bin;
memset(&bin, 0, sizeof(bin));
bin_init(&bin, 1);
@@ -161,8 +161,8 @@ test_bin_find_entry(struct lruhash* table)
/** test lru_front lru_remove */
static void test_lru(struct lruhash* table)
{
- testkey_t* k = newkey(12);
- testkey_t* k2 = newkey(14);
+ testkey_type* k = newkey(12);
+ testkey_type* k2 = newkey(14);
lock_quick_lock(&table->lock);
unit_assert( table->lru_start == NULL && table->lru_end == NULL);
@@ -208,10 +208,10 @@ static void test_lru(struct lruhash* table)
static void
test_short_table(struct lruhash* table)
{
- testkey_t* k = newkey(12);
- testkey_t* k2 = newkey(14);
- testdata_t* d = newdata(128);
- testdata_t* d2 = newdata(129);
+ testkey_type* k = newkey(12);
+ testkey_type* k2 = newkey(14);
+ testdata_type* d = newdata(128);
+ testdata_type* d2 = newdata(129);
k->entry.data = d;
k2->entry.data = d2;
@@ -232,11 +232,11 @@ test_short_table(struct lruhash* table)
/** test adding a random element */
static void
-testadd(struct lruhash* table, testdata_t* ref[])
+testadd(struct lruhash* table, testdata_type* ref[])
{
int numtoadd = random() % HASHTESTMAX;
- testdata_t* data = newdata(numtoadd);
- testkey_t* key = newkey(numtoadd);
+ testdata_type* data = newdata(numtoadd);
+ testkey_type* key = newkey(numtoadd);
key->entry.data = data;
lruhash_insert(table, myhash(numtoadd), &key->entry, data, NULL);
ref[numtoadd] = data;
@@ -244,10 +244,10 @@ testadd(struct lruhash* table, testdata_t* ref[])
/** test adding a random element */
static void
-testremove(struct lruhash* table, testdata_t* ref[])
+testremove(struct lruhash* table, testdata_type* ref[])
{
int num = random() % HASHTESTMAX;
- testkey_t* key = newkey(num);
+ testkey_type* key = newkey(num);
lruhash_remove(table, myhash(num), key);
ref[num] = NULL;
delkey(key);
@@ -255,12 +255,12 @@ testremove(struct lruhash* table, testdata_t* ref[])
/** test adding a random element */
static void
-testlookup(struct lruhash* table, testdata_t* ref[])
+testlookup(struct lruhash* table, testdata_type* ref[])
{
int num = random() % HASHTESTMAX;
- testkey_t* key = newkey(num);
+ testkey_type* key = newkey(num);
struct lruhash_entry* en = lruhash_lookup(table, myhash(num), key, 0);
- testdata_t* data = en? (testdata_t*)en->data : NULL;
+ testdata_type* data = en? (testdata_type*)en->data : NULL;
if(en) {
unit_assert(en->key);
unit_assert(en->data);
@@ -310,11 +310,11 @@ check_table(struct lruhash* table)
/** test adding a random element (unlimited range) */
static void
-testadd_unlim(struct lruhash* table, testdata_t** ref)
+testadd_unlim(struct lruhash* table, testdata_type** ref)
{
int numtoadd = random() % (HASHTESTMAX * 10);
- testdata_t* data = newdata(numtoadd);
- testkey_t* key = newkey(numtoadd);
+ testdata_type* data = newdata(numtoadd);
+ testkey_type* key = newkey(numtoadd);
key->entry.data = data;
lruhash_insert(table, myhash(numtoadd), &key->entry, data, NULL);
if(ref)
@@ -323,10 +323,10 @@ testadd_unlim(struct lruhash* table, testdata_t** ref)
/** test adding a random element (unlimited range) */
static void
-testremove_unlim(struct lruhash* table, testdata_t** ref)
+testremove_unlim(struct lruhash* table, testdata_type** ref)
{
int num = random() % (HASHTESTMAX*10);
- testkey_t* key = newkey(num);
+ testkey_type* key = newkey(num);
lruhash_remove(table, myhash(num), key);
if(ref)
ref[num] = NULL;
@@ -335,12 +335,12 @@ testremove_unlim(struct lruhash* table, testdata_t** ref)
/** test adding a random element (unlimited range) */
static void
-testlookup_unlim(struct lruhash* table, testdata_t** ref)
+testlookup_unlim(struct lruhash* table, testdata_type** ref)
{
int num = random() % (HASHTESTMAX*10);
- testkey_t* key = newkey(num);
+ testkey_type* key = newkey(num);
struct lruhash_entry* en = lruhash_lookup(table, myhash(num), key, 0);
- testdata_t* data = en? (testdata_t*)en->data : NULL;
+ testdata_type* data = en? (testdata_type*)en->data : NULL;
if(en) {
unit_assert(en->key);
unit_assert(en->data);
@@ -360,7 +360,7 @@ static void
test_long_table(struct lruhash* table)
{
/* assuming it all fits in the hashtable, this check will work */
- testdata_t* ref[HASHTESTMAX * 100];
+ testdata_type* ref[HASHTESTMAX * 100];
size_t i;
memset(ref, 0, sizeof(ref));
/* test assumption */
@@ -422,7 +422,7 @@ struct test_thr {
/** thread num, first entry. */
int num;
/** id */
- ub_thread_t id;
+ ub_thread_type id;
/** hash table */
struct lruhash* table;
};
diff --git a/external/unbound/testcode/unitmain.c b/external/unbound/testcode/unitmain.c
index 0b32dcd86..fd56e64d3 100644
--- a/external/unbound/testcode/unitmain.c
+++ b/external/unbound/testcode/unitmain.c
@@ -73,7 +73,7 @@ int testcount = 0;
/** test alloc code */
static void
alloc_test(void) {
- alloc_special_t *t1, *t2;
+ alloc_special_type *t1, *t2;
struct alloc_cache major, minor1, minor2;
int i;
@@ -380,6 +380,28 @@ config_memsize_test(void)
unit_assert( cfg_parse_memsize("0 Gb", &v) && v==0*1024*1024);
}
+/** test config_file: test tag code */
+static void
+config_tag_test(void)
+{
+ unit_show_func("util/config_file.c", "taglist_intersect");
+ unit_assert( taglist_intersect(
+ (uint8_t*)"\000\000\000", 3, (uint8_t*)"\001\000\001", 3
+ ) == 0);
+ unit_assert( taglist_intersect(
+ (uint8_t*)"\000\000\001", 3, (uint8_t*)"\001\000\001", 3
+ ) == 1);
+ unit_assert( taglist_intersect(
+ (uint8_t*)"\001\000\000", 3, (uint8_t*)"\001\000\001", 3
+ ) == 1);
+ unit_assert( taglist_intersect(
+ (uint8_t*)"\001", 1, (uint8_t*)"\001\000\001", 3
+ ) == 1);
+ unit_assert( taglist_intersect(
+ (uint8_t*)"\001\000\001", 3, (uint8_t*)"\001", 1
+ ) == 1);
+}
+
#include "util/rtt.h"
/** test RTT code */
static void
@@ -536,6 +558,269 @@ rnd_test(void)
ub_randfree(r);
}
+#include "respip/respip.h"
+#include "services/localzone.h"
+#include "util/data/packed_rrset.h"
+typedef struct addr_action {char* ip; char* sact; enum respip_action act;}
+ addr_action_t;
+
+/** Utility function that verifies that the respip set has actions as expected */
+static void
+verify_respip_set_actions(struct respip_set* set, addr_action_t actions[],
+ int actions_len)
+{
+ int i = 0;
+ struct rbtree_type* tree = respip_set_get_tree(set);
+ for (i=0; i<actions_len; i++) {
+ struct sockaddr_storage addr;
+ int net;
+ socklen_t addrlen;
+ struct resp_addr* node;
+ netblockstrtoaddr(actions[i].ip, UNBOUND_DNS_PORT, &addr,
+ &addrlen, &net);
+ node = (struct resp_addr*)addr_tree_find(tree, &addr, addrlen, net);
+
+ /** we have the node and the node has the correct action
+ * and has no data */
+ unit_assert(node);
+ unit_assert(actions[i].act ==
+ resp_addr_get_action(node));
+ unit_assert(resp_addr_get_rrset(node) == NULL);
+ }
+ unit_assert(actions_len && i == actions_len);
+ unit_assert(actions_len == (int)tree->count);
+}
+
+/** Global respip actions test; apply raw config data and verify that
+ * all the nodes in the respip set, looked up by address, have expected
+ * actions */
+static void
+respip_conf_actions_test(void)
+{
+ addr_action_t config_response_ip[] = {
+ {"192.0.1.0/24", "deny", respip_deny},
+ {"192.0.2.0/24", "redirect", respip_redirect},
+ {"192.0.3.0/26", "inform", respip_inform},
+ {"192.0.4.0/27", "inform_deny", respip_inform_deny},
+ {"2001:db8:1::/48", "always_transparent", respip_always_transparent},
+ {"2001:db8:2::/49", "always_refuse", respip_always_refuse},
+ {"2001:db8:3::/50", "always_nxdomain", respip_always_nxdomain},
+ };
+ int i;
+ struct respip_set* set = respip_set_create();
+ struct config_file cfg;
+ int clen = (int)(sizeof(config_response_ip) / sizeof(addr_action_t));
+
+ unit_assert(set);
+ unit_show_feature("global respip config actions apply");
+ memset(&cfg, 0, sizeof(cfg));
+ for(i=0; i<clen; i++) {
+ char* ip = strdup(config_response_ip[i].ip);
+ char* sact = strdup(config_response_ip[i].sact);
+ unit_assert(ip && sact);
+ if(!cfg_str2list_insert(&cfg.respip_actions, ip, sact))
+ unit_assert(0);
+ }
+ unit_assert(respip_global_apply_cfg(set, &cfg));
+ verify_respip_set_actions(set, config_response_ip, clen);
+}
+
+/** Per-view respip actions test; apply raw configuration with two views
+ * and verify that actions are as expected in respip sets of both views */
+static void
+respip_view_conf_actions_test(void)
+{
+ addr_action_t config_response_ip_view1[] = {
+ {"192.0.1.0/24", "deny", respip_deny},
+ {"192.0.2.0/24", "redirect", respip_redirect},
+ {"192.0.3.0/26", "inform", respip_inform},
+ {"192.0.4.0/27", "inform_deny", respip_inform_deny},
+ };
+ addr_action_t config_response_ip_view2[] = {
+ {"2001:db8:1::/48", "always_transparent", respip_always_transparent},
+ {"2001:db8:2::/49", "always_refuse", respip_always_refuse},
+ {"2001:db8:3::/50", "always_nxdomain", respip_always_nxdomain},
+ };
+ int i;
+ struct config_file cfg;
+ int clen1 = (int)(sizeof(config_response_ip_view1) / sizeof(addr_action_t));
+ int clen2 = (int)(sizeof(config_response_ip_view2) / sizeof(addr_action_t));
+ struct config_view* cv1;
+ struct config_view* cv2;
+ int have_respip_cfg = 0;
+ struct views* views = NULL;
+ struct view* v = NULL;
+
+ unit_show_feature("per-view respip config actions apply");
+ memset(&cfg, 0, sizeof(cfg));
+ cv1 = (struct config_view*)calloc(1, sizeof(struct config_view));
+ cv2 = (struct config_view*)calloc(1, sizeof(struct config_view));
+ unit_assert(cv1 && cv2);
+ cv1->name = strdup("view1");
+ cv2->name = strdup("view2");
+ unit_assert(cv1->name && cv2->name);
+ cv1->next = cv2;
+ cfg.views = cv1;
+
+ for(i=0; i<clen1; i++) {
+ char* ip = strdup(config_response_ip_view1[i].ip);
+ char* sact = strdup(config_response_ip_view1[i].sact);
+ unit_assert(ip && sact);
+ if(!cfg_str2list_insert(&cv1->respip_actions, ip, sact))
+ unit_assert(0);
+ }
+ for(i=0; i<clen2; i++) {
+ char* ip = strdup(config_response_ip_view2[i].ip);
+ char* sact = strdup(config_response_ip_view2[i].sact);
+ unit_assert(ip && sact);
+ if(!cfg_str2list_insert(&cv2->respip_actions, ip, sact))
+ unit_assert(0);
+ }
+ views = views_create();
+ unit_assert(views);
+ unit_assert(views_apply_cfg(views, &cfg));
+ unit_assert(respip_views_apply_cfg(views, &cfg, &have_respip_cfg));
+
+ /* now verify the respip sets in each view */
+ v = views_find_view(views, "view1", 0);
+ unit_assert(v);
+ verify_respip_set_actions(v->respip_set, config_response_ip_view1, clen1);
+ lock_rw_unlock(&v->lock);
+ v = views_find_view(views, "view2", 0);
+ unit_assert(v);
+ verify_respip_set_actions(v->respip_set, config_response_ip_view2, clen2);
+ lock_rw_unlock(&v->lock);
+}
+
+typedef struct addr_data {char* ip; char* data;} addr_data_t;
+
+/** find the respip address node in the specified tree (by address lookup)
+ * and verify type and address of the specified rdata (by index) in this
+ * node's rrset */
+static void
+verify_rrset(struct respip_set* set, const char* ipstr,
+ const char* rdatastr, size_t rdi, uint16_t type)
+{
+ struct sockaddr_storage addr;
+ int net;
+ char buf[65536];
+ socklen_t addrlen;
+ struct rbtree_type* tree;
+ struct resp_addr* node;
+ const struct ub_packed_rrset_key* rrs;
+
+ netblockstrtoaddr(ipstr, UNBOUND_DNS_PORT, &addr, &addrlen, &net);
+ tree = respip_set_get_tree(set);
+ node = (struct resp_addr*)addr_tree_find(tree, &addr, addrlen, net);
+ unit_assert(node);
+ unit_assert((rrs = resp_addr_get_rrset(node)));
+ unit_assert(ntohs(rrs->rk.type) == type);
+ packed_rr_to_string((struct ub_packed_rrset_key*)rrs,
+ rdi, 0, buf, sizeof(buf));
+ unit_assert(strstr(buf, rdatastr));
+}
+
+/** Dataset used to test redirect rrset initialization for both
+ * global and per-view respip redirect configuration */
+static addr_data_t config_response_ip_data[] = {
+ {"192.0.1.0/24", "A 1.2.3.4"},
+ {"192.0.1.0/24", "A 11.12.13.14"},
+ {"192.0.2.0/24", "CNAME www.example.com."},
+ {"2001:db8:1::/48", "AAAA 2001:db8:1::2:1"},
+};
+
+/** Populate raw respip redirect config data, used for both global and
+ * view-based respip redirect test case */
+static void
+cfg_insert_respip_data(struct config_str2list** respip_actions,
+ struct config_str2list** respip_data)
+{
+ int clen = (int)(sizeof(config_response_ip_data) / sizeof(addr_data_t));
+ int i = 0;
+
+ /* insert actions (duplicate netblocks don't matter) */
+ for(i=0; i<clen; i++) {
+ char* ip = strdup(config_response_ip_data[i].ip);
+ char* sact = strdup("redirect");
+ unit_assert(ip && sact);
+ if(!cfg_str2list_insert(respip_actions, ip, sact))
+ unit_assert(0);
+ }
+ /* insert data */
+ for(i=0; i<clen; i++) {
+ char* ip = strdup(config_response_ip_data[i].ip);
+ char* data = strdup(config_response_ip_data[i].data);
+ unit_assert(ip && data);
+ if(!cfg_str2list_insert(respip_data, ip, data))
+ unit_assert(0);
+ }
+}
+
+/** Test global respip redirect w/ data directives */
+static void
+respip_conf_data_test(void)
+{
+ struct respip_set* set = respip_set_create();
+ struct config_file cfg;
+
+ unit_show_feature("global respip config data apply");
+ memset(&cfg, 0, sizeof(cfg));
+
+ cfg_insert_respip_data(&cfg.respip_actions, &cfg.respip_data);
+
+ /* apply configuration and verify rrsets */
+ unit_assert(respip_global_apply_cfg(set, &cfg));
+ verify_rrset(set, "192.0.1.0/24", "1.2.3.4", 0, LDNS_RR_TYPE_A);
+ verify_rrset(set, "192.0.1.0/24", "11.12.13.14", 1, LDNS_RR_TYPE_A);
+ verify_rrset(set, "192.0.2.0/24", "www.example.com", 0, LDNS_RR_TYPE_CNAME);
+ verify_rrset(set, "2001:db8:1::/48", "2001:db8:1::2:1", 0, LDNS_RR_TYPE_AAAA);
+}
+
+/** Test per-view respip redirect w/ data directives */
+static void
+respip_view_conf_data_test(void)
+{
+ struct config_file cfg;
+ struct config_view* cv;
+ int have_respip_cfg = 0;
+ struct views* views = NULL;
+ struct view* v = NULL;
+
+ unit_show_feature("per-view respip config data apply");
+ memset(&cfg, 0, sizeof(cfg));
+ cv = (struct config_view*)calloc(1, sizeof(struct config_view));
+ unit_assert(cv);
+ cv->name = strdup("view1");
+ unit_assert(cv->name);
+ cfg.views = cv;
+ cfg_insert_respip_data(&cv->respip_actions, &cv->respip_data);
+ views = views_create();
+ unit_assert(views);
+ unit_assert(views_apply_cfg(views, &cfg));
+
+ /* apply configuration and verify rrsets */
+ unit_assert(respip_views_apply_cfg(views, &cfg, &have_respip_cfg));
+ v = views_find_view(views, "view1", 0);
+ unit_assert(v);
+ verify_rrset(v->respip_set, "192.0.1.0/24", "1.2.3.4",
+ 0, LDNS_RR_TYPE_A);
+ verify_rrset(v->respip_set, "192.0.1.0/24", "11.12.13.14",
+ 1, LDNS_RR_TYPE_A);
+ verify_rrset(v->respip_set, "192.0.2.0/24", "www.example.com",
+ 0, LDNS_RR_TYPE_CNAME);
+ verify_rrset(v->respip_set, "2001:db8:1::/48", "2001:db8:1::2:1",
+ 0, LDNS_RR_TYPE_AAAA);
+}
+
+/** respip unit tests */
+static void respip_test(void)
+{
+ respip_view_conf_data_test();
+ respip_conf_data_test();
+ respip_view_conf_actions_test();
+ respip_conf_actions_test();
+}
+
void unit_show_func(const char* file, const char* func)
{
printf("test %s:%s\n", file, func);
@@ -546,6 +831,9 @@ void unit_show_feature(const char* feature)
printf("test %s functions\n", feature);
}
+#ifdef USE_ECDSA_EVP_WORKAROUND
+void ecdsa_evp_workaround_init(void);
+#endif
/**
* Main unit test program. Setup, teardown and report errors.
* @param argc: arg count.
@@ -563,13 +851,15 @@ main(int argc, char* argv[])
}
printf("Start of %s unit test.\n", PACKAGE_STRING);
#ifdef HAVE_SSL
+# ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS
ERR_load_crypto_strings();
-# ifdef HAVE_OPENSSL_CONFIG
- OPENSSL_config("unbound");
# endif
# ifdef USE_GOST
(void)sldns_key_EVP_load_gost_id();
# endif
+# ifdef USE_ECDSA_EVP_WORKAROUND
+ ecdsa_evp_workaround_init();
+# endif
#elif defined(HAVE_NSS)
if(NSS_NoDB_Init(".") != SECSuccess)
fatal_exit("could not init NSS");
@@ -577,9 +867,11 @@ main(int argc, char* argv[])
checklock_start();
neg_test();
rnd_test();
+ respip_test();
verify_test();
net_test();
config_memsize_test();
+ config_tag_test();
dname_test();
rtt_test();
anchors_test();
@@ -590,6 +882,9 @@ main(int argc, char* argv[])
infra_test();
ldns_test();
msgparse_test();
+#ifdef CLIENT_SUBNET
+ ecs_test();
+#endif /* CLIENT_SUBNET */
checklock_stop();
printf("%d checks ok.\n", testcount);
#ifdef HAVE_SSL
@@ -597,14 +892,21 @@ main(int argc, char* argv[])
sldns_key_EVP_unload_gost();
# endif
# ifdef HAVE_OPENSSL_CONFIG
+# ifdef HAVE_EVP_CLEANUP
EVP_cleanup();
+# endif
ENGINE_cleanup();
CONF_modules_free();
# endif
+# ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
CRYPTO_cleanup_all_ex_data();
- ERR_remove_state(0);
+# endif
+# ifdef HAVE_ERR_FREE_STRINGS
ERR_free_strings();
+# endif
+# ifdef HAVE_RAND_CLEANUP
RAND_cleanup();
+# endif
#elif defined(HAVE_NSS)
if(NSS_Shutdown() != SECSuccess)
fatal_exit("could not shutdown NSS");
diff --git a/external/unbound/testcode/unitmain.h b/external/unbound/testcode/unitmain.h
index c27bd1437..d81b603b2 100644
--- a/external/unbound/testcode/unitmain.h
+++ b/external/unbound/testcode/unitmain.h
@@ -72,6 +72,10 @@ void verify_test(void);
void neg_test(void);
/** unit test for regional allocator functions */
void regional_test(void);
+#ifdef CLIENT_SUBNET
+/** Unit test for ECS functions */
+void ecs_test(void);
+#endif /* CLIENT_SUBNET */
/** unit test for ldns functions */
void ldns_test(void);
diff --git a/external/unbound/testcode/unitneg.c b/external/unbound/testcode/unitneg.c
index 36fa6b906..2b67df182 100644
--- a/external/unbound/testcode/unitneg.c
+++ b/external/unbound/testcode/unitneg.c
@@ -242,7 +242,7 @@ static void remove_item(struct val_neg_cache* neg)
{
int n, i;
struct val_neg_data* d;
- rbnode_t* walk;
+ rbnode_type* walk;
struct val_neg_zone* z;
lock_basic_lock(&neg->lock);
@@ -324,7 +324,7 @@ static size_t sumtrees_inuse(struct val_neg_cache* neg)
RBTREE_FOR(z, struct val_neg_zone*, &neg->tree) {
/* get count of highest parent for num in use */
d = (struct val_neg_data*)rbtree_first(&z->tree);
- if(d && (rbnode_t*)d!=RBTREE_NULL)
+ if(d && (rbnode_type*)d!=RBTREE_NULL)
res += d->count;
}
return res;
diff --git a/external/unbound/testcode/unitslabhash.c b/external/unbound/testcode/unitslabhash.c
index 783468883..565d36139 100644
--- a/external/unbound/testcode/unitslabhash.c
+++ b/external/unbound/testcode/unitslabhash.c
@@ -44,24 +44,24 @@
#include "util/storage/slabhash.h"
/** use this type for the slabhash test key */
-typedef struct slabhash_testkey testkey_t;
+typedef struct slabhash_testkey testkey_type;
/** use this type for the slabhash test data */
-typedef struct slabhash_testdata testdata_t;
+typedef struct slabhash_testdata testdata_type;
/** delete key */
static void delkey(struct slabhash_testkey* k) {
lock_rw_destroy(&k->entry.lock); free(k);}
/** hash func, very bad to improve collisions, both high and low bits */
-static hashvalue_t myhash(int id) {
- hashvalue_t h = (hashvalue_t)id & 0x0f;
+static hashvalue_type myhash(int id) {
+ hashvalue_type h = (hashvalue_type)id & 0x0f;
h |= (h << 28);
return h;
}
/** allocate new key, fill in hash */
-static testkey_t* newkey(int id) {
- testkey_t* k = (testkey_t*)calloc(1, sizeof(testkey_t));
+static testkey_type* newkey(int id) {
+ testkey_type* k = (testkey_type*)calloc(1, sizeof(testkey_type));
if(!k) fatal_exit("out of memory");
k->id = id;
k->entry.hash = myhash(id);
@@ -70,9 +70,9 @@ static testkey_t* newkey(int id) {
return k;
}
/** new data el */
-static testdata_t* newdata(int val) {
- testdata_t* d = (testdata_t*)calloc(1,
- sizeof(testdata_t));
+static testdata_type* newdata(int val) {
+ testdata_type* d = (testdata_type*)calloc(1,
+ sizeof(testdata_type));
if(!d) fatal_exit("out of memory");
d->data = val;
return d;
@@ -82,10 +82,10 @@ static testdata_t* newdata(int val) {
static void
test_short_table(struct slabhash* table)
{
- testkey_t* k = newkey(12);
- testkey_t* k2 = newkey(14);
- testdata_t* d = newdata(128);
- testdata_t* d2 = newdata(129);
+ testkey_type* k = newkey(12);
+ testkey_type* k2 = newkey(14);
+ testdata_type* d = newdata(128);
+ testdata_type* d2 = newdata(129);
k->entry.data = d;
k2->entry.data = d2;
@@ -106,11 +106,11 @@ test_short_table(struct slabhash* table)
/** test adding a random element */
static void
-testadd(struct slabhash* table, testdata_t* ref[])
+testadd(struct slabhash* table, testdata_type* ref[])
{
int numtoadd = random() % HASHTESTMAX;
- testdata_t* data = newdata(numtoadd);
- testkey_t* key = newkey(numtoadd);
+ testdata_type* data = newdata(numtoadd);
+ testkey_type* key = newkey(numtoadd);
key->entry.data = data;
slabhash_insert(table, myhash(numtoadd), &key->entry, data, NULL);
ref[numtoadd] = data;
@@ -118,10 +118,10 @@ testadd(struct slabhash* table, testdata_t* ref[])
/** test adding a random element */
static void
-testremove(struct slabhash* table, testdata_t* ref[])
+testremove(struct slabhash* table, testdata_type* ref[])
{
int num = random() % HASHTESTMAX;
- testkey_t* key = newkey(num);
+ testkey_type* key = newkey(num);
slabhash_remove(table, myhash(num), key);
ref[num] = NULL;
delkey(key);
@@ -129,12 +129,12 @@ testremove(struct slabhash* table, testdata_t* ref[])
/** test adding a random element */
static void
-testlookup(struct slabhash* table, testdata_t* ref[])
+testlookup(struct slabhash* table, testdata_type* ref[])
{
int num = random() % HASHTESTMAX;
- testkey_t* key = newkey(num);
+ testkey_type* key = newkey(num);
struct lruhash_entry* en = slabhash_lookup(table, myhash(num), key, 0);
- testdata_t* data = en? (testdata_t*)en->data : NULL;
+ testdata_type* data = en? (testdata_type*)en->data : NULL;
if(en) {
unit_assert(en->key);
unit_assert(en->data);
@@ -193,11 +193,11 @@ check_table(struct slabhash* table)
/** test adding a random element (unlimited range) */
static void
-testadd_unlim(struct slabhash* table, testdata_t** ref)
+testadd_unlim(struct slabhash* table, testdata_type** ref)
{
int numtoadd = random() % (HASHTESTMAX * 10);
- testdata_t* data = newdata(numtoadd);
- testkey_t* key = newkey(numtoadd);
+ testdata_type* data = newdata(numtoadd);
+ testkey_type* key = newkey(numtoadd);
key->entry.data = data;
slabhash_insert(table, myhash(numtoadd), &key->entry, data, NULL);
if(ref)
@@ -206,10 +206,10 @@ testadd_unlim(struct slabhash* table, testdata_t** ref)
/** test adding a random element (unlimited range) */
static void
-testremove_unlim(struct slabhash* table, testdata_t** ref)
+testremove_unlim(struct slabhash* table, testdata_type** ref)
{
int num = random() % (HASHTESTMAX*10);
- testkey_t* key = newkey(num);
+ testkey_type* key = newkey(num);
slabhash_remove(table, myhash(num), key);
if(ref)
ref[num] = NULL;
@@ -218,12 +218,12 @@ testremove_unlim(struct slabhash* table, testdata_t** ref)
/** test adding a random element (unlimited range) */
static void
-testlookup_unlim(struct slabhash* table, testdata_t** ref)
+testlookup_unlim(struct slabhash* table, testdata_type** ref)
{
int num = random() % (HASHTESTMAX*10);
- testkey_t* key = newkey(num);
+ testkey_type* key = newkey(num);
struct lruhash_entry* en = slabhash_lookup(table, myhash(num), key, 0);
- testdata_t* data = en? (testdata_t*)en->data : NULL;
+ testdata_type* data = en? (testdata_type*)en->data : NULL;
if(en) {
unit_assert(en->key);
unit_assert(en->data);
@@ -243,7 +243,7 @@ static void
test_long_table(struct slabhash* table)
{
/* assuming it all fits in the hashtable, this check will work */
- testdata_t* ref[HASHTESTMAX * 100];
+ testdata_type* ref[HASHTESTMAX * 100];
size_t i;
memset(ref, 0, sizeof(ref));
/* test assumption */
@@ -301,7 +301,7 @@ struct slab_test_thr {
/** thread num, first entry. */
int num;
/** id */
- ub_thread_t id;
+ ub_thread_type id;
/** hash table */
struct slabhash* table;
};
diff --git a/external/unbound/testcode/unitverify.c b/external/unbound/testcode/unitverify.c
index 9cb0eb99e..37994a377 100644
--- a/external/unbound/testcode/unitverify.c
+++ b/external/unbound/testcode/unitverify.c
@@ -412,7 +412,7 @@ nsectest(void)
/** Test hash algo - NSEC3 hash it and compare result */
static void
-nsec3_hash_test_entry(struct entry* e, rbtree_t* ct,
+nsec3_hash_test_entry(struct entry* e, rbtree_type* ct,
struct alloc_cache* alloc, struct regional* region,
sldns_buffer* buf)
{
@@ -468,7 +468,7 @@ nsec3_hash_test(const char* fname)
*
* The test does not perform canonicalization during the compare.
*/
- rbtree_t ct;
+ rbtree_type ct;
struct regional* region = regional_create();
struct alloc_cache alloc;
sldns_buffer* buf = sldns_buffer_new(65535);
@@ -496,24 +496,34 @@ void
verify_test(void)
{
unit_show_feature("signature verify");
+#ifdef USE_SHA1
verifytest_file("testdata/test_signatures.1", "20070818005004");
+#endif
+#if defined(USE_DSA) && defined(USE_SHA1)
verifytest_file("testdata/test_signatures.2", "20080414005004");
verifytest_file("testdata/test_signatures.3", "20080416005004");
verifytest_file("testdata/test_signatures.4", "20080416005004");
verifytest_file("testdata/test_signatures.5", "20080416005004");
verifytest_file("testdata/test_signatures.6", "20080416005004");
verifytest_file("testdata/test_signatures.7", "20070829144150");
+#endif /* USE_DSA */
+#ifdef USE_SHA1
verifytest_file("testdata/test_signatures.8", "20070829144150");
+#endif
#if (defined(HAVE_EVP_SHA256) || defined(HAVE_NSS) || defined(HAVE_NETTLE)) && defined(USE_SHA2)
verifytest_file("testdata/test_sigs.rsasha256", "20070829144150");
+# ifdef USE_SHA1
verifytest_file("testdata/test_sigs.sha1_and_256", "20070829144150");
+# endif
verifytest_file("testdata/test_sigs.rsasha256_draft", "20090101000000");
#endif
#if (defined(HAVE_EVP_SHA512) || defined(HAVE_NSS) || defined(HAVE_NETTLE)) && defined(USE_SHA2)
verifytest_file("testdata/test_sigs.rsasha512_draft", "20070829144150");
#endif
+#ifdef USE_SHA1
verifytest_file("testdata/test_sigs.hinfo", "20090107100022");
verifytest_file("testdata/test_sigs.revoked", "20080414005004");
+#endif
#ifdef USE_GOST
if(sldns_key_EVP_load_gost_id())
verifytest_file("testdata/test_sigs.gost", "20090807060504");
@@ -527,7 +537,9 @@ verify_test(void)
}
dstest_file("testdata/test_ds.sha384");
#endif
+#ifdef USE_SHA1
dstest_file("testdata/test_ds.sha1");
+#endif
nsectest();
nsec3_hash_test("testdata/test_nsec3_hash.1");
}