mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-11-04 14:22:11 +08:00
fix(sysproxy): wait for the network before the login-time proxy write
This commit is contained in:
@@ -17,6 +17,9 @@ const fn should_wait_for_service(tun_enabled: bool, service_ready: bool, is_admi
|
||||
tun_enabled && !service_ready && !is_admin
|
||||
}
|
||||
|
||||
/// How long a login-time start waits for the network before writing the system proxy.
|
||||
const STARTUP_NETWORK_WAIT: std::time::Duration = std::time::Duration::from_secs(30);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
enum StartupDecision {
|
||||
Service,
|
||||
@@ -465,6 +468,22 @@ impl CoreManager {
|
||||
.ok_or_else(|| {
|
||||
anyhow::anyhow!("cannot apply system proxy before core readiness").context(SysproxyFailure::CoreNotReady)
|
||||
})?;
|
||||
// Startup only; a user toggling while offline should fail fast.
|
||||
if cfg!(target_os = "macos")
|
||||
&& !crate::utils::resolve::is_resolve_done()
|
||||
&& Config::verge()
|
||||
.await
|
||||
.latest_arc()
|
||||
.enable_system_proxy
|
||||
.unwrap_or_default()
|
||||
&& !proxy_control::wait_for_network_service(STARTUP_NETWORK_WAIT).await
|
||||
{
|
||||
logging!(
|
||||
warn,
|
||||
Type::Core,
|
||||
"no network service {STARTUP_NETWORK_WAIT:?} after startup; applying the system proxy anyway"
|
||||
);
|
||||
}
|
||||
proxy_control::apply().await?;
|
||||
if !expectation.is_valid(
|
||||
self.get_running_mode().as_ref(),
|
||||
|
||||
@@ -384,6 +384,23 @@ async fn current_service_proxy_config(verge: &IVerge) -> Result<MacosProxyConfig
|
||||
service_proxy_config(verge, mixed_port, 0)
|
||||
}
|
||||
|
||||
/// Wait, up to `limit`, for a network service to write the proxy on. At login the app usually
|
||||
/// comes up before the network does, and nothing re-applies a proxy the first write missed.
|
||||
pub async fn wait_for_network_service(limit: Duration) -> bool {
|
||||
let no_service = || {
|
||||
tokio::task::spawn_blocking(
|
||||
|| matches!(sysproxy::Sysproxy::get_system_proxy(), Err(error) if is_missing_network_service(&error)),
|
||||
)
|
||||
};
|
||||
tokio::time::timeout(limit, async {
|
||||
while no_service().await.unwrap_or(false) {
|
||||
tokio::time::sleep(Duration::from_secs(1)).await;
|
||||
}
|
||||
})
|
||||
.await
|
||||
.is_ok()
|
||||
}
|
||||
|
||||
pub fn is_reportable(error: &anyhow::Error) -> bool {
|
||||
is_reportable_given(error, notification::has_pending_failure)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user