Stop converting IPv6-compatible IPv4 addresses to IPv4
Zcash only uses IPv6-mapped IPv4 addresses in its network protocol.
This commit is contained in:
parent
c0114a2c5f
commit
6fb94baeb9
|
@ -1,7 +1,7 @@
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::{
|
use std::{
|
||||||
convert::TryInto,
|
convert::TryInto,
|
||||||
net::{IpAddr, SocketAddr},
|
net::{IpAddr, Ipv6Addr, SocketAddr},
|
||||||
};
|
};
|
||||||
|
|
||||||
use byteorder::{BigEndian, LittleEndian, ReadBytesExt};
|
use byteorder::{BigEndian, LittleEndian, ReadBytesExt};
|
||||||
|
@ -95,16 +95,11 @@ pub trait ReadZcashExt: io::Read {
|
||||||
/// Read an IP address in Bitcoin format.
|
/// Read an IP address in Bitcoin format.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn read_ip_addr(&mut self) -> io::Result<IpAddr> {
|
fn read_ip_addr(&mut self) -> io::Result<IpAddr> {
|
||||||
use std::net::{IpAddr::*, Ipv6Addr};
|
|
||||||
|
|
||||||
let mut octets = [0u8; 16];
|
let mut octets = [0u8; 16];
|
||||||
self.read_exact(&mut octets)?;
|
self.read_exact(&mut octets)?;
|
||||||
let v6_addr = Ipv6Addr::from(octets);
|
let v6_addr = Ipv6Addr::from(octets);
|
||||||
|
|
||||||
match v6_addr.to_ipv4() {
|
Ok(canonical_ip_addr(&v6_addr))
|
||||||
Some(v4_addr) => Ok(V4(v4_addr)),
|
|
||||||
None => Ok(V6(v6_addr)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read a Bitcoin-encoded `SocketAddr`.
|
/// Read a Bitcoin-encoded `SocketAddr`.
|
||||||
|
@ -150,3 +145,20 @@ pub trait ReadZcashExt: io::Read {
|
||||||
|
|
||||||
/// Mark all types implementing `Read` as implementing the extension.
|
/// Mark all types implementing `Read` as implementing the extension.
|
||||||
impl<R: io::Read + ?Sized> ReadZcashExt for R {}
|
impl<R: io::Read + ?Sized> ReadZcashExt for R {}
|
||||||
|
|
||||||
|
/// Transform a Zcash-deserialized IPv6 address into a canonical Zebra IP address.
|
||||||
|
///
|
||||||
|
/// Zcash uses IPv6-mapped IPv4 addresses in its network protocol. Zebra converts
|
||||||
|
/// those addresses to `Ipv4Addr`s, for maximum compatibility with systems that
|
||||||
|
/// don't understand IPv6.
|
||||||
|
pub fn canonical_ip_addr(v6_addr: &Ipv6Addr) -> IpAddr {
|
||||||
|
use IpAddr::*;
|
||||||
|
|
||||||
|
// TODO: replace with `to_ipv4_mapped` when that stabilizes
|
||||||
|
// https://github.com/rust-lang/rust/issues/27709
|
||||||
|
match v6_addr.to_ipv4() {
|
||||||
|
// workaround for unstable `to_ipv4_mapped`
|
||||||
|
Some(v4_addr) if v4_addr.to_ipv6_mapped() == *v6_addr => V4(v4_addr),
|
||||||
|
Some(_) | None => V6(*v6_addr),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue