Fix goroutines memory leak by unbuffered channel blocking (#2136)
* Use buffered channel to avoid goroutine hanging on A send on an unbuffered channel can proceed if a receiver is ready. * Balance captivePortalHandler.cancelChannels for Stop
This commit is contained in:
parent
59ce17e0ab
commit
0e2bb13254
|
@ -84,6 +84,7 @@ func handleColdStartClient(clientPc *net.UDPConn, cancelChannel chan struct{}, i
|
|||
exit := false
|
||||
select {
|
||||
case <-cancelChannel:
|
||||
cancelChannel <- struct{}{}
|
||||
exit = true
|
||||
default:
|
||||
}
|
||||
|
@ -95,6 +96,12 @@ func handleColdStartClient(clientPc *net.UDPConn, cancelChannel chan struct{}, i
|
|||
}
|
||||
if err != nil {
|
||||
dlog.Warn(err)
|
||||
select {
|
||||
case <-cancelChannel:
|
||||
cancelChannel <- struct{}{}
|
||||
default:
|
||||
cancelChannel = make(chan struct{}, 1)
|
||||
}
|
||||
return true
|
||||
}
|
||||
packet := buffer[:length]
|
||||
|
@ -134,7 +141,6 @@ func addColdStartListener(
|
|||
for !handleColdStartClient(clientPc, cancelChannel, ipsMap) {
|
||||
}
|
||||
clientPc.Close()
|
||||
cancelChannel <- struct{}{}
|
||||
}()
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -316,7 +316,7 @@ func DNSExchange(
|
|||
) (*dns.Msg, time.Duration, bool, error) {
|
||||
for {
|
||||
cancelChannel := make(chan struct{})
|
||||
channel := make(chan DNSExchangeResponse)
|
||||
channel := make(chan DNSExchangeResponse, 6)
|
||||
var err error
|
||||
options := 0
|
||||
|
||||
|
@ -325,32 +325,32 @@ func DNSExchange(
|
|||
queryCopy := query.Copy()
|
||||
queryCopy.Id += uint16(options)
|
||||
go func(query *dns.Msg, delay time.Duration) {
|
||||
option := _dnsExchange(proxy, proto, query, serverAddress, relay, 1500)
|
||||
time.Sleep(delay)
|
||||
option := DNSExchangeResponse{err: errors.New("Canceled")}
|
||||
select {
|
||||
case <-cancelChannel:
|
||||
default:
|
||||
option = _dnsExchange(proxy, proto, query, serverAddress, relay, 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) {
|
||||
option := _dnsExchange(proxy, proto, query, serverAddress, relay, 480)
|
||||
time.Sleep(delay)
|
||||
option := DNSExchangeResponse{err: errors.New("Canceled")}
|
||||
select {
|
||||
case <-cancelChannel:
|
||||
default:
|
||||
option = _dnsExchange(proxy, proto, query, serverAddress, relay, 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++
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue