Peer-to-Peer (P2P) communication across middleboxes(翻译5)

原文版权 : Copyright (C) The Internet Society (2003).All Rights Reserved.

原文地址: http://midcom-p2p.sourceforge.net/draft-ford-midcom-p2p-01.txt

译文版权申明:请引用此文的作者或网站注明出处: http://blog.csdn.net/hxhbluestar **,以尊重译者的劳动成果!
**

** 注: 在看这篇文章之前,读者需要了解 TCP 的基础知识,了解 TCP 建立连接的基本步骤
**

3.5. Simultaneous TCP open ** 同时开放 ** ** TCP ** ** 连接 **

There is a method that can be used in some cases to establish direct peer-to-peer TCP connections between a pair of nodes that are both behind existing middleboxes. Most TCP sessions start with one endpoint sending a SYN packet, to which the other party responds with a SYN-ACK packet. It is possible and legal, however, for two endpoints to start a TCP session by simultaneously sending each other SYN packets, to which each party subsequently responds with a separate ACK. This procedure is known as a "simultaneous open."

这里有一种方法能够在某种情况下建立一个穿透 NAT 的端对端 TCP 直连。我们知道,绝大多数的 TCP 会话的建立,都是通过一端先发送一个 SYN 包开始,另一方则回发一个 SYN-ACK 包的过程。然而,这里确实存在另外一种情况,就是 P2P 的双方各自同时地发出一个 SYN 包到对方的公网地址上,然后各自都单独地返回一个 ACK 响应来建立一个 TCP 会话,这个过程被称之为: “Simultaneous open” ( “ 同时开放连接 ” )。

If a middlebox receives a TCP SYN packet from outside the private network attempting to initiate an incoming TCP connection, the middlebox will normally reject the connection attempt by either dropping the SYN packet or sending back a TCP RST (connection reset) packet. If, however, the SYN packet arrives with source and destination addresses and port numbers that correspond to a TCP session that the middlebox believes is already active, then the middlebox will allow the packet to pass through. In particular, if the middlebox has just recently seen and transmitted an outgoing SYN packet with the same addresses and port numbers, then it will consider the session active and allow the incoming SYN through.
If clients A and B can each correctly predict the public port number that its respective middlebox will assign the next outgoing TCP connection, and if each client initiates an outgoing TCP connection with the other client timed so that each client's outgoing SYN passes through its local middlebox before either SYN reaches the opposite middlebox, then a working peer-to-peer TCP connection will result.

如果一个 NAT 接收到一个来自私有网络外面的 TCP SYN 包,这个包想发起一个 “ 引入 ” 的 TCP 连接,一般来说, NAT 会拒绝这个连接请求并扔掉这个 SYN 包,或者回送一个 TCP RST ( connection reset ,重建连接)包给请求方。但是,有一种情况,当这个接收到的 SYN 包 中的源 IP 地址和端口、目标 IP 地址和端口都与 NAT 登记的一个已经激活的 TCP 会话中的地址信息相符时, NAT 将会放行这个 SYN 包,让它进入 NAT 内部。特别要指出,如果 NAT 恰好看到一个刚刚发送出去的一个 SYN 包也和上面接收到的 SYN 包中的地址信息相符合的话,那么 NAT 将会认为这个 TCP 连接已经被激活,并将允许这个方向的 SYN 包进入 NAT 内部。

如果 Client A 和 Client B 能够彼此正确的预知对方的 NAT 将会给下一个 TCP 连接分配的公网 TCP 端口,并且两个客户端能够同时地发起一个 “ 外出 ” 的 TCP 连接,并在对方的 SYN 包到达之前,自己刚发送出去的 SYN 包都能顺利的穿过自己的 NAT 的话,一条端对端的 TCP 连接就成功地建立了。

