package chat
import (
"context"
"net"
"testing"
)
// CheckPublicHost applies the bridge dialer's own rule to a host the
// caller will hand to another program.
func TestCheckPublicHostRefusesWhatTheBridgeRefuses(t *testing.T) {
ctx := context.Background()
for _, bad := range []string{"127.0.0.1", "10.0.0.5", "192.168.1.1", "169.254.169.254", "::1", "0.0.0.0",
"100.64.0.1", "100.100.100.100", "100.127.255.254", "198.18.0.1", "198.19.255.254",
"0.0.0.1", "0.255.255.255", "192.0.0.8", "240.0.0.1", "255.255.255.254",
// An IPv6 address carrying a reserved IPv4 one: NAT64 and 6to4.
"64:ff9b::7f00:1", "64:ff9b::a00:5", "64:ff9b::a9fe:a9fe", "2002:7f00:1::1", "2002:a00:5::", "2002:c0a8:101::1"} {
if err := CheckPublicHost(ctx, bad); err == nil {
t.Errorf("FAIL: %s passed", bad)
}
}
for _, ok := range []string{"93.184.216.34", "100.63.255.255", "100.128.0.1", "198.17.255.255", "198.20.0.1", "1.0.0.1", "223.255.255.255",
// The same gateways carrying a public IPv4 address.
"64:ff9b::5db8:d822", "2002:5db8:d822::1"} {
if err := CheckPublicHost(ctx, ok); err != nil {
t.Errorf("FAIL: %s refused: %v", ok, err)
}
}
// A name is checked by what it resolves to, every address of it.
was := lookupIP
t.Cleanup(func() { lookupIP = was })
answers := map[string][]string{
"cgnat.example": {"100.64.3.4"},
"mixed.example": {"93.184.216.34", "100.64.3.4"},
"public.example": {"93.184.216.34"},
"private.example": {"10.0.0.9"},
}
lookupIP = func(_ context.Context, host string) ([]net.IPAddr, error) {
var out []net.IPAddr
for _, a := range answers[host] {
out = append(out, net.IPAddr{IP: net.ParseIP(a)})
}
return out, nil
}
for name, wantErr := range map[string]bool{"cgnat.example": true, "mixed.example": true, "private.example": true, "public.example": false, "none.example": true} {
if err := CheckPublicHost(ctx, name); (err != nil) != wantErr {
t.Errorf("FAIL: the name %s: refused=%v, want %v (%v)", name, err != nil, wantErr, err)
}
}
t.Log("ok")
}