SAIF.Framework.DNS architecture¶
SAIF.Framework.DNS is a small, self-contained, low-level DNS client that performs lookups over raw UDP sockets in accordance with RFC1035 message framing. It has zero dependencies on other SAIF framework components and performs no I/O other than DNS UDP requests.
Responsibilities¶
- Build DNS query messages from caller-supplied domain, type, and class values (
Request,Question). - Transmit query messages over UDP to a caller-specified DNS server on port 53, with retry and timeout handling (
Resolver). - Parse raw UDP reply bytes into a structured
Response, including header flags/counts and Question/Answer/NameServer/AdditionalRecord sections (Response,Pointer). - Decode individual resource-record RDATA into typed records (
ANameRecord,MXRecord,NSRecord,SoaRecord) based on the record'sDnsType, skipping unrecognized types. - Provide a convenience MX-lookup operation that filters and sorts MX answers by preference (
Resolver.MXLookup). - Signal failure conditions via typed exceptions (
NoResponseException,InvalidResponseException).
Component boundaries¶
Resolver: static-only (sealed, private constructor) entry-point facade exposingLookupandMXLookup; owns UDP socket transfer and retry logic.Request: caller-facing message builder; holds one or moreQuestioninstances and serializes them to wire format viaGetMessage().Question: represents a single DNS query (domain/type/class); validates inputs and can also be constructed internally from aPointerwhen decoding an embedded question in a response.Response: parses a raw reply byte array intoReturnCode, questions, and resource-record arrays.ResourceRecord(and semantic subtypesAnswer,NameServer,AdditionalRecord): shared RR wire-format parser producing aRecordBasepayload.RecordBasesubtypes (ANameRecord,MXRecord,NSRecord,SoaRecord): typed RDATA payloads for the record kinds this library understands.Pointer: internal byte-array cursor used across parsing components to decode domain names (including RFC1035 message-compression pointers) and primitive wire values.Enums(DnsType,DnsClass,ReturnCode,Opcode): shared value types used across the request/response boundary.InvalidResponseException/NoResponseException: typed failure signals surfaced to callers.MXHelper.cs(namespaceSAIF.Framework.DNSLib): a parallel, independent MX-lookup implementation (its ownUdpClient-based transport and a distinctMXRecordtype) that is not part of the compiled component boundary — see Design constraints.
Interaction model¶
- Caller constructs a
Requestand adds one or moreQuestionobjects. Resolver.Lookup(request, dnsServer)serializes the request viaRequest.GetMessage(), sends it over UDP to port 53 with up to_udpRetryAttempts(2) retries and a 1-second receive timeout, then wraps the raw reply in aResponse.Response's constructor parses the DNS message header (flags, counts) and, via an internalPointercursor, decodesQuestion,Answer,NameServer, andAdditionalRecordarrays in wire order.- Each
ResourceRecorddecodes its RDATA into aRecordBasesubtype based onDnsType; unrecognized types are skipped by advancing the pointer past the record length. Resolver.MXLookup(domain, dnsServer)is a convenience wrapper that issues an MX question, filtersAnswers toMXRecordinstances, and returns them sorted by preference usingMXRecord'sIComparableimplementation.- The library does not call into any other SAIF assembly, database, configuration system, or security component; all interaction is confined to the caller and the target DNS server over UDP.
Architecture diagram¶
The following diagram shows the high-level component interactions for a lookup request.
flowchart TD
Caller[Caller] --> Request[Request / Question]
Request --> Resolver[Resolver]
Resolver -->|UDP port 53, retry x2, 1s timeout| DnsServer[External DNS server]
DnsServer -->|raw reply bytes| Resolver
Resolver --> Response[Response]
Response --> Pointer[Pointer<br>wire-format cursor]
Pointer --> Records[RecordBase subtypes<br>ANameRecord / MXRecord / NSRecord / SoaRecord]
Records --> Caller
Sequence diagram¶
The following diagram shows the primary request/response sequence for a lookup, including the retry path.
sequenceDiagram
participant Caller
participant Resolver
participant DnsServer as External DNS server
participant Response
Caller->>Resolver: Lookup(request, dnsServer) / MXLookup(domain, dnsServer)
Resolver->>DnsServer: UDP datagram (stamped transaction id)
alt matching-id reply received within 1s
DnsServer-->>Resolver: UDP reply bytes
else timeout or SocketException
Resolver->>DnsServer: retry (up to 2 additional attempts)
DnsServer-->>Resolver: UDP reply bytes
end
Resolver->>Response: new Response(replyBytes)
Response-->>Resolver: parsed Answer/NameServer/AdditionalRecord arrays
Resolver-->>Caller: Response (or thrown NoResponseException)
Design constraints¶
Resolveris a static-only utility class (private constructor,sealed), consistent with a stateless helper; it holds no instance state across calls.- Unrecognized resource-record types are skipped rather than causing a parse failure, so the response model is intentionally tolerant of unknown
DnsTypevalues. - A returned UDP datagram is only accepted if its 2-byte transaction id matches the request's stamped id; mismatched packets are ignored, implicitly triggering the retry loop.
- Malformed embedded questions during response parsing abort construction via
InvalidResponseExceptionrather than returning a partially-parsedResponse. - Dead/parallel implementation:
MXHelper.cs(namespaceSAIF.Framework.DNSLib) implements an independent, self-contained MX-lookup mechanism with its own rawUdpClienttransport, manual DNS wire encode/decode, and its own distinctMXRecordtype. It is present in the project folder but is not included in the<Compile>item group ofSAIF.BOF.Framework.DNS.csproj, so it has no effect on the assembly's public surface or runtime behavior. Its source is nonetheless captured by the repository-wide packaging nuspec glob (SAIF.Framework.Core\SAIF.BOF.Framework.Core.nuspec), which bundles it as loose source under the package'ssrcfolder even though it never executes*. Maintainers should treat this file as dead code and consider removing it or restoring it to the compile list to avoid confusion about which MX-lookup implementation is authoritative. It is not documented as part of the API reference for this library because it is not part of the compiled public surface.
Note: Statements marked with * were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts. Statements marked with ** could not be confirmed; treat as unknown until verified.
Related documentation¶
Sources¶
- SAIF.Framework.DNS\SAIF.BOF.Framework.DNS.csproj
- SAIF.Framework.DNS\Resolver.cs
- SAIF.Framework.DNS\Request.cs
- SAIF.Framework.DNS\Question.cs
- SAIF.Framework.DNS\Response.cs
- SAIF.Framework.DNS\ResourceRecord.cs
- SAIF.Framework.DNS\RecordBase.cs
- SAIF.Framework.DNS\ANameRecord.cs
- SAIF.Framework.DNS\MXRecord.cs
- SAIF.Framework.DNS\NSRecord.cs
- SAIF.Framework.DNS\SoaRecord.cs
- SAIF.Framework.DNS\Pointer.cs
- SAIF.Framework.DNS\Enums.cs
- SAIF.Framework.DNS\InvalidResponseException.cs
- SAIF.Framework.DNS\NoResponseException.cs
- SAIF.Framework.DNS\MXHelper.cs
- SAIF.Framework.Core\SAIF.BOF.Framework.Core.nuspec