Skip to content

DNS response parsing

This operation converts the raw reply datagram into the library's object model. It reads the DNS header flags and section counts, walks the question and resource-record sections in wire order, and dispatches each supported RDATA payload into a typed record class, skipping any record type it does not recognize.

Field Value
Operation ID OP-DNS-005
Trigger Generic DNS lookup receives reply bytes from the UDP transfer stage
Inputs Reply byte[]
Outputs Populated Response; throws InvalidResponseException when the question section cannot be parsed
Primary components Response.Response, Question, Answer, NameServer, AdditionalRecord, ResourceRecord, Pointer.ReadDomain
Entry point SAIF.Framework.DNS\Response.cs

Steps

  1. Read bytes 2 and 3 of the reply as the DNS header flag bytes.
  2. Convert the low four bits of byte 3 into a ReturnCode; if the resulting value is greater than 6, coerce it to ReturnCode.Other.
  3. Derive AuthoritativeAnswer, RecursionAvailable, and MessageTruncated from their respective header flag bits.
  4. Read the question, answer, name-server, and additional-record counts from bytes 4 through 11, and allocate arrays of the corresponding sizes.
  5. Create a Pointer positioned at byte 12, immediately after the fixed 12-byte DNS header.
  6. Parse each question in order by constructing new Question(pointer).
  7. If a question cannot be parsed, catch the exception and rethrow it as InvalidResponseException, so the caller never receives a partially built Response (BR-007).
  8. Parse each answer, name-server, and additional record in wire order by constructing the matching ResourceRecord subtype.
  9. For each resource record, read the owner domain, record type, record class, TTL, and RDATA length.
  10. Dispatch RDATA decoding according to the record's DnsType.
  11. DnsType.NS: read one domain name and populate an NSRecord.
  12. DnsType.MX: read the 16-bit preference value, then read the exchange domain name, and populate an MXRecord.
  13. DnsType.ANAME: read four raw bytes and convert them into an IPv4 address for an ANameRecord.
  14. DnsType.SOA: read two domain names, then five integer fields (serial, refresh, retry, expire, and default TTL), and populate a SoaRecord.
  15. Any other DnsType: advance the pointer past the declared RDATA length without decoding it, leaving Record unset for that entry.
  16. Whenever a domain name needs decoding, delegate to Pointer.ReadDomain.
    • Read the next length byte.
    • If its top two bits mark RFC1035 name compression, follow the referenced pointer recursively and append the resolved suffix.
    • Otherwise, read the label's character bytes, inserting a . separator between labels, and stop when a zero-length label terminates the name.
  17. Leave the populated header flags and record arrays on the Response instance for the caller to read.

Process flow

The following diagram visualizes this operation's control flow.

flowchart TD
    Start([Response constructed from reply bytes]) --> H[Read header flags and section counts]
    H --> Q[Parse question section]
    Q --> D{Question parses successfully?}
    D -->|No| EndErr([Throw InvalidResponseException])
    D -->|Yes| R[Parse answer, name-server, additional records]
    R --> T[Decode supported RDATA types and domain names]
    T --> EndOk([Return populated Response])

Failure and edge-case behavior

  • Unsupported resource-record types are skipped by advancing past their RDATA rather than treated as a fatal parse error; the corresponding Record property is left unset.
  • Only question-section parsing failures are explicitly wrapped as InvalidResponseException; exceptions raised while constructing answer, name-server, or additional-record entries propagate directly, unwrapped.
  • Domain-name decoding follows RFC1035 compression pointers recursively, so compressed and uncompressed names both resolve to the same dotted-string representation.

Sources

  • SAIF.Framework.DNS\Response.cs
  • SAIF.Framework.DNS\Question.cs
  • SAIF.Framework.DNS\ResourceRecord.cs
  • SAIF.Framework.DNS\Pointer.cs
  • SAIF.Framework.DNS\MXRecord.cs
  • SAIF.Framework.DNS\ANameRecord.cs
  • SAIF.Framework.DNS\NSRecord.cs
  • SAIF.Framework.DNS\SoaRecord.cs