tuic
tuic copied to clipboard
Bug: `quinn::connection::Connection::open_bi` will hang when reach `max_concurrent_bi_streams` limit
Bug: 当同时开启的stream数到达quinn的max_concurrent_bi_streams
(默认为100)上限后,调用quinn::connection::Connection::open_bi()
将会挂起task,导致连接超时。
可以考虑的解决方案:
-
tuic_client::relay::connection::Connection::get_bi_stream()
处通过Register
的流计数实现自动扩容流上限 - 加入可配置项允许用户设置
max_concurrent_bi_streams
值 - 创建
quic::connection::Connection
时调用set_max_concurrent_bi_streams
设置为更大值
Bug: quinn::connection::Connection::open_bi
will hang when reach max_concurrent_bi_streams
limit, cause relay task timeout.
possible solutions:
- make
tuic_client::relay::connection::Connection::get_bi_stream()
call expandmax_concurrent_bi_streams
automatically; - add a configuration option to allow customizing the value of
max_concurrent_bi_stream
; - call
set_max_concurrent_bi_streams
with a number larger than 100 when creatingquic::connection::Connection
refs:
- https://github.com/quinn-rs/quinn/issues/1231#issuecomment-1008331336
connection完成超时(大于1分钟)的统计图表。 a connection finish time tracing diagram.
临时补丁/workaround patch
client:
diff --git a/client/src/relay/connection.rs b/client/src/relay/connection.rs
index 1face7d..d4accc7 100644
--- a/client/src/relay/connection.rs
+++ b/client/src/relay/connection.rs
@@ -163,6 +163,9 @@ impl Connection {
conn.await?
};
+ connection.set_max_concurrent_bi_streams(65536u32.into());
+ connection.set_max_concurrent_uni_streams(65536u32.into());
+
let conn = Self::new(connection, config).await;
let uni_streams = IncomingUniStreams::new(uni_streams, conn.stream_reg.get_registry());
server:
diff --git a/server/src/connection/mod.rs b/server/src/connection/mod.rs
index a4c8ff0..b2904a2 100644
--- a/server/src/connection/mod.rs
+++ b/server/src/connection/mod.rs
@@ -59,6 +59,9 @@ impl Connection {
let is_closed = IsClosed::new();
let is_authed = IsAuthenticated::new(is_closed.clone());
+ connection.set_max_concurrent_uni_streams(65536u32.into());
+ connection.set_max_concurrent_bi_streams(65536u32.into());
+
let conn = Self {
controller: connection,
udp_packet_from: UdpPacketFrom::new(),
修改后会有比较大的内存占用。
may cause dramatic memory consumption.
最近正在重构,打算用思路 1 解决这个问题。
quinn 的文档中提到的 max_concurrent_uni_streams
:
Modify the number of remotely initiated unidirectional streams that may be concurrently open
因此 max_concurrent_uni_streams
的数值应只会影响 streams initiated by peer。目前 TUIC 的 register 只针对 task 进行计数,没有区分 stream 流向,所以需要重构这一部分