Skip to content

Commit 053bc3f

Browse files
committed
Refactor address byte swapping
When encoding a `network::Address` two of the fields are encoded big-endian instead of little-endian as is done by `consensus_encode`. In order to achieve this we have a helper function `addr_to_be` that swaps the bytes. This function is miss-named because it is not converting to a specific endian-ness (which implies different behaviour on machines with different endian-ness) but is reversing the byte order irrespective of the underlying architecture. - Remove function `addr_to_be` - Inline the endian-ness code when encoding an address - Remove TODO and use `to_be_bytes` when encoding port - Add a function for reading big-endian bytes `read_be_address` - Use `read_be_address` when decoding `Address` and `Addrv2` Refactor only, no logic changes. Code path is already covered by unit tests.
1 parent bb495a2 commit 053bc3f

File tree

1 file changed

+25
-20
lines changed

1 file changed

+25
-20
lines changed

src/network/address.rs

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -67,25 +67,19 @@ impl Address {
6767
}
6868
}
6969

70-
fn addr_to_be(addr: [u16; 8]) -> [u16; 8] {
71-
// consensus_encode always encodes in LE, and we want to encode in BE.
72-
// this utility fn swap bytes before encoding so that the encoded result will be BE
73-
let mut result = addr;
74-
for word in &mut result {
75-
*word = word.swap_bytes();
76-
}
77-
result
78-
}
79-
8070
impl Encodable for Address {
8171
#[inline]
8272
fn consensus_encode<S: io::Write>(&self, mut s: S) -> Result<usize, io::Error> {
83-
let len = self.services.consensus_encode(&mut s)?
84-
+ addr_to_be(self.address).consensus_encode(&mut s)?
73+
let mut len = self.services.consensus_encode(&mut s)?;
74+
75+
for word in &self.address {
76+
s.write_all(&word.to_be_bytes())?;
77+
len += 2;
78+
}
79+
80+
s.write_all(&self.port.to_be_bytes())?;
81+
len += 2;
8582

86-
// consensus_encode always encodes in LE, and we want to encode in BE.
87-
//TODO `len += io::Write::write(&mut e, &self.port.to_be_bytes())?;` when MSRV >= 1.32
88-
+ self.port.swap_bytes().consensus_encode(s)?;
8983
Ok(len)
9084
}
9185
}
@@ -95,12 +89,24 @@ impl Decodable for Address {
9589
fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, encode::Error> {
9690
Ok(Address {
9791
services: Decodable::consensus_decode(&mut d)?,
98-
address: addr_to_be(Decodable::consensus_decode(&mut d)?),
92+
address: read_be_address(&mut d)?,
9993
port: u16::swap_bytes(Decodable::consensus_decode(d)?)
10094
})
10195
}
10296
}
10397

98+
/// Read a big-endian address from reader.
99+
fn read_be_address<R: io::Read>(mut r: R) -> Result<[u16; 8], encode::Error> {
100+
let mut address = [0u16; 8];
101+
let mut buf = [0u8; 2];
102+
103+
for word in &mut address {
104+
io::Read::read_exact(&mut r, &mut buf)?;
105+
*word = u16::from_be_bytes(buf)
106+
}
107+
Ok(address)
108+
}
109+
104110
impl fmt::Debug for Address {
105111
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
106112
let ipv6 = Ipv6Addr::from(self.address);
@@ -180,7 +186,7 @@ impl Decodable for AddrV2 {
180186
if len != 16 {
181187
return Err(encode::Error::ParseFailed("Invalid IPv6 address"));
182188
}
183-
let addr: [u16; 8] = addr_to_be(Decodable::consensus_decode(&mut d)?);
189+
let addr: [u16; 8] = read_be_address(&mut d)?;
184190
if addr[0..3] == ONION {
185191
return Err(encode::Error::ParseFailed("OnionCat address sent with IPv6 network id"));
186192
}
@@ -214,12 +220,11 @@ impl Decodable for AddrV2 {
214220
if len != 16 {
215221
return Err(encode::Error::ParseFailed("Invalid CJDNS address"));
216222
}
217-
let addr: [u16; 8] = Decodable::consensus_decode(&mut d)?;
223+
let addr: [u16; 8] = read_be_address(&mut d)?;
218224
// check the first byte for the CJDNS marker
219-
if addr[0] as u8 != 0xFC {
225+
if addr[0] != u16::from_be_bytes([0xFC, 0x00]) {
220226
return Err(encode::Error::ParseFailed("Invalid CJDNS address"));
221227
}
222-
let addr = addr_to_be(addr);
223228
AddrV2::Cjdns(Ipv6Addr::new(addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7]))
224229
},
225230
_ => {

0 commit comments

Comments
 (0)