mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-25 19:15:34 +00:00
net/socks5/tssocks: add a SOCKS5 dialer type, method-ifying code
https://twitter.com/bradfitz/status/1409605220376580097 Prep for #1970, #2264, #2268 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
3910c1edaf
commit
15677d8a0e
@ -27,34 +27,53 @@
|
|||||||
//
|
//
|
||||||
// If ns is non-nil, it is used for dialing when needed.
|
// If ns is non-nil, it is used for dialing when needed.
|
||||||
func NewServer(logf logger.Logf, e wgengine.Engine, ns *netstack.Impl) *socks5.Server {
|
func NewServer(logf logger.Logf, e wgengine.Engine, ns *netstack.Impl) *socks5.Server {
|
||||||
srv := &socks5.Server{
|
d := &dialer{ns: ns}
|
||||||
|
e.AddNetworkMapCallback(d.onNewNetmap)
|
||||||
|
return &socks5.Server{
|
||||||
Logf: logf,
|
Logf: logf,
|
||||||
|
Dialer: d.DialContext,
|
||||||
}
|
}
|
||||||
var (
|
}
|
||||||
mu sync.Mutex // guards the following field
|
|
||||||
|
// dialer is the Tailscale SOCKS5 dialer.
|
||||||
|
type dialer struct {
|
||||||
|
ns *netstack.Impl
|
||||||
|
|
||||||
|
mu sync.Mutex
|
||||||
dns netstack.DNSMap
|
dns netstack.DNSMap
|
||||||
)
|
}
|
||||||
e.AddNetworkMapCallback(func(nm *netmap.NetworkMap) {
|
|
||||||
mu.Lock()
|
func (d *dialer) onNewNetmap(nm *netmap.NetworkMap) {
|
||||||
defer mu.Unlock()
|
d.mu.Lock()
|
||||||
dns = netstack.DNSMapFromNetworkMap(nm)
|
defer d.mu.Unlock()
|
||||||
})
|
d.dns = netstack.DNSMapFromNetworkMap(nm)
|
||||||
useNetstackForIP := func(ip netaddr.IP) bool {
|
}
|
||||||
|
|
||||||
|
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.ns != nil && d.useNetstackForIP(ipp.IP()) {
|
||||||
|
return d.ns.DialContextTCP(ctx, ipp.String())
|
||||||
|
}
|
||||||
|
var stdDialer net.Dialer
|
||||||
|
return stdDialer.DialContext(ctx, network, ipp.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *dialer) useNetstackForIP(ip netaddr.IP) bool {
|
||||||
|
if d.ns == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
// TODO(bradfitz): this isn't exactly right.
|
// TODO(bradfitz): this isn't exactly right.
|
||||||
// We should also support subnets when the
|
// We should also support subnets when the
|
||||||
// prefs are configured as such.
|
// prefs are configured as such.
|
||||||
return tsaddr.IsTailscaleIP(ip)
|
return tsaddr.IsTailscaleIP(ip)
|
||||||
}
|
}
|
||||||
srv.Dialer = func(ctx context.Context, network, addr string) (net.Conn, error) {
|
|
||||||
ipp, err := dns.Resolve(ctx, addr)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if ns != nil && useNetstackForIP(ipp.IP()) {
|
|
||||||
return ns.DialContextTCP(ctx, addr)
|
|
||||||
}
|
|
||||||
var d net.Dialer
|
|
||||||
return d.DialContext(ctx, network, ipp.String())
|
|
||||||
}
|
|
||||||
return srv
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user