Changeset 523


Ignore:
Timestamp:
06/12/13 17:17:57 (11 years ago)
Author:
Kris Deugau
Message:

/trunk

Swap forward and reverse zone export order to better handle dangling =
records created by tiny-import.pl's -l option. Exporting all reverse-zone
pseudotype records first will let us ignore most of them while exporting
forward zones, without skipping the dangling ones not associated with a
reverse zone.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/DNSDB.pm

    r521 r523  
    48834883  my %recflags;
    48844884
    4885   my $domsth = $dbh->prepare("SELECT domain_id,domain,status,changed FROM domains WHERE status=1");
    4886   my $recsth = $dbh->prepare("SELECT host,type,val,distance,weight,port,ttl,record_id,location ".
    4887         "FROM records WHERE domain_id=? AND type < 65280");     # Just exclude all types relating to rDNS
    4888   my $zonesth = $dbh->prepare("UPDATE domains SET changed='n' WHERE domain_id=?");
    4889   $domsth->execute();
    4890   while (my ($domid,$dom,$domstat,$changed) = $domsth->fetchrow_array) {
    4891 ##fixme: need to find a way to block opening symlinked files without introducing a race.
    4892 #       O_NOFOLLOW
    4893 #              If  pathname  is a symbolic link, then the open fails.  This is a FreeBSD extension, which was
    4894 #              added to Linux in version 2.1.126.  Symbolic links in earlier components of the pathname  will
    4895 #              still be followed.
    4896 # but that doesn't help other platforms.  :/
    4897     my $cachefile = "$self->{exportcache}/$dom";
    4898     my $tmpcache = "$self->{exportcache}/tmp.$dom.$$";
    4899     eval {
    4900 
    4901       # only update the cache file if the zone has changed, or if the cache file has nothing in it.
    4902       if ($changed || !-e $cachefile || -z $cachefile) {
    4903         open ZONECACHE, ">$tmpcache" or die "Error creating temporary file $tmpcache: $!\n";
    4904 
    4905         $recsth->execute($domid);
    4906         while (my ($host,$type,$val,$dist,$weight,$port,$ttl,$recid,$loc) = $recsth->fetchrow_array) {
    4907           next if $recflags{$recid};
    4908 
    4909           $loc = '' if !$loc;   # de-nullify - just in case
    4910 ##fixme:  handle case of record-with-location-that-doesn't-exist better.
    4911 # note this currently fails safe (tested) - records with a location that
    4912 # doesn't exist will not be sent to any client
    4913 #       $loc = '' if !$lochash->{$loc};
    4914 
    4915 ##fixme:  record validity timestamp. tinydns supports fiddling with timestamps.
    4916 # note $ttl must be set to 0 if we want to use tinydns's auto-expiring timestamps.
    4917 # timestamps are TAI64
    4918 # ~~ 2^62 + time()
    4919           my $stamp = '';
    4920 
    4921           # support tinydns' auto-TTL
    4922           $ttl = '' if $ttl == -1;
    4923 
    4924           # Spaces are evil.
    4925           $host =~ s/^\s+//;
    4926           $host =~ s/\s+$//;
    4927           if ($typemap{$type} ne 'TXT') {
    4928             # Leading or trailng spaces could be legit in TXT records.
    4929             $val =~ s/^\s+//;
    4930             $val =~ s/\s+$//;
    4931           }
    4932 
    4933           _printrec_tiny(*ZONECACHE, 'n', \%recflags,
    4934                 $dom, $host, $type, $val, $dist, $weight, $port, $ttl, $loc, $stamp)
    4935                 if *ZONECACHE;
    4936 
    4937           $recflags{$recid} = 1;
    4938 
    4939         } # while ($recsth)
    4940 
    4941         close ZONECACHE; # force the file to be written
    4942 
    4943         # catch obvious write errors that leave an empty temp file
    4944         if (-s $tmpcache) {
    4945           rename $tmpcache, $cachefile
    4946             or die "Error overwriting cache file $cachefile with temporary file: $!\n";
    4947         }
    4948 
    4949       } # if $changed or cache filesize is 0
    4950 
    4951     };
    4952     if ($@) {
    4953       print "error writing new data for $dom: $@\n";
    4954       # error!  something borked, and we should be able to fall back on the old cache file
    4955       # report the error, somehow.
    4956     } else {
    4957       # mark domain as unmodified.  Only do this if no errors, that way
    4958       # export failures should recover a little more automatically.
    4959       $zonesth->execute($domid);
    4960     }
    4961     # Always stream the cache (even if stale or obsolete due to errors creating the new cache)
    4962     open CACHE, "<$cachefile";
    4963     print $datafile $_ while <CACHE>;
    4964     close CACHE;
    4965 
    4966   } # while ($domsth)
    4967 
    49684885# For reasons unknown, we can't sanely UNION these statements.  Feh.
    49694886# Supposedly it should work though (note last 3 lines):
     
    49804897  my $soasth = $dbh->prepare("SELECT host,type,val,distance,weight,port,ttl,record_id,location ".
    49814898        "FROM records WHERE rdns_id=? AND type=6");
    4982   $recsth = $dbh->prepare("SELECT host,type,val,distance,weight,port,ttl,record_id,location ".
     4899  my $recsth = $dbh->prepare("SELECT host,type,val,distance,weight,port,ttl,record_id,location ".
    49834900        "FROM records WHERE rdns_id=? AND not type=6 ".
    49844901        "ORDER BY masklen(CAST(val AS inet)) DESC, CAST(val AS inet)");
    49854902  my $revsth = $dbh->prepare("SELECT rdns_id,revnet,status,changed FROM revzones WHERE status=1 ".
    49864903        "ORDER BY masklen(revnet) DESC");
    4987   $zonesth = $dbh->prepare("UPDATE revzones SET changed='n' WHERE rdns_id=?");
     4904  my $zonesth = $dbh->prepare("UPDATE revzones SET changed='n' WHERE rdns_id=?");
    49884905  $revsth->execute();
    49894906  while (my ($revid,$revzone,$revstat,$changed) = $revsth->fetchrow_array) {
     
    50584975      # export failures should recover a little more automatically.
    50594976      $zonesth->execute($revid);
     4977    }
     4978    # Always stream the cache (even if stale or obsolete due to errors creating the new cache)
     4979    open CACHE, "<$cachefile";
     4980    print $datafile $_ while <CACHE>;
     4981    close CACHE;
     4982
     4983  } # while ($revsth)
     4984
     4985  my $domsth = $dbh->prepare("SELECT domain_id,domain,status,changed FROM domains WHERE status=1");
     4986  $recsth = $dbh->prepare("SELECT host,type,val,distance,weight,port,ttl,record_id,location ".
     4987        "FROM records WHERE domain_id=?");      # Just exclude all types relating to rDNS
     4988#       "FROM records WHERE domain_id=? AND type < 65280");     # Just exclude all types relating to rDNS
     4989  $zonesth = $dbh->prepare("UPDATE domains SET changed='n' WHERE domain_id=?");
     4990  $domsth->execute();
     4991  while (my ($domid,$dom,$domstat,$changed) = $domsth->fetchrow_array) {
     4992##fixme: need to find a way to block opening symlinked files without introducing a race.
     4993#       O_NOFOLLOW
     4994#              If  pathname  is a symbolic link, then the open fails.  This is a FreeBSD extension, which was
     4995#              added to Linux in version 2.1.126.  Symbolic links in earlier components of the pathname  will
     4996#              still be followed.
     4997# but that doesn't help other platforms.  :/
     4998    my $cachefile = "$self->{exportcache}/$dom";
     4999    my $tmpcache = "$self->{exportcache}/tmp.$dom.$$";
     5000    eval {
     5001
     5002      # only update the cache file if the zone has changed, or if the cache file has nothing in it.
     5003      if ($changed || !-e $cachefile || -z $cachefile) {
     5004        open ZONECACHE, ">$tmpcache" or die "Error creating temporary file $tmpcache: $!\n";
     5005
     5006        $recsth->execute($domid);
     5007        while (my ($host,$type,$val,$dist,$weight,$port,$ttl,$recid,$loc) = $recsth->fetchrow_array) {
     5008          next if $recflags{$recid};
     5009
     5010          $loc = '' if !$loc;   # de-nullify - just in case
     5011##fixme:  handle case of record-with-location-that-doesn't-exist better.
     5012# note this currently fails safe (tested) - records with a location that
     5013# doesn't exist will not be sent to any client
     5014#       $loc = '' if !$lochash->{$loc};
     5015
     5016##fixme:  record validity timestamp. tinydns supports fiddling with timestamps.
     5017# note $ttl must be set to 0 if we want to use tinydns's auto-expiring timestamps.
     5018# timestamps are TAI64
     5019# ~~ 2^62 + time()
     5020          my $stamp = '';
     5021
     5022          # support tinydns' auto-TTL
     5023          $ttl = '' if $ttl == -1;
     5024
     5025          # Spaces are evil.
     5026          $host =~ s/^\s+//;
     5027          $host =~ s/\s+$//;
     5028          if ($typemap{$type} ne 'TXT') {
     5029            # Leading or trailng spaces could be legit in TXT records.
     5030            $val =~ s/^\s+//;
     5031            $val =~ s/\s+$//;
     5032          }
     5033
     5034          _printrec_tiny(*ZONECACHE, 'n', \%recflags,
     5035                $dom, $host, $type, $val, $dist, $weight, $port, $ttl, $loc, $stamp)
     5036                if *ZONECACHE;
     5037
     5038          $recflags{$recid} = 1;
     5039
     5040        } # while ($recsth)
     5041
     5042        close ZONECACHE; # force the file to be written
     5043
     5044        # catch obvious write errors that leave an empty temp file
     5045        if (-s $tmpcache) {
     5046          rename $tmpcache, $cachefile
     5047            or die "Error overwriting cache file $cachefile with temporary file: $!\n";
     5048        }
     5049
     5050      } # if $changed or cache filesize is 0
     5051
     5052    };
     5053    if ($@) {
     5054      print "error writing new data for $dom: $@\n";
     5055      # error!  something borked, and we should be able to fall back on the old cache file
     5056      # report the error, somehow.
     5057    } else {
     5058      # mark domain as unmodified.  Only do this if no errors, that way
     5059      # export failures should recover a little more automatically.
     5060      $zonesth->execute($domid);
    50605061    }
    50615062    # Always stream the cache (even if stale or obsolete due to errors creating the new cache)
Note: See TracChangeset for help on using the changeset viewer.