-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Implement network primitives with ideal Rust layout, not C system layout #78802
Conversation
r? @sfackler (rust_highfive has picked a reviewer for you, use r? to override) |
Is the reduced size the only argument for this change? I'm opposed to it per say, but it will cost some compute to go from Rust's address to C's address format. I imagine the most common use case for most address types is use in system calls, so are there any benchmarks for this? Also I maintain both Mio and socket2 so changes those shouldn't be problem, thanks for the heads-up. |
No. There is a list of benefits in the PR description. I think the most asked for is the move to I'm working on benchmarks. See the internals forums threads linked in the PR description. But my initial results show that any conversion is dirt cheap anyway so it does not really matter. |
#[stable(feature = "rust1", since = "1.0.0")] | ||
pub struct Ipv6Addr { | ||
inner: c::in6_addr, | ||
octets: [u8; 16], |
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 not use a u128 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.
Any benefit of doing that? It looks like the value is accessed as an array more often, so this felt like a more natural representation. Also it lowers the memory alignment from 4 to 1.
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 not entirely clear to me that a lowered alignment is actually beneficial. At least given the fact there will now be a fair number of conversions between this type and the libc one when interacting with the system APIs, the alignment of 1 effectively forces (especially on architectures with strict alignment requirements) a memcpy
for each such conversion.
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 you are talking about performance I would argue it's not a valid argument unless proven. As everything regarding optimization. Can you find any usage of this type where it's converted to/from the system representation where said conversion takes up more than a tiny fraction of the time the entire syscall takes?
I'm not saying my benchmarks are perfect. But I have at least tried to check this, and I have not found anything indicating this PR makes anything slower: https://internals.rust-lang.org/t/why-are-socketaddrv4-socketaddrv6-based-on-low-level-sockaddr-in-6/13321/13
I'm not saying alignment 1 is strictly better than 4. Just that I can't find any downsides. And it would be artificial to try to keep it at 4 unless needed, since the most natural representation does not have alignment 4 automatically.
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 the representation was a u128
then checking if an address is in a prefix like ::ffff/96
(IPv4-mapped addresses) could be efficiently computed with:
let mask: u128 = u128::MAX << (128 - 96);
self.inner & mask == Ipv6Addr::from("::ffff").inner
Still possible if the representation is [u8; 16]
using u128::from_be_bytes
, but because of the alignment that might require a copy.
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.
The soon to be released Go 1.18 includes a whole new IP package called net/netip
: https://github.com/golang/go/blob/master/src/net/netip/netip.go
A blogpost on its design can be found here (the package was originally called inet.af/netaddr
here, because it was not in the stdlib): https://tailscale.com/blog/netaddr-new-ip-type-for-go/
Importantly for this discussion is that using a pair of uint64 (Go does not have native uint128 support) was quite a bit faster than using an array of bytes. See commit message here for details: inetaf/netaddr@4eb479d
I think it's definitely worth running similar benchmarks 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.
I agree that we should run benchmarks and try to find the best internal representation. But I don't think it should block this PR. Unless we think the PR as is will mean performance regressions I think it brings so many other nice things to the table that it can be ignored for now and iterated upon later. The memory layout of these types are not part of the public API and can change any number of times after this PR is merged.
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.
Regarding perf regressions, this is most likely used around syscalls and thus irrelevant. Various Rust APIs like File
already heap allocate on syscalls based on same arguments and heap allocations are significantly slower than a few mov
s here.
This is not going to be able to land for quite a while, FYI. |
Why is that? |
Because it will break large swaths of the ecosystem. |
@faern already fixed Mio (tokio-rs/mio#1388) and socket2 (rust-lang/socket2#120), I'll release updates for both next week. Could we run crater after that to test what crates also break? |
Also waiting for this to be fixed in |
ef7343b
to
a3c4764
Compare
This repository is a giant workspace with a |
@faern only top-level lockfile will be respected when building a workspace member package (which RLS is), and so its lockfile will be effectively ignored when building RLS in the context of this workspace. I can update RLS' lockfile separately in https://github.com/rust-lang/rls but this should not block anything here. |
For context: rust-lang/rust#78802
There is good progress. Out of all the offending crates we have already had this fixed and published in The problem still exists in the |
Note that the change to let ip : Ipv4Addr = ...;
match ip {
Ipv4Addr::LOCALHOST => { ... },
_ => { ... }
} This becomes part of the contract of these primitives, falling under the stability guarantees of the standard library, which is why I propose adding a regression test similar those added when the representation of rust/library/core/tests/ops.rs Lines 161 to 199 in c6a6105
|
For context: rust-lang/rust#78802
upcoming stdlib 1.64 will switch to pure rust types rust-lang/rust#78802 fix #3
upcoming stdlib 1.64 will switch to pure rust types rust-lang/rust#78802 fix #3
upcoming stdlib 1.64 will switch to pure rust types rust-lang/rust#78802 fix #3
Pkgsrc changes: * Add patch to fix vendor/kqueue issue (on 32-bit hosts) * Adjust other patches & line numbers * Version bumps & checksum changes. Upstream changes: Version 1.64.0 (2022-09-22) =========================== Language -------- - [Unions with mutable references or tuples of allowed types are now allowed](rust-lang/rust#97995) - It is now considered valid to deallocate memory pointed to by a shared reference `&T` [if every byte in `T` is inside an `UnsafeCell`](rust-lang/rust#98017) - Unused tuple struct fields are now warned against in an allow-by-default lint, [`unused_tuple_struct_fields`] (rust-lang/rust#95977), similar to the existing warning for unused struct fields. This lint will become warn-by-default in the future. Compiler -------- - [Add Nintendo Switch as tier 3 target] (rust-lang/rust#88991) - Refer to Rust's [platform support page][platform-support-doc] for more information on Rust's tiered platform support. - [Only compile `#[used]` as llvm.compiler.used for ELF targets] (rust-lang/rust#93718) - [Add the `--diagnostic-width` compiler flag to define the terminal width.] (rust-lang/rust#95635) - [Add support for link-flavor `rust-lld` for iOS, tvOS and watchOS] (rust-lang/rust#98771) Libraries --------- - [Remove restrictions on compare-exchange memory ordering.] (rust-lang/rust#98383) - You can now `write!` or `writeln!` into an `OsString`: [Implement `fmt::Write` for `OsString`](rust-lang/rust#97915) - [Make RwLockReadGuard covariant] (rust-lang/rust#96820) - [Implement `FusedIterator` for `std::net::[Into]Incoming`] (rust-lang/rust#97300) - [`impl<T: AsRawFd> AsRawFd for {Arc,Box}<T>`] (rust-lang/rust#97437) - [`ptr::copy` and `ptr::swap` are doing untyped copies] (rust-lang/rust#97712) - [Add cgroupv1 support to `available_parallelism`] (rust-lang/rust#97925) - [Mitigate many incorrect uses of `mem::uninitialized`] (rust-lang/rust#99182) Stabilized APIs --------------- - [`future::IntoFuture`] (https://doc.rust-lang.org/stable/std/future/trait.IntoFuture.html) - [`future::poll_fn`] (https://doc.rust-lang.org/stable/std/future/fn.poll_fn.html) - [`task::ready!`] (https://doc.rust-lang.org/stable/std/task/macro.ready.html) - [`num::NonZero*::checked_mul`] (https://doc.rust-lang.org/stable/std/num/struct.NonZeroUsize.html#method.checked_mul) - [`num::NonZero*::checked_pow`] (https://doc.rust-lang.org/stable/std/num/struct.NonZeroUsize.html#method.checked_pow) - [`num::NonZero*::saturating_mul`] (https://doc.rust-lang.org/stable/std/num/struct.NonZeroUsize.html#method.saturating_mul) - [`num::NonZero*::saturating_pow`] (https://doc.rust-lang.org/stable/std/num/struct.NonZeroUsize.html#method.saturating_pow) - [`num::NonZeroI*::abs`] (https://doc.rust-lang.org/stable/std/num/struct.NonZeroIsize.html#method.abs) - [`num::NonZeroI*::checked_abs`] (https://doc.rust-lang.org/stable/std/num/struct.NonZeroIsize.html#method.checked_abs) - [`num::NonZeroI*::overflowing_abs`] (https://doc.rust-lang.org/stable/std/num/struct.NonZeroIsize.html#method.overflowing_abs) - [`num::NonZeroI*::saturating_abs`] (https://doc.rust-lang.org/stable/std/num/struct.NonZeroIsize.html#method.saturating_abs) - [`num::NonZeroI*::unsigned_abs`] (https://doc.rust-lang.org/stable/std/num/struct.NonZeroIsize.html#method.unsigned_abs) - [`num::NonZeroI*::wrapping_abs`] (https://doc.rust-lang.org/stable/std/num/struct.NonZeroIsize.html#method.wrapping_abs) - [`num::NonZeroU*::checked_add`] (https://doc.rust-lang.org/stable/std/num/struct.NonZeroUsize.html#method.checked_add) - [`num::NonZeroU*::checked_next_power_of_two`] (https://doc.rust-lang.org/stable/std/num/struct.NonZeroUsize.html#method.checked_next_power_of_two) - [`num::NonZeroU*::saturating_add`] (https://doc.rust-lang.org/stable/std/num/struct.NonZeroUsize.html#method.saturating_add) - [`os::unix::process::CommandExt::process_group`] (https://doc.rust-lang.org/stable/std/os/unix/process/trait.CommandExt.html#tymethod.process_group) - [`os::windows::fs::FileTypeExt::is_symlink_dir`] (https://doc.rust-lang.org/stable/std/os/windows/fs/trait.FileTypeExt.html#tymethod.is_symlink_dir) - [`os::windows::fs::FileTypeExt::is_symlink_file`] (https://doc.rust-lang.org/stable/std/os/windows/fs/trait.FileTypeExt.html#tymethod.is_symlink_file) These types were previously stable in `std::ffi`, but are now also available in `core` and `alloc`: - [`core::ffi::CStr`] (https://doc.rust-lang.org/stable/core/ffi/struct.CStr.html) - [`core::ffi::FromBytesWithNulError`] (https://doc.rust-lang.org/stable/core/ffi/struct.FromBytesWithNulError.html) - [`alloc::ffi::CString`] (https://doc.rust-lang.org/stable/alloc/ffi/struct.CString.html) - [`alloc::ffi::FromVecWithNulError`] (https://doc.rust-lang.org/stable/alloc/ffi/struct.FromVecWithNulError.html) - [`alloc::ffi::IntoStringError`] (https://doc.rust-lang.org/stable/alloc/ffi/struct.IntoStringError.html) - [`alloc::ffi::NulError`] (https://doc.rust-lang.org/stable/alloc/ffi/struct.NulError.html) These types were previously stable in `std::os::raw`, but are now also available in `core::ffi` and `std::ffi`: - [`ffi::c_char`] (https://doc.rust-lang.org/stable/std/ffi/type.c_char.html) - [`ffi::c_double`] (https://doc.rust-lang.org/stable/std/ffi/type.c_double.html) - [`ffi::c_float`] (https://doc.rust-lang.org/stable/std/ffi/type.c_float.html) - [`ffi::c_int`] (https://doc.rust-lang.org/stable/std/ffi/type.c_int.html) - [`ffi::c_long`] (https://doc.rust-lang.org/stable/std/ffi/type.c_long.html) - [`ffi::c_longlong`] (https://doc.rust-lang.org/stable/std/ffi/type.c_longlong.html) - [`ffi::c_schar`] (https://doc.rust-lang.org/stable/std/ffi/type.c_schar.html) - [`ffi::c_short`] (https://doc.rust-lang.org/stable/std/ffi/type.c_short.html) - [`ffi::c_uchar`] (https://doc.rust-lang.org/stable/std/ffi/type.c_uchar.html) - [`ffi::c_uint`] (https://doc.rust-lang.org/stable/std/ffi/type.c_uint.html) - [`ffi::c_ulong`] (https://doc.rust-lang.org/stable/std/ffi/type.c_ulong.html) - [`ffi::c_ulonglong`] (https://doc.rust-lang.org/stable/std/ffi/type.c_ulonglong.html) - [`ffi::c_ushort`] (https://doc.rust-lang.org/stable/std/ffi/type.c_ushort.html) These APIs are now usable in const contexts: - [`slice::from_raw_parts`] (https://doc.rust-lang.org/stable/core/slice/fn.from_raw_parts.html) Cargo ----- - [Packages can now inherit settings from the workspace so that the settings can be centralized in one place.] (rust-lang/cargo#10859) See [`workspace.package`](https://doc.rust-lang.org/nightly/cargo/reference/workspaces.html#the-workspacepackage-table) and [`workspace.dependencies`](https://doc.rust-lang.org/nightly/cargo/reference/workspaces.html#the-workspacedependencies-table) for more details on how to define these common settings. - [Cargo commands can now accept multiple `--target` flags to build for multiple targets at once] (rust-lang/cargo#10766), and the [`build.target`](https://doc.rust-lang.org/nightly/cargo/reference/config.html#buildtarget) config option may now take an array of multiple targets. - [The `--jobs` argument can now take a negative number to count backwards from the max CPUs.] (rust-lang/cargo#10844) - [`cargo add` will now update `Cargo.lock`.] (rust-lang/cargo#10902) - [Added](rust-lang/cargo#10838) the [`--crate-type`](https://doc.rust-lang.org/nightly/cargo/commands/cargo-rustc.html#option-cargo-rustc---crate-type) flag to `cargo rustc` to override the crate type. - [Significantly improved the performance fetching git dependencies from GitHub when using a hash in the `rev` field.] (rust-lang/cargo#10079) Misc ---- - [The `rust-analyzer` rustup component is now available on the stable channel.] (rust-lang/rust#98640) Compatibility Notes ------------------- - The minimum required versions for all `-linux-gnu` targets are now at least kernel 3.2 and glibc 2.17, for targets that previously supported older versions: [Increase the minimum linux-gnu versions](rust-lang/rust#95026) - [Network primitives are now implemented with the ideal Rust layout, not the C system layout] (rust-lang/rust#78802). This can cause problems when transmuting the types. - [Add assertion that `transmute_copy`'s `U` is not larger than `T`] (rust-lang/rust#98839) - [A soundness bug in `BTreeMap` was fixed] (rust-lang/rust#99413) that allowed data it was borrowing to be dropped before the container. - [The Drop behavior of C-like enums cast to ints has changed] (rust-lang/rust#96862). These are already discouraged by a compiler warning. - [Relate late-bound closure lifetimes to parent fn in NLL] (rust-lang/rust#98835) - [Errors at const-eval time are now in future incompatibility reports] (rust-lang/rust#97743) - On the `thumbv6m-none-eabi` target, some incorrect `asm!` statements were erroneously accepted if they used the high registers (r8 to r14) as an input/output operand. [This is no longer accepted] (rust-lang/rust#99155). - [`impl Trait` was accidentally accepted as the associated type value of return-position `impl Trait`] (rust-lang/rust#97346), without fulfilling all the trait bounds of that associated type, as long as the hidden type satisfies said bounds. This has been fixed. Internal Changes ---------------- These changes do not affect any public interfaces of Rust, but they represent significant improvements to the performance or internals of rustc and related tools. - Windows builds now use profile-guided optimization, providing 10-20% improvements to compiler performance: [Utilize PGO for windows x64 rustc dist builds] (rust-lang/rust#96978) - [Stop keeping metadata in memory before writing it to disk] (rust-lang/rust#96544) - [compiletest: strip debuginfo by default for mode=ui] (rust-lang/rust#98140) - Many improvements to generated code for derives, including performance improvements: - [Don't use match-destructuring for derived ops on structs.] (rust-lang/rust#98446) - [Many small deriving cleanups] (rust-lang/rust#98741) - [More derive output improvements] (rust-lang/rust#98758) - [Clarify deriving code](rust-lang/rust#98915) - [Final derive output improvements] (rust-lang/rust#99046) - [Stop injecting `#[allow(unused_qualifications)]` in generated `derive` implementations](rust-lang/rust#99485) - [Improve `derive(Debug)`](rust-lang/rust#98190) - [Bump to clap 3](rust-lang/rust#98213) - [fully move dropck to mir](rust-lang/rust#98641) - [Optimize `Vec::insert` for the case where `index == len`.] (rust-lang/rust#98755) - [Convert rust-analyzer to an in-tree tool] (rust-lang/rust#99603)
This has now been in stable for a full release cycle. Seems to have worked out well. Maybe it's time to move on with the improvements this allows for? For example stabilizing the constructors as |
Pkgsrc changes: * This package now contains rust-analyzer, so implicitly conflicts with that pkgsrc package. The same goes for the rust-src package. * Add NetBSD/arm6 port * Add unfinished NetBSD/mipsel port * Revert the use of the internal LLVM, should now build with the new pkgsrc LLVM (15). * Add depndence on compat80 for sparc64 to fix the build * Adapt patches * Add CHECK_INTERPRETER_SKIP for a few (mostly unused) files. (A proper fix may come later.) Upstream changes: Version 1.64.0 (2022-09-22) =========================== Language -------- - [Unions with mutable references or tuples of allowed types are now allowed](rust-lang/rust#97995) - It is now considered valid to deallocate memory pointed to by a shared reference `&T` [if every byte in `T` is inside an `UnsafeCell`](rust-lang/rust#98017) - Unused tuple struct fields are now warned against in an allow-by-default lint, [`unused_tuple_struct_fields`] (rust-lang/rust#95977), similar to the existing warning for unused struct fields. This lint will become warn-by-default in the future. Compiler -------- - [Add Nintendo Switch as tier 3 target] (rust-lang/rust#88991) - Refer to Rust's [platform support page][platform-support-doc] for more information on Rust's tiered platform support. - [Only compile `#[used]` as llvm.compiler.used for ELF targets] (rust-lang/rust#93718) - [Add the `--diagnostic-width` compiler flag to define the terminal width.] (rust-lang/rust#95635) - [Add support for link-flavor `rust-lld` for iOS, tvOS and watchOS] (rust-lang/rust#98771) Libraries --------- - [Remove restrictions on compare-exchange memory ordering.] (rust-lang/rust#98383) - You can now `write!` or `writeln!` into an `OsString`: [Implement `fmt::Write` for `OsString`](rust-lang/rust#97915) - [Make RwLockReadGuard covariant] (rust-lang/rust#96820) - [Implement `FusedIterator` for `std::net::[Into]Incoming`] (rust-lang/rust#97300) - [`impl<T: AsRawFd> AsRawFd for {Arc,Box}<T>`] (rust-lang/rust#97437) - [`ptr::copy` and `ptr::swap` are doing untyped copies] (rust-lang/rust#97712) - [Add cgroupv1 support to `available_parallelism`] (rust-lang/rust#97925) - [Mitigate many incorrect uses of `mem::uninitialized`] (rust-lang/rust#99182) Stabilized APIs --------------- - [`future::IntoFuture`] (https://doc.rust-lang.org/stable/std/future/trait.IntoFuture.html) - [`future::poll_fn`] (https://doc.rust-lang.org/stable/std/future/fn.poll_fn.html) - [`task::ready!`] (https://doc.rust-lang.org/stable/std/task/macro.ready.html) - [`num::NonZero*::checked_mul`] (https://doc.rust-lang.org/stable/std/num/struct.NonZeroUsize.html#method.checked_mul) - [`num::NonZero*::checked_pow`] (https://doc.rust-lang.org/stable/std/num/struct.NonZeroUsize.html#method.checked_pow) - [`num::NonZero*::saturating_mul`] (https://doc.rust-lang.org/stable/std/num/struct.NonZeroUsize.html#method.saturating_mul) - [`num::NonZero*::saturating_pow`] (https://doc.rust-lang.org/stable/std/num/struct.NonZeroUsize.html#method.saturating_pow) - [`num::NonZeroI*::abs`] (https://doc.rust-lang.org/stable/std/num/struct.NonZeroIsize.html#method.abs) - [`num::NonZeroI*::checked_abs`] (https://doc.rust-lang.org/stable/std/num/struct.NonZeroIsize.html#method.checked_abs) - [`num::NonZeroI*::overflowing_abs`] (https://doc.rust-lang.org/stable/std/num/struct.NonZeroIsize.html#method.overflowing_abs) - [`num::NonZeroI*::saturating_abs`] (https://doc.rust-lang.org/stable/std/num/struct.NonZeroIsize.html#method.saturating_abs) - [`num::NonZeroI*::unsigned_abs`] (https://doc.rust-lang.org/stable/std/num/struct.NonZeroIsize.html#method.unsigned_abs) - [`num::NonZeroI*::wrapping_abs`] (https://doc.rust-lang.org/stable/std/num/struct.NonZeroIsize.html#method.wrapping_abs) - [`num::NonZeroU*::checked_add`] (https://doc.rust-lang.org/stable/std/num/struct.NonZeroUsize.html#method.checked_add) - [`num::NonZeroU*::checked_next_power_of_two`] (https://doc.rust-lang.org/stable/std/num/struct.NonZeroUsize.html#method.checked_next_power_of_two) - [`num::NonZeroU*::saturating_add`] (https://doc.rust-lang.org/stable/std/num/struct.NonZeroUsize.html#method.saturating_add) - [`os::unix::process::CommandExt::process_group`] (https://doc.rust-lang.org/stable/std/os/unix/process/trait.CommandExt.html#tymethod.process_group) - [`os::windows::fs::FileTypeExt::is_symlink_dir`] (https://doc.rust-lang.org/stable/std/os/windows/fs/trait.FileTypeExt.html#tymethod.is_symlink_dir) - [`os::windows::fs::FileTypeExt::is_symlink_file`] (https://doc.rust-lang.org/stable/std/os/windows/fs/trait.FileTypeExt.html#tymethod.is_symlink_file) These types were previously stable in `std::ffi`, but are now also available in `core` and `alloc`: - [`core::ffi::CStr`] (https://doc.rust-lang.org/stable/core/ffi/struct.CStr.html) - [`core::ffi::FromBytesWithNulError`] (https://doc.rust-lang.org/stable/core/ffi/struct.FromBytesWithNulError.html) - [`alloc::ffi::CString`] (https://doc.rust-lang.org/stable/alloc/ffi/struct.CString.html) - [`alloc::ffi::FromVecWithNulError`] (https://doc.rust-lang.org/stable/alloc/ffi/struct.FromVecWithNulError.html) - [`alloc::ffi::IntoStringError`] (https://doc.rust-lang.org/stable/alloc/ffi/struct.IntoStringError.html) - [`alloc::ffi::NulError`] (https://doc.rust-lang.org/stable/alloc/ffi/struct.NulError.html) These types were previously stable in `std::os::raw`, but are now also available in `core::ffi` and `std::ffi`: - [`ffi::c_char`] (https://doc.rust-lang.org/stable/std/ffi/type.c_char.html) - [`ffi::c_double`] (https://doc.rust-lang.org/stable/std/ffi/type.c_double.html) - [`ffi::c_float`] (https://doc.rust-lang.org/stable/std/ffi/type.c_float.html) - [`ffi::c_int`] (https://doc.rust-lang.org/stable/std/ffi/type.c_int.html) - [`ffi::c_long`] (https://doc.rust-lang.org/stable/std/ffi/type.c_long.html) - [`ffi::c_longlong`] (https://doc.rust-lang.org/stable/std/ffi/type.c_longlong.html) - [`ffi::c_schar`] (https://doc.rust-lang.org/stable/std/ffi/type.c_schar.html) - [`ffi::c_short`] (https://doc.rust-lang.org/stable/std/ffi/type.c_short.html) - [`ffi::c_uchar`] (https://doc.rust-lang.org/stable/std/ffi/type.c_uchar.html) - [`ffi::c_uint`] (https://doc.rust-lang.org/stable/std/ffi/type.c_uint.html) - [`ffi::c_ulong`] (https://doc.rust-lang.org/stable/std/ffi/type.c_ulong.html) - [`ffi::c_ulonglong`] (https://doc.rust-lang.org/stable/std/ffi/type.c_ulonglong.html) - [`ffi::c_ushort`] (https://doc.rust-lang.org/stable/std/ffi/type.c_ushort.html) These APIs are now usable in const contexts: - [`slice::from_raw_parts`] (https://doc.rust-lang.org/stable/core/slice/fn.from_raw_parts.html) Cargo ----- - [Packages can now inherit settings from the workspace so that the settings can be centralized in one place.] (rust-lang/cargo#10859) See [`workspace.package`](https://doc.rust-lang.org/nightly/cargo/reference/workspaces.html#the-workspacepackage-table) and [`workspace.dependencies`](https://doc.rust-lang.org/nightly/cargo/reference/workspaces.html#the-workspacedependencies-table) for more details on how to define these common settings. - [Cargo commands can now accept multiple `--target` flags to build for multiple targets at once] (rust-lang/cargo#10766), and the [`build.target`](https://doc.rust-lang.org/nightly/cargo/reference/config.html#buildtarget) config option may now take an array of multiple targets. - [The `--jobs` argument can now take a negative number to count backwards from the max CPUs.] (rust-lang/cargo#10844) - [`cargo add` will now update `Cargo.lock`.] (rust-lang/cargo#10902) - [Added](rust-lang/cargo#10838) the [`--crate-type`](https://doc.rust-lang.org/nightly/cargo/commands/cargo-rustc.html#option-cargo-rustc---crate-type) flag to `cargo rustc` to override the crate type. - [Significantly improved the performance fetching git dependencies from GitHub when using a hash in the `rev` field.] (rust-lang/cargo#10079) Misc ---- - [The `rust-analyzer` rustup component is now available on the stable channel.] (rust-lang/rust#98640) Compatibility Notes ------------------- - The minimum required versions for all `-linux-gnu` targets are now at least kernel 3.2 and glibc 2.17, for targets that previously supported older versions: [Increase the minimum linux-gnu versions](rust-lang/rust#95026) - [Network primitives are now implemented with the ideal Rust layout, not the C system layout] (rust-lang/rust#78802). This can cause problems when transmuting the types. - [Add assertion that `transmute_copy`'s `U` is not larger than `T`] (rust-lang/rust#98839) - [A soundness bug in `BTreeMap` was fixed] (rust-lang/rust#99413) that allowed data it was borrowing to be dropped before the container. - [The Drop behavior of C-like enums cast to ints has changed] (rust-lang/rust#96862). These are already discouraged by a compiler warning. - [Relate late-bound closure lifetimes to parent fn in NLL] (rust-lang/rust#98835) - [Errors at const-eval time are now in future incompatibility reports] (rust-lang/rust#97743) - On the `thumbv6m-none-eabi` target, some incorrect `asm!` statements were erroneously accepted if they used the high registers (r8 to r14) as an input/output operand. [This is no longer accepted] (rust-lang/rust#99155). - [`impl Trait` was accidentally accepted as the associated type value of return-position `impl Trait`] (rust-lang/rust#97346), without fulfilling all the trait bounds of that associated type, as long as the hidden type satisfies said bounds. This has been fixed. Internal Changes ---------------- These changes do not affect any public interfaces of Rust, but they represent significant improvements to the performance or internals of rustc and related tools. - Windows builds now use profile-guided optimization, providing 10-20% improvements to compiler performance: [Utilize PGO for windows x64 rustc dist builds] (rust-lang/rust#96978) - [Stop keeping metadata in memory before writing it to disk] (rust-lang/rust#96544) - [compiletest: strip debuginfo by default for mode=ui] (rust-lang/rust#98140) - Many improvements to generated code for derives, including performance improvements: - [Don't use match-destructuring for derived ops on structs.] (rust-lang/rust#98446) - [Many small deriving cleanups] (rust-lang/rust#98741) - [More derive output improvements] (rust-lang/rust#98758) - [Clarify deriving code](rust-lang/rust#98915) - [Final derive output improvements] (rust-lang/rust#99046) - [Stop injecting `#[allow(unused_qualifications)]` in generated `derive` implementations](rust-lang/rust#99485) - [Improve `derive(Debug)`](rust-lang/rust#98190) - [Bump to clap 3](rust-lang/rust#98213) - [fully move dropck to mir](rust-lang/rust#98641) - [Optimize `Vec::insert` for the case where `index == len`.] (rust-lang/rust#98755) - [Convert rust-analyzer to an in-tree tool] (rust-lang/rust#99603)
…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.
…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.
…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.
Most code and macros to convert from and to rust layout such as Ipv4Addr, Ipv6Addr, SocketAddrV4, SocketAddrV6 has been copied from the mio crate. All system calls have been replaced by the syscall macro similarly to the mio crate. Fixes phsym#12
This PR is the result of this internals forum thread: https://internals.rust-lang.org/t/why-are-socketaddrv4-socketaddrv6-based-on-low-level-sockaddr-in-6/13321.
Instead of basing
std:::net::{Ipv4Addr, Ipv6Addr, SocketAddrV4, SocketAddrV6}
on system (C) structs, they are encoded in a more optimal and idiomatic Rust way.This changes the public API of std by introducing structural equality impls for all four types here, which means that
match ipv4addr { SOME_CONSTANT => ... }
will now compile, whereas previously this was an error. No other intentional changes are introduced to public API.It's possible to observe the current layout of these types (e.g., by pointer casting); most but not all libraries which were found by Crater to do this have had updates issued and affected versions yanked. See report below.
Benefits of this change
std
intocore
(RFC).const fn
s today can be madeconst fn
s with this change.SocketAddrV4
only occupies 6 bytes instead of 16 bytes.unsafe
.Ipv4Addr
against a constantRemainingPrevious problemsThis change obviously changes the memory layout of the types. And it turns out some libraries invalidly assumes the memory layout and does very dangerous pointer casts to convert them. These libraries will have undefined behaviour and perform invalid memory access until patched.
mio
- Issue: mio::sys::unix::net::socket_addr assumes the layout of std::net::SocketAddrV{4,6} matches libc::sockaddr tokio-rs/mio#1386.0.7
branch Don't assume memory layout of std::net::SocketAddr tokio-rs/mio#13880.7.6
published Release v0.7.6 tokio-rs/mio#13980.7
versions older than0.7.6
<0.7.6
to RustSec Advisory Database https://rustsec.org/advisories/RUSTSEC-2020-0081.htmlsocket2
- Issue: The code assumes the memory layout of SocketAddrV{4,6} socket2#119.0.3.x
branch Don't assume memory layout of std::net::SocketAddr (0.3.x) socket2#1200.3.16
publishedmaster
branch Don't assume memory layout of std::net::SocketAddr (master) socket2#1220.3
versions older than0.3.16
<0.3.16
to RustSec Advisory Database https://rustsec.org/advisories/RUSTSEC-2020-0079.htmlnet2
- Issue: net2 assumes the layout of std::net::SocketAddrV{4,6} matches libc::sockaddr deprecrated/net2-rs#1050.2.36
published0.2
versions older than0.2.36
<0.2.36
to RustSec Advisory Database https://rustsec.org/advisories/RUSTSEC-2020-0078.htmlmiow
- Issue: Invalidly assumes the memory layout of SocketAddrV{4,6} yoshuawuyts/miow#380.3.x
- Don't assume memory layout of std::net::SocketAddr yoshuawuyts/miow#390.3.6
published0.2.x
- Don't assume memory layout of std::net::SocketAddr (0.2.x) yoshuawuyts/miow#400.2.2
published0.2
versions older than0.2.2
0.3
versions older than0.3.6
<0.2.2
and<0.3.6
to RustSec Advisory Database https://rustsec.org/advisories/RUSTSEC-2020-0080.htmlquinn master
(aka what became 0.7) - Invalid assumption about SocketAddrV{4,6} layout quinn-rs/quinn#968 Sound addr quinn-rs/quinn#987quinn 0.6
- [0.6.x] Don't assume representation of SocketAddr quinn-rs/quinn#1045quinn 0.5
- [0.5.x] Don't assume representation of SocketAddr quinn-rs/quinn#10460.7.0
,0.6.2
and0.5.4
nb-connect
- Invalid assumption of SocketAddrV{4,6} layout smol-rs/nb-connect#11.0.3
1.0.3
shadowsocks-rust
- Invalid layout assumptions forstd::net::SocketAddrV{4, 6}
shadowsocks/shadowsocks-rust#462rio
- Invalid layout assumptions for std::net::SocketAddrV{4, 6} spacejam/rio#44seaslug
- Invalid layout assumptions for std::net::SocketAddrV{4, 6} spacejam/seaslug#1Fixed crate versions
All crates I have found that assumed the memory layout have been fixed and published. The crates and versions that will continue working even as/if this PR is merged is (please upgrade these to help unblock this PR):
net2 0.2.36
socket2 0.3.16
miow 0.2.2
miow 0.3.6
mio 0.7.6
mio 0.6.23
- Never had the invalid assumption itself, but has now been bumped to only allow fixed dependencies (net2
+miow
)nb-connect 1.0.3
quinn 0.5.4
quinn 0.6.2
Release notes draft
This release changes the memory layout of
Ipv4Addr
,Ipv6Addr
,SocketAddrV4
andSocketAddrV6
. The standard library no longer implements these as the correspondinglibc
structs (sockaddr_in
,sockaddr_in6
etc.). This internal representation was never exposed, but some crates relied on it anyway by unsafely transmuting. This change will cause those crates to make invalid memory accesses. Notablynet2 <0.2.36
,socket2 <0.3.16
,mio <0.7.6
,miow <0.3.6
and a few other crates are affected. All known affected crates have been patched and have had fixed versions published over a year ago. If any affected crate is still in your dependency tree, you need to upgrade them before using this version of Rust.