net/socks5/tssocks: add a SOCKS5 dialer type, method-ifying code
Prep for
//
// 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 {
- srv := &socks5.Server{
+ d := &dialer{ns: ns}
+ e.AddNetworkMapCallback(d.onNewNetmap)
+ return &socks5.Server{
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
- )
- e.AddNetworkMapCallback(func(nm *netmap.NetworkMap) {
- mu.Lock()
- defer mu.Unlock()
- dns = netstack.DNSMapFromNetworkMap(nm)
- })
- useNetstackForIP := func(ip netaddr.IP) bool {
- // TODO(bradfitz): this isn't exactly right.
- // We should also support subnets when the
- // prefs are configured as such.
- return tsaddr.IsTailscaleIP(ip)
}
- srv.Dialer = func(ctx context.Context, network, addr string) (net.Conn, error) {
- ipp, err := dns.Resolve(ctx, addr)
+
+func (d *dialer) onNewNetmap(nm *netmap.NetworkMap) {
+ d.mu.Lock()
+ defer d.mu.Unlock()
+ d.dns = netstack.DNSMapFromNetworkMap(nm)
+}
+
+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 ns != nil && useNetstackForIP(ipp.IP()) {
- return ns.DialContextTCP(ctx, addr)
+ if d.ns != nil && d.useNetstackForIP(ipp.IP()) {
+ return d.ns.DialContextTCP(ctx, ipp.String())
}
- var d net.Dialer
- return d.DialContext(ctx, network, 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
}
- return srv
+ // TODO(bradfitz): this isn't exactly right.
+ // We should also support subnets when the
+ // prefs are configured as such.
+ return tsaddr.IsTailscaleIP(ip)
}
