TCP hole punching
TCP hole punching odkazuje v počítačových sítích na situaci, kdy se dva počítače umístěné v LAN síti za NATem pokouší navzájem spojit pomocí odchozího TCP spojení. Taková situace je důležitá v případě peer-to-peer komunikace, jako je například VoIP (Voice over Internet Protocol), sdílení souborů, telekonference, chatovacích systémů a podobných aplikací.
TCP hole punching je běžně používaná NAT traversal technika pro vytvoření TCP spojení mezi dvěma peery za NATem v počítačové síti Internet. Termín NAT traversal je obecný pojem pro techniky, které vytvářejí a udržují TCP/IP spojení a nebo TCP spojení procházející NAT bránou.
Použité pojmy
V následujícím textu budou použity pojmy host, klient a peer téměř zaměnitelně.
Pojmy místní koncový bod a vnitřní koncový bod označují lokální IP:port, jak je viděn hostem na místní úrovni a jako vnitřní částí NATu.
Pojmy veřejný koncový bod a externí koncový bod označují externí IP:port mapován NATem, jak je vidět v síti a ve vnější části NATu.
Pojem vzdálený koncový bod označuje IP:port na jiného peera, jak je vidět ze sítě nebo vnějšími částmi obou NATů.
Popis
NAT traversal prostřednictvím TCP hole punching, je metoda pro vytvoření obousměrného TCP spojení mezi hosty v privátních sítích pomocí NATu. Tato metoda nebude fungovat se všemi typy NATů, protože jejich chování není standardizováné. Když se dva hosti připojí k sobě navzájem s pomocí TCP a přes odchozí spojení, jsou v "simultaneous TCP open" případu TCP stavu strojového diagramu.
Diagram Sítě
Peer A ←→ Brána A (NAT-a) ← .. Síť .. → Brána B (NAT-b) ←→ Peer B
Typy NATu
Dostupnost TCP hole punching techniky závisí na typu přidělování portů počítače používaného NATem. Dva peery za NATem pro připojení se navzájem prostřednictvím TCP simultaneous open[zdroj?] o sobě potřebují vědět trochu víc. Jedna věc, kterou nezbytně potřebují vědět, je „umístění“ druhého peeru, nebo vzdáleného koncového bodu.
Vzdálený koncový bod je údaj o IP adrese a portu, kam se peer chce připojí. Když dvojice peerů A a B, zahájí TCP spojení vazbou na místní porty Pa a Pb, tak potřebují vědět port vzdáleného koncového bodu tak, jak je mapován NATem, aby došlo k připojení.
Tady nastává jádro problému: pokud jsou oba peerové za NATem, jak se uhodne jaký je veřejný koncový bod druhého peeru? Tento problém se nazývá predikce NAT portu. Všechny TCP NAT traversal a hole punching metody musí vyřešit problém predikce portů.
Můžou být dva typy přidělování NAT portů:
- předvídatelné: Brána používá jednoduchý algoritmus pro mapování místního portu k portu NATu. Většinu času NAT bude používat port preservation, což znamená, že místní port je mapován k stejnému portu na NAT.
- nepředvídatelné: Brány použijí algoritmus, který je buď náhodný nebo příliš nepraktický na předvěď.
V závislosti na tom, zda NAT bude používat předvídatelné nebo nepředvídatelné chování, bude možné nebo nemožné provést TCP připojení přes TCP simultaneous open, jak je uvedeno níže v tabůlce připojení reprezentující různé případy a jejich dopad na koncovou komunikaci:
A Předvídatelné A Nepředvídatelné B předvídatelné ANO ANO B nepředvídatelné ANO NE - ANO: spojení bude fungovat pořád
- NE: spojení nebude téměř nikdy fungovat
Techniky
Metody Predikce Portů (s předvídatelnými NATem)
Zde jsou některé z metod, které používá NAT, aby umožnil peerům provést předpověď portu:
- NAT přiřazuje k po sobě jdoucím interním portům po sobě jdoucí externí porty.
Pokud vzdálený peer má informace o mapování, pak může uhodnout hodnoty následujícího mapování. TCP připojení se odehraje ve dvou krocích. V prvním kroku se peery připojí k třetí straně a získají informace o jejich mapování. Ve druhém kroku oba peery mohou uhodnout mapování portů NATu pro všechny následující připojení, což řeší problém s predikcí.
Tato metoda vyžaduje vykonání alespoň dvou po sobě jdoucích připojení pro každého z peerů a navíc je potřeba použít třetí stranu. Tato metoda nefunguje korektně v případě CGN (Carrier Grade NAT), který má více uživatelů za každou IP adresou, protože je dostupné omezené množství portů a alokování po sobě jdoucích portů pro stejného vnitřního hosta může být nepraktické nebo nemožné.
- NAT používá port „preservation allocation“ metodu, při které se mapuje zdrojový port lokálního peeru na stejný veřejný port.
V tomto případě je predikce portů triviální. Peerové si prostě musí předat port, ke kterému jsou vázány, pomocí jiného komunikačního kanálu (jako např. UDP nebo DHT) než vykonají odchozí spojení TCP simultaneous open. Tato metoda vyžaduje pouze jedno připojení pro každého z peerů a navíc není potřeba použití třetí strany pro vykonání predikce.
- NAT používá „endpoint independent mapping“: dva po sobě jdoucí úspěšná TCP spojení, pocházející ze stejného vnitřního koncového bodu jsou mapovány na stejný veřejný koncový bod. V tomto řešení se peerové nejdřív připojí k serveru třetí strany, který uloží jejich hodnotu pro mapování portů a předá dvojici peerů hodnotu toho druhého. Ve druhém kroku oba peerové použijí stejný místní koncový bod, aby navzájem vykonali TCP simultaneous open.
Tento postup bohužel vyžaduje použití SO_REUSEADDR na TCP socket, což narušuje TCP standard a může vést k poškození dat. Je doporučeno používat pouze tehdy, pokud je aplikace schopná se ochránit vůči poškození dat.
Podrobnosti o typických instancích TCP spojení s použitím TCP Hole Punching
Předpokládáme, že predikce portů již byla vykonána s pomocí jedne z výše uvedených metod a že každý z peerů zná vzdálený koncový bod. Oba peerové vykonají POSIXový příkaz connect na koncový bod toho druhého. TCP simultaneous open proběhne následujícím způsobem:
-
- Peer A pošle SYN Peeru B
- Peer B pošle SYN Peeru A
-
- Když NAT A obdrží odchozí SYN od Peeru A, vytvoří mapování v jeho stavovém automatu.
- Když NAT B obdrží odchozí SYN od Peeru B, vytvoří mapování v jeho stavovém automatu.
- Oba SYN se někde protnou podél síťové cesty, pak:
- SYN z Peer A dosahuje NATu B, SYN z Peer B dosáhne NATu A.
- V závislosti na načasování těchto událostí (kde se SYN v síti protnou),
- tak alespoň jeden z NATů umožní příchozímu SYN projít a namapuje ho do vnitřního cílového peeru.
- SYN z Peer A dosahuje NATu B, SYN z Peer B dosáhne NATu A.
- Po obdržení SYN peer pošle SYN+ACK zpět a je navázáno spojení.
Požadavky na NAT pro TCP Hole Punching
Další požadavky na NAT, aby byl v souladu s TCP simultaneous open
Aby TCP simultaneous open fungoval, tak by NAT měl:
- neposílat RST jako odpověď na příchozí SYN paket, který není částí žádného mapování
- přijmout příchozí SYN pro veřejný koncový bod, když NAT dříve viděl odchozí SYN pro stejný koncový bod
Toto je dostatečnou zárukou toho, že se NAT bude chovat správně v závislosti k TCP simultaneous open.
TCP Hole Punching a Carrier-grade NAT (CGN)
Technika popsaná výše funguje dobře s Carrier-grade NAT (CGN). CGN může taktéž využívat port overloading, což znamená, že odlišné vnitřní koncové body se stejnou hodnotou portů můžou být mapovány na stejný veřejný koncový bod. Tento postup nenarušuje sjednocenost následující pětice:
{protocol, public address, public port, remote address, remote port}
Tento výsledek je díky tomu přijatelný. TCP port preservation může vést k případům, kdy CGN porty jsou přetíženy, kdy tento stav neohrožuje spolehlivost protokolu. Port overloading pro TCP umožňuje CGN vtěsnat vnitřně více hostů a zároveň zachovávat záruku koncové TCP komunikace.
Odkazy
Související články
- Hole punching
- ICMP hole punching
- Port Control Protocol (PCP)
- UDP hole punching
Reference
V tomto článku byl použit překlad textu z článku TCP hole punching na anglické Wikipedii.