|
|
@@ -0,0 +1,94 @@
|
|
|
+package json
|
|
|
+
|
|
|
+import (
|
|
|
+ "encoding/json"
|
|
|
+ "errors"
|
|
|
+ "net"
|
|
|
+ "strings"
|
|
|
+
|
|
|
+ "github.com/v2ray/v2ray-core/app/point/config"
|
|
|
+ v2net "github.com/v2ray/v2ray-core/common/net"
|
|
|
+ v2netjson "github.com/v2ray/v2ray-core/common/net/json"
|
|
|
+)
|
|
|
+
|
|
|
+type Rule struct {
|
|
|
+ Type string `json:"type"`
|
|
|
+ OutboundTag string `json:"outboundTag"`
|
|
|
+}
|
|
|
+
|
|
|
+func (this *Rule) Tag() *config.DetourTag {
|
|
|
+ detourTag := config.DetourTag(this.OutboundTag)
|
|
|
+ return &detourTag
|
|
|
+}
|
|
|
+
|
|
|
+func (this *Rule) Apply(dest v2net.Destination) bool {
|
|
|
+ return false
|
|
|
+}
|
|
|
+
|
|
|
+type FieldRule struct {
|
|
|
+ Rule
|
|
|
+ Domain string
|
|
|
+ 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 && address.IsDomain() {
|
|
|
+ if !strings.Contains(address.Domain(), this.Domain) {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if this.IP != nil && (address.IsIPv4() || address.IsIPv6()) {
|
|
|
+ if !this.IP.Contains(address.IP()) {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if this.Port != nil {
|
|
|
+ port := address.Port()
|
|
|
+ if port < this.Port.From() || port > this.Port.To() {
|
|
|
+ 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 string `json:"domain"`
|
|
|
+ IP string `json:"ip"`
|
|
|
+ Port *v2netjson.PortRange
|
|
|
+ Network *v2netjson.NetworkList
|
|
|
+ }
|
|
|
+ rawFieldRule := RawFieldRule{}
|
|
|
+ err := json.Unmarshal(data, &rawFieldRule)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ this.Type = rawFieldRule.Type
|
|
|
+ this.OutboundTag = rawFieldRule.OutboundTag
|
|
|
+ this.Domain = rawFieldRule.Domain
|
|
|
+ _, ipNet, err := net.ParseCIDR(rawFieldRule.IP)
|
|
|
+ if err != nil {
|
|
|
+ return errors.New("Invalid IP range in router rule: " + err.Error())
|
|
|
+ }
|
|
|
+ this.IP = ipNet
|
|
|
+ if rawFieldRule.Port != nil {
|
|
|
+ this.Port = rawFieldRule.Port
|
|
|
+ }
|
|
|
+ if rawFieldRule.Network != nil {
|
|
|
+ this.Network = rawFieldRule.Network
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+}
|