utp_go

package module
v0.0.0-...-0508310 Latest Latest
Warning

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

Go to latest
Published: Jun 1, 2025 License: MIT Imports: 18 Imported by: 1

README

utp-go

A Go implementation of the µTorrent Transport Protocol (uTP).

Documentation

Index

Constants

View Source
const (
	Initial = iota
	Retransmission
)
View Source
const (
	MINIMAL_HEADER_SIZE                    = 20
	MINIMAL_HEADER_SIZE_WITH_SELECTIVE_ACK = 26
	PROTOCOL_VERSION_ONE                   = 1
	ZERO_MOMENT                            = time.Duration(0)
	ACKS_ARRAY_LENGTH                      = byte(4)
	PACKET_HEADER_LEN                      = 20
	SELECTIVE_ACK_BITS                     = 32
	EXTENSION_TYPE_LEN                     = 1
	EXTENSION_LEN_LEN                      = 1
)
View Source
const (
	MAX_UDP_PAYLOAD_SIZE         = math.MaxUint16
	CidGenerationTryWarningCount = 10
	AWAITING_CONNECTION_TIMEOUT  = time.Second * 20
)
View Source
const DefaultBufferSize = 1024 * 1024
View Source
const DefaultMaxIdleTimeout = 60 * time.Second
View Source
const DefaultWindowSize = 1024 * 1024
View Source
const LossThreshold = 3
View Source
const (
	MAX_SELECTIVE_ACK_COUNT int = 32 * 63
)

Variables

View Source
var (
	ErrInsufficientWindowSize = errors.New("insufficient window size")
	ErrUnknownSeqNum          = errors.New("unknown sequence number")
	ErrDuplicateTransmission  = errors.New("duplicate transmission")
)
View Source
var (
	ErrEmptyDataPayload  = errors.New("empty data payload")
	ErrConnInvalidAckNum = errors.New("invalid ack number")
	ErrInvalidFin        = errors.New("invalid fin")
	ErrInvalidSeqNum     = errors.New("invalid seq number")
	ErrInvalidSyn        = errors.New("invalid syn")
	ErrReset             = errors.New("reset")
	ErrSynFromAcceptor   = errors.New("syn from acceptor")
	ErrTimedOut          = errors.New("timed out")
)
View Source
var (
	ErrInvalidHeaderSize           = errors.New("invalid header size")
	ErrInvalidPacketVersion        = errors.New("invalid packet version")
	ErrInvalidPacketType           = errors.New("invalid packet type")
	ErrInvalidExtensionType        = errors.New("invalid extension type")
	ErrInsufficientLen             = errors.New("insufficient length for extension")
	ErrPacketTooShort              = errors.New("packet too short for selective ack extension")
	ErrInsufficientSelectiveAckLen = errors.New("insufficient length for selective ACK")
	ErrInvalidSelectiveAckLen      = errors.New("invalid length for selective ACK")
)
View Source
var (
	BASE_CONTEXT = context.Background()
)
View Source
var ErrCannotFindLostPacket = errors.New("cannot mark unsent packet lost")
View Source
var (
	ErrConnect = errors.New("utp_socket: connect error")
)
View Source
var ErrInvalidAckNum = errors.New("invalid ack number")
View Source
var ErrNoneAckNum = errors.New("none ack number")
View Source
var (
	ErrNotConnected = errors.New("not connected")
)
View Source
var ErrSentPacketMarkLost = errors.New("lost packet was previously sent")

Functions

func ClampUint32

func ClampUint32(value, min, max uint32) uint32

func DecodePacket

func DecodePacket(b []byte) (*packet, error)

func DurationBetween

func DurationBetween(earlier uint32, later uint32) time.Duration

func NowMicro

func NowMicro() uint32

func RandomUint16

func RandomUint16() uint16

Types

type Accept

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

type Ack

type Ack struct {
	Delay      time.Duration
	RTT        time.Duration
	ReceivedAt time.Time
}

type ClosingRecord

type ClosingRecord struct {
	LocalFin  *uint16
	RemoteFin *uint16
}

type Conn

type Conn interface {
	ReadFrom(b []byte) (int, ConnectionPeer, error)
	WriteTo(b []byte, dst ConnectionPeer) (int, error)
	Close() error
}

type ConnState

type ConnState struct {
	RecvBuf     *receiveBuffer
	SendBuf     *sendBuffer
	SentPackets *sentPackets

	Err error
	// contains filtered or unexported fields
}

