-
Notifications
You must be signed in to change notification settings - Fork 424
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Preserve EDNS OPT record in a response if truncation occurs #1364
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,7 +16,6 @@ | |
|
||
//! Basic protocol message for DNS | ||
|
||
use std::iter; | ||
use std::mem; | ||
use std::ops::Deref; | ||
use std::sync::Arc; | ||
|
@@ -769,6 +768,23 @@ where | |
N: EmitAndCount, | ||
D: EmitAndCount, | ||
{ | ||
let real_encoder_max_size = encoder.max_size(); | ||
if let Some(edns) = edns { | ||
// From RFC 6891 section-7: | ||
// The minimal response MUST be the DNS header, question section, and an | ||
// OPT record. This MUST also occur when a truncated response (using | ||
// the DNS header's TC bit) is returned. | ||
// Hence, we reserve some space for the EDNS OPT record | ||
encoder.set_max_size(match real_encoder_max_size.checked_sub(edns.len()) { | ||
Some(size) => size, | ||
None => { | ||
return Err( | ||
ProtoErrorKind::MaxBufferSizeExceeded(real_encoder_max_size as usize).into(), | ||
) | ||
} | ||
}); | ||
} | ||
|
||
let include_sig0: bool = encoder.mode() != EncodeMode::Signing; | ||
let place = encoder.place::<Header>()?; | ||
|
||
|
@@ -780,10 +796,10 @@ where | |
let mut additional_count = count_was_truncated(additionals.emit(encoder))?; | ||
|
||
if let Some(edns) = edns { | ||
encoder.set_max_size(real_encoder_max_size); | ||
// need to commit the error code | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What does this comment mean btw? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that is referring to the fact that the response error code may need to be committed to the EDNS record... i.e. in EDNS the response (error code) is has high-order bits stored in the EDNS record that augment those in the original DNS Header. So I think that's what this may be talking about... |
||
let count = count_was_truncated(encoder.emit_all(iter::once(&Record::from(edns))))?; | ||
additional_count.0 += count.0; | ||
additional_count.1 |= count.1; | ||
Record::from(edns).emit(encoder)?; | ||
additional_count.0 += 1; | ||
} | ||
|
||
// this is a little hacky, but if we are Verifying a signature, i.e. the original Message | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we should consider adding some consts for these things, or perhaps instead use
std::mem::size_of
It would make the code a bit more self-documenting. Thoughts?I know we have a similar practice elsewhere in the code, maybe I'll file a cleanup issue for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, could we use
EncodedSize
for this?Let's do this in another PR anyway