bind on random ports

This commit is contained in:
Milo Turner 2020-03-07 23:50:41 -05:00
parent 778995ae15
commit 4a70ba8df7
4 changed files with 102 additions and 16 deletions

74
Cargo.lock generated
View File

@ -12,6 +12,15 @@ version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "130aac562c0dd69c56b3b1cc8ffd2e17be31d0b6c25b61c96b76231aa23e39e1"
[[package]]
name = "c2-chacha"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb"
dependencies = [
"ppv-lite86",
]
[[package]]
name = "cfg-if"
version = "0.1.10"
@ -34,10 +43,22 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
[[package]]
name = "getrandom"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "hptp"
version = "0.1.0"
dependencies = [
"rand",
"tokio",
]
@ -153,6 +174,12 @@ version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "237844750cfbb86f67afe27eee600dfbbcb6188d734139b534cbfbf4f96792ae"
[[package]]
name = "ppv-lite86"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
[[package]]
name = "proc-macro2"
version = "1.0.9"
@ -171,6 +198,47 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
dependencies = [
"getrandom",
"libc",
"rand_chacha",
"rand_core",
"rand_hc",
]
[[package]]
name = "rand_chacha"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853"
dependencies = [
"c2-chacha",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
dependencies = [
"getrandom",
]
[[package]]
name = "rand_hc"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
dependencies = [
"rand_core",
]
[[package]]
name = "slab"
version = "0.4.2"
@ -227,6 +295,12 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]]
name = "winapi"
version = "0.2.8"

View File

@ -5,8 +5,7 @@ extern crate tokio;
extern crate thiserror;
use hptp::log::Logger;
use std::net::Ipv4Addr;
use tokio::net::UdpSocket;
// use tokio::net::UdpSocket;
#[derive(Error, Debug)]
enum Error {
@ -37,7 +36,9 @@ fn main() {
}
async fn start(log: &mut Logger) -> Result<(), Error> {
let sock = udp_listen_or_retry(3700, 4).await?;
let sock = hptp::udp_retrying_bind(16, hptp::random_port)
.await
.map_err(|_| Error::NoPortAvail)?;
log.bound(sock.local_addr()?.port()).await;
let (mut rx, _tx) = sock.split();
@ -51,13 +52,3 @@ async fn start(log: &mut Logger) -> Result<(), Error> {
.await;
}
}
async fn udp_listen_or_retry(init_port: u16, max_tries: u16) -> Result<UdpSocket, Error> {
for tries in 0..max_tries {
let port = init_port + tries;
if let Ok(sock) = UdpSocket::bind((Ipv4Addr::LOCALHOST, port)).await {
return Ok(sock);
}
}
Err(Error::NoPortAvail)
}

View File

@ -8,4 +8,5 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
tokio = {version = "0.2.*", features = ["io-std", "io-util"]}
tokio = {version = "0.2.*", features = ["io-std", "io-util", "udp"]}
rand = "0.7.*"

View File

@ -1,4 +1,24 @@
pub const SEND_GREETING: &'static str = "*pat*";
pub const RECV_GREETING: &'static str = "owo";
extern crate rand;
pub mod log;
use std::net::Ipv4Addr;
use tokio::net::UdpSocket;
pub async fn udp_retrying_bind<F>(max_tries: usize, mut pick_port: F) -> Result<UdpSocket, ()>
where
F: FnMut() -> u16,
{
for _ in 0..max_tries {
let port = pick_port();
if let Ok(sock) = UdpSocket::bind((Ipv4Addr::LOCALHOST, port)).await {
return Ok(sock);
}
}
Err(())
}
pub fn random_port() -> u16 {
use rand::distributions::{Distribution, Uniform};
Uniform::new(1025, 65535u16).sample(&mut rand::thread_rng())
}