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

[pal] Helper Function to Convert std::net::SocketAddrV4 to libc::sockaddr_in #413

Merged
merged 1 commit into from
Jan 12, 2023

Conversation

ppenna
Copy link
Contributor

@ppenna ppenna commented Jan 11, 2023

Description

This PR closes #412

Summary of Changes

  • Added a helper functionsockaddrv4_to_sockaddr_in() to perform the conversion between a std::net::SocketAddrV4 to libc::sockaddr_in
  • Changed the concerned code to rely on the helper function.
  • Changed the conversion of sin_port and sin_addr.s_addr to be on network order.

@ppenna ppenna added the enhancement Enhancement Request on an Existing Feature label Jan 11, 2023
@ppenna ppenna requested a review from BrianZill January 11, 2023 13:53
@ppenna ppenna self-assigned this Jan 11, 2023
/// Converts a [std::net::SocketAddrV4] into a [libc::sockaddr_in].
pub fn socketaddrv4_to_sockaddr_in(addr: &SocketAddrV4) -> libc::sockaddr_in {
libc::sockaddr_in {
sin_family: libc::AF_INET as u16,
Copy link
Contributor

Choose a reason for hiding this comment

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

I have no idea why libc defines AF_INET as a libc::c_int instead of as a libc::sa_family_t. If they had, you wouldn't need this "as" clause. But since you do need it, shouldn't it be "as libc::sa_family_t"?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for noting this. u16 was also working, but I agree that moving to the correct type cast is better.

sin_port: u16::to_be(addr.port()),
sin_addr: libc::in_addr {
s_addr: u32::to_be(u32::from_be_bytes(addr.ip().octets())),
},
Copy link
Contributor

Choose a reason for hiding this comment

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

Again, libc uses its own type (libc::in_addr_t) as the type for s_addr. So, I think line 72 should technically have "as libc::in_addr_t" added to the end of it.

But yes, this conversion is correct. The version you're replacing was also correct (and avoided an unnecessary byte-swap), but only on little-endian machines. The ideal thing here would probably be to define our own pal::in_addr_t type, with a from_be_bytes() method that creates the equivalent of a big-endian 32-bit unsigned value.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Leaving off the casting was working, but I introduced it, so that we are technically correct.

Also, I have introduced conditional compilation to select the right byte conversion technique.

@@ -61,3 +62,15 @@ pub unsafe fn set_nonblock(fd: RawFd) -> i32 {
flags |= libc::O_NONBLOCK;
libc::fcntl(fd, libc::F_SETFL, flags, 1)
}

/// Converts a [std::net::SocketAddrV4] into a [libc::sockaddr_in].
pub fn socketaddrv4_to_sockaddr_in(addr: &SocketAddrV4) -> libc::sockaddr_in {
Copy link
Contributor

@BrianZill BrianZill Jan 12, 2023

Choose a reason for hiding this comment

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

Ideally, this function wouldn't be here, it would be in src/rust/pal/sockets.rs (or somesuch), and it would return a value of a platform independent type, like pal::sockaddr_in (or somesuch). And then there would be separate implementations of it for linux and Windows.

I.e. all platform-dependent code would be under pal, and everything in catcollor, catnap, catpowder, et cetera would be platform-independent.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree that we should discuss a better approach for structuring the PAL module. Let us have it and then I handle the necessary reorg.

Copy link
Contributor

@BrianZill BrianZill left a comment

Choose a reason for hiding this comment

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

This is okay, but we should really clean up the PAL at some point to actually be an abstraction layer and not a dumping ground for platform-specific code (see my comment about where socketaddrv4_to_sockaddr_in() should live).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Enhancement Request on an Existing Feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[pal] Helper Function to Convert std::net::SocketAddrV4 to libc::sockaddr_in
2 participants