Back to Site
Loading...
Searching...
No Matches
nat_status.h File Reference

What the mesh has told us about our own side of the NAT. More...

#include "librats/util/rats_export.h"
#include "librats/core/address.h"
#include "librats/peer/peer_id.h"
#include <cstddef>
#include <mutex>
#include <unordered_map>
#include <vector>
Include dependency graph for nat_status.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

class  librats::ExternalAddressService
 The read side, published in the node's ServiceRegistry so a NAT-traversal module can consult it without holding the Node: More...
 
class  librats::NatStatus
 

Namespaces

namespace  librats
 

Enumerations

enum class  librats::NatMapping : uint8_t { librats::Unknown , librats::Open , librats::EndpointIndependent , librats::EndpointDependent }
 How the NAT in front of our shared datagram socket maps it, as far as the mesh has been able to show. More...
 

Functions

const char * librats::to_string (NatMapping) noexcept
 

Detailed Description

What the mesh has told us about our own side of the NAT.

A node behind a NAT cannot see its own external endpoint; only somebody on the other side can. The usual answer is a STUN server, but a connected mesh already carries the same information for free — and, unlike a single STUN reply, it carries it from several independent vantage points, which is what turns a bare address into a statement about how the NAT behaves.

The source is the identify exchange (node/identify.h). Each peer reports the address it observed us connecting from; on a DATAGRAM link that address is the NAT's rewriting of the one socket every UDP peer shares, so its port is exactly the port a third party must aim at to reach us. (On TCP the port is an ephemeral one our OS picked per connection and means nothing, so it is not reported and never reaches this class.)

Two peers are then enough to classify the mapping:

  • both see the SAME external port → the NAT maps our socket to one port regardless of who we are talking to (endpoint-independent, "cone"). This is the case a hole punch works in: the port one peer tells us about is the port another peer can dial.
  • they see DIFFERENT ports → the NAT picks a fresh mapping per destination (endpoint-dependent, "symmetric"). Nothing we learn from one peer predicts what a third will see, so punching to an advertised endpoint cannot work and a relay is the only way through.
  • the observed endpoint is one of our own local addresses → there is no NAT in the path at all, and an ordinary dial already reaches us.

Threading: observations arrive on reactor threads (possibly several), readers are application/subsystem threads. One small mutex; nothing on a data path.

Definition in file nat_status.h.