跳至内容

Junyi's Lab

P2P 技术

Table of Contents

本文主要记录自己学习的 P2P 技术

在这篇文章里,主要区分了各种 NAT 的类型,包括全锥形、地址限制锥形、端口限制锥形的内容和区别

# 网络地址转换 NAT (Network Address Translation)

## 基本网络地址转换 Basic NAT

简单来讲,就是直接把内部 IP 翻译成外部 IP,这种转换技术受限于对外地址的数量,是 IP 到 IP 的转换(端口不换)

需要了解的名词有:

  • SNAT:源地址转换
  • DNAT:目标地址转换

以只有一个对外地址举例,如果 ClientA 和 ClientB 同时访问同一个 Web Server,那么当 NAT Gatway 收到这个 Web Server 响应包的时候,就无法判断将数据包转发给哪台客户机。

于是就有了我们接下来要介绍的 NAPT 技术

## 网络地址端口转换 NAPT

先明确几个概念:

内网主机拥有的网络地址:(LocalIP:LocalPort)

经由 NAT 转换后的网络地址:(PublicIP:PublicPort)

外网主机拥有的网络地址:(RemoteIP:RemotePort)

源端口目标端口同时进行转换。这样就可以让一个公网IP满足多个后端主机同时访问外部网络。比如家庭宽带。

这项技术最为常见,它检测并修改出入数据包的IP 地址端口号,从而允许多个内网主机共享同一个公网 IP 地址

NAT 分为 锥形NAT对称型NAT

# 锥形 NAT

同一个内部主机的地址和端口,无论目的地址是否相同,NAT 都将它转换成同一个外部地址和端口。

192.168.1.2:8000 访问 Baidu.com:80 和 google.com:80 时,经由 NAT 转换,内部的 192.168.1.2:8000 都会被转化成 1.2.3.4:5000,baidu 看到的是 5000 端口,谷歌看到的也是

192.168.1.2:8001 访问 baidu.com:80 和 google.com:80 时,经由 NAT 转换,内部的 192.168.1.2:8001 都会变成 1.2.3.4:5001,baidu 看到的是 5001 端口,google 看到的也是。

懂了吗,这就是锥形的由来

# 全锥形 NAT (Full Cone NAT)

内向外:(特定本地IP:特定本地端口) –> (固定映射IP:固定映射端口) –> (特定远端IP:特定远端端口)

建立 Full Cone NAT 转换后

外向内:(特定本地IP:特定本地端口) <– (固定映射IP:固定映射端口) <– (任意远端IP:任意端口)

当内部主机向外发送请求时,NAT 网关会打开一个端口创建一个公网映射,形成一个 IP 端口元组,然后会将传入这个端口的数据全部转发给内部主机。一旦映射建立,那么任意一台主机,只要给映射出来的公网 IP 和端口发送数据,就可以直接到达后端服务

也就是,内部主机以相同的 (LocalIP:LocalPort) 对 2 个不同的 (RemoteIP:RemotePort) 发送 UDP 报文时,NAT 会为内部主机只分配一个 (PublicIP:PublicPort)任意一台主机都可以给 (PublicIP:PublicPort) 发送数据

# 地址限制锥形 NAT (Address Restricted Cone NAT)

远端 IP 地址受限,远端端口无所谓

内向外:(特定本地IP:特定本地端口) –> (固定映射IP:固定映射端口) –> (特定远端IP:特定远端端口)

建立 Address Restricted Cone NAT 转换后

外向内:(特定本地IP:特定本地端口) <– (固定映射IP:固定映射端口) <– (特定远端IP:任意端口)

(注意这里变成了 任意端口)

我更喜欢它的英文形式,中文翻译的很不恰当。英文叫地址受限的锥形 NAT。当内部主机向外发送请求时,NAT 网关会打开一个端口创建一个公网映射,同时记录外网的 IP 地址。一旦映射建立,只有被记录的 IP 地址给映射出来的公网 IP 和端口发送数据,才可以到达后端服务,其他 IP 地址发送给 NAT 网关的,将会被丢弃。

