Release 3.10.0+1: sidebar UI (Home / Profiles / Settings / Logs / About), remembered account with 50 GB monthly renew + auto-renew, Windows VPN mode (wintun + tun2socks).
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+40
-46
@@ -98,6 +98,42 @@ func BestOK(results []Result) (Result, bool) {
|
||||
return best, found
|
||||
}
|
||||
|
||||
// HostPort extracts the remote server endpoint from a share/proxy URI using
|
||||
// protocol hints. Used for pings and for VPN-mode route exclusions.
|
||||
func HostPort(proto config.Protocol, proxyURI string) (string, string, error) {
|
||||
hy2 := proto == config.ProtocolHysteria2 || hysteria2.Detect(proxyURI)
|
||||
isAWG := proto == config.ProtocolAWG || awg.Detect(proxyURI)
|
||||
isXray := proto == config.ProtocolVLESS || proto == config.ProtocolVMess || proto == config.ProtocolTrojan || xray.Detect(proxyURI)
|
||||
switch {
|
||||
case isAWG:
|
||||
return awg.HostPort(proxyURI)
|
||||
case isXray:
|
||||
return xray.HostPort(proxyURI)
|
||||
case hy2:
|
||||
return hysteria2.HostPort(proxyURI)
|
||||
}
|
||||
normalized, _, _, err := linknorm.Normalize(proto, proxyURI)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
rest := normalized
|
||||
if i := strings.Index(rest, "://"); i >= 0 {
|
||||
rest = rest[i+3:]
|
||||
}
|
||||
if at := strings.LastIndex(rest, "@"); at >= 0 {
|
||||
rest = rest[at+1:]
|
||||
}
|
||||
if i := strings.IndexAny(rest, "/?#"); i >= 0 {
|
||||
rest = rest[:i]
|
||||
}
|
||||
host, port := rest, "443"
|
||||
if i := strings.LastIndex(rest, ":"); i >= 0 {
|
||||
host = rest[:i]
|
||||
port = rest[i+1:]
|
||||
}
|
||||
return host, port, nil
|
||||
}
|
||||
|
||||
// PingProfile pings using protocol hints when available.
|
||||
// Naive uses TCP; Hysteria 2 uses UDP (QUIC) — TCP would always look "refused".
|
||||
func PingProfile(ctx context.Context, name string, proto config.Protocol, proxyURI string) Result {
|
||||
@@ -109,51 +145,10 @@ func PingProfile(ctx context.Context, name string, proto config.Protocol, proxyU
|
||||
|
||||
hy2 := proto == config.ProtocolHysteria2 || hysteria2.Detect(proxyURI)
|
||||
isAWG := proto == config.ProtocolAWG || awg.Detect(proxyURI)
|
||||
isXray := proto == config.ProtocolVLESS || proto == config.ProtocolVMess || proto == config.ProtocolTrojan || xray.Detect(proxyURI)
|
||||
var host, port string
|
||||
if isAWG {
|
||||
h, p, err := awg.HostPort(proxyURI)
|
||||
if err != nil {
|
||||
res.Error = err.Error()
|
||||
return res
|
||||
}
|
||||
host, port = h, p
|
||||
} else if isXray {
|
||||
h, p, err := xray.HostPort(proxyURI)
|
||||
if err != nil {
|
||||
res.Error = err.Error()
|
||||
return res
|
||||
}
|
||||
host, port = h, p
|
||||
} else if hy2 {
|
||||
h, p, err := hysteria2.HostPort(proxyURI)
|
||||
if err != nil {
|
||||
res.Error = err.Error()
|
||||
return res
|
||||
}
|
||||
host, port = h, p
|
||||
} else {
|
||||
normalized, _, _, err := linknorm.Normalize(proto, proxyURI)
|
||||
if err != nil {
|
||||
res.Error = err.Error()
|
||||
return res
|
||||
}
|
||||
rest := normalized
|
||||
if i := strings.Index(rest, "://"); i >= 0 {
|
||||
rest = rest[i+3:]
|
||||
}
|
||||
if at := strings.LastIndex(rest, "@"); at >= 0 {
|
||||
rest = rest[at+1:]
|
||||
}
|
||||
if i := strings.IndexAny(rest, "/?#"); i >= 0 {
|
||||
rest = rest[:i]
|
||||
}
|
||||
host = rest
|
||||
port = "443"
|
||||
if i := strings.LastIndex(rest, ":"); i >= 0 {
|
||||
host = rest[:i]
|
||||
port = rest[i+1:]
|
||||
}
|
||||
host, port, err := HostPort(proto, proxyURI)
|
||||
if err != nil {
|
||||
res.Error = err.Error()
|
||||
return res
|
||||
}
|
||||
|
||||
res.Host = host
|
||||
@@ -164,7 +159,6 @@ func PingProfile(ctx context.Context, name string, proto config.Protocol, proxyU
|
||||
}
|
||||
|
||||
start := time.Now()
|
||||
var err error
|
||||
if hy2 || isAWG {
|
||||
err = probeUDP(ctx, host, port)
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user