ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-FastPing/FPing.pm
Revision: 1.2
Committed: Fri May 4 07:36:45 2007 UTC (17 years, 3 months ago) by root
Branch: MAIN
Changes since 1.1: +28 -14 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 =head1 NAME
2
3 Net::FPing - quickly ping a large number of hosts
4
5 =head1 SYNOPSIS
6
7 use Net::FPing;
8
9 =head1 DESCRIPTION
10
11 This module was written for a signle purpose only: sendinf ICMP EHCO
12 REQUEST packets as quickly as possible to a large number of hosts
13 (thousands to millions).
14
15 It employs a sending thread and is fully event-driven (using AnyEvent), so
16 you have to run an event model supported by AnyEvent to use this module.
17
18 Receiving and processing reply packets is not currently supported by this
19 module.
20
21 =over 4
22
23 =cut
24
25 package Net::FPing;
26
27 use AnyEvent;
28
29 BEGIN {
30 $VERSION = '0.01';
31 @ISA = qw(Exporter);
32
33 require Exporter;
34 Exporter::export_ok_tags(keys %EXPORT_TAGS);
35
36 require XSLoader;
37 XSLoader::load __PACKAGE__, $VERSION;
38 }
39
40 our $THR_REQ_FH; open $THR_REQ_FH, ">&=$THR_REQ_FD" or die "FATAL: cannot fdopen";
41 our $THR_RES_FH; open $THR_RES_FH, "<&=$THR_RES_FD" or die "FATAL: cannot fdopen";
42
43 our $THR_REQ_W;
44 our $THR_RES_W = AnyEvent->io (fh => $THR_RES_FH, poll => 'r', cb => sub {
45 my $sv = _read_res
46 or return;
47
48 $sv->();
49 });
50
51 our @THR_REQ_BUF;
52
53 sub _send_req($) {
54 $THR_REQ_BUF .= $_[0];
55
56 $THR_REQ_W ||= AnyEvent->io (fh => $THR_REQ_FH, poll => 'w', cb => sub {
57 my $len = syswrite $THR_REQ_FH, $THR_REQ_BUF;
58 substr $THR_REQ_BUF, 0, $len, "";
59
60 undef $THR_REQ_W unless length $THR_REQ_BUF;
61 });
62 }
63
64 =item Net::FPing::ipv4_supported
65
66 Returns true if IPv4 is supported in this module and on this system.
67
68 =item Net::FPing::ipv6_supported
69
70 Returns true if IPv6 is supported in this module and on this system.
71
72 =item Net::FPing::ipv4_pktsize
73
74 Returns the number of bytes each IPv4 ping packet has.
75
76 =item Net::FPing::ipv6_pktsize
77
78 Returns the number of bytes each IPv4 ping packet has.
79
80 =item Net::FPing::icmp_ping [ranges...], $send_interval, $payload, \&callback
81
82 Ping the given IPv4 address ranges. Each range is an arrayref of the
83 form C<[lo, hi, interval]>, where C<lo> and C<hi> are octet strings with
84 either 4 octets (for IPv4 addresses) or 16 octets (for IPV6 addresses),
85 representing the lowest and highest address to ping (you can convert a
86 dotted-quad IPv4 address to this format by using C<inet_aton $address>. The
87 range C<interval> is the minimum time in seconds between pings to the
88 given range. If omitted, defaults to C<$send_interval>.
89
90 The C<$send_interval> is the minimum interval between sending any two
91 packets and is a way to make an overall rate limit. If omitted, pings will
92 be send as fast as possible.
93
94 The C<$payload> is a 32 bit integer given as the ICMP ECHO REQUEST ident
95 and sequence numbers (in unspecified order :).
96
97 The request will be queued and all requests will be served by a background
98 thread in order. When all ranges have been pinged, the C<callback> will be
99 called.
100
101 Algorithm: Each range has an associated "next time to send packet"
102 time. The algorithm loops as long as there are ranges with hosts to be
103 pinged and always serves the range with the most urgent packet send
104 time. It will at most send one packet every C<$send_interval> seconds. The
105 algorithm to send each packet is O(log n) on the number of ranges, so even
106 a large number of ranges (many thousands) is managable. No storage is
107 allocated per address.
108
109 Performance: On my 2 GHZ Opteron system with a pretty average nvidia
110 gigabit network card I can ping around 60k to 200k adresses per second,
111 depending on routing decisions.
112
113 Example: ping 10.0.0.1-10.0.0.15 with at most 100 packets/s, and
114 11.0.0.1-11.0.255.255 with at most 1000 packets/s. Do not, however, exceed
115 1000 packets/s overall:
116
117 Net::FPing::icmp_ping
118 [v10.0.0.1, v10.0.0.15, .01],
119 [v11.0.0.1, v11.0.255.255, .001],
120 .001, 0x12345678,
121 sub {
122 warn "all ranges pinged\n";
123 }
124 ;
125
126 =cut
127
128 sub icmp_ping($$$&) {
129 _send_req _req_icmp_ping @_;
130 }
131
132 our $ICMP4_FH;
133 our $ICMP4_W = (open $ICMP4_FH, "<&=$ICMP4_FD") && AnyEvent->io (fh => $ICMP4_FH, poll => 'r', cb => \&_recv_icmp4);
134 our $ICMP6_FH;
135 our $ICMP6_W = (open $ICMP6_FH, "<&=$ICMP6_FD") && AnyEvent->io (fh => $ICMP6_FH, poll => 'r', cb => \&_recv_icmp6);
136
137 1;
138
139 =back
140
141 =head1 BUGS AND SHORTCOMINGS
142
143 - replies are not yet accessible.
144 - ipv6 support has never ever been tested.
145
146 =head1 AUTHOR
147
148 Marc Lehmann <schmorp@schmorp.de>
149 http://home.schmorp.de/
150
151 =head1 AUTHOR
152
153 This software is distributed under the GENERAL PUBLIC LICENSE,
154 version 2 or any later.
155
156 =cut
157