diff --git a/adapter/outbound/vless.go b/adapter/outbound/vless.go index 83ce4e57..2456c2c3 100644 --- a/adapter/outbound/vless.go +++ b/adapter/outbound/vless.go @@ -57,6 +57,7 @@ type VlessOption struct { UUID string `proxy:"uuid"` Flow string `proxy:"flow,omitempty"` TLS bool `proxy:"tls,omitempty"` + ALPN []string `proxy:"alpn,omitempty"` UDP bool `proxy:"udp,omitempty"` PacketAddr bool `proxy:"packet-addr,omitempty"` XUDP bool `proxy:"xudp,omitempty"` @@ -211,6 +212,7 @@ func (v *Vless) streamTLSConn(ctx context.Context, conn net.Conn, isH2 bool) (ne FingerPrint: v.option.Fingerprint, ClientFingerprint: v.option.ClientFingerprint, Reality: v.realityConfig, + NextProtos: v.option.ALPN, } if isH2 { diff --git a/adapter/outbound/vmess.go b/adapter/outbound/vmess.go index 8a94c082..7495d8a3 100644 --- a/adapter/outbound/vmess.go +++ b/adapter/outbound/vmess.go @@ -52,6 +52,7 @@ type VmessOption struct { UDP bool `proxy:"udp,omitempty"` Network string `proxy:"network,omitempty"` TLS bool `proxy:"tls,omitempty"` + ALPN []string `proxy:"alpn,omitempty"` SkipCertVerify bool `proxy:"skip-cert-verify,omitempty"` Fingerprint string `proxy:"fingerprint,omitempty"` ServerName string `proxy:"servername,omitempty"` @@ -149,6 +150,7 @@ func (v *Vmess) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.M SkipCertVerify: v.option.SkipCertVerify, ClientFingerprint: v.option.ClientFingerprint, Reality: v.realityConfig, + NextProtos: v.option.ALPN, } if v.option.ServerName != "" { @@ -205,6 +207,7 @@ func (v *Vmess) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.M SkipCertVerify: v.option.SkipCertVerify, ClientFingerprint: v.option.ClientFingerprint, Reality: v.realityConfig, + NextProtos: v.option.ALPN, } if v.option.ServerName != "" { diff --git a/common/buf/sing.go b/common/buf/sing.go index 4585bf74..d204ba11 100644 --- a/common/buf/sing.go +++ b/common/buf/sing.go @@ -14,13 +14,6 @@ var NewSize = buf.NewSize var With = buf.With var As = buf.As -var KeepAlive = common.KeepAlive - -//go:norace -func Dup[T any](obj T) T { - return common.Dup(obj) -} - var ( Must = common.Must Error = common.Error diff --git a/common/convert/converter.go b/common/convert/converter.go index 1f1b086d..ddc5c944 100644 --- a/common/convert/converter.go +++ b/common/convert/converter.go @@ -50,7 +50,9 @@ func ConvertsV2Ray(buf []byte) ([]map[string]any, error) { hysteria["port"] = urlHysteria.Port() hysteria["sni"] = query.Get("peer") hysteria["obfs"] = query.Get("obfs") - hysteria["alpn"] = []string{query.Get("alpn")} + if alpn := query.Get("alpn"); alpn != "" { + hysteria["alpn"] = strings.Split(alpn, ",") + } hysteria["auth_str"] = query.Get("auth") hysteria["protocol"] = query.Get("protocol") up := query.Get("up") @@ -127,10 +129,12 @@ func ConvertsV2Ray(buf []byte) ([]map[string]any, error) { trojan["udp"] = true trojan["skip-cert-verify"], _ = strconv.ParseBool(query.Get("allowInsecure")) - sni := query.Get("sni") - if sni != "" { + if sni := query.Get("sni"); sni != "" { trojan["sni"] = sni } + if alpn := query.Get("alpn"); alpn != "" { + trojan["alpn"] = strings.Split(alpn, ",") + } network := strings.ToLower(query.Get("type")) if network != "" { @@ -258,6 +262,9 @@ func ConvertsV2Ray(buf []byte) ([]map[string]any, error) { if strings.HasSuffix(tls, "tls") { vmess["tls"] = true } + if alpn, ok := values["alpn"].(string); ok { + vmess["alpn"] = strings.Split(alpn, ",") + } } switch network { @@ -373,6 +380,7 @@ func ConvertsV2Ray(buf []byte) ([]map[string]any, error) { } } proxies = append(proxies, ss) + case "ssr": dcBuf, err := encRaw.DecodeString(body) if err != nil { diff --git a/common/convert/v.go b/common/convert/v.go index 23949aab..2d8cf732 100644 --- a/common/convert/v.go +++ b/common/convert/v.go @@ -24,8 +24,6 @@ func handleVShareLink(names map[string]int, url *url.URL, scheme string, proxy m proxy["port"] = url.Port() proxy["uuid"] = url.User.Username() proxy["udp"] = true - proxy["skip-cert-verify"] = false - proxy["tls"] = false tls := strings.ToLower(query.Get("security")) if strings.HasSuffix(tls, "tls") || tls == "reality" { proxy["tls"] = true @@ -34,6 +32,9 @@ func handleVShareLink(names map[string]int, url *url.URL, scheme string, proxy m } else { proxy["client-fingerprint"] = fingerprint } + if alpn := query.Get("alpn"); alpn != "" { + proxy["alpn"] = strings.Split(alpn, ",") + } } if sni := query.Get("sni"); sni != "" { proxy["servername"] = sni diff --git a/transport/gun/utils.go b/transport/gun/utils.go index e5f6e019..e4a66315 100644 --- a/transport/gun/utils.go +++ b/transport/gun/utils.go @@ -1,10 +1,26 @@ package gun func UVarintLen(x uint64) int { - i := 0 - for x >= 0x80 { - x >>= 7 - i++ + switch { + case x < 1<<(7*1): + return 1 + case x < 1<<(7*2): + return 2 + case x < 1<<(7*3): + return 3 + case x < 1<<(7*4): + return 4 + case x < 1<<(7*5): + return 5 + case x < 1<<(7*6): + return 6 + case x < 1<<(7*7): + return 7 + case x < 1<<(7*8): + return 8 + case x < 1<<(7*9): + return 9 + default: + return 10 } - return i + 1 }