Refactor Vision reader writer

- Vision now use traffic states to capture two-way info about a connection
- XTLS is de-couple with Vision, it only read traffic states to switch to direct copy mode
- fix a edge case error when Vision unpadding read 5 command bytes
This commit is contained in:
yuhan6665 2023-09-02 11:37:50 -04:00
parent efd32b0fb2
commit d6d225c698
5 changed files with 440 additions and 374 deletions

View file

@ -22,6 +22,7 @@ import (
"github.com/xtls/xray-core/common/xudp"
"github.com/xtls/xray-core/core"
"github.com/xtls/xray-core/features/policy"
"github.com/xtls/xray-core/proxy"
"github.com/xtls/xray-core/proxy/vless"
"github.com/xtls/xray-core/proxy/vless/encoding"
"github.com/xtls/xray-core/transport"
@ -183,13 +184,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
clientReader := link.Reader // .(*pipe.Reader)
clientWriter := link.Writer // .(*pipe.Writer)
enableXtls := false
isTLS12orAbove := false
isTLS := false
var cipher uint16 = 0
var remainingServerHello int32 = -1
numberOfPacketToFilter := 8
trafficState := proxy.NewTrafficState(account.ID.Bytes())
if request.Command == protocol.RequestCommandUDP && h.cone && request.Port != 53 && request.Port != 443 {
request.Command = protocol.RequestCommandMux
request.Address = net.DomainAddress("v1.mux.cool")
@ -205,22 +200,14 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
}
// default: serverWriter := bufferWriter
serverWriter := encoding.EncodeBodyAddons(bufferWriter, request, requestAddons)
serverWriter := encoding.EncodeBodyAddons(bufferWriter, request, requestAddons, trafficState, ctx)
if request.Command == protocol.RequestCommandMux && request.Port == 666 {
serverWriter = xudp.NewPacketWriter(serverWriter, target, xudp.GetGlobalID(ctx))
}
userUUID := account.ID.Bytes()
timeoutReader, ok := clientReader.(buf.TimeoutReader)
if ok {
multiBuffer, err1 := timeoutReader.ReadMultiBufferTimeout(time.Millisecond * 500)
if err1 == nil {
if requestAddons.Flow == vless.XRV {
encoding.XtlsFilterTls(multiBuffer, &numberOfPacketToFilter, &enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello, ctx)
multiBuffer = encoding.ReshapeMultiBuffer(ctx, multiBuffer)
for i, b := range multiBuffer {
multiBuffer[i] = encoding.XtlsPadding(b, encoding.CommandPaddingContinue, &userUUID, isTLS, ctx)
}
}
if err := serverWriter.WriteMultiBuffer(multiBuffer); err != nil {
return err // ...
}
@ -228,10 +215,9 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
return err1
} else if requestAddons.Flow == vless.XRV {
mb := make(buf.MultiBuffer, 1)
mb[0] = encoding.XtlsPadding(nil, encoding.CommandPaddingContinue, &userUUID, true, ctx) // we do a long padding to hide vless header
newError("Insert padding with empty content to camouflage VLESS header ", mb.Len()).WriteToLog(session.ExportIDToError(ctx))
if err := serverWriter.WriteMultiBuffer(mb); err != nil {
return err
return err // ...
}
}
} else {
@ -254,8 +240,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
}
}
ctx1 := session.ContextWithOutbound(ctx, nil) // TODO enable splice
err = encoding.XtlsWrite(clientReader, serverWriter, timer, conn, ctx1, &numberOfPacketToFilter,
&enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello)
err = encoding.XtlsWrite(clientReader, serverWriter, timer, conn, trafficState, ctx1)
} else {
// from clientReader.ReadMultiBuffer to serverWriter.WriteMultiBufer
err = buf.Copy(clientReader, serverWriter, buf.UpdateActivity(timer))
@ -286,8 +271,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
}
if requestAddons.Flow == vless.XRV {
err = encoding.XtlsRead(serverReader, clientWriter, timer, conn, input, rawInput, ctx, account.ID.Bytes(),
&numberOfPacketToFilter, &enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello)
err = encoding.XtlsRead(serverReader, clientWriter, timer, conn, input, rawInput, trafficState, ctx)
} else {
// from serverReader.ReadMultiBuffer to clientWriter.WriteMultiBufer
err = buf.Copy(serverReader, clientWriter, buf.UpdateActivity(timer))