Skip to content

Commit

Permalink
Fix crash in #33 due to EAGAIN/EWOULDBLOCK
Browse files Browse the repository at this point in the history
  • Loading branch information
int08h committed Nov 28, 2022
1 parent 505a6cb commit 40afb97
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 13 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "roughenough"
version = "1.2.0-draft5"
version = "1.2.1-draft5"
repository = "https://github.com/int08h/roughenough"
authors = ["Stuart Stock <[email protected]>", "Aaron Hill <[email protected]>"]
license = "Apache-2.0"
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ pub mod stats;
pub mod version;

/// Version of Roughenough
pub const VERSION: &str = "1.2.0-draft5";
pub const VERSION: &str = "1.2.1-draft5";

/// Roughenough version string enriched with any compile-time optional features
pub fn roughenough_version() -> String {
Expand Down
21 changes: 14 additions & 7 deletions src/responder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,14 @@ impl Responder {
Version::Rfc => resp_msg.encode_framed().unwrap(),
};

let bytes_sent = socket
.send_to(&resp_bytes, &src_addr)
.expect("send_to failed");
let mut bytes_sent: usize = 0;
let mut successful_send: bool = true;
match socket.send_to(&resp_bytes, &src_addr) {
Ok(n_bytes) => bytes_sent = n_bytes,
Err(_) => successful_send = false,
}

info!(
debug!(
"Responded {} {} bytes to {} for '{}..' (#{} in batch)",
self.version,
bytes_sent,
Expand All @@ -125,9 +128,13 @@ impl Responder {
idx + 1,
);

match self.version {
Version::Classic => stats.add_classic_response(&src_addr.ip(), bytes_sent),
Version::Rfc => stats.add_rfc_response(&src_addr.ip(), bytes_sent),
if successful_send {
match self.version {
Version::Classic => stats.add_classic_response(&src_addr.ip(), bytes_sent),
Version::Rfc => stats.add_rfc_response(&src_addr.ip(), bytes_sent),
}
} else {
stats.add_failed_send_attempt(&src_addr.ip());
}
}
}
Expand Down
10 changes: 6 additions & 4 deletions src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,19 +275,20 @@ impl Server {

for (addr, counts) in vec {
info!(
"{:16}: {} classic req, {} rfc req; {} invalid requests; {} classic resp, {} rfc resp ({} sent)",
"{:16}: {} classic req, {} rfc req; {} invalid requests; {} classic resp, {} rfc resp ({} sent); {} failed sends",
format!("{}", addr),
counts.classic_requests,
counts.rfc_requests,
counts.invalid_requests,
counts.classic_responses_sent,
counts.rfc_responses_sent,
counts.bytes_sent.file_size(fsopts::BINARY).unwrap()
counts.bytes_sent.file_size(fsopts::BINARY).unwrap(),
counts.failed_send_attempts
);
}

info!(
"Totals: {} unique clients; {} total req ({} classic req, {} rfc req); {} invalid requests; {} total resp ({} classic resp, {} rfc resp); {} sent",
"Totals: {} unique clients; {} total req ({} classic req, {} rfc req); {} invalid requests; {} total resp ({} classic resp, {} rfc resp); {} sent; {} failed sends",
self.stats.total_unique_clients(),
self.stats.total_valid_requests(),
self.stats.num_classic_requests(),
Expand All @@ -296,7 +297,8 @@ impl Server {
self.stats.total_responses_sent(),
self.stats.num_classic_responses_sent(),
self.stats.num_rfc_responses_sent(),
self.stats.total_bytes_sent().file_size(fsopts::BINARY) .unwrap()
self.stats.total_bytes_sent().file_size(fsopts::BINARY).unwrap(),
self.stats.total_failed_send_attempts()
);

self.timer.set_timeout(self.status_interval, ());
Expand Down
10 changes: 10 additions & 0 deletions src/stats/aggregated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ pub struct AggregatedStats {
rfc_responses_sent: u64,
classic_responses_sent: u64,
bytes_sent: usize,
failed_send_attempts: u64,
empty_map: HashMap<IpAddr, ClientStatEntry>,
}

Expand All @@ -52,6 +53,7 @@ impl AggregatedStats {
rfc_responses_sent: 0,
classic_responses_sent: 0,
bytes_sent: 0,
failed_send_attempts: 0,
empty_map: HashMap::new(),
}
}
Expand All @@ -70,6 +72,10 @@ impl ServerStats for AggregatedStats {
self.invalid_requests += 1
}

fn add_failed_send_attempt(&mut self, _: &IpAddr) {
self.failed_send_attempts += 1;
}

fn add_health_check(&mut self, _: &IpAddr) {
self.health_checks += 1
}
Expand Down Expand Up @@ -104,6 +110,10 @@ impl ServerStats for AggregatedStats {
self.health_checks
}

fn total_failed_send_attempts(&self) -> u64 {
self.failed_send_attempts
}

fn total_responses_sent(&self) -> u64 {
self.rfc_responses_sent + self.classic_responses_sent
}
Expand Down
9 changes: 9 additions & 0 deletions src/stats/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ pub struct ClientStatEntry {
pub rfc_responses_sent: u64,
pub classic_responses_sent: u64,
pub bytes_sent: usize,
pub failed_send_attempts: u64,
}

impl ClientStatEntry {
Expand All @@ -49,6 +50,7 @@ impl ClientStatEntry {
rfc_responses_sent: 0,
classic_responses_sent: 0,
bytes_sent: 0,
failed_send_attempts: 0,
}
}
}
Expand All @@ -63,6 +65,8 @@ pub trait ServerStats {

fn add_invalid_request(&mut self, addr: &IpAddr);

fn add_failed_send_attempt(&mut self, addr: &IpAddr);

fn add_health_check(&mut self, addr: &IpAddr);

fn add_rfc_response(&mut self, addr: &IpAddr, bytes_sent: usize);
Expand All @@ -79,6 +83,8 @@ pub trait ServerStats {

fn total_health_checks(&self) -> u64;

fn total_failed_send_attempts(&self) -> u64;

fn total_responses_sent(&self) -> u64;

fn num_rfc_responses_sent(&self) -> u64;
Expand Down Expand Up @@ -112,6 +118,7 @@ mod test {
assert_eq!(stats.total_responses_sent(), 0);
assert_eq!(stats.total_bytes_sent(), 0);
assert_eq!(stats.total_unique_clients(), 0);
assert_eq!(stats.total_failed_send_attempts(), 0);
assert_eq!(stats.num_overflows(), 0);
}

Expand Down Expand Up @@ -146,13 +153,15 @@ mod test {
stats.add_rfc_response(&ip, 2048);
stats.add_classic_response(&ip, 1024);
stats.add_classic_response(&ip, 1024);
stats.add_failed_send_attempt(&ip);

let entry = stats.stats_for_client(&ip).unwrap();
assert_eq!(entry.classic_requests, 1);
assert_eq!(entry.invalid_requests, 0);
assert_eq!(entry.rfc_responses_sent, 1);
assert_eq!(entry.classic_responses_sent, 2);
assert_eq!(entry.bytes_sent, 4096);
assert_eq!(entry.failed_send_attempts, 1);
}

#[test]
Expand Down
14 changes: 14 additions & 0 deletions src/stats/per_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,16 @@ impl ServerStats for PerClientStats {
.invalid_requests += 1;
}

fn add_failed_send_attempt(&mut self, addr: &IpAddr) {
if self.too_many_entries() {
return;
}
self.clients
.entry(*addr)
.or_insert_with(ClientStatEntry::new)
.failed_send_attempts += 1;
}

fn add_health_check(&mut self, addr: &IpAddr) {
if self.too_many_entries() {
return;
Expand Down Expand Up @@ -168,6 +178,10 @@ impl ServerStats for PerClientStats {
self.clients.values().map(|&v| v.health_checks).sum()
}

fn total_failed_send_attempts(&self) -> u64 {
self.clients.values().map(|&v| v.failed_send_attempts).sum()
}

fn total_responses_sent(&self) -> u64 {
self.clients
.values()
Expand Down

0 comments on commit 40afb97

Please sign in to comment.