mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-07-27 12:59:57 +00:00

Adds a new reserved service to route UDP requests towards the local DNS resolver. Closes TUN-9472
135 lines
3.6 KiB
Go
135 lines
3.6 KiB
Go
package origins
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"net"
|
|
"net/netip"
|
|
"testing"
|
|
|
|
"github.com/rs/zerolog"
|
|
)
|
|
|
|
func TestDNSResolver_DefaultResolver(t *testing.T) {
|
|
log := zerolog.Nop()
|
|
service := NewDNSResolver(&log)
|
|
mockResolver := &mockPeekResolver{
|
|
address: "127.0.0.2:53",
|
|
}
|
|
service.resolver = mockResolver
|
|
if service.address != defaultResolverAddr {
|
|
t.Errorf("resolver address should be the default: %s, was: %s", defaultResolverAddr, service.address)
|
|
}
|
|
}
|
|
|
|
func TestDNSResolver_UpdateResolverAddress(t *testing.T) {
|
|
log := zerolog.Nop()
|
|
service := NewDNSResolver(&log)
|
|
|
|
mockResolver := &mockPeekResolver{}
|
|
service.resolver = mockResolver
|
|
|
|
expectedAddr := netip.MustParseAddrPort("127.0.0.2:53")
|
|
addresses := []string{
|
|
"127.0.0.2:53",
|
|
"127.0.0.2", // missing port should be added (even though this is unlikely to happen)
|
|
}
|
|
|
|
for _, addr := range addresses {
|
|
mockResolver.address = addr
|
|
// Update the resolver address
|
|
err := service.update(t.Context())
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
// Validate expected
|
|
if service.address != expectedAddr {
|
|
t.Errorf("resolver address should be: %s, was: %s", expectedAddr, service.address)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestDNSResolver_UpdateResolverAddressInvalid(t *testing.T) {
|
|
log := zerolog.Nop()
|
|
service := NewDNSResolver(&log)
|
|
mockResolver := &mockPeekResolver{}
|
|
service.resolver = mockResolver
|
|
|
|
invalidAddresses := []string{
|
|
"999.999.999.999",
|
|
"localhost",
|
|
"255.255.255",
|
|
}
|
|
|
|
for _, addr := range invalidAddresses {
|
|
mockResolver.address = addr
|
|
// Update the resolver address should not update for these invalid addresses
|
|
err := service.update(t.Context())
|
|
if err == nil {
|
|
t.Error("service update should throw an error")
|
|
}
|
|
// Validate expected
|
|
if service.address != defaultResolverAddr {
|
|
t.Errorf("resolver address should not be updated from default: %s, was: %s", defaultResolverAddr, service.address)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestDNSResolver_UpdateResolverErrorIgnored(t *testing.T) {
|
|
log := zerolog.Nop()
|
|
service := NewDNSResolver(&log)
|
|
resolverErr := errors.New("test resolver error")
|
|
mockResolver := &mockPeekResolver{err: resolverErr}
|
|
service.resolver = mockResolver
|
|
|
|
// Update the resolver address should not update when the resolver cannot complete the lookup
|
|
err := service.update(t.Context())
|
|
if err != resolverErr {
|
|
t.Error("service update should throw an error")
|
|
}
|
|
// Validate expected
|
|
if service.address != defaultResolverAddr {
|
|
t.Errorf("resolver address should not be updated from default: %s, was: %s", defaultResolverAddr, service.address)
|
|
}
|
|
}
|
|
|
|
func TestDNSResolver_DialUsesResolvedAddress(t *testing.T) {
|
|
log := zerolog.Nop()
|
|
service := NewDNSResolver(&log)
|
|
mockResolver := &mockPeekResolver{}
|
|
service.resolver = mockResolver
|
|
mockDialer := &mockDialer{expected: defaultResolverAddr}
|
|
service.dialer = mockDialer
|
|
|
|
// Attempt a dial to 127.0.0.2:53 which should be ignored and instead resolve to 127.0.0.1:53
|
|
_, err := service.DialUDP(netip.MustParseAddrPort("127.0.0.2:53"))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
type mockPeekResolver struct {
|
|
err error
|
|
address string
|
|
}
|
|
|
|
func (r *mockPeekResolver) addr() (network, address string) {
|
|
return "udp", r.address
|
|
}
|
|
|
|
func (r *mockPeekResolver) lookupNetIP(ctx context.Context, host string) ([]netip.Addr, error) {
|
|
// We can return an empty result as it doesn't matter as long as the lookup doesn't fail
|
|
return []netip.Addr{}, r.err
|
|
}
|
|
|
|
type mockDialer struct {
|
|
expected netip.AddrPort
|
|
}
|
|
|
|
func (d *mockDialer) DialUDP(addr netip.AddrPort) (net.Conn, error) {
|
|
if d.expected != addr {
|
|
return nil, errors.New("unexpected address dialed")
|
|
}
|
|
return nil, nil
|
|
}
|