System Design
Design scope
The tunnel transfers a file in one direction, from a client to an authoritative server. Rather than encapsulating arbitrary IP packets, it divides the file into chunks and places each encoded chunk in a DNS query name.
The receiver extracts the encoded labels, recovers the protected data, and places the decoded file fragment in a reassembly buffer. Transfer metadata identifies the file, the position of the fragment, and the number of chunks required for completion.
Architecture
The system has three relevant participants:
- Client: reads the file, constructs chunks, protects and encodes them, and sends queries.
- DNS resolution infrastructure: forwards queries under the controlled domain to its authoritative nameserver.
- Authoritative server: receives query names, decodes and authenticates chunks, and reconstructs the file.
The client can send directly to the authoritative server or to a recursive resolver. Through recursive resolution, the client sends an ordinary DNS request to the resolver, which eventually delivers the queried name to the domain’s authoritative server.

Sequence diagram of the proposed DNS tunneling tool.
Transfer pipeline
The transfer proceeds through the following stages:
- Establish a session, either with a fixed development key or an ECDH exchange.
- Read the input file as a byte sequence.
- Divide it into payload fragments.
- Append a metadata section to each fragment.
- Encrypt and authenticate the complete chunk.
- Transform the protected data into the selected DNS-compatible representation.
- Append the controlled domain to form a complete query name.
- Send the query to the configured server or resolver.
- At the receiver, extract the encoded labels and reverse the representation.
- Authenticate, decrypt, and parse the chunk.
- Insert the payload at its indexed position in the corresponding transfer buffer.
- Reconstruct the file when every expected chunk is present.
The transport and reassembly logic are independent of the selected encoding. This allows regex/FTE, weighted Huffman, and the Base32 baseline to operate within the same file-transfer pipeline.
Chunk sizes
The configured size specifies the total pre-encryption chunk length, including metadata. The metadata length is fixed at 16 bytes, so the maximum file-payload length in a full chunk is
The final fragment can be shorter than . Its actual length is recorded in the metadata rather than inferred from the configured size. The encryption envelope and the subsequent encoding expand the chunk further, so the configured size must leave enough capacity for those layers as well.
Metadata layout
Each plaintext chunk has the structure
<file-payload> || <16-byte metadata>
| Field | Type | Size | Purpose |
|---|---|---|---|
version | u8 | 1 byte | Identifies the metadata format. |
flags | u8 | 1 byte | Provides room for transfer options and extensions. |
payload_len | u16 | 2 bytes | Records the actual file-payload length in this chunk. |
chunk_index | u32 | 4 bytes | Identifies the fragment’s position in the file. |
total_chunks | u32 | 4 bytes | Records the number of fragments required for completion. |
file_id | u32 | 4 bytes | Groups chunks belonging to the same file. |
The metadata supports three important properties. Payload length handles a short final fragment. Indexes permit out-of-order arrival. File identifiers and total counts allow simultaneous receiver state and completion checks without depending on arrival order.
Session establishment
When key exchange is enabled, the client sends an initial TXT query containing a transfer identifier, the chosen curve, and its public key. The server replies with its public key. Both derive the same symmetric encryption and authentication keys from the ECDH secret.
The none mode bypasses this exchange and uses the fixed key provided for development. It is useful for testing the pipeline, but does not provide meaningful secrecy.
Query-name assembly
Each encoded chunk is placed before the controlled domain:
<encoded-chunk>.<controlled-domain>.<TLD>
This structure preserves normal DNS routing. The controlled suffix determines which authoritative server receives the query; the labels before it contain the encoded chunk.
The assembled name must satisfy both the per-label limit and the complete-name limit. A longer suffix leaves less room for encoded payload. With weighted Huffman output, name length also depends on the particular ciphertext bits, so a capacity estimate based on average codeword length requires a margin.
Sending and acknowledging queries
The client generates one DNS query per encoded chunk. Runtime options control query type, timeout, retries, retry delay, and an optional delay between queries. These settings govern delivery and pace without changing the underlying representation.
The server returns a DNS response code indicating success or error. The client tracks the outcome of each query and can retry according to its configured policy. Repeated delivery of an already accepted chunk must not append the same file data a second time.
Receiver processing
The server runs a UDP DNS loop. For each incoming request it:
- Parses the DNS packet and obtains the query name.
- Checks whether the name belongs to the configured domain.
- Extracts the encoded part of a matching name.
- Reverses the selected encoding and validates the protected chunk.
- Separates payload from metadata and validates its fields.
- Inserts the fragment into the buffer selected by file identifier and chunk index.
- Returns the appropriate DNS response.
Unrelated DNS traffic is not treated as a transfer chunk. Duplicate indexes are counted but not reinserted. Sessions that do not complete can expire according to the configured lifetime.
Reassembly
Completion occurs when all expected chunk indexes are present. Payloads are concatenated in index order, producing the original file byte stream. The output uses a .bin extension with a generated name:
recv_<file_id>_<total_chunks>_<timestamp>.bin
The receiver’s reconstruction therefore depends on the explicit metadata, not on the lexical order of names or the order of packet arrival.
Design limitations
Encoding can reduce certain payload indicators, but the transport still produces many distinct queries to a controlled domain. Long query names and high DNS volume remain visible. Frequency shaping also requires more characters per encrypted bit on average, increasing the number of chunks needed for a transfer.