V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
FinalTheory
V2EX  ›  程序员

来安利一下自己开发的 Mac OS 弱网络环境模拟与重现工具~

  •  3
     
  •   FinalTheory ·
    FinalTheory · 2016-03-26 16:33:09 +08:00 · 10662 次点击
    这是一个创建于 3147 天前的主题,其中的信息可能已经有所发展或是发生改变。

    先贴 github 地址骗几个 star😂

    https://finaltheory.github.io/wireless-network-reproduction/

    然后解释一下这个命名为 WNR 的工具解决了怎样的问题。

    事实上现在网络模拟工具已经有好多了,比如 Mac OS 上有 Apple 官方的 Network Link Conditioner , FaceBook 推出了基于 tc 的 ATC , Windows 上面有 Network Emulator for Windows Toolkit 以及非官方的 clumsy ,甚至 Chrome 都自带网络模拟功能……

    正常情况下如果只是为了检查自己开发的 App 能否在低速网络下工作,那么上述这些工具基本都能够满足需求。但是在我们的实际工作中发现,有时候需要对一些特定的弱网络环境进行重现,从而进行针对性的改进。这个时候,现有的各种软件就统统派不上用场了。因此, WNR 这个东西,说白了就是用来从网络层( IP 协议)干扰数据传输的通用工具,能够真实地模拟出一切可能出现的客户端弱网环境,从而能够用于移动端 App 的深度网络优化。

    WNR 模拟器主要提供以下这些弱网模拟功能:

    • 动态丢包
    • 动态延迟
    • 节流(一段短时间内的数据包被截获后,停留一段时间,再批量交付给应用程序)
    • 乱序(延迟的某种特殊形式,随机地将数据包打乱顺序交付给应用)
    • 篡改(模拟某些无良劫持行为)
    • 重发(可以看做是流量干扰,理论上应该不会影响 TCP 协议的正常工作)
    • TCP 重置(模拟某些运营商的特殊行为,随机地重置数据流量大的 TCP 连接)
    • 带宽限制(从 IP 数据包的层面卡住整个进程的数据传输速率)

    并且具有如下高级特性:

    • 上述效果相互之间可以任意叠加,即一系列数据包可能先被作用了延迟效果,再被作用节流效果,最后又被打乱顺序再交付给应用。从而能够尽可能灵活地模拟出真实的弱网场景。
    • 我们可以设置上述的这些策略的作用范围,即:作用于某个进程(如 Android 虚拟机或者 WiFi 热点)、作用于接收或者发出的包、作用于某些协议、作用于载荷长度在某个区间范围内的包(比如忽略掉不携带 payload 的 ACK 包)等等,非常灵活。
    • 同样支持设置所有这些效果随着时间的变化,如带宽随时间变化、丢包率可能随着时间变化,延迟时长随时间变化、某个包被乱序的概率随时间变化等等。
    • 可以导出整个交互过程中的所有数据包,并使用附带的数据分析工具进行可视化与分析。

    WNR 可以针对性地干扰特定进程的网络传输,并且不影响其他进程的正常网络 IO 。假如 Mac 上跑着一个 GenyMotion 虚拟机,你就可以针对虚拟机的进程来进行网络模拟,然后把整个网络交互过程导出为 pcap 文件,来进行进一步的分析。也就是说,你可以从网络流量中筛选出你所感兴趣的那个进程,来查看它所发出 /收到的数据包。

    下面举个简单的例子。百度地图在使用过程中,由于移动所造成的网络抖动,有时候会卡死在检索页上。由于网络抖动之类的特征是随着时间变化的,因此完全无法使用上述工具来模拟,但使用新开发的这套工具,则可以轻易复现这种环境。比如模拟一种带宽随着时间呈正弦波动的网络,那么实际的wget下载速度变化就会如下图所示:

    另一方面,如果你开发了一种针对弱网络环境的优化策略,想要说明收益的时候,按照正常流程,你需要把功能先小流量上线,收集反馈数据,根据数据反馈调整策略,从而完成一轮次的优化迭代,这个过程是非常耗时的,而且收益情况还不一定符合你的预期。但如果使用这种本地重现网络环境的方式,你可以直接先把自己的策略在一些具有代表性的弱网环境上跑出结果,这样直接就得到了初步的收益评估。

    说了这么多,接下来该简单说说这货怎么用了。其实非常简单:下载,解压,双击打开即可。配置文件的写法可以参考这里,就是简单的 json 文件,如果有人愿意试用的话,先看看示例配置即可上手,最近正在准备文档。

    最后补充一句, WNR 里面用到了一个内核扩展来查询数据包的所属进程,然而我并非 iOS 开发者,没有用于内核签名的账号,导致使用 WNR 的话需要手动停用 Mac OS 的内核扩展签名检查,这带来了一定的安全隐患。这部分代码非常少,仅有不到 1k 行,并且以后基本不会再变动,因此希望能有 V 友帮忙签名一下,感激不尽!

    26 条回复    2019-12-26 20:54:37 +08:00
    UnisandK
        1
    UnisandK  
       2016-03-26 16:55:01 +08:00
    卧槽正需要这个
    感谢楼主分享
    scys
        2
    scys  
       2016-03-26 17:07:24 +08:00
    好工具~已经 Star
    FinalTheory
        3
    FinalTheory  
    OP
       2016-03-26 17:13:58 +08:00
    @UnisandK @scys 谢谢支持~有问题欢迎来这里留言或者提 issue ,以便及时改进
    congeec
        4
    congeec  
       2016-03-26 17:37:14 +08:00
    比自带的 Network Link Conditioner 好多了
    owlsec
        5
    owlsec  
       2016-03-26 17:45:57 +08:00
    star 为敬
    xi_lin
        6
    xi_lin  
       2016-03-26 19:37:43 +08:00
    赞!功能很强啊
    everettjf
        7
    everettjf  
       2016-03-26 19:53:33 +08:00
    学习了。看起来高大上啊。明天给公司产品试用下。
    konakona
        8
    konakona  
       2016-03-26 23:12:16 +08:00
    3Q!已 STAR !
    其实想问下...如果要测 IOS APP 的话怎么使..
    FinalTheory
        9
    FinalTheory  
    OP
       2016-03-26 23:52:27 +08:00 via iPhone
    @everettjf 注意最后一句哈,使用时需要手动禁用内核扩展签名,不然无法工作的……毕竟不是 iOS 研发,开发者帐号略贵😂
    FinalTheory
        10
    FinalTheory  
    OP
       2016-03-26 23:54:13 +08:00 via iPhone
    @konakona 理论上只要知道 iOS 模拟器的进程名字就可以了,比如 VirtualBox 的进程名是 vboxheadless ,那么针对这个进程进行网络模拟即可。
    auser
        11
    auser  
       2016-03-27 08:26:56 +08:00 via iPhone
    看了下内核扩展的实现 拿进程信息的方式真够霸气
    作者对 darwin 源码掌握真好
    想知道作者的技术方向有哪些
    spance
        12
    spance  
       2016-03-27 09:04:18 +08:00
    好东西,正好可以用来考验下 suft.
    以前用 clumsy 时候,加个丢包乱序之后 io 效率火爆下降,不知道 wnr 会不会也是。
    FinalTheory
        13
    FinalTheory  
    OP
       2016-03-27 12:19:51 +08:00 via iPhone
    @auser 表示根本不是做 Mac OS 研发的,写这个都是硬着头皮参考各种资料外加自己 YY 出来的😂
    wzxjohn
        14
    wzxjohn  
       2016-03-27 18:13:26 +08:00
    @FinalTheory 找了半天没找到怎么载入的 Kernel Extension 。。。虽然自己签了一个但是不知大怎么用=。=
    konakona
        15
    konakona  
       2016-03-27 19:12:09 +08:00
    @FinalTheory 呃,并没有用到 OSX 。直接是在 IOS 上干!
    FinalTheory
        16
    FinalTheory  
    OP
       2016-03-27 19:17:31 +08:00 via iPhone
    @konakona 唔这样啊,那直接共享出 WiFi 就可以模拟啦
    FinalTheory
        17
    FinalTheory  
    OP
       2016-03-27 19:18:57 +08:00 via iPhone
    @wzxjohn 是启动模拟器的时候自动载入的,只是由于没有签名,会提示你载入失败,然后需要先禁用内核签名检查
    wzxjohn
        18
    wzxjohn  
       2016-03-27 21:54:02 +08:00 via iPhone
    @FinalTheory 我指的就是自动载入的部分。。。没找到具体载入的代码在哪ˊ_>ˋ
    FinalTheory
        19
    FinalTheory  
    OP
       2016-03-28 12:45:46 +08:00
    @wzxjohn 用来载入内核扩展的实际上是一个 C 函数,然后由 Python 调用。 Python 调用的入口在这里: https://github.com/FinalTheory/wireless-network-reproduction/blob/master/macdivert/macdivert.py#L139 然后调用的 C 函数在这里: https://github.com/FinalTheory/libdivert/blob/master/divert_kext.c
    wzxjohn
        20
    wzxjohn  
       2016-03-28 15:48:13 +08:00
    @FinalTheory 看到了。。。可是我在你打包的 dmg 里面完全没看到这个 PacketPID.kext 文件夹?
    FinalTheory
        21
    FinalTheory  
    OP
       2016-03-28 16:28:15 +08:00
    @wzxjohn 可能是藏得比较深😂 在 Contents/Resources/lib/python2.7/macdivert/PacketPID.kext 这个位置
    wzxjohn
        22
    wzxjohn  
       2016-03-28 17:05:56 +08:00
    @FinalTheory 我勒个去。。。我看到 lib 里面是 python2.7 都没进去看。。。看了一下普通的开发者是没法签的,要特别申请,填一堆东西的。。。
    FinalTheory
        23
    FinalTheory  
    OP
       2016-03-28 17:41:37 +08:00 via iPhone
    @wzxjohn 因为 py2app 的打包方式比较深,所以路径就比较奇葩……另外我也看到了,内核扩展确实不是随便签名的,而且我的代码实现里面调用了一些不允许使用的函数,所以签名看来是不用指望了😂
    l1993419419
        24
    l1993419419  
       2017-03-15 10:36:30 +08:00
    求兼容最新 macos
    bluewintergg
        25
    bluewintergg  
       2017-08-16 18:13:45 +08:00
    seria 跑起来好像没有效果?是不兼容了吗
    zzqims9527q
        26
    zzqims9527q  
       2019-12-26 20:54:37 +08:00
    @FinalTheory 大佬,能针对 ip 限速吗
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4518 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 05:35 · PVG 13:35 · LAX 21:35 · JFK 00:35
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.