FunnyCat 最近的时间轴更新
FunnyCat

FunnyCat

V2EX 第 489034 号会员,加入于 2020-05-12 10:36:54 +08:00
FunnyCat 最近回复了
2020-06-29 19:44:51 +08:00
回复了 cs010 创建的主题 macOS macOS 如何让 socket 指定网卡发出数据(效果等同 Linux 的 SO_BINDTODEVICE)
@cs010
利用系统协议栈收的方法是这样的,默认全平台是由三层的 tun 设备来引流的情况下,tun 上的 ip 我们可以利用。在 tun 上这个 ip 起 tcp 和 udp 的 server,外部命中 tun 路由的流量首先会被你从 tun 上 read 到,通过读到的 ip 报文修改目的 ip 和目的端口号(当然,包括首部检验和),将其修改为你 tun 上的端口和地址再写回 tun 。然后系统自然就会帮你组包,你就可拿到原始数据,再通过对应的 tcp 或 udp socket 绑定接口往外发(当然,你还得记录这些数据是送往哪个地址哪个端口的)。

当然,这种能力还是需要绑定接口不命中默认路由的。这是两个问题,一个是 tcp 和 udp 数据处理重组的问题,因为你在移动端发出去一定会带额外的头部。 另一个是不命中路由的这个问题, 这个 socket.SO_BINDTODEVICE 是可行的,你可以再试试。
2020-05-21 15:28:24 +08:00
回复了 cs010 创建的主题 macOS macOS 如何让 socket 指定网卡发出数据(效果等同 Linux 的 SO_BINDTODEVICE)
@cs010 不知道楼主现在问题解决了没有,有机会的话可以沟通交流一下。我做了一个跨平台的 VPN 软件,其中很多遇到的坑应该都和你一样踩过。看了很多回复,很多人真的太过于想当然了。从路由层面上来说,修改路由表是跨平台方案绝对不可行的一条路,在 ios/android 平台基本上属于死路。首先 VPN 的话,如果想做到尽可能多的事情,Android 的 VPNService,macos/ios 的 Network Extension 或 Network system Extension(PacketTunnelProvider ),windows 的 Wintun 都是不错的选择。至于在 default route 走 tun 情况下,其他流量怎么出去;首先系统为了防止到 VPN server 不再命中 default ,都提供了一种添加明细的方式(当然,大部分都是开启时指定,不能动态修改),如 Android 里 VPNService 的 protect, macos/ios 里 NE 的 SeverIP/Exculde routes 等可以帮助你做到这点。如果不满足的话,就像你说的必须经过协议栈(lwip,实际上有一种巧妙的方法可以让系统协议栈帮我们做这件事而不用嵌入用户态协议栈)拿到报文,你自己作为一个 TCP/UDP 代理再绑定接口把包发出去。socket.SO_BINDTODEVICE 这个选项如果不行,你可以直接绑定接口的 src ip 尝试一下,我实测两种方式都是 work 的,后者怀疑是 macos 有相关的策略路由 :)
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2366 人在线   最高记录 6543   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 11ms · UTC 07:02 · PVG 15:02 · LAX 00:02 · JFK 03:02
Developed with CodeLauncher
♥ Do have faith in what you're doing.