Merge branch 'master' into features/downstream-cookies

This commit is contained in:
George Thessalonikefs
2023-08-05 20:37:48 +02:00
217 changed files with 8924 additions and 2262 deletions
+8 -1
View File
@@ -226,9 +226,16 @@ make_query(char* qname, char* qtype, char* qclass)
printf("cannot parse query name: '%s'\n", qname);
exit(1);
}
qinfo.qtype = sldns_get_rr_type_by_name(qtype);
if(qinfo.qtype == 0 && strcmp(qtype, "TYPE0") != 0) {
printf("cannot parse query type: '%s'\n", qtype);
exit(1);
}
qinfo.qclass = sldns_get_rr_class_by_name(qclass);
if(qinfo.qclass == 0 && strcmp(qclass, "CLASS0") != 0) {
printf("cannot parse query class: '%s'\n", qclass);
exit(1);
}
qinfo.local_alias = NULL;
qinfo_query_encode(buf, &qinfo); /* flips buffer */
+78 -91
View File
@@ -2,24 +2,24 @@
* testcode/fake_event.c - fake event handling that replays existing scenario.
*
* Copyright (c) 2007, 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
@@ -65,6 +65,7 @@
#include "sldns/wire2str.h"
#include "sldns/str2wire.h"
#include "daemon/remote.h"
#include "util/timeval_func.h"
#include <signal.h>
struct worker;
struct daemon_remote;
@@ -95,21 +96,7 @@ struct fake_commpoint {
/** Global variable: the scenario. Saved here for when event_init is done. */
static struct replay_scenario* saved_scenario = NULL;
/** add timers and the values do not overflow or become negative */
static void
timeval_add(struct timeval* d, const struct timeval* add)
{
#ifndef S_SPLINT_S
d->tv_sec += add->tv_sec;
d->tv_usec += add->tv_usec;
if(d->tv_usec >= 1000000) {
d->tv_usec -= 1000000;
d->tv_sec++;
}
#endif
}
void
void
fake_temp_file(const char* adj, const char* id, char* buf, size_t len)
{
#ifdef USE_WINSOCK
@@ -121,13 +108,13 @@ fake_temp_file(const char* adj, const char* id, char* buf, size_t len)
#endif
}
void
void
fake_event_init(struct replay_scenario* scen)
{
saved_scenario = scen;
}
void
void
fake_event_cleanup(void)
{
replay_scenario_delete(saved_scenario);
@@ -172,7 +159,7 @@ repevt_string(enum replay_event_type t)
}
/** delete a fake pending */
static void
static void
delete_fake_pending(struct fake_pending* pend)
{
if(!pend)
@@ -200,8 +187,8 @@ delete_replay_answer(struct replay_answer* a)
/**
* return: true if pending query matches the now event.
*/
static int
pending_matches_current(struct replay_runtime* runtime,
static int
pending_matches_current(struct replay_runtime* runtime,
struct entry** entry, struct fake_pending **pend)
{
struct fake_pending* p;
@@ -233,7 +220,7 @@ pending_matches_current(struct replay_runtime* runtime,
* @return: true if a match is found.
*/
static int
pending_find_match(struct replay_runtime* runtime, struct entry** entry,
pending_find_match(struct replay_runtime* runtime, struct entry** entry,
struct fake_pending* pend)
{
int timenow = runtime->now->time_step;
@@ -245,7 +232,7 @@ pending_find_match(struct replay_runtime* runtime, struct entry** entry,
(*entry = find_match(p->match, pend->pkt, pend->pkt_len,
pend->transport))) {
log_info("matched query time %d in range [%d, %d] "
"with entry line %d", timenow,
"with entry line %d", timenow,
p->start_step, p->end_step, (*entry)->lineno);
if(p->addrlen != 0)
log_addr(0, "matched ip", &p->addr, p->addrlen);
@@ -266,8 +253,8 @@ pending_find_match(struct replay_runtime* runtime, struct entry** entry,
* @param pend: if true, the outgoing message that matches is returned.
* @return: true if pending query matches the now event.
*/
static int
pending_matches_range(struct replay_runtime* runtime,
static int
pending_matches_range(struct replay_runtime* runtime,
struct entry** entry, struct fake_pending** pend)
{
struct fake_pending* p = runtime->pending_list;
@@ -405,9 +392,9 @@ answer_callback_from_entry(struct replay_runtime* runtime,
static void
answer_check_it(struct replay_runtime* runtime)
{
struct replay_answer* ans = runtime->answer_list,
struct replay_answer* ans = runtime->answer_list,
*prev = NULL;
log_assert(runtime && runtime->now &&
log_assert(runtime && runtime->now &&
runtime->now->evt_type == repevt_front_reply);
while(ans) {
enum transport_type tr = transport_tcp;
@@ -420,7 +407,7 @@ answer_check_it(struct replay_runtime* runtime)
ans->pkt_len, tr)) {
log_info("testbound matched event entry from line %d",
runtime->now->match->lineno);
log_info("testbound: do STEP %d %s",
log_info("testbound: do STEP %d %s",
runtime->now->time_step,
repevt_string(runtime->now->evt_type));
if(prev)
@@ -474,7 +461,7 @@ fake_front_query(struct replay_runtime* runtime, struct replay_moment *todo)
log_pkt("query pkt", todo->match->reply_list->reply_pkt,
todo->match->reply_list->reply_len);
/* call the callback for incoming queries */
if((*runtime->callback_query)(repinfo.c, runtime->cb_arg,
if((*runtime->callback_query)(repinfo.c, runtime->cb_arg,
NETEVENT_NOERROR, &repinfo)) {
/* send immediate reply */
comm_point_send_reply(&repinfo);
@@ -487,7 +474,7 @@ fake_front_query(struct replay_runtime* runtime, struct replay_moment *todo)
* Perform callback for fake pending message.
*/
static void
fake_pending_callback(struct replay_runtime* runtime,
fake_pending_callback(struct replay_runtime* runtime,
struct replay_moment* todo, int error)
{
struct fake_pending* p = runtime->pending_list;
@@ -566,7 +553,7 @@ time_passes(struct replay_runtime* runtime, struct replay_moment* mom)
timeval_add(&runtime->now_tv, &tv);
runtime->now_secs = (time_t)runtime->now_tv.tv_sec;
#ifndef S_SPLINT_S
log_info("elapsed %d.%6.6d now %d.%6.6d",
log_info("elapsed %d.%6.6d now %d.%6.6d",
(int)tv.tv_sec, (int)tv.tv_usec,
(int)runtime->now_tv.tv_sec, (int)runtime->now_tv.tv_usec);
#endif
@@ -603,7 +590,7 @@ autotrust_check(struct replay_runtime* runtime, struct replay_moment* mom)
}
strip_end_white(line);
expanded = macro_process(runtime->vars, runtime, p->str);
if(!expanded)
if(!expanded)
fatal_exit("could not expand macro line %d", lineno);
if(verbosity >= 7 && strcmp(p->str, expanded) != 0)
log_info("expanded '%s' to '%s'", p->str, expanded);
@@ -656,7 +643,7 @@ tempfile_check(struct replay_runtime* runtime, struct replay_moment* mom)
}
strip_end_white(line);
expanded = macro_process(runtime->vars, runtime, p->str);
if(!expanded)
if(!expanded)
fatal_exit("could not expand macro line %d", lineno);
if(verbosity >= 7 && strcmp(p->str, expanded) != 0)
log_info("expanded '%s' to '%s'", p->str, expanded);
@@ -746,7 +733,7 @@ do_moment_and_advance(struct replay_runtime* runtime)
advance_moment(runtime);
return;
}
log_info("testbound: do STEP %d %s", runtime->now->time_step,
log_info("testbound: do STEP %d %s", runtime->now->time_step,
repevt_string(runtime->now->evt_type));
switch(runtime->now->evt_type) {
case repevt_nothing:
@@ -761,7 +748,7 @@ do_moment_and_advance(struct replay_runtime* runtime)
fake_front_query(runtime, mom);
break;
case repevt_front_reply:
if(runtime->answer_list)
if(runtime->answer_list)
log_err("testbound: There are unmatched answers.");
fatal_exit("testbound: query answer not matched");
break;
@@ -810,7 +797,7 @@ do_moment_and_advance(struct replay_runtime* runtime)
advance_moment(runtime);
break;
default:
fatal_exit("testbound: unknown event type %d",
fatal_exit("testbound: unknown event type %d",
runtime->now->evt_type);
}
}
@@ -831,15 +818,15 @@ run_scenario(struct replay_runtime* runtime)
/* else if precoded_range matches pending, do it */
/* else do the current moment */
if(pending_matches_current(runtime, &entry, &pending)) {
log_info("testbound: do STEP %d CHECK_OUT_QUERY",
log_info("testbound: do STEP %d CHECK_OUT_QUERY",
runtime->now->time_step);
advance_moment(runtime);
if(entry->copy_id)
answer_callback_from_entry(runtime, entry,
answer_callback_from_entry(runtime, entry,
pending);
} else if(runtime->answer_list && runtime->now &&
} else if(runtime->answer_list && runtime->now &&
runtime->now->evt_type == repevt_front_reply) {
answer_check_it(runtime);
answer_check_it(runtime);
advance_moment(runtime);
} else if(pending_matches_range(runtime, &entry, &pending)) {
answer_callback_from_entry(runtime, entry, pending);
@@ -870,7 +857,7 @@ run_scenario(struct replay_runtime* runtime)
/*********** Dummy routines ***********/
struct listen_dnsport*
struct listen_dnsport*
listen_create(struct comm_base* base, struct listen_port* ATTR_UNUSED(ports),
size_t bufsize, int ATTR_UNUSED(tcp_accept_count),
int ATTR_UNUSED(tcp_idle_timeout),
@@ -898,7 +885,7 @@ listen_create(struct comm_base* base, struct listen_port* ATTR_UNUSED(ports),
return l;
}
void
void
listen_delete(struct listen_dnsport* listen)
{
if(!listen)
@@ -907,7 +894,7 @@ listen_delete(struct listen_dnsport* listen)
free(listen);
}
struct comm_base*
struct comm_base*
comm_base_create(int ATTR_UNUSED(sigs))
{
/* we return the runtime structure instead. */
@@ -921,7 +908,7 @@ comm_base_create(int ATTR_UNUSED(sigs))
return (struct comm_base*)runtime;
}
void
void
comm_base_delete(struct comm_base* b)
{
struct replay_runtime* runtime = (struct replay_runtime*)b;
@@ -961,7 +948,7 @@ comm_base_timept(struct comm_base* b, time_t** tt, struct timeval** tv)
*tv = &runtime->now_tv;
}
void
void
comm_base_dispatch(struct comm_base* b)
{
struct replay_runtime* runtime = (struct replay_runtime*)b;
@@ -971,7 +958,7 @@ comm_base_dispatch(struct comm_base* b)
else exit(0); /* OK exit when LIBEVENT_SIGNAL_PROBLEM exists */
}
void
void
comm_base_exit(struct comm_base* b)
{
struct replay_runtime* runtime = (struct replay_runtime*)b;
@@ -981,7 +968,7 @@ comm_base_exit(struct comm_base* b)
}
}
struct comm_signal*
struct comm_signal*
comm_signal_create(struct comm_base* base,
void (*callback)(int, void*), void* cb_arg)
{
@@ -991,20 +978,20 @@ comm_signal_create(struct comm_base* base,
return calloc(1, sizeof(struct comm_signal));
}
int
comm_signal_bind(struct comm_signal* ATTR_UNUSED(comsig), int
int
comm_signal_bind(struct comm_signal* ATTR_UNUSED(comsig), int
ATTR_UNUSED(sig))
{
return 1;
}
void
void
comm_signal_delete(struct comm_signal* comsig)
{
free(comsig);
}
void
void
comm_point_send_reply(struct comm_reply* repinfo)
{
struct replay_answer* ans = (struct replay_answer*)calloc(1,
@@ -1028,7 +1015,7 @@ comm_point_send_reply(struct comm_reply* repinfo)
log_pkt("reply pkt: ", ans->pkt, ans->pkt_len);
}
void
void
comm_point_drop_reply(struct comm_reply* repinfo)
{
log_info("comm_point_drop_reply fake");
@@ -1038,14 +1025,14 @@ comm_point_drop_reply(struct comm_reply* repinfo)
}
}
struct outside_network*
outside_network_create(struct comm_base* base, size_t bufsize,
size_t ATTR_UNUSED(num_ports), char** ATTR_UNUSED(ifs),
int ATTR_UNUSED(num_ifs), int ATTR_UNUSED(do_ip4),
int ATTR_UNUSED(do_ip6), size_t ATTR_UNUSED(num_tcp),
struct outside_network*
outside_network_create(struct comm_base* base, size_t bufsize,
size_t ATTR_UNUSED(num_ports), char** ATTR_UNUSED(ifs),
int ATTR_UNUSED(num_ifs), int ATTR_UNUSED(do_ip4),
int ATTR_UNUSED(do_ip6), size_t ATTR_UNUSED(num_tcp),
int ATTR_UNUSED(dscp),
struct infra_cache* infra,
struct ub_randstate* ATTR_UNUSED(rnd),
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),
@@ -1057,7 +1044,7 @@ outside_network_create(struct comm_base* base, size_t bufsize,
int ATTR_UNUSED(tcp_auth_query_timeout))
{
struct replay_runtime* runtime = (struct replay_runtime*)base;
struct outside_network* outnet = calloc(1,
struct outside_network* outnet = calloc(1,
sizeof(struct outside_network));
(void)unwanted_action;
if(!outnet)
@@ -1072,7 +1059,7 @@ outside_network_create(struct comm_base* base, size_t bufsize,
return outnet;
}
void
void
outside_network_delete(struct outside_network* outnet)
{
if(!outnet)
@@ -1081,12 +1068,12 @@ outside_network_delete(struct outside_network* outnet)
free(outnet);
}
void
void
outside_network_quit_prepare(struct outside_network* ATTR_UNUSED(outnet))
{
}
struct pending*
struct pending*
pending_udp_query(struct serviced_query* sq, sldns_buffer* packet,
int timeout, comm_point_callback_type* callback, void* callback_arg)
{
@@ -1128,7 +1115,7 @@ pending_udp_query(struct serviced_query* sq, sldns_buffer* packet,
repevt_string(runtime->now->evt_type));
advance_moment(runtime);
/* still create the pending, because we need it to callback */
}
}
log_info("testbound: created fake pending");
/* add to list */
pend->next = runtime->pending_list;
@@ -1178,7 +1165,7 @@ pending_tcp_query(struct serviced_query* sq, sldns_buffer* packet,
repevt_string(runtime->now->evt_type));
advance_moment(runtime);
/* still create the pending, because we need it to callback */
}
}
log_info("testbound: created fake pending");
/* add to list */
pend->next = runtime->pending_list;
@@ -1202,10 +1189,10 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
sizeof(struct fake_pending));
char z[256];
log_assert(pend);
log_nametypeclass(VERB_OPS, "pending serviced query",
log_nametypeclass(VERB_OPS, "pending serviced query",
qinfo->qname, qinfo->qtype, qinfo->qclass);
dname_str(zone, z);
verbose(VERB_OPS, "pending serviced query zone %s flags%s%s%s%s",
verbose(VERB_OPS, "pending serviced query zone %s flags%s%s%s%s",
z, (flags&BIT_RD)?" RD":"", (flags&BIT_CD)?" CD":"",
(flags&~(BIT_RD|BIT_CD))?" MORE":"", (dnssec)?" DO":"");
@@ -1303,7 +1290,7 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
repevt_string(runtime->now->evt_type));
advance_moment(runtime);
/* still create the pending, because we need it to callback */
}
}
log_info("testbound: created fake pending");
/* add to list */
pend->next = runtime->pending_list;
@@ -1358,7 +1345,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_type* ATTR_UNUSED(callback),
comm_point_callback_type* ATTR_UNUSED(callback),
void* ATTR_UNUSED(callback_arg))
{
struct fake_commpoint* fc = (struct fake_commpoint*)calloc(1,
@@ -1370,7 +1357,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_type* ATTR_UNUSED(callback),
comm_point_callback_type* ATTR_UNUSED(callback),
void* ATTR_UNUSED(callback_arg))
{
/* no pipe comm possible */
@@ -1381,7 +1368,7 @@ struct comm_point* comm_point_create_raw(struct comm_base* ATTR_UNUSED(base),
return (struct comm_point*)fc;
}
void comm_point_start_listening(struct comm_point* ATTR_UNUSED(c),
void comm_point_start_listening(struct comm_point* ATTR_UNUSED(c),
int ATTR_UNUSED(newfd), int ATTR_UNUSED(sec))
{
/* no bg write pipe comm possible */
@@ -1426,7 +1413,7 @@ size_t serviced_get_mem(struct serviced_query* ATTR_UNUSED(c))
}
/* fake for fptr wlist */
int outnet_udp_cb(struct comm_point* ATTR_UNUSED(c),
int outnet_udp_cb(struct comm_point* ATTR_UNUSED(c),
void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
struct comm_reply *ATTR_UNUSED(reply_info))
{
@@ -1434,7 +1421,7 @@ int outnet_udp_cb(struct comm_point* ATTR_UNUSED(c),
return 0;
}
int outnet_tcp_cb(struct comm_point* ATTR_UNUSED(c),
int outnet_tcp_cb(struct comm_point* ATTR_UNUSED(c),
void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
struct comm_reply *ATTR_UNUSED(reply_info))
{
@@ -1462,67 +1449,67 @@ void outnet_tcptimer(void* ATTR_UNUSED(arg))
log_assert(0);
}
void comm_point_udp_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(event),
void comm_point_udp_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(event),
void* ATTR_UNUSED(arg))
{
log_assert(0);
}
void comm_point_udp_ancil_callback(int ATTR_UNUSED(fd),
void comm_point_udp_ancil_callback(int ATTR_UNUSED(fd),
short ATTR_UNUSED(event), void* ATTR_UNUSED(arg))
{
log_assert(0);
}
void comm_point_tcp_accept_callback(int ATTR_UNUSED(fd),
void comm_point_tcp_accept_callback(int ATTR_UNUSED(fd),
short ATTR_UNUSED(event), void* ATTR_UNUSED(arg))
{
log_assert(0);
}
void comm_point_tcp_handle_callback(int ATTR_UNUSED(fd),
void comm_point_tcp_handle_callback(int ATTR_UNUSED(fd),
short ATTR_UNUSED(event), void* ATTR_UNUSED(arg))
{
log_assert(0);
}
void comm_timer_callback(int ATTR_UNUSED(fd),
void comm_timer_callback(int ATTR_UNUSED(fd),
short ATTR_UNUSED(event), void* ATTR_UNUSED(arg))
{
log_assert(0);
}
void comm_signal_callback(int ATTR_UNUSED(fd),
void comm_signal_callback(int ATTR_UNUSED(fd),
short ATTR_UNUSED(event), void* ATTR_UNUSED(arg))
{
log_assert(0);
}
void comm_point_http_handle_callback(int ATTR_UNUSED(fd),
void comm_point_http_handle_callback(int ATTR_UNUSED(fd),
short ATTR_UNUSED(event), void* ATTR_UNUSED(arg))
{
log_assert(0);
}
void comm_point_local_handle_callback(int ATTR_UNUSED(fd),
void comm_point_local_handle_callback(int ATTR_UNUSED(fd),
short ATTR_UNUSED(event), void* ATTR_UNUSED(arg))
{
log_assert(0);
}
void comm_point_raw_handle_callback(int ATTR_UNUSED(fd),
void comm_point_raw_handle_callback(int ATTR_UNUSED(fd),
short ATTR_UNUSED(event), void* ATTR_UNUSED(arg))
{
log_assert(0);
}
void comm_base_handle_slow_accept(int ATTR_UNUSED(fd),
void comm_base_handle_slow_accept(int ATTR_UNUSED(fd),
short ATTR_UNUSED(event), void* ATTR_UNUSED(arg))
{
log_assert(0);
}
int serviced_udp_callback(struct comm_point* ATTR_UNUSED(c),
int serviced_udp_callback(struct comm_point* ATTR_UNUSED(c),
void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
struct comm_reply* ATTR_UNUSED(reply_info))
{
@@ -1530,7 +1517,7 @@ int serviced_udp_callback(struct comm_point* ATTR_UNUSED(c),
return 0;
}
int serviced_tcp_callback(struct comm_point* ATTR_UNUSED(c),
int serviced_tcp_callback(struct comm_point* ATTR_UNUSED(c),
void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
struct comm_reply* ATTR_UNUSED(reply_info))
{
@@ -1563,7 +1550,7 @@ int reuse_id_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
}
/* timers in testbound for autotrust. statistics tested in tdir. */
struct comm_timer* comm_timer_create(struct comm_base* base,
struct comm_timer* comm_timer_create(struct comm_base* base,
void (*cb)(void*), void* cb_arg)
{
struct replay_runtime* runtime = (struct replay_runtime*)base;
@@ -1591,7 +1578,7 @@ void comm_timer_set(struct comm_timer* timer, struct timeval* tv)
struct fake_timer* t = (struct fake_timer*)timer;
t->enabled = 1;
t->tv = *tv;
log_info("fake timer set %d.%6.6d",
log_info("fake timer set %d.%6.6d",
(int)t->tv.tv_sec, (int)t->tv.tv_usec);
timeval_add(&t->tv, &t->runtime->now_tv);
}
+2
View File
@@ -177,6 +177,8 @@ static int readup_str(char** str, FILE* in)
}
buf[len] = 0;
*str = strdup(buf);
if(!*str)
fatal_exit("strdup failed: out of memory");
return 1;
}
+8
View File
@@ -458,9 +458,17 @@ qlist_parse_line(sldns_buffer* buf, char* p)
if(strcmp(tp, "IN") == 0 || strcmp(tp, "CH") == 0) {
qinfo.qtype = sldns_get_rr_type_by_name(cl);
qinfo.qclass = sldns_get_rr_class_by_name(tp);
if((qinfo.qtype == 0 && strcmp(cl, "TYPE0") != 0) ||
(qinfo.qclass == 0 && strcmp(tp, "CLASS0") != 0)) {
return 0;
}
} else {
qinfo.qtype = sldns_get_rr_type_by_name(tp);
qinfo.qclass = sldns_get_rr_class_by_name(cl);
if((qinfo.qtype == 0 && strcmp(tp, "TYPE0") != 0) ||
(qinfo.qclass == 0 && strcmp(cl, "CLASS0") != 0)) {
return 0;
}
}
if(fl[0] == '+') rec = 1;
else if(fl[0] == '-') rec = 0;
+35 -50
View File
@@ -2,24 +2,24 @@
* testcode/replay.c - store and use a replay of events for the DNS resolver.
*
* Copyright (c) 2007, 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
@@ -51,6 +51,7 @@
#include "testcode/testpkts.h"
#include "testcode/fake_event.h"
#include "sldns/str2wire.h"
#include "util/timeval_func.h"
/** max length of lines in file */
#define MAX_LINE_LEN 10240
@@ -59,35 +60,19 @@
* Expand a macro
* @param store: value storage
* @param runtime: replay runtime for other stuff.
* @param text: the macro text, after the ${, Updated to after the } when
* @param text: the macro text, after the ${, Updated to after the } when
* done (successfully).
* @return expanded text, malloced. NULL on failure.
*/
static char* macro_expand(rbtree_type* store,
static char* macro_expand(rbtree_type* store,
struct replay_runtime* runtime, char** text);
/** compare of time values */
static int
timeval_smaller(const struct timeval* x, const struct timeval* y)
{
#ifndef S_SPLINT_S
if(x->tv_sec < y->tv_sec)
return 1;
else if(x->tv_sec == y->tv_sec) {
if(x->tv_usec <= y->tv_usec)
return 1;
else return 0;
}
else return 0;
#endif
}
/** parse keyword in string.
/** parse keyword in string.
* @param line: if found, the line is advanced to after the keyword.
* @param keyword: string.
* @return: true if found, false if not.
* @return: true if found, false if not.
*/
static int
static int
parse_keyword(char** line, const char* keyword)
{
size_t len = (size_t)strlen(keyword);
@@ -135,8 +120,8 @@ strip_end_white(char* p)
}
}
/**
* Read a range from file.
/**
* Read a range from file.
* @param remain: Rest of line (after RANGE keyword).
* @param in: file to read from.
* @param name: name to print in errors.
@@ -181,7 +166,7 @@ replay_range_read(char* remain, FILE* in, const char* name,
strip_end_white(parse);
if(!extstrtoaddr(parse, &rng->addr, &rng->addrlen,
UNBOUND_DNS_PORT)) {
log_err("Line %d: could not read ADDRESS: %s",
log_err("Line %d: could not read ADDRESS: %s",
pstate->lineno, parse);
free(rng);
return NULL;
@@ -255,8 +240,8 @@ read_assign_step(char* remain, struct replay_moment* mom)
fatal_exit("out of memory");
}
/**
* Read a replay moment 'STEP' from file.
/**
* Read a replay moment 'STEP' from file.
* @param remain: Rest of line (after STEP keyword).
* @param in: file to read from.
* @param name: name to print in errors.
@@ -376,18 +361,18 @@ replay_moment_read(char* remain, FILE* in, const char* name,
strip_end_white(remain);
if(!extstrtoaddr(remain, &mom->addr, &mom->addrlen,
UNBOUND_DNS_PORT)) {
log_err("line %d: could not parse ADDRESS: %s",
log_err("line %d: could not parse ADDRESS: %s",
pstate->lineno, remain);
free(mom);
return NULL;
}
}
}
if(parse_keyword(&remain, "ELAPSE")) {
double sec;
errno = 0;
sec = strtod(remain, &remain);
if(sec == 0. && errno != 0) {
log_err("line %d: could not parse ELAPSE: %s (%s)",
log_err("line %d: could not parse ELAPSE: %s (%s)",
pstate->lineno, remain, strerror(errno));
free(mom);
return NULL;
@@ -397,7 +382,7 @@ replay_moment_read(char* remain, FILE* in, const char* name,
mom->elapse.tv_usec = (int)((sec - (double)mom->elapse.tv_sec)
*1000000. + 0.5);
#endif
}
}
if(readentry) {
mom->match = read_entry(in, name, pstate, 1);
@@ -433,7 +418,7 @@ make_scenario(char* line)
return scen;
}
struct replay_scenario*
struct replay_scenario*
replay_scenario_read(FILE* in, const char* name, int* lineno)
{
char line[MAX_LINE_LEN];
@@ -451,7 +436,7 @@ replay_scenario_read(FILE* in, const char* name, int* lineno)
(*lineno)++;
while(isspace((unsigned char)*parse))
parse++;
if(!*parse)
if(!*parse)
continue; /* empty line */
if(parse_keyword(&parse, ";"))
continue; /* comment */
@@ -462,11 +447,11 @@ replay_scenario_read(FILE* in, const char* name, int* lineno)
if(!scen)
fatal_exit("%d: could not make scen", *lineno);
continue;
}
}
if(!scen)
fatal_exit("%d: expected SCENARIO", *lineno);
if(parse_keyword(&parse, "RANGE_BEGIN")) {
struct replay_range* newr = replay_range_read(parse,
struct replay_range* newr = replay_range_read(parse,
in, name, &pstate, line);
if(!newr)
fatal_exit("%d: bad range", pstate.lineno);
@@ -474,12 +459,12 @@ replay_scenario_read(FILE* in, const char* name, int* lineno)
newr->next_range = scen->range_list;
scen->range_list = newr;
} else if(parse_keyword(&parse, "STEP")) {
struct replay_moment* mom = replay_moment_read(parse,
struct replay_moment* mom = replay_moment_read(parse,
in, name, &pstate);
if(!mom)
fatal_exit("%d: bad moment", pstate.lineno);
*lineno = pstate.lineno;
if(scen->mom_last &&
if(scen->mom_last &&
scen->mom_last->time_step >= mom->time_step)
fatal_exit("%d: time goes backwards", *lineno);
if(scen->mom_last)
@@ -502,7 +487,7 @@ replay_scenario_read(FILE* in, const char* name, int* lineno)
return NULL;
}
void
void
replay_scenario_delete(struct replay_scenario* scen)
{
struct replay_moment* mom, *momn;
@@ -630,7 +615,7 @@ do_macro_recursion(rbtree_type* store, struct replay_runtime* runtime,
{
char* after = at+2;
char* expand = macro_expand(store, runtime, &after);
if(!expand)
if(!expand)
return NULL; /* expansion failed */
if(!do_buf_insert(at, remain, after, expand)) {
free(expand);
@@ -665,7 +650,7 @@ do_macro_variable(rbtree_type* store, char* buf, size_t remain)
}
/* terminator, we are working in macro_expand() buffer */
sv = *at;
*at = 0;
*at = 0;
v = macro_getvar(store, name);
*at = sv;
@@ -816,7 +801,7 @@ macro_expand(rbtree_type* store, struct replay_runtime* runtime, char** text)
time_t res = 0;
if(runtime) {
struct fake_timer* t = first_timer(runtime);
if(t && (time_t)t->tv.tv_sec >= runtime->now_secs)
if(t && (time_t)t->tv.tv_sec >= runtime->now_secs)
res = (time_t)t->tv.tv_sec - runtime->now_secs;
}
snprintf(buf, sizeof(buf), ARG_LL "d", (long long)res);
@@ -855,9 +840,9 @@ macro_expand(rbtree_type* store, struct replay_runtime* runtime, char** text)
if(dofunc) {
/* post process functions, buf has the argument(s) */
if(strncmp(buf, "ctime", 5) == 0) {
return do_macro_ctime(buf+6);
return do_macro_ctime(buf+6);
} else if(strncmp(buf, "range", 5) == 0) {
return do_macro_range(buf+6);
return do_macro_range(buf+6);
}
}
return strdup(buf);
@@ -891,7 +876,7 @@ macro_process(rbtree_type* store, struct replay_runtime* runtime, char* text)
return strdup(buf);
}
char*
char*
macro_lookup(rbtree_type* store, char* name)
{
struct replay_var* x = macro_getvar(store, name);
@@ -907,7 +892,7 @@ void macro_print_debug(rbtree_type* store)
}
}
int
int
macro_assign(rbtree_type* store, char* name, char* value)
{
struct replay_var* x = macro_getvar(store, name);
+15 -3
View File
@@ -132,7 +132,15 @@ write_q(int fd, int udp, SSL* ssl, sldns_buffer* buf, uint16_t id,
/* qtype and qclass */
qinfo.qtype = sldns_get_rr_type_by_name(strtype);
if(qinfo.qtype == 0 && strcmp(strtype, "TYPE0") != 0) {
printf("cannot parse query type: '%s'\n", strtype);
exit(1);
}
qinfo.qclass = sldns_get_rr_class_by_name(strclass);
if(qinfo.qclass == 0 && strcmp(strclass, "CLASS0") != 0) {
printf("cannot parse query class: '%s'\n", strclass);
exit(1);
}
/* clear local alias */
qinfo.local_alias = NULL;
@@ -371,15 +379,19 @@ static void
send_em(const char* svr, const char* pp2_client, int udp, int usessl,
int noanswer, int onarrival, int delay, int num, char** qs)
{
sldns_buffer* buf = sldns_buffer_new(65553);
sldns_buffer* proxy_buf = sldns_buffer_new(65553);
struct sockaddr_storage svr_addr;
socklen_t svr_addrlen;
int fd = open_svr(svr, udp, &svr_addr, &svr_addrlen);
int i, wait_results = 0, pp2_parsed;
SSL_CTX* ctx = NULL;
SSL* ssl = NULL;
if(!buf) fatal_exit("out of memory");
sldns_buffer* buf = sldns_buffer_new(65553);
sldns_buffer* proxy_buf = sldns_buffer_new(65553);
if(!buf || !proxy_buf) {
sldns_buffer_free(buf);
sldns_buffer_free(proxy_buf);
fatal_exit("out of memory");
}
pp2_parsed = parse_pp2_client(pp2_client, udp, proxy_buf);
if(usessl) {
ctx = connect_sslctx_create(NULL, NULL, NULL, 0);
+11 -11
View File
@@ -94,7 +94,7 @@ test_bin_find_entry(struct lruhash* table)
bin_overflow_remove(&bin, &k->entry);
/* find in empty list */
unit_assert( bin_find_entry(table, &bin, h, k) == NULL );
unit_assert( bin_find_entry(table, &bin, h, k, NULL) == NULL );
/* insert */
lock_quick_lock(&bin.lock);
@@ -102,20 +102,20 @@ test_bin_find_entry(struct lruhash* table)
lock_quick_unlock(&bin.lock);
/* find, hash not OK. */
unit_assert( bin_find_entry(table, &bin, myhash(13), k) == NULL );
unit_assert( bin_find_entry(table, &bin, myhash(13), k, NULL) == NULL );
/* find, hash OK, but cmp not */
unit_assert( k->entry.hash == k2->entry.hash );
unit_assert( bin_find_entry(table, &bin, h, k2) == NULL );
unit_assert( bin_find_entry(table, &bin, h, k2, NULL) == NULL );
/* find, hash OK, and cmp too */
unit_assert( bin_find_entry(table, &bin, h, k) == &k->entry );
unit_assert( bin_find_entry(table, &bin, h, k, NULL) == &k->entry );
/* remove the element */
lock_quick_lock(&bin.lock);
bin_overflow_remove(&bin, &k->entry);
lock_quick_unlock(&bin.lock);
unit_assert( bin_find_entry(table, &bin, h, k) == NULL );
unit_assert( bin_find_entry(table, &bin, h, k, NULL) == NULL );
/* prepend two different elements; so the list is long */
/* one has the same hash, but different cmp */
@@ -127,28 +127,28 @@ test_bin_find_entry(struct lruhash* table)
lock_quick_unlock(&bin.lock);
/* find, hash not OK. */
unit_assert( bin_find_entry(table, &bin, myhash(13), k) == NULL );
unit_assert( bin_find_entry(table, &bin, myhash(13), k, NULL) == NULL );
/* find, hash OK, but cmp not */
unit_assert( k->entry.hash == k2->entry.hash );
unit_assert( bin_find_entry(table, &bin, h, k2) == NULL );
unit_assert( bin_find_entry(table, &bin, h, k2, NULL) == NULL );
/* find, hash OK, and cmp too */
unit_assert( bin_find_entry(table, &bin, h, k) == &k->entry );
unit_assert( bin_find_entry(table, &bin, h, k, NULL) == &k->entry );
/* remove middle element */
unit_assert( bin_find_entry(table, &bin, k4->entry.hash, k4)
unit_assert( bin_find_entry(table, &bin, k4->entry.hash, k4, NULL)
== &k4->entry );
lock_quick_lock(&bin.lock);
bin_overflow_remove(&bin, &k4->entry);
lock_quick_unlock(&bin.lock);
unit_assert( bin_find_entry(table, &bin, k4->entry.hash, k4) == NULL);
unit_assert( bin_find_entry(table, &bin, k4->entry.hash, k4, NULL) == NULL);
/* remove last element */
lock_quick_lock(&bin.lock);
bin_overflow_remove(&bin, &k->entry);
lock_quick_unlock(&bin.lock);
unit_assert( bin_find_entry(table, &bin, h, k) == NULL );
unit_assert( bin_find_entry(table, &bin, h, k, NULL) == NULL );
lock_quick_destroy(&bin.lock);
delkey(k);
+214
View File
@@ -1040,6 +1040,218 @@ static void respip_test(void)
respip_conf_actions_test();
}
#include "util/regional.h"
#include "sldns/sbuffer.h"
#include "util/data/dname.h"
#include "util/data/msgreply.h"
#include "util/data/msgencode.h"
#include "sldns/str2wire.h"
static void edns_ede_encode_setup(struct edns_data* edns,
struct regional* region)
{
memset(edns, 0, sizeof(*edns));
edns->edns_present = 1;
edns->edns_version = EDNS_ADVERTISED_VERSION;
edns->udp_size = EDNS_ADVERTISED_SIZE;
edns->bits &= EDNS_DO;
/* Fill up opt_list_out with EDEs */
unit_assert(
edns_opt_list_append_ede(&edns->opt_list_out, region,
LDNS_EDE_OTHER, "Too long other text"));
unit_assert(
edns_opt_list_append_ede(&edns->opt_list_out, region,
LDNS_EDE_OTHER, "Too long other text"));
unit_assert(
edns_opt_list_append_ede(&edns->opt_list_out, region,
LDNS_EDE_BLOCKED, "Too long blocked text"));
unit_assert(
edns_opt_list_append_ede(&edns->opt_list_out, region,
LDNS_EDE_OTHER, "Too long other text"));
unit_assert(
edns_opt_list_append_ede(&edns->opt_list_out, region,
LDNS_EDE_BLOCKED, "Too long blocked text"));
/* Fill up opt_list_inplace_cb_out with EDEs */
unit_assert(
edns_opt_list_append_ede(&edns->opt_list_inplace_cb_out, region,
LDNS_EDE_OTHER, "Too long other text"));
unit_assert(
edns_opt_list_append_ede(&edns->opt_list_inplace_cb_out, region,
LDNS_EDE_OTHER, "Too long other text"));
unit_assert(
edns_opt_list_append_ede(&edns->opt_list_inplace_cb_out, region,
LDNS_EDE_BLOCKED, "Too long blocked text"));
unit_assert(
edns_opt_list_append_ede(&edns->opt_list_inplace_cb_out, region,
LDNS_EDE_OTHER, "Too long other text"));
unit_assert(
edns_opt_list_append_ede(&edns->opt_list_inplace_cb_out, region,
LDNS_EDE_BLOCKED, "Too long blocked text"));
/* append another EDNS option to both lists */
unit_assert(
edns_opt_list_append(&edns->opt_list_out,
LDNS_EDNS_UNBOUND_CACHEDB_TESTFRAME_TEST, 0, NULL, region));
unit_assert(
edns_opt_list_append(&edns->opt_list_inplace_cb_out,
LDNS_EDNS_UNBOUND_CACHEDB_TESTFRAME_TEST, 0, NULL, region));
/* append LDNS_EDE_OTHER at the end of both lists */
unit_assert(
edns_opt_list_append_ede(&edns->opt_list_out, region,
LDNS_EDE_OTHER, "Too long other text"));
unit_assert(
edns_opt_list_append_ede(&edns->opt_list_inplace_cb_out, region,
LDNS_EDE_OTHER, "Too long other text"));
}
static void edns_ede_encode_encodedecode(struct query_info* qinfo,
struct reply_info* rep, struct regional* region,
struct edns_data* edns, sldns_buffer* pkt)
{
/* encode */
unit_assert(
reply_info_answer_encode(qinfo, rep, 1, rep->flags, pkt,
0, 0, region, 65535, edns, 0, 0));
/* buffer ready for reading; skip after the question section */
sldns_buffer_skip(pkt, LDNS_HEADER_SIZE);
(void)query_dname_len(pkt);
sldns_buffer_skip(pkt, 2 + 2);
/* decode */
unit_assert(parse_edns_from_query_pkt(pkt, edns, NULL, NULL, NULL, 0,
region) == 0);
}
static void edns_ede_encode_check(struct edns_data* edns, int* found_ede,
int* found_ede_other, int* found_ede_txt, int* found_other_edns)
{
struct edns_option* opt;
for(opt = edns->opt_list_in; opt; opt = opt->next) {
if(opt->opt_code == LDNS_EDNS_EDE) {
(*found_ede)++;
if(opt->opt_len > 2)
(*found_ede_txt)++;
if(opt->opt_len >= 2 && sldns_read_uint16(
opt->opt_data) == LDNS_EDE_OTHER)
(*found_ede_other)++;
} else {
(*found_other_edns)++;
}
}
}
static void edns_ede_encode_fit_test(struct query_info* qinfo,
struct reply_info* rep, struct regional* region)
{
struct edns_data edns;
int found_ede = 0, found_ede_other = 0, found_ede_txt = 0;
int found_other_edns = 0;
sldns_buffer* pkt = sldns_buffer_new(65535);
unit_assert(pkt);
edns_ede_encode_setup(&edns, region);
/* leave the pkt buffer as is; everything should fit */
edns_ede_encode_encodedecode(qinfo, rep, region, &edns, pkt);
edns_ede_encode_check(&edns, &found_ede, &found_ede_other,
&found_ede_txt, &found_other_edns);
unit_assert(found_ede == 12);
unit_assert(found_ede_other == 8);
unit_assert(found_ede_txt == 12);
unit_assert(found_other_edns == 2);
/* cleanup */
sldns_buffer_free(pkt);
}
static void edns_ede_encode_notxt_fit_test( struct query_info* qinfo,
struct reply_info* rep, struct regional* region)
{
struct edns_data edns;
sldns_buffer* pkt;
uint16_t edns_field_size, ede_txt_size;
int found_ede = 0, found_ede_other = 0, found_ede_txt = 0;
int found_other_edns = 0;
edns_ede_encode_setup(&edns, region);
/* pkt buffer should fit everything if the ede txt is cropped.
* OTHER EDE should not be there since it is useless without text. */
edns_field_size = calc_edns_field_size(&edns);
(void)calc_ede_option_size(&edns, &ede_txt_size);
pkt = sldns_buffer_new(LDNS_HEADER_SIZE
+ qinfo->qname_len
+ 2 + 2 /* qtype + qclass */
+ 11 /* opt record */
+ edns_field_size
- ede_txt_size);
unit_assert(pkt);
edns_ede_encode_encodedecode(qinfo, rep, region, &edns, pkt);
edns_ede_encode_check(&edns, &found_ede, &found_ede_other,
&found_ede_txt, &found_other_edns);
unit_assert(found_ede == 4);
unit_assert(found_ede_other == 0);
unit_assert(found_ede_txt == 0);
unit_assert(found_other_edns == 2);
/* cleanup */
sldns_buffer_free(pkt);
}
static void edns_ede_encode_no_fit_test( struct query_info* qinfo,
struct reply_info* rep, struct regional* region)
{
struct edns_data edns;
sldns_buffer* pkt;
uint16_t edns_field_size, ede_size, ede_txt_size;
int found_ede = 0, found_ede_other = 0, found_ede_txt = 0;
int found_other_edns = 0;
edns_ede_encode_setup(&edns, region);
/* pkt buffer should fit only non-EDE options. */
edns_field_size = calc_edns_field_size(&edns);
ede_size = calc_ede_option_size(&edns, &ede_txt_size);
pkt = sldns_buffer_new(LDNS_HEADER_SIZE
+ qinfo->qname_len
+ 2 + 2 /* qtype + qclass */
+ 11 /* opt record */
+ edns_field_size
- ede_size);
unit_assert(pkt);
edns_ede_encode_encodedecode(qinfo, rep, region, &edns, pkt);
edns_ede_encode_check(&edns, &found_ede, &found_ede_other,
&found_ede_txt, &found_other_edns);
unit_assert(found_ede == 0);
unit_assert(found_ede_other == 0);
unit_assert(found_ede_txt == 0);
unit_assert(found_other_edns == 2);
/* cleanup */
sldns_buffer_free(pkt);
}
/** test optional EDE encoding with various buffer
* available sizes */
static void edns_ede_answer_encode_test(void)
{
struct regional* region = regional_create();
struct reply_info* rep;
struct query_info qinfo;
unit_show_feature("edns ede optional encoding");
unit_assert(region);
rep = construct_reply_info_base(region,
LDNS_RCODE_NOERROR | BIT_QR, 1,
3600, 3600, 3600,
0, 0, 0, 0,
sec_status_unchecked, LDNS_EDE_NONE);
unit_assert(rep);
memset(&qinfo, 0, sizeof(qinfo));
qinfo.qname = sldns_str2wire_dname("encode.ede.", &qinfo.qname_len);
unit_assert(qinfo.qname);
qinfo.qtype = LDNS_RR_TYPE_TXT;
qinfo.qclass = LDNS_RR_CLASS_IN;
edns_ede_encode_fit_test(&qinfo, rep, region);
edns_ede_encode_notxt_fit_test(&qinfo, rep, region);
edns_ede_encode_no_fit_test(&qinfo, rep, region);
/* cleanup */
free(qinfo.qname);
regional_free_all(region);
regional_destroy(region);
}
void unit_show_func(const char* file, const char* func)
{
printf("test %s:%s\n", file, func);
@@ -1053,6 +1265,7 @@ void unit_show_feature(const char* 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.
@@ -1111,6 +1324,7 @@ main(int argc, char* argv[])
zonemd_test();
tcpreuse_test();
msgparse_test();
edns_ede_answer_encode_test();
#ifdef CLIENT_SUBNET
ecs_test();
#endif /* CLIENT_SUBNET */