aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2014-10-16 23:18:18 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2014-10-16 23:18:18 +0300
commitd8477a3b0687660b6a90bc97dd86313d2aedf519 (patch)
tree4ca0d51bd12426adc9461903f2f2408e252c9937
parentb042d54681f0b8a3eecfd5debc1f2d76ecdcf4d7 (diff)
downloaddnstools-d8477a3b0687660b6a90bc97dd86313d2aedf519.tar.gz
dnstools-d8477a3b0687660b6a90bc97dd86313d2aedf519.tar.bz2
Cache ttl. Bugfixes
* whoseip/Whoseip/DB.pm (ipdb_open): New argument ttl=>N (ipdb_save_page): Bugfix: seek to the correct offset. (ipdb_lookup_unlocked): Handle ttl setting. * whoseip/whoseip.pl (ripe_fmt): New function. Pass -r option to ripe to avoid blacklisting our IP. New option --cache-ttl.
-rw-r--r--whoseip/Whoseip/DB.pm35
-rw-r--r--whoseip/whoseip.pl26
2 files changed, 44 insertions, 17 deletions
diff --git a/whoseip/Whoseip/DB.pm b/whoseip/Whoseip/DB.pm
index f6b08f0..55e86d2 100644
--- a/whoseip/Whoseip/DB.pm
+++ b/whoseip/Whoseip/DB.pm
@@ -264,6 +264,7 @@ sub ipdb_open {
my $ug = new Data::UUID;
print STDERR "file $filename, UUID ".$ug->to_string($ipdbfile{uuid})."\n";
}
+ $ipdbfile{ttl} = $_{ttl};
push @ipdb_open_files, \%ipdbfile;
return \%ipdbfile;
}
@@ -359,15 +360,15 @@ sub ipdb_locker {
sub ipdb_save_page($$) {
my ($dbf, $page) = @_;
- if (sysseek($dbf->{fd}, $page->{off}, SEEK_SET) != $page->{off}) {
- croak "$dbf->{filename}: can't seek: $!";
- }
my $ret;
if ($page->{type} == IPDB_PAGE_INDEX) {
print STDERR "saving index page $page->{off}: ".
join(',', @{$page->{tab}})."\n"
if $dbf->{debug} > 1;
+ if (sysseek($dbf->{fd}, $page->{off}, SEEK_SET) != $page->{off}) {
+ croak "$dbf->{filename}: can't seek: $!";
+ }
$ret = syswrite($dbf->{fd}, pack('LL[257].',
$page->{type},
@{$page->{tab}},
@@ -386,15 +387,7 @@ sub ipdb_save_page($$) {
my $i = 0;
my $a;
foreach my $ent (@{$page->{tab}}) {
- my $fdata = eval { freeze($ent->[4]) };
- if ($@) {
- print STDERR "failed to freeze data for " .
- inet_ntoa(pack('N', $ent->[0])) . "/" .
- inet_ntoa(pack('N', $ent->[1])) . ":".
- $ent->[3] ."\n";
- exit;
- }
- my $x = pack('LLLa2L/a', @{$ent}[0 .. 3],$fdata);
+ my $x = pack('LLLa2L/a', @{$ent}[0 .. 3], freeze($ent->[4]));
my $l = length($x);
if ($size + $l > $dbf->{pagesize}) {
print STDERR "SPLIT at $i: $size + $l, rest ".
@@ -412,6 +405,9 @@ sub ipdb_save_page($$) {
$a .= $x;
++$i;
}
+ if (sysseek($dbf->{fd}, $page->{off}, SEEK_SET) != $page->{off}) {
+ croak "$dbf->{filename}: can't seek: $!";
+ }
$ret = syswrite($dbf->{fd},
pack('LLLa'.length($a).'@'.$dbf->{pagesize},
$page->{type},
@@ -492,7 +488,8 @@ sub ipdb_cache_get($$) {
my ($dbf,$off) = @_;
my $page;
if (defined($dbf->{pagecache}{$off})) {
- print STDERR "$off found in cache\n" if $dbf->{debug};
+ print STDERR "$off found in cache: ".
+ pagetypestr($dbf->{pagecache}{$off}{type})."\n" if $dbf->{debug};
$page = $dbf->{pagecache}{$off};
if (defined($page->{lru_newer})) {
print STDERR "promoting $page->{off}\n" if $dbf->{debug} > 2;
@@ -613,7 +610,7 @@ sub ipdb_get_page($$) {
push @{$ret{tab}}, [ @a[$i*5 .. $i*5 + 3], $href ];
}
} else {
- croak "$dbf->{filename}: invalid page type at offset $off";
+ croak "$dbf->{filename}: invalid page type $ret{type} at offset $off";
}
return \%ret;
@@ -724,6 +721,7 @@ sub ipdb_lookup_unlocked($$) {
$page = ipdb_cache_get($dbf, $page->{tab}[LEAF_IDX]);
}
+ my $i = 0;
foreach my $r (@{$page->{tab}}) {
print STDERR "ipdb_lookup: compare ($ipn & $r->[1]) == $r->[0]\n"
if $dbf->{debug};
@@ -731,6 +729,14 @@ sub ipdb_lookup_unlocked($$) {
# FIXME: check timestamp
print STDERR "ipdb_lookup: MATCH $r->[3]\n"
if $dbf->{debug};
+ if (defined($dbf->{ttl}) and
+ (time - $r->[2]) > $dbf->{ttl}) {
+ print STDERR "ipdb_lookup: record expired, removing\n"
+ if $dbf->{debug};
+ splice @{$page->{tab}}, $i, 1;
+ $page->{dirty} = 1;
+ return undef;
+ }
my %res = ( country => $r->[3],
network => inet_ntoa(pack('N', $r->[0])),
netmask => inet_ntoa(pack('N', $r->[1])) );
@@ -738,6 +744,7 @@ sub ipdb_lookup_unlocked($$) {
if (defined($r->[4]) and ref($r->[4]) eq 'HASH');
return %res;
}
+ ++$i;
}
return undef if (!$page->{next});
$page = ipdb_cache_get($dbf, $page->{next});
diff --git a/whoseip/whoseip.pl b/whoseip/whoseip.pl
index d5f58d0..78f7f8a 100644
--- a/whoseip/whoseip.pl
+++ b/whoseip/whoseip.pl
@@ -207,6 +207,24 @@ use constant RIPE_INIT => 0;
use constant RIPE_TEXT => 1;
use constant RIPE_IGNR => 2;
+sub ripe_fmt {
+ # From the RIPE Database FAQ:
+ #
+ # Q: Why did I receive an Error 201: Access Denied?
+ #
+ # * You (or your application) performed too many queries that
+ # returned contact information (e.g. person or role objects) from the
+ # RIPE Database. There is a daily limit on the amount of personal
+ # data returned as described in the Acceptable Use Policy.
+ #
+ # * Even if you queried for other types of objects, the associated
+ # contact information is returned by default. To avoid this situation
+ # please use the "-r" flag to prevent any associated contact
+ # information from being returned.
+ my $q = shift;
+ return "-r $q";
+}
+
sub ripe_decode {
my ($input, $ref) = @_;
@@ -364,7 +382,7 @@ sub nobistech_decode {
my %srvtab = (
'whois.arin.net' => { q => \&arin_fmt, d => \&arin_decode },
'whois.lacnic.net' => { d => \&lacnic_decode },
- 'whois.ripe.net' => { d => \&ripe_decode },
+ 'whois.ripe.net' => { q => \&ripe_fmt, d => \&ripe_decode },
'rwhois.gin.ntt.net' => { d => \&ntt_decode },
'whois.twnic.net' => { d => \&twnic_decode },
'whois.nic.ad.jp' => { q => \&nic_ad_jp_fmt, d => \&nic_ad_jp_decode },
@@ -665,6 +683,7 @@ sub docgi {
my $output_format;
my $fastcgi;
my $single_query;
+my $cache_ttl;
if (defined($ENV{WHOSEIP_CONF})) {
read_config_file($ENV{WHOSEIP_CONF});
@@ -701,12 +720,13 @@ GetOptions("h" => sub {
"fastcgi:s" => \$fastcgi,
"cache-file|c:s" => \$dbfile,
"no-cache|N" => sub { $dbfile = undef; },
- "single-query" => \$single_query
+ "single-query" => \$single_query,
+ "cache-ttl|ttl|t=n" => \$cache_ttl,
) or exit(EX_USAGE);
if (defined($dbfile)) {
$dbfile .= "whoseip.db" if (-d $dbfile);
- $dbf = ipdb_open($dbfile, debug => $debug);
+ $dbf = ipdb_open($dbfile, debug => $debug, ttl => $cache_ttl);
}
if (defined($fastcgi)) {

Return to:

Send suggestions and report system problems to the System administrator.