# How MasterDnsVPN Handles Packet Loss in Its Custom DNS Tunnel Protocol

> MasterDnsVPN ensures reliable data transfer over DNS tunnels by implementing an ARQ layer with state tracking adaptive timers retransmissions and NACK handling for robust performance.

- Repository: [Amin Mahmoudi/MasterDnsVPN](https://github.com/masterking32/MasterDnsVPN)
- Tags: internals
- Published: 2026-05-10

---

**MasterDnsVPN implements a full-featured ARQ (Automatic Repeat reQuest) layer that combines per-packet state tracking, adaptive RTO timers, periodic retransmit checks, and explicit NACK handling to guarantee reliable delivery over unreliable DNS/UDP transports.**

MasterDnsVPN is an open-source VPN solution that tunnels traffic through DNS queries to bypass network restrictions and censorship. Because DNS uses UDP—a connectionless, best-effort transport—the project must handle packet loss internally. The solution is a sophisticated reliability layer implemented in Go that mimics TCP-like guarantees while operating within DNS payload constraints.

## Per-Packet State Tracking in the Send Buffer

The ARQ engine maintains granular state for every transmitted packet until acknowledgment. These records live in the `sndBuf` map for data packets and `controlSndBuf` for control packets, both defined in [`internal/arq/arq.go`](https://github.com/masterking32/MasterDnsVPN/blob/main/internal/arq/arq.go).

### The sndBuf and controlSndBuf Maps

According to the source code at lines 1340-1380, each entry stores:
- The packet **sequence number**
- **CreatedAt**: timestamp of first transmission
- **LastSentAt**: timestamp of most recent transmission
- **CurrentRTO**: the retransmission timeout value currently applied
- **Retries**: counter for retransmission attempts
- **SampleEligible**: boolean flag indicating whether this transmission may be used for RTT sampling

This state persistence allows the system to detect missing acknowledgments and determine precisely when a retransmission is required.

### Retry Counters and RTO Tracking

Every packet carries a `Retries` counter that increments with each retransmission attempt. When this counter exceeds `maxDataRetries` (default approximately 60), the ARQ layer terminates the stream with an RST packet. This prevents infinite retransmission loops on permanently failed connections.

## The Retransmit Loop and Timeout Detection

A dedicated background goroutine runs `retransmitLoop`, which periodically invokes `checkRetransmits()` to scan for overdue packets.

### Periodic Checks with checkRetransmits()

As implemented in [`internal/arq/arq.go`](https://github.com/masterking32/MasterDnsVPN/blob/main/internal/arq/arq.go) at lines 1464-1490, this function executes approximately every **RTO/3** seconds. It compares the current time against each packet's `LastSentAt` timestamp. When `now - LastSentAt >= CurrentRTO`, the packet is immediately re-queued for transmission with an updated timeout.

### Exponential Backoff with Growth Factors

The ARQ layer applies adaptive backoff to prevent network congestion. Data packets use a growth factor of **1.35** (`dataRetransmitRTOGrowthFactor`), while control packets use **1.25** (`controlRetransmitRTOGrowthFactor`). These constants, defined in the same file, multiply the `CurrentRTO` value with each retransmission attempt, spacing subsequent retries further apart while maintaining responsiveness.

## Explicit Loss Recovery via Negative Acknowledgments

Beyond timer-based retransmission, MasterDnsVPN supports proactive loss signaling through `HandleDataNack`. When a receiver detects a missing sequence number, it transmits a NACK packet. Upon reception, the sender immediately re-queues the specific missing fragment using `PACKET_STREAM_RESEND`, bypassing the normal timeout wait. This mechanism, found at lines 1660-1670 of [`internal/arq/arq.go`](https://github.com/masterking32/MasterDnsVPN/blob/main/internal/arq/arq.go), enables rapid recovery from burst loss scenarios without waiting for the retransmission timer to expire.

## Adaptive RTT Estimation for Dynamic Networks

The protocol maintains two independent estimators—`dataAdaptiveRTO` and `controlAdaptiveRTO`—that dynamically adjust to network conditions. The `updateAdaptiveRTO` function processes RTT samples from acknowledged packets (marked with `SampleEligible`), updating the smoothed RTT (`srtt`) and variance (`rttvar`) using standard TCP-style algorithms. This adaptation ensures that retransmission timeouts remain tightly coupled to actual latency, reducing unnecessary retransmits on high-delay links while maintaining responsiveness on fast networks.

When `ReceiveAck` processes an acknowledgment, it removes the entry from the send buffer, records the RTT sample if eligible, and calls `signalWindowNotFull` to unblock the flow-control window.

## Implementation Example

The following Go code demonstrates configuring the ARQ layer for reliable DNS tunneling:

```go
// Create an ARQ instance (client side)
cfg := arq.Config{
    WindowSize:      512,
    RTO:             0.2,   // 200 ms base RTO
    MaxRTO:          5.0,   // seconds
    MaxDataRetries:  10,
    EnableControlReliability: true,
}
a := arq.NewARQ(1, 0, enqueuer, conn, 1400, logger, cfg)

// Start background workers (IO, write, retransmit)
a.Start()

// Send a payload – the ARQ layer stores it in sndBuf
payload := []byte("hello over DNS tunnel")
a.SendData(payload)

// Simulate loss by dropping the first transmission in the network
// (the test harness can configure the UDP socket to drop packets).

// After RTO expires, the retransmitLoop will call checkRetransmits(),
// see that the packet's CurrentRTO has elapsed, and push a resend:
//   enqueuer.PushTXPacket(... PACKET_STREAM_RESEND ...)
// The receiver will ACK the retransmitted copy, causing the entry to be removed.

```

## Summary

- MasterDnsVPN uses a complete ARQ implementation in [`internal/arq/arq.go`](https://github.com/masterking32/MasterDnsVPN/blob/main/internal/arq/arq.go) to provide TCP-like reliability over DNS/UDP
- Per-packet state in `sndBuf` and `controlSndBuf` enables precise timeout detection and retransmission tracking
- The `retransmitLoop` and `checkRetransmits()` functions provide periodic scans every RTO/3 seconds
- Adaptive RTO calculation with growth factors of 1.35 (data) and 1.25 (control) prevents congestion collapse while ensuring timely recovery
- Explicit NACK handling via `HandleDataNack` allows immediate recovery without waiting for timeouts
- Retry limits (default ~60) with RST fallback prevent resource exhaustion on unrecoverable connections

## Frequently Asked Questions

### What is the default retransmission timeout in MasterDnsVPN?

The base RTO is configurable but defaults to 200 milliseconds in the standard configuration. The actual timeout adapts dynamically based on network latency measurements, clamped to a maximum of 5 seconds (`MaxRTO`) to prevent excessive delays.

### How does MasterDnsVPN distinguish between original transmissions and retransmissions?

The protocol uses distinct packet type identifiers defined in [`internal/enums/packet_identity.go`](https://github.com/masterking32/MasterDnsVPN/blob/main/internal/enums/packet_identity.go). Retransmitted packets are marked as `PACKET_STREAM_RESEND` rather than `PACKET_STREAM_DATA`, allowing the receiver to handle them appropriately for RTT sampling and duplicate detection.

### What happens when the retry limit is reached?

When a packet's retry counter exceeds `maxDataRetries` (approximately 60 by default), the ARQ layer terminates the connection by sending an RST packet and closing the stream. This prevents infinite retransmission loops when the network path is completely broken.

### Why doesn't MasterDnsVPN use TCP instead of implementing custom ARQ?

MasterDnsVPN tunnels through DNS queries, which typically use UDP transport. Since many networks block or restrict non-DNS traffic, the application must encapsulate VPN data within standard DNS packets. TCP cannot be used for this encapsulation because DNS responses must fit within UDP datagram constraints, requiring a custom reliability layer optimized for DNS tunneling.