feat: add desktop updater and release automation

This commit is contained in:
lbl
2026-08-22 10:00:24 +08:00
parent da72670154
commit 60a4403f0e
42 changed files with 1374 additions and 257 deletions
+3 -3
View File
@@ -1,6 +1,6 @@
fn main() {
let protoc_path = protoc_bin_vendored::protoc_bin_path()
.expect("failed to find vendored protoc");
let protoc_path =
protoc_bin_vendored::protoc_bin_path().expect("failed to find vendored protoc");
let mut config = prost_build::Config::new();
@@ -19,4 +19,4 @@ fn main() {
&["proto"],
)
.unwrap();
}
}
@@ -100,7 +100,6 @@ impl QuicInnerInboundReceiver {
}
}
#[cfg(test)]
mod tests {
use super::*;
@@ -350,7 +350,6 @@ fn spawn_dest_sender(
});
}
#[cfg(test)]
mod tests {
use super::*;
+15 -7
View File
@@ -412,11 +412,7 @@ mod tests {
build_packet(fec, 0x81, 0)
}
fn build_packet(
fec: FecPacket,
type_byte: u8,
flags_byte: u8,
) -> NetPacket<TransmissionBytes> {
fn build_packet(fec: FecPacket, type_byte: u8, flags_byte: u8) -> NetPacket<TransmissionBytes> {
let fec_payload = fec.encode_to_vec();
let buffer = TransmissionBytes::zeroed(HEAD_LENGTH + fec_payload.len());
let mut pkt = NetPacket::new(buffer).unwrap();
@@ -467,13 +463,25 @@ mod tests {
// 收到 pkt0、pkt1pkt2 丢失,随后收到校验包
assert!(
decoder
.receive(build_data_packet(group_id, 0, type_bytes[0], 0, payloads[0]))
.receive(build_data_packet(
group_id,
0,
type_bytes[0],
0,
payloads[0]
))
.unwrap()
.is_some()
);
assert!(
decoder
.receive(build_data_packet(group_id, 1, type_bytes[1], 0, payloads[1]))
.receive(build_data_packet(
group_id,
1,
type_bytes[1],
0,
payloads[1]
))
.unwrap()
.is_some()
);
+6 -3
View File
@@ -194,7 +194,6 @@ async fn inner_icmp_socket_recv(
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
@@ -221,8 +220,12 @@ mod tests {
let now = Instant::now();
let mut map: IcmpNatMap = HashMap::new();
let (k_fresh, v_fresh) = entry("8.8.8.8", 1, 1, now);
let (k_stale, v_stale) =
entry("1.1.1.1", 2, 2, now - ICMP_NAT_TIMEOUT - Duration::from_secs(1));
let (k_stale, v_stale) = entry(
"1.1.1.1",
2,
2,
now - ICMP_NAT_TIMEOUT - Duration::from_secs(1),
);
map.insert(k_fresh, v_fresh);
map.insert(k_stale, v_stale);
@@ -98,7 +98,6 @@ async fn stream_copy(
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
@@ -174,7 +174,6 @@ async fn udp_mapping_handle(
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
+1 -2
View File
@@ -349,8 +349,7 @@ mod tests {
/// 接收方以 metric = max_ttl - curr_ttl 计算路由距离。
#[test]
fn relay_reply_survives_one_hop() {
let mut packet =
NetPacket::new(BytesMut::from(&[0u8; HEAD_LENGTH][..])).unwrap();
let mut packet = NetPacket::new(BytesMut::from(&[0u8; HEAD_LENGTH][..])).unwrap();
packet.set_msg_type(MsgType::RelayProbeReply);
// 目标方回复时 TTL 必须允许一次中继
packet.set_ttl(2);
+6 -1
View File
@@ -86,7 +86,12 @@ impl DeviceIOManager {
let device = Arc::new(create_tun(device_config)?);
let receiver = receiver.take().unwrap();
let enhanced_outbound = enhanced_outbound.take().unwrap();
let task = create(&self.task_group, device, receiver.receiver, enhanced_outbound);
let task = create(
&self.task_group,
device,
receiver.receiver,
enhanced_outbound,
);
self.device.lock().await.0.replace(task);
Ok(())
}
+2 -4
View File
@@ -281,10 +281,8 @@ impl P2pInboundHandler {
}
MsgType::RelayProbeReply => {
let metric = ctx.max_ttl - ctx.ttl;
self.route_table.add_route(
ctx.src_ip,
Route::from_default_rt(route_key, metric),
);
self.route_table
.add_route(ctx.src_ip, Route::from_default_rt(route_key, metric));
}
_ => {}
}
@@ -321,7 +321,6 @@ impl RouteTableInner {
}
}
#[cfg(test)]
mod tests {
use super::*;
@@ -437,7 +437,6 @@ fn default_tcp_stun() -> Vec<String> {
]
}
#[cfg(test)]
mod tests {
use super::*;
@@ -452,7 +451,10 @@ mod tests {
let scanned = vec![ip("192.168.1.2"), ip("10.0.0.3")];
let (primary, list) = select_local_ipv4(Some(ip("172.16.0.2")), &scanned).unwrap();
assert_eq!(primary, ip("172.16.0.2"));
assert_eq!(list, vec![ip("172.16.0.2"), ip("192.168.1.2"), ip("10.0.0.3")]);
assert_eq!(
list,
vec![ip("172.16.0.2"), ip("192.168.1.2"), ip("10.0.0.3")]
);
}
/// 探测失败/0.0.0.0 时:回退到扫描结果首个地址
@@ -463,8 +465,7 @@ mod tests {
assert_eq!(primary, ip("192.168.1.2"));
assert_eq!(list, scanned);
let (primary, _) =
select_local_ipv4(Some(Ipv4Addr::UNSPECIFIED), &scanned).unwrap();
let (primary, _) = select_local_ipv4(Some(Ipv4Addr::UNSPECIFIED), &scanned).unwrap();
assert_eq!(primary, ip("192.168.1.2"));
}
@@ -160,10 +160,7 @@ pub async fn ping_all(
}
}
}
pub async fn route_timeout_task(
route_table: RouteTable,
packet_loss_stats: PacketLossStats,
) {
pub async fn route_timeout_task(route_table: RouteTable, packet_loss_stats: PacketLossStats) {
loop {
tokio::time::sleep(Duration::from_secs(10)).await;
let expired_time = std::time::Instant::now() - Duration::from_secs(10);
@@ -227,10 +224,7 @@ pub async fn relay_probe_task(
if non_direct_targets.len() <= 10 {
non_direct_targets
} else {
non_direct_targets
.sample(&mut rng, 10)
.copied()
.collect()
non_direct_targets.sample(&mut rng, 10).copied().collect()
}
};
@@ -187,7 +187,6 @@ impl ConnectConfig {
}
}
#[cfg(test)]
mod tests {
use super::*;
-1
View File
@@ -278,7 +278,6 @@ pub async fn aaaa_dns(
Ok(rs)
}
#[cfg(test)]
mod tests {
use super::*;
+3 -6
View File
@@ -321,11 +321,8 @@ mod tests {
);
let _ = exit_tx.send(());
tokio::time::timeout(
std::time::Duration::from_secs(2),
group.wait_all_stopped(),
)
.await
.expect("wait_all_stopped should return after observer exits");
tokio::time::timeout(std::time::Duration::from_secs(2), group.wait_all_stopped())
.await
.expect("wait_all_stopped should return after observer exits");
}
}