-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add RFC for ipv6addr octets interface
- Loading branch information
Showing
1 changed file
with
69 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
- Feature Name: ipv6addr_octets_interface | ||
- Start Date: 2016-02-12 | ||
- RFC PR: (leave this empty) | ||
- Rust Issue: (leave this empty) | ||
|
||
# Summary | ||
[summary]: #summary | ||
|
||
Add constructor and getter functions to `std::net::Ipv6Addr` that are | ||
oriented around octets. | ||
|
||
# Motivation | ||
[motivation]: #motivation | ||
|
||
Currently, the interface for `std::net::Ipv6Addr` is oriented around 16-bit | ||
"segments". The constructor takes eight 16-bit integers as arguments, | ||
and the sole getter function, `segments`, returns an array of eight | ||
16-bit integers. This interface is unnatural when doing low-level network | ||
programming, where IPv6 addresses are treated as a sequence of 16 octets. | ||
For example, building and parsing IPv6 packets requires doing | ||
bitwise arithmetic with careful attention to byte order in order to convert | ||
between the on-wire format of 16 octets and the eight segments format used | ||
by `std::net::Ipv6Addr`. | ||
|
||
# Detailed design | ||
[design]: #detailed-design | ||
|
||
Two functions would be added to `impl std::net::Ipv6Addr`: | ||
|
||
``` | ||
pub fn from_octets(octets: &[u8; 16]) -> Ipv6Addr { | ||
let mut addr: c::in6_addr = unsafe { std::mem::zeroed() }; | ||
addr.s6_addr = *octets; | ||
Ipv6Addr { inner: addr } | ||
} | ||
pub fn octets(&self) -> &[u8; 16] { | ||
&self.inner.s6_addr | ||
} | ||
``` | ||
|
||
# Drawbacks | ||
[drawbacks]: #drawbacks | ||
|
||
It adds additional functions to the `Ipv6Addr` API, which increases cognitive load | ||
and maintenance burden. That said, the functions are conceptually very simple | ||
and their implementations short. | ||
|
||
Returning a reference from `octets` ties the interface to the internal representation | ||
of `Ipv6Addr`, which is currently `[u8; 16]`. It would not be possible to change `Ipv6Addr` | ||
to use a different representation without changing the return type of `octets` to be a non-reference. | ||
|
||
# Alternatives | ||
[alternatives]: #alternatives | ||
|
||
Do nothing. The downside is that developers will need to resort to | ||
bitwise arithmetic, which is awkward and error-prone (particularly with | ||
respect to byte ordering) to convert between `Ipv6Addr` and the on-wire | ||
representation of IPv6 addresses. Or they will use their alternative | ||
implementations of `Ipv6Addr`, fragmenting the ecosystem. | ||
|
||
`octets` could return a non-reference to avoid tying the interface to the | ||
internal representation. However, it seems unlikely that the internal | ||
representation would ever be anything besides a `[u8; 16]`. | ||
|
||
# Unresolved questions | ||
[unresolved]: #unresolved-questions | ||
|
||
Should `octets` return a reference? Pro: avoid a copy. Con: ties the interface to the internal | ||
representation, which is presently `[u8; 16]`. |