ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-FastPing/FastPing.pm
(Generate patch)

Comparing AnyEvent-FastPing/FastPing.pm (file contents):
Revision 1.3 by root, Sun May 18 20:10:05 2008 UTC vs.
Revision 1.11 by root, Mon Jan 31 05:35:48 2011 UTC

21 21
22=cut 22=cut
23 23
24package AnyEvent::FastPing; 24package AnyEvent::FastPing;
25 25
26use strict; 26use common::sense;
27no warnings;
28 27
29use AnyEvent; 28use AnyEvent;
30 29
31BEGIN { 30BEGIN {
32 our $VERSION = '1.11'; 31 our $VERSION = '2.0';
33 our @ISA = qw(Exporter); 32 our @ISA = qw(Exporter);
34 33
35 require Exporter; 34 require Exporter;
36 #Exporter::export_ok_tags (keys %EXPORT_TAGS); 35 #Exporter::export_ok_tags (keys %EXPORT_TAGS);
37 36
38 require XSLoader; 37 require XSLoader;
39 XSLoader::load (__PACKAGE__, $VERSION); 38 XSLoader::load (__PACKAGE__, $VERSION);
40} 39}
41 40
42our ($THR_REQ_FD, $THR_RES_FD, $ICMP4_FD, $ICMP6_FD); 41our ($THR_RES_FD, $ICMP4_FD, $ICMP6_FD);
43 42
44our $THR_REQ_FH; open $THR_REQ_FH, ">&=$THR_REQ_FD" or die "FATAL: cannot fdopen";
45our $THR_RES_FH; open $THR_RES_FH, "<&=$THR_RES_FD" or die "FATAL: cannot fdopen"; 43our $THR_RES_FH; open $THR_RES_FH, "<&=$THR_RES_FD" or die "FATAL: cannot fdopen";
46 44
47our $THR_REQ_W; 45our $ICMP4_FH; our $ICMP4_W = $ICMP4_FD >= 0 && (open $ICMP4_FH, "<&=$ICMP4_FD") && AE::io $ICMP4_FH, 0, \&_recv_icmp4;
48our $THR_RES_W = AnyEvent->io (fh => $THR_RES_FH, poll => 'r', cb => sub { 46our $ICMP6_FH; our $ICMP6_W = $ICMP6_FD >= 0 && (open $ICMP6_FH, "<&=$ICMP6_FD") && AE::io $ICMP6_FH, 0, \&_recv_icmp6;
49 my $sv = _read_res
50 or return;
51 47
52 $sv->(); 48=item AnyEvent::FastPing::ipv4_supported
49
50Returns true if IPv4 is supported in this module and on this system.
51
52=item AnyEvent::FastPing::ipv6_supported
53
54Returns true if IPv6 is supported in this module and on this system.
55
56=item AnyEvent::FastPing::icmp4_pktsize
57
58Returns the number of bytes each IPv4 ping packet has.
59
60=item AnyEvent::FastPing::icmp6_pktsize
61
62Returns the number of bytes each IPv4 ping packet has.
63
64=cut
65
66sub new {
67 my ($klass) = @_;
68
69 _new $klass, (rand 65536), (rand 65536), (rand 65536)
70}
71
72our @IDLE_CB;
73
74sub DESTROY {
75 undef $IDLE_CB[ &id ];
76 &_free;
77}
78
79sub on_idle {
80 $IDLE_CB[ &id ] = $_[1];
81}
82
83our $THR_RES_W = AE::io $THR_RES_FH, 0, sub {
84 sysread $THR_RES_FH, my $buf, 8;
85
86 for my $id (unpack "S*", $buf) {
87 _stop_id $id;
88 ($IDLE_CB[$id] || sub { })->();
89 }
90};
91
92for(1..10) {
93my $p = new AnyEvent::FastPing;#d#
94$p->interval (0);
95$p->max_rtt (0.5);
96#$p->add_range (v127.0.0.1, v127.255.255.254, 0);
97$p->add_range (v1.0.0.1, v1.255.255.254, 0);
98$p->on_idle (my $cv = AE::cv);
99my $cnt;
100$p->on_recv (sub {
101 $cnt++;
53}); 102});
54 103$p->start;
55our $THR_REQ_BUF; 104$cv->recv;
56 105warn $cnt;
57sub _send_req($) {
58 $THR_REQ_BUF .= $_[0];
59
60 $THR_REQ_W ||= AnyEvent->io (fh => $THR_REQ_FH, poll => 'w', cb => sub {
61 my $len = syswrite $THR_REQ_FH, $THR_REQ_BUF;
62 substr $THR_REQ_BUF, 0, $len, "";
63
64 undef $THR_REQ_W unless length $THR_REQ_BUF;
65 });
66} 106}
67
68=item AnyEvent::FastPing::ipv4_supported
69
70Returns true if IPv4 is supported in this module and on this system.
71
72=item AnyEvent::FastPing::ipv6_supported
73
74Returns true if IPv6 is supported in this module and on this system.
75
76=item AnyEvent::FastPing::icmp4_pktsize
77
78Returns the number of bytes each IPv4 ping packet has.
79
80=item AnyEvent::FastPing::icmp6_pktsize
81
82Returns the number of bytes each IPv4 ping packet has.
83 107
84=item AnyEvent::FastPing::icmp_ping [ranges...], $send_interval, $payload, \&callback 108=item AnyEvent::FastPing::icmp_ping [ranges...], $send_interval, $payload, \&callback
85 109
86Ping the given IPv4 address ranges. Each range is an arrayref of the 110Ping the given IPv4 address ranges. Each range is an arrayref of the
87form C<[lo, hi, interval]>, where C<lo> and C<hi> are octet strings with 111form C<[lo, hi, interval]>, where C<lo> and C<hi> are octet strings with
91range C<interval> is the minimum time in seconds between pings to the 115range C<interval> is the minimum time in seconds between pings to the
92given range. If omitted, defaults to C<$send_interval>. 116given range. If omitted, defaults to C<$send_interval>.
93 117
94The C<$send_interval> is the minimum interval between sending any two 118The C<$send_interval> is the minimum interval between sending any two
95packets and is a way to make an overall rate limit. If omitted, pings will 119packets and is a way to make an overall rate limit. If omitted, pings will
96be send as fast as possible. 120be sent as fast as possible.
97 121
98The C<$payload> is a 32 bit unsigned integer given as the ICMP ECHO 122The C<$payload> is a 32 bit unsigned integer given as the ICMP ECHO
99REQUEST ident and sequence numbers (in unspecified order :). 123REQUEST ident and sequence numbers (in unspecified order :).
100 124
101The request will be queued and all requests will be served by a background 125The request will be queued and all requests will be served by a background
141 $done->wait; 165 $done->wait;
142 166
143=cut 167=cut
144 168
145sub icmp_ping($$$&) { 169sub icmp_ping($$$&) {
146 _send_req _req_icmp_ping @_; 170# _send_req _req_icmp_ping @_;
147} 171}
148
149our $ICMP4_FH;
150our $ICMP4_W = (open $ICMP4_FH, "<&=$ICMP4_FD") && AnyEvent->io (fh => $ICMP4_FH, poll => 'r', cb => \&_recv_icmp4);
151our $ICMP6_FH;
152our $ICMP6_W = (open $ICMP6_FH, "<&=$ICMP6_FD") && AnyEvent->io (fh => $ICMP6_FH, poll => 'r', cb => \&_recv_icmp6);
153 172
154=item AnyEvent::FastPing::register_cb \&cb 173=item AnyEvent::FastPing::register_cb \&cb
155 174
156Register a callback that is called for every received ping reply 175Register a callback that is called for every received ping reply
157(regardless of whether a ping is still in process or not and regardless of 176(regardless of whether a ping is still in process or not and regardless of
158whether the reply is actually a reply to a ping sent earlier). 177whether the reply is actually a reply to a ping sent earlier).
159 178
160The code reference gets a single parameter - an arrayref with an 179The code reference gets a single parameter - an arrayref with an
161entry for each received packet (replies are beign batched for greater 180entry for each received packet (replies are being batched for greater
162efficiency). Each packet is represented by an arrayref with three members: 181efficiency). Each packet is represented by an arrayref with three members:
163the source address (an octet string of either 4 (IPv4) or 16 (IPv6) octets 182the source address (an octet string of either 4 (IPv4) or 16 (IPv6) octets
164length), the payload as passed to C<icmp_ping> and the round trip time in 183length), the payload as passed to C<icmp_ping> and the round trip time in
165seconds. 184seconds.
185
186Example: register a callback which simply dumps the received data. Since
187the coderef is created on the fly via sub, it would be hard to unregister
188this callback again :)
189
190 AnyEvent::FastPing::register_cb sub {
191 for (@{$_[0]}) {
192 printf "%s %d %g\n",
193 (4 == length $_->[0] ? inet_ntoa $_->[0] : Socket6::inet_ntop (&AF_INET6, $_->[0])),
194 $_->[2],
195 $_->[1];
196 }
197 };
166 198
167Example: a single ping reply with payload of 1 from C<::1> gets passed 199Example: a single ping reply with payload of 1 from C<::1> gets passed
168like this: 200like this:
169 201
170 [ [ 202 [ [
196 228
197=cut 229=cut
198 230
199our @CB; 231our @CB;
200 232
201sub register_cb(&) { 233sub register_cb($) {
202 push @CB, $_[0]; 234 push @CB, $_[0];
203} 235}
204 236
205sub unregister_cb($) { 237sub unregister_cb($) {
206 @CB = grep $_ != $_[0], @CB; 238 @CB = grep $_ != $_[0], @CB;
210 242
211=back 243=back
212 244
213=head1 AUTHOR 245=head1 AUTHOR
214 246
215 Marc Lehmann <schmorp@schmorp.de> 247 Marc Lehmann <schmorp@schmorp.de>
216 http://home.schmorp.de/ 248 http://home.schmorp.de/
217 249
218=head1 AUTHOR 250=head1 LICENSE
219 251
220 This software is distributed under the GENERAL PUBLIC LICENSE, version 2 252 This software is distributed under the GENERAL PUBLIC LICENSE, version 2
221 or any later version or, at your option, the Artistic License. 253 or any later version or, at your option, the Artistic License.
222 254
223=cut 255=cut
224 256

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines