Open keakon opened 8 months ago
@keakon 重新创建client会导致一个和原版不一致的现象,即hop的时候源端口号也会发生变化,实际上这会导致quic的整个握手重新发生,建议你还是想办法去修改sing-quic库,反正meta这边的库也是fork的,并不一定要和上游保持完全一致
@wwqgtxx 我 copy 了 hysteria 的源码,目前 TCP 是正常的,UDP 我平时用不到,不确定这么改是否正确,需要帮忙看下。这2天得了流感,实在研究不动了。
写了个UDP服务来测试,没遇到问题。但是我并没有用到 ctx、opts 这 2 个参数,不清楚是否对于控制超时、连接有什么特殊用处。
这个实现在与 ClashMetaForAndroid 一起使用时会遇到 hop 后无法继续使用的 bug,原因未知。并且还发现 ticker 在未到期时多次触发的 bug,也不知道原因。
修改了 hop 的实现,不去复制 packets 就正常了。
Hysteria2Option{
Up string `proxy:"up,omitempty"`
Down string `proxy:"down,omitempty"`
}
up和down还是允许为空吧,和以前的格式不兼容了
初始化的时候,proxy-providers中的proxies某一个不可用,会导致整个group都无效
proxy 12: connect error: timeout: no recent network activity
Hysteria2Option{ Up string `proxy:"up,omitempty"` Down string `proxy:"down,omitempty"` }
up和down还是允许为空吧,和以前的格式不兼容了
已修复
大佬你好,我魔改了sing-quic库,newClient的时候调用client 的offerNew()函数,然后也是通过ticker触发NewClient给他创建新的client 实际使用很完美,"端口跳跃"了,新的client中conn可以直接使用,不会断流,核心思想就是到了切换时间,先建立连接,再切换client,不需要等到流量到了client.offer出现错误的时候再去建立连接,我愿称他为伪端口跳跃,这个实现方式怎么样?
大佬你好,我魔改了sing-quic库,newClient的时候调用client 的offerNew()函数,然后也是通过ticker触发NewClient给他创建新的client 实际使用很完美,"端口跳跃"了,新的client中conn可以直接使用,不会断流,核心思想就是到了切换时间,先建立连接,再切换client,不需要等到流量到了client.offer出现错误的时候再去建立连接,我愿称他为伪端口跳跃,这个实现方式怎么样?
我不是大佬啊。 看上去可能会有额外的开销,你可以看看 offerNew() 里的后半段,创建了一个 http3.RoundTripper 对象来发起认证请求。 开销最低的方式就是我现在的方案,直接复用之前的连接,往其他端口写,但这不符合原版实现。 其次是创建一个新的 UDP 连接,但是需要同时监听和读写两个连接的数据,说实话这更适合用 epoll 来写(不过不跨平台)。
大佬你好,我魔改了sing-quic库,newClient的时候调用client 的offerNew()函数,然后也是通过ticker触发NewClient给他创建新的client 实际使用很完美,"端口跳跃"了,新的client中conn可以直接使用,不会断流,核心思想就是到了切换时间,先建立连接,再切换client,不需要等到流量到了client.offer出现错误的时候再去建立连接,我愿称他为伪端口跳跃,这个实现方式怎么样?
我不是大佬啊。 看上去可能会有额外的开销,你可以看看 offerNew() 里的后半段,创建了一个 http3.RoundTripper 对象来发起认证请求。 开销最低的方式就是我现在的方案,直接复用之前的连接,往其他端口写,但这不符合原版实现。 其次是创建一个新的 UDP 连接,但是需要同时监听和读写两个连接的数据,说实话这更适合用 epoll 来写(不过不跨平台)。
我这个实现把offerNew改了新增一个方法只获得conn,后面的loopMessage等到实际切换的时候再调用,确实存在这个重新连接,不过好在切换的连接都是可以直接发包的,切换的时候并没有卡顿,体验一晚上感觉很不错,有空学习一下你的代码😁
这个实现在与 ClashMetaForAndroid 一起使用时会遇到 hop 后无法继续使用的 bug,原因未知。并且还发现 ticker 在未到期时多次触发的 bug,也不知道原因。
我这个用ClashMetaForAndroid很爽哦,学校公共网20mbps,配置文件写最高15mbps流畅看1080,最开始一个版本用ticker改client,手机会出现触摸失灵,后面改了,不用这个ticker就好了
写了个UDP服务来测试,没遇到问题。但是我并没有用到 ctx、opts 这 2 个参数,不清楚是否对于控制超时、连接有什么特殊用处。
ctx控制gorountine退出的opots应该提供拓展空间吧
这个实现在与 ClashMetaForAndroid 一起使用时会遇到 hop 后无法继续使用的 bug,原因未知。并且还发现 ticker 在未到期时多次触发的 bug,也不知道原因。
我这个用ClashMetaForAndroid很爽哦,学校公共网20mbps,配置文件写最高15mbps流畅看1080,最开始一个版本用ticker改client,手机会出现触摸失灵,后面改了,不用这个ticker就好了
你好,请问在 ClashMetaForAndroid 怎么实现端口跳跃?需要用最新版代码手动编译吗?配置文件的 hysteria 端口跳跃部分该怎么写?看如今这个功能应该是开发完成了,但我在 PC 也不知道该如何配置端口跳跃
看了下代码做了些猜测,应该配置是这样的
ports: 2333-23333,
hop-interval: 45,
CMFA也是一样的配置,测试没有报错,但不知实际是否用上了端口跳跃
看了下代码做了些猜测,应该配置是这样的
ports: 2333-23333, hop-interval: 45,
CMFA也是一样的配置,测试没有报错,但不知实际是否用上了端口跳跃
ports 启用时,忽略 port 的设置(但是 port 仍然必填)。 hop-interval 默认为 30 秒。 设置 log-level: debug 就可以看到端口跳跃的日志了。
看了下代码做了些猜测,应该配置是这样的
ports: 2333-23333, hop-interval: 45,
CMFA也是一样的配置,测试没有报错,但不知实际是否用上了端口跳跃
ports 启用时,忽略 port 的设置(但是 port 仍然必填)。 hop-interval 默认为 30 秒。 设置 log-level: debug 就可以看到端口跳跃的日志了。
那请问 ports 里面的内容格式是怎么样的?我能这样写吗?ports: {2000,2333-23333}
看了下代码做了些猜测,应该配置是这样的
ports: 2333-23333, hop-interval: 45,
CMFA也是一样的配置,测试没有报错,但不知实际是否用上了端口跳跃
ports 启用时,忽略 port 的设置(但是 port 仍然必填)。 hop-interval 默认为 30 秒。 设置 log-level: debug 就可以看到端口跳跃的日志了。
那请问 ports 里面的内容格式是怎么样的?我能这样写吗?
ports: {2000,2333-23333}
https://github.com/MetaCubeX/mihomo/blob/81c832ef9ef97265da9e59298b3642554ca17fe7/common/utils/ranges.go#L17 https://github.com/MetaCubeX/mihomo/blob/81c832ef9ef97265da9e59298b3642554ca17fe7/common/utils/ranges.go#L23
@keakon 另外 https://github.com/MetaCubeX/mihomo/commit/012e4485621939af60bbd8708c4d15c8a04039e9 已经去掉了ports启用时,port必填的需求了
看了下代码做了些猜测,应该配置是这样的
ports: 2333-23333, hop-interval: 45,
CMFA也是一样的配置,测试没有报错,但不知实际是否用上了端口跳跃
ports 启用时,忽略 port 的设置(但是 port 仍然必填)。 hop-interval 默认为 30 秒。 设置 log-level: debug 就可以看到端口跳跃的日志了。
那请问 ports 里面的内容格式是怎么样的?我能这样写吗?
ports: {2000,2333-23333}
200,204,401-429,501-503
这样的写法感觉有些不符合 yaml 规范,不知后面是否有计划改进
我使用 yaml 格式化工具对包含 ports: 2000,2333-23333,
的配置文件进行格式化的时候,2333-23333,
会自动被分到下一行
@MMMMMoris 你需要加引号,又没让你直接写
Verify steps
Description
mihomo 目前支持 hysteria 1 代的 port hopping,却不支持 2 代。我看了 issue 列表,在这个回复中得到了不会支持的答复。
阅读代码后我发现对 hysteria 2 的支持是基于 sing-quic,而后者的开发者表示「暂时没有计划添加这种服务器只能使用特定 Linux 系统 + 特权运行的功能。」。 对于这种服务端不支持就不允许客户端支持的做法,我也也只能选择绕过它来实现了。
Possible Solution
目前我的实现(#981)是在
DialContext()
时判断是否需要更换端口,如果需要,则重新创建一个hysteria2.Client
。由于只读了半天源码,不确定是否有遗漏的地方,需要帮忙看看。
此外,考虑到效率问题,我并没有去加锁,但是经过几小时的测试,并未遇到异常。如果需要加锁的话,应该在调用
h.client.DialConn()
时加个读锁,确保获取到未关闭的 client 即可。