199 lines
5.9 KiB
Go
199 lines
5.9 KiB
Go
package option
|
|
|
|
import (
|
|
"net/url"
|
|
|
|
C "github.com/sagernet/sing-box/constant"
|
|
E "github.com/sagernet/sing/common/exceptions"
|
|
"github.com/sagernet/sing/common/json"
|
|
"github.com/sagernet/sing/common/json/badjson"
|
|
"github.com/sagernet/sing/common/json/badoption"
|
|
)
|
|
|
|
type Hysteria2InboundOptions struct {
|
|
ListenOptions
|
|
UpMbps int `json:"up_mbps,omitempty"`
|
|
DownMbps int `json:"down_mbps,omitempty"`
|
|
Obfs *Hysteria2Obfs `json:"obfs,omitempty"`
|
|
Users []Hysteria2User `json:"users,omitempty"`
|
|
IgnoreClientBandwidth bool `json:"ignore_client_bandwidth,omitempty"`
|
|
InboundTLSOptionsContainer
|
|
QUICOptions
|
|
Masquerade *Hysteria2Masquerade `json:"masquerade,omitempty"`
|
|
BBRProfile string `json:"bbr_profile,omitempty"`
|
|
BrutalDebug bool `json:"brutal_debug,omitempty"`
|
|
Realm *Hysteria2InboundRealm `json:"realm,omitempty"`
|
|
}
|
|
|
|
type Hysteria2Realm struct {
|
|
ServerURL string `json:"server_url"`
|
|
Token string `json:"token,omitempty"`
|
|
RealmID string `json:"realm_id"`
|
|
STUNServers badoption.Listable[string] `json:"stun_servers"`
|
|
HTTPClient *HTTPClientOptions `json:"http_client,omitempty"`
|
|
}
|
|
|
|
type Hysteria2InboundRealm struct {
|
|
Hysteria2Realm
|
|
STUNDomainResolver *DomainResolveOptions `json:"stun_domain_resolver,omitempty"`
|
|
}
|
|
|
|
type Hysteria2ObfsGecko struct {
|
|
MinPacketSize int `json:"min_packet_size,omitempty"`
|
|
MaxPacketSize int `json:"max_packet_size,omitempty"`
|
|
}
|
|
|
|
type _Hysteria2Obfs struct {
|
|
Type string `json:"type,omitempty"`
|
|
Password string `json:"password,omitempty"`
|
|
GeckoOptions Hysteria2ObfsGecko `json:"-"`
|
|
}
|
|
|
|
type Hysteria2Obfs _Hysteria2Obfs
|
|
|
|
func (o Hysteria2Obfs) MarshalJSON() ([]byte, error) {
|
|
var v any
|
|
switch o.Type {
|
|
case C.Hysteria2ObfsTypeSalamander:
|
|
case C.Hysteria2ObfsTypeGecko:
|
|
v = o.GeckoOptions
|
|
default:
|
|
return nil, E.New("unknown obfs type: ", o.Type)
|
|
}
|
|
if v == nil {
|
|
return json.Marshal((_Hysteria2Obfs)(o))
|
|
}
|
|
return badjson.MarshallObjects((_Hysteria2Obfs)(o), v)
|
|
}
|
|
|
|
func (o *Hysteria2Obfs) UnmarshalJSON(bytes []byte) error {
|
|
err := json.Unmarshal(bytes, (*_Hysteria2Obfs)(o))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
var v any
|
|
switch o.Type {
|
|
case C.Hysteria2ObfsTypeSalamander:
|
|
case C.Hysteria2ObfsTypeGecko:
|
|
v = &o.GeckoOptions
|
|
default:
|
|
return E.New("unknown obfs type: ", o.Type)
|
|
}
|
|
if v == nil {
|
|
return nil
|
|
}
|
|
return badjson.UnmarshallExcluded(bytes, (*_Hysteria2Obfs)(o), v)
|
|
}
|
|
|
|
type Hysteria2User struct {
|
|
Name string `json:"name,omitempty"`
|
|
Password string `json:"password,omitempty"`
|
|
}
|
|
|
|
type _Hysteria2Masquerade struct {
|
|
Type string `json:"type,omitempty"`
|
|
FileOptions Hysteria2MasqueradeFile `json:"-"`
|
|
ProxyOptions Hysteria2MasqueradeProxy `json:"-"`
|
|
StringOptions Hysteria2MasqueradeString `json:"-"`
|
|
}
|
|
|
|
type Hysteria2Masquerade _Hysteria2Masquerade
|
|
|
|
func (m Hysteria2Masquerade) MarshalJSON() ([]byte, error) {
|
|
var v any
|
|
switch m.Type {
|
|
case C.Hysterai2MasqueradeTypeFile:
|
|
v = m.FileOptions
|
|
case C.Hysterai2MasqueradeTypeProxy:
|
|
v = m.ProxyOptions
|
|
case C.Hysterai2MasqueradeTypeString:
|
|
v = m.StringOptions
|
|
default:
|
|
return nil, E.New("unknown masquerade type: ", m.Type)
|
|
}
|
|
return badjson.MarshallObjects((_Hysteria2Masquerade)(m), v)
|
|
}
|
|
|
|
func (m *Hysteria2Masquerade) UnmarshalJSON(bytes []byte) error {
|
|
var urlString string
|
|
err := json.Unmarshal(bytes, &urlString)
|
|
if err == nil {
|
|
masqueradeURL, err := url.Parse(urlString)
|
|
if err != nil {
|
|
return E.Cause(err, "invalid masquerade URL")
|
|
}
|
|
switch masqueradeURL.Scheme {
|
|
case "file":
|
|
m.Type = C.Hysterai2MasqueradeTypeFile
|
|
m.FileOptions.Directory = masqueradeURL.Path
|
|
case "http", "https":
|
|
m.Type = C.Hysterai2MasqueradeTypeProxy
|
|
m.ProxyOptions.URL = urlString
|
|
default:
|
|
return E.New("unknown masquerade URL scheme: ", masqueradeURL.Scheme)
|
|
}
|
|
return nil
|
|
}
|
|
err = json.Unmarshal(bytes, (*_Hysteria2Masquerade)(m))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
var v any
|
|
switch m.Type {
|
|
case C.Hysterai2MasqueradeTypeFile:
|
|
v = &m.FileOptions
|
|
case C.Hysterai2MasqueradeTypeProxy:
|
|
v = &m.ProxyOptions
|
|
case C.Hysterai2MasqueradeTypeString:
|
|
v = &m.StringOptions
|
|
default:
|
|
return E.New("unknown masquerade type: ", m.Type)
|
|
}
|
|
return badjson.UnmarshallExcluded(bytes, (*_Hysteria2Masquerade)(m), v)
|
|
}
|
|
|
|
type Hysteria2MasqueradeFile struct {
|
|
Directory string `json:"directory"`
|
|
}
|
|
|
|
type Hysteria2MasqueradeProxy struct {
|
|
URL string `json:"url"`
|
|
RewriteHost bool `json:"rewrite_host,omitempty"`
|
|
}
|
|
|
|
type Hysteria2MasqueradeString struct {
|
|
StatusCode int `json:"status_code,omitempty"`
|
|
Headers badoption.HTTPHeader `json:"headers,omitempty"`
|
|
Content string `json:"content"`
|
|
}
|
|
|
|
type Hysteria2OutboundOptions struct {
|
|
DialerOptions
|
|
ServerOptions
|
|
ServerPorts badoption.Listable[string] `json:"server_ports,omitempty"`
|
|
HopInterval badoption.Duration `json:"hop_interval,omitempty"`
|
|
HopIntervalMax badoption.Duration `json:"hop_interval_max,omitempty"`
|
|
UpMbps int `json:"up_mbps,omitempty"`
|
|
DownMbps int `json:"down_mbps,omitempty"`
|
|
Obfs *Hysteria2Obfs `json:"obfs,omitempty"`
|
|
Password string `json:"password,omitempty"`
|
|
Network NetworkList `json:"network,omitempty"`
|
|
OutboundTLSOptionsContainer
|
|
QUICOptions
|
|
BBRProfile string `json:"bbr_profile,omitempty"`
|
|
BrutalDebug bool `json:"brutal_debug,omitempty"`
|
|
Realm *Hysteria2Realm `json:"realm,omitempty"`
|
|
}
|
|
|
|
type HysteriaRealmUser struct {
|
|
Name string `json:"name"`
|
|
Token string `json:"token"`
|
|
MaxRealms int `json:"max_realms,omitempty"`
|
|
}
|
|
|
|
type HysteriaRealmServiceOptions struct {
|
|
ListenOptions
|
|
InboundTLSOptionsContainer
|
|
HTTP2Options
|
|
Users []HysteriaRealmUser `json:"users"`
|
|
}
|