也就是,内部主机以相同的 (LocalIP:LocalPort) 对 2 个不同的 (RemoteIP:RemotePort) 发送 UDP 报文时,NAT 会为内部主机只分配一个 (PublicIP:PublicPort),同时,也只有这 2 个 RemoteIP 可以给 (PublicIP: PublicPort) 发送数据(因为先由内向外发过),这两个 RemoteIP 的 RemotePort 可以是任意的

# 端口限制锥形 NAT (Port Restricted Cone NAT)

远端 IP 地址和端口都受限,且只有内部主机向外发送过消息才可以建立。

一旦内部地址(iAddr:iPort)映射到外部地址(eAddr:ePort),所有发自 iAddr:iPort 的数据包都经由 eAddr:ePort 向外发送。

内向外:(特定本地 IP:特定本地端口) –>(固定映射 IP:固定映射端口) –> (特定远端 IP:特定远端端口)

建立 Port Restricted Cone NAT 转换后

外向内:(特定本地 IP:特定本地端口) <– (固定映射 IP:固定映射端口) <– (特定远端 IP:特定端口)

(注意这里变成了 特定端口)

这种模式同时记录内部主机的 IP 和端口外部主机的 IP 和端口,也就是形成了一种绑定关系。

与 Address Restricted Cone NAT 的区别是,Address Restricted Cone NAT 记录的只有外网主机的 IP,不记录端口,那个外网主机的随便一个端口给内网主机发送数据都可以。

Port Restricted Cone NAT 是记录外网主机的 IP 和端口,只有 (内网 IP, 内网端口) 和 (外网 IP, 外网端口) 这两个条件同时满足,数据才会转发给内网主机。而且以后给外部任何主机发送数据,都会用之前转换的 (PublicIP:PublicPort) 给外部主机发送数据。

也就是,内部主机以相同的 (LocalIP:LocalPort) 对 2 个不同的 (RemoteIP:RemotePort) 发送 UDP 报文时,NAT 会为内部主机只分配一个 (PublicIP:PublicPort),同时,也只有这 2 个 (RemoteIP:ReportPort) 可以给 (PublicIP: PublicPort) 发送数据(因为先由内向外发过)

# 对称形 NAT(Symmetric NAT)

连接不同的外部目标,NAT 打开的端口不同。是一种「一对一映射关系」。

换句话讲,不同的 (iAddr:port, eAddr:port) 组合,NAT 网关会产生不同的链路。

看起来也就是对称的了。(本地地址:端口,目标地址:端口)

比如 localA:8000 经过一台拥有 global 的一台对称 NAT 的 Gateway,访问 baidu:80 和 google:80,

baidu 看到的可能是来自 global:5003 的请求,google 看到的可能是来自 global:5010 的请求。

打个比方,当内部主机以相同的 (LocalIP:LocalPort) 对 2 个不同的 (RemoteIP:RemotePort) 发送 UDP 报文时,此时 NAT 将会为内部主机分配两个不同的 (PublicIP:PublicPort),并且建立起两个不同的内、外部 Tuple 转换关系

# Symmetric 和 Port Restricted 的区别

Port Restricted: drawing

  • 一旦内部地址(iAddr:iPort)映射到外部地址(eAddr:ePort),所有发自 iAddr:iPort 的数据包都经由 eAddr:ePort 向外发送。

Symmetric: drawing

  • 每一个来自相同内部 IP 与端口,到一个特定目的地 IP 和端口的请求,都映射到一个独特的外部 IP 和端口。

# References

[1] P2P 通信原理与实现

[2] 网络之 NAT 和 N2N VPN

[3] NAT 的四种类型及类型检测 2【很好】

[4] 网络地址转换 - Wikipedia