4.3.30 · D3Computer Networks

Worked examples — NAT traversal, VPN, tunneling

2,645 words12 min readBack to topic

The scenario matrix

Before working examples, let us enumerate every case class this topic can throw at you. Each example below is tagged with the cell it fills.

Cell Case class What makes it different Example
A Simple encapsulation overhead one wrapper, positive-sized packet Ex 1
B Stacked / double tunnel (VPN-in-tunnel) overhead adds up Ex 2
C Degenerate: inner packet exceeds effective MTU fragmentation / drop Ex 3
D Limiting case: tiny payload overhead ratio → near 1 Ex 4
E Limiting case: huge payload overhead ratio → 0 Ex 4
F NAT-type decision (which traversal works?) full-cone vs symmetric Ex 5
G STUN mapping read-off (public IP:port) table arithmetic Ex 6
H Real-world word problem (throughput cost of TURN) latency + bandwidth Ex 7
I Exam twist: encryption expands the payload crypto overhead ≠ header only Ex 8

Why a matrix first? So you can see there are no hidden scenarios. Positive/normal, degenerate (too big), the two limits (tiny/huge), and the discrete decision cases (NAT type) — every input space is covered.


The two formulas we reuse

Everything here rests on two relations from the parent note. Let us re-anchor them so no symbol is unearned.

Why "ratio" and not just "bytes"? The ratio answers "what fraction of my bandwidth is wasted on wrappers?" — a percentage, comparable across packet sizes. The raw byte count answers "will it fit?". Different questions, different tools.


Cell A — Simple encapsulation overhead

  1. Add the outer headers. B. Why this step? GRE stacks an IP delivery header plus its own 8-byte GRE header; both are "outer" bytes the wire carries.
  2. Effective inner MTU. B. Why this step? The inner packet must fit inside the outer one; 28 B are spent before any inner byte.
  3. Does 1400 fit? ✓ — no fragmentation. Why this step? Always compare against , never against 1500.
  4. Overhead ratio. .

Verify: Wrapped packet = ✓ fits the path. Overhead means ~98% of wire bytes are useful — plausible for a fat 1400-byte packet.


Cell B — Stacked tunnels (double wrap)

  1. Sum all outer bytes. B. Why this step? Each wrapper is opaque to the one outside it; from the wire's view they are just more outer header. Bytes add.
  2. Effective inner MTU. B. Why this step? Both layers eat into the same 1500-B budget.
  3. Fit check. ✓.
  4. Overhead ratio. .

Verify: Total on-wire = ✓. Overhead 5.8% > Ex 1's 1.96% — more wrappers, more waste, as expected.


Cell C — Degenerate: inner packet too big

Figure — NAT traversal, VPN, tunneling
  1. Effective inner MTU. B. Why this step? IPsec tunnel mode wraps the entire inner IP packet plus ESP overhead — a hefty 73 B here.
  2. Compare. . The wrapped packet would be B — too big for the path. Why this step? This is exactly the degenerate cell: inner size exceeds effective MTU.
  3. Outcome. Either the router fragments it (slow, sometimes blocked by Firewalls) or, if the inner packet has the Don't-Fragment bit set, it is dropped and an ICMP "too big" is returned — which a firewall may swallow, causing a silent stall. Why this step? Look at s01: the red packet is longer than the outer envelope's mouth — it cannot go in whole.
  4. Largest safe inner packet. B.

Verify: ✓ exactly fits. One more byte () gives ✗ — so 1427 is the true ceiling.


Cells D & E — The two limits (tiny and huge payload)

Figure — NAT traversal, VPN, tunneling
  1. Tiny payload (cell D). . Why this step? When , the fraction : almost all bytes are wrapper. This is why interactive traffic (SSH keystrokes, VoIP) is bandwidth-inefficient through tunnels.
  2. Huge payload (cell E). . Why this step? When , : the fixed wrapper is negligible against a giant payload.
  3. The trend. Look at s02: as grows left→right, the overhead curve falls from ~100% toward 0. The fixed header is a toll: cheap per big truck, expensive per tiny scooter.

Verify: Both limits are bracketed: ✓. The function is strictly decreasing in , so tiny gives the max and huge gives the min. ✓


