ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-FastPing/README
Revision: 1.10
Committed: Sun Feb 6 00:23:45 2011 UTC (13 years, 3 months ago) by root
Branch: MAIN
CVS Tags: rel-2_03, rel-2_02, rel-2_01, rel-2_1, HEAD
Changes since 1.9: +2 -3 lines
Log Message:
2.01

File Contents

# Content
1 NAME
2 AnyEvent::FastPing - quickly ping a large number of hosts
3
4 SYNOPSIS
5 use AnyEvent::FastPing;
6
7 DESCRIPTION
8 This module was written for a single purpose only: sending ICMP ECHO
9 REQUEST packets as quickly as possible to a large number of hosts
10 (thousands to millions).
11
12 It employs a separate thread and is fully event-driven (using AnyEvent),
13 so you have to run an event model supported by AnyEvent to use this
14 module.
15
16 FUNCTIONS
17 AnyEvent::FastPing::ipv4_supported
18 Returns true iff IPv4 is supported in this module and on this
19 system.
20
21 AnyEvent::FastPing::ipv6_supported
22 Returns true iff IPv6 is supported in this module and on this
23 system.
24
25 AnyEvent::FastPing::icmp4_pktsize
26 Returns the number of octets per IPv4 ping packet (the whole IP
27 packet including headers, excluding lower-level headers or trailers
28 such as Ethernet).
29
30 Can be used to calculate e.g. octets/s from rate ...
31
32 my $octets_per_second = $packets_per_second * AnyEvent::FastPing::icmp4_pktsize;
33
34 ... or convert kilobit/second to packet rate ...
35
36 my $packets_per_second = $kilobit_per_second
37 * (1000 / 8 / AnyEvent::FastPing::icmp4_pktsize);
38
39 etc.
40
41 AnyEvent::FastPing::icmp6_pktsize
42 Like AnyEvent::FastPing::icmp4_pktsize, but for IPv6.
43
44 THE AnyEvent::FastPing CLASS
45 The AnyEvent::FastPing class represents a single "pinger". A "pinger"
46 comes with its own thread to send packets in the background, a
47 rate-limit machinery and separate idle/receive callbacks.
48
49 The recommended workflow (there are others) is this: 1. create a new
50 AnyEvent::FastPing object 2. configure the address lists and ranges to
51 ping, also configure an idle callback and optionally a receive callback
52 3. "start" the pinger.
53
54 When the pinger has finished pinging all the configured addresses it
55 will call the idle callback.
56
57 The pinging process works like this: every range has a minimum interval
58 between sends, which is used to limit the rate at which hosts in that
59 range are being pinged. Distinct ranges are independent of each other,
60 which is why there is a per-pinger "global" minimum interval as well.
61
62 The pinger sends pings as fats as possible, while both obeying the
63 pinger rate limit as well as range limits.
64
65 When a range is exhausted, it is removed. When all ranges are exhausted,
66 the pinger waits another "max_rtt" seconds and then exits, causing the
67 idle callback to trigger.
68
69 Performance: On my 2 GHz Opteron system with a pretty average nvidia
70 gigabit network card I can ping around 60k to 200k addresses per second,
71 depending on routing decisions.
72
73 Example: ping 10.0.0.1-10.0.0.15 with at most 100 packets/s, and
74 11.0.0.1-11.0.255.255 with at most 1000 packets/s. Also ping the IPv6
75 loopback address 5 times as fast as possible. Do not, however, exceed
76 1000 packets/s overall. Also dump each received reply.
77
78 use AnyEvent::Socket;
79 use AnyEvent::FastPing;
80
81 my $done = AnyEvent->condvar;
82
83 my $pinger = new AnyEvent::FastPing;
84
85 $pinger->interval (1/1000);
86 $pinger->max_rtt (0.1); # reasonably fast/reliable network
87
88 $pinger->add_range (v10.0.0.1, v10.0.0.15, 1/100);
89 $pinger->add_range (v11.0.0.1, v11.0.255.255, 1/1000);
90 $pinger->add_hosts ([ (v0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1) x 5 ]);
91
92 $pinger->on_recv (sub {
93 for (@{ $_[0] }) {
94 printf "%s %g\n", (AnyEvent::Socket::format_address $_->[0]), $_->[1];
95 }
96 });
97
98 $pinger->on_idle (sub {
99 print "done\n";
100 undef $pinger;
101 });
102
103 $pinger->start;
104 $done->wait;
105
106 METHODS
107 $pinger = new AnyEvent::FastPing
108 Creates a new pinger - right now there can be at most 65536 pingers
109 in a process, although that limit might change to something
110 drastically lower - you should be stingy with your pinger objects.
111
112 $pinger->on_recv ($callback->([[$host, $rtt], ...]))
113 Registers a callback to be called for ping replies. If no callback
114 has been registered than ping replies will be ignored, otherwise
115 this module calculates the round trip time, in seconds, for each
116 reply and calls this callback.
117
118 The callback receives a single argument, which is an array reference
119 with an entry for each reply packet (the replies will be batched for
120 efficiency). Each member in the array reference is again an array
121 reference with exactly two members: the binary host address (4
122 octets for IPv4, 16 for IPv6) and the approximate round trip time,
123 in seconds.
124
125 The replies will be passed to the callback as soon as they arrive,
126 and this callback can be called many times with batches of replies.
127
128 The receive callback will be called whenever a suitable reply
129 arrives, whether generated by this pinger or not, whether this
130 pinger is started or not. The packets will have a unique 64 bit ID
131 to distinguish them from other pinger objects and other generators,
132 but this doesn't help against malicious replies.
133
134 Note that very high packet rates can overwhelm your process, causing
135 replies to be dropped (configure your kernel with long receive
136 queues for raw sockets if this is a problem).
137
138 Example: register a callback which simply dumps the received data.
139
140 use AnyEvent::Socket;
141
142 $pinger->on_recv (sub {
143 for (@{ $_[0] }) {
144 printf "%s %g\n", (AnyEvent::Socket::format_address $_->[0]), $_->[1];
145 }
146 });
147
148 Example: a single ping reply with payload of 1 from "::1" gets
149 passed like this:
150
151 [
152 [ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1", 0.000280141830444336 ]
153 ]
154
155 Example: ping replies for 127.0.0.1 and 127.0.0.2:
156
157 [
158 [ "\177\0\0\1", 0.00015711784362793 ],
159 [ "\177\0\0\2", 0.00090184211731 ]
160 ]
161
162 $pinger->on_idle ($callback->())
163 Registers a callback to be called when the pinger becomes *idle*,
164 that is, it has been started, has exhausted all ping ranges and
165 waited for the "max_rtt" time. An idle pinger is also stopped, so
166 the callback can instantly add new ranges, if it so desires.
167
168 $pinger->interval ($seconds)
169 Configures the minimum interval between packet sends for this pinger
170 - the pinger will not send packets faster than this rate (or
171 actually 1 / rate), even if individual ranges have a lower interval.
172
173 A value of 0 selects the fastest possible speed (currently no faster
174 than 1_000_000 packets/s).
175
176 $pinger->max_rtt ($seconds)
177 If your idle callback were called instantly after all ranges were
178 exhausted and you destroyed the object inside (which is common),
179 then there would be no chance to receive some replies, as there
180 would be no time of the packet to travel over the network.
181
182 This can be fixed by starting a timer in the idle callback, or more
183 simply by selecting a suitable "max_rtt" value, which should be the
184 maximum time you allow a ping packet to travel to its destination
185 and back.
186
187 The pinger thread automatically waits for this amount of time before
188 becoming idle.
189
190 The default is currently 0.5 seconds, which is usually plenty.
191
192 $pinger->add_range ($lo, $hi[, $interval])
193 Ping the IPv4 (or IPv6, but see below) address range, starting at
194 binary address $lo and ending at $hi (both $lo and $hi will be
195 pinged), generating no more than one ping per $interval seconds (or
196 as fast as possible if omitted).
197
198 You can convert IP addresses from text to binary form by using
199 "AnyEvent::Util::parse_address", "Socket::inet_aton",
200 "Socket6::inet_pton" or any other method that you like :)
201
202 The algorithm to select the next address is O(log n) on the number
203 of ranges, so even a large number of ranges (many thousands) is
204 manageable.
205
206 No storage is allocated per address.
207
208 Note that, while IPv6 addresses are currently supported, the
209 usefulness of this option is extremely limited and might be gone in
210 future versions - if you want to ping a number of IPv6 hosts, better
211 specify them individually using the "add_hosts" method.
212
213 $pinger->add_hosts ([$host...], $interval, $interleave)
214 Similar to "add_range", but uses a list of single addresses instead.
215 The list is specified as an array reference as first argument. Each
216 entry in the array should be a binary host address, either IPv4 or
217 IPv6. If all addresses are IPv4 addresses, then a compact IPv4-only
218 format will be used to store the list internally.
219
220 Minimum $interval is the same as for "add_range" and can be left
221 out.
222
223 $interlave specifies an increment between addresses: often address
224 lists are generated in a way that results in clustering - first all
225 addresses from one subnet, then from the next, and so on. To avoid
226 this, you can specify an interleave factor. If it is 1 (the
227 default), then every address is pinged in the order specified. If it
228 is 2, then only every second address will be pinged in the first
229 round, followed by a second round with the others. Higher factors
230 will create $interleave runs of addresses spaced $interleave indices
231 in the list.
232
233 The special value 0 selects a (hopefully) suitable interleave factor
234 automatically - currently 256 for lists with less than 65536
235 addresses, and the square root of the list length otherwise.
236
237 $pinger->start
238 Start the pinger, unless it is running already. While a pinger is
239 running you must not modify the pinger. If you want to change a
240 parameter, you have to "stop" the pinger first.
241
242 The pinger will automatically stop when destroyed.
243
244 $pinger->stop
245 Stop the pinger, if it is running. A pinger can be stopped at any
246 time, after which it's current state is preserved - starting it
247 again will continue where it left off.
248
249 AUTHOR
250 Marc Lehmann <schmorp@schmorp.de>
251 http://home.schmorp.de/
252
253 LICENSE
254 This software is distributed under the GENERAL PUBLIC LICENSE, version 2
255 or any later version or, at your option, the Artistic License.
256