#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)] pubenum ConnectionEvent { /// Cert authentication needed
AuthenticationNeeded, /// Encrypted client hello fallback occurred. The certificate for the /// public name needs to be authenticated.
EchFallbackAuthenticationNeeded {
public_name: String,
}, /// A new uni (read) or bidi stream has been opened by the peer.
NewStream {
stream_id: StreamId,
}, /// Space available in the buffer for an application write to succeed.
SendStreamWritable {
stream_id: StreamId,
}, /// New bytes available for reading.
RecvStreamReadable {
stream_id: StreamId,
}, /// Peer reset the stream.
RecvStreamReset {
stream_id: StreamId,
app_error: AppError,
}, /// Peer has sent `STOP_SENDING`
SendStreamStopSending {
stream_id: StreamId,
app_error: AppError,
}, /// Peer has acked everything sent on the stream.
SendStreamComplete {
stream_id: StreamId,
}, /// Peer increased `MAX_STREAMS`
SendStreamCreatable {
stream_type: StreamType,
}, /// Connection state change.
StateChange(State), /// The server rejected 0-RTT. /// This event invalidates all state in streams that has been created. /// Any data written to streams needs to be written again.
ZeroRttRejected,
ResumptionToken(ResumptionToken),
Datagram(Vec<u8>),
OutgoingDatagramOutcome {
id: u64,
outcome: OutgoingDatagramOutcome,
},
IncomingDatagramDropped, /// An update was received to SCONE throughput advice. /// The value is the approximate rate in bits per second; None = unknown.
SconeUpdated(Option<NonZeroU64>), /// A path migration completed; the connection is now sending on this path.
PathMigrated {
local: SocketAddr,
remote: SocketAddr,
},
}
pubfn client_0rtt_rejected(&self) { // If 0rtt rejected, must start over and existing events are no longer // relevant. self.events.borrow_mut().clear(); self.insert(ConnectionEvent::ZeroRttRejected);
}
pubfn recv_stream_complete(&self, stream_id: StreamId) { // If stopped, no longer readable. self.remove(|evt| matches!(evt, ConnectionEvent::RecvStreamReadable { stream_id: x } if*x == stream_id.as_u64()));
}
// The number of datagrams in the events queue is limited to max_queued_datagrams. // This function ensure this and deletes the oldest datagrams (head-drop) if needed. fn check_datagram_queued(&self, max_queued_datagrams: usize, stats: &mut Stats) { letmut queue = self.events.borrow_mut(); let count = queue
.iter()
.filter(|evt| matches!(evt, ConnectionEvent::Datagram(_)))
.count(); if count < max_queued_datagrams { // Below the limit. No action needed. return;
} let first = queue
.iter_mut()
.find(|evt| matches!(evt, ConnectionEvent::Datagram(_)))
.expect("Checked above"); // Remove the oldest (head-drop), replacing it with an // IncomingDatagramDropped placeholder.
*first = ConnectionEvent::IncomingDatagramDropped;
stats.incoming_datagram_dropped += 1;
}
// Fill the queue to capacity, verify that and that there are no drops yet. let e = ConnectionEvents::default(); letmut stats = Stats::default();
e.add_datagram(MAX_QUEUED, &[1], &mut stats);
e.add_datagram(MAX_QUEUED, &[2], &mut stats);
assert_eq!(stats.incoming_datagram_dropped, 0);
assert_eq!(e.events.borrow().len(), MAX_QUEUED);
// Add one more datagram - this should drop the oldest ("1").
e.add_datagram(MAX_QUEUED, &[3], &mut stats);
assert_eq!(stats.incoming_datagram_dropped, 1);
// Should have one `IncomingDatagramDropped` event + `MAX_QUEUED` datagrams.
assert_eq!(
e.events.borrow().iter().collect::<Vec<_>>(),
[
&ConnectionEvent::IncomingDatagramDropped,
&ConnectionEvent::Datagram(vec![2]),
&ConnectionEvent::Datagram(vec![3]),
]
);
}
/// Previously `check_datagram_queued` had a bug that caused it to /// potentially drop an unrelated event. /// /// See <https://github.com/mozilla/neqo/pull/3105> for details. #[test] fn datagram_queue_drops_datagram_not_unrelated_event() { const MAX_QUEUED: usize = 2;
let e = ConnectionEvents::default(); letmut stats = Stats::default();
// Add unrelated event.
e.new_stream(4.into());
// Fill the queue with datagrams to capacity.
e.add_datagram(MAX_QUEUED, &[1], &mut stats);
e.add_datagram(MAX_QUEUED, &[2], &mut stats);
assert_eq!(stats.incoming_datagram_dropped, 0);
assert_eq!(e.events.borrow().len(), 1 + MAX_QUEUED);
// Add one more datagram - this should drop the oldest ("1"), not the // unrelated event.
e.add_datagram(MAX_QUEUED, &[3], &mut stats);
assert_eq!(stats.incoming_datagram_dropped, 1);
// Should have one `IncomingDatagramDropped` event + `MAX_QUEUED` datagrams.
assert_eq!(
e.events.borrow().iter().collect::<Vec<_>>(),
[
&ConnectionEvent::NewStream {
stream_id: StreamId::new(4)
},
&ConnectionEvent::IncomingDatagramDropped,
&ConnectionEvent::Datagram(vec![2]),
&ConnectionEvent::Datagram(vec![3]),
]
);
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-08-25)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.