ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/myhttpd/netgeo.pl
(Generate patch)

Comparing Coro/myhttpd/netgeo.pl (file contents):
Revision 1.3 by root, Thu Aug 16 16:40:07 2001 UTC vs.
Revision 1.6 by root, Thu Aug 30 03:35:56 2001 UTC

2 2
3# APNIC refer: KRNIC (for 211.104.0.0) 3# APNIC refer: KRNIC (for 211.104.0.0)
4 4
5use Socket; 5use Socket;
6use Fcntl; 6use Fcntl;
7
8use PApp::SQL;
9 7
10use Coro; 8use Coro;
11use Coro::Event; 9use Coro::Event;
12use Coro::Semaphore; 10use Coro::Semaphore;
11use Coro::SemaphoreSet;
13use Coro::Socket; 12use Coro::Socket;
14 13
15$Event::DIED = sub { 14$Event::DIED = sub {
16 Event::verbose_exception_handler(@_); 15 Event::verbose_exception_handler(@_);
17 #Event::unloop_all(); 16 #Event::unloop_all();
18}; 17};
19 18
19tie %netgeo::whois, BerkeleyDB::Btree,
20 -Env => $db_env,
21 -Filename => "whois",
22 -Flags => DB_CREATE,
23 or die "unable to create/open whois table";
24$netgeo::iprange = new BerkeleyDB::Btree
25 -Env => $db_env,
26 -Filename => "iprange",
27 -Flags => DB_CREATE,
28 or die "unable to create/open iprange table";
29
20package Whois; 30package Whois;
21 31
22use PApp::SQL;
23use Coro::Event; 32use Coro::Event;
24 33
25sub new { 34sub new {
26 my $class = shift; 35 my $class = shift;
27 my $name = shift; 36 my $name = shift;
39 $_[1]; 48 $_[1];
40} 49}
41 50
42sub whois_request { 51sub whois_request {
43 my ($self, $query) = @_; 52 my ($self, $query) = @_;
44 my ($id, $whois);
45 53
46 my $st = sql_exec \($id, $whois), 54 my $id = "$self->{name}\x0$query";
47 "select id, whois from whois 55 my $whois = $netgeo::whois{$id};
48 where nic = ? and query = ?",
49 $self->{name}, $query;
50 56
51 unless ($st->fetch) { 57 unless (defined $whois) {
58 print "WHOIS($self->{name},$query)\n";
59
52 my $guard = $self->{maxjobs}->guard; 60 my $guard = $self->{maxjobs}->guard;
53 my $timeout = 5; 61 my $timeout = 5;
54 62
55 while () { 63 while () {
56 my $fh = new Coro::Socket 64 my $fh = new Coro::Socket
76 last; 84 last;
77 } 85 }
78 } 86 }
79 } 87 }
80 88
81 sql_exec "replace into whois values (NULL,?,?,NULL,?,?)", 89 $netgeo::whois{$id} = $whois;
82 $self->{name}, $query, $whois, time;
83
84 my $st = sql_exec \$id,
85 "select id from whois
86 where nic = ? and query = ?",
87 $self->{name}, $query;
88 $st->fetch or die;
89 } 90 }
90 91
91 $whois; 92 $whois;
92} 93}
93 94
94package Whois::ARIN; 95package Whois::ARIN;
95 96
96use Date::Parse; 97use Date::Parse;
97use PApp::SQL;
98 98
99use base Whois; 99use base Whois;
100 100
101sub sanitize { 101sub sanitize {
102 local $_ = $_[1]; 102 local $_ = $_[1];
165 $whois; 165 $whois;
166} 166}
167 167
168package Whois::RIPE; 168package Whois::RIPE;
169 169
170use PApp::SQL;
171
172use base Whois; 170use base Whois;
173 171
174sub sanitize { 172sub sanitize {
175 local $_ = $_[1]; 173 local $_ = $_[1];
176 s/^%.*\n//gm; 174 s/^%.*\n//gm;
202 $whois =~ s/\n+$//; 200 $whois =~ s/\n+$//;
203 201
204 $whois; 202 $whois;
205} 203}
206 204
207package main; 205package netgeo;
206
207use BerkeleyDB;
208use Socket;
208 209
209sub ip2int($) { 210sub ip2int($) {
210 unpack "N", inet_aton $_[0]; 211 unpack "N", inet_aton $_[0];
211} 212}
212 213
218 219
219$WHOIS{ARIN} = new Whois::ARIN ARIN => "whois.arin.net", maxjobs => 12; 220$WHOIS{ARIN} = new Whois::ARIN ARIN => "whois.arin.net", maxjobs => 12;
220$WHOIS{RIPE} = new Whois::RIPE RIPE => "whois.ripe.net", maxjobs => 20; 221$WHOIS{RIPE} = new Whois::RIPE RIPE => "whois.ripe.net", maxjobs => 20;
221$WHOIS{APNIC} = new Whois::RIPE APNIC => "whois.apnic.net", maxjobs => 20; 222$WHOIS{APNIC} = new Whois::RIPE APNIC => "whois.apnic.net", maxjobs => 20;
222 223
224$whoislock = new Coro::SemaphoreSet;
225
223sub ip_request { 226sub ip_request {
224 my $ip = $_[0]; 227 my $ip = $_[0];
225 my $_ip = ip2int($ip);
226 228
227 my $st = sql_exec \my($whois, $ip0), 229 my $guard = $whoislock->guard($ip);
228 "select data, ip0 from iprange
229 where ? <= ip1
230 having ip0 <= ?
231 order by ip1
232 limit 1",
233 $_ip, $_ip;
234 230
235 unless ($st->fetch) { 231 my $c = $iprange->db_cursor;
236 my ($arin, $ripe, $apnic); 232 my $v;
237 233
238 $whois = $WHOIS{APNIC}->ip_request($ip) 234 if (!$c->c_get((inet_aton $ip), $v, DB_SET_RANGE)) {
239 || $WHOIS{RIPE} ->ip_request($ip) 235 my ($ip0, $ip1, $whois) = split /\x0/, $v;
240 || $WHOIS{ARIN} ->ip_request($ip);
241
242 $whois =~ /^\*in: ([0-9.]+)\s+-\s+([0-9.]+)\s*$/mi
243 or do { warn "$whois($ip): no addresses found\n", last };
244
245 my ($ip0, $ip1) = ($1, $2);
246
247 my $_ip0 = ip2int($ip0); 236 my $_ip = ip2int $ip;
248 my $_ip1 = ip2int($ip1); 237 if ($ip0 <= $_ip && $_ip <= $ip1) {
249 238 return $whois;
250 if ($_ip0 + 256 < $_ip1) {
251 $_ip = $_ip & 0xffffff00;
252 $_ip0 = $_ip if $_ip0 < $_ip;
253 $_ip1 = $_ip + 255 if $_ip1 > $_ip + 255;
254 } 239 }
255
256 sql_exec "replace into iprange values (?, ?, NULL, ?)",
257 $_ip0, $_ip1, $whois;
258
259 #print "$ip ($ip0, $ip1 ($_ip0, $_ip1)\n$whois\n";
260 } 240 }
261 241
262 $whois; 242 my ($arin, $ripe, $apnic);
263}
264 243
244 $whois = $WHOIS{APNIC}->ip_request($ip)
245 || $WHOIS{RIPE} ->ip_request($ip)
246 || $WHOIS{ARIN} ->ip_request($ip);
265 247
248 $whois =~ /^\*in: ([0-9.]+)\s+-\s+([0-9.]+)\s*$/mi
249 or do { warn "$whois($ip): no addresses found\n", last };
266 250
251 my ($ip0, $ip1) = ($1, $2);
252
253 my $_ip = ip2int($ip);
254 my $_ip0 = ip2int($ip0);
255 my $_ip1 = ip2int($ip1);
256
257 if ($_ip0 + 256 < $_ip1) {
258 $_ip = $_ip & 0xffffff00;
259 $_ip0 = $_ip if $_ip0 < $_ip;
260 $_ip1 = $_ip + 255 if $_ip1 > $_ip + 255;
261 }
262
263 $iprange->db_put((pack "N", $_ip1), (join "\x0", $_ip0, $_ip1, $whois));
264 (tied %whois)->db_sync;
265 $iprange->db_sync;
266
267 $whois;
268}
269
270
271

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines