Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/MHSanaei/3x-ui.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'sub/subService.go')
-rw-r--r--sub/subService.go52
1 files changed, 49 insertions, 3 deletions
diff --git a/sub/subService.go b/sub/subService.go
index bf9c029c..dd6bbcc9 100644
--- a/sub/subService.go
+++ b/sub/subService.go
@@ -906,7 +906,6 @@ func (s *SubService) genShadowsocksLink(inbound *model.Inbound, email string) st
}
func (s *SubService) genHysteriaLink(inbound *model.Inbound, email string) string {
- address := s.address
if inbound.Protocol != model.Hysteria {
return ""
}
@@ -921,7 +920,6 @@ func (s *SubService) genHysteriaLink(inbound *model.Inbound, email string) strin
}
}
auth := clients[clientIndex].Auth
- port := inbound.Port
params := make(map[string]string)
params["security"] = "tls"
@@ -950,6 +948,26 @@ func (s *SubService) genHysteriaLink(inbound *model.Inbound, email string) strin
}
}
+ // salamander obfs (Hysteria2). The panel-side link generator already
+ // emits these; keep the subscription output in sync so a client has
+ // the obfs password to match the server.
+ if finalmask, ok := stream["finalmask"].(map[string]interface{}); ok {
+ if udpMasks, ok := finalmask["udp"].([]interface{}); ok {
+ for _, m := range udpMasks {
+ mask, _ := m.(map[string]interface{})
+ if mask == nil || mask["type"] != "salamander" {
+ continue
+ }
+ settings, _ := mask["settings"].(map[string]interface{})
+ if pw, ok := settings["password"].(string); ok && pw != "" {
+ params["obfs"] = "salamander"
+ params["obfs-password"] = pw
+ break
+ }
+ }
+ }
+ }
+
var settings map[string]interface{}
json.Unmarshal([]byte(inbound.Settings), &settings)
version, _ := settings["version"].(float64)
@@ -958,7 +976,35 @@ func (s *SubService) genHysteriaLink(inbound *model.Inbound, email string) strin
protocol = "hysteria"
}
- link := fmt.Sprintf("%s://%s@%s:%d", protocol, auth, address, port)
+ // Fan out one link per External Proxy entry if any. Previously this
+ // generator ignored `externalProxy` entirely, so the link kept the
+ // server's own IP/port even when the admin configured an alternate
+ // endpoint (e.g. a CDN hostname + port that forwards to the node).
+ // Matches the behaviour of genVlessLink / genTrojanLink / ….
+ externalProxies, _ := stream["externalProxy"].([]interface{})
+ if len(externalProxies) > 0 {
+ links := make([]string, 0, len(externalProxies))
+ for _, externalProxy := range externalProxies {
+ ep, _ := externalProxy.(map[string]interface{})
+ dest, _ := ep["dest"].(string)
+ epPort := int(ep["port"].(float64))
+ epRemark, _ := ep["remark"].(string)
+
+ link := fmt.Sprintf("%s://%s@%s:%d", protocol, auth, dest, epPort)
+ u, _ := url.Parse(link)
+ q := u.Query()
+ for k, v := range params {
+ q.Add(k, v)
+ }
+ u.RawQuery = q.Encode()
+ u.Fragment = s.genRemark(inbound, email, epRemark)
+ links = append(links, u.String())
+ }
+ return strings.Join(links, "\n")
+ }
+
+ // No external proxy configured — fall back to the request host.
+ link := fmt.Sprintf("%s://%s@%s:%d", protocol, auth, s.address, inbound.Port)
url, _ := url.Parse(link)
q := url.Query()
for k, v := range params {