diff --git a/src/analyzer/protocol/dns/DNS.cc b/src/analyzer/protocol/dns/DNS.cc index 58b0444b32..99c87c44e4 100644 --- a/src/analyzer/protocol/dns/DNS.cc +++ b/src/analyzer/protocol/dns/DNS.cc @@ -713,7 +713,7 @@ bool DNS_Interpreter::ParseRR_EDNS(DNS_MsgInfo* msg, uint16_t option_code = ExtractShort(data, len); int option_len = ExtractShort(data, len); // check for invalid option length - if ( (option_len > len) || (0 == option_len) ) { + if ( (option_len > len) ) { break; } len -= option_len; @@ -786,39 +786,36 @@ bool DNS_Interpreter::ParseRR_EDNS(DNS_MsgInfo* msg, case TYPE_TCP_KA: { - EDNS_TCP_KEEPALIVE edns_tcp_keepalive{ - .keepalive_timeout_omitted = true, - .keepalive_timeout = 0 - - }; - if ( option_len == 0 || option_len == 2) - { - // 0 bytes is permitted by RFC 7828, showing that the timeout value is missing. - if (option_len == 2) { - edns_tcp_keepalive.keepalive_timeout = ExtractShort(data, option_len); - edns_tcp_keepalive.keepalive_timeout_omitted = false; - } + EDNS_TCP_KEEPALIVE edns_tcp_keepalive{ + .keepalive_timeout_omitted = true, + .keepalive_timeout = 0 + }; + if ( option_len == 0 || option_len == 2) + { + // 0 bytes is permitted by RFC 7828, showing that the timeout value is missing. + if (option_len == 2) { + edns_tcp_keepalive.keepalive_timeout = ExtractShort(data, option_len); + edns_tcp_keepalive.keepalive_timeout_omitted = false; + } - if (analyzer->Conn()->ConnTransport() == TRANSPORT_UDP) { - /* - * Based on RFC 7828, clients and servers MUST NOT negotiate - * TCP Keepalive timeout in DNS-over-UDP. - * Record in Weird and proceed to the next EDNS option - */ - analyzer->Weird("EDNS_TCP_Keepalive_Record_In_UDP"); - break; - } - analyzer->EnqueueConnEvent(dns_EDNS_tcp_keepalive, - analyzer->ConnVal(), - msg->BuildHdrVal(), - msg->BuildEDNS_TCP_KA_Val(&edns_tcp_keepalive) - ); - break; - } - else - { - break; // error. MUST BE 0 or 2 bytes - } + if (analyzer->Conn()->ConnTransport() == TRANSPORT_UDP) { + /* + * Based on RFC 7828 (3.2.1/3.2.2), clients and servers MUST NOT + * negotiate TCP Keepalive timeout in DNS-over-UDP. + */ + analyzer->Weird("EDNS_TCP_Keepalive_Record_In_UDP"); + } + analyzer->EnqueueConnEvent(dns_EDNS_tcp_keepalive, + analyzer->ConnVal(), + msg->BuildHdrVal(), + msg->BuildEDNS_TCP_KA_Val(&edns_tcp_keepalive) + ); + break; + } + else + { + break; // error. MUST BE 0 or 2 bytes + } } // END EDNS TCP KEEPALIVE default: diff --git a/testing/btest/Baseline/scripts.base.protocols.dns.dns-edns-tcp-keepalive/output b/testing/btest/Baseline/scripts.base.protocols.dns.dns-edns-tcp-keepalive/output new file mode 100644 index 0000000000..1372490c4c --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.dns.dns-edns-tcp-keepalive/output @@ -0,0 +1,4 @@ +[keepalive_timeout_omitted=F, keepalive_timeout=10] +[keepalive_timeout_omitted=F, keepalive_timeout=370] +[keepalive_timeout_omitted=T, keepalive_timeout=0] +[keepalive_timeout_omitted=F, keepalive_timeout=370] \ No newline at end of file diff --git a/testing/btest/Traces/dns-edns-tcp-keepalive.pcap b/testing/btest/Traces/dns-edns-tcp-keepalive.pcap new file mode 100644 index 0000000000..07b5ab1581 Binary files /dev/null and b/testing/btest/Traces/dns-edns-tcp-keepalive.pcap differ diff --git a/testing/btest/scripts/base/protocols/dns/dns-edns-tcp-keepalive.zeek b/testing/btest/scripts/base/protocols/dns/dns-edns-tcp-keepalive.zeek new file mode 100644 index 0000000000..2291bc68fe --- /dev/null +++ b/testing/btest/scripts/base/protocols/dns/dns-edns-tcp-keepalive.zeek @@ -0,0 +1,8 @@ +# @TEST-EXEC: zeek -C -r $TRACES/dns-edns-tcp-keepalive.pcap %INPUT > output +# @TEST-EXEC: btest-diff output +@load policy/protocols/dns/auth-addl + +event dns_EDNS_tcp_keepalive(c: connection, msg: dns_msg, opt: dns_edns_tcp_keepalive) + { + print opt; + } \ No newline at end of file