Skip to content

Commit 0044ddf

Browse files
committed
refactor: Share record/handshake header parsing between CH peek helpers
Extract client_hello_handshake() so looks_like_client_hello and client_hello_wants_psk both go through the same record-header + handshake-header validation. Pure dedup, no behavior change.
1 parent 01d8d46 commit 0044ddf

1 file changed

Lines changed: 24 additions & 23 deletions

File tree

src/lib.rs

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -294,25 +294,37 @@ fn is_dtls12_psk_only(config: &Config) -> bool {
294294
.is_some_and(|first| first.is_psk() && suites.all(|s| s.is_psk()))
295295
}
296296

297-
/// Lightweight structural check: does this packet look like a ClientHello?
297+
/// If `packet` is a Handshake record carrying a ClientHello, return the
298+
/// inner handshake message bytes (msg_type + length + message_seq +
299+
/// fragment_offset + fragment_length + body). Returns `None` for any
300+
/// other content type, message type, or malformed framing.
298301
///
299-
/// Used by the auto-sense server to gate the DTLS 1.2 fallback on parse
300-
/// errors. A packet that fails to parse in the DTLS 1.3 engine should
301-
/// only trigger a downgrade if it at least claims to be a ClientHello —
302-
/// otherwise random/garbage traffic could force fallback.
303-
fn looks_like_client_hello(packet: &[u8]) -> bool {
302+
/// Shared by [`looks_like_client_hello`] (structural check only) and
303+
/// [`client_hello_wants_psk`] (which inspects cipher suites further).
304+
fn client_hello_handshake(packet: &[u8]) -> Option<&[u8]> {
304305
// DTLS record header: content_type(1) + version(2) + epoch(2) + seq(6) + length(2) = 13
305306
if packet.len() < 13 || packet[0] != 0x16 {
306-
return false;
307+
return None;
307308
}
308309
let record_len = u16::from_be_bytes([packet[11], packet[12]]) as usize;
309-
let Some(record_body) = packet.get(13..13 + record_len) else {
310-
return false;
311-
};
310+
let record_body = packet.get(13..13 + record_len)?;
312311

313312
// Handshake header: msg_type(1) + length(3) + message_seq(2) +
314313
// fragment_offset(3) + fragment_length(3) = 12
315-
record_body.len() >= 12 && record_body[0] == 0x01
314+
if record_body.len() < 12 || record_body[0] != 0x01 {
315+
return None;
316+
}
317+
Some(record_body)
318+
}
319+
320+
/// Lightweight structural check: does this packet look like a ClientHello?
321+
///
322+
/// Used by the auto-sense server to gate the DTLS 1.2 fallback on parse
323+
/// errors. A packet that fails to parse in the DTLS 1.3 engine should
324+
/// only trigger a downgrade if it at least claims to be a ClientHello —
325+
/// otherwise random/garbage traffic could force fallback.
326+
fn looks_like_client_hello(packet: &[u8]) -> bool {
327+
client_hello_handshake(packet).is_some()
316328
}
317329

318330
/// Peek at a buffered DTLS 1.2 ClientHello to decide whether the auto-sense
@@ -329,21 +341,10 @@ fn looks_like_client_hello(packet: &[u8]) -> bool {
329341
fn client_hello_wants_psk(packet: &[u8], config: &Config) -> bool {
330342
use dtls12::message::Dtls12CipherSuite;
331343

332-
// DTLS record header: content_type(1) + version(2) + epoch(2) + seq(6) + length(2) = 13
333-
if packet.len() < 13 || packet[0] != 0x16 {
334-
return false;
335-
}
336-
let record_len = u16::from_be_bytes([packet[11], packet[12]]) as usize;
337-
let Some(record_body) = packet.get(13..13 + record_len) else {
344+
let Some(record_body) = client_hello_handshake(packet) else {
338345
return false;
339346
};
340347

341-
// Handshake header: msg_type(1) + length(3) + message_seq(2) +
342-
// fragment_offset(3) + fragment_length(3) = 12
343-
if record_body.len() < 12 || record_body[0] != 0x01 {
344-
return false;
345-
}
346-
347348
let frag_off =
348349
((record_body[6] as u32) << 16) | ((record_body[7] as u32) << 8) | record_body[8] as u32;
349350
if frag_off != 0 {

0 commit comments

Comments
 (0)