[net-dns-users] IXFR methods
Wessels, Duane
dwessels at verisign.com
Tue Dec 18 21:42:56 UTC 2012
Chris,
Looks good, but I don't understand why you're discarding the DNSSEC types? Isn't it
possible that the caller would want those records?
DW
On Dec 18, 2012, at 12:22 PM, Chris Buxton wrote:
> Hello all,
>
> As Doug said, it's very nice to have a list.
>
> Has anyone else created an IXFR method for Net::DNS::Resolver? I have, and I think it's pretty good, but I think it could probably be improved.
>
> Here's my code -- requires perl 5.10 or later:
>
> # Hack IXFR capability into Net::DNS::Resolver
> sub Net::DNS::Resolver::Base::ixfr($$$)
> {
> my( $res, $zone, $serial ) = @_;
> local $_;
>
> # Send IXFR requests over TCP
> $res->usevc(1);
>
> # Construct the request. It contains an abbreviated SOA record in
> # the authority section, where the only fields that matter are name,
> # class, type, and old serial number.
> my $packet = new Net::DNS::Packet( $zone, 'IXFR' );
> my $soa = Net::DNS::RR->new(
> name => $zone,
> type => 'SOA',
> mname => '',
> rname => '',
> serial => $serial,
> refresh => 0,
> retry => 0,
> expire => 0,
> minimum => 0
> );
> $packet->push( authority => $soa );
>
> # Send the request and store the result in an array reference.
> my $result = $res->send( $packet );
>
> # The method here is, we're going to accumulate records into arrays
> # of @$items, and then put those into @$hunks like [ $mode, $items
> # ]. We then push each $hunk onto @diff. $mode will switch from '+'
> # to '-' and back again for each new @$hunk. Therefore:
> #
> # @diff = (
> # [ $mode, [ $rr, ... ] ],
> # ...
> # )
> #
> # Each @$hunk ends with an SOA record. Every time we encounter an
> # SOA record, we start a new hunk right afterward (with the next
> # record) and switch the $mode (the operator for each hunk).
> #
> # If you look carefully, you'll see that the very first SOA record
> # is inserted into an empty @$items, but this @$items array doesn't
> # get attached to @diff before being replaced with a fresh array. So
> # we're processing it to set the $mode, but we're otherwise throwing
> # it away.
> #
> # The last hunk (started after the final SOA record of the IXFR) has
> # no records. Always. So we remove it before returning @diff.
> # Therefore, an IXFR that requests changes since the current serial
> # will return an empty array; an AXFR-style IXFR will contain
> # exactly one hunk. To summarize:
> #
> # @diff == 1 # no changes since the presented serial number
> # @diff == 2 # AXFR-style IXFR
> # @diff > 2 # Normal IXFR containing changes
> #
> # Algorithm to interpret an IXFR courtesy of Mark Andrews @ISC, via
> # a quick and dirty awk script he posted to BIND Users.
>
> # Get ready to parse the result.
> my( @diff, $hunk, $items );
> my $mode = '-';
>
> for my $rr ( $result->answer )
> {
> given( $rr->type )
> {
> when( 'SOA' )
> {
> push @$items, $rr;
> $mode = ( $mode eq '-' ? '+' : '-' );
> $hunk = [ $mode, [] ];
> $items = $hunk->[1];
> push @diff, $hunk;
> }
> when( [ qw( RRSIG NSEC NSEC3 NSEC3PARAM ) ] )
> {
> # Strip out DNSSEC records like this, as we can't really
> # do anything useful with them
> }
> when( 'TSIG' )
> {
> # TODO: Add some error checking here
> # For now, strip these out also
> }
> default
> {
> # Anything else gets added to @$items
> push @$items, $rr;
> }
> }
> }
>
> # Discard the empty hunk from the end and return everything else
> pop @diff;
> return @diff;
> }
>
> Chris
> _______________________________________________
> net-dns-users mailing list
> net-dns-users at nlnetlabs.nl
> https://www.nlnetlabs.nl/mailman/listinfo/net-dns-users
More information about the net-dns-users
mailing list