MCPcopy
hub / github.com/tailscale/tailscale / dial

Method dial

control/controlhttp/client.go:98–171  ·  view source on GitHub ↗

to record at init time whether it's in use

(ctx context.Context)

Source from the content-addressed store, hash-verified

96var _ = envknob.RegisterBool("TS_USE_CONTROL_DIAL_PLAN") // to record at init time whether it's in use
97
98func (a *Dialer) dial(ctx context.Context) (*ClientConn, error) {
99
100 a.logPort80Failure.Store(true)
101
102 // If we don't have a dial plan, just fall back to dialing the single
103 // host we know about.
104 useDialPlan := envknob.BoolDefaultTrue("TS_USE_CONTROL_DIAL_PLAN")
105 if !useDialPlan || a.DialPlan == nil || len(a.DialPlan.Candidates) == 0 {
106 return a.dialHost(ctx)
107 }
108 candidates := a.DialPlan.Candidates
109
110 // Create a context to be canceled as we return, so once we get a good connection,
111 // we can drop all the other ones.
112 ctx, cancel := context.WithCancel(ctx)
113 defer cancel()
114
115 // Now, for each candidate, kick off a dial in parallel.
116 type dialResult struct {
117 conn *ClientConn
118 err error
119 }
120 resultsCh := make(chan dialResult) // unbuffered, never closed
121
122 dialCand := func(cand tailcfg.ControlIPCandidate) (*ClientConn, error) {
123 if cand.ACEHost != "" {
124 a.logf("[v2] controlhttp: waited %.2f seconds, dialing %q via ACE %s (%s)", cand.DialStartDelaySec, a.Hostname, cand.ACEHost, cmp.Or(cand.IP.String(), "dns"))
125 } else {
126 a.logf("[v2] controlhttp: waited %.2f seconds, dialing %q @ %s", cand.DialStartDelaySec, a.Hostname, cand.IP.String())
127 }
128
129 ctx, cancel := context.WithTimeout(ctx, time.Duration(cand.DialTimeoutSec*float64(time.Second)))
130 defer cancel()
131 return a.dialHostOpt(ctx, cand.IP, cand.ACEHost)
132 }
133
134 for _, cand := range candidates {
135 timer := time.AfterFunc(time.Duration(cand.DialStartDelaySec*float64(time.Second)), func() {
136 go func() {
137 conn, err := dialCand(cand)
138 select {
139 case resultsCh <- dialResult{conn, err}:
140 if err == nil {
141 a.logf("[v1] controlhttp: succeeded dialing %q @ %v from dial plan", a.Hostname, cmp.Or(cand.ACEHost, cand.IP.String()))
142 }
143 case <-ctx.Done():
144 if conn != nil {
145 conn.Close()
146 }
147 }
148 }()
149 })
150 defer timer.Stop()
151 }
152
153 var errs []error
154 for {
155 select {

Callers 3

DialMethod · 0.95
testControlHTTPFunction · 0.95
runDialPlanTestFunction · 0.95

Calls 11

dialHostMethod · 0.95
logfMethod · 0.95
dialHostOptMethod · 0.95
BoolDefaultTrueFunction · 0.92
StoreMethod · 0.65
StringMethod · 0.65
AfterFuncMethod · 0.65
DoneMethod · 0.65
CloseMethod · 0.65
StopMethod · 0.65
ErrMethod · 0.45

Tested by 2

testControlHTTPFunction · 0.76
runDialPlanTestFunction · 0.76