skip to content
ryu

NAT bought us IPv4. It made real-time audio weird.

NAT let the internet outgrow its public IPv4 address supply. It also made a connected VoIP call a surprisingly different problem from a working one.

8 min read

A diagram showing NAT translating a private address and port into a public mapping.

The phone rings. Both sides answer. The call timer starts.

Then nobody can hear anything.

I work on the telephony stack behind OmniDimension, and this is one of the problems that makes voice infrastructure look easy right up until it is not. The AI can have a great voice, the speech recognition can be fast, and the prompt can be perfect. None of it matters if the audio cannot find a stable route to the other person.

The culprit is often NAT.

NAT was a very good idea#

The old internet model was simple: a machine had a public IP address and another machine could send packets to it. That stopped scaling when the world ran short on IPv4 addresses.

NAT, short for Network Address Translation, gave us a practical compromise. A home, office, mobile carrier, or cloud network can use private addresses internally and share a smaller number of public addresses with the internet.

Your laptop might be 192.168.1.20:5004 inside a network. When it sends a packet outward, the router can create a mapping like this:

192.168.1.20:5004  ->  203.0.113.8:62001

To the internet, the packet appears to come from 203.0.113.8:62001. The NAT remembers that replies to that public address and port should be passed back to the laptop.

That one idea let an enormous number of devices share scarce IPv4 space. It is hard to overstate how useful that was.

But it changed the shape of connectivity. A device behind NAT is no longer directly addressable in the way an old internet host was. It can usually start an outbound conversation. It cannot assume that an arbitrary incoming packet knows how to reach it.

That is fine for loading a website. It is much more interesting for a live call.

A connected call and a working call are different things#

VoIP has two jobs that are easy to confuse.

Signaling creates and controls the call. With SIP, that is the conversation that says “call this number,” “it is ringing,” “they answered,” and “hang up.”

Media carries the actual sound. That is usually RTP: a continuous flow of small, time-sensitive packets in both directions.

Signaling can succeed while media fails.

SIP signaling succeeds while an inbound RTP media path is blocked at the NAT PHONE NAT VOICE EDGE SIP: invite SIP: answered RTP: audio out RTP: audio back call state: connected blocked mapping
the call can be connected while one direction of audio has no route

That is why a call can look completely connected in an application while producing silence or one-way audio. The call session exists. The audio packets simply do not have a viable bidirectional route.

This distinction is not academic. It changes how I debug a bad call.

  • Ringing but silence on both sides: look at the media path, not the prompt or the model.
  • Caller can hear the agent but the agent cannot hear the caller: one direction of RTP is working and the other is not.
  • Audio works for a short time, then dies: suspect NAT state, keepalives, or a stateful firewall.
  • It works on home Wi-Fi but not an office network: the code did not change. The network policy probably did.

The NAT detail that decides the outcome#

There are two useful questions to ask about a NAT. Old terminology such as “full cone” and “symmetric NAT” tries to compress these into labels, but the behavior is easier to reason about directly.

How does it map addresses? Some NATs keep the same public address and port while an internal device talks to different destinations. Others create a different public mapping for each destination.

Who can send packets back? Some NATs allow packets from any external sender once a mapping exists. Others only permit a known address, or the exact address and port the device contacted first.

The more restrictive those rules are, the less likely a direct media path becomes. That is not a broken router. It is usually a reasonable security or network-management decision. A voice system has to work with that reality instead of expecting customers to reconfigure their office firewall for every call.

STUN, ICE, and TURN are not three competing features#

They are a sequence.

STUN asks a public server, “what address and port do you see me coming from?” It gives a client a view of the public mapping created by its NAT.

ICE collects possible routes for both sides, then tests them. It can try a local route, a public-facing route learned through STUN, and a relay route. The point is not to guess which path should work. The point is to prove it.

TURN is the fallback when direct connectivity is not possible. It gives the client a public relay address. Both sides can send media to the relay, and the relay forwards the packets between them.

STUN discovers a public mapping, ICE tests possible routes, and TURN relays media when direct connectivity fails STUN discover public mapping ICE test candidate routes TURN relay media when needed prefer a proven direct path direct path failed
discovery, testing, then a relay when the network will not permit a direct path

TURN costs bandwidth and adds another hop, so a good implementation prefers a direct path when one is available. But a relay is not a failure. It is the reason a call still works from a restrictive enterprise network, a carrier-grade NAT, or a hotel Wi-Fi network that would otherwise make direct media impossible.

The standards describe this flow precisely: ICE gathers and checks candidates, while TURN provides the relay path when needed. STUN is the discovery mechanism underneath them.

What this means when you own a telephony stack#

At OmniDimension, calls can arrive through Twilio, Exotel, or an existing SIP carrier. That means the product encounters the public internet in all its normal, messy forms: carrier networks, enterprise firewalls, consumer routers, mobile networks, and private cloud boundaries.

The responsibility starts before the speech model sees a word and ends after the caller hears the answer.

The practical system has to care about all of this:

  • SIP session setup and the media address it negotiates
  • RTP reaching both directions, not just a successful call-status event
  • codec boundaries between carrier audio and the real-time conversation
  • media continuity through transfers and recordings
  • useful call traces when the failure only happens on one network

The point is not that every call uses STUN, ICE, or TURN in the same way. PSTN calls, SIP trunks, browser calls, and carrier media streams have different shapes. The deeper rule is the same: signaling and media are separate paths, and each one has to be observed as its own system.

That is the knowledge I keep returning to. “The call connected” is an event. “The caller had a clear conversation” is the outcome.

NAT did not make the internet worse#

It made the IPv4 internet possible at a scale we still rely on. The awkwardness comes from asking a network built around outbound mappings to behave like a direct, real-time conversation between two private devices.

Once you see that trade-off, a lot of VoIP bugs stop looking random.

The call did not fail because the AI was confused. It failed because the audio needed a route, and the route had to be discovered, kept alive, and sometimes relayed.

That is the unglamorous part of telephony infrastructure. When it works, nobody notices it. When it does not, the smartest voice model in the world is just talking into the void.

Further reading#