参考文档:
https://www.jianshu.com/p/4a15556c6318
https://www.cnblogs.com/pannengzhi/p/5048965.html
我们在STUN工作过程介绍的文章中提到过,STUN能够处理Cone NAT,但是没有处理对称NAT的能力,也就是说位于对称NAT后面的2台内网机器是无法进行p2p连接的。
TURN协议就是为了解决对称NAT的问题,它扩展了STUN(所以说TURN服务也会提供STUN的功能), 添加了一个中继(Relaying)的功能,使得位于对称NAT后面的2台内网机器能够进行通信。
需要注意的是,使用TURN进行的通信,本质上讲它不是p2p,同时由于需要中继数据,从而增加了TURN服务器的负担。
下面将从数据的传输过程来了解TURN是如何让对称NAT后面的内网机器间进行通信的。
先解释一个名词,这样有利于后面的描述:
反射地址(Reflexive Transport Address): 它是NAT分配给内网机器与外网进行通信的公网IP和端口
环境:
client A: 位于对称NAT后的内网机器, 192.168.10.2:1234
NAT A: client A 到达公网时的最后一个NAT,反射地址为 112.11.11.11:4000
TURN Server: TURN服务器,位于公网, 112.11.11.11:3478
NAT B: client B 到达公网时的最后一个NAT,反射地址为 112.11.11.11:6000
client B: 位于对称NAT后的内网机器, 192.168.10.2:4321
1. 准备中继地址
要使得2个client能够通信,我们需要TURN为我们准备一个位于公网的中继地址
1)client A 向TURN服务器发送了Allocate请求
2)服务器根据请求为A分配了一个位于公网的中继地址
3)服务器向A发送响应,响应中包括中继地址信息
2. 信息传递过程
上一步中Client A已经拿到了TURN为其分配的中继地址,需要通过其他方式将这个中继地址告诉其他想和A通信的对象,例如Client B。 当ClientB拿到这个中继地址后,就可以和A进行通信了,过程如下:
上图中所示,整个过程是B给A发了个Hello消息,然后A给B回了个Hi,下面详细分析下这个过程:
1. 蓝色箭头代表的是B的发送信息的过程, 绿色箭头代表A回应B的信息的过程。
2. 在编号为 1,2的两个阶段,发送的是单纯的UDP数据, 而4,5两个阶段发送是使用STUN协议封装过的“Hello”,它被称为Data Indication。
3. 同样的, 在6,7阶段被发送的是被STUN协议封装过的“Hi”,被称为 Send Indication。 而9,10阶段发送的单纯的包含Hi的udp包。
4. 在4,5阶段中,数据是从STUN port转发过来的,进行了STUN封装,目的是告诉A这些数据是谁发过来的,也就是包含了B的反射地址信息
5. 在6,7阶段中,对Hi进行了封装,也就是添加了目的地信息(就是B的反射地址信息),这样TURN才能知道把这个数据通过中继地址发给谁。
6. 在阶段3中,为数据“hello”进行TURN封装(主要是加入了B的反射地址)
7. 在阶段8中,对被TURN封装的“HI”解封装,获取数据“Hi”和目的地址,经由中继端口发出
在上面的例子中,我们看到是B先发起的请求,那A怎么先发起请求呢??
主动发起方必须获取对方的中继信息后才能发起请求,也就意味着,如果A想主动发起,那边B必须首先建立自己的中继通道,然后通知A。