From c4153d65b659d12a188bc8150f53ad943adbfe94 Mon Sep 17 00:00:00 2001 From: Luca Joss <43531661+ljoss17@users.noreply.github.com> Date: Fri, 8 Nov 2024 09:26:21 +0100 Subject: [PATCH] Fix gRPC over IPv6 (#4231) * Improve TLS configuration to only configure if required * Add changelog entry * Move and improve changelog --- .../4237-improve-tls-configuration.md | 3 +++ crates/relayer/src/error.rs | 4 ++++ crates/relayer/src/util.rs | 23 +++++++++---------- 3 files changed, 18 insertions(+), 12 deletions(-) create mode 100644 .changelog/unreleased/bug-fixes/ibc-relayer/4237-improve-tls-configuration.md diff --git a/.changelog/unreleased/bug-fixes/ibc-relayer/4237-improve-tls-configuration.md b/.changelog/unreleased/bug-fixes/ibc-relayer/4237-improve-tls-configuration.md new file mode 100644 index 0000000000..1c246d6aef --- /dev/null +++ b/.changelog/unreleased/bug-fixes/ibc-relayer/4237-improve-tls-configuration.md @@ -0,0 +1,3 @@ +- Fix an issue where Hermes would fail to connect to gRPC servers + with an IPv6 address. + ([\#4237](https://github.com/informalsystems/hermes/issues/4237)) \ No newline at end of file diff --git a/crates/relayer/src/error.rs b/crates/relayer/src/error.rs index 8fa5bd4847..c8ac6d656d 100644 --- a/crates/relayer/src/error.rs +++ b/crates/relayer/src/error.rs @@ -607,6 +607,10 @@ define_error! { [ TraceError ] |_| { "HTTP response body error" }, + InvalidHttpHost + { endpoint: String } + |e| { format!("HTTP host is invalid for the endpoint `{}`", e.endpoint) }, + JsonDeserialize [ TraceError ] |_| { "JSON deserialization error" }, diff --git a/crates/relayer/src/util.rs b/crates/relayer/src/util.rs index 497999af6f..9799e6cc4e 100644 --- a/crates/relayer/src/util.rs +++ b/crates/relayer/src/util.rs @@ -21,28 +21,27 @@ pub async fn create_grpc_client( grpc_addr: &tonic::transport::Uri, client_constructor: impl FnOnce(tonic::transport::Channel) -> T, ) -> Result { - let tls_config = tonic::transport::ClientTlsConfig::new().with_native_roots(); let builder = tonic::transport::Channel::builder(grpc_addr.clone()); // Don't configures TLS for the endpoint if using IPv6 - let builder = if is_ipv6(grpc_addr) { - builder - } else { + let builder = if grpc_addr.scheme() == Some(&http::uri::Scheme::HTTPS) { + let domain = grpc_addr + .host() + .map(|d| d.replace(['[', ']'], "")) + .ok_or_else(|| crate::error::Error::invalid_http_host(grpc_addr.to_string()))?; + let tls_config = tonic::transport::ClientTlsConfig::new() + .with_native_roots() + .domain_name(domain); builder .tls_config(tls_config) .map_err(crate::error::Error::grpc_transport)? + } else { + builder }; + let channel = builder .connect() .await .map_err(crate::error::Error::grpc_transport)?; Ok(client_constructor(channel)) } - -fn is_ipv6(uri: &tonic::transport::Uri) -> bool { - if let Some(host) = uri.host() { - host.starts_with('[') && host.ends_with(']') - } else { - false - } -}