mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-12-21 01:27:03 -05:00
bug fixes to dns server
This commit is contained in:
parent
49c8c31e26
commit
18d75cb7b4
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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})
|
||||
|
@ -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
|
||||
})
|
||||
|
@ -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()
|
||||
|
@ -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() {
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user