Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 62 additions & 21 deletions daemonapi/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,30 @@

package daemonapi

// Connection is an opaque handle to a daemon stream connection.
import "github.com/pilot-protocol/common/protocol"

// Connection is the daemon-facing handle to a stream connection.
// Plugins receive Connection values from DialConnection / Accept and
// pass them back to SendData / CloseConnection / NewConnReadWriter.
// The concrete *daemon.Connection in web4/pkg/daemon satisfies this
// via Go's structural typing — there are no methods on the interface
// itself; it's a marker token.
//
// Keeping Connection an opaque marker is deliberate: plugins like
// runtime treat connections as values they hand back to the daemon
// for any operation. They never inspect connection internals.
// Anything that ever does (writing bytes, reading bytes, closing)
// goes through ConnReadWriter — see below.
type Connection interface{}
// The Info accessor returns a struct snapshot of the four endpoint
// quantities a plugin commonly needs (local/remote address + port).
// This avoids exposing every field of the concrete *daemon.Connection
// through the interface, and avoids name collisions between Go's
// exported struct fields and same-named methods on the interface.
type Connection interface {
// Info returns an endpoint snapshot. The returned struct is a
// value copy, so plugins may hold it across goroutines.
Info() ConnectionInfo
}

// ConnectionInfo is the endpoint snapshot returned by Connection.Info.
type ConnectionInfo struct {
LocalAddr protocol.Addr
LocalPort uint16
RemoteAddr protocol.Addr
RemotePort uint16
}

// ConnReadWriter is the read/write adapter plugins use when they
// need net.Conn-style I/O on a Connection. Construct one via
Expand All @@ -25,14 +36,44 @@ type ConnReadWriter interface {
Close() error
}

// PortAllocator is an opaque handle to the daemon's port table.
// Plugins receive it via Daemon.Ports() and typically hand it to
// other plugins that need to bind well-known ports. Like Connection,
// it has no methods on this interface — concrete daemon types
// satisfy it via structural typing.
type PortAllocator interface{}

// TunnelRegistry is an opaque handle to the daemon's tunnel table.
// Same opaque-marker shape as PortAllocator: plugins pass it
// around, the daemon owns the implementation.
type TunnelRegistry interface{}
// Listener is a bound port that yields inbound Connection values
// via Accept. Plugins (notably handshake on PortHandshake) hold a
// Listener for the lifetime of their server loop.
type Listener interface {
// Accept blocks until an inbound Connection lands on the
// listener or the listener is closed. ok=false signals close
// (no further Connections will arrive).
Accept() (conn Connection, ok bool)

// Port returns the bound port. Stable for the listener's lifetime.
Port() uint16

// Close releases the port and stops accepting new Connections.
Close() error
}

// PortAllocator is the daemon's port table. Plugins receive it via
// Daemon.Ports() and bind / unbind well-known ports through it. The
// concrete *daemon.PortManager satisfies this via structural typing.
type PortAllocator interface {
// Bind takes ownership of the given port and returns a Listener
// that will receive Connections targeting it. Returns an error
// if the port is already bound.
Bind(port uint16) (Listener, error)

// Unbind releases the port. The Listener returned by Bind also
// stops accepting (its Accept loop returns ok=false). Idempotent;
// unbinding an unbound port is a no-op.
Unbind(port uint16)
}

// TunnelRegistry is the daemon's tunnel table. Plugins use RemovePeer
// to tear down a peer's tunnel state when revoking trust or closing
// a connection. The concrete *daemon.TunnelManager satisfies this
// via structural typing.
type TunnelRegistry interface {
// RemovePeer tears down the encrypted tunnel for the given peer.
// All per-peer state (session keys, retransmit queues, routing
// entries) is dropped. Safe to call when no tunnel exists.
RemovePeer(nodeID uint32)
}
Loading