Create a CanonicalAddr serialization and key type #2364
Labels
A-network
Area: Network protocol updates or fixes
A-rust
Area: Updates to Rust code
C-security
Category: Security issues
I-invalid-data
Zebra relies on invalid or untrusted data, or sends invalid data
I-remote-node-overload
Zebra can overload other nodes on the network
Motivation
In PR #2276, we make sure that all
SocketAddr
s are canonical in theMetaAddr
andMetaAddrChange
constructors.Otherwise, some
SocketAddr
s could compare unequal, but actually connect to the same peer. This breaks Zebra's network security overall connection limits (PeerSet
/AddressBook
) and new connection rate-limits (CandidateSet
/AddressBook
).But non-canonical addresses could accidentally be added in new code. So we should enforce canonical addresses using a
CanonicalAddr
type.IPv4 in IPv6 Specifications
Bitcoin
https://developer.bitcoin.org/reference/p2p_networking.html#addr
Rust API
But the Rust
IPv6Addr::to_ipv4
method supports IPv4-compatible and IPv4-mapped IPv6 addresses:https://doc.rust-lang.org/std/net/struct.Ipv6Addr.html#method.to_ipv4
IPv4-mapped IPv6 Addresses
https://datatracker.ietf.org/doc/html/rfc6890#page-15
IPv4-compatible IPv6 Addresses
https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.5.1
Rust IPv6 APIs
https://doc.rust-lang.org/std/net/struct.SocketAddrV6.html
PartialEq for SocketAddrV6
also checks theflowinfo
andscope_id
fields:https://doc.rust-lang.org/src/std/net/addr.rs.html#700-707
https://doc.rust-lang.org/std/net/struct.SocketAddrV6.html#method.scope_id
https://doc.rust-lang.org/std/net/struct.SocketAddrV6.html#method.flowinfo
Solution
CanonicalAddr
type tozebra_chain::serialization::socket_addr
ip: IpAddr
andport: u16
fieldsFrom<SocketAddr>
andFromStr
methodsSocketAddr
SocketAddr
withCanonicalAddr
inzebra-network
:Message
Request
/Response
MetaAddr
/AddressBook
impl Arbitrary for CanonicalAddr
, then remove thecanonical_socket_addr
strategy attributesAlternatives
Currently Zebra converts
SocketAddr
s into their canonical form in a few different places. It would be easy to forget to add this conversion, or forget to test it.We could just store an IPv6 address internally, and map IPv4-mapped IPv6 addresses to an IPv4 address in the
ip
method. (And in theDebug
impl.)We could just work in IPv6 addresses, but this makes debugging harder, and might impact compatibility with older C libraries with poor IPv6 support.
The text was updated successfully, but these errors were encountered: