Skip to content

net/linux_kernel: add unnamed Unix-domain addresses#1242

Merged
sunfishcode merged 2 commits intobytecodealliance:mainfrom
Kijewski:pr-unnamed-un
Jan 30, 2025
Merged

net/linux_kernel: add unnamed Unix-domain addresses#1242
sunfishcode merged 2 commits intobytecodealliance:mainfrom
Kijewski:pr-unnamed-un

Conversation

@Kijewski
Copy link
Copy Markdown
Contributor

@Kijewski Kijewski commented Dec 16, 2024

I think it would be useful to have unnamed Unix-domain addressed in rustix. This PR adds the methods SocketAddrUnix::new_unnamed() and SocketAddrUnix::is_unnamed().

In C it is possible to have an unnamed Unix-domain socket name, when you set len = 2 = sizeof(c::socklen_t). Then the kernel will choose an abstract Unix-domain name for you when you bind the socket. The same feature present is also in Python, when you call sock.bind("").

Invoking SocketAddrUnix::new_abstract_name(b"") gives you an empty abstract socket address, i.e. SocketAddrUnix::len == 3. The kernel will keep this empty abstract name on calling bind().

I think it would be useful to have unnamed Unix-domain addressed in
rustix. This PR adds the methods `SocketAddrUnix::new_unnamed()` and
`SocketAddrUnix::is_unnamed()`.

In C it is possible to have an [unnamed Unix-domain] socket name, when
you set `len` = 2 = `sizeof(c::socklen_t)`. Then the kernel will choose
an abstract Unix-domain name for you when you bind the socket. The same
feature present also in Python, when you call [`sock.bind("")`].

Invoking [`SocketAddrUnix::new_abstract_name(b"")`] gives you an empty
abstract socket address, i.e. `SocketAddrUnix::len == 3`. The kernel
will keep this empty abstract name on calling `bind()`.

[unnamed Unix-domain]: https://manpages.debian.org/bookworm/manpages/unix.7.en.html#unnamed
[`sock.bind("")`]: https://docs.python.org/3.13/library/socket.html#socket.socket.bind
[`SocketAddrUnix::new_abstract_name(b"")`]: https://docs.rs/rustix/0.38.42/rustix/net/struct.SocketAddrUnix.html#method.new_abstract_name
Comment thread src/backend/libc/net/addr.rs Outdated
let len = self.len();
if len != 0 && self.unix.sun_path[0] == 0 {
let end = len as usize - offsetof_sun_path();
let end = self.len().saturating_sub(offsetof_sun_path());
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can you comment on why you changed this to use saturating_sub?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I wanted to remove one indentation level by removing the test if len == 0, followed by len > offsetof_sun_path. I don't know if there actually is a case where len == 0. If there isn't, then a normal subtraction would be good enough. Alternatively, because the method returns an Option, checked_sub would work, too.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Or was your question why I changed the method at all? The current implementation cannot tell unnamed socket addresses and abstract addresses apart and will panic on an unnamed address.

@Kijewski
Copy link
Copy Markdown
Contributor Author

I refactored all three methods, SocketAddrUnix::path(), …::abstract_name() and …::is_unnamed(), to deduplicate code and make it (IMHO) easier to read. Please tell me, if I should revert the change.

@sunfishcode
Copy link
Copy Markdown
Member

Thanks!

@sunfishcode sunfishcode merged commit b77cbc8 into bytecodealliance:main Jan 30, 2025
@Kijewski Kijewski deleted the pr-unnamed-un branch January 30, 2025 18:19
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.

2 participants