|
| 1 | +- Feature Name: `core_net_ipaddr_types` |
| 2 | +- Start Date: 2019-12-06 |
| 3 | +- RFC PR: [rust-lang/rfcs#2832](https://github.com/rust-lang/rfcs/pull/2832) |
| 4 | +- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) |
| 5 | + |
| 6 | +# Summary |
| 7 | +[summary]: #summary |
| 8 | + |
| 9 | +Make the `IpAddr`, `Ipv4Addr` and `Ipv6Addr` types available in `no_std` |
| 10 | +contexts by moving them into a `core::net` module. |
| 11 | + |
| 12 | +# Motivation |
| 13 | +[motivation]: #motivation |
| 14 | + |
| 15 | +The motivation here is to provide common types for both `no_std` and `std` |
| 16 | +targets which in turn will ease the creation of libraries based around IP |
| 17 | +addresses. Embedded IoT development is one area where this will be beneficial. |
| 18 | +IP addresses are portable across all platforms and have no external |
| 19 | +dependencies which is in line with the definition of the core library. |
| 20 | + |
| 21 | +# Guide-level explanation |
| 22 | +[guide-level-explanation]: #guide-level-explanation |
| 23 | + |
| 24 | +The `core::net::IpAddr`, `core::net::Ipv4Addr` and `core::net::Ipv6Addr` types |
| 25 | +are available in `no_std` contexts. |
| 26 | + |
| 27 | +Library developers should use `core::net` to implement abstractions in order |
| 28 | +for them to work in `no_std` contexts as well. |
| 29 | + |
| 30 | +# Reference-level explanation |
| 31 | +[reference-level-explanation]: #reference-level-explanation |
| 32 | + |
| 33 | +Currently, the IP address types depend on their corresponding `libc` |
| 34 | +counterpart for their `inner` value. |
| 35 | + |
| 36 | +IPv4 addresses are well-defined. [IETF RFC 791] specifically states: |
| 37 | + |
| 38 | +> Addresses are fixed length of four octets (32 bits). |
| 39 | +
|
| 40 | +IPv6 addresses are well-defined. [IETF RFC 4291] specifically states: |
| 41 | + |
| 42 | +> IPv6 addresses are 128-bit identifiers |
| 43 | +
|
| 44 | +Since the size and representation of IPv4 and IPv6 addresses are well defined, |
| 45 | +we can replace the `inner` value of `Ipv4Addr` with a `[u8; 4]` and the `inner` |
| 46 | +value of `IPv6Addr` with a `[u8; 16]`. |
| 47 | + |
| 48 | +The inner types `[u8; 4]` and `[u8; 16]` are expected to correspond to `u32` |
| 49 | +and `u128` in big-endian byte order. Currently, this is already ensured: |
| 50 | + |
| 51 | +- `u32::to_be` is used when constructing the corresponding `libc` type for |
| 52 | + `Ipv4Addr`. |
| 53 | +- The corresponding `libc` type for `IPv6Addr` is already represented as a |
| 54 | + `[u8; 16]` internally on all platforms. |
| 55 | + |
| 56 | +[IETF RFC 791]: https://tools.ietf.org/html/rfc791 |
| 57 | +[IETF RFC 4291]: https://tools.ietf.org/html/rfc4291 |
| 58 | + |
| 59 | +# Drawbacks |
| 60 | +[drawbacks]: #drawbacks |
| 61 | + |
| 62 | +Moving the `std::net` types to `core::net` makes the core library less *minimal*. |
| 63 | + |
| 64 | +# Rationale and alternatives |
| 65 | +[rationale-and-alternatives]: #rationale-and-alternatives |
| 66 | + |
| 67 | +- Given the size of IP addresses is well defined by IETF RFCs, there is no |
| 68 | + inherent need to have these types depend on `libc`. |
| 69 | + |
| 70 | +- Eliminates the need to use different abstractions for `no_std` and `std`. |
| 71 | + |
| 72 | +# Prior art |
| 73 | +[prior-art]: #prior-art |
| 74 | + |
| 75 | +There was a prior discussion at |
| 76 | + |
| 77 | +https://internals.rust-lang.org/t/std-ipv4addr-in-core/11247/15 |
| 78 | + |
| 79 | +and an experimental branch from [@Nemo157](https://github.com/Nemo157) at |
| 80 | + |
| 81 | +https://github.com/Nemo157/rust/tree/core-ip |
| 82 | + |
| 83 | +# Unresolved questions |
| 84 | +[unresolved-questions]: #unresolved-questions |
| 85 | + |
| 86 | +None. |
| 87 | + |
| 88 | +# Future possibilities |
| 89 | +[future-possibilities]: #future-possibilities |
| 90 | + |
| 91 | +`SocketAddr`, `SocketAddrV4` and `SocketAddrV6` could also be moved in the |
| 92 | +future. |
0 commit comments