1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-12-22 01:57:12 -05:00
v2fly/app/router/config_json.go
2016-10-12 16:11:13 +02:00

169 lines
3.7 KiB
Go

// +build json
package router
import (
"encoding/json"
"errors"
"strconv"
"strings"
"v2ray.com/core/common/collect"
"v2ray.com/core/common/log"
v2net "v2ray.com/core/common/net"
)
type JsonRule struct {
Type string `json:"type"`
OutboundTag string `json:"outboundTag"`
}
func parseIP(s string) *IP {
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)
if !ip.Family().Either(v2net.AddressFamilyIPv4, v2net.AddressFamilyIPv6) {
return nil
}
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)
return nil
}
return &IP{
Ip: []byte(ip.IP()),
UnmatchingBits: 32 - bits,
}
}
func parseFieldRule(msg json.RawMessage) (*RoutingRule, error) {
type RawFieldRule struct {
JsonRule
Domain *collect.StringList `json:"domain"`
IP *collect.StringList `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
}
rule := new(RoutingRule)
rule.Tag = rawFieldRule.OutboundTag
if rawFieldRule.Domain != nil {
for _, domain := range *rawFieldRule.Domain {
domainRule := new(Domain)
if strings.HasPrefix(domain, "regexp:") {
domainRule.Type = Domain_Regex
domainRule.Value = domain[7:]
} else {
domainRule.Type = Domain_Plain
domainRule.Value = domain
}
rule.Domain = append(rule.Domain, domainRule)
}
}
if rawFieldRule.IP != nil {
for _, ip := range *rawFieldRule.IP {
ipRule := parseIP(ip)
if ipRule != nil {
rule.Ip = append(rule.Ip, ipRule)
}
}
}
if rawFieldRule.Port != nil {
rule.PortRange = rawFieldRule.Port
}
if rawFieldRule.Network != nil {
rule.NetworkList = rawFieldRule.Network
}
return rule, nil
}
func ParseRule(msg json.RawMessage) *RoutingRule {
rawRule := new(JsonRule)
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
}
func (this *Config) UnmarshalJSON(data []byte) error {
type JsonRulesConfig struct {
RuleList []json.RawMessage `json:"rules"`
DomainStrategy string `json:"domainStrategy"`
}
type JsonConfig struct {
Settings *JsonRulesConfig `json:"settings"`
}
jsonConfig := new(JsonConfig)
if err := json.Unmarshal(data, jsonConfig); err != nil {
return err
}
if jsonConfig.Settings == nil {
return errors.New("Router settings is not specified.")
}
settings := jsonConfig.Settings
this.DomainStrategy = Config_AsIs
this.Rule = make([]*RoutingRule, len(settings.RuleList))
domainStrategy := strings.ToLower(settings.DomainStrategy)
if domainStrategy == "alwaysip" {
this.DomainStrategy = Config_UseIp
} else if domainStrategy == "ipifnonmatch" {
this.DomainStrategy = Config_IpIfNonMatch
}
for idx, rawRule := range settings.RuleList {
rule := ParseRule(rawRule)
this.Rule[idx] = rule
}
return nil
}