Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/net/tcp/listener.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ use crate::net::TcpStream;
#[cfg(any(unix, target_os = "hermit"))]
use crate::sys::tcp::set_reuseaddr;
#[cfg(not(target_os = "wasi"))]
use crate::sys::tcp::{bind, listen, new_for_addr};
use crate::sys::{
tcp::{bind, listen, new_for_addr},
LISTEN_BACKLOG_SIZE,
};
use crate::{event, sys, Interest, Registry, Token};

/// A structure representing a socket server
Expand Down Expand Up @@ -78,7 +81,7 @@ impl TcpListener {
set_reuseaddr(&listener.inner, true)?;

bind(&listener.inner, addr)?;
listen(&listener.inner, 1024)?;
listen(&listener.inner, LISTEN_BACKLOG_SIZE)?;
Ok(listener)
}

Expand Down
65 changes: 65 additions & 0 deletions src/sys/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,68 @@ cfg_not_os_poll! {
pub use self::unix::SourceFd;
}
}

/// Define the `listen` backlog parameters as in the standard library. This
/// helps avoid hardcoded unsynchronized values and allows better control of
/// default values depending on the target.
///
/// Selecting a “valid” default value can be tricky due to:
///
/// - It often serves only as a hint and may be rounded, trimmed, or ignored by
/// the OS.
///
/// - It is sometimes provided as a "magic" value, for example, -1. This
/// value is undocumented and not standard, but it is often used to represent
/// the largest possible backlog size. This happens due to signed/unsigned
/// conversion and rounding to the upper bound performed by the OS.
///
/// - Default values vary depending on the OS and its version. Common defaults
/// include: -1, 128, 1024, and 4096.
///
// Here is the original code from the standard library
// https://github.com/rust-lang/rust/blob/4f808ba6bf9f1c8dde30d009e73386d984491587/library/std/src/os/unix/net/listener.rs#L72
//
#[allow(dead_code)]
#[cfg(any(
target_os = "windows",
target_os = "redox",
target_os = "espidf",
target_os = "horizon"
))]
pub(crate) const LISTEN_BACKLOG_SIZE: i32 = 128;
Copy link
Collaborator

Choose a reason for hiding this comment

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

cfg_select! once stable would be handy here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I agree. It’s pretty wordy now


/// This is a special case for some target(s) supported by `mio`. This value
/// is needed because `libc::SOMAXCON` (used as a fallback for unknown targets)
/// is not implemented for them. Feel free to update this if the `libc` crate
/// changes.
#[allow(dead_code)]
#[cfg(target_os = "hermit")]
pub(crate) const LISTEN_BACKLOG_SIZE: i32 = 1024;

#[allow(dead_code)]
#[cfg(any(
// Silently capped to `/proc/sys/net/core/somaxconn`.
target_os = "linux",
// Silently capped to `kern.ipc.soacceptqueue`.
target_os = "freebsd",
// Silently capped to `kern.somaxconn sysctl`.
target_os = "openbsd",
// Silently capped to the default 128.
target_vendor = "apple",
))]
pub(crate) const LISTEN_BACKLOG_SIZE: i32 = -1;

#[allow(dead_code)]
#[cfg(not(any(
target_os = "windows",
target_os = "redox",
target_os = "espidf",
target_os = "horizon",
target_os = "linux",
target_os = "freebsd",
target_os = "openbsd",
target_os = "wasi",
target_os = "hermit",
target_vendor = "apple",
)))]
pub(crate) const LISTEN_BACKLOG_SIZE: i32 = libc::SOMAXCONN;
2 changes: 1 addition & 1 deletion src/sys/shell/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub(crate) fn connect(_: &net::TcpStream, _: SocketAddr) -> io::Result<()> {
}

#[cfg(not(target_os = "wasi"))]
pub(crate) fn listen(_: &net::TcpListener, _: u32) -> io::Result<()> {
pub(crate) fn listen(_: &net::TcpListener, _: i32) -> io::Result<()> {
os_required!();
}

Expand Down
4 changes: 1 addition & 3 deletions src/sys/unix/tcp.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use std::convert::TryInto;
use std::io;
use std::mem::{size_of, MaybeUninit};
use std::net::{self, SocketAddr};
Expand Down Expand Up @@ -38,8 +37,7 @@ pub(crate) fn connect(socket: &net::TcpStream, addr: SocketAddr) -> io::Result<(
}
}

pub(crate) fn listen(socket: &net::TcpListener, backlog: u32) -> io::Result<()> {
let backlog = backlog.try_into().unwrap_or(i32::MAX);
pub(crate) fn listen(socket: &net::TcpListener, backlog: i32) -> io::Result<()> {
syscall!(listen(socket.as_raw_fd(), backlog))?;
Ok(())
}
Expand Down
3 changes: 2 additions & 1 deletion src/sys/unix/uds/listener.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use std::{io, mem};
use crate::net::UnixStream;
use crate::sys::unix::net::new_socket;
use crate::sys::unix::uds::{path_offset, unix_addr};
use crate::sys::LISTEN_BACKLOG_SIZE;

pub(crate) fn bind_addr(address: &SocketAddr) -> io::Result<net::UnixListener> {
let fd = new_socket(libc::AF_UNIX, libc::SOCK_STREAM)?;
Expand All @@ -16,7 +17,7 @@ pub(crate) fn bind_addr(address: &SocketAddr) -> io::Result<net::UnixListener> {
let (unix_address, addrlen) = unix_addr(address);
let sockaddr = &unix_address as *const libc::sockaddr_un as *const libc::sockaddr;
syscall!(bind(fd, sockaddr, addrlen))?;
syscall!(listen(fd, 1024))?;
syscall!(listen(fd, LISTEN_BACKLOG_SIZE))?;

Ok(socket)
}
Expand Down
4 changes: 1 addition & 3 deletions src/sys/windows/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,9 @@ pub(crate) fn connect(socket: &net::TcpStream, addr: SocketAddr) -> io::Result<(
}
}

pub(crate) fn listen(socket: &net::TcpListener, backlog: u32) -> io::Result<()> {
use std::convert::TryInto;
pub(crate) fn listen(socket: &net::TcpListener, backlog: i32) -> io::Result<()> {
use WinSock::listen;

let backlog = backlog.try_into().unwrap_or(i32::MAX);
syscall!(
listen(socket.as_raw_socket() as _, backlog),
PartialEq::eq,
Expand Down
Loading