@@ -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 {
329341fn 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