AnyEvent-FastPing
view release on metacpan or search on metacpan
FastPing.pm view on Meta::CPAN
package AnyEvent::FastPing;
use common::sense;
use AnyEvent;
BEGIN {
our $VERSION = 2.1;
our @ISA = qw(Exporter);
require Exporter;
#Exporter::export_ok_tags (keys %EXPORT_TAGS);
require XSLoader;
XSLoader::load (__PACKAGE__, $VERSION);
}
our ($THR_RES_FD, $ICMP4_FD, $ICMP6_FD);
our $THR_RES_FH;
our $ICMP4_FH;
our $ICMP6_FH;
our @IDLE_CB;
=item AnyEvent::FastPing::ipv4_supported
Returns true iff IPv4 is supported in this module and on this system.
=item AnyEvent::FastPing::ipv6_supported
Returns true iff IPv6 is supported in this module and on this system.
=item AnyEvent::FastPing::icmp4_pktsize
Returns the number of octets per IPv4 ping packet (the whole IP packet
including headers, excluding lower-level headers or trailers such as
Ethernet).
Can be used to calculate e.g. octets/s from rate ...
my $octets_per_second = $packets_per_second * AnyEvent::FastPing::icmp4_pktsize;
... or convert kilobit/second to packet rate ...
my $packets_per_second = $kilobit_per_second
* (1000 / 8 / AnyEvent::FastPing::icmp4_pktsize);
etc.
=item AnyEvent::FastPing::icmp6_pktsize
Like AnyEvent::FastPing::icmp4_pktsize, but for IPv6.
=back
=head1 THE AnyEvent::FastPing CLASS
The AnyEvent::FastPing class represents a single "pinger". A "pinger"
comes with its own thread to send packets in the background, a rate-limit
machinery and separate idle/receive callbacks.
The recommended workflow (there are others) is this: 1. create a new
AnyEvent::FastPing object 2. configure the address lists and ranges to
ping, also configure an idle callback and optionally a receive callback
3. C<start> the pinger.
When the pinger has finished pinging all the configured addresses it will
call the idle callback.
The pinging process works like this: every range has a minimum interval
between sends, which is used to limit the rate at which hosts in that
range are being pinged. Distinct ranges are independent of each other,
which is why there is a per-pinger "global" minimum interval as well.
The pinger sends pings as fats as possible, while both obeying the pinger
rate limit as well as range limits.
When a range is exhausted, it is removed. When all ranges are exhausted,
the pinger waits another C<max_rtt> seconds and then exits, causing the
idle callback to trigger.
Performance: On my 2 GHz Opteron system with a pretty average nvidia
gigabit network card I can ping around 60k to 200k addresses per second,
depending on routing decisions.
Example: ping 10.0.0.1-10.0.0.15 with at most 100 packets/s, and
11.0.0.1-11.0.255.255 with at most 1000 packets/s. Also ping the IPv6
loopback address 5 times as fast as possible. Do not, however, exceed 1000
packets/s overall. Also dump each received reply.
use AnyEvent::Socket;
use AnyEvent::FastPing;
my $done = AnyEvent->condvar;
my $pinger = new AnyEvent::FastPing;
$pinger->interval (1/1000);
$pinger->max_rtt (0.1); # reasonably fast/reliable network
$pinger->add_range (v10.0.0.1, v10.0.0.15, 1/100);
$pinger->add_range (v11.0.0.1, v11.0.255.255, 1/1000);
$pinger->add_hosts ([ (v0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1) x 5 ]);
$pinger->on_recv (sub {
for (@{ $_[0] }) {
printf "%s %g\n", (AnyEvent::Socket::format_address $_->[0]), $_->[1];
}
});
$pinger->on_idle (sub {
print "done\n";
undef $pinger;
});
$pinger->start;
$done->wait;
=head2 METHODS
( run in 3.556 seconds using v1.01-cache-2.11-cpan-f56aa216473 )