X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=src%2Fmain.rs;h=4bf93510c5e3aaa41ba8fb38e8c4356965f3af73;hb=2cf23b8a5638990cbf244e7aaf0b9b8b47f24f2e;hp=a1d03d2b978533266f94c80f03d25e4196387c5b;hpb=591344ed66e57115f5847b995f7ec42dc9eaa871;p=dnsseed-rust diff --git a/src/main.rs b/src/main.rs index a1d03d2..4bf9351 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(()); }, @@ -202,8 +224,10 @@ 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 && state_lock.recvd_pong { - if !state_lock.recvd_addrs { + if state_lock.fail_reason == AddressState::TimeoutDuringRequest && state_lock.recvd_version && state_lock.recvd_verack { + 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; @@ -211,8 +235,8 @@ pub fn scan_node(scan_time: Instant, node: SocketAddr, manual: bool) { } let old_state = store.set_node_state(node, state_lock.fail_reason, 0); if (manual || old_state != state_lock.fail_reason) && state_lock.fail_reason == AddressState::TimeoutDuringRequest { - printer.add_line(format!("Updating {} from {} to Timeout During Request (ver: {}, vack: {}, pong: {})", - node, old_state.to_str(), state_lock.recvd_version, state_lock.recvd_verack, state_lock.recvd_pong), true); + printer.add_line(format!("Updating {} from {} to Timeout During Request (ver: {}, vack: {})", + node, old_state.to_str(), state_lock.recvd_version, state_lock.recvd_verack), true); } else if manual || (old_state != state_lock.fail_reason && state_lock.msg.0 != "" && state_lock.msg.1) { printer.add_line(format!("Updating {} from {} to {} {}", node, old_state.to_str(), state_lock.fail_reason.to_str(), &state_lock.msg.0), state_lock.msg.1); }