mirror of
https://github.com/telemt/telemt.git
synced 2026-05-25 05:01:44 +03:00
Implement user connection reservation management and enhance relay task handling in proxy
This commit is contained in:
@@ -178,3 +178,112 @@ async fn direct_relay_abort_midflight_releases_route_gauge() {
|
||||
tg_accept_task.abort();
|
||||
let _ = tg_accept_task.await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn direct_relay_cutover_midflight_releases_route_gauge() {
|
||||
let tg_listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
|
||||
let tg_addr = tg_listener.local_addr().unwrap();
|
||||
|
||||
let tg_accept_task = tokio::spawn(async move {
|
||||
let (stream, _) = tg_listener.accept().await.unwrap();
|
||||
let _hold_stream = stream;
|
||||
tokio::time::sleep(Duration::from_secs(60)).await;
|
||||
});
|
||||
|
||||
let stats = Arc::new(Stats::new());
|
||||
let mut config = ProxyConfig::default();
|
||||
config
|
||||
.dc_overrides
|
||||
.insert("2".to_string(), vec![tg_addr.to_string()]);
|
||||
let config = Arc::new(config);
|
||||
|
||||
let upstream_manager = Arc::new(UpstreamManager::new(
|
||||
vec![UpstreamConfig {
|
||||
upstream_type: UpstreamType::Direct {
|
||||
interface: None,
|
||||
bind_addresses: None,
|
||||
},
|
||||
weight: 1,
|
||||
enabled: true,
|
||||
scopes: String::new(),
|
||||
selected_scope: String::new(),
|
||||
}],
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
false,
|
||||
stats.clone(),
|
||||
));
|
||||
|
||||
let rng = Arc::new(SecureRandom::new());
|
||||
let buffer_pool = Arc::new(BufferPool::new());
|
||||
let route_runtime = Arc::new(RouteRuntimeController::new(RelayRouteMode::Direct));
|
||||
let route_snapshot = route_runtime.snapshot();
|
||||
|
||||
let (server_side, client_side) = duplex(64 * 1024);
|
||||
let (server_reader, server_writer) = tokio::io::split(server_side);
|
||||
let client_reader = make_crypto_reader(server_reader);
|
||||
let client_writer = make_crypto_writer(server_writer);
|
||||
|
||||
let success = HandshakeSuccess {
|
||||
user: "cutover-direct-user".to_string(),
|
||||
dc_idx: 2,
|
||||
proto_tag: ProtoTag::Intermediate,
|
||||
dec_key: [0u8; 32],
|
||||
dec_iv: 0,
|
||||
enc_key: [0u8; 32],
|
||||
enc_iv: 0,
|
||||
peer: "127.0.0.1:50002".parse().unwrap(),
|
||||
is_tls: false,
|
||||
};
|
||||
|
||||
let relay_task = tokio::spawn(handle_via_direct(
|
||||
client_reader,
|
||||
client_writer,
|
||||
success,
|
||||
upstream_manager,
|
||||
stats.clone(),
|
||||
config,
|
||||
buffer_pool,
|
||||
rng,
|
||||
route_runtime.subscribe(),
|
||||
route_snapshot,
|
||||
0xface_cafe,
|
||||
));
|
||||
|
||||
tokio::time::timeout(Duration::from_secs(2), async {
|
||||
loop {
|
||||
if stats.get_current_connections_direct() == 1 {
|
||||
break;
|
||||
}
|
||||
tokio::time::sleep(Duration::from_millis(10)).await;
|
||||
}
|
||||
})
|
||||
.await
|
||||
.expect("direct relay must increment route gauge before cutover");
|
||||
|
||||
assert!(
|
||||
route_runtime.set_mode(RelayRouteMode::Middle).is_some(),
|
||||
"cutover must advance route generation"
|
||||
);
|
||||
|
||||
let relay_result = tokio::time::timeout(Duration::from_secs(6), relay_task)
|
||||
.await
|
||||
.expect("direct relay must terminate after cutover")
|
||||
.expect("direct relay task must not panic");
|
||||
assert!(
|
||||
relay_result.is_err(),
|
||||
"cutover should terminate direct relay session"
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
stats.get_current_connections_direct(),
|
||||
0,
|
||||
"route gauge must be released when direct relay exits on cutover"
|
||||
);
|
||||
|
||||
drop(client_side);
|
||||
tg_accept_task.abort();
|
||||
let _ = tg_accept_task.await;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user