mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2024-05-11 05:55:12 +00:00
BIND: Simplify serial number generation (#652)
* The old algorithm was very complex for no good reason. * The new algorithm is simply: Use yymmdd00 or (previous serial number +1) whichever is bigger.
This commit is contained in:
@ -3,7 +3,6 @@ package bind
|
||||
import (
|
||||
"log"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -20,36 +19,20 @@ func generateSerial(oldSerial uint32) uint32 {
|
||||
// At no time will a serial number == 0 be returned.
|
||||
|
||||
original := oldSerial
|
||||
oldSerialStr := strconv.FormatUint(uint64(oldSerial), 10)
|
||||
var newSerial uint32
|
||||
|
||||
// Make draft new serial number:
|
||||
today := nowFunc().UTC()
|
||||
todayStr := today.Format("20060102")
|
||||
version := uint32(1)
|
||||
todayNum, err := strconv.ParseUint(todayStr, 10, 32)
|
||||
if err != nil {
|
||||
log.Fatalf("new serial won't fit in 32 bits: %v", err)
|
||||
}
|
||||
draft := uint32(todayNum)*100 + version
|
||||
draft := uint32(todayNum * 100)
|
||||
|
||||
method := "none" // Used only in debugging.
|
||||
if oldSerial > draft {
|
||||
// If old_serial was really slow, upgrade to new yyyymmddvv standard:
|
||||
method = "o>d"
|
||||
newSerial = oldSerial + 1
|
||||
newSerial = oldSerial + 1
|
||||
} else if oldSerial == draft {
|
||||
// Edge case: increment old serial:
|
||||
method = "o=d"
|
||||
newSerial = draft + 1
|
||||
} else if len(oldSerialStr) != 10 {
|
||||
// If old_serial is wrong number of digits, upgrade to yyyymmddvv standard:
|
||||
method = "len!=10"
|
||||
newSerial = draft
|
||||
} else if strings.HasPrefix(oldSerialStr, todayStr) {
|
||||
// If old_serial just needs to be incremented:
|
||||
method = "prefix"
|
||||
if oldSerial >= draft {
|
||||
method = "o>=d"
|
||||
newSerial = oldSerial + 1
|
||||
} else {
|
||||
// First serial number to be requested today:
|
||||
|
@ -14,28 +14,31 @@ func Test_generate_serial_1(t *testing.T) {
|
||||
Today time.Time
|
||||
Expected uint32
|
||||
}{
|
||||
{0, d1, 2015010801},
|
||||
{123, d1, 2015010801},
|
||||
{0, d1, 2015010800},
|
||||
{1, d1, 2015010800},
|
||||
{123, d1, 2015010800},
|
||||
{2015010800, d1, 2015010801},
|
||||
{2015010801, d1, 2015010802},
|
||||
{2015010802, d1, 2015010803},
|
||||
{2015010898, d1, 2015010899},
|
||||
{2015010899, d1, 2015010900},
|
||||
{2015090401, d1, 2015090402},
|
||||
{201509040, d1, 2015010801},
|
||||
{20150904, d1, 2015010801},
|
||||
{2015090, d1, 2015010801},
|
||||
{201509040, d1, 2015010800},
|
||||
{20150904, d1, 2015010800},
|
||||
{2015090, d1, 2015010800},
|
||||
// If the number is very large, just increment:
|
||||
{2099000000, d1, 2099000001},
|
||||
// Verify 32-bits is enough to carry us 200 years in the future:
|
||||
{4015090401, d4, 4015090402},
|
||||
// Verify Dec 31 edge-case:
|
||||
{2015123099, d12, 2015123101},
|
||||
{2015123099, d12, 2015123100},
|
||||
{2015123100, d12, 2015123101},
|
||||
{2015123101, d12, 2015123102},
|
||||
{2015123102, d12, 2015123103},
|
||||
{2015123198, d12, 2015123199},
|
||||
{2015123199, d12, 2015123200},
|
||||
{2015123200, d12, 2015123201},
|
||||
{201512310, d12, 2015123101},
|
||||
{201512310, d12, 2015123100},
|
||||
}
|
||||
|
||||
for i, tst := range tests {
|
||||
|
@ -23,7 +23,7 @@ func Test_makeSoa(t *testing.T) {
|
||||
&models.RecordConfig{Target: "", SoaMbox: "", SoaSerial: 0, SoaRefresh: 0, SoaRetry: 0, SoaExpire: 0, SoaMinttl: 0},
|
||||
&models.RecordConfig{Target: "", SoaMbox: "", SoaSerial: 0, SoaRefresh: 0, SoaRetry: 0, SoaExpire: 0, SoaMinttl: 0},
|
||||
&models.RecordConfig{Target: "DEFAULT_NOT_SET.", SoaMbox: "DEFAULT_NOT_SET.", SoaSerial: 1, SoaRefresh: 3600, SoaRetry: 600, SoaExpire: 604800, SoaMinttl: 1440},
|
||||
2019022301,
|
||||
2019022300,
|
||||
},
|
||||
{
|
||||
// If everything is filled, leave the desired values in place.
|
||||
@ -31,7 +31,7 @@ func Test_makeSoa(t *testing.T) {
|
||||
&models.RecordConfig{Target: "a", SoaMbox: "aa", SoaSerial: 10, SoaRefresh: 11, SoaRetry: 12, SoaExpire: 13, SoaMinttl: 14},
|
||||
&models.RecordConfig{Target: "b", SoaMbox: "bb", SoaSerial: 15, SoaRefresh: 16, SoaRetry: 17, SoaExpire: 18, SoaMinttl: 19},
|
||||
&models.RecordConfig{Target: "b", SoaMbox: "bb", SoaSerial: 15, SoaRefresh: 16, SoaRetry: 17, SoaExpire: 18, SoaMinttl: 19},
|
||||
2019022301,
|
||||
2019022300,
|
||||
},
|
||||
{
|
||||
// Test incrementing serial.
|
||||
@ -55,7 +55,7 @@ func Test_makeSoa(t *testing.T) {
|
||||
&models.RecordConfig{Target: "", SoaMbox: "aa", SoaSerial: 0, SoaRefresh: 11, SoaRetry: 0, SoaExpire: 13, SoaMinttl: 0},
|
||||
&models.RecordConfig{Target: "b", SoaMbox: "", SoaSerial: 15, SoaRefresh: 0, SoaRetry: 17, SoaExpire: 0, SoaMinttl: 19},
|
||||
&models.RecordConfig{Target: "b", SoaMbox: "aa", SoaSerial: 15, SoaRefresh: 11, SoaRetry: 17, SoaExpire: 13, SoaMinttl: 19},
|
||||
2019022301,
|
||||
2019022300,
|
||||
},
|
||||
{
|
||||
// Gaps + existing==nil
|
||||
@ -63,7 +63,7 @@ func Test_makeSoa(t *testing.T) {
|
||||
nil,
|
||||
&models.RecordConfig{Target: "b", SoaMbox: "", SoaSerial: 15, SoaRefresh: 0, SoaRetry: 17, SoaExpire: 0, SoaMinttl: 19},
|
||||
&models.RecordConfig{Target: "b", SoaMbox: "root.example.com", SoaSerial: 15, SoaRefresh: 2, SoaRetry: 17, SoaExpire: 4, SoaMinttl: 19},
|
||||
2019022301,
|
||||
2019022300,
|
||||
},
|
||||
{
|
||||
// Gaps + desired==nil
|
||||
@ -72,7 +72,7 @@ func Test_makeSoa(t *testing.T) {
|
||||
&models.RecordConfig{Target: "", SoaMbox: "aa", SoaSerial: 0, SoaRefresh: 11, SoaRetry: 0, SoaExpire: 13, SoaMinttl: 0},
|
||||
nil,
|
||||
&models.RecordConfig{Target: "ns.example.com", SoaMbox: "aa", SoaSerial: 1, SoaRefresh: 11, SoaRetry: 3, SoaExpire: 13, SoaMinttl: 5},
|
||||
2019022301,
|
||||
2019022300,
|
||||
},
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user