Documentation should be clearer about lack of support for IPv4-mapped IPv6 addresses in helper methods
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
Location (URL)
https://doc.rust-lang.org/std/net/enum.IpAddr.html
https://doc.rust-lang.org/std/net/struct.Ipv6Addr.html
Summary
There has been past discussion about whether Rust should support IPv4-mapped IPv6 addresses, and I don't want to raise that issue again. But the current behaviour has some footguns that I think should be documented better.
For example, I think it's reasonable to write a function such as:
/// Ensure that we don't make TCP connections to loopback addresses.
fn connect_if_not_loopback(s: SocketAddr) -> std::io::Result<Option<TcpStream>> {
if s.ip().is_loopback() {
return Ok(None);
}
Ok(Some(TcpStream::connect(s)?))
}
and it would be reasonable to expect that it would prevent connections to loopback addresses. And there isn't anything in IpAddr that would suggest otherwise.
But since Ipv6Addr::is_loopback() does not handle IPv4-mapped IPv6 addresses, this code is broken, and may lead to security issues in code where the author wasn't knowledgeable of IPv4-mapped IPv6 addresses.
For example:
let localhost = IpAddr::V6(Ipv4Addr::LOCALHOST.to_ipv6_mapped());
// We expect this to return `None`, but it connects to the loopback address and returns `Some`.
// This assertion panics.
assert!(connect_if_not_loopback(SocketAddr::new(localhost, 9000)).unwrap().is_none());
The correct code (AFAIK) should use s.ip().to_canonical().is_loopback(), but this isn't clear from the documentation. And this isn't an issue for just is_loopback(), but also other methods like is_unspecified() and the various nightly methods.
There is some top-level documentation in Ipv6Addr, but it doesn't mention to_canonical() at all and is easy to miss.
So I think it would be helpful (and remove a footgun) for IpAddr and Ipv6Addr if the helper is_foo() methods had a sentence explaining that they don't handle IPv4-mapped IPv6 addresses, and linked to a paragraph for how to handle them properly.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the IpAddr and Ipv6Addr documentation pages named in the issue, including the “embedding IPv4 addresses” section and the listed is_foo() helper methods. Clarify that these helpers do not handle IPv4-mapped IPv6 addresses, and link to the documented canonicalization approach. Done means the affected helper documentation clearly explains the limitation and how to handle mapped addresses.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- documentation, networking
- Issue type
- Documentation
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100