turbotunnel

package
v0.2.7 Latest Latest
Warning

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

Go to latest
Published: Apr 1, 2026 License: CC0-1.0 Imports: 10 Imported by: 0

Documentation

Overview

Package turbotunnel is facilities for embedding packet-based reliability protocols inside other protocols.

https://github.com/net4people/bbs/issues/9

Index

Constants

View Source
const QueueSize = 512

QueueSize is the size of send and receive queues in QueuePacketConn and RemoteMap.

Variables

This section is empty.

Functions

This section is empty.

Types

type ClientID

type ClientID string

ClientID is an abstract identifier that binds together all the communications belonging to a single client session, even though those communications may arrive from multiple IP addresses or over multiple lower-level connections. It plays the same role that an (IP address, port number) tuple plays in a net.UDPConn: it's the return address pertaining to a long-lived abstract client session. The client attaches its ClientID to each of its communications, enabling the server to disambiguate requests among its many clients. ClientID implements the net.Addr interface.

ClientID is backed by a string (immutable and comparable) so it can serve as a map key in RemoteMap while supporting variable sizes. The default size is 2 bytes; dnstt compatibility mode uses 8 bytes.

func NewClientID

func NewClientID(size int) ClientID

NewClientID generates a random ClientID of the given byte size.

func (ClientID) Bytes

func (id ClientID) Bytes() []byte

Bytes returns the raw bytes of the ClientID.

func (ClientID) Len

func (id ClientID) Len() int

Len returns the byte length of the ClientID.

func (ClientID) Network

func (id ClientID) Network() string

func (ClientID) String

func (id ClientID) String() string

type DummyAddr

type DummyAddr struct{}

DummyAddr is a placeholder net.Addr, for when a programming interface requires a net.Addr but there is none relevant. All DummyAddrs compare equal to each other.

func (DummyAddr) Network

func (addr DummyAddr) Network() string

func (DummyAddr) String

func (addr DummyAddr) String() string

type QueueOverflowMode added in v0.2.6

type QueueOverflowMode string

QueueOverflowMode controls how QueuePacketConn behaves when its queues are full.

const (
	// QueueOverflowDrop silently drops packets when queues are full. This is
	// the original dnstt/vaydns behavior and the correct default for
	// KCP-over-DNS where KCP handles retransmission of lost packets.
	QueueOverflowDrop QueueOverflowMode = "drop"
	// QueueOverflowBlock applies backpressure by blocking writers until queue
	// space is available or the connection is closed.
	QueueOverflowBlock QueueOverflowMode = "block"

	DefaultQueueOverflowMode = QueueOverflowDrop
)

func ParseQueueOverflowMode added in v0.2.6

func ParseQueueOverflowMode(s string) (QueueOverflowMode, error)

ParseQueueOverflowMode validates a queue overflow mode string.

type QueuePacketConn

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

QueuePacketConn implements net.PacketConn by storing queues of packets. There is one incoming queue (where packets are additionally tagged by the source address of the peer that sent them). There are many outgoing queues, one for each remote peer address that has been recently seen. The QueueIncoming method inserts a packet into the incoming queue, to eventually be returned by ReadFrom. WriteTo inserts a packet into an address-specific outgoing queue, which can later by accessed through the OutgoingQueue method.

Besides the outgoing queues, there is also a one-element "stash" for each remote peer address. You can stash a packet using the Stash method, and get it back later by receiving from the channel returned by Unstash. The stash is meant as a convenient place to temporarily store a single packet, such as when you've read one too many packets from the send queue and need to store the extra packet to be processed first in the next pass. It's the caller's responsibility to Unstash what they have Stashed. Calling Stash does not put the packet at the head of the send queue; if there is the possibility that a packet has been stashed, it must be checked for by calling Unstash in addition to OutgoingQueue.

func NewQueuePacketConn

func NewQueuePacketConn(localAddr net.Addr, timeout time.Duration, queueSize int, overflowMode QueueOverflowMode) *QueuePacketConn

NewQueuePacketConn makes a new QueuePacketConn, set to track recent peers for at least a duration of timeout. If queueSize is <= 0, the default QueueSize is used. If overflowMode is empty, QueueOverflowDrop is used.

func (*QueuePacketConn) Close

func (c *QueuePacketConn) Close() error

Close unblocks pending operations and makes future operations fail with a "closed connection" error.

func (*QueuePacketConn) Closed added in v0.2.5

func (c *QueuePacketConn) Closed() <-chan struct{}

Closed returns a channel that is closed when the QueuePacketConn is closed.

func (*QueuePacketConn) LocalAddr

func (c *QueuePacketConn) LocalAddr() net.Addr

LocalAddr returns the localAddr value that was passed to NewQueuePacketConn.

func (*QueuePacketConn) OutgoingQueue

func (c *QueuePacketConn) OutgoingQueue(addr net.Addr) <-chan []byte

OutgoingQueue returns the queue of outgoing packets corresponding to addr, creating it if necessary. The contents of the queue will be packets that are written to the address in question using WriteTo.

func (*QueuePacketConn) QueueIncoming

func (c *QueuePacketConn) QueueIncoming(p []byte, addr net.Addr)

QueueIncoming queues and incoming packet and its source address, to be returned in a future call to ReadFrom.

func (*QueuePacketConn) ReadFrom

func (c *QueuePacketConn) ReadFrom(p []byte) (int, net.Addr, error)

ReadFrom returns a packet and address previously stored by QueueIncoming.

func (*QueuePacketConn) SetDeadline

func (c *QueuePacketConn) SetDeadline(t time.Time) error

func (*QueuePacketConn) SetReadDeadline

func (c *QueuePacketConn) SetReadDeadline(t time.Time) error

func (*QueuePacketConn) SetWriteDeadline

func (c *QueuePacketConn) SetWriteDeadline(t time.Time) error

func (*QueuePacketConn) Stash

func (c *QueuePacketConn) Stash(p []byte, addr net.Addr) bool

Stash places p in the stash for addr, if the stash is not already occupied. Returns true if the packet was placed in the stash, or false if the stash was already occupied. This method is similar to WriteTo, except that it puts the packet in the stash queue (accessible via Unstash), rather than the outgoing queue (accessible via OutgoingQueue).

func (*QueuePacketConn) Unstash

func (c *QueuePacketConn) Unstash(addr net.Addr) <-chan []byte

Unstash returns the channel that represents the stash for addr.

func (*QueuePacketConn) WriteTo

func (c *QueuePacketConn) WriteTo(p []byte, addr net.Addr) (int, error)

WriteTo queues an outgoing packet for the given address. The queue can later be retrieved using the OutgoingQueue method.

type RemoteMap

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

RemoteMap manages a mapping of live remote peers, keyed by address, to their respective send queues. Each peer has two queues: a primary send queue, and a "stash". The primary send queue is returned by the SendQueue method. The stash is an auxiliary one-element queue accessed using the Stash and Unstash methods. The stash is meant for use by callers that need to "unread" a packet that's already been removed from the primary send queue.

RemoteMap's functions are safe to call from multiple goroutines.

func NewRemoteMap

func NewRemoteMap(timeout time.Duration, queueSize int) *RemoteMap

NewRemoteMap creates a RemoteMap that expires peers after a timeout.

If the timeout is 0, peers never expire.

The timeout does not have to be kept in sync with smux's idle timeout. If a peer is removed from the map while the smux session is still live, the worst that can happen is a loss of whatever packets were in the send queue at the time. If smux later decides to send more packets to the same peer, we'll instantiate a new send queue, and if the peer is ever seen again with a matching address, we'll deliver them.

func (*RemoteMap) SendQueue

func (m *RemoteMap) SendQueue(addr net.Addr) chan []byte

SendQueue returns the send queue corresponding to addr, creating it if necessary.

func (*RemoteMap) Stash

func (m *RemoteMap) Stash(addr net.Addr, p []byte) bool

Stash places p in the stash corresponding to addr, if the stash is not already occupied. Returns true if the p was placed in the stash, false otherwise.

func (*RemoteMap) Unstash

func (m *RemoteMap) Unstash(addr net.Addr) <-chan []byte

Unstash returns the channel that reads from the stash for addr.

type WireConfig

type WireConfig struct {
	// ClientIDSize is the number of bytes used for the ClientID on the wire.
	// Default is 2 (VayDNS). dnstt compatibility mode sets this to 8.
	ClientIDSize int
	// Compat enables the original dnstt wire format with padding prefixes.
	Compat bool
}

WireConfig holds wire protocol parameters that differ between VayDNS and dnstt compatibility mode.

func (WireConfig) DataOverhead

func (wc WireConfig) DataOverhead() int

DataOverhead returns the number of bytes consumed by per-query framing (ClientID, padding, length prefix) before the actual data payload.

func (WireConfig) IsDnstt

func (wc WireConfig) IsDnstt() bool

IsDnstt reports whether dnstt wire compatibility is active.

func (WireConfig) MaxDataLen

func (wc WireConfig) MaxDataLen() int

MaxDataLen returns the maximum number of data bytes that can be carried in a single upstream query packet.

Jump to

Keyboard shortcuts

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