@@ -40,9 +40,9 @@ func TestDNSTransportFallback(t *testing.T) {
40
40
testenv .MustHaveExternalNetwork (t )
41
41
42
42
for _ , tt := range dnsTransportFallbackTests {
43
- ctx , cancel := context .WithTimeout (context .Background (), time . Duration ( tt . timeout ) * time . Second )
43
+ ctx , cancel := context .WithCancel (context .Background ())
44
44
defer cancel ()
45
- msg , err := exchange (ctx , tt .server , tt .name , tt .qtype )
45
+ msg , err := exchange (ctx , tt .server , tt .name , tt .qtype , time . Second )
46
46
if err != nil {
47
47
t .Error (err )
48
48
continue
@@ -82,9 +82,9 @@ func TestSpecialDomainName(t *testing.T) {
82
82
83
83
server := "8.8.8.8:53"
84
84
for _ , tt := range specialDomainNameTests {
85
- ctx , cancel := context .WithTimeout (context .Background (), 3 * time . Second )
85
+ ctx , cancel := context .WithCancel (context .Background ())
86
86
defer cancel ()
87
- msg , err := exchange (ctx , server , tt .name , tt .qtype )
87
+ msg , err := exchange (ctx , server , tt .name , tt .qtype , 3 * time . Second )
88
88
if err != nil {
89
89
t .Error (err )
90
90
continue
@@ -501,7 +501,7 @@ func TestErrorForOriginalNameWhenSearching(t *testing.T) {
501
501
d := & fakeDNSDialer {}
502
502
testHookDNSDialer = func () dnsDialer { return d }
503
503
504
- d .rh = func (s string , q * dnsMsg ) (* dnsMsg , error ) {
504
+ d .rh = func (s string , q * dnsMsg , _ time. Time ) (* dnsMsg , error ) {
505
505
r := & dnsMsg {
506
506
dnsMsgHdr : dnsMsgHdr {
507
507
id : q .id ,
@@ -540,14 +540,15 @@ func TestIgnoreLameReferrals(t *testing.T) {
540
540
}
541
541
defer conf .teardown ()
542
542
543
- if err := conf .writeAndUpdate ([]string {"nameserver 192.0.2.1" , "nameserver 192.0.2.2" }); err != nil {
543
+ if err := conf .writeAndUpdate ([]string {"nameserver 192.0.2.1" , // the one that will give a lame referral
544
+ "nameserver 192.0.2.2" }); err != nil {
544
545
t .Fatal (err )
545
546
}
546
547
547
548
d := & fakeDNSDialer {}
548
549
testHookDNSDialer = func () dnsDialer { return d }
549
550
550
- d .rh = func (s string , q * dnsMsg ) (* dnsMsg , error ) {
551
+ d .rh = func (s string , q * dnsMsg , _ time. Time ) (* dnsMsg , error ) {
551
552
t .Log (s , q )
552
553
r := & dnsMsg {
553
554
dnsMsgHdr : dnsMsgHdr {
@@ -634,28 +635,30 @@ func BenchmarkGoLookupIPWithBrokenNameServer(b *testing.B) {
634
635
635
636
type fakeDNSDialer struct {
636
637
// reply handler
637
- rh func (s string , q * dnsMsg ) (* dnsMsg , error )
638
+ rh func (s string , q * dnsMsg , t time. Time ) (* dnsMsg , error )
638
639
}
639
640
640
641
func (f * fakeDNSDialer ) dialDNS (_ context.Context , n , s string ) (dnsConn , error ) {
641
- return & fakeDNSConn {f .rh , s }, nil
642
+ return & fakeDNSConn {f .rh , s , time. Time {} }, nil
642
643
}
643
644
644
645
type fakeDNSConn struct {
645
- rh func (s string , q * dnsMsg ) (* dnsMsg , error )
646
+ rh func (s string , q * dnsMsg , t time. Time ) (* dnsMsg , error )
646
647
s string
648
+ t time.Time
647
649
}
648
650
649
651
func (f * fakeDNSConn ) Close () error {
650
652
return nil
651
653
}
652
654
653
- func (f * fakeDNSConn ) SetDeadline (time.Time ) error {
655
+ func (f * fakeDNSConn ) SetDeadline (t time.Time ) error {
656
+ f .t = t
654
657
return nil
655
658
}
656
659
657
660
func (f * fakeDNSConn ) dnsRoundTrip (q * dnsMsg ) (* dnsMsg , error ) {
658
- return f .rh (f .s , q )
661
+ return f .rh (f .s , q , f . t )
659
662
}
660
663
661
664
// UDP round-tripper algorithm should ignore invalid DNS responses (issue 13281).
@@ -725,3 +728,72 @@ func TestIgnoreDNSForgeries(t *testing.T) {
725
728
t .Errorf ("got address %v, want %v" , got , TestAddr )
726
729
}
727
730
}
731
+
732
+ // Issue 16865. If a name server times out, continue to the next.
733
+ func TestRetryTimeout (t * testing.T ) {
734
+ origTestHookDNSDialer := testHookDNSDialer
735
+ defer func () { testHookDNSDialer = origTestHookDNSDialer }()
736
+
737
+ conf , err := newResolvConfTest ()
738
+ if err != nil {
739
+ t .Fatal (err )
740
+ }
741
+ defer conf .teardown ()
742
+
743
+ if err := conf .writeAndUpdate ([]string {"nameserver 192.0.2.1" , // the one that will timeout
744
+ "nameserver 192.0.2.2" }); err != nil {
745
+ t .Fatal (err )
746
+ }
747
+
748
+ d := & fakeDNSDialer {}
749
+ testHookDNSDialer = func () dnsDialer { return d }
750
+
751
+ var deadline0 time.Time
752
+
753
+ d .rh = func (s string , q * dnsMsg , deadline time.Time ) (* dnsMsg , error ) {
754
+ t .Log (s , q , deadline )
755
+
756
+ if deadline .IsZero () {
757
+ t .Error ("zero deadline" )
758
+ }
759
+
760
+ if s == "192.0.2.1:53" {
761
+ deadline0 = deadline
762
+ time .Sleep (10 * time .Millisecond )
763
+ return nil , errTimeout
764
+ }
765
+
766
+ if deadline == deadline0 {
767
+ t .Error ("deadline didn't change" )
768
+ }
769
+
770
+ r := & dnsMsg {
771
+ dnsMsgHdr : dnsMsgHdr {
772
+ id : q .id ,
773
+ response : true ,
774
+ recursion_available : true ,
775
+ },
776
+ question : q .question ,
777
+ answer : []dnsRR {
778
+ & dnsRR_CNAME {
779
+ Hdr : dnsRR_Header {
780
+ Name : q .question [0 ].Name ,
781
+ Rrtype : dnsTypeCNAME ,
782
+ Class : dnsClassINET ,
783
+ },
784
+ Cname : "golang.org" ,
785
+ },
786
+ },
787
+ }
788
+ return r , nil
789
+ }
790
+
791
+ _ , err = goLookupCNAME (context .Background (), "www.golang.org" )
792
+ if err != nil {
793
+ t .Fatal (err )
794
+ }
795
+
796
+ if deadline0 .IsZero () {
797
+ t .Error ("deadline0 still zero" , deadline0 )
798
+ }
799
+ }
0 commit comments