-
Notifications
You must be signed in to change notification settings - Fork 666
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sys::socket listen's Backlog wrapper type addition. #2276
Conversation
3e2735c
to
6158e15
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this PR! I have left some comments. BTW, I would appreciate it if we can have doc comments for these new public types.
A changelog is also needed.
src/sys/socket/mod.rs
Outdated
impl Backlog { | ||
/// Sets the listen queue size to system `SOMAXCONN` value | ||
#[cfg(target_os = "redox")] | ||
pub const DEFAULT: Self = Self(128); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Redox has SOMAXCONN
defined, we should use it:
$ pwd
/home/steve/Documents/workspace/libcs/libc/src/unix/redox
$ rg "SOMAXCONN"
mod.rs
816:pub const SOMAXCONN: ::c_int = 128;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got an error on CI we might just need to update libc version again (I m the one adding the constant in this crate for redox).
src/sys/socket/mod.rs
Outdated
#[cfg(target_os = "redox")] | ||
pub const DEFAULT: Self = Self(128); | ||
#[cfg(not(target_os = "redox"))] | ||
pub const DEFAULT: Self = Self(libc::SOMAXCONN); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we calling this value DEFAULT
? But not MAX
or simply SOMAXCONN
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is mostly what people use we can call it differently sure.
src/sys/socket/mod.rs
Outdated
/// Reasonable upper limit, while in theory we might be able | ||
/// to set it to a higher boundary, comes with a risk | ||
/// of resource exhaustion in return | ||
pub const MAXVALUE: Self = Self(511); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it really necessary to expose a MAXVALUE
that is specified by us rather than the system?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might refine it a bit (e.g. linux/glibc which has SOMAXCONN to 4096, for this case we might go up to 65535).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMHO, we should not put a restriction that the OS does not have, so I kinda tend to remove this and use SOMAXCONN as the upper bound
src/sys/socket/mod.rs
Outdated
fn try_from(backlog: i64) -> std::result::Result<Self, Self::Error> { | ||
match backlog { | ||
..=-2 => Err(BacklogTryFromError::TooNegative), | ||
-1..=511 => Ok(Self(i32::try_from(backlog).map_err(|_| BacklogTryFromError::TooPositive)?)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If a backlog of value -1
is only valid on Linux and FreeBSD, why are we allowing it for other OSes here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure. still a draft :) just wanted first impressions.
c34b1d7
to
b8630c3
Compare
src/sys/socket/mod.rs
Outdated
impl From<u16> for Backlog { | ||
fn from(backlog: u16) -> Self { | ||
Self(i32::from(backlog)) | ||
} | ||
} | ||
|
||
impl From<u8> for Backlog { | ||
fn from(backlog: u8) -> Self { | ||
Self(i32::from(backlog)) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just realized that we need to check the value even the value is in range of i32
, so what about defining a new(val: i32)
function and remove all the helper functions (TryFrom/From) for other types:
/// The `backlog` argument of [`listen()`].
pub struct Backlog(i32);
impl Backlog {
/// Sets the listen queue size to system `SOMAXCONN` value
pub const MAXCONN: Backlog = Backlog(libc::SOMAXCONN);
/// Sets the listen queue size to -1 for system supporting it
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
pub const MAXALLOWABLE: Backlog = Backlog(-1);
/// Create a `Backlog`, an `EINVAL` will be returned if `val` is invalid.
pub fn new(val: i32) -> Result<Self> {
cfg_if! {
if #[cfg(any(target_os = "linux", target_os = "freebsd"))] {
const MIN: i32 = -1;
} else {
const MIN: i32 = 0;
}
}
if !(MIN..libc::SOMAXCONN).contains(&val) {
return Err(Errno::EINVAL);
}
Ok(Self(val))
}
}
If we want to be generic, we can also do new<I: Into<i32>>(val: I)
.
5064960
to
792b568
Compare
src/sys/socket/mod.rs
Outdated
pub const MAXALLOWABLE: Self = Self(-1); | ||
|
||
// Create a `Backlog`, an `EINVAL` will be returned if `val` is invalid. | ||
pub fn new<I: Into<i32> + PartialOrd<I> + From<i32>>(val: I) -> Result<Self> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I
is Into<i32>
, why not just cast it to i32
and do the comparison:
let val = val.into();
And, with this generic function, the other From/TryFrom
impls are no longer needed, they are making things overly complicated.
792b568
to
fbb37d1
Compare
src/sys/socket/mod.rs
Outdated
#[cfg(any(target_os = "linux", target_os = "freebsd"))] | ||
pub const MAXALLOWABLE: Self = Self(-1); | ||
|
||
// Create a `Backlog`, an `EINVAL` will be returned if `val` is invalid. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use a doc comment:
// Create a `Backlog`, an `EINVAL` will be returned if `val` is invalid. | |
/// Create a `Backlog`, an `EINVAL` will be returned if `val` is invalid. |
src/sys/socket/mod.rs
Outdated
/// Listen for connections on a socket | ||
/// | ||
/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html) | ||
pub fn listen<F: AsFd>(sock: &F, backlog: usize) -> Result<()> { | ||
pub fn listen<F: AsFd, B: Into<Backlog>>(sock: &F, backlog: B) -> Result<()> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the current impl, we can just use the Backlog
type here:
pub fn listen<F: AsFd, B: Into<Backlog>>(sock: &F, backlog: B) -> Result<()> { | |
pub fn listen<F: AsFd>(sock: &F, backlog: Backlog) -> Result<()> { |
src/sys/socket/mod.rs
Outdated
let fd = sock.as_fd().as_raw_fd(); | ||
let res = unsafe { libc::listen(fd, backlog as c_int) }; | ||
let res = unsafe { libc::listen(fd, i32::from(backlog.into())) }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Backlog
is Into<i32>
, so we can simply do this:
let res = unsafe { libc::listen(fd, i32::from(backlog.into())) }; | |
let res = unsafe { libc::listen(fd, backlog.into()) }; |
test/sys/test_socket.rs
Outdated
assert!(Backlog::new(5012).is_err()); | ||
assert!(Backlog::new(65535).is_err()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For these 2 assertions, why not use the libc::SOMAXCONN
, like this:
assert!(Backlog::new(libc::SOMAXCONN + 1).is_err());
changing the sys::socket::listen backlog type from `usize` to a `i32` wrapper, offering known sane values, from -1/0, to SOMAXCONN. close nix-rustgh-2264
fbb37d1
to
d8e7cbe
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
changing the sys::socket::listen backlog type from
usize
to ai32
wrapper, offering known sane values, from -1, SOMAXCONN to511.
close gh-2264