Skip to content

Commit bfda813

Browse files
committed
Set SO_REUSEPORT on listening sockets
While `tokio`'s `TcpListener::bind` sets `SO_REUSEADDR` by default, it does *not* set `SO_REUSEPORT`, which means that rebinding exactly the same addr/port tuple might still fail with OS err 98. Here, we set `SO_REUSEPORT` on the `TcpSocket`, which however requires us to do the listener setup manually, which we do in accordance to the `tokio` docs (see https://docs.rs/exstd/latest/exstd/tokio/net/struct.TcpSocket.html)
1 parent 8f39539 commit bfda813

File tree

1 file changed

+20
-6
lines changed

1 file changed

+20
-6
lines changed

src/lib.rs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ mod types;
103103
mod wallet;
104104

105105
use std::default::Default;
106+
use std::net::SocketAddr;
106107
use std::net::ToSocketAddrs;
107108
use std::sync::{Arc, Mutex, RwLock};
108109
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
@@ -154,6 +155,7 @@ use payment::{
154155
use peer_store::{PeerInfo, PeerStore};
155156
use rand::Rng;
156157
use runtime::Runtime;
158+
use tokio::net::{TcpListener, TcpSocket};
157159
use types::{
158160
Broadcaster, BumpTransactionEventHandler, ChainMonitor, ChannelManager, Graph, KeysManager,
159161
OnionMessenger, PaymentStore, PeerManager, Router, Scorer, Sweeper, Wallet,
@@ -344,15 +346,12 @@ impl Node {
344346

345347
let logger = Arc::clone(&listening_logger);
346348
let listeners = self.runtime.block_on(async move {
347-
let mut listeners = Vec::new();
349+
let mut listeners: Vec<TcpListener> = Vec::new();
348350

349351
// Try to bind to all addresses
350352
for addr in &*bind_addrs {
351-
match tokio::net::TcpListener::bind(addr).await {
352-
Ok(listener) => {
353-
log_trace!(logger, "Listener bound to {}", addr);
354-
listeners.push(listener);
355-
},
353+
match setup_tcp_listener(*addr) {
354+
Ok(listener) => listeners.push(listener),
356355
Err(e) => {
357356
log_error!(
358357
logger,
@@ -1835,3 +1834,18 @@ pub(crate) fn total_anchor_channels_reserve_sats(
18351834
* anchor_channels_config.per_channel_reserve_sats
18361835
})
18371836
}
1837+
1838+
fn setup_tcp_listener(addr: SocketAddr) -> Result<TcpListener, tokio::io::Error> {
1839+
let socket = match addr {
1840+
SocketAddr::V4(_) => TcpSocket::new_v4()?,
1841+
SocketAddr::V6(_) => TcpSocket::new_v6()?,
1842+
};
1843+
socket.set_reuseaddr(true)?;
1844+
#[cfg(not(target_os = "windows"))]
1845+
socket.set_reuseport(true)?;
1846+
socket.bind(addr)?;
1847+
1848+
// The max number of pending connections. 1024 is the tokio default value.
1849+
const TCP_CONN_BACKLOG: u32 = 1024;
1850+
socket.listen(TCP_CONN_BACKLOG)
1851+
}

0 commit comments

Comments
 (0)