Skip to content

Commit a4ce26b

Browse files
committed
Fix issue with reading large files and error being returned if 0 packets were read
1 parent 0cd6b39 commit a4ce26b

File tree

2 files changed

+66
-27
lines changed

2 files changed

+66
-27
lines changed

src/packet/future.rs

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -144,40 +144,46 @@ async fn dispatch(args: DispatchArgs) -> Result<DispatchResult, Error> {
144144
error!("Error encountered when calling pcap_dispatch: {}", err);
145145
return Err(err);
146146
}
147-
0 if args.live_capture => {
148-
trace!("No packets in buffer");
149-
if should_return_packets(packets.len()) {
150-
debug!(
151-
"Capture loop returning with {} packets",
152-
args.max_packets_read
153-
);
154-
return Ok(DispatchResult {
155-
args: args,
156-
result: Some(packets.into_inner()),
157-
});
158-
} else {
159-
let timeout = if packets.is_empty() {
160-
None
161-
} else {
162-
args.buffer_for
163-
.checked_sub(Instant::now().duration_since(started_at))
164-
};
165-
if let InterfaceReady::No = args.poll(timeout).await? {
147+
0 => {
148+
if args.live_capture {
149+
trace!("No packets in buffer");
150+
if should_return_packets(packets.len()) {
151+
debug!(
152+
"Capture loop returning with {} packets",
153+
args.max_packets_read
154+
);
166155
return Ok(DispatchResult {
167156
args: args,
168157
result: Some(packets.into_inner()),
169158
});
159+
} else {
160+
let timeout = if packets.is_empty() {
161+
None
162+
} else {
163+
args.buffer_for
164+
.checked_sub(Instant::now().duration_since(started_at))
165+
};
166+
if let InterfaceReady::No = args.poll(timeout).await? {
167+
return Ok(DispatchResult {
168+
args: args,
169+
result: Some(packets.into_inner()),
170+
});
171+
}
170172
}
173+
} else {
174+
debug!("Not live capture and no packets, calling breakloop");
175+
unsafe { pcap_sys::pcap_breakloop(args.pcap_handle.as_mut_ptr()) }
176+
let res = if packets.is_empty() {
177+
None
178+
} else {
179+
Some(packets.into_inner())
180+
};
181+
return Ok(DispatchResult {
182+
args: args,
183+
result: res,
184+
});
171185
}
172186
}
173-
0 if !packets.is_empty() => {
174-
debug!("Not live capture and no packets, calling breakloop");
175-
unsafe { pcap_sys::pcap_breakloop(args.pcap_handle.as_mut_ptr()) }
176-
return Ok(DispatchResult {
177-
args: args,
178-
result: Some(packets.into_inner()),
179-
});
180-
}
181187
x if x > 0 => {
182188
trace!("Capture loop captured {} packets", x);
183189
if should_return_packets(packets.len()) {

src/stream.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,39 @@ mod tests {
155155
assert_eq!(actual_length, 54);
156156
}
157157

158+
#[test]
159+
fn packets_from_large_file() {
160+
let _ = env_logger::try_init();
161+
162+
let pcap_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
163+
.join("resources")
164+
.join("4SICS-GeekLounge-151020.pcap");
165+
166+
info!("Testing against {:?}", pcap_path);
167+
168+
let handle = Handle::file_capture(pcap_path.to_str().expect("No path found"))
169+
.expect("No handle created");
170+
171+
let packets = smol::run(async move {
172+
let packet_provider =
173+
PacketStream::new(Config::default(), Arc::clone(&handle)).expect("Failed to build");
174+
let fut_packets = packet_provider.collect::<Vec<_>>();
175+
let packets: Vec<_> = fut_packets
176+
.await
177+
.into_iter()
178+
.flatten()
179+
.flatten()
180+
.filter(|p| p.data().len() == p.actual_length() as usize)
181+
.collect();
182+
183+
handle.interrupt();
184+
185+
packets
186+
});
187+
188+
assert_eq!(packets.len(), 246137);
189+
}
190+
158191
#[test]
159192
fn packets_from_file_next() {
160193
let _ = env_logger::try_init();

0 commit comments

Comments
 (0)