Skip to content

Commit 40afb97

Browse files
committed
Fix crash in #33 due to EAGAIN/EWOULDBLOCK
1 parent 505a6cb commit 40afb97

File tree

7 files changed

+55
-13
lines changed

7 files changed

+55
-13
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "roughenough"
3-
version = "1.2.0-draft5"
3+
version = "1.2.1-draft5"
44
repository = "https://github.com/int08h/roughenough"
55
authors = ["Stuart Stock <stuart@int08h.com>", "Aaron Hill <aa1ronham@gmail.com>"]
66
license = "Apache-2.0"

src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ pub mod stats;
7979
pub mod version;
8080

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

8484
/// Roughenough version string enriched with any compile-time optional features
8585
pub fn roughenough_version() -> String {

src/responder.rs

+14-7
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,14 @@ impl Responder {
112112
Version::Rfc => resp_msg.encode_framed().unwrap(),
113113
};
114114

115-
let bytes_sent = socket
116-
.send_to(&resp_bytes, &src_addr)
117-
.expect("send_to failed");
115+
let mut bytes_sent: usize = 0;
116+
let mut successful_send: bool = true;
117+
match socket.send_to(&resp_bytes, &src_addr) {
118+
Ok(n_bytes) => bytes_sent = n_bytes,
119+
Err(_) => successful_send = false,
120+
}
118121

119-
info!(
122+
debug!(
120123
"Responded {} {} bytes to {} for '{}..' (#{} in batch)",
121124
self.version,
122125
bytes_sent,
@@ -125,9 +128,13 @@ impl Responder {
125128
idx + 1,
126129
);
127130

128-
match self.version {
129-
Version::Classic => stats.add_classic_response(&src_addr.ip(), bytes_sent),
130-
Version::Rfc => stats.add_rfc_response(&src_addr.ip(), bytes_sent),
131+
if successful_send {
132+
match self.version {
133+
Version::Classic => stats.add_classic_response(&src_addr.ip(), bytes_sent),
134+
Version::Rfc => stats.add_rfc_response(&src_addr.ip(), bytes_sent),
135+
}
136+
} else {
137+
stats.add_failed_send_attempt(&src_addr.ip());
131138
}
132139
}
133140
}

src/server.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -275,19 +275,20 @@ impl Server {
275275

276276
for (addr, counts) in vec {
277277
info!(
278-
"{:16}: {} classic req, {} rfc req; {} invalid requests; {} classic resp, {} rfc resp ({} sent)",
278+
"{:16}: {} classic req, {} rfc req; {} invalid requests; {} classic resp, {} rfc resp ({} sent); {} failed sends",
279279
format!("{}", addr),
280280
counts.classic_requests,
281281
counts.rfc_requests,
282282
counts.invalid_requests,
283283
counts.classic_responses_sent,
284284
counts.rfc_responses_sent,
285-
counts.bytes_sent.file_size(fsopts::BINARY).unwrap()
285+
counts.bytes_sent.file_size(fsopts::BINARY).unwrap(),
286+
counts.failed_send_attempts
286287
);
287288
}
288289

289290
info!(
290-
"Totals: {} unique clients; {} total req ({} classic req, {} rfc req); {} invalid requests; {} total resp ({} classic resp, {} rfc resp); {} sent",
291+
"Totals: {} unique clients; {} total req ({} classic req, {} rfc req); {} invalid requests; {} total resp ({} classic resp, {} rfc resp); {} sent; {} failed sends",
291292
self.stats.total_unique_clients(),
292293
self.stats.total_valid_requests(),
293294
self.stats.num_classic_requests(),
@@ -296,7 +297,8 @@ impl Server {
296297
self.stats.total_responses_sent(),
297298
self.stats.num_classic_responses_sent(),
298299
self.stats.num_rfc_responses_sent(),
299-
self.stats.total_bytes_sent().file_size(fsopts::BINARY) .unwrap()
300+
self.stats.total_bytes_sent().file_size(fsopts::BINARY).unwrap(),
301+
self.stats.total_failed_send_attempts()
300302
);
301303

302304
self.timer.set_timeout(self.status_interval, ());

src/stats/aggregated.rs

+10
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ pub struct AggregatedStats {
3232
rfc_responses_sent: u64,
3333
classic_responses_sent: u64,
3434
bytes_sent: usize,
35+
failed_send_attempts: u64,
3536
empty_map: HashMap<IpAddr, ClientStatEntry>,
3637
}
3738

@@ -52,6 +53,7 @@ impl AggregatedStats {
5253
rfc_responses_sent: 0,
5354
classic_responses_sent: 0,
5455
bytes_sent: 0,
56+
failed_send_attempts: 0,
5557
empty_map: HashMap::new(),
5658
}
5759
}
@@ -70,6 +72,10 @@ impl ServerStats for AggregatedStats {
7072
self.invalid_requests += 1
7173
}
7274

75+
fn add_failed_send_attempt(&mut self, _: &IpAddr) {
76+
self.failed_send_attempts += 1;
77+
}
78+
7379
fn add_health_check(&mut self, _: &IpAddr) {
7480
self.health_checks += 1
7581
}
@@ -104,6 +110,10 @@ impl ServerStats for AggregatedStats {
104110
self.health_checks
105111
}
106112

113+
fn total_failed_send_attempts(&self) -> u64 {
114+
self.failed_send_attempts
115+
}
116+
107117
fn total_responses_sent(&self) -> u64 {
108118
self.rfc_responses_sent + self.classic_responses_sent
109119
}

src/stats/mod.rs

+9
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ pub struct ClientStatEntry {
3737
pub rfc_responses_sent: u64,
3838
pub classic_responses_sent: u64,
3939
pub bytes_sent: usize,
40+
pub failed_send_attempts: u64,
4041
}
4142

4243
impl ClientStatEntry {
@@ -49,6 +50,7 @@ impl ClientStatEntry {
4950
rfc_responses_sent: 0,
5051
classic_responses_sent: 0,
5152
bytes_sent: 0,
53+
failed_send_attempts: 0,
5254
}
5355
}
5456
}
@@ -63,6 +65,8 @@ pub trait ServerStats {
6365

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

68+
fn add_failed_send_attempt(&mut self, addr: &IpAddr);
69+
6670
fn add_health_check(&mut self, addr: &IpAddr);
6771

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

8084
fn total_health_checks(&self) -> u64;
8185

86+
fn total_failed_send_attempts(&self) -> u64;
87+
8288
fn total_responses_sent(&self) -> u64;
8389

8490
fn num_rfc_responses_sent(&self) -> u64;
@@ -112,6 +118,7 @@ mod test {
112118
assert_eq!(stats.total_responses_sent(), 0);
113119
assert_eq!(stats.total_bytes_sent(), 0);
114120
assert_eq!(stats.total_unique_clients(), 0);
121+
assert_eq!(stats.total_failed_send_attempts(), 0);
115122
assert_eq!(stats.num_overflows(), 0);
116123
}
117124

@@ -146,13 +153,15 @@ mod test {
146153
stats.add_rfc_response(&ip, 2048);
147154
stats.add_classic_response(&ip, 1024);
148155
stats.add_classic_response(&ip, 1024);
156+
stats.add_failed_send_attempt(&ip);
149157

150158
let entry = stats.stats_for_client(&ip).unwrap();
151159
assert_eq!(entry.classic_requests, 1);
152160
assert_eq!(entry.invalid_requests, 0);
153161
assert_eq!(entry.rfc_responses_sent, 1);
154162
assert_eq!(entry.classic_responses_sent, 2);
155163
assert_eq!(entry.bytes_sent, 4096);
164+
assert_eq!(entry.failed_send_attempts, 1);
156165
}
157166

158167
#[test]

src/stats/per_client.rs

+14
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,16 @@ impl ServerStats for PerClientStats {
109109
.invalid_requests += 1;
110110
}
111111

112+
fn add_failed_send_attempt(&mut self, addr: &IpAddr) {
113+
if self.too_many_entries() {
114+
return;
115+
}
116+
self.clients
117+
.entry(*addr)
118+
.or_insert_with(ClientStatEntry::new)
119+
.failed_send_attempts += 1;
120+
}
121+
112122
fn add_health_check(&mut self, addr: &IpAddr) {
113123
if self.too_many_entries() {
114124
return;
@@ -168,6 +178,10 @@ impl ServerStats for PerClientStats {
168178
self.clients.values().map(|&v| v.health_checks).sum()
169179
}
170180

181+
fn total_failed_send_attempts(&self) -> u64 {
182+
self.clients.values().map(|&v| v.failed_send_attempts).sum()
183+
}
184+
171185
fn total_responses_sent(&self) -> u64 {
172186
self.clients
173187
.values()

0 commit comments

Comments
 (0)