From f2380585a764df1311307376b9317fa4d1eeaa9f Mon Sep 17 00:00:00 2001 From: Antioch Peverell Date: Thu, 27 Feb 2020 07:49:38 +0000 Subject: [PATCH] explicit read_timeout and write_timeout during hand/shake (#3249) * explicit read_timeout and write_timeout during hand/shake * longer timeout for reading Hand and Shake messages to give peer time to send it over --- p2p/src/handshake.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/p2p/src/handshake.rs b/p2p/src/handshake.rs index ad09291bb..59d17f098 100644 --- a/p2p/src/handshake.rs +++ b/p2p/src/handshake.rs @@ -24,6 +24,7 @@ use rand::{thread_rng, Rng}; use std::collections::VecDeque; use std::net::{SocketAddr, TcpStream}; use std::sync::Arc; +use std::time::Duration; /// Local generated nonce for peer connecting. /// Used for self-connecting detection (on receiver side), @@ -34,6 +35,21 @@ const NONCES_CAP: usize = 100; /// 10 should be enough since most of servers don't have more than 10 IP addresses. const ADDRS_CAP: usize = 10; +/// The initial Hand message should come in immediately after the connection is initiated. +/// But for consistency use the same timeout for reading both Hand and Shake messages. +const HAND_READ_TIMEOUT: Duration = Duration::from_millis(10_000); + +/// We need to allow time for the peer to receive our Hand message and send back a Shake reply. +const SHAKE_READ_TIMEOUT: Duration = Duration::from_millis(10_000); + +/// Fail fast when trying to write a Hand message to the tcp stream. +/// If we cannot write it within a couple of seconds then something has likely gone wrong. +const HAND_WRITE_TIMEOUT: Duration = Duration::from_millis(2_000); + +/// Fail fast when trying to write a Shake message to the tcp stream. +/// If we cannot write it within a couple of seconds then something has likely gone wrong. +const SHAKE_WRITE_TIMEOUT: Duration = Duration::from_millis(2_000); + /// Handles the handshake negotiation when two peers connect and decides on /// protocol. pub struct Handshake { @@ -83,6 +99,12 @@ impl Handshake { self_addr: PeerAddr, conn: &mut TcpStream, ) -> Result { + // Set explicit timeouts on the tcp stream for hand/shake messages. + // Once the peer is up and running we will set new values for these. + // We initiate this connection, writing a Hand message and read a Shake reply. + let _ = conn.set_write_timeout(Some(HAND_WRITE_TIMEOUT)); + let _ = conn.set_read_timeout(Some(SHAKE_READ_TIMEOUT)); + // prepare the first part of the handshake let nonce = self.next_nonce(); let peer_addr = match conn.peer_addr() { @@ -148,6 +170,12 @@ impl Handshake { total_difficulty: Difficulty, conn: &mut TcpStream, ) -> Result { + // Set explicit timeouts on the tcp stream for hand/shake messages. + // Once the peer is up and running we will set new values for these. + // We accept an inbound connection, reading a Hand then writing a Shake reply. + let _ = conn.set_read_timeout(Some(HAND_READ_TIMEOUT)); + let _ = conn.set_write_timeout(Some(SHAKE_WRITE_TIMEOUT)); + let hand: Hand = read_message(conn, self.protocol_version, Type::Hand)?; // all the reasons we could refuse this connection for