mirror of
https://github.com/uqbar-dao/nectar.git
synced 2024-12-23 00:21:38 +03:00
fix: reserve ws port early and enforce it (hopefully)
This commit is contained in:
parent
abdac56660
commit
85d97c685b
@ -100,18 +100,18 @@ pub fn deserialize_headers(hashmap: HashMap<String, String>) -> HeaderMap {
|
|||||||
header_map
|
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 {
|
for port in start_at..end_at {
|
||||||
let bind_addr = format!("0.0.0.0:{}", port);
|
let bind_addr = format!("0.0.0.0:{}", port);
|
||||||
if is_port_available(&bind_addr).await {
|
if let Some(bound) = is_port_available(&bind_addr).await {
|
||||||
return Some(port);
|
return Some(bound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn is_port_available(bind_addr: &str) -> bool {
|
pub async fn is_port_available(bind_addr: &str) -> Option<TcpListener> {
|
||||||
TcpListener::bind(bind_addr).await.is_ok()
|
TcpListener::bind(bind_addr).await.ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _binary_encoded_string_to_bytes(s: &str) -> Vec<u8> {
|
pub fn _binary_encoded_string_to_bytes(s: &str) -> Vec<u8> {
|
||||||
|
@ -44,7 +44,7 @@ const DEFAULT_PROVIDERS_MAINNET: &str = include_str!("eth/default_providers_main
|
|||||||
async fn serve_register_fe(
|
async fn serve_register_fe(
|
||||||
home_directory_path: &str,
|
home_directory_path: &str,
|
||||||
our_ip: String,
|
our_ip: String,
|
||||||
ws_networking_port: Option<u16>,
|
ws_networking: (tokio::net::TcpListener, bool),
|
||||||
http_server_port: u16,
|
http_server_port: u16,
|
||||||
testnet: bool,
|
testnet: bool,
|
||||||
) -> (Identity, Vec<u8>, Keyfile) {
|
) -> (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 (tx, mut rx) = mpsc::channel::<(Identity, Keyfile, Vec<u8>)>(1);
|
||||||
let (our, decoded_keyfile, encoded_keyfile) = tokio::select! {
|
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")
|
panic!("registration failed")
|
||||||
}
|
}
|
||||||
Some((our, decoded_keyfile, encoded_keyfile)) = rx.recv() => {
|
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 {
|
let http_server_port = if let Some(port) = http_port {
|
||||||
match http::utils::find_open_port(*port, port + 1).await {
|
match http::utils::find_open_port(*port, port + 1).await {
|
||||||
Some(port) => port,
|
Some(bound) => bound.local_addr().unwrap().port(),
|
||||||
None => {
|
None => {
|
||||||
println!(
|
println!(
|
||||||
"error: couldn't bind {}; first available port found was {}. \
|
"error: couldn't bind {}; first available port found was {}. \
|
||||||
@ -268,14 +268,17 @@ async fn main() {
|
|||||||
port,
|
port,
|
||||||
http::utils::find_open_port(*port, port + 1000)
|
http::utils::find_open_port(*port, port + 1000)
|
||||||
.await
|
.await
|
||||||
.expect("no ports found in range"),
|
.expect("no ports found in range")
|
||||||
|
.local_addr()
|
||||||
|
.unwrap()
|
||||||
|
.port(),
|
||||||
);
|
);
|
||||||
panic!();
|
panic!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
match http::utils::find_open_port(8080, 8999).await {
|
match http::utils::find_open_port(8080, 8999).await {
|
||||||
Some(port) => port,
|
Some(bound) => bound.local_addr().unwrap().port(),
|
||||||
None => {
|
None => {
|
||||||
println!(
|
println!(
|
||||||
"error: couldn't bind any ports between 8080 and 8999. \
|
"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!(
|
println!(
|
||||||
"login or register at http://localhost:{}\r",
|
"login or register at http://localhost:{}\r",
|
||||||
http_server_port
|
http_server_port
|
||||||
@ -295,7 +320,7 @@ async fn main() {
|
|||||||
let (our, encoded_keyfile, decoded_keyfile) = serve_register_fe(
|
let (our, encoded_keyfile, decoded_keyfile) = serve_register_fe(
|
||||||
home_directory_path,
|
home_directory_path,
|
||||||
our_ip.to_string(),
|
our_ip.to_string(),
|
||||||
ws_networking_port.copied(),
|
(ws_tcp_handle, flag_used),
|
||||||
http_server_port,
|
http_server_port,
|
||||||
on_testnet, // true if testnet mode
|
on_testnet, // true if testnet mode
|
||||||
)
|
)
|
||||||
@ -309,7 +334,7 @@ async fn main() {
|
|||||||
serve_register_fe(
|
serve_register_fe(
|
||||||
&home_directory_path,
|
&home_directory_path,
|
||||||
our_ip.to_string(),
|
our_ip.to_string(),
|
||||||
ws_networking_port.copied(),
|
(ws_tcp_handle, flag_used),
|
||||||
http_server_port,
|
http_server_port,
|
||||||
on_testnet, // true if testnet mode
|
on_testnet, // true if testnet mode
|
||||||
)
|
)
|
||||||
|
@ -117,7 +117,7 @@ pub async fn register(
|
|||||||
tx: RegistrationSender,
|
tx: RegistrationSender,
|
||||||
kill_rx: oneshot::Receiver<bool>,
|
kill_rx: oneshot::Receiver<bool>,
|
||||||
ip: String,
|
ip: String,
|
||||||
ws_networking_port: Option<u16>,
|
ws_networking: (tokio::net::TcpListener, bool),
|
||||||
http_port: u16,
|
http_port: u16,
|
||||||
keyfile: Option<Vec<u8>>,
|
keyfile: Option<Vec<u8>>,
|
||||||
testnet: bool,
|
testnet: bool,
|
||||||
@ -127,29 +127,12 @@ pub async fn register(
|
|||||||
let net_keypair = Arc::new(serialized_networking_keypair.as_ref().to_vec());
|
let net_keypair = Arc::new(serialized_networking_keypair.as_ref().to_vec());
|
||||||
let tx = Arc::new(tx);
|
let tx = Arc::new(tx);
|
||||||
|
|
||||||
let (ws_port, flag_used) = if let Some(port) = ws_networking_port {
|
let ws_port = ws_networking.0.local_addr().unwrap().port();
|
||||||
(
|
let ws_flag_used = ws_networking.1;
|
||||||
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)
|
|
||||||
};
|
|
||||||
|
|
||||||
// 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 {
|
let our_temp_id = Arc::new(Identity {
|
||||||
networking_key: format!("0x{}", public_key),
|
networking_key: format!("0x{}", public_key),
|
||||||
name: "".to_string(),
|
name: "".to_string(),
|
||||||
@ -185,6 +168,7 @@ pub async fn register(
|
|||||||
let net_keypair = warp::any().map(move || net_keypair.clone());
|
let net_keypair = warp::any().map(move || net_keypair.clone());
|
||||||
let tx = warp::any().map(move || tx.clone());
|
let tx = warp::any().map(move || tx.clone());
|
||||||
let ip = warp::any().map(move || ip.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/"));
|
let static_files = warp::path("static").and(static_dir!("src/register-ui/build/static/"));
|
||||||
|
|
||||||
@ -228,10 +212,10 @@ pub async fn register(
|
|||||||
Vec<u8>,
|
Vec<u8>,
|
||||||
)>(keyfile.as_ref())
|
)>(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::content_length_limit(1024 * 16))
|
||||||
.and(warp::body::json())
|
.and(warp::body::json())
|
||||||
.and(ip.clone())
|
.and(ip.clone())
|
||||||
.and(warp::any().map(move || if flag_used { Some(ws_port) } else { None }))
|
.and(ws_port.clone())
|
||||||
.and(tx.clone())
|
.and(tx.clone())
|
||||||
.and_then(move |boot_info, ip, ws_port, tx| {
|
.and_then(move |boot_info, ip, ws_port, tx| {
|
||||||
let import_provider = import_provider.clone();
|
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::content_length_limit(1024 * 16))
|
||||||
.and(warp::body::json())
|
.and(warp::body::json())
|
||||||
.and(ip)
|
.and(ip)
|
||||||
.and(warp::any().map(move || if flag_used { Some(ws_port) } else { None }))
|
.and(ws_port.clone())
|
||||||
.and(tx.clone())
|
.and(tx.clone())
|
||||||
.and(keyfile.clone())
|
.and(keyfile.clone())
|
||||||
.and_then(move |boot_info, ip, ws_port, tx, keyfile| {
|
.and_then(move |boot_info, ip, ws_port, tx, keyfile| {
|
||||||
@ -320,31 +304,6 @@ pub async fn register(
|
|||||||
.and(keyfile)
|
.and(keyfile)
|
||||||
.and_then(confirm_change_network_keys),
|
.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();
|
let mut headers = HeaderMap::new();
|
||||||
headers.insert(
|
headers.insert(
|
||||||
|
Loading…
Reference in New Issue
Block a user