Files
sing-box-extended-mirror/option/options.go
T

97 lines
2.5 KiB
Go
Raw Normal View History

2022-07-02 14:07:50 +08:00
package option
import (
"bytes"
2024-11-02 00:39:02 +08:00
"context"
2022-07-03 01:57:04 +08:00
2025-03-29 19:51:21 +08:00
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/json"
)
type _Options struct {
2023-12-10 22:57:28 +08:00
RawMessage json.RawMessage `json:"-"`
2023-03-13 10:58:29 +08:00
Schema string `json:"$schema,omitempty"`
2023-02-28 19:02:27 +08:00
Log *LogOptions `json:"log,omitempty"`
DNS *DNSOptions `json:"dns,omitempty"`
NTP *NTPOptions `json:"ntp,omitempty"`
2025-01-08 10:34:45 +08:00
Certificate *CertificateOptions `json:"certificate,omitempty"`
2024-11-21 18:10:41 +08:00
Endpoints []Endpoint `json:"endpoints,omitempty"`
2023-02-28 19:02:27 +08:00
Inbounds []Inbound `json:"inbounds,omitempty"`
Outbounds []Outbound `json:"outbounds,omitempty"`
Route *RouteOptions `json:"route,omitempty"`
2025-03-29 17:24:34 +08:00
Services []Service `json:"services,omitempty"`
2023-02-28 19:02:27 +08:00
Experimental *ExperimentalOptions `json:"experimental,omitempty"`
2022-07-02 14:07:50 +08:00
}
type Options _Options
2024-11-02 00:39:02 +08:00
func (o *Options) UnmarshalJSONContext(ctx context.Context, content []byte) error {
decoder := json.NewDecoderContext(ctx, bytes.NewReader(content))
decoder.DisallowUnknownFields()
2022-07-07 21:47:21 +08:00
err := decoder.Decode((*_Options)(o))
2023-12-10 22:57:28 +08:00
if err != nil {
return err
2022-07-07 21:47:21 +08:00
}
2023-12-10 22:57:28 +08:00
o.RawMessage = content
2025-03-29 19:51:21 +08:00
return checkOptions(o)
}
2022-07-19 22:16:49 +08:00
type LogOptions struct {
2022-07-04 16:45:32 +08:00
Disabled bool `json:"disabled,omitempty"`
Level string `json:"level,omitempty"`
Output string `json:"output,omitempty"`
Timestamp bool `json:"timestamp,omitempty"`
DisableColor bool `json:"-"`
2022-07-02 14:07:50 +08:00
}
2024-11-02 00:39:02 +08:00
type StubOptions struct{}
2025-03-29 19:51:21 +08:00
func checkOptions(options *Options) error {
err := checkInbounds(options.Inbounds)
if err != nil {
return err
}
err = checkOutbounds(options.Outbounds, options.Endpoints)
if err != nil {
return err
}
return nil
}
func checkInbounds(inbounds []Inbound) error {
seen := make(map[string]bool)
for _, inbound := range inbounds {
if inbound.Tag == "" {
continue
}
if seen[inbound.Tag] {
return E.New("duplicate inbound tag: ", inbound.Tag)
}
seen[inbound.Tag] = true
}
return nil
}
func checkOutbounds(outbounds []Outbound, endpoints []Endpoint) error {
seen := make(map[string]bool)
for _, outbound := range outbounds {
if outbound.Tag == "" {
continue
}
if seen[outbound.Tag] {
return E.New("duplicate outbound/endpoint tag: ", outbound.Tag)
}
seen[outbound.Tag] = true
}
for _, endpoint := range endpoints {
if endpoint.Tag == "" {
continue
}
if seen[endpoint.Tag] {
return E.New("duplicate outbound/endpoint tag: ", endpoint.Tag)
}
seen[endpoint.Tag] = true
}
return nil
}