--- /dev/null
+Stream Receive Buffers
+======================
+
+This is a QUIC specific module that retains the received stream data
+until the application reads it with SSL_read() or any future stream read
+calls.
+
+Receive Buffers requirements for MVP
+------------------------------------
+
+These are the requirements that were identified for MVP:
+
+- As packets with stream frames are received in arbitrary frames the
+ received data must be stored until all the data with earlier offsets
+ are received.
+- As packets can be received before application calls SSL_read() to read
+ the data the data must be stored.
+- The application should be able to set the limit on how much data should
+ be stored. The flow controller should be used to limit the peer to not send
+ more data. Without the flow control limit a rogue peer could trigger
+ a DoS via unlimited flow of incoming stream data frames.
+- After the data is passed via SSL_read() to the application the stored
+ data can be released and flow control limit can be raised.
+- As the peer can recreate stream data frames when resending them, the
+ implementation must be able to handle properly frames with partially
+ or fully overlapping data with previously received frames.
+
+Optional Receive Buffers requirements
+-------------------------------------
+
+These are optional features of the stream receive buffers implementation.
+They are not required for MVP but they are otherwise desirable:
+
+- To support a single copy operation with a future stream read call
+ the received data should not be copied out of the decrypted packets to
+ store the data. The only information actually stored would be a list
+ of offset, length, and pointers to data, along with a pointer to the
+ decrypted QUIC packet that stores the actual frame.
+
+Proposed new public API calls
+-----------------------------
+
+```C
+int SSL_set_max_stored_stream_data(SSL *stream, size_t length);
+```
+
+This function adjusts the current data flow control limit on the `stream`
+to allow storing `length` bytes of quic stream data before it is read by
+the application.
+
+OpenSSL handles sending MAX_STREAM_DATA frames appropriately when the
+application reads the stored data.
+
+```C
+int SSL_set_max_unprocessed_packet_data(SSL *connection,
+ size_t length);
+```
+
+This sets the limit on unprocessed quic packet data `length` in bytes that
+is allowed to be allocated for the `connection`.
+See the [Other considerations](#other-considerations) section below.
+
+Interfaces to other QUIC implementation modules
+-----------------------------------------------
+
+### Front End I/O API
+
+SSL_read() copies data out of the stored buffers if available and
+eventually triggers release of stored unprocessed packet(s).
+
+SSL_peek(), SSL_pending(), SSL_has_pending() peek into the stored
+buffers for any information about the stored data.
+
+### RX Depacketizer
+
+The Receive Buffers module obtains the stream data via the ssl_queue_data()
+callback.
+
+The module uses ossl_qrx_pkt_wrap_up_ref() and ossl_qrx_pkt_wrap_release()
+functions to keep and release decrypted packets with unprocessed data.
+
+### Flow Control
+
+The Receive Buffers module provides an appropriate value for the Flow
+Control module to send MAX_DATA and MAX_STREAM_DATA frames. Details
+TBD.
+
+### QUIC Read Record Layer
+
+The Receive Buffers module needs to know whether it should stop holding
+the decrypted quic packets and start copying the stream data due to
+the limit reached. See the `SSL_set_max_unprocessed_quic_packet_data()`
+function above and the [Other considerations](#other-considerations) section
+below. Details TBD.
+
+Implementation details
+----------------------
+
+TBD
+
+Other considerations
+--------------------
+
+The peer is allowed to recreate the stream data frames. As we aim for
+a single-copy operation a rogue peer could use this to override the stored
+data limits by sending duplicate frames with only slight changes in the
+offset. For example: 1st frame - offset 0 length 1000, 2nd frame -
+offset 1 length 1000, 3rd frame - offset 2 length 1000, and so on. We
+would have to keep the packet data for all these frames which would
+effectively raise the stream data flow control limit quadratically.
+
+And this is not the only way how a rogue peer could make us occupy much
+more data than what is allowed by the stream data flow control limit
+in the single-copy scenario.
+
+Although intuitively the MAX_DATA flow control limit might be used to
+somehow limit the allocated packet buffer size, it is defined as sum
+of allowed data to be sent across all the streams in the connection instead.
+The packet buffer will contain much more data than just the stream frames
+especially with a rogue peer, that means MAX_DATA limit cannot be used
+to limit the memory occupied by packet buffers.
+
+To resolve this problem, we fall back to copying the data off the
+decrypted packet buffer once we reach a limit on unprocessed decrypted
+packets. We might also consider falling back to copying the data in case
+we receive stream data frames that are partially overlapping and one frame
+not being a subrange of the other.
+
+Because in MVP only a single bidirectional stream to receive
+any data will be supported, the MAX_DATA flow control limit should be equal
+to MAX_STREAM_DATA limit for that stream.