p2p点对点通信

0-前言

学习的文章:

P2P中的NAT穿越(打洞)方案详解 - 休耕 - 博客园

通信能否建立成功取决于当前的NAT设备是否支持不同端口之间的UDP数据包能否到达(即Hairpin转换特性)

1-UDP打洞情景

1>两个客户端位于同一个NAT设备后

​ 当A向集中服务器发出消息请求与B连接,集中服务器将B的外网地址二元组以及内网地址二元组发给A,同时把A的外网以及内网的地址二元组信息发给B。

2>两个客户端位于不同NAT设备后

​ 在A向服务器发送的登陆消息中,包含有A的内网地址二元组信息,即10.0.0.1:4321;服务器会记录下A的内网地址二元组信息,同时会把自己观察到的A的外网地址二元组信息记录下来。同理,服务器也会记录下B的内网地址二元组信息和由服务器观察到的客户端B的外网地址二元组信息。无论A与B二者中的任何一方向服务器发送P2P连接请求,服务器都会将其记录下来的上述的外网和内网地址二元组发送给A或B。

一旦A与B都向对方的NAT设备在外网上的地址二元组发送了数据包,就打开了A与B之间的“洞”

3>两个客户端位于两层(多层)NAT设备后

经典示例是家庭路由器:

​ 现在的家用网,即便是路由器映射端口过了一层但上面还有一层运营商提供的nat

存在内网地址重复的可能性

​ 因此客户端别无选择,只能使用由公网服务器观察到的A,B的公网地址二元组进行“打洞”操作,用于“打洞”的数据包将由NAT C进行转发。

2-P2P的TCP流

从协议层来看,TCP“打洞”与UDP“打洞”是几乎完全相同的过程

流程

  • 客户端A使用其与服务器的连接向服务器发送请求,要求服务器协助其连接客户端B;
  • 服务器将B的公网和内网的TCP地址的二元组信息返回给A,同时服务器将A的公网和内网的地址二元组也发送给B;
  • 客户端A和B使用连接服务器的端口异步地发起向对方的公网、内网地址二元组的TCP连接,同时监听各自的本地TCP端口是否有外部的连接联入;
  • A和B开始等待向外的连接是否成功,检查是否有新连接联入。如果向外的连接由于某种网络错误而失败,如:“连接被重置”或者“节点无法访问”,客户端只需要延迟一小段时间(例如延迟一秒钟),然后重新发起连接即可,延迟的时间和重复连接的次数可以由应用程序编写者来确定;
  • TCP连接建立起来以后,客户端之间应该开始鉴权操作,确保目前联入的连接就是所希望的连接。如果鉴权失败,客户端将关闭连接,并且继续等待新的连接联入。客户端通常采用“先入为主”的策略,只接受第一个通过鉴权操作的客户端,然后将进入P2P通信过程不再继续等待是否有新的连接联入。

3-应用

n2nc:Nat 2 Nat 连接器项目

n2n 是一个开放源代码的2层跨越3层的VPN程序

n2nc的应用介绍:n2n动态路由异地组网方案

pwnat


VPN介绍:

openVPN

Tailscale

ZeroTier