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

RFC: Move std::net::IpAddr types into core::net. #2832

Merged
merged 5 commits into from
Feb 25, 2023

Conversation

reitermarkus
Copy link
Contributor

@reitermarkus reitermarkus commented Dec 6, 2019

Make the IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4,
SocketAddrV6, Ipv6MulticastScope and AddrParseError types available in no_std
contexts by moving them into a core::net module.

Rendered


Implementation: rust-lang/rust#104265

@Nemo157
Copy link
Member

Nemo157 commented Dec 6, 2019

Given that most IP based networking is done over UDP/TCP, even for IoT devices, I think it would make sense to move the SocketAddr types at the same time. This also makes the string parser easier to move (in my branch I initially only intended to move the IP types, but I think I ran into issues with interdependencies between the parsers which would have needed a larger rewrite of them).

JohnTitor added a commit to JohnTitor/rust that referenced this pull request Dec 6, 2019
…mulacrum

Remove boxed closures in address parser.

Simplify address parser by removing unnecessary boxed closures.

Also relevant for rust-lang/rfcs#2832.
@joshtriplett
Copy link
Member

This seems entirely reasonable to me.

One thing the RFC should discuss, though: will all platforms that use a given target have the same interpretation of the type? Is the inner storage expected to be in network-endian byte order or native-endian byte order?

@reitermarkus
Copy link
Contributor Author

The inner octets should always be stored in network/big-endian order. The current Ipv4Addr implementation already ensures this by constructing the libc type with u32::to_be and the libc type for Ipv6Addr already uses a [u8; 16] internally on all platforms.

@reitermarkus
Copy link
Contributor Author

I agree that it makes sense to move the SocketAddr types at the same time.

Now there are two options on how to represent them:

The Rust Way:

pub struct SocketAddrV4 {
    ip: Ipv4Addr,
    port: u16,
}

pub struct SocketAddrV6 {
    ip: Ipv6Addr,
    port: u16,
    flowinfo: u32,
    scope_id: u32,
}

This makes these types as portable as possible but we have to construct the corresponding libc type when interfacing with libc.

The C Way:

pub struct SocketAddrV4 {
    __padding: [u8; 2],
    port: u16,
    ip: Ipv4Addr,
    __zero: [u8; 8]
}

pub struct SocketAddrV6 {
    __padding: [u8; 2],
    port: u16,
    flowinfo: u32,
    ip: Ipv6Addr,
    scope_id: u32,
}

According to RFC 2553, __padding can either be

len: u8,
family: u8,

or just

family: u16,

and __zero should be [u8; 8], but there are some platforms that don't have it at all and some that use [u8; 24].

Note that in the current implementation we never set len, even if the libc type has that field.

This way we can cast directly to the libc type, however there are a few drawbacks:

  • family must be still be set to libc::AF_INET/libc::AF_INET6 before interfacing with libc which would mutate an immutable reference. Also the type itself already encodes whether it is IPv4 or IPv6.
  • Size of __zero conflicts with the libc type on some platforms.

@joshtriplett
Copy link
Member

@reitermarkus If the socketaddr types aren't identical across platforms, I don't think we want them in core.

@reitermarkus
Copy link
Contributor Author

reitermarkus commented Dec 9, 2019

They are definitely identical with the pure Rust representation. Also SocketAddrV6 is identical in the C representation on all platforms.

Now for the C representation of SocketAddrV4, after looking further into the __zero issue, I found that all targets using no such field at all or [u8; 0] either simply don't support sockets at all or are using a different socket API .

RFC 2553 also states the following:

Each protocol-specific data structure is designed so it can be cast into a
protocol-independent data structure — the sockaddr structure.

So even if there were platforms actually using [u8; 0], it would still be safe to cast to the libc type.

RFC 2553 also mentions:

The sockaddr_in structure is the protocol-specific data structure
for IPv4. This data structure actually includes 8-octets of unused
space, …

That means that __zero: [u8; 8] is definitely correct according to the RFC. And in fact all platforms except Haiku define it this way.

That means we will have to provide a shim for Haiku, since it will try to zero a [u8; 24].

