Network System 0.1.1
High-performance modular networking library for scalable client-server applications
Loading...
Searching...
No Matches
kcenon::network::protocols::quic::stream Class Reference

QUIC stream implementation (RFC 9000 Sections 2-4) More...

#include <stream.h>

Collaboration diagram for kcenon::network::protocols::quic::stream:
Collaboration graph

Public Member Functions

 stream (uint64_t id, bool is_local, uint64_t initial_max_data=65536)
 Construct a stream.
 
 ~stream ()=default
 
 stream (const stream &)=delete
 
auto operator= (const stream &) -> stream &=delete
 
 stream (stream &&) noexcept=default
 
auto operator= (stream &&) noexcept -> stream &=default
 
auto id () const noexcept -> uint64_t
 Get stream identifier.
 
auto is_local () const noexcept -> bool
 Check if stream is locally initiated.
 
auto is_unidirectional () const noexcept -> bool
 Check if stream is unidirectional.
 
auto is_bidirectional () const noexcept -> bool
 Check if stream is bidirectional.
 
auto send_state () const noexcept -> send_stream_state
 Get send state.
 
auto can_send () const noexcept -> bool
 Check if stream can send data.
 
auto write (std::span< const uint8_t > data) -> Result< size_t >
 Write data to stream.
 
auto finish () -> VoidResult
 Mark stream as finished (send FIN)
 
auto reset (uint64_t error_code) -> VoidResult
 Reset the stream with error code.
 
auto fin_sent () const noexcept -> bool
 Check if FIN has been sent.
 
auto pending_bytes () const noexcept -> size_t
 Get number of bytes pending to send.
 
auto next_stream_frame (size_t max_size) -> std::optional< stream_frame >
 Get next STREAM frame to send.
 
void acknowledge_data (uint64_t offset, uint64_t length)
 Acknowledge sent data.
 
auto recv_state () const noexcept -> recv_stream_state
 Get receive state.
 
auto has_data () const noexcept -> bool
 Check if stream has data to read.
 
auto read (std::span< uint8_t > buffer) -> Result< size_t >
 Read data from stream.
 
auto is_fin_received () const noexcept -> bool
 Check if all data has been received.
 
auto stop_sending (uint64_t error_code) -> VoidResult
 Signal that incoming data is no longer wanted.
 
auto receive_data (uint64_t offset, std::span< const uint8_t > data, bool fin) -> VoidResult
 Receive STREAM frame data.
 
auto receive_reset (uint64_t error_code, uint64_t final_size) -> VoidResult
 Handle received RESET_STREAM frame.
 
auto receive_stop_sending (uint64_t error_code) -> VoidResult
 Handle received STOP_SENDING frame.
 
void set_max_send_data (uint64_t max)
 Set peer's MAX_STREAM_DATA (our send limit)
 
auto max_send_data () const noexcept -> uint64_t
 Get peer's MAX_STREAM_DATA.
 
auto available_send_window () const noexcept -> size_t
 Get available send window.
 
void set_max_recv_data (uint64_t max)
 Update our MAX_STREAM_DATA (peer's send limit)
 
auto max_recv_data () const noexcept -> uint64_t
 Get our MAX_STREAM_DATA.
 
auto bytes_consumed () const noexcept -> uint64_t
 Get bytes consumed from receive buffer.
 
auto should_send_max_stream_data () const noexcept -> bool
 Check if MAX_STREAM_DATA frame should be sent.
 
auto generate_max_stream_data () -> std::optional< uint64_t >
 Generate MAX_STREAM_DATA frame if needed.
 
auto reset_error_code () const noexcept -> std::optional< uint64_t >
 Get reset error code (if stream was reset)
 
auto stop_sending_error_code () const noexcept -> std::optional< uint64_t >
 Get stop sending error code (if STOP_SENDING received)
 

Private Member Functions

void reassemble_data ()
 
void update_send_state ()
 
void update_recv_state ()
 

Private Attributes

uint64_t id_
 
bool is_local_
 
send_stream_state send_state_ {send_stream_state::ready}
 
std::deque< uint8_t > send_buffer_
 
uint64_t send_offset_ {0}
 
uint64_t acked_offset_ {0}
 
bool fin_sent_ {false}
 
bool fin_acked_ {false}
 
recv_stream_state recv_state_ {recv_stream_state::recv}
 
std::map< uint64_t, std::vector< uint8_t > > recv_buffer_
 
std::deque< uint8_t > recv_ready_
 
uint64_t recv_offset_ {0}
 
bool recv_fin_ {false}
 
std::optional< uint64_t > final_size_
 
uint64_t max_send_offset_ {0}
 
uint64_t max_recv_offset_ {65536}
 
uint64_t recv_window_size_ {65536}
 
std::optional< uint64_t > reset_error_code_
 
std::optional< uint64_t > stop_sending_error_code_
 

Static Private Attributes

static constexpr double window_update_threshold_ {0.5}
 

Detailed Description

QUIC stream implementation (RFC 9000 Sections 2-4)

A QUIC stream is an ordered, reliable, bidirectional or unidirectional byte stream within a QUIC connection.

Definition at line 146 of file stream.h.

Constructor & Destructor Documentation

◆ stream() [1/3]

kcenon::network::protocols::quic::stream::stream ( uint64_t id,
bool is_local,
uint64_t initial_max_data = 65536 )
explicit

Construct a stream.

Parameters
idStream identifier
is_localTrue if locally initiated
initial_max_dataInitial flow control limit

Definition at line 13 of file stream.cpp.

◆ ~stream()

kcenon::network::protocols::quic::stream::~stream ( )
default

◆ stream() [2/3]

kcenon::network::protocols::quic::stream::stream ( const stream & )
delete

◆ stream() [3/3]

kcenon::network::protocols::quic::stream::stream ( stream && )
defaultnoexcept

Member Function Documentation

◆ acknowledge_data()

void kcenon::network::protocols::quic::stream::acknowledge_data ( uint64_t offset,
uint64_t length )

Acknowledge sent data.

Parameters
offsetStart offset of acknowledged data
lengthLength of acknowledged data

Definition at line 169 of file stream.cpp.

170{
171 // Track acknowledgments
172 if (offset + length > acked_offset_) {
173 // Simple implementation: assume in-order ACKs
174 acked_offset_ = offset + length;
175 }
176
177 // Check if FIN is acknowledged
178 if (fin_sent_ && send_buffer_.empty() && acked_offset_ >= send_offset_) {
179 fin_acked_ = true;
180 }
181
183}
std::deque< uint8_t > send_buffer_
Definition stream.h:386

References acked_offset_, fin_acked_, fin_sent_, send_buffer_, send_offset_, and update_send_state().

Here is the call graph for this function:

◆ available_send_window()

auto kcenon::network::protocols::quic::stream::available_send_window ( ) const -> size_t
nodiscardnoexcept

Get available send window.

Definition at line 365 of file stream.cpp.

366{
367 const uint64_t sent = send_offset_ + send_buffer_.size();
368 if (sent >= max_send_offset_) {
369 return 0;
370 }
371 return static_cast<size_t>(max_send_offset_ - sent);
372}

References max_send_offset_, send_buffer_, and send_offset_.

◆ bytes_consumed()

auto kcenon::network::protocols::quic::stream::bytes_consumed ( ) const -> uint64_t
inlinenodiscardnoexcept

Get bytes consumed from receive buffer.

Definition at line 347 of file stream.h.

References recv_offset_.

◆ can_send()

auto kcenon::network::protocols::quic::stream::can_send ( ) const -> bool
nodiscardnoexcept

Check if stream can send data.

Definition at line 26 of file stream.cpp.

27{
28 if (is_unidirectional() && !is_local_) {
29 // Cannot send on peer-initiated unidirectional stream
30 return false;
31 }
32
33 switch (send_state_) {
36 return true;
37 default:
38 return false;
39 }
40}
auto is_unidirectional() const noexcept -> bool
Check if stream is unidirectional.
Definition stream.h:184

References is_local_, is_unidirectional(), kcenon::network::protocols::quic::ready, kcenon::network::protocols::quic::send, and send_state_.

Here is the call graph for this function:

◆ fin_sent()

auto kcenon::network::protocols::quic::stream::fin_sent ( ) const -> bool
inlinenodiscardnoexcept

Check if FIN has been sent.

Definition at line 234 of file stream.h.

234{ return fin_sent_; }

References fin_sent_.

◆ finish()

auto kcenon::network::protocols::quic::stream::finish ( ) -> VoidResult
nodiscard

Mark stream as finished (send FIN)

Returns
Success or error

Definition at line 76 of file stream.cpp.

77{
78 if (!can_send()) {
80 "Stream cannot be finished in current state",
81 "quic::stream");
82 }
83
84 if (fin_sent_) {
86 "FIN already sent",
87 "quic::stream");
88 }
89
90 fin_sent_ = true;
92 return ok();
93}
auto can_send() const noexcept -> bool
Check if stream can send data.
Definition stream.cpp:26
VoidResult error_void(int code, const std::string &message, const std::string &source="network_system", const std::string &details="")
VoidResult ok()

