@@ -1074,7 +1074,7 @@ func (r *resolver) refreshAll() (string, error) {
10741074
10751075 core .Gx ("r.refresh" , r .refresh )
10761076 core .Gx ("r.refresh.clearcache" , dialers .Clear )
1077- s := tr2csv (r .all ())
1077+ s := tr2csv (true /*active*/ , r .all ())
10781078 if dc , err := r .dcProxy (); err == nil {
10791079 if x , err := dc .Refresh (); err == nil {
10801080 s += "," + x
@@ -1093,7 +1093,7 @@ func (r *resolver) LiveTransports() string {
10931093 log .W ("dns: liveTransports: closed for business" )
10941094 return ""
10951095 }
1096- s := tr2csv (r .all ())
1096+ s := tr2csv (true /*active*/ , r .all ())
10971097 if dc , err := r .dcProxy (); err == nil {
10981098 x := dc .LiveTransports ()
10991099 s += "," + x
@@ -1150,8 +1150,8 @@ func (r *resolver) preferencesFrom(qname string, qtyp uint16, s *x.DNSOpts, chos
11501150 // no-op
11511151 } else {
11521152 // TODO: fallback on all id1s
1153- id1 = r .chooseOne (x ... )
1154- id2 = r .chooseOne (xx ... ) // mostly, just 0 or 1 secondary
1153+ id1 = r .chooseOne (true /*at random*/ , x ... )
1154+ id2 = r .chooseOne (true /*at random*/ , xx ... ) // mostly, just 0 or 1 secondary
11551155 }
11561156
11571157 if ! firstEmpty (chosenids ) && len (chosenids ) > 0 {
@@ -1227,7 +1227,7 @@ func (r *resolver) requiresGoosOrLocal(qname string) (id string) {
12271227 return
12281228}
12291229
1230- func (r * resolver ) chooseOne (ids ... string ) (theone string ) {
1230+ func (r * resolver ) chooseOne (chooseRandom bool , ids ... string ) (theone string ) {
12311231 if len (ids ) <= 0 {
12321232 return ""
12331233 }
@@ -1238,32 +1238,47 @@ func (r *resolver) chooseOne(ids ...string) (theone string) {
12381238 return ids [0 ]
12391239 }
12401240
1241+ miss := make ([]string , 0 )
12411242 trs := make ([]Transport , 0 , len (ids ))
12421243 r .RLock ()
12431244 for _ , id := range ids {
12441245 id = strings .TrimSpace (id )
12451246 if t := r .transports [id ]; t != nil {
12461247 trs = append (trs , t )
1248+ } else {
1249+ miss = append (miss , id )
12471250 }
12481251 }
12491252 r .RUnlock ()
12501253
12511254 best , preferred , recoverables , errored , ended := Categorize (trs )
12521255 if settings .Debug {
12531256 defer func () {
1254- loged (len (theone ) <= 0 )("dns: pref: chose: %s from best(%v) prefer(%v) recov(%v) err(%v) dead(%v)" ,
1255- theone , best , preferred , recoverables , errored , ended )
1257+ loged (len (theone ) <= 0 )("dns: pref: chose: %s from best(%v) prefer(%v) recov(%v) err(%v) dead(%v) miss(%v) " ,
1258+ theone , tr2csv2 ( best ), tr2csv2 ( preferred ), tr2csv2 ( recoverables ), tr2csv2 ( errored ), tr2csv2 ( ended ), strings . Join ( miss , "," ) )
12561259 }()
12571260 }
12581261
12591262 if len (best ) > 0 {
1263+ if chooseRandom {
1264+ return idstr (core .ChooseOne (best ))
1265+ }
12601266 return idstr (best [0 ])
12611267 } else if len (preferred ) > 0 {
1268+ if chooseRandom {
1269+ return idstr (core .ChooseOne (preferred ))
1270+ }
12621271 return idstr (preferred [0 ])
12631272 } else if len (recoverables ) > 0 {
1264- return idstr (core .ChooseOne (recoverables ))
1273+ if chooseRandom {
1274+ return idstr (core .ChooseOne (recoverables ))
1275+ }
1276+ return idstr (recoverables [0 ])
12651277 } else if len (errored ) > 0 {
1266- return idstr (core .ChooseOne (errored ))
1278+ if chooseRandom {
1279+ return idstr (core .ChooseOne (errored ))
1280+ }
1281+ return idstr (errored [0 ])
12671282 }
12681283 log .E ("dns: pref: no transports for %v [all ended? %v]" , ids , ended )
12691284 return ""
@@ -1286,6 +1301,8 @@ func Categorize(ts []Transport) (best []Transport, preferred []Transport, recove
12861301 errored = append (errored , t )
12871302 }
12881303 }
1304+ best = core .Sort (best , Fastest )
1305+ preferred = core .Sort (preferred , Fastest )
12891306 return
12901307}
12911308
@@ -1531,14 +1548,19 @@ func qtype(msg *dns.Msg) int {
15311548 return int (xdns .QType (msg ))
15321549}
15331550
1534- func tr2csv (ts []Transport ) string {
1535- s := ""
1551+ func tr2csv (activeOnly bool , ts []Transport ) string {
1552+ var s strings. Builder
15361553 for _ , t := range ts {
1537- if activeTransport (t ) {
1538- s += idstr (t ) + ","
1554+ if ! activeOnly || activeTransport (t ) {
1555+ s .WriteString (idstr (t ))
1556+ s .WriteString ("," )
15391557 }
15401558 }
1541- return trimcsv (s )
1559+ return trimcsv (s .String ())
1560+ }
1561+
1562+ func tr2csv2 (ts []Transport ) string {
1563+ return tr2csv (false /*activeOnly*/ , ts )
15421564}
15431565
15441566func trimcsv (s string ) string {
0 commit comments