diff --git a/client-test/tests/client.rs b/client-test/tests/client.rs index 8d8e938abc8..d58219fed6c 100644 --- a/client-test/tests/client.rs +++ b/client-test/tests/client.rs @@ -6,6 +6,7 @@ use { solana_keypair::Keypair, solana_ledger::{blockstore::Blockstore, get_tmp_ledger_path_auto_delete}, solana_native_token::sol_to_lamports, + solana_net_utils::sockets::localhost_port_single_for_tests, solana_pubkey::Pubkey, solana_pubsub_client::{nonblocking, pubsub_client::PubsubClient}, solana_rpc::{ @@ -51,8 +52,10 @@ use { }; fn pubsub_addr() -> SocketAddr { - let port_range = solana_net_utils::sockets::localhost_port_range_for_tests(); - SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), port_range.0) + SocketAddr::new( + IpAddr::V4(Ipv4Addr::LOCALHOST), + localhost_port_single_for_tests(), + ) } #[test] diff --git a/client/src/connection_cache.rs b/client/src/connection_cache.rs index 28ae2157266..7bdff6135c3 100644 --- a/client/src/connection_cache.rs +++ b/client/src/connection_cache.rs @@ -205,10 +205,8 @@ mod tests { #[test] fn test_connection_with_specified_client_endpoint() { - let port_range = localhost_port_range_for_tests(); - let mut port_range = port_range.0..port_range.1; - let client_socket = - bind_to(IpAddr::V4(Ipv4Addr::LOCALHOST), port_range.next().unwrap()).unwrap(); + let mut pr = localhost_port_range_for_tests(); + let client_socket = bind_to(IpAddr::V4(Ipv4Addr::LOCALHOST), pr.next().unwrap()).unwrap(); let connection_cache = ConnectionCache::new_with_client_options( "connection_cache_test", 1, // connection_pool_size @@ -218,13 +216,13 @@ mod tests { ); // server port 1: - let port1 = port_range.next().unwrap(); + let port1 = pr.next().unwrap(); let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), port1); let conn = connection_cache.get_connection(&addr); assert_eq!(conn.server_addr().port(), port1); // server port 2: - let port2 = port_range.next().unwrap(); + let port2 = pr.next().unwrap(); let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), port2); let conn = connection_cache.get_connection(&addr); assert_eq!(conn.server_addr().port(), port2); diff --git a/core/src/repair/ancestor_hashes_service.rs b/core/src/repair/ancestor_hashes_service.rs index 7b86e421289..20093b2c64f 100644 --- a/core/src/repair/ancestor_hashes_service.rs +++ b/core/src/repair/ancestor_hashes_service.rs @@ -923,7 +923,7 @@ mod test { blockstore::make_many_slot_entries, get_tmp_ledger_path, get_tmp_ledger_path_auto_delete, shred::Nonce, }, - solana_net_utils::bind_to_unspecified, + solana_net_utils::sockets::bind_to_localhost_unique, solana_perf::packet::Packet, solana_runtime::bank_forks::BankForks, solana_signer::Signer, @@ -1357,7 +1357,8 @@ mod test { impl ManageAncestorHashesState { fn new(bank_forks: Arc>) -> Self { let ancestor_hashes_request_statuses = Arc::new(DashMap::new()); - let ancestor_hashes_request_socket = Arc::new(bind_to_unspecified().unwrap()); + let ancestor_hashes_request_socket = + Arc::new(bind_to_localhost_unique().expect("should bind")); let epoch_schedule = bank_forks .read() .unwrap() diff --git a/core/src/repair/quic_endpoint.rs b/core/src/repair/quic_endpoint.rs index d128cd8b0af..1920e35eab9 100644 --- a/core/src/repair/quic_endpoint.rs +++ b/core/src/repair/quic_endpoint.rs @@ -1038,9 +1038,8 @@ mod tests { .build() .unwrap(); let keypairs: Vec = repeat_with(Keypair::new).take(NUM_ENDPOINTS).collect(); - let port_range = localhost_port_range_for_tests(); let ip_addr = IpAddr::V4(Ipv4Addr::LOCALHOST); - let sockets: Vec = (port_range.0..port_range.1) + let sockets: Vec = localhost_port_range_for_tests() .map(|port| bind_to(ip_addr, port).unwrap()) .take(NUM_ENDPOINTS) .collect(); diff --git a/core/src/repair/repair_service.rs b/core/src/repair/repair_service.rs index 420afa8e943..fefa3aacb00 100644 --- a/core/src/repair/repair_service.rs +++ b/core/src/repair/repair_service.rs @@ -1276,18 +1276,12 @@ mod test { get_tmp_ledger_path_auto_delete, shred::max_ticks_per_n_shreds, }, - solana_net_utils::{ - bind_to_unspecified, - sockets::{bind_to, localhost_port_range_for_tests}, - }, + solana_net_utils::sockets::bind_to_localhost_unique, solana_runtime::bank::Bank, solana_signer::Signer, solana_streamer::socket::SocketAddrSpace, solana_time_utils::timestamp, - std::{ - collections::HashSet, - net::{IpAddr, Ipv4Addr}, - }, + std::collections::HashSet, }; fn new_test_cluster_info() -> ClusterInfo { @@ -1303,10 +1297,9 @@ mod test { let pubkey = cluster_info.id(); let slot = 100; let shred_index = 50; - let port_range = localhost_port_range_for_tests(); - let reader = bind_to(IpAddr::V4(Ipv4Addr::LOCALHOST), port_range.0).expect("should bind"); + let reader = bind_to_localhost_unique().expect("should bind"); let address = reader.local_addr().unwrap(); - let sender = bind_to(IpAddr::V4(Ipv4Addr::LOCALHOST), port_range.1).expect("should bind"); + let sender = bind_to_localhost_unique().expect("should bind"); let outstanding_repair_requests = Arc::new(RwLock::new(OutstandingShredRepairs::default())); // Send a repair request @@ -1662,7 +1655,7 @@ mod test { }; let mut duplicate_slot_repair_statuses = HashMap::new(); let dead_slot = 9; - let receive_socket = &bind_to_unspecified().unwrap(); + let receive_socket = &bind_to_localhost_unique().expect("should bind"); let duplicate_status = DuplicateSlotRepairStatus { correct_ancestor_to_repair: (dead_slot, Hash::default()), start_ts: u64::MAX, @@ -1691,7 +1684,7 @@ mod test { &blockstore, &serve_repair, &mut RepairStats::default(), - &bind_to_unspecified().unwrap(), + &bind_to_localhost_unique().expect("should bind"), &None, &RwLock::new(OutstandingRequests::default()), &identity_keypair, @@ -1717,7 +1710,7 @@ mod test { &blockstore, &serve_repair, &mut RepairStats::default(), - &bind_to_unspecified().unwrap(), + &bind_to_localhost_unique().expect("should bind"), &None, &RwLock::new(OutstandingRequests::default()), &identity_keypair, @@ -1736,7 +1729,7 @@ mod test { &blockstore, &serve_repair, &mut RepairStats::default(), - &bind_to_unspecified().unwrap(), + &bind_to_localhost_unique().expect("should bind"), &None, &RwLock::new(OutstandingRequests::default()), &identity_keypair, @@ -1751,7 +1744,10 @@ mod test { let bank_forks = BankForks::new_rw_arc(bank); let dummy_addr = Some(( Pubkey::default(), - bind_to_unspecified().unwrap().local_addr().unwrap(), + bind_to_localhost_unique() + .expect("should bind") + .local_addr() + .unwrap(), )); let cluster_info = Arc::new(new_test_cluster_info()); let ledger_path = get_tmp_ledger_path_auto_delete!(); diff --git a/gossip/src/cluster_info.rs b/gossip/src/cluster_info.rs index cd6e61ce0b0..8b9b2a9b8ff 100644 --- a/gossip/src/cluster_info.rs +++ b/gossip/src/cluster_info.rs @@ -59,7 +59,7 @@ use { localhost_port_range_for_tests, multi_bind_in_range_with_config, SocketConfiguration as SocketConfig, }, - PortRange, VALIDATOR_PORT_RANGE, + PortRange, RangeExt, VALIDATOR_PORT_RANGE, }, solana_perf::{ data_budget::DataBudget, @@ -2440,8 +2440,8 @@ impl Node { bind_ip_addrs: BindIpAddrs { addrs: vec![bind_ip_addr], }, - gossip_port: port_range.0, - port_range, + gossip_port: port_range.start, + port_range: port_range.as_tuple(), advertised_ip: bind_ip_addr, public_tpu_addr: None, public_tpu_forwards_addr: None, @@ -2452,7 +2452,8 @@ impl Node { vortexor_receiver_addr: None, }; let mut node = Self::new_with_external_ip(pubkey, config); - let rpc_ports: [u16; 2] = find_available_ports_in_range(bind_ip_addr, port_range).unwrap(); + let rpc_ports: [u16; 2] = + find_available_ports_in_range(bind_ip_addr, port_range.as_tuple()).unwrap(); let rpc_addr = SocketAddr::new(bind_ip_addr, rpc_ports[0]); let rpc_pubsub_addr = SocketAddr::new(bind_ip_addr, rpc_ports[1]); node.info.set_rpc(rpc_addr).unwrap(); @@ -3142,7 +3143,7 @@ mod tests { let config = NodeConfig { advertised_ip: IpAddr::V4(ip), gossip_port: 0, - port_range, + port_range: port_range.as_tuple(), bind_ip_addrs: BindIpAddrs::new(vec![IpAddr::V4(ip)]).unwrap(), public_tpu_addr: None, public_tpu_forwards_addr: None, @@ -3154,7 +3155,7 @@ mod tests { let node = Node::new_with_external_ip(&solana_pubkey::new_rand(), config); - check_node_sockets(&node, IpAddr::V4(ip), port_range); + check_node_sockets(&node, IpAddr::V4(ip), port_range.as_tuple()); } #[test] @@ -3163,11 +3164,11 @@ mod tests { // port returned by `bind_in_range()` might be snatched up before `Node::new_with_external_ip()` runs let port_range = localhost_port_range_for_tests(); let ip = IpAddr::V4(Ipv4Addr::LOCALHOST); - let port = port_range.0; + let port = port_range.start; let config = NodeConfig { advertised_ip: ip, gossip_port: port, - port_range, + port_range: port_range.as_tuple(), bind_ip_addrs: BindIpAddrs::new(vec![ip]).unwrap(), public_tpu_addr: None, public_tpu_forwards_addr: None, @@ -3179,7 +3180,7 @@ mod tests { let node = Node::new_with_external_ip(&solana_pubkey::new_rand(), config); - check_node_sockets(&node, ip, port_range); + check_node_sockets(&node, ip, port_range.as_tuple()); assert_eq!(node.sockets.gossip.local_addr().unwrap().port(), port); } diff --git a/net-utils/src/lib.rs b/net-utils/src/lib.rs index 5b5eb70c53e..36fb0f5d16d 100644 --- a/net-utils/src/lib.rs +++ b/net-utils/src/lib.rs @@ -31,10 +31,22 @@ use { std::{ io::{self}, net::{IpAddr, Ipv4Addr, SocketAddr, TcpListener, ToSocketAddrs, UdpSocket}, + ops::Range, }, url::Url, }; +/// Helper for code that still expects port ranges as `(u16, u16)` +pub trait RangeExt { + fn as_tuple(&self) -> (u16, u16); +} + +impl RangeExt for Range { + fn as_tuple(&self) -> (u16, u16) { + (self.start, self.end) + } +} + /// A data type representing a public Udp socket pub struct UdpSocketPair { pub addr: SocketAddr, // Public address of the socket @@ -604,6 +616,7 @@ mod tests { super::*, ip_echo_server::IpEchoServerResponse, itertools::Itertools, + sockets::localhost_port_range_for_tests, std::{net::Ipv4Addr, time::Duration}, tokio::runtime::Runtime, }; @@ -710,23 +723,26 @@ mod tests { #[test] fn test_bind() { - let (pr_s, pr_e) = sockets::localhost_port_range_for_tests(); - let ip_addr = IpAddr::V4(Ipv4Addr::UNSPECIFIED); - let s = bind_in_range(ip_addr, (pr_s, pr_e)).unwrap(); - assert_eq!(s.0, pr_s, "bind_in_range should use first available port"); - let ip_addr = IpAddr::V4(Ipv4Addr::UNSPECIFIED); + let pr = sockets::localhost_port_range_for_tests(); + let ip_addr = IpAddr::V4(Ipv4Addr::LOCALHOST); + let s = bind_in_range(ip_addr, pr.as_tuple()).unwrap(); + assert_eq!( + s.0, pr.start, + "bind_in_range should use first available port" + ); + let ip_addr = IpAddr::V4(Ipv4Addr::LOCALHOST); let config = SocketConfig::default().reuseport(true); - let x = bind_to_with_config(ip_addr, pr_s + 1, config).unwrap(); - let y = bind_to_with_config(ip_addr, pr_s + 1, config).unwrap(); + let x = bind_to_with_config(ip_addr, pr.start + 1, config).unwrap(); + let y = bind_to_with_config(ip_addr, pr.start + 1, config).unwrap(); assert_eq!( x.local_addr().unwrap().port(), y.local_addr().unwrap().port() ); - bind_to(ip_addr, pr_s, false).unwrap_err(); - bind_in_range(ip_addr, (pr_s, pr_s + 2)).unwrap_err(); + bind_to(ip_addr, pr.start, false).unwrap_err(); + bind_in_range(ip_addr, (pr.start, pr.start + 2)).unwrap_err(); let (port, v) = - multi_bind_in_range_with_config(ip_addr, (pr_s + 5, pr_e), config, 10).unwrap(); + multi_bind_in_range_with_config(ip_addr, (pr.start + 5, pr.end), config, 10).unwrap(); for sock in &v { assert_eq!(port, sock.local_addr().unwrap().port()); } @@ -734,7 +750,7 @@ mod tests { #[test] fn test_bind_with_any_port() { - let ip_addr = IpAddr::V4(Ipv4Addr::UNSPECIFIED); + let ip_addr = IpAddr::V4(Ipv4Addr::LOCALHOST); let config = SocketConfig::default(); let x = bind_with_any_port_with_config(ip_addr, config).unwrap(); let y = bind_with_any_port_with_config(ip_addr, config).unwrap(); @@ -746,7 +762,7 @@ mod tests { #[test] fn test_bind_in_range_nil() { - let ip_addr = IpAddr::V4(Ipv4Addr::UNSPECIFIED); + let ip_addr = IpAddr::V4(Ipv4Addr::LOCALHOST); bind_in_range(ip_addr, (2000, 2000)).unwrap_err(); bind_in_range(ip_addr, (2000, 1999)).unwrap_err(); } @@ -754,13 +770,13 @@ mod tests { #[test] fn test_find_available_port_in_range() { let ip_addr = IpAddr::V4(Ipv4Addr::LOCALHOST); - let (pr_s, pr_e) = sockets::localhost_port_range_for_tests(); + let pr = sockets::localhost_port_range_for_tests(); assert_eq!( - find_available_port_in_range(ip_addr, (pr_s, pr_s + 1)).unwrap(), - pr_s + find_available_port_in_range(ip_addr, (pr.start, pr.start + 1)).unwrap(), + pr.start ); - let port = find_available_port_in_range(ip_addr, (pr_s, pr_e)).unwrap(); - assert!((pr_s..pr_e).contains(&port)); + let port = find_available_port_in_range(ip_addr, pr.as_tuple()).unwrap(); + assert!(pr.contains(&port)); let _socket = bind_to(ip_addr, port, false).unwrap(); find_available_port_in_range(ip_addr, (port, port + 1)).unwrap_err(); @@ -769,11 +785,11 @@ mod tests { #[test] fn test_find_available_ports_in_range() { let ip_addr = IpAddr::V4(Ipv4Addr::LOCALHOST); - let port_range = sockets::localhost_port_range_for_tests(); - assert!(port_range.1 - port_range.0 > 16); + let pr = sockets::localhost_port_range_for_tests(); + assert!(pr.end - pr.start > 16); // reserve 1 port to make it non-trivial - let sock = bind_to_with_config(ip_addr, port_range.0 + 2, SocketConfig::default()).unwrap(); - let ports: [u16; 15] = find_available_ports_in_range(ip_addr, port_range).unwrap(); + let sock = bind_to_with_config(ip_addr, pr.start + 2, SocketConfig::default()).unwrap(); + let ports: [u16; 15] = find_available_ports_in_range(ip_addr, pr.as_tuple()).unwrap(); let mut ports_vec = Vec::from(ports); ports_vec.push(sock.local_addr().unwrap().port()); let res: Vec<_> = ports_vec.into_iter().unique().collect(); @@ -783,11 +799,11 @@ mod tests { #[test] fn test_bind_common_in_range() { let ip_addr = IpAddr::V4(Ipv4Addr::LOCALHOST); - let (pr_s, pr_e) = sockets::localhost_port_range_for_tests(); + let pr = sockets::localhost_port_range_for_tests(); let config = SocketConfig::default(); let (port, _sockets) = - bind_common_in_range_with_config(ip_addr, (pr_s, pr_e), config).unwrap(); - assert!((pr_s..pr_e).contains(&port)); + bind_common_in_range_with_config(ip_addr, pr.as_tuple(), config).unwrap(); + assert!(pr.contains(&port)); bind_common_in_range_with_config(ip_addr, (port, port + 1), config).unwrap_err(); } @@ -796,10 +812,14 @@ mod tests { fn test_get_public_ip_addr_none() { solana_logger::setup(); let ip_addr = IpAddr::V4(Ipv4Addr::LOCALHOST); - let (pr_s, pr_e) = sockets::localhost_port_range_for_tests(); let config = SocketConfig::default(); let (_server_port, (server_udp_socket, server_tcp_listener)) = - bind_common_in_range_with_config(ip_addr, (pr_s, pr_e), config).unwrap(); + bind_common_in_range_with_config( + ip_addr, + localhost_port_range_for_tests().as_tuple(), + config, + ) + .expect("should bind"); let _runtime = ip_echo_server( server_tcp_listener, @@ -809,11 +829,8 @@ mod tests { let server_ip_echo_addr = server_udp_socket.local_addr().unwrap(); assert_eq!( - get_public_ip_addr_with_binding( - &server_ip_echo_addr, - IpAddr::V4(Ipv4Addr::UNSPECIFIED) - ) - .unwrap(), + get_public_ip_addr_with_binding(&server_ip_echo_addr, IpAddr::V4(Ipv4Addr::LOCALHOST)) + .unwrap(), parse_host("127.0.0.1").unwrap(), ); assert_eq!(get_cluster_shred_version(&server_ip_echo_addr).unwrap(), 42); @@ -825,12 +842,12 @@ mod tests { fn test_get_public_ip_addr_reachable() { solana_logger::setup(); let ip_addr = IpAddr::V4(Ipv4Addr::LOCALHOST); - let port_range = sockets::localhost_port_range_for_tests(); + let pr = sockets::localhost_port_range_for_tests().as_tuple(); let config = SocketConfig::default(); let (_server_port, (server_udp_socket, server_tcp_listener)) = - bind_common_in_range_with_config(ip_addr, port_range, config).unwrap(); + bind_common_in_range_with_config(ip_addr, pr, config).unwrap(); let (_client_port, (client_udp_socket, client_tcp_listener)) = - bind_common_in_range_with_config(ip_addr, port_range, config).unwrap(); + bind_common_in_range_with_config(ip_addr, pr, config).unwrap(); let _runtime = ip_echo_server( server_tcp_listener, @@ -865,16 +882,16 @@ mod tests { fn test_verify_ports_tcp_unreachable() { solana_logger::setup(); let ip_addr = IpAddr::V4(Ipv4Addr::LOCALHOST); - let port_range = sockets::localhost_port_range_for_tests(); + let pr = sockets::localhost_port_range_for_tests().as_tuple(); let config = SocketConfig::default(); let (_server_port, (server_udp_socket, _server_tcp_listener)) = - bind_common_in_range_with_config(ip_addr, port_range, config).unwrap(); + bind_common_in_range_with_config(ip_addr, pr, config).unwrap(); // make the socket unreachable by not running the ip echo server! let server_ip_echo_addr = server_udp_socket.local_addr().unwrap(); let (_, (_client_udp_socket, client_tcp_listener)) = - bind_common_in_range_with_config(ip_addr, port_range, config).unwrap(); + bind_common_in_range_with_config(ip_addr, pr, config).unwrap(); let rt = runtime(); assert!(!rt.block_on(ip_echo_client::verify_all_reachable_tcp( @@ -888,16 +905,16 @@ mod tests { fn test_verify_ports_udp_unreachable() { solana_logger::setup(); let ip_addr = IpAddr::V4(Ipv4Addr::LOCALHOST); - let port_range = sockets::localhost_port_range_for_tests(); + let pr = sockets::localhost_port_range_for_tests().as_tuple(); let config = SocketConfig::default(); let (_server_port, (server_udp_socket, _server_tcp_listener)) = - bind_common_in_range_with_config(ip_addr, port_range, config).unwrap(); + bind_common_in_range_with_config(ip_addr, pr, config).unwrap(); // make the socket unreachable by not running the ip echo server! let server_ip_echo_addr = server_udp_socket.local_addr().unwrap(); let (_correct_client_port, (client_udp_socket, _client_tcp_listener)) = - bind_common_in_range_with_config(ip_addr, port_range, config).unwrap(); + bind_common_in_range_with_config(ip_addr, pr, config).unwrap(); let rt = runtime(); assert!(!rt.block_on(ip_echo_client::verify_all_reachable_udp( @@ -939,11 +956,8 @@ mod tests { ); assert_eq!( - get_public_ip_addr_with_binding( - &ip_echo_server_addr, - IpAddr::V4(Ipv4Addr::UNSPECIFIED) - ) - .unwrap(), + get_public_ip_addr_with_binding(&ip_echo_server_addr, IpAddr::V4(Ipv4Addr::LOCALHOST)) + .unwrap(), parse_host("127.0.0.1").unwrap(), ); @@ -958,7 +972,7 @@ mod tests { #[test] fn test_bind_two_in_range_with_offset() { solana_logger::setup(); - let ip_addr = IpAddr::V4(Ipv4Addr::UNSPECIFIED); + let ip_addr = IpAddr::V4(Ipv4Addr::LOCALHOST); let offset = 6; if let Ok(((port1, _), (port2, _))) = bind_two_in_range_with_offset(ip_addr, (1024, 65535), offset) @@ -994,9 +1008,12 @@ mod tests { let ip_a = IpAddr::V4(Ipv4Addr::LOCALHOST); let ip_b = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)); - let server_ports = sockets::localhost_port_range_for_tests(); - let (_srv_udp_port, (srv_udp_sock, srv_tcp_listener)) = - bind_common_in_range_with_config(ip_a, server_ports, config).unwrap(); + let (_srv_udp_port, (srv_udp_sock, srv_tcp_listener)) = bind_common_in_range_with_config( + ip_a, + localhost_port_range_for_tests().as_tuple(), + config, + ) + .expect("should bind"); let ip_echo_server_addr = srv_udp_sock.local_addr().unwrap(); let _runtime = ip_echo_server( @@ -1008,13 +1025,13 @@ mod tests { let mut udp_sockets = Vec::new(); let (_p1, (sock_a, _tl_a)) = bind_common_in_range_with_config( ip_a, - sockets::localhost_port_range_for_tests(), + localhost_port_range_for_tests().as_tuple(), config, ) .unwrap(); let (_p2, (sock_b, _tl_b)) = bind_common_in_range_with_config( ip_b, - sockets::localhost_port_range_for_tests(), + localhost_port_range_for_tests().as_tuple(), config, ) .unwrap(); diff --git a/net-utils/src/sockets.rs b/net-utils/src/sockets.rs index 20017a6f38a..594a321b2e7 100644 --- a/net-utils/src/sockets.rs +++ b/net-utils/src/sockets.rs @@ -1,22 +1,22 @@ +#[cfg(feature = "dev-context-only-utils")] +use tokio::net::UdpSocket as TokioUdpSocket; use { crate::PortRange, log::warn, socket2::{Domain, SockAddr, Socket, Type}, std::{ io, - net::{IpAddr, SocketAddr, TcpListener, UdpSocket}, + net::{IpAddr, Ipv4Addr, SocketAddr, TcpListener, UdpSocket}, + ops::Range, sync::atomic::{AtomicU16, Ordering}, }, }; -#[cfg(feature = "dev-context-only-utils")] -use {std::net::Ipv4Addr, tokio::net::UdpSocket as TokioUdpSocket}; + // base port for deconflicted allocations const BASE_PORT: u16 = 5000; // how much to allocate per individual process. // we expect to have at most 64 concurrent tests in CI at any moment on a given host. const SLICE_PER_PROCESS: u16 = (u16::MAX - BASE_PORT) / 64; -/// Retrieve a free 20-port slice for unit tests -/// /// When running under nextest, this will try to provide /// a unique slice of port numbers (assuming no other nextest processes /// are running on the same host) based on NEXTEST_TEST_GLOBAL_SLOT variable @@ -25,9 +25,9 @@ const SLICE_PER_PROCESS: u16 = (u16::MAX - BASE_PORT) / 64; /// When running without nextest, this will only bump an atomic and eventually /// panic when it runs out of port numbers to assign. #[allow(clippy::arithmetic_side_effects)] -pub fn localhost_port_range_for_tests() -> (u16, u16) { +pub fn unique_port_range_for_tests(size: u16) -> Range { static SLICE: AtomicU16 = AtomicU16::new(0); - let offset = SLICE.fetch_add(20, Ordering::Relaxed); + let offset = SLICE.fetch_add(size, Ordering::Relaxed); let start = offset + match std::env::var("NEXTEST_TEST_GLOBAL_SLOT") { Ok(slot) => { @@ -40,8 +40,42 @@ pub fn localhost_port_range_for_tests() -> (u16, u16) { } Err(_) => BASE_PORT, }; - assert!(start < u16::MAX - 20, "ran out of port numbers!"); - (start, start + 20) + assert!(start < u16::MAX - size, "Ran out of port numbers!"); + start..start + size +} + +/// Retrieve a free 20-port slice for unit tests +/// +/// When running under nextest, this will try to provide +/// a unique slice of port numbers (assuming no other nextest processes +/// are running on the same host) based on NEXTEST_TEST_GLOBAL_SLOT variable +/// The port ranges will be reused following nextest logic. +/// +/// When running without nextest, this will only bump an atomic and eventually +/// panic when it runs out of port numbers to assign. +pub fn localhost_port_range_for_tests() -> Range { + unique_port_range_for_tests(20) +} + +/// Retrieve a free single port for unit tests +/// +/// When running under nextest, this will try to provide +/// a unique port number (assuming no other nextest processes +/// are running on the same host) based on NEXTEST_TEST_GLOBAL_SLOT variable +/// The port will be reused following nextest logic. +/// +/// When running without nextest, this will only bump an atomic and eventually +/// panic when it runs out of port numbers to assign. +pub fn localhost_port_single_for_tests() -> u16 { + unique_port_range_for_tests(1).start +} + +/// Bind a `UdpSocket` to a unique port. +pub fn bind_to_localhost_unique() -> io::Result { + bind_to( + IpAddr::V4(Ipv4Addr::LOCALHOST), + localhost_port_single_for_tests(), + ) } pub fn bind_gossip_port_in_range( @@ -246,7 +280,11 @@ pub async fn bind_to_async(ip_addr: IpAddr, port: u16) -> io::Result io::Result { - bind_to_async(IpAddr::V4(Ipv4Addr::LOCALHOST), 0).await + bind_to_async( + IpAddr::V4(Ipv4Addr::LOCALHOST), + localhost_port_range_for_tests().start, + ) + .await } #[cfg(feature = "dev-context-only-utils")] @@ -342,29 +380,32 @@ pub fn bind_more_with_config( mod tests { use { super::*, - crate::{bind_in_range, sockets::localhost_port_range_for_tests}, + crate::{bind_in_range, sockets::localhost_port_range_for_tests, RangeExt}, std::net::Ipv4Addr, }; #[test] fn test_bind() { - let (pr_s, pr_e) = localhost_port_range_for_tests(); - let ip_addr = IpAddr::V4(Ipv4Addr::UNSPECIFIED); + let pr = localhost_port_range_for_tests(); + let ip_addr = IpAddr::V4(Ipv4Addr::LOCALHOST); let config = SocketConfiguration::default(); - let s = bind_in_range(ip_addr, (pr_s, pr_e)).unwrap(); - assert_eq!(s.0, pr_s, "bind_in_range should use first available port"); - let ip_addr = IpAddr::V4(Ipv4Addr::UNSPECIFIED); - let x = bind_to_with_config(ip_addr, pr_s + 1, config).unwrap(); + let s = bind_in_range(ip_addr, pr.as_tuple()).unwrap(); + assert_eq!( + s.0, pr.start, + "bind_in_range should use first available port" + ); + let ip_addr = IpAddr::V4(Ipv4Addr::LOCALHOST); + let x = bind_to_with_config(ip_addr, pr.start + 1, config).unwrap(); let y = bind_more_with_config(x, 2, config).unwrap(); assert_eq!( y[0].local_addr().unwrap().port(), y[1].local_addr().unwrap().port() ); - bind_to_with_config(ip_addr, pr_s, SocketConfiguration::default()).unwrap_err(); - bind_in_range(ip_addr, (pr_s, pr_s + 2)).unwrap_err(); + bind_to_with_config(ip_addr, pr.start, SocketConfiguration::default()).unwrap_err(); + bind_in_range(ip_addr, (pr.start, pr.start + 2)).unwrap_err(); let (port, v) = - multi_bind_in_range_with_config(ip_addr, (pr_s + 5, pr_e), config, 10).unwrap(); + multi_bind_in_range_with_config(ip_addr, (pr.start + 5, pr.end), config, 10).unwrap(); for sock in &v { assert_eq!(port, sock.local_addr().unwrap().port()); } @@ -372,7 +413,7 @@ mod tests { #[test] fn test_bind_with_any_port() { - let ip_addr = IpAddr::V4(Ipv4Addr::UNSPECIFIED); + let ip_addr = IpAddr::V4(Ipv4Addr::LOCALHOST); let config = SocketConfiguration::default(); let x = bind_with_any_port_with_config(ip_addr, config).unwrap(); let y = bind_with_any_port_with_config(ip_addr, config).unwrap(); @@ -384,7 +425,7 @@ mod tests { #[test] fn test_bind_in_range_nil() { - let ip_addr = IpAddr::V4(Ipv4Addr::UNSPECIFIED); + let ip_addr = IpAddr::V4(Ipv4Addr::LOCALHOST); bind_in_range(ip_addr, (2000, 2000)).unwrap_err(); bind_in_range(ip_addr, (2000, 1999)).unwrap_err(); } @@ -393,21 +434,20 @@ mod tests { fn test_bind_on_top() { let config = SocketConfiguration::default(); let localhost = IpAddr::V4(Ipv4Addr::LOCALHOST); - let port_range = localhost_port_range_for_tests(); - let (_p, s) = bind_in_range_with_config(localhost, port_range, config).unwrap(); + let pr = localhost_port_range_for_tests().as_tuple(); + let (_p, s) = bind_in_range_with_config(localhost, pr, config).unwrap(); let _socks = bind_more_with_config(s, 8, config).unwrap(); - - let _socks2 = multi_bind_in_range_with_config(localhost, port_range, config, 8).unwrap(); + let _socks2 = multi_bind_in_range_with_config(localhost, pr, config, 8).unwrap(); } #[test] fn test_bind_common_in_range() { let ip_addr = IpAddr::V4(Ipv4Addr::LOCALHOST); - let (pr_s, pr_e) = localhost_port_range_for_tests(); + let pr = localhost_port_range_for_tests(); let config = SocketConfiguration::default(); let (port, _sockets) = - bind_common_in_range_with_config(ip_addr, (pr_s, pr_e), config).unwrap(); - assert!((pr_s..pr_e).contains(&port)); + bind_common_in_range_with_config(ip_addr, pr.as_tuple(), config).unwrap(); + assert!(pr.contains(&port)); bind_common_in_range_with_config(ip_addr, (port, port + 1), config).unwrap_err(); } @@ -416,7 +456,7 @@ mod tests { fn test_bind_two_in_range_with_offset() { solana_logger::setup(); let config = SocketConfiguration::default(); - let ip_addr = IpAddr::V4(Ipv4Addr::UNSPECIFIED); + let ip_addr = IpAddr::V4(Ipv4Addr::LOCALHOST); let offset = 6; if let Ok(((port1, _), (port2, _))) = bind_two_in_range_with_offset_and_config(ip_addr, (1024, 65535), offset, config, config) diff --git a/quic-client/tests/quic_client.rs b/quic-client/tests/quic_client.rs index d6c8e23eb5c..023c5dcbc2b 100644 --- a/quic-client/tests/quic_client.rs +++ b/quic-client/tests/quic_client.rs @@ -5,7 +5,7 @@ mod tests { log::*, solana_connection_cache::connection_cache_stats::ConnectionCacheStats, solana_keypair::Keypair, - solana_net_utils::sockets::{bind_to, localhost_port_range_for_tests}, + solana_net_utils::sockets::bind_to_localhost_unique, solana_packet::PACKET_DATA_SIZE, solana_perf::packet::PacketBatch, solana_quic_client::nonblocking::quic_client::QuicLazyInitializedEndpoint, @@ -15,7 +15,7 @@ mod tests { }, solana_tls_utils::{new_dummy_x509_certificate, QuicClientCertificate}, std::{ - net::{IpAddr, Ipv4Addr, SocketAddr, UdpSocket}, + net::{SocketAddr, UdpSocket}, sync::{ atomic::{AtomicBool, Ordering}, Arc, RwLock, @@ -51,9 +51,8 @@ mod tests { } fn server_args() -> (UdpSocket, Arc, Keypair) { - let port_range = localhost_port_range_for_tests(); ( - bind_to(IpAddr::V4(Ipv4Addr::LOCALHOST), port_range.0).expect("should bind"), + bind_to_localhost_unique().expect("should bind"), Arc::new(AtomicBool::new(false)), Keypair::new(), ) diff --git a/rpc-test/tests/rpc.rs b/rpc-test/tests/rpc.rs index 5c02280ce71..061fe0b48f0 100644 --- a/rpc-test/tests/rpc.rs +++ b/rpc-test/tests/rpc.rs @@ -10,7 +10,7 @@ use { solana_commitment_config::CommitmentConfig, solana_hash::Hash, solana_keypair::Keypair, - solana_net_utils::bind_to_unspecified, + solana_net_utils::sockets::bind_to_localhost_unique, solana_pubkey::Pubkey, solana_pubsub_client::nonblocking::pubsub_client::PubsubClient, solana_rent::Rent, @@ -290,7 +290,7 @@ fn test_rpc_subscriptions() { let test_validator = TestValidator::with_no_fees_udp(alice.pubkey(), None, SocketAddrSpace::Unspecified); - let transactions_socket = bind_to_unspecified().unwrap(); + let transactions_socket = bind_to_localhost_unique().expect("should bind"); transactions_socket.connect(test_validator.tpu()).unwrap(); let rpc_client = RpcClient::new(test_validator.rpc_url()); diff --git a/rpc/src/rpc_service.rs b/rpc/src/rpc_service.rs index 36dce48b3b2..22528a99900 100644 --- a/rpc/src/rpc_service.rs +++ b/rpc/src/rpc_service.rs @@ -962,6 +962,9 @@ mod tests { genesis_utils::{create_genesis_config, GenesisConfigInfo}, get_tmp_ledger_path_auto_delete, }, + solana_net_utils::{ + find_available_port_in_range, sockets::localhost_port_range_for_tests, RangeExt, + }, solana_rpc_client_api::config::RpcContextConfig, solana_runtime::bank::Bank, solana_signer::Signer, @@ -983,11 +986,11 @@ mod tests { let validator_exit = create_validator_exit(exit.clone()); let bank = Bank::new_for_tests(&genesis_config); let cluster_info = Arc::new(new_test_cluster_info()); - let ip_addr = IpAddr::V4(Ipv4Addr::UNSPECIFIED); - let port_range = solana_net_utils::sockets::localhost_port_range_for_tests(); + let ip_addr = IpAddr::V4(Ipv4Addr::LOCALHOST); let rpc_addr = SocketAddr::new( ip_addr, - solana_net_utils::find_available_port_in_range(ip_addr, port_range).unwrap(), + find_available_port_in_range(ip_addr, localhost_port_range_for_tests().as_tuple()) + .unwrap(), ); let bank_forks = BankForks::new_rw_arc(bank); let ledger_path = get_tmp_ledger_path_auto_delete!(); diff --git a/send-transaction-service/src/test_utils.rs b/send-transaction-service/src/test_utils.rs index 6b2bc3f9223..5c8985dba36 100644 --- a/send-transaction-service/src/test_utils.rs +++ b/send-transaction-service/src/test_utils.rs @@ -9,11 +9,8 @@ use { }, }, solana_client::connection_cache::ConnectionCache, - solana_net_utils::sockets::{bind_to, localhost_port_range_for_tests}, - std::{ - net::{IpAddr, Ipv4Addr, SocketAddr}, - sync::Arc, - }, + solana_net_utils::sockets::bind_to_localhost_unique, + std::{net::SocketAddr, sync::Arc}, tokio::runtime::Handle, tokio_util::sync::CancellationToken, }; @@ -57,9 +54,8 @@ impl CreateClient for TpuClientNextClient { ) -> Self { let runtime_handle = maybe_runtime.expect("Runtime should be provided for the TpuClientNextClient."); - let port_range = localhost_port_range_for_tests(); - let bind_socket = bind_to(IpAddr::V4(Ipv4Addr::LOCALHOST), port_range.0) - .expect("Should be able to open UdpSocket for tests."); + let bind_socket = + bind_to_localhost_unique().expect("Should be able to open UdpSocket for tests."); Self::new::( runtime_handle, my_tpu_address, diff --git a/streamer/src/nonblocking/sendmmsg.rs b/streamer/src/nonblocking/sendmmsg.rs index 68f43c85d3b..ccefef3682b 100644 --- a/streamer/src/nonblocking/sendmmsg.rs +++ b/streamer/src/nonblocking/sendmmsg.rs @@ -61,7 +61,7 @@ mod tests { sendmmsg::SendPktsError, }, assert_matches::assert_matches, - solana_net_utils::sockets::{bind_to_localhost_async, bind_to_unspecified_async}, + solana_net_utils::sockets::bind_to_localhost_async, solana_packet::PACKET_DATA_SIZE, std::{ io::ErrorKind, @@ -177,7 +177,7 @@ mod tests { ]; let dest_refs: Vec<_> = vec![&ip4, &ip6, &ip4]; - let sender = bind_to_unspecified_async().await.expect("bind"); + let sender = bind_to_localhost_async().await.expect("should bind"); let res = batch_send(&sender, &packet_refs[..]).await; assert_matches!(res, Err(SendPktsError::IoError(_, /*num_failed*/ 1))); let res = multi_target_send(&sender, &packets[0], &dest_refs).await; @@ -189,7 +189,7 @@ mod tests { let packets: Vec<_> = (0..5).map(|_| vec![0u8; PACKET_DATA_SIZE]).collect(); let ipv4local = SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 8080); let ipv4broadcast = SocketAddr::new(IpAddr::V4(Ipv4Addr::BROADCAST), 8080); - let sender = bind_to_unspecified_async().await.expect("bind"); + let sender = bind_to_localhost_async().await.expect("should bind"); // test intermediate failures for batch_send let packet_refs: Vec<_> = vec![ diff --git a/streamer/src/nonblocking/testing_utilities.rs b/streamer/src/nonblocking/testing_utilities.rs index 5db38ecf20d..d295f7ec75f 100644 --- a/streamer/src/nonblocking/testing_utilities.rs +++ b/streamer/src/nonblocking/testing_utilities.rs @@ -17,6 +17,7 @@ use { localhost_port_range_for_tests, multi_bind_in_range_with_config, SocketConfiguration as SocketConfig, }, + RangeExt, }, solana_perf::packet::PacketBatch, solana_quic_definitions::{QUIC_KEEP_ALIVE, QUIC_MAX_TIMEOUT, QUIC_SEND_FAIRNESS}, @@ -65,10 +66,9 @@ pub fn create_quic_server_sockets() -> Vec { } else { 1 }; - let port_range = localhost_port_range_for_tests(); multi_bind_in_range_with_config( IpAddr::V4(Ipv4Addr::LOCALHOST), - port_range, + localhost_port_range_for_tests().as_tuple(), SocketConfig::default(), num, ) diff --git a/streamer/src/recvmmsg.rs b/streamer/src/recvmmsg.rs index 78f0976acf1..7510aeb04e5 100644 --- a/streamer/src/recvmmsg.rs +++ b/streamer/src/recvmmsg.rs @@ -182,9 +182,12 @@ pub fn recv_mmsg(sock: &UdpSocket, packets: &mut [Packet]) -> io::Result io::Result { - let port_range = localhost_port_range_for_tests(); - let reader = bind_in_range_with_config(ip, port_range, SocketConfig::default())?.1; + let pr = localhost_port_range_for_tests().as_tuple(); + let reader = bind_in_range_with_config(ip, pr, SocketConfig::default())?.1; let reader_addr = reader.local_addr()?; - let sender = bind_in_range_with_config(ip, port_range, SocketConfig::default())?.1; + let sender = bind_in_range_with_config(ip, pr, SocketConfig::default())?.1; let sender_addr = sender.local_addr()?; Ok((reader, reader_addr, sender, sender_addr)) } @@ -298,18 +301,18 @@ mod tests { #[test] pub fn test_recv_mmsg_multi_addrs() { let ip = IpAddr::V4(Ipv4Addr::LOCALHOST); - let port_range = localhost_port_range_for_tests(); - let reader = bind_in_range_with_config(ip, port_range, SocketConfig::default()) + let pr = localhost_port_range_for_tests().as_tuple(); + let reader = bind_in_range_with_config(ip, pr, SocketConfig::default()) .unwrap() .1; let reader_addr = reader.local_addr().unwrap(); - let sender1 = bind_in_range_with_config(ip, port_range, SocketConfig::default()) + let sender1 = bind_in_range_with_config(ip, pr, SocketConfig::default()) .unwrap() .1; let sender1_addr = sender1.local_addr().unwrap(); let sent1 = TEST_NUM_MSGS - 1; - let sender2 = bind_in_range_with_config(ip, port_range, SocketConfig::default()) + let sender2 = bind_in_range_with_config(ip, pr, SocketConfig::default()) .unwrap() .1; let sender_addr = sender2.local_addr().unwrap(); diff --git a/streamer/src/sendmmsg.rs b/streamer/src/sendmmsg.rs index 84a9d90ccbb..52522befc43 100644 --- a/streamer/src/sendmmsg.rs +++ b/streamer/src/sendmmsg.rs @@ -247,7 +247,7 @@ mod tests { sendmmsg::{batch_send, multi_target_send, SendPktsError}, }, assert_matches::assert_matches, - solana_net_utils::{bind_to_localhost, bind_to_unspecified}, + solana_net_utils::sockets::bind_to_localhost_unique, solana_packet::PACKET_DATA_SIZE, std::{ io::ErrorKind, @@ -257,9 +257,9 @@ mod tests { #[test] pub fn test_send_mmsg_one_dest() { - let reader = bind_to_localhost().expect("bind"); + let reader = bind_to_localhost_unique().expect("should bind"); let addr = reader.local_addr().unwrap(); - let sender = bind_to_localhost().expect("bind"); + let sender = bind_to_localhost_unique().expect("should bind"); let packets: Vec<_> = (0..32).map(|_| vec![0u8; PACKET_DATA_SIZE]).collect(); let packet_refs: Vec<_> = packets.iter().map(|p| (&p[..], &addr)).collect(); @@ -274,13 +274,13 @@ mod tests { #[test] pub fn test_send_mmsg_multi_dest() { - let reader = bind_to_localhost().expect("bind"); + let reader = bind_to_localhost_unique().expect("should bind"); let addr = reader.local_addr().unwrap(); - let reader2 = bind_to_localhost().expect("bind"); + let reader2 = bind_to_localhost_unique().expect("should bind"); let addr2 = reader2.local_addr().unwrap(); - let sender = bind_to_localhost().expect("bind"); + let sender = bind_to_localhost_unique().expect("should bind"); let packets: Vec<_> = (0..32).map(|_| vec![0u8; PACKET_DATA_SIZE]).collect(); let packet_refs: Vec<_> = packets @@ -309,19 +309,19 @@ mod tests { #[test] pub fn test_multicast_msg() { - let reader = bind_to_localhost().expect("bind"); + let reader = bind_to_localhost_unique().expect("should bind"); let addr = reader.local_addr().unwrap(); - let reader2 = bind_to_localhost().expect("bind"); + let reader2 = bind_to_localhost_unique().expect("should bind"); let addr2 = reader2.local_addr().unwrap(); - let reader3 = bind_to_localhost().expect("bind"); + let reader3 = bind_to_localhost_unique().expect("should bind"); let addr3 = reader3.local_addr().unwrap(); - let reader4 = bind_to_localhost().expect("bind"); + let reader4 = bind_to_localhost_unique().expect("should bind"); let addr4 = reader4.local_addr().unwrap(); - let sender = bind_to_localhost().expect("bind"); + let sender = bind_to_localhost_unique().expect("should bind"); let packet = Packet::default(); @@ -362,7 +362,7 @@ mod tests { ]; let dest_refs: Vec<_> = vec![&ip4, &ip6, &ip4]; - let sender = bind_to_unspecified().expect("bind"); + let sender = bind_to_localhost_unique().expect("should bind"); let res = batch_send(&sender, packet_refs); assert_matches!(res, Err(SendPktsError::IoError(_, /*num_failed*/ 1))); let res = multi_target_send(&sender, &packets[0], &dest_refs); @@ -374,7 +374,7 @@ mod tests { let packets: Vec<_> = (0..5).map(|_| vec![0u8; PACKET_DATA_SIZE]).collect(); let ipv4local = SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 8080); let ipv4broadcast = SocketAddr::new(IpAddr::V4(Ipv4Addr::BROADCAST), 8080); - let sender = bind_to_unspecified().expect("bind"); + let sender = bind_to_localhost_unique().expect("should bind"); // test intermediate failures for batch_send let packet_refs: Vec<_> = vec![ diff --git a/test-validator/src/lib.rs b/test-validator/src/lib.rs index 417755ac265..a87fad6af11 100644 --- a/test-validator/src/lib.rs +++ b/test-validator/src/lib.rs @@ -38,7 +38,9 @@ use { solana_loader_v3_interface::state::UpgradeableLoaderState, solana_message::Message, solana_native_token::sol_to_lamports, - solana_net_utils::{find_available_ports_in_range, PortRange}, + solana_net_utils::{ + find_available_ports_in_range, sockets::localhost_port_range_for_tests, PortRange, RangeExt, + }, solana_pubkey::Pubkey, solana_rent::Rent, solana_rpc::{rpc::JsonRpcConfig, rpc_pubsub_service::PubSubConfig}, @@ -100,10 +102,10 @@ impl Default for TestValidatorNodeConfig { #[cfg(not(debug_assertions))] let port_range = solana_net_utils::VALIDATOR_PORT_RANGE; #[cfg(debug_assertions)] - let port_range = solana_net_utils::sockets::localhost_port_range_for_tests(); + let port_range = localhost_port_range_for_tests(); Self { - gossip_addr: SocketAddr::new(bind_ip_addr, port_range.0), - port_range, + gossip_addr: SocketAddr::new(bind_ip_addr, port_range.start), + port_range: port_range.as_tuple(), bind_ip_addr, } } diff --git a/tpu-client-next/src/workers_cache.rs b/tpu-client-next/src/workers_cache.rs index 7d005e832f3..030eaa25ed5 100644 --- a/tpu-client-next/src/workers_cache.rs +++ b/tpu-client-next/src/workers_cache.rs @@ -327,7 +327,11 @@ mod tests { SendTransactionStats, }, quinn::Endpoint, - solana_net_utils::{bind_in_range, sockets::localhost_port_range_for_tests}, + solana_net_utils::{ + bind_in_range, + sockets::{localhost_port_range_for_tests, localhost_port_single_for_tests}, + RangeExt, + }, solana_tls_utils::QuicClientCertificate, std::{ net::{IpAddr, Ipv4Addr, SocketAddr}, @@ -342,10 +346,12 @@ mod tests { const TEST_MAX_TIME: Duration = Duration::from_secs(5); fn create_test_endpoint() -> Endpoint { - let port_range = localhost_port_range_for_tests(); - let socket = bind_in_range(IpAddr::V4(Ipv4Addr::LOCALHOST), port_range) - .unwrap() - .1; + let socket = bind_in_range( + IpAddr::V4(Ipv4Addr::LOCALHOST), + localhost_port_range_for_tests().as_tuple(), + ) + .expect("should bind") + .1; let client_config = create_client_config(&QuicClientCertificate::new(None)); create_client_endpoint(BindTarget::Socket(socket), client_config).unwrap() } @@ -354,8 +360,10 @@ mod tests { async fn test_worker_stopped_after_failed_connect() { let endpoint = create_test_endpoint(); - let port_range = localhost_port_range_for_tests(); - let peer: SocketAddr = SocketAddr::new(Ipv4Addr::LOCALHOST.into(), port_range.0); + let peer: SocketAddr = SocketAddr::new( + Ipv4Addr::LOCALHOST.into(), + localhost_port_single_for_tests(), + ); let worker_channel_size = 1; let skip_check_transaction_age = true; @@ -388,9 +396,10 @@ mod tests { async fn test_worker_shutdown() { let endpoint = create_test_endpoint(); - let port_range = localhost_port_range_for_tests(); - let peer: SocketAddr = SocketAddr::new(Ipv4Addr::LOCALHOST.into(), port_range.0); - + let peer: SocketAddr = SocketAddr::new( + Ipv4Addr::LOCALHOST.into(), + localhost_port_single_for_tests(), + ); let worker_channel_size = 1; let skip_check_transaction_age = true; let max_reconnect_attempts = 0; @@ -421,8 +430,10 @@ mod tests { let cancel = CancellationToken::new(); let mut cache = WorkersCache::new(10, cancel.clone()); - let port_range = localhost_port_range_for_tests(); - let peer: SocketAddr = SocketAddr::new(Ipv4Addr::LOCALHOST.into(), port_range.0); + let peer: SocketAddr = SocketAddr::new( + Ipv4Addr::LOCALHOST.into(), + localhost_port_single_for_tests(), + ); let worker_channel_size = 1; let skip_check_transaction_age = true; let max_reconnect_attempts = 0; diff --git a/turbine/src/broadcast_stage/standard_broadcast_run.rs b/turbine/src/broadcast_stage/standard_broadcast_run.rs index cb6b3211150..378dcb913d6 100644 --- a/turbine/src/broadcast_stage/standard_broadcast_run.rs +++ b/turbine/src/broadcast_stage/standard_broadcast_run.rs @@ -499,7 +499,7 @@ mod test { get_tmp_ledger_path, shred::{max_ticks_per_n_shreds, DATA_SHREDS_PER_FEC_BLOCK}, }, - solana_net_utils::bind_to_unspecified, + solana_net_utils::sockets::bind_to_localhost_unique, solana_runtime::bank::Bank, solana_signer::Signer, solana_streamer::socket::SocketAddrSpace, @@ -531,7 +531,7 @@ mod test { leader_keypair.clone(), SocketAddrSpace::Unspecified, )); - let socket = bind_to_unspecified().unwrap(); + let socket = bind_to_localhost_unique().expect("should bind"); let mut genesis_config = create_genesis_config(10_000).genesis_config; genesis_config.ticks_per_slot = max_ticks_per_n_shreds(num_shreds_per_slot, None) + 1; diff --git a/turbine/src/quic_endpoint.rs b/turbine/src/quic_endpoint.rs index 5afdf4fca2c..2843457279e 100644 --- a/turbine/src/quic_endpoint.rs +++ b/turbine/src/quic_endpoint.rs @@ -845,7 +845,7 @@ mod tests { let keypairs: Vec = repeat_with(Keypair::new).take(NUM_ENDPOINTS).collect(); let port_range = localhost_port_range_for_tests(); let ip_addr = IpAddr::V4(Ipv4Addr::LOCALHOST); - let sockets: Vec = (port_range.0..port_range.1) + let sockets: Vec = port_range .map(|port| bind_to(ip_addr, port).unwrap()) .take(NUM_ENDPOINTS) .collect(); diff --git a/validator/src/admin_rpc_service.rs b/validator/src/admin_rpc_service.rs index d53fc0d9087..7145e279167 100644 --- a/validator/src/admin_rpc_service.rs +++ b/validator/src/admin_rpc_service.rs @@ -961,7 +961,7 @@ mod tests { create_genesis_config, create_genesis_config_with_leader, GenesisConfigInfo, }, }, - solana_net_utils::bind_to_unspecified, + solana_net_utils::sockets::bind_to_localhost_unique, solana_program_option::COption, solana_program_pack::Pack, solana_pubkey::Pubkey, @@ -1030,7 +1030,7 @@ mod tests { vote_account, repair_whitelist, notifies: Arc::new(RwLock::new(KeyUpdaters::default())), - repair_socket: Arc::new(bind_to_unspecified().unwrap()), + repair_socket: Arc::new(bind_to_localhost_unique().expect("should bind")), outstanding_repair_requests: Arc::< RwLock, >::default(),