mirror of
				https://github.com/StackExchange/dnscontrol.git
				synced 2025-10-31 08:26:26 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			64 lines
		
	
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			64 lines
		
	
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package bind
 | |
| 
 | |
| import (
 | |
| 	"log"
 | |
| 	"strconv"
 | |
| 	"time"
 | |
| 
 | |
| 	"github.com/StackExchange/dnscontrol/v4/pkg/bindserial"
 | |
| )
 | |
| 
 | |
| var nowFunc = time.Now
 | |
| 
 | |
| // generateSerial takes an old SOA serial number and increments it.
 | |
| func generateSerial(oldSerial uint32) uint32 {
 | |
| 	// Serial numbers are in the format yyyymmddvv
 | |
| 	// where vv is a version count that starts at 01 each day.
 | |
| 	// Multiple serial numbers generated on the same day increase vv.
 | |
| 	// If the old serial number is not in this format, it gets replaced
 | |
| 	// with the new format. However if that would mean a new serial number
 | |
| 	// that is smaller than the old one, we punt and increment the old number.
 | |
| 	// At no time will a serial number == 0 be returned.
 | |
| 
 | |
| 	if bindserial.ForcedValue != 0 {
 | |
| 		// https://github.com/StackExchange/dnscontrol/issues/1859
 | |
| 		// User needs to have reproducible builds and BIND generates
 | |
| 		return uint32(bindserial.ForcedValue & 0xFFFF)
 | |
| 	}
 | |
| 
 | |
| 	original := oldSerial
 | |
| 	var newSerial uint32
 | |
| 
 | |
| 	// Make draft new serial number:
 | |
| 	today := nowFunc().UTC()
 | |
| 	todayStr := today.Format("20060102")
 | |
| 	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)
 | |
| 
 | |
| 	// First serial number to be requested today:
 | |
| 	method := "default"
 | |
| 	newSerial = draft
 | |
| 	if oldSerial >= newSerial {
 | |
| 		// If that would be going backwards, just increment the old one.
 | |
| 		method = "o>=d"
 | |
| 		newSerial = oldSerial + 1
 | |
| 	}
 | |
| 
 | |
| 	if newSerial == 0 {
 | |
| 		// We never return 0 as the serial number.
 | |
| 		newSerial = 1
 | |
| 	}
 | |
| 
 | |
| 	// Assertions that should never happen.
 | |
| 	if oldSerial == newSerial {
 | |
| 		log.Fatalf("%v: old_serial == new_serial (%v == %v) draft=%v method=%v", original, oldSerial, newSerial, draft, method)
 | |
| 	}
 | |
| 	if oldSerial > newSerial {
 | |
| 		log.Fatalf("%v: old_serial > new_serial (%v > %v) draft=%v method=%v", original, oldSerial, newSerial, draft, method)
 | |
| 	}
 | |
| 
 | |
| 	return newSerial
 | |
| }
 |