mirror of https://github.com/v2ray/v2ray-core
smarter DNS query
parent
2c82f65189
commit
4ec96efe84
|
@ -21,6 +21,10 @@ const (
|
||||||
CleanupThreshold = 512
|
CleanupThreshold = 512
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
pseudoDestination = v2net.UDPDestination(v2net.LocalHostIP, v2net.Port(53))
|
||||||
|
)
|
||||||
|
|
||||||
type ARecord struct {
|
type ARecord struct {
|
||||||
IPs []net.IP
|
IPs []net.IP
|
||||||
Expire time.Time
|
Expire time.Time
|
||||||
|
@ -86,7 +90,7 @@ func (this *UDPNameServer) AssignUnusedID(response chan<- *ARecord) uint16 {
|
||||||
}
|
}
|
||||||
log.Debug("DNS: Add pending request id ", id)
|
log.Debug("DNS: Add pending request id ", id)
|
||||||
this.requests[id] = &PendingRequest{
|
this.requests[id] = &PendingRequest{
|
||||||
expire: time.Now().Add(time.Second * 16),
|
expire: time.Now().Add(time.Second * 8),
|
||||||
response: response,
|
response: response,
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
@ -139,12 +143,10 @@ func (this *UDPNameServer) HandleResponse(dest v2net.Destination, payload *alloc
|
||||||
close(request.response)
|
close(request.response)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *UDPNameServer) QueryA(domain string) <-chan *ARecord {
|
func (this *UDPNameServer) BuildQueryA(domain string, id uint16) *alloc.Buffer {
|
||||||
response := make(chan *ARecord, 1)
|
|
||||||
|
|
||||||
buffer := alloc.NewBuffer()
|
buffer := alloc.NewBuffer()
|
||||||
msg := new(dns.Msg)
|
msg := new(dns.Msg)
|
||||||
msg.Id = this.AssignUnusedID(response)
|
msg.Id = id
|
||||||
msg.RecursionDesired = true
|
msg.RecursionDesired = true
|
||||||
msg.Question = []dns.Question{
|
msg.Question = []dns.Question{
|
||||||
dns.Question{
|
dns.Question{
|
||||||
|
@ -156,8 +158,32 @@ func (this *UDPNameServer) QueryA(domain string) <-chan *ARecord {
|
||||||
writtenBuffer, _ := msg.PackBuffer(buffer.Value)
|
writtenBuffer, _ := msg.PackBuffer(buffer.Value)
|
||||||
buffer.Slice(0, len(writtenBuffer))
|
buffer.Slice(0, len(writtenBuffer))
|
||||||
|
|
||||||
fakeDestination := v2net.UDPDestination(v2net.LocalHostIP, v2net.Port(53))
|
return buffer
|
||||||
this.udpServer.Dispatch(fakeDestination, this.address, buffer, this.HandleResponse)
|
}
|
||||||
|
|
||||||
|
func (this *UDPNameServer) DispatchQuery(payload *alloc.Buffer) {
|
||||||
|
this.udpServer.Dispatch(pseudoDestination, this.address, payload, this.HandleResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *UDPNameServer) QueryA(domain string) <-chan *ARecord {
|
||||||
|
response := make(chan *ARecord, 1)
|
||||||
|
id := this.AssignUnusedID(response)
|
||||||
|
|
||||||
|
this.DispatchQuery(this.BuildQueryA(domain, id))
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
for i := 0; i < 2; i++ {
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
this.Lock()
|
||||||
|
_, found := this.requests[id]
|
||||||
|
this.Unlock()
|
||||||
|
if found {
|
||||||
|
this.DispatchQuery(this.BuildQueryA(domain, id))
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue