Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions lib/core/services/server_connection_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -422,9 +422,27 @@ class ServerConnectionManager {
});

if (Platform.isAndroid) {
// 主动获取网络状态,确保能拿到子网代理路由
List<String> proxyCidrs = [];
try {
final netStatus = await getNetworkStatus();
ServiceManager().connectionState.netStatus.value = netStatus;
for (final node in netStatus.nodes) {
for (final cidr in node.proxyCidrs) {
if (isValidCIDR(cidr) && !proxyCidrs.contains(cidr)) {
proxyCidrs.add(cidr);
}
}
}
} catch (_) {
// 如果获取失败,回退到从 state 中读取
proxyCidrs = _extractProxyCidrs();
}

await VpnManager.instance.start(
ipv4Addr: ServiceManager().networkConfigState.ipv4.value,
mtu: ServiceManager().networkConfigState.mtu.value,
proxyCidrs: proxyCidrs,
);

if (ServiceManager().appSettingsState.enableConnectionNotification.value) {
Expand Down Expand Up @@ -500,6 +518,22 @@ class ServerConnectionManager {
}
}

/// 从网络状态中提取子网代理路由
List<String> _extractProxyCidrs() {
final netStatus = ServiceManager().connectionState.netStatus.value;
if (netStatus == null) return [];

final cidrs = <String>[];
for (final node in netStatus.nodes) {
for (final cidr in node.proxyCidrs) {
if (isValidCIDR(cidr) && !cidrs.contains(cidr)) {
cidrs.add(cidr);
}
}
}
return cidrs;
}

/// 提取IPv4地址
String _extractIpv4Address(Map<String, dynamic> data) {
final virtualIpv4 = data['my_node_info']?['virtual_ipv4'];
Expand Down
6 changes: 5 additions & 1 deletion lib/core/services/vpn_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class VpnManager {
required String ipv4Addr,
int mtu = 1300,
List<String> disallowedApplications = const ['com.kevin.astral'],
List<String> proxyCidrs = const [],
}) async {
final plugin = _plugin;
if (plugin == null) return;
Expand All @@ -48,10 +49,13 @@ class VpnManager {
}

// 获取有效的VPN路由
final routes =
final customRoutes =
ServiceManager().vpnState.customVpn.value
.where((route) => isValidCIDR(route))
.toList();

// 合并自定义路由和子网代理路由
final routes = [...customRoutes, ...proxyCidrs.where((route) => isValidCIDR(route))];

await plugin.startVpn(
ipv4Addr: finalIpv4,
Expand Down
8 changes: 6 additions & 2 deletions lib/src/rust/api/simple.dart
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ class KVNodeInfo {
final BigInt txBytes;
final String version;
final int cost;
final List<String> proxyCidrs;

const KVNodeInfo({
required this.peerId,
Expand All @@ -307,6 +308,7 @@ class KVNodeInfo {
required this.txBytes,
required this.version,
required this.cost,
this.proxyCidrs = const [],
});

@override
Expand All @@ -324,7 +326,8 @@ class KVNodeInfo {
rxBytes.hashCode ^
txBytes.hashCode ^
version.hashCode ^
cost.hashCode;
cost.hashCode ^
proxyCidrs.hashCode;

@override
bool operator ==(Object other) =>
Expand All @@ -344,7 +347,8 @@ class KVNodeInfo {
rxBytes == other.rxBytes &&
txBytes == other.txBytes &&
version == other.version &&
cost == other.cost;
cost == other.cost &&
proxyCidrs == other.proxyCidrs;
}

class NodeHopStats {
Expand Down
8 changes: 6 additions & 2 deletions lib/src/rust/frb_generated.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2898,8 +2898,8 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
KVNodeInfo dco_decode_kv_node_info(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
final arr = raw as List<dynamic>;
if (arr.length != 14)
throw Exception('unexpected arr length: expect 14 but see ${arr.length}');
if (arr.length != 15)
throw Exception('unexpected arr length: expect 15 but see ${arr.length}');
return KVNodeInfo(
peerId: dco_decode_u_32(arr[0]),
hostname: dco_decode_String(arr[1]),
Expand All @@ -2915,6 +2915,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
txBytes: dco_decode_u_64(arr[11]),
version: dco_decode_String(arr[12]),
cost: dco_decode_i_32(arr[13]),
proxyCidrs: dco_decode_list_String(arr[14]),
);
}

Expand Down Expand Up @@ -3572,6 +3573,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
var var_txBytes = sse_decode_u_64(deserializer);
var var_version = sse_decode_String(deserializer);
var var_cost = sse_decode_i_32(deserializer);
var var_proxyCidrs = sse_decode_list_String(deserializer);
return KVNodeInfo(
peerId: var_peerId,
hostname: var_hostname,
Expand All @@ -3587,6 +3589,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
txBytes: var_txBytes,
version: var_version,
cost: var_cost,
proxyCidrs: var_proxyCidrs,
);
}

Expand Down Expand Up @@ -4306,6 +4309,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
sse_encode_u_64(self.txBytes, serializer);
sse_encode_String(self.version, serializer);
sse_encode_i_32(self.cost, serializer);
sse_encode_list_String(self.proxyCidrs, serializer);
}

@protected
Expand Down
1 change: 1 addition & 0 deletions rust/src/api/p2p.rs
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,7 @@ pub async fn get_network_status(instance_id: String) -> KVNetworkStatus {
.to_string(),
rx_bytes: pair.get_rx_bytes().unwrap_or_default(),
tx_bytes: pair.get_tx_bytes().unwrap_or_default(),
proxy_cidrs: route.proxy_cidrs.clone(),
};

if let Some(peer) = &pair.peer {
Expand Down
2 changes: 2 additions & 0 deletions rust/src/api/simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ pub struct KVNodeInfo {

pub version: String,
pub cost: i32,
pub proxy_cidrs: Vec<String>,
}
// 定义节点网络状态结构体
pub struct KVNetworkStatus {
Expand Down Expand Up @@ -928,6 +929,7 @@ pub async fn get_network_status() -> KVNetworkStatus {
.to_string(),
rx_bytes: pair.get_rx_bytes().unwrap_or_default(),
tx_bytes: pair.get_tx_bytes().unwrap_or_default(),
proxy_cidrs: route.proxy_cidrs.clone(),
};

// 收集连接统计信息
Expand Down
4 changes: 4 additions & 0 deletions rust/src/frb_generated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2918,6 +2918,7 @@ impl SseDecode for crate::api::simple::KVNodeInfo {
let mut var_txBytes = <u64>::sse_decode(deserializer);
let mut var_version = <String>::sse_decode(deserializer);
let mut var_cost = <i32>::sse_decode(deserializer);
let mut var_proxyCidrs = <Vec<String>>::sse_decode(deserializer);
return crate::api::simple::KVNodeInfo {
peer_id: var_peerId,
hostname: var_hostname,
Expand All @@ -2933,6 +2934,7 @@ impl SseDecode for crate::api::simple::KVNodeInfo {
tx_bytes: var_txBytes,
version: var_version,
cost: var_cost,
proxy_cidrs: var_proxyCidrs,
};
}
}
Expand Down Expand Up @@ -3729,6 +3731,7 @@ impl flutter_rust_bridge::IntoDart for crate::api::simple::KVNodeInfo {
self.tx_bytes.into_into_dart().into_dart(),
self.version.into_into_dart().into_dart(),
self.cost.into_into_dart().into_dart(),
self.proxy_cidrs.into_into_dart().into_dart(),
]
.into_dart()
}
Expand Down Expand Up @@ -4159,6 +4162,7 @@ impl SseEncode for crate::api::simple::KVNodeInfo {
<u64>::sse_encode(self.tx_bytes, serializer);
<String>::sse_encode(self.version, serializer);
<i32>::sse_encode(self.cost, serializer);
<Vec<String>>::sse_encode(self.proxy_cidrs, serializer);
}
}

Expand Down