Cancel dnsExchange goroutines as soon as we have a best response

This commit is contained in:
Frank Denis 2020-03-26 12:53:22 +01:00
parent ad36321dc8
commit 9542109d66
1 changed files with 15 additions and 3 deletions

View File

@ -193,31 +193,42 @@ type dnsExchangeResponse struct {
func dnsExchange(proxy *Proxy, proto string, query *dns.Msg, serverAddress string, relayUDPAddr *net.UDPAddr, relayTCPAddr *net.TCPAddr, serverName *string, tryFragmentsSupport bool) (*dns.Msg, time.Duration, bool, error) {
for {
cancelChannel := make(chan struct{})
channel := make(chan dnsExchangeResponse)
var err error
options := 0
for tries := 2; tries >= 0; tries-- {
for tries := 0; tries < 3; tries++ {
if tryFragmentsSupport {
queryCopy := query.Copy()
queryCopy.Id += uint16(options)
go func(query *dns.Msg, delay time.Duration) {
time.Sleep(delay)
option := _dnsExchange(proxy, proto, query, serverAddress, relayUDPAddr, relayTCPAddr, 1500)
option.fragmentsBlocked = false
option.priority = 0
channel <- option
time.Sleep(delay)
select {
case <-cancelChannel:
return
default:
}
}(queryCopy, time.Duration(200*tries)*time.Millisecond)
options++
}
queryCopy := query.Copy()
queryCopy.Id += uint16(options)
go func(query *dns.Msg, delay time.Duration) {
time.Sleep(delay)
option := _dnsExchange(proxy, proto, query, serverAddress, relayUDPAddr, relayTCPAddr, 480)
option.fragmentsBlocked = true
option.priority = 1
channel <- option
time.Sleep(delay)
select {
case <-cancelChannel:
return
default:
}
}(queryCopy, time.Duration(250*tries)*time.Millisecond)
options++
}
@ -228,6 +239,7 @@ func dnsExchange(proxy *Proxy, proto string, query *dns.Msg, serverAddress strin
(dnsExchangeResponse.priority == bestOption.priority && dnsExchangeResponse.rtt < bestOption.rtt) {
bestOption = &dnsExchangeResponse
if bestOption.priority == 0 {
close(cancelChannel)
break
}
}