ip-echo-server: Name the header length magic number

This commit is contained in:
Trent Nelson 2020-11-11 20:37:43 -07:00 committed by mergify[bot]
parent 114b91afe6
commit aab5f24518
2 changed files with 17 additions and 10 deletions

View File

@ -1,3 +1,4 @@
use crate::HEADER_LENGTH;
use bytes::Bytes; use bytes::Bytes;
use log::*; use log::*;
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
@ -52,13 +53,14 @@ pub fn ip_echo_server(tcp: std::net::TcpListener) -> IpEchoServer {
let processor = reader let processor = reader
.and_then(move |data| { .and_then(move |data| {
if data.len() < 4 { if data.len() < HEADER_LENGTH {
return Err(io::Error::new( return Err(io::Error::new(
io::ErrorKind::Other, io::ErrorKind::Other,
format!("Request too short, received {} bytes", data.len()), format!("Request too short, received {} bytes", data.len()),
)); ));
} }
let request_header: String = data[0..4].iter().map(|b| *b as char).collect(); let request_header: String =
data[0..HEADER_LENGTH].iter().map(|b| *b as char).collect();
if request_header != "\0\0\0\0" { if request_header != "\0\0\0\0" {
// Explicitly check for HTTP GET/POST requests to more gracefully handle // Explicitly check for HTTP GET/POST requests to more gracefully handle
// the case where a user accidentally tried to use a gossip entrypoint in // the case where a user accidentally tried to use a gossip entrypoint in
@ -74,7 +76,7 @@ pub fn ip_echo_server(tcp: std::net::TcpListener) -> IpEchoServer {
let expected_len = let expected_len =
bincode::serialized_size(&IpEchoServerMessage::default()).unwrap() as usize; bincode::serialized_size(&IpEchoServerMessage::default()).unwrap() as usize;
let actual_len = data[4..].len(); let actual_len = data[HEADER_LENGTH..].len();
if actual_len < expected_len { if actual_len < expected_len {
return Err(io::Error::new( return Err(io::Error::new(
io::ErrorKind::Other, io::ErrorKind::Other,
@ -85,7 +87,7 @@ pub fn ip_echo_server(tcp: std::net::TcpListener) -> IpEchoServer {
)); ));
} }
bincode::deserialize::<IpEchoServerMessage>(&data[4..]) bincode::deserialize::<IpEchoServerMessage>(&data[HEADER_LENGTH..])
.map(Some) .map(Some)
.map_err(|err| { .map_err(|err| {
io::Error::new( io::Error::new(
@ -177,10 +179,11 @@ pub fn ip_echo_server(tcp: std::net::TcpListener) -> IpEchoServer {
// conflict with the first four bytes of a valid HTTP response. // conflict with the first four bytes of a valid HTTP response.
let mut bytes = vec![ let mut bytes = vec![
0; 0;
4 + bincode::serialized_size(&peer_addr.ip()).unwrap() HEADER_LENGTH + bincode::serialized_size(&peer_addr.ip()).unwrap()
as usize as usize
]; ];
bincode::serialize_into(&mut bytes[4..], &peer_addr.ip()).unwrap(); bincode::serialize_into(&mut bytes[HEADER_LENGTH..], &peer_addr.ip())
.unwrap();
Ok(Bytes::from(bytes)) Ok(Bytes::from(bytes))
} }
}); });

View File

@ -22,6 +22,8 @@ pub struct UdpSocketPair {
pub type PortRange = (u16, u16); pub type PortRange = (u16, u16);
pub(crate) const HEADER_LENGTH: usize = 4;
fn ip_echo_server_request( fn ip_echo_server_request(
ip_echo_server_addr: &SocketAddr, ip_echo_server_addr: &SocketAddr,
msg: IpEchoServerMessage, msg: IpEchoServerMessage,
@ -31,7 +33,8 @@ fn ip_echo_server_request(
let timeout = Duration::new(5, 0); let timeout = Duration::new(5, 0);
TcpStream::connect_timeout(ip_echo_server_addr, timeout) TcpStream::connect_timeout(ip_echo_server_addr, timeout)
.and_then(|mut stream| { .and_then(|mut stream| {
let mut bytes = vec![0; 4]; // Start with 4 null bytes to avoid looking like an HTTP GET/POST request // Start with HEADER_LENGTH null bytes to avoid looking like an HTTP GET/POST request
let mut bytes = vec![0; HEADER_LENGTH];
bytes.append(&mut bincode::serialize(&msg).expect("serialize IpEchoServerMessage")); bytes.append(&mut bincode::serialize(&msg).expect("serialize IpEchoServerMessage"));
@ -48,14 +51,15 @@ fn ip_echo_server_request(
// It's common for users to accidentally confuse the validator's gossip port and JSON // It's common for users to accidentally confuse the validator's gossip port and JSON
// RPC port. Attempt to detect when this occurs by looking for the standard HTTP // RPC port. Attempt to detect when this occurs by looking for the standard HTTP
// response header and provide the user with a helpful error message // response header and provide the user with a helpful error message
if data.len() < 4 { if data.len() < HEADER_LENGTH {
return Err(io::Error::new( return Err(io::Error::new(
io::ErrorKind::Other, io::ErrorKind::Other,
format!("Response too short, received {} bytes", data.len()), format!("Response too short, received {} bytes", data.len()),
)); ));
} }
let response_header: String = data[0..4].iter().map(|b| *b as char).collect(); let response_header: String =
data[0..HEADER_LENGTH].iter().map(|b| *b as char).collect();
if response_header != "\0\0\0\0" { if response_header != "\0\0\0\0" {
if response_header == "HTTP" { if response_header == "HTTP" {
let http_response = data.iter().map(|b| *b as char).collect::<String>(); let http_response = data.iter().map(|b| *b as char).collect::<String>();
@ -76,7 +80,7 @@ fn ip_echo_server_request(
)); ));
} }
bincode::deserialize(&data[4..]).map_err(|err| { bincode::deserialize(&data[HEADER_LENGTH..]).map_err(|err| {
io::Error::new( io::Error::new(
io::ErrorKind::Other, io::ErrorKind::Other,
format!("Failed to deserialize: {:?}", err), format!("Failed to deserialize: {:?}", err),