protocol

package
v1.1.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 3, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Index

Constants

View Source
const (
	SmallBufferSize  = 256         // For heartbeats, errors
	MediumBufferSize = 4096        // For typical messages
	LargeBufferSize  = 65536       // For large payloads
	CopyBufferSize   = 512 * 1024  // 512KB for data copy operations
	MaxPooledBuffer  = 1024 * 1024 // 1MB - don't pool larger buffers
)

Buffer size constants for common message types

View Source
const (
	MsgTypeRegister    = 0x01 // Client registration
	MsgTypeRegisterAck = 0x02 // Server acknowledgment
	MsgTypeHeartbeat   = 0x03 // Keepalive
	MsgTypeNewConn     = 0x04 // New connection metadata
	MsgTypeConnClose   = 0x06 // Connection closed
	MsgTypeError       = 0xFF // Error message
)

Message types

View Source
const (
	// DefaultDatagramBufferSize is the default size for QUIC datagram buffers
	DefaultDatagramBufferSize = MaxDatagramSize // 1200 bytes

	// DefaultReadBufferSize is the default size for UDP read buffers
	DefaultReadBufferSize = 65535

	// DefaultFragmentBufferSize is the default size for fragment storage
	// Calculated as: DatagramSize - FragmentHeaderSize (9 bytes)
	DefaultFragmentBufferSize = DefaultDatagramBufferSize - UDPFragHeaderSize
)

Default UDP buffer size constants

View Source
const (
	UDPHeaderSize     = 4                                   // Session ID only (for unfragmented packets)
	UDPFragHeaderSize = 9                                   // Full fragment header
	MaxDatagramSize   = 1200                                // Safe QUIC datagram payload size
	MaxUDPPayload     = MaxDatagramSize - UDPHeaderSize     // Max payload for unfragmented
	MaxFragPayload    = MaxDatagramSize - UDPFragHeaderSize // Max payload per fragment
	FragmentTimeout   = 5 * time.Second                     // Timeout for incomplete fragments

	// DefaultShardCount is the default number of shards for the fragment assembler
	DefaultShardCount = 16
)

UDP fragment header format: [4 bytes session ID][2 bytes fragment ID][1 byte flags][1 byte fragment index][1 byte total fragments][payload] Flags: 0x01 = more fragments follow

View Source
const (
	FlagMoreFragments = 0x01
	FlagFragmented    = 0x80 // Indicates this is a fragmented packet
)
View Source
const ProtocolVersion = "1.0"

Variables

View Source
var (
	DatagramBufferSize = DefaultDatagramBufferSize
	ReadBufferSize     = DefaultReadBufferSize
	FragmentBufferSize = DefaultFragmentBufferSize
)

Current buffer sizes (can be configured via InitBufferPool)

View Source
var (
	ErrPacketTooLarge        = errors.New("packet too large to fragment")
	ErrSessionIDMismatch     = errors.New("session ID mismatch")
	ErrInvalidFragIndex      = errors.New("invalid fragment index")
	ErrDatagramTooShort      = errors.New("datagram too short")
	ErrFragmentationDisabled = errors.New("fragmentation disabled, packet too large")
)

Functions

func CopyBuffered added in v1.0.5

func CopyBuffered(dst io.Writer, src io.Reader) (int64, error)

CopyBuffered copies from src to dst using a pooled 512KB buffer for better throughput. Returns the number of bytes copied and any error encountered.

func DecodeMessage

func DecodeMessage(payload []byte, msg interface{}) error

DecodeMessage decodes a payload into a message structure

func FragmentUDP added in v1.0.5

func FragmentUDP(sessionID uint32, data []byte, fragIDCounter *uint16, enableFragmentation bool) ([][]byte, error)

FragmentUDP splits a UDP packet into fragments if needed Returns a slice of datagrams ready to send If enableFragmentation is false and packet is too large, returns error

func GetBuffer

func GetBuffer() *bytes.Buffer

GetBuffer retrieves a buffer from the pool. The buffer is reset and ready for use.

func GetBufferWithSize

func GetBufferWithSize(sizeHint int) *bytes.Buffer

GetBufferWithSize retrieves a buffer from the pool and grows it to the specified size hint. This helps reduce reallocations when the approximate size is known.

func GetCopyBuffer added in v1.0.5

func GetCopyBuffer() *[]byte

