v2ray před 9 roky
rodič
revize
dac1339d6e

+ 1 - 1
app/dns/internal/config.go → app/dns/config.go

@@ -1,4 +1,4 @@
-package internal
+package dns
 
 import (
 	v2net "github.com/v2ray/v2ray-core/common/net"

+ 1 - 1
app/dns/internal/config_json.go → app/dns/config_json.go

@@ -1,6 +1,6 @@
 // +build json
 
-package internal
+package dns
 
 import (
 	"encoding/json"

+ 0 - 4
app/dns/dns.go

@@ -28,10 +28,6 @@ func (this *contextedDnsServer) Get(domain string) []net.IP {
 	return this.dnsCache.Get(this.context, domain)
 }
 
-func CreateDNSServer(rawConfig interface{}) (Server, error) {
-	return nil, nil
-}
-
 func init() {
 	app.Register(APP_ID, func(context app.Context, obj interface{}) interface{} {
 		dcContext := obj.(dnsServerWithContext)

+ 1 - 1
app/dns/internal/nameserver.go → app/dns/nameserver.go

@@ -1,4 +1,4 @@
-package internal
+package dns
 
 import (
 	"math/rand"

+ 6 - 6
app/dns/internal/dns.go → app/dns/server.go

@@ -1,4 +1,4 @@
-package internal
+package dns
 
 import (
 	"net"
@@ -19,14 +19,14 @@ type DomainRecord struct {
 	A *ARecord
 }
 
-type Server struct {
+type CacheServer struct {
 	sync.RWMutex
 	records map[string]*DomainRecord
 	servers []NameServer
 }
 
-func NewServer(space app.Space, config *Config) *Server {
-	server := &Server{
+func NewCacheServer(space app.Space, config *Config) *CacheServer {
+	server := &CacheServer{
 		records: make(map[string]*DomainRecord),
 		servers: make([]NameServer, len(config.NameServers)),
 	}
@@ -38,7 +38,7 @@ func NewServer(space app.Space, config *Config) *Server {
 }
 
 //@Private
-func (this *Server) GetCached(domain string) []net.IP {
+func (this *CacheServer) GetCached(domain string) []net.IP {
 	this.RLock()
 	defer this.RUnlock()
 
@@ -48,7 +48,7 @@ func (this *Server) GetCached(domain string) []net.IP {
 	return nil
 }
 
-func (this *Server) Get(context app.Context, domain string) []net.IP {
+func (this *CacheServer) Get(context app.Context, domain string) []net.IP {
 	domain = dns.Fqdn(domain)
 	ips := this.GetCached(domain)
 	if ips != nil {

+ 6 - 6
app/dns/internal/dns_test.go → app/dns/server_test.go

@@ -1,4 +1,4 @@
-package internal_test
+package dns_test
 
 import (
 	"net"
@@ -6,7 +6,7 @@ import (
 
 	"github.com/v2ray/v2ray-core/app"
 	"github.com/v2ray/v2ray-core/app/dispatcher"
-	. "github.com/v2ray/v2ray-core/app/dns/internal"
+	. "github.com/v2ray/v2ray-core/app/dns"
 	apptesting "github.com/v2ray/v2ray-core/app/testing"
 	v2net "github.com/v2ray/v2ray-core/common/net"
 	netassert "github.com/v2ray/v2ray-core/common/net/testing/assert"
@@ -45,8 +45,8 @@ func TestDnsAdd(t *testing.T) {
 	spaceController.Bind(dispatcher.APP_ID, d)
 	space := spaceController.ForContext("test")
 
-	domain := "v2ray.com"
-	server := NewServer(space, &Config{
+	domain := "local.v2ray.com"
+	server := NewCacheServer(space, &Config{
 		NameServers: []v2net.Destination{
 			v2net.UDPDestination(v2net.IPAddress([]byte{8, 8, 8, 8}), v2net.Port(53)),
 		},
@@ -54,6 +54,6 @@ func TestDnsAdd(t *testing.T) {
 	ips := server.Get(&apptesting.Context{
 		CallerTagValue: "a",
 	}, domain)
-	assert.Int(len(ips)).Equals(2)
-	netassert.IP(ips[0].To4()).Equals(net.IP([]byte{104, 27, 154, 107}))
+	assert.Int(len(ips)).Equals(1)
+	netassert.IP(ips[0].To4()).Equals(net.IP([]byte{127, 0, 0, 1}))
 }

+ 4 - 3
app/router/router.go

@@ -1,6 +1,7 @@
 package router
 
 import (
+	"github.com/v2ray/v2ray-core/app"
 	v2net "github.com/v2ray/v2ray-core/common/net"
 )
 
@@ -9,7 +10,7 @@ type Router interface {
 }
 
 type RouterFactory interface {
-	Create(rawConfig interface{}) (Router, error)
+	Create(rawConfig interface{}, space app.Space) (Router, error)
 }
 
 var (
@@ -22,9 +23,9 @@ func RegisterRouter(name string, factory RouterFactory) error {
 	return nil
 }
 
-func CreateRouter(name string, rawConfig interface{}) (Router, error) {
+func CreateRouter(name string, rawConfig interface{}, space app.Space) (Router, error) {
 	if factory, found := routerCache[name]; found {
-		return factory.Create(rawConfig)
+		return factory.Create(rawConfig, space)
 	}
 	return nil, ErrorRouterNotFound
 }

+ 1 - 1
app/router/router_test.go

@@ -21,7 +21,7 @@ func TestRouter(t *testing.T) {
 	pointConfig, err := point.LoadConfig(filepath.Join(baseDir, "vpoint_socks_vmess.json"))
 	assert.Error(err).IsNil()
 
-	router, err := CreateRouter(pointConfig.RouterConfig.Strategy, pointConfig.RouterConfig.Settings)
+	router, err := CreateRouter(pointConfig.RouterConfig.Strategy, pointConfig.RouterConfig.Settings, nil)
 	assert.Error(err).IsNil()
 
 	dest := v2net.TCPDestination(v2net.IPAddress(net.ParseIP("120.135.126.1")), 80)

+ 10 - 2
app/router/rules/config.go

@@ -13,7 +13,15 @@ func (this *Rule) Apply(dest v2net.Destination) bool {
 	return this.Condition.Apply(dest)
 }
 
+type DomainStrategy int
+
+var (
+	DomainAsIs      = DomainStrategy(0)
+	AlwaysUseIP     = DomainStrategy(1)
+	UseIPIfNonMatch = DomainStrategy(2)
+)
+
 type RouterRuleConfig struct {
-	Rules         []*Rule
-	ResolveDomain bool
+	Rules          []*Rule
+	DomainStrategy DomainStrategy
 }

+ 10 - 4
app/router/rules/config_json.go

@@ -117,16 +117,22 @@ func ParseRule(msg json.RawMessage) *Rule {
 func init() {
 	router.RegisterRouterConfig("rules", func(data []byte) (interface{}, error) {
 		type JsonConfig struct {
-			RuleList      []json.RawMessage `json:"rules"`
-			ResolveDomain bool              `json:"resolveDomain"`
+			RuleList       []json.RawMessage `json:"rules"`
+			DomainStrategy string            `json:"domainStrategy"`
 		}
 		jsonConfig := new(JsonConfig)
 		if err := json.Unmarshal(data, jsonConfig); err != nil {
 			return nil, err
 		}
 		config := &RouterRuleConfig{
-			Rules:         make([]*Rule, len(jsonConfig.RuleList)),
-			ResolveDomain: jsonConfig.ResolveDomain,
+			Rules:          make([]*Rule, len(jsonConfig.RuleList)),
+			DomainStrategy: DomainAsIs,
+		}
+		domainStrategy := serial.StringLiteral(jsonConfig.DomainStrategy).ToLower()
+		if domainStrategy.String() == "alwaysip" {
+			config.DomainStrategy = AlwaysUseIP
+		} else if domainStrategy.String() == "ipifnonmatch" {
+			config.DomainStrategy = UseIPIfNonMatch
 		}
 		for idx, rawRule := range jsonConfig.RuleList {
 			rule := ParseRule(rawRule)

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

@@ -4,6 +4,8 @@ import (
 	"errors"
 	"time"
 
+	"github.com/v2ray/v2ray-core/app"
+	"github.com/v2ray/v2ray-core/app/dns"
 	"github.com/v2ray/v2ray-core/app/router"
 	"github.com/v2ray/v2ray-core/common/collect"
 	v2net "github.com/v2ray/v2ray-core/common/net"
@@ -40,21 +42,54 @@ func (this *cacheEntry) Extend() {
 type Router struct {
 	config *RouterRuleConfig
 	cache  *collect.ValidityMap
+	space  app.Space
 }
 
-func NewRouter(config *RouterRuleConfig) *Router {
+func NewRouter(config *RouterRuleConfig, space app.Space) *Router {
 	return &Router{
 		config: config,
 		cache:  collect.NewValidityMap(3600),
+		space:  space,
 	}
 }
 
+// @Private
+func (this *Router) ResolveIP(dest v2net.Destination) []v2net.Destination {
+	dnsServer := this.space.GetApp(dns.APP_ID).(dns.Server)
+	ips := dnsServer.Get(dest.Address().Domain())
+	if len(ips) == 0 {
+		return nil
+	}
+	dests := make([]v2net.Destination, len(ips))
+	for idx, ip := range ips {
+		if dest.IsTCP() {
+			dests[idx] = v2net.TCPDestination(v2net.IPAddress(ip), dest.Port())
+		} else {
+			dests[idx] = v2net.UDPDestination(v2net.IPAddress(ip), dest.Port())
+		}
+	}
+	return dests
+}
+
 func (this *Router) takeDetourWithoutCache(dest v2net.Destination) (string, error) {
 	for _, rule := range this.config.Rules {
 		if rule.Apply(dest) {
 			return rule.Tag, nil
 		}
 	}
+	if this.config.DomainStrategy == UseIPIfNonMatch && dest.Address().IsDomain() {
+		ipDests := this.ResolveIP(dest)
+		if ipDests != nil {
+			for _, ipDest := range ipDests {
+				for _, rule := range this.config.Rules {
+					if rule.Apply(ipDest) {
+						return rule.Tag, nil
+					}
+				}
+			}
+		}
+	}
+
 	return "", ErrorNoRuleApplicable
 }
 
@@ -72,8 +107,8 @@ func (this *Router) TakeDetour(dest v2net.Destination) (string, error) {
 type RouterFactory struct {
 }
 
-func (this *RouterFactory) Create(rawConfig interface{}) (router.Router, error) {
-	return NewRouter(rawConfig.(*RouterRuleConfig)), nil
+func (this *RouterFactory) Create(rawConfig interface{}, space app.Space) (router.Router, error) {
+	return NewRouter(rawConfig.(*RouterRuleConfig), space), nil
 }
 
 func init() {

+ 1 - 1
app/router/rules/router_test.go

@@ -21,7 +21,7 @@ func TestSimpleRouter(t *testing.T) {
 		},
 	}
 
-	router := NewRouter(config)
+	router := NewRouter(config, nil)
 
 	tag, err := router.TakeDetour(v2net.TCPDestination(v2net.DomainAddress("v2ray.com"), 80))
 	assert.Error(err).IsNil()

+ 2 - 0
shell/point/config.go

@@ -1,6 +1,7 @@
 package point
 
 import (
+	"github.com/v2ray/v2ray-core/app/dns"
 	"github.com/v2ray/v2ray-core/app/router"
 	"github.com/v2ray/v2ray-core/common/log"
 	v2net "github.com/v2ray/v2ray-core/common/net"
@@ -47,6 +48,7 @@ type Config struct {
 	Port            v2net.Port
 	LogConfig       *LogConfig
 	RouterConfig    *router.Config
+	DNSConfig       *dns.Config
 	InboundConfig   *ConnectionConfig
 	OutboundConfig  *ConnectionConfig
 	InboundDetours  []*InboundDetourConfig

+ 3 - 0
shell/point/config_json.go

@@ -8,6 +8,7 @@ import (
 	"os"
 	"strings"
 
+	"github.com/v2ray/v2ray-core/app/dns"
 	"github.com/v2ray/v2ray-core/app/router"
 	"github.com/v2ray/v2ray-core/common/log"
 	v2net "github.com/v2ray/v2ray-core/common/net"
@@ -22,6 +23,7 @@ func (this *Config) UnmarshalJSON(data []byte) error {
 		Port            v2net.Port              `json:"port"` // Port of this Point server.
 		LogConfig       *LogConfig              `json:"log"`
 		RouterConfig    *router.Config          `json:"routing"`
+		DNSConfig       *dns.Config             `json:"dns"`
 		InboundConfig   *ConnectionConfig       `json:"inbound"`
 		OutboundConfig  *ConnectionConfig       `json:"outbound"`
 		InboundDetours  []*InboundDetourConfig  `json:"inboundDetour"`
@@ -38,6 +40,7 @@ func (this *Config) UnmarshalJSON(data []byte) error {
 	this.OutboundConfig = jsonConfig.OutboundConfig
 	this.InboundDetours = jsonConfig.InboundDetours
 	this.OutboundDetours = jsonConfig.OutboundDetours
+	this.DNSConfig = jsonConfig.DNSConfig
 	return nil
 }
 

+ 8 - 1
shell/point/point.go

@@ -7,6 +7,7 @@ package point
 import (
 	"github.com/v2ray/v2ray-core/app"
 	"github.com/v2ray/v2ray-core/app/dispatcher"
+	"github.com/v2ray/v2ray-core/app/dns"
 	"github.com/v2ray/v2ray-core/app/proxyman"
 	"github.com/v2ray/v2ray-core/app/router"
 	"github.com/v2ray/v2ray-core/common/log"
@@ -120,9 +121,15 @@ func NewPoint(pConfig *Config) (*Point, error) {
 		}
 	}
 
+	dnsConfig := pConfig.DNSConfig
+	if dnsConfig != nil {
+		dnsServer := dns.NewCacheServer(vpoint.space.ForContext("system.dns"), dnsConfig)
+		vpoint.space.Bind(dns.APP_ID, dnsServer)
+	}
+
 	routerConfig := pConfig.RouterConfig
 	if routerConfig != nil {
-		r, err := router.CreateRouter(routerConfig.Strategy, routerConfig.Settings)
+		r, err := router.CreateRouter(routerConfig.Strategy, routerConfig.Settings, vpoint.space.ForContext("system.router"))
 		if err != nil {
 			log.Error("Failed to create router: ", err)
 			return nil, ErrorBadConfiguration