欢迎来到好人卡资源网,专注网络技术资源收集,我们不仅是网络资源的搬运工,也生产原创资源。寻找资源请留言或关注公众号:烈日下的男人

改了一点realm, 顺便说说目前常见的转发工具

网站源码 sky995 来源:loc 3年前 (2021-05-04) 795次浏览 0个评论

本文及资源最后更新时间 2021-05-04 by sky995

最近抽空学了一点rust(刚看完the book & async programming),  顺便研究了一下realm
作者 @zhboner 平时似乎不怎么上线(两周前合并了一个PR(关于TCP连接关闭的),这之前很长一段时间没有活动)
目前Issue区还有几个问题没解决,我就自己动手改了一下代码,希望可以帮到有需要的人(不知道还有人用没)

先说第一个问题(个人认为比较重要):https://github.com/zhboner/realm/issues/25

这个程序支持批量监听端口。程序启动以后会先单独启动一个线程用于解析域名,随后为每个端口分配一个异步任务,
在每个异步任务中又会开启两个线程用于转发UDP。当监听端口数量比较多的时候,会开启大量线程(用于UDP转发),
占用大量资源。这时候线程间频繁的上下文切换会产生不少额外开销(以及锁),况且大多数人的机器也就1个CPU
(顶多俩个),开这么多线程实在不值得。 Issue里也有人反映端口增加的时候 CPU/内存 占用飙升。

改动: 把线程全都改成异步任务(包括DNS解析),保留了锁。因为如果跑在多核的机器上,tokio就会开启多个线程。

第二个问题: UDP丢包 https://github.com/zhboner/realm/issues/26

UDP转发的逻辑有点暴力:绑定的端口接受到UDP包以后,依次记录来源。等到收到回复的时候再把包转发给之前记录的第一个来源。
只有假设 客户端发送一个包,服务器返回一个包,这种情况下才能正常转发。并且客户端只有一个,不然返回包发送顺序可能会乱。

改动:单独加了个UDP转发模块。每有一个不同的来源,就为其单独分配一个socket 负责跟服务端通讯,持续一段时间。
(应该能用,但是我不清楚这样做是否科学)

主要改动就以上这两个。仓库:https://github.com/zephyrchien/realm
https://github.com/zephyrchien/realm/releases/tag/v1.2.0

另外我单独开了一个分支,把程序改成了单线程的,去掉了锁,并且去掉了输出(因为是同步的,想好好打印日志就最好改成异步的)
随后研究了一下zero copy,和tfo。想要实现这些功能得亲自调用C api (或者用封装库),并且得亲自实现Future trait,
不如直接拿C++写一个
==================================================================================================
端口转发是个很简单的功能,很多工具都能拿来干这活。realm的好处就在于它足够简洁,开箱即用。
顺便我想借题发挥一下,说说目前常见的转发工具:

iptables: 工作于IP层,让内核负责转发。可惜享受不到TCP拥塞控制。

haproxy: 性能很好,功能性够强。支持配置入站/出站tls(以及sni, alpn),可以纯TCP转发,也可以处理HTTP(2),还可以用acl分流

nginx: 同上,但是我自己用的时候速度差强人意。<del>同样不支持UDP转发(一般也用不到)</del> (nginx可以转发UDP,加上udp关键字就行)

golang系列转发工具: 功能都很多,但是我自己基本用不上,有些配置比较复杂。(纯转发的话不如自己写个,开俩io.Copy()就行,自动实现零拷贝)

总体来说这些工具都够用,个人更倾向于稳定(haproxy) 或者短小精悍的(realm)。


好人卡资源网 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:改了一点realm, 顺便说说目前常见的转发工具
喜欢 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址