- Error if EDNS Keepalive received over UDP.

implement and add test.


git-svn-id: file:///svn/unbound/trunk@4803 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2018-07-31 07:16:25 +00:00
parent 007123ee2c
commit 6da37e5ecd
2 changed files with 131 additions and 23 deletions

View file

@ -1246,29 +1246,52 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
server_stats_insrcode(&worker->stats, c->buffer);
goto send_reply;
}
if(edns.edns_present && edns.edns_version != 0) {
edns.ext_rcode = (uint8_t)(EDNS_RCODE_BADVERS>>4);
edns.edns_version = EDNS_ADVERTISED_VERSION;
edns.udp_size = EDNS_ADVERTISED_SIZE;
edns.bits &= EDNS_DO;
edns.opt_list = NULL;
verbose(VERB_ALGO, "query with bad edns version.");
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
error_encode(c->buffer, EDNS_RCODE_BADVERS&0xf, &qinfo,
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
sldns_buffer_read_u16_at(c->buffer, 2), NULL);
if(sldns_buffer_capacity(c->buffer) >=
sldns_buffer_limit(c->buffer)+calc_edns_field_size(&edns))
attach_edns_record(c->buffer, &edns);
regional_free_all(worker->scratchpad);
goto send_reply;
}
if(edns.edns_present && edns.udp_size < NORMAL_UDP_SIZE &&
worker->daemon->cfg->harden_short_bufsize) {
verbose(VERB_QUERY, "worker request: EDNS bufsize %d ignored",
(int)edns.udp_size);
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
edns.udp_size = NORMAL_UDP_SIZE;
if(edns.edns_present) {
struct edns_option* edns_opt;
if(edns.edns_version != 0) {
edns.ext_rcode = (uint8_t)(EDNS_RCODE_BADVERS>>4);
edns.edns_version = EDNS_ADVERTISED_VERSION;
edns.udp_size = EDNS_ADVERTISED_SIZE;
edns.bits &= EDNS_DO;
edns.opt_list = NULL;
verbose(VERB_ALGO, "query with bad edns version.");
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
error_encode(c->buffer, EDNS_RCODE_BADVERS&0xf, &qinfo,
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
sldns_buffer_read_u16_at(c->buffer, 2), NULL);
if(sldns_buffer_capacity(c->buffer) >=
sldns_buffer_limit(c->buffer)+calc_edns_field_size(&edns))
attach_edns_record(c->buffer, &edns);
regional_free_all(worker->scratchpad);
goto send_reply;
}
if(edns.udp_size < NORMAL_UDP_SIZE &&
worker->daemon->cfg->harden_short_bufsize) {
verbose(VERB_QUERY, "worker request: EDNS bufsize %d ignored",
(int)edns.udp_size);
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
edns.udp_size = NORMAL_UDP_SIZE;
}
edns_opt = edns_opt_list_find(edns.opt_list, LDNS_EDNS_KEEPALIVE);
if(edns_opt && c->type != comm_udp) {
if(edns_opt->opt_len > 0) {
edns.ext_rcode = 0;
edns.edns_version = EDNS_ADVERTISED_VERSION;
edns.udp_size = EDNS_ADVERTISED_SIZE;
edns.bits &= EDNS_DO;
edns.opt_list = NULL;
verbose(VERB_ALGO, "query with bad edns keepalive.");
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
error_encode(c->buffer, LDNS_RCODE_FORMERR, &qinfo,
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
sldns_buffer_read_u16_at(c->buffer, 2), NULL);
if(sldns_buffer_capacity(c->buffer) >=
sldns_buffer_limit(c->buffer)+calc_edns_field_size(&edns))
attach_edns_record(c->buffer, &edns);
regional_free_all(worker->scratchpad);
goto send_reply;
}
}
}
if(edns.udp_size > worker->daemon->cfg->max_udp_size &&
c->type == comm_udp) {

85
testdata/edns_keepalive.rpl vendored Normal file
View file

@ -0,0 +1,85 @@
server:
verbosity: 3
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN TCP Keepalive
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
RANGE_END
;; ----------------------------------------
STEP 1 QUERY
ENTRY_BEGIN
MATCH TCP ednsdata
REPLY RD
SECTION QUESTION
www.example.com. IN A
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
00 0b ; Opcode 11
00 02 ; Length 2
00 ff ; Timeout
HEX_EDNSDATA_END
ENTRY_END
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH TCP ednsdata
REPLY RD FORMERR
SECTION QUESTION
www.example.com. IN A
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
; Empty
HEX_EDNSDATA_END
ENTRY_END
STEP 20 QUERY
ENTRY_BEGIN
MATCH TCP ednsdata
REPLY RD
SECTION QUESTION
. IN NS
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
00 0b ; Opcode 11
00 00 ; Length 0
HEX_EDNSDATA_END
ENTRY_END
STEP 30 CHECK_ANSWER
ENTRY_BEGIN
MATCH TCP ednsdata
REPLY QR RD RA 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
SCENARIO_END