一、 P2P(peer to peer)

P2P 是一个“点对点传输技术”,也就是 2 台计算机之间不需要第三台机器作为服务端就能实现数据的传输。每台计算机即是客户端又是服务端。如果每台计算机都有自己的独立的公网 IP,那么 P2P 技术就比较好实现了,但是现实中由于 NAT 的存在,使得 P2P 技术最大的难点就在于穿越 NAT 的限制,俗称“打洞”。

二、 NAT(Network Address Translation)

2.1 NAT 的产生背景

IPv4 即网际网协议第 4 版——Internet Protocol Version 4 的缩写。
如果我们把 Internet 比作一个邮政系统,那么 IP 地址的作用就等同于包含城市、街区、门牌编号在内的完整地址,可以准确的定位到某一台计算机。IPv4 使用 32bits 整数表达一个地址,地址最大范围就是 232 约为 43 亿。以 IP 创始时期可被联网的设备来看,这样的一个空间已经很大,很难被短时间用完。然而,事实远远超出人们的设想,计算机网络在此后的几十年里迅速壮大,网络终端数量也呈爆炸性增长。

更为糟糕的是,为了路由和管理方便,43 亿的地址空间被按照不同前缀长度划分为 A,B,C,D 类地址网络和保留地址。IANA 向超大型企业/组织分配 A 类网络地址,一次一段。向中型企业或教育机构分配 B 类网络地址,一次一段。这样一种分配策略使得 IP 地址浪费很严重,很多被分配出去的地址没有真实被利用,地址消耗很快。以至于二十世纪 90 年代初,网络专家们意识到,这样大手大脚下去,IPv4 地址很快就要耗光了。于是,人们开始考虑 IPv4 的替代方案,同时采取一系列的措施来减缓 IPv4 地址的消耗。正是在这样一个背景之下,NAT 应运而生。

2.2 NAT

NAT(Network Address Translation)网络地址转换,就是在内网 IP 和公网 IP 之前相互转换。NAT 通常部署在一个组织的网络出口位置。

2.2.1 什么是内部网络地址(内网 IP)?

RFC1918 规定了三个保留地址段落,这三个范围分别处于 A,B,C 类的地址段,不向特定的用户分配,被 IANA 作为私有地址保留。这些地址可以在任何组织或企业内部使用。和其他 IPv4 地址的区别就是,仅能在内部使用,不能作为全球路由地址。这就是说,出了组织的管理范围这些地址就不再有意义,无论是作为源地址,还是目的地址。对于一个封闭的组织,如果其网络不连接到外部 Internet,就可以使用这些地址而不用向 IANA 提出申请,而在内部的路由管理和报文传递方式与其他网络没有差异。

1
2
3
10.0.0.0-10.255.255.255
172.16.0.0-172.31.255.255
192.168.0.0-192.168.255.255

对于有 Internet 访问需求而内部又使用私有地址的网络,就要在组织的出口位置部署 NAT 网关,在报文离开私网进入 Internet 时,将源 IP 替换为公网地址,通常是出口设备的接口地址。一个对外的访问请求在到达目标以后,表现为由本组织出口设备发起,因此被请求的服务端可将响应内容由 Internet 发回到出口网关。出口网关再将目的地址替换为私网的源主机地址,发回内部。这样一次由私网主机向公网服务端的请求和响应就在通信两端均无感知的情况下完成了。依据这种模型,数量庞大的内网主机就不再需要公有 IP 地址了。

