aboutsummaryrefslogtreecommitdiff
path: root/external/unbound/testcode
diff options
context:
space:
mode:
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");
}