Ignore:
Timestamp:
01/14/26 17:37:37 (12 days ago)
Author:
Kris Deugau
Message:

/branches/cname-collision

Account for future valid-after records when checking CNAME collisions.
See #72

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/cname-collision/DNSDB.pm

    r981 r983  
    662662      }
    663663    }
    664   }
    665 
    666 #  } else {
    667 #    # Non-CNAME records will only collide with CNAMEs
    668 #    my @t = $dbh->selectrow_array("SELECT count(*) FROM "._rectable($args{defrec}, $args{revrec}).
    669 #       " WHERE "._recparent($args{defrec}, $args{revrec})." = ? AND type = 5 AND $hfield = ?",
    670 #       undef, $args{id}, $hcheck);
    671 #    return ('FAIL', "There is already a CNAME present for $hcheck.  Only one CNAME may be present for a given name.")
    672 #       if $t[0] > 1;
    673 #  }
     664
     665    # Check timestamps of pending active-after records.  Coerce expires-at fields to soonest match if found.
     666    if ($args{defrec} eq 'n') {
     667      $sql = "SELECT extract(epoch from stamp) FROM "._rectable($args{defrec}, $args{revrec}).
     668       " WHERE "._recparent($args{defrec}, $args{revrec})." = ? AND type $tcompare 5 AND $hfield = ?".
     669       " AND stampactive = 't' AND expires = 'f' AND stamp >= now() ";
     670      my @lookupargs = ($args{id}, $hcheck);
     671      if ($args{update}) {
     672        $sql .= "AND record_id <> ? ";
     673        push @lookupargs, $args{update};
     674      }
     675      $sql .= "ORDER BY stamp LIMIT 1";
     676      my @t = $dbh->selectrow_array($sql, undef, @lookupargs);
     677      if (@t) {
     678        # existing record with valid-after stamp is present
     679        if (${$args{stamp}}) {
     680          # caller requested an expiry time
     681          if (${$args{expires}} eq 'f') {
     682            # valid-after can't be used together with expires-at, so we can't coerce
     683            # the new record to expire as well as keeping valid-after
     684            return ('FAIL', "Cannot add CNAME, another record with a later valid-after time already exists");
     685          }
     686          my $reqstamp = str2time(${$args{stamp}});
     687          if ($reqstamp < $t[0]) {
     688            # do nothing, new record will expire before the one we found
     689          } else {
     690            # coerce the expiry timestamp
     691            ${$args{stamp}} = strftime('Y-%m-%d %H:%M:%S', localtime($t[0]));
     692            return ('WARN', "CNAME added with modified expiry time;  conflicting valid-after record found");
     693          }
     694        } else {
     695          # no expiry requested, but we found a valid-after, so coerce the new record down to expiring at that time
     696          ${$args{stamp}} = strftime('%Y-%m-%d %H:%M:%S', localtime($t[0]));
     697          ${$args{expires}} = 't';
     698          return ('WARN', "CNAME added with expiry time;  conflicting valid-after record found");
     699        }
     700      }
     701    } # args{defrecs} eq 'n'
     702  } # each $tcompare
     703
    674704  return ('OK', 'OK');
    675 
    676705} # _cname_collision()
    677706
Note: See TracChangeset for help on using the changeset viewer.