Implement route rules
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
package option
|
||||
|
||||
type Options struct {
|
||||
Log *LogOption `json:"log"`
|
||||
Inbounds []Inbound `json:"inbounds,omitempty"`
|
||||
Outbounds []Outbound `json:"outbounds,omitempty"`
|
||||
Routes []Rule `json:"routes,omitempty"`
|
||||
Log *LogOption `json:"log"`
|
||||
Inbounds []Inbound `json:"inbounds,omitempty"`
|
||||
Outbounds []Outbound `json:"outbounds,omitempty"`
|
||||
Route *RouteOptions `json:"route,omitempty"`
|
||||
}
|
||||
|
||||
type LogOption struct {
|
||||
|
||||
27
option/listable.go
Normal file
27
option/listable.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package option
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
type Listable[T any] []T
|
||||
|
||||
func (l *Listable[T]) MarshalJSON() ([]byte, error) {
|
||||
arrayList := []T(*l)
|
||||
if len(arrayList) == 1 {
|
||||
return json.Marshal(arrayList[0])
|
||||
}
|
||||
return json.Marshal(arrayList)
|
||||
}
|
||||
|
||||
func (l *Listable[T]) UnmarshalJSON(bytes []byte) error {
|
||||
err := json.Unmarshal(bytes, (*[]T)(l))
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
var singleItem T
|
||||
err = json.Unmarshal(bytes, &singleItem)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*l = []T{singleItem}
|
||||
return nil
|
||||
}
|
||||
@@ -2,7 +2,6 @@ package option
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
@@ -11,19 +10,24 @@ import (
|
||||
type NetworkList []string
|
||||
|
||||
func (v *NetworkList) UnmarshalJSON(data []byte) error {
|
||||
var networkList string
|
||||
var networkList []string
|
||||
err := json.Unmarshal(data, &networkList)
|
||||
if err != nil {
|
||||
return err
|
||||
var networkItem string
|
||||
err = json.Unmarshal(data, &networkItem)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
networkList = []string{networkItem}
|
||||
}
|
||||
for _, networkName := range strings.Split(networkList, ",") {
|
||||
for _, networkName := range networkList {
|
||||
switch networkName {
|
||||
case "tcp", "udp":
|
||||
*v = append(*v, networkName)
|
||||
default:
|
||||
return E.New("unknown network: " + networkName)
|
||||
}
|
||||
}
|
||||
*v = networkList
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -9,10 +9,21 @@ import (
|
||||
|
||||
var ErrUnknownRuleType = E.New("unknown rule type")
|
||||
|
||||
type RouteOptions struct {
|
||||
GeoIP *GeoIPOptions `json:"geoip,omitempty"`
|
||||
Rules []Rule `json:"rules,omitempty"`
|
||||
}
|
||||
|
||||
type GeoIPOptions struct {
|
||||
Path string `json:"path,omitempty"`
|
||||
DownloadURL string `json:"download_url,omitempty"`
|
||||
DownloadDetour string `json:"download_detour,omitempty"`
|
||||
}
|
||||
|
||||
type _Rule struct {
|
||||
Type string `json:"type"`
|
||||
DefaultOptions DefaultRule `json:"default_options,omitempty"`
|
||||
LogicalOptions LogicalRule `json:"logical_options,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
DefaultOptions *DefaultRule `json:"default_options,omitempty"`
|
||||
LogicalOptions *LogicalRule `json:"logical_options,omitempty"`
|
||||
}
|
||||
|
||||
type Rule _Rule
|
||||
@@ -45,9 +56,15 @@ func (r *Rule) UnmarshalJSON(bytes []byte) error {
|
||||
}
|
||||
switch r.Type {
|
||||
case "", C.RuleTypeDefault:
|
||||
err = json.Unmarshal(bytes, &r.DefaultOptions)
|
||||
if r.DefaultOptions == nil {
|
||||
break
|
||||
}
|
||||
err = json.Unmarshal(bytes, r.DefaultOptions)
|
||||
case C.RuleTypeLogical:
|
||||
err = json.Unmarshal(bytes, &r.LogicalOptions)
|
||||
if r.LogicalOptions == nil {
|
||||
break
|
||||
}
|
||||
err = json.Unmarshal(bytes, r.LogicalOptions)
|
||||
default:
|
||||
err = E.Extend(ErrUnknownRuleType, r.Type)
|
||||
}
|
||||
@@ -55,22 +72,22 @@ func (r *Rule) UnmarshalJSON(bytes []byte) error {
|
||||
}
|
||||
|
||||
type DefaultRule struct {
|
||||
Inbound []string `json:"inbound,omitempty"`
|
||||
IPVersion []int `json:"ip_version,omitempty"`
|
||||
Network []string `json:"network,omitempty"`
|
||||
Protocol []string `json:"protocol,omitempty"`
|
||||
Domain []string `json:"domain,omitempty"`
|
||||
DomainSuffix []string `json:"domain_suffix,omitempty"`
|
||||
DomainKeyword []string `json:"domain_keyword,omitempty"`
|
||||
SourceGeoIP []string `json:"source_geoip,omitempty"`
|
||||
GeoIP []string `json:"geoip,omitempty"`
|
||||
SourceIPCIDR []string `json:"source_ipcidr,omitempty"`
|
||||
SourcePort []string `json:"source_port,omitempty"`
|
||||
IPCIDR []string `json:"destination_ipcidr,omitempty"`
|
||||
Port []string `json:"destination_port,omitempty"`
|
||||
ProcessName []string `json:"process_name,omitempty"`
|
||||
ProcessPath []string `json:"process_path,omitempty"`
|
||||
Outbound string `json:"outbound,omitempty"`
|
||||
Inbound Listable[string] `json:"inbound,omitempty"`
|
||||
IPVersion int `json:"ip_version,omitempty"`
|
||||
Network string `json:"network,omitempty"`
|
||||
Protocol Listable[string] `json:"protocol,omitempty"`
|
||||
Domain Listable[string] `json:"domain,omitempty"`
|
||||
DomainSuffix Listable[string] `json:"domain_suffix,omitempty"`
|
||||
DomainKeyword Listable[string] `json:"domain_keyword,omitempty"`
|
||||
SourceGeoIP Listable[string] `json:"source_geoip,omitempty"`
|
||||
GeoIP Listable[string] `json:"geoip,omitempty"`
|
||||
SourceIPCIDR Listable[string] `json:"source_ip_cidr,omitempty"`
|
||||
IPCIDR Listable[string] `json:"ip_cidr,omitempty"`
|
||||
SourcePort Listable[uint16] `json:"source_port,omitempty"`
|
||||
Port Listable[uint16] `json:"port,omitempty"`
|
||||
// ProcessName Listable[string] `json:"process_name,omitempty"`
|
||||
// ProcessPath Listable[string] `json:"process_path,omitempty"`
|
||||
Outbound string `json:"outbound,omitempty"`
|
||||
}
|
||||
|
||||
type LogicalRule struct {
|
||||
|
||||
Reference in New Issue
Block a user