mirror of https://github.com/v2ray/v2ray-core
Use dns in router
parent
3b545abe02
commit
dac1339d6e
|
@ -1,4 +1,4 @@
|
|||
package internal
|
||||
package dns
|
||||
|
||||
import (
|
||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
|
@ -1,6 +1,6 @@
|
|||
// +build json
|
||||
|
||||
package internal
|
||||
package dns
|
||||
|
||||
import (
|
||||
"encoding/json"
|
|
@ -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,4 +1,4 @@
|
|||
package internal
|
||||
package dns
|
||||
|
||||
import (
|
||||
"math/rand"
|
|
@ -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 {
|
|
@ -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}))
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue