mirror of
https://github.com/telemt/telemt.git
synced 2026-04-23 05:24:10 +03:00
Noisy-network peer Close Errors Classification
This commit is contained in:
@@ -231,7 +231,8 @@ fn print_help() {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::resolve_runtime_config_path;
|
use super::{is_expected_handshake_eof, resolve_runtime_config_path};
|
||||||
|
use crate::error::{ProxyError, StreamError};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn resolve_runtime_config_path_anchors_relative_to_startup_cwd() {
|
fn resolve_runtime_config_path_anchors_relative_to_startup_cwd() {
|
||||||
@@ -299,6 +300,20 @@ mod tests {
|
|||||||
|
|
||||||
let _ = std::fs::remove_dir(&startup_cwd);
|
let _ = std::fs::remove_dir(&startup_cwd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn expected_handshake_eof_matches_connection_reset() {
|
||||||
|
let err = ProxyError::Io(std::io::Error::from(std::io::ErrorKind::ConnectionReset));
|
||||||
|
assert!(is_expected_handshake_eof(&err));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn expected_handshake_eof_matches_stream_io_unexpected_eof() {
|
||||||
|
let err = ProxyError::Stream(StreamError::Io(std::io::Error::from(
|
||||||
|
std::io::ErrorKind::UnexpectedEof,
|
||||||
|
)));
|
||||||
|
assert!(is_expected_handshake_eof(&err));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn print_proxy_links(host: &str, port: u16, config: &ProxyConfig) {
|
pub(crate) fn print_proxy_links(host: &str, port: u16, config: &ProxyConfig) {
|
||||||
@@ -428,7 +443,30 @@ pub(crate) async fn wait_until_admission_open(admission_rx: &mut watch::Receiver
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn is_expected_handshake_eof(err: &crate::error::ProxyError) -> bool {
|
pub(crate) fn is_expected_handshake_eof(err: &crate::error::ProxyError) -> bool {
|
||||||
err.to_string().contains("expected 64 bytes, got 0")
|
matches!(
|
||||||
|
err,
|
||||||
|
crate::error::ProxyError::Io(ioe)
|
||||||
|
if matches!(
|
||||||
|
ioe.kind(),
|
||||||
|
std::io::ErrorKind::UnexpectedEof
|
||||||
|
| std::io::ErrorKind::ConnectionReset
|
||||||
|
| std::io::ErrorKind::ConnectionAborted
|
||||||
|
| std::io::ErrorKind::BrokenPipe
|
||||||
|
| std::io::ErrorKind::NotConnected
|
||||||
|
)
|
||||||
|
) || matches!(err, crate::error::ProxyError::Stream(crate::error::StreamError::UnexpectedEof))
|
||||||
|
|| matches!(
|
||||||
|
err,
|
||||||
|
crate::error::ProxyError::Stream(crate::error::StreamError::Io(ioe))
|
||||||
|
if matches!(
|
||||||
|
ioe.kind(),
|
||||||
|
std::io::ErrorKind::UnexpectedEof
|
||||||
|
| std::io::ErrorKind::ConnectionReset
|
||||||
|
| std::io::ErrorKind::ConnectionAborted
|
||||||
|
| std::io::ErrorKind::BrokenPipe
|
||||||
|
| std::io::ErrorKind::NotConnected
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn load_startup_proxy_config_snapshot(
|
pub(crate) async fn load_startup_proxy_config_snapshot(
|
||||||
|
|||||||
@@ -331,10 +331,31 @@ fn record_handshake_failure_class(
|
|||||||
error: &ProxyError,
|
error: &ProxyError,
|
||||||
) {
|
) {
|
||||||
let class = match error {
|
let class = match error {
|
||||||
ProxyError::Io(err) if err.kind() == std::io::ErrorKind::UnexpectedEof => {
|
ProxyError::Io(err)
|
||||||
|
if matches!(
|
||||||
|
err.kind(),
|
||||||
|
std::io::ErrorKind::UnexpectedEof
|
||||||
|
| std::io::ErrorKind::ConnectionReset
|
||||||
|
| std::io::ErrorKind::ConnectionAborted
|
||||||
|
| std::io::ErrorKind::BrokenPipe
|
||||||
|
| std::io::ErrorKind::NotConnected
|
||||||
|
) =>
|
||||||
|
{
|
||||||
"expected_64_got_0"
|
"expected_64_got_0"
|
||||||
}
|
}
|
||||||
ProxyError::Stream(StreamError::UnexpectedEof) => "expected_64_got_0",
|
ProxyError::Stream(StreamError::UnexpectedEof) => "expected_64_got_0",
|
||||||
|
ProxyError::Stream(StreamError::Io(err))
|
||||||
|
if matches!(
|
||||||
|
err.kind(),
|
||||||
|
std::io::ErrorKind::UnexpectedEof
|
||||||
|
| std::io::ErrorKind::ConnectionReset
|
||||||
|
| std::io::ErrorKind::ConnectionAborted
|
||||||
|
| std::io::ErrorKind::BrokenPipe
|
||||||
|
| std::io::ErrorKind::NotConnected
|
||||||
|
) =>
|
||||||
|
{
|
||||||
|
"expected_64_got_0"
|
||||||
|
}
|
||||||
_ => "other",
|
_ => "other",
|
||||||
};
|
};
|
||||||
record_beobachten_class(beobachten, config, peer_ip, class);
|
record_beobachten_class(beobachten, config, peer_ip, class);
|
||||||
|
|||||||
@@ -2493,6 +2493,46 @@ fn unexpected_eof_is_classified_without_string_matching() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn connection_reset_is_classified_as_expected_handshake_close() {
|
||||||
|
let beobachten = BeobachtenStore::new();
|
||||||
|
let mut config = ProxyConfig::default();
|
||||||
|
config.general.beobachten = true;
|
||||||
|
config.general.beobachten_minutes = 1;
|
||||||
|
|
||||||
|
let reset = ProxyError::Io(std::io::Error::from(std::io::ErrorKind::ConnectionReset));
|
||||||
|
let peer_ip: IpAddr = "198.51.100.202".parse().unwrap();
|
||||||
|
|
||||||
|
record_handshake_failure_class(&beobachten, &config, peer_ip, &reset);
|
||||||
|
|
||||||
|
let snapshot = beobachten.snapshot_text(Duration::from_secs(60));
|
||||||
|
assert!(
|
||||||
|
snapshot.contains("[expected_64_got_0]"),
|
||||||
|
"ConnectionReset must be classified as expected handshake close"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn stream_io_unexpected_eof_is_classified_without_string_matching() {
|
||||||
|
let beobachten = BeobachtenStore::new();
|
||||||
|
let mut config = ProxyConfig::default();
|
||||||
|
config.general.beobachten = true;
|
||||||
|
config.general.beobachten_minutes = 1;
|
||||||
|
|
||||||
|
let eof = ProxyError::Stream(StreamError::Io(std::io::Error::from(
|
||||||
|
std::io::ErrorKind::UnexpectedEof,
|
||||||
|
)));
|
||||||
|
let peer_ip: IpAddr = "198.51.100.203".parse().unwrap();
|
||||||
|
|
||||||
|
record_handshake_failure_class(&beobachten, &config, peer_ip, &eof);
|
||||||
|
|
||||||
|
let snapshot = beobachten.snapshot_text(Duration::from_secs(60));
|
||||||
|
assert!(
|
||||||
|
snapshot.contains("[expected_64_got_0]"),
|
||||||
|
"StreamError::Io(UnexpectedEof) must be classified as expected handshake close"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn non_eof_error_is_classified_as_other() {
|
fn non_eof_error_is_classified_as_other() {
|
||||||
let beobachten = BeobachtenStore::new();
|
let beobachten = BeobachtenStore::new();
|
||||||
|
|||||||
Reference in New Issue
Block a user