Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion cmd/clawpatrol/daemon_session_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,17 @@ func newRunUDPProtocolHandler(s *stack.Stack, handler udp.ForwarderHandler) func
}
}

type udpDNSGateway interface {
udpDNSGatewayAddr() netip.Addr
}

func udpDialAddr(transport daemonTransport, dstIP string, dstPort uint16) string {
if gateway, ok := transport.(udpDNSGateway); ok && dstPort == 53 {
dstIP = gateway.udpDNSGatewayAddr().String()
}
return net.JoinHostPort(dstIP, strconv.Itoa(int(dstPort)))
}

func newTransportUDPProtocolHandler(ctx context.Context, s *stack.Stack, transport daemonTransport, idleTimeout time.Duration, slots chan struct{}) func(stack.TransportEndpointID, *stack.PacketBuffer) bool {
return newRunUDPProtocolHandler(s, func(req *udp.ForwarderRequest) bool {
select {
Expand All @@ -214,7 +225,7 @@ func newTransportUDPProtocolHandler(ctx context.Context, s *stack.Stack, transpo
return true
}
local := gonet.NewUDPConn(&wq, ep)
dstAddr := net.JoinHostPort(id.LocalAddress.String(), strconv.Itoa(int(id.LocalPort)))
dstAddr := udpDialAddr(transport, id.LocalAddress.String(), id.LocalPort)
go func() {
dialCtx, cancel := context.WithTimeout(ctx, transportDialTimeout)
defer cancel()
Expand Down
17 changes: 17 additions & 0 deletions cmd/clawpatrol/daemon_session_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,23 @@ func TestRunUDPProtocolHandlerFlowLimitRejectionDoesNotClonePacket(t *testing.T)
}
}

func TestUDPDialAddrRewritesTSnetDNS(t *testing.T) {
tsnet := &tsnetTransport{gatewayAddr: netip.MustParseAddr("100.64.0.1")}
if got, want := udpDialAddr(tsnet, "8.8.8.8", 53), "100.64.0.1:53"; got != want {
t.Fatalf("udpDialAddr(tsnet DNS) = %q, want %q", got, want)
}
if got, want := udpDialAddr(tsnet, "8.8.8.8", 443), "8.8.8.8:443"; got != want {
t.Fatalf("udpDialAddr(tsnet non-DNS) = %q, want %q", got, want)
}
plain := &fakeTransport{}
if got, want := udpDialAddr(plain, "8.8.8.8", 53), "8.8.8.8:53"; got != want {
t.Fatalf("udpDialAddr(non-tsnet DNS) = %q, want %q", got, want)
}
if got, want := udpDialAddr(plain, "2001:db8::53", 53), "[2001:db8::53]:53"; got != want {
t.Fatalf("udpDialAddr(non-tsnet IPv6 DNS) = %q, want %q", got, want)
}
}

// pump copies outbound packets from src's channel endpoint into dst's
// inbound path until ctx is done.
func pump(ctx context.Context, src, dst *channel.Endpoint) {
Expand Down
10 changes: 6 additions & 4 deletions cmd/clawpatrol/daemon_transport_tsnet_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,18 @@ import (
type tsnetTransport struct {
s *tsnet.Server
localAddr netip.Addr
gatewayAddr netip.Addr
bootWarning string
}

func (t *tsnetTransport) Dial(ctx context.Context, network, addr string) (net.Conn, error) {
return t.s.Dial(ctx, network, addr)
}

func (t *tsnetTransport) LocalAddr() netip.Addr { return t.localAddr }
func (t *tsnetTransport) BootWarning() string { return t.bootWarning }
func (t *tsnetTransport) Close() error { return t.s.Close() }
func (t *tsnetTransport) LocalAddr() netip.Addr { return t.localAddr }
func (t *tsnetTransport) udpDNSGatewayAddr() netip.Addr { return t.gatewayAddr }
func (t *tsnetTransport) BootWarning() string { return t.bootWarning }
func (t *tsnetTransport) Close() error { return t.s.Close() }

// startTsnetTransport reads persisted join state (auth-key, control-url,
// gateway-ip), starts a tsnet.Server, waits for it to come up, points
Expand Down Expand Up @@ -126,7 +128,7 @@ func startTsnetTransport() (daemonTransport, error) {
// daemon restart.
daemonRegisterTsnetPeer(s, tsIP)

return &tsnetTransport{s: s, localAddr: tsIP, bootWarning: bootWarning}, nil
return &tsnetTransport{s: s, localAddr: tsIP, gatewayAddr: gwIP, bootWarning: bootWarning}, nil
}

// daemonRegisterTsnetPeer POSTs this daemon's tsnet IP to the
Expand Down
Loading