From ed6f61ea2adf657fdd3a088d83afef7952d7359d Mon Sep 17 00:00:00 2001 From: lbl <1791778603@qq.com> Date: Fri, 21 Aug 2026 01:55:02 +0800 Subject: [PATCH] =?UTF-8?q?fix(p2p):=20=E8=B7=AF=E7=94=B1=E8=AF=84?= =?UTF-8?q?=E5=88=86=E5=88=86=E6=AF=8D=20u32=20=E6=BA=A2=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit rtt > 约39s 时 rtt * (10000 + loss_v * 10) 超出 u32 范围, debug 构建下直接 panic,release 下评分错误。 改用 u64 计算并钳制回 u32。 测试:test_get_channel_score_large_rtt_no_overflow 覆盖 u32::MAX rtt 与正常大小关系。 --- vnt-core/src/tunnel_core/p2p/route_table.rs | 26 ++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/vnt-core/src/tunnel_core/p2p/route_table.rs b/vnt-core/src/tunnel_core/p2p/route_table.rs index 5182333..954e991 100644 --- a/vnt-core/src/tunnel_core/p2p/route_table.rs +++ b/vnt-core/src/tunnel_core/p2p/route_table.rs @@ -87,13 +87,14 @@ pub fn get_channel_score(rtt: u32, loss_v: u32, is_relay: bool) -> u32 { let weight = if is_relay { 100 } else { 120 }; let k_adj = 10; // 丢包惩罚系数 + // 用 u64 计算避免溢出:分母最大 rtt * 110000,rtt > 约39s 时 u32 溢出 // 分子:代表"有效做功"的放大值 - let numerator = weight * (10000 - loss_v) * 100; + let numerator = weight as u64 * (10000 - loss_v) as u64 * 100; // 分母:代表"链路阻力" - let denominator = rtt * (10000 + loss_v * k_adj); + let denominator = rtt as u64 * (10000 + loss_v * k_adj) as u64; - numerator / denominator + (numerator / denominator).min(u32::MAX as u64) as u32 } #[derive(Clone)] @@ -319,3 +320,22 @@ impl RouteTableInner { expired_keys } } + + +#[cfg(test)] +mod tests { + use super::*; + + /// rtt 极大(>39s)时分母不能 u32 溢出(debug 构建下溢出会 panic) + #[test] + fn test_get_channel_score_large_rtt_no_overflow() { + let score = get_channel_score(u32::MAX, 0, false); + assert_eq!(score, 0); + let score = get_channel_score(u32::MAX, 10000, true); + assert_eq!(score, 0); + // 正常值结果与预期一致:低 rtt 零丢包得分高 + let good = get_channel_score(10, 0, false); + let bad = get_channel_score(1000, 5000, true); + assert!(good > bad); + } +}