From 7a67efa8689273c81b69a46cbd5a9984d593289a Mon Sep 17 00:00:00 2001 From: travis laduke Date: Tue, 28 Mar 2023 14:51:03 -0700 Subject: [PATCH 1/2] Fail the app when binding to a port fails tokio is was eating the panics and continuing on with no socket listening on 53 making tokio crash would take a bunch of rewrite i think, so i moved the `bind` calls out to a different, non-async fn --- src/init.rs | 16 +++++++++++----- src/server.rs | 16 ++++++++++++---- tests/service/mod.rs | 17 ++++++++++++++++- 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/src/init.rs b/src/init.rs index 70fe5fa..c350984 100644 --- a/src/init.rs +++ b/src/init.rs @@ -222,11 +222,17 @@ impl Launcher { None }; - tokio::spawn( - server - .clone() - .listen(ip, Duration::new(1, 0), tls_cert, chain, key), - ); + let (tcp_socket, udp_socket) = Server::bind(ip).await?; + + tokio::spawn(server.clone().listen( + ip, + Duration::new(1, 0), + tls_cert, + chain, + key, + tcp_socket, + udp_socket, + )); } return Ok(ztauthority); diff --git a/src/server.rs b/src/server.rs index 22d6205..914e768 100644 --- a/src/server.rs +++ b/src/server.rs @@ -2,6 +2,7 @@ use std::{ net::{IpAddr, SocketAddr}, time::Duration, }; +use anyhow::Context; use tracing::info; use openssl::{ @@ -23,6 +24,15 @@ impl Server { Self(zt) } + pub async fn bind(ip: IpAddr) -> Result<(TcpListener, UdpSocket), anyhow::Error> { + let sa = SocketAddr::new(ip, 53); + + let tcp = TcpListener::bind(sa).await.with_context(|| "Failed to bind TCP port 53")?; + let udp = UdpSocket::bind(sa).await.with_context(|| "Failed to bind UDP port 53")?; + + return Ok((tcp, udp)); + } + // listener routine for TCP and UDP. pub async fn listen( self, @@ -31,11 +41,9 @@ impl Server { certs: Option, cert_chain: Option>, key: Option>, + tcp: TcpListener, + udp: UdpSocket, ) -> Result<(), anyhow::Error> { - let sa = SocketAddr::new(ip, 53); - let tcp = TcpListener::bind(sa).await?; - let udp = UdpSocket::bind(sa).await?; - let mut sf = ServerFuture::new(init_catalog(self.0).await?); if let (Some(certs), Some(key)) = (certs.clone(), key.clone()) { diff --git a/tests/service/mod.rs b/tests/service/mod.rs index 9051ea1..31c4b4e 100644 --- a/tests/service/mod.rs +++ b/tests/service/mod.rs @@ -239,8 +239,23 @@ impl Service { for ip in listen_ips.clone() { let server = Server::new(ztauthority.to_owned()); + + let (tcp_socket, udp_socket) = match Server::bind(ip.ip()).await { + Ok(x) => x, + Err(e) => { + panic!("Could not bind port. {}", e); + } + }; info!("Serving {}", ip.clone()); - tokio::spawn(server.listen(ip.ip(), Duration::new(1, 0), None, None, None)); + tokio::spawn(server.listen( + ip.ip(), + Duration::new(1, 0), + None, + None, + None, + tcp_socket, + udp_socket, + )); } listen_ips From 7c1a92a02047dfc4acea20e8270a2b24a701bb16 Mon Sep 17 00:00:00 2001 From: travis laduke Date: Wed, 29 Mar 2023 10:44:56 -0700 Subject: [PATCH 2/2] Hacked in checking the DoT socket too --- src/init.rs | 4 ++-- src/server.rs | 25 ++++++++++++++++--------- tests/service/mod.rs | 4 ++-- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/init.rs b/src/init.rs index c350984..bf478f7 100644 --- a/src/init.rs +++ b/src/init.rs @@ -222,16 +222,16 @@ impl Launcher { None }; - let (tcp_socket, udp_socket) = Server::bind(ip).await?; + let (tcp_socket, udp_socket, tls_socket) = Server::bind(ip, chain.is_some()).await?; tokio::spawn(server.clone().listen( - ip, Duration::new(1, 0), tls_cert, chain, key, tcp_socket, udp_socket, + tls_socket )); } diff --git a/src/server.rs b/src/server.rs index 914e768..3e5b260 100644 --- a/src/server.rs +++ b/src/server.rs @@ -24,35 +24,42 @@ impl Server { Self(zt) } - pub async fn bind(ip: IpAddr) -> Result<(TcpListener, UdpSocket), anyhow::Error> { + pub async fn bind(ip: IpAddr, use_dot: bool) -> Result<(TcpListener, UdpSocket, Option), anyhow::Error> { let sa = SocketAddr::new(ip, 53); let tcp = TcpListener::bind(sa).await.with_context(|| "Failed to bind TCP port 53")?; let udp = UdpSocket::bind(sa).await.with_context(|| "Failed to bind UDP port 53")?; - return Ok((tcp, udp)); + + let tls = match use_dot { + true => TcpListener::bind(SocketAddr::new(ip, 853)).await.with_context(|| "Failed to bind TCP port 853 (DoT)").ok(), + false => None + }; + + return Ok((tcp, udp, tls)); } // listener routine for TCP and UDP. pub async fn listen( self, - ip: IpAddr, tcp_timeout: Duration, certs: Option, cert_chain: Option>, key: Option>, tcp: TcpListener, udp: UdpSocket, + dot: Option, ) -> Result<(), anyhow::Error> { let mut sf = ServerFuture::new(init_catalog(self.0).await?); - if let (Some(certs), Some(key)) = (certs.clone(), key.clone()) { - info!("Configuring DoT Listener"); - let tls = TcpListener::bind(SocketAddr::new(ip, 853)).await?; + if let Some(dot) = dot { + if let (Some(certs), Some(key)) = (certs.clone(), key.clone()) { + info!("Configuring DoT Listener"); - match sf.register_tls_listener(tls, tcp_timeout, ((certs, cert_chain), key)) { - Ok(_) => {} - Err(e) => tracing::error!("Cannot start DoT listener: {}", e), + match sf.register_tls_listener(dot, tcp_timeout, ((certs, cert_chain), key)) { + Ok(_) => {} + Err(e) => tracing::error!("Cannot start DoT listener: {}", e), + } } } diff --git a/tests/service/mod.rs b/tests/service/mod.rs index 31c4b4e..afe845c 100644 --- a/tests/service/mod.rs +++ b/tests/service/mod.rs @@ -240,7 +240,7 @@ impl Service { for ip in listen_ips.clone() { let server = Server::new(ztauthority.to_owned()); - let (tcp_socket, udp_socket) = match Server::bind(ip.ip()).await { + let (tcp_socket, udp_socket, tls_socket) = match Server::bind(ip.ip(), false).await { Ok(x) => x, Err(e) => { panic!("Could not bind port. {}", e); @@ -248,13 +248,13 @@ impl Service { }; info!("Serving {}", ip.clone()); tokio::spawn(server.listen( - ip.ip(), Duration::new(1, 0), None, None, None, tcp_socket, udp_socket, + tls_socket )); }