diff --git a/defaults.go b/defaults.go index 1778b1ca..15fd8c02 100644 --- a/defaults.go +++ b/defaults.go @@ -244,12 +244,19 @@ func ReverseAddr(addr string) (arpa string, err error) { if ip == nil { return "", &Error{err: "unrecognized address: " + addr} } - if ip.To4() != nil { - return strconv.Itoa(int(ip[15])) + "." + strconv.Itoa(int(ip[14])) + "." + strconv.Itoa(int(ip[13])) + "." + - strconv.Itoa(int(ip[12])) + ".in-addr.arpa.", nil + if v4 := ip.To4(); v4 != nil { + buf := make([]byte, 0, net.IPv4len*4+len("in-addr.arpa.")) + // Add it, in reverse, to the buffer + for i := len(v4) - 1; i >= 0; i-- { + buf = strconv.AppendInt(buf, int64(v4[i]), 10) + buf = append(buf, '.') + } + // Append "in-addr.arpa." and return (buf already has the final .) + buf = append(buf, "in-addr.arpa."...) + return string(buf), nil } // Must be IPv6 - buf := make([]byte, 0, len(ip)*4+len("ip6.arpa.")) + buf := make([]byte, 0, net.IPv6len*4+len("ip6.arpa.")) // Add it, in reverse, to the buffer for i := len(ip) - 1; i >= 0; i-- { v := ip[i] diff --git a/dns_bench_test.go b/dns_bench_test.go index d1f1002a..a34fe994 100644 --- a/dns_bench_test.go +++ b/dns_bench_test.go @@ -342,3 +342,29 @@ func BenchmarkIdGeneration(b *testing.B) { _ = id() } } + +func BenchmarkReverseAddr(b *testing.B) { + b.Run("IP4", func(b *testing.B) { + for n := 0; n < b.N; n++ { + addr, err := ReverseAddr("192.0.2.1") + if err != nil { + b.Fatal(err) + } + if expect := "1.2.0.192.in-addr.arpa."; addr != expect { + b.Fatalf("invalid reverse address, expected %q, got %q", expect, addr) + } + } + }) + + b.Run("IP6", func(b *testing.B) { + for n := 0; n < b.N; n++ { + addr, err := ReverseAddr("2001:db8::68") + if err != nil { + b.Fatal(err) + } + if expect := "8.6.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa."; addr != expect { + b.Fatalf("invalid reverse address, expected %q, got %q", expect, addr) + } + } + }) +}