From 8ef609ff46cd764138d9427bb97c57fdc28d150f Mon Sep 17 00:00:00 2001 From: yuhan6665 <1588741+yuhan6665@users.noreply.github.com> Date: Sun, 6 Nov 2022 21:50:19 -0500 Subject: [PATCH] Enable UTLS fingerprint for XTLS Vision --- proxy/vless/encoding/encoding.go | 10 +++++----- proxy/vless/inbound/inbound.go | 19 +++++++++++++------ proxy/vless/outbound/outbound.go | 22 ++++++++++++++++------ 3 files changed, 34 insertions(+), 17 deletions(-) diff --git a/proxy/vless/encoding/encoding.go b/proxy/vless/encoding/encoding.go index 79d9c51e..9253ca5c 100644 --- a/proxy/vless/encoding/encoding.go +++ b/proxy/vless/encoding/encoding.go @@ -246,7 +246,7 @@ func ReadV(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, c } // XtlsRead filter and read xtls protocol -func XtlsRead(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, conn *tls.Conn, rawConn syscall.RawConn, counter stats.Counter, ctx context.Context, userUUID []byte, numberOfPacketToFilter *int, isTLS13 *bool, isTLS12 *bool, isTLS *bool) error { +func XtlsRead(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, conn net.Conn, rawConn syscall.RawConn, counter stats.Counter, ctx context.Context, userUUID []byte, numberOfPacketToFilter *int, isTLS13 *bool, isTLS12 *bool, isTLS *bool) error { err := func() error { var ct stats.Counter filterUUID := true @@ -270,7 +270,7 @@ func XtlsRead(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater if tc, ok := iConn.(*net.TCPConn); ok { newError("XtlsRead splice").WriteToLog(session.ExportIDToError(ctx)) runtime.Gosched() // necessary - w, err := tc.ReadFrom(conn.NetConn()) + w, err := tc.ReadFrom(conn) if counter != nil { counter.Add(w) } @@ -285,7 +285,7 @@ func XtlsRead(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater // panic("XTLS Splice: nil inbound or nil inbound.Conn") } } - reader = buf.NewReadVReader(conn.NetConn(), rawConn, nil) + reader = buf.NewReadVReader(conn, rawConn, nil) ct = counter newError("XtlsRead readV").WriteToLog(session.ExportIDToError(ctx)) } @@ -327,7 +327,7 @@ func XtlsRead(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater } // XtlsWrite filter and write xtls protocol -func XtlsWrite(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, conn *tls.Conn, counter stats.Counter, ctx context.Context, userUUID *[]byte, numberOfPacketToFilter *int, isTLS13 *bool, isTLS12 *bool, isTLS *bool) error { +func XtlsWrite(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, conn net.Conn, counter stats.Counter, ctx context.Context, userUUID *[]byte, numberOfPacketToFilter *int, isTLS13 *bool, isTLS12 *bool, isTLS *bool) error { err := func() error { var ct stats.Counter filterTlsApplicationData := true @@ -369,7 +369,7 @@ func XtlsWrite(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdate } } buffer = directBuffer - writer = buf.NewWriter(conn.NetConn()) + writer = buf.NewWriter(conn) ct = counter newError("XtlsWrite writeV ", xtlsSpecIndex, " ", length, " ", buffer.Len()).WriteToLog(session.ExportIDToError(ctx)) time.Sleep(5 * time.Millisecond) // for some device, the first xtls direct packet fails without this delay diff --git a/proxy/vless/inbound/inbound.go b/proxy/vless/inbound/inbound.go index 46c080cc..b791f880 100644 --- a/proxy/vless/inbound/inbound.go +++ b/proxy/vless/inbound/inbound.go @@ -439,6 +439,7 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s // Flow: requestAddons.Flow, } + var netConn net.Conn var rawConn syscall.RawConn switch requestAddons.Flow { @@ -451,11 +452,17 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s return newError(requestAddons.Flow + " doesn't support UDP").AtWarning() case protocol.RequestCommandTCP: if requestAddons.Flow == vless.XRV { - if _, ok := iConn.(*xtls.Conn); ok { + if tlsConn, ok := iConn.(*tls.Conn); ok { + netConn = tlsConn.NetConn() + if sc, ok := netConn.(syscall.Conn); ok { + rawConn, _ = sc.SyscallConn() + } + } else if _, ok := iConn.(*tls.UConn); ok { + return newError("XTLS only supports UTLS fingerprint for the outbound.").AtWarning() + } else if _, ok := iConn.(*xtls.Conn); ok { return newError(`failed to use ` + requestAddons.Flow + `, vision "security" must be "tls"`).AtWarning() - } - if sc, ok := iConn.(*tls.Conn).NetConn().(syscall.Conn); ok { - rawConn, _ = sc.SyscallConn() + } else { + return newError("XTLS only supports TCP, mKCP and DomainSocket for now.").AtWarning() } } else if xtlsConn, ok := iConn.(*xtls.Conn); ok { xtlsConn.RPRX = true @@ -522,7 +529,7 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s //TODO enable splice ctx = session.ContextWithInbound(ctx, nil) if requestAddons.Flow == vless.XRV { - err = encoding.XtlsRead(clientReader, serverWriter, timer, iConn.(*tls.Conn), rawConn, counter, ctx, account.ID.Bytes(), &numberOfPacketToFilter, &isTLS13, &isTLS12, &isTLS) + err = encoding.XtlsRead(clientReader, serverWriter, timer, netConn, rawConn, counter, ctx, account.ID.Bytes(), &numberOfPacketToFilter, &isTLS13, &isTLS12, &isTLS) } else { err = encoding.ReadV(clientReader, serverWriter, timer, iConn.(*xtls.Conn), rawConn, counter, ctx) } @@ -576,7 +583,7 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s if statConn != nil { counter = statConn.WriteCounter } - err = encoding.XtlsWrite(serverReader, clientWriter, timer, iConn.(*tls.Conn), counter, ctx, &userUUID, &numberOfPacketToFilter, &isTLS13, &isTLS12, &isTLS) + err = encoding.XtlsWrite(serverReader, clientWriter, timer, netConn, counter, ctx, &userUUID, &numberOfPacketToFilter, &isTLS13, &isTLS12, &isTLS) } else { // from serverReader.ReadMultiBuffer to clientWriter.WriteMultiBufer err = buf.Copy(serverReader, clientWriter, buf.UpdateActivity(timer)) diff --git a/proxy/vless/outbound/outbound.go b/proxy/vless/outbound/outbound.go index 1e290caf..b090e197 100644 --- a/proxy/vless/outbound/outbound.go +++ b/proxy/vless/outbound/outbound.go @@ -127,6 +127,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte Flow: account.Flow, } + var netConn net.Conn var rawConn syscall.RawConn allowUDP443 := false switch requestAddons.Flow { @@ -145,11 +146,20 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte requestAddons.Flow = "" case protocol.RequestCommandTCP: if requestAddons.Flow == vless.XRV { - if _, ok := iConn.(*xtls.Conn); ok { + if tlsConn, ok := iConn.(*tls.Conn); ok { + netConn = tlsConn.NetConn() + if sc, ok := netConn.(syscall.Conn); ok { + rawConn, _ = sc.SyscallConn() + } + } else if utlsConn, ok := iConn.(*tls.UConn); ok { + netConn = utlsConn.Conn.NetConn() + if sc, ok := netConn.(syscall.Conn); ok { + rawConn, _ = sc.SyscallConn() + } + } else if _, ok := iConn.(*xtls.Conn); ok { return newError(`failed to use ` + requestAddons.Flow + `, vision "security" must be "tls"`).AtWarning() - } - if sc, ok := iConn.(*tls.Conn).NetConn().(syscall.Conn); ok { - rawConn, _ = sc.SyscallConn() + } else { + return newError("XTLS only supports TCP, mKCP and DomainSocket for now.").AtWarning() } } else if xtlsConn, ok := iConn.(*xtls.Conn); ok { xtlsConn.RPRX = true @@ -231,7 +241,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte if statConn != nil { counter = statConn.WriteCounter } - err = encoding.XtlsWrite(clientReader, serverWriter, timer, iConn.(*tls.Conn), counter, ctx, &userUUID, &numberOfPacketToFilter, &isTLS13, &isTLS12, &isTLS) + err = encoding.XtlsWrite(clientReader, serverWriter, timer, netConn, counter, ctx, &userUUID, &numberOfPacketToFilter, &isTLS13, &isTLS12, &isTLS) } else { // from clientReader.ReadMultiBuffer to serverWriter.WriteMultiBufer err = buf.Copy(clientReader, serverWriter, buf.UpdateActivity(timer)) @@ -267,7 +277,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte counter = statConn.ReadCounter } if requestAddons.Flow == vless.XRV { - err = encoding.XtlsRead(serverReader, clientWriter, timer, iConn.(*tls.Conn), rawConn, counter, ctx, account.ID.Bytes(), &numberOfPacketToFilter, &isTLS13, &isTLS12, &isTLS) + err = encoding.XtlsRead(serverReader, clientWriter, timer, netConn, rawConn, counter, ctx, account.ID.Bytes(), &numberOfPacketToFilter, &isTLS13, &isTLS12, &isTLS) } else { err = encoding.ReadV(serverReader, clientWriter, timer, iConn.(*xtls.Conn), rawConn, counter, ctx) }