References kcenon::network::error_void(), kcenon::network::ok(), and kcenon::network::protocols::quic::stream_error::stream_state_error.

Here is the call graph for this function:

◆ generate_max_stream_data()

auto kcenon::network::protocols::quic::stream::generate_max_stream_data ( ) -> std::optional<uint64_t>
nodiscard

Generate MAX_STREAM_DATA frame if needed.

Returns
New MAX_STREAM_DATA value or nullopt

Definition at line 391 of file stream.cpp.

392{
394 return std::nullopt;
395 }
396
397 // Increase the window
399 return max_recv_offset_;
400}
auto should_send_max_stream_data() const noexcept -> bool
Check if MAX_STREAM_DATA frame should be sent.
Definition stream.cpp:381

◆ has_data()

auto kcenon::network::protocols::quic::stream::has_data ( ) const -> bool
nodiscardnoexcept

Check if stream has data to read.

Definition at line 189 of file stream.cpp.

190{
191 return !recv_ready_.empty();
192}
std::deque< uint8_t > recv_ready_
Definition stream.h:395

References recv_ready_.

◆ id()

auto kcenon::network::protocols::quic::stream::id ( ) const -> uint64_t
inlinenodiscardnoexcept

Get stream identifier.

Definition at line 174 of file stream.h.

174{ return id_; }

References id_.

◆ is_bidirectional()

auto kcenon::network::protocols::quic::stream::is_bidirectional ( ) const -> bool
inlinenodiscardnoexcept

Check if stream is bidirectional.

Definition at line 192 of file stream.h.

193 {
195 }
constexpr auto is_bidirectional(uint64_t stream_id) noexcept -> bool
Check if stream is bidirectional.
Definition stream.h:60

References id_, and kcenon::network::protocols::quic::stream_id_type::is_bidirectional().

Here is the call graph for this function:

◆ is_fin_received()

auto kcenon::network::protocols::quic::stream::is_fin_received ( ) const -> bool
inlinenodiscardnoexcept

Check if all data has been received.

Definition at line 279 of file stream.h.

References recv_fin_.

◆ is_local()

auto kcenon::network::protocols::quic::stream::is_local ( ) const -> bool
inlinenodiscardnoexcept

Check if stream is locally initiated.

Definition at line 179 of file stream.h.

179{ return is_local_; }

References is_local_.

◆ is_unidirectional()

auto kcenon::network::protocols::quic::stream::is_unidirectional ( ) const -> bool
inlinenodiscardnoexcept

Check if stream is unidirectional.

Definition at line 184 of file stream.h.

185 {
187 }
constexpr auto is_unidirectional(uint64_t stream_id) noexcept -> bool
Check if stream is unidirectional.
Definition stream.h:68

References id_, and kcenon::network::protocols::quic::stream_id_type::is_unidirectional().

Referenced by can_send().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ max_recv_data()

auto kcenon::network::protocols::quic::stream::max_recv_data ( ) const -> uint64_t
inlinenodiscardnoexcept

Get our MAX_STREAM_DATA.

Definition at line 342 of file stream.h.

342{ return max_recv_offset_; }

References max_recv_offset_.

◆ max_send_data()

auto kcenon::network::protocols::quic::stream::max_send_data ( ) const -> uint64_t
inlinenodiscardnoexcept

Get peer's MAX_STREAM_DATA.

Definition at line 326 of file stream.h.

326{ return max_send_offset_; }

References max_send_offset_.

◆ next_stream_frame()

