-
Notifications
You must be signed in to change notification settings - Fork 33
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
Fix default settings of queries #1397
Conversation
lib/Zonemaster/Engine/Nameserver.pm
Outdated
if ( $flags{q{dnssec}} ) { | ||
$flags{q{edns_size}} = $href->{q{edns_size}} // $UDP_EDNS_QUERY_DEFAULT; | ||
} | ||
else { | ||
$flags{q{edns_size}} = $href->{q{edns_size}} // 0; | ||
} |
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.
The value must no be larger than 64 kB. If the value is smaller than 512 it must be treated as 512. Maybe we will create a test case where it is set smaller.
Is it possible by this code to create a non-DNSSEC EDNS query without specifying the size and get the default?
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've entirely reworked this PR, it should now align with our expectations. Please see commit 2566bcc (description and unit tests, in particular)
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 agree that it doesn’t make much sense to set a value larger than 65 535. I suggest to croak
in this situation.
However, if the argument is 512 or lower, we have two options:
- be a good citizen, not expose bugs in other people’s nameservers, log a warning on our side and force the value to be 512;
- or, on the contrary, allow ourselves to send EDNS queries with silly buffer size values and see how other servers respond to that.
How should we proceed?
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've added a check for both lower (0) and upper (65535) bounds for this parameter.
Unit tests data need to be re-recorded. I'll switch this PR to a draft state in the meantime. |
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.
Looking pretty good already. Just some minor issues with the updated POD.
lib/Zonemaster/Engine/Nameserver.pm
Outdated
if ( $flags{q{dnssec}} ) { | ||
$flags{q{edns_size}} = $href->{q{edns_size}} // $UDP_EDNS_QUERY_DEFAULT; | ||
} | ||
else { | ||
$flags{q{edns_size}} = $href->{q{edns_size}} // 0; | ||
} |
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 agree that it doesn’t make much sense to set a value larger than 65 535. I suggest to croak
in this situation.
However, if the argument is 512 or lower, we have two options:
- be a good citizen, not expose bugs in other people’s nameservers, log a warning on our side and force the value to be 512;
- or, on the contrary, allow ourselves to send EDNS queries with silly buffer size values and see how other servers respond to that.
How should we proceed?
The EDNS UDP buffer size is a 16-bit value. If the code tries to set something larger than that I think the code should "crash". This would only come from bad (Zonemaster) code. If we ever want to set something lower than 512 we must permit that. We do not have such use case today, so I suggest that the code should "crash" so that we do not try to do the wrong thing. |
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’ve made bad suggestions and I apologize. It turns out that the >
in those ->
I made you add needed escaping. My new suggestions are correct: I’ve actually tested them with perldoc
.
fbc11e9
to
52bc120
Compare
@matsduf @marc-vanderwal @mattias-p This PR is now ready for review. Unit tests have been re-recorded where applicable, comments have been adressed, and it has been rebased on top of #1398 (commit e9060d1) so that the CI can pass. |
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.
Besides some detailed comments it looks fine.
} | ||
|
||
croak "edns_size (or edns_details->size) parameter must be a value between 0 and 65535" if $edns_size > 65535 or $edns_size < 0; |
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.
croak "edns_size (or edns_details->size) parameter must be a value between 0 and 65535" if $edns_size > 65535 or $edns_size < 0; | |
croak "edns_size (or edns_details->size) parameter must be 0 (no EDNS) or a value between 512 and 65535" if $edns_size != 0 and ($edns_size > 65535 or $edns_size < 512); |
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.
Today we have no use cases for values 1-511. Any such value would today be a mistake and it would be better to catch those. For EDNS 0-511 is defined to mean the same thing as 512. If we ever want to check for servers handling small values we could always change the logic.
One could also argue that high values would never be used. We have today no use cases for high values. From that perspective it could be argued that the code should set a limit to catch mistakes.
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'm not sure that it is really needed to have such "subjective" checks. These are still "valid" values in the sense that the underlying library (LDNS) will accept them. I don't think we should impose those to us, or to any other user of Zonemaster-Engine.
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.
OK.
Set the EDNS0 UDP maximum size. The value must be comprised between 0 and 65535. | ||
Defaults to 0, or 512 if the query is a non-DNSSEC EDNS query, or 1232 if the query is a DNSSEC query. |
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.
Set the EDNS0 UDP maximum size. The value must be comprised between 0 and 65535. | |
Defaults to 0, or 512 if the query is a non-DNSSEC EDNS query, or 1232 if the query is a DNSSEC query. | |
Set the EDNS0 UDP requestor's maximum size. The value must be 0 or comprised between 512 and 65535 (inclusive). | |
Defaults to 0 (non-EDNS query), or 512 (non-DNSSEC EDNS query), or 1232 (DNSSEC query). |
The merge-base changed after approval.
Due to an oversight in a previous refactoring, all non-DNSSEC DNS queries sent by Zonemaster became EDNS queries. This commit makes it so that those queries are now non-EDNS queries. Default EDNS0 packet size values will now be properly used when appropriate, and a new, missing one has been created for DNSSEC. The caching logic of queries was also impacted. Simply put, a DNSSEC query using the default EDNS0 packet size of 1232 is made by setting parameter "dnssec" and/or "edns_details{do}" (the latter has precedence). For a non-DNSSEC EDNS query, setting parameter "edns_size" and/or "edns_details{size}" (the latter has precedence) will do the trick, but then it will use the provided value for the EDNS0 packet size. To use the default value of 512, just set parameter "edns_details" with an empty hash (or non-empty with any of its subkey(s) other than edns_details{do,size}) instead. - Fix logic related to flags dnssec and edns_size for when to use default values, and also when combined with edns_details - Fix caching logic when using dnssec and edns_size parameters - Make combined usage of dnssec with edns_details but without edns_details{do} to correctly set the dnssec (DO) flag - Removed uneeded code related to resetting flags between queries (- it was already done earlier in the same method) - Add constant UDP_DNSSEC_QUERY_DEFAULT (set to 1232) - Rename constant UDP_COMMON_EDNS_LIMIT to UDP_EDNS_COMMON_LIMIT - Add and update documentation - Add unit tests
…::Nameserver->query() The maximum value for this parameter, set either by "edns_size" or "edns_details->size", is a 16-bit value, thus it should not exceed 65535. Documentation and unit tests are updated too.
…::Nameserver->query() This parameter, set either by "edns_size" or "edns_details->size", is an unsigned 16-bit value, thus the minimum value should be 0. Documentation and unit tests are updated too.
Use a different query name for each query as to make sure that we do not get a cached response from previous, equivalent queries. This is needed because the tested object is actually the underlying object in the "dns" attribute of the Zonemaster::Engine::Nameserver class, which is only updated by the "_query()" method, and not the "query()" method.
Renamed some constants: - UDP_DNSSEC_QUERY_DEFAULT to EDNS_UDP_PAYLOAD_DNSSEC_DEFAULT - UDP_EDNS_QUERY_DEFAULT to EDNS_UDP_PAYLOAD_DEFAULT - UDP_EDNS_COMMON_LIMIT to EDNS_UDP_PAYLOAD_COMMON_LIMIT
@matsduf I fixed a conflict and rebased on latest develop, please re-review. |
Purpose
This PR proposes a fix to the default settings of queries which, due to an oversight regarding the
edns_size
flag from #1147, made all non-DNSSEC queries to be EDNS queries instead of regular non-EDNS queries. Default EDNS0 packet size values will now be properly used when appropriate, and a new, missing one has been created for DNSSEC to align with current specification. The caching logic of queries was also impacted.The basic usage for creating DNSSEC and EDNS queries remains unchanged.
Context
Fixes zonemaster/zonemaster#1308
Changes
dnssec
andedns_size
for when to use default values, and also when combined withedns_details
dnssec
andedns_size
parametersedns_size
dnssec
withedns_details
but withoutedns_details{do}
to correctly set thednssec
(DO) flagUDP_DNSSEC_QUERY_DEFAULT
(set to 1232)UDP_COMMON_EDNS_LIMIT
toUDP_EDNS_COMMON_LIMIT
How to test this PR
Units tests have been added or updated and should pass. Note that most of the newly added unit tests cannot be properly tested when replaying unit test data files (i.e without
ZONEMASTER_RECORD=1
), as the actual tested object is thedns
attribute of aZonemaster::Engine::Nameserver
object and its properties are not changed when getting query responses directly from the cache.Manual testing can be done using the commands below:
Default DNS query
An optional hash can be passed as parameter to the
query
method, with keys such asdnssec
,edns_size
andedns_details
. They should be changed and/or removed with various combinaisons to see the different behaviors.Default DNSSEC query
Default EDNS query