This way libcore will be in spec with the platform-agnostic RFC while libstd will provide the platform-specific shim for Haiku.

@JelteF
Copy link

JelteF commented Dec 13, 2019

Small nitpick, both the title of the PR and the commit message say: core::.net, not core::net

This would be a funny module name, given that .NET Core is the name of the .NET compiler. But I think it's both a bit too confusing, since std::.net does not exist, and it's actually a typo because the rfc itself only mentions core::net

So I suggest changing it to core::net in the PR and commit title.

@reitermarkus reitermarkus changed the title RFC: Move std::net types into core:.net. RFC: Move std::net types into core::net. Dec 13, 2019
@dtolnay dtolnay added the T-libs-api Relevant to the library API team, which will review and decide on the RFC. label Jan 16, 2020
@jonas-schievink jonas-schievink added A-net Proposals relating to networking. A-no_std Proposals relating to #[no_std]. labels Mar 3, 2020
@scottmcm
Copy link
Member

scottmcm commented May 1, 2020

👍 the IpAddr-Ipv4Addr-and-Ipv6Addr version of this. I like that the version-specific ones have well-defined byte orders and sizes, so there are no real surpises or choices here.

Harder questions like SocketAddr* can always be a future RFC.

(P.S. The title of this RFC surprised me -- it makes it seem like everything, not a subset.)

@reitermarkus
Copy link
Contributor Author

it makes it seem like everything, not a subset

Well, the idea was to move most types, but I think scoping this RFC to just IP address types might be best to get things moving.

@reitermarkus reitermarkus changed the title RFC: Move std::net types into core::net. RFC: Move std::net::IpAddr types into core::net. May 1, 2020
@reitermarkus reitermarkus force-pushed the core-net-types branch 3 times, most recently from c3a4a4f to a36fb49 Compare May 2, 2020 11:03
@reitermarkus
Copy link
Contributor Author

Any more concerns or suggestions?

@ryankurte
Copy link

it would be super great to have net::IpAddr* moved to core, it's a definite improvement, and it makes sense not to block on things that require more discussion...

however, without the net::SocketAddr* types we still have all the overhead of managing alternate SockAddr types for no_std applications, or finding types to substitute if we support both, i'd love to see both of em in core so we can remove this whole pain point.

@Manishearth Manishearth removed their request for review June 11, 2020 20:41
@Manishearth
Copy link
Member

Manishearth commented Jun 12, 2020

Please stop.

I am not on the libs team, I don't know why you want my review here. If someone undoes an action you've taken you should at most ask why, not immediately do it again.

@rfcbot rfcbot removed the proposed-final-comment-period Currently awaiting signoff of all team members in order to enter the final comment period. label Jan 3, 2023
@rfcbot
Copy link
Collaborator

rfcbot commented Jan 3, 2023

🔔 This is now entering its final comment period, as per the review above. 🔔

@pinkforest
Copy link

pinkforest commented Jan 4, 2023

wasm32-unknown-unknown is very bloat sensitive target and there are microcontrollers which don't need this and also very limited space. no_std networking would be nice but is core really the right place even for these additional types without addressing the -u-u concerns first ? I get that things like error types belong there but networking that has bias towards IP type (over Ethernet, MPLS, ..) networks favoring one target over the other especially when there are widely used targets with no networking at all ? also cdylib in wasm context.

@ojeda
Copy link

ojeda commented Jan 4, 2023

Ideally core would be configurable or split into several pieces, so that particular use cases may employ different subsets, and thus making bloat an orthogonal concern to functionality.

@Nemo157
Copy link
Member

Nemo157 commented Jan 4, 2023

What's the issue with having unused code in core that doesn't get linked into the binaries that don't need it? (For wasm32-unknown-unknown specifically this code already exists as part of its incomplete-std and gets dropped by the linker).

@pinkforest
Copy link

pinkforest commented Jan 4, 2023

So this is actually going to happen with the current core if this would be done here ? I think this assumption should be stated as such in RFC for clarity and so it continues to be tested for code-size tests. For reference wasm32-u-u std is ~30 kB and wasm32-wasi std is ~70 kB w/ x86_64-linux host and detached std allocator is 4 kB which can be cheated out with 300-600 byte allocator and with heapless crate (or without heap) even less. Also maybe thumbv7em-none-eabi should be checked. This considering the core is going to grow like this in the future.

