resolved: don't append RFC6975 data to stub replies

We previously checked the QR bit to decide whether the RFC6975 algorithm
data in our packets. But that doesn't work in many cases, since we
initialize the QR flags along with the other flags usually only after
appending OPT (since success to do so propagates into flags). Hence,
let's add an explicit parameter that controls whether to include RFC6975
data in DNS packets, and set it to false for stub reply, and on true for
upstream queries.

Fixes: #17217
This commit is contained in:
Lennart Poettering 2020-10-09 16:47:34 +02:00 committed by Zbigniew Jędrzejewski-Szmek
parent 5fa661a4fb
commit c36d5b5be9
4 changed files with 15 additions and 6 deletions

View File

@ -689,7 +689,14 @@ fail:
}
/* Append the OPT pseudo-RR described in RFC6891 */
int dns_packet_append_opt(DnsPacket *p, uint16_t max_udp_size, bool edns0_do, int rcode, size_t *start) {
int dns_packet_append_opt(
DnsPacket *p,
uint16_t max_udp_size,
bool edns0_do,
bool include_rfc6975,
int rcode,
size_t *start) {
size_t saved_size;
int r;
@ -732,8 +739,10 @@ int dns_packet_append_opt(DnsPacket *p, uint16_t max_udp_size, bool edns0_do, in
goto fail;
/* RDLENGTH */
if (edns0_do && !DNS_PACKET_QR(p)) {
/* If DO is on and this is not a reply, also append RFC6975 Algorithm data */
if (edns0_do && include_rfc6975) {
/* If DO is on and this is requested, also append RFC6975 Algorithm data. This is supposed to
* be done on queries, not on replies, hencer callers should turn this off when finishing off
* replies. */
static const uint8_t rfc6975[] = {

View File

@ -198,7 +198,7 @@ int dns_packet_append_label(DnsPacket *p, const char *s, size_t l, bool canonica
int dns_packet_append_name(DnsPacket *p, const char *name, bool allow_compression, bool canonical_candidate, size_t *start);
int dns_packet_append_key(DnsPacket *p, const DnsResourceKey *key, const DnsAnswerFlags flags, size_t *start);
int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, const DnsAnswerFlags flags, size_t *start, size_t *rdata_start);
int dns_packet_append_opt(DnsPacket *p, uint16_t max_udp_size, bool edns0_do, int rcode, size_t *start);
int dns_packet_append_opt(DnsPacket *p, uint16_t max_udp_size, bool edns0_do, bool include_rfc6975, int rcode, size_t *start);
int dns_packet_append_question(DnsPacket *p, DnsQuestion *q);
int dns_packet_append_answer(DnsPacket *p, DnsAnswer *a);

View File

@ -535,7 +535,7 @@ int dns_server_adjust_opt(DnsServer *server, DnsPacket *packet, DnsServerFeature
else
packet_size = server->received_udp_packet_max;
return dns_packet_append_opt(packet, packet_size, edns_do, 0, NULL);
return dns_packet_append_opt(packet, packet_size, edns_do, /* include_rfc6975 = */ true, 0, NULL);
}
int dns_server_ifindex(const DnsServer *s) {

View File

@ -162,7 +162,7 @@ static int dns_stub_finish_reply_packet(
assert(p);
if (add_opt) {
r = dns_packet_append_opt(p, ADVERTISE_DATAGRAM_SIZE_MAX, edns0_do, rcode, NULL);
r = dns_packet_append_opt(p, ADVERTISE_DATAGRAM_SIZE_MAX, edns0_do, /* include_rfc6975 = */ false, rcode, NULL);
if (r == -EMSGSIZE) /* Hit the size limit? then indicate truncation */
tc = true;
else if (r < 0)