@@ -14,6 +14,7 @@ import (
1414
1515 C "github.com/sagernet/sing-box/constant"
1616 mdns "github.com/sagernet/sing-box/dns"
17+ "github.com/sagernet/sing-box/hiddify/ipinfo"
1718 "github.com/sagernet/sing-box/option"
1819 dns "github.com/sagernet/sing-dns"
1920 "github.com/sagernet/sing/common/json/badoption"
@@ -62,11 +63,6 @@ func BuildConfig(ctx context.Context, hopts *HiddifyOptions, inputOpt *ReadOptio
6263 options .Route = input .Route
6364 }
6465
65- if hopts .Warp .EnableWarp && hopts .Warp .Mode == "warp_over_proxy" {
66- OutboundMainProxyTag = WARPConfigTag
67- } else {
68- OutboundMainProxyTag = OutboundSelectTag
69- }
7066 setClashAPI (& options , hopts )
7167 setLog (& options , hopts )
7268 setInbound (& options , hopts )
@@ -107,46 +103,37 @@ func getHostnameIfNotIP(inp string) (string, error) {
107103
108104func setOutbounds (options * option.Options , input * option.Options , opt * HiddifyOptions , staticIPs * map [string ][]string ) error {
109105 var outbounds []option.Outbound
106+ var endpoints []option.Endpoint
110107 var tags []string
111108 // OutboundMainProxyTag = OutboundSelectTag
112109 // inbound==warp over proxies
113110 // outbound==proxies over warp
114- if opt .Warp .EnableWarp {
115- for _ , out := range input .Outbounds {
116- if out .Type == C .TypeCustom {
117- opts := out .Options .(map [string ]any )
118- if warp , ok := opts ["warp" ].(map [string ]any ); ok {
119- key , _ := warp ["key" ].(string )
120- if key == "p1" {
121- opt .Warp .EnableWarp = false
122- break
123- }
124- }
125- }
126- if out .Type == C .TypeWireGuard {
127- opts := out .Options .(option.WireGuardEndpointOptions )
128- if opts .PrivateKey == opt .Warp .WireguardConfig .PrivateKey || opts .PrivateKey == "p1" {
129- opt .Warp .EnableWarp = false
130- break
131- }
132- }
133- }
134- }
111+ OutboundMainProxyTag = OutboundSelectTag
135112 if opt .Warp .EnableWarp && (opt .Warp .Mode == "warp_over_proxy" || opt .Warp .Mode == "proxy_over_warp" ) {
136- wg := getOrGenerateWarpLocallyIfNeeded (& opt .Warp )
137- out , err := GenerateWarpSingbox (wg , opt .Warp .CleanIP , opt .Warp .CleanPort , opt .Warp .FakePackets , opt .Warp .FakePacketSize , opt .Warp .FakePacketDelay , opt .Warp .FakePacketMode )
113+ // wg := getOrGenerateWarpLocallyIfNeeded(&opt.Warp)
114+
115+ // out, err := GenerateWarpSingbox(wg, opt.Warp.CleanIP, opt.Warp.CleanPort, &option.WireGuardHiddify{
116+ // FakePackets: opt.Warp.FakePackets,
117+ // FakePacketsSize: opt.Warp.FakePacketSize,
118+ // FakePacketsDelay: opt.Warp.FakePacketDelay,
119+ // FakePacketsMode: opt.Warp.FakePacketMode,
120+ // })
121+ out , err := GenerateWarpSingboxNew ("p1" , & option.WireGuardHiddify {})
138122 if err != nil {
139123 return fmt .Errorf ("failed to generate warp config: %v" , err )
140124 }
141125 out .Tag = WARPConfigTag
142- opts := out .Options .(option.WireGuardEndpointOptions )
143- if opt .Warp .Mode == "warp_over_proxy" {
144- opts .Detour = OutboundSelectTag
145- } else {
146- opts .Detour = OutboundDirectTag
126+ if opts , ok := out .Options .(* option.WireGuardEndpointOptions ); ok {
127+ if opt .Warp .Mode == "warp_over_proxy" {
128+ opts .Detour = OutboundSelectTag
129+ } else {
130+ opts .Detour = OutboundDirectTag
131+ }
147132 }
148- patchWarp (out , opt , true , nil )
149- outbounds = append (outbounds , * out )
133+
134+ OutboundMainProxyTag = WARPConfigTag
135+ // patchWarp(out, opt, true, nil)
136+ endpoints = append (endpoints , * out )
150137 }
151138 for _ , out := range input .Outbounds {
152139 if contains (PredefinedOutboundTags , out .Tag ) {
@@ -166,30 +153,62 @@ func setOutbounds(options *option.Options, input *option.Options, opt *HiddifyOp
166153 case C .TypeCustom :
167154 continue
168155 default :
169- if opt .Warp .EnableWarp && opt .Warp .Mode == "warp_over_proxy" && out .Tag == WARPConfigTag {
170- continue
171- }
156+
172157 if contains ([]string {"direct" , "bypass" , "block" }, out .Tag ) {
173158 continue
174159 }
175160 if ! strings .Contains (out .Tag , "§hide§" ) {
176161 tags = append (tags , out .Tag )
177162 }
178- out = patchHiddifyWarpFromConfig (out , * opt )
163+ out = * patchHiddifyWarpFromConfig (& out , * opt )
179164 outbounds = append (outbounds , out )
180165 }
181166 }
182- testurls := []string {opt .ConnectionTestUrl , "http://captive.apple.com/generate_204" , "https://cp.cloudflare.com" , "https://google.com/generate_204" }
183- if isBlockedConnectionTestUrl (opt .ConnectionTestUrl ) {
184- testurls = []string {opt .ConnectionTestUrl }
167+ for _ , end := range input .Endpoints {
168+ if opt .Warp .EnableWarp {
169+ if end .Type == C .TypeWARP {
170+ if opts , ok := end .Options .(* option.WireGuardWARPEndpointOptions ); ok {
171+ if opts .UniqueIdentifier == "p1" {
172+ continue
173+ }
174+ }
175+ }
176+ if end .Type == C .TypeWireGuard {
177+ if opts , ok := end .Options .(* option.WireGuardEndpointOptions ); ok {
178+ if opts .PrivateKey == opt .Warp .WireguardConfig .PrivateKey {
179+ continue
180+ }
181+ }
182+ }
183+ if opt .Warp .Mode == "warp_over_proxy" && end .Tag == WARPConfigTag {
184+ continue
185+ }
186+ }
187+
188+ out , err := patchEndpoint (end , * opt , staticIPs )
189+ if err != nil {
190+ return err
191+ }
192+
193+ if ! strings .Contains (out .Tag , "§hide§" ) {
194+ tags = append (tags , out .Tag )
195+ }
196+
197+ endpoints = append (endpoints , * out )
198+ }
199+ if len (opt .ConnectionTestUrls ) == 0 {
200+ opt .ConnectionTestUrls = []string {opt .ConnectionTestUrl , "http://captive.apple.com/generate_204" , "https://cp.cloudflare.com" , "https://google.com/generate_204" }
201+ if isBlockedConnectionTestUrl (opt .ConnectionTestUrl ) {
202+ opt .ConnectionTestUrls = []string {opt .ConnectionTestUrl }
203+ }
185204 }
186205 urlTest := option.Outbound {
187206 Type : C .TypeURLTest ,
188207 Tag : OutboundURLTestTag ,
189208 Options : & option.URLTestOutboundOptions {
190209 Outbounds : tags ,
191210 URL : opt .ConnectionTestUrl ,
192- URLs : testurls ,
211+ URLs : opt . ConnectionTestUrls ,
193212 Interval : badoption .Duration (opt .URLTestInterval .Duration ()),
194213 // IdleTimeout: badoption.Duration(opt.URLTestIdleTimeout.Duration()),
195214 Tolerance : 1 ,
@@ -215,7 +234,7 @@ func setOutbounds(options *option.Options, input *option.Options, opt *HiddifyOp
215234 }
216235
217236 outbounds = append ([]option.Outbound {selector , urlTest }, outbounds ... )
218-
237+ options . Endpoints = endpoints
219238 options .Outbounds = append (
220239 outbounds ,
221240 []option.Outbound {
@@ -277,8 +296,9 @@ func setClashAPI(options *option.Options, opt *HiddifyOptions) {
277296 },
278297
279298 CacheFile : & option.CacheFileOptions {
280- Enabled : true ,
281- Path : "data/clash.db" ,
299+ Enabled : true ,
300+ StoreWARPConfig : true ,
301+ Path : "data/clash.db" ,
282302 },
283303 }
284304 }
@@ -418,22 +438,57 @@ func setRoutingOptions(options *option.Options, hopt *HiddifyOptions) error {
418438 // // )
419439 // }
420440
421- dnsRules = append (dnsRules , option.DefaultDNSRule {
422- RawDefaultDNSRule : option.RawDefaultDNSRule {},
423- DNSRuleAction : option.DNSRuleAction {
424- Action : C .RuleActionTypeRoute ,
425- RouteOptions : option.DNSRouteActionOptions {
426- Server : DNSStaticTag ,
427- },
428- },
429- },
430- )
441+ // dnsRules = append(dnsRules, option.DefaultDNSRule{
442+ // RawDefaultDNSRule: option.RawDefaultDNSRule{},
443+ // DNSRuleAction: option.DNSRuleAction{
444+ // Action: C.RuleActionTypeRoute,
445+ // RouteOptions: option.DNSRouteActionOptions{
446+ // Server: DNSStaticTag,
447+ // },
448+ // },
449+ // },
450+ // )
431451 forceDirectRules , err := addForceDirect (options , hopt )
432452 if err != nil {
433453 return err
434454 }
435455 dnsRules = append (dnsRules , forceDirectRules ... )
436456
457+ if len (hopt .ConnectionTestUrls ) > 0 { //To avoid dns bug when using urltest
458+ domains := []string {}
459+ for _ , url := range hopt .ConnectionTestUrls {
460+ if host , err := getHostnameIfNotIP (url ); err == nil {
461+ domains = append (domains , host )
462+ }
463+ }
464+ if len (domains ) > 0 {
465+ dnsRules = append (dnsRules , option.DefaultDNSRule {
466+ RawDefaultDNSRule : option.RawDefaultDNSRule {
467+ Domain : domains ,
468+ },
469+ DNSRuleAction : option.DNSRuleAction {
470+ Action : C .RuleActionTypeRoute ,
471+ RouteOptions : option.DNSRouteActionOptions {
472+ Server : DNSDirectTag ,
473+ },
474+ },
475+ })
476+ }
477+ }
478+ if ipinfoDomains := ipinfo .GetAllIPCheckerDomainsDomains (); len (ipinfoDomains ) > 0 { //To avoid dns bug when using urltest
479+ dnsRules = append (dnsRules , option.DefaultDNSRule {
480+ RawDefaultDNSRule : option.RawDefaultDNSRule {
481+ Domain : ipinfoDomains ,
482+ },
483+ DNSRuleAction : option.DNSRuleAction {
484+ Action : C .RuleActionTypeRoute ,
485+ RouteOptions : option.DNSRouteActionOptions {
486+ Server : DNSDirectTag ,
487+ },
488+ },
489+ })
490+ }
491+
437492 routeRules = append (routeRules , option.Rule {
438493 Type : C .RuleTypeDefault ,
439494 DefaultOptions : option.DefaultRule {
@@ -871,7 +926,7 @@ func setRoutingOptions(options *option.Options, hopt *HiddifyOptions) error {
871926 return nil
872927}
873928
874- func patchHiddifyWarpFromConfig (out option.Outbound , opt HiddifyOptions ) option.Outbound {
929+ func patchHiddifyWarpFromConfig (out * option.Outbound , opt HiddifyOptions ) * option.Outbound {
875930 if opt .Warp .EnableWarp && opt .Warp .Mode == "proxy_over_warp" {
876931 if opts , ok := out .Options .(option.DialerOptionsWrapper ); ok {
877932 dialer := opts .TakeDialerOptions ()
0 commit comments