1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-06-10 09:50:43 +00:00

bug fixes to dns server

This commit is contained in:
v2ray 2016-05-16 11:53:18 -07:00
parent 49c8c31e26
commit 18d75cb7b4
10 changed files with 46 additions and 28 deletions

View File

@ -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)

View File

@ -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
}

View File

@ -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()
}

View File

@ -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

View File

@ -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()

View File

@ -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})

View File

@ -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
})

View File

@ -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()

View File

@ -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() {

View File

@ -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)