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

use net utils for binding UDP sockets #3705

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

gregcusack
Copy link

@gregcusack gregcusack commented Nov 19, 2024

Problem

We are in the process of properly sizing UDP socket buffers. Buffer sizing will happen in net-utils. Also, the code base is fragmented in the sense that some services use net-utils to bind to sockets and some use UdpSocket::bind.

Summary of Changes

switch all cases of UdpSocket::bind to use solana_net_utils::bind_to and all cases of tokio::new::UdpSocket::bind() to use solana_net_utils::bind_to_async

Next PR will update socket binds to take in a SocketConfig to properly size buffers: #3618

@gregcusack gregcusack force-pushed the use-net-utils-to-bind branch 5 times, most recently from b0f3959 to 767e5a1 Compare November 19, 2024 18:48
@gregcusack gregcusack marked this pull request as ready for review November 19, 2024 19:18
@t-nelson
Copy link

we can leverage clippy's disallowed_methods lint to prevent future introduction of UdpSocket::bind

Copy link

@steviez steviez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor requested change that will save us from pasting the default values in 10's of place + potentially save us from touching the same spots should we add a new parameter to bind_to() (which seems possible given that I believe you'll be extending SocketConfig).

In some other parts of the codebase, we have helpers like new_for_tests() and new_for_benches(); not sure if that is appropriate here or not (maybe as part of the next PR where you actually tune buffer sizes) ?

client/src/connection_cache.rs Outdated Show resolved Hide resolved
bench-streamer/src/main.rs Outdated Show resolved Hide resolved
@gregcusack gregcusack force-pushed the use-net-utils-to-bind branch 3 times, most recently from be45088 to 506e152 Compare November 26, 2024 01:03
Copy link

@steviez steviez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for making the changes - just a couple more minor things

Comment on lines 2672 to 2673
let broadcast = vec![bind_to_localhost().unwrap()];
let retransmit_socket = bind_to_localhost().unwrap();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These were both previously unspecified but localhost now. I'm not sure which is more proper, but I'm leaning towards keeping same behavior in this PR and we can change in a separate one (where the change in behavior will be much more apparent)

Comment on lines 2676 to 2677
let ancestor_hashes_requests = bind_to_localhost().unwrap();
let ancestor_hashes_requests_quic = bind_to_localhost().unwrap();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above - these were both previously unspecified

.map_err(|e| io::Error::new(io::ErrorKind::InvalidInput, e))?;
let reader = bind_to_async(
sock_addr.ip(),
/*port*/ sock_addr.port(),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I think sock_addr.port() is telling enough that we don't need the /*port*/ comment.

let sender = UdpSocket::bind(ip_str).await?;
let sender = bind_to_async(
sock_addr.ip(),
/*port*/ sock_addr.port(),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above - I think sock_addr.port() is telling enough that we don't need the /*port*/ comment

.map_err(|e| io::Error::new(io::ErrorKind::InvalidInput, e))?;
let reader = bind_to(
sock_addr.ip(),
/*port:*/ sock_addr.port(),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above - I think sock_addr.port() is telling enough that we don't need the /*port*/ comment

let sender = UdpSocket::bind(ip_str)?;
let sender = bind_to(
sock_addr.ip(),
/*port:*/ sock_addr.port(),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above - I think sock_addr.port() is telling enough that we don't need the /*port*/ comment

bind_to(
IpAddr::V4(Ipv4Addr::LOCALHOST),
/*port*/ 0,
/*reuseport:*/ true,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just making sure - we couldn't use the convenience helper since reuseport = true here ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

correct, although we could change the helper to always accept a reuse port argument. or add a separate helper that is something like: bind_to_localhost_reuse_port() but that feels excessive.

@@ -177,7 +177,13 @@ mod tests {
];
let dest_refs: Vec<_> = vec![&ip4, &ip6, &ip4];

let sender = UdpSocket::bind("0.0.0.0:0").await.expect("bind");
let sender = bind_to_async(
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that we have a bind_to_localhost_async(), it wouldn't seem too crazy to add a bind_to_unspecified_async(). But, this test looks to contain the only two instances so I don't think this is a "must-do" either

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

true. tbh probably worth it to add it for future development use if needed

@@ -23,6 +23,7 @@ solana-entry = { workspace = true }
solana-gossip = { workspace = true }
solana-ledger = { workspace = true }
solana-logger = { workspace = true }
solana-net-utils = { workspace = true }
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replying to this question: #3705 (comment)

side note, bind_to_localhost is used directly in LocalCluster. And while LocalCluster is technically only used for testing, it is its own standalone crate. based on my understanding, it seems like we can't make bind_to_localhost #[cfg(feature = "dev-context-only-utils")]. is that right?

I think you could if you do:

solana-net-utils = { workspace = true, features = ["dev-context-only-utils"] }

Like you said, LocalCluster itself is primarily testing so I think it falls in the category of core development crate

# Firstly, detect any misuse of dev-context-only-utils as normal/build
# dependencies. Also, allow some exceptions for special purpose crates. This
# white-listing mechanism can be used for core-development-oriented crates like
# bench bins.

I see some dcou in dev-dependencies, but given that you're modifying "source" and not tests, I don't think you could include it in dev-dep list

[dev-dependencies]
assert_matches = { workspace = true }
fs_extra = { workspace = true }
gag = { workspace = true }
serial_test = { workspace = true }
solana-core = { workspace = true, features = ["dev-context-only-utils"] }
solana-download-utils = { workspace = true }
solana-ledger = { workspace = true, features = ["dev-context-only-utils"] }
solana-local-cluster = { path = ".", features = ["dev-context-only-utils"] }
solana-runtime = { workspace = true, features = ["dev-context-only-utils"] }

@gregcusack gregcusack force-pushed the use-net-utils-to-bind branch 5 times, most recently from 2462284 to ed809ba Compare November 26, 2024 20:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants