@@ -502,6 +502,7 @@ func (px *proxifier) ProxyTo(who string, ipp netip.AddrPort, proto, uid string,
502502 return nil , e (errMissingAddress )
503503 }
504504
505+ totalStalledSec := uint32 (0 )
505506 stalledSec := uint32 (0 )
506507 var circular []string
507508
@@ -517,11 +518,12 @@ func (px *proxifier) ProxyTo(who string, ipp netip.AddrPort, proto, uid string,
517518 time .Sleep (time .Duration (minWaitPeriodSec - stalledSec ) * time .Second )
518519 stalledSec = minWaitPeriodSec
519520 }
521+ totalStalledSec += stalledSec
520522 goto retryPin
521523 }
522524 }
523525 logev (err )("proxy: pin: single: 1 %s: %s: %s+%s; pin pid0: %s (stalled? %ds / waited? %t); err? %v" ,
524- who , proto , uid , ippstr , pids [0 ], stalledSec , waitedForMissingProxy , err )
526+ who , proto , uid , ippstr , pids [0 ], totalStalledSec , waitedForMissingProxy , err )
525527 if p != nil {
526528 pid0 := p .ID ()
527529 iscircle := iscircular (p , ippstr )
@@ -531,7 +533,7 @@ func (px *proxifier) ProxyTo(who string, ipp netip.AddrPort, proto, uid string,
531533
532534 if log .Verbose {
533535 log .V ("proxy: pin: single: 2 %s: %s: %s+%s; pin pid0: (%s <> %s) (stalled? %ds / waited? %t); err? %v; circular? %t; noroute? %t; canth3? %t; notok? %t" ,
534- who , proto , uid , ippstr , pid0 , pids [0 ], stalledSec , waitedForMissingProxy , err , iscircle , noroute , canth3 , notok )
536+ who , proto , uid , ippstr , pid0 , pids [0 ], totalStalledSec , waitedForMissingProxy , err , iscircle , noroute , canth3 , notok )
535537 }
536538
537539 if iscircle {
@@ -552,6 +554,7 @@ func (px *proxifier) ProxyTo(who string, ipp netip.AddrPort, proto, uid string,
552554 }
553555 if notok { // proxy not ok
554556 stalledSec = px .stall (uid + ippstr )
557+ totalStalledSec += stalledSec
555558 }
556559 // wipe out err; return p, even if err is not nil
557560 // helps client code verify for itself just why this proxy won't work...
@@ -589,7 +592,7 @@ func (px *proxifier) ProxyTo(who string, ipp netip.AddrPort, proto, uid string,
589592
590593 if log .Verbose {
591594 log .V ("proxy: pin: %s: %s: %s+%s; chosen and pinned: 1 (%s <> %s) (stalled? %ds); err? %v; circular? %t; noroute? %t; canth3? %t" ,
592- who , proto , uid , ippstr , pinnedpid , pidc , stalledSec , err , iscircle , noroute , canth3 )
595+ who , proto , uid , ippstr , pinnedpid , pidc , totalStalledSec , err , iscircle , noroute , canth3 )
593596 }
594597 // check for circular route before other checks
595598 if iscircle {
@@ -624,7 +627,7 @@ func (px *proxifier) ProxyTo(who string, ipp netip.AddrPort, proto, uid string,
624627
625628 defer func () {
626629 logev (err )("proxy: pin: %s: %s: %s+%s; chosen? %s; stalled? %ds; local: %v; miss: %v; notok: %v; noroute: %v; paused %v; ended %v; noh3: %v; circular: %v" ,
627- who , proto , uid , ippstr , idstr (theone ), stalledSec , loproxies , missproxies , notokproxies , norouteproxies , pausedproxies , endproxies , noh3proxies , circular )
630+ who , proto , uid , ippstr , idstr (theone ), totalStalledSec , loproxies , missproxies , notokproxies , norouteproxies , pausedproxies , endproxies , noh3proxies , circular )
628631 }()
629632
630633retrySearch:
@@ -686,7 +689,10 @@ retrySearch:
686689 // can route but not healthy; choose any one on random
687690 if len (notok ) > 0 || len (noh3 ) > 0 {
688691 // stall to allow a non-healthy proxy to recover
689- stalledSec = px .stall (uid + ippstr )
692+ if totalStalledSec < minWaitPeriodSec {
693+ stalledSec = px .stall (uid + ippstr )
694+ totalStalledSec += stalledSec
695+ }
690696 if one := core .ChooseOne (notok ); one != nil {
691697 if log .Verbose {
692698 log .V ("proxy: pin: %s: %s: %s+%s; pinned: %s; from notok: %v" ,
@@ -709,13 +715,12 @@ retrySearch:
709715 if len (missproxies ) > 0 && ! waitedForMissingProxy {
710716 // wait for the missing proxy to be added before returning error
711717 waitedForMissingProxy = true
712- stalledSec = px .stall (uid + ippstr )
713- if stalledSec < minWaitPeriodSec {
714- time .Sleep (time .Duration (minWaitPeriodSec - stalledSec ) * time .Second )
715- stalledSec = minWaitPeriodSec
718+ if totalStalledSec < minWaitPeriodSec {
719+ stalledSec = px .stall (uid + ippstr )
720+ totalStalledSec += stalledSec
716721 }
717722 log .W ("proxy: pin: %s: %s: %s+%s; missing: %v; notok: %v; noroute: %v; paused: %v; ended: %v; waited: %ds" ,
718- who , proto , uid , ippstr , missproxies , notokproxies , norouteproxies , pausedproxies , endproxies , stalledSec )
723+ who , proto , uid , ippstr , missproxies , notokproxies , norouteproxies , pausedproxies , endproxies , totalStalledSec )
719724 pids = missproxies
720725 clear (missproxies )
721726 goto retrySearch
@@ -763,7 +768,7 @@ func (px *proxifier) stall(k string) (secs uint32) {
763768 w := time .Duration (secs ) * time .Second
764769 time .Sleep (w )
765770 }
766- return
771+ return secs
767772}
768773
769774// pinID pins uid+ipp to proxy id, if found, and returns the proxy.
0 commit comments