From cedd1e37b820c14836ce6f110f49b124f56fcc86 Mon Sep 17 00:00:00 2001 From: Cao Ruijuan Date: Mon, 8 Apr 2024 18:33:51 +0800 Subject: [PATCH] feat: add bind_addr for NetworkOptions to enable TCPSocket.bind() --- rumqttc/CHANGELOG.md | 1 + rumqttc/src/eventloop.rs | 4 ++++ rumqttc/src/lib.rs | 15 ++++++++++++++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/rumqttc/CHANGELOG.md b/rumqttc/CHANGELOG.md index 1045cfcf..898f3936 100644 --- a/rumqttc/CHANGELOG.md +++ b/rumqttc/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * `size()` method on `Packet` calculates size once serialized. * `read()` and `write()` methods on `Packet`. * `ConnectionAborted` variant on `StateError` type to denote abrupt end to a connection +* `bind_addr` for `NetworkOptions` to enable `TCPSocket.bind()` ### Changed diff --git a/rumqttc/src/eventloop.rs b/rumqttc/src/eventloop.rs index a9b1ce8c..d0ee6a9c 100644 --- a/rumqttc/src/eventloop.rs +++ b/rumqttc/src/eventloop.rs @@ -324,6 +324,10 @@ pub(crate) async fn socket_connect( socket.set_recv_buffer_size(recv_buffer_size).unwrap(); } + if let Some(bind_addr) = network_options.bind_addr { + socket.bind(bind_addr)?; + } + #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] { if let Some(bind_device) = &network_options.bind_device { diff --git a/rumqttc/src/lib.rs b/rumqttc/src/lib.rs index 29cad1a3..0733b982 100644 --- a/rumqttc/src/lib.rs +++ b/rumqttc/src/lib.rs @@ -98,7 +98,10 @@ #[macro_use] extern crate log; -use std::fmt::{self, Debug, Formatter}; +use std::{ + fmt::{self, Debug, Formatter}, + net::{SocketAddr, ToSocketAddrs}, +}; #[cfg(any(feature = "use-rustls", feature = "websocket"))] use std::sync::Arc; @@ -370,6 +373,7 @@ pub struct NetworkOptions { tcp_send_buffer_size: Option, tcp_recv_buffer_size: Option, conn_timeout: u64, + bind_addr: Option, #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] bind_device: Option, } @@ -380,6 +384,7 @@ impl NetworkOptions { tcp_send_buffer_size: None, tcp_recv_buffer_size: None, conn_timeout: 5, + bind_addr: None, #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] bind_device: None, } @@ -404,6 +409,14 @@ impl NetworkOptions { self.conn_timeout } + /// bind connection to a specific socket address + pub fn set_bind_addr(&mut self, bind_addr: impl ToSocketAddrs) -> &mut Self { + self.bind_addr = bind_addr + .to_socket_addrs() + .map_or(None, |mut iter| iter.next()); + self + } + /// bind connection to a specific network device by name #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] #[cfg_attr(