2023-01-27 13:37:20 -08:00
|
|
|
// Copyright (c) Tailscale Inc & AUTHORS
|
|
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
2021-04-19 20:21:48 -07:00
|
|
|
|
|
|
|
package ipnlocal
|
|
|
|
|
|
|
|
import (
|
2023-10-27 14:20:10 -07:00
|
|
|
"context"
|
2024-01-31 13:49:52 -08:00
|
|
|
"encoding/json"
|
2021-04-19 20:21:48 -07:00
|
|
|
"net/http"
|
|
|
|
"net/http/httptest"
|
2022-07-25 20:55:44 -07:00
|
|
|
"net/netip"
|
2023-10-27 14:20:10 -07:00
|
|
|
"slices"
|
2021-04-19 20:21:48 -07:00
|
|
|
"strings"
|
|
|
|
"testing"
|
|
|
|
|
2022-07-24 20:08:42 -07:00
|
|
|
"go4.org/netipx"
|
2023-10-27 14:20:10 -07:00
|
|
|
"golang.org/x/net/dns/dnsmessage"
|
|
|
|
"tailscale.com/appc"
|
2024-01-22 16:57:31 -08:00
|
|
|
"tailscale.com/appc/appctest"
|
2024-05-03 10:59:22 -04:00
|
|
|
"tailscale.com/health"
|
2021-11-25 09:43:39 -08:00
|
|
|
"tailscale.com/ipn"
|
2022-11-09 10:58:10 +05:00
|
|
|
"tailscale.com/ipn/store/mem"
|
2021-04-19 20:21:48 -07:00
|
|
|
"tailscale.com/tailcfg"
|
2021-09-07 19:27:19 -07:00
|
|
|
"tailscale.com/tstest"
|
2021-11-25 09:43:39 -08:00
|
|
|
"tailscale.com/types/logger"
|
2022-11-16 23:36:01 +05:00
|
|
|
"tailscale.com/types/netmap"
|
2025-03-19 10:47:25 -07:00
|
|
|
"tailscale.com/util/eventbus"
|
2022-11-09 10:58:10 +05:00
|
|
|
"tailscale.com/util/must"
|
2024-09-23 18:34:00 +02:00
|
|
|
"tailscale.com/util/usermetric"
|
2021-11-25 09:43:39 -08:00
|
|
|
"tailscale.com/wgengine"
|
|
|
|
"tailscale.com/wgengine/filter"
|
2021-04-19 20:21:48 -07:00
|
|
|
)
|
|
|
|
|
|
|
|
type peerAPITestEnv struct {
|
|
|
|
ph *peerAPIHandler
|
|
|
|
rr *httptest.ResponseRecorder
|
2021-09-07 19:27:19 -07:00
|
|
|
logBuf tstest.MemLogger
|
2021-04-19 20:21:48 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
type check func(*testing.T, *peerAPITestEnv)
|
|
|
|
|
|
|
|
func checks(vv ...check) []check { return vv }
|
|
|
|
|
|
|
|
func httpStatus(wantStatus int) check {
|
|
|
|
return func(t *testing.T, e *peerAPITestEnv) {
|
|
|
|
if res := e.rr.Result(); res.StatusCode != wantStatus {
|
|
|
|
t.Errorf("HTTP response code = %v; want %v", res.Status, wantStatus)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func bodyContains(sub string) check {
|
|
|
|
return func(t *testing.T, e *peerAPITestEnv) {
|
|
|
|
if body := e.rr.Body.String(); !strings.Contains(body, sub) {
|
|
|
|
t.Errorf("HTTP response body does not contain %q; got: %s", sub, body)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-19 21:57:08 -07:00
|
|
|
func bodyNotContains(sub string) check {
|
|
|
|
return func(t *testing.T, e *peerAPITestEnv) {
|
|
|
|
if body := e.rr.Body.String(); strings.Contains(body, sub) {
|
|
|
|
t.Errorf("HTTP response body unexpectedly contains %q; got: %s", sub, body)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-22 13:01:42 -07:00
|
|
|
func TestHandlePeerAPI(t *testing.T) {
|
2021-04-19 20:21:48 -07:00
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
isSelf bool // the peer sending the request is owned by us
|
2022-09-25 14:29:55 -04:00
|
|
|
capSharing bool // self node has file sharing capability
|
2022-11-16 23:36:01 +05:00
|
|
|
debugCap bool // self node has debug capability
|
2023-09-26 12:22:13 -05:00
|
|
|
reqs []*http.Request
|
2021-04-19 20:21:48 -07:00
|
|
|
checks []check
|
|
|
|
}{
|
2021-04-19 21:57:08 -07:00
|
|
|
{
|
|
|
|
name: "not_peer_api",
|
|
|
|
isSelf: true,
|
|
|
|
capSharing: true,
|
2023-09-26 12:22:13 -05:00
|
|
|
reqs: []*http.Request{httptest.NewRequest("GET", "/", nil)},
|
2021-04-19 21:57:08 -07:00
|
|
|
checks: checks(
|
|
|
|
httpStatus(200),
|
|
|
|
bodyContains("This is my Tailscale device."),
|
|
|
|
bodyContains("You are the owner of this node."),
|
|
|
|
),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "not_peer_api_not_owner",
|
|
|
|
isSelf: false,
|
|
|
|
capSharing: true,
|
2023-09-26 12:22:13 -05:00
|
|
|
reqs: []*http.Request{httptest.NewRequest("GET", "/", nil)},
|
2021-04-19 21:57:08 -07:00
|
|
|
checks: checks(
|
|
|
|
httpStatus(200),
|
|
|
|
bodyContains("This is my Tailscale device."),
|
|
|
|
bodyNotContains("You are the owner of this node."),
|
|
|
|
),
|
|
|
|
},
|
2021-04-22 13:01:42 -07:00
|
|
|
{
|
2022-11-16 23:36:01 +05:00
|
|
|
name: "goroutines/deny-self-no-cap",
|
|
|
|
isSelf: true,
|
|
|
|
debugCap: false,
|
2023-09-26 12:22:13 -05:00
|
|
|
reqs: []*http.Request{httptest.NewRequest("GET", "/v0/goroutines", nil)},
|
2022-11-16 23:36:01 +05:00
|
|
|
checks: checks(httpStatus(403)),
|
2021-04-22 13:01:42 -07:00
|
|
|
},
|
|
|
|
{
|
2022-11-16 23:36:01 +05:00
|
|
|
name: "goroutines/deny-nonself",
|
|
|
|
isSelf: false,
|
|
|
|
debugCap: true,
|
2023-09-26 12:22:13 -05:00
|
|
|
reqs: []*http.Request{httptest.NewRequest("GET", "/v0/goroutines", nil)},
|
2022-11-16 23:36:01 +05:00
|
|
|
checks: checks(httpStatus(403)),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "goroutines/accept-self",
|
|
|
|
isSelf: true,
|
|
|
|
debugCap: true,
|
2023-09-26 12:22:13 -05:00
|
|
|
reqs: []*http.Request{httptest.NewRequest("GET", "/v0/goroutines", nil)},
|
2021-04-22 13:01:42 -07:00
|
|
|
checks: checks(
|
|
|
|
httpStatus(200),
|
|
|
|
bodyContains("ServeHTTP"),
|
|
|
|
),
|
|
|
|
},
|
2022-11-16 21:53:51 +05:00
|
|
|
{
|
2022-11-16 23:36:01 +05:00
|
|
|
name: "host-val/bad-ip",
|
|
|
|
isSelf: true,
|
|
|
|
debugCap: true,
|
2023-09-26 12:22:13 -05:00
|
|
|
reqs: []*http.Request{httptest.NewRequest("GET", "http://12.23.45.66:1234/v0/env", nil)},
|
2022-11-16 21:53:51 +05:00
|
|
|
checks: checks(
|
|
|
|
httpStatus(403),
|
|
|
|
),
|
|
|
|
},
|
|
|
|
{
|
2022-11-16 23:36:01 +05:00
|
|
|
name: "host-val/no-port",
|
|
|
|
isSelf: true,
|
|
|
|
debugCap: true,
|
2023-09-26 12:22:13 -05:00
|
|
|
reqs: []*http.Request{httptest.NewRequest("GET", "http://100.100.100.101/v0/env", nil)},
|
2022-11-16 21:53:51 +05:00
|
|
|
checks: checks(
|
|
|
|
httpStatus(403),
|
|
|
|
),
|
|
|
|
},
|
|
|
|
{
|
2022-11-16 23:36:01 +05:00
|
|
|
name: "host-val/peer",
|
|
|
|
isSelf: true,
|
|
|
|
debugCap: true,
|
2023-09-26 12:22:13 -05:00
|
|
|
reqs: []*http.Request{httptest.NewRequest("GET", "http://peer/v0/env", nil)},
|
2022-11-16 21:53:51 +05:00
|
|
|
checks: checks(
|
|
|
|
httpStatus(200),
|
|
|
|
),
|
|
|
|
},
|
2021-04-19 20:21:48 -07:00
|
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
2022-11-16 23:36:01 +05:00
|
|
|
selfNode := &tailcfg.Node{
|
|
|
|
Addresses: []netip.Prefix{
|
|
|
|
netip.MustParsePrefix("100.100.100.101/32"),
|
|
|
|
},
|
|
|
|
}
|
2022-11-17 00:07:21 +05:00
|
|
|
if tt.debugCap {
|
2024-03-23 16:23:59 -07:00
|
|
|
selfNode.CapMap = tailcfg.NodeCapMap{tailcfg.CapabilityDebug: nil}
|
2022-11-17 00:07:21 +05:00
|
|
|
}
|
2021-04-19 20:21:48 -07:00
|
|
|
var e peerAPITestEnv
|
|
|
|
lb := &LocalBackend{
|
2021-09-07 19:27:19 -07:00
|
|
|
logf: e.logBuf.Logf,
|
2021-04-22 09:25:00 +02:00
|
|
|
capFileSharing: tt.capSharing,
|
2023-08-21 10:53:57 -07:00
|
|
|
netMap: &netmap.NetworkMap{SelfNode: selfNode.View()},
|
2023-07-27 15:41:31 -04:00
|
|
|
clock: &tstest.Clock{},
|
2021-04-19 20:21:48 -07:00
|
|
|
}
|
|
|
|
e.ph = &peerAPIHandler{
|
2022-11-17 00:07:21 +05:00
|
|
|
isSelf: tt.isSelf,
|
2023-08-21 10:53:57 -07:00
|
|
|
selfNode: selfNode.View(),
|
2023-08-18 07:57:44 -07:00
|
|
|
peerNode: (&tailcfg.Node{
|
2021-04-19 20:21:48 -07:00
|
|
|
ComputedName: "some-peer-name",
|
2023-08-18 07:57:44 -07:00
|
|
|
}).View(),
|
2021-04-19 20:21:48 -07:00
|
|
|
ps: &peerAPIServer{
|
2022-11-17 00:07:21 +05:00
|
|
|
b: lb,
|
2021-04-19 20:21:48 -07:00
|
|
|
},
|
|
|
|
}
|
2023-09-26 12:22:13 -05:00
|
|
|
for _, req := range tt.reqs {
|
|
|
|
e.rr = httptest.NewRecorder()
|
|
|
|
if req.Host == "example.com" {
|
|
|
|
req.Host = "100.100.100.101:12345"
|
|
|
|
}
|
|
|
|
e.ph.ServeHTTP(e.rr, req)
|
2022-11-16 21:53:51 +05:00
|
|
|
}
|
2021-04-19 20:21:48 -07:00
|
|
|
for _, f := range tt.checks {
|
|
|
|
f(t, &e)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
2021-04-22 09:21:30 -07:00
|
|
|
|
2021-11-25 09:43:39 -08:00
|
|
|
func TestPeerAPIReplyToDNSQueries(t *testing.T) {
|
|
|
|
var h peerAPIHandler
|
|
|
|
|
|
|
|
h.isSelf = true
|
|
|
|
if !h.replyToDNSQueries() {
|
|
|
|
t.Errorf("for isSelf = false; want true")
|
|
|
|
}
|
|
|
|
h.isSelf = false
|
2022-07-25 20:55:44 -07:00
|
|
|
h.remoteAddr = netip.MustParseAddrPort("100.150.151.152:12345")
|
2021-11-25 09:43:39 -08:00
|
|
|
|
2025-03-19 10:47:25 -07:00
|
|
|
bus := eventbus.New()
|
|
|
|
defer bus.Close()
|
|
|
|
|
ipn/ipnlocal, all: plumb health trackers in tests
I saw some panics in CI, like:
2024-05-08T04:30:25.9553518Z ## WARNING: (non-fatal) nil health.Tracker (being strict in CI):
2024-05-08T04:30:25.9554043Z goroutine 801 [running]:
2024-05-08T04:30:25.9554489Z tailscale.com/health.(*Tracker).nil(0x0)
2024-05-08T04:30:25.9555086Z tailscale.com/health/health.go:185 +0x70
2024-05-08T04:30:25.9555688Z tailscale.com/health.(*Tracker).SetUDP4Unbound(0x0, 0x0)
2024-05-08T04:30:25.9556373Z tailscale.com/health/health.go:532 +0x2f
2024-05-08T04:30:25.9557296Z tailscale.com/wgengine/magicsock.(*Conn).bindSocket(0xc0003b4808, 0xc0003b4878, {0x1fbca53, 0x4}, 0x0)
2024-05-08T04:30:25.9558301Z tailscale.com/wgengine/magicsock/magicsock.go:2481 +0x12c5
2024-05-08T04:30:25.9559026Z tailscale.com/wgengine/magicsock.(*Conn).rebind(0xc0003b4808, 0x0)
2024-05-08T04:30:25.9559874Z tailscale.com/wgengine/magicsock/magicsock.go:2510 +0x16f
2024-05-08T04:30:25.9561038Z tailscale.com/wgengine/magicsock.NewConn({0xc000063c80, 0x0, 0xc000197930, 0xc000197950, 0xc000197960, {0x0, 0x0}, 0xc000197970, 0xc000198ee0, 0x0, ...})
2024-05-08T04:30:25.9562402Z tailscale.com/wgengine/magicsock/magicsock.go:476 +0xd5f
2024-05-08T04:30:25.9563779Z tailscale.com/wgengine.NewUserspaceEngine(0xc000063c80, {{0x22c8750, 0xc0001976b0}, 0x0, {0x22c3210, 0xc000063c80}, {0x22c31d8, 0x2d3c900}, 0x0, 0x0, ...})
2024-05-08T04:30:25.9564982Z tailscale.com/wgengine/userspace.go:389 +0x159d
2024-05-08T04:30:25.9565529Z tailscale.com/ipn/ipnlocal.newTestBackend(0xc000358b60)
2024-05-08T04:30:25.9566086Z tailscale.com/ipn/ipnlocal/serve_test.go:675 +0x2a5
2024-05-08T04:30:25.9566612Z ta
Updates #11874
Change-Id: I3432ed52d670743e532be4642f38dbd6e3763b1b
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-05-07 21:37:33 -07:00
|
|
|
ht := new(health.Tracker)
|
2024-09-23 18:34:00 +02:00
|
|
|
reg := new(usermetric.Registry)
|
2025-03-19 10:47:25 -07:00
|
|
|
eng, _ := wgengine.NewFakeUserspaceEngine(logger.Discard, 0, ht, reg, bus)
|
ipn/ipnlocal, all: plumb health trackers in tests
I saw some panics in CI, like:
2024-05-08T04:30:25.9553518Z ## WARNING: (non-fatal) nil health.Tracker (being strict in CI):
2024-05-08T04:30:25.9554043Z goroutine 801 [running]:
2024-05-08T04:30:25.9554489Z tailscale.com/health.(*Tracker).nil(0x0)
2024-05-08T04:30:25.9555086Z tailscale.com/health/health.go:185 +0x70
2024-05-08T04:30:25.9555688Z tailscale.com/health.(*Tracker).SetUDP4Unbound(0x0, 0x0)
2024-05-08T04:30:25.9556373Z tailscale.com/health/health.go:532 +0x2f
2024-05-08T04:30:25.9557296Z tailscale.com/wgengine/magicsock.(*Conn).bindSocket(0xc0003b4808, 0xc0003b4878, {0x1fbca53, 0x4}, 0x0)
2024-05-08T04:30:25.9558301Z tailscale.com/wgengine/magicsock/magicsock.go:2481 +0x12c5
2024-05-08T04:30:25.9559026Z tailscale.com/wgengine/magicsock.(*Conn).rebind(0xc0003b4808, 0x0)
2024-05-08T04:30:25.9559874Z tailscale.com/wgengine/magicsock/magicsock.go:2510 +0x16f
2024-05-08T04:30:25.9561038Z tailscale.com/wgengine/magicsock.NewConn({0xc000063c80, 0x0, 0xc000197930, 0xc000197950, 0xc000197960, {0x0, 0x0}, 0xc000197970, 0xc000198ee0, 0x0, ...})
2024-05-08T04:30:25.9562402Z tailscale.com/wgengine/magicsock/magicsock.go:476 +0xd5f
2024-05-08T04:30:25.9563779Z tailscale.com/wgengine.NewUserspaceEngine(0xc000063c80, {{0x22c8750, 0xc0001976b0}, 0x0, {0x22c3210, 0xc000063c80}, {0x22c31d8, 0x2d3c900}, 0x0, 0x0, ...})
2024-05-08T04:30:25.9564982Z tailscale.com/wgengine/userspace.go:389 +0x159d
2024-05-08T04:30:25.9565529Z tailscale.com/ipn/ipnlocal.newTestBackend(0xc000358b60)
2024-05-08T04:30:25.9566086Z tailscale.com/ipn/ipnlocal/serve_test.go:675 +0x2a5
2024-05-08T04:30:25.9566612Z ta
Updates #11874
Change-Id: I3432ed52d670743e532be4642f38dbd6e3763b1b
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-05-07 21:37:33 -07:00
|
|
|
pm := must.Get(newProfileManager(new(mem.Store), t.Logf, ht))
|
2021-11-25 09:43:39 -08:00
|
|
|
h.ps = &peerAPIServer{
|
|
|
|
b: &LocalBackend{
|
2022-11-09 10:58:10 +05:00
|
|
|
e: eng,
|
|
|
|
pm: pm,
|
|
|
|
store: pm.Store(),
|
2021-11-25 09:43:39 -08:00
|
|
|
},
|
|
|
|
}
|
|
|
|
if h.ps.b.OfferingExitNode() {
|
|
|
|
t.Fatal("unexpectedly offering exit node")
|
|
|
|
}
|
2022-11-09 10:58:10 +05:00
|
|
|
h.ps.b.pm.SetPrefs((&ipn.Prefs{
|
all: convert more code to use net/netip directly
perl -i -npe 's,netaddr.IPPrefixFrom,netip.PrefixFrom,' $(git grep -l -F netaddr.)
perl -i -npe 's,netaddr.IPPortFrom,netip.AddrPortFrom,' $(git grep -l -F netaddr. )
perl -i -npe 's,netaddr.IPPrefix,netip.Prefix,g' $(git grep -l -F netaddr. )
perl -i -npe 's,netaddr.IPPort,netip.AddrPort,g' $(git grep -l -F netaddr. )
perl -i -npe 's,netaddr.IP\b,netip.Addr,g' $(git grep -l -F netaddr. )
perl -i -npe 's,netaddr.IPv6Raw\b,netip.AddrFrom16,g' $(git grep -l -F netaddr. )
goimports -w .
Then delete some stuff from the net/netaddr shim package which is no
longer neeed.
Updates #5162
Change-Id: Ia7a86893fe21c7e3ee1ec823e8aba288d4566cd8
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2022-07-25 21:14:09 -07:00
|
|
|
AdvertiseRoutes: []netip.Prefix{
|
2022-07-25 20:55:44 -07:00
|
|
|
netip.MustParsePrefix("0.0.0.0/0"),
|
|
|
|
netip.MustParsePrefix("::/0"),
|
2021-11-25 09:43:39 -08:00
|
|
|
},
|
2023-11-16 21:40:23 -05:00
|
|
|
}).View(), ipn.NetworkProfile{})
|
2021-11-25 09:43:39 -08:00
|
|
|
if !h.ps.b.OfferingExitNode() {
|
|
|
|
t.Fatal("unexpectedly not offering exit node")
|
|
|
|
}
|
|
|
|
|
|
|
|
if h.replyToDNSQueries() {
|
|
|
|
t.Errorf("unexpectedly doing DNS without filter")
|
|
|
|
}
|
|
|
|
|
2022-07-24 20:08:42 -07:00
|
|
|
h.ps.b.setFilter(filter.NewAllowNone(logger.Discard, new(netipx.IPSet)))
|
2021-11-25 09:43:39 -08:00
|
|
|
if h.replyToDNSQueries() {
|
|
|
|
t.Errorf("unexpectedly doing DNS without filter")
|
|
|
|
}
|
|
|
|
|
|
|
|
f := filter.NewAllowAllForTest(logger.Discard)
|
|
|
|
|
|
|
|
h.ps.b.setFilter(f)
|
|
|
|
if !h.replyToDNSQueries() {
|
|
|
|
t.Errorf("unexpectedly deny; wanted to be a DNS server")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Also test IPv6.
|
2022-07-25 20:55:44 -07:00
|
|
|
h.remoteAddr = netip.MustParseAddrPort("[fe70::1]:12345")
|
2021-11-25 09:43:39 -08:00
|
|
|
if !h.replyToDNSQueries() {
|
|
|
|
t.Errorf("unexpectedly IPv6 deny; wanted to be a DNS server")
|
|
|
|
}
|
|
|
|
}
|
2023-10-27 14:20:10 -07:00
|
|
|
|
2024-01-31 13:49:52 -08:00
|
|
|
func TestPeerAPIPrettyReplyCNAME(t *testing.T) {
|
2024-04-11 10:12:13 -07:00
|
|
|
for _, shouldStore := range []bool{false, true} {
|
|
|
|
var h peerAPIHandler
|
|
|
|
h.remoteAddr = netip.MustParseAddrPort("100.150.151.152:12345")
|
|
|
|
|
2025-03-19 10:47:25 -07:00
|
|
|
bus := eventbus.New()
|
|
|
|
defer bus.Close()
|
|
|
|
|
ipn/ipnlocal, all: plumb health trackers in tests
I saw some panics in CI, like:
2024-05-08T04:30:25.9553518Z ## WARNING: (non-fatal) nil health.Tracker (being strict in CI):
2024-05-08T04:30:25.9554043Z goroutine 801 [running]:
2024-05-08T04:30:25.9554489Z tailscale.com/health.(*Tracker).nil(0x0)
2024-05-08T04:30:25.9555086Z tailscale.com/health/health.go:185 +0x70
2024-05-08T04:30:25.9555688Z tailscale.com/health.(*Tracker).SetUDP4Unbound(0x0, 0x0)
2024-05-08T04:30:25.9556373Z tailscale.com/health/health.go:532 +0x2f
2024-05-08T04:30:25.9557296Z tailscale.com/wgengine/magicsock.(*Conn).bindSocket(0xc0003b4808, 0xc0003b4878, {0x1fbca53, 0x4}, 0x0)
2024-05-08T04:30:25.9558301Z tailscale.com/wgengine/magicsock/magicsock.go:2481 +0x12c5
2024-05-08T04:30:25.9559026Z tailscale.com/wgengine/magicsock.(*Conn).rebind(0xc0003b4808, 0x0)
2024-05-08T04:30:25.9559874Z tailscale.com/wgengine/magicsock/magicsock.go:2510 +0x16f
2024-05-08T04:30:25.9561038Z tailscale.com/wgengine/magicsock.NewConn({0xc000063c80, 0x0, 0xc000197930, 0xc000197950, 0xc000197960, {0x0, 0x0}, 0xc000197970, 0xc000198ee0, 0x0, ...})
2024-05-08T04:30:25.9562402Z tailscale.com/wgengine/magicsock/magicsock.go:476 +0xd5f
2024-05-08T04:30:25.9563779Z tailscale.com/wgengine.NewUserspaceEngine(0xc000063c80, {{0x22c8750, 0xc0001976b0}, 0x0, {0x22c3210, 0xc000063c80}, {0x22c31d8, 0x2d3c900}, 0x0, 0x0, ...})
2024-05-08T04:30:25.9564982Z tailscale.com/wgengine/userspace.go:389 +0x159d
2024-05-08T04:30:25.9565529Z tailscale.com/ipn/ipnlocal.newTestBackend(0xc000358b60)
2024-05-08T04:30:25.9566086Z tailscale.com/ipn/ipnlocal/serve_test.go:675 +0x2a5
2024-05-08T04:30:25.9566612Z ta
Updates #11874
Change-Id: I3432ed52d670743e532be4642f38dbd6e3763b1b
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-05-07 21:37:33 -07:00
|
|
|
ht := new(health.Tracker)
|
2024-09-23 18:34:00 +02:00
|
|
|
reg := new(usermetric.Registry)
|
2025-03-19 10:47:25 -07:00
|
|
|
eng, _ := wgengine.NewFakeUserspaceEngine(logger.Discard, 0, ht, reg, bus)
|
ipn/ipnlocal, all: plumb health trackers in tests
I saw some panics in CI, like:
2024-05-08T04:30:25.9553518Z ## WARNING: (non-fatal) nil health.Tracker (being strict in CI):
2024-05-08T04:30:25.9554043Z goroutine 801 [running]:
2024-05-08T04:30:25.9554489Z tailscale.com/health.(*Tracker).nil(0x0)
2024-05-08T04:30:25.9555086Z tailscale.com/health/health.go:185 +0x70
2024-05-08T04:30:25.9555688Z tailscale.com/health.(*Tracker).SetUDP4Unbound(0x0, 0x0)
2024-05-08T04:30:25.9556373Z tailscale.com/health/health.go:532 +0x2f
2024-05-08T04:30:25.9557296Z tailscale.com/wgengine/magicsock.(*Conn).bindSocket(0xc0003b4808, 0xc0003b4878, {0x1fbca53, 0x4}, 0x0)
2024-05-08T04:30:25.9558301Z tailscale.com/wgengine/magicsock/magicsock.go:2481 +0x12c5
2024-05-08T04:30:25.9559026Z tailscale.com/wgengine/magicsock.(*Conn).rebind(0xc0003b4808, 0x0)
2024-05-08T04:30:25.9559874Z tailscale.com/wgengine/magicsock/magicsock.go:2510 +0x16f
2024-05-08T04:30:25.9561038Z tailscale.com/wgengine/magicsock.NewConn({0xc000063c80, 0x0, 0xc000197930, 0xc000197950, 0xc000197960, {0x0, 0x0}, 0xc000197970, 0xc000198ee0, 0x0, ...})
2024-05-08T04:30:25.9562402Z tailscale.com/wgengine/magicsock/magicsock.go:476 +0xd5f
2024-05-08T04:30:25.9563779Z tailscale.com/wgengine.NewUserspaceEngine(0xc000063c80, {{0x22c8750, 0xc0001976b0}, 0x0, {0x22c3210, 0xc000063c80}, {0x22c31d8, 0x2d3c900}, 0x0, 0x0, ...})
2024-05-08T04:30:25.9564982Z tailscale.com/wgengine/userspace.go:389 +0x159d
2024-05-08T04:30:25.9565529Z tailscale.com/ipn/ipnlocal.newTestBackend(0xc000358b60)
2024-05-08T04:30:25.9566086Z tailscale.com/ipn/ipnlocal/serve_test.go:675 +0x2a5
2024-05-08T04:30:25.9566612Z ta
Updates #11874
Change-Id: I3432ed52d670743e532be4642f38dbd6e3763b1b
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-05-07 21:37:33 -07:00
|
|
|
pm := must.Get(newProfileManager(new(mem.Store), t.Logf, ht))
|
2024-04-11 10:12:13 -07:00
|
|
|
var a *appc.AppConnector
|
|
|
|
if shouldStore {
|
|
|
|
a = appc.NewAppConnector(t.Logf, &appctest.RouteCollector{}, &appc.RouteInfo{}, fakeStoreRoutes)
|
|
|
|
} else {
|
|
|
|
a = appc.NewAppConnector(t.Logf, &appctest.RouteCollector{}, nil, nil)
|
|
|
|
}
|
|
|
|
h.ps = &peerAPIServer{
|
|
|
|
b: &LocalBackend{
|
|
|
|
e: eng,
|
|
|
|
pm: pm,
|
|
|
|
store: pm.Store(),
|
|
|
|
// configure as an app connector just to enable the API.
|
|
|
|
appConnector: a,
|
2024-01-31 13:49:52 -08:00
|
|
|
},
|
2024-04-11 10:12:13 -07:00
|
|
|
}
|
2024-01-31 13:49:52 -08:00
|
|
|
|
2024-04-11 10:12:13 -07:00
|
|
|
h.ps.resolver = &fakeResolver{build: func(b *dnsmessage.Builder) {
|
|
|
|
b.CNAMEResource(
|
|
|
|
dnsmessage.ResourceHeader{
|
|
|
|
Name: dnsmessage.MustNewName("www.example.com."),
|
|
|
|
Type: dnsmessage.TypeCNAME,
|
|
|
|
Class: dnsmessage.ClassINET,
|
|
|
|
TTL: 0,
|
|
|
|
},
|
|
|
|
dnsmessage.CNAMEResource{
|
|
|
|
CNAME: dnsmessage.MustNewName("example.com."),
|
|
|
|
},
|
|
|
|
)
|
|
|
|
b.AResource(
|
|
|
|
dnsmessage.ResourceHeader{
|
|
|
|
Name: dnsmessage.MustNewName("example.com."),
|
|
|
|
Type: dnsmessage.TypeA,
|
|
|
|
Class: dnsmessage.ClassINET,
|
|
|
|
TTL: 0,
|
|
|
|
},
|
|
|
|
dnsmessage.AResource{
|
|
|
|
A: [4]byte{192, 0, 0, 8},
|
|
|
|
},
|
|
|
|
)
|
|
|
|
}}
|
|
|
|
f := filter.NewAllowAllForTest(logger.Discard)
|
|
|
|
h.ps.b.setFilter(f)
|
2024-01-31 13:49:52 -08:00
|
|
|
|
2024-04-11 10:12:13 -07:00
|
|
|
if !h.replyToDNSQueries() {
|
|
|
|
t.Errorf("unexpectedly deny; wanted to be a DNS server")
|
|
|
|
}
|
|
|
|
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
h.handleDNSQuery(w, httptest.NewRequest("GET", "/dns-query?q=www.example.com.", nil))
|
|
|
|
if w.Code != http.StatusOK {
|
|
|
|
t.Errorf("unexpected status code: %v", w.Code)
|
|
|
|
}
|
|
|
|
var addrs []string
|
|
|
|
json.NewDecoder(w.Body).Decode(&addrs)
|
|
|
|
if len(addrs) == 0 {
|
|
|
|
t.Fatalf("no addresses returned")
|
|
|
|
}
|
|
|
|
for _, addr := range addrs {
|
|
|
|
netip.MustParseAddr(addr)
|
|
|
|
}
|
2024-01-31 13:49:52 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-27 14:20:10 -07:00
|
|
|
func TestPeerAPIReplyToDNSQueriesAreObserved(t *testing.T) {
|
2024-04-11 10:12:13 -07:00
|
|
|
for _, shouldStore := range []bool{false, true} {
|
|
|
|
ctx := context.Background()
|
|
|
|
var h peerAPIHandler
|
|
|
|
h.remoteAddr = netip.MustParseAddrPort("100.150.151.152:12345")
|
|
|
|
|
2025-03-19 10:47:25 -07:00
|
|
|
bus := eventbus.New()
|
|
|
|
defer bus.Close()
|
2024-04-11 10:12:13 -07:00
|
|
|
rc := &appctest.RouteCollector{}
|
ipn/ipnlocal, all: plumb health trackers in tests
I saw some panics in CI, like:
2024-05-08T04:30:25.9553518Z ## WARNING: (non-fatal) nil health.Tracker (being strict in CI):
2024-05-08T04:30:25.9554043Z goroutine 801 [running]:
2024-05-08T04:30:25.9554489Z tailscale.com/health.(*Tracker).nil(0x0)
2024-05-08T04:30:25.9555086Z tailscale.com/health/health.go:185 +0x70
2024-05-08T04:30:25.9555688Z tailscale.com/health.(*Tracker).SetUDP4Unbound(0x0, 0x0)
2024-05-08T04:30:25.9556373Z tailscale.com/health/health.go:532 +0x2f
2024-05-08T04:30:25.9557296Z tailscale.com/wgengine/magicsock.(*Conn).bindSocket(0xc0003b4808, 0xc0003b4878, {0x1fbca53, 0x4}, 0x0)
2024-05-08T04:30:25.9558301Z tailscale.com/wgengine/magicsock/magicsock.go:2481 +0x12c5
2024-05-08T04:30:25.9559026Z tailscale.com/wgengine/magicsock.(*Conn).rebind(0xc0003b4808, 0x0)
2024-05-08T04:30:25.9559874Z tailscale.com/wgengine/magicsock/magicsock.go:2510 +0x16f
2024-05-08T04:30:25.9561038Z tailscale.com/wgengine/magicsock.NewConn({0xc000063c80, 0x0, 0xc000197930, 0xc000197950, 0xc000197960, {0x0, 0x0}, 0xc000197970, 0xc000198ee0, 0x0, ...})
2024-05-08T04:30:25.9562402Z tailscale.com/wgengine/magicsock/magicsock.go:476 +0xd5f
2024-05-08T04:30:25.9563779Z tailscale.com/wgengine.NewUserspaceEngine(0xc000063c80, {{0x22c8750, 0xc0001976b0}, 0x0, {0x22c3210, 0xc000063c80}, {0x22c31d8, 0x2d3c900}, 0x0, 0x0, ...})
2024-05-08T04:30:25.9564982Z tailscale.com/wgengine/userspace.go:389 +0x159d
2024-05-08T04:30:25.9565529Z tailscale.com/ipn/ipnlocal.newTestBackend(0xc000358b60)
2024-05-08T04:30:25.9566086Z tailscale.com/ipn/ipnlocal/serve_test.go:675 +0x2a5
2024-05-08T04:30:25.9566612Z ta
Updates #11874
Change-Id: I3432ed52d670743e532be4642f38dbd6e3763b1b
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-05-07 21:37:33 -07:00
|
|
|
ht := new(health.Tracker)
|
2024-09-23 18:34:00 +02:00
|
|
|
reg := new(usermetric.Registry)
|
2025-03-19 10:47:25 -07:00
|
|
|
eng, _ := wgengine.NewFakeUserspaceEngine(logger.Discard, 0, ht, reg, bus)
|
ipn/ipnlocal, all: plumb health trackers in tests
I saw some panics in CI, like:
2024-05-08T04:30:25.9553518Z ## WARNING: (non-fatal) nil health.Tracker (being strict in CI):
2024-05-08T04:30:25.9554043Z goroutine 801 [running]:
2024-05-08T04:30:25.9554489Z tailscale.com/health.(*Tracker).nil(0x0)
2024-05-08T04:30:25.9555086Z tailscale.com/health/health.go:185 +0x70
2024-05-08T04:30:25.9555688Z tailscale.com/health.(*Tracker).SetUDP4Unbound(0x0, 0x0)
2024-05-08T04:30:25.9556373Z tailscale.com/health/health.go:532 +0x2f
2024-05-08T04:30:25.9557296Z tailscale.com/wgengine/magicsock.(*Conn).bindSocket(0xc0003b4808, 0xc0003b4878, {0x1fbca53, 0x4}, 0x0)
2024-05-08T04:30:25.9558301Z tailscale.com/wgengine/magicsock/magicsock.go:2481 +0x12c5
2024-05-08T04:30:25.9559026Z tailscale.com/wgengine/magicsock.(*Conn).rebind(0xc0003b4808, 0x0)
2024-05-08T04:30:25.9559874Z tailscale.com/wgengine/magicsock/magicsock.go:2510 +0x16f
2024-05-08T04:30:25.9561038Z tailscale.com/wgengine/magicsock.NewConn({0xc000063c80, 0x0, 0xc000197930, 0xc000197950, 0xc000197960, {0x0, 0x0}, 0xc000197970, 0xc000198ee0, 0x0, ...})
2024-05-08T04:30:25.9562402Z tailscale.com/wgengine/magicsock/magicsock.go:476 +0xd5f
2024-05-08T04:30:25.9563779Z tailscale.com/wgengine.NewUserspaceEngine(0xc000063c80, {{0x22c8750, 0xc0001976b0}, 0x0, {0x22c3210, 0xc000063c80}, {0x22c31d8, 0x2d3c900}, 0x0, 0x0, ...})
2024-05-08T04:30:25.9564982Z tailscale.com/wgengine/userspace.go:389 +0x159d
2024-05-08T04:30:25.9565529Z tailscale.com/ipn/ipnlocal.newTestBackend(0xc000358b60)
2024-05-08T04:30:25.9566086Z tailscale.com/ipn/ipnlocal/serve_test.go:675 +0x2a5
2024-05-08T04:30:25.9566612Z ta
Updates #11874
Change-Id: I3432ed52d670743e532be4642f38dbd6e3763b1b
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-05-07 21:37:33 -07:00
|
|
|
pm := must.Get(newProfileManager(new(mem.Store), t.Logf, ht))
|
2024-04-11 10:12:13 -07:00
|
|
|
var a *appc.AppConnector
|
|
|
|
if shouldStore {
|
|
|
|
a = appc.NewAppConnector(t.Logf, rc, &appc.RouteInfo{}, fakeStoreRoutes)
|
|
|
|
} else {
|
|
|
|
a = appc.NewAppConnector(t.Logf, rc, nil, nil)
|
|
|
|
}
|
|
|
|
h.ps = &peerAPIServer{
|
|
|
|
b: &LocalBackend{
|
|
|
|
e: eng,
|
|
|
|
pm: pm,
|
|
|
|
store: pm.Store(),
|
|
|
|
appConnector: a,
|
2024-01-31 13:49:52 -08:00
|
|
|
},
|
2024-04-11 10:12:13 -07:00
|
|
|
}
|
|
|
|
h.ps.b.appConnector.UpdateDomains([]string{"example.com"})
|
|
|
|
h.ps.b.appConnector.Wait(ctx)
|
|
|
|
|
|
|
|
h.ps.resolver = &fakeResolver{build: func(b *dnsmessage.Builder) {
|
|
|
|
b.AResource(
|
|
|
|
dnsmessage.ResourceHeader{
|
|
|
|
Name: dnsmessage.MustNewName("example.com."),
|
|
|
|
Type: dnsmessage.TypeA,
|
|
|
|
Class: dnsmessage.ClassINET,
|
|
|
|
TTL: 0,
|
|
|
|
},
|
|
|
|
dnsmessage.AResource{
|
|
|
|
A: [4]byte{192, 0, 0, 8},
|
|
|
|
},
|
|
|
|
)
|
|
|
|
}}
|
|
|
|
f := filter.NewAllowAllForTest(logger.Discard)
|
|
|
|
h.ps.b.setFilter(f)
|
2023-10-27 14:20:10 -07:00
|
|
|
|
2024-04-11 10:12:13 -07:00
|
|
|
if !h.ps.b.OfferingAppConnector() {
|
|
|
|
t.Fatal("expecting to be offering app connector")
|
|
|
|
}
|
|
|
|
if !h.replyToDNSQueries() {
|
|
|
|
t.Errorf("unexpectedly deny; wanted to be a DNS server")
|
|
|
|
}
|
2023-10-27 14:20:10 -07:00
|
|
|
|
2024-04-11 10:12:13 -07:00
|
|
|
w := httptest.NewRecorder()
|
|
|
|
h.handleDNSQuery(w, httptest.NewRequest("GET", "/dns-query?q=example.com.", nil))
|
|
|
|
if w.Code != http.StatusOK {
|
|
|
|
t.Errorf("unexpected status code: %v", w.Code)
|
|
|
|
}
|
|
|
|
h.ps.b.appConnector.Wait(ctx)
|
2023-10-27 14:20:10 -07:00
|
|
|
|
2024-04-11 10:12:13 -07:00
|
|
|
wantRoutes := []netip.Prefix{netip.MustParsePrefix("192.0.0.8/32")}
|
|
|
|
if !slices.Equal(rc.Routes(), wantRoutes) {
|
|
|
|
t.Errorf("got %v; want %v", rc.Routes(), wantRoutes)
|
|
|
|
}
|
2023-10-27 14:20:10 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-31 14:33:14 -08:00
|
|
|
func TestPeerAPIReplyToDNSQueriesAreObservedWithCNAMEFlattening(t *testing.T) {
|
2024-04-11 10:12:13 -07:00
|
|
|
for _, shouldStore := range []bool{false, true} {
|
|
|
|
ctx := context.Background()
|
|
|
|
var h peerAPIHandler
|
|
|
|
h.remoteAddr = netip.MustParseAddrPort("100.150.151.152:12345")
|
|
|
|
|
2025-03-19 10:47:25 -07:00
|
|
|
bus := eventbus.New()
|
|
|
|
defer bus.Close()
|
ipn/ipnlocal, all: plumb health trackers in tests
I saw some panics in CI, like:
2024-05-08T04:30:25.9553518Z ## WARNING: (non-fatal) nil health.Tracker (being strict in CI):
2024-05-08T04:30:25.9554043Z goroutine 801 [running]:
2024-05-08T04:30:25.9554489Z tailscale.com/health.(*Tracker).nil(0x0)
2024-05-08T04:30:25.9555086Z tailscale.com/health/health.go:185 +0x70
2024-05-08T04:30:25.9555688Z tailscale.com/health.(*Tracker).SetUDP4Unbound(0x0, 0x0)
2024-05-08T04:30:25.9556373Z tailscale.com/health/health.go:532 +0x2f
2024-05-08T04:30:25.9557296Z tailscale.com/wgengine/magicsock.(*Conn).bindSocket(0xc0003b4808, 0xc0003b4878, {0x1fbca53, 0x4}, 0x0)
2024-05-08T04:30:25.9558301Z tailscale.com/wgengine/magicsock/magicsock.go:2481 +0x12c5
2024-05-08T04:30:25.9559026Z tailscale.com/wgengine/magicsock.(*Conn).rebind(0xc0003b4808, 0x0)
2024-05-08T04:30:25.9559874Z tailscale.com/wgengine/magicsock/magicsock.go:2510 +0x16f
2024-05-08T04:30:25.9561038Z tailscale.com/wgengine/magicsock.NewConn({0xc000063c80, 0x0, 0xc000197930, 0xc000197950, 0xc000197960, {0x0, 0x0}, 0xc000197970, 0xc000198ee0, 0x0, ...})
2024-05-08T04:30:25.9562402Z tailscale.com/wgengine/magicsock/magicsock.go:476 +0xd5f
2024-05-08T04:30:25.9563779Z tailscale.com/wgengine.NewUserspaceEngine(0xc000063c80, {{0x22c8750, 0xc0001976b0}, 0x0, {0x22c3210, 0xc000063c80}, {0x22c31d8, 0x2d3c900}, 0x0, 0x0, ...})
2024-05-08T04:30:25.9564982Z tailscale.com/wgengine/userspace.go:389 +0x159d
2024-05-08T04:30:25.9565529Z tailscale.com/ipn/ipnlocal.newTestBackend(0xc000358b60)
2024-05-08T04:30:25.9566086Z tailscale.com/ipn/ipnlocal/serve_test.go:675 +0x2a5
2024-05-08T04:30:25.9566612Z ta
Updates #11874
Change-Id: I3432ed52d670743e532be4642f38dbd6e3763b1b
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-05-07 21:37:33 -07:00
|
|
|
ht := new(health.Tracker)
|
2024-09-23 18:34:00 +02:00
|
|
|
reg := new(usermetric.Registry)
|
2024-04-11 10:12:13 -07:00
|
|
|
rc := &appctest.RouteCollector{}
|
2025-03-19 10:47:25 -07:00
|
|
|
eng, _ := wgengine.NewFakeUserspaceEngine(logger.Discard, 0, ht, reg, bus)
|
ipn/ipnlocal, all: plumb health trackers in tests
I saw some panics in CI, like:
2024-05-08T04:30:25.9553518Z ## WARNING: (non-fatal) nil health.Tracker (being strict in CI):
2024-05-08T04:30:25.9554043Z goroutine 801 [running]:
2024-05-08T04:30:25.9554489Z tailscale.com/health.(*Tracker).nil(0x0)
2024-05-08T04:30:25.9555086Z tailscale.com/health/health.go:185 +0x70
2024-05-08T04:30:25.9555688Z tailscale.com/health.(*Tracker).SetUDP4Unbound(0x0, 0x0)
2024-05-08T04:30:25.9556373Z tailscale.com/health/health.go:532 +0x2f
2024-05-08T04:30:25.9557296Z tailscale.com/wgengine/magicsock.(*Conn).bindSocket(0xc0003b4808, 0xc0003b4878, {0x1fbca53, 0x4}, 0x0)
2024-05-08T04:30:25.9558301Z tailscale.com/wgengine/magicsock/magicsock.go:2481 +0x12c5
2024-05-08T04:30:25.9559026Z tailscale.com/wgengine/magicsock.(*Conn).rebind(0xc0003b4808, 0x0)
2024-05-08T04:30:25.9559874Z tailscale.com/wgengine/magicsock/magicsock.go:2510 +0x16f
2024-05-08T04:30:25.9561038Z tailscale.com/wgengine/magicsock.NewConn({0xc000063c80, 0x0, 0xc000197930, 0xc000197950, 0xc000197960, {0x0, 0x0}, 0xc000197970, 0xc000198ee0, 0x0, ...})
2024-05-08T04:30:25.9562402Z tailscale.com/wgengine/magicsock/magicsock.go:476 +0xd5f
2024-05-08T04:30:25.9563779Z tailscale.com/wgengine.NewUserspaceEngine(0xc000063c80, {{0x22c8750, 0xc0001976b0}, 0x0, {0x22c3210, 0xc000063c80}, {0x22c31d8, 0x2d3c900}, 0x0, 0x0, ...})
2024-05-08T04:30:25.9564982Z tailscale.com/wgengine/userspace.go:389 +0x159d
2024-05-08T04:30:25.9565529Z tailscale.com/ipn/ipnlocal.newTestBackend(0xc000358b60)
2024-05-08T04:30:25.9566086Z tailscale.com/ipn/ipnlocal/serve_test.go:675 +0x2a5
2024-05-08T04:30:25.9566612Z ta
Updates #11874
Change-Id: I3432ed52d670743e532be4642f38dbd6e3763b1b
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-05-07 21:37:33 -07:00
|
|
|
pm := must.Get(newProfileManager(new(mem.Store), t.Logf, ht))
|
2024-04-11 10:12:13 -07:00
|
|
|
var a *appc.AppConnector
|
|
|
|
if shouldStore {
|
|
|
|
a = appc.NewAppConnector(t.Logf, rc, &appc.RouteInfo{}, fakeStoreRoutes)
|
|
|
|
} else {
|
|
|
|
a = appc.NewAppConnector(t.Logf, rc, nil, nil)
|
|
|
|
}
|
|
|
|
h.ps = &peerAPIServer{
|
|
|
|
b: &LocalBackend{
|
|
|
|
e: eng,
|
|
|
|
pm: pm,
|
|
|
|
store: pm.Store(),
|
|
|
|
appConnector: a,
|
2024-01-31 14:33:14 -08:00
|
|
|
},
|
2024-04-11 10:12:13 -07:00
|
|
|
}
|
|
|
|
h.ps.b.appConnector.UpdateDomains([]string{"www.example.com"})
|
|
|
|
h.ps.b.appConnector.Wait(ctx)
|
|
|
|
|
|
|
|
h.ps.resolver = &fakeResolver{build: func(b *dnsmessage.Builder) {
|
|
|
|
b.CNAMEResource(
|
|
|
|
dnsmessage.ResourceHeader{
|
|
|
|
Name: dnsmessage.MustNewName("www.example.com."),
|
|
|
|
Type: dnsmessage.TypeCNAME,
|
|
|
|
Class: dnsmessage.ClassINET,
|
|
|
|
TTL: 0,
|
|
|
|
},
|
|
|
|
dnsmessage.CNAMEResource{
|
|
|
|
CNAME: dnsmessage.MustNewName("example.com."),
|
|
|
|
},
|
|
|
|
)
|
|
|
|
b.AResource(
|
|
|
|
dnsmessage.ResourceHeader{
|
|
|
|
Name: dnsmessage.MustNewName("example.com."),
|
|
|
|
Type: dnsmessage.TypeA,
|
|
|
|
Class: dnsmessage.ClassINET,
|
|
|
|
TTL: 0,
|
|
|
|
},
|
|
|
|
dnsmessage.AResource{
|
|
|
|
A: [4]byte{192, 0, 0, 8},
|
|
|
|
},
|
|
|
|
)
|
|
|
|
}}
|
|
|
|
f := filter.NewAllowAllForTest(logger.Discard)
|
|
|
|
h.ps.b.setFilter(f)
|
2024-01-31 14:33:14 -08:00
|
|
|
|
2024-04-11 10:12:13 -07:00
|
|
|
if !h.ps.b.OfferingAppConnector() {
|
|
|
|
t.Fatal("expecting to be offering app connector")
|
|
|
|
}
|
|
|
|
if !h.replyToDNSQueries() {
|
|
|
|
t.Errorf("unexpectedly deny; wanted to be a DNS server")
|
|
|
|
}
|
2024-01-31 14:33:14 -08:00
|
|
|
|
2024-04-11 10:12:13 -07:00
|
|
|
w := httptest.NewRecorder()
|
|
|
|
h.handleDNSQuery(w, httptest.NewRequest("GET", "/dns-query?q=www.example.com.", nil))
|
|
|
|
if w.Code != http.StatusOK {
|
|
|
|
t.Errorf("unexpected status code: %v", w.Code)
|
|
|
|
}
|
|
|
|
h.ps.b.appConnector.Wait(ctx)
|
2024-01-31 14:33:14 -08:00
|
|
|
|
2024-04-11 10:12:13 -07:00
|
|
|
wantRoutes := []netip.Prefix{netip.MustParsePrefix("192.0.0.8/32")}
|
|
|
|
if !slices.Equal(rc.Routes(), wantRoutes) {
|
|
|
|
t.Errorf("got %v; want %v", rc.Routes(), wantRoutes)
|
|
|
|
}
|
2024-01-31 14:33:14 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-31 13:49:52 -08:00
|
|
|
type fakeResolver struct {
|
|
|
|
build func(*dnsmessage.Builder)
|
|
|
|
}
|
2023-10-27 14:20:10 -07:00
|
|
|
|
|
|
|
func (f *fakeResolver) HandlePeerDNSQuery(ctx context.Context, q []byte, from netip.AddrPort, allowName func(name string) bool) (res []byte, err error) {
|
|
|
|
b := dnsmessage.NewBuilder(nil, dnsmessage.Header{})
|
|
|
|
b.EnableCompression()
|
|
|
|
b.StartAnswers()
|
2024-01-31 13:49:52 -08:00
|
|
|
f.build(&b)
|
2023-10-27 14:20:10 -07:00
|
|
|
return b.Finish()
|
|
|
|
}
|