[GH-ISSUE #2679] EDNS0 flags should not interpret Z field #1042

Closed
opened 2026-03-16 01:24:41 +03:00 by kerem · 5 comments
Owner

Originally created by @dead10ck on GitHub (Dec 15, 2024).
Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/2679

In #2549, a special type was added for encoding the EDNS flags. It added a field for the DO flag and one for a Z flag.

At first glance in RFC 6891, I can see how this was interpreted the way it was, since it seems to list DO and Z as separate flags.

[6.1.3](https://www.rfc-editor.org/rfc/rfc6891#section-6.1.3).  OPT Record TTL Field Use

   The extended RCODE and flags, which OPT stores in the RR Time to Live
   (TTL) field, are structured as follows:

                  +0 (MSB)                            +1 (LSB)
       +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
    0: |         EXTENDED-RCODE        |            VERSION            |
       +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
    2: | DO|                           Z                               |
       +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+

   EXTENDED-RCODE
      Forms the upper 8 bits of extended 12-bit RCODE (together with the
      4 bits defined in [[RFC1035](https://www.rfc-editor.org/rfc/rfc1035)].  Note that EXTENDED-RCODE value 0
      indicates that an unextended RCODE is in use (values 0 through
      15).

   VERSION
      Indicates the implementation level of the setter.  Full
      conformance with this specification is indicated by version '0'.
      Requestors are encouraged to set this to the lowest implemented
      level capable of expressing a transaction, to minimise the
      responder and network load of discovering the greatest common
      implementation level between requestor and responder.  A
      requestor's version numbering strategy MAY ideally be a run-time
      configuration option.
      If a responder does not implement the VERSION level of the
      request, then it MUST respond with RCODE=BADVERS.  All responses
      MUST be limited in format to the VERSION level of the request, but
      the VERSION of each response SHOULD be the highest implementation
      level of the responder.  In this way, a requestor will learn the
      implementation level of a responder as a side effect of every
      response, including error responses and including RCODE=BADVERS.

[6.1.4](https://www.rfc-editor.org/rfc/rfc6891#section-6.1.4).  Flags

   DO
      DNSSEC OK bit as defined by [[RFC3225](https://www.rfc-editor.org/rfc/rfc3225)].

   Z
      Set to zero by senders and ignored by receivers, unless modified
      in a subsequent specification.

However, two other RFCs that it references seem to suggest that Z is not a flag in and of itself, but rather refers to the whole two bytes as a collective field, in which DO is the first bit.

https://www.rfc-editor.org/rfc/rfc3225#section-3

The mechanism chosen for the explicit notification of the ability of
   the client to accept (if not understand) DNSSEC security RRs is using
   the most significant bit of the Z field on the EDNS0 OPT header in
   the query.  This bit is referred to as the "DNSSEC OK" (DO) bit.

And further, the RFC that precedes this one seems to further support this, by showing the whole 2 bytes without the DO bit present.

https://www.rfc-editor.org/rfc/rfc2671#section-4.6

[4.6](https://www.rfc-editor.org/rfc/rfc2671#section-4.6). The extended RCODE and flags (which OPT stores in the RR TTL field)
     are structured as follows:

                 +0 (MSB)                            +1 (LSB)
      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
   0: |         EXTENDED-RCODE        |            VERSION            |
      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
   2: |                               Z                               |
      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+

   EXTENDED-RCODE  Forms upper 8 bits of extended 12-bit RCODE.  Note
                   that EXTENDED-RCODE value "0" indicates that an
                   unextended RCODE is in use (values "0" through "15").

   VERSION         Indicates the implementation level of whoever sets
                   it.  Full conformance with this specification is
                   indicated by version "0."  Requestors are encouraged
                   to set this to the lowest implemented level capable
                   of expressing a transaction, to minimize the
                   responder and network load of discovering the
                   greatest common implementation level between
                   requestor and responder.  A requestor's version
                   numbering strategy should ideally be a run time
                   configuration option.

                   If a responder does not implement the VERSION level
                   of the request, then it answers with RCODE=BADVERS.
                   All responses will be limited in format to the



Vixie                       Standards Track                     [Page 4]


[RFC 2671](https://www.rfc-editor.org/rfc/rfc2671)          Extension Mechanisms for DNS (EDNS0)       August 1999


                   VERSION level of the request, but the VERSION of each
                   response will be the highest implementation level of
                   the responder.  In this way a requestor will learn
                   the implementation level of a responder as a side
                   effect of every response, including error responses,
                   including RCODE=BADVERS.

   Z               Set to zero by senders and ignored by receivers,
                   unless modified in a subsequent specification.

Semantically, it seems to just be unused bits that are expected to be zeroed. I don't think it makes much sense to interpret them as having any meaning at all. In my opinion, it should just be left out of the parsed structure.

Originally created by @dead10ck on GitHub (Dec 15, 2024). Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/2679 In #2549, a special type was added for encoding the EDNS flags. It added a field for the DO flag and one for a Z flag. At first glance in [RFC 6891](https://www.rfc-editor.org/rfc/rfc6891#section-6.1.4), I can see how this was interpreted the way it was, since it seems to list `DO` and `Z` as separate flags. ``` [6.1.3](https://www.rfc-editor.org/rfc/rfc6891#section-6.1.3). OPT Record TTL Field Use The extended RCODE and flags, which OPT stores in the RR Time to Live (TTL) field, are structured as follows: +0 (MSB) +1 (LSB) +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ 0: | EXTENDED-RCODE | VERSION | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ 2: | DO| Z | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ EXTENDED-RCODE Forms the upper 8 bits of extended 12-bit RCODE (together with the 4 bits defined in [[RFC1035](https://www.rfc-editor.org/rfc/rfc1035)]. Note that EXTENDED-RCODE value 0 indicates that an unextended RCODE is in use (values 0 through 15). VERSION Indicates the implementation level of the setter. Full conformance with this specification is indicated by version '0'. Requestors are encouraged to set this to the lowest implemented level capable of expressing a transaction, to minimise the responder and network load of discovering the greatest common implementation level between requestor and responder. A requestor's version numbering strategy MAY ideally be a run-time configuration option. If a responder does not implement the VERSION level of the request, then it MUST respond with RCODE=BADVERS. All responses MUST be limited in format to the VERSION level of the request, but the VERSION of each response SHOULD be the highest implementation level of the responder. In this way, a requestor will learn the implementation level of a responder as a side effect of every response, including error responses and including RCODE=BADVERS. [6.1.4](https://www.rfc-editor.org/rfc/rfc6891#section-6.1.4). Flags DO DNSSEC OK bit as defined by [[RFC3225](https://www.rfc-editor.org/rfc/rfc3225)]. Z Set to zero by senders and ignored by receivers, unless modified in a subsequent specification. ``` However, two other RFCs that it references seem to suggest that `Z` is not a flag in and of itself, but rather refers to the whole two bytes as a collective field, in which `DO` is the first bit. https://www.rfc-editor.org/rfc/rfc3225#section-3 ``` The mechanism chosen for the explicit notification of the ability of the client to accept (if not understand) DNSSEC security RRs is using the most significant bit of the Z field on the EDNS0 OPT header in the query. This bit is referred to as the "DNSSEC OK" (DO) bit. ``` And further, the RFC that precedes this one seems to further support this, by showing the whole 2 bytes without the DO bit present. https://www.rfc-editor.org/rfc/rfc2671#section-4.6 ``` [4.6](https://www.rfc-editor.org/rfc/rfc2671#section-4.6). The extended RCODE and flags (which OPT stores in the RR TTL field) are structured as follows: +0 (MSB) +1 (LSB) +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ 0: | EXTENDED-RCODE | VERSION | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ 2: | Z | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ EXTENDED-RCODE Forms upper 8 bits of extended 12-bit RCODE. Note that EXTENDED-RCODE value "0" indicates that an unextended RCODE is in use (values "0" through "15"). VERSION Indicates the implementation level of whoever sets it. Full conformance with this specification is indicated by version "0." Requestors are encouraged to set this to the lowest implemented level capable of expressing a transaction, to minimize the responder and network load of discovering the greatest common implementation level between requestor and responder. A requestor's version numbering strategy should ideally be a run time configuration option. If a responder does not implement the VERSION level of the request, then it answers with RCODE=BADVERS. All responses will be limited in format to the Vixie Standards Track [Page 4] [RFC 2671](https://www.rfc-editor.org/rfc/rfc2671) Extension Mechanisms for DNS (EDNS0) August 1999 VERSION level of the request, but the VERSION of each response will be the highest implementation level of the responder. In this way a requestor will learn the implementation level of a responder as a side effect of every response, including error responses, including RCODE=BADVERS. Z Set to zero by senders and ignored by receivers, unless modified in a subsequent specification. ``` Semantically, it seems to just be unused bits that are expected to be zeroed. I don't think it makes much sense to interpret them as having any meaning at all. In my opinion, it should just be left out of the parsed structure.
kerem closed this issue 2026-03-16 01:24:46 +03:00
Author
Owner

@bluejekyll commented on GitHub (Dec 16, 2024):

Is there a reason that we wouldn’t want to expose this? One problem I see is that if anyone needs to integrate with a system that uses the Z bits for anything, it is possible with the current layout, but wouldn’t be in the future. That is, this is somewhat future proof, and is really only directly accessible if using Message at a low level, otherwise the server, recursor, and resolver all manage EDNS settings directly.

<!-- gh-comment-id:2544548833 --> @bluejekyll commented on GitHub (Dec 16, 2024): Is there a reason that we wouldn’t want to expose this? One problem I see is that if anyone needs to integrate with a system that uses the Z bits for anything, it is possible with the current layout, but wouldn’t be in the future. That is, this is somewhat future proof, and is really only directly accessible if using Message at a low level, otherwise the server, recursor, and resolver all manage EDNS settings directly.
Author
Owner

@djc commented on GitHub (Dec 16, 2024):

Semantically, it seems to just be unused bits that are expected to be zeroed. I don't think it makes much sense to interpret them as having any meaning at all. In my opinion, it should just be left out of the parsed structure.

Do you have any underlying concerns?

Like @bluejekyll I don't see a problem with exposing this. I'm also inclined to think that RFC 6891 (which was published 12 / 14 years after 3225 / 2671) benefits from a bunch of additional experience, so I'd prefer to trust it instead of the much older RFCs.

<!-- gh-comment-id:2545347911 --> @djc commented on GitHub (Dec 16, 2024): > Semantically, it seems to just be unused bits that are expected to be zeroed. I don't think it makes much sense to interpret them as having any meaning at all. In my opinion, it should just be left out of the parsed structure. Do you have any underlying concerns? Like @bluejekyll I don't see a problem with exposing this. I'm also inclined to think that RFC 6891 (which was published 12 / 14 years after 3225 / 2671) benefits from a bunch of additional experience, so I'd prefer to trust it instead of the much older RFCs.
Author
Owner

@dead10ck commented on GitHub (Dec 16, 2024):

Exposing them for future use does indeed make sense, but the flags were changed to an opaque boolean, so that wouldn't even be possible. If we want to expose the raw bytes for future use, then it should be raw binary. As it stands, the way Z is exposed is both meaningless in the present and useless in the future.

<!-- gh-comment-id:2545589020 --> @dead10ck commented on GitHub (Dec 16, 2024): Exposing them for future use does indeed make sense, but the flags were changed to an opaque boolean, so that wouldn't even be possible. If we want to expose the raw bytes for future use, then it should be raw binary. As it stands, the way Z is exposed is both meaningless in the present and useless in the future.
Author
Owner

@djc commented on GitHub (Dec 18, 2024):

Fair enough, I've submitted a fix in https://github.com/hickory-dns/hickory-dns/pull/2684.

<!-- gh-comment-id:2550954279 --> @djc commented on GitHub (Dec 18, 2024): Fair enough, I've submitted a fix in https://github.com/hickory-dns/hickory-dns/pull/2684.
Author
Owner

@dead10ck commented on GitHub (Dec 19, 2024):

Thanks for taking the feedback, and the fix! And for all the work you do to maintain this lib. You folks are awesome. ♥️

<!-- gh-comment-id:2552680685 --> @dead10ck commented on GitHub (Dec 19, 2024): Thanks for taking the feedback, and the fix! And for all the work you do to maintain this lib. You folks are awesome. ♥️
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/hickory-dns#1042
No description provided.