I am writing a small web service in Rust that listens to the UDP traffic, and writes the content into local files. For that I use the Rust pcap library.
I manage to listen to the stream and write to a file, but I would like to be able to detect that a file has finished to be streamed and the next one is starting. So I thought to use a timer, to detect that if after e.g. 2 seconds of inactivity, I can close the current file, and start to write on the next one as soon as new packets are coming in.
However I cannot find a way to do that with pcap.
So far my code look like that. It listen to UDP and blocks after a message as been received, until the next message.
#[tokio::main]
async fn main() {
...
let mut cap = Capture::from_device(_device_name)
.unwrap()
.open()
.unwrap();
process_pcap(&pcap);
}
pub fn process_pcap<T: Activated>(cap: &mut Capture<T>) -> String {
info!("Processing pcap stream...");
let mut opened_file = open_new_file();
while let Ok(packet) = cap.next_packet() {
if let ControlFlow::Break(_) = process_packet(packet, &mut iq_open_file.file) {
continue;
}
}
info!("Done. Content available in {}", opened_file.path);
return opened_file.path.clone();
}
fn process_packet(packet: pcap::Packet<'_>, file: &mut File) -> ControlFlow<()> {
...
let _ = write_packet_data_to_file(file, payload);
let _ = file.flush();
...
}
I thought about using the nonblicking mode (with .setnonblock() on the Capture), and reset a timeout each time a message arrives, but that seems a bit hacky.
Do you know if there are cleaner way to achieve this goal?