Fix service.go to work with singbox 1.8.2

Drop deprecated feautre (Clash API: cache_file and store_selected)
Add feature (Cache File: path)
Add new idle_timeout field for URLTest outbound
Refactor outbound.go
Add feature to omit TLSTricks and Fragment on VLESS Reality configs.
This commit is contained in:
83hd4d
2024-01-22 04:07:32 +03:30
parent 1b0ed4afc1
commit bccb34c333
4 changed files with 78 additions and 50 deletions

View File

@@ -53,8 +53,10 @@ func BuildConfig(configOpt ConfigOptions, input option.Options) (*option.Options
options.Experimental = &option.ExperimentalOptions{
ClashAPI: &option.ClashAPIOptions{
ExternalController: fmt.Sprintf("%s:%d", "127.0.0.1", configOpt.ClashApiPort),
StoreSelected: true,
CacheFile: "clash.db",
},
CacheFile: &option.CacheFileOptions{
Enabled: true,
Path: "clash.db",
},
}
}
@@ -354,9 +356,10 @@ func BuildConfig(configOpt ConfigOptions, input option.Options) (*option.Options
Type: C.TypeURLTest,
Tag: "auto",
URLTestOptions: option.URLTestOutboundOptions{
Outbounds: tags,
URL: configOpt.ConnectionTestUrl,
Interval: configOpt.URLTestInterval,
Outbounds: tags,
URL: configOpt.ConnectionTestUrl,
Interval: configOpt.URLTestInterval,
IdleTimeout: configOpt.URLTestIdleTimeout,
},
}
@@ -408,7 +411,6 @@ func applyOverrides(overrides ConfigOptions, options option.Options) *option.Opt
if overrides.EnableClashApi {
options.Experimental.ClashAPI = &option.ClashAPIOptions{
ExternalController: fmt.Sprintf("%s:%d", "127.0.0.1", overrides.ClashApiPort),
StoreSelected: true,
}
}

View File