(好似一个间谍活动

Unfortunately, this trick may be even more fragile and timing-sensitive than the UDP port number prediction trick described above. First, unless both middleboxes are simple firewalls or implement cone NAT behavior on their TCP traffic, all the same things can go wrong with each side's attempt to predict the public port numbers that the respective NATs will assign to the new sessions. In addition, if either client's SYN arrives at the opposite middlebox too quickly, then the remote middlebox may reject the SYN with a RST packet, causing the local middlebox in turn to close the new session and make future SYN retransmission attempts using the same port numbers futile. Finally, even though support for simultaneous open is technically a mandatory part of the TCP specification [TCP], it is not implemented correctly in some common operating systems. For this reason, this trick is likewise mentioned here only for historical reasons; it is NOT recommended for use by applications. Applications that require efficient, direct peer-to-peer communication over existing NATs should use UDP.

不幸的是,这个诡计比 3.4 节所讲的 UDP 端口预言更容易被粉碎,并且对时间的敏感性的依赖更多!即使双方的 NAT 都是 Simple firewall (名词解释会统一给出) 或者都像 cone NAT 那样处理 TCP 的通信,仍然会出现连接失败,因为它同时还依赖于 “ 端口预言 ” ,这个技术的脆弱性在 3.4 节已经讲过了。

另外,如果双方的 SYN 到达对方的 NAT 速度太快(举例来说,就是 SYN A 的还未穿过 NAT A 时, SYN B 已经提早到达了 NAT A ),对方的 NAT 会将这个 SYN 扔掉,并返回一个 RST 包,这样就使得这个发快了的一方 NAT 关闭原来的会话,又重新建立一个新的会话,再利用这个新的会话重发一个 SYN ,这时端口预言就失效了,因为再次分配到相同的端口地址的几率太小了。

最后,尽管在 “TCP 规范 ” 中说明了 “Simultaneous open” 是一种支持的标准技术,但是在一些公共操作系统中,对这种技术的支持并不好。基于这个原因,我们也在这里郑重申明,并不推荐使用这个技术。如果您的应用程序想要穿透 NAT 并进行高效率高性能的 P2P 的通信,应该使用 UDP 技术!

这里我将这个技术的详细过程描述如下,欢迎大家指正:

**

过程详细描述: **

Client A 发送一个 TCP SYN 包给 Client B , 我们把这个 SYN 包叫做 ** SYN A, ** 包含的信息如下 :

SrcAddress : 10.0.0.1 Tcp port : 1234

DestAddress : 138.76.29.7 Tcp port : 310000

同时 , Client B 发送一个 TCP SYN 包给 Client A , 我们把这个包叫做 ** SYN B, ** 包含的信息如下 :

SrcAddress : 10.1.1.3 Tcp port : 1234

DestAddress : 155.99.25.11 Tcp port : 620000

** SYN A ** 首先通过 NAT A (必须在 SYN B 到达 NAT A 之前), NAT A 看到这个包并将其地址信息进行转换为:

SrcAddress : 155.99.25.11 Tcp port : 620000

DestAddress : 138.76.29.7 Tcp port : 310000

我们把这个经过 NAT A 转换的包叫做 ** SYN A’ **

同样, ** SYN B ** 首先通过 NAT B (也必须在 SYN A 到达 NAT B 之前), NAT B 看到这个包并进行地址转换为:

SrcAddress : 138.76.29.7 Tcp port : 310000

DestAddress : 155.99.25.11 Tcp port : 620000

我们把这个经过 NAT B 转换的包叫做 ** SYN B’ **

这时, NAT A 和 NAT B 都在自己的 TCP 连接表中存储了含有上面两个公网 IP 地址和端口信息,因此,只要看到包含这两个信息的 SYN 包,都会让其通过。

就在这个瞬间, ** SYN A’ ** 到达了 NAT B , NAT B 检查了一下 ** SYN A’ ** ,发现它的地址信息和自己 TCP 连接表中的信息相符,便让 ** SYN A’ ** 通过了,并将 ** SYN A’ ** 的地址信息转换为:我们称这个包为 ** SYN A’’ **

SrcAddress : 155.99.25.11 Tcp port : 620000

DestAddress : 10.1.1.3 Tcp port : 1234

以使这个包能够到达内部网中 Client B <SPAN style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋

Published At
Categories with Web编程
Tagged with
comments powered by Disqus