From ab3f5956d4ba0b95d0102cd6116a9d8c877c156b Mon Sep 17 00:00:00 2001 From: Aiden McClelland Date: Thu, 15 Jun 2023 11:47:02 -0600 Subject: [PATCH] ipv6 --- backend/src/bin/embassy-init.rs | 28 +++++++++++++++++--- backend/src/bin/embassyd.rs | 20 +++++++++++--- backend/src/install/mod.rs | 19 +++++++++----- backend/src/net/vhost.rs | 14 +++++++--- backend/src/net/web_server.rs | 46 +++++++++++++++++++++++---------- 5 files changed, 97 insertions(+), 30 deletions(-) diff --git a/backend/src/bin/embassy-init.rs b/backend/src/bin/embassy-init.rs index d8ea9d19c..ddc5fcdbf 100644 --- a/backend/src/bin/embassy-init.rs +++ b/backend/src/bin/embassy-init.rs @@ -1,3 +1,4 @@ +use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr}; use std::path::{Path, PathBuf}; use std::sync::Arc; use std::time::Duration; @@ -59,7 +60,14 @@ async fn setup_or_init(cfg_path: Option) -> Result<(), Error> { let ctx = InstallContext::init(cfg_path).await?; - let server = WebServer::install(([0, 0, 0, 0], 80).into(), ctx.clone()).await?; + let server = WebServer::install( + [ + SocketAddr::new(Ipv4Addr::UNSPECIFIED.into(), 80), + SocketAddr::new(Ipv6Addr::UNSPECIFIED.into(), 80), + ], + ctx.clone(), + ) + .await?; tokio::time::sleep(Duration::from_secs(1)).await; // let the record state that I hate this CHIME.play().await?; @@ -81,7 +89,14 @@ async fn setup_or_init(cfg_path: Option) -> Result<(), Error> { { let ctx = SetupContext::init(cfg_path).await?; - let server = WebServer::setup(([0, 0, 0, 0], 80).into(), ctx.clone()).await?; + let server = WebServer::setup( + [ + SocketAddr::new(Ipv4Addr::UNSPECIFIED.into(), 80), + SocketAddr::new(Ipv6Addr::UNSPECIFIED.into(), 80), + ], + ctx.clone(), + ) + .await?; tokio::time::sleep(Duration::from_secs(1)).await; // let the record state that I hate this CHIME.play().await?; @@ -192,7 +207,14 @@ async fn inner_main(cfg_path: Option) -> Result, Error ) .await?; - let server = WebServer::diagnostic(([0, 0, 0, 0], 80).into(), ctx.clone()).await?; + let server = WebServer::diagnostic( + [ + SocketAddr::new(Ipv4Addr::UNSPECIFIED.into(), 80), + SocketAddr::new(Ipv6Addr::UNSPECIFIED.into(), 80), + ], + ctx.clone(), + ) + .await?; let shutdown = ctx.shutdown.subscribe().recv().await.unwrap(); diff --git a/backend/src/bin/embassyd.rs b/backend/src/bin/embassyd.rs index ad245e9ca..6b3d5e188 100644 --- a/backend/src/bin/embassyd.rs +++ b/backend/src/bin/embassyd.rs @@ -1,3 +1,4 @@ +use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr}; use std::path::{Path, PathBuf}; use std::sync::Arc; @@ -26,7 +27,14 @@ async fn inner_main(cfg_path: Option) -> Result, Error ) .await?; embassy::hostname::sync_hostname(&rpc_ctx.account.read().await.hostname).await?; - let server = WebServer::main(([0, 0, 0, 0], 80).into(), rpc_ctx.clone()).await?; + let server = WebServer::main( + [ + SocketAddr::new(Ipv4Addr::UNSPECIFIED.into(), 80), + SocketAddr::new(Ipv6Addr::UNSPECIFIED.into(), 80), + ], + rpc_ctx.clone(), + ) + .await?; let mut shutdown_recv = rpc_ctx.shutdown.subscribe(); @@ -141,8 +149,14 @@ fn main() { ) .await?; - let server = - WebServer::diagnostic(([0, 0, 0, 0], 80).into(), ctx.clone()).await?; + let server = WebServer::diagnostic( + [ + SocketAddr::new(Ipv4Addr::UNSPECIFIED.into(), 80), + SocketAddr::new(Ipv6Addr::UNSPECIFIED.into(), 80), + ], + ctx.clone(), + ) + .await?; let mut shutdown = ctx.shutdown.subscribe(); diff --git a/backend/src/install/mod.rs b/backend/src/install/mod.rs index e4dd57ab2..e5aaa7ec2 100644 --- a/backend/src/install/mod.rs +++ b/backend/src/install/mod.rs @@ -46,7 +46,7 @@ use crate::s9pk::reader::S9pkReader; use crate::status::{MainStatus, Status}; use crate::util::io::{copy_and_shutdown, response_to_reader}; use crate::util::serde::{display_serializable, Port}; -use crate::util::{assure_send, display_none, AsyncFileExt, Version}; +use crate::util::{display_none, AsyncFileExt, Version}; use crate::version::{Current, VersionT}; use crate::volume::{asset_dir, script_dir}; use crate::{Error, ErrorKind, ResultExt}; @@ -474,12 +474,17 @@ pub async fn sideload( } }); - recv.await; - - Response::builder() - .status(StatusCode::OK) - .body(Body::empty()) - .with_kind(ErrorKind::Network) + if let Ok(_) = recv.await { + Response::builder() + .status(StatusCode::OK) + .body(Body::empty()) + .with_kind(ErrorKind::Network) + } else { + Response::builder() + .status(StatusCode::INTERNAL_SERVER_ERROR) + .body(Body::from("installation aborted before upload completed")) + .with_kind(ErrorKind::Network) + } } .boxed() }); diff --git a/backend/src/net/vhost.rs b/backend/src/net/vhost.rs index 23f1d84f0..73c6aa37c 100644 --- a/backend/src/net/vhost.rs +++ b/backend/src/net/vhost.rs @@ -1,6 +1,6 @@ use std::collections::BTreeMap; use std::convert::Infallible; -use std::net::{IpAddr, SocketAddr}; +use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; use std::str::FromStr; use std::sync::{Arc, Weak}; @@ -88,9 +88,15 @@ struct VHostServer { impl VHostServer { async fn new(port: u16, ssl: Arc) -> Result { // check if port allowed - let listener = TcpListener::bind(SocketAddr::new([0, 0, 0, 0].into(), port)) - .await - .with_kind(crate::ErrorKind::Network)?; + let listener = TcpListener::bind( + [ + SocketAddr::new(Ipv4Addr::UNSPECIFIED.into(), 80), + SocketAddr::new(Ipv6Addr::UNSPECIFIED.into(), 80), + ] + .as_ref(), + ) + .await + .with_kind(crate::ErrorKind::Network)?; let mapping = Arc::new(RwLock::new(BTreeMap::new())); Ok(Self { mapping: Arc::downgrade(&mapping), diff --git a/backend/src/net/web_server.rs b/backend/src/net/web_server.rs index c2e25a413..5cfca0024 100644 --- a/backend/src/net/web_server.rs +++ b/backend/src/net/web_server.rs @@ -4,8 +4,10 @@ use std::net::SocketAddr; use futures::future::ready; use futures::FutureExt; use helpers::NonDetachingJoinHandle; +use hyper::server::conn::AddrIncoming; use hyper::service::{make_service_fn, service_fn}; use hyper::Server; +use tokio::net::TcpListener; use tokio::sync::oneshot; use crate::context::{DiagnosticContext, InstallContext, RpcContext, SetupContext}; @@ -20,17 +22,23 @@ pub struct WebServer { thread: NonDetachingJoinHandle<()>, } impl WebServer { - pub fn new(bind: SocketAddr, router: HttpHandler) -> Self { + pub fn new( + bind: impl AsRef<[SocketAddr]> + Send + Sync + 'static, + router: HttpHandler, + ) -> Self { let (shutdown, shutdown_recv) = oneshot::channel(); let thread = NonDetachingJoinHandle::from(tokio::spawn(async move { - let server = Server::bind(&bind) - .http1_preserve_header_case(true) - .http1_title_case_headers(true) - .serve(make_service_fn(move |_| { - let router = router.clone(); - ready(Ok::<_, Infallible>(service_fn(move |req| router(req)))) - })) - .with_graceful_shutdown(shutdown_recv.map(|_| ())); + let server = Server::builder( + AddrIncoming::from_listener(TcpListener::bind(bind.as_ref()).await.unwrap()) + .unwrap(), + ) + .http1_preserve_header_case(true) + .http1_title_case_headers(true) + .serve(make_service_fn(move |_| { + let router = router.clone(); + ready(Ok::<_, Infallible>(service_fn(move |req| router(req)))) + })) + .with_graceful_shutdown(shutdown_recv.map(|_| ())); if let Err(e) = server.await { tracing::error!("Spawning hyper server error: {}", e); } @@ -43,19 +51,31 @@ impl WebServer { self.thread.await.unwrap() } - pub async fn main(bind: SocketAddr, ctx: RpcContext) -> Result { + pub async fn main( + bind: impl AsRef<[SocketAddr]> + Send + Sync + 'static, + ctx: RpcContext, + ) -> Result { Ok(Self::new(bind, main_ui_server_router(ctx).await?)) } - pub async fn setup(bind: SocketAddr, ctx: SetupContext) -> Result { + pub async fn setup( + bind: impl AsRef<[SocketAddr]> + Send + Sync + 'static, + ctx: SetupContext, + ) -> Result { Ok(Self::new(bind, setup_ui_file_router(ctx).await?)) } - pub async fn diagnostic(bind: SocketAddr, ctx: DiagnosticContext) -> Result { + pub async fn diagnostic( + bind: impl AsRef<[SocketAddr]> + Send + Sync + 'static, + ctx: DiagnosticContext, + ) -> Result { Ok(Self::new(bind, diag_ui_file_router(ctx).await?)) } - pub async fn install(bind: SocketAddr, ctx: InstallContext) -> Result { + pub async fn install( + bind: impl AsRef<[SocketAddr]> + Send + Sync + 'static, + ctx: InstallContext, + ) -> Result { Ok(Self::new(bind, install_ui_file_router(ctx).await?)) } }