mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-25 19:15:34 +00:00
net/dns/resolver: add envknob to debug exit node DNS queries on on Windows
Add the envknob TS_DEBUG_EXIT_NODE_DNS_NET_PKG, which enables more verbose debug logging when calling the handleExitNodeDNSQueryWithNetPkg function. This function is currently only called on Windows and Android. Signed-off-by: Andrew Dunham <andrew@du.nham.ca> Change-Id: Ieb3ca7b98837d7dc69cd9ca47609c1c52e3afd7b
This commit is contained in:
parent
d2301db49c
commit
880a41bfcc
@ -23,6 +23,7 @@
|
||||
"time"
|
||||
|
||||
dns "golang.org/x/net/dns/dnsmessage"
|
||||
"tailscale.com/envknob"
|
||||
"tailscale.com/net/dns/resolvconffile"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/net/tsaddr"
|
||||
@ -341,7 +342,7 @@ func (r *Resolver) HandleExitNodeDNSQuery(ctx context.Context, q []byte, from ne
|
||||
default:
|
||||
return nil, errors.New("unsupported exit node OS")
|
||||
case "windows", "android":
|
||||
return handleExitNodeDNSQueryWithNetPkg(ctx, nil, resp)
|
||||
return handleExitNodeDNSQueryWithNetPkg(ctx, r.logf, nil, resp)
|
||||
case "darwin":
|
||||
// /etc/resolv.conf is a lie and only says one upstream DNS
|
||||
// but for now that's probably good enough. Later we'll
|
||||
@ -385,6 +386,8 @@ func (r *Resolver) HandleExitNodeDNSQuery(ctx context.Context, q []byte, from ne
|
||||
}
|
||||
}
|
||||
|
||||
var debugExitNodeDNSNetPkg = envknob.RegisterBool("TS_DEBUG_EXIT_NODE_DNS_NET_PKG")
|
||||
|
||||
// handleExitNodeDNSQueryWithNetPkg takes a DNS query message in q and
|
||||
// return a reply (for the ExitDNS DoH service) using the net package's
|
||||
// native APIs. This is only used on Windows for now.
|
||||
@ -393,7 +396,8 @@ func (r *Resolver) HandleExitNodeDNSQuery(ctx context.Context, q []byte, from ne
|
||||
//
|
||||
// response contains the pre-serialized response, which notably
|
||||
// includes the original question and its header.
|
||||
func handleExitNodeDNSQueryWithNetPkg(ctx context.Context, resolver *net.Resolver, resp *response) (res []byte, err error) {
|
||||
func handleExitNodeDNSQueryWithNetPkg(ctx context.Context, logf logger.Logf, resolver *net.Resolver, resp *response) (res []byte, err error) {
|
||||
logf = logger.WithPrefix(logf, "exitNodeDNSQueryWithNetPkg: ")
|
||||
if resp.Question.Class != dns.ClassINET {
|
||||
return nil, errors.New("unsupported class")
|
||||
}
|
||||
@ -406,9 +410,16 @@ func handleExitNodeDNSQueryWithNetPkg(ctx context.Context, resolver *net.Resolve
|
||||
|
||||
handleError := func(err error) (res []byte, _ error) {
|
||||
if isGoNoSuchHostError(err) {
|
||||
if debugExitNodeDNSNetPkg() {
|
||||
logf(`converting Go "no such host" error to a NXDOMAIN: %v`, err)
|
||||
}
|
||||
resp.Header.RCode = dns.RCodeNameError
|
||||
return marshalResponse(resp)
|
||||
}
|
||||
|
||||
if debugExitNodeDNSNetPkg() {
|
||||
logf("returning error: %v", err)
|
||||
}
|
||||
// TODO: map other errors to RCodeServerFailure?
|
||||
// Or I guess our caller should do that?
|
||||
return nil, err
|
||||
@ -422,6 +433,9 @@ func handleExitNodeDNSQueryWithNetPkg(ctx context.Context, resolver *net.Resolve
|
||||
if resp.Question.Type == dns.TypeAAAA {
|
||||
network = "ip6"
|
||||
}
|
||||
if debugExitNodeDNSNetPkg() {
|
||||
logf("resolving %s %q", network, name)
|
||||
}
|
||||
ips, err := r.LookupIP(ctx, network, name)
|
||||
if err != nil {
|
||||
return handleError(err)
|
||||
@ -432,6 +446,9 @@ func handleExitNodeDNSQueryWithNetPkg(ctx context.Context, resolver *net.Resolve
|
||||
}
|
||||
}
|
||||
case dns.TypeTXT:
|
||||
if debugExitNodeDNSNetPkg() {
|
||||
logf("resolving TXT %q", name)
|
||||
}
|
||||
strs, err := r.LookupTXT(ctx, name)
|
||||
if err != nil {
|
||||
return handleError(err)
|
||||
@ -443,6 +460,9 @@ func handleExitNodeDNSQueryWithNetPkg(ctx context.Context, resolver *net.Resolve
|
||||
// TODO: is this RCodeFormatError?
|
||||
return nil, errors.New("bogus PTR name")
|
||||
}
|
||||
if debugExitNodeDNSNetPkg() {
|
||||
logf("resolving PTR %q", ipStr)
|
||||
}
|
||||
addrs, err := r.LookupAddr(ctx, ipStr)
|
||||
if err != nil {
|
||||
return handleError(err)
|
||||
@ -451,12 +471,18 @@ func handleExitNodeDNSQueryWithNetPkg(ctx context.Context, resolver *net.Resolve
|
||||
resp.Name, _ = dnsname.ToFQDN(addrs[0])
|
||||
}
|
||||
case dns.TypeCNAME:
|
||||
if debugExitNodeDNSNetPkg() {
|
||||
logf("resolving CNAME %q", name)
|
||||
}
|
||||
cname, err := r.LookupCNAME(ctx, name)
|
||||
if err != nil {
|
||||
return handleError(err)
|
||||
}
|
||||
resp.CNAME = cname
|
||||
case dns.TypeSRV:
|
||||
if debugExitNodeDNSNetPkg() {
|
||||
logf("resolving SRV %q", name)
|
||||
}
|
||||
// Thanks, Go: "To accommodate services publishing SRV
|
||||
// records under non-standard names, if both service
|
||||
// and proto are empty strings, LookupSRV looks up
|
||||
@ -467,6 +493,9 @@ func handleExitNodeDNSQueryWithNetPkg(ctx context.Context, resolver *net.Resolve
|
||||
}
|
||||
resp.SRVs = srvs
|
||||
case dns.TypeNS:
|
||||
if debugExitNodeDNSNetPkg() {
|
||||
logf("resolving NS %q", name)
|
||||
}
|
||||
nss, err := r.LookupNS(ctx, name)
|
||||
if err != nil {
|
||||
return handleError(err)
|
||||
|
@ -10,6 +10,7 @@
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/netip"
|
||||
@ -1122,7 +1123,7 @@ func TestHandleExitNodeDNSQueryWithNetPkg(t *testing.T) {
|
||||
}
|
||||
|
||||
t.Run("no_such_host", func(t *testing.T) {
|
||||
res, err := handleExitNodeDNSQueryWithNetPkg(context.Background(), backResolver, &response{
|
||||
res, err := handleExitNodeDNSQueryWithNetPkg(context.Background(), t.Logf, backResolver, &response{
|
||||
Header: dnsmessage.Header{
|
||||
ID: 123,
|
||||
Response: true,
|
||||
@ -1233,7 +1234,7 @@ func TestHandleExitNodeDNSQueryWithNetPkg(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(fmt.Sprintf("%v_%v", tt.Type, strings.Trim(tt.Name, ".")), func(t *testing.T) {
|
||||
got, err := handleExitNodeDNSQueryWithNetPkg(context.Background(), backResolver, &response{
|
||||
got, err := handleExitNodeDNSQueryWithNetPkg(context.Background(), t.Logf, backResolver, &response{
|
||||
Header: dnsmessage.Header{
|
||||
ID: 123,
|
||||
Response: true,
|
||||
@ -1395,7 +1396,7 @@ func (a *wrapResolverConn) WriteTo(q []byte, _ net.Addr) (n int, err error) {
|
||||
if resp == nil {
|
||||
return 0, errors.New("bad query")
|
||||
}
|
||||
res, err := handleExitNodeDNSQueryWithNetPkg(context.Background(), a.r, resp)
|
||||
res, err := handleExitNodeDNSQueryWithNetPkg(context.Background(), log.Printf, a.r, resp)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user