使用STUN

时间:2015-08-11 17:24:25

标签: networking udp nat stun hole-punching

问题

我正在尝试开发一个通信系统:

A B 是NAT下的机器, A 是服务器 B 是客户端 S 是STUN服务器

S 正在Internet上可访问的计算机上运行

流程如下:

A hits S with an opcode saying he's the server
S registers A as server

B hits S with an opcode saying he's the client
S sends to A B's external infos (IP, PORT)
S sends to B A's external infos (IP, PORT)

A starts sending B an opcode saying he's the server every 500ms
and meanwhile listens for packets saying he's got a client

B starts sending A an opcode saying he's the client every 500ms
and meanwhile listen for packets saying he's got the server

<小时/>

故障

在麻烦开始的地方,STUN服务器完成其工作,因为两端都收到关于另一端的正确信息。

但是我从来没有收到过另一端的消息,所以两端都会继续听,而不会收到握手操作码或其他任何内容。

NAT的行为

我确实检查了这个NAT的行为,看起来确实像这样

A位于端口4444处的192.168.X.X处 连接到外面暴露N.N.N.N:4444 所以只要它是免费的,端口号就会被保留,如果没有,可以获得一个新的(随机?)端口号。

测试

我运行的测试看到两端(A,B)托管在同一台机器上,两者都绑定到机器的内部IP,试图绑定到127.0.0.1,0.0.0.0,没有任何改变。< / p>

如果他们正在听取握手我echo nclocalhost的某些内容,则会收到并显示(作为无法识别的消息)而没有任何问题。通过NAT路由的连接并不严格,每个数据包都被丢弃。

还尝试使用A托管在机器上,B在移动数据下的Android手机上,使用ad-hoc编写的简单应用程序。仍然锁定等待某些东西,比如nodejs测试。

更新 我尝试做的另一件事是用nc

打开一个洞

在同一个NAT下的两台不同的机器上运行:

echo "GREET UNKOWN PEER" | nc -u <NAT IP> 4567 -p 4568

echo "GREET UNKOWN PEER" | nc -u <NAT IP> 4568 -p 4567

每台机器的不同时间。根据我的理解,这应该在NAT中打一个洞,丢弃第一个数据包,然后转发。但没有任何事情发生,没有尽头得到消息。

我也尝试过:

来自本地机器 echo "GREET UNKOWN PEER" | nc -u <PUBLIC IP> 4567 -p 4568

来自公共机器 echo "GREET UNKOWN PEER" | nc -u <NAT IP> 4568 -p 4567

这个工作,NAT下的本地机器与公共机器联系,并且在第一个丢弃的数据包能够在指定的端口上接收和发送之后。我想知道为什么这不能在同一个NAT(???)

下的两台机器上工作

代码

我没有显示任何代码,因为我认为这有一些逻辑上的缺陷,不过这里有github项目。

index.js包含STUN服务器,tests文件夹包含测试用例:test.js启动stun服务器,PeerClientTest.jsPeerServerTest.js是客户端和服务器的模型。

运行node tests/test.js以在公共计算机上启动服务器(更改config.jstests/config.js中的IP)

然后node tests/PeerServerTest.js启动服务器(&#34; A&#34;)和node tests/PeerClientTest.js启动客户端(&#34; B&#34;)。两者都将通过STUN识别对方,然后在发送自己的握手操作码时监听另一端的握手操作码。这种情况从未发生过,所以他们只是永远地发送/收听。

节点不是必需的,所以如果有更好的解决方案在其他语言中告诉,将不胜感激。

1 个答案:

答案 0 :(得分:1)

B的NAT正在过滤A的数据包并且不允许它们通过。 NAT过滤发送给它的未知数据包。您的服务器A正在向客户端B发送数据包。但客户端B之前从未通过NAT向A发送数据包。因此,对于B的NAT A的数据包是未知的并被丢弃。

你需要在B的NAT中为NAT打一个洞以允许传入的数据包。从B发送数据包到NAT的IP:端口。在此之后,当您从A发送数据包到B时,B的NAT将不会丢弃A的数据包。

如果A和B的NAT具有Symmetric和Symmetric / PRC NAT之类的组合,则无效。在这种情况下,您将不得不使用TURN中继服务器。