fix: reserve ws port early and enforce it (hopefully)

This commit is contained in:
dr-frmr 2024-03-22 12:45:19 -06:00
parent abdac56660
commit 85d97c685b
No known key found for this signature in database
3 changed files with 48 additions and 64 deletions

View File

@ -100,18 +100,18 @@ pub fn deserialize_headers(hashmap: HashMap<String, String>) -> HeaderMap {
header_map
}
pub async fn find_open_port(start_at: u16, end_at: u16) -> Option<u16> {
pub async fn find_open_port(start_at: u16, end_at: u16) -> Option<TcpListener> {
for port in start_at..end_at {
let bind_addr = format!("0.0.0.0:{}", port);
if is_port_available(&bind_addr).await {
return Some(port);
if let Some(bound) = is_port_available(&bind_addr).await {
return Some(bound);
}
}
None
}
pub async fn is_port_available(bind_addr: &str) -> bool {
TcpListener::bind(bind_addr).await.is_ok()
pub async fn is_port_available(bind_addr: &str) -> Option<TcpListener> {
TcpListener::bind(bind_addr).await.ok()
}
pub fn _binary_encoded_string_to_bytes(s: &str) -> Vec<u8> {

View File

@ -44,7 +44,7 @@ const DEFAULT_PROVIDERS_MAINNET: &str = include_str!("eth/default_providers_main
async fn serve_register_fe(
home_directory_path: &str,
our_ip: String,
ws_networking_port: Option<u16>,
ws_networking: (tokio::net::TcpListener, bool),
http_server_port: u16,
testnet: bool,
) -> (Identity, Vec<u8>, Keyfile) {
@ -67,7 +67,7 @@ async fn serve_register_fe(
let (tx, mut rx) = mpsc::channel::<(Identity, Keyfile, Vec<u8>)>(1);
let (our, decoded_keyfile, encoded_keyfile) = tokio::select! {
_ = register::register(tx, kill_rx, our_ip, ws_networking_port, http_server_port, disk_keyfile, testnet) => {
_ = register::register(tx, kill_rx, our_ip, ws_networking, http_server_port, disk_keyfile, testnet) => {
panic!("registration failed")
}
Some((our, decoded_keyfile, encoded_keyfile)) = rx.recv() => {
@ -260,7 +260,7 @@ async fn main() {
let http_server_port = if let Some(port) = http_port {
match http::utils::find_open_port(*port, port + 1).await {
Some(port) => port,
Some(bound) => bound.local_addr().unwrap().port(),
None => {
println!(
"error: couldn't bind {}; first available port found was {}. \
@ -268,14 +268,17 @@ async fn main() {
port,
http::utils::find_open_port(*port, port + 1000)
.await
.expect("no ports found in range"),
.expect("no ports found in range")
.local_addr()
.unwrap()
.port(),
);
panic!();
}
}
} else {
match http::utils::find_open_port(8080, 8999).await {
Some(port) => port,
Some(bound) => bound.local_addr().unwrap().port(),
None => {
println!(
"error: couldn't bind any ports between 8080 and 8999. \
@ -286,6 +289,28 @@ async fn main() {
}
};
// if the --ws-port flag is used, bind to that port right away.
// if the flag is not used, find the first available port between 9000 and 65535.
// NOTE: if the node has a different port specified in its onchain (direct) id,
// booting will fail if the flag was used to select a different port.
// if the flag was not used, the bound port will be dropped in favor of the onchain port.
let (ws_tcp_handle, flag_used) = if let Some(port) = ws_networking_port {
(
http::utils::find_open_port(*port, port + 1)
.await
.expect("ws-port selected with flag could not be bound"),
true,
)
} else {
(
http::utils::find_open_port(9000, 65535)
.await
.expect("no ports found in range 9000-65535 for websocket server"),
false,
)
};
println!(
"login or register at http://localhost:{}\r",
http_server_port
@ -295,7 +320,7 @@ async fn main() {
let (our, encoded_keyfile, decoded_keyfile) = serve_register_fe(
home_directory_path,
our_ip.to_string(),
ws_networking_port.copied(),
(ws_tcp_handle, flag_used),
http_server_port,
on_testnet, // true if testnet mode
)
@ -309,7 +334,7 @@ async fn main() {
serve_register_fe(
&home_directory_path,
our_ip.to_string(),
ws_networking_port.copied(),
(ws_tcp_handle, flag_used),
http_server_port,
on_testnet, // true if testnet mode
)

View File

@ -117,7 +117,7 @@ pub async fn register(
tx: RegistrationSender,
kill_rx: oneshot::Receiver<bool>,
ip: String,
ws_networking_port: Option<u16>,
ws_networking: (tokio::net::TcpListener, bool),
http_port: u16,
keyfile: Option<Vec<u8>>,
testnet: bool,
@ -127,29 +127,12 @@ pub async fn register(
let net_keypair = Arc::new(serialized_networking_keypair.as_ref().to_vec());
let tx = Arc::new(tx);
let (ws_port, flag_used) = if let Some(port) = ws_networking_port {
(
crate::http::utils::find_open_port(port, port + 1)
.await
.expect(&format!(
"error: couldn't bind {}; first available port found was {}. \
Set an available port with `--ws-port` and try again.",
port,
crate::http::utils::find_open_port(port, port + 1000)
.await
.expect("no ports found in range"),
)),
true,
)
} else {
(crate::http::utils::find_open_port(9000, 65535)
.await
.expect(
"Unable to find free port between 9000 and 65535 for a new websocket, are you kidding?",
), false)
};
let ws_port = ws_networking.0.local_addr().unwrap().port();
let ws_flag_used = ws_networking.1;
// This is a temporary identity, passed to the UI. If it is confirmed through a /boot or /confirm-change-network-keys, then it will be used to replace the current identity
// This is a **temporary** identity, passed to the UI.
// If it is confirmed through a /boot or /confirm-change-network-keys,
// then it will be used to replace the current identity.
let our_temp_id = Arc::new(Identity {
networking_key: format!("0x{}", public_key),
name: "".to_string(),
@ -185,6 +168,7 @@ pub async fn register(
let net_keypair = warp::any().map(move || net_keypair.clone());
let tx = warp::any().map(move || tx.clone());
let ip = warp::any().map(move || ip.clone());
let ws_port = warp::any().map(move || if ws_flag_used { Some(ws_port) } else { None });
let static_files = warp::path("static").and(static_dir!("src/register-ui/build/static/"));
@ -228,10 +212,10 @@ pub async fn register(
Vec<u8>,
)>(keyfile.as_ref())
{
return warp::reply::json(&username);
return warp::reply::html(username);
}
}
warp::reply::json(&"")
warp::reply::html(String::new())
},
));
@ -282,7 +266,7 @@ pub async fn register(
.and(warp::body::content_length_limit(1024 * 16))
.and(warp::body::json())
.and(ip.clone())
.and(warp::any().map(move || if flag_used { Some(ws_port) } else { None }))
.and(ws_port.clone())
.and(tx.clone())
.and_then(move |boot_info, ip, ws_port, tx| {
let import_provider = import_provider.clone();
@ -294,7 +278,7 @@ pub async fn register(
.and(warp::body::content_length_limit(1024 * 16))
.and(warp::body::json())
.and(ip)
.and(warp::any().map(move || if flag_used { Some(ws_port) } else { None }))
.and(ws_port.clone())
.and(tx.clone())
.and(keyfile.clone())
.and_then(move |boot_info, ip, ws_port, tx, keyfile| {
@ -320,31 +304,6 @@ pub async fn register(
.and(keyfile)
.and_then(confirm_change_network_keys),
));
// .or(
// warp::path("our").and(warp::get().and(keyfile.clone()).and_then(move |keyfile| {
// if let Some(keyfile) = keyfile {
// if let Ok((username, _, _, _, _, _)) = bincode::deserialize::<(
// String,
// Vec<String>,
// Vec<u8>,
// Vec<u8>,
// Vec<u8>,
// Vec<u8>,
// )>(&keyfile)
// {
// return Ok(warp::reply::with_status(
// warp::reply::json(&username),
// StatusCode::OK,
// )
// .into_response());
// }
// }
// Ok(
// warp::reply::with_status(warp::reply::json(&""), StatusCode::OK)
// .into_response(),
// )
// })),
// );
let mut headers = HeaderMap::new();
headers.insert(