Created
April 6, 2010 19:48
-
-
Save bortzmeyer/358004 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Pseudo-code (syntax more or less Ada-like) to show what happens to | |
-- a DNS resolver when the root is signed and the responses become | |
-- larger. | |
-- Background information: | |
-- https://www.dns-oarc.net/oarc/services/replysizetest | |
-- RFC 5625 | |
-- http://www.iis.se/docs/Routertester_en.Pdf | |
-- SSAC report #35 http://www.icann.org/committees/security/sac035.pdf | |
-- Stephane Bortzmeyer <bortzmeyer@nic.fr> | |
-- Variables used: | |
-- EDNS0: boolean, indicates if the resolver sends EDNS0 requests | |
-- EDNS0_Size: positive integer, the buffer size advertised by EDNS0 | |
-- DO_DNSSEC: boolean, the DO flag indicating DNSSEC support by the resolver | |
-- Min_Response_Size: integer, the minimum (after dropping | |
-- unnecessary RR) size of the DNS response sent by the authoritative | |
-- server | |
-- Clean_path_for_fragments: boolean, indicates that UDP fragments | |
-- can travel from the authoritative name server to the resolver | |
-- Clean_Path_For_EDNS0: boolean, indicates that EDNS0 responses | |
-- (which may be larger than 512 bytes) can travel from the | |
-- authoritative name server to the resolver | |
-- Can_TCP: boolean, indicates that the resolver can ask through TCP | |
-- (which implies a clean TCP patch and an authoritative name server | |
-- which accept TCP) | |
-- The code can be executed several times for one request, for | |
-- instance because a resolver tries first with UDP, then retries | |
-- with TCP. | |
if UDP then | |
if EDNS0 then | |
if EDNS0_Size > MTU then | |
-- BIND default, EDNS0_size = 4096 bytes | |
if DO_DNSSEC then | |
-- BIND default, even if not configured for validation | |
if Min_Response_Size > MTU then -- Not the case today with the root | |
if Clean_Path_for_fragments then | |
OK; | |
else | |
-- After a while BIND will switch to no-EDNS0, start over | |
Retry("Responses not received may be because of EDNS0"); | |
end if; | |
elsif Min_Response_Size > 512 then | |
-- No fragmentation will occur | |
if Clean_Path_For_EDNS0 then | |
OK; -- That's the normal and typical case for a BIND resolver today, | |
-- with the signed root | |
else | |
Retry("Responses not received may be because of EDNS0"); | |
end if; | |
else -- Won't occur today, responses from the root are already > 512 | |
OK; | |
end if; | |
else | |
-- Without DNSSEC, responses wil be shorter but some | |
-- responses from the root already are > 512 | |
if Min_Response_Size > MTU then | |
-- Unlikely, without DNSSEC | |
if Clean_Path_for_fragments then | |
OK; | |
else | |
Retry("Responses not received may be because of EDNS0"); | |
end if; | |
elsif Min_Response_Size > 512 then | |
if Clean_Path_For_EDNS0 then | |
OK; | |
else | |
Retry("Responses not received may be because of EDNS0"); | |
end if; | |
else -- Most common case today, the typical unsigned answer is 100-200 bytes | |
OK; | |
end if; | |
end if; | |
elsif EDNS0_Size >= 512 then -- But lower than the MTU | |
if DO_DNSSEC then | |
if Min_Response_Size > EDNS0_Size then | |
-- This assumes that DNS packets with TC bit set arrive safely, not always true | |
Retry("Truncation"); | |
elsif Min_Response_Size >= 512 then | |
if Clean_Path_for_EDNS0 then | |
OK; | |
else | |
Retry("Responses not received may be because of EDNS0"); | |
end if; | |
else -- Won't often occur today, some responses from the root are already > 512 | |
OK; -- Not always, some middleboxes may block EDNS0 responses, even with size <= 512 | |
end if; | |
else | |
-- No DNSSEC, so replies will probably be under EDNS0_Size | |
if Min_Response_Size > 512 then | |
if Clean_Path_For_EDNS0 then | |
OK; | |
else | |
Retry("Responses not received may be because of EDNS0"); | |
end if; | |
else | |
OK; | |
end if; | |
end if; | |
else -- EDNS0 with size < 512 | |
Error("Stupid value"); | |
end if; | |
else -- No EDNS0 at all | |
if Min_Response_Size > 512 then | |
Retry("Truncation"); | |
else | |
OK; | |
end if; | |
end if; | |
else -- TCP | |
if Can_TCP then | |
OK; -- But higher latency and higher load on authoritative name servers | |
else | |
Error("Fallback to TCP failed"); | |
end if; | |
end if; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment