fix ipv6 in link and sub #1220

This commit is contained in:
Alireza Ahmadi 2026-08-12 14:58:33 +02:00
parent 1ca4fc80f9
commit 0cefd07d21
5 changed files with 45 additions and 17 deletions

View file

@ -118,10 +118,7 @@ func (s *ClashService) ConvertToClashMeta(outbounds *[]map[string]interface{}, b
proxy["type"] = t
server, _ := obMap["server"].(string)
if len(server) > 0 && strings.Contains(server, ":") && !strings.Contains(server, ".") && !(strings.HasPrefix(server, "[") && strings.HasSuffix(server, "]")) {
server = "'[" + server + "]'"
}
proxy["server"] = server
proxy["server"] = util.NormalizeHost(server)
proxy["port"] = obMap["server_port"]

View file

@ -186,7 +186,8 @@ func (j *JsonService) getOutbounds(clientConfig json.RawMessage, inbounds []*mod
newOut[key] = value
}
// Change and push copied config
newOut["server"], _ = addr["server"].(string)
server, _ := addr["server"].(string)
newOut["server"] = util.NormalizeHost(server)
port, _ := addr["server_port"].(float64)
newOut["server_port"] = int(port)

View file

@ -75,6 +75,12 @@ func LinkGenerator(clientConfig json.RawMessage, i *model.Inbound, hostname stri
}
}
for index := range Addrs {
if server, ok := Addrs[index]["server"].(string); ok {
Addrs[index]["server"] = NormalizeHost(server)
}
}
switch i.Type {
case "socks":
return socksLink(userConfig["socks"], Addrs)
@ -141,7 +147,7 @@ func prepareTls(t *model.Tls) map[string]interface{} {
func socksLink(userConfig map[string]interface{}, addrs []map[string]interface{}) []string {
var links []string
for _, addr := range addrs {
links = append(links, fmt.Sprintf("socks5://%s:%s@%s:%d", userConfig["username"], userConfig["password"], addr["server"].(string), uint(addr["server_port"].(float64))))
links = append(links, fmt.Sprintf("socks5://%s:%s@%s:%d", userConfig["username"], userConfig["password"], HostForURI(addr["server"].(string)), uint(addr["server_port"].(float64))))
}
return links
}
@ -153,7 +159,7 @@ func httpLink(userConfig map[string]interface{}, addrs []map[string]interface{})
if addr["tls"] != nil {
protocol = "https"
}
links = append(links, fmt.Sprintf("%s://%s:%s@%s:%d", protocol, userConfig["username"], userConfig["password"], addr["server"].(string), uint(addr["server_port"].(float64))))
links = append(links, fmt.Sprintf("%s://%s:%s@%s:%d", protocol, userConfig["username"], userConfig["password"], HostForURI(addr["server"].(string)), uint(addr["server_port"].(float64))))
}
return links
}
@ -187,7 +193,7 @@ func shadowsocksLink(
var links []string
for _, addr := range addrs {
port, _ := addr["server_port"].(float64)
link := fmt.Sprintf("%s@%s:%.0f", uriBase, addr["server"].(string), port)
link := fmt.Sprintf("%s@%s:%.0f", uriBase, HostForURI(addr["server"].(string)), port)
if plugin != "" {
pluginVal := plugin
if pluginOpts != "" {
@ -237,7 +243,7 @@ func naiveLink(
}
port, _ := addr["server_port"].(float64)
uri := baseUri + toBase64([]byte(fmt.Sprintf("%s:%s@%s:%.0f", username, password, addr["server"].(string), port)))
uri := baseUri + toBase64([]byte(fmt.Sprintf("%s:%s@%s:%.0f", username, password, HostForURI(addr["server"].(string)), port)))
links = append(links, addParams(uri, params, addr["remark"].(string)))
network, _ := inbound["network"].(string)
@ -252,7 +258,7 @@ func naiveLink(
}
for _, scheme := range schemes {
plainUri := fmt.Sprintf("%s://%s:%s@%s:%.0f", scheme,
url.QueryEscape(username), url.QueryEscape(password), addr["server"].(string), port)
url.QueryEscape(username), url.QueryEscape(password), HostForURI(addr["server"].(string)), port)
links = append(links, addParams(plainUri, params, addr["remark"].(string)))
}
}
@ -302,7 +308,7 @@ func hysteriaLink(
}
port, _ := addr["server_port"].(float64)
uri := fmt.Sprintf("%s%s:%.0f", baseUri, addr["server"].(string), port)
uri := fmt.Sprintf("%s%s:%.0f", baseUri, HostForURI(addr["server"].(string)), port)
links = append(links, addParams(uri, params, addr["remark"].(string)))
}
@ -355,7 +361,7 @@ func hysteria2Link(
}
port, _ := addr["server_port"].(float64)
uri := fmt.Sprintf("%s%s:%.0f", baseUri, addr["server"].(string), port)
uri := fmt.Sprintf("%s%s:%.0f", baseUri, HostForURI(addr["server"].(string)), port)
links = append(links, addParams(uri, params, addr["remark"].(string)))
}
@ -377,7 +383,7 @@ func anytlsLink(
}
port, _ := addr["server_port"].(float64)
uri := fmt.Sprintf("%s%s:%.0f", baseUri, addr["server"].(string), port)
uri := fmt.Sprintf("%s%s:%.0f", baseUri, HostForURI(addr["server"].(string)), port)
links = append(links, addParams(uri, params, addr["remark"].(string)))
}
@ -413,7 +419,7 @@ func tuicLink(
}
port, _ := addr["server_port"].(float64)
uri := fmt.Sprintf("%s%s:%.0f", baseUri, addr["server"].(string), port)
uri := fmt.Sprintf("%s%s:%.0f", baseUri, HostForURI(addr["server"].(string)), port)
links = append(links, addParams(uri, params, addr["remark"].(string)))
}
@ -443,7 +449,7 @@ func vlessLink(
}
}
port, _ := addr["server_port"].(float64)
uri := fmt.Sprintf("vless://%s@%s:%.0f", uuid, addr["server"].(string), port)
uri := fmt.Sprintf("vless://%s@%s:%.0f", uuid, HostForURI(addr["server"].(string)), port)
uri = addParams(uri, params, addr["remark"].(string))
links = append(links, uri)
}
@ -466,7 +472,7 @@ func trojanLink(
getTlsParams(&params, tls, "trojan")
}
port, _ := addr["server_port"].(float64)
uri := fmt.Sprintf("trojan://%s@%s:%.0f", password, addr["server"].(string), port)
uri := fmt.Sprintf("trojan://%s@%s:%.0f", password, HostForURI(addr["server"].(string)), port)
uri = addParams(uri, params, addr["remark"].(string))
links = append(links, uri)
}

24
util/host.go Normal file
View file

@ -0,0 +1,24 @@
package util
import "strings"
// NormalizeHost strips URI brackets from an IPv6 literal ("[::1]" -> "::1").
// Bare hosts, IPv4 addresses and domains are returned unchanged. Config
// formats (sing-box JSON, clash YAML, vmess "add") want the bare form (#1220).
func NormalizeHost(host string) string {
if strings.HasPrefix(host, "[") && strings.HasSuffix(host, "]") {
return host[1 : len(host)-1]
}
return host
}
// HostForURI returns the host formatted for a URI authority: IPv6 literals
// are wrapped in brackets so "host:port" stays parseable, everything else is
// returned unchanged.
func HostForURI(host string) string {
h := NormalizeHost(host)
if strings.Contains(h, ":") {
return "[" + h + "]"
}
return h
}

View file

@ -37,7 +37,7 @@ func FillOutJson(i *model.Inbound, hostname string) error {
outJson["type"] = i.Type
outJson["tag"] = i.Tag
outJson["server"] = hostname
outJson["server"] = NormalizeHost(hostname)
outJson["server_port"] = (*inbound)["listen_port"]
switch i.Type {