github.com/inazumav/sing-box@v0.0.0-20230926072359-ab51429a14f1/option/rule.go (about) 1 package option 2 3 import ( 4 "reflect" 5 6 "github.com/inazumav/sing-box/common/json" 7 C "github.com/inazumav/sing-box/constant" 8 "github.com/sagernet/sing/common" 9 E "github.com/sagernet/sing/common/exceptions" 10 ) 11 12 type _Rule struct { 13 Type string `json:"type,omitempty"` 14 DefaultOptions DefaultRule `json:"-"` 15 LogicalOptions LogicalRule `json:"-"` 16 } 17 18 type Rule _Rule 19 20 func (r Rule) MarshalJSON() ([]byte, error) { 21 var v any 22 switch r.Type { 23 case C.RuleTypeDefault: 24 r.Type = "" 25 v = r.DefaultOptions 26 case C.RuleTypeLogical: 27 v = r.LogicalOptions 28 default: 29 return nil, E.New("unknown rule type: " + r.Type) 30 } 31 return MarshallObjects((_Rule)(r), v) 32 } 33 34 func (r *Rule) UnmarshalJSON(bytes []byte) error { 35 err := json.Unmarshal(bytes, (*_Rule)(r)) 36 if err != nil { 37 return err 38 } 39 var v any 40 switch r.Type { 41 case "", C.RuleTypeDefault: 42 r.Type = C.RuleTypeDefault 43 v = &r.DefaultOptions 44 case C.RuleTypeLogical: 45 v = &r.LogicalOptions 46 default: 47 return E.New("unknown rule type: " + r.Type) 48 } 49 err = UnmarshallExcluded(bytes, (*_Rule)(r), v) 50 if err != nil { 51 return E.Cause(err, "route rule") 52 } 53 return nil 54 } 55 56 type DefaultRule struct { 57 Inbound Listable[string] `json:"inbound,omitempty"` 58 IPVersion int `json:"ip_version,omitempty"` 59 Network Listable[string] `json:"network,omitempty"` 60 AuthUser Listable[string] `json:"auth_user,omitempty"` 61 Protocol Listable[string] `json:"protocol,omitempty"` 62 Domain Listable[string] `json:"domain,omitempty"` 63 DomainSuffix Listable[string] `json:"domain_suffix,omitempty"` 64 DomainKeyword Listable[string] `json:"domain_keyword,omitempty"` 65 DomainRegex Listable[string] `json:"domain_regex,omitempty"` 66 Geosite Listable[string] `json:"geosite,omitempty"` 67 SourceGeoIP Listable[string] `json:"source_geoip,omitempty"` 68 GeoIP Listable[string] `json:"geoip,omitempty"` 69 SourceIPCIDR Listable[string] `json:"source_ip_cidr,omitempty"` 70 IPCIDR Listable[string] `json:"ip_cidr,omitempty"` 71 SourcePort Listable[uint16] `json:"source_port,omitempty"` 72 SourcePortRange Listable[string] `json:"source_port_range,omitempty"` 73 Port Listable[uint16] `json:"port,omitempty"` 74 PortRange Listable[string] `json:"port_range,omitempty"` 75 ProcessName Listable[string] `json:"process_name,omitempty"` 76 ProcessPath Listable[string] `json:"process_path,omitempty"` 77 PackageName Listable[string] `json:"package_name,omitempty"` 78 User Listable[string] `json:"user,omitempty"` 79 UserID Listable[int32] `json:"user_id,omitempty"` 80 ClashMode string `json:"clash_mode,omitempty"` 81 Invert bool `json:"invert,omitempty"` 82 Outbound string `json:"outbound,omitempty"` 83 } 84 85 func (r DefaultRule) IsValid() bool { 86 var defaultValue DefaultRule 87 defaultValue.Invert = r.Invert 88 defaultValue.Outbound = r.Outbound 89 return !reflect.DeepEqual(r, defaultValue) 90 } 91 92 type LogicalRule struct { 93 Mode string `json:"mode"` 94 Rules []DefaultRule `json:"rules,omitempty"` 95 Invert bool `json:"invert,omitempty"` 96 Outbound string `json:"outbound,omitempty"` 97 } 98 99 func (r LogicalRule) IsValid() bool { 100 return len(r.Rules) > 0 && common.All(r.Rules, DefaultRule.IsValid) 101 }