auto kcenon::network::protocols::quic::stream::next_stream_frame ( size_t max_size) -> std::optional<stream_frame>
nodiscard

Get next STREAM frame to send.

Parameters
max_sizeMaximum frame size
Returns
Optional STREAM frame or nullopt if no data

Definition at line 111 of file stream.cpp.

112{
113 if (send_buffer_.empty() && !fin_sent_) {
114 return std::nullopt;
115 }
116
117 // Check if we have pending data or need to send FIN
118 if (send_buffer_.empty() && fin_sent_ && !fin_acked_) {
119 // Send FIN-only frame
120 stream_frame frame;
121 frame.stream_id = id_;
122 frame.offset = send_offset_;
123 frame.fin = true;
124 return frame;
125 }
126
127 if (send_buffer_.empty()) {
128 return std::nullopt;
129 }
130
131 // Calculate how much we can send (considering flow control)
132 const auto window_available = available_send_window();
133 if (window_available == 0) {
134 return std::nullopt;
135 }
136
137 // Reserve space for frame header (stream_id + offset + length as varints)
138 // Maximum varint size is 8 bytes each, plus 1 byte for frame type
139 constexpr size_t max_header_size = 1 + 8 + 8 + 8;
140 if (max_size <= max_header_size) {
141 return std::nullopt;
142 }
143
144 const size_t max_payload = max_size - max_header_size;
145 const size_t to_send = std::min({send_buffer_.size(), window_available, max_payload});
146
147 stream_frame frame;
148 frame.stream_id = id_;
149 frame.offset = send_offset_;
150 frame.data.reserve(to_send);
151
152 // Copy data from buffer
153 for (size_t i = 0; i < to_send; ++i) {
154 frame.data.push_back(send_buffer_[i]);
155 }
156
157 // Remove sent data from buffer
158 send_buffer_.erase(send_buffer_.begin(), send_buffer_.begin() + to_send);
159 send_offset_ += to_send;
160
161 // Set FIN if this is the last data and FIN was requested
162 if (fin_sent_ && send_buffer_.empty()) {
163 frame.fin = true;
164 }
165
166 return frame;
167}
auto available_send_window() const noexcept -> size_t
Get available send window.
Definition stream.cpp:365
std::variant< padding_frame, ping_frame, ack_frame, reset_stream_frame, stop_sending_frame, crypto_frame, new_token_frame, stream_frame, max_data_frame, max_stream_data_frame, max_streams_frame, data_blocked_frame, stream_data_blocked_frame, streams_blocked_frame, new_connection_id_frame, retire_connection_id_frame, path_challenge_frame, path_response_frame, connection_close_frame, handshake_done_frame > frame
Variant type holding any QUIC frame.

References kcenon::network::protocols::quic::stream_frame::stream_id.

◆ operator=() [1/2]

auto kcenon::network::protocols::quic::stream::operator= ( const stream & ) -> stream &=delete
delete

◆ operator=() [2/2]

auto kcenon::network::protocols::quic::stream::operator= ( stream && ) -> stream &=default
defaultnoexcept

◆ pending_bytes()

auto kcenon::network::protocols::quic::stream::pending_bytes ( ) const -> size_t
inlinenodiscardnoexcept

Get number of bytes pending to send.

Definition at line 239 of file stream.h.

239{ return send_buffer_.size(); }

References send_buffer_.

◆ read()

auto kcenon::network::protocols::quic::stream::read ( std::span< uint8_t > buffer) -> Result<size_t>
nodiscard

Read data from stream.

Parameters
bufferBuffer to read into
Returns
Number of bytes read or error

Definition at line 194 of file stream.cpp.

195{
196 if (is_unidirectional() && is_local_) {
197 // Cannot receive on locally-initiated unidirectional stream
199 "Cannot read from local unidirectional stream",
200 "quic::stream");
201 }
202
205 "Stream was reset by peer",
206 "quic::stream");
207 }
208
209 if (recv_ready_.empty()) {
210 if (recv_fin_ && recv_buffer_.empty()) {
211 // All data has been read and FIN was received
213 return ok(static_cast<size_t>(0));
214 }
215 return ok(static_cast<size_t>(0));
216 }
217
218 size_t to_read = std::min(buffer.size(), recv_ready_.size());
219 for (size_t i = 0; i < to_read; ++i) {
220 buffer[i] = recv_ready_[i];
221 }
222
223 recv_ready_.erase(recv_ready_.begin(), recv_ready_.begin() + static_cast<std::ptrdiff_t>(to_read));
224
225 // Update receive state
227
228 return ok(std::move(to_read));
229}
std::map< uint64_t, std::vector< uint8_t > > recv_buffer_
Definition stream.h:394
@ error
Black hole detected, reset to base.
@ data_read
All data read by application (terminal)

