You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
To increase connectivity between nodes as much as we can.
Relay is good, but is not so "peer-to-peer", and at the cost of community maintained relay servers. Also, as we have tested, many of our customers are behind some kind of NATs. Hopefully hole-punching would solve some other percents of the problem.
Technical details
Hole-punching is better understood at protocol level. To track an NAT mapping, a gateway(or some other device) would record at least 3 addresses(and ports): local internal address, local external address and remote external address. For an outbound packet, the gateway would replace its local internal address with local external address; for a inbound packet, the gateway would replace its local external address with local internal address. From the perspective of a internal node, the connection is between local internal address and remote external address.
If a gateway only do some translations, the problem would be much easier. But a gateway would also apply some restrictions to inbound packets, mainly for security reasons. This wiki lists 4 types of NATs and their restrictions for inbound packets, and theoretically UDP hole-punching could solve 3 types. For TCP packets, I observed additional restrictions, like sequence number check, so UDP is a better choice.
The diagram below is a punching example.
Node1 and Node2 are two nodes behind different NAT gateways, with internal address 192.168.0.1:4001 and 10.0.0.2:4001, respectively. A helper node with public IP 3.0.0.1 would assist connection establishment, but not relay data for them.
For the first step, the public IP node would see Node1 has external address 100.100.0.1:10000, Node2 has 200.200.0.1:20000, and send this information to one another side. Knowing the other's external address, Node1 would send packets to 200.200.0.1:20000, on receiving Node1's packet, NAT1 would allow inbound packets from 200.200.0.1:20000 (otherwise normal communication is disturbed). Node2 and NAT2 are the same. The first 1 or more packets might be dropped because of timing (inbound packets not already allowed), but eventually a 2-way communication would be established.
And for multiple layers of NATs, the situation is similar, only take longer time.
Reason
To increase connectivity between nodes as much as we can.
Relay is good, but is not so "peer-to-peer", and at the cost of community maintained relay servers. Also, as we have tested, many of our customers are behind some kind of NATs. Hopefully hole-punching would solve some other percents of the problem.
Technical details
Hole-punching is better understood at protocol level. To track an NAT mapping, a gateway(or some other device) would record at least 3 addresses(and ports): local internal address, local external address and remote external address. For an outbound packet, the gateway would replace its local internal address with local external address; for a inbound packet, the gateway would replace its local external address with local internal address. From the perspective of a internal node, the connection is between local internal address and remote external address.
If a gateway only do some translations, the problem would be much easier. But a gateway would also apply some restrictions to inbound packets, mainly for security reasons. This wiki lists 4 types of NATs and their restrictions for inbound packets, and theoretically UDP hole-punching could solve 3 types. For TCP packets, I observed additional restrictions, like sequence number check, so UDP is a better choice.
The diagram below is a punching example.
Node1
andNode2
are two nodes behind different NAT gateways, with internal address192.168.0.1:4001
and10.0.0.2:4001
, respectively. A helper node with public IP3.0.0.1
would assist connection establishment, but not relay data for them.For the first step, the public IP node would see
Node1
has external address100.100.0.1:10000
,Node2
has200.200.0.1:20000
, and send this information to one another side. Knowing the other's external address,Node1
would send packets to200.200.0.1:20000
, on receivingNode1
's packet,NAT1
would allow inbound packets from200.200.0.1:20000
(otherwise normal communication is disturbed).Node2
andNAT2
are the same. The first 1 or more packets might be dropped because of timing (inbound packets not already allowed), but eventually a 2-way communication would be established.And for multiple layers of NATs, the situation is similar, only take longer time.
Limitations
Implementation
I noticed inside libp2p ecosystem, we already have port reuse and QUIC transport, both are great technologies. The missing parts include:
I'd like to know if someone is also digging on the problem, or some work is done or on-going? I plan to code for it very soon.
The text was updated successfully, but these errors were encountered: