From f13ac3cb55a1f1b4d8a13462bb197dad5eeb2e59 Mon Sep 17 00:00:00 2001 From: RPRX <63339210+rprx@users.noreply.github.com> Date: Thu, 14 Jan 2021 21:55:52 +0000 Subject: [PATCH] Fix VLESS fallbacks SNI shunt --- proxy/vless/inbound/inbound.go | 94 ++++++++++++++++++++++------------ 1 file changed, 60 insertions(+), 34 deletions(-) diff --git a/proxy/vless/inbound/inbound.go b/proxy/vless/inbound/inbound.go index 59de471e..0cd0815a 100644 --- a/proxy/vless/inbound/inbound.go +++ b/proxy/vless/inbound/inbound.go @@ -109,12 +109,30 @@ func New(ctx context.Context, config *Config, dc dns.Client) (*Handler, error) { } */ } + for _, apfb := range handler.fallbacks { + if apfb[""] != nil { + for alpn, pfb := range apfb { + if alpn != "" { // && alpn != "h2" { + for path, fb := range apfb[""] { + if pfb[path] == nil { + pfb[path] = fb + } + } + } + } + } + } if handler.fallbacks[""] != nil { - for alpn, pfb := range handler.fallbacks { - if alpn != "" { // && alpn != "h2" { - for path, fb := range handler.fallbacks[""] { - if pfb[path] == nil { - pfb[path] = fb + for name, apfb := range handler.fallbacks { + if name != "" { + for alpn, pfb := range handler.fallbacks[""] { + if apfb[alpn] == nil { + apfb[alpn] = make(map[string]*Fallback) + } + for path, fb := range pfb { + if apfb[alpn][path] == nil { + apfb[alpn][path] = fb + } } } } @@ -175,8 +193,8 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection i var requestAddons *encoding.Addons var err error - apfb := h.fallbacks - isfb := apfb != nil + napfb := h.fallbacks + isfb := napfb != nil if isfb && firstLen < 18 { err = newError("fallback directly") @@ -193,36 +211,44 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection i name := "" alpn := "" - if len(apfb) > 1 || apfb[""] == nil { - if tlsConn, ok := iConn.(*tls.Conn); ok { - name = tlsConn.ConnectionState().ServerName - alpn = tlsConn.ConnectionState().NegotiatedProtocol - newError("realServerName = " + name).AtInfo().WriteToLog(sid) - newError("realAlpn = " + alpn).AtInfo().WriteToLog(sid) - } else if xtlsConn, ok := iConn.(*xtls.Conn); ok { - name = xtlsConn.ConnectionState().ServerName - alpn = xtlsConn.ConnectionState().NegotiatedProtocol - newError("realServerName = " + name).AtInfo().WriteToLog(sid) - newError("realAlpn = " + alpn).AtInfo().WriteToLog(sid) - } - labels := strings.Split(name, ".") - for i := range labels { - labels[i] = "*" - candidate := strings.Join(labels, ".") - if apfb[candidate] != nil { - name = candidate - break + if tlsConn, ok := iConn.(*tls.Conn); ok { + cs := tlsConn.ConnectionState() + name = cs.ServerName + alpn = cs.NegotiatedProtocol + newError("realName = " + name).AtInfo().WriteToLog(sid) + newError("realAlpn = " + alpn).AtInfo().WriteToLog(sid) + } else if xtlsConn, ok := iConn.(*xtls.Conn); ok { + cs := xtlsConn.ConnectionState() + name = cs.ServerName + alpn = cs.NegotiatedProtocol + newError("realName = " + name).AtInfo().WriteToLog(sid) + newError("realAlpn = " + alpn).AtInfo().WriteToLog(sid) + } + + if len(napfb) > 1 || napfb[""] == nil { + if napfb[name] == nil { + generic := "*" + if index := strings.IndexByte(name, '.'); index != -1 { + generic += name[index:] + } + if napfb[generic] != nil { + name = generic } } - if apfb[name] == nil { - name = "" - } - if apfb[name][alpn] == nil { - alpn = "" - } - } - pfb := apfb[name][alpn] + + if napfb[name] == nil { + name = "" + } + apfb := napfb[name] + if apfb == nil { + return newError(`failed to find the default "name" config`).AtWarning() + } + + if apfb[alpn] == nil { + alpn = "" + } + pfb := apfb[alpn] if pfb == nil { return newError(`failed to find the default "alpn" config`).AtWarning() }