package dnsd;
 
use warnings;
use strict;

use Net::DNS::Nameserver;
use Net::DNS::Resolver;
use Data::Dump qw/dump/;

use server;
our $debug = server::debug;

my $res = Net::DNS::Resolver->new(
#	nameserver => [ '10.60.0.1' ],
	recurse => 1,
	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);

	server->refresh;
	$debug = server::debug;

	print "$qname $qclass $qtype $peerhost to ". $conn->{"sockhost"}. "\n";
	$query->print if $debug;

	my $local = $1     if $qname =~ m{^(.+)\.\Q$server::domain_name\E$};
	   $local = $qname if $qname !~ m{\.};

	my $ttl = 3600;

	if ( $local ) {
		warn "local[$local] $qname $qtype";
		$rcode = "NOERROR";
		my $rdata;
		if ( $qtype eq "A" && $local eq "server" ) {
			$rdata = name_ip( $local, $server::ip );
		} 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");
			} else {
warn "## ",dump( $ptr_cache );
				$rcode = "NXDOMAIN";
			}
	} elsif ( my $packet = $res->query( $qname, $qtype ) ) {

		$packet->print;
		push @ans, $_ foreach $packet->answer;
		$rcode = "NOERROR";

	} else {
		# not found
		$rcode = "NXDOMAIN";
	}

	warn "rcode: $rcode ",dump( @ans );

	# mark the answer as authoritive (by setting the 'aa' flag
	return ($rcode, \@ans, \@auth, \@add, { aa => 1 });
}

sub start {
	my $ns = Net::DNS::Nameserver->new(
		LocalPort    => 53,
		ReplyHandler => \&reply_handler,
		Verbose      => $debug,
	) || die "couldn't create nameserver object\n";

	warn "DNS $server::domain_name";

	$ns->main_loop;
}

1; 
