【开源项目】LocalSend Switch —— 解决 LocalSend 在校园网无法跨子网发现设备的问题
为什么要做这个玩意儿
不知道大家有没有遇到过这种问题,用 LocalSend 时两台设备在现实中相距很近,也在同一个专用网络中,但因为接入的子网不同导致两台设备没法相互发现,不过可以手动添加 IP 来指定设备进行文件传输(比如咱实验室中的一台计算机连接的是有线网,但是我笔记本连接的是 WiFi,就没法互相发现,这台计算机和我的笔记本其实都在校园网中)。
- 但是这两种接入方式分配的都是动态 IP 来着,可能过一段时间就变了。
从 LocalSend 协议 可以看到在发现设备时用的是 UDP 组播,而其他 REST API 用的是单播的 HTTP (S)。咱自己搜索了一下发现,校园网涉及到了 VLAN 和子网划分,不同 VLAN 对应了不同子网,组播被隔离在各个子网中,而单播则有三层设备的规则来跨子网进行传输,于是就有了上述的这种情况(无法组播发现设备,但是可以通过指定 IP 进行单播)。
用 Wireshark 抓包也能看到,组播包中 TTL=1,是无法被转发的。
正好最近学了 Go,就想熟悉一下这个语言,简单写个交换桥梁来解决这个问题,于是 LocalSend Switch 这个小工具就诞生了~
解决思路其实很简单,在每台有 LocalSend 的客户端上都启动 LocalSend Switch,捕获其发出的 UDP 组播包,取出其中的客户端信息通过单播进行转发 (转发途径的 Switch 节点可以是内网或者外网中有静态 IP 的节点),客户端信息最终会转发到其他的终端 Switch 节点手里,这些 Switch 节点会请求客户端信息中的地址和端口,通过 REST API 来代替 LocalSend 进行响应和注册。
比如上面这个例子就是 A, B, C, D 为四台主机上的 Switch 节点。其中 A 和 D 在允许单播的大局域网中,它们所在的主机有 LocalSend 客户端在运行;B 和 C 节点则纯担当转发角色,它们最好有静态 IP。
A 捕获组播包后拆出其中的客户端信息进行转发,转发途径 B, C 节点最终到 D,D 于是向 LocalSend A 发出 LocalSend D 客户端的信息来进行注册。反之从 D 到 A 的过程也类似,是 A 向 LocalSend D 来发出注册请求,由此来实现互相发现。
简单来说 LocalSend Switch 充当的角色就有点类似于 BT 下载中的 Tracker 服务器了,但同时也会帮忙发送单播的注册请求,用于辅助 组播隔离、单播允许 的局域网子网之间的 LocalSend 客户端互相发现。
更多详细的实现和原理说明可以见 README: localsend-switch/README.zh_CN.md at main · SomeBottle/localsend-switch
项目地址
如果这个项目帮助到了大家,希望能给个 star ˋ(° ▽、°)
其他碎碎念
- 虽然传递的信息不算那么敏感,但每个 Switch 节点仍然支持配置一个对称加密密钥进行端侧 AES 加密,让传输的是密文。
- 为了尽量消除环路,每条客户端信息都带有 TTL 和唯一 ID。
- 支持开机启动,资源占用很低。
目前已经在咱实验室的计算机上实装了,现在传文件真的要轻松更多了 ╰( ̄ω ̄o)
