From 65def4e6e028537a232ed8a1c4446ef89a1e0c0b Mon Sep 17 00:00:00 2001 From: Jonathan Parris Date: Wed, 8 Nov 2023 14:25:02 -0700 Subject: [PATCH 1/2] Adds local_address as an option Endpoint builder. --- tonic/src/transport/channel/endpoint.rs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/tonic/src/transport/channel/endpoint.rs b/tonic/src/transport/channel/endpoint.rs index 07910fe06..f76c76c19 100644 --- a/tonic/src/transport/channel/endpoint.rs +++ b/tonic/src/transport/channel/endpoint.rs @@ -9,7 +9,7 @@ use bytes::Bytes; use http::{uri::Uri, HeaderValue}; use hyper::rt; use hyper_util::client::legacy::connect::HttpConnector; -use std::{fmt, future::Future, pin::Pin, str::FromStr, time::Duration}; +use std::{fmt, future::Future, net::IpAddr, pin::Pin, str::FromStr, time::Duration}; use tower_service::Service; /// Channel builder. @@ -37,6 +37,7 @@ pub struct Endpoint { pub(crate) connect_timeout: Option, pub(crate) http2_adaptive_window: Option, pub(crate) executor: SharedExec, + pub(crate) local_address: Option, } impl Endpoint { @@ -325,12 +326,30 @@ impl Endpoint { ) } + /// Set the local address + /// + /// This sets the IP address the client will use. By default we let hyper select the IP address. + /// ``` + /// # use std::net::IpAddr; + /// # use std::str::FromStr; + /// # use tonic::transport::Endpoint; + /// # let mut builder = Endpoint::from_static("https://example.com"); + /// # builder.local_address(IpAddr::from_str("127.0.0.1").expect("Unable to parse IP address")); + /// ``` + pub fn local_address(self, addr: IpAddr) -> Self { + Endpoint { + local_address: Some(addr), + ..self + } + } + pub(crate) fn http_connector(&self) -> service::Connector { let mut http = HttpConnector::new(); http.enforce_http(false); http.set_nodelay(self.tcp_nodelay); http.set_keepalive(self.tcp_keepalive); http.set_connect_timeout(self.connect_timeout); + http.set_local_address(self.local_address); self.connector(http) } @@ -452,6 +471,7 @@ impl From for Endpoint { connect_timeout: None, http2_adaptive_window: None, executor: SharedExec::tokio(), + local_address: None, } } } From 4341f0d1598e2d2499de818c96d4cb8403936baf Mon Sep 17 00:00:00 2001 From: Jonathan Parris Date: Thu, 16 Jan 2025 14:28:16 -0700 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: tottoto --- tonic/src/transport/channel/endpoint.rs | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/tonic/src/transport/channel/endpoint.rs b/tonic/src/transport/channel/endpoint.rs index f76c76c19..16934f34f 100644 --- a/tonic/src/transport/channel/endpoint.rs +++ b/tonic/src/transport/channel/endpoint.rs @@ -36,8 +36,8 @@ pub struct Endpoint { pub(crate) http2_max_header_list_size: Option, pub(crate) connect_timeout: Option, pub(crate) http2_adaptive_window: Option, - pub(crate) executor: SharedExec, pub(crate) local_address: Option, + pub(crate) executor: SharedExec, } impl Endpoint { @@ -326,19 +326,12 @@ impl Endpoint { ) } - /// Set the local address + /// Set the local address. /// - /// This sets the IP address the client will use. By default we let hyper select the IP address. - /// ``` - /// # use std::net::IpAddr; - /// # use std::str::FromStr; - /// # use tonic::transport::Endpoint; - /// # let mut builder = Endpoint::from_static("https://example.com"); - /// # builder.local_address(IpAddr::from_str("127.0.0.1").expect("Unable to parse IP address")); - /// ``` - pub fn local_address(self, addr: IpAddr) -> Self { + /// This sets the IP address the client will use. By default we let hyper select the IP address. + pub fn local_address(self, addr: Option) -> Self { Endpoint { - local_address: Some(addr), + local_address: addr, ..self } }