fix(async): finish the blocking-call sweep — scan, 3 SSH handlers, DNS
A codebase sweep for siblings of e282c059 (blocking network I/O parked
on the tokio runtime) found the openwrt fix was incomplete:
- openwrt.scan: scan_subnet is async in name only — up to 255 SEQUENTIAL
blocking TCP probes at 500ms each (~2 min on a /24 that silently
drops) plus a blocking SSH verify per candidate. One click of 'scan
for routers' held a worker for that whole time. Now spawn_blocking.
- provision-tollgate / scan-wifi / configure-wan still ran their SSH
exchanges inline; bounded_tcp caps each socket op but a session is
many sequential ops (provision runs opkg install over SSH), so worst
case was minutes. All three now spawn_blocking.
- network::check_dns: blocking glibc to_socket_addrs with no app-level
bound, on every Server-tab load via network.diagnostics. Against a
stale resolver — the moved-network case — that is 5-40s per refresh.
Now spawn_blocking plus a 5s cap, so the tile reports 'no DNS'
instead of hanging.
Verified false positives left alone: every other bare TcpStream::connect
targets 127.0.0.1 (fails instantly), and every remote reqwest client
already sets a timeout.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
6e89acced7
commit
203c2b6e50
@@ -302,9 +302,24 @@ async fn check_tor_connectivity() -> bool {
|
||||
}
|
||||
|
||||
/// Check DNS resolution works.
|
||||
///
|
||||
/// `to_socket_addrs` is blocking glibc resolution with no app-level bound:
|
||||
/// against a dead or stale resolver — the moved-network case — it can block
|
||||
/// 5–40s (timeout × attempts × nameservers). This runs on every Server-tab
|
||||
/// load via `network.diagnostics`, so inline it parked a tokio worker each
|
||||
/// refresh. Off the runtime, and bounded so the tile reports "no DNS"
|
||||
/// instead of hanging.
|
||||
async fn check_dns() -> bool {
|
||||
use std::net::ToSocketAddrs;
|
||||
"cloudflare.com:443".to_socket_addrs().is_ok()
|
||||
let probe = tokio::task::spawn_blocking(|| {
|
||||
use std::net::ToSocketAddrs;
|
||||
"cloudflare.com:443".to_socket_addrs().is_ok()
|
||||
});
|
||||
match tokio::time::timeout(std::time::Duration::from_secs(5), probe).await {
|
||||
Ok(Ok(ok)) => ok,
|
||||
// Timed out or the task failed: the blocking resolve may still be
|
||||
// running on the pool, but the caller is no longer waiting on it.
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
// --- Router Compatibility Abstraction ---
|
||||
|
||||
Reference in New Issue
Block a user