GetCopyBuffer retrieves a copy buffer from the pool.

func GetDatagramBuffer added in v1.0.5

func GetDatagramBuffer() *[]byte

GetDatagramBuffer returns a buffer for datagram operations. The returned buffer has a length of exactly DatagramBufferSize. Callers must call PutDatagramBuffer when done to return the buffer to the pool.

func GetFragmentBuffer added in v1.0.5

func GetFragmentBuffer() *[]byte

GetFragmentBuffer returns a buffer for fragment storage. The returned buffer has a length of exactly FragmentBufferSize. Callers must call PutFragmentBuffer when done to return the buffer to the pool.

func GetReadBuffer added in v1.0.5

func GetReadBuffer() *[]byte

GetReadBuffer returns a buffer for UDP read operations. The returned buffer has a length of exactly ReadBufferSize. Callers must call PutReadBuffer when done to return the buffer to the pool.

func InitBufferPool added in v1.0.7

func InitBufferPool(datagramSize, readSize, fragmentSize int)

InitBufferPool initializes the buffer pool with custom sizes. This should be called once at startup before any buffer operations. If any size is <= 0, the default value will be used.

func ParseUDPDatagram added in v1.0.5

func ParseUDPDatagram(dgram []byte) (uint32, bool, uint16, uint8, uint8, []byte, error)

ParseUDPDatagram parses a UDP datagram header Returns sessionID, isFragmented, fragID, fragIndex, fragTotal, payload

func PutBuffer

func PutBuffer(buf *bytes.Buffer)

PutBuffer returns a buffer to the pool. Buffers larger than MaxPooledBuffer are not pooled to prevent memory bloat.

func PutCopyBuffer added in v1.0.5

func PutCopyBuffer(buf *[]byte)

PutCopyBuffer returns a copy buffer to the pool.

func PutDatagramBuffer added in v1.0.5

func PutDatagramBuffer(buf *[]byte)

PutDatagramBuffer returns a datagram buffer to the pool. If buf is nil or has incorrect size, it is silently discarded.

func PutFragmentBuffer added in v1.0.5

func PutFragmentBuffer(buf *[]byte)

PutFragmentBuffer returns a fragment buffer to the pool. If buf is nil, it is silently ignored.

func PutReadBuffer added in v1.0.5

func PutReadBuffer(buf *[]byte)

PutReadBuffer returns a read buffer to the pool. If buf is nil or has incorrect size, it is silently discarded.

func ReadMessage

func ReadMessage(r io.Reader) (msgType byte, payload []byte, err error)

ReadMessage reads a message from the reader with optimized allocations. Uses a fixed header buffer to avoid allocations for header reading.

func ReadTypedMessage

func ReadTypedMessage(r io.Reader, expectedType byte, msg interface{}) error

ReadTypedMessage reads and decodes a message in one call

func Relay added in v1.0.5

func Relay(a, b io.ReadWriter) error

Relay performs bidirectional copy between two io.ReadWriter. It uses optimized buffers and returns when either direction closes.

func ReleaseDatagramResults added in v1.0.5

func ReleaseDatagramResults(results []DatagramResult)

ReleaseDatagramResults returns all buffers to the pool. This function should be called after all datagrams have been sent to return the pooled buffers for reuse.

func WriteConnClose

func WriteConnClose(w io.Writer, connID uint64, reason string) error

WriteConnClose writes a connection close message

func WriteError

func WriteError(w io.Writer, code uint32, message string) error

WriteError writes an error message

func WriteHeartbeat

func WriteHeartbeat(w io.Writer, timestamp int64) error

WriteHeartbeat writes a heartbeat message

func WriteMessage

func WriteMessage(w io.Writer, msgType byte, payload interface{}) error

WriteMessage writes a message to the writer using buffer pooling to reduce allocations.

func WriteNewConn

func WriteNewConn(w io.Writer, connID uint64, protocol, sourceAddr, destAddr string, timestamp int64) error

WriteNewConn writes a new connection message

func WriteRegister

func WriteRegister(w io.Writer, clientID, version string, capabilities []string) error

WriteRegister writes a registration message

func WriteRegisterAck

func WriteRegisterAck(w io.Writer, success bool, message string) error

WriteRegisterAck writes a registration acknowledgment

Types

type ConnCloseMsg

