28 |
my ($qname, $qclass, $qtype, $peerhost,$query,$conn) = @_; |
my ($qname, $qclass, $qtype, $peerhost,$query,$conn) = @_; |
29 |
my ($rcode, @ans, @auth, @add); |
my ($rcode, @ans, @auth, @add); |
30 |
|
|
|
server->refresh; |
|
31 |
$debug = server::debug; |
$debug = server::debug; |
32 |
|
|
33 |
CouchDB::audit( 'request', { |
my $audit = { |
34 |
qname => $qname, |
qname => $qname, |
35 |
qclass => $qclass, |
qclass => $qclass, |
36 |
qtype => $qtype, |
qtype => $qtype, |
37 |
peerhost => $peerhost, |
peerhost => $peerhost, |
38 |
sockhost => $conn->{"sockhost"} |
sockhost => $conn->{"sockhost"}, |
39 |
}); |
source => 'unknown', |
40 |
|
}; |
41 |
|
|
42 |
$query->print if $debug; |
$query->print if $debug; |
43 |
|
|
52 |
my $rdata; |
my $rdata; |
53 |
if ( $qtype eq "A" && $local eq "server" ) { |
if ( $qtype eq "A" && $local eq "server" ) { |
54 |
$rdata = name_ip( $local, $server::ip ); |
$rdata = name_ip( $local, $server::ip ); |
55 |
CouchDB::audit('local', $rdata); |
$audit->{source} = 'local'; |
56 |
} else { |
} else { |
57 |
$rcode = "NXDOMAIN"; |
$rcode = "NXDOMAIN"; |
58 |
} |
} |
63 |
if ( my $rdata = $ptr_cache->{$1} ) { |
if ( my $rdata = $ptr_cache->{$1} ) { |
64 |
$rdata .= '.' . $server::domain_name; |
$rdata .= '.' . $server::domain_name; |
65 |
push @ans, Net::DNS::RR->new("$qname $ttl $qclass $qtype $rdata"); |
push @ans, Net::DNS::RR->new("$qname $ttl $qclass $qtype $rdata"); |
66 |
CouchDB::audit('ptr', $rdata ); |
$audit->{source} = 'PTR'; |
67 |
} else { |
} else { |
68 |
warn "## ",dump( $ptr_cache ); |
warn "## ",dump( $ptr_cache ); |
69 |
$rcode = "NXDOMAIN"; |
$rcode = "NXDOMAIN"; |
70 |
} |
} |
71 |
} elsif ( my $packet = $res->query( $qname, $qtype ) ) { |
} elsif ( my $packet = $res->query( $qname, $qtype ) ) { |
72 |
|
|
73 |
CouchDB::audit( 'upstream', $packet ); |
$audit->{source} = 'upstream'; |
74 |
$packet->print; |
$packet->print; |
75 |
push @ans, $_ foreach $packet->answer; |
push @ans, $_ foreach $packet->answer; |
76 |
$rcode = "NOERROR"; |
$rcode = "NOERROR"; |
82 |
|
|
83 |
warn "rcode: $rcode ",dump( @ans ); |
warn "rcode: $rcode ",dump( @ans ); |
84 |
|
|
85 |
CouchDB::audit('response', { rcode => $rcode, ans => [ @ans ], auth => [ @auth ], add => [ @add ] }); |
$audit->{rcode} = $rcode; |
86 |
|
$audit->{ans} = [ map { |
87 |
|
my $data; |
88 |
|
foreach my $n ( keys %$_ ) { |
89 |
|
$data->{$n} = $_->{$n}; |
90 |
|
} |
91 |
|
$data; |
92 |
|
} @ans ]; |
93 |
|
|
94 |
|
CouchDB::audit( 'response', $audit ); |
95 |
|
|
96 |
# mark the answer as authoritive (by setting the 'aa' flag |
# mark the answer as authoritive (by setting the 'aa' flag |
97 |
return ($rcode, \@ans, \@auth, \@add, { aa => 1 }); |
return ($rcode, \@ans, \@auth, \@add, { aa => 1 }); |
100 |
sub start { |
sub start { |
101 |
my $ns = Net::DNS::Nameserver->new( |
my $ns = Net::DNS::Nameserver->new( |
102 |
LocalPort => 53, |
LocalPort => 53, |
103 |
ReplyHandler => \&reply_handler, |
ReplyHandler => sub { |
104 |
|
server->refresh; |
105 |
|
reply_handler(@_); |
106 |
|
}, |
107 |
Verbose => $debug, |
Verbose => $debug, |
108 |
) || die "couldn't create nameserver object\n"; |
) || die "couldn't create nameserver object\n"; |
109 |
|
|
110 |
CouchDB::audit('start', { listen => { port => 53, domain_name => $server::domain_name } }); |
CouchDB::audit('start', { port => 53, domain_name => $server::domain_name }); |
111 |
warn "DNS $server::domain_name"; |
warn "DNS $server::domain_name"; |
112 |
|
|
113 |
$ns->main_loop; |
$ns->main_loop; |