Skip to content

Commit

Permalink
Add quic_packet_header_info() to extract cid related info from quic p…
Browse files Browse the repository at this point in the history
…ackets (#333)
  • Loading branch information
iyangsj authored Jul 15, 2024
1 parent 9048ad5 commit b649842
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 3 deletions.
11 changes: 11 additions & 0 deletions include/tquic.h
Original file line number Diff line number Diff line change
Expand Up @@ -1215,6 +1215,17 @@ int quic_stream_set_context(struct quic_conn_t *conn, uint64_t stream_id, void *
*/
void *quic_stream_context(struct quic_conn_t *conn, uint64_t stream_id);

/**
* Extract the header form, version and destination connection id from the
* QUIC packet.
*/
int quic_packet_header_info(uint8_t *buf,
size_t buf_len,
uint8_t dcid_len,
bool *long_header,
uint32_t *version,
struct ConnectionId *dcid);

/**
* Create default config for HTTP3.
*/
Expand Down
24 changes: 24 additions & 0 deletions src/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1838,6 +1838,30 @@ impl crate::ConnectionIdGenerator for ConnectionIdGenerator {
}
}

/// Extract the header form, version and destination connection id from the
/// QUIC packet.
#[no_mangle]
pub extern "C" fn quic_packet_header_info(
buf: *mut u8,
buf_len: size_t,
dcid_len: u8,
long_header: &mut bool,
version: &mut u32,
dcid: &mut ConnectionId,
) -> c_int {
let buf = unsafe { slice::from_raw_parts_mut(buf, buf_len) };

match crate::PacketHeader::header_info(buf, dcid_len as usize) {
Ok((long, ver, cid)) => {
*long_header = long;
*version = ver;
*dcid = cid;
return 0;
}
Err(e) => return e.to_errno() as i32,
}
}

/// Create default config for HTTP3.
#[no_mangle]
pub extern "C" fn http3_config_new() -> *mut Http3Config {
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1150,6 +1150,7 @@ pub use crate::connection::Connection;
pub use crate::endpoint::Endpoint;
pub use crate::error::Error;
pub use crate::multipath_scheduler::MultipathAlgorithm;
pub use crate::packet::PacketHeader;
pub use crate::tls::TlsConfig;
pub use crate::tls::TlsConfigSelector;

Expand Down
55 changes: 52 additions & 3 deletions src/packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,29 @@ impl PacketHeader {
))
}

/// Extract the header form, version and destination connection id.
///
/// Return (true, version, cid) for the quic packet with a long header
/// Return (false, 0, cid) for the quic packet with a short header
/// See RFC 8999 Section 5
pub fn header_info(mut buf: &[u8], dcid_len: usize) -> Result<(bool, u32, ConnectionId)> {
let first = buf.read_u8()?;

// Decode in short header form for 1-RTT.
if !PacketHeader::long_header(first) {
let dcid = buf.read(dcid_len)?;
let dcid = ConnectionId::new(&dcid);
return Ok((false, 0, dcid));
}

// Decode in long header form.
let version = buf.read_u32()?;
let dcid_len = buf.read_u8()?;
let dcid = buf.read(dcid_len as usize)?;
let dcid = ConnectionId::new(&dcid);
Ok((true, version, dcid))
}

/// Return true if the packet has a long header.
fn long_header(header_first_byte: u8) -> bool {
header_first_byte & HEADER_LONG_FORM_BIT != 0
Expand Down Expand Up @@ -833,7 +856,13 @@ mod tests {
token=040404040404040404040404040404040404040404040404"
);
let len = initial_hdr.to_bytes(&mut buf)?;
assert_eq!((initial_hdr, len), PacketHeader::from_bytes(&mut buf, 20)?);
assert_eq!(
(initial_hdr.clone(), len),
PacketHeader::from_bytes(&mut buf, 20)?
);

let info = PacketHeader::header_info(&mut buf, 20)?;
assert_eq!(info, (true, initial_hdr.version, initial_hdr.dcid));
Ok(())
}

Expand Down Expand Up @@ -864,7 +893,13 @@ mod tests {

let mut buf = [0; 128];
let len = hsk_hdr.to_bytes(&mut buf)?;
assert_eq!((hsk_hdr, len), PacketHeader::from_bytes(&mut buf, 20)?);
assert_eq!(
(hsk_hdr.clone(), len),
PacketHeader::from_bytes(&mut buf, 20)?
);

let info = PacketHeader::header_info(&mut buf, 20)?;
assert_eq!(info, (true, hsk_hdr.version, hsk_hdr.dcid));
Ok(())
}

Expand Down Expand Up @@ -895,7 +930,13 @@ mod tests {

let mut buf = [0; 128];
let len = zero_rtt_hdr.to_bytes(&mut buf)?;
assert_eq!((zero_rtt_hdr, len), PacketHeader::from_bytes(&mut buf, 20)?);
assert_eq!(
(zero_rtt_hdr.clone(), len),
PacketHeader::from_bytes(&mut buf, 20)?
);

let info = PacketHeader::header_info(&mut buf, 20)?;
assert_eq!(info, (true, zero_rtt_hdr.version, zero_rtt_hdr.dcid));
Ok(())
}

Expand Down Expand Up @@ -939,6 +980,8 @@ mod tests {
// Note: key phase is encrypted and not parsed by from_bytes()
assert_eq!(PacketHeader::from_bytes(&mut buf, 20)?.0.key_phase, false);

let info = PacketHeader::header_info(&mut buf, 20)?;
assert_eq!(info, (false, one_rtt_hdr.version, one_rtt_hdr.dcid));
Ok(())
}

Expand Down Expand Up @@ -969,6 +1012,9 @@ mod tests {
scid=0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c"
);

let info = PacketHeader::header_info(&mut buf, 20)?;
assert_eq!(info, (true, hdr.version, hdr.dcid));

let mut br = &buf[hdr_len..];
let ver = br.read_u32()?;
assert_eq!(ver, crate::QUIC_VERSION_V1);
Expand Down Expand Up @@ -1022,6 +1068,9 @@ mod tests {
token=71756963c0a8010a0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e"
);

let info = PacketHeader::header_info(&mut buf, 20)?;
assert_eq!(info, (true, hdr.version, hdr.dcid));

verify_retry_integrity_tag(&mut buf[..len], &odcid, crate::QUIC_VERSION_V1)?;
Ok(())
}
Expand Down

0 comments on commit b649842

Please sign in to comment.