2024年3月29日发(作者:)
点对点UDP连接(UDP hole punching)
2006-08-04 09:02
以下文章为整理,感谢各位网络技术高人。
点对点UDP连接
UDP hole punching
当两个需要通讯的主机可能都在middlebox后面的时候,UDP hole punching依赖于cone NAT和
普通防火墙的一些特性,允许合适的P2P应用程序以"punch holes"方式通过middlebox并且建立
彼此之间直接的连接。这种技术在RFC 3027[NAT- PORT]的5.1节中简要的提及,并且在英特网
[KEGEL]非证实的提到,也在最近的一些协议[TEREDO, ICE]中用到。正如名字中的所提到的,这
种技术只能用于UDP连接。
我们将会考虑两个特别情况,并且考虑应用程序如何完善的处理两者之间的握手连接。第一种情
况下,也是较为普通的情况,两个在不通的NAT后面的客户端要求直接的进行P2P连接。第二种
情况,两台客户端位于同一个NAT后面,但不能肯定(两台客户端位于同一个NAT后面)。
1、位于不同NAT后面(Peers behind different NATs)
假设客户端A和B都有自己的私有IP地址,也都位于不同的NAT后面。P2P应用程序在A、B和服
务器S上运行,用的都是UDP端口1234。A和B各自和服务器S建立UDP通讯连接,使NAT A为A
的连接分配一个自己的公共端口62000,而NAT B为B的连接分配的是31000端口。
Server S
18.181.0.31:1234
|
|
+----------------------+----------------------+
| |
NAT A NAT B
155.99.25.11:62000 138.76.29.7:31000
| |
| |
Client A Client B
10.0.0.1:1234 10.1.1.3:1234
现在推想一下,客户端A想要直接和B建立一个UDP通讯会话。假设A简单的发一个UDP信息包
到B的公共地址138.76.29.7:31000,然而NAT B将会丢弃这些进入的数据信息(除非它是一个FULL
cone NAT),原因是NAT B和S已经建立的外部会话,而A发送的信息中的源地址和端口号是和S
不匹配的(可以参照一下上面的内容,匹配才能接受)。同样,假如B发送一个条UDP数据包给A
的公网地址,NAT A也会丢弃。
但是,假设A发出一个UDP数据信息给B的公网IP地址,同时也通过服务器S传递一个请求给B,
要求B也发一个UDP信息给A的公网IP地址。A直接向B的公共IP地址(138.76.29.7:31000)发
送的数据包会让NAT A在A的私有地址和B的公网地址之间建立了一个新的连接会话。同时,B到
A的公网地址(155.99.25.11:62000)的信息会导致NAT B在B的私有地址和A的公共地址之间建立
一个新的连接会话。一旦这种新的UDP连接在两者之间建立起来,客户端A和B就不需要服务器S
的"介绍"就能彼此直接通讯了。
UDP hole punching技术有几个很有用的特点。一旦在两个位于middlebox后面的客户端建立了一
个直接的P2P连接,在连接中的任何一方都可以扮演一个"介绍人"的角色,依次继续和另一个客
户端建立连接,减少了最初的服务器S的负担。如果说有[STUN]的话,假如两个中的任意一个或
两个都碰巧不在middlebox后面,上述应用程序将同样可以建立P2P通讯通道,应用程序不需要
尝试明确middlebox的类型。Hole punching技术甚至可以自动的运用在多级NAT下面,多重NAT
就是那些客户端需要经历多级地址转换才能进入公网。
2、位于同一NAT后(Peers behind the same NAT)
现在考虑两台客户端(但并不确定)都在同一个NAT后面的情况,因此会有私有IP地址空间。客户
端A与服务器S建立一个UDP会话,NAT会分配一个公共端口62000。客户端B与服务器S也建立
一个简单的连接,NAT为此分配一个公共端口62001。
Server S
18.181.0.31:1234
|
|
NAT
A-S 155.99.25.11:62000
B-S 155.99.25.11:62001
|
+----------------------+----------------------+
| |
Client A Client B
10.0.0.1:1234 10.1.1.3:1234
假想A和B使用UDP hole punching技术与服务器S的建立一个外部的通讯路线做为中间介绍。
然后A和B将可以通过服务器S得到各自公共IP地址和端口号,然后使用这些地址各自向对方发
送数据。两个客户能够以这种方式彼此通讯,只要NAT不仅仅允许外网上的主机可以和内网上的
主机进行UDP传输会话,也可以允许内网上的主机可以和其他内网的主机进行UDP会话。我们在
"loopback translation"中设计到这种情况,因为来自私有网络的数据包到达NAT后,会"looped
back"到私有网络上就象从公网来的一样。例如,当A向B的公共IP地址发送一个UDP包,这个
包的包头有一个源IP地址和端口,是10.0.0.1:1234,而目的地址是155.99.25.11.62001。NAT
接受到这个包,会把源地址转换(映射)为155.99.25.11:62000(就是A的公网地址),把目的地址
转换为10.1.1.3:1234,然后发给B。即使NAT支持回环映射,NAT的转换和发送步骤看上去是多
余的,在A和B通讯时似乎为NAT添加了潜在的负担。
这个问题的解决方法是直接的。当A和B一开始在服务器S上交换地址信息时,它们就可以包含
他们自己的IP地址和端口号,并且是可见的,对服务器S也是可见的。客户端根据它们得到的地
址同时开始向对方发数据包,并建立成功的通讯。假如这两个客户端都在同一NAT后面,数据包
象通讯一开始就能直接到达,而不需要通过NAT就能建立直接连接。假如这两个客户端位于不同
的NAT后,到达彼此私有地址的数据包会被丢弃,但是客户端可以通过各自的公共地址来建立连


发布评论