Skip to content
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

Refactor UnixAddr #1618

Merged
merged 2 commits into from
Dec 31, 2021
Merged

Refactor UnixAddr #1618

merged 2 commits into from
Dec 31, 2021

Conversation

asomers
Copy link
Member

@asomers asomers commented Dec 26, 2021

  • Within UnixAddr, replace the path_len variable (length of the sun_path
    field) with sun_len (length of the whole structure). This is more
    similar to how other sockaddr types work, and it's the same way that the
    BSDs use the sun_len field.

    Also, don't require that sun_path be nul-terminated. The OS doesn't
    require it.

  • On BSD-derived operating systems, struct sockaddr has a sa_len field
    that holds the length of the structure. UnixAddr's path_len field is
    redundant. Remove path_len on BSD-derived OSes, retaining it only for
    Illumos and Linux-based OSes.

Within UnixAddr, replace the path_len variable (length of the sun_path
field) with sun_len (length of the whole structure).  This is more
similar to how other sockaddr types work, and it's the same way that the
BSDs use the sun_len field.

Also, don't require that sun_path be nul-terminated. The OS doesn't
require it.
@asomers
Copy link
Member Author

asomers commented Dec 26, 2021

cc @coolreader18

@coolreader18
Copy link
Contributor

Oh this looks good! I think it's kinda what I was going for (though it's a little hard to remember at this point) but obviously you've looked more into the issue

@asomers
Copy link
Member Author

asomers commented Dec 27, 2021

So the test failures on Linux are due to a Linux kernel bug. getsockname returns a length that includes the path's trailing NUL, even if the length passed to bind did not include that trailing NUL, and EVEN if the path passed to bind was not nul-terminated. I'm not sure if I should adjust the getsockname test to account for that, or if I should explicitly trim the trailing NUL in UnixAddr::from_raw_parts.

The Illumos failure is my fault and easy to fix.

@asomers asomers marked this pull request as ready for review December 30, 2021 03:01
@asomers asomers requested a review from rtzoeller December 30, 2021 03:01
Copy link
Collaborator

@rtzoeller rtzoeller left a comment

Choose a reason for hiding this comment

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

Looks good to me, just a few minor nitpicks/questions.

Tests are passing on DragonFly.

Self::Pathname(Path::new(OsStr::from_bytes(pathname)))
let pathname = slice::from_raw_parts(sun.sun_path.as_ptr() as *const u8, path_len);
if pathname.last() == Some(&0) {
// A trailing NUL is not considered part of the path, and it does
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: you're using both NUL and nul for b'\0'. Pick one.

unsafe {
let sun = *(addr as *const _ as *const sockaddr_un);
Ok(SockAddr::Unix(UnixAddr::from_raw_parts(sun, pathlen)))
let sun_len = len.try_into().unwrap();
Copy link
Collaborator

Choose a reason for hiding this comment

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

Unwrapping here makes me a little concerned, but I'm not familiar with the previous behavior. Should we return an Err instead of panicking?

Copy link
Member Author

Choose a reason for hiding this comment

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

The unwrap is guaranteed to pass, because of the assertion on line 1914.

@rtzoeller
Copy link
Collaborator

@asomers GitHub says you live in Longmont, so stay safe re: wildfires!

On BSD-derived operating systems, struct sockaddr has a sa_len field
that holds the length of the structure.  UnixAddr's path_len field is
redundant.  Remove path_len on BSD-derived OSes, retaining it only for
Illumos and Linux-based OSes.

Also, ensure that two UnixAddrs compare equal if they differ only by the
presence of a trailing NUL.  On Linux, syscalls like getsockname add a
trailing NUL to the sockaddr they return, even if no NUL was present on
the sockaddr originally passed to the kernel via a syscall like bind,
and even though the docs explicitly say that any NUL passed to bind is
not considered to be part of the address.  Work around this bug by
stripping it in UnixAddrKind::get(), so that at least two UnixAddrs will
compare identical even if they differ in the presence of a trailing NUL.
@asomers
Copy link
Member Author

asomers commented Dec 31, 2021

@asomers GitHub says you live in Longmont, so stay safe re: wildfires!

Fortunately the big one is downwind of me. There's a closer one upwind, but it's controlled now, and didn't do much damage. And oh yeah, it's SNOWING NOW!!!

bors r+

@bors bors bot merged commit b5a23c7 into nix-rust:master Dec 31, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants