github.com/StackExchange/DNSControl@v0.2.8/providers/bind/serial.go (about) 1 package bind 2 3 import ( 4 "log" 5 "strconv" 6 "strings" 7 "time" 8 ) 9 10 var nowFunc = time.Now 11 12 // generateSerial takes an old SOA serial number and increments it. 13 func generateSerial(oldSerial uint32) uint32 { 14 // Serial numbers are in the format yyyymmddvv 15 // where vv is a version count that starts at 01 each day. 16 // Multiple serial numbers generated on the same day increase vv. 17 // If the old serial number is not in this format, it gets replaced 18 // with the new format. However if that would mean a new serial number 19 // that is smaller than the old one, we punt and increment the old number. 20 // At no time will a serial number == 0 be returned. 21 22 original := oldSerial 23 oldSerialStr := strconv.FormatUint(uint64(oldSerial), 10) 24 var newSerial uint32 25 26 // Make draft new serial number: 27 today := nowFunc().UTC() 28 todayStr := today.Format("20060102") 29 version := uint32(1) 30 todayNum, err := strconv.ParseUint(todayStr, 10, 32) 31 if err != nil { 32 log.Fatalf("new serial won't fit in 32 bits: %v", err) 33 } 34 draft := uint32(todayNum)*100 + version 35 36 method := "none" // Used only in debugging. 37 if oldSerial > draft { 38 // If old_serial was really slow, upgrade to new yyyymmddvv standard: 39 method = "o>d" 40 newSerial = oldSerial + 1 41 newSerial = oldSerial + 1 42 } else if oldSerial == draft { 43 // Edge case: increment old serial: 44 method = "o=d" 45 newSerial = draft + 1 46 } else if len(oldSerialStr) != 10 { 47 // If old_serial is wrong number of digits, upgrade to yyyymmddvv standard: 48 method = "len!=10" 49 newSerial = draft 50 } else if strings.HasPrefix(oldSerialStr, todayStr) { 51 // If old_serial just needs to be incremented: 52 method = "prefix" 53 newSerial = oldSerial + 1 54 } else { 55 // First serial number to be requested today: 56 method = "default" 57 newSerial = draft 58 } 59 60 if newSerial == 0 { 61 // We never return 0 as the serial number. 62 newSerial = 1 63 } 64 if oldSerial == newSerial { 65 log.Fatalf("%v: old_serial == new_serial (%v == %v) draft=%v method=%v", original, oldSerial, newSerial, draft, method) 66 } 67 if oldSerial > newSerial { 68 log.Fatalf("%v: old_serial > new_serial (%v > %v) draft=%v method=%v", original, oldSerial, newSerial, draft, method) 69 } 70 return newSerial 71 }