v2ray-core/tools/conf/router.go

238 lines
5.9 KiB
Go
Raw Normal View History

2016-10-17 12:35:13 +00:00
package conf
2016-01-17 15:20:49 +00:00
import (
"encoding/json"
2016-10-12 14:11:13 +00:00
"strconv"
"strings"
2016-01-17 15:20:49 +00:00
2017-02-02 13:42:31 +00:00
"v2ray.com/core/app/log"
2016-10-17 12:35:13 +00:00
"v2ray.com/core/app/router"
2016-10-12 14:11:13 +00:00
v2net "v2ray.com/core/common/net"
2016-10-17 12:35:13 +00:00
"v2ray.com/core/tools/geoip"
2016-10-17 14:35:18 +00:00
"github.com/golang/protobuf/proto"
2016-01-17 15:20:49 +00:00
)
2016-10-17 12:35:13 +00:00
type RouterRulesConfig struct {
RuleList []json.RawMessage `json:"rules"`
DomainStrategy string `json:"domainStrategy"`
}
type RouterConfig struct {
Settings *RouterRulesConfig `json:"settings"`
}
2016-11-27 20:39:09 +00:00
func (v *RouterConfig) Build() (*router.Config, error) {
if v.Settings == nil {
2017-04-08 23:43:25 +00:00
return nil, newError("Config: Router settings is not specified.")
2016-10-17 12:35:13 +00:00
}
config := new(router.Config)
2016-11-27 20:39:09 +00:00
settings := v.Settings
2016-10-17 12:35:13 +00:00
config.DomainStrategy = router.Config_AsIs
config.Rule = make([]*router.RoutingRule, len(settings.RuleList))
domainStrategy := strings.ToLower(settings.DomainStrategy)
if domainStrategy == "alwaysip" {
config.DomainStrategy = router.Config_UseIp
} else if domainStrategy == "ipifnonmatch" {
config.DomainStrategy = router.Config_IpIfNonMatch
}
for idx, rawRule := range settings.RuleList {
2017-02-02 13:42:31 +00:00
rule, err := ParseRule(rawRule)
if err != nil {
return nil, err
}
2016-10-17 12:35:13 +00:00
config.Rule[idx] = rule
}
return config, nil
}
type RouterRule struct {
2016-10-12 14:11:13 +00:00
Type string `json:"type"`
OutboundTag string `json:"outboundTag"`
}
2017-02-02 13:42:31 +00:00
func parseIP(s string) (*router.CIDR, error) {
2016-10-12 14:11:13 +00:00
var addr, mask string
i := strings.Index(s, "/")
if i < 0 {
addr = s
} else {
addr = s[:i]
mask = s[i+1:]
}
ip := v2net.ParseAddress(addr)
2016-10-18 09:36:45 +00:00
switch ip.Family() {
case v2net.AddressFamilyIPv4:
bits := uint32(32)
if len(mask) > 0 {
bits64, err := strconv.ParseUint(mask, 10, 32)
if err != nil {
2017-04-08 23:43:25 +00:00
return nil, newError("Config: invalid network mask for router: ", mask).Base(err)
2016-10-18 09:36:45 +00:00
}
bits = uint32(bits64)
}
if bits > 32 {
2017-04-08 23:43:25 +00:00
return nil, newError("Config: invalid network mask for router: ", bits)
2016-10-12 14:11:13 +00:00
}
2016-10-18 14:42:22 +00:00
return &router.CIDR{
Ip: []byte(ip.IP()),
Prefix: bits,
2017-02-02 13:42:31 +00:00
}, nil
2016-10-18 09:36:45 +00:00
case v2net.AddressFamilyIPv6:
bits := uint32(128)
if len(mask) > 0 {
bits64, err := strconv.ParseUint(mask, 10, 32)
if err != nil {
2017-04-08 23:43:25 +00:00
return nil, newError("Config: invalid network mask for router: ", mask).Base(err)
2016-10-18 09:36:45 +00:00
}
bits = uint32(bits64)
}
if bits > 128 {
2017-04-08 23:43:25 +00:00
return nil, newError("Config: invalid network mask for router: ", bits)
2016-10-18 09:36:45 +00:00
}
2016-10-18 14:42:22 +00:00
return &router.CIDR{
Ip: []byte(ip.IP()),
Prefix: bits,
2017-02-02 13:42:31 +00:00
}, nil
2016-10-18 09:36:45 +00:00
default:
2017-04-08 23:43:25 +00:00
return nil, newError("Config: unsupported address for router: ", s)
2016-10-12 14:11:13 +00:00
}
}
2016-10-17 12:35:13 +00:00
func parseFieldRule(msg json.RawMessage) (*router.RoutingRule, error) {
2016-10-12 14:11:13 +00:00
type RawFieldRule struct {
2016-10-17 12:35:13 +00:00
RouterRule
2016-11-13 20:23:34 +00:00
Domain *StringList `json:"domain"`
IP *StringList `json:"ip"`
Port *PortRange `json:"port"`
Network *NetworkList `json:"network"`
SourceIP *StringList `json:"source"`
User *StringList `json:"user"`
InboundTag *StringList `json:"inboundTag"`
2016-10-12 14:11:13 +00:00
}
rawFieldRule := new(RawFieldRule)
err := json.Unmarshal(msg, rawFieldRule)
if err != nil {
return nil, err
}
2016-10-17 12:35:13 +00:00
rule := new(router.RoutingRule)
2016-10-12 14:11:13 +00:00
rule.Tag = rawFieldRule.OutboundTag
if rawFieldRule.Domain != nil {
for _, domain := range *rawFieldRule.Domain {
2016-10-17 12:35:13 +00:00
domainRule := new(router.Domain)
2016-10-12 14:11:13 +00:00
if strings.HasPrefix(domain, "regexp:") {
2016-10-17 12:35:13 +00:00
domainRule.Type = router.Domain_Regex
2016-10-12 14:11:13 +00:00
domainRule.Value = domain[7:]
} else {
2016-10-17 12:35:13 +00:00
domainRule.Type = router.Domain_Plain
2016-10-12 14:11:13 +00:00
domainRule.Value = domain
}
rule.Domain = append(rule.Domain, domainRule)
}
}
if rawFieldRule.IP != nil {
for _, ip := range *rawFieldRule.IP {
2017-02-02 13:42:31 +00:00
ipRule, err := parseIP(ip)
if err != nil {
2017-04-08 23:43:25 +00:00
return nil, newError("Config: invalid IP: ", ip).Base(err)
2016-10-12 14:11:13 +00:00
}
2017-02-02 13:42:31 +00:00
rule.Cidr = append(rule.Cidr, ipRule)
2016-10-12 14:11:13 +00:00
}
}
if rawFieldRule.Port != nil {
2016-10-17 12:35:13 +00:00
rule.PortRange = rawFieldRule.Port.Build()
2016-10-12 14:11:13 +00:00
}
if rawFieldRule.Network != nil {
2016-10-17 12:35:13 +00:00
rule.NetworkList = rawFieldRule.Network.Build()
2016-10-12 14:11:13 +00:00
}
2016-10-18 21:14:48 +00:00
if rawFieldRule.SourceIP != nil {
2016-11-09 09:56:15 +00:00
for _, ip := range *rawFieldRule.SourceIP {
2017-02-02 13:42:31 +00:00
ipRule, err := parseIP(ip)
if err != nil {
2017-04-08 23:43:25 +00:00
return nil, newError("Config: invalid IP: ", ip).Base(err)
2016-10-18 21:14:48 +00:00
}
2017-02-02 13:42:31 +00:00
rule.SourceCidr = append(rule.SourceCidr, ipRule)
2016-10-18 21:14:48 +00:00
}
}
if rawFieldRule.User != nil {
for _, s := range *rawFieldRule.User {
rule.UserEmail = append(rule.UserEmail, s)
}
}
2016-11-13 20:23:34 +00:00
if rawFieldRule.InboundTag != nil {
for _, s := range *rawFieldRule.InboundTag {
rule.InboundTag = append(rule.InboundTag, s)
}
}
2016-10-12 14:11:13 +00:00
return rule, nil
}
2017-02-02 13:42:31 +00:00
func ParseRule(msg json.RawMessage) (*router.RoutingRule, error) {
2016-10-17 12:35:13 +00:00
rawRule := new(RouterRule)
2016-10-12 14:11:13 +00:00
err := json.Unmarshal(msg, rawRule)
if err != nil {
2017-04-08 23:43:25 +00:00
return nil, newError("Config: Invalid router rule.").Base(err)
2016-10-12 14:11:13 +00:00
}
if rawRule.Type == "field" {
fieldrule, err := parseFieldRule(msg)
if err != nil {
2017-04-08 23:43:25 +00:00
return nil, newError("Config: Invalid field rule.").Base(err)
2016-10-12 14:11:13 +00:00
}
2017-02-02 13:42:31 +00:00
return fieldrule, nil
2016-10-12 14:11:13 +00:00
}
if rawRule.Type == "chinaip" {
chinaiprule, err := parseChinaIPRule(msg)
if err != nil {
2017-04-08 23:43:25 +00:00
return nil, newError("Config: Invalid chinaip rule.").Base(err)
2016-10-12 14:11:13 +00:00
}
2017-02-02 13:42:31 +00:00
return chinaiprule, nil
2016-10-12 14:11:13 +00:00
}
if rawRule.Type == "chinasites" {
chinasitesrule, err := parseChinaSitesRule(msg)
if err != nil {
2017-04-08 23:43:25 +00:00
return nil, newError("Config: Invalid chinasites rule.").Base(err)
2016-10-12 14:11:13 +00:00
}
2017-02-02 13:42:31 +00:00
return chinasitesrule, nil
2016-10-12 14:11:13 +00:00
}
2017-04-08 23:43:25 +00:00
return nil, newError("Config: Unknown router rule type: ", rawRule.Type)
2016-10-12 14:11:13 +00:00
}
2016-10-17 12:35:13 +00:00
func parseChinaIPRule(data []byte) (*router.RoutingRule, error) {
rawRule := new(RouterRule)
err := json.Unmarshal(data, rawRule)
if err != nil {
2017-04-08 23:43:25 +00:00
return nil, newError("Config: Invalid router rule.").Base(err)
2016-10-12 14:11:13 +00:00
}
2016-10-17 14:35:18 +00:00
var chinaIPs geoip.CountryIPRange
if err := proto.Unmarshal(geoip.ChinaIPs, &chinaIPs); err != nil {
2017-04-08 23:43:25 +00:00
return nil, newError("Config: Invalid china ips.").Base(err)
2016-10-17 14:35:18 +00:00
}
2016-10-17 12:35:13 +00:00
return &router.RoutingRule{
2016-10-18 14:42:22 +00:00
Tag: rawRule.OutboundTag,
Cidr: chinaIPs.Ips,
2016-10-17 12:35:13 +00:00
}, nil
}
func parseChinaSitesRule(data []byte) (*router.RoutingRule, error) {
rawRule := new(RouterRule)
err := json.Unmarshal(data, rawRule)
if err != nil {
2017-04-08 23:43:25 +00:00
log.Trace(newError("Router: Invalid router rule: ", err).AtError())
2016-10-17 12:35:13 +00:00
return nil, err
2016-01-17 15:20:49 +00:00
}
2016-10-17 12:35:13 +00:00
return &router.RoutingRule{
Tag: rawRule.OutboundTag,
Domain: chinaSitesDomains,
}, nil
2016-01-17 15:20:49 +00:00
}