Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

explicit read_timeout and write_timeout during hand/shake #3249

Merged
merged 2 commits into from
Feb 27, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions p2p/src/handshake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -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 {
Expand Down Expand Up @@ -83,6 +99,12 @@ impl Handshake {
self_addr: PeerAddr,
conn: &mut TcpStream,
) -> Result<PeerInfo, Error> {
// 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() {
Expand Down Expand Up @@ -148,6 +170,12 @@ impl Handshake {
total_difficulty: Difficulty,
conn: &mut TcpStream,
) -> Result<PeerInfo, Error> {
// 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
Expand Down