Section 4.2). Connected but Sessionless: A connection exists, but a DSO Session has not been established. DNS messages can be sent from the client to server, and DNS responses can be sent from the server to the client. In this state, a client that wishes to use DSO can attempt to establish a DSO Session (Section 5.1). Standard DNS- over-TCP inactivity timeout handling is in effect [RFC7766] (see Section 7.1.2 of this document). DSO Session Establishment in Progress: A client has sent a DSO request within the last 30 seconds, but has not yet received a DSO response for that request. In this phase, the client may send more DSO requests and more DNS requests, but MUST NOT send DSO unidirectional messages (Section 5.1). DSO Session Establishment Timeout: A client has sent a DSO request, and after 30 seconds has still received no DSO response for that request. This means that the server is now in an indeterminate state. The client forcibly aborts the connection. The client MAY reconnect without using DSO, if appropriate. DSO Session Establishment Failed: A client has sent a DSO request, and received a corresponding DSO response with a nonzero RCODE. This means that the attempt to establish the DSO Session did not succeed. At this point, the client is permitted to continue operating without a DSO Session (Connected but Sessionless) but does not send further DSO messages (Section 5.1). DSO Session Established: A client has sent a DSO request, and received a corresponding DSO response with RCODE set to NOERROR (0). A DSO Session has now been successfully established. Both client and server may send DSO messages and DNS messages; both may send replies in response to messages they receive (Section 5.2). The inactivity timer (Section 6.4) is active; the keepalive timer (Section 6.5) is active. Standard DNS-over-TCP inactivity timeout handling is no longer in effect [RFC7766] (see Section 7.1.2 of this document).
Server Shutdown: The server has decided to gracefully terminate the session and has sent the client a Retry Delay message (Section 6.6.1). There may still be unprocessed messages from the client; the server will ignore these. The server will not send any further messages to the client (Section 220.127.116.11). Client Shutdown: The client has decided to disconnect, either because it no longer needs service, the connection is inactive (Section 6.4.1), or because the server sent it a Retry Delay message (Section 6.6.1). The client closes the connection gracefully (Section 5.3). Reconnect: The client disconnected as a result of a server shutdown. The client either waits for the server-specified Retry Delay to expire (Section 6.6.3) or else contacts a different server instance. If the client no longer needs service, it does not reconnect. Forcibly Abort: The client or server detected a protocol error, and further communication would have undefined behavior. The client or server forcibly aborts the connection (Section 5.3). Abort Reconnect Wait: The client has forcibly aborted the connection but still needs service. Or, the server forcibly aborted the connection, but the client still needs service. The client either connects to a different service instance (Section 9.1) or waits to reconnect (Section 18.104.22.168). Section 4.2). In some environments, it may be known in advance by external means that both client and server support DSO, and in these cases either client or server may initiate DSO messages at any time. In this case, the session is established as soon as the connection is established; this is referred to as implicit DSO Session establishment. However, in the typical case a server will not know in advance whether a client supports DSO, so in general, unless it is known in advance by other means that a client does support DSO, a server MUST NOT initiate DSO request messages or DSO unidirectional messages until a DSO Session has been mutually established by at least one successful DSO request/response exchange initiated by the client, as
described below. This is referred to as explicit DSO Session establishment. Until a DSO Session has been implicitly or explicitly established, a client MUST NOT initiate DSO unidirectional messages. A DSO Session is established over a connection by the client sending a DSO request message, such as a DSO Keepalive request message (Section 7.1), and receiving a response with a matching MESSAGE ID, and RCODE set to NOERROR (0), indicating that the DSO request was successful. Some DSO messages are permitted as early data (Section 11.1). Others are not. Unidirectional messages are never permitted as early data, unless an implicit DSO Session exists. If a server receives a DSO message in early data whose Primary TLV is not permitted to appear in early data, the server MUST forcibly abort the connection. If a client receives a DSO message in early data, and there is no implicit DSO Session, the client MUST forcibly abort the connection. This can only be enforced on TLS connections; therefore, servers MUST NOT enable TCP Fast Open (TFO) when listening for a connection that does not require TLS.
When a DSO message is received by an existing DNS server that doesn't recognize the DSO OPCODE, two other possible outcomes exist: the server might send no response to the DSO message, or the server might drop the connection. If the server sends no response to the DSO message, the client SHOULD wait 30 seconds, after which time the server will be assumed not to support DSO. If the server doesn't respond within 30 seconds, it can be assumed that it is not going to respond; this leaves it in an unspecified state: there is no specification requiring that a response be sent to an unknown message, but there is also no specification stating what state the server is in if no response is sent. Therefore the client MUST forcibly abort the connection to the server. The client MAY reconnect, but not use DSO, if appropriate (Section 22.214.171.124). By disconnecting and reconnecting, the client ensures that the server is in a known state before sending any subsequent requests. If the server drops the connection the client SHOULD mark that service instance as not supporting DSO, and not attempt a DSO connection for some period of time (at least an hour) after the failed attempt. The client MAY reconnect but not use DSO, if appropriate (Section 126.96.36.199). RFC7766]. Because a server that supports DNS Stateful Operations MUST return an RCODE of "NOERROR" when it receives a Keepalive TLV DSO request message, the Keepalive TLV is an ideal candidate for use in establishing a DSO Session. Any other option that can only succeed
when sent to a server of the desired kind is also a good candidate for use in establishing a DSO Session. For clients that implement only the DSO-TYPEs defined in this base specification, sending a Keepalive TLV is the only DSO request message they have available to initiate a DSO Session. Even for clients that do implement other future DSO-TYPEs, for simplicity they MAY elect to always send an initial DSO Keepalive request message as their way of initiating a DSO Session. A future definition of a new response-requiring DSO- TYPE gives implementers the option of using that new DSO-TYPE if they wish, but does not change the fact that sending a Keepalive TLV remains a valid way of initiating a DSO Session.
describes this latter form of error condition as a "fatal error" and specifies that an implementation encountering a fatal error condition "MUST forcibly abort the connection immediately". RFC1035] with the OPCODE field set to the DSO OPCODE (6). However, unlike standard DNS messages, the question section, answer section, authority records section, and additional records sections are not present. The corresponding count fields (QDCOUNT, ANCOUNT, NSCOUNT, ARCOUNT) MUST be set to zero on transmission. If a DSO message is received where any of the count fields are not zero, then a FORMERR MUST be returned. 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | MESSAGE ID | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ |QR | OPCODE (6) | Z | RCODE | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | QDCOUNT (MUST be zero) | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ANCOUNT (MUST be zero) | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | NSCOUNT (MUST be zero) | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ARCOUNT (MUST be zero) | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | | / DSO Data / / / +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Push] or a Discovery Relay interface subscription [Relay]. Whether a message is a DSO request message or a DSO unidirectional message is determined only by the specification for the Primary TLV. An acknowledgment cannot be requested by including a nonzero MESSAGE ID in a message that is required according to its Primary TLV to be unidirectional. Nor can an acknowledgment be prevented by sending a MESSAGE ID of zero in a message that is required to be a DSO request message according to its Primary TLV. A responder that receives either such malformed message MUST treat it as a fatal error and forcibly abort the connection immediately. In a DSO request message or DSO unidirectional message, the DNS Header Query/Response (QR) bit MUST be zero (QR=0). If the QR bit is not zero, the message is not a DSO request or DSO unidirectional message. In a DSO response message, the DNS Header QR bit MUST be one (QR=1). If the QR bit is not one, the message is not a DSO response message. In a DSO response message (QR=1), the MESSAGE ID field MUST NOT be zero, and MUST contain a copy of the value of the (nonzero) MESSAGE ID field in the DSO request message being responded to. If a DSO response message (QR=1) is received where the MESSAGE ID is zero, this is a fatal error and the recipient MUST forcibly abort the connection immediately. The DNS Header OPCODE field holds the DSO OPCODE value (6). The Z bits are currently unused in DSO messages; in both DSO request messages and DSO responses, the Z bits MUST be set to zero (0) on transmission and MUST be ignored on reception. In a DSO request message (QR=0), the RCODE is set according to the definition of the request. For example, in a Retry Delay message (Section 6.6.1), the RCODE indicates the reason for termination. However, in most DSO request messages (QR=0), except where clearly
specified otherwise, the RCODE is set to zero on transmission, and silently ignored on reception. The RCODE value in a response message (QR=1) may be one of the following values: +------+-----------+------------------------------------------------+ | Code | Mnemonic | Description | +------+-----------+------------------------------------------------+ | 0 | NOERROR | Operation processed successfully | | | | | | 1 | FORMERR | Format error | | | | | | 2 | SERVFAIL | Server failed to process DSO request message | | | | due to a problem with the server | | | | | | 4 | NOTIMP | DSO not supported | | | | | | 5 | REFUSED | Operation declined for policy reasons | | | | | | 11 | DSOTYPENI | Primary TLV's DSO-Type is not implemented | +------+-----------+------------------------------------------------+ Use of the above RCODEs is likely to be common in DSO but does not preclude the definition and use of other codes in future documents that make use of DSO. If a document defining a new DSO-TYPE makes use of response codes not defined here, then that document MUST specify the specific interpretation of those RCODE values in the context of that new DSO TLV. The RCODE field is followed by the four zero-valued count fields, followed by the DSO Data. Section 5.4.4. A DSO request message or DSO unidirectional message MUST contain at least one TLV. The first TLV in a DSO request message or DSO unidirectional message is referred to as the "Primary TLV" and determines the nature of the operation being performed, including whether it is a DSO request or a DSO unidirectional operation. In some cases, it may be appropriate to include other TLVs in a DSO request message or DSO unidirectional message, such as the DSO
Encryption Padding TLV (Section 7.3). Additional TLVs follow the Primary TLV. Additional TLVs are not limited to what is defined in this document. New Additional TLVs may be defined in the future. Their definitions will describe when their use is appropriate. An unrecognized Primary TLV results in a DSOTYPENI error response. Unrecognized Additional TLVs are silently ignored, as described in Sections 5.4.5 and 8.2. A DSO response message may contain no TLVs, or may contain one or more TLVs, appropriate to the information being communicated. Any TLVs with the same DSO-TYPE as the Primary TLV from the corresponding DSO request message are Response Primary TLV(s) and MUST appear first in a DSO response message. A DSO response message may contain multiple Response Primary TLVs, or a single Response Primary TLV, or in some cases, no Response Primary TLV. A Response Primary TLV is not required; for most DSO operations the MESSAGE ID field in the DNS message header is sufficient to identify the DSO request message to which a particular response message relates. Any other TLVs in a DSO response message are Response Additional TLVs, such as the DSO Encryption Padding TLV (Section 7.3). Response Additional TLVs follow the Response Primary TLV(s), if present. Response Additional TLVs are not limited to what is defined in this document. New Response Additional TLVs may be defined in the future. Their definitions will describe when their use is appropriate. Unrecognized Response Additional TLVs are silently ignored, as described in Sections 5.4.5 and 8.2. The specification for each DSO TLV determines what TLVs are required in a response to a DSO request message using that TLV. If a DSO response is received for an operation where the specification requires that the response carry a particular TLV or TLVs, and the required TLV(s) are not present, then this is a fatal error and the recipient of the defective response message MUST forcibly abort the connection immediately. Similarly, if more than the specified number of instances of a given TLV are present, this is a fatal error and the recipient of the defective response message MUST forcibly abort the connection immediately.
Push], the subsequent event notifications are then sent as DSO unidirectional messages. This is appropriate because the client initiated the message stream by virtue of its Push Notification subscription, thereby indicating its support of Push Notifications and its desire to receive those notifications. Similarly, after a Discovery Relay client has subscribed to receive inbound multicast DNS (mDNS) [RFC6762] traffic from a Discovery Relay, the subsequent stream of received packets is then sent using DSO unidirectional messages. This is appropriate because the client initiated the message stream by virtue of its Discovery Relay link subscription, thereby indicating its support of Discovery Relay and its desire to receive inbound mDNS packets over that DSO Session [Relay].
RFC7830] used for security purposes is not permitted in a DSO message, so if message padding is desired for DSO messages, then the DSO Encryption Padding TLV described in Section 7.3 MUST be used. A DSO message can't contain a TSIG record because a TSIG record is included in the additional section of the message, which would mean that ARCOUNT would be greater than zero. DSO messages are required to have an ARCOUNT of zero. Therefore, if use of signatures with DSO messages becomes necessary in the future, a new DSO TLV would have to be defined to perform this function. Note, however, that while DSO *messages* cannot include EDNS(0) or TSIG records, a DSO *session* is typically used to carry a whole series of DNS messages of different kinds, including DSO messages and other DNS message types like Query [RFC1034] [RFC1035] and Update [RFC2136]. These messages can carry EDNS(0) and TSIG records. Although messages may contain other EDNS(0) options as appropriate, this specification explicitly prohibits use of the edns-tcp-keepalive EDNS(0) Option [RFC7828] in *any* messages sent on a DSO Session (because it is obsoleted by the functionality provided by the DSO Keepalive operation). If any message sent on a DSO Session contains an edns-tcp-keepalive EDNS(0) Option, this is a fatal error and the recipient of the defective message MUST forcibly abort the connection immediately.
Section 5.4.1, whether an outgoing DSO message with the QR bit in the DNS header set to zero is a DSO request or a DSO unidirectional message is determined by the specification for the Primary TLV, which in turn determines whether the MESSAGE ID field in that outgoing message will be zero or nonzero. Every DSO message with the QR bit in the DNS header set to zero and a nonzero MESSAGE ID field is a DSO request message, and MUST elicit a corresponding response, with the QR bit in the DNS header set to one and the MESSAGE ID field set to the value given in the corresponding DSO request message. Valid DSO request messages sent by the client with a nonzero MESSAGE ID field elicit a response from the server, and valid DSO request messages sent by the server with a nonzero MESSAGE ID field elicit a response from the client. Every DSO message with both the QR bit in the DNS header and the MESSAGE ID field set to zero is a DSO unidirectional message and MUST NOT elicit a response.
Section 9.5 for further discussion of why this is important.
Section 5.4.1, an initiator MUST NOT reuse a MESSAGE ID that it already has in use for an outstanding DSO request message (unless specified otherwise by the relevant specification for the DSO-TYPE in question). At the very least, this means that a MESSAGE ID can't be reused in a particular direction on a particular DSO Session while the initiator is waiting for a response to a previous DSO request message using that MESSAGE ID on that DSO Session (unless specified otherwise by the relevant specification for the DSO-TYPE in question), and for a long-lived operation, the MESSAGE ID for the operation can't be reused while that operation remains active. If a client or server receives a response (QR=1) where the MESSAGE ID is zero, or is any other value that does not match the MESSAGE ID of any of its outstanding operations, this is a fatal error and the recipient MUST forcibly abort the connection immediately. If a responder receives a DSO request message (QR=0) where the MESSAGE ID is not zero, the responder tracks request MESSAGE IDs, and the MESSAGE ID matches the MESSAGE ID of a DSO request message it received for which a response has not yet been sent, it MUST forcibly abort the connection immediately. This behavior is required to prevent a hypothetical attack that takes advantage of undefined behavior in this case. However, if the responder does not track MESSAGE IDs in this way, no such risk exists. Therefore, tracking MESSAGE IDs just to implement this sanity check is not required.
Section 6.6.1. Upon receiving an error response from the server, a client SHOULD NOT automatically close the DSO Session. An error relating to one particular operation on a DSO Session does not necessarily imply that all other operations on that DSO Session have also failed or that future operations will fail. The client should assume that the server will make its own decision about whether or not to end the DSO Session based on the server's determination of whether the error condition pertains to this particular operation or to any subsequent operations. If the server does not end the DSO Session by sending the client a Retry Delay message (Section 6.6.1), then the client SHOULD continue to use that DSO Session for subsequent operations. When a DSO unidirectional message type is received (MESSAGE ID field is zero), the receiver should already be expecting this DSO message type. Section 5.4.5 describes the handling of unknown DSO message types. When a DSO unidirectional message of an unexpected type is received, the receiver SHOULD forcibly abort the connection. Whether the connection should be forcibly aborted for other internal errors processing the DSO unidirectional message is implementation dependent according to the severity of the error.
Push] and Discovery Relay interface subscriptions [Relay]. Long-lived operations, if successful, will remain active until the initiator terminates the operation. However, it is possible that a long-lived operation may be valid at the time it was initiated, but then a later change of circumstances may render that operation invalid. For example, a long-lived client operation may pertain to a name that the server is authoritative for, but then the server configuration is changed such that it is no longer authoritative for that name. In such cases, instead of terminating the entire session, it may be desirable for the responder to be able to cancel selectively only those operations that have become invalid. The responder performs this selective cancellation by sending a new DSO response message with the MESSAGE ID field containing the MESSAGE ID of the long-lived operation that is to be terminated (that it had previously acknowledged with a NOERROR RCODE) and the RCODE field of the new DSO response message giving the reason for cancellation. After a DSO response message with nonzero RCODE has been sent, that operation has been terminated from the responder's point of view, and the responder sends no more messages relating to that operation. After a DSO response message with nonzero RCODE has been received by the initiator, that operation has been terminated from the initiator's point of view, and the canceled operation's MESSAGE ID is now free for reuse.