References kcenon::network::protocols::quic::data_read, kcenon::network::protocols::quic::error, kcenon::network::ok(), kcenon::network::protocols::quic::reset_recvd, kcenon::network::protocols::quic::stream_error::stream_reset, and kcenon::network::protocols::quic::stream_error::stream_state_error.

Here is the call graph for this function:

◆ reassemble_data()

void kcenon::network::protocols::quic::stream::reassemble_data ( )
private

Definition at line 406 of file stream.cpp.

407{
408 while (!recv_buffer_.empty()) {
409 auto it = recv_buffer_.find(recv_offset_);
410 if (it == recv_buffer_.end()) {
411 break; // Gap in data
412 }
413
414 recv_ready_.insert(recv_ready_.end(), it->second.begin(), it->second.end());
415 recv_offset_ += it->second.size();
416 recv_buffer_.erase(it);
417 }
418}

References recv_buffer_, recv_offset_, and recv_ready_.

◆ receive_data()

auto kcenon::network::protocols::quic::stream::receive_data ( uint64_t offset,
std::span< const uint8_t > data,
bool fin ) -> VoidResult
nodiscard

Receive STREAM frame data.

Parameters
offsetData offset in stream
dataFrame data
finTrue if this is the final frame
Returns
Success or error

Definition at line 243 of file stream.cpp.

245{
246 if (is_unidirectional() && is_local_) {
248 "Cannot receive on local unidirectional stream",
249 "quic::stream");
250 }
251
255 "Stream was reset",
256 "quic::stream");
257 }
258
259 // Check for final size violations
260 if (final_size_.has_value()) {
261 if (offset + data.size() > *final_size_) {
263 "Data exceeds final size",
264 "quic::stream");
265 }
266 }
267
268 if (fin) {
269 const uint64_t new_final_size = offset + data.size();
270 if (final_size_.has_value() && *final_size_ != new_final_size) {
272 "Final size changed",
273 "quic::stream");
274 }
275 final_size_ = new_final_size;
276 recv_fin_ = true;
277 }
278
279 // Check flow control
280 if (offset + data.size() > max_recv_offset_) {
282 "Received data exceeds flow control limit",
283 "quic::stream");
284 }
285
286 // Handle data placement
287 if (offset < recv_offset_) {
288 // Overlapping retransmission
289 const size_t overlap = static_cast<size_t>(recv_offset_ - offset);
290 if (overlap >= data.size()) {
291 // Entirely duplicate, ignore
293 return ok();
294 }
295 // Trim leading overlap
296 offset = recv_offset_;
297 data = data.subspan(overlap);
298 }
299
300 if (offset == recv_offset_) {
301 // Contiguous data - append directly
302 recv_ready_.insert(recv_ready_.end(), data.begin(), data.end());
303 recv_offset_ += data.size();
304
305 // Try to reassemble any buffered data
307 } else {
308 // Gap in data - buffer for later
309 recv_buffer_[offset] = std::vector<uint8_t>(data.begin(), data.end());
310 }
311
313 return ok();
314}
std::optional< uint64_t > final_size_
Definition stream.h:398
@ reset_read
Reset acknowledged by application (terminal)

References kcenon::network::error_void(), kcenon::network::protocols::quic::stream_error::final_size_error, kcenon::network::protocols::quic::stream_error::flow_control_error, kcenon::network::ok(), kcenon::network::protocols::quic::reset_read, kcenon::network::protocols::quic::reset_recvd, and kcenon::network::protocols::quic::stream_error::stream_state_error.

Here is the call graph for this function:

◆ receive_reset()

auto kcenon::network::protocols::quic::stream::receive_reset ( uint64_t error_code,
uint64_t final_size ) -> VoidResult
nodiscard

