Changeset 566
- Timestamp:
- 12/19/13 18:08:22 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/DNSDB.pm
r565 r566 4943 4943 4944 4944 if ($target eq 'tiny') { 4945 $self->__export_tiny(@_);4945 return $self->__export_tiny(@_); 4946 4946 } 4947 4947 # elsif ($target eq 'foo') { … … 4967 4967 ##fixme: fail if $datafile isn't an open, writable file 4968 4968 4969 # Error check - does the cache dir exist, if we're using one? 4970 if ($self->{usecache}) { 4971 die "Cache directory does not exist\n" if !-e $self->{exportcache}; 4972 die "$self->{exportcache} is not a directory\n" if !-d $self->{exportcache}; 4973 die "$self->{exportcache} must be both readable and writable\n" 4974 if !-r $self->{exportcache} || !-w $self->{exportcache}; 4975 } 4976 4969 4977 # easy case - export all evarything 4970 4978 # not-so-easy case - export item(s) specified … … 4974 4982 # of remaining data, allows up to 255 raw bytes 4975 4983 4976 # Locations/views - worth including in the caching setup? 4977 my $lochash = $dbh->selectall_hashref("SELECT location,iplist FROM locations", 'location'); 4978 foreach my $location (keys %$lochash) { 4979 foreach my $ipprefix (split /[,\s]+/, $lochash->{$location}{iplist}) { 4980 $ipprefix =~ s/\s+//g; 4981 $ipprefix = new NetAddr::IP $ipprefix; 4984 # note: the only I/O failures we seem to be able to actually catch 4985 # here are "closed filehandle" errors. we're probably not writing 4986 # enough data at this point to properly trigger an "out of space" 4987 # error. :/ 4988 eval { 4989 use warnings FATAL => ('io'); 4990 # Locations/views - worth including in the caching setup? 4991 my $lochash = $dbh->selectall_hashref("SELECT location,iplist FROM locations", 'location'); 4992 foreach my $location (keys %$lochash) { 4993 foreach my $ipprefix (split /[,\s]+/, $lochash->{$location}{iplist}) { 4994 $ipprefix =~ s/\s+//g; 4995 $ipprefix = new NetAddr::IP $ipprefix; 4982 4996 ##fixme: how to handle IPv6? 4983 4997 next if $ipprefix->{isv6}; 4984 # have to account for /nn CIDR entries. tinydns only speaks octet-sliced prefix. 4985 if ($ipprefix->masklen <= 8) { 4986 foreach ($ipprefix->split(8)) { 4987 my $tmp = $_->addr; 4988 $tmp =~ s/\.\d+\.\d+\.\d+$//; 4989 print $datafile "%$location:$tmp\n"; 4990 } 4991 } elsif ($ipprefix->masklen <= 16) { 4992 foreach ($ipprefix->split(16)) { 4993 my $tmp = $_->addr; 4994 $tmp =~ s/\.\d+\.\d+$//; 4995 print $datafile "%$location:$tmp\n"; 4996 } 4997 } elsif ($ipprefix->masklen <= 24) { 4998 foreach ($ipprefix->split(24)) { 4999 my $tmp = $_->addr; 5000 $tmp =~ s/\.\d+$//; 5001 print $datafile "%$location:$tmp\n"; 5002 } 5003 } else { 5004 foreach ($ipprefix->split(32)) { 5005 print $datafile "%$location:".$_->addr."\n"; 4998 # have to account for /nn CIDR entries. tinydns only speaks octet-sliced prefix. 4999 if ($ipprefix->masklen <= 8) { 5000 foreach ($ipprefix->split(8)) { 5001 my $tmp = $_->addr; 5002 $tmp =~ s/\.\d+\.\d+\.\d+$//; 5003 print $datafile "%$location:$tmp\n"; 5004 } 5005 } elsif ($ipprefix->masklen <= 16) { 5006 foreach ($ipprefix->split(16)) { 5007 my $tmp = $_->addr; 5008 $tmp =~ s/\.\d+\.\d+$//; 5009 print $datafile "%$location:$tmp\n"; 5010 } 5011 } elsif ($ipprefix->masklen <= 24) { 5012 foreach ($ipprefix->split(24)) { 5013 my $tmp = $_->addr; 5014 $tmp =~ s/\.\d+$//; 5015 print $datafile "%$location:$tmp\n"; 5016 } 5017 } else { 5018 foreach ($ipprefix->split(32)) { 5019 print $datafile "%$location:".$_->addr."\n"; 5020 } 5006 5021 } 5007 5022 } 5008 } 5009 print $datafile "%$location\n" if !$lochash->{$location}{iplist}; 5023 print $datafile "%$location\n" if !$lochash->{$location}{iplist}; 5024 } 5025 }; 5026 if ($@) { 5027 die "Error writing locations to master file: $@, $!\n"; 5010 5028 } 5011 5029 … … 5031 5049 "ORDER BY masklen(CAST(val AS inet)) DESC, CAST(val AS inet)"); 5032 5050 my $revsth = $dbh->prepare("SELECT rdns_id,revnet,status,changed FROM revzones WHERE status=1 ". 5033 "ORDER BY masklen(revnet) DESC ");5051 "ORDER BY masklen(revnet) DESC, rdns_id"); 5034 5052 my $zonesth = $dbh->prepare("UPDATE revzones SET changed='n' WHERE rdns_id=?"); 5035 5053 $revsth->execute(); … … 5101 5119 }; 5102 5120 if ($@) { 5103 print "error writing new data for$revzone: $@\n";5121 die "error writing ".($self->{usecache} ? 'new data for ' : '')."$revzone: $@\n"; 5104 5122 # error! something borked, and we should be able to fall back on the old cache file 5105 5123 # report the error, somehow. … … 5113 5131 # We've already made as sure as we can that a cached zone file is "good", 5114 5132 # although possibly stale/obsolete due to errors creating a new one. 5115 open CACHE, "<$cachefile"; 5116 print $datafile $_ while <CACHE>; 5117 close CACHE; 5133 eval { 5134 open CACHE, "<$cachefile" or die $!; 5135 print $datafile $_ or die "error copying cached $revzone to master file: $!" while <CACHE>; 5136 close CACHE; 5137 }; 5138 die $@ if $@; 5118 5139 } 5119 5140 5120 5141 } # while ($revsth) 5121 5142 5122 my $domsth = $dbh->prepare("SELECT domain_id,domain,status,changed FROM domains WHERE status=1 ");5143 my $domsth = $dbh->prepare("SELECT domain_id,domain,status,changed FROM domains WHERE status=1 ORDER BY domain_id"); 5123 5144 $recsth = $dbh->prepare("SELECT host,type,val,distance,weight,port,ttl,record_id,location,extract(epoch from stamp),expires,stampactive ". 5124 5145 "FROM records WHERE domain_id=?"); # Just exclude all types relating to rDNS … … 5183 5204 }; 5184 5205 if ($@) { 5185 print "error writing new data for$dom: $@\n";5206 die "error writing ".($self->{usecache} ? 'new data for ' : '')."$dom: $@\n"; 5186 5207 # error! something borked, and we should be able to fall back on the old cache file 5187 5208 # report the error, somehow. … … 5195 5216 # We've already made as sure as we can that a cached zone file is "good", 5196 5217 # although possibly stale/obsolete due to errors creating a new one. 5197 open CACHE, "<$cachefile"; 5198 print $datafile $_ while <CACHE>; 5199 close CACHE; 5218 eval { 5219 open CACHE, "<$cachefile" or die $!; 5220 print $datafile $_ or die "error copying cached $dom to master file: $!" while <CACHE>; 5221 close CACHE; 5222 }; 5223 die $@ if $@; 5200 5224 } 5201 5225 5202 5226 } # while ($domsth) 5203 5227 5228 return 1; 5204 5229 } # end __export_tiny() 5205 5230 … … 5319 5344 _template4_expand(\$rec, $ip); 5320 5345 print $fh ($ptronly ? "^"._ZONE($_, 'ZONE.in-addr.arpa', 'r', '.').":$rec" : "=$rec:$ip"). 5321 ":$ttl:$stamp:$loc\n" ;5346 ":$ttl:$stamp:$loc\n" or die $!; 5322 5347 } 5323 5348 } … … 5341 5366 foreach my $szone ($zone->split($zone->masklen + (8 - $zone->masklen % 8))) { 5342 5367 $szone = _ZONE($szone, 'ZONE.in-addr.arpa', 'r', '.'); 5343 print $datafile "Z$szone:$primary:$email"."::$refresh:$retry:$expire:$min_ttl:$ttl:$stamp:$loc\n"; 5368 print $datafile "Z$szone:$primary:$email"."::$refresh:$retry:$expire:$min_ttl:$ttl:$stamp:$loc\n" 5369 or die $!; 5344 5370 } 5345 5371 return; # skips "default" bits just below … … 5347 5373 $zone = _ZONE($zone, 'ZONE', 'r', '.').($zone->{isv6} ? '.ip6.arpa' : '.in-addr.arpa'); 5348 5374 } 5349 print $datafile "Z$zone:$primary:$email"."::$refresh:$retry:$expire:$min_ttl:$ttl:$stamp:$loc\n"; 5375 print $datafile "Z$zone:$primary:$email"."::$refresh:$retry:$expire:$min_ttl:$ttl:$stamp:$loc\n" 5376 or die $!; 5350 5377 5351 5378 } elsif ($typemap{$type} eq 'A') { 5352 5379 5353 print $datafile "+$host:$val:$ttl:$stamp:$loc\n" ;5380 print $datafile "+$host:$val:$ttl:$stamp:$loc\n" or die $!; 5354 5381 5355 5382 } elsif ($typemap{$type} eq 'NS') { … … 5362 5389 my $szone2 = _ZONE($szone, 'ZONE.in-addr.arpa', 'r', '.'); 5363 5390 next if $$recflags{$szone2} && $$recflags{$szone2} > $val->masklen; 5364 print $datafile "\&$szone2"."::$host:$ttl:$stamp:$loc\n" ;5391 print $datafile "\&$szone2"."::$host:$ttl:$stamp:$loc\n" or die $!; 5365 5392 $$recflags{$szone2} = $val->masklen; 5366 5393 } … … 5369 5396 my $szone2 = _ZONE($szone, 'ZONE.ip6.arpa', 'r', '.'); 5370 5397 next if $$recflags{$szone2} && $$recflags{$szone2} > $val->masklen; 5371 print $datafile "\&$szone2"."::$host:$ttl:$stamp:$loc\n" ;5398 print $datafile "\&$szone2"."::$host:$ttl:$stamp:$loc\n" or die $!; 5372 5399 $$recflags{$szone2} = $val->masklen; 5373 5400 } 5374 5401 } else { 5375 5402 my $val2 = _ZONE($val, 'ZONE', 'r', '.').($val->{isv6} ? '.ip6.arpa' : '.in-addr.arpa'); 5376 print $datafile "\&$val2"."::$host:$ttl:$stamp:$loc\n" ;5403 print $datafile "\&$val2"."::$host:$ttl:$stamp:$loc\n" or die $!; 5377 5404 $$recflags{$val2} = $val->masklen; 5378 5405 } 5379 5406 } else { 5380 print $datafile "\&$host"."::$val:$ttl:$stamp:$loc\n" ;5407 print $datafile "\&$host"."::$val:$ttl:$stamp:$loc\n" or die $!; 5381 5408 } 5382 5409 5383 5410 } elsif ($typemap{$type} eq 'AAAA') { 5384 5411 5385 print $datafile ":$host:28:";5412 # print $datafile ":$host:28:"; 5386 5413 my $altgrp = 0; 5387 5414 my @altconv; … … 5396 5423 } 5397 5424 } 5425 my $prefix = ":$host:28:"; 5398 5426 foreach my $octet (@altconv) { 5399 5427 # if not 's', output 5400 print $datafile$octet unless $octet =~ /^s$/;5428 $prefix .= $octet unless $octet =~ /^s$/; 5401 5429 # if 's', output (9-array length)x literal '\000\000' 5402 print $datafile'\000\000'x(9-$altgrp) if $octet =~ /^s$/;5430 $prefix .= '\000\000'x(9-$altgrp) if $octet =~ /^s$/; 5403 5431 } 5404 print $datafile " :$ttl:$stamp:$loc\n";5432 print $datafile "$prefix:$ttl:$stamp:$loc\n" or die $!; 5405 5433 5406 5434 } elsif ($typemap{$type} eq 'MX') { 5407 5435 5408 print $datafile "\@$host"."::$val:$dist:$ttl:$stamp:$loc\n"; 5436 ##fixme: what if we get an MX AXFRed into a reverse zone? 5437 print $datafile "\@$host"."::$val:$dist:$ttl:$stamp:$loc\n" or die $!; 5409 5438 5410 5439 } elsif ($typemap{$type} eq 'TXT') { … … 5413 5442 if ($revrec eq 'n') { 5414 5443 $val =~ s/:/\\072/g; # may need to replace other symbols 5415 print $datafile "'$host:$val:$ttl:$stamp:$loc\n" ;5444 print $datafile "'$host:$val:$ttl:$stamp:$loc\n" or die $!; 5416 5445 } else { 5417 5446 $host =~ s/:/\\072/g; # may need to replace other symbols 5418 5447 my $val2 = NetAddr::IP->new($val); 5419 5448 print $datafile "'"._ZONE($val2, 'ZONE', 'r', '.').($val2->{isv6} ? '.ip6.arpa' : '.in-addr.arpa'). 5420 ":$host:$ttl:$stamp:$loc\n" ;5449 ":$host:$ttl:$stamp:$loc\n" or die $!; 5421 5450 } 5422 5451 … … 5441 5470 5442 5471 if ($revrec eq 'n') { 5443 print $datafile "C$host:$val:$ttl:$stamp:$loc\n" ;5472 print $datafile "C$host:$val:$ttl:$stamp:$loc\n" or die $!; 5444 5473 } else { 5445 5474 my $val2 = NetAddr::IP->new($val); 5446 5475 print $datafile "C"._ZONE($val2, 'ZONE', 'r', '.').($val2->{isv6} ? '.ip6.arpa' : '.in-addr.arpa'). 5447 ":$host:$ttl:$stamp:$loc\n" ;5476 ":$host:$ttl:$stamp:$loc\n" or die $!; 5448 5477 } 5449 5478 … … 5453 5482 # followed by length/string data 5454 5483 5455 print $datafile ":$host:33:".octalize($dist,'d').octalize($weight,'d').octalize($port,'d') ;5484 print $datafile ":$host:33:".octalize($dist,'d').octalize($weight,'d').octalize($port,'d') or die $!; 5456 5485 5457 5486 $val .= '.' if $val !~ /\.$/; 5458 5487 foreach (split /\./, $val) { 5459 printf $datafile "\\%0.3o%s", length($_), $_ ;5488 printf $datafile "\\%0.3o%s", length($_), $_ or die $!; 5460 5489 } 5461 print $datafile "\\000:$ttl:$stamp:$loc\n" ;5490 print $datafile "\\000:$ttl:$stamp:$loc\n" or die $!; 5462 5491 5463 5492 } elsif ($typemap{$type} eq 'RP') { … … 5466 5495 # The first is supposed to be an email address with @ replaced by . (as with the SOA contact) 5467 5496 # The second is the "hostname" of a TXT record with more info. 5468 print $datafile":$host:17:";5497 my $prefix = ":$host:17:"; 5469 5498 my ($who,$what) = split /\s/, $val; 5470 5499 foreach (split /\./, $who) { 5471 printf $datafile"\\%0.3o%s", length($_), $_;5500 $prefix .= sprintf "\\%0.3o%s", length($_), $_; 5472 5501 } 5473 print $datafile'\000';5502 $prefix .= '\000'; 5474 5503 foreach (split /\./, $what) { 5475 printf $datafile"\\%0.3o%s", length($_), $_;5504 $prefix .= sprintf "\\%0.3o%s", length($_), $_; 5476 5505 } 5477 print $datafile " \\000:$ttl:$stamp:$loc\n";5506 print $datafile "$prefix\\000:$ttl:$stamp:$loc\n" or die $!; 5478 5507 5479 5508 } elsif ($typemap{$type} eq 'PTR') { … … 5484 5513 ($val) = ($val =~ /\.(\d+)$/); 5485 5514 print $datafile "^$val."._ZONE($zone, 'ZONE', 'r', '.').'.in-addr.arpa'. 5486 ":$host:ttl:$stamp:$loc\n" ;5515 ":$host:ttl:$stamp:$loc\n" or die $!; 5487 5516 } else { 5488 5517 $val = NetAddr::IP->new($val); 5489 5518 print $datafile "^". 5490 5519 _ZONE($val, 'ZONE', 'r', '.').($val->{isv6} ? '.ip6.arpa' : '.in-addr.arpa'). 5491 ":$host:$ttl:$stamp:$loc\n" ;5520 ":$host:$ttl:$stamp:$loc\n" or die $!; 5492 5521 } 5493 5522 … … 5495 5524 5496 5525 $$recflags{$val}++; 5497 print $datafile "=$host:$val:$ttl:$stamp:$loc\n" ;5526 print $datafile "=$host:$val:$ttl:$stamp:$loc\n" or die $!; 5498 5527 5499 5528 } elsif ($type == 65281) { # AAAA+PTR … … 5561 5590 my ($oct) = ($_->addr =~ /(\d+)$/); 5562 5591 print $datafile "C"._ZONE($_, 'ZONE.in-addr.arpa', 'r', '.').":$oct.". 5563 _ZONE($dblock, 'ZONE.in-addr.arpa', 'r', '.').":$ttl:$stamp:$loc\n" ;5592 _ZONE($dblock, 'ZONE.in-addr.arpa', 'r', '.').":$ttl:$stamp:$loc\n" or die $!; 5564 5593 $$recflags{"$_"}++; 5565 5594 } … … 5579 5608 $fp =~ s/^..//; 5580 5609 } 5581 print $datafile "$rec:$ttl:$stamp:$loc\n" ;5610 print $datafile "$rec:$ttl:$stamp:$loc\n" or die $!; 5582 5611 5583 5612 } else {
Note:
See TracChangeset
for help on using the changeset viewer.