Changes between Version 10 and Version 11 of EDNS0


Ignore:
Timestamp:
07/01/2013 10:14:29 AM (17 months ago)
Author:
rwall
Comment:

Tidied up formatting and added some more bullet points

Legend:

Unmodified
Added
Removed
Modified
  • EDNS0

    v10 v11  
    11= EDNS Plan = 
    22 
    3 An attempt to understand the pieces of EDNS0 and the changes necessary to have Twisted Names support it: 
     3An attempt to understand the pieces of EDNS0 and DNSSEC and the 
     4changes necessary to have Twisted Names support it: 
    45 
    56[[PageOutline(2-4)]] 
    67 
     8== Overview == 
     9Twisted.names includes widely used public APIs that have existed for 
     10over twelve years (r440). 
     11 
     12However many of these existing APIs are inelegant and too broad. eg 
     13 * [/documents/current/api/twisted.names.dns.Message.html] 
     14So we will introduce new EDNS related classes with carefully designed, 
     15minimal public APIs. New APIs will be designed for maximum usability 
     16but as narrow as possible, to minimise future backwards compatibility 
     17complications. 
     18 
     19Twisted has a strict wiki:CompatibilityPolicy. So we will aim for zero 
     20changes to existing public APIs. 
     21 
     22Existing classes will be wrapped where appropriate and in other cases, 
     23shared functionality will be re-factored for reuse in new classes. 
     24 * #6382 
     25 * wiki:TheWayWeDoThingsNow 
     26 * http://pyvideo.org/video/1684/the-end-of-object-inheritance-the-beginning-of 
     27 
     28With the introduction of the new EDNS APIs, old sub-optimal APIs can 
     29then be deprecated and eventually removed in future releases. 
     30 * #1216 
     31 
     32Before designing and implementing new APIs, we will examine existing 
     33open source DNS projects for APIs and code that we can reuse / 
     34integrate. 
     35 * https://www.nlnetlabs.nl/projects/ldns/index.html 
     36 * http://trac.secdev.org/scapy/ticket/84 
     37 * http://doc.powerdns.com/html/recursor-design-and-engineering.html#idp9245952 
     38 * https://bazaar.launchpad.net/~ubuntu-branches/ubuntu/saucy/bind9/saucy/view/head:/lib/dns/message.c 
     39 
     40Use of an existing Python DNS library (or a C library with Python 
     41bindings) will be considered if it is well written, actively 
     42maintained, well tested and has a compatible licence. However the 
     43potential time savings from reusing an existing library will be 
     44weighed against the overhead of introducing an additional Twisted 
     45install dependency. eg 
     46 * http://www.dnspython.org/ 
     47 
     48Below are some specific examples of new APIs that we plan to 
     49introduce. 
    750 
    851== EDNS0 == 
    952 
    1053=== [ticket:5668 OPT record] === 
    11       - Explicit OPT record class/type 
    12         - Teach cache about it - MUST NOT BE CACHED 
    13           - EDNSMessage will remove OPT records during decoding so they 
    14             may never be seen by cache or clients if EDNSMessage 
    15             becomes the standard message factory for DNSDatagramProtocol. 
    16         - Teach recursive resolver about it - MUST NOT BE FORWARDED 
    17         - Teach loaders about - MUST NOT BE LOADED FROM MASTER FILE 
    18       - ~~Extended label ("0" "1" type) parsing~~ (REJECTED BY 2671bis) 
    19       - Maximum UDP datagram size field 
    20       - Arbitrary extension support (attribute/value pairs in RDATA section) 
     54 1. Explicit OPT record class/type 
     55    1. wrap the existing RRHeader class - to minimise code duplication 
     56       and maintenance overhead by only requiring a single 
     57       implementation of RRHeader byte string parser. 
     58    2. extracts OPT specific header fields from the equivalent RRHeader 
     59       fields. 
     60    3. Maximum UDP datagram size field 
     61    4. Arbitrary extension support (attribute/value pairs in RDATA section) 
     62    5. OPTHeader will encode and decode OPT variable options in an 
     63       underlying UnknownRecord payload class. 
     64 2. Discussion 
     65    1. Teach cache about it - MUST NOT BE CACHED 
     66    2. Teach recursive resolver about it - MUST NOT BE FORWARDED 
     67    3. EDNSMessage will remove OPT records during decoding so they may 
     68       never be seen by cache or clients if EDNSMessage becomes the 
     69       standard message factory for DNSDatagramProtocol. 
     70    4. Teach loaders about - MUST NOT BE LOADED FROM MASTER FILE 
     71    5. ~~Extended label ("0" "1" type) parsing~~ (REJECTED BY 2671bis) 
    2172 
    2273=== [ticket:5675 Extended Message object with additional EDNS0 items] === 
    23       - Subclass of Message? (no! subclassing is bad!) 
    24       - maxSize (Message has it already, can we re-use it?) 
    25       - Extended RCODE - partly defined by RCODE field in OPT record 
    26  
    27 === Configure Max payload size === 
    28  
    29 Accept max UDP size as configuration? 
    30  
    31 Determine it from system automatically? 
    32       - Server and client need this 
     74 1. Write a new EDNSMessage class. 
     75    1. It will wrap the existing dns.Message class. 
     76    2. Its decode method will extract an OPT record from the additional 
     77       section and merge its attributes with those of the underlying 
     78       non-EDNS Message. 
     79    3. Its encode method will check for EDNS specific attributes (eg 
     80       RCODE > 15) and add an OPT record to the additional records of 
     81       its underlying Message class before encoding. 
     82 2. Discussion 
     83    1. maxSize (Message has it already, can we re-use it?) 
    3384 
    3485=== [ticket:5670 Client] === 
    35       - Automatically send EDNS0 queries 
    36       - Fall back to DNS queries when detecting server does not support EDNS0? 
     86 1. A new EDNSAgent client API 
     87    1. Automatically send EDNS0 queries 
     88    2. Fall back to DNS queries when detecting server does not support EDNS0? 
     89    3. It will be modelled on twisted.web.client.Agent which was 
     90       introduced to replace the old twisted.web.client APIs. 
     91    4. Agents can be chainable / composable. 
     92    5. Eg An EDNSAgent will be introduced with a fixed maxUdpPayloadSize parameter. 
     93    6. Another AutoMTUDiscoveryAgent can wrap EDNSAgent and will reissue 
     94       queries with successively lower advertised UDP payload size until 
     95       a response is received. 
     96    7. A future DNSSECValidatingAgent can validate responses by issuing 
     97       queries for the DS and DNSKEY records from the root down. 
     98 2. Discussion 
     99    1. How to choose max UDP size? 
     100       1. Accept max UDP size as configuration? 
     101       2. Determine it from system automatically? 
     102       3. Server and client need this 
    37103 
    38104=== [ticket:5669 Server] === 
    39       - Send EDNS0 responses to EDNS0 queries 
    40       - (Do not send EDNS0 responses to DNS queries) 
    41  
     105 1. A new EDNS server API 
     106    1. Send EDNS0 responses to EDNS0 queries 
     107    2. (Do not send EDNS0 responses to DNS queries) 
     108    3. Ensures the EDNS requests are responded to using the advertised 
     109       UDP payload size. 
     110    4. Limits additional RRSETs so that responses fit the client max UDP 
     111       payload size or marks response Messages truncated. 
     112    5. Sets EDNS RCODEs in response to malformed EDNS requests. 
     113 
     114== RRSET improvements == 
     115 
     116DNSSEC seems to rely on stable RRSETs. eg for signatures, for 
     117predictable caching of records and signatures, for predictable 
     118truncation of large DNSSEC responses. 
     119 
     120There appear to be various problems with twisted.names current 
     121handling of RRSETs. 
     122 
     123=== Canonical Form and Order of Resource Records === 
     124 
     125https://tools.ietf.org/html/rfc4034#section-6 
     126 
     127RRSETs must be arranged in canonical order before their signatures are 
     128calculated / verified. 
     129 
     130This ticket will introduce an algorithm for sorting records 
     131according to the rules described in 
     132https://tools.ietf.org/html/rfc4034#section-6. 
     133 
     134Sorting appears to be the responsibility of the verifying client 
     135not the server. 
     136 
     137The fact that Bind has config options for changing the order of 
     138RRSETS on the server side and the client side suggests that the 
     139canonical ordering of records should be done only for the purpose 
     140of DNSSEC validation. It should probably not change the order of 
     141records returned by various IResolver methods. 
     142 
     143 * http://www.zytrax.com/books/dns/ch7/queries.html#rrset-order 
     144 
     145=== Serving RRSETs === 
     146 
     147twisted.names.dns.Message should follow the guidance in RFC2181 
     148regarding the handling of TTLs for records in the same 
     149RRSET. Alternatively consider handling this higher up in 
     150t.n.authority.FileAuthority, t.n.cache, t.n.resolver etc. 
     151 
     152 * https://tools.ietf.org/html/rfc2181#section-5 
     153 * https://tools.ietf.org/html/rfc2181#section-5.2 
     154 * "the use of differing TTLs in an RRSet is hereby deprecated, 
     155   the TTLs of all RRs in an RRSet must be the same" 
     156 * "In no case may a server send an RRSet with TTLs not all 
     157   equal." 
     158 * https://tools.ietf.org/html/rfc2181#section-5.5 
     159 * "A Resource Record Set should only be included once in any DNS 
     160   reply.  It may occur in any of the Answer, Authority, or 
     161   Additional Information sections, as required.  However it 
     162   should not be repeated in the same, or any other, section, 
     163   except where explicitly required by a specification." 
     164 
     165=== Receiving RRSETs === 
     166 
     167twisted.names.client should somehow signal an error if it receives 
     168RRSETs whose RRs have different TTLs. 
     169 
     170twisted.names.resolver,root should discard RRSETs whose RRs have 
     171diffent TTLs. 
     172 
     173 * https://tools.ietf.org/html/rfc2181#section-5.2 
     174 * "Should a client receive a response containing RRs from an 
     175   RRSet with differing TTLs, it should treat this as an error. 
     176   If the RRSet concerned is from a non-authoritative source for 
     177   this data, the client should simply ignore the RRSet," 
     178 
     179=== Caching RRSETs === 
     180 
     181twisted.names.cache should follow the RRSET ranking guidance when 
     182serving and replacing items in its cache. 
     183 
     184 * https://tools.ietf.org/html/rfc2181#section-5.4 
     185 * "Servers must never merge RRs from a response with RRs in their 
     186   cache to form an RRSet.  If a response contains data that would 
     187   form an RRSet with data in a server's cache the server must 
     188   either ignore the RRs in the response, or discard the entire 
     189   RRSet currently in the cache, as appropriate." 
     190 * https://tools.ietf.org/html/rfc2181#section-5.4.1 
     191 * "When considering whether to accept an RRSet in a reply, or 
     192   retain an RRSet already in its cache instead, a server should 
     193   consider the relative likely trustworthiness of the various 
     194   data" 
     195 
     196=== Selective truncate === 
     197 
     198twisted.names.dns.Message currently truncates messages based on the 
     199combined length of the answer, auth, and additional sections. Instead 
     200it (or something higher up) should look at the length of the answers 
     201and only set the truncate flag if the entire answers RRSET is greater 
     202than the maxPayloadSize. If there is room, the auth and additional 
     203records can also be included, but entire RRSETs must be included or 
     204none. 
     205 
     206 * https://tools.ietf.org/html/rfc2181#section-9 
     207 * "The TC bit should be set in responses only when an RRSet is 
     208   required as a part of the response, but could not be included 
     209   in its entirety." 
    42210 
    43211== DNSSEC == 
    44212 
    45     Much of this work (including tests) has already been implemented by 
    46     BobNovas in two large patches attached to original 
    47     tickets: #5450, #5453, #5454. Look there before implementing 
    48     anything from scratch. 
     213Much of this work (including tests) has already been implemented by 
     214BobNovas in two large patches attached to original 
     215tickets: #5450, #5453, #5454. Look there before implementing anything 
     216from scratch. 
    49217 
    50218=== New DNSSEC Records and Lookup Methods === 
    51  
    52        DNSSEC introduces six new resource record types. Each new record 
    53        type will require a new dns.Record subclass and a new 
    54        lookupMethod added to t.i.interfaces.IResolver, 
    55        t.n.common.ResolverBase and a corresponding free function in 
    56        t.n.client. 
    57  
    58        For ease of review, this work can be split into six tickets. 
    59  
    60        These new records can be implemented independently of EDNS and 
    61        independently of DNSSEC validation and new DNSSEC related message 
    62        headers. 
    63  
    64        Initially, this will allow twisted.names clients to explicitly 
    65        request these DNSSEC related records. 
    66  
    67        lookupZone will return DNSSEC related records when transferring 
    68        from DNSSEC authoritative servers. 
    69  
    70        t.n.secondary.SecondaryAuthority will download DNSSEC records and 
    71        serve them when queries specifically ask for them by type. 
    72  
    73        t.n.authority.FileAuthority will load DNSSEC records and serve 
    74        them when queries specifically ask for them by type. 
    75  
    76        * DNSKey 
    77          https://tools.ietf.org/html/rfc4034#section-2 
    78        * RRSIG 
    79          https://tools.ietf.org/html/rfc4034#section-3 
    80        * NSEC 
    81          https://tools.ietf.org/html/rfc4034#section-4 
    82        * DS 
    83          https://tools.ietf.org/html/rfc4034#section-5 
    84        * NSEC3 
    85          https://tools.ietf.org/html/rfc5155#section-3 
    86        * NSEC3Param 
    87          https://tools.ietf.org/html/rfc5155#section-4 
    88  
    89  
    90 === RRSET improvements === 
    91  
    92        DNSSEC seems to rely on stable RRSETs. eg for signatures, for 
    93        predictable caching of records and signatures, for predictable 
    94        truncation of large DNSSEC responses. 
    95  
    96        There appear to be various problems with twisted.names current 
    97        handling of RRSETs. 
    98  
    99 ==== Canonical Form and Order of Resource Records ==== 
    100  
    101           https://tools.ietf.org/html/rfc4034#section-6 
    102  
    103           RRSETs must be arranged in canonical order before their signatures are 
    104           calculated / verified. 
    105  
    106           This ticket will introduce an algorithm for sorting records 
    107           according to the rules described in 
    108           https://tools.ietf.org/html/rfc4034#section-6. 
    109  
    110           Sorting appears to be the responsibility of the verifying client 
    111           not the server. 
    112  
    113           The fact that Bind has config options for changing the order of 
    114           RRSETS on the server side and the client side suggests that the 
    115           canonical ordering of records should be done only for the purpose 
    116           of DNSSEC validation. It should probably not change the order of 
    117           records returned by various IResolver methods. 
    118  
    119           * http://www.zytrax.com/books/dns/ch7/queries.html#rrset-order 
    120  
    121 ==== Serving RRSETs ==== 
    122  
    123           twisted.names.dns.Message should follow the guidance in RFC2181 
    124           regarding the handling of TTLs for records in the same 
    125           RRSET. Alternatively consider handling this higher up in 
    126           t.n.authority.FileAuthority, t.n.cache, t.n.resolver etc. 
    127  
    128           * https://tools.ietf.org/html/rfc2181#section-5 
    129           * https://tools.ietf.org/html/rfc2181#section-5.2 
    130           * "the use of differing TTLs in an RRSet is hereby deprecated, 
    131             the TTLs of all RRs in an RRSet must be the same" 
    132           * "In no case may a server send an RRSet with TTLs not all 
    133             equal." 
    134           * https://tools.ietf.org/html/rfc2181#section-5.5 
    135           * "A Resource Record Set should only be included once in any DNS 
    136             reply.  It may occur in any of the Answer, Authority, or 
    137             Additional Information sections, as required.  However it 
    138             should not be repeated in the same, or any other, section, 
    139             except where explicitly required by a specification." 
    140  
    141 ==== Receiving RRSETs ==== 
    142  
    143           twisted.names.client should somehow signal an error if it 
    144           receives RRSETs whose RRs have different TTLs. 
    145  
    146           twisted.names.resolver,root should discard RRSETs whose RRs 
    147           have diffent TTLs. 
    148  
    149           * https://tools.ietf.org/html/rfc2181#section-5.2 
    150           * "Should a client receive a response containing RRs from an 
    151             RRSet with differing TTLs, it should treat this as an error. 
    152             If the RRSet concerned is from a non-authoritative source for 
    153             this data, the client should simply ignore the RRSet," 
    154  
    155 ==== Caching RRSETs ==== 
    156  
    157           twisted.names.cache should follow the RRSET ranking guidance 
    158           when serving and replacing items in its cache. 
    159  
    160           * https://tools.ietf.org/html/rfc2181#section-5.4 
    161           * "Servers must never merge RRs from a response with RRs in their 
    162             cache to form an RRSet.  If a response contains data that would 
    163             form an RRSet with data in a server's cache the server must 
    164             either ignore the RRs in the response, or discard the entire 
    165             RRSet currently in the cache, as appropriate." 
    166           * https://tools.ietf.org/html/rfc2181#section-5.4.1 
    167           * "When considering whether to accept an RRSet in a reply, or 
    168             retain an RRSet already in its cache instead, a server should 
    169             consider the relative likely trustworthiness of the various 
    170             data" 
    171  
    172 ==== Selective truncate ==== 
    173  
    174           twisted.names.dns.Message currently truncates messages based on 
    175           the combined length of the answer, auth, and additional 
    176           sections. Instead it (or something higher up) should look at 
    177           the length of the answers and only set the truncate flag if the 
    178           entire answers RRSET is greater than the 
    179           maxPayloadSize. If there is room, the auth and additional 
    180           records can also be included, but entire RRSETs must be 
    181           included or none. 
    182  
    183           * https://tools.ietf.org/html/rfc2181#section-9 
    184           * "The TC bit should be set in responses only when an RRSet is 
    185             required as a part of the response, but could not be included 
    186             in its entirety." 
    187  
    188 ==== Security-aware Non-validating Client ==== 
    189  
    190        A twisted.names.client will be able to generate EDNS queries with 
    191        one or both the DO bit and the AD bit set. 
    192  
    193        It will examine the state of the AD bit in the response to 
    194        determine whether the upstream resolver claims to have validated 
    195        the records in the response. 
    196  
    197        If the DO bit was set, it will expect to receive DNSSEC related 
    198        records in the response. 
    199  
    200        https://tools.ietf.org/html/rfc4035#section-4.9 
    201  
    202 ==== Validating Client ==== 
    203  
    204        A twisted.names.client which sends DO + CD flagged queries and 
    205        performs its own validation of the returned DNSSEC signatures. 
    206  
    207        TODO: needs more thought. 
    208  
    209 ==== Validating Recursive / Forwarding Server ==== 
    210  
    211        This can use the Validating client API above, but may need to do 
    212        some processing of answers based on the query flags. 
    213  
    214        TODO: needs more thought. 
    215  
    216 ==== DNSSEC Aware Authoritative Server ==== 
    217  
    218        A twisted.names.authority API which knows where and when to 
    219        include RRSIG, DNSKEY, NSEC, NSEC3 records etc with responses. 
    220  
    221        The actual generation of the DNSSEC records can be performed 
    222        using external tools such as 
    223        [http://linux.die.net/man/8/dnssec-signzone dnssec-signzone] 
    224  
    225        TODO: needs more thought. 
     219 1. DNSSEC introduces six new resource record types. Each new record 
     220    type will require a new dns.Record subclass and a new lookupMethod 
     221    added to t.i.interfaces.IResolver, t.n.common.ResolverBase and a 
     222    corresponding free function in t.n.client. 
     223    1. DNSKey 
     224       https://tools.ietf.org/html/rfc4034#section-2 
     225    2. RRSIG 
     226       https://tools.ietf.org/html/rfc4034#section-3 
     227    3. NSEC 
     228       https://tools.ietf.org/html/rfc4034#section-4 
     229    4. DS 
     230       https://tools.ietf.org/html/rfc4034#section-5 
     231    5. NSEC3 
     232       https://tools.ietf.org/html/rfc5155#section-3 
     233    6. NSEC3Param 
     234       https://tools.ietf.org/html/rfc5155#section-4 
     235 2. For ease of review, this work can be split into six tickets. 
     236 3. These new records can be implemented independently of EDNS and 
     237    independently of DNSSEC validation and new DNSSEC related message 
     238    headers. 
     239 4. Initially, this will allow twisted.names clients to explicitly 
     240    request these DNSSEC related records. 
     241 5. lookupZone will return DNSSEC related records when transferring 
     242    from DNSSEC authoritative servers. 
     243 6. t.n.secondary.SecondaryAuthority will download DNSSEC records and 
     244    serve them when queries specifically ask for them by type. 
     245 7. t.n.authority.FileAuthority will load DNSSEC records and serve 
     246    them when queries specifically ask for them by type. 
     247 
     248 
     249=== Security-aware Non-validating Client === 
     250 
     251A twisted.names.client will be able to generate EDNS queries with one 
     252or both the DO bit and the AD bit set. 
     253 
     254It will examine the state of the AD bit in the response to determine 
     255whether the upstream resolver claims to have validated the records in 
     256the response. 
     257 
     258If the DO bit was set, it will expect to receive DNSSEC related 
     259records in the response. 
     260 
     261https://tools.ietf.org/html/rfc4035#section-4.9 
     262 
     263 
     264=== Validating Client === 
     265 
     266A twisted.names.client which sends DO + CD flagged queries and 
     267performs its own validation of the returned DNSSEC signatures. 
     268 
     269TODO: needs more thought. 
     270 
     271=== Validating Recursive / Forwarding Server === 
     272 
     273This can use the Validating client API above, but may need to do some 
     274processing of answers based on the query flags. 
     275 
     276TODO: needs more thought. 
     277 
     278=== DNSSEC Aware Authoritative Server === 
     279 
     280A twisted.names.authority API which knows where and when to include 
     281RRSIG, DNSKEY, NSEC, NSEC3 records etc with responses. 
     282 
     283The actual generation of the DNSSEC records can be performed using 
     284external tools such as 
     285[http://linux.die.net/man/8/dnssec-signzone dnssec-signzone] 
     286 
     287TODO: needs more thought. 
    226288 
    227289== RFCs == 
    228290 
    229    General: 
    230     - [https://tools.ietf.org/html/rfc1034 1034:DOMAIN NAMES - CONCEPTS AND FACILITIES] 
    231     - [https://tools.ietf.org/html/rfc1035 1035: DOMAIN NAMES - IMPLEMENTATION AND SPECIFICATION] 
    232     - [https://tools.ietf.org/html/rfc2181 2181: Clarifications to the DNS Specification] 
    233     - [https://tools.ietf.org/html/rfc4697 4697: Observed DNS Resolution Misbehavior] 
    234     - [https://tools.ietf.org/html/rfc5625 5625: DNS Proxy Implementation Guidelines] 
    235  
    236    EDNS: 
    237     - [http://tools.ietf.org/html/rfc6891 6891: Extension Mechanisms for DNS (EDNS(0))] 
    238  
    239    DNSSEC: 
    240     - [https://tools.ietf.org/html/rfc4033 4033: DNS Security Introduction and Requirements] 
    241     - [https://tools.ietf.org/html/rfc4034 4034: Resource Records for the DNS Security Extensions] 
    242     - [https://tools.ietf.org/html/rfc4035 4035: Protocol Modifications for the DNS Security Extensions] 
    243     - [https://tools.ietf.org/html/rfc5155 5155: DNS Security (DNSSEC) Hashed Authenticated Denial of Existence] 
    244     - [https://tools.ietf.org/html/rfc6781 6781: DNSSEC Operational Practices, Version 2] 
    245     - [https://tools.ietf.org/html/rfc6840 6840: Clarifications and Implementation Notes for DNS Security (DNSSEC)] 
    246     - [https://tools.ietf.org/html/rfc3833 3833: Threat Analysis of the Domain Name System (DNS)] 
     291=== General === 
     292 1. [https://tools.ietf.org/html/rfc1034 1034:DOMAIN NAMES - CONCEPTS AND FACILITIES] 
     293 2. [https://tools.ietf.org/html/rfc1035 1035: DOMAIN NAMES - IMPLEMENTATION AND SPECIFICATION] 
     294 3. [https://tools.ietf.org/html/rfc2181 2181: Clarifications to the DNS Specification] 
     295 4. [https://tools.ietf.org/html/rfc4697 4697: Observed DNS Resolution Misbehavior] 
     296 5. [https://tools.ietf.org/html/rfc5625 5625: DNS Proxy Implementation Guidelines] 
     297 
     298=== EDNS === 
     299 1. [http://tools.ietf.org/html/rfc6891 6891: Extension Mechanisms for DNS (EDNS(0))] 
     300 
     301=== DNSSEC === 
     302 1. [https://tools.ietf.org/html/rfc4033 4033: DNS Security Introduction and Requirements] 
     303 2. [https://tools.ietf.org/html/rfc4034 4034: Resource Records for the DNS Security Extensions] 
     304 3. [https://tools.ietf.org/html/rfc4035 4035: Protocol Modifications for the DNS Security Extensions] 
     305 4. [https://tools.ietf.org/html/rfc5155 5155: DNS Security (DNSSEC) Hashed Authenticated Denial of Existence] 
     306 5. [https://tools.ietf.org/html/rfc6781 6781: DNSSEC Operational Practices, Version 2] 
     307 6. [https://tools.ietf.org/html/rfc6840 6840: Clarifications and Implementation Notes for DNS Security (DNSSEC)] 
     308 7. [https://tools.ietf.org/html/rfc3833 3833: Threat Analysis of the Domain Name System (DNS)] 
    247309 
    248310== MISC / TODO / Notes == 
    249     1. "If a query message with more than one OPT RR is received, a 
    250        FORMERR (RCODE=1) MUST be returned." 
    251        [https://tools.ietf.org/html/rfc6891#section-6.1.1 RFC6891 6.1.1] 
    252  
    253        * Multiple OPT RR will be detected in EDNSMessage.decode 
    254        * If multiple OPT RR are detected, set EDNSMessage.decodingErrors.append(EFORMAT) 
    255        * DNSServerFactory.messageReceived checks message.decodingErrors 
    256        * If not empty, it sets message.rCode = 
    257          message.decodingErrors.pop(0) before sending the message back 
    258          to client without further processing. 
    259        * If DNSServerFactory.verbose logging is enabled, all message.decodingErrors will 
    260          be logged. 
    261        * I tested Google DNS and Bind Authoritative DNS responses to 
    262          multi OPT queries. 
    263          * Google seems to ignore all but the first OPT RR and responds 
    264            without error. 
    265          * Bind responds with RCODE=1 
    266          * https://bazaar.launchpad.net/~ubuntu-branches/ubuntu/saucy/bind9/saucy/view/head:/lib/dns/message.c#L1274 
    267            {{{ 
    268                   } else if (rdtype == dns_rdatatype_opt) { 
    269                           /* 
    270            * The name of an OPT record must be ".", it 
    271            * must be in the additional data section, and 
    272            * it must be the first OPT we've seen. 
    273                            */ 
    274                           if (!dns_name_equal(dns_rootname, name) || 
    275                               msg->opt != NULL) 
    276                                   DO_FORMERR; 
    277                           skip_name_search = ISC_TRUE; 
    278                           skip_type_search = ISC_TRUE; 
    279             }}} 
    280          * PowerDNS appears to ignore all but the first OPT RR (untested) 
    281            https://github.com/PowerDNS/pdns/blob/master/pdns/dnsrecords.cc#L375 
    282            {{{ 
    283  
    284            bool getEDNSOpts(const MOADNSParser& mdp, EDNSOpts* eo) 
    285            { 
    286              if(mdp.d_header.arcount && !mdp.d_answers.empty()) { 
    287                BOOST_FOREACH(const MOADNSParser::answers_t::value_type& val, mdp.d_answers) { 
    288                  if(val.first.d_place == DNSRecord::Additional && val.first.d_type == QType::OPT) { 
    289                    eo->d_packetsize=val.first.d_class; 
    290  
    291                    EDNS0Record stuff; 
    292                    uint32_t ttl=ntohl(val.first.d_ttl); 
    293                    memcpy(&stuff, &ttl, sizeof(stuff)); 
    294  
    295                    eo->d_extRCode=stuff.extRCode; 
    296                    eo->d_version=stuff.version; 
    297                    eo->d_Z = ntohs(stuff.Z); 
    298                    OPTRecordContent* orc = 
    299                      dynamic_cast<OPTRecordContent*>(val.first.d_content.get()); 
    300                    if(!orc) 
    301                      return false; 
    302                    orc->getData(eo->d_options); 
    303                    return true; 
    304                  } 
    305                } 
    306              } 
    307              return false; 
    308            } 
    309  
    310            }}} 
    311  
    312     2. "EXTENDED-RCODE Forms the upper 8 bits of extended 12-bit RCODE" 
    313        [https://tools.ietf.org/html/rfc6891#section-6.1.3 RFC6891 6.1.3] 
    314  
    315        * Decode: EDNSMessage.decode will merge the RCODE and 
    316          OPTHeader.extendedRCODE setting the  rCode attribute. 
    317  
    318        * Encode: If rCode is > 15, EDNSMessage.encode will set the lower 
    319          4 bits as RCODE and set the upper 8 bits on a new or existing 
    320          OPTHeader which will be added to the additional section. 
    321  
    322     3. "VERSION Indicates the implementation level of the setter" 
    323        [https://tools.ietf.org/html/rfc6891#section-6.1.3 RFC6891 6.1.3] 
    324  
    325        * "If a responder does not implement the VERSION level of the 
    326          request, then it MUST respond with RCODE=BADVERS" 
    327  
    328          * Decode: in EDNSMessage.decode, if version > 0, EDNSMessage.decodingErrors.append(EBADVERS) 
    329  
    330        * "This document assigns EDNS Extended RCODE 16 to "BADVERS" in 
    331          the DNS RCODES registry" https://tools.ietf.org/html/rfc6891#section-9 
    332  
    333          * Create dns.EBADVERS = 16 
    334  
    335     4. "DO DNSSEC OK bit as defined by [RFC3225]." https://tools.ietf.org/html/rfc6891#section-6.1.4 
    336  
    337        * Set EDNSMessage.dnssecOK during decode using value from 
    338          OPTHeader.dnssecOK. 
    339  
    340        * Add or update an existing OPTHeader instance during encode. 
     311 1. "If a query message with more than one OPT RR is received, a 
     312    FORMERR (RCODE=1) MUST be returned." 
     313    [https://tools.ietf.org/html/rfc6891#section-6.1.1 RFC6891 6.1.1] 
     314    1. Multiple OPT RR will be detected in EDNSMessage.decode 
     315    2. If multiple OPT RR are detected, set EDNSMessage.decodingErrors.append(EFORMAT) 
     316    3. DNSServerFactory.messageReceived checks message.decodingErrors 
     317    4. If not empty, it sets message.rCode = 
     318       message.decodingErrors.pop(0) before sending the message back 
     319       to client without further processing. 
     320    5. If DNSServerFactory.verbose logging is enabled, all message.decodingErrors will 
     321       be logged. 
     322    6. I tested Google DNS and Bind Authoritative DNS responses to 
     323       multi OPT queries. 
     324       1. Google seems to ignore all but the first OPT RR and responds 
     325          without error. 
     326       2. Bind responds with RCODE=1 
     327       3. https://bazaar.launchpad.net/~ubuntu-branches/ubuntu/saucy/bind9/saucy/view/head:/lib/dns/message.c#L1274 
     328          {{{ 
     329 
     330          } else if (rdtype == dns_rdatatype_opt) { 
     331                  /* 
     332          * The name of an OPT record must be ".", it 
     333          * must be in the additional data section, and 
     334          * it must be the first OPT we've seen. 
     335                   */ 
     336                  if (!dns_name_equal(dns_rootname, name) || 
     337                      msg->opt != NULL) 
     338                          DO_FORMERR; 
     339                  skip_name_search = ISC_TRUE; 
     340                  skip_type_search = ISC_TRUE; 
     341 
     342          }}} 
     343       4. PowerDNS appears to ignore all but the first OPT RR (untested) 
     344          https://github.com/PowerDNS/pdns/blob/master/pdns/dnsrecords.cc#L375 
     345          {{{ 
     346 
     347          bool getEDNSOpts(const MOADNSParser& mdp, EDNSOpts* eo) 
     348          { 
     349            if(mdp.d_header.arcount && !mdp.d_answers.empty()) { 
     350              BOOST_FOREACH(const MOADNSParser::answers_t::value_type& val, mdp.d_answers) { 
     351                if(val.first.d_place == DNSRecord::Additional && val.first.d_type == QType::OPT) { 
     352                  eo->d_packetsize=val.first.d_class; 
     353 
     354                  EDNS0Record stuff; 
     355                  uint32_t ttl=ntohl(val.first.d_ttl); 
     356                  memcpy(&stuff, &ttl, sizeof(stuff)); 
     357 
     358                  eo->d_extRCode=stuff.extRCode; 
     359                  eo->d_version=stuff.version; 
     360                  eo->d_Z = ntohs(stuff.Z); 
     361                  OPTRecordContent* orc = 
     362                    dynamic_cast<OPTRecordContent*>(val.first.d_content.get()); 
     363                  if(!orc) 
     364                    return false; 
     365                  orc->getData(eo->d_options); 
     366                  return true; 
     367                } 
     368              } 
     369            } 
     370            return false; 
     371          } 
     372 
     373          }}} 
     374 
     375 2. "EXTENDED-RCODE Forms the upper 8 bits of extended 12-bit RCODE" 
     376    [https://tools.ietf.org/html/rfc6891#section-6.1.3 RFC6891 6.1.3] 
     377    1. Decode: EDNSMessage.decode will merge the RCODE and 
     378       OPTHeader.extendedRCODE setting the  rCode attribute. 
     379    2. Encode: If rCode is > 15, EDNSMessage.encode will set the lower 
     380       4 bits as RCODE and set the upper 8 bits on a new or existing 
     381       OPTHeader which will be added to the additional section. 
     382 
     383 3. "VERSION Indicates the implementation level of the setter" 
     384    [https://tools.ietf.org/html/rfc6891#section-6.1.3 RFC6891 6.1.3] 
     385    1. "If a responder does not implement the VERSION level of the 
     386       request, then it MUST respond with RCODE=BADVERS" 
     387       1. Decode: in EDNSMessage.decode, if version > 0, EDNSMessage.decodingErrors.append(EBADVERS) 
     388 
     389    2. "This document assigns EDNS Extended RCODE 16 to "BADVERS" in 
     390       the DNS RCODES registry" https://tools.ietf.org/html/rfc6891#section-9 
     391       1. Create dns.EBADVERS = 16 
     392 
     393 4. "DO DNSSEC OK bit as defined by [RFC3225]." https://tools.ietf.org/html/rfc6891#section-6.1.4 
     394    1. Set EDNSMessage.dnssecOK during decode using value from 
     395       OPTHeader.dnssecOK. 
     396    2. Add or update an existing OPTHeader instance during encode.