diff --git a/quiche/include/quiche.h b/quiche/include/quiche.h index f553873296..b4ed0ae55d 100644 --- a/quiche/include/quiche.h +++ b/quiche/include/quiche.h @@ -426,6 +426,18 @@ void quiche_conn_trace_id(const quiche_conn *conn, const uint8_t **out, size_t * // Returns the source connection ID. void quiche_conn_source_id(const quiche_conn *conn, const uint8_t **out, size_t *out_len); +typedef struct quiche_connection_id_iter quiche_connection_id_iter; + +// Returns all active source connection IDs.. +quiche_connection_id_iter *quiche_conn_source_ids(quiche_conn *conn); + +// Fetches the next id from the given iterator. Returns false if there are +// no more elements in the iterator. +bool quiche_connection_id_iter_next(quiche_connection_id_iter *iter, const uint8_t **out, size_t *out_len); + +// Frees the given path iterator object. +void quiche_connection_id_iter_free(quiche_connection_id_iter *iter); + // Returns the destination connection ID. void quiche_conn_destination_id(const quiche_conn *conn, const uint8_t **out, size_t *out_len); diff --git a/quiche/src/ffi.rs b/quiche/src/ffi.rs index d18193c53c..2d76fe268e 100644 --- a/quiche/src/ffi.rs +++ b/quiche/src/ffi.rs @@ -941,6 +941,52 @@ pub extern fn quiche_conn_trace_id( *out_len = trace_id.len(); } +/// An iterator over connection ids. +#[derive(Default)] +pub struct ConnectionIdIter<'a> { + cids: Vec>, + index: usize, +} + +impl<'a> Iterator for ConnectionIdIter<'a> { + type Item = ConnectionId<'a>; + + #[inline] + fn next(&mut self) -> Option { + let v = self.cids.get(self.index)?; + self.index += 1; + Some(v.clone()) + } +} + +#[no_mangle] +pub extern fn quiche_conn_source_ids(conn: &Connection) -> *mut ConnectionIdIter { + let vec = conn.source_ids().cloned().collect(); + Box::into_raw(Box::new(ConnectionIdIter { + cids: vec, + index: 0, + })) +} + +#[no_mangle] +pub extern fn quiche_connection_id_iter_next( + iter: &mut ConnectionIdIter, out: &mut *const u8, out_len: &mut size_t, +) -> bool { + if let Some(conn_id) = iter.next() { + let id = conn_id.as_ref(); + *out = id.as_ptr(); + *out_len = id.len(); + return true; + } + + false +} + +#[no_mangle] +pub extern fn quiche_connection_id_iter_free(iter: *mut ConnectionIdIter) { + drop(unsafe { Box::from_raw(iter) }); +} + #[no_mangle] pub extern fn quiche_conn_source_id( conn: &Connection, out: &mut *const u8, out_len: &mut size_t,