Cell F — Which traversal works? (NAT-type decision)

  1. Recall what each NAT does. Full-cone: one public port opened, anyone can use it. Symmetric: a new public port per destination. Why this step? Traversal success depends entirely on whether the port a peer learns via STUN is the same port used to reach the other peer.
  2. P learns its mapping via STUN. But P's NAT is symmetric: the port P sees when talking to the STUN server is different from the port it will allocate when talking to Q. Why this step? Q would send to P's STUN-reflexive port — but that port only maps back to the STUN server, not to Q. Q's packet has no matching entry → dropped.
  3. Try the reverse direction. P sends to Q's full-cone mapping — that does work (full-cone admits anyone). So P→Q punches a hole. But for a two-way connection ICE needs a working pair; Q→P still fails because of step 2. Why this step? A media connection needs both directions; one-way success is not enough.
  4. Decision. Symmetric × anything (except full-cone-with-luck) → fall back to TURN relay.

Verify: Matches the parent rule: "Symmetric NAT → traversal often fails → use TURN." The relay always works because both peers initiate outbound to the relay, each punching its own valid hole. ✓


Cell G — STUN mapping read-off

  1. Identify the reflexive candidate. The public mapping the peer must use is 198.51.100.7:41000. Why this step? STUN's whole job is to reveal the outside view — the address the NAT table maps back to this host.
  2. Why not the private one? 192.168.1.20 is non-routable on the public Internet (RFC 1918). A peer packet aimed there would never leave the peer's own LAN. Why this step? Private ranges (192.168.x.x, 10.x, 172.16–31.x) are reused everywhere; they cannot be globally addressed. See IPv4 exhaustion.
  3. Advertise. Host tells peer via signaling: "reach me at 198.51.100.7:41000."

Verify: The reply address = the NAT's outside mapping = 198.51.100.7:41000, matching the table entry 192.168.1.20:52000 ↔ 198.51.100.7:41000. ✓ Port advertised (41000) equals the translated port, not the internal 52000. ✓


Cell H — Real-world word problem (TURN cost)

  1. Total bitrate through relay. Up + down = Mbps. Why this step? TURN relays each direction separately, so both legs consume relay bandwidth.
  2. Duration in seconds. s.
  3. Total bits. bits. Why this step? bitrate × time = total bits. Watch units: Mbps = bits/s.
  4. Convert to gigabytes. bytes bytes GB (using bytes). Why this step? Bandwidth is billed in bytes; divide bits by 8.
  5. Cost. 0.3 \text{ GB} \times \0.10/\text{GB} = $0.03$.

Verify: Units cascade: \text{Mbit/s} \to \text{bit} \to \text{byte} \to \text{GB} \to \text{\}4\text{ Mbps}\times 600\text{ s} = 2400\text{ Mbit} = 300\text{ MB} = 0.3\text{ GB}, cost \0.03. Cheap per call — but multiply by thousands of concurrent calls and TURN becomes the reason engineers prefer direct traversal. ✓


Cell I — Exam twist: encryption expands the payload

  1. Padding first. ESP encrypts (payload + 2 trailer bytes) and pads to a 16-byte multiple. Encrypted region before pad = B. Next multiple of 16 above 1402 is . Pad bytes = B. Why this step? Block ciphers (TLS/IPsec often use AES with 16-byte blocks) require input length to be a whole number of blocks — this is real overhead that grows the payload, unlike a fixed header.
  2. Sum every added byte. B. Why this step? Encryption overhead = headers + IV + padding + authentication tag — students who count only the IP header get this exam question wrong.
  3. Fit check. Wrapped = ✓.
  4. Overhead ratio. .

Verify: rounded up to a 16-multiple: , so next multiple is , pad ✓. Total ✓. On-wire ✓, no fragmentation. ✓


Recall

Recall Which formula for "will it fit" vs "how wasteful"?

Fit ::: compare against . Waste ::: overhead ratio .

Recall Ex 3: largest safe inner packet with

, path 1500? B ::: (1428 would overflow to 1501).

Recall Ex 4: overhead limits as payload → 0 and → ∞?

ratio → 100%; ratio → 0% ::: fixed header is a toll — brutal on tiny packets, negligible on huge ones.

Recall Ex 5: symmetric × full-cone NAT — direct or TURN?

TURN relay ::: symmetric NAT allocates a new port per destination, so the STUN-learned port doesn't match; hole punching fails one way.

Recall Ex 8: why is crypto overhead more than a header?

It adds IV + padding-to-block-size + auth tag ::: padding even grows with payload alignment, not a fixed constant.