| Safe Haskell | None |
|---|---|
| Language | GHC2021 |
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
- data NegotiationResult
- type ProtocolId = Text
- data StreamIO = StreamIO {
- streamWrite :: ByteString -> IO ()
- streamReadByte :: IO Word8
- streamReadChunk :: Int -> IO ByteString
- streamClose :: IO ()
- negotiateInitiator :: StreamIO -> [ProtocolId] -> IO NegotiationResult
- negotiateResponder :: StreamIO -> [ProtocolId] -> IO NegotiationResult
- mkByteStreamIO :: (ByteString -> IO ()) -> IO Word8 -> IO () -> StreamIO
- mkMemoryStreamPair :: IO (StreamIO, StreamIO)
- readExactBounded :: StreamIO -> Int -> Int -> IO (Either String ByteString)
- closeQuietly :: StreamIO -> IO ()
Documentation
data NegotiationResult Source #
Result of a negotiation attempt.
Constructors
| Accepted !ProtocolId | |
| NoProtocol |
Instances
| Show NegotiationResult Source # | |
Defined in LibP2P.MultistreamSelect.Negotiation Methods showsPrec :: Int -> NegotiationResult -> ShowS # show :: NegotiationResult -> String # showList :: [NegotiationResult] -> ShowS # | |
| Eq NegotiationResult Source # | |
Defined in LibP2P.MultistreamSelect.Negotiation Methods (==) :: NegotiationResult -> NegotiationResult -> Bool # (/=) :: NegotiationResult -> NegotiationResult -> Bool # | |
type ProtocolId = Text Source #
A protocol identifier (e.g. "noise", "yamux/1.0.0").
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.
mkByteStreamIO :: (ByteString -> IO ()) -> IO Word8 -> IO () -> StreamIO Source #
Build a StreamIO from byte-level primitives: streamReadChunk
falls back to one byte per call. Correct for any consumer (chunk
reads promise at least one byte, not n), just not fast — intended
for tests and mocks built on byte queues.
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.
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 read via streamReadChunk in requests of at most
readChunkSize, keeping transient memory use proportional to the
chunk size, not to n. A chunk request never exceeds the bytes
still owed, so no byte beyond n is consumed from the stream.
I/O failures during the read (stream reset, EOF) are returned as
Left instead of propagating as IOExceptions.
closeQuietly :: StreamIO -> IO () Source #
Close a stream, swallowing any exception (best-effort EOF signal). Shared by protocol handlers that must release a stream on every exit path without letting a close-time error mask the real outcome.