Go打孔库rndz-go
2 min read

Go打孔库rndz-go

之前写的rust打孔库rndz现在有了go版本rndz-go,两者协议相同,可以互通。

与rust打孔完毕返回原生socket一样,go版本也是返回原生的net.Conn和net.Listener。

import "github.com/optman/rndz-go/client/tcp"

c := tcp.New(rndzServer, "c1", netip.AddrPort{})
defer c.Close()
l, _ := c.Listen(context.Background())
defer l.Close()
for {
	conn, _ := l.Accept()
    defer conn.Close()
    ...
}
import "github.com/optman/rndz-go/client/tcp"

c := tcp.New(rndzServer, "c2", netip.AddrPort{})
defer c.Close()
conn, _ := c.Connect(context.Background(), "c1")
defer conn.Close()

作为第一个测试应用,我对p2p-tun进行了修改。不再依赖中转节点实现所谓分布式打孔,而是直接依赖特定的rndz服务器完成打孔,连接建立速度要快很多。

p2p-tun原本是基于libp2p实现的,利用libp2p实现了连接复用,数据加密和身份认证等功能。因此,rndz的加入,还将基于libp2p的框架。为此,需要对原来的tcp-transport和quic-transport模块进行改造,得到rndz-tcp-transportrndz-quic-transport。还增加了rndz-multiaddr模块,用于封装rndz服务器地址和peerid,可以通过listen addresss指定rndz服务器,比如/ip4/0.0.0.0/udp/0/rndz/dns/rndz.optman.net/udp/8888。连接发起方则使用/dns/rndz.optman.net/tcp/8888/p2p/16Uiu2HAm19Fic7qSLVVmFVe5RDzrdKrii7fcVUU7wYHXEtRTjXrw地址进行连接,这样就可以灵活指定rndz服务器地址了。还有,直接使用peerid作为rndz里的id,方便且统一。

针对libp2p不能对relay进行自动重连的bug,我在rndz-go的listen方法内部增加了自动重连rndz服务器的机制,以适应长时间运行。