mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-11 21:27:31 +00:00
net/tsdial: move more weirdo dialing into new tsdial package, plumb
Not done yet, but this move more of the outbound dial special casing from random packages into tsdial, which aspires to be the one unified place for all outbound dialing shenanigans. Then this plumbs it all around, so everybody is ultimately holding on to the same dialer. As of this commit, macOS/iOS using an exit node should be able to reach to the exit node's DoH DNS proxy over peerapi, doing the sockopt to stay within the Network Extension. A number of steps remain, including but limited to: * move a bunch more random dialing stuff * make netstack-mode tailscaled be able to use exit node's DNS proxy, teaching tsdial's resolver to use it when an exit node is in use. Updates #1713 Change-Id: I1e8ee378f125421c2b816f47bc2c6d913ddcd2f5 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:

committed by
Brad Fitzpatrick

parent
bf1d69f25b
commit
c37af58ea4
@@ -13,6 +13,7 @@ import (
|
||||
"tailscale.com/health"
|
||||
"tailscale.com/net/dns/resolver"
|
||||
"tailscale.com/net/tsaddr"
|
||||
"tailscale.com/net/tsdial"
|
||||
"tailscale.com/types/dnstype"
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/util/dnsname"
|
||||
@@ -39,11 +40,14 @@ type Manager struct {
|
||||
}
|
||||
|
||||
// NewManagers created a new manager from the given config.
|
||||
func NewManager(logf logger.Logf, oscfg OSConfigurator, linkMon *monitor.Mon, linkSel resolver.ForwardLinkSelector) *Manager {
|
||||
func NewManager(logf logger.Logf, oscfg OSConfigurator, linkMon *monitor.Mon, dialer *tsdial.Dialer, linkSel resolver.ForwardLinkSelector) *Manager {
|
||||
if dialer == nil {
|
||||
panic("nil Dialer")
|
||||
}
|
||||
logf = logger.WithPrefix(logf, "dns: ")
|
||||
m := &Manager{
|
||||
logf: logf,
|
||||
resolver: resolver.New(logf, linkMon, linkSel),
|
||||
resolver: resolver.New(logf, linkMon, linkSel, dialer),
|
||||
os: oscfg,
|
||||
}
|
||||
m.logf("using %T", m.os)
|
||||
@@ -230,7 +234,7 @@ func Cleanup(logf logger.Logf, interfaceName string) {
|
||||
logf("creating dns cleanup: %v", err)
|
||||
return
|
||||
}
|
||||
dns := NewManager(logf, oscfg, nil, nil)
|
||||
dns := NewManager(logf, oscfg, nil, new(tsdial.Dialer), nil)
|
||||
if err := dns.Down(); err != nil {
|
||||
logf("dns down: %v", err)
|
||||
}
|
||||
|
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/dns/resolver"
|
||||
"tailscale.com/net/tsdial"
|
||||
"tailscale.com/types/dnstype"
|
||||
"tailscale.com/util/dnsname"
|
||||
)
|
||||
@@ -398,7 +399,7 @@ func TestManager(t *testing.T) {
|
||||
SplitDNS: test.split,
|
||||
BaseConfig: test.bs,
|
||||
}
|
||||
m := NewManager(t.Logf, &f, nil, nil)
|
||||
m := NewManager(t.Logf, &f, nil, new(tsdial.Dialer), nil)
|
||||
m.resolver.TestOnlySetHook(f.SetResolver)
|
||||
|
||||
if err := m.Set(test.in); err != nil {
|
||||
|
@@ -26,6 +26,7 @@ import (
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/hostinfo"
|
||||
"tailscale.com/net/netns"
|
||||
"tailscale.com/net/tsdial"
|
||||
"tailscale.com/types/dnstype"
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/util/dnsname"
|
||||
@@ -159,7 +160,8 @@ type resolverAndDelay struct {
|
||||
type forwarder struct {
|
||||
logf logger.Logf
|
||||
linkMon *monitor.Mon
|
||||
linkSel ForwardLinkSelector
|
||||
linkSel ForwardLinkSelector // TODO(bradfitz): remove this when tsdial.Dialer absords it
|
||||
dialer *tsdial.Dialer
|
||||
dohSem chan struct{}
|
||||
|
||||
ctx context.Context // good until Close
|
||||
@@ -205,11 +207,12 @@ func maxDoHInFlight(goos string) int {
|
||||
return 1000
|
||||
}
|
||||
|
||||
func newForwarder(logf logger.Logf, responses chan packet, linkMon *monitor.Mon, linkSel ForwardLinkSelector) *forwarder {
|
||||
func newForwarder(logf logger.Logf, responses chan packet, linkMon *monitor.Mon, linkSel ForwardLinkSelector, dialer *tsdial.Dialer) *forwarder {
|
||||
f := &forwarder{
|
||||
logf: logger.WithPrefix(logf, "forward: "),
|
||||
linkMon: linkMon,
|
||||
linkSel: linkSel,
|
||||
dialer: dialer,
|
||||
responses: responses,
|
||||
dohSem: make(chan struct{}, maxDoHInFlight(runtime.GOOS)),
|
||||
}
|
||||
@@ -423,10 +426,7 @@ func (f *forwarder) sendDoH(ctx context.Context, urlBase string, c *http.Client,
|
||||
// send expects the reply to have the same txid as txidOut.
|
||||
func (f *forwarder) send(ctx context.Context, fq *forwardQuery, rr resolverAndDelay) ([]byte, error) {
|
||||
if strings.HasPrefix(rr.name.Addr, "http://") {
|
||||
// TODO(bradfitz): this only work for TUN mode right now; plumb a universal dialer
|
||||
// that can handle the dozen special cases for modes/platforms/routes.
|
||||
TODOHTTPClient := http.DefaultClient
|
||||
return f.sendDoH(ctx, rr.name.Addr, TODOHTTPClient, fq.packet)
|
||||
return f.sendDoH(ctx, rr.name.Addr, f.dialer.PeerAPIHTTPClient(), fq.packet)
|
||||
}
|
||||
if strings.HasPrefix(rr.name.Addr, "https://") {
|
||||
metricDNSFwdErrorType.Add(1)
|
||||
|
@@ -27,6 +27,7 @@ import (
|
||||
dns "golang.org/x/net/dns/dnsmessage"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/tsaddr"
|
||||
"tailscale.com/net/tsdial"
|
||||
"tailscale.com/types/dnstype"
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/util/clientmetric"
|
||||
@@ -192,6 +193,7 @@ func WriteRoutes(w *bufio.Writer, routes map[dnsname.FQDN][]dnstype.Resolver) {
|
||||
type Resolver struct {
|
||||
logf logger.Logf
|
||||
linkMon *monitor.Mon // or nil
|
||||
dialer *tsdial.Dialer // non-nil
|
||||
saveConfigForTests func(cfg Config) // used in tests to capture resolver config
|
||||
// forwarder forwards requests to upstream nameservers.
|
||||
forwarder *forwarder
|
||||
@@ -223,7 +225,10 @@ type ForwardLinkSelector interface {
|
||||
|
||||
// New returns a new resolver.
|
||||
// linkMon optionally specifies a link monitor to use for socket rebinding.
|
||||
func New(logf logger.Logf, linkMon *monitor.Mon, linkSel ForwardLinkSelector) *Resolver {
|
||||
func New(logf logger.Logf, linkMon *monitor.Mon, linkSel ForwardLinkSelector, dialer *tsdial.Dialer) *Resolver {
|
||||
if dialer == nil {
|
||||
panic("nil Dialer")
|
||||
}
|
||||
r := &Resolver{
|
||||
logf: logger.WithPrefix(logf, "resolver: "),
|
||||
linkMon: linkMon,
|
||||
@@ -232,8 +237,9 @@ func New(logf logger.Logf, linkMon *monitor.Mon, linkSel ForwardLinkSelector) *R
|
||||
closed: make(chan struct{}),
|
||||
hostToIP: map[dnsname.FQDN][]netaddr.IP{},
|
||||
ipToHost: map[netaddr.IP]dnsname.FQDN{},
|
||||
dialer: dialer,
|
||||
}
|
||||
r.forwarder = newForwarder(r.logf, r.responses, linkMon, linkSel)
|
||||
r.forwarder = newForwarder(r.logf, r.responses, linkMon, linkSel, dialer)
|
||||
return r
|
||||
}
|
||||
|
||||
|
@@ -18,6 +18,7 @@ import (
|
||||
|
||||
dns "golang.org/x/net/dns/dnsmessage"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/tsdial"
|
||||
"tailscale.com/tstest"
|
||||
"tailscale.com/types/dnstype"
|
||||
"tailscale.com/util/dnsname"
|
||||
@@ -308,7 +309,7 @@ func TestRDNSNameToIPv6(t *testing.T) {
|
||||
}
|
||||
|
||||
func newResolver(t testing.TB) *Resolver {
|
||||
return New(t.Logf, nil /* no link monitor */, nil /* no link selector */)
|
||||
return New(t.Logf, nil /* no link monitor */, nil /* no link selector */, new(tsdial.Dialer))
|
||||
}
|
||||
|
||||
func TestResolveLocal(t *testing.T) {
|
||||
@@ -1062,7 +1063,7 @@ func TestForwardLinkSelection(t *testing.T) {
|
||||
return "special"
|
||||
}
|
||||
return ""
|
||||
}))
|
||||
}), new(tsdial.Dialer))
|
||||
|
||||
// Test non-special IP.
|
||||
if got, err := fwd.packetListener(netaddr.IP{}); err != nil {
|
||||
|
Reference in New Issue
Block a user