From db72fe688c71821d3a979409a574f4e14ee9913b Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Thu, 12 Nov 2020 10:13:25 -0800 Subject: [PATCH 1/6] http: enable PING frames on h2 clients Signed-off-by: Eliza Weisman --- linkerd/proxy/http/src/h2.rs | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/linkerd/proxy/http/src/h2.rs b/linkerd/proxy/http/src/h2.rs index 35cf4af158..6b35b1b3d3 100644 --- a/linkerd/proxy/http/src/h2.rs +++ b/linkerd/proxy/http/src/h2.rs @@ -6,6 +6,7 @@ use hyper::{ client::conn::{self, SendRequest}, }; use linkerd2_error::Error; +use std::time::Duration; use std::{ future::Future, marker::PhantomData, @@ -20,6 +21,7 @@ use tracing_futures::Instrument; pub struct Settings { pub initial_stream_window_size: Option, pub initial_connection_window_size: Option, + pub keepalive_timeout: Option, } #[derive(Debug)] @@ -79,6 +81,7 @@ where let Settings { initial_connection_window_size, initial_stream_window_size, + keepalive_timeout, } = self.h2_settings; let connect = self @@ -89,12 +92,25 @@ where Box::pin( async move { let io = connect.err_into::().await?; - - let (tx, conn) = conn::Builder::new() + let mut builder = conn::Builder::new(); + builder .http2_only(true) .http2_initial_stream_window_size(initial_stream_window_size) .http2_initial_connection_window_size(initial_connection_window_size) - .executor(trace::Executor::new()) + .executor(trace::Executor::new()); + + // Configure HTTP/2 PING frames + if let Some(timeout) = keepalive_timeout { + // XXX(eliza): is this a reasonable interval between + // PING frames? + let interval = timeout / 4; + builder + .http2_keep_alive_timeout(timeout) + .http2_keep_alive_interval(interval) + .http2_keep_alive_while_idle(true); + } + + let (tx, conn) = conn::Builder::new() .handshake(io) .instrument(trace_span!("handshake")) .await?; From 2c3a8ed20860f967035720b1a51445e398879430 Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Thu, 12 Nov 2020 10:44:33 -0800 Subject: [PATCH 2/6] http: add PING frames to h2 servers Signed-off-by: Eliza Weisman --- linkerd/proxy/http/src/detect.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/linkerd/proxy/http/src/detect.rs b/linkerd/proxy/http/src/detect.rs index 2029239562..32380acbde 100644 --- a/linkerd/proxy/http/src/detect.rs +++ b/linkerd/proxy/http/src/detect.rs @@ -58,6 +58,16 @@ impl DetectHttp { .http2_initial_stream_window_size(h2.initial_stream_window_size) .http2_initial_connection_window_size(h2.initial_connection_window_size); + // Configure HTTP/2 PING frames + if let Some(timeout) = h2.keepalive_timeout { + // XXX(eliza): is this a reasonable interval between + // PING frames? + let interval = timeout / 4; + server + .http2_keep_alive_timeout(timeout) + .http2_keep_alive_interval(interval); + } + Self { server, tcp, From a5d769ebf51a1d702c320b3bbdd7f25f2835ba0f Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Thu, 12 Nov 2020 10:51:43 -0800 Subject: [PATCH 3/6] http: wire up keepalive through config Signed-off-by: Eliza Weisman --- linkerd/app/src/env.rs | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/linkerd/app/src/env.rs b/linkerd/app/src/env.rs index 1f59d3ff8e..8051629bb9 100644 --- a/linkerd/app/src/env.rs +++ b/linkerd/app/src/env.rs @@ -371,28 +371,36 @@ pub fn parse_config(strings: &S) -> Result let ingress_mode = parse(strings, ENV_INGRESS_MODE, parse_bool)?.unwrap_or(false); let outbound = { + let keepalive = outbound_accept_keepalive?; let bind = listen::Bind::new( outbound_listener_addr? .unwrap_or_else(|| parse_socket_addr(DEFAULT_OUTBOUND_LISTEN_ADDR).unwrap()), - outbound_accept_keepalive?, + keepalive, ); let server = ServerConfig { bind: bind.with_orig_dst_addr(outbound_orig_dst), - h2_settings, + h2_settings: h2::Settings { + keepalive_timeout: keepalive, + ..h2_settings + }, }; let cache_max_idle_age = outbound_cache_max_idle_age?.unwrap_or(DEFAULT_OUTBOUND_ROUTER_MAX_IDLE_AGE); let max_idle = outbound_max_idle_per_endoint?.unwrap_or(DEFAULT_OUTBOUND_MAX_IDLE_CONNS_PER_ENDPOINT); + let keepalive = outbound_connect_keepalive?; let connect = ConnectConfig { - keepalive: outbound_connect_keepalive?, + keepalive, timeout: outbound_connect_timeout?.unwrap_or(DEFAULT_OUTBOUND_CONNECT_TIMEOUT), backoff: parse_backoff( strings, OUTBOUND_CONNECT_BASE, DEFAULT_OUTBOUND_CONNECT_BACKOFF, )?, - h2_settings, + h2_settings: h2::Settings { + keepalive_timeout: Keepalive, + ..h2_settings, + }, h1_settings: h1::PoolSettings { max_idle, idle_timeout: cache_max_idle_age, @@ -425,28 +433,36 @@ pub fn parse_config(strings: &S) -> Result }; let inbound = { + let keepalive = inbound_accept_keepalive?; let bind = listen::Bind::new( inbound_listener_addr? .unwrap_or_else(|| parse_socket_addr(DEFAULT_INBOUND_LISTEN_ADDR).unwrap()), - inbound_accept_keepalive?, + keepalive, ); let server = ServerConfig { bind: bind.with_orig_dst_addr(inbound_orig_dst), - h2_settings, + h2_settings: h2::Settings { + keepalive_timeout: keepalive, + ..h2_settings + }, }; let cache_max_idle_age = inbound_cache_max_idle_age?.unwrap_or(DEFAULT_INBOUND_ROUTER_MAX_IDLE_AGE); let max_idle = inbound_max_idle_per_endpoint?.unwrap_or(DEFAULT_INBOUND_MAX_IDLE_CONNS_PER_ENDPOINT); + let keepalive = inbound_connect_keepalive?; let connect = ConnectConfig { - keepalive: inbound_connect_keepalive?, + keepalive, timeout: inbound_connect_timeout?.unwrap_or(DEFAULT_INBOUND_CONNECT_TIMEOUT), backoff: parse_backoff( strings, INBOUND_CONNECT_BASE, DEFAULT_INBOUND_CONNECT_BACKOFF, )?, - h2_settings, + h2_settings: h2::Settings { + keepalive_timeout: keepalive, + ..h2_settings + }, h1_settings: h1::PoolSettings { max_idle, idle_timeout: cache_max_idle_age, From 98d5d1f3e827b787d4426100e012bb8e1f1c52c6 Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Thu, 12 Nov 2020 11:48:52 -0800 Subject: [PATCH 4/6] Update linkerd/app/src/env.rs Co-authored-by: Oliver Gould --- linkerd/app/src/env.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linkerd/app/src/env.rs b/linkerd/app/src/env.rs index 8051629bb9..719df27f16 100644 --- a/linkerd/app/src/env.rs +++ b/linkerd/app/src/env.rs @@ -398,7 +398,7 @@ pub fn parse_config(strings: &S) -> Result DEFAULT_OUTBOUND_CONNECT_BACKOFF, )?, h2_settings: h2::Settings { - keepalive_timeout: Keepalive, + keepalive_timeout: keepalive, ..h2_settings, }, h1_settings: h1::PoolSettings { From a74335d30a7eaa2e9ba13164dffae7e511be04b4 Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Thu, 12 Nov 2020 12:43:38 -0800 Subject: [PATCH 5/6] fixywixy Signed-off-by: Eliza Weisman --- linkerd/app/src/env.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/linkerd/app/src/env.rs b/linkerd/app/src/env.rs index 8051629bb9..16f62eb059 100644 --- a/linkerd/app/src/env.rs +++ b/linkerd/app/src/env.rs @@ -340,6 +340,7 @@ pub fn parse_config(strings: &S) -> Result initial_connection_window_size: Some( initial_connection_window_size?.unwrap_or(DEFAULT_INITIAL_CONNECTION_WINDOW_SIZE), ), + ..Default::default() }; let buffer_capacity = buffer_capacity?.unwrap_or(DEFAULT_BUFFER_CAPACITY); @@ -399,7 +400,7 @@ pub fn parse_config(strings: &S) -> Result )?, h2_settings: h2::Settings { keepalive_timeout: Keepalive, - ..h2_settings, + ..h2_settings }, h1_settings: h1::PoolSettings { max_idle, From ccb8b38bfb7200884c5f3147c4f7ab3cba35b7c4 Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Thu, 12 Nov 2020 14:01:20 -0800 Subject: [PATCH 6/6] hmm, maybe try not throwing away the builder Signed-off-by: Eliza Weisman --- linkerd/proxy/http/src/h2.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linkerd/proxy/http/src/h2.rs b/linkerd/proxy/http/src/h2.rs index 6b35b1b3d3..3ef16e2a01 100644 --- a/linkerd/proxy/http/src/h2.rs +++ b/linkerd/proxy/http/src/h2.rs @@ -110,7 +110,7 @@ where .http2_keep_alive_while_idle(true); } - let (tx, conn) = conn::Builder::new() + let (tx, conn) = builder .handshake(io) .instrument(trace_span!("handshake")) .await?;