Skip to content

Commit d1a5df4

Browse files
committed
Increase timeouts
1 parent 7ee2481 commit d1a5df4

File tree

1 file changed

+42
-21
lines changed

1 file changed

+42
-21
lines changed

www/tester.go

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -408,11 +408,11 @@ func (t *Tester) testDNSCrypt(stamp stamps.ServerStamp) error {
408408
// The provider name in the stamp is already the full name to query (e.g., "2.dnscrypt.default.ns1.adguard.com")
409409
certName := providerName
410410

411-
ctx, cancel := context.WithTimeout(context.Background(), t.timeout)
411+
// Use 3x timeout to allow for retries with slow resolvers (some take 5s to respond)
412+
// Budget: 3 UDP attempts * timeout + 2 delays + 1 TCP attempt
413+
ctx, cancel := context.WithTimeout(context.Background(), t.timeout*3)
412414
defer cancel()
413415

414-
dialer := net.Dialer{Timeout: t.timeout}
415-
416416
// Create TXT query for the certificate
417417
query := new(dns.Msg)
418418
query.SetQuestion(dns.Fqdn(certName), dns.TypeTXT)
@@ -430,15 +430,24 @@ func (t *Tester) testDNSCrypt(stamp stamps.ServerStamp) error {
430430
var lastErr error
431431
for attempt := 0; attempt < maxUDPRetries; attempt++ {
432432
if attempt > 0 {
433-
time.Sleep(udpRetryDelay)
433+
select {
434+
case <-ctx.Done():
435+
return fmt.Errorf("timeout after %d UDP attempts: %v", attempt, lastErr)
436+
case <-time.After(udpRetryDelay):
437+
}
434438
}
435439

436-
conn, err := dialer.DialContext(ctx, "udp", addr)
440+
// Per-attempt timeout for dialing
441+
dialCtx, dialCancel := context.WithTimeout(ctx, t.timeout)
442+
conn, err := new(net.Dialer).DialContext(dialCtx, "udp", addr)
443+
dialCancel()
437444
if err != nil {
438445
lastErr = err
439446
continue
440447
}
441448

449+
// Per-attempt timeout for the query
450+
conn.SetDeadline(time.Now().Add(t.timeout))
442451
response, err := t.sendDNSQuery(conn, wireFormat, false)
443452
conn.Close()
444453
if err != nil {
@@ -450,12 +459,15 @@ func (t *Tester) testDNSCrypt(stamp stamps.ServerStamp) error {
450459
}
451460

452461
// UDP failed after retries, try TCP
453-
conn, err := dialer.DialContext(ctx, "tcp", addr)
462+
dialCtx, dialCancel := context.WithTimeout(ctx, t.timeout)
463+
conn, err := new(net.Dialer).DialContext(dialCtx, "tcp", addr)
464+
dialCancel()
454465
if err != nil {
455466
return fmt.Errorf("connection failed (UDP: %v, TCP: %v)", lastErr, err)
456467
}
457468
defer conn.Close()
458469

470+
conn.SetDeadline(time.Now().Add(t.timeout))
459471
response, err := t.sendDNSQuery(conn, wireFormat, true)
460472
if err != nil {
461473
return err
@@ -464,10 +476,9 @@ func (t *Tester) testDNSCrypt(stamp stamps.ServerStamp) error {
464476
return t.validateDNSCryptResponse(response, stamp)
465477
}
466478

467-
// sendDNSQuery sends a DNS query over an established connection and returns the response
479+
// sendDNSQuery sends a DNS query over an established connection and returns the response.
480+
// The caller must set the connection deadline before calling this function.
468481
func (t *Tester) sendDNSQuery(conn net.Conn, wireFormat []byte, useTCP bool) (*dns.Msg, error) {
469-
conn.SetDeadline(time.Now().Add(t.timeout))
470-
471482
if useTCP {
472483
// TCP requires 2-byte length prefix
473484
length := make([]byte, 2)
@@ -708,11 +719,11 @@ func (t *Tester) testRelay(stamp stamps.ServerStamp) error {
708719
return fmt.Errorf("no server address in stamp")
709720
}
710721

711-
ctx, cancel := context.WithTimeout(context.Background(), t.timeout)
722+
// Use 3x timeout to allow for retries with slow relays
723+
// Budget: 3 UDP attempts * timeout + 2 delays (1s each) + 1 TCP attempt
724+
ctx, cancel := context.WithTimeout(context.Background(), t.timeout*3)
712725
defer cancel()
713726

714-
dialer := net.Dialer{Timeout: t.timeout}
715-
716727
// Create a DNS TXT query for the reference server's certificate
717728
query := new(dns.Msg)
718729
query.SetQuestion(dns.Fqdn(referenceProviderName), dns.TypeTXT)
@@ -735,15 +746,24 @@ func (t *Tester) testRelay(stamp stamps.ServerStamp) error {
735746
var lastErr error
736747
for attempt := 0; attempt < maxUDPRetries; attempt++ {
737748
if attempt > 0 {
738-
time.Sleep(udpRetryDelay)
749+
select {
750+
case <-ctx.Done():
751+
return fmt.Errorf("timeout after %d UDP attempts: %v", attempt, lastErr)
752+
case <-time.After(udpRetryDelay):
753+
}
739754
}
740755

741-
conn, err := dialer.DialContext(ctx, "udp", addr)
756+
// Per-attempt timeout for dialing
757+
dialCtx, dialCancel := context.WithTimeout(ctx, t.timeout)
758+
conn, err := new(net.Dialer).DialContext(dialCtx, "udp", addr)
759+
dialCancel()
742760
if err != nil {
743761
lastErr = err
744762
continue
745763
}
746764

765+
// Per-attempt timeout for the query
766+
conn.SetDeadline(time.Now().Add(t.timeout))
747767
response, err := t.sendRelayQuery(conn, anonPacket)
748768
conn.Close()
749769
if err != nil {
@@ -761,12 +781,15 @@ func (t *Tester) testRelay(stamp stamps.ServerStamp) error {
761781
}
762782

763783
// UDP failed after retries, try TCP
764-
conn, err := dialer.DialContext(ctx, "tcp", addr)
784+
dialCtx, dialCancel := context.WithTimeout(ctx, t.timeout)
785+
conn, err := new(net.Dialer).DialContext(dialCtx, "tcp", addr)
786+
dialCancel()
765787
if err != nil {
766788
return fmt.Errorf("relay test failed (UDP: %v, TCP connect: %v)", lastErr, err)
767789
}
768790
defer conn.Close()
769791

792+
conn.SetDeadline(time.Now().Add(t.timeout))
770793
response, err := t.sendRelayQueryTCP(conn, anonPacket)
771794
if err != nil {
772795
return fmt.Errorf("relay test failed (UDP: %v, TCP: %v)", lastErr, err)
@@ -789,10 +812,9 @@ func buildAnonPacket(serverIP net.IP, serverPort int, dnsQuery []byte) []byte {
789812
return packet
790813
}
791814

792-
// sendRelayQuery sends a query through the relay via UDP and returns the response
815+
// sendRelayQuery sends a query through the relay via UDP and returns the response.
816+
// The caller must set the connection deadline before calling this function.
793817
func (t *Tester) sendRelayQuery(conn net.Conn, packet []byte) (*dns.Msg, error) {
794-
conn.SetDeadline(time.Now().Add(t.timeout))
795-
796818
if _, err := conn.Write(packet); err != nil {
797819
return nil, fmt.Errorf("failed to write query: %v", err)
798820
}
@@ -811,10 +833,9 @@ func (t *Tester) sendRelayQuery(conn net.Conn, packet []byte) (*dns.Msg, error)
811833
return response, nil
812834
}
813835

814-
// sendRelayQueryTCP sends a query through the relay via TCP and returns the response
836+
// sendRelayQueryTCP sends a query through the relay via TCP and returns the response.
837+
// The caller must set the connection deadline before calling this function.
815838
func (t *Tester) sendRelayQueryTCP(conn net.Conn, packet []byte) (*dns.Msg, error) {
816-
conn.SetDeadline(time.Now().Add(t.timeout))
817-
818839
// TCP requires 2-byte length prefix
819840
length := make([]byte, 2)
820841
length[0] = byte(len(packet) >> 8)

0 commit comments

Comments
 (0)