mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-26 11:35:35 +00:00
62 lines
1.7 KiB
Go
62 lines
1.7 KiB
Go
|
// Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved.
|
||
|
// Use of this source code is governed by a BSD-style
|
||
|
// license that can be found in the LICENSE file.
|
||
|
|
||
|
// Package tsdial provides a Dialer type that can dial out of tailscaled.
|
||
|
package tsdial
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"errors"
|
||
|
"net"
|
||
|
"sync"
|
||
|
|
||
|
"inet.af/netaddr"
|
||
|
)
|
||
|
|
||
|
// Dialer dials out of tailscaled, while taking care of details while
|
||
|
// handling the dozens of edge cases depending on the server mode
|
||
|
// (TUN, netstack), the OS network sandboxing style (macOS/iOS
|
||
|
// Extension, none), user-selected route acceptance prefs, etc.
|
||
|
type Dialer struct {
|
||
|
// UseNetstackForIP if non-nil is whether NetstackDialTCP (if
|
||
|
// it's non-nil) should be used to dial the provided IP.
|
||
|
UseNetstackForIP func(netaddr.IP) bool
|
||
|
|
||
|
// NetstackDialTCP dials the provided IPPort using netstack.
|
||
|
// If nil, it's not used.
|
||
|
NetstackDialTCP func(context.Context, netaddr.IPPort) (net.Conn, error)
|
||
|
|
||
|
mu sync.Mutex
|
||
|
dns DNSMap
|
||
|
}
|
||
|
|
||
|
func (d *Dialer) SetDNSMap(m DNSMap) {
|
||
|
d.mu.Lock()
|
||
|
defer d.mu.Unlock()
|
||
|
d.dns = m
|
||
|
}
|
||
|
|
||
|
func (d *Dialer) resolve(ctx context.Context, addr string) (netaddr.IPPort, error) {
|
||
|
d.mu.Lock()
|
||
|
dns := d.dns
|
||
|
d.mu.Unlock()
|
||
|
return dns.Resolve(ctx, addr)
|
||
|
}
|
||
|
|
||
|
func (d *Dialer) DialContext(ctx context.Context, network, addr string) (net.Conn, error) {
|
||
|
ipp, err := d.resolve(ctx, addr)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
if d.UseNetstackForIP != nil && d.UseNetstackForIP(ipp.IP()) {
|
||
|
if d.NetstackDialTCP == nil {
|
||
|
return nil, errors.New("Dialer not initialized correctly")
|
||
|
}
|
||
|
return d.NetstackDialTCP(ctx, ipp)
|
||
|
}
|
||
|
// TODO(bradfitz): netns, etc
|
||
|
var stdDialer net.Dialer
|
||
|
return stdDialer.DialContext(ctx, network, ipp.String())
|
||
|
}
|