Skip to content

Commit

Permalink
Skip connecting PeerWithSelf by checking ip address (#2253)
Browse files Browse the repository at this point in the history
* skip the connecting to self
  • Loading branch information
garyyu authored Dec 30, 2018
1 parent 9c98b79 commit ea7eea3
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 8 deletions.
16 changes: 15 additions & 1 deletion p2p/src/handshake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

use crate::util::RwLock;
use std::collections::VecDeque;
use std::net::{SocketAddr, TcpStream};
use std::net::{Shutdown, SocketAddr, TcpStream};
use std::sync::Arc;

use chrono::prelude::*;
Expand All @@ -29,13 +29,16 @@ use crate::peer::Peer;
use crate::types::{Capabilities, Direction, Error, P2PConfig, PeerInfo, PeerLiveInfo};

const NONCES_CAP: usize = 100;
const ADDRS_CAP: usize = 10;

/// Handles the handshake negotiation when two peers connect and decides on
/// protocol.
pub struct Handshake {
/// Ring buffer of nonces sent to detect self connections without requiring
/// a node id.
nonces: Arc<RwLock<VecDeque<u64>>>,
/// Ring buffer of self addr(s) collected from PeerWithSelf detection (by nonce).
pub addrs: Arc<RwLock<VecDeque<SocketAddr>>>,
/// The genesis block header of the chain seen by this node.
/// We only want to connect to other nodes seeing the same chain (forks are
/// ok).
Expand All @@ -48,6 +51,7 @@ impl Handshake {
pub fn new(genesis: Hash, config: P2PConfig) -> Handshake {
Handshake {
nonces: Arc::new(RwLock::new(VecDeque::with_capacity(NONCES_CAP))),
addrs: Arc::new(RwLock::new(VecDeque::with_capacity(ADDRS_CAP))),
genesis,
config,
}
Expand Down Expand Up @@ -145,7 +149,17 @@ impl Handshake {
} else {
// check the nonce to see if we are trying to connect to ourselves
let nonces = self.nonces.read();
let addr = extract_ip(&hand.sender_addr.0, &conn);
if nonces.contains(&hand.nonce) {
// save ip addresses of ourselves
let mut addrs = self.addrs.write();
addrs.push_back(addr);
if addrs.len() >= ADDRS_CAP {
addrs.pop_front();
}
if let Err(e) = conn.shutdown(Shutdown::Both) {
debug!("Error shutting down conn: {:?}", e);
}
return Err(Error::PeerWithSelf);
}
}
Expand Down
18 changes: 11 additions & 7 deletions p2p/src/serv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use crate::lmdb;

use crate::core::core;
use crate::core::core::hash::Hash;
use crate::core::global;
use crate::core::pow::Difficulty;
use crate::handshake::Handshake;
use crate::peer::Peer;
Expand Down Expand Up @@ -108,13 +109,16 @@ impl Server {
return Err(Error::ConnectionClose);
}

// check ip and port to see if we are trying to connect to ourselves
// todo: this can't detect all cases of PeerWithSelf, for example config.host is '0.0.0.0'
//
if self.config.port == addr.port()
&& (addr.ip().is_loopback() || addr.ip() == self.config.host)
{
return Err(Error::PeerWithSelf);
if global::is_production_mode() {
let hs = self.handshake.clone();
let addrs = hs.addrs.read();
if addrs.contains(&addr) {
debug!(
"connect: ignore the connecting to PeerWithSelf, addr: {}",
addr
);
return Err(Error::PeerWithSelf);
}
}

if let Some(p) = self.peers.get_connected_peer(addr) {
Expand Down

0 comments on commit ea7eea3

Please sign in to comment.