@@ -129,6 +129,18 @@ func (h *auto) dial(network, laddr, raddr string) (protect.Conn, error) {
129129 remoteOnly := settings .AutoAlwaysRemote ()
130130 parallelDial := settings .AutoDialsParallel .Load ()
131131
132+ var c protect.Conn
133+ var err error
134+
135+ // non-parallel dial states
136+ who := - 1
137+ previdx , recent := h .exp .Get (raddr )
138+ delpin := false
139+
140+ // parallel dial states
141+ tothealthy := - 1
142+ totdials := - 1
143+
132144 if ! parallelDial {
133145 rpns := []Proxy {exit , exit64 , sep , win }
134146 healthy := core .Map (
@@ -150,7 +162,13 @@ func (h *auto) dial(network, laddr, raddr string) (protect.Conn, error) {
150162 func (p Proxy ) protect.RDialer {
151163 return p .Dialer ()
152164 })
153- if len (healthy ) <= 0 {
165+
166+ tothealthy = len (healthy )
167+ if len (healthy ) > 0 {
168+ // dial healthy proxies
169+ c , err = dialAny (healthy , network , laddr , raddr )
170+ totdials = len (healthy )
171+ } else {
154172 // no healthy proxies; fail open
155173 d := core .Map (rpns , func (p Proxy ) protect.RDialer {
156174 if p == nil || core .IsNil (p ) {
@@ -161,122 +179,121 @@ func (h *auto) dial(network, laddr, raddr string) (protect.Conn, error) {
161179 }
162180 return p .Dialer ()
163181 })
182+ totdials = len (d )
164183 if len (d ) > 0 {
165184 // dialAny delegates to dialers.DialAny which pins IPs
166185 // to proxies (against their IDs) for 30s.
167- return dialAny (core .WithoutNils (d ), network , laddr , raddr )
186+ c , err = dialAny (core .WithoutNils (d ), network , laddr , raddr )
187+ } else {
188+ c , err = nil , core .OneErr (pxrerrs , errNoProxyHealthy )
168189 }
169- return nil , core .OneErr (pxrerrs , errNoProxyHealthy )
170190 }
171- return dialAny (healthy , network , laddr , raddr )
172- }
173-
174- previdx , recent := h .exp .Get (raddr )
191+ } else {
192+ c , who , err = core .Race (
193+ network + ".dial-auto." + raddr ,
194+ tlsHandshakeTimeout ,
195+ func (ctx context.Context ) (protect.Conn , error ) {
196+ const myidx = 0
197+ if exit == nil { // exit must always be present
198+ return nil , exerr
199+ }
200+ if ! remoteOnly {
201+ select {
202+ case <- ctx .Done ():
203+ return nil , ctx .Err ()
204+ default : // dial ahead
205+ }
206+ } else {
207+ return nil , errNotRemote
208+ }
209+ if recent {
210+ if previdx != myidx {
211+ return nil , errNotPinned
212+ }
213+ // ip pinned to this proxy
214+ return h .dialAlways (exit , network , laddr , raddr )
215+ }
216+ return h .dialIfReachable (exit , network , laddr , raddr )
217+ }, func (ctx context.Context ) (protect.Conn , error ) {
218+ const myidx = 1
219+ if exit64 == nil {
220+ return nil , ex64err
221+ }
222+ if remoteOnly {
223+ return nil , errNotRemote
224+ }
225+ if recent {
226+ if previdx != myidx {
227+ return nil , errNotPinned
228+ }
229+ // ip pinned to this proxy
230+ return h .dialAlways (exit64 , network , laddr , raddr )
231+ }
175232
176- c , who , err := core .Race (
177- network + ".dial-auto." + raddr ,
178- tlsHandshakeTimeout ,
179- func (ctx context.Context ) (protect.Conn , error ) {
180- const myidx = 0
181- if exit == nil { // exit must always be present
182- return nil , exerr
183- }
184- if ! remoteOnly {
185233 select {
186234 case <- ctx .Done ():
187235 return nil , ctx .Err ()
188- default : // dial ahead
189- }
190- } else {
191- return nil , errNotRemote
192- }
193- if recent {
194- if previdx != myidx {
195- return nil , errNotPinned
236+ case <- time .After (shortdelay * myidx ): // 300ms
196237 }
197- // ip pinned to this proxy
198- return h .dialAlways (exit , network , laddr , raddr )
199- }
200- return h .dialIfReachable (exit , network , laddr , raddr )
201- }, func (ctx context.Context ) (protect.Conn , error ) {
202- const myidx = 1
203- if exit64 == nil {
204- return nil , ex64err
205- }
206- if remoteOnly {
207- return nil , errNotRemote
208- }
209- if recent {
210- if previdx != myidx {
211- return nil , errNotPinned
238+ return h .dialIfHealthy (exit64 , network , laddr , raddr )
239+ }, func (ctx context.Context ) (protect.Conn , error ) {
240+ const myidx = 2
241+ if sep == nil {
242+ return nil , seerr
212243 }
213- // ip pinned to this proxy
214- return h .dialAlways (exit64 , network , laddr , raddr )
215- }
216-
217- select {
218- case <- ctx .Done ():
219- return nil , ctx .Err ()
220- case <- time .After (shortdelay * myidx ): // 300ms
221- }
222- return h .dialIfHealthy (exit64 , network , laddr , raddr )
223- }, func (ctx context.Context ) (protect.Conn , error ) {
224- const myidx = 2
225- if sep == nil {
226- return nil , seerr
227- }
228- if recent {
229- if previdx != myidx {
230- return nil , errNotPinned
231- }
232- // ip pinned to this proxy
233- return h .dialAlways (sep , network , laddr , raddr )
234- }
235-
236- select {
237- case <- ctx .Done ():
238- return nil , ctx .Err ()
239- case <- time .After (shortdelay * myidx ): // 400ms
240- }
241- return h .dialIfHealthy (sep , network , laddr , raddr )
242- }, func (ctx context.Context ) (protect.Conn , error ) {
243- const myidx = 3
244- if win == nil {
245- return nil , winerr
246- }
247- if recent {
248- if previdx != myidx {
249- return nil , errNotPinned
244+ if recent {
245+ if previdx != myidx {
246+ return nil , errNotPinned
247+ }
248+ // ip pinned to this proxy
249+ return h .dialAlways (sep , network , laddr , raddr )
250250 }
251- // ip pinned to this proxy
252- return h .dialAlways (win , network , laddr , raddr )
253- }
254251
255- // wait only if exit was used
256- if ! remoteOnly {
257252 select {
258253 case <- ctx .Done ():
259254 return nil , ctx .Err ()
260- case <- time .After (shortdelay * myidx ): // 500ms
255+ case <- time .After (shortdelay * myidx ): // 400ms
261256 }
262- }
263- return h .dialIfHealthy (win , network , laddr , raddr )
264- },
265- )
257+ return h .dialIfHealthy (sep , network , laddr , raddr )
258+ }, func (ctx context.Context ) (protect.Conn , error ) {
259+ const myidx = 3
260+ if win == nil {
261+ return nil , winerr
262+ }
263+ if recent {
264+ if previdx != myidx {
265+ return nil , errNotPinned
266+ }
267+ // ip pinned to this proxy
268+ return h .dialAlways (win , network , laddr , raddr )
269+ }
270+
271+ // wait only if exit was used
272+ if ! remoteOnly {
273+ select {
274+ case <- ctx .Done ():
275+ return nil , ctx .Err ()
276+ case <- time .After (shortdelay * myidx ): // 500ms
277+ }
278+ }
279+ return h .dialIfHealthy (win , network , laddr , raddr )
280+ },
281+ )
282+
283+ if err != nil || c == nil || core .IsNil (c ) {
284+ h .exp .Del (raddr )
285+ c = nil
286+ delpin = true // remove pin
287+ } else {
288+ h .exp .Put (raddr , who )
289+ }
290+ }
266291
267292 defer localDialStatus (h .status , err )
268293
269- delpin := false
270- if err != nil || c == nil || core .IsNil (c ) {
271- h .exp .Del (raddr )
272- c = nil
273- delpin = true // remove pin
274- } else {
275- h .exp .Put (raddr , who )
276- }
277294 kaenabled := maybeKeepAlive (c )
278- logei (err )("proxy: auto: w(%d) pin(%t+%t/%d), dial(%s) %s, ka? %t; errs? %v+%v" ,
279- who , recent , ! delpin , previdx , network , raddr , kaenabled , err , pxrerrs )
295+ logei (err )("proxy: auto: w(%d) pin(%t+%t/%d), dial(%s) %s, ka? %t / parallel? %t / remote? %t; tot(healthy %d / dials %d) ; errs? %v+%v" ,
296+ who , recent , ! delpin , previdx , network , raddr , kaenabled , parallelDial , remoteOnly , tothealthy , totdials , err , pxrerrs )
280297
281298 return c , err
282299}
0 commit comments