Skip to content

feat(server): IPv6 dual-stack and SO_REUSEADDR for run()#1187

Open
Greg Lamberson (glamberson) wants to merge 2 commits intoDevolutions:masterfrom
lamco-admin:feat/enhanced-server-listener
Open

feat(server): IPv6 dual-stack and SO_REUSEADDR for run()#1187
Greg Lamberson (glamberson) wants to merge 2 commits intoDevolutions:masterfrom
lamco-admin:feat/enhanced-server-listener

Conversation

@glamberson
Copy link
Copy Markdown
Contributor

@glamberson Greg Lamberson (glamberson) commented Mar 28, 2026

Replace TcpListener::bind() with TcpSocket for control over socket
options before binding:

SO_REUSEADDR: Prevents EADDRINUSE on server restart. The previous
TcpListener::bind() doesn't set this, so the port stays in TIME_WAIT
for ~60 seconds after shutdown.

IPv6 dual-stack: Detects address family from the configured
SocketAddr. When IPv6 (e.g. [::]:3389), creates a v6 socket that
accepts both IPv4 and IPv6 via dual-stack (Linux default
bindv6only=0). When IPv4, uses new_v4() as before.

Backlog: Increased from the TcpListener default to 1024.

No new dependencies. Backward compatible.

Replace TcpListener::bind() with TcpSocket for control over socket
options before binding:

- SO_REUSEADDR: prevents EADDRINUSE on server restart (TIME_WAIT)
- IPv6 dual-stack: when bound to [::], accepts both IPv4 and IPv6
  on a single socket. Address family is detected from SocketAddr.
- Backlog increased from default to 1024
@glamberson Greg Lamberson (glamberson) changed the title feat(server): IPv6 dual-stack, SO_REUSEADDR, and ConnectionHandler for run() feat(server): IPv6 dual-stack and SO_REUSEADDR for run() Mar 28, 2026
Copy link
Copy Markdown
Member

@CBenoit Benoît Cortier (CBenoit) left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the RDP server’s run() listener setup to use tokio::net::TcpSocket so socket options can be set prior to binding, aiming to improve restart behavior and support IPv6 dual-stack binding.

Changes:

  • Replace TcpListener::bind() with TcpSocket to configure socket options before bind().
  • Enable SO_REUSEADDR to reduce EADDRINUSE likelihood on restart.
  • Increase listen backlog to 1024.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Replace TcpListener::bind() with TcpSocket for control over socket
options before binding:

SO_REUSEADDR (unix-only): Prevents EADDRINUSE on server restart. Gated
behind cfg(unix) because Windows SO_REUSEADDR has different semantics
that allow port hijacking.

IPv6 dual-stack: Detects address family from configured SocketAddr.
When IPv6, documents platform-specific IPV6_V6ONLY behavior (Linux
defaults to dual-stack, Windows/BSDs may not).

Backlog: Extracted to LISTENER_BACKLOG constant (1024).

No new dependencies. Backward compatible.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants