|
| 1 | +- Feature Name: ipaddr_octet_arrays |
| 2 | +- Start Date: 2016-02-12 |
| 3 | +- RFC PR: (leave this empty) |
| 4 | +- Rust Issue: (leave this empty) |
| 5 | + |
| 6 | +# Summary |
| 7 | +[summary]: #summary |
| 8 | + |
| 9 | +Add constructor and conversion functions for `std::net::Ipv6Addr` and |
| 10 | +`std::net::Ipv4Addr` that are oriented around arrays of octets. |
| 11 | + |
| 12 | +# Motivation |
| 13 | +[motivation]: #motivation |
| 14 | + |
| 15 | +Currently, the interface for `std::net::Ipv6Addr` is oriented around 16-bit |
| 16 | +"segments". The constructor takes eight 16-bit integers as arguments, |
| 17 | +and the sole getter function, `segments`, returns an array of eight |
| 18 | +16-bit integers. This interface is unnatural when doing low-level network |
| 19 | +programming, where IPv6 addresses are treated as a sequence of 16 octets. |
| 20 | +For example, building and parsing IPv6 packets requires doing |
| 21 | +bitwise arithmetic with careful attention to byte order in order to convert |
| 22 | +between the on-wire format of 16 octets and the eight segments format used |
| 23 | +by `std::net::Ipv6Addr`. |
| 24 | + |
| 25 | +# Detailed design |
| 26 | +[design]: #detailed-design |
| 27 | + |
| 28 | +The following method would be added to `impl std::net::Ipv6Addr`: |
| 29 | + |
| 30 | +``` |
| 31 | +pub fn octets(&self) -> [u8; 16] { |
| 32 | + self.inner.s6_addr |
| 33 | +} |
| 34 | +``` |
| 35 | + |
| 36 | +The following `From` trait would be implemented: |
| 37 | + |
| 38 | +``` |
| 39 | +impl From<[u8; 16]> for Ipv6Addr { |
| 40 | + fn from(octets: [u8; 16]) -> Ipv6Addr { |
| 41 | + let mut addr: c::in6_addr = unsafe { std::mem::zeroed() }; |
| 42 | + addr.s6_addr = octets; |
| 43 | + Ipv6Addr { inner: addr } |
| 44 | + } |
| 45 | +} |
| 46 | +``` |
| 47 | + |
| 48 | +For consistency, the following `From` trait would be |
| 49 | +implemented for `Ipv4Addr`: |
| 50 | + |
| 51 | +``` |
| 52 | +impl From<[u8; 4]> for Ipv4Addr { |
| 53 | + fn from(octets: [u8; 4]) -> Ipv4Addr { |
| 54 | + Ipv4Addr::new(octets[0], octets[1], octets[2], octets[3]) |
| 55 | + } |
| 56 | +} |
| 57 | +``` |
| 58 | + |
| 59 | +Note: `Ipv4Addr` already has an `octets` method that returns a `[u8; 4]`. |
| 60 | + |
| 61 | +# Drawbacks |
| 62 | +[drawbacks]: #drawbacks |
| 63 | + |
| 64 | +It adds additional functions to the API, which increases cognitive load |
| 65 | +and maintenance burden. That said, the functions are conceptually very simple |
| 66 | +and their implementations short. |
| 67 | + |
| 68 | +# Alternatives |
| 69 | +[alternatives]: #alternatives |
| 70 | + |
| 71 | +Do nothing. The downside is that developers will need to resort to |
| 72 | +bitwise arithmetic, which is awkward and error-prone (particularly with |
| 73 | +respect to byte ordering) to convert between `Ipv6Addr` and the on-wire |
| 74 | +representation of IPv6 addresses. Or they will use their alternative |
| 75 | +implementations of `Ipv6Addr`, fragmenting the ecosystem. |
| 76 | + |
| 77 | +# Unresolved questions |
| 78 | +[unresolved]: #unresolved-questions |
| 79 | + |
0 commit comments