From 9a59e0db8fd2b61ad45a095c81fc7944fcd4ed4f Mon Sep 17 00:00:00 2001 From: Jonathan Parris Date: Wed, 8 Nov 2023 14:25:02 -0700 Subject: [PATCH] Adds local_address as an option Endpoint builder. --- tonic/src/transport/channel/endpoint.rs | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/tonic/src/transport/channel/endpoint.rs b/tonic/src/transport/channel/endpoint.rs index aaf977346..b781cd66e 100644 --- a/tonic/src/transport/channel/endpoint.rs +++ b/tonic/src/transport/channel/endpoint.rs @@ -9,9 +9,11 @@ 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; +// use crate::transport::E + /// Channel builder. /// /// This struct is used to build and configure HTTP/2 channels. @@ -37,6 +39,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 { @@ -324,6 +327,23 @@ impl Endpoint { self.tls.clone(), ) } + + /// 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 + } + } /// Create a channel from this config. pub async fn connect(&self) -> Result { @@ -332,6 +352,7 @@ impl Endpoint { 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); let connector = self.connector(http); @@ -440,6 +461,7 @@ impl From for Endpoint { connect_timeout: None, http2_adaptive_window: None, executor: SharedExec::tokio(), + local_address: None, } } }