Skip to content

Routing: Add mutex for Attributes temporarily#3908

Merged
RPRX merged 2 commits intomainfrom
attr-mutex
Oct 15, 2024
Merged

Routing: Add mutex for Attributes temporarily#3908
RPRX merged 2 commits intomainfrom
attr-mutex

Conversation

@Fangliding
Copy link
Member

@Fangliding Fangliding commented Oct 12, 2024

#3904
mmm似乎在inbound上遇到了类似的问题 这里的问题是content
问题还是老问题 对于一条被mux的连接 多个子请求在内部共享一条ctx
mmm的做法是在mux阶段创建一个深拷贝避免它们相互影响
这里更麻烦一些 因为content是在mux后面的dispatcher才被创建的 没法在mux处理 我也拿不定怎么搞 或许WithCancel另起一个新的ctx? 不是很敢乱动
说回这个issue 本质是多个连接都在尝试往content写入数据 当同时写入的时候遇到竞争就炸了 临时解决办法是加锁 这样好歹不会崩溃 但是并没有解决多个连接共享content的问题 这可能导致预期外的路由或者其他非规定行为

@mmmray
Copy link
Contributor

mmmray commented Oct 12, 2024

ok, this is #3718 but for client?

@Fangliding
Copy link
Member Author

Fangliding commented Oct 12, 2024

ok, this is #3718 but for client?

For server, too
And this fix nothing, just prevents getting panic

@RPRX
Copy link
Member

RPRX commented Oct 13, 2024

既然知道了会有 race condition,加个锁就行了,还加 error log 是干嘛

@Fangliding
Copy link
Member Author

Fangliding commented Oct 13, 2024

既然知道了会有 race condition,加个锁就行了,还加 error log 是干嘛

因为它们本来就不应该尝试往一个map写入 这个修改等于不炸了 换成一个log警告 如果嫌多可以换到debug级别

@RPRX
Copy link
Member

RPRX commented Oct 13, 2024

看了下,所以加锁是治标不治本

直接治本吧,本来就不应该共享同一个 content

这里更麻烦一些 因为content是在mux后面的dispatcher才被创建的 没法在mux处理 我也拿不定怎么搞 或许WithCancel另起一个新的ctx? 不是很敢乱动

你改一下我看看

@RPRX
Copy link
Member

RPRX commented Oct 15, 2024

同样这个也打算先合了,治一下标,晚点再研究治本

@RPRX RPRX changed the title Routing: Add mutex for attr Routing: Add mutex for Attributes temporarily Oct 15, 2024
@RPRX RPRX merged commit 8625753 into main Oct 15, 2024
leninalive pushed a commit to amnezia-vpn/amnezia-xray-core that referenced this pull request Oct 29, 2024
@RPRX
Copy link
Member

RPRX commented Mar 4, 2025

#3904
mmm似乎在inbound上遇到了类似的问题 这里的问题是content
问题还是老问题 对于一条被mux的连接 多个子请求在内部共享一条ctx
mmm的做法是在mux阶段创建一个深拷贝避免它们相互影响
这里更麻烦一些 因为content是在mux后面的dispatcher才被创建的 没法在mux处理 我也拿不定怎么搞 或许WithCancel另起一个新的ctx? 不是很敢乱动
说回这个issue 本质是多个连接都在尝试往content写入数据 当同时写入的时候遇到竞争就炸了 临时解决办法是加锁 这样好歹不会崩溃 但是并没有解决多个连接共享content的问题 这可能导致预期外的路由或者其他非规定行为

又被你带偏了,我仔细看了一下,如果“content是在mux后面的dispatcher才被创建的”,则不应存在“本质是多个连接都在尝试往content写入数据”的问题

只有一种可能就是 content 在 mux 前就被创建了,比如说你看 worker.go 里那三个 callback() 的代码,如果有 sniffing:

content := new(session.Content)
if w.sniffingConfig != nil {
content.SniffingRequest.Enabled = w.sniffingConfig.Enabled
content.SniffingRequest.OverrideDestinationForProtocol = w.sniffingConfig.DestinationOverride
content.SniffingRequest.ExcludeForDomain = w.sniffingConfig.DomainsExcluded
content.SniffingRequest.MetadataOnly = w.sniffingConfig.MetadataOnly
content.SniffingRequest.RouteOnly = w.sniffingConfig.RouteOnly
}
ctx = session.ContextWithContent(ctx, content)

所以 mux 那里同时对 content 深拷贝是可以解决问题的,并且我看了下此时 Attributes 不为 nil 的话直接 panic 就行,因为在 mux 之前只有 HTTP 代理入站会设置这个,而它不应配合 mux 使用


我发现 SniffingRequest 里有 ExcludeForDomain 和 OverrideDestinationForProtocol 这两个 slice,不过它们在后面是只读的

倒是 worker.go UDP 那里没给 ExcludeForDomain 赋值,需要补上

RPRX added a commit that referenced this pull request Mar 4, 2025
@Fangliding
Copy link
Member Author

当时是看岔了 dispatcher里确实有一个附加content的行为 现在看来应该是供被核心内部dispatch出来的连接(eg. doh-nonlocal)
顺便QUIC嗅探的问题从隔壁抄来的 隔壁修了 无聊的话可以一起搬过来

@RPRX
Copy link
Member

RPRX commented Mar 4, 2025

顺便QUIC嗅探的问题从隔壁抄来的 隔壁修了 无聊的话可以一起搬过来

你搬一下吧,不过我印象中隔壁开始嗅探多个 QUIC 包,是不是加了缓存?

RPRX added a commit that referenced this pull request Mar 4, 2025
@RPRX
Copy link
Member

RPRX commented Mar 5, 2025

顺便QUIC嗅探的问题从隔壁抄来的 隔壁修了 无聊的话可以一起搬过来

本来想现在就搬,彻底修好 #3914 ,但发现隔壁的新版 sniffer 也遇到了原因不明的问题,等他们稳定后再搬吧

it2konst pushed a commit to it2konst/gametunnel-core that referenced this pull request Mar 1, 2026
it2konst pushed a commit to it2konst/gametunnel-core that referenced this pull request Mar 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants