support anytls link #611

This commit is contained in:
Alireza Ahmadi
2025-05-30 22:46:59 +02:00
parent 596dc8a884
commit a5f4c46066
2 changed files with 75 additions and 1 deletions
+37 -1
View File
@@ -10,7 +10,7 @@ import (
"strings" "strings"
) )
var InboundTypeWithLink = []string{"shadowsocks", "naive", "hysteria", "hysteria2", "tuic", "vless", "trojan", "vmess"} var InboundTypeWithLink = []string{"shadowsocks", "naive", "hysteria", "hysteria2", "anytls", "tuic", "vless", "trojan", "vmess"}
func LinkGenerator(clientConfig json.RawMessage, i *model.Inbound, hostname string) []string { func LinkGenerator(clientConfig json.RawMessage, i *model.Inbound, hostname string) []string {
inbound, err := i.MarshalFull() inbound, err := i.MarshalFull()
@@ -73,6 +73,8 @@ func LinkGenerator(clientConfig json.RawMessage, i *model.Inbound, hostname stri
return tuicLink(userConfig["tuic"], *inbound, Addrs) return tuicLink(userConfig["tuic"], *inbound, Addrs)
case "vless": case "vless":
return vlessLink(userConfig["vless"], *inbound, Addrs) return vlessLink(userConfig["vless"], *inbound, Addrs)
case "anytls":
return anytlsLink(userConfig["anytls"], Addrs)
case "trojan": case "trojan":
return trojanLink(userConfig["trojan"], *inbound, Addrs) return trojanLink(userConfig["trojan"], *inbound, Addrs)
case "vmess": case "vmess":
@@ -280,6 +282,40 @@ func hysteria2Link(
return links return links
} }
func anytlsLink(
userConfig map[string]interface{},
addrs []map[string]interface{}) []string {
password, _ := userConfig["password"].(string)
baseUri := fmt.Sprintf("%s%s@", "anytls://", password)
var links []string
for _, addr := range addrs {
params := map[string]string{}
if tls, ok := addr["tls"].(map[string]interface{}); ok {
if sni, ok := tls["server_name"].(string); ok {
params["sni"] = sni
}
if alpn, ok := tls["alpn"].([]interface{}); ok {
alpnList := make([]string, len(alpn))
for i, v := range alpn {
alpnList[i] = v.(string)
}
params["alpn"] = strings.Join(alpnList, ",")
}
if insecure, ok := tls["insecure"].(bool); ok && insecure {
params["insecure"] = "1"
}
}
port, _ := addr["server_port"].(float64)
uri := fmt.Sprintf("%s%s:%d", baseUri, addr["server"].(string), uint(port))
links = append(links, addParams(uri, params, addr["remark"].(string)))
}
return links
}
func tuicLink( func tuicLink(
userConfig map[string]interface{}, userConfig map[string]interface{},
inbound map[string]interface{}, inbound map[string]interface{},
+38
View File
@@ -24,6 +24,8 @@ func GetOutbound(uri string, i int) (*map[string]interface{}, string, error) {
return hy(u, i) return hy(u, i)
case "hy2", "hysteria2": case "hy2", "hysteria2":
return hy2(u, i) return hy2(u, i)
case "anytls":
return anytls(u, i)
case "tuic": case "tuic":
return tuic(u, i) return tuic(u, i)
case "ss", "shadowsocks": case "ss", "shadowsocks":
@@ -293,6 +295,42 @@ func hy2(u *url.URL, i int) (*map[string]interface{}, string, error) {
return &hy2, tag, nil return &hy2, tag, nil
} }
func anytls(u *url.URL, i int) (*map[string]interface{}, string, error) {
query, _ := url.ParseQuery(u.RawQuery)
host, portStr, _ := net.SplitHostPort(u.Host)
port := 443
if len(portStr) > 0 {
port, _ = strconv.Atoi(portStr)
}
tls := map[string]interface{}{
"enabled": true,
"server_name": query.Get("sni"),
}
alpn := query.Get("alpn")
insecure := query.Get("insecure")
if len(alpn) > 0 {
tls["alpn"] = strings.Split(alpn, ",")
}
if insecure == "1" || insecure == "true" {
tls["insecure"] = true
}
tag := u.Fragment
if i > 0 {
tag = fmt.Sprintf("%d.%s", i, u.Fragment)
}
anytls := map[string]interface{}{
"type": "anytls",
"tag": tag,
"server": host,
"server_port": port,
"password": u.User.Username(),
"tls": tls,
}
return &anytls, tag, nil
}
func tuic(u *url.URL, i int) (*map[string]interface{}, string, error) { func tuic(u *url.URL, i int) (*map[string]interface{}, string, error) {
query, _ := url.ParseQuery(u.RawQuery) query, _ := url.ParseQuery(u.RawQuery)
host, portStr, _ := net.SplitHostPort(u.Host) host, portStr, _ := net.SplitHostPort(u.Host)