Handle received RESET_STREAM frame.

Parameters
error_codeError code from peer
final_sizeFinal size of stream
Returns
Success or error

Definition at line 316 of file stream.cpp.

317{
318 if (is_unidirectional() && is_local_) {
320 "Cannot receive reset on local unidirectional stream",
321 "quic::stream");
322 }
323
324 // Check final size consistency
325 if (final_size_.has_value() && *final_size_ != final_size) {
327 "Reset final size differs from previously received",
328 "quic::stream");
329 }
330
331 final_size_ = final_size;
334
335 // Clear buffered data
336 recv_buffer_.clear();
337
338 return ok();
339}
std::optional< uint64_t > reset_error_code_
Definition stream.h:409
error_code
HTTP/2 error codes (RFC 7540 Section 7)
Definition frame.h:471

References kcenon::network::error_void(), kcenon::network::protocols::quic::stream_error::final_size_error, kcenon::network::ok(), kcenon::network::protocols::quic::reset_recvd, and kcenon::network::protocols::quic::stream_error::stream_state_error.

Here is the call graph for this function:

◆ receive_stop_sending()

auto kcenon::network::protocols::quic::stream::receive_stop_sending ( uint64_t error_code) -> VoidResult
nodiscard

Handle received STOP_SENDING frame.

Parameters
error_codeError code from peer
Returns
Success or error

Definition at line 341 of file stream.cpp.

342{
343 if (!can_send()) {
345 "Cannot handle STOP_SENDING in current state",
346 "quic::stream");
347 }
348
350 // The sender SHOULD reset the stream in response
351 return ok();
352}
std::optional< uint64_t > stop_sending_error_code_
Definition stream.h:410

References kcenon::network::error_void(), kcenon::network::ok(), and kcenon::network::protocols::quic::stream_error::stream_state_error.

Here is the call graph for this function:

◆ recv_state()

auto kcenon::network::protocols::quic::stream::recv_state ( ) const -> recv_stream_state
inlinenodiscardnoexcept

Get receive state.

Definition at line 262 of file stream.h.

262{ return recv_state_; }

References recv_state_.

◆ reset()

auto kcenon::network::protocols::quic::stream::reset ( uint64_t error_code) -> VoidResult
nodiscard

Reset the stream with error code.

Parameters
error_codeApplication error code
Returns
Success or error

Definition at line 95 of file stream.cpp.

96{
101 "Stream already in terminal state",
102 "quic::stream");
103 }
104
107 send_buffer_.clear();
108 return ok();
109}
@ reset_recvd
Reset acknowledged by peer (terminal)
@ data_recvd
All data acknowledged (terminal)

References kcenon::network::protocols::quic::data_recvd, kcenon::network::error_void(), kcenon::network::ok(), kcenon::network::protocols::quic::reset_recvd, kcenon::network::protocols::quic::reset_sent, and kcenon::network::protocols::quic::stream_error::stream_state_error.

Here is the call graph for this function:

◆ reset_error_code()

auto kcenon::network::protocols::quic::stream::reset_error_code ( ) const -> std::optional<uint64_t>
inlinenodiscardnoexcept

Get reset error code (if stream was reset)

Definition at line 367 of file stream.h.

368 {
369 return reset_error_code_;
370 }

References reset_error_code_.

◆ send_state()

auto kcenon::network::protocols::quic::stream::send_state ( ) const -> send_stream_state
inlinenodiscardnoexcept

Get send state.

Definition at line 204 of file stream.h.

204{ return send_state_; }

References send_state_.

◆ set_max_recv_data()

void kcenon::network::protocols::quic::stream::set_max_recv_data ( uint64_t max)

