首页 文章

使用STUN在NAT下进行服务器/客户端通信的UDP打孔

提问于
浏览
3

问题

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

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位于192.168.X.X,端口4444连接到外部暴露N.N.N.N:4444所以端口号保持只要它是空闲的,如果不可用则获得一个新的(随机?) .

测试

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

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

还尝试了在机器上托管的A,在移动数据下的Android手机上的B,以及一个简单的app-hoc应用程序 . 仍然锁等待某事,比如nodejs测试 .


Update: 我试图做的另一件事是用 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下的两台机器(???)


代码

我没有't show any code because I think there is some kind logic flaw in this, however here'这是github项目 .

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

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

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

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

1 回答

  • 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中继服务器 .

相关问题