mirror of https://github.com/v2ray/v2ray-core
remove json packages in app folder
parent
48f1d34ca5
commit
ae8121e633
|
@ -1,6 +1,6 @@
|
||||||
package router
|
package router
|
||||||
|
|
||||||
type Config interface {
|
type Config struct {
|
||||||
Strategy() string
|
Strategy string
|
||||||
Settings() interface{}
|
Settings interface{}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
package json
|
package router
|
||||||
|
|
||||||
type ConfigObjectCreator func() interface{}
|
import (
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ConfigObjectCreator func([]byte) (interface{}, error)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
configCache map[string]ConfigObjectCreator
|
configCache map[string]ConfigObjectCreator
|
||||||
|
|
||||||
|
ErrorRouterNotFound = errors.New("Router not found.")
|
||||||
)
|
)
|
||||||
|
|
||||||
func RegisterRouterConfig(strategy string, creator ConfigObjectCreator) error {
|
func RegisterRouterConfig(strategy string, creator ConfigObjectCreator) error {
|
||||||
|
@ -12,12 +18,12 @@ func RegisterRouterConfig(strategy string, creator ConfigObjectCreator) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateRouterConfig(strategy string) interface{} {
|
func CreateRouterConfig(strategy string, data []byte) (interface{}, error) {
|
||||||
creator, found := configCache[strategy]
|
creator, found := configCache[strategy]
|
||||||
if !found {
|
if !found {
|
||||||
return nil
|
return nil, ErrorRouterNotFound
|
||||||
}
|
}
|
||||||
return creator()
|
return creator(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
|
@ -0,0 +1,28 @@
|
||||||
|
// +build json
|
||||||
|
|
||||||
|
package router
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/v2ray/v2ray-core/common/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (this *Config) UnmarshalJSON(data []byte) error {
|
||||||
|
type JsonConfig struct {
|
||||||
|
Strategy string `json:"strategy"`
|
||||||
|
Settings json.RawMessage `json:"settings"`
|
||||||
|
}
|
||||||
|
jsonConfig := new(JsonConfig)
|
||||||
|
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
settings, err := CreateRouterConfig(jsonConfig.Strategy, []byte(jsonConfig.Settings))
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Router: Failed to load router settings: %v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
this.Strategy = jsonConfig.Strategy
|
||||||
|
this.Settings = settings
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -1,26 +0,0 @@
|
||||||
package json
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
|
|
||||||
"github.com/v2ray/v2ray-core/common/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
type RouterConfig struct {
|
|
||||||
StrategyValue string `json:"strategy"`
|
|
||||||
SettingsValue json.RawMessage `json:"settings"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *RouterConfig) Strategy() string {
|
|
||||||
return this.StrategyValue
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *RouterConfig) Settings() interface{} {
|
|
||||||
settings := CreateRouterConfig(this.Strategy())
|
|
||||||
err := json.Unmarshal(this.SettingsValue, settings)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Failed to load router settings: %v", err)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return settings
|
|
||||||
}
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
. "github.com/v2ray/v2ray-core/app/router"
|
. "github.com/v2ray/v2ray-core/app/router"
|
||||||
_ "github.com/v2ray/v2ray-core/app/router/rules/json"
|
_ "github.com/v2ray/v2ray-core/app/router/rules"
|
||||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||||
"github.com/v2ray/v2ray-core/shell/point/json"
|
"github.com/v2ray/v2ray-core/shell/point/json"
|
||||||
v2testing "github.com/v2ray/v2ray-core/testing"
|
v2testing "github.com/v2ray/v2ray-core/testing"
|
||||||
|
@ -21,7 +21,7 @@ func TestRouter(t *testing.T) {
|
||||||
pointConfig, err := json.LoadConfig(filepath.Join(baseDir, "vpoint_socks_vmess.json"))
|
pointConfig, err := json.LoadConfig(filepath.Join(baseDir, "vpoint_socks_vmess.json"))
|
||||||
assert.Error(err).IsNil()
|
assert.Error(err).IsNil()
|
||||||
|
|
||||||
router, err := CreateRouter(pointConfig.RouterConfig().Strategy(), pointConfig.RouterConfig().Settings())
|
router, err := CreateRouter(pointConfig.RouterConfig().Strategy, pointConfig.RouterConfig().Settings)
|
||||||
assert.Error(err).IsNil()
|
assert.Error(err).IsNil()
|
||||||
|
|
||||||
dest := v2net.TCPDestination(v2net.IPAddress(net.ParseIP("120.135.126.1")), 80)
|
dest := v2net.TCPDestination(v2net.IPAddress(net.ParseIP("120.135.126.1")), 80)
|
||||||
|
|
|
@ -1,23 +1,25 @@
|
||||||
package json
|
// +build json
|
||||||
|
|
||||||
|
package rules
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/v2ray/v2ray-core/common/log"
|
||||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ChinaIPRule struct {
|
func parseChinaIPRule(data []byte) (*Rule, error) {
|
||||||
Rule
|
rawRule := new(JsonRule)
|
||||||
|
err := json.Unmarshal(data, rawRule)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Router: Invalid router rule: %v", err)
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
return &Rule{
|
||||||
func (this *ChinaIPRule) Apply(dest v2net.Destination) bool {
|
Tag: rawRule.OutboundTag,
|
||||||
address := dest.Address()
|
Condition: NewIPv4Matcher(chinaIPNet),
|
||||||
if address.IsDomain() {
|
}, nil
|
||||||
return false
|
|
||||||
}
|
|
||||||
if address.IsIPv6() {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
ip := address.IP()
|
|
||||||
return chinaIPNet.Contains(ip)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
|
@ -1,4 +1,4 @@
|
||||||
package json
|
package rules
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
|
@ -16,7 +16,7 @@ func makeDestination(ip string) v2net.Destination {
|
||||||
func TestChinaIP(t *testing.T) {
|
func TestChinaIP(t *testing.T) {
|
||||||
v2testing.Current(t)
|
v2testing.Current(t)
|
||||||
|
|
||||||
rule := &ChinaIPRule{}
|
rule := NewIPv4Matcher(chinaIPNet)
|
||||||
assert.Bool(rule.Apply(makeDestination("121.14.1.189"))).IsTrue() // sina.com.cn
|
assert.Bool(rule.Apply(makeDestination("121.14.1.189"))).IsTrue() // sina.com.cn
|
||||||
assert.Bool(rule.Apply(makeDestination("101.226.103.106"))).IsTrue() // qq.com
|
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("115.239.210.36"))).IsTrue() // image.baidu.com
|
|
@ -1,29 +1,38 @@
|
||||||
package json
|
// +build json
|
||||||
|
|
||||||
|
package rules
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"encoding/json"
|
||||||
|
"github.com/v2ray/v2ray-core/common/log"
|
||||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ChinaSitesRule struct {
|
type ChinaSitesCondition struct {
|
||||||
Rule
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ChinaSitesRule) Apply(dest v2net.Destination) bool {
|
func (this *ChinaSitesCondition) Apply(dest v2net.Destination) bool {
|
||||||
address := dest.Address()
|
for _, cond := range chinaSitesConds {
|
||||||
if !address.IsDomain() {
|
if cond.Apply(dest) {
|
||||||
return false
|
|
||||||
}
|
|
||||||
domain := strings.ToLower(address.Domain())
|
|
||||||
for _, matcher := range compiledMatchers {
|
|
||||||
if matcher.Match(domain) {
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseChinaSitesRule(data []byte) (*Rule, error) {
|
||||||
|
rawRule := new(JsonRule)
|
||||||
|
err := json.Unmarshal(data, rawRule)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Router: Invalid router rule: %v", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Rule{
|
||||||
|
Tag: rawRule.OutboundTag,
|
||||||
|
Condition: &ChinaSitesCondition{},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
anySubDomain = "^(.*\\.)?"
|
anySubDomain = "^(.*\\.)?"
|
||||||
dotAm = "\\.am$"
|
dotAm = "\\.am$"
|
||||||
|
@ -39,12 +48,10 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
compiledMatchers []*RegexpDomainMatcher
|
chinaSitesConds []Condition
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
compiledMatchers = make([]*RegexpDomainMatcher, 0, 1024)
|
|
||||||
|
|
||||||
regexpDomains := []string{
|
regexpDomains := []string{
|
||||||
dotCn,
|
dotCn,
|
||||||
"\\.xn--fiqs8s$", /* .中国 */
|
"\\.xn--fiqs8s$", /* .中国 */
|
||||||
|
@ -353,11 +360,12 @@ func init() {
|
||||||
anySubDomain + "zhubajie" + dotCom,
|
anySubDomain + "zhubajie" + dotCom,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, pattern := range regexpDomains {
|
chinaSitesConds = make([]Condition, len(regexpDomains))
|
||||||
|
for idx, pattern := range regexpDomains {
|
||||||
matcher, err := NewRegexpDomainMatcher(pattern)
|
matcher, err := NewRegexpDomainMatcher(pattern)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
compiledMatchers = append(compiledMatchers, matcher)
|
chinaSitesConds[idx] = matcher
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,6 @@
|
||||||
package json
|
// +build json
|
||||||
|
|
||||||
|
package rules
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -15,7 +17,7 @@ func makeDomainDestination(domain string) v2net.Destination {
|
||||||
func TestChinaSites(t *testing.T) {
|
func TestChinaSites(t *testing.T) {
|
||||||
v2testing.Current(t)
|
v2testing.Current(t)
|
||||||
|
|
||||||
rule := &ChinaSitesRule{}
|
rule := new(ChinaSitesCondition)
|
||||||
assert.Bool(rule.Apply(makeDomainDestination("v.qq.com"))).IsTrue()
|
assert.Bool(rule.Apply(makeDomainDestination("v.qq.com"))).IsTrue()
|
||||||
assert.Bool(rule.Apply(makeDomainDestination("www.163.com"))).IsTrue()
|
assert.Bool(rule.Apply(makeDomainDestination("www.163.com"))).IsTrue()
|
||||||
assert.Bool(rule.Apply(makeDomainDestination("ngacn.cc"))).IsTrue()
|
assert.Bool(rule.Apply(makeDomainDestination("ngacn.cc"))).IsTrue()
|
|
@ -0,0 +1,144 @@
|
||||||
|
package rules
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"regexp"
|
||||||
|
|
||||||
|
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||||
|
"github.com/v2ray/v2ray-core/common/serial"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Condition interface {
|
||||||
|
Apply(dest v2net.Destination) bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type ConditionChan []Condition
|
||||||
|
|
||||||
|
func NewConditionChan() *ConditionChan {
|
||||||
|
var condChan ConditionChan = make([]Condition, 0, 8)
|
||||||
|
return &condChan
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *ConditionChan) Add(cond Condition) *ConditionChan {
|
||||||
|
*this = append(*this, cond)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *ConditionChan) Apply(dest v2net.Destination) bool {
|
||||||
|
for _, cond := range *this {
|
||||||
|
if !cond.Apply(dest) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *ConditionChan) Len() int {
|
||||||
|
return len(*this)
|
||||||
|
}
|
||||||
|
|
||||||
|
type PlainDomainMatcher struct {
|
||||||
|
pattern serial.StringLiteral
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPlainDomainMatcher(pattern string) *PlainDomainMatcher {
|
||||||
|
return &PlainDomainMatcher{
|
||||||
|
pattern: serial.StringLiteral(pattern),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *PlainDomainMatcher) Apply(dest v2net.Destination) bool {
|
||||||
|
if !dest.Address().IsDomain() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
domain := serial.StringLiteral(dest.Address().Domain())
|
||||||
|
return domain.Contains(this.pattern)
|
||||||
|
}
|
||||||
|
|
||||||
|
type RegexpDomainMatcher struct {
|
||||||
|
pattern *regexp.Regexp
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRegexpDomainMatcher(pattern string) (*RegexpDomainMatcher, error) {
|
||||||
|
r, err := regexp.Compile(pattern)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &RegexpDomainMatcher{
|
||||||
|
pattern: r,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *RegexpDomainMatcher) Apply(dest v2net.Destination) bool {
|
||||||
|
if !dest.Address().IsDomain() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
domain := serial.StringLiteral(dest.Address().Domain())
|
||||||
|
return this.pattern.MatchString(domain.ToLower().String())
|
||||||
|
}
|
||||||
|
|
||||||
|
type CIDRMatcher struct {
|
||||||
|
cidr *net.IPNet
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCIDRMatcher(ipnet string) (*CIDRMatcher, error) {
|
||||||
|
_, cidr, err := net.ParseCIDR(ipnet)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &CIDRMatcher{
|
||||||
|
cidr: cidr,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *CIDRMatcher) Apply(dest v2net.Destination) bool {
|
||||||
|
if !dest.Address().IsIPv4() && !dest.Address().IsIPv6() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return this.cidr.Contains(dest.Address().IP())
|
||||||
|
}
|
||||||
|
|
||||||
|
type IPv4Matcher struct {
|
||||||
|
ipv4net *v2net.IPNet
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewIPv4Matcher(ipnet *v2net.IPNet) *IPv4Matcher {
|
||||||
|
return &IPv4Matcher{
|
||||||
|
ipv4net: ipnet,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *IPv4Matcher) Apply(dest v2net.Destination) bool {
|
||||||
|
if !dest.Address().IsIPv4() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return this.ipv4net.Contains(dest.Address().IP())
|
||||||
|
}
|
||||||
|
|
||||||
|
type PortMatcher struct {
|
||||||
|
port v2net.PortRange
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPortMatcher(portRange v2net.PortRange) *PortMatcher {
|
||||||
|
return &PortMatcher{
|
||||||
|
port: portRange,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *PortMatcher) Apply(dest v2net.Destination) bool {
|
||||||
|
return this.port.Contains(dest.Port())
|
||||||
|
}
|
||||||
|
|
||||||
|
type NetworkMatcher struct {
|
||||||
|
network *v2net.NetworkList
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewNetworkMatcher(network *v2net.NetworkList) *NetworkMatcher {
|
||||||
|
return &NetworkMatcher{
|
||||||
|
network: network,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *NetworkMatcher) Apply(dest v2net.Destination) bool {
|
||||||
|
return this.network.HasNetwork(v2net.Network(dest.Network()))
|
||||||
|
}
|
|
@ -4,11 +4,30 @@ import (
|
||||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Rule interface {
|
type Rule struct {
|
||||||
Tag() string
|
Tag string
|
||||||
Apply(dest v2net.Destination) bool
|
Condition Condition
|
||||||
}
|
}
|
||||||
|
|
||||||
type RouterRuleConfig interface {
|
func (this *Rule) Apply(dest v2net.Destination) bool {
|
||||||
Rules() []Rule
|
return this.Condition.Apply(dest)
|
||||||
|
}
|
||||||
|
|
||||||
|
type RouterRuleConfig struct {
|
||||||
|
rules []*Rule
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRouterRuleConfig() *RouterRuleConfig {
|
||||||
|
return &RouterRuleConfig{
|
||||||
|
rules: make([]*Rule, 0, 16),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *RouterRuleConfig) Add(rule *Rule) *RouterRuleConfig {
|
||||||
|
this.rules = append(this.rules, rule)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *RouterRuleConfig) Rules() []*Rule {
|
||||||
|
return this.rules
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,166 +0,0 @@
|
||||||
package json
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"net"
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
|
||||||
"github.com/v2ray/v2ray-core/common/serial"
|
|
||||||
)
|
|
||||||
|
|
||||||
type DomainMatcher interface {
|
|
||||||
Match(domain string) bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type PlainDomainMatcher struct {
|
|
||||||
pattern string
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewPlainDomainMatcher(pattern string) *PlainDomainMatcher {
|
|
||||||
return &PlainDomainMatcher{
|
|
||||||
pattern: strings.ToLower(pattern),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *PlainDomainMatcher) Match(domain string) bool {
|
|
||||||
return strings.Contains(strings.ToLower(domain), this.pattern)
|
|
||||||
}
|
|
||||||
|
|
||||||
type RegexpDomainMatcher struct {
|
|
||||||
pattern *regexp.Regexp
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewRegexpDomainMatcher(pattern string) (*RegexpDomainMatcher, error) {
|
|
||||||
r, err := regexp.Compile(pattern)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &RegexpDomainMatcher{
|
|
||||||
pattern: r,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *RegexpDomainMatcher) Match(domain string) bool {
|
|
||||||
return this.pattern.MatchString(strings.ToLower(domain))
|
|
||||||
}
|
|
||||||
|
|
||||||
type FieldRule struct {
|
|
||||||
Rule
|
|
||||||
Domain []DomainMatcher
|
|
||||||
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 {
|
|
||||||
if !address.IsDomain() {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
foundMatch := false
|
|
||||||
for _, domain := range this.Domain {
|
|
||||||
if domain.Match(address.Domain()) {
|
|
||||||
foundMatch = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !foundMatch {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if this.IP != nil && len(this.IP) > 0 {
|
|
||||||
if !(address.IsIPv4() || address.IsIPv6()) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
foundMatch := false
|
|
||||||
for _, ipnet := range this.IP {
|
|
||||||
if ipnet.Contains(address.IP()) {
|
|
||||||
foundMatch = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !foundMatch {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if this.Port != nil {
|
|
||||||
port := dest.Port()
|
|
||||||
if port.Value() < this.Port.From.Value() || port.Value() > this.Port.To.Value() {
|
|
||||||
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 *serial.StringLiteralList `json:"domain"`
|
|
||||||
IP *serial.StringLiteralList `json:"ip"`
|
|
||||||
Port *v2net.PortRange `json:"port"`
|
|
||||||
Network *v2net.NetworkList `json:"network"`
|
|
||||||
}
|
|
||||||
rawFieldRule := RawFieldRule{}
|
|
||||||
err := json.Unmarshal(data, &rawFieldRule)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
this.Type = rawFieldRule.Type
|
|
||||||
this.OutboundTag = rawFieldRule.OutboundTag
|
|
||||||
|
|
||||||
hasField := false
|
|
||||||
if rawFieldRule.Domain != nil && rawFieldRule.Domain.Len() > 0 {
|
|
||||||
this.Domain = make([]DomainMatcher, rawFieldRule.Domain.Len())
|
|
||||||
for idx, rawDomain := range *(rawFieldRule.Domain) {
|
|
||||||
var matcher DomainMatcher
|
|
||||||
if strings.HasPrefix(rawDomain.String(), "regexp:") {
|
|
||||||
rawMatcher, err := NewRegexpDomainMatcher(rawDomain.String()[7:])
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
matcher = rawMatcher
|
|
||||||
} else {
|
|
||||||
matcher = NewPlainDomainMatcher(rawDomain.String())
|
|
||||||
}
|
|
||||||
this.Domain[idx] = matcher
|
|
||||||
}
|
|
||||||
hasField = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if rawFieldRule.IP != nil && rawFieldRule.IP.Len() > 0 {
|
|
||||||
this.IP = make([]*net.IPNet, 0, rawFieldRule.IP.Len())
|
|
||||||
for _, ipStr := range *(rawFieldRule.IP) {
|
|
||||||
_, ipNet, err := net.ParseCIDR(ipStr.String())
|
|
||||||
if err != nil {
|
|
||||||
return errors.New("Invalid IP range in router rule: " + err.Error())
|
|
||||||
}
|
|
||||||
this.IP = append(this.IP, ipNet)
|
|
||||||
}
|
|
||||||
hasField = true
|
|
||||||
}
|
|
||||||
if rawFieldRule.Port != nil {
|
|
||||||
this.Port = rawFieldRule.Port
|
|
||||||
hasField = true
|
|
||||||
}
|
|
||||||
if rawFieldRule.Network != nil {
|
|
||||||
this.Network = rawFieldRule.Network
|
|
||||||
hasField = true
|
|
||||||
}
|
|
||||||
if !hasField {
|
|
||||||
return errors.New("This rule has no effective fields.")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,103 +0,0 @@
|
||||||
package json
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
|
||||||
v2testing "github.com/v2ray/v2ray-core/testing"
|
|
||||||
"github.com/v2ray/v2ray-core/testing/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestDomainMatching(t *testing.T) {
|
|
||||||
v2testing.Current(t)
|
|
||||||
|
|
||||||
rawJson := `{
|
|
||||||
"type": "field",
|
|
||||||
"domain": ["google.com", "regexp:v2ray.com$"],
|
|
||||||
"tag": "test"
|
|
||||||
}`
|
|
||||||
rule := parseRule([]byte(rawJson))
|
|
||||||
dest := v2net.TCPDestination(v2net.DomainAddress("www.v2ray.com"), 80)
|
|
||||||
assert.Bool(rule.Apply(dest)).IsTrue()
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPortMatching(t *testing.T) {
|
|
||||||
v2testing.Current(t)
|
|
||||||
|
|
||||||
rule := &FieldRule{
|
|
||||||
Port: &v2net.PortRange{
|
|
||||||
From: 0,
|
|
||||||
To: 100,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
dest := v2net.TCPDestination(v2net.DomainAddress("www.v2ray.com"), 80)
|
|
||||||
assert.Bool(rule.Apply(dest)).IsTrue()
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIPMatching(t *testing.T) {
|
|
||||||
v2testing.Current(t)
|
|
||||||
|
|
||||||
rawJson := `{
|
|
||||||
"type": "field",
|
|
||||||
"ip": "10.0.0.0/8",
|
|
||||||
"tag": "test"
|
|
||||||
}`
|
|
||||||
rule := parseRule([]byte(rawJson))
|
|
||||||
dest := v2net.TCPDestination(v2net.IPAddress([]byte{10, 0, 0, 1}), 80)
|
|
||||||
assert.Bool(rule.Apply(dest)).IsTrue()
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIPListMatching(t *testing.T) {
|
|
||||||
v2testing.Current(t)
|
|
||||||
|
|
||||||
rawJson := `{
|
|
||||||
"type": "field",
|
|
||||||
"ip": ["10.0.0.0/8", "192.168.0.0/16"],
|
|
||||||
"tag": "test"
|
|
||||||
}`
|
|
||||||
rule := parseRule([]byte(rawJson))
|
|
||||||
dest := v2net.TCPDestination(v2net.IPAddress([]byte{192, 168, 1, 1}), 80)
|
|
||||||
assert.Bool(rule.Apply(dest)).IsTrue()
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPortNotMatching(t *testing.T) {
|
|
||||||
v2testing.Current(t)
|
|
||||||
|
|
||||||
rawJson := `{
|
|
||||||
"type": "field",
|
|
||||||
"port": "80-100",
|
|
||||||
"tag": "test"
|
|
||||||
}`
|
|
||||||
rule := parseRule([]byte(rawJson))
|
|
||||||
dest := v2net.TCPDestination(v2net.IPAddress([]byte{10, 0, 0, 1}), 79)
|
|
||||||
assert.Bool(rule.Apply(dest)).IsFalse()
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDomainNotMatching(t *testing.T) {
|
|
||||||
v2testing.Current(t)
|
|
||||||
|
|
||||||
rawJson := `{
|
|
||||||
"type": "field",
|
|
||||||
"domain": ["google.com", "v2ray.com"],
|
|
||||||
"tag": "test"
|
|
||||||
}`
|
|
||||||
rule := parseRule([]byte(rawJson))
|
|
||||||
dest := v2net.TCPDestination(v2net.IPAddress([]byte{10, 0, 0, 1}), 80)
|
|
||||||
assert.Bool(rule.Apply(dest)).IsFalse()
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDomainNotMatchingDomain(t *testing.T) {
|
|
||||||
v2testing.Current(t)
|
|
||||||
|
|
||||||
rawJson := `{
|
|
||||||
"type": "field",
|
|
||||||
"domain": ["google.com", "v2ray.com"],
|
|
||||||
"tag": "test"
|
|
||||||
}`
|
|
||||||
rule := parseRule([]byte(rawJson))
|
|
||||||
dest := v2net.TCPDestination(v2net.DomainAddress("baidu.com"), 80)
|
|
||||||
assert.Bool(rule.Apply(dest)).IsFalse()
|
|
||||||
|
|
||||||
dest = v2net.TCPDestination(v2net.DomainAddress("www.google.com"), 80)
|
|
||||||
assert.Bool(rule.Apply(dest)).IsTrue()
|
|
||||||
}
|
|
|
@ -1,63 +0,0 @@
|
||||||
package json
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
|
|
||||||
v2routerjson "github.com/v2ray/v2ray-core/app/router/json"
|
|
||||||
"github.com/v2ray/v2ray-core/app/router/rules"
|
|
||||||
"github.com/v2ray/v2ray-core/common/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
type RouterRuleConfig struct {
|
|
||||||
RuleList []json.RawMessage `json:"rules"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseRule(msg json.RawMessage) rules.Rule {
|
|
||||||
rule := new(Rule)
|
|
||||||
err := json.Unmarshal(msg, rule)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Invalid router rule: %v", err)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if rule.Type == "field" {
|
|
||||||
fieldrule := new(FieldRule)
|
|
||||||
err = json.Unmarshal(msg, fieldrule)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Invalid field rule: %v", err)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return fieldrule
|
|
||||||
}
|
|
||||||
if rule.Type == "chinaip" {
|
|
||||||
chinaiprule := new(ChinaIPRule)
|
|
||||||
if err := json.Unmarshal(msg, chinaiprule); err != nil {
|
|
||||||
log.Error("Invalid chinaip rule: %v", err)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return chinaiprule
|
|
||||||
}
|
|
||||||
if rule.Type == "chinasites" {
|
|
||||||
chinasitesrule := new(ChinaSitesRule)
|
|
||||||
if err := json.Unmarshal(msg, chinasitesrule); err != nil {
|
|
||||||
log.Error("Invalid chinasites rule: %v", err)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return chinasitesrule
|
|
||||||
}
|
|
||||||
log.Error("Unknown router rule type: %s", rule.Type)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *RouterRuleConfig) Rules() []rules.Rule {
|
|
||||||
rules := make([]rules.Rule, len(this.RuleList))
|
|
||||||
for idx, rawRule := range this.RuleList {
|
|
||||||
rules[idx] = parseRule(rawRule)
|
|
||||||
}
|
|
||||||
return rules
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
v2routerjson.RegisterRouterConfig("rules", func() interface{} {
|
|
||||||
return new(RouterRuleConfig)
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
package json
|
|
||||||
|
|
||||||
import (
|
|
||||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Rule struct {
|
|
||||||
Type string `json:"type"`
|
|
||||||
OutboundTag string `json:"outboundTag"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *Rule) Tag() string {
|
|
||||||
return this.OutboundTag
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *Rule) Apply(dest v2net.Destination) bool {
|
|
||||||
return false
|
|
||||||
}
|
|
|
@ -38,18 +38,18 @@ func (this *cacheEntry) Extend() {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Router struct {
|
type Router struct {
|
||||||
rules []Rule
|
rules []*Rule
|
||||||
cache *collect.ValidityMap
|
cache *collect.ValidityMap
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRouter() *Router {
|
func NewRouter() *Router {
|
||||||
return &Router{
|
return &Router{
|
||||||
rules: make([]Rule, 0, 16),
|
rules: make([]*Rule, 0, 16),
|
||||||
cache: collect.NewValidityMap(3600),
|
cache: collect.NewValidityMap(3600),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Router) AddRule(rule Rule) *Router {
|
func (this *Router) AddRule(rule *Rule) *Router {
|
||||||
this.rules = append(this.rules, rule)
|
this.rules = append(this.rules, rule)
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ func (this *Router) AddRule(rule Rule) *Router {
|
||||||
func (this *Router) takeDetourWithoutCache(dest v2net.Destination) (string, error) {
|
func (this *Router) takeDetourWithoutCache(dest v2net.Destination) (string, error) {
|
||||||
for _, rule := range this.rules {
|
for _, rule := range this.rules {
|
||||||
if rule.Apply(dest) {
|
if rule.Apply(dest) {
|
||||||
return rule.Tag(), nil
|
return rule.Tag, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "", NoRuleApplicable
|
return "", NoRuleApplicable
|
||||||
|
@ -78,7 +78,7 @@ type RouterFactory struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *RouterFactory) Create(rawConfig interface{}) (router.Router, error) {
|
func (this *RouterFactory) Create(rawConfig interface{}) (router.Router, error) {
|
||||||
config := rawConfig.(RouterRuleConfig)
|
config := rawConfig.(*RouterRuleConfig)
|
||||||
rules := config.Rules()
|
rules := config.Rules()
|
||||||
router := NewRouter()
|
router := NewRouter()
|
||||||
for _, rule := range rules {
|
for _, rule := range rules {
|
||||||
|
|
|
@ -0,0 +1,129 @@
|
||||||
|
// +build json
|
||||||
|
|
||||||
|
package rules
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
router "github.com/v2ray/v2ray-core/app/router"
|
||||||
|
"github.com/v2ray/v2ray-core/common/log"
|
||||||
|
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||||
|
"github.com/v2ray/v2ray-core/common/serial"
|
||||||
|
)
|
||||||
|
|
||||||
|
type JsonRule struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
OutboundTag string `json:"outboundTag"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseFieldRule(msg json.RawMessage) (*Rule, error) {
|
||||||
|
type RawFieldRule struct {
|
||||||
|
JsonRule
|
||||||
|
Domain *serial.StringLiteralList `json:"domain"`
|
||||||
|
IP *serial.StringLiteralList `json:"ip"`
|
||||||
|
Port *v2net.PortRange `json:"port"`
|
||||||
|
Network *v2net.NetworkList `json:"network"`
|
||||||
|
}
|
||||||
|
rawFieldRule := new(RawFieldRule)
|
||||||
|
err := json.Unmarshal(msg, rawFieldRule)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
conds := NewConditionChan()
|
||||||
|
|
||||||
|
if rawFieldRule.Domain != nil && rawFieldRule.Domain.Len() > 0 {
|
||||||
|
for _, rawDomain := range *(rawFieldRule.Domain) {
|
||||||
|
var matcher Condition
|
||||||
|
if strings.HasPrefix(rawDomain.String(), "regexp:") {
|
||||||
|
rawMatcher, err := NewRegexpDomainMatcher(rawDomain.String()[7:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
matcher = rawMatcher
|
||||||
|
} else {
|
||||||
|
matcher = NewPlainDomainMatcher(rawDomain.String())
|
||||||
|
}
|
||||||
|
conds.Add(matcher)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if rawFieldRule.IP != nil && rawFieldRule.IP.Len() > 0 {
|
||||||
|
for _, ipStr := range *(rawFieldRule.IP) {
|
||||||
|
cidrMatcher, err := NewCIDRMatcher(ipStr.String())
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Router: Invalid IP range in router rule: %v", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
conds.Add(cidrMatcher)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if rawFieldRule.Port != nil {
|
||||||
|
conds.Add(NewPortMatcher(*rawFieldRule.Port))
|
||||||
|
}
|
||||||
|
if rawFieldRule.Network != nil {
|
||||||
|
conds.Add(NewNetworkMatcher(rawFieldRule.Network))
|
||||||
|
}
|
||||||
|
if conds.Len() == 0 {
|
||||||
|
return nil, errors.New("Router: This rule has no effective fields.")
|
||||||
|
}
|
||||||
|
return &Rule{
|
||||||
|
Tag: rawFieldRule.OutboundTag,
|
||||||
|
Condition: conds,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseRule(msg json.RawMessage) *Rule {
|
||||||
|
rawRule := new(JsonRule)
|
||||||
|
err := json.Unmarshal(msg, rawRule)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Router: Invalid router rule: %v", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if rawRule.Type == "field" {
|
||||||
|
|
||||||
|
fieldrule, err := parseFieldRule(msg)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Invalid field rule: %v", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fieldrule
|
||||||
|
}
|
||||||
|
if rawRule.Type == "chinaip" {
|
||||||
|
chinaiprule, err := parseChinaIPRule(msg)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Router: Invalid chinaip rule: %v", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return chinaiprule
|
||||||
|
}
|
||||||
|
if rawRule.Type == "chinasites" {
|
||||||
|
chinasitesrule, err := parseChinaSitesRule(msg)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Invalid chinasites rule: %v", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return chinasitesrule
|
||||||
|
}
|
||||||
|
log.Error("Unknown router rule type: %s", rawRule.Type)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
router.RegisterRouterConfig("rules", func(data []byte) (interface{}, error) {
|
||||||
|
type JsonConfig struct {
|
||||||
|
RuleList []json.RawMessage `json:"rules"`
|
||||||
|
}
|
||||||
|
jsonConfig := new(JsonConfig)
|
||||||
|
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
config := NewRouterRuleConfig()
|
||||||
|
for _, rawRule := range jsonConfig.RuleList {
|
||||||
|
rule := parseRule(rawRule)
|
||||||
|
config.Add(rule)
|
||||||
|
}
|
||||||
|
return config, nil
|
||||||
|
})
|
||||||
|
}
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
. "github.com/v2ray/v2ray-core/app/router/rules"
|
. "github.com/v2ray/v2ray-core/app/router/rules"
|
||||||
testinconfig "github.com/v2ray/v2ray-core/app/router/rules/testing"
|
|
||||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||||
v2testing "github.com/v2ray/v2ray-core/testing"
|
v2testing "github.com/v2ray/v2ray-core/testing"
|
||||||
"github.com/v2ray/v2ray-core/testing/assert"
|
"github.com/v2ray/v2ray-core/testing/assert"
|
||||||
|
@ -14,11 +13,9 @@ func TestSimpleRouter(t *testing.T) {
|
||||||
v2testing.Current(t)
|
v2testing.Current(t)
|
||||||
|
|
||||||
router := NewRouter().AddRule(
|
router := NewRouter().AddRule(
|
||||||
&testinconfig.TestRule{
|
&Rule{
|
||||||
TagValue: "test",
|
Tag: "test",
|
||||||
Function: func(dest v2net.Destination) bool {
|
Condition: NewNetworkMatcher(v2net.Network("tcp").AsList()),
|
||||||
return dest.IsTCP()
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
|
||||||
tag, err := router.TakeDetour(v2net.TCPDestination(v2net.DomainAddress("v2ray.com"), 80))
|
tag, err := router.TakeDetour(v2net.TCPDestination(v2net.DomainAddress("v2ray.com"), 80))
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
package testing
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/v2ray/v2ray-core/app/router/rules"
|
|
||||||
)
|
|
||||||
|
|
||||||
type RouterRuleConfig struct {
|
|
||||||
RuleList []*TestRule
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *RouterRuleConfig) Rules() []rules.Rule {
|
|
||||||
rules := make([]rules.Rule, len(this.RuleList))
|
|
||||||
for idx, rule := range this.RuleList {
|
|
||||||
rules[idx] = rule
|
|
||||||
}
|
|
||||||
return rules
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
package testing
|
|
||||||
|
|
||||||
import (
|
|
||||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
|
||||||
)
|
|
||||||
|
|
||||||
type TestRule struct {
|
|
||||||
Function func(v2net.Destination) bool
|
|
||||||
TagValue string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *TestRule) Apply(dest v2net.Destination) bool {
|
|
||||||
return this.Function(dest)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *TestRule) Tag() string {
|
|
||||||
return this.TagValue
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
package testing
|
|
||||||
|
|
||||||
type RouterConfig struct {
|
|
||||||
StrategyValue string
|
|
||||||
SettingsValue interface{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *RouterConfig) Strategy() string {
|
|
||||||
return this.StrategyValue
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *RouterConfig) Settings() interface{} {
|
|
||||||
return this.SettingsValue
|
|
||||||
}
|
|
|
@ -11,6 +11,11 @@ const (
|
||||||
|
|
||||||
type Network serial.StringLiteral
|
type Network serial.StringLiteral
|
||||||
|
|
||||||
|
func (this Network) AsList() *NetworkList {
|
||||||
|
list := NetworkList([]Network{this})
|
||||||
|
return &list
|
||||||
|
}
|
||||||
|
|
||||||
type NetworkList []Network
|
type NetworkList []Network
|
||||||
|
|
||||||
func NewNetworkList(networks serial.StringLiteralList) NetworkList {
|
func NewNetworkList(networks serial.StringLiteralList) NetworkList {
|
||||||
|
|
|
@ -26,3 +26,7 @@ type PortRange struct {
|
||||||
From Port
|
From Port
|
||||||
To Port
|
To Port
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this PortRange) Contains(port Port) bool {
|
||||||
|
return this.From <= port && port <= this.To
|
||||||
|
}
|
||||||
|
|
|
@ -15,6 +15,10 @@ func NewStringLiteral(str String) StringLiteral {
|
||||||
return StringLiteral(str.String())
|
return StringLiteral(str.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this StringLiteral) Contains(str String) bool {
|
||||||
|
return strings.Contains(this.String(), str.String())
|
||||||
|
}
|
||||||
|
|
||||||
func (this StringLiteral) String() string {
|
func (this StringLiteral) String() string {
|
||||||
return string(this)
|
return string(this)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/v2ray/v2ray-core"
|
"github.com/v2ray/v2ray-core"
|
||||||
_ "github.com/v2ray/v2ray-core/app/router/json"
|
|
||||||
_ "github.com/v2ray/v2ray-core/app/router/rules"
|
_ "github.com/v2ray/v2ray-core/app/router/rules"
|
||||||
_ "github.com/v2ray/v2ray-core/app/router/rules/json"
|
|
||||||
"github.com/v2ray/v2ray-core/common/log"
|
"github.com/v2ray/v2ray-core/common/log"
|
||||||
"github.com/v2ray/v2ray-core/shell/point"
|
"github.com/v2ray/v2ray-core/shell/point"
|
||||||
pointjson "github.com/v2ray/v2ray-core/shell/point/json"
|
pointjson "github.com/v2ray/v2ray-core/shell/point/json"
|
||||||
|
|
|
@ -52,7 +52,7 @@ type OutboundDetourConfig interface {
|
||||||
type PointConfig interface {
|
type PointConfig interface {
|
||||||
Port() v2net.Port
|
Port() v2net.Port
|
||||||
LogConfig() LogConfig
|
LogConfig() LogConfig
|
||||||
RouterConfig() router.Config
|
RouterConfig() *router.Config
|
||||||
InboundConfig() ConnectionConfig
|
InboundConfig() ConnectionConfig
|
||||||
OutboundConfig() ConnectionConfig
|
OutboundConfig() ConnectionConfig
|
||||||
InboundDetours() []InboundDetourConfig
|
InboundDetours() []InboundDetourConfig
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/v2ray/v2ray-core/app/router"
|
"github.com/v2ray/v2ray-core/app/router"
|
||||||
routerjson "github.com/v2ray/v2ray-core/app/router/json"
|
|
||||||
"github.com/v2ray/v2ray-core/common/log"
|
"github.com/v2ray/v2ray-core/common/log"
|
||||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||||
"github.com/v2ray/v2ray-core/shell/point"
|
"github.com/v2ray/v2ray-core/shell/point"
|
||||||
|
@ -16,7 +15,7 @@ import (
|
||||||
type Config struct {
|
type Config struct {
|
||||||
PortValue v2net.Port `json:"port"` // Port of this Point server.
|
PortValue v2net.Port `json:"port"` // Port of this Point server.
|
||||||
LogConfigValue *LogConfig `json:"log"`
|
LogConfigValue *LogConfig `json:"log"`
|
||||||
RouterConfigValue *routerjson.RouterConfig `json:"routing"`
|
RouterConfigValue *router.Config `json:"routing"`
|
||||||
InboundConfigValue *ConnectionConfig `json:"inbound"`
|
InboundConfigValue *ConnectionConfig `json:"inbound"`
|
||||||
OutboundConfigValue *ConnectionConfig `json:"outbound"`
|
OutboundConfigValue *ConnectionConfig `json:"outbound"`
|
||||||
InboundDetoursValue []*InboundDetourConfig `json:"inboundDetour"`
|
InboundDetoursValue []*InboundDetourConfig `json:"inboundDetour"`
|
||||||
|
@ -34,7 +33,7 @@ func (config *Config) LogConfig() point.LogConfig {
|
||||||
return config.LogConfigValue
|
return config.LogConfigValue
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Config) RouterConfig() router.Config {
|
func (this *Config) RouterConfig() *router.Config {
|
||||||
if this.RouterConfigValue == nil {
|
if this.RouterConfigValue == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
_ "github.com/v2ray/v2ray-core/app/router/rules"
|
||||||
netassert "github.com/v2ray/v2ray-core/common/net/testing/assert"
|
netassert "github.com/v2ray/v2ray-core/common/net/testing/assert"
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/dokodemo"
|
_ "github.com/v2ray/v2ray-core/proxy/dokodemo"
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/freedom"
|
_ "github.com/v2ray/v2ray-core/proxy/freedom"
|
||||||
|
|
|
@ -102,7 +102,7 @@ func NewPoint(pConfig PointConfig) (*Point, error) {
|
||||||
|
|
||||||
routerConfig := pConfig.RouterConfig()
|
routerConfig := pConfig.RouterConfig()
|
||||||
if routerConfig != nil {
|
if routerConfig != nil {
|
||||||
r, err := router.CreateRouter(routerConfig.Strategy(), routerConfig.Settings())
|
r, err := router.CreateRouter(routerConfig.Strategy, routerConfig.Settings)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Failed to create router: %v", err)
|
log.Error("Failed to create router: %v", err)
|
||||||
return nil, BadConfiguration
|
return nil, BadConfiguration
|
||||||
|
|
|
@ -2,7 +2,6 @@ package mocks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/v2ray/v2ray-core/app/router"
|
"github.com/v2ray/v2ray-core/app/router"
|
||||||
routertesting "github.com/v2ray/v2ray-core/app/router/testing"
|
|
||||||
"github.com/v2ray/v2ray-core/common/log"
|
"github.com/v2ray/v2ray-core/common/log"
|
||||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||||
"github.com/v2ray/v2ray-core/shell/point"
|
"github.com/v2ray/v2ray-core/shell/point"
|
||||||
|
@ -88,7 +87,7 @@ func (this *OutboundDetourConfig) Tag() string {
|
||||||
type Config struct {
|
type Config struct {
|
||||||
PortValue v2net.Port
|
PortValue v2net.Port
|
||||||
LogConfigValue *LogConfig
|
LogConfigValue *LogConfig
|
||||||
RouterConfigValue *routertesting.RouterConfig
|
RouterConfigValue *router.Config
|
||||||
InboundConfigValue *ConnectionConfig
|
InboundConfigValue *ConnectionConfig
|
||||||
OutboundConfigValue *ConnectionConfig
|
OutboundConfigValue *ConnectionConfig
|
||||||
InboundDetoursValue []*InboundDetourConfig
|
InboundDetoursValue []*InboundDetourConfig
|
||||||
|
@ -106,7 +105,7 @@ func (config *Config) LogConfig() point.LogConfig {
|
||||||
return config.LogConfigValue
|
return config.LogConfigValue
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Config) RouterConfig() router.Config {
|
func (this *Config) RouterConfig() *router.Config {
|
||||||
if this.RouterConfigValue == nil {
|
if this.RouterConfigValue == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
_ "github.com/v2ray/v2ray-core/app/router/json"
|
|
||||||
_ "github.com/v2ray/v2ray-core/app/router/rules"
|
_ "github.com/v2ray/v2ray-core/app/router/rules"
|
||||||
_ "github.com/v2ray/v2ray-core/app/router/rules/json"
|
|
||||||
"github.com/v2ray/v2ray-core/common/log"
|
"github.com/v2ray/v2ray-core/common/log"
|
||||||
"github.com/v2ray/v2ray-core/shell/point"
|
"github.com/v2ray/v2ray-core/shell/point"
|
||||||
pointjson "github.com/v2ray/v2ray-core/shell/point/json"
|
pointjson "github.com/v2ray/v2ray-core/shell/point/json"
|
||||||
|
|
Loading…
Reference in New Issue