Skip to content

Commit e64446b

Browse files
authored
Changing port of ReponseBody::Pong to NonZeroU16 (#220)
* Change `port` from u16 to NonZeroU16 * Fix tests * Fix test: the PONG port can't be zero * Fix clippy warnings
1 parent f289bbd commit e64446b

File tree

5 files changed

+72
-47
lines changed

5 files changed

+72
-47
lines changed

src/handler/tests.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ use crate::{
77
rpc::{Request, Response},
88
ConfigBuilder, IpMode,
99
};
10-
use std::net::{Ipv4Addr, Ipv6Addr};
10+
use std::{
11+
convert::TryInto,
12+
net::{Ipv4Addr, Ipv6Addr},
13+
};
1114

1215
use crate::{
1316
handler::{session::build_dummy_session, HandlerOut::RequestFailed},
@@ -258,7 +261,7 @@ async fn multiple_messages() {
258261
body: ResponseBody::Pong {
259262
enr_seq: 1,
260263
ip: ip.into(),
261-
port: sender_port,
264+
port: sender_port.try_into().unwrap(),
262265
},
263266
};
264267

src/ipmode.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,17 @@ impl IpMode {
6969
}
7070
}
7171

72+
/// Copied from the standard library. See <https://github.com/rust-lang/rust/issues/27709>
73+
/// The current code is behind the `ip` feature.
74+
pub const fn to_ipv4_mapped(ip: &std::net::Ipv6Addr) -> Option<std::net::Ipv4Addr> {
75+
match ip.octets() {
76+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, a, b, c, d] => {
77+
Some(std::net::Ipv4Addr::new(a, b, c, d))
78+
}
79+
_ => None,
80+
}
81+
}
82+
7283
#[cfg(test)]
7384
mod tests {
7485
use super::*;
@@ -230,14 +241,3 @@ mod tests {
230241
.test();
231242
}
232243
}
233-
234-
/// Copied from the standard library. See <https://github.com/rust-lang/rust/issues/27709>
235-
/// The current code is behind the `ip` feature.
236-
pub const fn to_ipv4_mapped(ip: &std::net::Ipv6Addr) -> Option<std::net::Ipv4Addr> {
237-
match ip.octets() {
238-
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, a, b, c, d] => {
239-
Some(std::net::Ipv4Addr::new(a, b, c, d))
240-
}
241-
_ => None,
242-
}
243-
}

src/rpc.rs

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
use enr::{CombinedKey, Enr};
22
use rlp::{DecoderError, RlpStream};
3-
use std::net::{IpAddr, Ipv6Addr};
3+
use std::{
4+
convert::TryInto,
5+
net::{IpAddr, Ipv6Addr},
6+
num::NonZeroU16,
7+
};
48
use tracing::{debug, warn};
59

610
/// Type to manage the request IDs.
@@ -89,7 +93,7 @@ pub enum ResponseBody {
8993
/// Our external IP address as observed by the responder.
9094
ip: IpAddr,
9195
/// Our external UDP port as observed by the responder.
92-
port: u16,
96+
port: NonZeroU16,
9397
},
9498
/// A NODES response.
9599
Nodes {
@@ -186,7 +190,7 @@ impl Response {
186190
IpAddr::V4(addr) => s.append(&(&addr.octets() as &[u8])),
187191
IpAddr::V6(addr) => s.append(&(&addr.octets() as &[u8])),
188192
};
189-
s.append(&port);
193+
s.append(&port.get());
190194
buf.extend_from_slice(&s.out());
191195
buf
192196
}
@@ -378,15 +382,20 @@ impl Message {
378382
return Err(DecoderError::RlpIncorrectListLen);
379383
}
380384
};
381-
let port = rlp.val_at::<u16>(3)?;
382-
Message::Response(Response {
383-
id,
384-
body: ResponseBody::Pong {
385-
enr_seq: rlp.val_at::<u64>(1)?,
386-
ip,
387-
port,
388-
},
389-
})
385+
let raw_port = rlp.val_at::<u16>(3)?;
386+
if let Ok(port) = raw_port.try_into() {
387+
Message::Response(Response {
388+
id,
389+
body: ResponseBody::Pong {
390+
enr_seq: rlp.val_at::<u64>(1)?,
391+
ip,
392+
port,
393+
},
394+
})
395+
} else {
396+
debug!("The port number should be non zero: {raw_port}");
397+
return Err(DecoderError::Custom("PONG response port number invalid"));
398+
}
390399
}
391400
3 => {
392401
// FindNodeRequest
@@ -530,7 +539,11 @@ mod tests {
530539
let port = 5000;
531540
let message = Message::Response(Response {
532541
id,
533-
body: ResponseBody::Pong { enr_seq, ip, port },
542+
body: ResponseBody::Pong {
543+
enr_seq,
544+
ip,
545+
port: port.try_into().unwrap(),
546+
},
534547
});
535548

536549
// expected hex output
@@ -647,7 +660,7 @@ mod tests {
647660
body: ResponseBody::Pong {
648661
enr_seq: 15,
649662
ip: "127.0.0.1".parse().unwrap(),
650-
port: 80,
663+
port: 80.try_into().unwrap(),
651664
},
652665
});
653666

@@ -665,7 +678,7 @@ mod tests {
665678
body: ResponseBody::Pong {
666679
enr_seq: 15,
667680
ip: IpAddr::V6(Ipv4Addr::new(192, 0, 2, 1).to_ipv6_mapped()),
668-
port: 80,
681+
port: 80.try_into().unwrap(),
669682
},
670683
});
671684

