feat: added the ability to start new listeners
This commit is contained in:
parent
ba5145c5ae
commit
f5afd60086
67
Cargo.lock
generated
67
Cargo.lock
generated
@ -89,6 +89,12 @@ version = "1.0.95"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
|
checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "arc-swap"
|
||||||
|
version = "1.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-compression"
|
name = "async-compression"
|
||||||
version = "0.4.18"
|
version = "0.4.18"
|
||||||
@ -189,6 +195,31 @@ version = "1.4.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aws-lc-rs"
|
||||||
|
version = "1.12.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4c2b7ddaa2c56a367ad27a094ad8ef4faacf8a617c2575acb2ba88949df999ca"
|
||||||
|
dependencies = [
|
||||||
|
"aws-lc-sys",
|
||||||
|
"paste",
|
||||||
|
"zeroize",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aws-lc-sys"
|
||||||
|
version = "0.25.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "71b2ddd3ada61a305e1d8bb6c005d1eaa7d14d903681edfc400406d523a9b491"
|
||||||
|
dependencies = [
|
||||||
|
"bindgen",
|
||||||
|
"cc",
|
||||||
|
"cmake",
|
||||||
|
"dunce",
|
||||||
|
"fs_extra",
|
||||||
|
"paste",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "axum"
|
name = "axum"
|
||||||
version = "0.7.9"
|
version = "0.7.9"
|
||||||
@ -290,6 +321,7 @@ version = "0.7.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "56bac90848f6a9393ac03c63c640925c4b7c8ca21654de40d53f55964667c7d8"
|
checksum = "56bac90848f6a9393ac03c63c640925c4b7c8ca21654de40d53f55964667c7d8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"arc-swap",
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"http",
|
"http",
|
||||||
@ -298,6 +330,9 @@ dependencies = [
|
|||||||
"hyper",
|
"hyper",
|
||||||
"hyper-util",
|
"hyper-util",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
"rustls",
|
||||||
|
"rustls-pemfile",
|
||||||
|
"rustls-pki-types",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-rustls",
|
"tokio-rustls",
|
||||||
"tower 0.4.13",
|
"tower 0.4.13",
|
||||||
@ -490,6 +525,15 @@ dependencies = [
|
|||||||
"vec_map",
|
"vec_map",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cmake"
|
||||||
|
version = "0.1.53"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e24a03c8b52922d68a1589ad61032f2c1aa5a8158d2aa0d93c6e9534944bbad6"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "codee"
|
name = "codee"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
@ -799,6 +843,12 @@ version = "0.1.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "669a445ee724c5c69b1b06fe0b63e70a1c84bc9bb7d9696cd4f4e3ec45050408"
|
checksum = "669a445ee724c5c69b1b06fe0b63e70a1c84bc9bb7d9696cd4f4e3ec45050408"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dunce"
|
||||||
|
version = "1.0.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "either"
|
name = "either"
|
||||||
version = "1.13.0"
|
version = "1.13.0"
|
||||||
@ -922,6 +972,12 @@ dependencies = [
|
|||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fs_extra"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures"
|
name = "futures"
|
||||||
version = "0.3.31"
|
version = "0.3.31"
|
||||||
@ -2674,6 +2730,7 @@ version = "0.23.21"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8f287924602bf649d949c63dc8ac8b235fa5387d394020705b80c4eb597ce5b8"
|
checksum = "8f287924602bf649d949c63dc8ac8b235fa5387d394020705b80c4eb597ce5b8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"aws-lc-rs",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
"rustls-webpki",
|
"rustls-webpki",
|
||||||
@ -2681,6 +2738,15 @@ dependencies = [
|
|||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls-pemfile"
|
||||||
|
version = "2.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50"
|
||||||
|
dependencies = [
|
||||||
|
"rustls-pki-types",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-pki-types"
|
name = "rustls-pki-types"
|
||||||
version = "1.10.1"
|
version = "1.10.1"
|
||||||
@ -2693,6 +2759,7 @@ version = "0.102.8"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9"
|
checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"aws-lc-rs",
|
||||||
"ring",
|
"ring",
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
"untrusted",
|
"untrusted",
|
||||||
|
|||||||
@ -20,7 +20,7 @@ tower-http = { version = "0.5", features = ["fs", "compression-br", "compression
|
|||||||
wasm-bindgen = "0.2"
|
wasm-bindgen = "0.2"
|
||||||
thiserror = "1"
|
thiserror = "1"
|
||||||
http = "1"
|
http = "1"
|
||||||
axum-server = { version = "^0.7", features = ["tokio-rustls"], optional = true }
|
axum-server = { version = "^0.7", features = ["tokio-rustls", "tls-rustls"], optional = true }
|
||||||
tracing-subscriber = { version = "0.3", features = ["chrono", "env-filter", "serde", "tracing", "tracing-serde"], optional = true }
|
tracing-subscriber = { version = "0.3", features = ["chrono", "env-filter", "serde", "tracing", "tracing-serde"], optional = true }
|
||||||
structopt = { version = "0.3", optional = true }
|
structopt = { version = "0.3", optional = true }
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
|
|||||||
@ -3,8 +3,97 @@ use std::{
|
|||||||
sync::{Arc, RwLock},
|
sync::{Arc, RwLock},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use axum::routing::{get, post, Router};
|
||||||
|
use axum_server::{service::MakeService, tls_rustls::RustlsConfig};
|
||||||
|
use sqlx::SqlitePool;
|
||||||
use tokio::task::JoinHandle;
|
use tokio::task::JoinHandle;
|
||||||
|
|
||||||
pub type BeaconListenerHandle = JoinHandle<()>;
|
pub struct BeaconListenerHandle {
|
||||||
|
join_handle: JoinHandle<()>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BeaconListenerHandle {
|
||||||
|
pub fn is_finished(&self) -> bool {
|
||||||
|
self.join_handle.is_finished()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn abort(&self) {
|
||||||
|
self.join_handle.abort()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub type BeaconListenerMap = Arc<RwLock<HashMap<i64, BeaconListenerHandle>>>;
|
pub type BeaconListenerMap = Arc<RwLock<HashMap<i64, BeaconListenerHandle>>>;
|
||||||
|
|
||||||
|
pub async fn start_all_listeners(beacon_listener_map: BeaconListenerMap, db: SqlitePool) -> Result<(), crate::error::Error> {
|
||||||
|
let listener_ids = sqlx::query!("SELECT listener_id FROM beacon_listener")
|
||||||
|
.fetch_all(&db)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
tracing::info!("Starting {} listener(s)...", listener_ids.len());
|
||||||
|
|
||||||
|
for listener in listener_ids {
|
||||||
|
start_listener(Arc::clone(&beacon_listener_map), listener.listener_id, db.clone()).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct ListenerState {
|
||||||
|
db: SqlitePool
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn start_listener(beacon_listener_map: BeaconListenerMap, listener_id: i64, db: SqlitePool) -> Result<(), crate::error::Error> {
|
||||||
|
{
|
||||||
|
let Ok(blm_handle) = beacon_listener_map.read() else {
|
||||||
|
return Err(crate::error::Error::Generic("Could not acquire write lock on beacon listener map".to_string()));
|
||||||
|
};
|
||||||
|
|
||||||
|
if blm_handle.get(&listener_id).is_some() {
|
||||||
|
return Err(crate::error::Error::Generic("Beacon listener already started".to_string()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let listener = sqlx::query!("SELECT * FROM beacon_listener WHERE listener_id = ?", listener_id)
|
||||||
|
.fetch_one(&db)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let app: Router<()> = Router::new()
|
||||||
|
.route("/register_beacon", post(|| async {}))
|
||||||
|
.route("/test", get(|| async {
|
||||||
|
"hi there"
|
||||||
|
}))
|
||||||
|
.with_state(ListenerState {
|
||||||
|
db
|
||||||
|
});
|
||||||
|
|
||||||
|
let hidden_app = Router::new().nest("/hidden_sparse", app);
|
||||||
|
|
||||||
|
let tls_config = RustlsConfig::from_pem(
|
||||||
|
listener.certificate.as_bytes().to_vec(),
|
||||||
|
listener.privkey.as_bytes().to_vec()
|
||||||
|
).await?;
|
||||||
|
|
||||||
|
let addr = std::net::SocketAddr::from(([0, 0, 0, 0], listener.port as u16));
|
||||||
|
|
||||||
|
tracing::debug!("Starting listener {}, {}, on port {}", listener_id, listener.domain_name, listener.port);
|
||||||
|
|
||||||
|
let join_handle = tokio::task::spawn(async move {
|
||||||
|
let res = axum_server::tls_rustls::bind_rustls(addr, tls_config)
|
||||||
|
.serve(hidden_app.into_make_service())
|
||||||
|
.await;
|
||||||
|
|
||||||
|
if let Err(e) = res {
|
||||||
|
tracing::error!("error running sparse listener: {e:?}");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let Ok(mut blm_handle) = beacon_listener_map.write() else {
|
||||||
|
return Err(crate::error::Error::Generic("Could not acquire write lock on beacon listener map".to_string()));
|
||||||
|
};
|
||||||
|
|
||||||
|
blm_handle.insert(listener_id, BeaconListenerHandle {
|
||||||
|
join_handle
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|||||||
@ -111,7 +111,19 @@ pub async fn remove_listener(listener_id: i64) -> Result<(), ServerFnError> {
|
|||||||
|
|
||||||
#[server]
|
#[server]
|
||||||
pub async fn start_listener(listener_id: i64) -> Result<(), ServerFnError> {
|
pub async fn start_listener(listener_id: i64) -> Result<(), ServerFnError> {
|
||||||
unimplemented!()
|
let user = user::get_auth_session().await?;
|
||||||
|
|
||||||
|
if user.is_none() {
|
||||||
|
return Err(ServerFnError::<NoCustomError>::ServerError("You are not signed in!".to_owned()));
|
||||||
|
}
|
||||||
|
|
||||||
|
crate::beacon_handler::start_listener(
|
||||||
|
expect_context(),
|
||||||
|
listener_id,
|
||||||
|
expect_context()
|
||||||
|
).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
@ -193,7 +205,7 @@ fn DisplayListeners(listeners: Vec<PubListener>) -> impl IntoView {
|
|||||||
{listener.public_ip.clone()}
|
{listener.public_ip.clone()}
|
||||||
":"
|
":"
|
||||||
{listener.port}
|
{listener.port}
|
||||||
")"
|
") "
|
||||||
{match listener.active {
|
{match listener.active {
|
||||||
true => Either::Left(view! {
|
true => Either::Left(view! {
|
||||||
<span>"active!"</span>
|
<span>"active!"</span>
|
||||||
|
|||||||
@ -30,10 +30,6 @@ pub enum Command {
|
|||||||
/// Address to bind to for the management interface
|
/// Address to bind to for the management interface
|
||||||
#[structopt(default_value = "127.0.0.1:3000")]
|
#[structopt(default_value = "127.0.0.1:3000")]
|
||||||
management_address: SocketAddrV4,
|
management_address: SocketAddrV4,
|
||||||
|
|
||||||
/// Public address to bind to for the beacons to call back to
|
|
||||||
#[structopt(default_value = "127.0.0.1:5000")]
|
|
||||||
bind_address: SocketAddrV4,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Extract the public key and print it to standard out
|
/// Extract the public key and print it to standard out
|
||||||
|
|||||||
@ -8,6 +8,8 @@ pub enum Error {
|
|||||||
TokioJoin(tokio::task::JoinError),
|
TokioJoin(tokio::task::JoinError),
|
||||||
#[cfg(feature = "ssr")]
|
#[cfg(feature = "ssr")]
|
||||||
Pbkdf2(pbkdf2::password_hash::errors::Error),
|
Pbkdf2(pbkdf2::password_hash::errors::Error),
|
||||||
|
#[cfg(feature = "ssr")]
|
||||||
|
Io(std::io::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for Error {
|
impl std::fmt::Display for Error {
|
||||||
@ -31,6 +33,10 @@ impl std::fmt::Display for Error {
|
|||||||
Error::Pbkdf2(err) => {
|
Error::Pbkdf2(err) => {
|
||||||
write!(f, "password hash error: {err:?}")
|
write!(f, "password hash error: {err:?}")
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "ssr")]
|
||||||
|
Error::Io(err) => {
|
||||||
|
write!(f, "io error: {err:?}")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -42,6 +48,8 @@ impl std::error::Error for Error {
|
|||||||
Error::Sqlx(err) => Some(err),
|
Error::Sqlx(err) => Some(err),
|
||||||
#[cfg(feature = "ssr")]
|
#[cfg(feature = "ssr")]
|
||||||
Error::TokioJoin(err) => Some(err),
|
Error::TokioJoin(err) => Some(err),
|
||||||
|
#[cfg(feature = "ssr")]
|
||||||
|
Error::Io(err) => Some(err),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,3 +83,10 @@ impl From<pbkdf2::password_hash::errors::Error> for Error {
|
|||||||
Self::Pbkdf2(err)
|
Self::Pbkdf2(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "ssr")]
|
||||||
|
impl From<std::io::Error> for Error {
|
||||||
|
fn from(err: std::io::Error) -> Self {
|
||||||
|
Self::Io(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -79,9 +79,9 @@ async fn main() -> anyhow::Result<std::process::ExitCode> {
|
|||||||
tracing::info!("Done running database migrations!");
|
tracing::info!("Done running database migrations!");
|
||||||
|
|
||||||
match options.command.clone() {
|
match options.command.clone() {
|
||||||
Some(cli::Command::Serve { management_address, bind_address }) => {
|
Some(cli::Command::Serve { management_address }) => {
|
||||||
tracing::info!("Performing requested action, acting as web server");
|
tracing::info!("Performing requested action, acting as web server");
|
||||||
webserver::serve_web(management_address, bind_address, pool).await
|
webserver::serve_web(management_address, pool).await
|
||||||
}
|
}
|
||||||
Some(cli::Command::ExtractPubKey { }) => {
|
Some(cli::Command::ExtractPubKey { }) => {
|
||||||
Ok(ExitCode::SUCCESS)
|
Ok(ExitCode::SUCCESS)
|
||||||
@ -95,8 +95,7 @@ async fn main() -> anyhow::Result<std::process::ExitCode> {
|
|||||||
tracing::info!("Performing default action of acting as web server");
|
tracing::info!("Performing default action of acting as web server");
|
||||||
|
|
||||||
let default_management_ip = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 3000);
|
let default_management_ip = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 3000);
|
||||||
let default_beacon_ip = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 5000);
|
webserver::serve_web(default_management_ip, pool).await
|
||||||
webserver::serve_web(default_management_ip, default_beacon_ip, pool).await
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,7 @@ use {
|
|||||||
crate::db::user
|
crate::db::user
|
||||||
};
|
};
|
||||||
|
|
||||||
fn format_delta(time: chrono::TimeDelta) -> String {
|
pub fn format_delta(time: chrono::TimeDelta) -> String {
|
||||||
let seconds = time.num_seconds();
|
let seconds = time.num_seconds();
|
||||||
|
|
||||||
match seconds {
|
match seconds {
|
||||||
|
|||||||
@ -8,7 +8,7 @@ use tokio::signal;
|
|||||||
|
|
||||||
use sparse_server::app::*;
|
use sparse_server::app::*;
|
||||||
|
|
||||||
pub async fn serve_web(management_address: SocketAddrV4, _bind_address: SocketAddrV4, db: SqlitePool) -> anyhow::Result<ExitCode> {
|
pub async fn serve_web(management_address: SocketAddrV4, db: SqlitePool) -> anyhow::Result<ExitCode> {
|
||||||
let conf = get_configuration(None).unwrap();
|
let conf = get_configuration(None).unwrap();
|
||||||
let leptos_options = conf.leptos_options;
|
let leptos_options = conf.leptos_options;
|
||||||
let routes = generate_route_list(App);
|
let routes = generate_route_list(App);
|
||||||
@ -20,6 +20,8 @@ pub async fn serve_web(management_address: SocketAddrV4, _bind_address: SocketAd
|
|||||||
.br(true)
|
.br(true)
|
||||||
.zstd(true);
|
.zstd(true);
|
||||||
|
|
||||||
|
crate::beacon_handler::start_all_listeners(std::sync::Arc::clone(&beacon_listeners), db.clone()).await?;
|
||||||
|
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
.leptos_routes_with_context(
|
.leptos_routes_with_context(
|
||||||
&leptos_options,
|
&leptos_options,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user