XTLS / Xray-core

Xray, Penetrates Everything. Also the best v2ray-core, with XTLS support. Fully compatible configuration.
https://t.me/projectXray
Mozilla Public License 2.0
24.19k stars 3.81k forks source link

windows httpupgrade panic #3128

Closed FDeghy closed 5 months ago

FDeghy commented 5 months ago

Xray 1.8.9 (Xray, Penetrates Everything.) 37f8654 (go1.22.1 windows/amd64)

panic: runtime error: invalid memory address or nil pointer dereference [signal 0xc0000005 code=0x0 addr=0x18 pc=0x7827a5]

goroutine 54 [running]: bufio.(Writer).Flush(0xc000132f80) bufio/bufio.go:639 +0x45 net/http.(Request).write(0xc000342240, {0x0, 0x0}, 0x0, 0x0, 0x0) net/http/request.go:764 +0xbd7 net/http.(Request).Write(...) net/http/request.go:555 github.com/xtls/xray-core/transport/internet/httpupgrade.dialhttpUpgrade({0x1658f80, 0xc000398600}, {{0x1659108, 0xc0003882a0}, 0x1f90, 0x2}, 0xc000373b80) github.com/xtls/xray-core/transport/internet/httpupgrade/dialer.go:56 +0x8be github.com/xtls/xray-core/transport/internet/httpupgrade.dial({0x1658f80, 0xc000398600}, {{0x1659108, 0xc0003882a0}, 0x1f90, 0x2}, 0xc000373b80) github.com/xtls/xray-core/transport/internet/httpupgrade/dialer.go:78 +0x189 github.com/xtls/xray-core/transport/internet.Dial({0x1658f80, 0xc000398600}, {{0x1659108?, 0xc0003882a0?}, 0x82a0?, 0xc0?}, 0x0?) github.com/xtls/xray-core/transport/internet/dialer.go:60 +0x1c7 github.com/xtls/xray-core/app/proxyman/outbound.(Handler).Dial(0xc00038e700, {0x1658f80?, 0xc000398600?}, {{0x1659108, 0xc0003882a0}, 0x1f90, 0x2}) github.com/xtls/xray-core/app/proxyman/outbound/handler.go:280 +0xa13 github.com/xtls/xray-core/proxy/vless/outbound.(Handler).Process.func1() github.com/xtls/xray-core/proxy/vless/outbound/outbound.go:85 +0xa6 github.com/xtls/xray-core/common/retry.(retryer).On(0xc0000f3bd8, 0xc0000f3c68) github.com/xtls/xray-core/common/retry/retry.go:27 +0xc6 github.com/xtls/xray-core/proxy/vless/outbound.(Handler).Process(0xc0003981b0, {0x1658f80, 0xc000398600}, 0xc00038c140, {0x1656610, 0xc00038e700}) github.com/xtls/xray-core/proxy/vless/outbound/outbound.go:82 +0x28e github.com/xtls/xray-core/app/proxyman/outbound.(Handler).Dispatch(0xc00038e700, {0x1658f80, 0xc000398600}, 0xc00038c140) github.com/xtls/xray-core/app/proxyman/outbound/handler.go:206 +0x3d8 github.com/xtls/xray-core/app/dispatcher.(DefaultDispatcher).routedDispatch(0xc000392000, {0x1658f80, 0xc000398600}, 0xc00038c140, {{0x1658d88, 0xc000386060}, 0x1bb, 0x2}) github.com/xtls/xray-core/app/dispatcher/default.go:443 +0xca6 github.com/xtls/xray-core/app/dispatcher.(DefaultDispatcher).Dispatch.func1() github.com/xtls/xray-core/app/dispatcher/default.go:266 +0x3f9 created by github.com/xtls/xray-core/app/dispatcher.(*DefaultDispatcher).Dispatch in goroutine 53 github.com/xtls/xray-core/app/dispatcher/default.go:239 +0x40b

RPRX commented 5 months ago

看代码是没加 TLS 时会 panic,已修复,请测试 https://github.com/XTLS/Xray-core/commit/d3a218f896b5db0208f83535b8f8a30b4dae3e53

Fangliding commented 5 months ago

看代码是没加 TLS 时会 panic,已修复,请测试 d3a218f

可以考虑一下实现 httpupgrade 0-rtt 嘛()

RPRX commented 5 months ago

可以考虑一下实现 httpupgrade 0-rtt 嘛()

目测继承 conn重写 Read(),第一次被调用时再 http.ReadResponse() 就行,太简单了你写吧,还是 C++ 的术语方便交流

RPRX commented 5 months ago

可以考虑一下实现 httpupgrade 0-rtt 嘛()

写了,但我没搭建 HTTPUpgrade 所以没测试,你们试一下 CF 接不接受它 @Fangliding @yuhan6665 @maskedeken @FDeghy

maskedeken commented 5 months ago

https://github.com/XTLS/Xray-core/commit/c144470b627f04c6d50b1dae49841750f43c9b7e#r139725007

RPRX commented 5 months ago

c144470#r139725007

