Refactored loop connection detection and processing.
This commit is contained in:
@@ -11,6 +11,8 @@ pub enum Message {
|
|||||||
Shake { origin: String, version: u32, ok: bool, height: u64 },
|
Shake { origin: String, version: u32, ok: bool, height: u64 },
|
||||||
Ping { height: u64, hash: Bytes },
|
Ping { height: u64, hash: Bytes },
|
||||||
Pong { height: u64, hash: Bytes },
|
Pong { height: u64, hash: Bytes },
|
||||||
|
Twin,
|
||||||
|
Loop,
|
||||||
GetPeers,
|
GetPeers,
|
||||||
Peers { peers: Vec<String> },
|
Peers { peers: Vec<String> },
|
||||||
GetBlock { index: u64 },
|
GetBlock { index: u64 },
|
||||||
|
|||||||
+28
-13
@@ -109,18 +109,10 @@ impl Network {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If connection is from the same IP and not from loopback we ignore it to avoid connection loops
|
//debug!("Accepted connection from: {} to local IP: {}", address, local_ip);
|
||||||
let local_ip = stream.local_addr().unwrap_or("0.0.0.0:0".parse().unwrap());
|
let token = next(&mut unique_token);
|
||||||
if !local_ip.ip().is_loopback() && local_ip.ip() == address.ip() {
|
poll.registry().register(&mut stream, token, Interest::READABLE).expect("Error registering poll");
|
||||||
peers.ignore_ip(&address.ip());
|
peers.add_peer(token, Peer::new(address, stream, State::Connected, true));
|
||||||
stream.shutdown(Shutdown::Both).unwrap_or_else(|e|{ warn!("Error in shutdown, {}", e); });
|
|
||||||
warn!("Detected connection loop, ignoring IP: {}", &address.ip());
|
|
||||||
} else {
|
|
||||||
//debug!("Accepted connection from: {} to local IP: {}", address, local_ip);
|
|
||||||
let token = next(&mut unique_token);
|
|
||||||
poll.registry().register(&mut stream, token, Interest::READABLE).expect("Error registering poll");
|
|
||||||
peers.add_peer(token, Peer::new(address, stream, State::Connected, true));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Err(_) => {}
|
Err(_) => {}
|
||||||
}
|
}
|
||||||
@@ -260,6 +252,18 @@ fn handle_connection_event(context: Arc<Mutex<Context>>, peers: &mut Peers, regi
|
|||||||
State::Offline { .. } => {
|
State::Offline { .. } => {
|
||||||
peer.set_state(State::offline());
|
peer.set_state(State::offline());
|
||||||
}
|
}
|
||||||
|
State::Loop => {
|
||||||
|
peer.set_state(State::Loop);
|
||||||
|
peers.ignore_peer(registry, &event.token());
|
||||||
|
}
|
||||||
|
State::SendLoop => {
|
||||||
|
registry.reregister(stream, event.token(), Interest::WRITABLE).unwrap();
|
||||||
|
peer.set_state(State::SendLoop);
|
||||||
|
}
|
||||||
|
State::Twin => {
|
||||||
|
registry.reregister(stream, event.token(), Interest::WRITABLE).unwrap();
|
||||||
|
peer.set_state(State::Twin);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(_) => { return false; }
|
Err(_) => { return false; }
|
||||||
@@ -305,6 +309,15 @@ fn handle_connection_event(context: Arc<Mutex<Context>>, peers: &mut Peers, regi
|
|||||||
State::Error => {}
|
State::Error => {}
|
||||||
State::Banned => {}
|
State::Banned => {}
|
||||||
State::Offline { .. } => {}
|
State::Offline { .. } => {}
|
||||||
|
State::Loop => {}
|
||||||
|
State::SendLoop => {
|
||||||
|
let data = serde_json::to_string(&Message::Loop).unwrap();
|
||||||
|
send_message(peer.get_stream(), &data.into_bytes()).unwrap_or_else(|e| warn!("Error sending loop {}", e));
|
||||||
|
}
|
||||||
|
State::Twin => {
|
||||||
|
let data = serde_json::to_string(&Message::Twin).unwrap();
|
||||||
|
send_message(peer.get_stream(), &data.into_bytes()).unwrap_or_else(|e| warn!("Error sending loop {}", e));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
registry.reregister(peer.get_stream(), event.token(), Interest::READABLE).unwrap();
|
registry.reregister(peer.get_stream(), event.token(), Interest::READABLE).unwrap();
|
||||||
}
|
}
|
||||||
@@ -378,7 +391,7 @@ fn handle_message(context: Arc<Mutex<Context>>, message: Message, peers: &mut Pe
|
|||||||
Message::Hand { app_version, origin, version, public, rand} => {
|
Message::Hand { app_version, origin, version, public, rand} => {
|
||||||
if peers.is_our_own_connect(&rand) {
|
if peers.is_our_own_connect(&rand) {
|
||||||
warn!("Detected loop connect");
|
warn!("Detected loop connect");
|
||||||
State::Banned
|
State::SendLoop
|
||||||
} else {
|
} else {
|
||||||
if origin.eq(my_origin) && version == my_version {
|
if origin.eq(my_origin) && version == my_version {
|
||||||
let peer = peers.get_mut_peer(token).unwrap();
|
let peer = peers.get_mut_peer(token).unwrap();
|
||||||
@@ -493,6 +506,8 @@ fn handle_message(context: Arc<Mutex<Context>>, message: Message, peers: &mut Pe
|
|||||||
info!("Received block {} with hash {:?}", block.index, &block.hash);
|
info!("Received block {} with hash {:?}", block.index, &block.hash);
|
||||||
handle_block(context, peers, token, block)
|
handle_block(context, peers, token, block)
|
||||||
}
|
}
|
||||||
|
Message::Twin => { State::Twin }
|
||||||
|
Message::Loop => { State::Loop }
|
||||||
};
|
};
|
||||||
answer
|
answer
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-1
@@ -75,6 +75,15 @@ impl Peers {
|
|||||||
State::Offline { .. } => {
|
State::Offline { .. } => {
|
||||||
info!("Peer connection {} to {:?} is offline", &token.0, &peer.get_addr());
|
info!("Peer connection {} to {:?} is offline", &token.0, &peer.get_addr());
|
||||||
}
|
}
|
||||||
|
State::SendLoop => {
|
||||||
|
info!("Peer connection {} from {:?} is a loop", &token.0, &peer.get_addr());
|
||||||
|
}
|
||||||
|
State::Loop => {
|
||||||
|
info!("Peer connection {} to {:?} is a loop", &token.0, &peer.get_addr());
|
||||||
|
}
|
||||||
|
State::Twin => {
|
||||||
|
info!("Peer connection {} to {:?} is a twin", &token.0, &peer.get_addr());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.peers.remove(token);
|
self.peers.remove(token);
|
||||||
@@ -182,7 +191,9 @@ impl Peers {
|
|||||||
|
|
||||||
pub fn ignore_peer(&mut self, registry: &Registry, token: &Token) {
|
pub fn ignore_peer(&mut self, registry: &Registry, token: &Token) {
|
||||||
let peer = self.peers.get_mut(token).unwrap();
|
let peer = self.peers.get_mut(token).unwrap();
|
||||||
peer.set_state(State::Banned);
|
if !peer.get_state().is_loop() {
|
||||||
|
peer.set_state(State::Banned);
|
||||||
|
}
|
||||||
let ip = peer.get_addr().ip().clone();
|
let ip = peer.get_addr().ip().clone();
|
||||||
self.close_peer(registry, token);
|
self.close_peer(registry, token);
|
||||||
self.ignored.insert(ip);
|
self.ignored.insert(ip);
|
||||||
|
|||||||
@@ -9,6 +9,9 @@ pub enum State {
|
|||||||
Message { data: Vec<u8> },
|
Message { data: Vec<u8> },
|
||||||
Error,
|
Error,
|
||||||
Banned,
|
Banned,
|
||||||
|
SendLoop,
|
||||||
|
Loop,
|
||||||
|
Twin,
|
||||||
Offline { from: Instant },
|
Offline { from: Instant },
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,6 +36,14 @@ impl State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_loop(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
State::Loop { .. } => { true }
|
||||||
|
State::SendLoop { .. } => { true }
|
||||||
|
_ => { false }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn disabled(&self) -> bool {
|
pub fn disabled(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
State::Error => { true }
|
State::Error => { true }
|
||||||
|
|||||||
Reference in New Issue
Block a user