|
@@ -10,14 +10,13 @@ pub use ip_echo_server::{
|
|
|
ip_echo_server, IpEchoServer, DEFAULT_IP_ECHO_SERVER_THREADS, MAX_PORT_COUNT_PER_MESSAGE,
|
|
ip_echo_server, IpEchoServer, DEFAULT_IP_ECHO_SERVER_THREADS, MAX_PORT_COUNT_PER_MESSAGE,
|
|
|
MINIMUM_IP_ECHO_SERVER_THREADS,
|
|
MINIMUM_IP_ECHO_SERVER_THREADS,
|
|
|
};
|
|
};
|
|
|
-#[cfg(feature = "dev-context-only-utils")]
|
|
|
|
|
-use tokio::net::UdpSocket as TokioUdpSocket;
|
|
|
|
|
use {
|
|
use {
|
|
|
|
|
+ crate::sockets::{udp_socket_with_config, PLATFORM_SUPPORTS_SOCKET_CONFIGS},
|
|
|
ip_echo_client::{ip_echo_server_request, ip_echo_server_request_with_binding},
|
|
ip_echo_client::{ip_echo_server_request, ip_echo_server_request_with_binding},
|
|
|
ip_echo_server::IpEchoServerMessage,
|
|
ip_echo_server::IpEchoServerMessage,
|
|
|
log::*,
|
|
log::*,
|
|
|
rand::{thread_rng, Rng},
|
|
rand::{thread_rng, Rng},
|
|
|
- socket2::{Domain, SockAddr, Socket, Type},
|
|
|
|
|
|
|
+ socket2::SockAddr,
|
|
|
std::{
|
|
std::{
|
|
|
io::{self},
|
|
io::{self},
|
|
|
net::{IpAddr, Ipv4Addr, SocketAddr, TcpListener, ToSocketAddrs, UdpSocket},
|
|
net::{IpAddr, Ipv4Addr, SocketAddr, TcpListener, ToSocketAddrs, UdpSocket},
|
|
@@ -225,6 +224,10 @@ pub fn is_host_port(string: String) -> Result<(), String> {
|
|
|
parse_host_port(&string).map(|_| ())
|
|
parse_host_port(&string).map(|_| ())
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+#[deprecated(
|
|
|
|
|
+ since = "2.3.2",
|
|
|
|
|
+ note = "Please use the equivalent struct from solana-net-utils::sockets"
|
|
|
|
|
+)]
|
|
|
#[derive(Clone, Copy, Debug, Default)]
|
|
#[derive(Clone, Copy, Debug, Default)]
|
|
|
pub struct SocketConfig {
|
|
pub struct SocketConfig {
|
|
|
reuseport: bool,
|
|
reuseport: bool,
|
|
@@ -232,6 +235,7 @@ pub struct SocketConfig {
|
|
|
send_buffer_size: Option<usize>,
|
|
send_buffer_size: Option<usize>,
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+#[allow(deprecated)]
|
|
|
impl SocketConfig {
|
|
impl SocketConfig {
|
|
|
pub fn reuseport(mut self, reuseport: bool) -> Self {
|
|
pub fn reuseport(mut self, reuseport: bool) -> Self {
|
|
|
self.reuseport = reuseport;
|
|
self.reuseport = reuseport;
|
|
@@ -261,40 +265,12 @@ impl SocketConfig {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-#[cfg(any(windows, target_os = "ios"))]
|
|
|
|
|
-fn udp_socket_with_config(_config: SocketConfig) -> io::Result<Socket> {
|
|
|
|
|
- let sock = Socket::new(Domain::IPV4, Type::DGRAM, None)?;
|
|
|
|
|
- Ok(sock)
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-#[cfg(not(any(windows, target_os = "ios")))]
|
|
|
|
|
-fn udp_socket_with_config(config: SocketConfig) -> io::Result<Socket> {
|
|
|
|
|
- use nix::sys::socket::{setsockopt, sockopt::ReusePort};
|
|
|
|
|
- let SocketConfig {
|
|
|
|
|
- reuseport,
|
|
|
|
|
- recv_buffer_size,
|
|
|
|
|
- send_buffer_size,
|
|
|
|
|
- } = config;
|
|
|
|
|
-
|
|
|
|
|
- let sock = Socket::new(Domain::IPV4, Type::DGRAM, None)?;
|
|
|
|
|
-
|
|
|
|
|
- // Set buffer sizes
|
|
|
|
|
- if let Some(recv_buffer_size) = recv_buffer_size {
|
|
|
|
|
- sock.set_recv_buffer_size(recv_buffer_size)?;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if let Some(send_buffer_size) = send_buffer_size {
|
|
|
|
|
- sock.set_send_buffer_size(send_buffer_size)?;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if reuseport {
|
|
|
|
|
- setsockopt(&sock, ReusePort, &true).ok();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- Ok(sock)
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-// Find a port in the given range with a socket config that is available for both TCP and UDP
|
|
|
|
|
|
|
+#[deprecated(
|
|
|
|
|
+ since = "2.3.2",
|
|
|
|
|
+ note = "Please use the equivalent from solana-net-utils::sockets"
|
|
|
|
|
+)]
|
|
|
|
|
+#[allow(deprecated)]
|
|
|
|
|
+/// Find a port in the given range with a socket config that is available for both TCP and UDP
|
|
|
pub fn bind_common_in_range_with_config(
|
|
pub fn bind_common_in_range_with_config(
|
|
|
ip_addr: IpAddr,
|
|
ip_addr: IpAddr,
|
|
|
range: PortRange,
|
|
range: PortRange,
|
|
@@ -312,23 +288,28 @@ pub fn bind_common_in_range_with_config(
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
pub fn bind_in_range(ip_addr: IpAddr, range: PortRange) -> io::Result<(u16, UdpSocket)> {
|
|
pub fn bind_in_range(ip_addr: IpAddr, range: PortRange) -> io::Result<(u16, UdpSocket)> {
|
|
|
- let config = SocketConfig::default();
|
|
|
|
|
- bind_in_range_with_config(ip_addr, range, config)
|
|
|
|
|
|
|
+ let config = sockets::SocketConfiguration::default();
|
|
|
|
|
+ sockets::bind_in_range_with_config(ip_addr, range, config)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+#[deprecated(
|
|
|
|
|
+ since = "2.3.2",
|
|
|
|
|
+ note = "Please use the equivalent from solana-net-utils::sockets"
|
|
|
|
|
+)]
|
|
|
|
|
+#[allow(deprecated)]
|
|
|
pub fn bind_in_range_with_config(
|
|
pub fn bind_in_range_with_config(
|
|
|
ip_addr: IpAddr,
|
|
ip_addr: IpAddr,
|
|
|
range: PortRange,
|
|
range: PortRange,
|
|
|
config: SocketConfig,
|
|
config: SocketConfig,
|
|
|
) -> io::Result<(u16, UdpSocket)> {
|
|
) -> io::Result<(u16, UdpSocket)> {
|
|
|
- let sock = udp_socket_with_config(config)?;
|
|
|
|
|
|
|
+ let socket = udp_socket_with_config(config.into())?;
|
|
|
|
|
|
|
|
for port in range.0..range.1 {
|
|
for port in range.0..range.1 {
|
|
|
let addr = SocketAddr::new(ip_addr, port);
|
|
let addr = SocketAddr::new(ip_addr, port);
|
|
|
|
|
|
|
|
- if sock.bind(&SockAddr::from(addr)).is_ok() {
|
|
|
|
|
- let sock: UdpSocket = sock.into();
|
|
|
|
|
- return Result::Ok((sock.local_addr().unwrap().port(), sock));
|
|
|
|
|
|
|
+ if socket.bind(&SockAddr::from(addr)).is_ok() {
|
|
|
|
|
+ let udp_socket: UdpSocket = socket.into();
|
|
|
|
|
+ return Result::Ok((udp_socket.local_addr().unwrap().port(), udp_socket));
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -337,11 +318,16 @@ pub fn bind_in_range_with_config(
|
|
|
)))
|
|
)))
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+#[deprecated(
|
|
|
|
|
+ since = "2.3.2",
|
|
|
|
|
+ note = "Please use the equivalent from solana-net-utils::sockets"
|
|
|
|
|
+)]
|
|
|
|
|
+#[allow(deprecated)]
|
|
|
pub fn bind_with_any_port_with_config(
|
|
pub fn bind_with_any_port_with_config(
|
|
|
ip_addr: IpAddr,
|
|
ip_addr: IpAddr,
|
|
|
config: SocketConfig,
|
|
config: SocketConfig,
|
|
|
) -> io::Result<UdpSocket> {
|
|
) -> io::Result<UdpSocket> {
|
|
|
- let sock = udp_socket_with_config(config)?;
|
|
|
|
|
|
|
+ let sock = udp_socket_with_config(config.into())?;
|
|
|
let addr = SocketAddr::new(ip_addr, 0);
|
|
let addr = SocketAddr::new(ip_addr, 0);
|
|
|
match sock.bind(&SockAddr::from(addr)) {
|
|
match sock.bind(&SockAddr::from(addr)) {
|
|
|
Ok(_) => Result::Ok(sock.into()),
|
|
Ok(_) => Result::Ok(sock.into()),
|
|
@@ -349,6 +335,11 @@ pub fn bind_with_any_port_with_config(
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+#[deprecated(
|
|
|
|
|
+ since = "2.3.2",
|
|
|
|
|
+ note = "Please use the equivalent from solana-net-utils::sockets"
|
|
|
|
|
+)]
|
|
|
|
|
+#[allow(deprecated)]
|
|
|
/// binds num sockets to the same port in a range with config
|
|
/// binds num sockets to the same port in a range with config
|
|
|
pub fn multi_bind_in_range_with_config(
|
|
pub fn multi_bind_in_range_with_config(
|
|
|
ip_addr: IpAddr,
|
|
ip_addr: IpAddr,
|
|
@@ -356,122 +347,68 @@ pub fn multi_bind_in_range_with_config(
|
|
|
config: SocketConfig,
|
|
config: SocketConfig,
|
|
|
mut num: usize,
|
|
mut num: usize,
|
|
|
) -> io::Result<(u16, Vec<UdpSocket>)> {
|
|
) -> io::Result<(u16, Vec<UdpSocket>)> {
|
|
|
- if !config.reuseport {
|
|
|
|
|
- return Err(io::Error::new(
|
|
|
|
|
- io::ErrorKind::InvalidInput,
|
|
|
|
|
- "SocketConfig.reuseport must be true for multi_bind_in_range_with_config",
|
|
|
|
|
- ));
|
|
|
|
|
- }
|
|
|
|
|
- if cfg!(windows) && num != 1 {
|
|
|
|
|
|
|
+ if !PLATFORM_SUPPORTS_SOCKET_CONFIGS && num != 1 {
|
|
|
// See https://github.com/solana-labs/solana/issues/4607
|
|
// See https://github.com/solana-labs/solana/issues/4607
|
|
|
warn!(
|
|
warn!(
|
|
|
- "multi_bind_in_range_with_config() only supports 1 socket in windows ({} requested)",
|
|
|
|
|
|
|
+ "multi_bind_in_range_with_config() only supports 1 socket on this platform ({} requested)",
|
|
|
num
|
|
num
|
|
|
);
|
|
);
|
|
|
num = 1;
|
|
num = 1;
|
|
|
}
|
|
}
|
|
|
- let mut sockets = Vec::with_capacity(num);
|
|
|
|
|
-
|
|
|
|
|
- const NUM_TRIES: usize = 100;
|
|
|
|
|
- let mut port = 0;
|
|
|
|
|
- let mut error = None;
|
|
|
|
|
- for _ in 0..NUM_TRIES {
|
|
|
|
|
- port = {
|
|
|
|
|
- let (port, _) = bind_in_range(ip_addr, range)?;
|
|
|
|
|
- port
|
|
|
|
|
- }; // drop the probe, port should be available... briefly.
|
|
|
|
|
-
|
|
|
|
|
- for _ in 0..num {
|
|
|
|
|
- let sock = bind_to_with_config(ip_addr, port, config);
|
|
|
|
|
- if let Ok(sock) = sock {
|
|
|
|
|
- sockets.push(sock);
|
|
|
|
|
- } else {
|
|
|
|
|
- error = Some(sock);
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- if sockets.len() == num {
|
|
|
|
|
- break;
|
|
|
|
|
- } else {
|
|
|
|
|
- sockets.clear();
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- if sockets.len() != num {
|
|
|
|
|
- error.unwrap()?;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ let (port, socket) = bind_in_range_with_config(ip_addr, range, config)?;
|
|
|
|
|
+ let sockets = bind_more_with_config(socket, num, config)?;
|
|
|
Ok((port, sockets))
|
|
Ok((port, sockets))
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+#[deprecated(
|
|
|
|
|
+ since = "2.3.2",
|
|
|
|
|
+ note = "Please use the eqiuvalent from solana-net-utils::sockets"
|
|
|
|
|
+)]
|
|
|
|
|
+#[allow(deprecated)]
|
|
|
pub fn bind_to(ip_addr: IpAddr, port: u16, reuseport: bool) -> io::Result<UdpSocket> {
|
|
pub fn bind_to(ip_addr: IpAddr, port: u16, reuseport: bool) -> io::Result<UdpSocket> {
|
|
|
- let config = SocketConfig::default().reuseport(reuseport);
|
|
|
|
|
|
|
+ let config = SocketConfig {
|
|
|
|
|
+ reuseport,
|
|
|
|
|
+ ..Default::default()
|
|
|
|
|
+ };
|
|
|
bind_to_with_config(ip_addr, port, config)
|
|
bind_to_with_config(ip_addr, port, config)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-#[cfg(feature = "dev-context-only-utils")]
|
|
|
|
|
-pub async fn bind_to_async(
|
|
|
|
|
- ip_addr: IpAddr,
|
|
|
|
|
- port: u16,
|
|
|
|
|
- reuseport: bool,
|
|
|
|
|
-) -> io::Result<TokioUdpSocket> {
|
|
|
|
|
- let config = SocketConfig::default().reuseport(reuseport);
|
|
|
|
|
- let socket = bind_to_with_config_non_blocking(ip_addr, port, config)?;
|
|
|
|
|
- TokioUdpSocket::from_std(socket)
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
pub fn bind_to_localhost() -> io::Result<UdpSocket> {
|
|
pub fn bind_to_localhost() -> io::Result<UdpSocket> {
|
|
|
- bind_to(
|
|
|
|
|
- IpAddr::V4(Ipv4Addr::LOCALHOST),
|
|
|
|
|
- /*port:*/ 0,
|
|
|
|
|
- /*reuseport:*/ false,
|
|
|
|
|
- )
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-#[cfg(feature = "dev-context-only-utils")]
|
|
|
|
|
-pub async fn bind_to_localhost_async() -> io::Result<TokioUdpSocket> {
|
|
|
|
|
- bind_to_async(
|
|
|
|
|
- IpAddr::V4(Ipv4Addr::LOCALHOST),
|
|
|
|
|
- /*port:*/ 0,
|
|
|
|
|
- /*reuseport:*/ false,
|
|
|
|
|
- )
|
|
|
|
|
- .await
|
|
|
|
|
|
|
+ let config = sockets::SocketConfiguration::default();
|
|
|
|
|
+ sockets::bind_to_with_config(IpAddr::V4(Ipv4Addr::LOCALHOST), 0, config)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
pub fn bind_to_unspecified() -> io::Result<UdpSocket> {
|
|
pub fn bind_to_unspecified() -> io::Result<UdpSocket> {
|
|
|
- bind_to(
|
|
|
|
|
- IpAddr::V4(Ipv4Addr::UNSPECIFIED),
|
|
|
|
|
- /*port:*/ 0,
|
|
|
|
|
- /*reuseport:*/ false,
|
|
|
|
|
- )
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-#[cfg(feature = "dev-context-only-utils")]
|
|
|
|
|
-pub async fn bind_to_unspecified_async() -> io::Result<TokioUdpSocket> {
|
|
|
|
|
- bind_to_async(
|
|
|
|
|
- IpAddr::V4(Ipv4Addr::UNSPECIFIED),
|
|
|
|
|
- /*port:*/ 0,
|
|
|
|
|
- /*reuseport:*/ false,
|
|
|
|
|
- )
|
|
|
|
|
- .await
|
|
|
|
|
|
|
+ let config = sockets::SocketConfiguration::default();
|
|
|
|
|
+ sockets::bind_to_with_config(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0, config)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+#[deprecated(
|
|
|
|
|
+ since = "2.3.2",
|
|
|
|
|
+ note = "Please avoid this function in favor of sockets::bind_to_with_config"
|
|
|
|
|
+)]
|
|
|
|
|
+#[allow(deprecated)]
|
|
|
pub fn bind_to_with_config(
|
|
pub fn bind_to_with_config(
|
|
|
ip_addr: IpAddr,
|
|
ip_addr: IpAddr,
|
|
|
port: u16,
|
|
port: u16,
|
|
|
config: SocketConfig,
|
|
config: SocketConfig,
|
|
|
) -> io::Result<UdpSocket> {
|
|
) -> io::Result<UdpSocket> {
|
|
|
- let sock = udp_socket_with_config(config)?;
|
|
|
|
|
-
|
|
|
|
|
|
|
+ let sock = udp_socket_with_config(config.into())?;
|
|
|
let addr = SocketAddr::new(ip_addr, port);
|
|
let addr = SocketAddr::new(ip_addr, port);
|
|
|
-
|
|
|
|
|
sock.bind(&SockAddr::from(addr)).map(|_| sock.into())
|
|
sock.bind(&SockAddr::from(addr)).map(|_| sock.into())
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+#[deprecated(
|
|
|
|
|
+ since = "2.3.2",
|
|
|
|
|
+ note = "Please avoid this function, it is easy to misuse"
|
|
|
|
|
+)]
|
|
|
|
|
+#[allow(deprecated)]
|
|
|
pub fn bind_to_with_config_non_blocking(
|
|
pub fn bind_to_with_config_non_blocking(
|
|
|
ip_addr: IpAddr,
|
|
ip_addr: IpAddr,
|
|
|
port: u16,
|
|
port: u16,
|
|
|
config: SocketConfig,
|
|
config: SocketConfig,
|
|
|
) -> io::Result<UdpSocket> {
|
|
) -> io::Result<UdpSocket> {
|
|
|
- let sock = udp_socket_with_config(config)?;
|
|
|
|
|
|
|
+ let sock = udp_socket_with_config(config.into())?;
|
|
|
|
|
|
|
|
let addr = SocketAddr::new(ip_addr, port);
|
|
let addr = SocketAddr::new(ip_addr, port);
|
|
|
|
|
|
|
@@ -480,19 +417,28 @@ pub fn bind_to_with_config_non_blocking(
|
|
|
Ok(sock.into())
|
|
Ok(sock.into())
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+#[deprecated(
|
|
|
|
|
+ since = "2.3.2",
|
|
|
|
|
+ note = "Please avoid this function in favor of sockets::bind_common_with_config"
|
|
|
|
|
+)]
|
|
|
/// binds both a UdpSocket and a TcpListener
|
|
/// binds both a UdpSocket and a TcpListener
|
|
|
pub fn bind_common(ip_addr: IpAddr, port: u16) -> io::Result<(UdpSocket, TcpListener)> {
|
|
pub fn bind_common(ip_addr: IpAddr, port: u16) -> io::Result<(UdpSocket, TcpListener)> {
|
|
|
- let config = SocketConfig::default();
|
|
|
|
|
- bind_common_with_config(ip_addr, port, config)
|
|
|
|
|
|
|
+ let config = sockets::SocketConfiguration::default();
|
|
|
|
|
+ sockets::bind_common_with_config(ip_addr, port, config)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+#[deprecated(
|
|
|
|
|
+ since = "2.3.2",
|
|
|
|
|
+ note = "Please avoid this function in favor of sockets::bind_common_with_config"
|
|
|
|
|
+)]
|
|
|
|
|
+#[allow(deprecated)]
|
|
|
/// binds both a UdpSocket and a TcpListener on the same port
|
|
/// binds both a UdpSocket and a TcpListener on the same port
|
|
|
pub fn bind_common_with_config(
|
|
pub fn bind_common_with_config(
|
|
|
ip_addr: IpAddr,
|
|
ip_addr: IpAddr,
|
|
|
port: u16,
|
|
port: u16,
|
|
|
config: SocketConfig,
|
|
config: SocketConfig,
|
|
|
) -> io::Result<(UdpSocket, TcpListener)> {
|
|
) -> io::Result<(UdpSocket, TcpListener)> {
|
|
|
- let sock = udp_socket_with_config(config)?;
|
|
|
|
|
|
|
+ let sock = udp_socket_with_config(config.into())?;
|
|
|
|
|
|
|
|
let addr = SocketAddr::new(ip_addr, port);
|
|
let addr = SocketAddr::new(ip_addr, port);
|
|
|
let sock_addr = SockAddr::from(addr);
|
|
let sock_addr = SockAddr::from(addr);
|
|
@@ -500,16 +446,31 @@ pub fn bind_common_with_config(
|
|
|
.and_then(|_| TcpListener::bind(addr).map(|listener| (sock.into(), listener)))
|
|
.and_then(|_| TcpListener::bind(addr).map(|listener| (sock.into(), listener)))
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+#[deprecated(
|
|
|
|
|
+ since = "2.3.2",
|
|
|
|
|
+ note = "Please avoid this function, in favor of sockets::bind_two_in_range_with_offset_and_config"
|
|
|
|
|
+)]
|
|
|
|
|
+#[allow(deprecated)]
|
|
|
pub fn bind_two_in_range_with_offset(
|
|
pub fn bind_two_in_range_with_offset(
|
|
|
ip_addr: IpAddr,
|
|
ip_addr: IpAddr,
|
|
|
range: PortRange,
|
|
range: PortRange,
|
|
|
offset: u16,
|
|
offset: u16,
|
|
|
) -> io::Result<((u16, UdpSocket), (u16, UdpSocket))> {
|
|
) -> io::Result<((u16, UdpSocket), (u16, UdpSocket))> {
|
|
|
- let sock1_config = SocketConfig::default();
|
|
|
|
|
- let sock2_config = SocketConfig::default();
|
|
|
|
|
- bind_two_in_range_with_offset_and_config(ip_addr, range, offset, sock1_config, sock2_config)
|
|
|
|
|
|
|
+ let sock_config = sockets::SocketConfiguration::default();
|
|
|
|
|
+ sockets::bind_two_in_range_with_offset_and_config(
|
|
|
|
|
+ ip_addr,
|
|
|
|
|
+ range,
|
|
|
|
|
+ offset,
|
|
|
|
|
+ sock_config,
|
|
|
|
|
+ sock_config,
|
|
|
|
|
+ )
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+#[deprecated(
|
|
|
|
|
+ since = "2.3.2",
|
|
|
|
|
+ note = "Please avoid this function, in favor of sockets::bind_two_in_range_with_offset_and_config"
|
|
|
|
|
+)]
|
|
|
|
|
+#[allow(deprecated)]
|
|
|
pub fn bind_two_in_range_with_offset_and_config(
|
|
pub fn bind_two_in_range_with_offset_and_config(
|
|
|
ip_addr: IpAddr,
|
|
ip_addr: IpAddr,
|
|
|
range: PortRange,
|
|
range: PortRange,
|
|
@@ -522,6 +483,7 @@ pub fn bind_two_in_range_with_offset_and_config(
|
|
|
"range too small to find two ports with the correct offset".to_string(),
|
|
"range too small to find two ports with the correct offset".to_string(),
|
|
|
));
|
|
));
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
for port in range.0..range.1 {
|
|
for port in range.0..range.1 {
|
|
|
if let Ok(first_bind) = bind_to_with_config(ip_addr, port, sock1_config) {
|
|
if let Ok(first_bind) = bind_to_with_config(ip_addr, port, sock1_config) {
|
|
|
if range.1.saturating_sub(port) >= offset {
|
|
if range.1.saturating_sub(port) >= offset {
|
|
@@ -571,9 +533,10 @@ pub fn find_available_ports_in_range<const N: usize>(
|
|
|
.take(range.len()) // never take the same value twice
|
|
.take(range.len()) // never take the same value twice
|
|
|
.peekable();
|
|
.peekable();
|
|
|
let mut num = 0;
|
|
let mut num = 0;
|
|
|
|
|
+ let config = sockets::SocketConfiguration::default();
|
|
|
while num < N {
|
|
while num < N {
|
|
|
let port_to_try = next_port_to_try.next().unwrap(); // this unwrap never fails since we exit earlier
|
|
let port_to_try = next_port_to_try.next().unwrap(); // this unwrap never fails since we exit earlier
|
|
|
- match bind_common(ip_addr, port_to_try) {
|
|
|
|
|
|
|
+ match sockets::bind_common_with_config(ip_addr, port_to_try, config) {
|
|
|
Ok(_) => {
|
|
Ok(_) => {
|
|
|
result[num] = port_to_try;
|
|
result[num] = port_to_try;
|
|
|
num = num.saturating_add(1);
|
|
num = num.saturating_add(1);
|
|
@@ -588,20 +551,36 @@ pub fn find_available_ports_in_range<const N: usize>(
|
|
|
Ok(result)
|
|
Ok(result)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+#[deprecated(
|
|
|
|
|
+ since = "2.3.2",
|
|
|
|
|
+ note = "Please avoid this function, in favor of sockets::bind_more_with_config"
|
|
|
|
|
+)]
|
|
|
|
|
+#[allow(deprecated)]
|
|
|
pub fn bind_more_with_config(
|
|
pub fn bind_more_with_config(
|
|
|
socket: UdpSocket,
|
|
socket: UdpSocket,
|
|
|
num: usize,
|
|
num: usize,
|
|
|
config: SocketConfig,
|
|
config: SocketConfig,
|
|
|
) -> io::Result<Vec<UdpSocket>> {
|
|
) -> io::Result<Vec<UdpSocket>> {
|
|
|
- let addr = socket.local_addr().unwrap();
|
|
|
|
|
- let ip = addr.ip();
|
|
|
|
|
- let port = addr.port();
|
|
|
|
|
- std::iter::once(Ok(socket))
|
|
|
|
|
- .chain((1..num).map(|_| bind_to_with_config(ip, port, config)))
|
|
|
|
|
- .collect()
|
|
|
|
|
|
|
+ if !PLATFORM_SUPPORTS_SOCKET_CONFIGS {
|
|
|
|
|
+ if num > 1 {
|
|
|
|
|
+ warn!(
|
|
|
|
|
+ "bind_more_with_config() only supports 1 socket on this platform ({} requested)",
|
|
|
|
|
+ num
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+ Ok(vec![socket])
|
|
|
|
|
+ } else {
|
|
|
|
|
+ let addr = socket.local_addr().unwrap();
|
|
|
|
|
+ let ip = addr.ip();
|
|
|
|
|
+ let port = addr.port();
|
|
|
|
|
+ std::iter::once(Ok(socket))
|
|
|
|
|
+ .chain((1..num).map(|_| bind_to_with_config(ip, port, config)))
|
|
|
|
|
+ .collect()
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
#[cfg(test)]
|
|
|
|
|
+#[allow(deprecated)]
|
|
|
mod tests {
|
|
mod tests {
|
|
|
use {
|
|
use {
|
|
|
super::*,
|
|
super::*,
|