quic: parse gquic version Q039

Ticket: #5166
pull/7678/head
Philippe Antoine 3 years ago committed by Philippe Antoine
parent 018fef5ef8
commit b9c1d9e86b

@ -40,6 +40,7 @@ use std::convert::TryFrom;
pub struct QuicVersion(pub u32);
impl QuicVersion {
pub const Q039: QuicVersion = QuicVersion(0x51303339);
pub const Q043: QuicVersion = QuicVersion(0x51303433);
pub const Q044: QuicVersion = QuicVersion(0x51303434);
pub const Q045: QuicVersion = QuicVersion(0x51303435);
@ -56,6 +57,7 @@ impl QuicVersion {
impl From<QuicVersion> for String {
fn from(from: QuicVersion) -> Self {
match from {
QuicVersion(0x51303339) => "Q039".to_string(),
QuicVersion(0x51303433) => "Q043".to_string(),
QuicVersion(0x51303434) => "Q044".to_string(),
QuicVersion(0x51303435) => "Q045".to_string(),
@ -86,16 +88,23 @@ pub enum QuicType {
Short,
}
const QUIC_FLAG_MULTIPATH: u8 = 0x40;
const QUIC_FLAG_DCID_LEN: u8 = 0x8;
const QUIC_FLAG_NONCE: u8 = 0x4;
const QUIC_FLAG_VERSION: u8 = 0x1;
#[derive(Debug, PartialEq)]
pub struct PublicFlags {
pub is_long: bool,
pub raw: u8,
}
impl PublicFlags {
pub fn new(value: u8) -> Self {
let is_long = value & 0x80 == 0x80;
let raw = value;
PublicFlags { is_long }
PublicFlags { is_long, raw }
}
}
@ -185,27 +194,80 @@ impl QuicHeader {
}
pub(crate) fn from_bytes(
input: &[u8], dcid_len: usize,
input: &[u8], _dcid_len: usize,
) -> IResult<&[u8], QuicHeader, QuicError> {
let (rest, first) = be_u8(input)?;
let flags = PublicFlags::new(first);
if !flags.is_long {
if !flags.is_long && (flags.raw & QUIC_FLAG_MULTIPATH) == 0 {
let (mut rest, dcid) = if (flags.raw & QUIC_FLAG_DCID_LEN) != 0 {
take(8_usize)(rest)?
} else {
take(0_usize)(rest)?
};
if (flags.raw & QUIC_FLAG_NONCE) != 0 && (flags.raw & QUIC_FLAG_DCID_LEN) == 0 {
let (rest1, _) = take(32_usize)(rest)?;
rest = rest1;
}
let version_buf: &[u8];
let version;
if (flags.raw & QUIC_FLAG_VERSION) != 0 {
let (_, version_buf1) = take(4_usize)(rest)?;
let (rest1, version1) = map(be_u32, QuicVersion)(rest)?;
rest = rest1;
version = version1;
version_buf = version_buf1;
} else {
version = QuicVersion(0);
version_buf = &rest[..0];
}
let pkt_num_len = 1 + ((flags.raw & 0x30) >> 4);
let (mut rest, _pkt_num) = take(pkt_num_len)(rest)?;
if (flags.raw & QUIC_FLAG_DCID_LEN) != 0 {
let (rest1, _msg_auth_hash) = take(12_usize)(rest)?;
rest = rest1;
}
let ty = if (flags.raw & QUIC_FLAG_VERSION) != 0 {
QuicType::Initial
} else {
QuicType::Short
};
if let Ok(plength) = u16::try_from(rest.len()) {
return Ok((
rest,
QuicHeader {
flags,
ty: ty,
version: version,
version_buf: version_buf.to_vec(),
dcid: dcid.to_vec(),
scid: Vec::new(),
length: plength,
},
));
} else {
return Err(nom::Err::Error(QuicError::InvalidPacket));
}
} else if !flags.is_long {
// Decode short header
let (rest, dcid) = take(dcid_len)(rest)?;
return Ok((
rest,
QuicHeader {
flags,
ty: QuicType::Short,
version: QuicVersion(0),
version_buf: Vec::new(),
dcid: dcid.to_vec(),
scid: Vec::new(),
length: 0,
},
));
// depends on version let (rest, dcid) = take(_dcid_len)(rest)?;
if let Ok(plength) = u16::try_from(rest.len()) {
return Ok((
rest,
QuicHeader {
flags,
ty: QuicType::Short,
version: QuicVersion(0),
version_buf: Vec::new(),
dcid: Vec::new(),
scid: Vec::new(),
length: plength,
},
));
} else {
return Err(nom::Err::Error(QuicError::InvalidPacket));
}
} else {
// Decode Long header
let (_, version_buf) = take(4_usize)(rest)?;
@ -335,7 +397,13 @@ mod tests {
#[test]
fn public_flags_test() {
let pf = PublicFlags::new(0xcb);
assert_eq!(PublicFlags { is_long: true }, pf);
assert_eq!(
PublicFlags {
is_long: true,
raw: 0xcb
},
pf
);
}
const TEST_DEFAULT_CID_LENGTH: usize = 8;
@ -348,7 +416,10 @@ mod tests {
QuicHeader::from_bytes(data.as_ref(), TEST_DEFAULT_CID_LENGTH).unwrap();
assert_eq!(
QuicHeader {
flags: PublicFlags { is_long: true },
flags: PublicFlags {
is_long: true,
raw: 0xcb
},
ty: QuicType::Initial,
version: QuicVersion(0xff00001d),
version_buf: vec![0xff, 0x00, 0x00, 0x1d],
@ -372,7 +443,10 @@ mod tests {
assert_eq!(
QuicHeader {
flags: PublicFlags { is_long: true },
flags: PublicFlags {
is_long: true,
raw: 0xff
},
ty: QuicType::Initial,
version: QuicVersion::Q044,
version_buf: vec![0x51, 0x30, 0x34, 0x34],

Loading…
Cancel
Save