1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-11-04 09:17:32 -05:00
v2fly/tools/conf/router.go

244 lines
5.5 KiB
Go
Raw Normal View History

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