diff --git a/quinn-proto/src/connection/mod.rs b/quinn-proto/src/connection/mod.rs index 4a48babf0..5bb792bdb 100644 --- a/quinn-proto/src/connection/mod.rs +++ b/quinn-proto/src/connection/mod.rs @@ -5007,6 +5007,7 @@ impl Connection { builder: &mut PacketBuilder<'a, 'b>, ) -> SentFrames { let pn = builder.exact_number; + let stats = &mut self.stats; let mut sent = SentFrames::default(); let is_multipath_negotiated = self.is_multipath_negotiated(); let space = &mut self.spaces[space_id]; @@ -5020,7 +5021,7 @@ impl Connection { // HANDSHAKE_DONE if !is_0rtt && mem::replace(&mut space.pending.handshake_done, false) { trace!("HANDSHAKE_DONE"); - builder.encode(frame::HandshakeDone, &mut self.stats); + builder.encode(frame::HandshakeDone, stats); sent.retransmits.get_or_create().handshake_done = true; } @@ -5031,7 +5032,7 @@ impl Connection { let reach_out = frame::ReachOut::new(*round, local_addr); if builder.frame_space_remaining() > reach_out.size() { trace!(%round, ?local_addr, "REACH_OUT"); - builder.encode(reach_out, &mut self.stats); + builder.encode(reach_out, stats); let sent_reachouts = sent .retransmits .get_or_create() @@ -5060,7 +5061,7 @@ impl Connection { let frame = frame::ObservedAddr::new(path.remote, self.next_observed_addr_seq_no); if builder.frame_space_remaining() > frame.size() { trace!(seq = %frame.seq_no, ip = %frame.ip, port = frame.port, "OBSERVED_ADDRESS"); - builder.encode(frame, &mut self.stats); + builder.encode(frame, stats); self.next_observed_addr_seq_no = self.next_observed_addr_seq_no.saturating_add(1u8); path.observed_addr_sent = true; @@ -5073,10 +5074,8 @@ impl Connection { // PING if mem::replace(&mut space.for_path(path_id).ping_pending, false) { trace!("PING"); - buf.write(frame::FrameType::Ping); + builder.encode(frame::Ping, stats); sent.non_retransmits = true; - self.stats.frame_tx.ping += 1; - qlog.frame(&Frame::Ping); } // IMMEDIATE_ACK @@ -5087,10 +5086,8 @@ impl Connection { "immediate acks must be sent in the data space" ); trace!("IMMEDIATE_ACK"); - buf.write(frame::FrameType::ImmediateAck); + builder.encode(frame::ImmediateAck, stats); sent.non_retransmits = true; - self.stats.frame_tx.immediate_ack += 1; - qlog.frame(&Frame::ImmediateAck); } // ACK diff --git a/quinn-proto/src/frame.rs b/quinn-proto/src/frame.rs index 2cddd6e31..0d0a4fffa 100644 --- a/quinn-proto/src/frame.rs +++ b/quinn-proto/src/frame.rs @@ -166,6 +166,8 @@ pub(super) enum EncodableFrame<'a> { HandshakeDone(HandshakeDone), ReachOut(ReachOut), ObservedAddr(ObservedAddr), + Ping(Ping), + ImmediateAck(ImmediateAck), } impl<'a> EncodableFrame<'a> { @@ -179,6 +181,8 @@ impl<'a> EncodableFrame<'a> { HandshakeDone(_) => FrameType::HandshakeDone, ReachOut(reach_out) => reach_out.get_type(), ObservedAddr(observed_addr) => observed_addr.get_type(), + Ping(_) => FrameType::Ping, + ImmediateAck(_) => FrameType::ImmediateAck, } } } @@ -193,6 +197,8 @@ impl<'a> Encodable for EncodableFrame<'a> { EncodableFrame::HandshakeDone(handshake_done) => handshake_done.encode(buf), EncodableFrame::ReachOut(reach_out) => reach_out.encode(buf), EncodableFrame::ObservedAddr(observed_addr) => observed_addr.encode(buf), + EncodableFrame::Ping(ping) => ping.encode(buf), + EncodableFrame::ImmediateAck(immediate_ack) => immediate_ack.encode(buf), } } } @@ -254,6 +260,22 @@ impl Encodable for HandshakeDone { } } +pub(crate) struct Ping; + +impl Encodable for Ping { + fn encode(&self, buf: &mut B) { + FrameType::Ping.encode(buf); + } +} + +pub(crate) struct ImmediateAck; + +impl Encodable for ImmediateAck { + fn encode(&self, buf: &mut B) { + FrameType::ImmediateAck.encode(buf); + } +} + #[derive(Debug, Copy, Clone, Eq, PartialEq, derive_more::Display)] #[display("STREAM")] pub struct StreamInfo(u8);