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