Changeset 764


Ignore:
Timestamp:
06/13/17 18:37:39 (7 years ago)
Author:
Kris Deugau
Message:

/trunk

Extract a key, complex, core bit of ALIAS processing (grabbing the chained
A records for the target and collapsing them into a blob for storage/export)
from two places, and put it in a sub for better maintenance.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/DNSDB.pm

    r763 r764  
    13991399  my ($iplist) = $self->{dbh}->selectrow_array("SELECT auxdata FROM records WHERE record_id = ?", undef, $args{recid});
    14001400  my $warnmsg;
    1401 
    1402   my $res = Net::DNS::Resolver->new;
    1403   # Set short timeouts to minimize disruption.  If the target's DNS is slow the site will likely be broken anyway.
    1404   $res->tcp_timeout(2);
    1405   $res->udp_timeout(2);
    1406   my $reply = $res->query(${$args{val}});
    1407   my @newlist;
    1408   if ($reply) {
    1409     foreach my $rr ($reply->answer) {
    1410       next unless $rr->type eq "A";
    1411       push @newlist, $rr->address;
    1412     }
    1413   } else {
    1414     $warnmsg = "Failure retrieving IP list from DNS for cache validation/update on ALIAS '${$args{host}} -> ${$args{val}}': ".
    1415         $res->errorstring;
    1416   }
    1417 
    1418   # we don't need this to be perfectly correct IP address order, just consistent.
    1419   my $liveips = join(':', sort(@newlist));
     1401  $iplist = '' if !$iplist;
     1402
     1403  # shared target-name-to-IP converter
     1404  my $liveips = $self->_grab_65300($args{recid}, ${$args{val}});
     1405  $liveips = '' if !$liveips;
    14201406
    14211407  # check to see if there was an OOOOPS checking for updated A records on the target.  also make sure we have something cached.
     
    14241410      # not fatal since we do the lookup on export as well
    14251411      return ('WARN',
    1426         join("\n", $warnmsg, "No cached data and no live DNS data for ALIAS target ${$args{val}};  record may be SKIPPED on export!") );
    1427 #    } else {
    1428 #      return ('WARN', "No live DNS data for ALIAS target ${$args{val}};  falling back to cache");
     1412        join("\n", $errstr, "No cached data and no live DNS data for ALIAS target ${$args{val}};  record may be SKIPPED on export!") );
    14291413    }
    14301414  }
     
    14401424  return ('OK','OK');
    14411425} # done ALIAS record
     1426
     1427# this segment used multiple places to update ALIAS target details
     1428sub _grab_65300 {
     1429  my $self = shift;
     1430  my $dbh = $self->{dbh};
     1431
     1432  my $recid = shift;
     1433  my $target = shift;
     1434
     1435  my $res = Net::DNS::Resolver->new;
     1436  $res->tcp_timeout(2);
     1437  $res->udp_timeout(2);
     1438  my $reply = $res->query($target);
     1439
     1440  my $liveips;
     1441  if ($reply) {
     1442    # default to a one-hour TTL, which should be variously modified down the chain.  Arguably this could
     1443    # default even lower, since "The Cloud" often uses sub-1-minute TTLs on the final A records.
     1444    my $minttl = 3600;
     1445    my @newlist;
     1446    foreach my $rr ($reply->answer) {  #@alist) {
     1447      next unless $rr->type eq "A";
     1448      push @newlist, $rr->address;
     1449      $minttl = $rr->ttl if $rr->ttl < $minttl;
     1450    }
     1451    # safety limit.  could arguably take this lower, or for extra
     1452    # complexity, reference off the zone SOA minTTL
     1453    $minttl = 60 if $minttl < 60;
     1454    # we don't need this to be perfectly correct IP address order, just consistent.
     1455    $liveips = "$minttl:".join(':', sort(@newlist));
     1456  } else {
     1457    $errstr = "Lookup failure retrieving ALIAS IP list: ".$res->errorstring;
     1458  }
     1459
     1460  return $liveips;
     1461} # _grab_65300()
    14421462
    14431463
     
    67406760
    67416761    my ($iplist) = $self->{dbh}->selectrow_array("SELECT auxdata FROM records WHERE record_id = ?", undef, $recid);
    6742     my $res = Net::DNS::Resolver->new;
    6743     my $reply = $res->query($val);
    6744 
    6745     if ($reply) {
    6746       my $liveips;
    6747       my @newlist;
    6748       foreach my $rr ($reply->answer) {  #@alist) {
    6749         next unless $rr->type eq "A";
    6750         push @newlist, $rr->address;
    6751       }
    6752       # we don't need this to be perfectly correct IP address order, just consistent.
    6753       $liveips = join(':', sort(@newlist));
    6754       if ($iplist ne $liveips) {
    6755         # update the cache of IPs from the target
    6756         $self->{dbh}->do("UPDATE records SET auxdata = ? WHERE record_id = ?", undef, $liveips, $recid);
    6757         $iplist = $liveips;
    6758       }
    6759     } else {
    6760       warn "Failure retrieving IP list for cache validation/update on ALIAS '$host -> $val': ", $res->errorstring, "\n";
    6761     }
     6762
     6763    # shared target-name-to-IP converter
     6764    my $liveips = $self->_grab_65300($recid, $val);
     6765    if ($iplist ne $liveips) {
     6766      $self->{dbh}->do("UPDATE records SET auxdata = ? WHERE record_id = ?", undef, $liveips, $recid);
     6767      $iplist = $liveips;
     6768    }
     6769
     6770    # slice the TTL we'll actually publish off the front
     6771    my @asubs = split ':', $iplist;
     6772    my $attl = shift @asubs;
    67626773
    67636774    # output a plain old A record for each IP the target name really points to.
    6764     foreach my $subip (split ':', $iplist) {
    6765       print "+$host:$subip:$ttl:$stamp:$loc\n" or die $!;
     6775    # in the event that, for whatever reason, no A records are available for $val, nothing will be output.
     6776    foreach my $subip (@asubs) {
     6777      print $datafile "+$host:$subip:$attl:$stamp:$loc\n" or die $!;
    67666778    }
    67676779
Note: See TracChangeset for help on using the changeset viewer.