Fix and test rfc 1982 arithmetic

This commit is contained in:
Miek Gieben 2012-05-15 12:24:57 +02:00
parent 0cfe2d6a43
commit f0154aa0c2
3 changed files with 56 additions and 8 deletions

2
dns.go
View File

@ -82,7 +82,7 @@ import (
)
const (
Year68 = 1 << 32 // For RFC1982 (Serial Arithmetic) calculations in 32 bits.
Year68 = 1 << 31 // For RFC1982 (Serial Arithmetic) calculations in 32 bits.
DefaultMsgSize = 4096 // Standard default for larger than 512 packets.
UDPMsgSize = 512 // Default buffer size for servers receiving UDP packets.
MaxMsgSize = 65536 // Largest possible DNS packet.

View File

@ -509,3 +509,47 @@ func TestLineNumberError2(t *testing.T) {
// fmt.Printf("%s\n", err.Error())
}
}
// Test if the calculations are correct
func TestRfc1982(t *testing.T) {
// If the current time and the timestamp are more than 68 years apart
// it means the date has wrapped. 0 is 1970
// fall in the current 68 year span
strtests := []string{"20120525134203", "19700101000000", "20380119031408"}
for _, v := range strtests {
if x, _ := DateToTime(v); v != TimeToDate(x) {
t.Logf("1982 arithmetic string failure %s (%s:%d)", v, TimeToDate(x), x)
t.Fail()
}
}
inttests := map[uint32]string{0: "19700101000000",
1 << 31: "20380119031408",
1<<32 - 1: "21060207062815",
}
for i, v := range inttests {
if TimeToDate(i) != v {
t.Logf("1982 arithmetic int failure %d:%s (%s)", i, v, TimeToDate(i))
t.Fail()
}
}
// Future tests, these dates get parsed to a date within the current 136 year span
future := map[string]string{"22680119031408": "20631123173144",
"19010101121212": "20370206184028",
"19210101121212": "20570206184028",
"19500101121212": "20860206184028",
"19700101000000": "19700101000000",
"19690101000000": "21050207062816",
"29210101121212": "21040522212236",
}
for from, to := range future {
x, _ := DateToTime(from)
y := TimeToDate(x)
if y != to {
t.Logf("1982 arithmetic future failure %s:%s (%s)", from, to, y)
t.Fail()
}
}
}

View File

@ -1100,23 +1100,27 @@ func (rr *RR_HIP) Len() int {
// string representation used when printing the record.
// It takes serial arithmetic (RFC 1982) into account. [TODO]
func TimeToDate(t uint32) string {
// utc := time.Now().UTC().Unix()
// mod := (int64(t) - utc) / Year68
ti := time.Unix(int64(t), 0).UTC()
mod := ( (int64(t) - time.Now().Unix()) / Year68 ) - 1
if mod < 0 {
mod = 0
}
ti := time.Unix(int64(t) - (mod * Year68), 0).UTC()
return ti.Format("20060102150405")
}
// DateToTime translates the RRSIG's incep. and expir. times from
// string values like "20110403154150" to an 32 bit integer.
// It takes serial arithmetic (RFC 1982) into account. [TODO]
// It takes serial arithmetic (RFC 1982) into account.
func DateToTime(s string) (uint32, error) {
t, e := time.Parse("20060102150405", s)
if e != nil {
return 0, e
}
mod := t.Unix() / Year68
ti := uint32(t.Unix() - (mod * Year68))
return ti, nil
mod := ( t.Unix() / Year68 ) - 1
if mod < 0 {
mod = 0
}
return uint32(t.Unix() - (mod * Year68)), nil
}
// saltString converts a NSECX salt to uppercase and