diff --git a/gossip/src/cluster_info.rs b/gossip/src/cluster_info.rs index 4994a82309447e..c0a8712f783ba8 100644 --- a/gossip/src/cluster_info.rs +++ b/gossip/src/cluster_info.rs @@ -48,7 +48,7 @@ use { solana_ledger::shred::Shred, solana_measure::measure::Measure, solana_net_utils::{ - bind_common, bind_common_in_range, bind_in_range, bind_two_consecutive_in_range, + bind_common, bind_common_in_range, bind_in_range, bind_two_in_range_with_offset, find_available_port_in_range, multi_bind_in_range, PortRange, }, solana_perf::{ @@ -2746,20 +2746,21 @@ impl Node { } pub fn new_localhost_with_pubkey(pubkey: &Pubkey) -> Self { let bind_ip_addr = IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)); + let port_range = (1024, 65535); let ((_tpu_port, tpu), (_tpu_quic_port, tpu_quic)) = - bind_two_consecutive_in_range(bind_ip_addr, (1024, 65535)).unwrap(); + bind_two_in_range_with_offset(bind_ip_addr, port_range, QUIC_PORT_OFFSET).unwrap(); let (gossip_port, (gossip, ip_echo)) = - bind_common_in_range(bind_ip_addr, (1024, 65535)).unwrap(); + bind_common_in_range(bind_ip_addr, port_range).unwrap(); let gossip_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), gossip_port); let tvu = UdpSocket::bind("127.0.0.1:0").unwrap(); let tvu_forwards = UdpSocket::bind("127.0.0.1:0").unwrap(); let ((_tpu_forwards_port, tpu_forwards), (_tpu_forwards_quic_port, tpu_forwards_quic)) = - bind_two_consecutive_in_range(bind_ip_addr, (1024, 65535)).unwrap(); + bind_two_in_range_with_offset(bind_ip_addr, port_range, QUIC_PORT_OFFSET).unwrap(); let tpu_vote = UdpSocket::bind("127.0.0.1:0").unwrap(); let repair = UdpSocket::bind("127.0.0.1:0").unwrap(); - let rpc_port = find_available_port_in_range(bind_ip_addr, (1024, 65535)).unwrap(); + let rpc_port = find_available_port_in_range(bind_ip_addr, port_range).unwrap(); let rpc_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), rpc_port); - let rpc_pubsub_port = find_available_port_in_range(bind_ip_addr, (1024, 65535)).unwrap(); + let rpc_pubsub_port = find_available_port_in_range(bind_ip_addr, port_range).unwrap(); let rpc_pubsub_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), rpc_pubsub_port); @@ -2835,9 +2836,9 @@ impl Node { 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), (_tpu_quic_port, tpu_quic)) = - bind_two_consecutive_in_range(bind_ip_addr, port_range).unwrap(); + bind_two_in_range_with_offset(bind_ip_addr, port_range, QUIC_PORT_OFFSET).unwrap(); let ((tpu_forwards_port, tpu_forwards), (_tpu_forwards_quic_port, tpu_forwards_quic)) = - bind_two_consecutive_in_range(bind_ip_addr, port_range).unwrap(); + bind_two_in_range_with_offset(bind_ip_addr, port_range, QUIC_PORT_OFFSET).unwrap(); let (tpu_vote_port, tpu_vote) = Self::bind(bind_ip_addr, port_range); let (_, retransmit_socket) = Self::bind(bind_ip_addr, port_range); let (repair_port, repair) = Self::bind(bind_ip_addr, port_range); diff --git a/net-utils/src/lib.rs b/net-utils/src/lib.rs index 9f60bb9b5749b2..ecee6d98f6f582 100644 --- a/net-utils/src/lib.rs +++ b/net-utils/src/lib.rs @@ -519,31 +519,34 @@ pub fn bind_common( .and_then(|_| TcpListener::bind(&addr).map(|listener| (sock.into(), listener))) } -pub fn bind_two_consecutive_in_range( +pub fn bind_two_in_range_with_offset( ip_addr: IpAddr, range: PortRange, + offset: u16, ) -> io::Result<((u16, UdpSocket), (u16, UdpSocket))> { - let mut first: Option = None; + if range.1.saturating_sub(range.0) < offset { + return Err(io::Error::new( + io::ErrorKind::Other, + "range too small to find two ports with the correct offset".to_string(), + )); + } for port in range.0..range.1 { - if let Ok(bind) = bind_to(ip_addr, port, false) { - match first { - Some(first_bind) => { + if let Ok(first_bind) = bind_to(ip_addr, port, false) { + if range.1.saturating_sub(port) >= offset { + if let Ok(second_bind) = bind_to(ip_addr, port + offset, false) { return Ok(( (first_bind.local_addr().unwrap().port(), first_bind), - (bind.local_addr().unwrap().port(), bind), + (second_bind.local_addr().unwrap().port(), second_bind), )); } - None => { - first = Some(bind); - } + } else { + break; } - } else { - first = None; } } Err(io::Error::new( io::ErrorKind::Other, - "couldn't find two consecutive ports in range".to_string(), + "couldn't find two ports with the correct offset in range".to_string(), )) } @@ -818,12 +821,21 @@ mod tests { } #[test] - fn test_bind_two_consecutive_in_range() { + fn test_bind_two_in_range_with_offset() { solana_logger::setup(); let ip_addr = IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)); - if let Ok(((port1, _), (port2, _))) = bind_two_consecutive_in_range(ip_addr, (1024, 65535)) + let offset = 6; + if let Ok(((port1, _), (port2, _))) = + bind_two_in_range_with_offset(ip_addr, (1024, 65535), offset) + { + assert!(port2 == port1 + offset); + } + let offset = 42; + if let Ok(((port1, _), (port2, _))) = + bind_two_in_range_with_offset(ip_addr, (1024, 65535), offset) { - assert!(port2 == port1 + 1); + assert!(port2 == port1 + offset); } + assert!(bind_two_in_range_with_offset(ip_addr, (1024, 1044), offset).is_err()); } }