1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-12-21 09:36:34 -05:00

dns cache

This commit is contained in:
v2ray 2015-12-06 11:00:10 +01:00
parent 59030814cb
commit e1c58fae2b
16 changed files with 320 additions and 16 deletions

10
app/dns.go Normal file
View File

@ -0,0 +1,10 @@
package app
import (
"net"
)
type DnsCache interface {
Get(domain string) net.IP
Add(domain string, ip net.IP)
}

5
app/dns/config.go Normal file
View File

@ -0,0 +1,5 @@
package dns
type CacheConfig interface {
TrustedSource() []string
}

88
app/dns/dns.go Normal file
View File

@ -0,0 +1,88 @@
package dns
import (
"net"
"sync"
"time"
)
type entry struct {
domain string
ip net.IP
validUntil time.Time
}
func newEntry(domain string, ip net.IP) *entry {
this := &entry{
domain: domain,
ip: ip,
}
this.Extend()
return this
}
func (this *entry) IsValid() bool {
return this.validUntil.After(time.Now())
}
func (this *entry) Extend() {
this.validUntil = time.Now().Add(time.Hour)
}
type DnsCache struct {
sync.RWMutex
cache map[string]*entry
}
func NewCache() *DnsCache {
cache := &DnsCache{
cache: make(map[string]*entry),
}
go cache.cleanup()
return cache
}
func (this *DnsCache) cleanup() {
for range time.Tick(10 * time.Second) {
entry2Remove := make([]*entry, 0, 128)
this.RLock()
for _, entry := range this.cache {
if !entry.IsValid() {
entry2Remove = append(entry2Remove, entry)
}
}
this.RUnlock()
for _, entry := range entry2Remove {
if !entry.IsValid() {
this.Lock()
delete(this.cache, entry.domain)
this.Unlock()
}
}
}
}
func (this *DnsCache) Add(domain string, ip net.IP) {
this.RLock()
entry, found := this.cache[domain]
this.RUnlock()
if found {
entry.ip = ip
entry.Extend()
} else {
this.Lock()
this.cache[domain] = newEntry(domain, ip)
this.Unlock()
}
}
func (this *DnsCache) Get(domain string) net.IP {
this.RLock()
entry, found := this.cache[domain]
this.RUnlock()
if found {
return entry.ip
}
return nil
}

23
app/dns/dns_test.go Normal file
View File

@ -0,0 +1,23 @@
package dns_test
import (
"net"
"testing"
"github.com/v2ray/v2ray-core/app/dns"
netassert "github.com/v2ray/v2ray-core/common/net/testing/assert"
v2testing "github.com/v2ray/v2ray-core/testing"
)
func TestDnsAdd(t *testing.T) {
v2testing.Current(t)
domain := "v2ray.com"
cache := dns.NewCache()
ip := cache.Get(domain)
netassert.IP(ip).IsNil()
cache.Add(domain, []byte{1, 2, 3, 4})
ip = cache.Get(domain)
netassert.IP(ip).Equals(net.IP([]byte{1, 2, 3, 4}))
}

View File

