Sfoglia il codice sorgente

config for rule based router

V2Ray 10 anni fa
parent
commit
d48ac4418f

+ 5 - 6
app/point/config/config.go

@@ -1,5 +1,9 @@
 package config
 
+import (
+	v2net "github.com/v2ray/v2ray-core/common/net"
+)
+
 type DetourTag string
 
 type ConnectionConfig interface {
@@ -11,14 +15,9 @@ type LogConfig interface {
 	AccessLog() string
 }
 
-type PortRange interface {
-	From() uint16
-	To() uint16
-}
-
 type InboundDetourConfig interface {
 	Protocol() string
-	PortRange() PortRange
+	PortRange() v2net.PortRange
 	Settings() interface{}
 }
 

+ 6 - 5
app/point/config/json/inbound_detour.go

@@ -3,21 +3,22 @@ package json
 import (
 	"encoding/json"
 
-	"github.com/v2ray/v2ray-core/app/point/config"
+	v2net "github.com/v2ray/v2ray-core/common/net"
+	v2netjson "github.com/v2ray/v2ray-core/common/net/json"
 	proxyconfig "github.com/v2ray/v2ray-core/proxy/common/config"
 )
 
 type InboundDetourConfig struct {
-	ProtocolValue  string          `json:"protocol"`
-	PortRangeValue *PortRange      `json:"port"`
-	SettingsValue  json.RawMessage `json:"settings"`
+	ProtocolValue  string               `json:"protocol"`
+	PortRangeValue *v2netjson.PortRange `json:"port"`
+	SettingsValue  json.RawMessage      `json:"settings"`
 }
 
 func (this *InboundDetourConfig) Protocol() string {
 	return this.ProtocolValue
 }
 
-func (this *InboundDetourConfig) PortRange() config.PortRange {
+func (this *InboundDetourConfig) PortRange() v2net.PortRange {
 	return this.PortRangeValue
 }
 

+ 2 - 1
app/point/config/testing/mocks/config.go

@@ -2,6 +2,7 @@ package mocks
 
 import (
 	"github.com/v2ray/v2ray-core/app/point/config"
+	v2net "github.com/v2ray/v2ray-core/common/net"
 )
 
 type ConnectionConfig struct {
@@ -39,7 +40,7 @@ type InboundDetourConfig struct {
 	PortRangeValue *PortRange
 }
 
-func (this *InboundDetourConfig) PortRange() config.PortRange {
+func (this *InboundDetourConfig) PortRange() v2net.PortRange {
 	return this.PortRangeValue
 }
 

+ 32 - 0
app/router/rules/json/fieldrule_test.go

@@ -0,0 +1,32 @@
+package json
+
+import (
+	"testing"
+
+	v2net "github.com/v2ray/v2ray-core/common/net"
+	v2nettesting "github.com/v2ray/v2ray-core/common/net/testing"
+	"github.com/v2ray/v2ray-core/testing/unit"
+)
+
+func TestDomainMatching(t *testing.T) {
+	assert := unit.Assert(t)
+
+	rule := &FieldRule{
+		Domain: "v2ray.com",
+	}
+	dest := v2net.NewTCPDestination(v2net.DomainAddress("www.v2ray.com", 80))
+	assert.Bool(rule.Apply(dest)).IsTrue()
+}
+
+func TestPortMatching(t *testing.T) {
+	assert := unit.Assert(t)
+
+	rule := &FieldRule{
+		Port: &v2nettesting.PortRange{
+			FromValue: 0,
+			ToValue:   100,
+		},
+	}
+	dest := v2net.NewTCPDestination(v2net.DomainAddress("www.v2ray.com", 80))
+	assert.Bool(rule.Apply(dest)).IsTrue()
+}

+ 94 - 0
app/router/rules/json/rules.go

@@ -0,0 +1,94 @@
+package json
+
+import (
+	"encoding/json"
+	"errors"
+	"net"
+	"strings"
+
+	"github.com/v2ray/v2ray-core/app/point/config"
+	v2net "github.com/v2ray/v2ray-core/common/net"
+	v2netjson "github.com/v2ray/v2ray-core/common/net/json"
+)
+
+type Rule struct {
+	Type        string `json:"type"`
+	OutboundTag string `json:"outboundTag"`
+}
+
+func (this *Rule) Tag() *config.DetourTag {
+	detourTag := config.DetourTag(this.OutboundTag)
+	return &detourTag
+}
+
+func (this *Rule) Apply(dest v2net.Destination) bool {
+	return false
+}
+
+type FieldRule struct {
+	Rule
+	Domain  string
+	IP      *net.IPNet
+	Port    v2net.PortRange
+	Network v2net.NetworkList
+}
+
+func (this *FieldRule) Apply(dest v2net.Destination) bool {
+	address := dest.Address()
+	if len(this.Domain) > 0 && address.IsDomain() {
+		if !strings.Contains(address.Domain(), this.Domain) {
+			return false
+		}
+	}
+
+	if this.IP != nil && (address.IsIPv4() || address.IsIPv6()) {
+		if !this.IP.Contains(address.IP()) {
+			return false
+		}
+	}
+
+	if this.Port != nil {
+		port := address.Port()
+		if port < this.Port.From() || port > this.Port.To() {
+			return false
+		}
+	}
+
+	if this.Network != nil {
+		if !this.Network.HasNetwork(v2net.Network(dest.Network())) {
+			return false
+		}
+	}
+
+	return true
+}
+
+func (this *FieldRule) UnmarshalJSON(data []byte) error {
+	type RawFieldRule struct {
+		Rule
+		Domain  string `json:"domain"`
+		IP      string `json:"ip"`
+		Port    *v2netjson.PortRange
+		Network *v2netjson.NetworkList
+	}
+	rawFieldRule := RawFieldRule{}
+	err := json.Unmarshal(data, &rawFieldRule)
+	if err != nil {
+		return err
+	}
+	this.Type = rawFieldRule.Type
+	this.OutboundTag = rawFieldRule.OutboundTag
+	this.Domain = rawFieldRule.Domain
+	_, ipNet, err := net.ParseCIDR(rawFieldRule.IP)
+	if err != nil {
+		return errors.New("Invalid IP range in router rule: " + err.Error())
+	}
+	this.IP = ipNet
+	if rawFieldRule.Port != nil {
+		this.Port = rawFieldRule.Port
+	}
+	if rawFieldRule.Network != nil {
+		this.Network = rawFieldRule.Network
+	}
+	return nil
+}

+ 11 - 0
app/router/rules/rules.go

@@ -0,0 +1,11 @@
+package rules
+
+import (
+	"github.com/v2ray/v2ray-core/app/point/config"
+	v2net "github.com/v2ray/v2ray-core/common/net"
+)
+
+type Rule interface {
+	Tag() *config.DetourTag
+	Apply(dest v2net.Destination) bool
+}

+ 0 - 0
app/point/config/json/portrange.go → common/net/json/portrange.go


+ 0 - 0
app/point/config/json/portrange_test.go → common/net/json/portrange_test.go


+ 6 - 0
common/net/portrange.go

@@ -0,0 +1,6 @@
+package net
+
+type PortRange interface {
+	From() uint16
+	To() uint16
+}

+ 14 - 0
common/net/testing/portrange.go

@@ -0,0 +1,14 @@
+package testing
+
+type PortRange struct {
+	FromValue uint16
+	ToValue   uint16
+}
+
+func (this *PortRange) From() uint16 {
+	return this.FromValue
+}
+
+func (this *PortRange) To() uint16 {
+	return this.ToValue
+}