EDIT: I added some test suggestions- rust-lang/rust#104265 (comment) - I think RFC should still cover the impact and/or at least the intent here properly what would or should and should not happen as currently it is vague to this respect.

@JelteF
Copy link

JelteF commented Jan 4, 2023

@pinkforest could you explain why you think codesize of the final linked binary would change? If you don't use types they should be stripped out by the linker when you build a binary.

@pinkforest
Copy link

pinkforest commented Jan 4, 2023

Problem is this RFC is vague and it is left to assumption that this lto happen now and in the future. RFC should state the goals more clear what would and should not happen considering this is now / further making the core as standard library -like without taking into account carefully between different types of targets.

Ideally there should be statements which then can be turned into tests to alleviate these concerns. It's like trying to deal with #[inline] and the various intepretations and the reality of between rust versions.

These kind of changes need guarantees and clarity on assumptions not just having to rely on current assumptions what will happen in the future - also considering there used to be a lot of target specific stuff.

Every statement in any RFC should be something that can be tested across all the targets and hosts that doesn't rely on people relying on assumptions.

Also someone should visit the definition what core is and means exactly. It is becoming very vague ?

# Drawbacks
[drawbacks]: #drawbacks

Moving the `std::net` types to `core::net` makes the core library less *minimal*.
Copy link

@pinkforest pinkforest Jan 4, 2023

Choose a reason for hiding this comment

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

Suggested change
Moving the `std::net` types to `core::net` makes the core library less *minimal*.
Moving the `std::net` types to `core::net` makes the core library less *seemingly minimal*.
However optimisations relied from the compiler means the dead code types must never be included
in the built binary when not used.

I think this could be best clarified here what this "minimal" means ?

Since the code is optimised away on cases where it is not used as #2832 (comment) - This provides testing coverage for rust-lang/rust#104265 (comment)

@Kixunil
Copy link

Kixunil commented Jan 4, 2023

@pinkforest dead code elimination is one of the most basic optimizations. Requiring the RFC to state that it is required is like requiring that RFC states that 1 + 1 == 2.

If you have it enabled (with LTO and such) you have nothing to worry about. If you make a space-limited project why wouldn't this be the first thing you enable? There's ton of other code it can eliminate as well, not just these types!

@slanterns
Copy link
Contributor

slanterns commented Jan 5, 2023

Also someone should visit the definition what core is and means exactly. It is becoming very vague ?

IMO when we want to add something new into the standard library then T-libs-api should prudently evaluate the necessity first, but moving something already in std into core is totally fine — every OS-independent library thing should live in libcore — like this one.

@Amanieu
Copy link
Member

Amanieu commented Jan 5, 2023

You don't even need to enable LTO: the linker will simply not include any functions that are not referenced in the binary.

@m-ou-se m-ou-se removed the I-libs-api-nominated Indicates that an issue has been nominated for prioritizing at the next libs-api team meeting. label Jan 10, 2023
@rfcbot rfcbot added finished-final-comment-period The final comment period is finished for this RFC. and removed final-comment-period Will be merged/postponed/closed in ~10 calendar days unless new substational objections are raised. labels Jan 13, 2023
@rfcbot
Copy link
Collaborator

rfcbot commented Jan 13, 2023

The final comment period, with a disposition to merge, as per the review above, is now complete.

As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed.

This will be merged soon.

@faern
Copy link
Contributor

faern commented Jan 28, 2023

I think the PR that implements this RFC is ready. And the FCP completed two weeks ago. Can we get this merged?

Also, note that a PR adding these to core::net should (initially) use type aliases rather than re-exporting, so that the core::net versions can start out nightly-only and become stabilized later.

I was not able to do this because of the url to the documentation changing. But from my testing it seems enough to just make the module core::net unstable and the types in it stable. Any user of the types must still opt in to the feature to use the types.

@joshtriplett
Copy link
Member

FCP completed; merging.

Tracking issue: rust-lang/rust#108443

Implementation in progress: rust-lang/rust#104265

@joshtriplett joshtriplett merged commit fd7c616 into rust-lang:master Feb 25, 2023
compiler-errors added a commit to compiler-errors/rust that referenced this pull request Feb 26, 2023
…riplett

Move IpAddr, SocketAddr and V4+V6 related types to `core`

Implements RFC rust-lang/rfcs#2832. The RFC has completed FCP with disposition merge, but is not yet merged.

Moves IP types to `core` as specified in the RFC.

The full list of moved types is: `IpAddr`, `Ipv4Addr`, `Ipv6Addr`, `SocketAddr`, `SocketAddrV4`, `SocketAddrV6`, `Ipv6MulticastScope` and `AddrParseError`.

Doing this move was one of the main driving arguments behind rust-lang#78802.
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this pull request Feb 27, 2023
…riplett

Move IpAddr, SocketAddr and V4+V6 related types to `core`

Implements RFC rust-lang/rfcs#2832. The RFC has completed FCP with disposition merge, but is not yet merged.

Moves IP types to `core` as specified in the RFC.

The full list of moved types is: `IpAddr`, `Ipv4Addr`, `Ipv6Addr`, `SocketAddr`, `SocketAddrV4`, `SocketAddrV6`, `Ipv6MulticastScope` and `AddrParseError`.

Doing this move was one of the main driving arguments behind rust-lang#78802.
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Feb 27, 2023
…riplett

Move IpAddr, SocketAddr and V4+V6 related types to `core`

Implements RFC rust-lang/rfcs#2832. The RFC has completed FCP with disposition merge, but is not yet merged.

Moves IP types to `core` as specified in the RFC.

The full list of moved types is: `IpAddr`, `Ipv4Addr`, `Ipv6Addr`, `SocketAddr`, `SocketAddrV4`, `SocketAddrV6`, `Ipv6MulticastScope` and `AddrParseError`.

Doing this move was one of the main driving arguments behind rust-lang#78802.
thomcc pushed a commit to tcdi/postgrestd that referenced this pull request May 31, 2023
Move IpAddr, SocketAddr and V4+V6 related types to `core`

Implements RFC rust-lang/rfcs#2832. The RFC has completed FCP with disposition merge, but is not yet merged.

Moves IP types to `core` as specified in the RFC.

The full list of moved types is: `IpAddr`, `Ipv4Addr`, `Ipv6Addr`, `SocketAddr`, `SocketAddrV4`, `SocketAddrV6`, `Ipv6MulticastScope` and `AddrParseError`.

Doing this move was one of the main driving arguments behind #78802.
bors added a commit to rust-lang-ci/rust that referenced this pull request Dec 24, 2023
Stabilize ip_in_core feature

Finally the last stage of rust-lang/rfcs#2832. Since the FCP was [just completed with disposition *merge*](rust-lang#108443 (comment)), I create the stabilization PR for the `ip_in_core` feature. Allowing usage of `core::net` on stable Rust.

The error type `core::net::AddrParseError` itself becomes stable with this PR. However, `core::error::Error` is still unstable, so the `Error` impl for this type is not available on stable rust. Simply because `error_in_core` is not stable yet, but that should be fine!
bors added a commit to rust-lang-ci/rust that referenced this pull request Dec 24, 2023
Stabilize ip_in_core feature

Finally the last stage of rust-lang/rfcs#2832. Since the FCP was [just completed with disposition *merge*](rust-lang#108443 (comment)), I create the stabilization PR for the `ip_in_core` feature. Allowing usage of `core::net` on stable Rust.

The error type `core::net::AddrParseError` itself becomes stable with this PR. However, `core::error::Error` is still unstable, so the `Error` impl for this type is not available on stable rust. Simply because `error_in_core` is not stable yet, but that should be fine!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-net Proposals relating to networking. A-no_std Proposals relating to #[no_std]. disposition-merge This RFC is in PFCP or FCP with a disposition to merge it. finished-final-comment-period The final comment period is finished for this RFC. Libs-Tracked Libs issues that are tracked on the team's project board. T-libs-api Relevant to the library API team, which will review and decide on the RFC. to-announce
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet