Improve error handling when the user mixes up gossip (8001) and RPC (8899) ports (#7158)
automerge
This commit is contained in:
@@ -30,7 +30,13 @@ fn ip_echo_server_request(
|
||||
TcpStream::connect_timeout(ip_echo_server_addr, timeout)
|
||||
.and_then(|mut stream| {
|
||||
let msg = bincode::serialize(&msg).expect("serialize IpEchoServerMessage");
|
||||
// Start with 4 null bytes to avoid looking like an HTTP GET/POST request
|
||||
stream.write_all(&[0; 4])?;
|
||||
|
||||
stream.write_all(&msg)?;
|
||||
|
||||
// Send a '\n' to make this request look HTTP-ish and tickle an error response back from an HTTP server
|
||||
stream.write_all(b"\n")?;
|
||||
stream.shutdown(std::net::Shutdown::Write)?;
|
||||
stream
|
||||
.set_read_timeout(Some(Duration::new(10, 0)))
|
||||
@@ -38,7 +44,38 @@ fn ip_echo_server_request(
|
||||
stream.read_to_end(&mut data)
|
||||
})
|
||||
.and_then(|_| {
|
||||
bincode::deserialize(&data).map_err(|err| {
|
||||
// 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
|
||||
// response header and provide the user with a helpful error message
|
||||
if data.len() < 4 {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
format!("Response too short, received {} bytes", data.len()),
|
||||
));
|
||||
}
|
||||
|
||||
let response_header: String = data[0..4].iter().map(|b| *b as char).collect();
|
||||
if response_header != "\0\0\0\0" {
|
||||
if response_header == "HTTP" {
|
||||
let http_response = data.iter().map(|b| *b as char).collect::<String>();
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
format!(
|
||||
"Invalid gossip entrypoint. {} looks to be an HTTP port: {}",
|
||||
ip_echo_server_addr, http_response
|
||||
),
|
||||
));
|
||||
}
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
format!(
|
||||
"Invalid gossip entrypoint. {} provided an invalid response header: '{}'",
|
||||
ip_echo_server_addr, response_header
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
bincode::deserialize(&data[3..]).map_err(|err| {
|
||||
io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
format!("Failed to deserialize: {:?}", err),
|
||||
@@ -435,6 +472,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_get_public_ip_addr() {
|
||||
solana_logger::setup();
|
||||
let (_server_port, (server_udp_socket, server_tcp_listener)) =
|
||||
bind_common_in_range((3200, 3250)).unwrap();
|
||||
let (client_port, (client_udp_socket, client_tcp_listener)) =
|
||||
|
Reference in New Issue
Block a user