Skip to content

Commit 399eedf

Browse files
authored
use net utils for binding UDP sockets (anza-xyz#3705)
* use net utils for binding sockets * use clippy disallowed methods to prevent direct calls to UdpSocket::bind * build helper fcn for bind to local host and unspecified * enforce dev-context-only-utils in net-utils
1 parent 6a5adbe commit 399eedf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+257
-135
lines changed

.clippy.toml

+6
Original file line numberDiff line numberDiff line change
@@ -1 +1,7 @@
11
too-many-arguments-threshold = 9
2+
3+
# Disallow specific methods from being used
4+
disallowed-methods = [
5+
{ path = "std::net::UdpSocket::bind", reason = "Use solana_net_utils::bind_with_config, bind_to, etc instead for proper socket configuration." },
6+
{ path = "tokio::net::UdpSocket::bind", reason = "Use solana_net_utils::bind_to_async or bind_to_with_config_non_blocking instead for proper socket configuration." },
7+
]

Cargo.lock

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bench-streamer/src/main.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33
use {
44
clap::{crate_description, crate_name, Arg, Command},
55
crossbeam_channel::unbounded,
6+
solana_net_utils::bind_to_unspecified,
67
solana_streamer::{
78
packet::{Packet, PacketBatch, PacketBatchRecycler, PACKET_DATA_SIZE},
89
streamer::{receiver, PacketBatchReceiver, StreamerReceiveStats},
910
},
1011
std::{
1112
cmp::max,
12-
net::{IpAddr, Ipv4Addr, SocketAddr, UdpSocket},
13+
net::{IpAddr, Ipv4Addr, SocketAddr},
1314
sync::{
1415
atomic::{AtomicBool, AtomicUsize, Ordering},
1516
Arc,
@@ -20,7 +21,7 @@ use {
2021
};
2122

2223
fn producer(addr: &SocketAddr, exit: Arc<AtomicBool>) -> JoinHandle<()> {
23-
let send = UdpSocket::bind("0.0.0.0:0").unwrap();
24+
let send = bind_to_unspecified().unwrap();
2425
let batch_size = 10;
2526
let mut packet_batch = PacketBatch::with_capacity(batch_size);
2627
packet_batch.resize(batch_size, Packet::default());

client/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ tokio = { workspace = true, features = ["full"] }
3737

3838
[dev-dependencies]
3939
crossbeam-channel = { workspace = true }
40+
solana-net-utils = { workspace = true, features = ["dev-context-only-utils"] }
4041

4142
[package.metadata.docs.rs]
4243
targets = ["x86_64-unknown-linux-gnu"]

client/src/connection_cache.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ mod tests {
201201
super::*,
202202
crate::connection_cache::ConnectionCache,
203203
crossbeam_channel::unbounded,
204+
solana_net_utils::bind_to_localhost,
204205
solana_sdk::signature::Keypair,
205206
solana_streamer::{
206207
quic::{QuicServerParams, SpawnServerResult},
@@ -217,7 +218,7 @@ mod tests {
217218

218219
fn server_args() -> (UdpSocket, Arc<AtomicBool>, Keypair) {
219220
(
220-
UdpSocket::bind("127.0.0.1:0").unwrap(),
221+
bind_to_localhost().unwrap(),
221222
Arc::new(AtomicBool::new(false)),
222223
Keypair::new(),
223224
)

core/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ solana-core = { path = ".", features = ["dev-context-only-utils"] }
109109
solana-cost-model = { workspace = true, features = ["dev-context-only-utils"] }
110110
solana-ledger = { workspace = true, features = ["dev-context-only-utils"] }
111111
solana-logger = { workspace = true }
112+
solana-net-utils = { workspace = true, features = ["dev-context-only-utils"] }
112113
solana-poh = { workspace = true, features = ["dev-context-only-utils"] }
113114
solana-program-runtime = { workspace = true }
114115
solana-sdk = { workspace = true, features = ["dev-context-only-utils"] }

core/src/banking_simulation.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use {
2121
blockstore::{Blockstore, PurgeType},
2222
leader_schedule_cache::LeaderScheduleCache,
2323
},
24+
solana_net_utils::bind_to_localhost,
2425
solana_poh::{
2526
poh_recorder::{PohRecorder, GRACE_TICKS_FACTOR, MAX_GRACE_SLOTS},
2627
poh_service::{PohService, DEFAULT_HASHES_PER_BATCH, DEFAULT_PINNED_CPU_CORE},
@@ -46,7 +47,6 @@ use {
4647
fmt::Display,
4748
fs::File,
4849
io::{self, BufRead, BufReader},
49-
net::{Ipv4Addr, UdpSocket},
5050
path::PathBuf,
5151
sync::{
5252
atomic::{AtomicBool, Ordering},
@@ -783,7 +783,7 @@ impl BankingSimulator {
783783
// Broadcast stage is needed to save the simulated blocks for post-run analysis by
784784
// inserting produced shreds into the blockstore.
785785
let broadcast_stage = BroadcastStageType::Standard.new_broadcast_stage(
786-
vec![UdpSocket::bind((Ipv4Addr::LOCALHOST, 0)).unwrap()],
786+
vec![bind_to_localhost().unwrap()],
787787
cluster_info.clone(),
788788
entry_receiver,
789789
retransmit_slots_receiver,

core/src/banking_stage/forwarder.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use {
1616
solana_connection_cache::client_connection::ClientConnection as TpuConnection,
1717
solana_feature_set::FeatureSet,
1818
solana_measure::measure_us,
19+
solana_net_utils::bind_to_unspecified,
1920
solana_perf::{data_budget::DataBudget, packet::Packet},
2021
solana_poh::poh_recorder::PohRecorder,
2122
solana_runtime::bank_forks::BankForks,
@@ -50,7 +51,7 @@ impl<T: LikeClusterInfo> Forwarder<T> {
5051
Self {
5152
poh_recorder,
5253
bank_forks,
53-
socket: UdpSocket::bind("0.0.0.0:0").unwrap(),
54+
socket: bind_to_unspecified().unwrap(),
5455
cluster_info,
5556
connection_cache,
5657
data_budget,

core/src/repair/ancestor_hashes_service.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -917,6 +917,7 @@ mod test {
917917
blockstore::make_many_slot_entries, get_tmp_ledger_path,
918918
get_tmp_ledger_path_auto_delete, shred::Nonce,
919919
},
920+
solana_net_utils::bind_to_unspecified,
920921
solana_runtime::{accounts_background_service::AbsRequestSender, bank_forks::BankForks},
921922
solana_sdk::{
922923
hash::Hash,
@@ -1345,7 +1346,7 @@ mod test {
13451346
impl ManageAncestorHashesState {
13461347
fn new(bank_forks: Arc<RwLock<BankForks>>) -> Self {
13471348
let ancestor_hashes_request_statuses = Arc::new(DashMap::new());
1348-
let ancestor_hashes_request_socket = Arc::new(UdpSocket::bind("0.0.0.0:0").unwrap());
1349+
let ancestor_hashes_request_socket = Arc::new(bind_to_unspecified().unwrap());
13491350
let epoch_schedule = bank_forks
13501351
.read()
13511352
.unwrap()

core/src/repair/quic_endpoint.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1021,9 +1021,10 @@ mod tests {
10211021
super::*,
10221022
itertools::{izip, multiunzip},
10231023
solana_ledger::genesis_utils::{create_genesis_config, GenesisConfigInfo},
1024+
solana_net_utils::bind_to_localhost,
10241025
solana_runtime::bank::Bank,
10251026
solana_sdk::signature::Signer,
1026-
std::{iter::repeat_with, net::Ipv4Addr, time::Duration},
1027+
std::{iter::repeat_with, time::Duration},
10271028
};
10281029

10291030
#[test]
@@ -1036,7 +1037,7 @@ mod tests {
10361037
.build()
10371038
.unwrap();
10381039
let keypairs: Vec<Keypair> = repeat_with(Keypair::new).take(NUM_ENDPOINTS).collect();
1039-
let sockets: Vec<UdpSocket> = repeat_with(|| UdpSocket::bind((Ipv4Addr::LOCALHOST, 0)))
1040+
let sockets: Vec<UdpSocket> = repeat_with(bind_to_localhost)
10401041
.take(NUM_ENDPOINTS)
10411042
.collect::<Result<_, _>>()
10421043
.unwrap();

core/src/repair/repair_service.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -1075,6 +1075,7 @@ mod test {
10751075
get_tmp_ledger_path_auto_delete,
10761076
shred::max_ticks_per_n_shreds,
10771077
},
1078+
solana_net_utils::{bind_to_localhost, bind_to_unspecified},
10781079
solana_runtime::bank::Bank,
10791080
solana_sdk::{
10801081
signature::{Keypair, Signer},
@@ -1097,9 +1098,9 @@ mod test {
10971098
let pubkey = cluster_info.id();
10981099
let slot = 100;
10991100
let shred_index = 50;
1100-
let reader = UdpSocket::bind("127.0.0.1:0").expect("bind");
1101+
let reader = bind_to_localhost().expect("bind");
11011102
let address = reader.local_addr().unwrap();
1102-
let sender = UdpSocket::bind("127.0.0.1:0").expect("bind");
1103+
let sender = bind_to_localhost().expect("bind");
11031104
let outstanding_repair_requests = Arc::new(RwLock::new(OutstandingShredRepairs::default()));
11041105

11051106
// Send a repair request
@@ -1452,7 +1453,7 @@ mod test {
14521453
);
14531454
let mut duplicate_slot_repair_statuses = HashMap::new();
14541455
let dead_slot = 9;
1455-
let receive_socket = &UdpSocket::bind("0.0.0.0:0").unwrap();
1456+
let receive_socket = &bind_to_unspecified().unwrap();
14561457
let duplicate_status = DuplicateSlotRepairStatus {
14571458
correct_ancestor_to_repair: (dead_slot, Hash::default()),
14581459
start_ts: u64::MAX,
@@ -1481,7 +1482,7 @@ mod test {
14811482
&blockstore,
14821483
&serve_repair,
14831484
&mut RepairStats::default(),
1484-
&UdpSocket::bind("0.0.0.0:0").unwrap(),
1485+
&bind_to_unspecified().unwrap(),
14851486
&None,
14861487
&RwLock::new(OutstandingRequests::default()),
14871488
&identity_keypair,
@@ -1507,7 +1508,7 @@ mod test {
15071508
&blockstore,
15081509
&serve_repair,
15091510
&mut RepairStats::default(),
1510-
&UdpSocket::bind("0.0.0.0:0").unwrap(),
1511+
&bind_to_unspecified().unwrap(),
15111512
&None,
15121513
&RwLock::new(OutstandingRequests::default()),
15131514
&identity_keypair,
@@ -1526,7 +1527,7 @@ mod test {
15261527
&blockstore,
15271528
&serve_repair,
15281529
&mut RepairStats::default(),
1529-
&UdpSocket::bind("0.0.0.0:0").unwrap(),
1530+
&bind_to_unspecified().unwrap(),
15301531
&None,
15311532
&RwLock::new(OutstandingRequests::default()),
15321533
&identity_keypair,
@@ -1541,7 +1542,7 @@ mod test {
15411542
let bank_forks = BankForks::new_rw_arc(bank);
15421543
let dummy_addr = Some((
15431544
Pubkey::default(),
1544-
UdpSocket::bind("0.0.0.0:0").unwrap().local_addr().unwrap(),
1545+
bind_to_unspecified().unwrap().local_addr().unwrap(),
15451546
));
15461547
let cluster_info = Arc::new(new_test_cluster_info());
15471548
let serve_repair = ServeRepair::new(

dos/src/main.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ use {
5656
gossip_service::{discover, get_client},
5757
},
5858
solana_measure::measure::Measure,
59+
solana_net_utils::bind_to_unspecified,
5960
solana_rpc_client::rpc_client::RpcClient,
6061
solana_sdk::{
6162
hash::Hash,
@@ -73,7 +74,7 @@ use {
7374
solana_tps_client::TpsClient,
7475
solana_tpu_client::tpu_client::DEFAULT_TPU_CONNECTION_POOL_SIZE,
7576
std::{
76-
net::{SocketAddr, UdpSocket},
77+
net::SocketAddr,
7778
process::exit,
7879
sync::Arc,
7980
thread,
@@ -725,7 +726,7 @@ fn run_dos<T: 'static + TpsClient + Send + Sync>(
725726
_ => panic!("Unsupported data_type detected"),
726727
};
727728

728-
let socket = UdpSocket::bind("0.0.0.0:0").unwrap();
729+
let socket = bind_to_unspecified().unwrap();
729730
let mut last_log = Instant::now();
730731
let mut total_count: usize = 0;
731732
let mut count: usize = 0;

gossip/src/cluster_info.rs

+24-21
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@ use {
5656
solana_measure::measure::Measure,
5757
solana_net_utils::{
5858
bind_common, bind_common_in_range, bind_in_range, bind_in_range_with_config,
59-
bind_more_with_config, bind_two_in_range_with_offset_and_config,
60-
find_available_port_in_range, multi_bind_in_range, PortRange, SocketConfig,
61-
VALIDATOR_PORT_RANGE,
59+
bind_more_with_config, bind_to_localhost, bind_to_unspecified,
60+
bind_two_in_range_with_offset_and_config, find_available_port_in_range,
61+
multi_bind_in_range, PortRange, SocketConfig, VALIDATOR_PORT_RANGE,
6262
},
6363
solana_perf::{
6464
data_budget::DataBudget,
@@ -224,7 +224,7 @@ impl ClusterInfo {
224224
GOSSIP_PING_CACHE_CAPACITY,
225225
)),
226226
stats: GossipStats::default(),
227-
socket: UdpSocket::bind("0.0.0.0:0").unwrap(),
227+
socket: bind_to_unspecified().unwrap(),
228228
local_message_pending_push_queue: Mutex::default(),
229229
contact_debug_interval: DEFAULT_CONTACT_DEBUG_INTERVAL_MILLIS,
230230
instance: RwLock::new(NodeInstance::new(&mut thread_rng(), id, timestamp())),
@@ -2626,8 +2626,6 @@ impl Node {
26262626
num_quic_endpoints: usize,
26272627
) -> Self {
26282628
let localhost_ip_addr = IpAddr::V4(Ipv4Addr::LOCALHOST);
2629-
let localhost_bind_addr = format!("{localhost_ip_addr:?}:0");
2630-
let unspecified_bind_addr = format!("{:?}:0", IpAddr::V4(Ipv4Addr::UNSPECIFIED));
26312629
let port_range = (1024, 65535);
26322630

26332631
let udp_config = SocketConfig { reuseport: false };
@@ -2646,8 +2644,8 @@ impl Node {
26462644
let (gossip_port, (gossip, ip_echo)) =
26472645
bind_common_in_range(localhost_ip_addr, port_range).unwrap();
26482646
let gossip_addr = SocketAddr::new(localhost_ip_addr, gossip_port);
2649-
let tvu = UdpSocket::bind(&localhost_bind_addr).unwrap();
2650-
let tvu_quic = UdpSocket::bind(&localhost_bind_addr).unwrap();
2647+
let tvu = bind_to_localhost().unwrap();
2648+
let tvu_quic = bind_to_localhost().unwrap();
26512649
let ((_tpu_forwards_port, tpu_forwards), (_tpu_forwards_quic_port, tpu_forwards_quic)) =
26522650
bind_two_in_range_with_offset_and_config(
26532651
localhost_ip_addr,
@@ -2660,24 +2658,23 @@ impl Node {
26602658
let tpu_forwards_quic =
26612659
bind_more_with_config(tpu_forwards_quic, num_quic_endpoints, quic_config.clone())
26622660
.unwrap();
2663-
let tpu_vote = UdpSocket::bind(&localhost_bind_addr).unwrap();
2664-
let tpu_vote_quic = UdpSocket::bind(&localhost_bind_addr).unwrap();
2665-
2661+
let tpu_vote = bind_to_localhost().unwrap();
2662+
let tpu_vote_quic = bind_to_localhost().unwrap();
26662663
let tpu_vote_quic =
26672664
bind_more_with_config(tpu_vote_quic, num_quic_endpoints, quic_config).unwrap();
26682665

2669-
let repair = UdpSocket::bind(&localhost_bind_addr).unwrap();
2670-
let repair_quic = UdpSocket::bind(&localhost_bind_addr).unwrap();
2666+
let repair = bind_to_localhost().unwrap();
2667+
let repair_quic = bind_to_localhost().unwrap();
26712668
let rpc_port = find_available_port_in_range(localhost_ip_addr, port_range).unwrap();
26722669
let rpc_addr = SocketAddr::new(localhost_ip_addr, rpc_port);
26732670
let rpc_pubsub_port = find_available_port_in_range(localhost_ip_addr, port_range).unwrap();
26742671
let rpc_pubsub_addr = SocketAddr::new(localhost_ip_addr, rpc_pubsub_port);
2675-
let broadcast = vec![UdpSocket::bind(&unspecified_bind_addr).unwrap()];
2676-
let retransmit_socket = UdpSocket::bind(&unspecified_bind_addr).unwrap();
2677-
let serve_repair = UdpSocket::bind(&localhost_bind_addr).unwrap();
2678-
let serve_repair_quic = UdpSocket::bind(&localhost_bind_addr).unwrap();
2679-
let ancestor_hashes_requests = UdpSocket::bind(&unspecified_bind_addr).unwrap();
2680-
let ancestor_hashes_requests_quic = UdpSocket::bind(&unspecified_bind_addr).unwrap();
2672+
let broadcast = vec![bind_to_unspecified().unwrap()];
2673+
let retransmit_socket = bind_to_unspecified().unwrap();
2674+
let serve_repair = bind_to_localhost().unwrap();
2675+
let serve_repair_quic = bind_to_localhost().unwrap();
2676+
let ancestor_hashes_requests = bind_to_unspecified().unwrap();
2677+
let ancestor_hashes_requests_quic = bind_to_unspecified().unwrap();
26812678

26822679
let mut info = ContactInfo::new(
26832680
*pubkey,
@@ -3019,7 +3016,7 @@ pub fn push_messages_to_peer(
30193016
"push_messages_to_peer",
30203017
&reqs,
30213018
);
3022-
let sock = UdpSocket::bind("0.0.0.0:0").unwrap();
3019+
let sock = bind_to_unspecified().unwrap();
30233020
packet::send_to(&packet_batch, &sock, socket_addr_space)?;
30243021
Ok(())
30253022
}
@@ -3152,6 +3149,7 @@ mod tests {
31523149
},
31533150
itertools::izip,
31543151
solana_ledger::shred::Shredder,
3152+
solana_net_utils::bind_to,
31553153
solana_sdk::signature::{Keypair, Signer},
31563154
solana_vote_program::{vote_instruction, vote_state::Vote},
31573155
std::{
@@ -4395,7 +4393,12 @@ mod tests {
43954393

43964394
let cluster_info44 = Arc::new({
43974395
let mut node = Node::new_localhost_with_pubkey(&keypair44.pubkey());
4398-
node.sockets.gossip = UdpSocket::bind("127.0.0.1:65534").unwrap();
4396+
node.sockets.gossip = bind_to(
4397+
IpAddr::V4(Ipv4Addr::LOCALHOST),
4398+
/*port*/ 65534,
4399+
/*reuseport:*/ false,
4400+
)
4401+
.unwrap();
43994402
info!("{:?}", node);
44004403
ClusterInfo::new(node.info, keypair44.clone(), SocketAddrSpace::Unspecified)
44014404
});

0 commit comments

Comments
 (0)