感谢,修了:https://github.com/XTLS/Xray-core/commit/5c41292836a94721427b56e512939895d5f7718c

RPRX commented 5 months ago

所以有人测试了 https://github.com/XTLS/Xray-core/commit/5c41292836a94721427b56e512939895d5f7718c 能过 CF 吗

FDeghy commented 5 months ago

~So someone has tested whether 5c41292 can pass CF?~

yes, can pass CF <3

H1JK commented 5 months ago

I would like to say that HTTPUpgrade is a part of V2Fly's (or xiaokangwang's) experiment to test if WebSocket headers are used to identify proxies. To be consistent with common HTTP/1.1 connections, it should send continuous data only after receiving the server response. So enabling 0-RTT here definitely breaks the experiment.

I think it would be better to add a option to switch if 0-RTT is enabled, and it should be turned off by default (means no 0-RTT by default to simulate common HTTP/1.1 connection).

RPRX commented 5 months ago

if WebSocket headers are used to identify proxies

细说

Fangliding commented 5 months ago

if WebSocket headers are used to identify proxies

~细说~

小绿的臆想而已 不少伊朗人都觉得http头有文章或者可以拿来大作文章(然而实际情况懂得都懂) httpupgrade实际上源于tor的webtunnel tor项目组也想实现类似的网页分流代理 但是他们并没有直接用ws而是自己新写了一个项目 就是我刚刚说的webtunnel 前段时间刚官宣 为了轻量就没有额外的考量了(可见说什么experiment就是扯淡 引入这个纯粹是因为占用比ws小不少) 所以v2fly的文档都写明了推荐和tls一起使用

H1JK commented 5 months ago

~细说~

There are frames, close handshake and some other mechanics in WebSocket protocol stack, but are all removed in HTTPUpgrade. This can be used as a rigorous contrast experiment to compare whether the WebSocket protocol stack in fully encrypted data stream is specifically identified, thus proves whether there is a targeted blocking of WebSocket, rather than other factors such as bandwidth or ALPN.

There is indeed a lack of reports on such rigorous contrast experiments in the current community, or the censors have used unstable black boxes to interfere with the conduct of such experiments.

yuhan6665 commented 5 months ago

If they use neural network, censors themselves probably don't know what traffic feature is used for recognition ;)

H1JK commented 5 months ago

If they use neural network, censors themselves probably don't know what traffic feature is used for recognition ;)

Then test whether it is targeted by the machine. 😜

In summary, I think it is important to keep the original HTTP/1.1 connection model, which should be the same as the design in the WebSocket transport layer (although this does not require additional mechanisms like early data to do 0-RTT), at least leave it a place.

RPRX commented 5 months ago

如果 WebSocket 协议的一些通信机制有固定的长度特征,那么它的确可以被用来识别 WSS。如果都能手写出识别,那么机器学习一定能发现并利用,就像 TLS in TLS 握手问题。不过有个更简单的分类方法是,如果 TLS 的 ALPN 为 http/1.1 且通信模式表现出全双工特性,那么它就是 WebSocket 或 HTTPUpgrade。ECH 应该可以隐藏真实 ALPN,但境内封锁境外 DoH,出现了鸡蛋问题。

If they use neural network, censors themselves probably don't know what traffic feature is used for recognition ;)

是的,所以“审查者根本不靠XX来识别”的言论,我不知道该怎么评价,用机器学习去找不同自然都能找到,只是权重大小的问题

at least leave it a place.

可以,那么也给 HTTPUpgrade 加个 ed 开关,这下与 WebSocket 一致了

Fangliding commented 5 months ago

统一行为多少是好的 顺带一提能把header选项也实现了不 这样俩协议除了名字结构上也完全一样了

RPRX commented 5 months ago

统一行为多少是好的 顺带一提能把header选项也实现了不 这样俩协议除了名字结构上也完全一样了

WebSocket 那个 headers 好像基本上只会填 host,所以

Fangliding commented 5 months ago

@RPRX 也行不过新的ed是把数据放在哪个头里了 好像不是sec-websocket-protocol?

RPRX commented 5 months ago

@RPRX 也行不过新的ed是把数据放在哪个头里了 好像不是sec-websocket-protocol?

HTTPUpgrade 0-RTT 的原理是“不等 Upgrade 的结果,直接发数据”(WS 协议规范有限制所以不能这么干),没放 header,无限发

还有你文档更新早了,参考一下 https://github.com/XTLS/Xray-core/pull/3152

RPRX commented 5 months ago

@Fangliding 顺便测一下 HTTPUpgrade 不填和填 ed 时是否正常,没问题的话我准备发条频道消息

jahboom commented 5 months ago

@FanglidingКстати, проверьте, нормально ли работает HTTPUpgrade, если оставить пустым и заполнить ред. Если проблем нет, я пришлю сообщение канала.

我是否认为不支持 WebSocket 的 CDN 也无法使用 HTTPUpgrade 方法?

RPRX commented 5 months ago

我是否认为不支持 WebSocket 的 CDN 也无法使用 HTTPUpgrade 方法?

ouilymadi9 commented 5 months ago

Aide-moi