165 lines
4.0 KiB
Go
165 lines
4.0 KiB
Go
package resolver_test
|
|
|
|
import (
|
|
"context"
|
|
"ekdns/resolver"
|
|
"io"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// CheckSplitHorizon tests (T015)
|
|
// ---------------------------------------------------------------------------
|
|
|
|
func TestCheckSplitHorizon_NoConflict_SameIPs(t *testing.T) {
|
|
qname := mustNewName("www.example.com.")
|
|
|
|
localAddr := startFakeDNSMulti(t, func(query []byte) []byte {
|
|
return buildAResponse(queryID(query), qname, [][4]byte{{93, 184, 216, 34}})
|
|
})
|
|
|
|
authIPs := []string{"93.184.216.34"}
|
|
result := resolver.CheckSplitHorizon(
|
|
context.Background(),
|
|
io.Discard,
|
|
[]string{localAddr},
|
|
"www.example.com",
|
|
authIPs,
|
|
"ns1.example.com",
|
|
2*time.Second,
|
|
)
|
|
|
|
if result.HasConflict {
|
|
t.Errorf("expected no conflict when IPs match, got conflict: local=%v auth=%v",
|
|
result.LocalIPs, result.AuthoritativeIPs)
|
|
}
|
|
}
|
|
|
|
func TestCheckSplitHorizon_Conflict_DifferentIPs(t *testing.T) {
|
|
qname := mustNewName("www.example.com.")
|
|
|
|
// Local resolver returns internal IP.
|
|
localAddr := startFakeDNSMulti(t, func(query []byte) []byte {
|
|
return buildAResponse(queryID(query), qname, [][4]byte{{10, 0, 5, 100}})
|
|
})
|
|
|
|
authIPs := []string{"203.0.113.50"} // authoritative returned a different IP
|
|
result := resolver.CheckSplitHorizon(
|
|
context.Background(),
|
|
io.Discard,
|
|
[]string{localAddr},
|
|
"www.example.com",
|
|
authIPs,
|
|
"ns1.example.com",
|
|
2*time.Second,
|
|
)
|
|
|
|
if !result.HasConflict {
|
|
t.Error("expected conflict when IPs differ")
|
|
}
|
|
if len(result.LocalIPs) == 0 {
|
|
t.Error("expected LocalIPs to be populated")
|
|
}
|
|
if result.LocalSource == "" {
|
|
t.Error("expected LocalSource to be populated")
|
|
}
|
|
}
|
|
|
|
func TestCheckSplitHorizon_NoConflict_LocalNXDOMAIN(t *testing.T) {
|
|
qname := mustNewName("www.example.com.")
|
|
|
|
localAddr := startFakeDNSMulti(t, func(query []byte) []byte {
|
|
return buildNXDOMAINResponse(queryID(query), qname)
|
|
})
|
|
|
|
authIPs := []string{"93.184.216.34"}
|
|
result := resolver.CheckSplitHorizon(
|
|
context.Background(),
|
|
io.Discard,
|
|
[]string{localAddr},
|
|
"www.example.com",
|
|
authIPs,
|
|
"ns1.example.com",
|
|
2*time.Second,
|
|
)
|
|
|
|
if result.HasConflict {
|
|
t.Error("expected no conflict when local returns NXDOMAIN")
|
|
}
|
|
if result.LocalIPs != nil {
|
|
t.Errorf("expected nil LocalIPs for NXDOMAIN, got %v", result.LocalIPs)
|
|
}
|
|
}
|
|
|
|
func TestCheckSplitHorizon_NoConflict_LocalTimeout(t *testing.T) {
|
|
silentAddr := startSilentDNS(t)
|
|
|
|
authIPs := []string{"93.184.216.34"}
|
|
result := resolver.CheckSplitHorizon(
|
|
context.Background(),
|
|
io.Discard,
|
|
[]string{silentAddr},
|
|
"www.example.com",
|
|
authIPs,
|
|
"ns1.example.com",
|
|
100*time.Millisecond,
|
|
)
|
|
|
|
if result.HasConflict {
|
|
t.Error("expected no conflict when local resolver times out")
|
|
}
|
|
if result.LocalIPs != nil {
|
|
t.Errorf("expected nil LocalIPs for timeout, got %v", result.LocalIPs)
|
|
}
|
|
}
|
|
|
|
func TestCheckSplitHorizon_NoConflict_OrderIndependent(t *testing.T) {
|
|
qname := mustNewName("www.example.com.")
|
|
|
|
// Local resolver returns IPs in different order than authoritative.
|
|
localAddr := startFakeDNSMulti(t, func(query []byte) []byte {
|
|
return buildAResponse(queryID(query), qname, [][4]byte{
|
|
{5, 6, 7, 8},
|
|
{1, 2, 3, 4},
|
|
})
|
|
})
|
|
|
|
// Authoritative had them in reverse order.
|
|
authIPs := []string{"1.2.3.4", "5.6.7.8"}
|
|
result := resolver.CheckSplitHorizon(
|
|
context.Background(),
|
|
io.Discard,
|
|
[]string{localAddr},
|
|
"www.example.com",
|
|
authIPs,
|
|
"ns1.example.com",
|
|
2*time.Second,
|
|
)
|
|
|
|
if result.HasConflict {
|
|
t.Errorf("expected no conflict for same IPs in different order: local=%v auth=%v",
|
|
result.LocalIPs, result.AuthoritativeIPs)
|
|
}
|
|
}
|
|
|
|
func TestCheckSplitHorizon_NoLocalResolvers(t *testing.T) {
|
|
authIPs := []string{"93.184.216.34"}
|
|
result := resolver.CheckSplitHorizon(
|
|
context.Background(),
|
|
io.Discard,
|
|
nil, // no local resolvers
|
|
"www.example.com",
|
|
authIPs,
|
|
"ns1.example.com",
|
|
2*time.Second,
|
|
)
|
|
|
|
if result.HasConflict {
|
|
t.Error("expected no conflict when no local resolvers provided")
|
|
}
|
|
if result.LocalIPs != nil {
|
|
t.Error("expected nil LocalIPs when no resolvers provided")
|
|
}
|
|
}
|