wip(hs): publish-wait ceiling + CBT floor for Arti descriptor upload
Rescued from the uncommitted working tree on main. Not reviewed, not tested against the network: - PUBLISH_WAIT 180s -> 420s (Arti's per-HsDir upload timeout is 5m) - CBT_MIN_TIMEOUT_MSEC = 10_000 via override_net_params cbtmintimeout - status line now prints elapsed/publish-wait and current_problem() - tests/tor_hs.rs adjusted to match
This commit is contained in:
parent
a278e71627
commit
dcd458ab53
2 changed files with 59 additions and 13 deletions
59
src/hs.rs
59
src/hs.rs
|
|
@ -12,14 +12,30 @@ use tor_hsservice::{HsNickname, OnionServiceConfig, RunningOnionService};
|
|||
use tor_rtcompat::PreferredRuntime;
|
||||
|
||||
pub const HS_PORT: u16 = 80;
|
||||
/// Ceiling for waiting on `Running` / `DegradedReachable`.
|
||||
///
|
||||
/// Arti's per-HsDir upload timeout is 5 minutes, and circuit timeouts keep
|
||||
/// the combined status at `Bootstrapping` well past 3 minutes. Keep this
|
||||
/// at or above 360s so first publish can finish.
|
||||
pub const PUBLISH_WAIT: Duration = Duration::from_secs(420);
|
||||
/// Floor for Arti circuit-build timeout (ms). Learned CBT on this host
|
||||
/// dropped to ~1s, which CircTimeouts every HsDir descriptor upload.
|
||||
pub const CBT_MIN_TIMEOUT_MSEC: i32 = 10_000;
|
||||
|
||||
pub type Client = Arc<TorClient<PreferredRuntime>>;
|
||||
|
||||
fn apply_net_overrides(builder: &mut TorClientConfigBuilder) {
|
||||
builder
|
||||
.override_net_params()
|
||||
.insert("cbtmintimeout".to_string(), CBT_MIN_TIMEOUT_MSEC);
|
||||
}
|
||||
|
||||
pub fn client_config(state_dir: &std::path::Path, cache_dir: &std::path::Path) -> TorClientConfig {
|
||||
std::fs::create_dir_all(state_dir).expect("state dir");
|
||||
std::fs::create_dir_all(cache_dir).expect("cache dir");
|
||||
let mut builder = TorClientConfigBuilder::from_directories(state_dir, cache_dir);
|
||||
builder.storage().permissions().dangerously_trust_everyone();
|
||||
apply_net_overrides(&mut builder);
|
||||
builder.build().expect("TorClientConfig")
|
||||
}
|
||||
|
||||
|
|
@ -49,11 +65,17 @@ pub fn onion_string(svc: &RunningOnionService) -> Result<String, String> {
|
|||
}
|
||||
|
||||
pub async fn wait_until_published(svc: &RunningOnionService, label: &str) -> Result<(), String> {
|
||||
let deadline = Instant::now() + Duration::from_secs(180);
|
||||
let started = Instant::now();
|
||||
let deadline = started + PUBLISH_WAIT;
|
||||
let mut events = svc.status_events();
|
||||
loop {
|
||||
let st = svc.status();
|
||||
eprintln!("{label} hs status: {:?}", st.state());
|
||||
eprintln!(
|
||||
"{label} hs status: {:?} ({:.0}s/{}s)",
|
||||
st.state(),
|
||||
started.elapsed().as_secs_f32(),
|
||||
PUBLISH_WAIT.as_secs()
|
||||
);
|
||||
match st.state() {
|
||||
State::Running | State::DegradedReachable => return Ok(()),
|
||||
State::Broken => {
|
||||
|
|
@ -66,8 +88,10 @@ pub async fn wait_until_published(svc: &RunningOnionService, label: &str) -> Res
|
|||
}
|
||||
if Instant::now() >= deadline {
|
||||
return Err(format!(
|
||||
"{label}: onion service did not publish within 180s: {:?}",
|
||||
st.state()
|
||||
"{label}: onion service did not publish within {}s: {:?} problem={:?}",
|
||||
PUBLISH_WAIT.as_secs(),
|
||||
st.state(),
|
||||
st.current_problem()
|
||||
));
|
||||
}
|
||||
tokio::select! {
|
||||
|
|
@ -76,3 +100,30 @@ pub async fn wait_until_published(svc: &RunningOnionService, label: &str) -> Res
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn publish_wait_covers_hsdir_upload_retries() {
|
||||
assert!(
|
||||
PUBLISH_WAIT >= Duration::from_secs(360),
|
||||
"HsDir circuit timeouts can keep Bootstrapping ~6min before DegradedReachable"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cbt_min_timeout_overrides_learned_subsecond_estimate() {
|
||||
let mut builder = TorClientConfigBuilder::from_directories("/tmp/ow-a", "/tmp/ow-b");
|
||||
apply_net_overrides(&mut builder);
|
||||
assert_eq!(
|
||||
builder.override_net_params().get("cbtmintimeout"),
|
||||
Some(&CBT_MIN_TIMEOUT_MSEC)
|
||||
);
|
||||
assert!(
|
||||
CBT_MIN_TIMEOUT_MSEC >= 10_000,
|
||||
"learned current_timeout was 998ms; HsDir uploads need a multi-second floor"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
use std::sync::Arc;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use arti_client::config::TorClientConfigBuilder;
|
||||
use arti_client::{DormantMode, TorClient, TorClientConfig};
|
||||
use futures::StreamExt;
|
||||
use futures::io::{AsyncReadExt, AsyncWriteExt};
|
||||
|
|
@ -23,12 +22,7 @@ const BOOTSTRAP_LOG: &str = "info";
|
|||
type Client = Arc<TorClient<PreferredRuntime>>;
|
||||
|
||||
fn client_config(state_dir: &std::path::Path, cache_dir: &std::path::Path) -> TorClientConfig {
|
||||
std::fs::create_dir_all(state_dir).expect("state dir");
|
||||
std::fs::create_dir_all(cache_dir).expect("cache dir");
|
||||
let mut builder = TorClientConfigBuilder::from_directories(state_dir, cache_dir);
|
||||
// Temp dirs sit under $TMP; skip fs-mistrust on the parent tree.
|
||||
builder.storage().permissions().dangerously_trust_everyone();
|
||||
builder.build().expect("TorClientConfig")
|
||||
onionwire::hs::client_config(state_dir, cache_dir)
|
||||
}
|
||||
|
||||
async fn bootstrapped(state_dir: &std::path::Path, cache_dir: &std::path::Path) -> Client {
|
||||
|
|
@ -89,7 +83,7 @@ async fn launch_echo(
|
|||
}
|
||||
|
||||
async fn wait_until_published(svc: &RunningOnionService, label: &str) {
|
||||
let deadline = Instant::now() + Duration::from_secs(180);
|
||||
let deadline = Instant::now() + onionwire::hs::PUBLISH_WAIT;
|
||||
let mut events = svc.status_events();
|
||||
loop {
|
||||
let st = svc.status();
|
||||
|
|
@ -103,7 +97,8 @@ async fn wait_until_published(svc: &RunningOnionService, label: &str) {
|
|||
}
|
||||
if Instant::now() >= deadline {
|
||||
panic!(
|
||||
"{label}: onion service did not publish within 180s: {:?}",
|
||||
"{label}: onion service did not publish within {}s: {:?}",
|
||||
onionwire::hs::PUBLISH_WAIT.as_secs(),
|
||||
st.state()
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue