Documentation
¶
Overview ¶
Package noise provides a high-level wrapper around the go-i2p/noise package implementing net.Conn, net.Listener, and net.Addr interfaces for the Noise Protocol Framework. It supports extensible handshake modification for implementing I2P's NTCP2 and SSU2 transport protocols.
Index ¶
- Constants
- func GetGlobalConnPool() *pool.ConnPool
- func GracefulShutdown() error
- func SetGlobalConnPool(p *pool.ConnPool)
- func SetGlobalShutdownManager(sm *ShutdownManager)
- type ConnConfig
- func (c *ConnConfig) AddModifier(modifier handshake.HandshakeModifier) *ConnConfig
- func (c *ConnConfig) ClearModifiers() *ConnConfig
- func (c *ConnConfig) GetModifierChain() *handshake.ModifierChain
- func (c *ConnConfig) Validate() error
- func (c *ConnConfig) WithHandshakeRetries(retries int) *ConnConfig
- func (c *ConnConfig) WithHandshakeTimeout(timeout time.Duration) *ConnConfig
- func (c *ConnConfig) WithModifiers(modifiers ...handshake.HandshakeModifier) *ConnConfig
- func (c *ConnConfig) WithReadTimeout(timeout time.Duration) *ConnConfig
- func (c *ConnConfig) WithRemoteKey(key []byte) *ConnConfig
- func (c *ConnConfig) WithRetryBackoff(backoff time.Duration) *ConnConfig
- func (c *ConnConfig) WithStaticKey(key []byte) *ConnConfig
- func (c *ConnConfig) WithWriteTimeout(timeout time.Duration) *ConnConfig
- type ConnState
- type ListenerConfig
- func (lc *ListenerConfig) Validate() error
- func (lc *ListenerConfig) WithAdditionalSymmetricKeyLabels(labels [][]byte) *ListenerConfig
- func (lc *ListenerConfig) WithHandshakeRetries(retries int) *ListenerConfig
- func (lc *ListenerConfig) WithHandshakeTimeout(timeout time.Duration) *ListenerConfig
- func (lc *ListenerConfig) WithModifiers(modifiers ...handshake.HandshakeModifier) *ListenerConfig
- func (lc *ListenerConfig) WithPostHandshakeHook(hook func(*NoiseConn) error) *ListenerConfig
- func (lc *ListenerConfig) WithReadTimeout(timeout time.Duration) *ListenerConfig
- func (lc *ListenerConfig) WithRetryBackoff(backoff time.Duration) *ListenerConfig
- func (lc *ListenerConfig) WithStaticKey(key []byte) *ListenerConfig
- func (lc *ListenerConfig) WithWriteTimeout(timeout time.Duration) *ListenerConfig
- type NoiseAddr
- type NoiseConn
- func DialNoise(network, addr string, config *ConnConfig) (*NoiseConn, error)
- func DialNoiseWithHandshake(network, addr string, config *ConnConfig) (*NoiseConn, error)
- func DialNoiseWithHandshakeContext(ctx context.Context, network, addr string, config *ConnConfig) (*NoiseConn, error)
- func DialNoiseWithPool(network, addr string, config *ConnConfig) (*NoiseConn, error)
- func DialNoiseWithPoolAndHandshake(network, addr string, config *ConnConfig) (*NoiseConn, error)
- func DialNoiseWithPoolAndHandshakeContext(ctx context.Context, network, addr string, config *ConnConfig) (*NoiseConn, error)
- func NewNoiseConn(underlying net.Conn, config *ConnConfig) (*NoiseConn, error)
- func WrapConn(conn net.Conn, config *ConnConfig) (*NoiseConn, error)
- func (nc *NoiseConn) AdditionalSymmetricKeys() [][]byte
- func (nc *NoiseConn) ChannelBinding() []byte
- func (nc *NoiseConn) Close() error
- func (nc *NoiseConn) CompleteHandshake()
- func (nc *NoiseConn) Decrypt(encrypted []byte) ([]byte, error)
- func (nc *NoiseConn) Encrypt(data []byte) ([]byte, error)
- func (nc *NoiseConn) FailHandshake()
- func (nc *NoiseConn) GetConnectionMetrics() (bytesRead, bytesWritten int64, handshakeDuration time.Duration)
- func (nc *NoiseConn) GetConnectionState() ConnState
- func (nc *NoiseConn) GetHandshakeHash() []byte
- func (nc *NoiseConn) GetModifierChain() *handshake.ModifierChain
- func (nc *NoiseConn) Handshake(ctx context.Context) error
- func (nc *NoiseConn) HandshakeWithRetry(ctx context.Context) error
- func (nc *NoiseConn) LocalAddr() net.Addr
- func (nc *NoiseConn) MixHashData(data []byte)
- func (nc *NoiseConn) PeerStatic() []byte
- func (nc *NoiseConn) Read(b []byte) (int, error)
- func (nc *NoiseConn) ReadHandshakeMsgFromBytes(phase handshake.HandshakePhase, wireData []byte) ([]byte, error)
- func (nc *NoiseConn) RecvCipherState() *noise.CipherState
- func (nc *NoiseConn) Rekey() error
- func (nc *NoiseConn) RemoteAddr() net.Addr
- func (nc *NoiseConn) RunPostHandshakeHook() error
- func (nc *NoiseConn) SendCipherState() *noise.CipherState
- func (nc *NoiseConn) SetDeadline(t time.Time) error
- func (nc *NoiseConn) SetReadDeadline(t time.Time) error
- func (nc *NoiseConn) SetShutdownManager(sm *ShutdownManager)
- func (nc *NoiseConn) SetWriteDeadline(t time.Time) error
- func (nc *NoiseConn) StartHandshake()
- func (nc *NoiseConn) Underlying() net.Conn
- func (nc *NoiseConn) Write(b []byte) (int, error)
- func (nc *NoiseConn) WriteHandshakeMsgToBytes(phase handshake.HandshakePhase, payload []byte) ([]byte, error)
- func (nc *NoiseConn) ZeroKeys()
- type NoiseListener
- type ShutdownManager
- func (sm *ShutdownManager) Context() context.Context
- func (sm *ShutdownManager) RegisterConnection(conn *NoiseConn)
- func (sm *ShutdownManager) RegisterListener(listener *NoiseListener)
- func (sm *ShutdownManager) Shutdown() error
- func (sm *ShutdownManager) UnregisterConnection(conn *NoiseConn)
- func (sm *ShutdownManager) UnregisterListener(listener *NoiseListener)
- func (sm *ShutdownManager) Wait()
Constants ¶
const ( // StateInit represents a newly created connection StateInit = internal.StateInit // StateHandshaking represents a connection performing handshake StateHandshaking = internal.StateHandshaking // StateEstablished represents a connection with completed handshake StateEstablished = internal.StateEstablished // StateClosed represents a closed connection StateClosed = internal.StateClosed )
Connection state constants for public API
Variables ¶
This section is empty.
Functions ¶
func GetGlobalConnPool ¶
GetGlobalConnPool returns the current global connection pool
func GracefulShutdown ¶
func GracefulShutdown() error
GracefulShutdown initiates graceful shutdown of all global components. This includes the global connection pool and all registered connections/listeners.
func SetGlobalConnPool ¶
SetGlobalConnPool sets a custom connection pool for transport functions
func SetGlobalShutdownManager ¶
func SetGlobalShutdownManager(sm *ShutdownManager)
SetGlobalShutdownManager sets a custom shutdown manager for transport functions. The previous shutdown manager will be shut down gracefully.
Types ¶
type ConnConfig ¶
type ConnConfig struct {
// Pattern is the Noise protocol pattern (e.g., "Noise_XX_25519_AESGCM_SHA256")
Pattern string
// Initiator indicates if this connection is the handshake initiator
Initiator bool
// StaticKey is the long-term static key for this peer (32 bytes for Curve25519)
StaticKey []byte
// RemoteKey is the remote peer's static public key (32 bytes for Curve25519)
// Required for some patterns, optional for others
RemoteKey []byte
// HandshakeTimeout is the maximum time to wait for handshake completion
// Default: 30 seconds
HandshakeTimeout time.Duration
// ReadTimeout is the timeout for read operations after handshake
// Default: no timeout (0)
ReadTimeout time.Duration
// WriteTimeout is the timeout for write operations after handshake
// Default: no timeout (0)
WriteTimeout time.Duration
// HandshakeRetries is the number of handshake retry attempts.
// Default: 0 (no retries). Set to a positive value and use
// HandshakeWithRetry() to enable retry semantics with exponential
// backoff. Handshake() always performs a single attempt regardless
// of this setting. Use -1 for infinite retries.
HandshakeRetries int
// RetryBackoff is the base delay between retry attempts
// Actual delay uses exponential backoff: delay = RetryBackoff * (2^attempt)
// Default: 1 second
RetryBackoff time.Duration
// Modifiers is a list of handshake modifiers for obfuscation and padding
// Modifiers are applied in order during outbound processing and in reverse
// order during inbound processing. Default: empty (no modifiers)
Modifiers []handshake.HandshakeModifier
// CipherSuite specifies the Noise cipher suite to use for the handshake.
// If nil, defaults to DH25519 + CipherAESGCM + SHA256.
// Protocols like NTCP2 require DH25519 + CipherChaChaPoly + SHA256.
CipherSuite noise.CipherSuite
// ProtocolName overrides the auto-generated Noise protocol name used
// for InitializeSymmetric(). When set, this exact byte string is used
// instead of constructing "Noise_" + Pattern.Name + "_" + CipherSuite.Name().
// Required for protocols like NTCP2 that use non-standard protocol names
// (e.g., "Noise_XKaesobfse+hs2+hs3_25519_ChaChaPoly_SHA256").
// If nil/empty, the standard Noise protocol name is constructed as usual.
ProtocolName []byte
// AdditionalSymmetricKeyLabels specifies labels for Additional Symmetric
// Key (ASK) derivation at Split() time, per Noise spec §10.3. Each label
// produces a 32-byte key derived from the chaining key. The derived keys
// are available via NoiseConn.AdditionalSymmetricKeys() after the
// handshake completes.
//
// For NTCP2, this should be set to [][]byte{[]byte("ask")} to derive
// the ask_master used for SipHash key derivation.
AdditionalSymmetricKeyLabels [][]byte
// PostHandshakeHook is an optional callback invoked after the Noise
// handshake completes successfully but before the connection transitions
// to the Established state. This allows protocol layers (e.g., NTCP2)
// to derive additional key material from the handshake hash, set up
// data-phase obfuscators, or perform any post-handshake validation.
//
// If the hook returns an error, the handshake is considered failed and
// the connection reverts to the Init state.
PostHandshakeHook func(*NoiseConn) error
// contains filtered or unexported fields
}
ConnConfig contains configuration for creating a NoiseConn. It follows the builder pattern for optional configuration and validation.
func NewConnConfig ¶
func NewConnConfig(pattern string, initiator bool) *ConnConfig
NewConnConfig creates a new ConnConfig with sensible defaults.
func (*ConnConfig) AddModifier ¶
func (c *ConnConfig) AddModifier(modifier handshake.HandshakeModifier) *ConnConfig
AddModifier appends a single modifier to the existing modifier list.
func (*ConnConfig) ClearModifiers ¶
func (c *ConnConfig) ClearModifiers() *ConnConfig
ClearModifiers removes all modifiers from the configuration.
func (*ConnConfig) GetModifierChain ¶
func (c *ConnConfig) GetModifierChain() *handshake.ModifierChain
GetModifierChain returns a ModifierChain containing all configured modifiers. Returns nil if no modifiers are configured. The chain is lazily initialized and cached; subsequent calls return the same instance until the modifier list is mutated via WithModifiers, AddModifier, or ClearModifiers.
func (*ConnConfig) Validate ¶
func (c *ConnConfig) Validate() error
Validate checks if the configuration is valid and complete. Returns an error with context if validation fails.
func (*ConnConfig) WithHandshakeRetries ¶
func (c *ConnConfig) WithHandshakeRetries(retries int) *ConnConfig
WithHandshakeRetries sets the number of handshake retry attempts used by HandshakeWithRetry. Handshake() always performs a single attempt regardless of this setting. Use 0 for no retries, -1 for infinite retries.
func (*ConnConfig) WithHandshakeTimeout ¶
func (c *ConnConfig) WithHandshakeTimeout(timeout time.Duration) *ConnConfig
WithHandshakeTimeout sets the handshake timeout.
func (*ConnConfig) WithModifiers ¶
func (c *ConnConfig) WithModifiers(modifiers ...handshake.HandshakeModifier) *ConnConfig
WithModifiers sets the handshake modifiers for obfuscation and padding. Modifiers are applied in the order provided for outbound data and in reverse order for inbound data.
func (*ConnConfig) WithReadTimeout ¶
func (c *ConnConfig) WithReadTimeout(timeout time.Duration) *ConnConfig
WithReadTimeout sets the read timeout for post-handshake operations.
func (*ConnConfig) WithRemoteKey ¶
func (c *ConnConfig) WithRemoteKey(key []byte) *ConnConfig
WithRemoteKey sets the remote peer's static public key. key must be 32 bytes for Curve25519.
func (*ConnConfig) WithRetryBackoff ¶
func (c *ConnConfig) WithRetryBackoff(backoff time.Duration) *ConnConfig
WithRetryBackoff sets the base delay between retry attempts. Actual delay uses exponential backoff: delay = backoff * (2^attempt).
func (*ConnConfig) WithStaticKey ¶
func (c *ConnConfig) WithStaticKey(key []byte) *ConnConfig
WithStaticKey sets the static key for this connection. key must be 32 bytes for Curve25519.
func (*ConnConfig) WithWriteTimeout ¶
func (c *ConnConfig) WithWriteTimeout(timeout time.Duration) *ConnConfig
WithWriteTimeout sets the write timeout for post-handshake operations.
type ListenerConfig ¶
type ListenerConfig struct {
// Pattern is the Noise protocol pattern (e.g., "Noise_XX_25519_AESGCM_SHA256")
Pattern string
// StaticKey is the long-term static key for this listener (32 bytes for Curve25519)
StaticKey []byte
// HandshakeTimeout is the maximum time to wait for handshake completion
// Default: 30 seconds
HandshakeTimeout time.Duration
// ReadTimeout is the timeout for read operations after handshake
// Default: no timeout (0)
ReadTimeout time.Duration
// WriteTimeout is the timeout for write operations after handshake
// Default: no timeout (0)
WriteTimeout time.Duration
// Modifiers is a list of handshake modifiers for obfuscation and padding.
// Modifiers are applied in order during outbound processing and in reverse
// order during inbound processing. Required for NTCP2 server-side
// connections that need AES-CBC obfuscation and SipHash length obfuscation.
// Default: empty (no modifiers)
Modifiers []handshake.HandshakeModifier
// PostHandshakeHook is an optional callback invoked after the Noise
// handshake completes successfully but before the connection transitions
// to the Established state. This allows protocol layers (e.g., NTCP2)
// to derive additional key material from the handshake hash, set up
// data-phase obfuscators, or perform post-handshake validation.
//
// If the hook returns an error, the handshake is considered failed and
// the connection reverts to the Init state.
PostHandshakeHook func(*NoiseConn) error
// AdditionalSymmetricKeyLabels specifies labels for Additional Symmetric
// Key (ASK) derivation at Split() time, per Noise spec §10.3. Each label
// produces a 32-byte key derived from the chaining key. The derived keys
// are available via NoiseConn.AdditionalSymmetricKeys() after the
// handshake completes.
//
// For NTCP2, this should be set to [][]byte{[]byte("ask")} to derive
// the ask_master used for SipHash key derivation.
AdditionalSymmetricKeyLabels [][]byte
// HandshakeRetries is the number of handshake retry attempts for accepted
// connections. 0 means no retries. Default: 0.
HandshakeRetries int
// RetryBackoff is the base delay between retry attempts for accepted
// connections. Actual delay uses exponential backoff. Default: 1 second.
RetryBackoff time.Duration
}
ListenerConfig contains configuration for creating a NoiseListener. It follows the builder pattern for optional configuration and validation.
func NewListenerConfig ¶
func NewListenerConfig(pattern string) *ListenerConfig
NewListenerConfig creates a new ListenerConfig with sensible defaults.
func (*ListenerConfig) Validate ¶
func (lc *ListenerConfig) Validate() error
Validate checks if the configuration is valid.
func (*ListenerConfig) WithAdditionalSymmetricKeyLabels ¶ added in v0.1.52
func (lc *ListenerConfig) WithAdditionalSymmetricKeyLabels(labels [][]byte) *ListenerConfig
WithAdditionalSymmetricKeyLabels sets labels for ASK derivation at Split() time. For NTCP2, use [][]byte{[]byte("ask")}.
func (*ListenerConfig) WithHandshakeRetries ¶ added in v0.1.52
func (lc *ListenerConfig) WithHandshakeRetries(retries int) *ListenerConfig
WithHandshakeRetries sets the number of handshake retry attempts for accepted connections. 0 means no retries.
func (*ListenerConfig) WithHandshakeTimeout ¶
func (lc *ListenerConfig) WithHandshakeTimeout(timeout time.Duration) *ListenerConfig
WithHandshakeTimeout sets the handshake timeout.
func (*ListenerConfig) WithModifiers ¶ added in v0.1.52
func (lc *ListenerConfig) WithModifiers(modifiers ...handshake.HandshakeModifier) *ListenerConfig
WithModifiers sets the handshake modifiers for accepted connections. Modifiers are applied in the order provided for outbound data and in reverse order for inbound data. Required for NTCP2 server-side connections.
func (*ListenerConfig) WithPostHandshakeHook ¶ added in v0.1.52
func (lc *ListenerConfig) WithPostHandshakeHook(hook func(*NoiseConn) error) *ListenerConfig
WithPostHandshakeHook sets a callback invoked after the Noise handshake completes but before the connection transitions to the Established state.
func (*ListenerConfig) WithReadTimeout ¶
func (lc *ListenerConfig) WithReadTimeout(timeout time.Duration) *ListenerConfig
WithReadTimeout sets the read timeout for accepted connections.
func (*ListenerConfig) WithRetryBackoff ¶ added in v0.1.52
func (lc *ListenerConfig) WithRetryBackoff(backoff time.Duration) *ListenerConfig
WithRetryBackoff sets the base delay between retry attempts for accepted connections. Actual delay uses exponential backoff.
func (*ListenerConfig) WithStaticKey ¶
func (lc *ListenerConfig) WithStaticKey(key []byte) *ListenerConfig
WithStaticKey sets the static key for this listener. key must be 32 bytes for Curve25519.
func (*ListenerConfig) WithWriteTimeout ¶
func (lc *ListenerConfig) WithWriteTimeout(timeout time.Duration) *ListenerConfig
WithWriteTimeout sets the write timeout for accepted connections.
type NoiseAddr ¶
type NoiseAddr struct {
// contains filtered or unexported fields
}
NoiseAddr implements net.Addr for Noise Protocol connections. It wraps an underlying net.Addr and adds Noise-specific addressing information.
func NewNoiseAddr ¶
NewNoiseAddr creates a new NoiseAddr wrapping an underlying network address. pattern should be a valid Noise protocol pattern (e.g., "Noise_XX_25519_AESGCM_SHA256"). role should be either "initiator" or "responder".
func (*NoiseAddr) Network ¶
Network returns the network type, prefixed with "noise+" to indicate Noise wrapping. For example, "noise+tcp" for Noise over TCP or "noise+udp" for Noise over UDP.
func (*NoiseAddr) String ¶
String returns a string representation of the Noise address. Format: "noise://[pattern]/[role]/[underlying_address]" Example: "noise://Noise_XX_25519_AESGCM_SHA256/initiator/192.168.1.1:8080"
func (*NoiseAddr) Underlying ¶
Underlying returns the wrapped network address. This allows access to the original address when needed.
type NoiseConn ¶
type NoiseConn struct {
// contains filtered or unexported fields
}
NoiseConn implements net.Conn with Noise Protocol encryption. It wraps an underlying net.Conn and provides encrypted communication following the Noise Protocol Framework specification.
Thread Safety: NoiseConn is safe for concurrent use by multiple goroutines with the following guarantees:
- Read() and Write() can be called concurrently from different goroutines
- Close() can be called concurrently with other operations and will be idempotent
- GetConnectionState() and GetConnectionMetrics() are safe for concurrent access
- Handshake() operations are serialized - only one handshake can occur at a time
- All operations that check connection state are atomic and consistent
Synchronization is achieved through multiple mutexes:
- stateMutex: Protects connection state transitions (RWMutex for read-heavy access)
- handshakeMutex: Serializes handshake operations
- closeMutex: Protects close operations from concurrent execution
- Internal metrics mutex: Protects connection metrics updates
func DialNoise ¶
func DialNoise(network, addr string, config *ConnConfig) (*NoiseConn, error)
DialNoise creates a connection to the given address and wraps it with NoiseConn. This is a convenience function that combines net.Dial and NewNoiseConn. For more control over the underlying connection, use net.Dial followed by NewNoiseConn.
func DialNoiseWithHandshake ¶
func DialNoiseWithHandshake(network, addr string, config *ConnConfig) (*NoiseConn, error)
DialNoiseWithHandshake creates a connection to the given address, wraps it with NoiseConn, and performs the handshake with retry logic. This is the recommended high-level function for establishing Noise connections with automatic retry capabilities.
func DialNoiseWithHandshakeContext ¶
func DialNoiseWithHandshakeContext(ctx context.Context, network, addr string, config *ConnConfig) (*NoiseConn, error)
DialNoiseWithHandshakeContext creates a connection with context support for cancellation. It combines dialing, NoiseConn creation, and handshake with retry in a single operation.
func DialNoiseWithPool ¶
func DialNoiseWithPool(network, addr string, config *ConnConfig) (*NoiseConn, error)
DialNoiseWithPool creates a connection to the given address, checking the pool first. If a suitable connection is available in the pool, it will be reused. Otherwise, a new connection is created. The connection will be automatically returned to the pool when the NoiseConn is closed.
func DialNoiseWithPoolAndHandshake ¶
func DialNoiseWithPoolAndHandshake(network, addr string, config *ConnConfig) (*NoiseConn, error)
DialNoiseWithPoolAndHandshake creates a connection with pool support and handshake retry. It checks the pool first, creates new if needed, and performs handshake with retry logic.
func DialNoiseWithPoolAndHandshakeContext ¶
func DialNoiseWithPoolAndHandshakeContext(ctx context.Context, network, addr string, config *ConnConfig) (*NoiseConn, error)
DialNoiseWithPoolAndHandshakeContext combines pool checking, dialing, and handshake with context. It reuses a pooled raw TCP connection when available (the pool keys by conn.RemoteAddr().String(), which equals addr), wraps it in a new NoiseConn, and performs the Noise handshake. Falls back to a fresh dial if the pool is empty or the pooled connection fails the handshake.
func NewNoiseConn ¶
func NewNoiseConn(underlying net.Conn, config *ConnConfig) (*NoiseConn, error)
NewNoiseConn creates a new NoiseConn wrapping the underlying connection. The handshake must be completed before using Read/Write operations.
func WrapConn ¶
func WrapConn(conn net.Conn, config *ConnConfig) (*NoiseConn, error)
WrapConn wraps an existing net.Conn with NoiseConn. This is an alias for NewNoiseConn for consistency with the transport API.
func (*NoiseConn) AdditionalSymmetricKeys ¶ added in v0.1.52
AdditionalSymmetricKeys returns the Additional Symmetric Key (ASK) values derived during the handshake Split(), per Noise spec §10.3. Returns nil if no labels were configured or the handshake hasn't completed. The returned keys correspond 1:1 to the configured AdditionalSymmetricKeyLabels.
func (*NoiseConn) ChannelBinding ¶ added in v0.1.52
ChannelBinding returns the handshake hash (h) from the completed Noise session. This is the hash of all handshake transcript data and can be used for:
- Channel binding (tying an application-layer credential to the Noise session)
- Deriving additional key material via HKDF (e.g., NTCP2's SipHash keys)
Returns nil if the handshake has not been initiated.
Thread Safety: This method is safe for concurrent use. The underlying HandshakeState.ChannelBinding() is mutex-protected.
func (*NoiseConn) Close ¶
Close closes the connection.
Thread Safety: This method is safe for concurrent use and is idempotent. Multiple goroutines can call Close simultaneously - only the first call will perform the actual close operation, subsequent calls will return nil. The close mutex ensures atomic close operations.
func (*NoiseConn) CompleteHandshake ¶ added in v0.1.52
func (nc *NoiseConn) CompleteHandshake()
CompleteHandshake marks the connection as fully established after the final handshake message has been processed. Call this once after the last WriteHandshakeMsgToBytes / ReadHandshakeMsgFromBytes call.
func (*NoiseConn) Decrypt ¶ added in v0.1.52
Decrypt decrypts ciphertext data using the connection's cipher state without reading from the underlying connection. This allows callers to separate decryption from wire-level framing (e.g., for NTCP2's SipHash-obfuscated length prefix).
The connection must have completed the Noise handshake. Thread Safety: Same guarantees as Read().
func (*NoiseConn) Encrypt ¶ added in v0.1.52
Encrypt encrypts plaintext data using the connection's cipher state without writing to the underlying connection. This allows callers to separate encryption from wire-level framing (e.g., for NTCP2's SipHash-obfuscated length prefix).
The connection must have completed the Noise handshake. Thread Safety: Same guarantees as Write().
func (*NoiseConn) FailHandshake ¶ added in v0.1.52
func (nc *NoiseConn) FailHandshake()
FailHandshake resets the handshake state machine so that a fresh attempt can be made (or so that close/cleanup code sees a consistent state).
func (*NoiseConn) GetConnectionMetrics ¶
func (nc *NoiseConn) GetConnectionMetrics() (bytesRead, bytesWritten int64, handshakeDuration time.Duration)
GetConnectionMetrics returns the current connection statistics
func (*NoiseConn) GetConnectionState ¶
GetConnectionState returns the current connection state
Thread Safety: This method is safe for concurrent use. It uses a read lock on the state mutex, allowing multiple goroutines to read the state simultaneously while preventing inconsistent reads during state transitions.
func (*NoiseConn) GetHandshakeHash ¶ added in v0.1.52
GetHandshakeHash returns the hash of the handshake transcript from the underlying noise.HandshakeState. This can be used by protocol layers to derive post-handshake key material (e.g. SipHash keys for NTCP2 data phase).
func (*NoiseConn) GetModifierChain ¶ added in v0.1.52
func (nc *NoiseConn) GetModifierChain() *handshake.ModifierChain
GetModifierChain returns the HandshakeModifier chain from the config. Returns nil if no modifiers are configured. NTCP2 framed I/O uses this to apply PhaseData transforms (padding, obfuscation) around Encrypt/Decrypt.
func (*NoiseConn) Handshake ¶
Handshake performs a single Noise Protocol handshake attempt. This must be called before using Read/Write operations.
Handshake always performs exactly one attempt and does not use the HandshakeRetries or RetryBackoff configuration fields. To perform a handshake with automatic retries and exponential backoff, use HandshakeWithRetry instead.
Thread Safety: This method is safe for concurrent use but handshake operations are serialized. Only one handshake can be in progress at a time per connection. If multiple goroutines call Handshake concurrently, they will be queued and execute sequentially. If the handshake is already complete, subsequent calls will return immediately without error.
func (*NoiseConn) HandshakeWithRetry ¶
HandshakeWithRetry performs a handshake with retry logic based on configuration. It uses the HandshakeRetries and RetryBackoff fields from ConnConfig to control the number of attempts and exponential backoff delay between retries. If HandshakeRetries is 0 (the default), this method behaves identically to Handshake() — a single attempt with no retries. It respects context cancellation between retry attempts.
func (*NoiseConn) MixHashData ¶ added in v0.1.52
MixHashData mixes additional data into the Noise symmetric hash state. This is required by the NTCP2 spec to authenticate cleartext padding bytes that appear after AEAD frames in messages 1 and 2 (§4.4.1, §4.4.2). Call this after reading and discarding cleartext padding, passing the raw padding bytes so that the hash state stays in sync with the peer.
func (*NoiseConn) PeerStatic ¶ added in v0.1.52
PeerStatic returns the static public key provided by the remote peer during the Noise handshake. Returns nil if the handshake has not completed or if the handshake pattern does not transmit a static key.
Thread Safety: This method is safe for concurrent use. The underlying HandshakeState.PeerStatic() is mutex-protected.
func (*NoiseConn) Read ¶
Read reads data from the connection. If the handshake is not complete, it will return an error.
Thread Safety: This method is safe for concurrent use. Multiple goroutines can call Read simultaneously; calls are serialized via readMutex to protect the receive cipher state nonce counter.
func (*NoiseConn) ReadHandshakeMsgFromBytes ¶ added in v0.1.52
func (nc *NoiseConn) ReadHandshakeMsgFromBytes(phase handshake.HandshakePhase, wireData []byte) ([]byte, error)
ReadHandshakeMsgFromBytes processes raw inbound Noise handshake bytes, applies the modifier chain, runs the Noise ReadMessage, and returns the decrypted payload. The caller must supply exactly the bytes that form the wire message (no length prefix).
The caller is responsible for calling StartHandshake before the first call and CompleteHandshake after the final message.
func (*NoiseConn) RecvCipherState ¶ added in v0.1.52
func (nc *NoiseConn) RecvCipherState() *noise.CipherState
RecvCipherState returns the receive-direction CipherState for direct access by protocol layers. Returns nil before the handshake produces cipher states.
func (*NoiseConn) Rekey ¶ added in v0.1.52
Rekey triggers a rekey operation on the underlying cipher state. This advances the encryption key material per the Noise Protocol specification (encrypts 32 zero bytes with nonce 2^64-1, takes first 32 bytes as new key).
Rekey requires the handshake to be complete (connection in Established state). It is safe for concurrent use; the underlying CipherState.Rekey() is mutex-protected.
func (*NoiseConn) RemoteAddr ¶
RemoteAddr returns the remote network address.
func (*NoiseConn) RunPostHandshakeHook ¶ added in v0.1.52
RunPostHandshakeHook executes the PostHandshakeHook configured on this connection, if one is set. Protocol-specific handshake implementations (e.g. NTCP2Conn.Handshake) must call this before CompleteHandshake so that post-handshake key derivation (e.g. SipHash keys) runs correctly.
Returns nil if no hook is configured.
func (*NoiseConn) SendCipherState ¶ added in v0.1.52
func (nc *NoiseConn) SendCipherState() *noise.CipherState
SendCipherState returns the send-direction CipherState for direct access by protocol layers (e.g., NTCP2 SipHash key derivation). Returns nil before the handshake produces cipher states.
func (*NoiseConn) SetDeadline ¶
SetDeadline sets the read and write deadlines.
func (*NoiseConn) SetReadDeadline ¶
SetReadDeadline sets the read deadline.
func (*NoiseConn) SetShutdownManager ¶
func (nc *NoiseConn) SetShutdownManager(sm *ShutdownManager)
SetShutdownManager sets the shutdown manager for this connection. If a shutdown manager is set, the connection will be automatically registered for graceful shutdown coordination.
func (*NoiseConn) SetWriteDeadline ¶
SetWriteDeadline sets the write deadline.
func (*NoiseConn) StartHandshake ¶ added in v0.1.52
func (nc *NoiseConn) StartHandshake()
StartHandshake transitions the connection to the handshaking state and records the handshake start time. Call this once before the first WriteHandshakeMsgToBytes or ReadHandshakeMsgFromBytes call.
func (*NoiseConn) Underlying ¶ added in v0.1.52
Underlying returns the underlying net.Conn for direct wire access. This is needed for protocols like NTCP2 that add framing (e.g., SipHash-obfuscated length prefixes) between the TCP connection and the encrypted Noise frames.
Callers should use Encrypt/Decrypt for crypto and write/read the resulting bytes to/from this connection with their own framing.
func (*NoiseConn) Write ¶
Write writes data to the connection. If the handshake is not complete, it will return an error.
Thread Safety: This method is safe for concurrent use. Multiple goroutines can call Write simultaneously; calls are serialized via writeMutex to protect the send cipher state nonce counter.
func (*NoiseConn) WriteHandshakeMsgToBytes ¶ added in v0.1.52
func (nc *NoiseConn) WriteHandshakeMsgToBytes(phase handshake.HandshakePhase, payload []byte) ([]byte, error)
WriteHandshakeMsgToBytes executes one Noise handshake outbound step with the given payload, runs it through the modifier chain, and returns the raw wire bytes WITHOUT any length-prefix framing. This is used by protocol-specific handshake implementations (e.g. NTCP2) that require exact control over wire framing.
The caller is responsible for calling StartHandshake before the first call and CompleteHandshake after the final message.
func (*NoiseConn) ZeroKeys ¶ added in v0.1.52
func (nc *NoiseConn) ZeroKeys()
ZeroKeys securely zeroes the send and receive cipher state key material. This delegates to the upstream CipherState.ZeroKey() which overwrites the key bytes with zeros and marks the cipher states as invalid.
After calling ZeroKeys, the connection can no longer encrypt or decrypt data. Any subsequent Read/Write calls will fail.
type NoiseListener ¶
type NoiseListener struct {
// contains filtered or unexported fields
}
NoiseListener implements net.Listener for accepting Noise Protocol connections. It wraps an underlying net.Listener and provides encrypted connections following the Noise Protocol Framework specification.
func ListenNoise ¶
func ListenNoise(network, addr string, config *ListenerConfig) (*NoiseListener, error)
ListenNoise creates a listener on the given address and wraps it with NoiseListener. This is a convenience function that combines net.Listen and NewNoiseListener. For more control over the underlying listener, use net.Listen followed by NewNoiseListener.
func NewNoiseListener ¶
func NewNoiseListener(underlying net.Listener, config *ListenerConfig) (*NoiseListener, error)
NewNoiseListener creates a new NoiseListener that wraps the underlying listener. The listener will accept connections and wrap them in NoiseConn instances configured as responders (non-initiators) using the provided configuration.
func WrapListener ¶
func WrapListener(listener net.Listener, config *ListenerConfig) (*NoiseListener, error)
WrapListener wraps an existing net.Listener with NoiseListener. This is an alias for NewNoiseListener for consistency with the transport API.
func (*NoiseListener) Accept ¶
func (nl *NoiseListener) Accept() (net.Conn, error)
Accept waits for and returns the next connection to the listener. The returned connection is wrapped in a NoiseConn configured as a responder. This method is safe for concurrent use by multiple goroutines.
func (*NoiseListener) Addr ¶
func (nl *NoiseListener) Addr() net.Addr
Addr returns the listener's network address. This is a NoiseAddr that wraps the underlying listener's address.
func (*NoiseListener) Close ¶
func (nl *NoiseListener) Close() error
Close closes the listener and prevents new connections from being accepted. Any blocked Accept operations will be unblocked and return errors.
func (*NoiseListener) SetShutdownManager ¶
func (nl *NoiseListener) SetShutdownManager(sm *ShutdownManager)
SetShutdownManager sets the shutdown manager for this listener. If a shutdown manager is set, the listener will be automatically registered for graceful shutdown coordination.
type ShutdownManager ¶
type ShutdownManager struct {
// contains filtered or unexported fields
}
ShutdownManager coordinates graceful shutdown of noise components. It provides context-based cancellation and ensures proper resource cleanup with configurable timeouts for graceful vs forceful shutdown.
func GetGlobalShutdownManager ¶
func GetGlobalShutdownManager() *ShutdownManager
GetGlobalShutdownManager returns the current global shutdown manager.
func NewShutdownManager ¶
func NewShutdownManager(timeout time.Duration) *ShutdownManager
NewShutdownManager creates a new shutdown manager with the given timeout. If timeout is 0, a default of 30 seconds is used.
func (*ShutdownManager) Context ¶
func (sm *ShutdownManager) Context() context.Context
Context returns the shutdown context for monitoring shutdown signals. Components can use this context to detect when shutdown has been initiated.
func (*ShutdownManager) RegisterConnection ¶
func (sm *ShutdownManager) RegisterConnection(conn *NoiseConn)
RegisterConnection adds a connection to be managed during shutdown. The connection will be gracefully closed during shutdown.
func (*ShutdownManager) RegisterListener ¶
func (sm *ShutdownManager) RegisterListener(listener *NoiseListener)
RegisterListener adds a listener to be managed during shutdown. The listener will be gracefully closed during shutdown.
func (*ShutdownManager) Shutdown ¶
func (sm *ShutdownManager) Shutdown() error
Shutdown initiates graceful shutdown of all managed components. It closes listeners first, waits for connections to drain, then forcefully closes remaining connections after the timeout period.
func (*ShutdownManager) UnregisterConnection ¶
func (sm *ShutdownManager) UnregisterConnection(conn *NoiseConn)
UnregisterConnection removes a connection from shutdown management. This should be called when a connection is closed normally.
func (*ShutdownManager) UnregisterListener ¶
func (sm *ShutdownManager) UnregisterListener(listener *NoiseListener)
UnregisterListener removes a listener from shutdown management. This should be called when a listener is closed normally.
func (*ShutdownManager) Wait ¶
func (sm *ShutdownManager) Wait()
Wait blocks until shutdown is complete. This can be used to wait for shutdown to finish after calling Shutdown().
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
examples
|
|
|
basic
command
Example: Basic usage of the go-noise library with configurable patterns and complete handshakes
|
Example: Basic usage of the go-noise library with configurable patterns and complete handshakes |
|
comprehensive-patterns
command
|
|
|
echoclient
command
Example: Echo Client using Noise Protocol with complete handshake
|
Example: Echo Client using Noise Protocol with complete handshake |
|
echoserver
command
Example: Echo Server using Noise Protocol with complete handshake
|
Example: Echo Server using Noise Protocol with complete handshake |
|
listener
command
Example: NoiseListener demonstration with complete handshake
|
Example: NoiseListener demonstration with complete handshake |
|
modifiers
command
|
|
|
ntcp2
command
Example: NTCP2 addressing and connection demonstration for I2P router addressing
|
Example: NTCP2 addressing and connection demonstration for I2P router addressing |
|
ntcp2-config
command
Example: NTCP2Config builder pattern demonstration for I2P transport configuration This example shows how to create and configure NTCP2Config objects using the builder pattern with proper argument handling and validation.
|
Example: NTCP2Config builder pattern demonstration for I2P transport configuration This example shows how to create and configure NTCP2Config objects using the builder pattern with proper argument handling and validation. |
|
ntcp2-listener
command
Example: NTCP2Listener demonstration for I2P transport This example shows how to create and use an NTCP2Listener for accepting I2P NTCP2 transport connections with router identity management.
|
Example: NTCP2Listener demonstration for I2P transport This example shows how to create and use an NTCP2Listener for accepting I2P NTCP2 transport connections with router identity management. |
|
ntcp2-shared
Package shared provides NTCP2-specific utilities for go-noise examples
|
Package shared provides NTCP2-specific utilities for go-noise examples |
|
pool
command
Example: Connection pooling demonstration with complete handshakes
|
Example: Connection pooling demonstration with complete handshakes |
|
retry
command
Example: Handshake retry mechanisms with complete connections
|
Example: Handshake retry mechanisms with complete connections |
|
shared
Package shared provides common utilities for go-noise examples
|
Package shared provides common utilities for go-noise examples |
|
shutdown
command
Example: Graceful shutdown demonstration with complete handshakes
|
Example: Graceful shutdown demonstration with complete handshakes |
|
state
command
Example: Connection state management demonstration with complete handshakes
|
Example: Connection state management demonstration with complete handshakes |
|
transport
command
Example: Transport wrapping demonstration with complete handshakes
|
Example: Transport wrapping demonstration with complete handshakes |
|
Package handshake provides a generic modifier framework for transforming handshake data during Noise protocol exchanges.
|
Package handshake provides a generic modifier framework for transforming handshake data during Noise protocol exchanges. |
|
Package internal provides shared helpers and secure utilities used across go-noise sub-packages, including state management and cryptographic zeroing.
|
Package internal provides shared helpers and secure utilities used across go-noise sub-packages, including state management and cryptographic zeroing. |
|
replaycache
Package replaycache provides a thread-safe, bounded, TTL-based cache for detecting replayed [32]byte keys.
|
Package replaycache provides a thread-safe, bounded, TTL-based cache for detecting replayed [32]byte keys. |
|
Package ntcp2 provides NTCP2-specific implementations for the Noise Protocol Framework supporting I2P's NTCP2 transport protocol with router identity and session management.
|
Package ntcp2 provides NTCP2-specific implementations for the Noise Protocol Framework supporting I2P's NTCP2 transport protocol with router identity and session management. |
|
Package pool provides a connection pool for reusing Noise-encrypted connections across multiple Dial operations, reducing handshake overhead for repeated peers.
|
Package pool provides a connection pool for reusing Noise-encrypted connections across multiple Dial operations, reducing handshake overhead for repeated peers. |
|
Package ratchet provides ECIES-X25519-AEAD-Ratchet cryptographic primitives.
|
Package ratchet provides ECIES-X25519-AEAD-Ratchet cryptographic primitives. |
|
Package ssu2 provides SSU2-specific implementations for the Noise Protocol Framework supporting I2P's SSU2 transport protocol with UDP-based connections and NAT traversal.
|
Package ssu2 provides SSU2-specific implementations for the Noise Protocol Framework supporting I2P's SSU2 transport protocol with UDP-based connections and NAT traversal. |