1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-12-22 10:08:15 -05:00
v2fly/infra/conf/synthetic/router/router.go

169 lines
4.4 KiB
Go
Raw Normal View History

2021-06-19 08:28:20 -04:00
package router
//go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen
2019-02-10 13:04:11 -05:00
import (
"context"
2019-02-10 13:04:11 -05:00
"encoding/json"
"strings"
2021-06-04 19:42:53 -04:00
"github.com/golang/protobuf/proto"
2021-05-04 09:52:35 -04:00
"github.com/v2fly/v2ray-core/v4/app/router"
"github.com/v2fly/v2ray-core/v4/common/platform"
"github.com/v2fly/v2ray-core/v4/common/serial"
"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon"
"github.com/v2fly/v2ray-core/v4/infra/conf/geodata"
rule2 "github.com/v2fly/v2ray-core/v4/infra/conf/rule"
2019-02-10 13:04:11 -05:00
)
type RouterRulesConfig struct {
RuleList []json.RawMessage `json:"rules"`
DomainStrategy string `json:"domainStrategy"`
}
2021-04-08 16:08:20 -04:00
// StrategyConfig represents a strategy config
type StrategyConfig struct {
Type string `json:"type"`
Settings *json.RawMessage `json:"settings"`
}
2019-02-10 13:04:11 -05:00
type BalancingRule struct {
Tag string `json:"tag"`
Selectors cfgcommon.StringList `json:"selector"`
Strategy StrategyConfig `json:"strategy"`
FallbackTag string `json:"fallbackTag"`
2019-02-10 13:04:11 -05:00
}
// Build builds the balancing rule
2019-02-10 13:04:11 -05:00
func (r *BalancingRule) Build() (*router.BalancingRule, error) {
if r.Tag == "" {
2019-02-10 13:04:11 -05:00
return nil, newError("empty balancer tag")
}
if len(r.Selectors) == 0 {
return nil, newError("empty selector list")
}
2021-04-08 16:08:20 -04:00
var strategy string
switch strings.ToLower(r.Strategy.Type) {
case strategyRandom, "":
r.Strategy.Type = strategyRandom
2021-04-08 16:08:20 -04:00
strategy = strategyRandom
case strategyLeastLoad:
strategy = strategyLeastLoad
2021-04-08 16:08:20 -04:00
case strategyLeastPing:
2021-06-19 08:28:20 -04:00
strategy = "leastping"
2021-04-08 16:08:20 -04:00
default:
return nil, newError("unknown balancing strategy: " + r.Strategy.Type)
}
settings := []byte("{}")
if r.Strategy.Settings != nil {
settings = ([]byte)(*r.Strategy.Settings)
}
rawConfig, err := strategyConfigLoader.LoadWithID(settings, r.Strategy.Type)
if err != nil {
return nil, newError("failed to parse to strategy config.").Base(err)
}
var ts proto.Message
2021-06-19 08:04:50 -04:00
if builder, ok := rawConfig.(cfgcommon.Buildable); ok {
ts, err = builder.Build()
if err != nil {
return nil, err
}
}
2019-02-10 13:04:11 -05:00
return &router.BalancingRule{
2021-04-08 16:08:20 -04:00
Strategy: strategy,
StrategySettings: serial.ToTypedMessage(ts),
FallbackTag: r.FallbackTag,
OutboundSelector: r.Selectors,
Tag: r.Tag,
2019-02-10 13:04:11 -05:00
}, nil
}
type RouterConfig struct {
Settings *RouterRulesConfig `json:"settings"` // Deprecated
RuleList []json.RawMessage `json:"rules"`
DomainStrategy *string `json:"domainStrategy"`
Balancers []*BalancingRule `json:"balancers"`
DomainMatcher string `json:"domainMatcher"`
cfgctx context.Context
2019-02-10 13:04:11 -05:00
}
func (c *RouterConfig) getDomainStrategy() router.Config_DomainStrategy {
ds := ""
if c.DomainStrategy != nil {
ds = *c.DomainStrategy
} else if c.Settings != nil {
ds = c.Settings.DomainStrategy
}
switch strings.ToLower(ds) {
case "alwaysip", "always_ip", "always-ip":
2019-02-10 13:04:11 -05:00
return router.Config_UseIp
case "ipifnonmatch", "ip_if_non_match", "ip-if-non-match":
2019-02-10 13:04:11 -05:00
return router.Config_IpIfNonMatch
case "ipondemand", "ip_on_demand", "ip-on-demand":
2019-02-10 13:04:11 -05:00
return router.Config_IpOnDemand
default:
return router.Config_AsIs
}
}
func (c *RouterConfig) BuildV5(ctx context.Context) (*router.Config, error) {
c.cfgctx = ctx
return c.Build()
}
2019-02-10 13:04:11 -05:00
func (c *RouterConfig) Build() (*router.Config, error) {
config := new(router.Config)
config.DomainStrategy = c.getDomainStrategy()
if c.cfgctx == nil {
c.cfgctx = cfgcommon.NewConfigureLoadingContext(context.Background())
geoloadername := platform.NewEnvFlag("v2ray.conf.geoloader").GetValue(func() string {
return "standard"
})
if loader, err := geodata.GetGeoDataLoader(geoloadername); err == nil {
cfgcommon.SetGeoDataLoader(c.cfgctx, loader)
} else {
return nil, newError("unable to create geo data loader ").Base(err)
}
}
var rawRuleList []json.RawMessage
if c != nil {
rawRuleList = c.RuleList
if c.Settings != nil {
c.RuleList = append(c.RuleList, c.Settings.RuleList...)
rawRuleList = c.RuleList
}
2019-02-10 13:04:11 -05:00
}
2019-02-10 13:04:11 -05:00
for _, rawRule := range rawRuleList {
rule, err := rule2.ParseRule(c.cfgctx, rawRule)
2019-02-10 13:04:11 -05:00
if err != nil {
return nil, err
}
if rule.DomainMatcher == "" {
rule.DomainMatcher = c.DomainMatcher
}
2019-02-10 13:04:11 -05:00
config.Rule = append(config.Rule, rule)
}
for _, rawBalancer := range c.Balancers {
balancer, err := rawBalancer.Build()
if err != nil {
return nil, err
}
config.BalancingRule = append(config.BalancingRule, balancer)
}
return config, nil
}