Noisy-network peer Close Errors Classification

This commit is contained in:
Alexey
2026-04-21 15:35:11 +03:00
parent 30e73adaac
commit db8d333ed6
3 changed files with 102 additions and 3 deletions

View File

@@ -331,10 +331,31 @@ fn record_handshake_failure_class(
error: &ProxyError,
) {
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"
}
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",
};
record_beobachten_class(beobachten, config, peer_ip, class);

View File

@@ -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]
fn non_eof_error_is_classified_as_other() {
let beobachten = BeobachtenStore::new();