9 |
use CouchDB; |
use CouchDB; |
10 |
|
|
11 |
use server; |
use server; |
12 |
|
use client; |
13 |
our $debug = server::debug; |
our $debug = server::debug; |
14 |
|
|
15 |
my $res = Net::DNS::Resolver->new( |
my $res = Net::DNS::Resolver->new( |
18 |
debug => $debug, |
debug => $debug, |
19 |
); |
); |
20 |
|
|
21 |
our $ptr_cache; |
our ( $ptr_cache, $a_cache ); |
22 |
sub name_ip { |
sub name_ip { |
23 |
my ( $name, $ip ) = @_; |
my ( $name, $ip ) = @_; |
24 |
$ptr_cache->{ join('.', reverse split(/\./, $ip)) } = $name; |
$ptr_cache->{ join('.', reverse split(/\./, $ip)) } = $name; |
25 |
|
$a_cache->{$name} = $ip; |
26 |
return $ip; |
return $ip; |
27 |
} |
} |
28 |
|
|
29 |
|
name_ip 'server' => $server::ip; |
30 |
|
|
31 |
|
foreach my $ip ( client::all_ips ) { |
32 |
|
if ( my $name = client::conf( $ip => 'hostname' ) ) { |
33 |
|
name_ip $name => $ip; |
34 |
|
} |
35 |
|
} |
36 |
|
|
37 |
sub reply_handler { |
sub reply_handler { |
38 |
my ($qname, $qclass, $qtype, $peerhost,$query,$conn) = @_; |
my ($qname, $qclass, $qtype, $peerhost,$query,$conn) = @_; |
39 |
my ($rcode, @ans, @auth, @add); |
my ($rcode, @ans, @auth, @add); |
60 |
warn "local[$local] $qname $qtype"; |
warn "local[$local] $qname $qtype"; |
61 |
$rcode = "NOERROR"; |
$rcode = "NOERROR"; |
62 |
my $rdata; |
my $rdata; |
63 |
if ( $qtype eq "A" && $local eq "server" ) { |
if ( $qtype eq "A" ) { |
64 |
$rdata = name_ip( $local, $server::ip ); |
if ( $rdata = $a_cache->{$local} ) { |
65 |
$audit->{source} = 'local'; |
$audit->{source} = 'local'; |
66 |
} else { |
} else { |
67 |
$rcode = "NXDOMAIN"; |
$rcode = "NXDOMAIN"; |
68 |
} |
warn "## no $local in ",dump( $a_cache ); |
69 |
|
} |
70 |
push @ans, Net::DNS::RR->new("$qname $ttl $qclass $qtype $rdata") if $ttl; |
} elsif ( $qtype eq 'PTR' ) { |
71 |
|
$qname =~ s{\.in-addr\.arpa$}{} || warn "W: can't strip suffix from $qtype $qname"; |
72 |
} elsif ( $qtype eq 'PTR' && $qname =~ m{^([0-9\.]*)\.in-addr\.arpa$} ) { |
if ( my $rdata = $ptr_cache->{$qname} ) { |
|
if ( my $rdata = $ptr_cache->{$1} ) { |
|
73 |
$rdata .= '.' . $server::domain; |
$rdata .= '.' . $server::domain; |
74 |
push @ans, Net::DNS::RR->new("$qname $ttl $qclass $qtype $rdata"); |
push @ans, Net::DNS::RR->new("$qname $ttl $qclass $qtype $rdata"); |
75 |
$audit->{source} = 'PTR'; |
$audit->{source} = 'PTR'; |
76 |
} else { |
} else { |
77 |
warn "## ",dump( $ptr_cache ); |
warn "## no $qname in ",dump( $ptr_cache ); |
78 |
$rcode = "NXDOMAIN"; |
$rcode = "NXDOMAIN"; |
79 |
} |
} |
80 |
|
} else { |
81 |
|
$audit->{warn} = "qtype $qtype not supported"; |
82 |
|
} |
83 |
|
|
84 |
|
push @ans, Net::DNS::RR->new("$qname $ttl $qclass $qtype $rdata") if $ttl; |
85 |
|
|
86 |
} elsif ( my $packet = $res->query( $qname, $qtype ) ) { |
} elsif ( my $packet = $res->query( $qname, $qtype ) ) { |
87 |
|
|
88 |
$audit->{source} = 'upstream'; |
$audit->{source} = 'upstream'; |