2.2.2 NAT 分类

  • 全锥形 NAT(Full Cone NAT)
    一旦内部主机端口对(iAddr:iPort)被 NAT 网关映射到(eAddr:ePort),所有后续的(iAddr:iPort)报文都会被转换为(eAddr:ePort);任何一个外部主机发送到(eAddr:ePort)的报文将会被转换后发到(iAddr:iPort)。

  • 限制锥形 NAT(Restricted Cone NAT)
    一旦内部主机端口对(iAddr:iPort)被映射到(eAddr:ePort),所有后续的(iAddr:iPort)报文都会被转换为(eAddr:ePort);只有 (iAddr:iPort)向特定的外部主机 hAddr 发送过数据,主机 hAddr 从任意端口发送到(eAddr:ePort)的报文将会被转发到(iAddr:iPort)。

  • 端口限制锥形 NAT(Port Restricted Cone NAT)
    一旦内部主机端口对(iAddr:iPort)被映射到(eAddr:ePort),所有后续的(iAddr:iPort)报文都会被转换为(eAddr:ePort);只有(iAddr:iPort)向特定的外部主机端口对(hAddr:hPort)发送过数据,由 (hAddr:hPort)发送到(eAddr:ePort)的报文将会被转发到(iAddr:iPort)。

  • 对称型 NAT(Symmetric NAT)
    NAT 网关会把内部主机“地址端口对”和外部主机“地址端口对”完全相同的报文看作一个连接,在 NAT 网关上创建一个公网“地址端口对”映射进行转换,只有收到报文的外部主机从对应的端口对发送回应的报文,才能被转换。即使内部主机使用之前用过的地址端口对去连接不同外部主机(或端口)时,NAT 网关也会建立新的映射关系。

三、 NAT 穿越技术

常见的 NAT 穿越技术有:STUN、TURN、ICE。

3.1 STUN(Session Traversal Utileties for NAT)

RFC3489RFC5389中的名称都是 STUN,但其全称是不同的。在 RFC3489 里,STUN 的全称是 Simple Traversal of User Datagram Protocol (UDP) Through Network Address Translators (NATs), 即穿越 NAT 的简单 UDP 传输,是一个轻量级的协议,允许应用程序发现自己和公网之间的中间件类型,同时也能允许应用程序发现自己被 NAT 分配的公网 IP。这个协议在 2003 年 3 月被提出,目前已经被 STUN/RFC5389 所替代。

但在 RFC5389 中,STUN 的全称变为 Session Traversal Utilities for NAT,即 NAT 环境下的会话传输工具,是一种处理 NAT 传输的协议,但主要作为一个工具来服务于其他协议。和 STUN/RFC3489 类似,可以被终端用来发现其公网 IP 和端口,同时可以检测端点间的连接性,也可以作为一种保活(keep-alive)协议来维持 NAT 的绑定。和 RFC3489 最大的不同点在于,STUN 本身不再是一个 完整的 NAT 传输解决方案,而是在 NAT 传输环境中作为一个辅助的解决方法,同时也增加了 TCP 的支持。RFC5389 废弃了 RFC3489,因此后者通常称为 classic STUN,但依旧是后向兼容的。STUN 是一种 Client/Server 的协议,也是一种 Request/Response 的协议,默认端口号是 3478。

STUN 完整的定义参考:RFC5398

3.2 TURN(Traversal Using Relay NAT)

Traversal Using Relay NAT 即使用中继穿透 NAT,STUN 的中继扩展。简单的说,TURN 与 STUN 的共同点都是通过修改应用层中的私网地址达到 NAT 穿透的效果,异同点是 TURN 是通过两方通讯的“中间人”方式实现穿透。

TURN 完整的定义参考:RFC5766

3.3 ICE(Interactive Connectivity Establishment)

Interactive Connectivity Establishment 即互动式连接建立,由 IETF 的 MMUSIC 工作组开发出来的,它所提供的是一种框架,使各种 NAT 穿透技术可以实现统一。ICE 跟 STUN 和 TURN 不一样,ICE 不是一种协议,而是一个框架(Framework),它整合了 STUN 和 TURN。

ICE 完整的定义参考:RFC5245

参考:
P2P 技术详解(一):NAT 详解——详细原理、P2P 简介 > P2P 技术详解(二):P2P 中的 NAT 穿越(打洞)方案详解 > P2P 技术详解(三):P2P 技术之 STUN、TURN、ICE 详解