@@ -23,6 +23,7 @@ type ConfigOptions struct {
TUNStack string `json:"tun-stack"`
ConnectionTestUrl string `json:"connection-test-url"`
URLTestInterval option.Duration `json:"url-test-interval"`
URLTestIdleTimeout option.Duration `json:"url-test-idle-timeout"`
EnableClashApi bool `json:"enable-clash-api"`
ClashApiPort uint16 `json:"clash-api-port"`
EnableTun bool `json:"enable-tun"`
@@ -72,6 +73,7 @@ func DefaultConfigOptions() *ConfigOptions {
TUNStack: "mixed",
ConnectionTestUrl: "https://cp.cloudflare.com/",
URLTestInterval: option.Duration(10 * time.Minute),
URLTestIdleTimeout: option.Duration(100 * time.Minute),
EnableClashApi: true,
ClashApiPort: 6756,
EnableTun: true,

View File

@@ -11,6 +11,70 @@ import (
type outboundMap map[string]interface{}
func patchOutboundMux(base option.Outbound, configOpt ConfigOptions, obj outboundMap) outboundMap {
if configOpt.EnableMux {
multiplex := option.OutboundMultiplexOptions{
Enabled: true,
Padding: configOpt.MuxPadding,
MaxStreams: configOpt.MaxStreams,
Protocol: configOpt.MuxProtocol,
}
obj["multiplex"] = multiplex
} else {
delete(obj, "multiplex")
}
return obj
}
func patchOutboundTLSTricks(base option.Outbound, configOpt ConfigOptions, obj outboundMap) outboundMap {
obj = patchOutboundFragment(base, configOpt, obj)
if tls, ok := obj["tls"].(map[string]interface{}); ok {
tlsTricks := option.TLSTricksOptions{
MixedCaseSNI: configOpt.TLSTricks.EnableMixedSNICase,
}
if configOpt.TLSTricks.EnablePadding {
tlsTricks.PaddingMode = "random"
tlsTricks.PaddingSize = configOpt.TLSTricks.PaddingSize
}
if tlsTricks.MixedCaseSNI || tlsTricks.PaddingMode != "" {
tls["tls_tricks"] = tlsTricks
} else {
tls["tls_tricks"] = nil
}
}
return obj
}
func patchOutboundFragment(base option.Outbound, configOpt ConfigOptions, obj outboundMap) outboundMap {
if configOpt.EnableFragment {
tlsFragment := option.TLSFragmentOptions{
Enabled: configOpt.TLSTricks.EnableFragment,
Size: configOpt.TLSTricks.FragmentSize,
Sleep: configOpt.TLSTricks.FragmentSleep,
}
obj["tls_fragment"] = tlsFragment
} else {
obj["tls_fragment"] = nil
}
return obj
}
func isOutboundReality(base option.Outbound) bool {
// this function checks reality status ONLY FOR VLESS.
// Some other protocols can also use reality, but it's discouraged as stated in the reality document
isReality := false
switch base.Type {
case C.TypeVLESS:
if base.VLESSOptions.TLS.Reality != nil {
isReality = base.VLESSOptions.TLS.Reality.Enabled
}
}
return isReality
}
func patchOutbound(base option.Outbound, configOpt ConfigOptions) (*option.Outbound, string, error) {
var serverDomain string
var outbound option.Outbound
@@ -35,50 +99,12 @@ func patchOutbound(base option.Outbound, configOpt ConfigOptions) (*option.Outbo
serverDomain = fmt.Sprintf("full:%s", server)
}
}
if !(base.Type == C.TypeSelector || base.Type == C.TypeURLTest || base.Type == C.TypeBlock || base.Type == C.TypeDNS) {
if configOpt.EnableFragment {
tlsFragment := option.TLSFragmentOptions{
Enabled: configOpt.TLSTricks.EnableFragment,
Size: configOpt.TLSTricks.FragmentSize,
Sleep: configOpt.TLSTricks.FragmentSleep,
}
obj["tls_fragment"] = tlsFragment
} else {
obj["tls_fragment"] = nil
}
if tls, ok := obj["tls"].(map[string]interface{}); ok {
tlsTricks := option.TLSTricksOptions{
MixedCaseSNI: configOpt.TLSTricks.EnableMixedSNICase,
}
if configOpt.TLSTricks.EnablePadding {
tlsTricks.PaddingMode = "random"
tlsTricks.PaddingSize = configOpt.TLSTricks.PaddingSize
}
if tlsTricks.MixedCaseSNI || tlsTricks.PaddingMode != "" {
tls["tls_tricks"] = tlsTricks
} else {
tls["tls_tricks"] = nil
}
}
if !(base.Type == C.TypeSelector || base.Type == C.TypeURLTest || base.Type == C.TypeBlock || base.Type == C.TypeDNS || isOutboundReality(base)) {
obj = patchOutboundTLSTricks(base, configOpt, obj)
}
switch base.Type {
case C.TypeVMess, C.TypeVLESS, C.TypeTrojan, C.TypeShadowsocks:
if configOpt.EnableMux {
multiplex := option.OutboundMultiplexOptions{
Enabled: true,
Padding: configOpt.MuxPadding,
MaxStreams: configOpt.MaxStreams,
Protocol: configOpt.MuxProtocol,
}
obj["multiplex"] = multiplex
} else {
delete(obj, "multiplex")
}
obj = patchOutboundMux(base, configOpt, obj)
}
modifiedJson, err := json.Marshal(obj)

View File

@@ -36,8 +36,6 @@ func NewService(options option.Options) (*libbox.BoxService, error) {
ctx = filemanager.WithDefault(ctx, sWorkingPath, sTempPath, sUserID, sGroupID)
urlTestHistoryStorage := urltest.NewHistoryStorage()
ctx = service.ContextWithPtr(ctx, urlTestHistoryStorage)
pauseManager := pause.WithDefaultManager(ctx)
// ctx = pause.ContextWithManager(ctx, pauseManager)
instance, err := B.New(B.Options{
Context: ctx,
Options: options,
@@ -51,7 +49,7 @@ func NewService(options option.Options) (*libbox.BoxService, error) {
ctx,
cancel,
instance,
pauseManager,
service.FromContext[pause.Manager](ctx),
urlTestHistoryStorage,
)
return &service, nil