next_with_timeout() with zero timeout waits indefinitely
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 2.6k
- Forks
- 329
- PR merge metrics
- No merged PRs in 30d
Description
The following code is expected to poll in a tight loop, instead it waits indefinitely for every packet (confirmed with strace(1)):
use pnet::{transport::*, packet::ip::*};
use std::time::Duration;
fn main() {
let (_, mut tx) = transport_channel(
4096, TransportChannelType::Layer4(
TransportProtocol::Ipv4(
IpNextHeaderProtocols::Icmp
))).unwrap();
loop {
let _ = icmp_packet_iter(&mut tx).next_with_timeout(Duration::new(0, 0));
}
}
I suspect this is because socket option SO_RCVTIMEO interprets zero timeout as infinite. From socket(7) man:
If the timeout is set to zero (the default) then the operation will never timeout.
The problem can be solved by specifying timeout as the smallest non-zero value (1000ns since timeval.tv_usec is in microseconds):
use pnet::{transport::*, packet::ip::*};
use std::time::Duration;
fn main() {
let (_, mut tx) = transport_channel(
4096, TransportChannelType::Layer4(
TransportProtocol::Ipv4(
IpNextHeaderProtocols::Icmp
))).unwrap();
loop {
let _ = icmp_packet_iter(&mut tx).next_with_timeout(Duration::new(0, 1000));
}
}
Either values from 0 to 999ns should be automatically converted to 1us or the documentation should be updated to mention this unexpected behavior. Since there is already a blocking method next() I prefer the former.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by locating the Rust implementation of next_with_timeout() and how Duration is converted into SO_RCVTIMEO, then reproduce the zero-timeout behavior with the example in the issue. Add or update tests for zero and sub-microsecond durations; done means these calls return without waiting indefinitely while the existing blocking behavior remains unchanged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- networking
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100