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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines