Documentation
¶
Overview ¶
Package adapter manages the post-transport lifecycle of a P2P tunnel. Given a ready Transport, it handles packet dispatch, per-socketID goroutine management, and TCP bridging for both host and client roles.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func RunAsClient ¶
RunAsClient starts the client-side adapter. It listens on localPort for incoming TCP connections; each accepted connection becomes a Socket that sends CONNECT and bridges data through the DataChannel. Blocks until the transport is done.
Types ¶
type Reassembler ¶
type Reassembler struct {
// contains filtered or unexported fields
}
Reassembler reorders out-of-order packets within a single socketID stream. Push and Drain are designed to run in separate goroutines:
- Push: called from the inbox-consuming goroutine (fast, mutex-guarded heap insert)
- Drain: called from the TCP-writing goroutine (pops consecutive in-order packets)
Ready() returns a channel that signals when drainable packets are available.
func NewReassembler ¶
func NewReassembler() *Reassembler
NewReassembler creates a reassembler expecting sequence numbers starting at 1.
func (*Reassembler) Drain ¶
func (r *Reassembler) Drain() []*protocol.Packet
Drain returns all consecutive in-order packets starting from the expected sequence number. It is goroutine-safe. Returns nil if no packets are currently drainable.
func (*Reassembler) Push ¶
func (r *Reassembler) Push(pkt *protocol.Packet) bool
Push inserts a packet into the reorder buffer. It is goroutine-safe and designed to be as fast as possible (single mutex-guarded heap push). Returns true if the buffer has exceeded the size limit (caller should treat this as a fatal condition and tear down the socket).
func (*Reassembler) Ready ¶
func (r *Reassembler) Ready() <-chan struct{}
Ready returns a channel that receives a signal whenever one or more packets become drainable (i.e. the next expected sequence number is at the front of the buffer). The consumer should call Drain after receiving each signal.
type SeqGen ¶
type SeqGen struct {
// contains filtered or unexported fields
}
SeqGen is a per-socketID atomic sequence number generator. It is shared across the socket's goroutines (main loop, TCP-to-DC pump, and cleanup), so all operations are atomic.
type Socket ¶
type Socket struct {
// contains filtered or unexported fields
}
Socket holds the complete lifecycle state for one socketID.
A Socket spawns up to three long-running goroutines (pushLoop, writeOrConnLoop/writeLoop, readLoop). Concurrent access is safe because:
- inbox is a buffered channel (dispatch → pushLoop)
- Reassembler is mutex-protected (pushLoop ↔ writeOrConnLoop/writeLoop)
- SeqGen uses atomic operations
- tcpConn is set before readLoop is launched (happens-before)
- cleanup is guarded by sync.Once
type Transport ¶
type Transport interface {
SendConnect(socketID, seqNum uint32)
SendData(socketID, seqNum uint32, payload []byte)
SendClose(socketID, seqNum uint32)
OnPacket(fn func(*protocol.Packet))
Done() <-chan struct{}
}
Transport defines the capabilities that adapter requires from the underlying data transport layer.