mirror of
https://github.com/SagerNet/sing.git
synced 2025-04-03 20:07:38 +03:00
89 lines
2 KiB
Go
89 lines
2 KiB
Go
package network
|
|
|
|
import (
|
|
"github.com/sagernet/sing/common/buf"
|
|
M "github.com/sagernet/sing/common/metadata"
|
|
)
|
|
|
|
type ReadWaitable interface {
|
|
InitializeReadWaiter(options ReadWaitOptions) (needCopy bool)
|
|
}
|
|
|
|
type ReadWaitOptions struct {
|
|
FrontHeadroom int
|
|
RearHeadroom int
|
|
MTU int
|
|
}
|
|
|
|
func NewReadWaitOptions(source any, destination any) ReadWaitOptions {
|
|
return ReadWaitOptions{
|
|
FrontHeadroom: CalculateFrontHeadroom(destination),
|
|
RearHeadroom: CalculateRearHeadroom(destination),
|
|
MTU: CalculateMTU(source, destination),
|
|
}
|
|
}
|
|
|
|
func (o ReadWaitOptions) NeedHeadroom() bool {
|
|
return o.FrontHeadroom > 0 || o.RearHeadroom > 0
|
|
}
|
|
|
|
func (o ReadWaitOptions) Copy(buffer *buf.Buffer) *buf.Buffer {
|
|
if o.FrontHeadroom > buffer.Start() ||
|
|
o.RearHeadroom > buffer.FreeLen() {
|
|
newBuffer := o.newBuffer(buf.UDPBufferSize, false)
|
|
newBuffer.Write(buffer.Bytes())
|
|
buffer.Release()
|
|
return newBuffer
|
|
} else {
|
|
return buffer
|
|
}
|
|
}
|
|
|
|
func (o ReadWaitOptions) NewBuffer() *buf.Buffer {
|
|
return o.newBuffer(buf.BufferSize, true)
|
|
}
|
|
|
|
func (o ReadWaitOptions) NewPacketBuffer() *buf.Buffer {
|
|
return o.newBuffer(buf.UDPBufferSize, true)
|
|
}
|
|
|
|
func (o ReadWaitOptions) newBuffer(defaultBufferSize int, reserve bool) *buf.Buffer {
|
|
var bufferSize int
|
|
if o.MTU > 0 {
|
|
bufferSize = o.MTU + o.FrontHeadroom + o.RearHeadroom
|
|
} else {
|
|
bufferSize = defaultBufferSize
|
|
}
|
|
buffer := buf.NewSize(bufferSize)
|
|
if o.FrontHeadroom > 0 {
|
|
buffer.Resize(o.FrontHeadroom, 0)
|
|
}
|
|
if o.RearHeadroom > 0 && reserve {
|
|
buffer.Reserve(o.RearHeadroom)
|
|
}
|
|
return buffer
|
|
}
|
|
|
|
func (o ReadWaitOptions) PostReturn(buffer *buf.Buffer) {
|
|
if o.RearHeadroom > 0 {
|
|
buffer.OverCap(o.RearHeadroom)
|
|
}
|
|
}
|
|
|
|
type ReadWaiter interface {
|
|
ReadWaitable
|
|
WaitReadBuffer() (buffer *buf.Buffer, err error)
|
|
}
|
|
|
|
type ReadWaitCreator interface {
|
|
CreateReadWaiter() (ReadWaiter, bool)
|
|
}
|
|
|
|
type PacketReadWaiter interface {
|
|
ReadWaitable
|
|
WaitReadPacket() (buffer *buf.Buffer, destination M.Socksaddr, err error)
|
|
}
|
|
|
|
type PacketReadWaitCreator interface {
|
|
CreateReadWaiter() (PacketReadWaiter, bool)
|
|
}
|