Changeset 752 for trunk/DNSDB.pm


Ignore:
Timestamp:
06/01/17 16:52:55 (7 years ago)
Author:
Kris Deugau
Message:

/trunk

Minor administrivia cleanups

Mostly finalize new ALIAS pseudotype. See #55.

  • Add validator
  • Tweak handling of ALIAS IP cache with new DB column
  • Fix an output typo that would have created broken record lines
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/DNSDB.pm

    r750 r752  
    33##
    44# $Id$
    5 # Copyright 2008-2016 Kris Deugau <kdeugau@deepnet.cx>
     5# Copyright 2008-2017 Kris Deugau <kdeugau@deepnet.cx>
    66#
    77#    This program is free software: you can redistribute it and/or modify
     
    13691369  }
    13701370  return ('OK','OK');
    1371 }
     1371} # done delegation record
     1372
     1373# ALIAS record
     1374# A specialized variant of the CNAME, which retrieves the A record list on each
     1375# export and publishes the A records instead.  Primarily for "root CNAME" or "apex
     1376# alias" records.  See https://secure.deepnet.cx/trac/dnsadmin/ticket/55.
     1377# Not allowed in reverse zones because this is already a hack, and reverse zones
     1378# don't get pointed to CNAMEed CDNs the way domains do.
     1379sub _validate_65300 {
     1380  my $self = shift;
     1381  my $dbh = $self->{dbh};
     1382
     1383  my %args = @_;
     1384
     1385  return ('FAIL',"ALIAS records are not permitted in reverse zones") if $args{revrec} eq 'y';
     1386
     1387  # Make sure target is a well-formed hostname
     1388  return ('FAIL', $errstr) if ! _check_hostname_form(${$args{val}}, ${$args{rectype}}, $args{defrec}, $args{revrec});
     1389
     1390  # Coerce all hostnames to end in ".DOMAIN" for group/default records,
     1391  # or the intended parent domain for live records.
     1392  my $pname = ($args{defrec} eq 'y' ? 'DOMAIN' : $self->domainName($args{id}));
     1393  ${$args{host}} =~ s/\.*$/\.$pname/ if (${$args{host}} ne '@' && ${$args{host}} !~ /$pname$/i); 
     1394
     1395  # don't do the cache thing on default records
     1396  return ('OK','OK') if $defrec ne 'n';
     1397
     1398  # now we check/update the cached target address info
     1399  my ($iplist) = $self->{dbh}->selectrow_array("SELECT auxdata FROM records WHERE record_id = ?", undef, $args{recid});
     1400  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}}': ".$res->errors$
     1415  }
     1416
     1417  # we don't need this to be perfectly correct IP address order, just consistent.
     1418  my $liveips = join(':', sort(@newlist));
     1419
     1420  # check to see if there was an OOOOPS checking for updated A records on the target.  also make sure we have something cached.
     1421  if (!$liveips) {
     1422    if (!$iplist) {
     1423      # not fatal since we do the lookup on export as well
     1424      return ('WARN',
     1425        join("\n", $warnmsg, "No cached data and no live DNS data for ALIAS target ${$args{val}};  record may be SKIPPED on export!") );
     1426#    } else {
     1427#      return ('WARN', "No live DNS data for ALIAS target ${$args{val}};  falling back to cache");
     1428    }
     1429  }
     1430
     1431  # munge the insert/update fieldlist and data array
     1432  if ($iplist ne $liveips) {
     1433    ${$args{fields}} .= "auxdata,";
     1434    push @{$args{vallist}}, $liveips;
     1435  }
     1436
     1437  return ('WARN', $warnmsg) if $warnmsg;
     1438 
     1439  return ('OK','OK');
     1440} # done ALIAS record
     1441
    13721442
    13731443# Subs not specific to a particular record type
     
    66646734    return if $revrec eq 'y';
    66656735
    6666     my ($target,$iplist) = split /:/, $val, 2;
     6736    my ($iplist) = $self->{dbh}->selectrow_array("SELECT auxdata FROM records WHERE record_id = ?", undef, $recid);
    66676737    my $res = Net::DNS::Resolver->new;
    6668     my $reply = $res->query($target);
    6669 
    6670     if ($reply) { 
     6738    my $reply = $res->query($val);
     6739
     6740    if ($reply) {
    66716741      my $liveips;
    66726742      my @newlist;
     
    66796749      if ($iplist ne $liveips) {
    66806750        # update the cache of IPs from the target
    6681         $self->{dbh}->do("UPDATE records SET val=? WHERE record_id=?", undef, "$target:$liveips", $recid);
     6751        $self->{dbh}->do("UPDATE records SET auxdata = ? WHERE record_id = ?", undef, $liveips, $recid);
    66826752        $iplist = $liveips;
    66836753      }
    66846754    } else {
    6685       warn "Failure retrieving IP list for cache validation/update on ALIAS '$host -> $target': ", $res->errorstring, "\n";
     6755      warn "Failure retrieving IP list for cache validation/update on ALIAS '$host -> $val': ", $res->errorstring, "\n";
    66866756    }
    66876757
    66886758    # output a plain old A record for each IP the target name really points to.
    66896759    foreach my $subip (split ':', $iplist) {
    6690       print "+$host:$subip:$ttl,$stamp,$loc\n" or die $!;
     6760      print "+$host:$subip:$ttl:$stamp:$loc\n" or die $!;
    66916761    }
    66926762
Note: See TracChangeset for help on using the changeset viewer.