瀏覽代碼

bug fixes to dns server

v2ray 9 年之前
父節點
當前提交
18d75cb7b4

+ 14 - 13
app/dns/nameserver.go

@@ -104,6 +104,7 @@ func (this *UDPNameServer) HandleResponse(dest v2net.Destination, payload *alloc
 	}
 	id := msg.Id
 	ttl := DefaultTTL
+	log.Debug("DNS: Handling response for id ", id, " content: ", msg.String())
 
 	this.Lock()
 	request, found := this.requests[id]
@@ -115,10 +116,16 @@ func (this *UDPNameServer) HandleResponse(dest v2net.Destination, payload *alloc
 	this.Unlock()
 
 	for _, rr := range msg.Answer {
-		if a, ok := rr.(*dns.A); ok {
-			record.IPs = append(record.IPs, a.A)
-			if a.Hdr.Ttl < ttl {
-				ttl = a.Hdr.Ttl
+		switch rr := rr.(type) {
+		case *dns.A:
+			record.IPs = append(record.IPs, rr.A)
+			if rr.Hdr.Ttl < ttl {
+				ttl = rr.Hdr.Ttl
+			}
+		case *dns.AAAA:
+			record.IPs = append(record.IPs, rr.AAAA)
+			if rr.Hdr.Ttl < ttl {
+				ttl = rr.Hdr.Ttl
 			}
 		}
 	}
@@ -129,7 +136,7 @@ func (this *UDPNameServer) HandleResponse(dest v2net.Destination, payload *alloc
 }
 
 func (this *UDPNameServer) QueryA(domain string) <-chan *ARecord {
-	response := make(chan *ARecord)
+	response := make(chan *ARecord, 1)
 
 	buffer := alloc.NewBuffer()
 	msg := new(dns.Msg)
@@ -140,13 +147,7 @@ func (this *UDPNameServer) QueryA(domain string) <-chan *ARecord {
 			Name:   dns.Fqdn(domain),
 			Qtype:  dns.TypeA,
 			Qclass: dns.ClassINET,
-		},
-		dns.Question{
-			Name:   dns.Fqdn(domain),
-			Qtype:  dns.TypeAAAA,
-			Qclass: dns.ClassINET,
-		},
-	}
+		}}
 
 	writtenBuffer, _ := msg.PackBuffer(buffer.Value)
 	buffer.Slice(0, len(writtenBuffer))
@@ -161,7 +162,7 @@ type LocalNameServer struct {
 }
 
 func (this *LocalNameServer) QueryA(domain string) <-chan *ARecord {
-	response := make(chan *ARecord)
+	response := make(chan *ARecord, 1)
 
 	go func() {
 		defer close(response)

+ 9 - 3
app/dns/server.go

@@ -7,12 +7,13 @@ import (
 
 	"github.com/v2ray/v2ray-core/app"
 	"github.com/v2ray/v2ray-core/app/dispatcher"
+	"github.com/v2ray/v2ray-core/common/log"
 
 	"github.com/miekg/dns"
 )
 
 const (
-	QueryTimeout = time.Second * 2
+	QueryTimeout = time.Second * 8
 )
 
 type DomainRecord struct {
@@ -62,16 +63,21 @@ func (this *CacheServer) Get(context app.Context, domain string) []net.IP {
 	for _, server := range this.servers {
 		response := server.QueryA(domain)
 		select {
-		case a := <-response:
+		case a, open := <-response:
+			if !open || a == nil {
+				continue
+			}
 			this.Lock()
 			this.records[domain] = &DomainRecord{
 				A: a,
 			}
 			this.Unlock()
+			log.Debug("DNS: Returning ", len(a.IPs), " IPs for domain ", domain)
 			return a.IPs
-		case <-time.Tick(QueryTimeout):
+		case <-time.After(QueryTimeout):
 		}
 	}
 
+	log.Debug("DNS: Returning nil for domain ", domain)
 	return nil
 }

+ 1 - 0
app/router/rules/chinaip_test.go

@@ -22,6 +22,7 @@ func TestChinaIP(t *testing.T) {
 	assert.Bool(rule.Apply(makeDestination("101.226.103.106"))).IsTrue() // qq.com
 	assert.Bool(rule.Apply(makeDestination("115.239.210.36"))).IsTrue()  // image.baidu.com
 	assert.Bool(rule.Apply(makeDestination("120.135.126.1"))).IsTrue()
+	assert.Bool(rule.Apply(makeDestination("101.201.173.126"))).IsTrue()
 
 	assert.Bool(rule.Apply(makeDestination("8.8.8.8"))).IsFalse()
 }

+ 3 - 0
app/router/rules/router.go

@@ -8,6 +8,7 @@ import (
 	"github.com/v2ray/v2ray-core/app/dns"
 	"github.com/v2ray/v2ray-core/app/router"
 	"github.com/v2ray/v2ray-core/common/collect"
+	"github.com/v2ray/v2ray-core/common/log"
 	v2net "github.com/v2ray/v2ray-core/common/net"
 )
 
@@ -78,9 +79,11 @@ func (this *Router) takeDetourWithoutCache(dest v2net.Destination) (string, erro
 		}
 	}
 	if this.config.DomainStrategy == UseIPIfNonMatch && dest.Address().IsDomain() {
+		log.Info("Router: Looking up IP for ", dest)
 		ipDests := this.ResolveIP(dest)
 		if ipDests != nil {
 			for _, ipDest := range ipDests {
+				log.Info("Router: Trying IP ", ipDest)
 				for _, rule := range this.config.Rules {
 					if rule.Apply(ipDest) {
 						return rule.Tag, nil

+ 1 - 1
proxy/freedom/freedom_test.go

@@ -34,7 +34,7 @@ func TestSinglePacket(t *testing.T) {
 	data2Send := "Data to be sent to remote"
 	payload := alloc.NewSmallBuffer().Clear().Append([]byte(data2Send))
 
-	go freedom.Dispatch(v2net.TCPDestination(v2net.IPAddress([]byte{127, 0, 0, 1}), port), payload, traffic)
+	go freedom.Dispatch(v2net.TCPDestination(v2net.LocalHostIP, port), payload, traffic)
 	traffic.InboundInput().Close()
 
 	respPayload, err := traffic.InboundOutput().Read()

+ 2 - 2
proxy/shadowsocks/protocol_test.go

@@ -21,7 +21,7 @@ func TestNormalRequestParsing(t *testing.T) {
 
 	request, err := ReadRequest(buffer, nil, false)
 	assert.Error(err).IsNil()
-	netassert.Address(request.Address).Equals(v2net.IPAddress([]byte{127, 0, 0, 1}))
+	netassert.Address(request.Address).Equals(v2net.LocalHostIP)
 	netassert.Port(request.Port).Equals(v2net.Port(80))
 	assert.Bool(request.OTA).IsFalse()
 }
@@ -110,7 +110,7 @@ func TestUDPRequestParsing(t *testing.T) {
 
 	request, err := ReadRequest(buffer, nil, true)
 	assert.Error(err).IsNil()
-	netassert.Address(request.Address).Equals(v2net.IPAddress([]byte{127, 0, 0, 1}))
+	netassert.Address(request.Address).Equals(v2net.LocalHostIP)
 	netassert.Port(request.Port).Equals(v2net.Port(80))
 	assert.Bool(request.OTA).IsFalse()
 	assert.Bytes(request.UDPPayload.Value).Equals([]byte{1, 2, 3, 4, 5, 6})

+ 1 - 1
proxy/socks/config_json.go

@@ -56,7 +56,7 @@ func init() {
 			if rawConfig.Host != nil {
 				socksConfig.Address = rawConfig.Host.Address
 			} else {
-				socksConfig.Address = v2net.IPAddress([]byte{127, 0, 0, 1})
+				socksConfig.Address = v2net.LocalHostIP
 			}
 			return socksConfig, nil
 		})

+ 2 - 2
testing/scenarios/socks_end_test.go

@@ -192,7 +192,7 @@ func TestUDPAssociate(t *testing.T) {
 
 	for i := 0; i < 100; i++ {
 		udpPayload := "UDP request to udp server."
-		udpRequest := socks5UDPRequest(v2net.UDPDestination(v2net.IPAddress([]byte{127, 0, 0, 1}), targetPort), []byte(udpPayload))
+		udpRequest := socks5UDPRequest(v2net.UDPDestination(v2net.LocalHostIP, targetPort), []byte(udpPayload))
 
 		nBytes, err = udpConn.Write(udpRequest)
 		assert.Int(nBytes).Equals(len(udpRequest))
@@ -202,7 +202,7 @@ func TestUDPAssociate(t *testing.T) {
 		nBytes, err = udpConn.Read(udpResponse)
 		assert.Error(err).IsNil()
 		assert.Bytes(udpResponse[:nBytes]).Equals(
-			socks5UDPRequest(v2net.UDPDestination(v2net.IPAddress([]byte{127, 0, 0, 1}), targetPort), []byte("Processed: UDP request to udp server.")))
+			socks5UDPRequest(v2net.UDPDestination(v2net.LocalHostIP, targetPort), []byte("Processed: UDP request to udp server.")))
 	}
 
 	udpConn.Close()

+ 1 - 1
testing/servers/http/http.go

@@ -28,7 +28,7 @@ func (server *Server) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
 
 func (server *Server) Start() (v2net.Destination, error) {
 	go http.ListenAndServe(":"+server.Port.String(), server)
-	return v2net.TCPDestination(v2net.IPAddress([]byte{127, 0, 0, 1}), v2net.Port(server.Port)), nil
+	return v2net.TCPDestination(v2net.LocalHostIP, v2net.Port(server.Port)), nil
 }
 
 func (this *Server) Close() {

+ 12 - 5
transport/hub/udp_server.go

@@ -21,11 +21,12 @@ type TimedInboundRay struct {
 	sync.RWMutex
 }
 
-func NewTimedInboundRay(name string, inboundRay ray.InboundRay) *TimedInboundRay {
+func NewTimedInboundRay(name string, inboundRay ray.InboundRay, server *UDPServer) *TimedInboundRay {
 	r := &TimedInboundRay{
 		name:       name,
 		inboundRay: inboundRay,
-		accessed:   make(chan bool),
+		accessed:   make(chan bool, 1),
+		server:     server,
 	}
 	go r.Monitor()
 	return r
@@ -38,6 +39,13 @@ func (this *TimedInboundRay) Monitor() {
 		case <-this.accessed:
 		default:
 			// Ray not accessed for a while, assuming communication is dead.
+			this.RLock()
+			if this.server == nil {
+				this.RUnlock()
+				return
+			}
+			this.server.RemoveRay(this.name)
+			this.RUnlock()
 			this.Release()
 			return
 		}
@@ -77,7 +85,6 @@ func (this *TimedInboundRay) Release() {
 	if this.server == nil {
 		return
 	}
-	this.server.RemoveRay(this.name)
 	this.server = nil
 	this.inboundRay.InboundInput().Close()
 	this.inboundRay.InboundOutput().Release()
@@ -114,7 +121,7 @@ func (this *UDPServer) locateExistingAndDispatch(name string, payload *alloc.Buf
 		}
 		err := outputStream.Write(payload)
 		if err != nil {
-			go this.RemoveRay(name)
+			go entry.Release()
 			return false
 		}
 		return true
@@ -131,7 +138,7 @@ func (this *UDPServer) Dispatch(source v2net.Destination, destination v2net.Dest
 
 	log.Info("UDP Server: establishing new connection for ", destString)
 	inboundRay := this.packetDispatcher.DispatchToOutbound(destination)
-	timedInboundRay := NewTimedInboundRay(destString, inboundRay)
+	timedInboundRay := NewTimedInboundRay(destString, inboundRay, this)
 	outputStream := timedInboundRay.InboundInput()
 	if outputStream != nil {
 		outputStream.Write(payload)