Update our MAX_STREAM_DATA (peer's send limit)

Parameters
maxMaximum data peer can send

Definition at line 374 of file stream.cpp.

375{
376 if (max > max_recv_offset_) {
377 max_recv_offset_ = max;
378 }
379}

References max_recv_offset_.

◆ set_max_send_data()

void kcenon::network::protocols::quic::stream::set_max_send_data ( uint64_t max)

Set peer's MAX_STREAM_DATA (our send limit)

Parameters
maxMaximum data we can send

Definition at line 358 of file stream.cpp.

359{
360 if (max > max_send_offset_) {
361 max_send_offset_ = max;
362 }
363}

References max_send_offset_.

◆ should_send_max_stream_data()

auto kcenon::network::protocols::quic::stream::should_send_max_stream_data ( ) const -> bool
nodiscardnoexcept

Check if MAX_STREAM_DATA frame should be sent.

Definition at line 381 of file stream.cpp.

382{
383 // Send update when we've consumed more than threshold of the window
384 const uint64_t consumed = recv_offset_;
385 const uint64_t threshold = static_cast<uint64_t>(
387
388 return consumed > (max_recv_offset_ - recv_window_size_ + threshold);
389}
static constexpr double window_update_threshold_
Definition stream.h:406

References max_recv_offset_, recv_offset_, recv_window_size_, and window_update_threshold_.

◆ stop_sending()

auto kcenon::network::protocols::quic::stream::stop_sending ( uint64_t error_code) -> VoidResult
nodiscard

Signal that incoming data is no longer wanted.

Parameters
error_codeApplication error code
Returns
Success or error

Definition at line 231 of file stream.cpp.

232{
233 if (is_unidirectional() && is_local_) {
235 "Cannot stop sending on local unidirectional stream",
236 "quic::stream");
237 }
238
240 return ok();
241}

References kcenon::network::error_void(), kcenon::network::ok(), and kcenon::network::protocols::quic::stream_error::stream_state_error.

Here is the call graph for this function:

◆ stop_sending_error_code()

auto kcenon::network::protocols::quic::stream::stop_sending_error_code ( ) const -> std::optional<uint64_t>
inlinenodiscardnoexcept

Get stop sending error code (if STOP_SENDING received)

Definition at line 375 of file stream.h.

376 {
378 }

References stop_sending_error_code_.

◆ update_recv_state()

◆ update_send_state()

void kcenon::network::protocols::quic::stream::update_send_state ( )
private

Definition at line 420 of file stream.cpp.

421{
422 switch (send_state_) {
424 if (!send_buffer_.empty()) {
426 }
427 break;
428
430 if (fin_sent_ && send_buffer_.empty()) {
432 }
433 break;
434
436 if (fin_acked_) {
438 }
439 break;
440
442 // Wait for acknowledgment
443 break;
444
447 // Terminal states
448 break;
449 }
450}

References kcenon::network::protocols::quic::data_recvd, kcenon::network::protocols::quic::data_sent, fin_acked_, fin_sent_, kcenon::network::protocols::quic::ready, kcenon::network::protocols::quic::reset_recvd, kcenon::network::protocols::quic::reset_sent, kcenon::network::protocols::quic::send, send_buffer_, and send_state_.

Referenced by acknowledge_data().

Here is the caller graph for this function:

◆ write()

auto kcenon::network::protocols::quic::stream::write ( std::span< const uint8_t > data) -> Result<size_t>
nodiscard

Write data to stream.

Parameters
dataData to write
Returns
Number of bytes written or error

Definition at line 42 of file stream.cpp.

43{
44 if (!can_send()) {
46 "Stream cannot send data in current state",
47 "quic::stream");
48 }
49
50 if (fin_sent_) {
52 "Cannot write after FIN sent",
53 "quic::stream");
54 }
55
56 // Check flow control
57 const auto available = available_send_window();
58 if (available == 0) {
60 "Send window exhausted",
61 "quic::stream");
62 }
63
64 // Write up to available window
65 size_t to_write = std::min(data.size(), available);
66 send_buffer_.insert(send_buffer_.end(), data.begin(), data.begin() + static_cast<std::ptrdiff_t>(to_write));
67
68 // Update state
71 }
72
73 return ok(std::move(to_write));
74}

References kcenon::network::protocols::quic::error, kcenon::network::protocols::quic::stream_error::flow_control_error, kcenon::network::ok(), kcenon::network::protocols::quic::ready, kcenon::network::protocols::quic::send, and kcenon::network::protocols::quic::stream_error::stream_state_error.

Here is the call graph for this function:

Member Data Documentation

◆ acked_offset_

uint64_t kcenon::network::protocols::quic::stream::acked_offset_ {0}
private

Definition at line 388 of file stream.h.

388{0}; // Highest contiguously acknowledged

Referenced by acknowledge_data().

◆ fin_acked_

