control/controlhttp: factor out some code in prep for future change

This pulls out the clock and forceNoise443 code into methods on the
Dialer as cleanup in its own commit to make a future change less
distracting.

Updates #13597

Change-Id: I7001e57fe7b508605930c5b141a061b6fb908733
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
pull/13599/head
Brad Fitzpatrick 3 weeks ago committed by Brad Fitzpatrick
parent d3f302d8e2
commit fd32f0ddf4

@ -86,7 +86,7 @@ func (a *Dialer) getProxyFunc() func(*http.Request) (*url.URL, error) {
// httpsFallbackDelay is how long we'll wait for a.HTTPPort to work before // httpsFallbackDelay is how long we'll wait for a.HTTPPort to work before
// starting to try a.HTTPSPort. // starting to try a.HTTPSPort.
func (a *Dialer) httpsFallbackDelay() time.Duration { func (a *Dialer) httpsFallbackDelay() time.Duration {
if forceNoise443() { if a.forceNoise443() {
return time.Nanosecond return time.Nanosecond
} }
if v := a.testFallbackDelay; v != 0 { if v := a.testFallbackDelay; v != 0 {
@ -151,10 +151,7 @@ func (a *Dialer) dial(ctx context.Context) (*ClientConn, error) {
// before we do anything. // before we do anything.
if c.DialStartDelaySec > 0 { if c.DialStartDelaySec > 0 {
a.logf("[v2] controlhttp: waiting %.2f seconds before dialing %q @ %v", c.DialStartDelaySec, a.Hostname, c.IP) a.logf("[v2] controlhttp: waiting %.2f seconds before dialing %q @ %v", c.DialStartDelaySec, a.Hostname, c.IP)
if a.Clock == nil { tmr, tmrChannel := a.clock().NewTimer(time.Duration(c.DialStartDelaySec * float64(time.Second)))
a.Clock = tstime.StdClock{}
}
tmr, tmrChannel := a.Clock.NewTimer(time.Duration(c.DialStartDelaySec * float64(time.Second)))
defer tmr.Stop() defer tmr.Stop()
select { select {
case <-ctx.Done(): case <-ctx.Done():
@ -268,6 +265,23 @@ func (a *Dialer) dial(ctx context.Context) (*ClientConn, error) {
// fixed, this is a workaround. It might also be useful for future debugging. // fixed, this is a workaround. It might also be useful for future debugging.
var forceNoise443 = envknob.RegisterBool("TS_FORCE_NOISE_443") var forceNoise443 = envknob.RegisterBool("TS_FORCE_NOISE_443")
// forceNoise443 reports whether the controlclient noise dialer should always
// use HTTPS connections as its underlay connection (double crypto). This can
// be necessary when networks or middle boxes are messing with port 80.
func (d *Dialer) forceNoise443() bool {
if forceNoise443() {
return true
}
return false
}
func (d *Dialer) clock() tstime.Clock {
if d.Clock != nil {
return d.Clock
}
return tstime.StdClock{}
}
var debugNoiseDial = envknob.RegisterBool("TS_DEBUG_NOISE_DIAL") var debugNoiseDial = envknob.RegisterBool("TS_DEBUG_NOISE_DIAL")
// dialHost connects to the configured Dialer.Hostname and upgrades the // dialHost connects to the configured Dialer.Hostname and upgrades the
@ -320,16 +334,13 @@ func (a *Dialer) dialHost(ctx context.Context, addr netip.Addr) (*ClientConn, er
} }
// Start the plaintext HTTP attempt first, unless disabled by the envknob. // Start the plaintext HTTP attempt first, unless disabled by the envknob.
if !forceNoise443() { if !a.forceNoise443() {
go try(u80) go try(u80)
} }
// In case outbound port 80 blocked or MITM'ed poorly, start a backup timer // In case outbound port 80 blocked or MITM'ed poorly, start a backup timer
// to dial port 443 if port 80 doesn't either succeed or fail quickly. // to dial port 443 if port 80 doesn't either succeed or fail quickly.
if a.Clock == nil { try443Timer := a.clock().AfterFunc(a.httpsFallbackDelay(), func() { try(u443) })
a.Clock = tstime.StdClock{}
}
try443Timer := a.Clock.AfterFunc(a.httpsFallbackDelay(), func() { try(u443) })
defer try443Timer.Stop() defer try443Timer.Stop()
var err80, err443 error var err80, err443 error

@ -95,8 +95,9 @@ type Dialer struct {
omitCertErrorLogging bool omitCertErrorLogging bool
testFallbackDelay time.Duration testFallbackDelay time.Duration
// tstime.Clock is used instead of time package for methods such as time.Now. // Clock, if non-nil, overrides the clock to use.
// If not specified, will default to tstime.StdClock{}. // If nil, tstime.StdClock is used.
// This exists primarily for tests.
Clock tstime.Clock Clock tstime.Clock
} }

Loading…
Cancel
Save