@ -2,12 +2,23 @@ package app
type Space struct {
packetDispatcher PacketDispatcher
dnsCache DnsCache
}
func NewSpace() *Space {
return new(Space)
}
func (this *Space) Bind(object interface{}) {
if packetDispatcher, ok := object.(PacketDispatcher); ok {
this.packetDispatcher = packetDispatcher
}
if dnsCache, ok := object.(DnsCache); ok {
this.dnsCache = dnsCache
}
}
func (this *Space) HasPacketDispatcher() bool {
return this.packetDispatcher != nil
}
@ -16,8 +27,10 @@ func (this *Space) PacketDispatcher() PacketDispatcher {
return this.packetDispatcher
}
func (this *Space) Bind(object interface{}) {
if packetDispatcher, ok := object.(PacketDispatcher); ok {
this.packetDispatcher = packetDispatcher
}
func (this *Space) HasDnsCache() bool {
return this.dnsCache != nil
}
func (this *Space) DnsCache() DnsCache {
return this.dnsCache
}

View File

@ -0,0 +1,39 @@
package assert
import (
"bytes"
"net"
"github.com/v2ray/v2ray-core/common/serial"
"github.com/v2ray/v2ray-core/testing/assert"
)
func IP(value net.IP) *IPSubject {
return &IPSubject{value: value}
}
type IPSubject struct {
assert.Subject
value net.IP
}
func (subject *IPSubject) Named(name string) *IPSubject {
subject.Subject.Named(name)
return subject
}
func (subject *IPSubject) DisplayString() string {
return subject.Subject.DisplayString(subject.value.String())
}
func (subject *IPSubject) IsNil() {
if subject.value != nil {
subject.Fail(subject.DisplayString(), "is", serial.StringLiteral("nil"))
}
}
func (subject *IPSubject) Equals(ip net.IP) {
if !bytes.Equal([]byte(subject.value), []byte(ip)) {
subject.Fail(subject.DisplayString(), "equals to", ip)
}
}

View File

@ -3,6 +3,7 @@ package blackhole
import (
"io/ioutil"
"github.com/v2ray/v2ray-core/app"
v2net "github.com/v2ray/v2ray-core/common/net"
"github.com/v2ray/v2ray-core/proxy/common/connhandler"
"github.com/v2ray/v2ray-core/transport/ray"
@ -31,7 +32,7 @@ func (this *BlackHole) Dispatch(firstPacket v2net.Packet, ray ray.OutboundRay) e
type BlackHoleFactory struct {
}
func (this BlackHoleFactory) Create(config interface{}) (connhandler.OutboundConnectionHandler, error) {
func (this BlackHoleFactory) Create(space *app.Space, config interface{}) (connhandler.OutboundConnectionHandler, error) {
return NewBlackHole(), nil
}

View File

@ -1,6 +1,7 @@
package connhandler
import (
"github.com/v2ray/v2ray-core/app"
v2net "github.com/v2ray/v2ray-core/common/net"
"github.com/v2ray/v2ray-core/transport/ray"
)
@ -8,7 +9,7 @@ import (
// An OutboundConnectionHandlerFactory creates OutboundConnectionHandler on demand.
type OutboundConnectionHandlerFactory interface {
// Create creates a new OutboundConnectionHandler with given config.
Create(config interface{}) (OutboundConnectionHandler, error)
Create(space *app.Space, config interface{}) (OutboundConnectionHandler, error)
}
// An OutboundConnectionHandler handles outbound network connection for V2Ray.

View File

@ -4,16 +4,14 @@ import (
"net"
"sync"
"github.com/v2ray/v2ray-core/app"
"github.com/v2ray/v2ray-core/common/log"
v2net "github.com/v2ray/v2ray-core/common/net"
"github.com/v2ray/v2ray-core/transport/ray"
)
type FreedomConnection struct {
}
func NewFreedomConnection() *FreedomConnection {
return &FreedomConnection{}
space *app.Space
}
func (this *FreedomConnection) Dispatch(firstPacket v2net.Packet, ray ray.OutboundRay) error {
@ -66,6 +64,19 @@ func (this *FreedomConnection) Dispatch(firstPacket v2net.Packet, ray ray.Outbou
v2net.ReaderToChan(output, conn)
}()
if this.space.HasDnsCache() {
if firstPacket.Destination().Address().IsDomain() {
domain := firstPacket.Destination().Address().Domain()
addr := conn.RemoteAddr()
switch typedAddr := addr.(type) {
case *net.TCPAddr:
this.space.DnsCache().Add(domain, typedAddr.IP)
case *net.UDPAddr:
this.space.DnsCache().Add(domain, typedAddr.IP)
}
}
}
writeMutex.Lock()
if tcpConn, ok := conn.(*net.TCPConn); ok {
tcpConn.CloseWrite()

View File

@ -1,14 +1,15 @@
package freedom
import (
"github.com/v2ray/v2ray-core/app"
"github.com/v2ray/v2ray-core/proxy/common/connhandler"
)
type FreedomFactory struct {
}
func (this FreedomFactory) Create(config interface{}) (connhandler.OutboundConnectionHandler, error) {
return NewFreedomConnection(), nil
func (this FreedomFactory) Create(space *app.Space, config interface{}) (connhandler.OutboundConnectionHandler, error) {
return &FreedomConnection{space: space}, nil
}
func init() {

View File

@ -4,6 +4,7 @@ import (
"io"
"sync"
"github.com/v2ray/v2ray-core/app"
v2net "github.com/v2ray/v2ray-core/common/net"
"github.com/v2ray/v2ray-core/proxy/common/connhandler"
"github.com/v2ray/v2ray-core/transport/ray"
@ -44,6 +45,6 @@ func (this *OutboundConnectionHandler) Dispatch(packet v2net.Packet, ray ray.Out
return nil
}
func (this *OutboundConnectionHandler) Create(config interface{}) (connhandler.OutboundConnectionHandler, error) {
func (this *OutboundConnectionHandler) Create(space *app.Space, config interface{}) (connhandler.OutboundConnectionHandler, error) {
return this, nil
}

View File

@ -6,6 +6,7 @@ import (
"net"
"sync"
"github.com/v2ray/v2ray-core/app"
"github.com/v2ray/v2ray-core/common/alloc"
v2crypto "github.com/v2ray/v2ray-core/common/crypto"
"github.com/v2ray/v2ray-core/common/log"
@ -19,6 +20,7 @@ import (
type VMessOutboundHandler struct {
receiverManager *ReceiverManager
space *app.Space
}
func (this *VMessOutboundHandler) Dispatch(firstPacket v2net.Packet, ray ray.OutboundRay) error {
@ -174,9 +176,10 @@ func handleResponse(conn net.Conn, request *protocol.VMessRequest, output chan<-
type VMessOutboundHandlerFactory struct {
}
func (this *VMessOutboundHandlerFactory) Create(rawConfig interface{}) (connhandler.OutboundConnectionHandler, error) {
func (this *VMessOutboundHandlerFactory) Create(space *app.Space, rawConfig interface{}) (connhandler.OutboundConnectionHandler, error) {
vOutConfig := rawConfig.(config.Outbound)
return &VMessOutboundHandler{
space: space,
receiverManager: NewReceiverManager(vOutConfig.Receivers()),
}, nil
}

View File

@ -1,6 +1,7 @@
package config
import (
"github.com/v2ray/v2ray-core/app/dns"
routerconfig "github.com/v2ray/v2ray-core/app/router/config"
"github.com/v2ray/v2ray-core/common/log"
v2net "github.com/v2ray/v2ray-core/common/net"
@ -17,6 +18,11 @@ type LogConfig interface {
LogLevel() log.LogLevel
}
type DnsConfig interface {
Enabled() bool
Settings() dns.CacheConfig
}
type InboundDetourConfig interface {
Protocol() string
PortRange() v2net.PortRange

View File

@ -73,7 +73,7 @@ func NewPoint(pConfig config.PointConfig) (*Point, error) {
return nil, config.BadConfiguration
}
ochConfig := pConfig.OutboundConfig().Settings()
och, err := ochFactory.Create(ochConfig)
och, err := ochFactory.Create(vpoint.space, ochConfig)
if err != nil {
log.Error("Failed to create outbound connection handler: %v", err)
return nil, err
@ -105,7 +105,7 @@ func NewPoint(pConfig config.PointConfig) (*Point, error) {
log.Error("Unknown detour outbound connection handler factory %s", detourConfig.Protocol())
return nil, config.BadConfiguration
}
detourHandler, err := detourFactory.Create(detourConfig.Settings())
detourHandler, err := detourFactory.Create(vpoint.space, detourConfig.Settings())
if err != nil {
log.Error("Failed to create detour outbound connection handler: %v", err)
return nil, err

View File

@ -0,0 +1,102 @@
2015/12/06 10:58:06 127.0.0.1:61726 accepted 127.0.0.1:50024
2015/12/06 10:58:06 127.0.0.1:61730 accepted 127.0.0.1:30001
2015/12/06 10:58:06 127.0.0.1:61733 accepted 127.0.0.1:30001
2015/12/06 10:58:06 127.0.0.1:61736 accepted 127.0.0.1:30001
2015/12/06 10:58:06 127.0.0.1:61739 accepted 127.0.0.1:30001
2015/12/06 10:58:06 127.0.0.1:61742 accepted 127.0.0.1:30001
2015/12/06 10:58:06 127.0.0.1:61745 accepted 127.0.0.1:30001
2015/12/06 10:58:06 127.0.0.1:61748 accepted 127.0.0.1:30001
2015/12/06 10:58:06 127.0.0.1:61751 accepted 127.0.0.1:30001
2015/12/06 10:58:06 127.0.0.1:61754 accepted 127.0.0.1:30001
2015/12/06 10:58:06 127.0.0.1:61757 accepted 127.0.0.1:30001
2015/12/06 10:58:06 127.0.0.1:61760 accepted 127.0.0.1:30001
2015/12/06 10:58:06 127.0.0.1:61763 accepted 127.0.0.1:30001
2015/12/06 10:58:06 127.0.0.1:61766 accepted 127.0.0.1:30001
2015/12/06 10:58:06 127.0.0.1:61769 accepted 127.0.0.1:30001
2015/12/06 10:58:06 127.0.0.1:61772 accepted 127.0.0.1:30001
2015/12/06 10:58:06 127.0.0.1:61775 accepted 127.0.0.1:30001
2015/12/06 10:58:06 127.0.0.1:61778 accepted 127.0.0.1:30001
2015/12/06 10:58:06 127.0.0.1:61781 accepted 127.0.0.1:30001
2015/12/06 10:58:06 127.0.0.1:61784 accepted 127.0.0.1:30001
2015/12/06 10:58:06 127.0.0.1:61787 accepted 127.0.0.1:30001
2015/12/06 10:58:06 127.0.0.1:61790 accepted 127.0.0.1:30001
2015/12/06 10:58:06 127.0.0.1:61793 accepted 127.0.0.1:30001
2015/12/06 10:58:06 127.0.0.1:61796 accepted 127.0.0.1:30001
2015/12/06 10:58:06 127.0.0.1:61799 accepted 127.0.0.1:30001
2015/12/06 10:58:06 127.0.0.1:61802 accepted 127.0.0.1:30001
2015/12/06 10:58:06 127.0.0.1:61805 accepted 127.0.0.1:30001
2015/12/06 10:58:06 127.0.0.1:61808 accepted 127.0.0.1:30001
2015/12/06 10:58:06 127.0.0.1:61811 accepted 127.0.0.1:30001
2015/12/06 10:58:06 127.0.0.1:61814 accepted 127.0.0.1:30001
2015/12/06 10:58:06 127.0.0.1:61817 accepted 127.0.0.1:30001
2015/12/06 10:58:06 127.0.0.1:61820 accepted 127.0.0.1:30001
2015/12/06 10:58:06 127.0.0.1:61823 accepted 127.0.0.1:30001
2015/12/06 10:58:06 127.0.0.1:61826 accepted 127.0.0.1:30001
2015/12/06 10:58:06 127.0.0.1:61829 accepted 127.0.0.1:30001
2015/12/06 10:58:07 127.0.0.1:61832 accepted 127.0.0.1:30001
2015/12/06 10:58:07 127.0.0.1:61835 accepted 127.0.0.1:30001
2015/12/06 10:58:07 127.0.0.1:61838 accepted 127.0.0.1:30001
2015/12/06 10:58:07 127.0.0.1:61841 accepted 127.0.0.1:30001
2015/12/06 10:58:07 127.0.0.1:61844 accepted 127.0.0.1:30001
2015/12/06 10:58:07 127.0.0.1:61849 accepted 127.0.0.1:30001
2015/12/06 10:58:07 127.0.0.1:61852 accepted 127.0.0.1:30001
2015/12/06 10:58:07 127.0.0.1:61855 accepted 127.0.0.1:30001
2015/12/06 10:58:07 127.0.0.1:61858 accepted 127.0.0.1:30001
2015/12/06 10:58:07 127.0.0.1:61861 accepted 127.0.0.1:30001
2015/12/06 10:58:07 127.0.0.1:61864 accepted 127.0.0.1:30001
2015/12/06 10:58:08 127.0.0.1:61867 accepted 127.0.0.1:30001
2015/12/06 10:58:08 127.0.0.1:61870 accepted 127.0.0.1:30001
2015/12/06 10:58:08 127.0.0.1:61873 accepted 127.0.0.1:30001
2015/12/06 10:58:08 127.0.0.1:61876 accepted 127.0.0.1:30001
2015/12/06 10:58:08 127.0.0.1:61879 accepted 127.0.0.1:30001
2015/12/06 10:58:08 127.0.0.1:61882 accepted 127.0.0.1:30001
2015/12/06 10:58:08 127.0.0.1:61885 accepted 127.0.0.1:30001
2015/12/06 10:58:08 127.0.0.1:61888 accepted 127.0.0.1:30001
2015/12/06 10:58:08 127.0.0.1:61891 accepted 127.0.0.1:30001
2015/12/06 10:58:08 127.0.0.1:61894 accepted 127.0.0.1:30001
2015/12/06 10:58:08 127.0.0.1:61897 accepted 127.0.0.1:30001
2015/12/06 10:58:08 127.0.0.1:61900 accepted 127.0.0.1:30001
2015/12/06 10:58:08 127.0.0.1:61903 accepted 127.0.0.1:30001
2015/12/06 10:58:08 127.0.0.1:61906 accepted 127.0.0.1:30001
2015/12/06 10:58:08 127.0.0.1:61909 accepted 127.0.0.1:30001
2015/12/06 10:58:08 127.0.0.1:61912 accepted 127.0.0.1:30001
2015/12/06 10:58:08 127.0.0.1:61915 accepted 127.0.0.1:30001
2015/12/06 10:58:08 127.0.0.1:61918 accepted 127.0.0.1:30001
2015/12/06 10:58:08 127.0.0.1:61921 accepted 127.0.0.1:30001
2015/12/06 10:58:08 127.0.0.1:61924 accepted 127.0.0.1:30001
2015/12/06 10:58:08 127.0.0.1:61927 accepted 127.0.0.1:30001
2015/12/06 10:58:08 127.0.0.1:61930 accepted 127.0.0.1:30001
2015/12/06 10:58:08 127.0.0.1:61933 accepted 127.0.0.1:30001
2015/12/06 10:58:09 127.0.0.1:61936 accepted 127.0.0.1:30001
2015/12/06 10:58:09 127.0.0.1:61939 accepted 127.0.0.1:30001
2015/12/06 10:58:09 127.0.0.1:61942 accepted 127.0.0.1:30001
2015/12/06 10:58:09 127.0.0.1:61945 accepted 127.0.0.1:30001
2015/12/06 10:58:09 127.0.0.1:61948 accepted 127.0.0.1:30001
2015/12/06 10:58:09 127.0.0.1:61951 accepted 127.0.0.1:30001
2015/12/06 10:58:09 127.0.0.1:61954 accepted 127.0.0.1:30001
2015/12/06 10:58:09 127.0.0.1:61957 accepted 127.0.0.1:30001
2015/12/06 10:58:09 127.0.0.1:61960 accepted 127.0.0.1:30001
2015/12/06 10:58:09 127.0.0.1:61963 accepted 127.0.0.1:30001
2015/12/06 10:58:09 127.0.0.1:61966 accepted 127.0.0.1:30001
2015/12/06 10:58:09 127.0.0.1:61969 accepted 127.0.0.1:30001
2015/12/06 10:58:09 127.0.0.1:61972 accepted 127.0.0.1:30001
2015/12/06 10:58:09 127.0.0.1:61975 accepted 127.0.0.1:30001
2015/12/06 10:58:09 127.0.0.1:61978 accepted 127.0.0.1:30001
2015/12/06 10:58:09 127.0.0.1:61981 accepted 127.0.0.1:30001
2015/12/06 10:58:09 127.0.0.1:61984 accepted 127.0.0.1:30001
2015/12/06 10:58:09 127.0.0.1:61987 accepted 127.0.0.1:30001
2015/12/06 10:58:09 127.0.0.1:61990 accepted 127.0.0.1:30001
2015/12/06 10:58:09 127.0.0.1:61993 accepted 127.0.0.1:30001
2015/12/06 10:58:09 127.0.0.1:61996 accepted 127.0.0.1:30001
2015/12/06 10:58:09 127.0.0.1:61999 accepted 127.0.0.1:30001
2015/12/06 10:58:09 127.0.0.1:62002 accepted 127.0.0.1:30001
2015/12/06 10:58:09 127.0.0.1:62005 accepted 127.0.0.1:30001
2015/12/06 10:58:09 127.0.0.1:62008 accepted 127.0.0.1:30001
2015/12/06 10:58:09 127.0.0.1:62011 accepted 127.0.0.1:30001
2015/12/06 10:58:09 127.0.0.1:62014 accepted 127.0.0.1:30001
2015/12/06 10:58:09 127.0.0.1:62017 accepted 127.0.0.1:30001
2015/12/06 10:58:09 127.0.0.1:62020 accepted 127.0.0.1:30001
2015/12/06 10:58:09 127.0.0.1:62023 accepted 127.0.0.1:30001
2015/12/06 10:58:09 127.0.0.1:62026 accepted 127.0.0.1:30001
2015/12/06 10:58:09 127.0.0.1:62029 accepted 127.0.0.1:30001
2015/12/06 10:58:09 127.0.0.1:62033 accepted 127.0.0.1:30003

View File