@@ -676,7 +689,7 @@ mod tests {
676689
body: ResponseBody::Pong {
677690
enr_seq: 15,
678691
ip: IpAddr::V4(Ipv4Addr::new(192, 0, 2, 1)),
679-
port: 80,
692+
port: 80.try_into().unwrap(),
680693
},
681694
});
682695

@@ -691,7 +704,7 @@ mod tests {
691704
body: ResponseBody::Pong {
692705
enr_seq: 15,
693706
ip: IpAddr::V6(Ipv6Addr::LOCALHOST),
694-
port: 80,
707+
port: 80.try_into().unwrap(),
695708
},
696709
});
697710

src/service.rs

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ use parking_lot::RwLock;
4040
use rpc::*;
4141
use std::{
4242
collections::HashMap,
43+
convert::TryInto,
4344
net::{IpAddr, SocketAddr},
4445
sync::Arc,
4546
task::Poll,
@@ -606,20 +607,24 @@ impl Service {
606607

607608
// build the PONG response
608609
let src = node_address.socket_addr;
609-
let response = Response {
610-
id,
611-
body: ResponseBody::Pong {
612-
enr_seq: self.local_enr.read().seq(),
613-
ip: src.ip(),
614-
port: src.port(),
615-
},
616-
};
617-
debug!("Sending PONG response to {}", node_address);
618-
if let Err(e) = self
619-
.handler_send
620-
.send(HandlerIn::Response(node_address, Box::new(response)))
621-
{
622-
warn!("Failed to send response {}", e)
610+
if let Ok(port) = src.port().try_into() {
611+
let response = Response {
612+
id,
613+
body: ResponseBody::Pong {
614+
enr_seq: self.local_enr.read().seq(),
615+
ip: src.ip(),
616+
port,
617+
},
618+
};
619+
debug!("Sending PONG response to {}", node_address);
620+
if let Err(e) = self
621+
.handler_send
622+
.send(HandlerIn::Response(node_address, Box::new(response)))
623+
{
624+
warn!("Failed to send response {}", e);
625+
}
626+
} else {
627+
warn!("The src port number should be non zero. {src}");
623628
}
624629
}
625630
RequestBody::Talk { protocol, request } => {
@@ -778,12 +783,16 @@ impl Service {
778783
ResponseBody::Pong { enr_seq, ip, port } => {
779784
// Send the response to the user, if they are who asked
780785
if let Some(CallbackResponse::Pong(callback)) = active_request.callback {
781-
let response = Pong { enr_seq, ip, port };
786+
let response = Pong {
787+
enr_seq,
788+
ip,
789+
port: port.get(),
790+
};
782791
if let Err(e) = callback.send(Ok(response)) {
783792
warn!("Failed to send callback response {:?}", e)
784793
};
785794
} else {
786-
let socket = SocketAddr::new(ip, port);
795+
let socket = SocketAddr::new(ip, port.get());
787796
// perform ENR majority-based update if required.
788797

789798
// Only count votes that from peers we have contacted.

src/service/test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ async fn test_updating_connection_on_ping() {
144144
body: ResponseBody::Pong {
145145
enr_seq: 2,
146146
ip: ip2.into(),
147-
port: DEFAULT_UDP_PORT,
147+
port: 9000.try_into().unwrap(),
148148
},
149149
};
150150

0 commit comments

Comments
 (0)