refactor UDPNameServer clean up task

pull/876/head v3.10
Darien Raymond 7 years ago
parent df34931ab3
commit 0a3b3d0b6d
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169

@ -10,14 +10,10 @@ import (
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
"v2ray.com/core/common/dice" "v2ray.com/core/common/dice"
"v2ray.com/core/common/net" "v2ray.com/core/common/net"
"v2ray.com/core/common/signal"
"v2ray.com/core/transport/internet/udp" "v2ray.com/core/transport/internet/udp"
) )
const (
CleanupInterval = time.Second * 120
CleanupThreshold = 512
)
var ( var (
multiQuestionDNS = map[net.Address]bool{ multiQuestionDNS = map[net.Address]bool{
net.IPAddress([]byte{8, 8, 8, 8}): true, net.IPAddress([]byte{8, 8, 8, 8}): true,
@ -42,10 +38,10 @@ type PendingRequest struct {
type UDPNameServer struct { type UDPNameServer struct {
sync.Mutex sync.Mutex
address net.Destination address net.Destination
requests map[uint16]*PendingRequest requests map[uint16]*PendingRequest
udpServer *udp.Dispatcher udpServer *udp.Dispatcher
nextCleanup time.Time cleanup *signal.PeriodicTask
} }
func NewUDPNameServer(address net.Destination, dispatcher core.Dispatcher) *UDPNameServer { func NewUDPNameServer(address net.Destination, dispatcher core.Dispatcher) *UDPNameServer {
@ -54,36 +50,35 @@ func NewUDPNameServer(address net.Destination, dispatcher core.Dispatcher) *UDPN
requests: make(map[uint16]*PendingRequest), requests: make(map[uint16]*PendingRequest),
udpServer: udp.NewDispatcher(dispatcher), udpServer: udp.NewDispatcher(dispatcher),
} }
s.cleanup = &signal.PeriodicTask{
Interval: time.Minute,
Execute: s.Cleanup,
}
s.cleanup.Start()
return s return s
} }
func (s *UDPNameServer) Cleanup() { func (s *UDPNameServer) Cleanup() error {
expiredRequests := make([]uint16, 0, 16)
now := time.Now() now := time.Now()
s.Lock() s.Lock()
for id, r := range s.requests { for id, r := range s.requests {
if r.expire.Before(now) { if r.expire.Before(now) {
expiredRequests = append(expiredRequests, id)
close(r.response) close(r.response)
delete(s.requests, id)
} }
} }
for _, id := range expiredRequests {
delete(s.requests, id)
}
s.Unlock() s.Unlock()
return nil
} }
func (s *UDPNameServer) AssignUnusedID(response chan<- *ARecord) uint16 { func (s *UDPNameServer) AssignUnusedID(response chan<- *ARecord) uint16 {
var id uint16 var id uint16
s.Lock() s.Lock()
if len(s.requests) > CleanupThreshold && s.nextCleanup.Before(time.Now()) {
s.nextCleanup = time.Now().Add(CleanupInterval)
go s.Cleanup()
}
for { for {
id = dice.RollUint16() id = dice.RollUint16()
if _, found := s.requests[id]; found { if _, found := s.requests[id]; found {
time.Sleep(time.Millisecond * 500)
continue continue
} }
newError("add pending request id ", id).AtDebug().WriteToLog() newError("add pending request id ", id).AtDebug().WriteToLog()

Loading…
Cancel
Save