Skip to content

Commit cdf5e0c

Browse files
committed
chore: rewrite vision client write
1 parent 48f3ea8 commit cdf5e0c

File tree

4 files changed

+40
-51
lines changed

4 files changed

+40
-51
lines changed

common/buf/sing.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ var NewPacket = buf.NewPacket
1414
var NewSize = buf.NewSize
1515
var With = buf.With
1616
var As = buf.As
17+
var ReleaseMulti = buf.ReleaseMulti
1718

1819
var (
1920
Must = common.Must

common/net/sing.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ type ExtendedReader = network.ExtendedReader
2222

2323
var WriteBuffer = bufio.WriteBuffer
2424

25+
type ReadWaitOptions = network.ReadWaitOptions
26+
27+
var NewReadWaitOptions = network.NewReadWaitOptions
28+
2529
func NewDeadlineConn(conn net.Conn) ExtendedConn {
2630
if deadline.IsPipe(conn) || deadline.IsPipe(network.UnwrapReader(conn)) {
2731
return NewExtendedConn(conn) // pipe always have correctly deadline implement

transport/vless/vision/conn.go

Lines changed: 27 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ func (vc *Conn) WriteBuffer(buffer *buf.Buffer) (err error) {
170170
if vc.needHandshake {
171171
vc.needHandshake = false
172172
if buffer.IsEmpty() {
173-
ApplyPadding(buffer, commandPaddingContinue, vc.userUUID, false)
173+
ApplyPadding(buffer, commandPaddingContinue, vc.userUUID, true) // we do a long padding to hide vless header
174174
} else {
175175
vc.FilterTLS(buffer.Bytes())
176176
ApplyPadding(buffer, commandPaddingContinue, vc.userUUID, vc.isTLS)
@@ -190,55 +190,37 @@ func (vc *Conn) WriteBuffer(buffer *buf.Buffer) (err error) {
190190
}
191191

192192
if vc.writeFilterApplicationData {
193-
buffer2 := ReshapeBuffer(buffer)
194-
defer buffer2.Release()
195193
vc.FilterTLS(buffer.Bytes())
196-
command := commandPaddingContinue
197-
if !vc.isTLS {
198-
command = commandPaddingEnd
199-
200-
// disable XTLS
201-
//vc.readProcess = false
202-
vc.writeFilterApplicationData = false
203-
vc.packetsToFilter = 0
204-
} else if buffer.Len() > 6 && bytes.Equal(buffer.To(3), tlsApplicationDataStart) || vc.packetsToFilter <= 0 {
205-
command = commandPaddingEnd
206-
if vc.enableXTLS {
207-
command = commandPaddingDirect
208-
vc.writeDirect = true
209-
}
210-
vc.writeFilterApplicationData = false
211-
}
212-
ApplyPadding(buffer, command, nil, vc.isTLS)
213-
err = vc.ExtendedWriter.WriteBuffer(buffer)
214-
if err != nil {
215-
return err
216-
}
217-
if vc.writeDirect {
218-
vc.ExtendedWriter = N.NewExtendedWriter(vc.netConn)
219-
log.Debugln("XTLS Vision direct write start")
220-
//time.Sleep(5 * time.Millisecond)
221-
}
222-
if buffer2 != nil {
223-
if vc.writeDirect || !vc.isTLS {
224-
return vc.ExtendedWriter.WriteBuffer(buffer2)
225-
}
226-
vc.FilterTLS(buffer2.Bytes())
227-
command = commandPaddingContinue
228-
if buffer2.Len() > 6 && bytes.Equal(buffer2.To(3), tlsApplicationDataStart) || vc.packetsToFilter <= 0 {
229-
command = commandPaddingEnd
230-
if vc.enableXTLS {
231-
command = commandPaddingDirect
232-
vc.writeDirect = true
194+
buffers := vc.ReshapeBuffer(buffer)
195+
applyPadding := true
196+
for i, buffer := range buffers {
197+
command := commandPaddingContinue
198+
if applyPadding {
199+
if vc.isTLS && buffer.Len() > 6 && bytes.Equal(buffer.To(3), tlsApplicationDataStart) {
200+
command = commandPaddingEnd
201+
if vc.enableXTLS {
202+
command = commandPaddingDirect
203+
vc.writeDirect = true
204+
}
205+
vc.writeFilterApplicationData = false
206+
applyPadding = false
207+
} else if !vc.isTLS12orAbove && vc.packetsToFilter <= 1 {
208+
command = commandPaddingEnd
209+
vc.writeFilterApplicationData = false
210+
applyPadding = false
233211
}
234-
vc.writeFilterApplicationData = false
212+
ApplyPadding(buffer, command, nil, vc.isTLS)
213+
}
214+
215+
err = vc.ExtendedWriter.WriteBuffer(buffer)
216+
if err != nil {
217+
buf.ReleaseMulti(buffers[i:]) // release unwritten buffers
218+
return
235219
}
236-
ApplyPadding(buffer2, command, nil, vc.isTLS)
237-
err = vc.ExtendedWriter.WriteBuffer(buffer2)
238-
if vc.writeDirect {
220+
if command == commandPaddingDirect {
239221
vc.ExtendedWriter = N.NewExtendedWriter(vc.netConn)
240222
log.Debugln("XTLS Vision direct write start")
241-
//time.Sleep(10 * time.Millisecond)
223+
//time.Sleep(5 * time.Millisecond)
242224
}
243225
}
244226
return err

transport/vless/vision/padding.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66

77
"github.com/metacubex/mihomo/common/buf"
88
"github.com/metacubex/mihomo/log"
9+
N "github.com/metacubex/sing/common/network"
910

1011
"github.com/gofrs/uuid/v5"
1112
"github.com/metacubex/randv2"
@@ -42,16 +43,17 @@ func ApplyPadding(buffer *buf.Buffer, command byte, userUUID *uuid.UUID, padding
4243
log.Debugln("XTLS Vision write padding: command=%d, payloadLen=%d, paddingLen=%d", command, contentLen, paddingLen)
4344
}
4445

45-
func ReshapeBuffer(buffer *buf.Buffer) *buf.Buffer {
46-
if buffer.Len() <= buf.BufferSize-PaddingHeaderLen {
47-
return nil
46+
func (vc *Conn) ReshapeBuffer(buffer *buf.Buffer) []*buf.Buffer {
47+
const xrayBufSize = 8192
48+
if buffer.Len() <= xrayBufSize-PaddingHeaderLen {
49+
return []*buf.Buffer{buffer}
4850
}
4951
cutAt := bytes.LastIndex(buffer.Bytes(), tlsApplicationDataStart)
5052
if cutAt == -1 {
51-
cutAt = buf.BufferSize / 2
53+
cutAt = xrayBufSize / 2
5254
}
53-
buffer2 := buf.New()
55+
buffer2 := N.NewReadWaitOptions(nil, vc).NewBuffer() // ensure the new buffer can send used in vc.WriteBuffer
5456
buffer2.Write(buffer.From(cutAt))
5557
buffer.Truncate(cutAt)
56-
return buffer2
58+
return []*buf.Buffer{buffer, buffer2}
5759
}

0 commit comments

Comments
 (0)