mirror of
https://github.com/SagerNet/sing.git
synced 2025-04-03 20:07:38 +03:00
90 lines
2.1 KiB
Go
90 lines
2.1 KiB
Go
package bufio
|
|
|
|
import (
|
|
"errors"
|
|
"io"
|
|
"syscall"
|
|
|
|
"github.com/sagernet/sing/common/buf"
|
|
M "github.com/sagernet/sing/common/metadata"
|
|
N "github.com/sagernet/sing/common/network"
|
|
)
|
|
|
|
func copyDirect(source syscall.Conn, destination syscall.Conn, readCounters []N.CountFunc, writeCounters []N.CountFunc) (handed bool, n int64, err error) {
|
|
rawSource, err := source.SyscallConn()
|
|
if err != nil {
|
|
return
|
|
}
|
|
rawDestination, err := destination.SyscallConn()
|
|
if err != nil {
|
|
return
|
|
}
|
|
handed, n, err = splice(rawSource, rawDestination, readCounters, writeCounters)
|
|
return
|
|
}
|
|
|
|
func copyWaitWithPool(originSource io.Reader, destination N.ExtendedWriter, source N.ReadWaiter, readCounters []N.CountFunc, writeCounters []N.CountFunc) (handled bool, n int64, err error) {
|
|
handled = true
|
|
var (
|
|
buffer *buf.Buffer
|
|
notFirstTime bool
|
|
)
|
|
for {
|
|
buffer, err = source.WaitReadBuffer()
|
|
if err != nil {
|
|
if errors.Is(err, io.EOF) {
|
|
err = nil
|
|
return
|
|
}
|
|
return
|
|
}
|
|
dataLen := buffer.Len()
|
|
err = destination.WriteBuffer(buffer)
|
|
if err != nil {
|
|
buffer.Leak()
|
|
if !notFirstTime {
|
|
err = N.ReportHandshakeFailure(originSource, err)
|
|
}
|
|
return
|
|
}
|
|
n += int64(dataLen)
|
|
for _, counter := range readCounters {
|
|
counter(int64(dataLen))
|
|
}
|
|
for _, counter := range writeCounters {
|
|
counter(int64(dataLen))
|
|
}
|
|
notFirstTime = true
|
|
}
|
|
}
|
|
|
|
func copyPacketWaitWithPool(originSource N.PacketReader, destinationConn N.PacketWriter, source N.PacketReadWaiter, readCounters []N.CountFunc, writeCounters []N.CountFunc, notFirstTime bool) (handled bool, n int64, err error) {
|
|
handled = true
|
|
var (
|
|
buffer *buf.Buffer
|
|
destination M.Socksaddr
|
|
)
|
|
for {
|
|
buffer, destination, err = source.WaitReadPacket()
|
|
if err != nil {
|
|
return
|
|
}
|
|
dataLen := buffer.Len()
|
|
err = destinationConn.WritePacket(buffer, destination)
|
|
if err != nil {
|
|
buffer.Leak()
|
|
if !notFirstTime {
|
|
err = N.ReportHandshakeFailure(originSource, err)
|
|
}
|
|
return
|
|
}
|
|
n += int64(dataLen)
|
|
for _, counter := range readCounters {
|
|
counter(int64(dataLen))
|
|
}
|
|
for _, counter := range writeCounters {
|
|
counter(int64(dataLen))
|
|
}
|
|
notFirstTime = true
|
|
}
|
|
}
|