tor: restart service on 3rd ping error, do not start API and Tor service before first successful sync, restart running service or rebuild client on config change
This commit is contained in:
parent
36d6b75c65
commit
665ab9ab82
3 changed files with 93 additions and 77 deletions
|
@ -285,6 +285,19 @@ impl WalletTransport {
|
|||
let os = OperatingSystem::from_target_os();
|
||||
let show_bridges = os != OperatingSystem::Android;
|
||||
|
||||
// Restart running service or rebuild client.
|
||||
let restart_or_rebuild = || {
|
||||
let service_id = &wallet.identifier();
|
||||
if Tor::is_service_running(service_id) {
|
||||
if let Ok(key) = wallet.secret_key() {
|
||||
let api_port = wallet.foreign_api_port().unwrap();
|
||||
Tor::restart_service(api_port, key, service_id);
|
||||
}
|
||||
} else {
|
||||
Tor::rebuild_client();
|
||||
}
|
||||
};
|
||||
|
||||
ui.add_space(6.0);
|
||||
if show_bridges {
|
||||
let bridge = TorConfig::get_bridge();
|
||||
|
@ -304,14 +317,8 @@ impl WalletTransport {
|
|||
Some(b)
|
||||
};
|
||||
TorConfig::save_bridge(value);
|
||||
// Restart service.
|
||||
if let Ok(key) = wallet.secret_key() {
|
||||
let service_id = &wallet.identifier();
|
||||
Tor::stop_service(service_id);
|
||||
Tor::rebuild_client();
|
||||
let api_port = wallet.foreign_api_port().unwrap();
|
||||
Tor::start_service(api_port, key, service_id);
|
||||
}
|
||||
// Restart running service or rebuild client.
|
||||
restart_or_rebuild();
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -341,14 +348,8 @@ impl WalletTransport {
|
|||
if current_bridge != bridge {
|
||||
TorConfig::save_bridge(Some(bridge.clone()));
|
||||
self.bridge_bin_path_edit = bridge.binary_path();
|
||||
// Restart service.
|
||||
if let Ok(key) = wallet.secret_key() {
|
||||
let service_id = &wallet.identifier();
|
||||
Tor::stop_service(service_id);
|
||||
Tor::rebuild_client();
|
||||
let api_port = wallet.foreign_api_port().unwrap();
|
||||
Tor::start_service(api_port, key, service_id);
|
||||
}
|
||||
// Restart running service or rebuild client.
|
||||
restart_or_rebuild();
|
||||
}
|
||||
|
||||
// Draw binary path text edit.
|
||||
|
@ -370,13 +371,8 @@ impl WalletTransport {
|
|||
}
|
||||
};
|
||||
TorConfig::save_bridge(Some(b));
|
||||
// Restart service.
|
||||
if let Ok(key) = wallet.secret_key() {
|
||||
let service_id = &wallet.identifier();
|
||||
Tor::stop_service(service_id);
|
||||
let api_port = wallet.foreign_api_port().unwrap();
|
||||
Tor::start_service(api_port, key, service_id);
|
||||
}
|
||||
// Restart running service or rebuild client.
|
||||
restart_or_rebuild();
|
||||
}
|
||||
ui.add_space(2.0);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ use std::sync::Arc;
|
|||
use std::thread;
|
||||
use std::time::Duration;
|
||||
use arti_client::config::pt::TransportConfigBuilder;
|
||||
use grin_api::client;
|
||||
use lazy_static::lazy_static;
|
||||
use futures::task::SpawnExt;
|
||||
|
||||
|
@ -34,7 +33,7 @@ use sha2::Sha512;
|
|||
use tokio::time::sleep;
|
||||
use tor_config::CfgPath;
|
||||
use tor_rtcompat::tokio::TokioNativeTlsRuntime;
|
||||
use tor_rtcompat::{BlockOn, Runtime};
|
||||
use tor_rtcompat::Runtime;
|
||||
use tor_hsrproxy::OnionServiceReverseProxy;
|
||||
use tor_hsrproxy::config::{Encapsulation, ProxyAction, ProxyPattern, ProxyRule, TargetAddr, ProxyConfigBuilder};
|
||||
use tor_hsservice::config::OnionServiceConfigBuilder;
|
||||
|
@ -115,7 +114,7 @@ impl Tor {
|
|||
.unwrap(), config)
|
||||
}
|
||||
|
||||
/// Recreate Tor client on configuration change.
|
||||
/// Recreate Tor client.
|
||||
pub fn rebuild_client() {
|
||||
let client_config = Self::build_client(TokioNativeTlsRuntime::create().unwrap());
|
||||
let mut w_client = TOR_SERVER_STATE.client_config.write();
|
||||
|
@ -182,6 +181,13 @@ impl Tor {
|
|||
r_services.contains(id)
|
||||
}
|
||||
|
||||
// Restart Onion service.
|
||||
pub fn restart_service(port: u16, key: SecretKey, id: &String) {
|
||||
Self::stop_service(id);
|
||||
Self::rebuild_client();
|
||||
Self::start_service(port, key, id)
|
||||
}
|
||||
|
||||
/// Stop running Onion service.
|
||||
pub fn stop_service(id: &String) {
|
||||
let mut w_services = TOR_SERVER_STATE.running_services.write();
|
||||
|
@ -237,9 +243,9 @@ impl Tor {
|
|||
}
|
||||
let url = format!("http://{}/v2/foreign", service.onion_name().unwrap().to_string());
|
||||
thread::spawn(move || {
|
||||
// Wait 5 seconds to start.
|
||||
thread::sleep(Duration::from_millis(5000));
|
||||
let runtime = TokioNativeTlsRuntime::create().unwrap();
|
||||
// Wait 1 second to start.
|
||||
thread::sleep(Duration::from_millis(1000));
|
||||
let runtime = client_thread.runtime();
|
||||
let client_runtime = runtime.clone();
|
||||
// Put service to checking.
|
||||
{
|
||||
|
@ -248,9 +254,10 @@ impl Tor {
|
|||
}
|
||||
runtime
|
||||
.spawn(async move {
|
||||
const MAX_ERRORS: i32 = 3;
|
||||
let mut errors_count = 0;
|
||||
loop {
|
||||
if !Self::is_service_running(&service_id) &&
|
||||
!Self::is_service_starting(&service_id) {
|
||||
if !Self::is_service_running(&service_id) {
|
||||
// Remove service from checking.
|
||||
let mut w_services = TOR_SERVER_STATE.checking_services.write();
|
||||
w_services.remove(&service_id);
|
||||
|
@ -276,29 +283,37 @@ impl Tor {
|
|||
.body(Body::from(data))
|
||||
.unwrap();
|
||||
// Send request.
|
||||
match http.request(req).await {
|
||||
Ok(r) => {
|
||||
match hyper::body::to_bytes(r).await {
|
||||
Ok(_) => {
|
||||
// Remove service from starting.
|
||||
let mut w_services = TOR_SERVER_STATE.starting_services.write();
|
||||
w_services.remove(&service_id);
|
||||
},
|
||||
Err(_) => {
|
||||
// Put service to starting.
|
||||
let mut w_services = TOR_SERVER_STATE.starting_services.write();
|
||||
w_services.insert(service_id.clone());
|
||||
},
|
||||
}
|
||||
let duration = match http.request(req).await {
|
||||
Ok(_) => {
|
||||
// Remove service from starting.
|
||||
let mut w_services = TOR_SERVER_STATE.starting_services.write();
|
||||
w_services.remove(&service_id);
|
||||
// Check again after 5 seconds.
|
||||
Duration::from_millis(5000)
|
||||
},
|
||||
Err(_) => {
|
||||
// Put service to starting.
|
||||
let mut w_services = TOR_SERVER_STATE.starting_services.write();
|
||||
w_services.insert(service_id.clone());
|
||||
// Restart service on 3rd error.
|
||||
let duration = if errors_count == MAX_ERRORS - 1 {
|
||||
errors_count = 0;
|
||||
let key = key.clone();
|
||||
let service_id = service_id.clone();
|
||||
let client_runtime = client_runtime.clone();
|
||||
thread::spawn(move || {
|
||||
Self::stop_service(&service_id);
|
||||
let client_config = Self::build_client(client_runtime);
|
||||
let mut w_client = TOR_SERVER_STATE.client_config.write();
|
||||
*w_client = client_config;
|
||||
Self::start_service(port, key, &service_id);
|
||||
});
|
||||
Duration::from_millis(5000)
|
||||
} else {
|
||||
errors_count += 1;
|
||||
Duration::from_millis(1000)
|
||||
};
|
||||
duration
|
||||
},
|
||||
}
|
||||
// Check once per 5 second.
|
||||
sleep(Duration::from_millis(5000)).await;
|
||||
};
|
||||
sleep(duration).await;
|
||||
}
|
||||
}).unwrap();
|
||||
});
|
||||
|
|
|
@ -1047,31 +1047,6 @@ fn start_sync(mut wallet: Wallet) -> Thread {
|
|||
}
|
||||
}
|
||||
|
||||
// Start Foreign API listener if API server is not running.
|
||||
let mut api_server_running = {
|
||||
wallet.foreign_api_server.read().is_some()
|
||||
};
|
||||
if !api_server_running && wallet.is_open() {
|
||||
match start_api_server(&mut wallet) {
|
||||
Ok(api_server) => {
|
||||
let mut api_server_w = wallet.foreign_api_server.write();
|
||||
*api_server_w = Some(api_server);
|
||||
api_server_running = true;
|
||||
}
|
||||
Err(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
// Start Tor service if API server is running and wallet is open.
|
||||
if wallet.auto_start_tor_listener() && wallet.is_open() && api_server_running &&
|
||||
!Tor::is_service_running(&wallet.identifier()) {
|
||||
let r_foreign_api = wallet.foreign_api_server.read();
|
||||
let api = r_foreign_api.as_ref().unwrap();
|
||||
if let Ok(sec_key) = wallet.secret_key() {
|
||||
Tor::start_service(api.1, sec_key, &wallet.identifier());
|
||||
}
|
||||
}
|
||||
|
||||
// Scan outputs if repair is needed or sync data if there is no error.
|
||||
if !wallet.sync_error() {
|
||||
if wallet.is_repairing() {
|
||||
|
@ -1093,8 +1068,38 @@ fn start_sync(mut wallet: Wallet) -> Thread {
|
|||
return;
|
||||
}
|
||||
|
||||
// Repeat after default or attempt delay if synchronization was not successful.
|
||||
// Setup flag to check if sync was failed.
|
||||
let failed_sync = wallet.sync_error() || wallet.get_sync_attempts() != 0;
|
||||
|
||||
// Start Foreign API server and Tor service only if first sync was successful.
|
||||
if !failed_sync {
|
||||
// Start Foreign API listener if API server is not running.
|
||||
let mut api_server_running = {
|
||||
wallet.foreign_api_server.read().is_some()
|
||||
};
|
||||
if !api_server_running && wallet.is_open() {
|
||||
match start_api_server(&mut wallet) {
|
||||
Ok(api_server) => {
|
||||
let mut api_server_w = wallet.foreign_api_server.write();
|
||||
*api_server_w = Some(api_server);
|
||||
api_server_running = true;
|
||||
}
|
||||
Err(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
// Start Tor service if API server is running and wallet is open.
|
||||
if wallet.auto_start_tor_listener() && wallet.is_open() && api_server_running &&
|
||||
!Tor::is_service_running(&wallet.identifier()) {
|
||||
let r_foreign_api = wallet.foreign_api_server.read();
|
||||
let api = r_foreign_api.as_ref().unwrap();
|
||||
if let Ok(sec_key) = wallet.secret_key() {
|
||||
Tor::start_service(api.1, sec_key, &wallet.identifier());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Repeat after default or attempt delay if synchronization was not successful.
|
||||
let delay = if failed_sync {
|
||||
ATTEMPT_DELAY
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue