-- 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 -- SSAC report #35 http://www.icann.org/committees/security/sac035.pdf -- Stephane Bortzmeyer -- 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 -- MOst common transport protocol for DNS 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"); -- Complete and total failure end if; end if;