in neqo-transport/src/connection/mod.rs [2155:2248]
fn write_appdata_frames(
&mut self,
builder: &mut PacketBuilder,
tokens: &mut Vec<RecoveryToken>,
now: Instant,
) {
let rtt = self.paths.primary().map_or_else(
|| RttEstimate::default().estimate(),
|p| p.borrow().rtt().estimate(),
);
let stats = &mut self.stats.borrow_mut();
let frame_stats = &mut stats.frame_tx;
if self.role == Role::Server {
if let Some(t) = self.state_signaling.write_done(builder) {
tokens.push(t);
frame_stats.handshake_done += 1;
}
}
self.streams
.write_frames(TransmissionPriority::Critical, builder, tokens, frame_stats);
if builder.is_full() {
return;
}
self.streams
.write_maintenance_frames(builder, tokens, frame_stats, now, rtt);
if builder.is_full() {
return;
}
self.streams.write_frames(
TransmissionPriority::Important,
builder,
tokens,
frame_stats,
);
if builder.is_full() {
return;
}
// NEW_CONNECTION_ID, RETIRE_CONNECTION_ID, and ACK_FREQUENCY.
self.cid_manager.write_frames(builder, tokens, frame_stats);
if builder.is_full() {
return;
}
self.paths.write_frames(builder, tokens, frame_stats);
if builder.is_full() {
return;
}
for prio in [TransmissionPriority::High, TransmissionPriority::Normal] {
self.streams
.write_frames(prio, builder, tokens, &mut stats.frame_tx);
if builder.is_full() {
return;
}
}
// Datagrams are best-effort and unreliable. Let streams starve them for now.
self.quic_datagrams.write_frames(builder, tokens, stats);
if builder.is_full() {
return;
}
// CRYPTO here only includes NewSessionTicket, plus NEW_TOKEN.
// Both of these are only used for resumption and so can be relatively low priority.
let frame_stats = &mut stats.frame_tx;
self.crypto.write_frame(
PacketNumberSpace::ApplicationData,
self.conn_params.sni_slicing_enabled(),
builder,
tokens,
frame_stats,
);
if builder.is_full() {
return;
}
self.new_token.write_frames(builder, tokens, frame_stats);
if builder.is_full() {
return;
}
self.streams
.write_frames(TransmissionPriority::Low, builder, tokens, frame_stats);
#[cfg(test)]
if let Some(w) = &mut self.test_frame_writer {
w.write_frames(builder);
}
}