--- lib/PXElator/dnsd.pm 2009/08/03 15:06:23 125 +++ lib/PXElator/dnsd.pm 2009/08/15 14:41:33 223 @@ -6,6 +6,7 @@ use Net::DNS::Nameserver; use Net::DNS::Resolver; use Data::Dump qw/dump/; +use CouchDB; use server; our $debug = server::debug; @@ -16,22 +17,62 @@ debug => $debug, ); +our $ptr_cache; +sub name_ip { + my ( $name, $ip ) = @_; + $ptr_cache->{ join('.', reverse split(/\./, $ip)) } = $name; + return $ip; +} + sub reply_handler { my ($qname, $qclass, $qtype, $peerhost,$query,$conn) = @_; my ($rcode, @ans, @auth, @add); - print "Received query from $peerhost to ". $conn->{"sockhost"}. "\n"; - $query->print; + server->refresh; + $debug = server::debug; - if ( $qtype eq "A" && $qname eq "pxelator" ) { - my ($ttl, $rdata) = (3600, "172.16.10.1"); - push @ans, Net::DNS::RR->new("$qname $ttl $qclass $qtype $rdata"); - $rcode = "NOERROR"; - } elsif ( $qname eq "foo.example.com" ) { - $rcode = "NOERROR"; + CouchDB::audit( 'request', { + qname => $qname, + qclass => $qclass, + qtype => $qtype, + peerhost => $peerhost, + sockhost => $conn->{"sockhost"} + }); + + $query->print if $debug; + + my $local = $1 if $qname =~ m{^(.+)\.\Q$server::domain_name\E$}; + $local = $qname if $qname !~ m{\.}; + + my $ttl = 3600; + my $audit = { source => 'unknown' }; + + if ( $local ) { + warn "local[$local] $qname $qtype"; + $rcode = "NOERROR"; + my $rdata; + if ( $qtype eq "A" && $local eq "server" ) { + $rdata = name_ip( $local, $server::ip ); + $audit->{source} = 'local'; + } else { + $rcode = "NXDOMAIN"; + } + + push @ans, Net::DNS::RR->new("$qname $ttl $qclass $qtype $rdata") if $ttl; + + } elsif ( $qtype eq 'PTR' && $qname =~ m{^([0-9\.]*)\.in-addr\.arpa$} ) { + if ( my $rdata = $ptr_cache->{$1} ) { + $rdata .= '.' . $server::domain_name; + push @ans, Net::DNS::RR->new("$qname $ttl $qclass $qtype $rdata"); + $audit->{source} = 'PTR'; + } else { +warn "## ",dump( $ptr_cache ); + $rcode = "NXDOMAIN"; + } } elsif ( my $packet = $res->query( $qname, $qtype ) ) { + $audit->{source} = 'upstream'; $packet->print; push @ans, $_ foreach $packet->answer; $rcode = "NOERROR"; @@ -41,6 +82,19 @@ $rcode = "NXDOMAIN"; } + warn "rcode: $rcode ",dump( @ans ); + + $audit->{rcode} = $rcode; + $audit->{ans} = [ map { + my $data; + foreach my $n ( keys %$_ ) { + $data->{$n} = $_->{$n}; + } + $data; + } @ans ]; + + CouchDB::audit( 'response', $audit ); + # mark the answer as authoritive (by setting the 'aa' flag return ($rcode, \@ans, \@auth, \@add, { aa => 1 }); } @@ -52,7 +106,10 @@ Verbose => $debug, ) || die "couldn't create nameserver object\n"; + CouchDB::audit('start', { listen => { port => 53, domain_name => $server::domain_name } }); + warn "DNS $server::domain_name"; + $ns->main_loop; } -1; +1;