diff --git a/Cargo.lock b/Cargo.lock index f69df25..39a5366 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -74,7 +74,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "matches 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", @@ -420,19 +420,19 @@ dependencies = [ [[package]] name = "regex" -version = "0.1.77" +version = "0.1.79" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex-syntax" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -503,7 +503,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.1.77 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.79 (registry+https://github.com/rust-lang/crates.io-index)", "slog 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "slog-stdlog 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "slog-term 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -768,8 +768,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum pnacl-build-helper 1.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "61c9231d31aea845007443d62fcbb58bb6949ab9c18081ee1e09920e0cf1118b" "checksum quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45" "checksum rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2791d88c6defac799c3f20d74f094ca33b9332612d9aef9078519c82e4fe04a5" -"checksum regex 0.1.77 (registry+https://github.com/rust-lang/crates.io-index)" = "64b03446c466d35b42f2a8b203c8e03ed8b91c0f17b56e1f84f7210a257aa665" -"checksum regex-syntax 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "48f0573bcee95a48da786f8823465b5f2a1fae288a55407aca991e5b3e0eae11" +"checksum regex 0.1.79 (registry+https://github.com/rust-lang/crates.io-index)" = "33afc849c34c7e9389435f5f2ac9bb0cc5eb69f137e9aa6e6b1ef0b2baab0226" +"checksum regex-syntax 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "01acf14447f3e18588a1f42ac1402c6c66e2204210f70bd5b7b5903ba8ba01d3" "checksum route-recognizer 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "4f0a750d020adb1978f5964ea7bca830585899b09da7cbb3f04961fc2400122d" "checksum router 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b94397bfa5b772b4375be4da12560a7c1c1e74b2e35c46ed312958aad56df726" "checksum rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "6159e4e6e559c81bd706afe9c8fd68f547d3e851ce12e76b1de7914bab61691b" diff --git a/src/main.rs b/src/main.rs index 43b21ab..8272eea 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,6 +21,8 @@ mod webservice; use asns::*; use clap::{Arg, App}; use std::sync::{Arc, RwLock}; +use std::thread; +use std::time::Duration; use webservice::*; fn logger_init() { @@ -39,10 +41,28 @@ fn logger_init() { slog_stdlog::set_logger(root_logger.clone()).unwrap(); } +fn get_asns(db_url: &str) -> Result { + info!("Retrieving ASNs"); + let asns = ASNs::new(db_url); + info!("ASNs loaded"); + asns +} + +fn update_asns(asns_arc: &Arc>>, db_url: &str) { + let asns = match get_asns(db_url) { + Ok(asns) => asns, + Err(e) => { + warn!("{}", e); + return; + } + }; + *asns_arc.write().unwrap() = Arc::new(asns); +} + fn main() { logger_init(); let matches = App::new("iptoasn webservice") - .version("0.1") + .version("0.2") .author("Frank Denis") .about("Webservice for https://iptoasn.com") .arg(Arg::with_name("listen_addr") @@ -60,13 +80,17 @@ fn main() { .takes_value(true) .default_value("https://iptoasn.com/data/ip2asn-combined.tsv.gz")) .get_matches(); - let db_url = matches.value_of("db_url").unwrap(); + let db_url = matches.value_of("db_url").unwrap().to_owned(); let listen_addr = matches.value_of("listen_addr").unwrap(); - let asns = match ASNs::new(db_url) { - Ok(asns) => asns, - Err(err) => panic!(format!("{} [{}]", err, db_url)), - }; - let asns_arc = RwLock::new(Arc::new(asns)); + let asns = get_asns(&db_url).expect("Unable to load the initial database"); + let asns_arc = Arc::new(RwLock::new(Arc::new(asns))); + let asns_arc_copy = asns_arc.clone(); + thread::spawn(move || { + loop { + thread::sleep(Duration::from_secs(3600)); + update_asns(&asns_arc_copy, &db_url); + } + }); info!("Starting the webservice"); WebService::start(asns_arc, listen_addr); } diff --git a/src/webservice.rs b/src/webservice.rs index 78b08d5..3ce2576 100644 --- a/src/webservice.rs +++ b/src/webservice.rs @@ -14,7 +14,7 @@ use std::sync::{Arc, RwLock}; const TTL: u32 = 86400; struct ASNsMiddleware { - asns_arc: RwLock>, + asns_arc: Arc>>, } impl typemap::Key for ASNsMiddleware { @@ -22,7 +22,7 @@ impl typemap::Key for ASNsMiddleware { } impl ASNsMiddleware { - fn new(asns_arc: RwLock>) -> ASNsMiddleware { + fn new(asns_arc: Arc>>) -> ASNsMiddleware { ASNsMiddleware { asns_arc: asns_arc } } } @@ -101,7 +101,7 @@ impl WebService { Ok(Response::with((status::Ok, mime_json, cache_header, json))) } - pub fn start(asns_arc: RwLock>, listen_addr: &str) { + pub fn start(asns_arc: Arc>>, listen_addr: &str) { let router = router!(index: get "/" => Self::index, ip_lookup: get "/v1/as/ip/:ip" => Self::ip_lookup); let mut chain = Chain::new(router);