return 0;
/* see if any of the pending queries matches */
for(p = runtime->pending_list; p; p = p->next) {
+ if(runtime->now->addrlen != 0 &&
+ sockaddr_cmp(&p->addr, p->addrlen, &runtime->now->addr,
+ runtime->now->addrlen) != 0)
+ continue;
if((e=find_match(runtime->now->match, p->pkt, p->transport))) {
*entry = e;
*pend = p;
struct replay_range* p = runtime->scenario->range_list;
while(p) {
if(p->start_step <= timenow && timenow <= p->end_step &&
+ (p->addrlen == 0 || sockaddr_cmp(&p->addr, p->addrlen,
+ &pend->addr, pend->addrlen) == 0) &&
(*entry = find_match(p->match, pend->pkt, pend->transport))) {
log_info("matched query time %d in range [%d, %d] "
"with entry line %d", timenow,
p->start_step, p->end_step, (*entry)->lineno);
+ if(p->addrlen != 0)
+ log_addr("matched ip", &p->addr, p->addrlen);
return 1;
}
p = p->next_range;
struct fake_pending* p = runtime->pending_list;
/* slow, O(N*N), but it works as advertised with weird matching */
while(p) {
+ log_info("check of pending");
if(pending_find_match(runtime, entry, p)) {
*pend = p;
return 1;
{
struct comm_point c;
struct comm_reply repinfo;
+ void* cb_arg = pend->cb_arg;
+ comm_point_callback_t* cb = pend->callback;
+
memset(&c, 0, sizeof(c));
c.fd = -1;
c.buffer = ldns_buffer_new(runtime->bufsize);
repinfo.c = &c;
repinfo.addrlen = pend->addrlen;
memcpy(&repinfo.addr, &pend->addr, pend->addrlen);
- if((*pend->callback)(&c, pend->cb_arg, NETEVENT_NOERROR, &repinfo)) {
+ if(!pend->serviced)
+ pending_list_delete(runtime, pend);
+ if((*cb)(&c, cb_arg, NETEVENT_NOERROR, &repinfo)) {
fatal_exit("testbound: unexpected: callback returned 1");
}
ldns_buffer_free(c.buffer);
- pending_list_delete(runtime, pend);
}
/** Check the now moment answer check event */
enum transport_type tr = transport_tcp;
if(ans->repinfo.c->type == comm_udp)
tr = transport_udp;
- if(find_match(runtime->now->match, ans->pkt, tr)) {
+ if((runtime->now->addrlen == 0 || sockaddr_cmp(
+ &runtime->now->addr, runtime->now->addrlen,
+ &ans->repinfo.addr, ans->repinfo.addrlen) == 0) &&
+ find_match(runtime->now->match, ans->pkt, tr)) {
struct replay_answer *n = ans->next;
log_info("testbound matched event entry from line %d",
runtime->now->match->lineno);
memset(&repinfo, 0, sizeof(repinfo));
repinfo.c = (struct comm_point*)calloc(1, sizeof(struct comm_point));
repinfo.addrlen = (socklen_t)sizeof(struct sockaddr_in);
+ if(todo->addrlen != 0) {
+ repinfo.addrlen = todo->addrlen;
+ memcpy(&repinfo.addr, &todo->addr, todo->addrlen);
+ }
repinfo.c->fd = -1;
repinfo.c->ev = (struct internal_event*)runtime;
repinfo.c->buffer = ldns_buffer_new(runtime->bufsize);
} while(runtime->now);
if(runtime->pending_list) {
+ struct fake_pending* p;
+ log_err("testbound: there are still messages pending.");
+ for(p = runtime->pending_list; p; p=p->next)
+ log_pkt("pending msg", p->pkt);
fatal_exit("testbound: there are still messages pending.");
}
if(runtime->answer_list) {
pend->timeout = timeout/1000;
pend->transport = transport_udp;
pend->pkt = NULL;
+ pend->serviced = 0;
pend->runtime = runtime;
status = ldns_buffer2pkt_wire(&pend->pkt, packet);
if(status != LDNS_STATUS_OK) {
/* see if it matches the current moment */
if(runtime->now && runtime->now->evt_type == repevt_back_query &&
+ (runtime->now->addrlen == 0 || sockaddr_cmp(
+ &runtime->now->addr, runtime->now->addrlen,
+ &pend->addr, pend->addrlen) == 0) &&
find_match(runtime->now->match, pend->pkt, pend->transport)) {
log_info("testbound: matched pending to event. "
"advance time between events.");
pend->transport = transport_tcp;
pend->pkt = NULL;
pend->runtime = runtime;
+ pend->serviced = 0;
status = ldns_buffer2pkt_wire(&pend->pkt, packet);
if(status != LDNS_STATUS_OK) {
log_err("ldns error parsing tcp output packet: %s",
/* see if it matches the current moment */
if(runtime->now && runtime->now->evt_type == repevt_back_query &&
+ (runtime->now->addrlen == 0 || sockaddr_cmp(
+ &runtime->now->addr, runtime->now->addrlen,
+ &pend->addr, pend->addrlen) == 0) &&
find_match(runtime->now->match, pend->pkt, pend->transport)) {
log_info("testbound: matched pending to event. "
"advance time between events.");
pend->transport = transport_udp; /* pretend UDP */
pend->pkt = NULL;
pend->runtime = runtime;
+ pend->serviced = 1;
status = ldns_buffer2pkt_wire(&pend->pkt, pend->buffer);
if(status != LDNS_STATUS_OK) {
log_err("ldns error parsing serviced output packet: %s",
/* see if it matches the current moment */
if(runtime->now && runtime->now->evt_type == repevt_back_query &&
+ (runtime->now->addrlen == 0 || sockaddr_cmp(
+ &runtime->now->addr, runtime->now->addrlen,
+ &pend->addr, pend->addrlen) == 0) &&
find_match(runtime->now->match, pend->pkt, pend->transport)) {
log_info("testbound: matched pending to event. "
"advance time between events.");
while(p) {
if(p == pend) {
log_assert(p->cb_arg == cb_arg);
+ log_info("serviced pending delete");
if(prev)
prev->next = p->next;
else runtime->pending_list = p->next;
- log_pkt("deleted pending serviced query.", p->pkt);
ldns_buffer_free(p->buffer);
ldns_pkt_free(p->pkt);
free(p);
prev = p;
p = p->next;
}
- log_pkt("double delet of pending serviced query", p->pkt);
+ log_info("double delete of pending serviced query");
}
struct listen_port* listening_ports_open(struct config_file* ATTR_UNUSED(cfg))
--- /dev/null
+; config options
+stub-zone:
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test resolution with recursion for NS target.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION AUTHORITY
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.net.
+ENTRY_END
+RANGE_END
+
+; e.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.12.94.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+RANGE_END
+
+; ns.example.net.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.44
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION ANSWER
+ns.example.net. IN A 1.2.3.44
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+www.example.net. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net IN A 1.2.3.44
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.net.
+; scrubbed off
+;SECTION ADDITIONAL
+;ns.example.net IN A 1.2.3.44
+ENTRY_END
+
+; due to ordering of answer packets, this is still outstanding, remove it
+STEP 21 CHECK_OUT_QUERY
+ENTRY_BEGIN
+ADJUST copy_id
+MATCH qname qtype
+REPLY QR
+SECTION QUESTION
+ns.example.net IN AAAA
+ENTRY_END
+
+SCENARIO_END