From 95b943716fc433c2e4d0b23d2be617527c5add25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Burnichon?= Date: Tue, 24 Oct 2023 16:36:30 +0200 Subject: [PATCH 1/3] Add capability to change keep_alive configuration --- src/server.rs | 46 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/src/server.rs b/src/server.rs index 929d96eb3..23bb7a7d4 100644 --- a/src/server.rs +++ b/src/server.rs @@ -6,6 +6,7 @@ use std::future::Future; use std::net::SocketAddr; #[cfg(feature = "tls")] use std::path::Path; +use std::time::Duration; use futures_util::{future, FutureExt, TryFuture, TryStream, TryStreamExt}; use hyper::server::conn::AddrIncoming; @@ -29,6 +30,7 @@ where Server { pipeline: false, filter, + tcp_keepalive_config: TcpKeepaliveConfig::default(), } } @@ -37,6 +39,22 @@ where pub struct Server { pipeline: bool, filter: F, + tcp_keepalive_config: TcpKeepaliveConfig, +} + +#[derive(Default, Debug, Clone, Copy)] +struct TcpKeepaliveConfig { + time: Option, + interval: Option, + retries: Option, +} + +impl TcpKeepaliveConfig { + fn configure(&self, incoming: &mut AddrIncoming) { + incoming.set_keepalive(self.time); + incoming.set_keepalive_interval(self.interval); + incoming.set_keepalive_retries(self.retries); + } } /// A Warp Server ready to filter requests over TLS. @@ -64,9 +82,10 @@ macro_rules! into_service { } macro_rules! addr_incoming { - ($addr:expr) => {{ + ($this:ident, $addr:expr) => {{ let mut incoming = AddrIncoming::bind($addr)?; incoming.set_nodelay(true); + $this.configure(&mut incoming); let addr = incoming.local_addr(); (addr, incoming) }}; @@ -75,7 +94,7 @@ macro_rules! addr_incoming { macro_rules! bind_inner { ($this:ident, $addr:expr) => {{ let service = into_service!($this.filter); - let (addr, incoming) = addr_incoming!($addr); + let (addr, incoming) = addr_incoming!($this.tcp_keepalive_config, $addr); let srv = HyperServer::builder(incoming) .http1_pipeline_flush($this.pipeline) .serve(service); @@ -84,7 +103,7 @@ macro_rules! bind_inner { (tls: $this:ident, $addr:expr) => {{ let service = into_service!($this.server.filter); - let (addr, incoming) = addr_incoming!($addr); + let (addr, incoming) = addr_incoming!($this.server.tcp_keepalive_config, $addr); let tls = $this.tls.build()?; let srv = HyperServer::builder(crate::tls::TlsAcceptor::new(tls, incoming)) .http1_pipeline_flush($this.server.pipeline) @@ -400,6 +419,27 @@ where self } + /// Set the duration to remain idle before sending TCP keepalive probes. + /// + /// If `None` is specified, keepalive is disabled. + pub fn set_keepalive(mut self, time: Option) -> Self { + self.tcp_keepalive_config.time = time; + self + } + + /// Set the duration between two successive TCP keepalive retransmissions, + /// if acknowledgement to the previous keepalive transmission is not received. + pub fn set_keepalive_interval(mut self, interval: Option) -> Self { + self.tcp_keepalive_config.interval = interval; + self + } + + /// Set the number of retransmissions to be carried out before declaring that remote end is not available. + pub fn set_keepalive_retries(mut self, retries: Option) -> Self { + self.tcp_keepalive_config.retries = retries; + self + } + /// Configure a server to use TLS. /// /// *This function requires the `"tls"` feature.* From 206b35a67f2ef7a1502d58a6201ad53bf8287a8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Burnichon?= Date: Tue, 24 Oct 2023 16:57:41 +0200 Subject: [PATCH 2/3] avoid using expression in macro --- src/server.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/server.rs b/src/server.rs index 23bb7a7d4..ce7b66706 100644 --- a/src/server.rs +++ b/src/server.rs @@ -94,7 +94,8 @@ macro_rules! addr_incoming { macro_rules! bind_inner { ($this:ident, $addr:expr) => {{ let service = into_service!($this.filter); - let (addr, incoming) = addr_incoming!($this.tcp_keepalive_config, $addr); + let config = &$this.tcp_keepalive_config; + let (addr, incoming) = addr_incoming!(config, $addr); let srv = HyperServer::builder(incoming) .http1_pipeline_flush($this.pipeline) .serve(service); @@ -103,7 +104,8 @@ macro_rules! bind_inner { (tls: $this:ident, $addr:expr) => {{ let service = into_service!($this.server.filter); - let (addr, incoming) = addr_incoming!($this.server.tcp_keepalive_config, $addr); + let config = &$this.server.tcp_keepalive_config; + let (addr, incoming) = addr_incoming!(config, $addr); let tls = $this.tls.build()?; let srv = HyperServer::builder(crate::tls::TlsAcceptor::new(tls, incoming)) .http1_pipeline_flush($this.server.pipeline) From f051117851e03897ad2d8f87ae7aea78af60b1b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Burnichon?= Date: Tue, 24 Oct 2023 17:02:04 +0200 Subject: [PATCH 3/3] Rename methods to include tcp in names --- src/server.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/server.rs b/src/server.rs index ce7b66706..feea30f8a 100644 --- a/src/server.rs +++ b/src/server.rs @@ -424,20 +424,20 @@ where /// Set the duration to remain idle before sending TCP keepalive probes. /// /// If `None` is specified, keepalive is disabled. - pub fn set_keepalive(mut self, time: Option) -> Self { + pub fn set_tcp_keepalive(mut self, time: Option) -> Self { self.tcp_keepalive_config.time = time; self } /// Set the duration between two successive TCP keepalive retransmissions, /// if acknowledgement to the previous keepalive transmission is not received. - pub fn set_keepalive_interval(mut self, interval: Option) -> Self { + pub fn set_tcp_keepalive_interval(mut self, interval: Option) -> Self { self.tcp_keepalive_config.interval = interval; self } /// Set the number of retransmissions to be carried out before declaring that remote end is not available. - pub fn set_keepalive_retries(mut self, retries: Option) -> Self { + pub fn set_tcp_keepalive_retries(mut self, retries: Option) -> Self { self.tcp_keepalive_config.retries = retries; self }