bool kcenon::network::protocols::quic::stream::fin_acked_ {false}
private

Definition at line 390 of file stream.h.

390{false};

Referenced by acknowledge_data(), and update_send_state().

◆ fin_sent_

bool kcenon::network::protocols::quic::stream::fin_sent_ {false}
private

Definition at line 389 of file stream.h.

389{false};

Referenced by acknowledge_data(), fin_sent(), and update_send_state().

◆ final_size_

std::optional<uint64_t> kcenon::network::protocols::quic::stream::final_size_
private

Definition at line 398 of file stream.h.

Referenced by update_recv_state().

◆ id_

uint64_t kcenon::network::protocols::quic::stream::id_
private

Definition at line 381 of file stream.h.

Referenced by id(), is_bidirectional(), and is_unidirectional().

◆ is_local_

bool kcenon::network::protocols::quic::stream::is_local_
private

Definition at line 382 of file stream.h.

Referenced by can_send(), and is_local().

◆ max_recv_offset_

uint64_t kcenon::network::protocols::quic::stream::max_recv_offset_ {65536}
private

Definition at line 404 of file stream.h.

404{65536}; // Our MAX_STREAM_DATA

Referenced by max_recv_data(), set_max_recv_data(), and should_send_max_stream_data().

◆ max_send_offset_

uint64_t kcenon::network::protocols::quic::stream::max_send_offset_ {0}
private

Definition at line 401 of file stream.h.

401{0}; // Peer's MAX_STREAM_DATA

Referenced by available_send_window(), max_send_data(), and set_max_send_data().

◆ recv_buffer_

std::map<uint64_t, std::vector<uint8_t> > kcenon::network::protocols::quic::stream::recv_buffer_
private

Definition at line 394 of file stream.h.

Referenced by reassemble_data().

◆ recv_fin_

bool kcenon::network::protocols::quic::stream::recv_fin_ {false}
private

Definition at line 397 of file stream.h.

397{false};

Referenced by is_fin_received(), and update_recv_state().

◆ recv_offset_

uint64_t kcenon::network::protocols::quic::stream::recv_offset_ {0}
private

Definition at line 396 of file stream.h.

396{0}; // Next expected offset

Referenced by bytes_consumed(), reassemble_data(), should_send_max_stream_data(), and update_recv_state().

◆ recv_ready_

std::deque<uint8_t> kcenon::network::protocols::quic::stream::recv_ready_
private

Definition at line 395 of file stream.h.

Referenced by has_data(), reassemble_data(), and update_recv_state().

◆ recv_state_

recv_stream_state kcenon::network::protocols::quic::stream::recv_state_ {recv_stream_state::recv}
private

Definition at line 393 of file stream.h.

Referenced by recv_state(), and update_recv_state().

◆ recv_window_size_

uint64_t kcenon::network::protocols::quic::stream::recv_window_size_ {65536}
private

Definition at line 405 of file stream.h.

405{65536};

Referenced by should_send_max_stream_data().

◆ reset_error_code_

std::optional<uint64_t> kcenon::network::protocols::quic::stream::reset_error_code_
private

Definition at line 409 of file stream.h.

Referenced by reset_error_code().

◆ send_buffer_

std::deque<uint8_t> kcenon::network::protocols::quic::stream::send_buffer_
private

◆ send_offset_

uint64_t kcenon::network::protocols::quic::stream::send_offset_ {0}
private

Definition at line 387 of file stream.h.

387{0}; // Next byte to send

Referenced by acknowledge_data(), and available_send_window().

◆ send_state_

send_stream_state kcenon::network::protocols::quic::stream::send_state_ {send_stream_state::ready}
private

Definition at line 385 of file stream.h.

Referenced by can_send(), send_state(), and update_send_state().

◆ stop_sending_error_code_

std::optional<uint64_t> kcenon::network::protocols::quic::stream::stop_sending_error_code_
private

Definition at line 410 of file stream.h.

Referenced by stop_sending_error_code().

◆ window_update_threshold_

double kcenon::network::protocols::quic::stream::window_update_threshold_ {0.5}
staticconstexprprivate

Definition at line 406 of file stream.h.

406{0.5};

Referenced by should_send_max_stream_data().


The documentation for this class was generated from the following files: