diff --git a/gossip/src/cluster_info.rs b/gossip/src/cluster_info.rs index 26aa6bb4f..7f0fcb520 100644 --- a/gossip/src/cluster_info.rs +++ b/gossip/src/cluster_info.rs @@ -42,8 +42,8 @@ use { solana_measure::measure::Measure, solana_metrics::{inc_new_counter_debug, inc_new_counter_error}, solana_net_utils::{ - bind_common, bind_common_in_range, bind_in_range, find_available_port_in_range, - multi_bind_in_range, PortRange, + bind_common, bind_common_in_range, bind_in_range, bind_two_consecutive_in_range, + find_available_port_in_range, multi_bind_in_range, PortRange, }, solana_perf::{ data_budget::DataBudget, @@ -2758,9 +2758,8 @@ impl Node { } pub fn new_localhost_with_pubkey(pubkey: &Pubkey) -> Self { let bind_ip_addr = IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)); - let tpu = UdpSocket::bind("127.0.0.1:0").unwrap(); - let tpu_quic_port = tpu.local_addr().unwrap().port() + QUIC_PORT_OFFSET; - let tpu_quic = UdpSocket::bind(format!("127.0.0.1:{}", tpu_quic_port)).unwrap(); + let ((_tpu_port, tpu), (_tpu_quic_port, tpu_quic)) = + bind_two_consecutive_in_range(bind_ip_addr, (1024, 65535)).unwrap(); let (gossip_port, (gossip, ip_echo)) = bind_common_in_range(bind_ip_addr, (1024, 65535)).unwrap(); let gossip_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), gossip_port); @@ -2845,11 +2844,8 @@ impl Node { Self::get_gossip_port(gossip_addr, port_range, bind_ip_addr); let (tvu_port, tvu) = Self::bind(bind_ip_addr, port_range); let (tvu_forwards_port, tvu_forwards) = Self::bind(bind_ip_addr, port_range); - let (tpu_port, tpu) = Self::bind(bind_ip_addr, port_range); - let (_tpu_port_quic, tpu_quic) = Self::bind( - bind_ip_addr, - (tpu_port + QUIC_PORT_OFFSET, tpu_port + QUIC_PORT_OFFSET + 1), - ); + let ((tpu_port, tpu), (_tpu_quic_port, tpu_quic)) = + bind_two_consecutive_in_range(bind_ip_addr, port_range).unwrap(); let (tpu_forwards_port, tpu_forwards) = Self::bind(bind_ip_addr, port_range); let (tpu_vote_port, tpu_vote) = Self::bind(bind_ip_addr, port_range); let (_, retransmit_socket) = Self::bind(bind_ip_addr, port_range); diff --git a/net-utils/src/lib.rs b/net-utils/src/lib.rs index b63ab8534..9bd5839c2 100644 --- a/net-utils/src/lib.rs +++ b/net-utils/src/lib.rs @@ -504,6 +504,34 @@ pub fn bind_common( .and_then(|_| TcpListener::bind(&addr).map(|listener| (sock.into(), listener))) } +pub fn bind_two_consecutive_in_range( + ip_addr: IpAddr, + range: PortRange, +) -> io::Result<((u16, UdpSocket), (u16, UdpSocket))> { + let mut first: Option = None; + for port in range.0..range.1 { + if let Ok(bind) = bind_to(ip_addr, port, false) { + match first { + Some(first_bind) => { + return Ok(( + (first_bind.local_addr().unwrap().port(), first_bind), + (bind.local_addr().unwrap().port(), bind), + )); + } + None => { + first = Some(bind); + } + } + } else { + first = None; + } + } + Err(io::Error::new( + io::ErrorKind::Other, + "couldn't find two consecutive ports in range".to_string(), + )) +} + pub fn find_available_port_in_range(ip_addr: IpAddr, range: PortRange) -> io::Result { let (start, end) = range; let mut tries_left = end - start;