Enable UTLS fingerprint for XTLS Vision

This commit is contained in:
yuhan6665 2022-11-06 21:50:19 -05:00
parent fffd908db2
commit 8ef609ff46
3 changed files with 34 additions and 17 deletions

View File

@ -246,7 +246,7 @@ func ReadV(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, c
} }
// XtlsRead filter and read xtls protocol // 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 { err := func() error {
var ct stats.Counter var ct stats.Counter
filterUUID := true filterUUID := true
@ -270,7 +270,7 @@ func XtlsRead(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater
if tc, ok := iConn.(*net.TCPConn); ok { if tc, ok := iConn.(*net.TCPConn); ok {
newError("XtlsRead splice").WriteToLog(session.ExportIDToError(ctx)) newError("XtlsRead splice").WriteToLog(session.ExportIDToError(ctx))
runtime.Gosched() // necessary runtime.Gosched() // necessary
w, err := tc.ReadFrom(conn.NetConn()) w, err := tc.ReadFrom(conn)
if counter != nil { if counter != nil {
counter.Add(w) 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") // panic("XTLS Splice: nil inbound or nil inbound.Conn")
} }
} }
reader = buf.NewReadVReader(conn.NetConn(), rawConn, nil) reader = buf.NewReadVReader(conn, rawConn, nil)
ct = counter ct = counter
newError("XtlsRead readV").WriteToLog(session.ExportIDToError(ctx)) 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 // 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 { err := func() error {
var ct stats.Counter var ct stats.Counter
filterTlsApplicationData := true filterTlsApplicationData := true
@ -369,7 +369,7 @@ func XtlsWrite(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdate
} }
} }
buffer = directBuffer buffer = directBuffer
writer = buf.NewWriter(conn.NetConn()) writer = buf.NewWriter(conn)
ct = counter ct = counter
newError("XtlsWrite writeV ", xtlsSpecIndex, " ", length, " ", buffer.Len()).WriteToLog(session.ExportIDToError(ctx)) 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 time.Sleep(5 * time.Millisecond) // for some device, the first xtls direct packet fails without this delay

View File

@ -439,6 +439,7 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s
// Flow: requestAddons.Flow, // Flow: requestAddons.Flow,
} }
var netConn net.Conn
var rawConn syscall.RawConn var rawConn syscall.RawConn
switch requestAddons.Flow { switch requestAddons.Flow {
@ -451,12 +452,18 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s
return newError(requestAddons.Flow + " doesn't support UDP").AtWarning() return newError(requestAddons.Flow + " doesn't support UDP").AtWarning()
case protocol.RequestCommandTCP: case protocol.RequestCommandTCP:
if requestAddons.Flow == vless.XRV { if requestAddons.Flow == vless.XRV {
if _, ok := iConn.(*xtls.Conn); ok { if tlsConn, ok := iConn.(*tls.Conn); ok {
return newError(`failed to use ` + requestAddons.Flow + `, vision "security" must be "tls"`).AtWarning() netConn = tlsConn.NetConn()
} if sc, ok := netConn.(syscall.Conn); ok {
if sc, ok := iConn.(*tls.Conn).NetConn().(syscall.Conn); ok {
rawConn, _ = sc.SyscallConn() 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()
} else {
return newError("XTLS only supports TCP, mKCP and DomainSocket for now.").AtWarning()
}
} else if xtlsConn, ok := iConn.(*xtls.Conn); ok { } else if xtlsConn, ok := iConn.(*xtls.Conn); ok {
xtlsConn.RPRX = true xtlsConn.RPRX = true
xtlsConn.SHOW = xtls_show xtlsConn.SHOW = xtls_show
@ -522,7 +529,7 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s
//TODO enable splice //TODO enable splice
ctx = session.ContextWithInbound(ctx, nil) ctx = session.ContextWithInbound(ctx, nil)
if requestAddons.Flow == vless.XRV { 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 { } else {
err = encoding.ReadV(clientReader, serverWriter, timer, iConn.(*xtls.Conn), rawConn, counter, ctx) 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 { if statConn != nil {
counter = statConn.WriteCounter 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 { } else {
// from serverReader.ReadMultiBuffer to clientWriter.WriteMultiBufer // from serverReader.ReadMultiBuffer to clientWriter.WriteMultiBufer
err = buf.Copy(serverReader, clientWriter, buf.UpdateActivity(timer)) err = buf.Copy(serverReader, clientWriter, buf.UpdateActivity(timer))

View File

@ -127,6 +127,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
Flow: account.Flow, Flow: account.Flow,
} }
var netConn net.Conn
var rawConn syscall.RawConn var rawConn syscall.RawConn
allowUDP443 := false allowUDP443 := false
switch requestAddons.Flow { switch requestAddons.Flow {
@ -145,12 +146,21 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
requestAddons.Flow = "" requestAddons.Flow = ""
case protocol.RequestCommandTCP: case protocol.RequestCommandTCP:
if requestAddons.Flow == vless.XRV { if requestAddons.Flow == vless.XRV {
if _, ok := iConn.(*xtls.Conn); ok { if tlsConn, ok := iConn.(*tls.Conn); ok {
return newError(`failed to use ` + requestAddons.Flow + `, vision "security" must be "tls"`).AtWarning() netConn = tlsConn.NetConn()
} if sc, ok := netConn.(syscall.Conn); ok {
if sc, ok := iConn.(*tls.Conn).NetConn().(syscall.Conn); ok {
rawConn, _ = sc.SyscallConn() 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()
} else {
return newError("XTLS only supports TCP, mKCP and DomainSocket for now.").AtWarning()
}
} else if xtlsConn, ok := iConn.(*xtls.Conn); ok { } else if xtlsConn, ok := iConn.(*xtls.Conn); ok {
xtlsConn.RPRX = true xtlsConn.RPRX = true
xtlsConn.SHOW = xtls_show xtlsConn.SHOW = xtls_show
@ -231,7 +241,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
if statConn != nil { if statConn != nil {
counter = statConn.WriteCounter 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 { } else {
// from clientReader.ReadMultiBuffer to serverWriter.WriteMultiBufer // from clientReader.ReadMultiBuffer to serverWriter.WriteMultiBufer
err = buf.Copy(clientReader, serverWriter, buf.UpdateActivity(timer)) 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 counter = statConn.ReadCounter
} }
if requestAddons.Flow == vless.XRV { 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 { } else {
err = encoding.ReadV(serverReader, clientWriter, timer, iConn.(*xtls.Conn), rawConn, counter, ctx) err = encoding.ReadV(serverReader, clientWriter, timer, iConn.(*xtls.Conn), rawConn, counter, ctx)
} }