Subject: | A huge lag in packet processing along with loss of multiple captures |
There is a problem with frequently accessing Pcap output on many non-Linux systems, such as FreeBSD, OpenBSD, etc. The problem is that pcap_fileno() file descriptor becomes ready quite rarely without special options. In order to fix the issue, libpcap recommends to set non-zero timeout in pcap_open_live(). In this module, the documentation lacks the procedure of handling multiple captured packets at a time. I've attached a patch, that implements timeout functionality for the module as well as improves the documentation to avoid possible captured packets mishandle.
Subject: | add-timeout.patch |
--- AnyEvent/Pcap.pm.orig 2020-09-30 19:37:46.934072471 +0300
+++ AnyEvent/Pcap.pm 2020-09-30 19:44:50.017356438 +0300
@@ -9,7 +9,7 @@
our $VERSION = '0.00002';
-__PACKAGE__->mk_accessors($_) for qw(utils device filter packet_handler fd);
+__PACKAGE__->mk_accessors($_) for qw(utils device filter packet_handler fd timeout);
sub new {
my $class = shift;
@@ -28,7 +28,8 @@
->();
croak $err if $err;
- my $pcap = Net::Pcap::pcap_open_live( $device, 1024, 1, 0, \$err );
+ my $timeout = $self->timeout || 0;
+ my $pcap = Net::Pcap::pcap_open_live( $device, 1024, 1, $timeout, \$err );
croak $err if $err;
my ( $address, $netmask );
@@ -94,17 +95,21 @@
$a_pcap = AnyEvent::Pcap->new(
device => "eth0",
filter => "tcp port 80",
+ timeout => 1000,
packet_handler => sub {
- my $header = shift;
- my $packet = shift;
+ my $io = pop;
+ while (@_) {
+ my $header = shift;
+ my $packet = shift;
- # you can use utils to get an NetPacket::TCP object.
- my $tcp = $a_pcap->utils->extract_tcp_packet($packet);
+ # you can use utils to get an NetPacket::TCP object.
+ my $tcp = $a_pcap->utils->extract_tcp_packet($packet);
- # or ...
- $tcp = AnyEvent::Pcap::Utils->extract_tcp_packet($packet);
+ # or ...
+ $tcp = AnyEvent::Pcap::Utils->extract_tcp_packet($packet);
- # do something....
+ # do something....
+ }
}
);
@@ -133,8 +138,15 @@
# Default is NULL
filter => "tcp port 80",
+ # How much time wait befor flush pcap buffer
+ # Default is 0 (unlimited)
+ timeout => 1000,
+
# set your coderef
packet_handler => sub {
+ my $io = pop;
+
+ # get first pair....
my $header = shift;
my $packet = shift;
@@ -174,6 +186,8 @@
=item packet_handler(I<[CODEREF]>)
+=item timeout(I<[INTEGER]>)
+
=back
=head1 AUTHOR