Skip to content

Commit

Permalink
Fix gRPC over IPv6 (#4231)
Browse files Browse the repository at this point in the history
* Improve TLS configuration to only configure if required

* Add changelog entry

* Move and improve changelog
  • Loading branch information
ljoss17 authored Nov 8, 2024
1 parent 0e45fc8 commit c4153d6
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -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))
4 changes: 4 additions & 0 deletions crates/relayer/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,10 @@ define_error! {
[ TraceError<reqwest::Error> ]
|_| { "HTTP response body error" },

InvalidHttpHost
{ endpoint: String }
|e| { format!("HTTP host is invalid for the endpoint `{}`", e.endpoint) },

JsonDeserialize
[ TraceError<serde_json::Error> ]
|_| { "JSON deserialization error" },
Expand Down
23 changes: 11 additions & 12 deletions crates/relayer/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,28 +21,27 @@ pub async fn create_grpc_client<T>(
grpc_addr: &tonic::transport::Uri,
client_constructor: impl FnOnce(tonic::transport::Channel) -> T,
) -> Result<T, crate::error::Error> {
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
}
}

0 comments on commit c4153d6

Please sign in to comment.