V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
ihciah
V2EX  ›  分享创造

用 Golang 糊了一个 TCP 双边加速器

  •  3
     
  •   ihciah ·
    ihciah · 2019-10-16 17:23:36 +08:00 · 10182 次点击
    这是一个创建于 1625 天前的主题,其中的信息可能已经有所发展或是发生改变。

    用 Golang 糊了一个支持任意 TCP 流量的双边加速器 Rabbit TCP

    https://github.com/ihciah/rabbit-tcp

    原理

    原理和我以前糊的某软件加速器差不多,通过建立多条 TCP 连接来承载上层用户连接,达到加速效果。

    这个过程会将上层连接的流数据拆成块,通过底层连接加密传输。底层连接持续存在,一定程度上还改变了流量的时序特征。

    大致示意图是这样(小学生画图水平 2333 ):

    示意图

    为什么不用 KCP

    我这边的 ISP 是上海联通,UDP 流量稍微多一点点就会直接掉到 1Mbps,UDP 流量是非常容易被 QoS 的。不巧我就是那个被 QoS 的。

    部署

    支持一键 docker-compose 部署。作为小白鼠用了一周了,稳定性没问题的。

    效果

    加速:

    带加速

    无加速:

    无加速

    End

    希望本项目能帮到更多的人,同时也希望你可以提出 issue 或者贡献代码,蟹蟹!

    43 条回复    2020-08-25 07:25:31 +08:00
    tulongtou
        1
    tulongtou  
       2019-10-16 17:33:05 +08:00 via iPhone
    支持一下 试试
    huyujievip
        2
    huyujievip  
       2019-10-16 17:36:03 +08:00 via Android
    试试,这个加速效果还是不错的呀
    justfly
        3
    justfly  
       2019-10-16 17:39:11 +08:00
    如果 client 和 server 之间的带宽是固定的,在这两者之间用单个 tcp 和多个 tcp 最终表现出速度差异的原理是什么呢,最终还是要传输相同的 IP 包。

    server 端搞个 bbr 也许会更好一些。
    est
        4
    est  
       2019-10-16 17:40:38 +08:00
    看上去像一个 demuxer ?如果支持多 ip 绑定就 6666 了。发送接受都多 ip。这样根本没法分析协议。
    ihciah
        5
    ihciah  
    OP
       2019-10-16 17:43:12 +08:00
    @justfly 和下载器的原理类似,多打连接就能尽量吃满带宽。
    和 BBR 不矛盾的,开了 BBR 会有一定提升。

    @est 多 ip 绑定具体是说?
    est
        6
    est  
       2019-10-16 17:48:39 +08:00   ❤️ 2
    @ihciah

    > 通过建立多条 TCP 连接来承载上层用户连接


    每一个 tcp 连接的五元组都不一样。

    因为服务器和客户端多网卡。每个网卡都可以绑多个 ip 的。但是 middle box 分析起来就费劲儿了。


    =========================


    另外

    > 当然坏处也是有的,因为负载的是任意 TCP 流量,并且需要隐藏 Block 数据包格式,所以这里需要在最外层做一次加密,对于 ShadowSocks 这种流量已加密的协议,相当于多做了一次加解密,会有一定的性能消耗。另一个坏处是可能需要做 QoS (目前没有实现),否则所有承载的流量权重相等,可能会有使用体验上的不适。

    我感觉可以完全新搞一个协议了。hhhh。

    如果自己重新设计一个协议,我的建议是允许 junk bytes。也就是未观察到符合目标字节之前允许插入任意乱码。这样为以后协议可混淆可扩展打下基础。
    justfly
        7
    justfly  
       2019-10-16 18:27:10 +08:00
    @ihciah 我理解和下载器的原理是不一样的。

    我们下载的文件在多个主机上,它通过和多个主机建立 tcp,分别下载不同的部分,因为每个主机到本机的带宽独立,所以加起来下载器会得到一个比较高的速度,跑满运营商分配给自己的带宽。

    对于一个 client 和 server 端的情况,带宽固定,能获得加速的原理是啥呢,我很好奇。
    wssy
        8
    wssy  
       2019-10-16 18:49:14 +08:00 via Android
    @justfly 可能是说单条 tcp 会被控制?
    Laynooor
        9
    Laynooor  
       2019-10-16 19:26:44 +08:00
    试了一下,Speedtest 单线程 70Mbps,加速后可以跑单线程 150Mbps,效果很不错。

    等会晚上 10 点 11 点的时候再试一下,那时候会被 Qos 到 3Mbps...
    ihciah
        10
    ihciah  
    OP
       2019-10-16 19:50:55 +08:00
    @est 感谢!这个项目初衷只是加速,混淆什么的可能要后续再加了。。多网卡那个,是不是 iptables 也可以搞定?我用 iptables 做过多端口的服务。

    @justfly TCP 有运营商的 QoS。因为不可能说你 1000M 宽带的下载国外的一个大文件就真的吃 1000M 的国际出口带宽,僧多粥少只能按人头分,多个连接就是多派几个人去分粥嘛。

    @Laynooor 联通网络贼差!到了晚上也是炸的不行。。
    wwqgtxx
        11
    wwqgtxx  
       2019-10-16 20:39:56 +08:00 via iPhone
    话说这种在多出口网络的情况下能正常使用么(比如多拨,或者有多条宽带出口 ip 不同,但是服务器 ip 唯一的情况下)
    ihciah
        12
    ihciah  
    OP
       2019-10-16 21:14:22 +08:00 via iPhone
    @wwqgtxx 应该不影响。但是因为数据块是随机选择连接发送,所以如果你的线路延迟差距较大,可能最终延迟会出现不稳定的情况。但是正常使用没问题的(应该)。。
    Jirajine
        13
    Jirajine  
       2019-10-16 21:16:55 +08:00 via Android
    @wwqgtxx 你是指单线程链路聚合吗?
    理论上你有 10 条 100m 宽带配合一个 G 口代理服务器应该可以。
    ericls
        14
    ericls  
       2019-10-16 21:20:59 +08:00 via iPhone
    HTTP 3 出来 会改变运营商对 UDP 的限制吗?
    Laynooor
        15
    Laynooor  
       2019-10-16 21:22:01 +08:00
    似乎有 BUG,会导致断流?必须重启 docker 才能恢复。
    情况 1:刚设置好 Rabbit,进行 Speedtest 测速,峰值带宽 150Mbps,下载测速完成之后断流,提示网络错误。重启客户端后恢复。

    情况 2:设置好后只是挂上某软件没有跑流量,过 1 个小时后再去用,发现网络错误。重启客户端后恢复。

    有日志可以查看吗?或许可以帮助解决这个问题
    fengtons
        16
    fengtons  
       2019-10-16 21:27:59 +08:00 via Android
    相当于以前的网络蚂蚁?
    est
        17
    est  
       2019-10-16 21:35:38 +08:00
    @ihciah iptables 是可以搞定。但是麻烦。。

    其实绑网卡就是 listen() 的时候传入一个 ip。。。
    ihciah
        18
    ihciah  
    OP
       2019-10-16 21:36:09 +08:00 via iPhone
    @Laynooor 我这边客户端跑在 NAS 上,日常全用这个还挺正常。(那个插件可能有点不稳定,原因未知)
    debug 的话可以改一下 verbose,然后 docker-compose logs 可以打 log。
    shansing
        19
    shansing  
       2019-10-16 21:44:41 +08:00
    不错诶。之前就经常有单线程速率不如多线程的情况,这下可以提速了。
    weyou
        20
    weyou  
       2019-10-16 22:04:49 +08:00 via Android
    其实类似于底层放了一个多线程下载器。将上层的所有的 tcp 连接都拆成多路并行传输。我猜这种方式对数据量较小的网页浏览,联机游戏应用的加速应该不明显,甚至会有劣化效果,而对于在线视频,大文件下载会有不错的效果。
    mywaiting
        21
    mywaiting  
       2019-10-16 22:17:28 +08:00
    希望楼主可以折腾一下,实现一套私有的多 IP 多链接下,类似于 Multipath TCP 的协议

    实现这样的一套协议,其数据天生就是乱序的,每个数据包的 payload 甚至只需基本的 rc4 加密即可,天然拥有出国的属性
    mywaiting
        22
    mywaiting  
       2019-10-16 22:26:36 +08:00
    附带很多年前看到的云风大牛的实现,一同分享 blog.codingnow.com/2015/07/mptun.html
    ihciah
        23
    ihciah  
    OP
       2019-10-16 22:53:23 +08:00
    @mywaiting 之前想过,做类似 Tinc 的 mesh vpn,但是流量会被分拆并多路传输的东西。权重怎么 update 感觉是个挺蛋疼的算法问题。
    mywaiting
        24
    mywaiting  
       2019-10-16 22:57:42 +08:00
    @ihciah 你可以看看我给的链接的,里面有个很简单的粗暴的权重计算方法,没有那么的蛋疼
    wwqgtxx
        25
    wwqgtxx  
       2019-10-16 23:52:51 +08:00 via iPhone
    @Jirajine 是这个意思,其实是解决一下垃圾校园网限速,我这边单账户限速 500k/s,用 20 个账户加 mwan3 均衡负载弄出来了一个 100mbps 的宽带,然后我有个百兆口的国内 vps,就看看能不能改善一下和这台 vps 的单线程通讯效率(用 frp 进行 rdp 转发)
    Jirajine
        26
    Jirajine  
       2019-10-17 00:10:28 +08:00 via Android
    @wwqgtxx 简单实现一个应该不难,但想要优雅一些,涉及到路由算法,传输控制,考虑到不同出口不同的时序造成的抖动,想要减少重传增加利用率降低时延并不容易。
    这真的是很小众的需求,楼上提到的在混淆流量对抗 GFW 方面的应用能有多少效果我表示怀疑,关键是需要有一个相对良好的实现,不能在小文件大并发方等面产生太大的副作用。
    还有,也许再过几年,TCP 都要淘汰了呢,自己实现传输控制协议灵活性更大一些。
    missdeer
        27
    missdeer  
       2019-10-17 08:31:26 +08:00
    摸摸头,上海电信 KCP 没被 QoS,速度比 TCP 直连快很多倍
    justfly
        28
    justfly  
       2019-10-17 09:57:25 +08:00
    @ihciah #10 多谢,了解了。
    zhaishunqi
        29
    zhaishunqi  
       2019-10-17 10:04:37 +08:00
    如果能突破贷款限制就牛皮了~
    zhaishunqi
        30
    zhaishunqi  
       2019-10-17 10:04:48 +08:00
    @zhaishunqi 带宽。。。
    azh7138m
        31
    azh7138m  
       2019-10-17 11:01:28 +08:00
    @wwqgtxx 可以做,Dialer 可以指定 LocalAddr
    然后就是某一路存在问题的时候,这部分流量要怎么处理
    等一个好心人来实现
    samwalt
        32
    samwalt  
       2019-10-17 15:46:44 +08:00
    学习一下
    lemonda
        33
    lemonda  
       2019-10-19 13:44:14 +08:00
    Win 下测试速度比较慢,下载速度时快时慢,进度条有时候卡住。
    有点奇怪做为插件时 serviceAddr 的写法,RabbitTCP Server<--> SSLibev,SS 的 IP:Port 不是应该写在服务器端么,怎么这个是写在本地端?会把 IP:Port 传输到服务器吗
    ihciah
        34
    ihciah  
    OP
       2019-10-19 22:34:19 +08:00 via iPhone   ❤️ 1
    @lemonda
    速度不稳定可能是正常的。因为数据到达不一定有序,会等待有序块到达后才从缓冲区返回给客户端。
    卡住不太清楚原因,有可能是速度太慢了?如果等待缺失块&&等待期间没有任何块(并不特指这个缺失块)到达,这个状态持续几秒钟(写死的常量)就会认为这个连接死掉了然后强制中断掉。(我觉得大概率是我写炸了…但是我这边还挺正常的…🤣)
    这个和 KCPTUN 的方式不同,目标地址是客户端传给服务端的。这样的好处就是加速多个服务可以共用同一个服务端。
    Allianzcortex
        35
    Allianzcortex  
       2019-10-27 22:57:14 +08:00
    唔 楼主的 CI 是怎么做的?没有用常见的 .travis / .circleci ?
    Allianzcortex
        36
    Allianzcortex  
       2019-10-27 23:01:30 +08:00
    原来是 github workflow.... 研究一下去(lll ¬ω¬)
    todragon
        37
    todragon  
       2019-11-26 10:14:12 +08:00 via iPhone
    楼主不更新了吗?
    ihciah
        38
    ihciah  
    OP
       2019-11-26 10:16:30 +08:00 via iPhone
    @todragon 最近比较忙…过了这阵
    todragon
        39
    todragon  
       2019-11-26 10:23:19 +08:00 via iPhone
    刚刚测试了一下,测速软件 speedtest 和 fast 都导致连接中断,重启客户端后恢复。
    ihciah
        40
    ihciah  
    OP
       2019-11-26 10:30:03 +08:00 via iPhone
    @todragon 是的,目前还有一些稳定性问题。忙完这阵修🤣
    todragon
        41
    todragon  
       2019-11-26 13:33:39 +08:00 via iPhone
    非常看好楼主这个项目,再报告一个问题吧,同样连了 aws 东京,浙江联通中转,speedtest 测试减速。
    zzutmebwd
        42
    zzutmebwd  
       2020-08-25 07:23:42 +08:00 via Android
    楼主赛高 我这边跨省跨网单线程限速 30mbps 准备挂了这个加速 先 mark
    zzutmebwd
        43
    zzutmebwd  
       2020-08-25 07:25:31 +08:00 via Android
    star 了先
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3433 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 84ms · UTC 11:13 · PVG 19:13 · LAX 04:13 · JFK 07:13
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.