diff --git a/control/controlhttp/client.go b/control/controlhttp/client.go index e01cb1f9a..7e95da427 100644 --- a/control/controlhttp/client.go +++ b/control/controlhttp/client.go @@ -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 // starting to try a.HTTPSPort. func (a *Dialer) httpsFallbackDelay() time.Duration { - if forceNoise443() { + if a.forceNoise443() { return time.Nanosecond } if v := a.testFallbackDelay; v != 0 { @@ -151,10 +151,7 @@ func (a *Dialer) dial(ctx context.Context) (*ClientConn, error) { // before we do anything. if c.DialStartDelaySec > 0 { a.logf("[v2] controlhttp: waiting %.2f seconds before dialing %q @ %v", c.DialStartDelaySec, a.Hostname, c.IP) - if a.Clock == nil { - a.Clock = tstime.StdClock{} - } - tmr, tmrChannel := a.Clock.NewTimer(time.Duration(c.DialStartDelaySec * float64(time.Second))) + tmr, tmrChannel := a.clock().NewTimer(time.Duration(c.DialStartDelaySec * float64(time.Second))) defer tmr.Stop() select { 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. 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") // 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. - if !forceNoise443() { + if !a.forceNoise443() { go try(u80) } // 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. - if a.Clock == nil { - a.Clock = tstime.StdClock{} - } - try443Timer := a.Clock.AfterFunc(a.httpsFallbackDelay(), func() { try(u443) }) + try443Timer := a.clock().AfterFunc(a.httpsFallbackDelay(), func() { try(u443) }) defer try443Timer.Stop() var err80, err443 error diff --git a/control/controlhttp/constants.go b/control/controlhttp/constants.go index 6b5116262..325c0691a 100644 --- a/control/controlhttp/constants.go +++ b/control/controlhttp/constants.go @@ -95,8 +95,9 @@ type Dialer struct { omitCertErrorLogging bool testFallbackDelay time.Duration - // tstime.Clock is used instead of time package for methods such as time.Now. - // If not specified, will default to tstime.StdClock{}. + // Clock, if non-nil, overrides the clock to use. + // If nil, tstime.StdClock is used. + // This exists primarily for tests. Clock tstime.Clock }