@@ -34,6 +34,7 @@ const (
3434 DefaultBootstrapResolver = "9.9.9.9:53"
3535 DefaultKeepAlive = 5 * time .Second
3636 DefaultTimeout = 30 * time .Second
37+ ResolverReadTimeout = 5 * time .Second
3738 SystemResolverIPTTL = 12 * time .Hour
3839 MinResolverIPTTL = 4 * time .Hour
3940 ResolverIPTTLMaxJitter = 15 * time .Minute
@@ -331,83 +332,88 @@ func (xTransport *XTransport) rebuildTransport() {
331332 }
332333}
333334
334- func (xTransport * XTransport ) resolveUsingSystem (host string ) (ip net.IP , ttl time.Duration , err error ) {
335- ttl = SystemResolverIPTTL
336- var foundIPs []string
337- foundIPs , err = net .LookupHost (host )
338- if err != nil {
339- return ip , ttl , err
335+ func (xTransport * XTransport ) resolveUsingSystem (host string , forceType uint16 ) ([]net.IP , time.Duration , error ) {
336+ ipa , err := net .LookupIP (host )
337+ queryIPv4 := xTransport .useIPv4
338+ queryIPv6 := xTransport .useIPv6
339+ if forceType == dns .TypeNone && queryIPv4 && queryIPv6 {
340+ return ipa , SystemResolverIPTTL , err
341+ }
342+ switch forceType {
343+ case dns .TypeA :
344+ queryIPv4 = true
345+ queryIPv6 = false
346+ case dns .TypeAAAA :
347+ queryIPv4 = false
348+ queryIPv6 = true
340349 }
341350 ips := make ([]net.IP , 0 )
342- for _ , ip := range foundIPs {
343- if foundIP := net .ParseIP (ip ); foundIP != nil {
344- isIPv4 := foundIP .To4 () != nil
345- if (isIPv4 && xTransport .useIPv4 ) || (! isIPv4 && xTransport .useIPv6 ) {
346- ips = append (ips , foundIP )
347- }
351+ for _ , ip := range ipa {
352+ ipv4 := ip .To4 ()
353+ if queryIPv4 && ipv4 != nil {
354+ ips = append (ips , ipv4 )
355+ }
356+ if queryIPv6 && ipv4 == nil {
357+ ips = append (ips , ip )
348358 }
349359 }
350- if len (ips ) > 0 {
351- ip = ips [rand .Intn (len (ips ))]
352- }
353- return ip , ttl , err
360+ return ips , SystemResolverIPTTL , err
354361}
355362
356363func (xTransport * XTransport ) resolveUsingResolver (
357364 proto , host string ,
358365 resolver string ,
359- ) (ip net.IP , ttl time.Duration , err error ) {
360- dnsClient := dns.Client {Net : proto }
361- if xTransport .useIPv4 {
362- msg := dns.Msg {}
363- msg .SetQuestion (dns .Fqdn (host ), dns .TypeA )
364- msg .SetEdns0 (uint16 (MaxDNSPacketSize ), true )
365- var in * dns.Msg
366- if in , _ , err = dnsClient .Exchange (& msg , resolver ); err == nil {
367- answers := make ([]dns.RR , 0 )
368- for _ , answer := range in .Answer {
369- if answer .Header ().Rrtype == dns .TypeA {
370- answers = append (answers , answer )
371- }
372- }
373- if len (answers ) > 0 {
374- answer := answers [rand .Intn (len (answers ))]
375- ip = answer .(* dns.A ).A
376- ttl = time .Duration (answer .Header ().Ttl ) * time .Second
377- return ip , ttl , err
378- }
366+ forceType uint16 ,
367+ ) (ips []net.IP , ttl time.Duration , err error ) {
368+ dnsClient := dns.Client {Net : proto , ReadTimeout : ResolverReadTimeout }
369+ queryType := make ([]uint16 , 0 , 2 )
370+ switch forceType {
371+ case dns .TypeA :
372+ queryType = append (queryType , dns .TypeA )
373+ case dns .TypeAAAA :
374+ queryType = append (queryType , dns .TypeAAAA )
375+ default :
376+ if xTransport .useIPv4 {
377+ queryType = append (queryType , dns .TypeA )
378+ }
379+ if xTransport .useIPv6 {
380+ queryType = append (queryType , dns .TypeAAAA )
379381 }
380382 }
381- if xTransport .useIPv6 {
383+ var rrTTL uint32
384+ for _ , rrType := range queryType {
382385 msg := dns.Msg {}
383- msg .SetQuestion (dns .Fqdn (host ), dns . TypeAAAA )
386+ msg .SetQuestion (dns .Fqdn (host ), rrType )
384387 msg .SetEdns0 (uint16 (MaxDNSPacketSize ), true )
385388 var in * dns.Msg
386389 if in , _ , err = dnsClient .Exchange (& msg , resolver ); err == nil {
387- answers := make ([]dns.RR , 0 )
388390 for _ , answer := range in .Answer {
389- if answer .Header ().Rrtype == dns .TypeAAAA {
390- answers = append (answers , answer )
391+ if answer .Header ().Rrtype == rrType {
392+ switch rrType {
393+ case dns .TypeA :
394+ ips = append (ips , answer .(* dns.A ).A )
395+ case dns .TypeAAAA :
396+ ips = append (ips , answer .(* dns.AAAA ).AAAA )
397+ }
398+ rrTTL = answer .Header ().Ttl
391399 }
392400 }
393- if len (answers ) > 0 {
394- answer := answers [rand .Intn (len (answers ))]
395- ip = answer .(* dns.AAAA ).AAAA
396- ttl = time .Duration (answer .Header ().Ttl ) * time .Second
397- return ip , ttl , err
398- }
399401 }
400402 }
401- return ip , ttl , err
403+ if len (ips ) > 0 {
404+ ttl = time .Duration (rrTTL ) * time .Second
405+ }
406+ return ips , ttl , err
402407}
403408
404409func (xTransport * XTransport ) resolveUsingResolvers (
405410 proto , host string ,
406411 resolvers []string ,
407- ) (ip net.IP , ttl time.Duration , err error ) {
412+ forceType uint16 ,
413+ ) (ips []net.IP , ttl time.Duration , err error ) {
408414 err = errors .New ("Empty resolvers" )
409415 for i , resolver := range resolvers {
410- ip , ttl , err = xTransport .resolveUsingResolver (proto , host , resolver )
416+ ips , ttl , err = xTransport .resolveUsingResolver (proto , host , resolver , forceType )
411417 if err == nil {
412418 if i > 0 {
413419 dlog .Infof ("Resolution succeeded with resolver %s[%s]" , proto , resolver )
@@ -417,34 +423,22 @@ func (xTransport *XTransport) resolveUsingResolvers(
417423 }
418424 dlog .Infof ("Unable to resolve [%s] using resolver [%s] (%s): %v" , host , resolver , proto , err )
419425 }
420- return ip , ttl , err
426+ return ips , ttl , err
421427}
422428
423- // If a name is not present in the cache, resolve the name and update the cache
424- func (xTransport * XTransport ) resolveAndUpdateCache (host string ) error {
425- if xTransport .proxyDialer != nil || xTransport .httpProxyFunction != nil {
426- return nil
427- }
428- if ParseIP (host ) != nil {
429- return nil
430- }
431- cachedIP , expired , updating := xTransport .loadCachedIP (host )
432- if cachedIP != nil && (! expired || updating ) {
433- return nil
434- }
435- xTransport .markUpdatingCachedIP (host )
429+ func (xTransport * XTransport ) resolveEncrypted (host string , forceType uint16 ) ([]net.IP , time.Duration , error ) {
430+ return xTransport .resolveUsingResolvers (xTransport .mainProto , host , xTransport .internalResolvers , forceType )
431+ }
436432
437- var foundIP net.IP
438- var ttl time.Duration
439- var err error
433+ func (xTransport * XTransport ) resolve (host string , forceType uint16 ) (ips []net.IP , ttl time.Duration , err error ) {
440434 protos := []string {"udp" , "tcp" }
441435 if xTransport .mainProto == "tcp" {
442436 protos = []string {"tcp" , "udp" }
443437 }
444438 if xTransport .ignoreSystemDNS {
445439 if xTransport .internalResolverReady {
446440 for _ , proto := range protos {
447- foundIP , ttl , err = xTransport .resolveUsingResolvers (proto , host , xTransport .internalResolvers )
441+ ips , ttl , err = xTransport .resolveUsingResolvers (proto , host , xTransport .internalResolvers , forceType )
448442 if err == nil {
449443 break
450444 }
@@ -454,7 +448,7 @@ func (xTransport *XTransport) resolveAndUpdateCache(host string) error {
454448 dlog .Notice (err )
455449 }
456450 } else {
457- foundIP , ttl , err = xTransport .resolveUsingSystem (host )
451+ ips , ttl , err = xTransport .resolveUsingSystem (host , forceType )
458452 if err != nil {
459453 err = errors .New ("System DNS is not usable yet" )
460454 dlog .Notice (err )
@@ -469,15 +463,37 @@ func (xTransport *XTransport) resolveAndUpdateCache(host string) error {
469463 proto ,
470464 )
471465 }
472- foundIP , ttl , err = xTransport .resolveUsingResolvers (proto , host , xTransport .bootstrapResolvers )
466+ ips , ttl , err = xTransport .resolveUsingResolvers (proto , host , xTransport .bootstrapResolvers , forceType )
473467 if err == nil {
474468 break
475469 }
476470 }
477471 }
478472 if err != nil && xTransport .ignoreSystemDNS {
479473 dlog .Noticef ("Bootstrap resolvers didn't respond - Trying with the system resolver as a last resort" )
480- foundIP , ttl , err = xTransport .resolveUsingSystem (host )
474+ ips , ttl , err = xTransport .resolveUsingSystem (host , forceType )
475+ }
476+ return ips , ttl , err
477+ }
478+
479+ // If a name is not present in the cache, resolve the name and update the cache
480+ func (xTransport * XTransport ) resolveAndUpdateCache (host string ) error {
481+ if xTransport .proxyDialer != nil || xTransport .httpProxyFunction != nil {
482+ return nil
483+ }
484+ if ParseIP (host ) != nil {
485+ return nil
486+ }
487+ cachedIP , expired , updating := xTransport .loadCachedIP (host )
488+ if cachedIP != nil && (! expired || updating ) {
489+ return nil
490+ }
491+ xTransport .markUpdatingCachedIP (host )
492+
493+ var foundIP net.IP
494+ ips , ttl , err := xTransport .resolve (host , dns .TypeNone )
495+ if len (ips ) > 0 {
496+ foundIP = ips [rand .Intn (len (ips ))]
481497 }
482498 if ttl < MinResolverIPTTL {
483499 ttl = MinResolverIPTTL
0 commit comments