Skip to content
Draft
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
16 changes: 11 additions & 5 deletions src/net/tcp/listener.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,7 @@ use crate::net::TcpStream;
))]
use crate::sys::tcp::set_reuseaddr;
#[cfg(not(all(target_os = "wasi", target_env = "p1")))]
use crate::sys::{
tcp::{bind, listen, new_for_addr},
LISTEN_BACKLOG_SIZE,
};
use crate::sys::tcp::{bind, listen, new_for_addr};
use crate::{event, sys, Interest, Registry, Token};

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

bind(&listener.inner, addr)?;
listen(&listener.inner, LISTEN_BACKLOG_SIZE)?;
// Use the same backlog value as the standard libary.
// <https://github.com/rust-lang/rust/blob/0028f344ce9f64766259577c998a1959ca1f6a0b/library/std/src/sys/net/connection/socket/mod.rs#L559-L571>
let backlog = if cfg!(target_os = "horizon") {
20
} else if cfg!(target_os = "haiku") {
32
} else {
128
};
listen(&listener.inner, backlog)?;
Ok(listener)
}

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

/// Define the `listen` backlog parameters. 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.
///
// The logic here is taken from the standard library for unix sockets. TCP
// sockets in the standard library use much smaller sizes.
// 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;

/// 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(any(target_os = "hermit", target_os = "wasi"))]
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;
22 changes: 20 additions & 2 deletions src/sys/unix/uds/listener.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ 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 @@ -17,7 +16,26 @@ 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, LISTEN_BACKLOG_SIZE))?;
// Use the same backlog value as the standard libary.
// <https://github.com/rust-lang/rust/blob/0028f344ce9f64766259577c998a1959ca1f6a0b/library/std/src/os/unix/net/listener.rs#L75-L106>
let backlog = if cfg!(any(
target_os = "windows",
target_os = "redox",
target_os = "espidf",
target_os = "horizon"
)) {
128
} else if cfg!(any(
target_os = "linux",
target_os = "freebsd",
target_os = "openbsd",
target_vendor = "apple"
)) {
-1
} else {
libc::SOMAXCONN
};
syscall!(listen(fd, backlog))?;

Ok(socket)
}
Expand Down
Loading