Below is a java program I wrote to model this stuff.  In the table, SF2 represents the number of clients that blew past twice the safety factor (for aR+aHD+aR), SF1 represents the number of clients that blew past the single safety factor.  OF is the number of clients using the activeRefreshOffset calculation that finished after the calculated interval (e.g. aR+aHD+aRO).  OF+s is the number of clients that finished after the activeRefreshOffset + safetyFactor (in the first table these are the same because of perfect responses).   In the second table, compare SF1 to OF+s - SF1 < OF+s suggesting that activeRefresh is a better choice that activeRefreshQuery for the third term of the equation.  You can try a lot of different combinations, but I haven't found any case where OF+s performs better that SF1.

The difference between lastStart and lAddHoldBegin represents the retransmits after the first query.  The differences between lAddHoldEnd and lFinalQuery represent retransmits after the last normal query before the end of the add hold down time until a valid answer was received after the addHoldDown time expired.

Feel free to twiddle with this.

In this table, almost 1/5th of each of the clients exceeds the activeRefreshOffset based calculation. Note that the safety factor doesn't come into play as this specifies a "0" query failure rate.
java Test5011
Original TTL? (enter dd:hh:mm:ss) 1:4:0:0
New TTL? (enter dd:hh:mm:ss) 1:4:0:0
RRSig expiration interval? (enter dd:hh:mm:ss) 7:0:0:0

Orig TTL: 100800 seconds
New TTL: 100800 seconds
RRSig interval: 604800 seconds
QueryInterval: 50400 seconds
FastQuery: 8640 seconds
AddHoldDown: 2592000 seconds
ActiveRefreshOffset: 21600 seconds
activeRefresh + addHoldDown + activeRefresh: 2692800

Number of trials(-1 to exit) 10
Number of clients(-1 to exit) 25000
Failure rate [0 to .99999](-1 to exit) 0
Calculated safety factor: 0 (0.000000)
aR + aHD + aR + sF: 2692800

Offset calc - aR + aHD + aRO: 2664000
Offset plus safety: 2664000

Trial  LastStart  lAddHoldBegin lAddHoldEnd  sOffset lFinalQuery SF2 SF1  OF  OF+s
-----------------------------------------------------------------------------------
0      50394      50394         2671194       28800 2671194    0    0    3459  3459 1      50399      50399         2671199       28800 2671199    0    0    3576  3576 2      50399      50399         2671199       28800 2671199    0    0    3540  3540 3      50399      50399         2671199       28800 2671199    0    0    3508  3508 4      50399      50399         2671199       28800 2671199    0    0    3610  3610 5      50399      50399         2671199       28800 2671199    0    0    3544  3544 6      50398      50398         2671198       28800 2671198    0    0    3546  3546 7      50399      50399         2671199       28800 2671199    0    0    3611  3611 8      50398      50398         2671198       28800 2671198    0    0    3579  3579 9      50398      50398         2671198       28800 2671198    0    0    3517  3517





$ !-2
java Test5011
Original TTL? (enter dd:hh:mm:ss) 1:0:0:0
New TTL? (enter dd:hh:mm:ss) 1:0:0:0
RRSig expiration interval? (enter dd:hh:mm:ss) 7:0:0:0

Orig TTL: 86400 seconds
New TTL: 86400 seconds
RRSig interval: 604800 seconds
QueryInterval: 43200 seconds
FastQuery: 8640 seconds
AddHoldDown: 2592000 seconds
ActiveRefreshOffset: 0 seconds
activeRefresh + addHoldDown + activeRefresh: 2678400

Number of trials(-1 to exit) 10
Number of clients(-1 to exit) 100000
Failure rate [0 to .99999](-1 to exit) .25
Calculated safety factor: 77760 (9.000000)
aR + aHD + aR + sF: 2756160

Offset calc - aR + aHD + aRO: 2635200
Offset plus safety: 2712960

Trial  LastStart  lAddHoldBegin lAddHoldEnd  sOffset lFinalQuery SF2 SF1  OF  OF+s
-----------------------------------------------------------------------------------
0      43199      108405        2769525       0 2769525    0    1    54772 31 1      43198      95039         2729831       0 2753326    0    0    55168 26 2      43199      111816        2725266       0 2740462    0    0    54697 44 3      43199      90159         2736412       0 2745052    0    0    54882 31 4      43199      100917        2727795       0 2729947    0    0    54869 33 5      43199      94115         2726425       0 2740485    0    0    54978 23 6      43199      117523        2735443       0 2743990    0    0    55306 27 7      43198      101417        2734743       0 2743383    0    0    55006 29 8      43199      94634         2728554       0 2747760    0    0    54943 36 9      43199      85218         2727853       0 2737153    0    0    55070 33



import java.io.*;
import java.security.SecureRandom;

public class Test5011 {


  static  BufferedReader in = new BufferedReader(new InputStreamReader (System.in));



  public static void main (String[] args)
    throws Exception {

    int ttl = getResponse("Original TTL");
    int newTTL = getResponse ("New TTL");
    int rrsigExpire = getResponse ("RRSig expiration interval");
    System.out.println();

    boolean useSafetyFactor = true;


    System.out.printf ("Orig TTL: %d seconds%nNew TTL: %d seconds%nRRSig interval: %d seconds%n", ttl, newTTL, rrsigExpire);

    int thirtyDays = convertToSeconds ("30:0:0:0");
    int oneDay = convertToSeconds ("1:0:0:0");

    int oneHour = convertToSeconds ("0:1:0:0");

    int queryInterval = Math.max (oneHour, Math.min (thirtyDays/2, Math.min (ttl/2, rrsigExpire/2)));

    int fastQuery = Math.max (oneHour, Math.min (oneDay/10, Math.min (ttl/10, rrsigExpire/10)));
    int addHoldDown = Math.max (thirtyDays, newTTL);
    System.out.printf ("QueryInterval: %d seconds%nFastQuery: %d seconds%nAddHoldDown: %d seconds%n",
               queryInterval, fastQuery, addHoldDown);
    int activeRefreshOffset = addHoldDown % queryInterval;
    System.out.printf ("ActiveRefreshOffset: %d seconds%n", activeRefreshOffset);     System.out.printf ("activeRefresh + addHoldDown + activeRefresh: %d%n%n",
               2*queryInterval + addHoldDown);

    int numberOfTrials = getInt ("Number of trials");
    int numberOfClients = getInt ("Number of clients");
    double queryFailureRate = getDouble ("Failure rate [0 to .99999]");

    double safetyFactorMultiple = Math.ceil((Math.log (numberOfClients)/Math.log(1.0/(queryFailureRate))));
    int origSafetyFactor = fastQuery * (int)safetyFactorMultiple;
    int safetyFactor = 2* fastQuery * (int)safetyFactorMultiple;
    int totalSafeInterval = safetyFactor + 2* queryInterval + addHoldDown;
    int totalOrigSafeInterval = origSafetyFactor + 2*queryInterval + addHoldDown;
    int offsetInterval = queryInterval + addHoldDown + activeRefreshOffset;
    int offsetSafeInterval = offsetInterval + origSafetyFactor;
    System.out.printf ("Calculated safety factor: %d (%.6f)%n", origSafetyFactor, safetyFactorMultiple);     System.out.printf ("aR + aHD + aR + sF: %d%n%n", totalOrigSafeInterval);     System.out.printf ("Offset calc - aR + aHD + aRO: %d%n", offsetInterval);
    System.out.printf ("Offset plus safety: %d%n%n", offsetSafeInterval);

    SecureRandom rnd = new SecureRandom();

    System.out.printf ("Trial  LastStart  lAddHoldBegin lAddHoldEnd  sOffset  lFinalQuery SF2 SF1  OF  OF+s%n"+
"-----------------------------------------------------------------------------------%n");
    for (int j = 0; j < numberOfTrials; j++) {
    int latestStartOffset = 0;
    int latestAddHoldBegin = 0;
    int latestAddHoldEnd = 0;
    int latestFinalQuery = 0;
    int smallestOffsetAtEndOfAddHold = queryInterval;
    int numExceededSafety = 0;
    int numExceedOrigSafety = 0;
    int numExceedOffset = 0;
    int numExceedOffsetSafe = 0;


    for (int i = 0; i < numberOfClients; i++) {
    // each trial
      int startOffset = rnd.nextInt(queryInterval);
      latestStartOffset = (startOffset > latestStartOffset) ? startOffset : latestStartOffset;

      /* Roll the dice after each query and if we roll a number < the query failure rate, queue up a fast query and retry */

      while (rnd.nextDouble () < queryFailureRate) {
    startOffset += fastQuery;
      }

      latestAddHoldBegin = (startOffset > latestAddHoldBegin) ? startOffset : latestAddHoldBegin;


      // At beginning of add hold down period
      int trialAddHoldDown = 0;
      do {
    startOffset += queryInterval;
    trialAddHoldDown += queryInterval;
    // and retransmits
    while  (rnd.nextDouble () < queryFailureRate) {
      startOffset += fastQuery;
      trialAddHoldDown += fastQuery;
    }


      } while (trialAddHoldDown  < addHoldDown);
      latestAddHoldEnd = (startOffset > latestAddHoldEnd) ? startOffset : latestAddHoldEnd;
      int holddiff = trialAddHoldDown - addHoldDown;
      smallestOffsetAtEndOfAddHold = (holddiff < smallestOffsetAtEndOfAddHold) ?
    holddiff : smallestOffsetAtEndOfAddHold;


      // past the end of the addHoldDown, the previous last query above

      while (rnd.nextDouble () < queryFailureRate) {
    startOffset += fastQuery;
      }

      latestFinalQuery = (startOffset > latestFinalQuery) ? startOffset : latestFinalQuery;
      if (startOffset > totalSafeInterval)
    numExceededSafety++;
      if (startOffset >totalOrigSafeInterval)
    numExceedOrigSafety++;
      if (startOffset > offsetInterval)
    numExceedOffset++;
      if (startOffset > offsetSafeInterval)
    numExceedOffsetSafe++;

    }
    //System.out.printf ("Clients: %d%nLatestStartOffset %d%nLatestAddHoldBegin: %d%nLatestAddHoldEnd: %d%nSmallest Offset: %d%nLatestFinalQuery %d%n%n",

    System.out.printf ("%-7d%-11d%-14d%-14d%-9d%-11d%-5d%-5d%-5d %-5d%n",
               j,latestStartOffset, latestAddHoldBegin,
                latestAddHoldEnd, smallestOffsetAtEndOfAddHold,
               latestFinalQuery, numExceededSafety,numExceedOrigSafety,numExceedOffset, numExceedOffsetSafe);
    }



  }

   public static double getDouble (String prompt)
    throws Exception {
    do {
      System.out.printf ("%s(-1 to exit) ", prompt);
      String resp = in.readLine();
      try {
    double val = Double.valueOf(resp);
    if (val < 0.0 || val >= 1.0)
      throw new NumberFormatException ("Number out of range");
    return val;
      } catch (NumberFormatException ex) {
    System.out.println (ex.getMessage());
      }
    } while (true);
  }


  public static int getInt (String prompt)
    throws Exception {
    do {
      System.out.printf ("%s(-1 to exit) ", prompt);
      String resp = in.readLine();
      try {
    int val = Integer.valueOf(resp);
    if (val < 0)
      System.exit(1);
    return val;
      } catch (NumberFormatException ex) {
    System.out.println (ex.getMessage());
      }
    } while (true);
  }

  // return interval in seconds
  public static int getResponse(String prompt)
    throws Exception{


    do {
      System.out.printf ("%s? (enter dd:hh:mm:ss) ", prompt);
      String resp = in.readLine();
      try {
    return convertToSeconds(resp);
      } catch (NumberFormatException ex) {
    System.out.println (ex.getMessage());
      }

    } while (true);
  }

  public static int convertToSeconds (String val)
    throws NumberFormatException {
    String[] comps = val.split(":");
    if (comps.length != 4) {
      throw new NumberFormatException ("Wrong number of components");
    }
    int[] conv = new int[4];

    for (int i = 0; i < 4; i++) {

      conv[i]  = Integer.valueOf(comps[i]);
      if (conv[i] < 0)
    throw new NumberFormatException("Less than zero");
    }


    if (conv[1] > 23 || conv[2] > 60 || conv[3] > 60) {
    throw new NumberFormatException ("Bad format - out of range for one or more elements");

    }
    return conv[3] + conv[2] * 60 + conv[1] * 3600 + conv[0] * 86400;

  }
}


_______________________________________________
DNSOP mailing list
DNSOP@ietf.org
https://www.ietf.org/mailman/listinfo/dnsop

Reply via email to