X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=src%2Fmain.rs;h=f72ba343a1972cbc1ddb03e06e2584ee7e25ded1;hb=a264197c4fa7babe2ce2865f1b12e4db07ae687e;hp=11bce61bf5968589a145381f074aa5b522e4c6a1;hpb=88eda2738aa841b96c47a9064971848c6d7b65c1;p=dnsseed-rust diff --git a/src/main.rs b/src/main.rs index 11bce61..f72ba34 100644 --- a/src/main.rs +++ b/src/main.rs @@ -69,6 +69,7 @@ pub fn scan_node(scan_time: Instant, node: SocketAddr, manual: bool) { msg: (String::new(), false), request: Arc::clone(&unsafe { REQUEST_BLOCK.as_ref().unwrap() }.lock().unwrap()), })); + let err_peer_state = Arc::clone(&peer_state); let final_peer_state = Arc::clone(&peer_state); let peer = Delay::new(scan_time).then(move |_| { @@ -77,7 +78,19 @@ pub fn scan_node(scan_time: Instant, node: SocketAddr, manual: bool) { Peer::new(node.clone(), Duration::from_secs(timeout), printer) }); tokio::spawn(peer.and_then(move |(mut write, read)| { - TimeoutStream::new_timeout(read, scan_time + Duration::from_secs(store.get_u64(U64Setting::RunTimeout))).map_err(|_| { () }).for_each(move |msg| { + TimeoutStream::new_timeout(read, scan_time + Duration::from_secs(store.get_u64(U64Setting::RunTimeout))).map_err(move |err| { + match err { + bitcoin::consensus::encode::Error::UnrecognizedNetworkCommand(ref msg) => { + // If we got here, we hit one of the explicitly disallowed messages indicating + // a bogus "node". + let mut state_lock = err_peer_state.lock().unwrap(); + state_lock.msg = (format!("(bad msg type {})", msg), true); + state_lock.fail_reason = AddressState::EvilNode; + }, + _ => {}, + } + () + }).for_each(move |msg| { let mut state_lock = peer_state.lock().unwrap(); macro_rules! check_set_flag { ($recvd_flag: ident, $msg: expr) => { { @@ -177,8 +190,17 @@ pub fn scan_node(scan_time: Instant, node: SocketAddr, manual: bool) { check_set_flag!(recvd_block, "block"); return future::err(()); }, + NetworkMessage::Inv(invs) => { + for inv in invs { + if inv.inv_type == InvType::Transaction { + state_lock.fail_reason = AddressState::EvilNode; + state_lock.msg = ("due to unrequested inv tx".to_string(), true); + return future::err(()); + } + } + }, NetworkMessage::Tx(_) => { - state_lock.fail_reason = AddressState::ProtocolViolation; + state_lock.fail_reason = AddressState::EvilNode; state_lock.msg = ("due to unrequested transaction".to_string(), true); return future::err(()); }, @@ -203,7 +225,9 @@ pub fn scan_node(scan_time: Instant, node: SocketAddr, manual: bool) { } else { assert!(state_lock.fail_reason != AddressState::Good); if state_lock.fail_reason == AddressState::TimeoutDuringRequest && state_lock.recvd_version && state_lock.recvd_verack { - if !state_lock.recvd_addrs { + if !state_lock.recvd_pong { + state_lock.fail_reason = AddressState::TimeoutAwaitingPong; + } else if !state_lock.recvd_addrs { state_lock.fail_reason = AddressState::TimeoutAwaitingAddr; } else if !state_lock.recvd_block { state_lock.fail_reason = AddressState::TimeoutAwaitingBlock; @@ -234,7 +258,8 @@ fn poll_dnsseeds() { printer.add_line(format!("Added {} new addresses from other DNS seeds", new_addrs), false); Delay::new(Instant::now() + Duration::from_secs(60)).then(|_| { let store = unsafe { DATA_STORE.as_ref().unwrap() }; - store.save_data().then(|_| { + let dns_future = store.write_dns(); + store.save_data().join(dns_future).then(|_| { if !START_SHUTDOWN.load(Ordering::Relaxed) { poll_dnsseeds(); }