func NewConnState

func NewConnState(connected chan error) *ConnState

type ConnStateType

type ConnStateType int
const (
	ConnConnecting ConnStateType = iota
	ConnConnected
	ConnClosed
)

type ConnectionConfig

type ConnectionConfig struct {
	MaxPacketSize   uint16
	MaxConnAttempts int
	MaxIdleTimeout  time.Duration
	InitialTimeout  time.Duration
	MinTimeout      time.Duration
	MaxTimeout      time.Duration
	TargetDelay     time.Duration
	WindowSize      uint32
	BufferSize      int
}

func NewConnectionConfig

func NewConnectionConfig() *ConnectionConfig

type ConnectionId

type ConnectionId struct {
	Send uint16
	Recv uint16
	Peer ConnectionPeer
	// contains filtered or unexported fields
}

ConnectionId represents a connection identifier with send and receive IDs and a peer.

func CidFromPacket

func CidFromPacket(
	packet *packet,
	src ConnectionPeer,
	idType IdType,
) *ConnectionId

func NewConnectionId

func NewConnectionId(peer ConnectionPeer, recvId uint16, sendId uint16) *ConnectionId

func (*ConnectionId) Hash

func (id *ConnectionId) Hash() string

func (*ConnectionId) String

func (id *ConnectionId) String() string

type ConnectionPeer

type ConnectionPeer interface {
	Hash() string
}

ConnectionPeer is an interface representing a remote peer.

type Controller

type Controller interface {
	OnTransmit(seqNum uint16, transmit Transmit, dataLen uint32) error
	OnAck(seqNum uint16, ack Ack) error
	OnLostPacket(seqNum uint16, retransmitting bool) error
	OnTimeout()
	Timeout() time.Duration
	BytesAvailableInWindow() uint32
}

type Endpoint

type Endpoint struct {
	Type     EndpointType
	SynNum   uint16
	SynAck   uint16
	Attempts int
}

type EndpointType

type EndpointType int
const (
	Initiator EndpointType = iota
	Acceptor
)

type ExtensionData

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

func DecodeRawExtensions

func DecodeRawExtensions(firstExt byte, data []byte) ([]ExtensionData, int, error)

type IdType

type IdType int
const (
	IdTypeRecvId IdType = iota
	IdTypeSendIdWeInitiated
	IdTypeSendIdPeerInitiated
)

func (IdType) String

func (i IdType) String() string

type IncomingPacket

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

type IncomingPacketRaw

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

type LostPacket

type LostPacket struct {
	SeqNum     uint16
	PacketType PacketType
	Data       []byte
}

type LostPacketSeqNums

type LostPacketSeqNums []uint16

func (LostPacketSeqNums) Remove

type PacketBuilder

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

func NewPacketBuilder

func NewPacketBuilder(
	packetType PacketType,
	connID uint16,
	tsMicros uint32,
	windowSize uint32,
	seqNum uint16,
) *PacketBuilder

func (*PacketBuilder) Build

func (b *PacketBuilder) Build() *packet

func (*PacketBuilder) WithAckNum

func (b *PacketBuilder) WithAckNum(ackNum uint16) *PacketBuilder

func (*PacketBuilder) WithPayload

func (b *PacketBuilder) WithPayload(payload []byte) *PacketBuilder

func (*PacketBuilder) WithSelectiveAck

func (b *PacketBuilder) WithSelectiveAck(selectiveAck *SelectiveAck) *PacketBuilder

func (*PacketBuilder) WithTsDiffMicros

func (b *PacketBuilder) WithTsDiffMicros(tsDiffMicros uint32) *PacketBuilder

func (*PacketBuilder) WithTsMicros

func (b *PacketBuilder) WithTsMicros(tsMicros uint32) *PacketBuilder

func (*PacketBuilder) WithWindowSize

func (b *PacketBuilder) WithWindowSize(windowSize uint32) *PacketBuilder

type PacketHeaderV1

type PacketHeaderV1 struct {
	PacketType    PacketType
	Version       byte
	Extension     byte
	ConnectionId  uint16
	Timestamp     int64
	TimestampDiff uint32
	WndSize       uint32
	SeqNum        uint16
	AckNum        uint16
}

func DecodePacketHeader

func DecodePacketHeader(value []byte) (*PacketHeaderV1, error)

func (*PacketHeaderV1) EncodeToBytes

func (h *PacketHeaderV1) EncodeToBytes() []byte

type PacketType

type PacketType byte

func (PacketType) Check

func (p PacketType) Check() error

func (*PacketType) String

func (p *PacketType) String() string

type PeerInfo

type PeerInfo interface {
	Hash() [32]byte
}

type SelectiveAck

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

SelectiveAck represents a selective acknowledgment

func DecodeSelectiveAck

func DecodeSelectiveAck(data []byte) (*SelectiveAck, error)

DecodeSelectiveAck decodes a byte slice into a SelectiveAck

func NewSelectiveAck

func NewSelectiveAck(acked []bool) *SelectiveAck

NewSelectiveAck creates a new SelectiveAck from a slice of booleans

func (*SelectiveAck) Acked

func (s *SelectiveAck) Acked() []bool

func (*SelectiveAck) Encode

func (s *SelectiveAck) Encode() []byte

Encode encodes the SelectiveAck into a byte slice

func (*SelectiveAck) EncodedLen

func (s *SelectiveAck) EncodedLen() int

type SelectiveAckExtension

type SelectiveAckExtension [4]byte

type StreamEventType

type StreamEventType int

type StreamResult

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

type TcpPeer

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

func (*TcpPeer) Hash

func (p *TcpPeer) Hash() string

func (*TcpPeer) String

func (p *TcpPeer) String() string

type Transmit

type Transmit int

type UdpConn

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

func (*UdpConn) Close

func (c *UdpConn) Close() error

func (*UdpConn) ReadFrom

func (c *UdpConn) ReadFrom(b []byte) (int, ConnectionPeer, error)

func (*UdpConn) WriteTo

func (c *UdpConn) WriteTo(b []byte, dst ConnectionPeer) (int, error)

type UdpPeer

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

SocketAddr is a simple implementation of the ConnectionPeer interface using net.UDPAddr.

func NewUdpPeer

func NewUdpPeer(addr *net.UDPAddr) *UdpPeer

func (*UdpPeer) Hash

func (p *UdpPeer) Hash() string

func (*UdpPeer) String

func (p *UdpPeer) String() string

type UtpSocket

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

func Bind

func Bind(ctx context.Context, network string, addr *net.UDPAddr, logger log.Logger) (*UtpSocket, error)

func WithSocket

func WithSocket(ctx context.Context, socket Conn, logger log.Logger) *UtpSocket

func (*UtpSocket) Accept

func (s *UtpSocket) Accept(ctx context.Context, config *ConnectionConfig) (*UtpStream, error)

func (*UtpSocket) AcceptWithCid

func (s *UtpSocket) AcceptWithCid(ctx context.Context, cid *ConnectionId, config *ConnectionConfig) (*UtpStream, error)

func (*UtpSocket) Cid

func (s *UtpSocket) Cid(peer ConnectionPeer, isInitiator bool) *ConnectionId

func (*UtpSocket) Close

func (s *UtpSocket) Close()

func (*UtpSocket) Connect

func (s *UtpSocket) Connect(ctx context.Context, peer ConnectionPeer, config *ConnectionConfig) (*UtpStream, error)

func (*UtpSocket) ConnectWithCid

func (s *UtpSocket) ConnectWithCid(
	ctx context.Context,
	cid *ConnectionId,
	config *ConnectionConfig,
) (*UtpStream, error)

func (*UtpSocket) GenerateCid

func (s *UtpSocket) GenerateCid(peer ConnectionPeer, isInitiator bool, eventCh chan *streamEvent) *ConnectionId

func (*UtpSocket) NumConnections

func (s *UtpSocket) NumConnections() int

type UtpStream

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

func NewUtpStream

func NewUtpStream(
	ctx context.Context,
	logger log.Logger,
	cid *ConnectionId,
	config *ConnectionConfig,
	syn *packet,
	socketEvents chan *socketEvent,
	streamEvents chan *streamEvent,
	connected chan error,
) *UtpStream

func (*UtpStream) Cid

func (s *UtpStream) Cid() *ConnectionId

func (*UtpStream) Close

func (s *UtpStream) Close()

func (*UtpStream) ReadToEOF

func (s *UtpStream) ReadToEOF(ctx context.Context, buf *[]byte) (int, error)

func (*UtpStream) Write

func (s *UtpStream) Write(ctx context.Context, buf []byte) (int, error)

Directories

Path Synopsis
native
cgo command

Jump to

Keyboard shortcuts

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