5
5
"errors"
6
6
"io"
7
7
"net"
8
- "reflect"
9
8
"syscall"
10
9
11
10
"github.com/sagernet/sing/common"
@@ -57,19 +56,21 @@ func Copy(destination io.Writer, source io.Reader) (n int64, err error) {
57
56
}
58
57
59
58
func CopyExtended (originSource io.Reader , destination N.ExtendedWriter , source N.ExtendedReader , readCounters []N.CountFunc , writeCounters []N.CountFunc ) (n int64 , err error ) {
60
- safeSrc := N .IsSafeReader (source )
61
- headroom := N .CalculateFrontHeadroom (destination ) + N .CalculateRearHeadroom (destination )
62
- if safeSrc != nil {
63
- if headroom == 0 {
64
- return CopyExtendedWithSrcBuffer (originSource , destination , safeSrc , readCounters , writeCounters )
65
- }
66
- }
59
+ frontHeadroom := N .CalculateFrontHeadroom (destination )
60
+ rearHeadroom := N .CalculateRearHeadroom (destination )
67
61
readWaiter , isReadWaiter := CreateReadWaiter (source )
68
62
if isReadWaiter {
69
- var handled bool
70
- handled , n , err = copyWaitWithPool (originSource , destination , readWaiter , readCounters , writeCounters )
71
- if handled {
72
- return
63
+ needCopy := readWaiter .InitializeReadWaiter (N.ReadWaitOptions {
64
+ FrontHeadroom : frontHeadroom ,
65
+ RearHeadroom : rearHeadroom ,
66
+ MTU : N .CalculateMTU (source , destination ),
67
+ })
68
+ if ! needCopy || common .LowMemory {
69
+ var handled bool
70
+ handled , n , err = copyWaitWithPool (originSource , destination , readWaiter , readCounters , writeCounters )
71
+ if handled {
72
+ return
73
+ }
73
74
}
74
75
}
75
76
return CopyExtendedWithPool (originSource , destination , source , readCounters , writeCounters )
@@ -113,38 +114,6 @@ func CopyExtendedBuffer(originSource io.Writer, destination N.ExtendedWriter, so
113
114
}
114
115
}
115
116
116
- func CopyExtendedWithSrcBuffer (originSource io.Reader , destination N.ExtendedWriter , source N.ThreadSafeReader , readCounters []N.CountFunc , writeCounters []N.CountFunc ) (n int64 , err error ) {
117
- var notFirstTime bool
118
- for {
119
- var buffer * buf.Buffer
120
- buffer , err = source .ReadBufferThreadSafe ()
121
- if err != nil {
122
- if errors .Is (err , io .EOF ) {
123
- err = nil
124
- return
125
- }
126
- return
127
- }
128
- dataLen := buffer .Len ()
129
- err = destination .WriteBuffer (buffer )
130
- if err != nil {
131
- buffer .Release ()
132
- if ! notFirstTime {
133
- err = N .ReportHandshakeFailure (originSource , err )
134
- }
135
- return
136
- }
137
- n += int64 (dataLen )
138
- for _ , counter := range readCounters {
139
- counter (int64 (dataLen ))
140
- }
141
- for _ , counter := range writeCounters {
142
- counter (int64 (dataLen ))
143
- }
144
- notFirstTime = true
145
- }
146
- }
147
-
148
117
func CopyExtendedWithPool (originSource io.Reader , destination N.ExtendedWriter , source N.ExtendedReader , readCounters []N.CountFunc , writeCounters []N.CountFunc ) (n int64 , err error ) {
149
118
frontHeadroom := N .CalculateFrontHeadroom (destination )
150
119
rearHeadroom := N .CalculateRearHeadroom (destination )
@@ -173,7 +142,7 @@ func CopyExtendedWithPool(originSource io.Reader, destination N.ExtendedWriter,
173
142
buffer .Resize (readBuffer .Start (), dataLen )
174
143
err = destination .WriteBuffer (buffer )
175
144
if err != nil {
176
- buffer .Release ()
145
+ buffer .Leak ()
177
146
if ! notFirstTime {
178
147
err = N .ReportHandshakeFailure (originSource , err )
179
148
}
@@ -256,69 +225,32 @@ func CopyPacket(destinationConn N.PacketWriter, source N.PacketReader) (n int64,
256
225
return
257
226
}
258
227
}
259
- safeSrc := N .IsSafePacketReader (source )
260
228
frontHeadroom := N .CalculateFrontHeadroom (destinationConn )
261
229
rearHeadroom := N .CalculateRearHeadroom (destinationConn )
262
- headroom := frontHeadroom + rearHeadroom
263
- if safeSrc != nil {
264
- if headroom == 0 {
265
- var copyN int64
266
- copyN , err = CopyPacketWithSrcBuffer (originSource , destinationConn , safeSrc , readCounters , writeCounters , n > 0 )
267
- n += copyN
268
- return
269
- }
270
- }
271
230
var (
272
231
handled bool
273
232
copeN int64
274
233
)
275
234
readWaiter , isReadWaiter := CreatePacketReadWaiter (source )
276
235
if isReadWaiter {
277
- handled , copeN , err = copyPacketWaitWithPool (originSource , destinationConn , readWaiter , readCounters , writeCounters , n > 0 )
278
- if handled {
279
- n += copeN
280
- return
236
+ needCopy := readWaiter .InitializeReadWaiter (N.ReadWaitOptions {
237
+ FrontHeadroom : frontHeadroom ,
238
+ RearHeadroom : rearHeadroom ,
239
+ MTU : N .CalculateMTU (source , destinationConn ),
240
+ })
241
+ if ! needCopy || common .LowMemory {
242
+ handled , copeN , err = copyPacketWaitWithPool (originSource , destinationConn , readWaiter , readCounters , writeCounters , n > 0 )
243
+ if handled {
244
+ n += copeN
245
+ return
246
+ }
281
247
}
282
248
}
283
249
copeN , err = CopyPacketWithPool (originSource , destinationConn , source , readCounters , writeCounters , n > 0 )
284
250
n += copeN
285
251
return
286
252
}
287
253
288
- func CopyPacketWithSrcBuffer (originSource N.PacketReader , destinationConn N.PacketWriter , source N.ThreadSafePacketReader , readCounters []N.CountFunc , writeCounters []N.CountFunc , notFirstTime bool ) (n int64 , err error ) {
289
- var buffer * buf.Buffer
290
- var destination M.Socksaddr
291
- for {
292
- buffer , destination , err = source .ReadPacketThreadSafe ()
293
- if err != nil {
294
- return
295
- }
296
- if buffer == nil {
297
- panic ("nil buffer returned from " + reflect .TypeOf (source ).String ())
298
- }
299
- dataLen := buffer .Len ()
300
- if dataLen == 0 {
301
- continue
302
- }
303
- err = destinationConn .WritePacket (buffer , destination )
304
- if err != nil {
305
- buffer .Release ()
306
- if ! notFirstTime {
307
- err = N .ReportHandshakeFailure (originSource , err )
308
- }
309
- return
310
- }
311
- n += int64 (dataLen )
312
- for _ , counter := range readCounters {
313
- counter (int64 (dataLen ))
314
- }
315
- for _ , counter := range writeCounters {
316
- counter (int64 (dataLen ))
317
- }
318
- notFirstTime = true
319
- }
320
- }
321
-
322
254
func CopyPacketWithPool (originSource N.PacketReader , destinationConn N.PacketWriter , source N.PacketReader , readCounters []N.CountFunc , writeCounters []N.CountFunc , notFirstTime bool ) (n int64 , err error ) {
323
255
frontHeadroom := N .CalculateFrontHeadroom (destinationConn )
324
256
rearHeadroom := N .CalculateRearHeadroom (destinationConn )
@@ -343,7 +275,7 @@ func CopyPacketWithPool(originSource N.PacketReader, destinationConn N.PacketWri
343
275
buffer .Resize (readBuffer .Start (), dataLen )
344
276
err = destinationConn .WritePacket (buffer , destination )
345
277
if err != nil {
346
- buffer .Release ()
278
+ buffer .Leak ()
347
279
if ! notFirstTime {
348
280
err = N .ReportHandshakeFailure (originSource , err )
349
281
}
@@ -379,7 +311,7 @@ func WritePacketWithPool(originSource N.PacketReader, destinationConn N.PacketWr
379
311
buffer .Resize (readBuffer .Start (), dataLen )
380
312
err = destinationConn .WritePacket (buffer , packetBuffer .Destination )
381
313
if err != nil {
382
- buffer .Release ()
314
+ buffer .Leak ()
383
315
if ! notFirstTime {
384
316
err = N .ReportHandshakeFailure (originSource , err )
385
317
}
0 commit comments