mirror of
https://mirror.suhoan.cn/https://github.com/EasyTier/EasyTier.git
synced 2025-12-12 04:37:23 +08:00
fix(mobile): Add DHCP polling to fix Android VPN startup failure (#1628)
This commit is contained in:
@@ -113,6 +113,39 @@ async fn run_network_instance(
|
|||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
|
#[cfg(target_os = "android")]
|
||||||
|
if let Some(instance_manager) = INSTANCE_MANAGER.read().await.as_ref() {
|
||||||
|
let instance_uuid = instance_id
|
||||||
|
.parse::<uuid::Uuid>()
|
||||||
|
.map_err(|e| e.to_string())?;
|
||||||
|
if let Some(instance_ref) = instance_manager
|
||||||
|
.iter()
|
||||||
|
.find(|item| *item.key() == instance_uuid)
|
||||||
|
{
|
||||||
|
if let Some(mut event_receiver) = instance_ref.value().subscribe_event() {
|
||||||
|
let app_clone = app.clone();
|
||||||
|
let instance_id_clone = instance_id.clone();
|
||||||
|
tokio::spawn(async move {
|
||||||
|
loop {
|
||||||
|
match event_receiver.recv().await {
|
||||||
|
Ok(event) => {
|
||||||
|
if let easytier::common::global_ctx::GlobalCtxEvent::DhcpIpv4Changed(_, _) = event {
|
||||||
|
let _ = app_clone.emit("dhcp_ip_changed", instance_id_clone.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(tokio::sync::broadcast::error::RecvError::Closed) => {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Err(tokio::sync::broadcast::error::RecvError::Lagged(_)) => {
|
||||||
|
event_receiver = event_receiver.resubscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
app.emit("post_run_network_instance", instance_id)
|
app.emit("post_run_network_instance", instance_id)
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -643,7 +676,8 @@ mod manager {
|
|||||||
app: &AppHandle,
|
app: &AppHandle,
|
||||||
) -> Result<(), easytier::rpc_service::remote_client::RemoteClientError<anyhow::Error>>
|
) -> Result<(), easytier::rpc_service::remote_client::RemoteClientError<anyhow::Error>>
|
||||||
{
|
{
|
||||||
for inst_id in self.get_enabled_instances_with_tun_ids() {
|
let inst_ids: Vec<uuid::Uuid> = self.get_enabled_instances_with_tun_ids().collect();
|
||||||
|
for inst_id in inst_ids {
|
||||||
self.handle_update_network_state(app.clone(), inst_id, true)
|
self.handle_update_network_state(app.clone(), inst_id, true)
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ const EVENTS = Object.freeze({
|
|||||||
PRE_RUN_NETWORK_INSTANCE: 'pre_run_network_instance',
|
PRE_RUN_NETWORK_INSTANCE: 'pre_run_network_instance',
|
||||||
POST_RUN_NETWORK_INSTANCE: 'post_run_network_instance',
|
POST_RUN_NETWORK_INSTANCE: 'post_run_network_instance',
|
||||||
VPN_SERVICE_STOP: 'vpn_service_stop',
|
VPN_SERVICE_STOP: 'vpn_service_stop',
|
||||||
|
DHCP_IP_CHANGED: 'dhcp_ip_changed',
|
||||||
});
|
});
|
||||||
|
|
||||||
function onSaveConfigs(event: Event<NetworkTypes.NetworkConfig[]>) {
|
function onSaveConfigs(event: Event<NetworkTypes.NetworkConfig[]>) {
|
||||||
@@ -30,15 +31,23 @@ async function onVpnServiceStop(event: Event<string>) {
|
|||||||
await onNetworkInstanceChange(event.payload);
|
await onNetworkInstanceChange(event.payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function onDhcpIpChanged(event: Event<string>) {
|
||||||
|
console.log(`Received event '${EVENTS.DHCP_IP_CHANGED}' for instance: ${event.payload}`);
|
||||||
|
if (type() === 'android') {
|
||||||
|
await onNetworkInstanceChange(event.payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function listenGlobalEvents() {
|
export async function listenGlobalEvents() {
|
||||||
const unlisteners = [
|
const unlisteners = [
|
||||||
await listen(EVENTS.SAVE_CONFIGS, onSaveConfigs),
|
await listen(EVENTS.SAVE_CONFIGS, onSaveConfigs),
|
||||||
await listen(EVENTS.PRE_RUN_NETWORK_INSTANCE, onPreRunNetworkInstance),
|
await listen(EVENTS.PRE_RUN_NETWORK_INSTANCE, onPreRunNetworkInstance),
|
||||||
await listen(EVENTS.POST_RUN_NETWORK_INSTANCE, onPostRunNetworkInstance),
|
await listen(EVENTS.POST_RUN_NETWORK_INSTANCE, onPostRunNetworkInstance),
|
||||||
await listen(EVENTS.VPN_SERVICE_STOP, onVpnServiceStop),
|
await listen(EVENTS.VPN_SERVICE_STOP, onVpnServiceStop),
|
||||||
|
await listen(EVENTS.DHCP_IP_CHANGED, onDhcpIpChanged),
|
||||||
];
|
];
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
unlisteners.forEach(unlisten => unlisten());
|
unlisteners.forEach(unlisten => unlisten());
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ interface vpnStatus {
|
|||||||
dns: string | null | undefined
|
dns: string | null | undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let dhcpPollingTimer: NodeJS.Timeout | null = null
|
||||||
|
const DHCP_POLLING_INTERVAL = 2000 // 2秒后重试
|
||||||
|
|
||||||
const curVpnStatus: vpnStatus = {
|
const curVpnStatus: vpnStatus = {
|
||||||
running: false,
|
running: false,
|
||||||
ipv4Addr: undefined,
|
ipv4Addr: undefined,
|
||||||
@@ -125,6 +128,12 @@ function getRoutesForVpn(routes: Route[], node_config: NetworkTypes.NetworkConfi
|
|||||||
|
|
||||||
export async function onNetworkInstanceChange(instanceId: string) {
|
export async function onNetworkInstanceChange(instanceId: string) {
|
||||||
console.error('vpn service network instance change id', instanceId)
|
console.error('vpn service network instance change id', instanceId)
|
||||||
|
|
||||||
|
if (dhcpPollingTimer) {
|
||||||
|
clearTimeout(dhcpPollingTimer)
|
||||||
|
dhcpPollingTimer = null
|
||||||
|
}
|
||||||
|
|
||||||
if (!instanceId) {
|
if (!instanceId) {
|
||||||
await doStopVpn()
|
await doStopVpn()
|
||||||
return
|
return
|
||||||
@@ -140,6 +149,15 @@ export async function onNetworkInstanceChange(instanceId: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const virtual_ip = Utils.ipv4ToString(curNetworkInfo?.my_node_info?.virtual_ipv4.address)
|
const virtual_ip = Utils.ipv4ToString(curNetworkInfo?.my_node_info?.virtual_ipv4.address)
|
||||||
|
|
||||||
|
if (config.dhcp && (!virtual_ip || !virtual_ip.length)) {
|
||||||
|
console.log('DHCP enabled but no IP yet, will retry in', DHCP_POLLING_INTERVAL, 'ms')
|
||||||
|
dhcpPollingTimer = setTimeout(() => {
|
||||||
|
onNetworkInstanceChange(instanceId)
|
||||||
|
}, DHCP_POLLING_INTERVAL)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (!virtual_ip || !virtual_ip.length) {
|
if (!virtual_ip || !virtual_ip.length) {
|
||||||
await doStopVpn()
|
await doStopVpn()
|
||||||
return
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user