github.com/sagernet/sing-box@v1.9.0-rc.20/option/rule.go (about) 1 package option 2 3 import ( 4 "reflect" 5 6 C "github.com/sagernet/sing-box/constant" 7 "github.com/sagernet/sing/common" 8 E "github.com/sagernet/sing/common/exceptions" 9 "github.com/sagernet/sing/common/json" 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 err 52 } 53 return nil 54 } 55 56 func (r Rule) IsValid() bool { 57 switch r.Type { 58 case C.RuleTypeDefault: 59 return r.DefaultOptions.IsValid() 60 case C.RuleTypeLogical: 61 return r.LogicalOptions.IsValid() 62 default: 63 panic("unknown rule type: " + r.Type) 64 } 65 } 66 67 type DefaultRule struct { 68 Inbound Listable[string] `json:"inbound,omitempty"` 69 IPVersion int `json:"ip_version,omitempty"` 70 Network Listable[string] `json:"network,omitempty"` 71 AuthUser Listable[string] `json:"auth_user,omitempty"` 72 Protocol Listable[string] `json:"protocol,omitempty"` 73 Domain Listable[string] `json:"domain,omitempty"` 74 DomainSuffix Listable[string] `json:"domain_suffix,omitempty"` 75 DomainKeyword Listable[string] `json:"domain_keyword,omitempty"` 76 DomainRegex Listable[string] `json:"domain_regex,omitempty"` 77 Geosite Listable[string] `json:"geosite,omitempty"` 78 SourceGeoIP Listable[string] `json:"source_geoip,omitempty"` 79 GeoIP Listable[string] `json:"geoip,omitempty"` 80 SourceIPCIDR Listable[string] `json:"source_ip_cidr,omitempty"` 81 SourceIPIsPrivate bool `json:"source_ip_is_private,omitempty"` 82 IPCIDR Listable[string] `json:"ip_cidr,omitempty"` 83 IPIsPrivate bool `json:"ip_is_private,omitempty"` 84 SourcePort Listable[uint16] `json:"source_port,omitempty"` 85 SourcePortRange Listable[string] `json:"source_port_range,omitempty"` 86 Port Listable[uint16] `json:"port,omitempty"` 87 PortRange Listable[string] `json:"port_range,omitempty"` 88 ProcessName Listable[string] `json:"process_name,omitempty"` 89 ProcessPath Listable[string] `json:"process_path,omitempty"` 90 PackageName Listable[string] `json:"package_name,omitempty"` 91 User Listable[string] `json:"user,omitempty"` 92 UserID Listable[int32] `json:"user_id,omitempty"` 93 ClashMode string `json:"clash_mode,omitempty"` 94 WIFISSID Listable[string] `json:"wifi_ssid,omitempty"` 95 WIFIBSSID Listable[string] `json:"wifi_bssid,omitempty"` 96 RuleSet Listable[string] `json:"rule_set,omitempty"` 97 RuleSetIPCIDRMatchSource bool `json:"rule_set_ipcidr_match_source,omitempty"` 98 Invert bool `json:"invert,omitempty"` 99 Outbound string `json:"outbound,omitempty"` 100 } 101 102 func (r DefaultRule) IsValid() bool { 103 var defaultValue DefaultRule 104 defaultValue.Invert = r.Invert 105 defaultValue.Outbound = r.Outbound 106 return !reflect.DeepEqual(r, defaultValue) 107 } 108 109 type LogicalRule struct { 110 Mode string `json:"mode"` 111 Rules []Rule `json:"rules,omitempty"` 112 Invert bool `json:"invert,omitempty"` 113 Outbound string `json:"outbound,omitempty"` 114 } 115 116 func (r LogicalRule) IsValid() bool { 117 return len(r.Rules) > 0 && common.All(r.Rules, Rule.IsValid) 118 }