---
title: DNS request serialization
summary: Converts an in-memory Request into the DNS wire-format byte layout the server expects.
status: draft
owner: SAIF Documentation
last_reviewed: 2026-07-30
library: SAIF.Framework.DNS
reference_type: package
operation_id: OP-DNS-003
trigger: Resolver.Lookup invokes Request.GetMessage
---

# DNS request serialization

This operation turns a `Request`'s in-memory state into the raw byte array that DNS servers expect on the wire. It writes the header, the section counts, and each encoded question in order, leaving the two transaction-id bytes blank so the transport stage can stamp them immediately before the datagram is sent.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-DNS-003 |
| **Trigger** | Generic DNS lookup needs request bytes to transmit |
| **Inputs** | `Opcode`, `RecursionDesired`, the `_questions` collection |
| **Outputs** | Request `byte[]` |
| **Primary components** | `Request.GetMessage`, `Request.AddDomain` |
| **Entry point** | `SAIF.Framework.DNS\Request.cs` |

## Steps

1. Create a growable `ArrayList` to accumulate the message bytes; the final length is not known until every question is encoded.
2. Reserve the first two bytes as zero-value placeholders for the transaction identifier; the transport stage overwrites these bytes with a real id immediately before sending.
3. Write the first flag byte by combining the request's `Opcode` with the recursion-desired bit when `RecursionDesired` is set.
4. Write a zero-value second flag byte.
5. Write the question count as a two-byte value taken from `_questions.Count`.
6. Write zero counts for the answer, name-server, and additional-record sections, because this library only ever sends a question section.
7. Iterate each `Question` in `_questions`, in the order they were added.
8. For each question, encode the domain name using `AddDomain`.
   - Split the dotted domain name into its labels.
   - Append each label's length byte, followed immediately by that label's character bytes.
   - Append a trailing zero byte to terminate the domain name.
9. After the encoded domain, append the question's type and class, each as a two-byte value with a zero high byte.
10. Copy the accumulated bytes into a fixed-length `byte[]` and return it.

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
	Start([GetMessage called]) --> H[Reserve id bytes and write flags]
	H --> C[Write question count and zeroed section counts]
	C --> Q[Encode each question: domain, type, class]
	Q --> A[Copy accumulated bytes to fixed byte array]
	A --> EndOk([Return request bytes])
```

## Failure and edge-case behavior

- This operation performs no validation of its own; it assumes every `Question` already holds a valid domain, type, and class, since those were checked when the `Question` was constructed.
- A request with zero questions still serializes successfully, producing a message with a question count of zero.
- A request with multiple questions serializes successfully as well, even though the source code's own comments note that many DNS servers do not support multi-question messages; the library does not enforce a single-question limit.

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)

## Sources
- SAIF.Framework.DNS\Request.cs
