libp2p-hs-0.1.0.0: Haskell implementation of the libp2p networking stack
Safe HaskellNone
LanguageGHC2021

LibP2P.MultistreamSelect.Negotiation

Description

multistream-select protocol negotiation.

Implements Initiator and Responder roles for negotiating which protocol to use over a connection or stream.

Synopsis

Documentation

type ProtocolId = Text Source #

A protocol identifier (e.g. "noise", "yamux/1.0.0").

data StreamIO Source #

Abstraction for stream I/O to enable testing with in-memory buffers.

Constructors

StreamIO 

Fields

negotiateInitiator :: StreamIO -> [ProtocolId] -> IO NegotiationResult Source #

Negotiate as the Initiator.

Pipelines the multistream header and the first protocol proposal in a single write before reading anything, as the multistream-select spec recommends ("the initiator SHOULD pipeline the multistream protocol id and the desired protocol id in the same packet"): this saves one round trip per negotiation. It then reads the header echo and the reply to the optimistic proposal; on na it falls back to proposing the remaining protocols sequentially.

negotiateResponder :: StreamIO -> [ProtocolId] -> IO NegotiationResult Source #

Negotiate as the Responder. Receives header, then responds to the initiator's proposal.

mkMemoryStreamPair :: IO (StreamIO, StreamIO) Source #

Create an in-memory stream pair for testing using STM TQueue. Writes to stream A appear as reads on stream B and vice versa.

readExactBounded Source #

Arguments

:: StreamIO 
-> Int

Maximum acceptable length (protocol-defined cap)

-> Int

Number of bytes to read

-> IO (Either String ByteString) 

Read exactly n bytes from a stream, bounded by maxLen.

Shared by every length-delimited protocol in the stack (see issue #169): the declared length is validated against the caller's protocol-defined cap before a single byte is read or allocated, so a hostile length prefix cannot trigger an unbounded allocation. Bytes are accumulated in chunks of at most readChunkSize, keeping transient memory use proportional to the chunk size, not to n.

I/O failures during the read (stream reset, EOF) are returned as Left instead of propagating as IOExceptions.