|
|
|
|
package locator_test
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"net/netip"
|
|
|
|
|
"path/filepath"
|
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
|
|
"g.activething.com/go/DateKeys/internal/testkit"
|
|
|
|
|
"g.activething.com/go/DateKeys/locator"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// testdata/vectors/resolved_ip.json: the address a name resolves to, with
|
|
|
|
|
// the NAT64 prefix of the network or none, and whether a reader may connect
|
|
|
|
|
// (spec v0.13, §44.1).
|
|
|
|
|
func TestResolvedIPVectors(t *testing.T) {
|
|
|
|
|
var f testkit.ResolvedIPVectorFile
|
|
|
|
|
if err := testkit.ReadJSON(filepath.Join("..", "testdata", "vectors", "resolved_ip.json"), &f); err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
if len(f.Cases) < 40 {
|
|
|
|
|
t.Fatalf("%d cases", len(f.Cases))
|
|
|
|
|
}
|
|
|
|
|
for _, c := range f.Cases {
|
|
|
|
|
ip := netip.MustParseAddr(c.IP)
|
|
|
|
|
var p netip.Prefix
|
|
|
|
|
if c.NAT64 != "" {
|
|
|
|
|
p = netip.MustParsePrefix(c.NAT64)
|
|
|
|
|
}
|
|
|
|
|
err := locator.CheckResolvedIP(ip, p)
|
|
|
|
|
switch {
|
|
|
|
|
case c.Result == testkit.ResultOK && err != nil:
|
|
|
|
|
t.Errorf("%s: %v", c.Name, err)
|
|
|
|
|
case c.Result != testkit.ResultOK && (err == nil || err.Error() != c.Error):
|
|
|
|
|
t.Errorf("%s: %v, want %s", c.Name, err, c.Error)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// An address of NAT64 is public exactly when the IPv4 address it holds is,
|
|
|
|
|
// for every IPv4 address of the special-purpose blocks and their edges.
|
|
|
|
|
func TestResolvedIPWellKnownPrefix(t *testing.T) {
|
|
|
|
|
wkp := netip.MustParsePrefix("64:ff9b::/96")
|
|
|
|
|
for _, s := range []string{
|
|
|
|
|
"0.0.0.0", "0.255.255.255", "1.0.0.0", "9.255.255.255", "10.0.0.0", "10.255.255.255", "11.0.0.0",
|
|
|
|
|
"100.63.255.255", "100.64.0.0", "100.127.255.255", "100.128.0.0", "126.255.255.255", "127.0.0.0",
|
|
|
|
|
"127.255.255.255", "128.0.0.0", "169.253.255.255", "169.254.0.0", "169.254.255.255", "169.255.0.0",
|
|
|
|
|
"172.15.255.255", "172.16.0.0", "172.31.255.255", "172.32.0.0", "192.0.0.0", "192.0.0.255", "192.0.1.0",
|
|
|
|
|
"192.0.2.0", "192.0.3.0", "192.88.99.0", "192.88.100.0", "192.167.255.255", "192.168.0.0",
|
|
|
|
|
"192.168.255.255", "192.169.0.0", "198.17.255.255", "198.18.0.0", "198.19.255.255", "198.20.0.0",
|
|
|
|
|
"198.51.100.0", "203.0.113.0", "203.0.114.0", "223.255.255.255", "224.0.0.0", "240.0.0.0", "255.255.255.255",
|
|
|
|
|
} {
|
|
|
|
|
v4 := netip.MustParseAddr(s)
|
|
|
|
|
b := v4.As4()
|
|
|
|
|
var a [16]byte
|
|
|
|
|
copy(a[:], netip.MustParseAddr("64:ff9b::").AsSlice())
|
|
|
|
|
copy(a[12:], b[:])
|
|
|
|
|
ip := netip.AddrFrom16(a)
|
|
|
|
|
for _, p := range []netip.Prefix{{}, wkp} {
|
|
|
|
|
got := locator.CheckResolvedIP(ip, p) == nil
|
|
|
|
|
want := locator.CheckResolvedIP(v4, netip.Prefix{}) == nil
|
|
|
|
|
if got != want {
|
|
|
|
|
t.Errorf("%s (%s) with prefix %v: public %v, its IPv4 address %v", ip, v4, p, got, want)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// An IPv4-mapped prefix is not one of NAT64: the texts of TypeScript and Dart
|
|
|
|
|
// follow this one.
|
|
|
|
|
func TestResolvedIPMappedPrefix(t *testing.T) {
|
|
|
|
|
err := locator.CheckResolvedIP(netip.MustParseAddr("8.8.8.8"), netip.MustParsePrefix("::ffff:0.0.0.0/96"))
|
|
|
|
|
if err == nil || err.Error() != "locator: the NAT64 prefix ::ffff:0.0.0.0/96 is not an IPv6 prefix" {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
}
|