type ConnCloseMsg struct {
	ConnID uint64 // Connection ID
	Reason string // Close reason
}

ConnCloseMsg indicates connection closure

type DatagramResult added in v1.0.5

type DatagramResult struct {
	Data   []byte  // Slice of the buffer containing the datagram
	Buffer *[]byte // The underlying pooled buffer (nil if not pooled)
}

DatagramResult holds a datagram and its buffer for later release. Data is a slice of the buffer containing the actual datagram content. Buffer is the underlying pooled buffer (nil if not pooled).

func FragmentUDPPooled added in v1.0.5

func FragmentUDPPooled(sessionID uint32, data []byte, fragIDCounter *atomic.Uint32, enableFragmentation bool) ([]DatagramResult, error)

FragmentUDPPooled splits a UDP packet into fragments using pooled buffers. The caller MUST call ReleaseDatagramResults after sending all datagrams to return the buffers to the pool.

For unfragmented packets (data <= MaxUDPPayload), returns a single DatagramResult with a simple 4-byte header containing only the session ID.

For fragmented packets, returns multiple DatagramResults with 9-byte headers containing session ID, fragment ID, flags, fragment index, and total fragments.

type ErrorMsg

type ErrorMsg struct {
	Code    uint32 // Error code
	Message string // Error message
}

ErrorMsg carries error information

type FragmentAssembler added in v1.0.5

type FragmentAssembler struct {
	// contains filtered or unexported fields
}

FragmentAssembler reassembles fragmented UDP packets

func NewFragmentAssembler added in v1.0.5

func NewFragmentAssembler() *FragmentAssembler

NewFragmentAssembler creates a new fragment assembler

func (*FragmentAssembler) AddFragment added in v1.0.5

func (fa *FragmentAssembler) AddFragment(sessionID uint32, fragID uint16, index, total uint8, payload []byte) ([]byte, error)

AddFragment adds a fragment and returns the complete packet if all fragments received Returns (nil, nil) if more fragments are needed

type HeartbeatMsg

type HeartbeatMsg struct {
	Timestamp int64 // Unix timestamp
}

HeartbeatMsg is sent periodically to keep connection alive

type Message

type Message struct {
	Type    byte
	Payload interface{}
}

Message wraps a typed message with its type

type NewConnMsg

type NewConnMsg struct {
	ConnID     uint64 // Unique connection ID
	Protocol   string // "tcp" or "udp"
	SourceAddr string // Original client address (IP:port)
	DestAddr   string // Target address on traffic listener (IP:port)
	Timestamp  int64  // Connection timestamp
}

NewConnMsg is sent by server to client when new connection arrives

type RegisterAckMsg

type RegisterAckMsg struct {
	Success bool   // Registration success
	Message string // Optional message
}

RegisterAckMsg is sent by server to acknowledge registration

type RegisterMsg

type RegisterMsg struct {
	ClientID     string   // Unique client identifier
	Version      string   // Protocol version
	Capabilities []string // Supported features (e.g., "tcp", "udp")
}

RegisterMsg is sent by client to register with server

type ShardedFragmentAssembler added in v1.0.5

type ShardedFragmentAssembler struct {
	// contains filtered or unexported fields
}

ShardedFragmentAssembler reassembles fragmented UDP packets with reduced lock contention

func NewShardedFragmentAssembler added in v1.0.5

func NewShardedFragmentAssembler(shardCount int) *ShardedFragmentAssembler

NewShardedFragmentAssembler creates a new sharded fragment assembler

func (*ShardedFragmentAssembler) AddFragment added in v1.0.5

func (sfa *ShardedFragmentAssembler) AddFragment(sessionID uint32, fragID uint16, index, total uint8, payload []byte) ([]byte, error)

AddFragment adds a fragment and returns the complete packet if all fragments received. It locks only the relevant shard for reduced contention. Uses pooled buffers for fragment storage and tracks them for cleanup. Returns (nil, nil) if more fragments are needed.

type UDPBufferPool added in v1.0.5

type UDPBufferPool struct {
	// contains filtered or unexported fields
}

UDPBufferPool provides pooled buffers for UDP operations. It maintains three tiers of buffer pools optimized for different use cases: - Datagram pool: buffers for QUIC datagram operations - Read pool: buffers for UDP socket read operations - Fragment pool: buffers for fragment storage

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL