-
Notifications
You must be signed in to change notification settings - Fork 24
Description
Description
Context
Most optimization related features of fastdialer like happy eyeballs algorithm, handling permanent errors, optimized for hostnames to rank ips and parallel dial etc
currently when proxyDialer is specified ( socks5 proxy dialer) via Options, it is used for creating non-tls connections as we can see here
fastdialer/fastdialer/dialer_private.go
Lines 303 to 327 in e12186b
if d.proxyDialer != nil { | |
dialer := *d.proxyDialer | |
// timeout not working for socks5 proxy dialer | |
// tying to handle it here | |
connectionCh := make(chan net.Conn, 1) | |
errCh := make(chan error, 1) | |
go func() { | |
conn, err = dialer.Dial(opts.network, hostPort) | |
if err != nil { | |
errCh <- err | |
return | |
} | |
connectionCh <- conn | |
}() | |
// using timer as time.After is not recovered gy GC | |
dialerTime := time.NewTimer(d.options.DialerTimeout) | |
defer dialerTime.Stop() | |
select { | |
case <-dialerTime.C: | |
return nil, fmt.Errorf("timeout after %v", d.options.DialerTimeout) | |
case conn = <-connectionCh: | |
case err = <-errCh: | |
} | |
err = d.handleDialError(err, opts) | |
} else { |
but when the network type is tls we skip using proxy dialer and fallback to using net.Dialer (
fastdialer/fastdialer/dialer_private.go
Lines 156 to 184 in e12186b
var finalDialer l4dialer = d.dialer | |
if dw == nil && hostname != "" && len(IPS) > 0 && d.proxyDialer == nil { | |
// only cache it if below conditions are met | |
// 1. it is already not present | |
// 2. it is a domain and not ip | |
// 3. it has at least 1 valid ip | |
// 4. proxy dialer is not set | |
dw, err = utils.NewDialWrap(d.dialer, IPS, opts.network, opts.address, opts.port) | |
if err != nil { | |
return nil, errkit.Wrap(err, "could not create dialwrap") | |
} | |
if err = d.dialCache.Set(opts.connHash(), dw); err != nil { | |
return nil, errkit.Wrap(err, "could not set dialwrap") | |
} | |
} | |
if dw != nil { | |
finalDialer = dw | |
// when using dw ip , network , port etc are preset | |
// so get any one of them to avoid breaking further logic | |
ip, port := dw.Address() | |
opts.ips = []string{ip} | |
opts.port = port | |
// also set hostname by parsing it from address | |
hostname, _, _ = net.SplitHostPort(opts.address) | |
opts.hostname = hostname | |
} | |
Possible Changes
- modify the utils.DialWrap implementation to accept ( proxyDialer ) as input instead of just net.Dial
- modify dialer_private.go to simply override l4Dialer with proxyDialer
Note: when modifying utils.DialWrap to accept proxyDialer , some options like happy eyeballs and other setting like multipath etc might not be possible and should be treated as no-op
Follow-up
- remove dialTLSContext override in nuclei where we override DialTLSContext to use net.Dialer when socks5 proxy is being used