mirror of https://github.com/v2ray/v2ray-core
parent
df34931ab3
commit
0a3b3d0b6d
|
@ -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,
|
||||||
|
@ -45,7 +41,7 @@ type UDPNameServer struct {
|
||||||
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)
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, id := range expiredRequests {
|
|
||||||
delete(s.requests, id)
|
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…
Reference in New Issue