@@ -10,16 +10,22 @@ use crate::{
10
10
server,
11
11
server:: ServerProviders ,
12
12
} ;
13
+ use s2n_codec:: DecoderBufferMut ;
13
14
use s2n_quic_core:: {
14
15
crypto:: tls,
15
16
dc:: testing:: MockDcEndpoint ,
16
- event:: { api:: DcState , Timestamp } ,
17
+ event:: {
18
+ api:: { DatagramDropReason , DcState , EndpointDatagramDropped , EndpointMeta , Subject } ,
19
+ Timestamp ,
20
+ } ,
17
21
frame:: ConnectionClose ,
22
+ packet:: interceptor:: { Datagram , Interceptor } ,
18
23
stateless_reset,
19
24
stateless_reset:: token:: testing:: { TEST_TOKEN_1 , TEST_TOKEN_2 } ,
20
25
transport,
21
26
varint:: VarInt ,
22
27
} ;
28
+ use std:: sync:: atomic:: Ordering ;
23
29
24
30
const SERVER_TOKENS : [ stateless_reset:: Token ; 1 ] = [ TEST_TOKEN_1 ] ;
25
31
const CLIENT_TOKENS : [ stateless_reset:: Token ; 1 ] = [ TEST_TOKEN_2 ] ;
@@ -63,7 +69,9 @@ fn dc_handshake_self_test() -> Result<()> {
63
69
. with_tls ( certificates:: CERT_PEM ) ?
64
70
. with_dc ( MockDcEndpoint :: new ( & CLIENT_TOKENS ) ) ?;
65
71
66
- self_test ( server, client, None , None )
72
+ self_test ( server, client, None , None ) ?;
73
+
74
+ Ok ( ( ) )
67
75
}
68
76
69
77
// Client Server
@@ -106,7 +114,9 @@ fn dc_mtls_handshake_self_test() -> Result<()> {
106
114
. with_tls ( client_tls) ?
107
115
. with_dc ( MockDcEndpoint :: new ( & SERVER_TOKENS ) ) ?;
108
116
109
- self_test ( server, client, None , None )
117
+ self_test ( server, client, None , None ) ?;
118
+
119
+ Ok ( ( ) )
110
120
}
111
121
112
122
#[ test]
@@ -133,7 +143,9 @@ fn dc_mtls_handshake_auth_failure_self_test() -> Result<()> {
133
143
}
134
144
. into ( ) ;
135
145
136
- self_test ( server, client, Some ( expected_client_error) , None )
146
+ self_test ( server, client, Some ( expected_client_error) , None ) ?;
147
+
148
+ Ok ( ( ) )
137
149
}
138
150
139
151
// Client Server
@@ -173,7 +185,9 @@ fn dc_mtls_handshake_server_not_supported_self_test() -> Result<()> {
173
185
"peer does not support specified dc versions" ,
174
186
) ) ,
175
187
Some ( expected_server_error) ,
176
- )
188
+ ) ?;
189
+
190
+ Ok ( ( ) )
177
191
}
178
192
179
193
// Client Server
@@ -218,22 +232,81 @@ fn dc_mtls_handshake_client_not_supported_self_test() -> Result<()> {
218
232
Some ( connection:: Error :: invalid_configuration (
219
233
"peer does not support specified dc versions" ,
220
234
) ) ,
221
- )
235
+ ) ?;
236
+
237
+ Ok ( ( ) )
238
+ }
239
+
240
+ #[ test]
241
+ fn dc_secret_control_packet ( ) -> Result < ( ) > {
242
+ dc_possible_secret_control_packet ( || true )
243
+ }
244
+
245
+ #[ test]
246
+ fn dc_not_secret_control_packet ( ) -> Result < ( ) > {
247
+ dc_possible_secret_control_packet ( || false )
248
+ }
249
+
250
+ fn dc_possible_secret_control_packet (
251
+ on_possible_secret_control_packet : fn ( ) -> bool ,
252
+ ) -> Result < ( ) > {
253
+ let server_tls = build_server_mtls_provider ( certificates:: MTLS_CA_CERT ) ?;
254
+ let server = Server :: builder ( )
255
+ . with_tls ( server_tls) ?
256
+ . with_dc ( MockDcEndpoint :: new ( & SERVER_TOKENS ) ) ?;
257
+
258
+ let client_tls = build_client_mtls_provider ( certificates:: MTLS_CA_CERT ) ?;
259
+ let mut dc_endpoint = MockDcEndpoint :: new ( & CLIENT_TOKENS ) ;
260
+ dc_endpoint. on_possible_secret_control_packet = on_possible_secret_control_packet;
261
+ let on_possible_secret_control_packet_count =
262
+ dc_endpoint. on_possible_secret_control_packet_count . clone ( ) ;
263
+
264
+ let client = Client :: builder ( )
265
+ . with_tls ( client_tls) ?
266
+ . with_dc ( dc_endpoint) ?
267
+ . with_packet_interceptor ( RandomShort :: default ( ) ) ?;
268
+
269
+ let ( client_events, _server_events) = self_test ( server, client, None , None ) ?;
270
+
271
+ assert_eq ! (
272
+ 1 ,
273
+ on_possible_secret_control_packet_count. load( Ordering :: Relaxed )
274
+ ) ;
275
+
276
+ let client_datagram_drops = client_events
277
+ . endpoint_datagram_dropped_events
278
+ . lock ( )
279
+ . unwrap ( ) ;
280
+
281
+ if on_possible_secret_control_packet ( ) {
282
+ // No datagrams should be recorded as dropped because MockDcEndpoint::on_possible_secret_control_packet
283
+ // returned true, indicating the given datagram was a secret control packet
284
+ assert_eq ! ( 0 , client_datagram_drops. len( ) ) ;
285
+ } else {
286
+ // The datagram was not a secret control packet, so it is dropped
287
+ assert_eq ! ( 1 , client_datagram_drops. len( ) ) ;
288
+ assert ! ( matches!(
289
+ client_datagram_drops[ 0 ] . reason,
290
+ DatagramDropReason :: UnknownDestinationConnectionId { .. }
291
+ ) ) ;
292
+ }
293
+
294
+ Ok ( ( ) )
222
295
}
223
296
224
297
fn self_test < S : ServerProviders , C : ClientProviders > (
225
298
server : server:: Builder < S > ,
226
299
client : client:: Builder < C > ,
227
300
expected_client_error : Option < connection:: Error > ,
228
301
expected_server_error : Option < connection:: Error > ,
229
- ) -> Result < ( ) > {
302
+ ) -> Result < ( DcRecorder , DcRecorder ) > {
230
303
let model = Model :: default ( ) ;
231
304
let rtt = Duration :: from_millis ( 100 ) ;
232
305
model. set_delay ( rtt / 2 ) ;
233
306
234
- let server_subscriber = DcStateChanged :: new ( ) ;
307
+ let server_subscriber = DcRecorder :: new ( ) ;
235
308
let server_events = server_subscriber. clone ( ) ;
236
- let client_subscriber = DcStateChanged :: new ( ) ;
309
+ let client_subscriber = DcRecorder :: new ( ) ;
237
310
let client_events = client_subscriber. clone ( ) ;
238
311
239
312
test ( model, |handle| {
@@ -284,7 +357,11 @@ fn self_test<S: ServerProviders, C: ClientProviders>(
284
357
}
285
358
} else {
286
359
assert ! ( result. is_ok( ) ) ;
287
- let client_events = client_events. events ( ) . lock ( ) . unwrap ( ) . clone ( ) ;
360
+ let client_events = client_events
361
+ . dc_state_changed_events ( )
362
+ . lock ( )
363
+ . unwrap ( )
364
+ . clone ( ) ;
288
365
assert_dc_complete ( & client_events) ;
289
366
// wait briefly so the ack for the `DC_STATELESS_RESET_TOKENS` frame from the server is sent
290
367
// before the client closes the connection. This is only necessary to confirm the `dc::State`
@@ -298,33 +375,55 @@ fn self_test<S: ServerProviders, C: ClientProviders>(
298
375
. unwrap ( ) ;
299
376
300
377
if expected_client_error. is_some ( ) || expected_server_error. is_some ( ) {
301
- return Ok ( ( ) ) ;
378
+ return Ok ( ( client_events , server_events ) ) ;
302
379
}
303
380
304
- let server_events = server_events. events ( ) . lock ( ) . unwrap ( ) . clone ( ) ;
305
- let client_events = client_events. events ( ) . lock ( ) . unwrap ( ) . clone ( ) ;
381
+ let server_dc_state_changed_events = server_events
382
+ . dc_state_changed_events ( )
383
+ . lock ( )
384
+ . unwrap ( )
385
+ . clone ( ) ;
386
+ let client_dc_state_changed_events = client_events
387
+ . dc_state_changed_events ( )
388
+ . lock ( )
389
+ . unwrap ( )
390
+ . clone ( ) ;
306
391
307
- assert_dc_complete ( & server_events ) ;
308
- assert_dc_complete ( & client_events ) ;
392
+ assert_dc_complete ( & server_dc_state_changed_events ) ;
393
+ assert_dc_complete ( & client_dc_state_changed_events ) ;
309
394
310
395
// Server path secrets are ready in 1.5 RTTs measured from the start of the test, since it takes
311
396
// .5 RTT for the Initial from the client to reach the server
312
397
assert_eq ! (
313
398
// remove floating point division error
314
399
Duration :: from_millis( rtt. mul_f32( 1.5 ) . as_millis( ) as u64 ) ,
315
- server_events[ 1 ] . timestamp. duration_since_start( )
400
+ server_dc_state_changed_events[ 1 ]
401
+ . timestamp
402
+ . duration_since_start( )
403
+ ) ;
404
+ assert_eq ! (
405
+ rtt,
406
+ client_dc_state_changed_events[ 1 ]
407
+ . timestamp
408
+ . duration_since_start( )
316
409
) ;
317
- assert_eq ! ( rtt, client_events[ 1 ] . timestamp. duration_since_start( ) ) ;
318
410
319
411
// Server completes in 2.5 RTTs measured from the start of the test, since it takes .5 RTT
320
412
// for the Initial from the client to reach the server
321
413
assert_eq ! (
322
414
rtt. mul_f32( 2.5 ) ,
323
- server_events[ 2 ] . timestamp. duration_since_start( )
415
+ server_dc_state_changed_events[ 2 ]
416
+ . timestamp
417
+ . duration_since_start( )
418
+ ) ;
419
+ assert_eq ! (
420
+ rtt * 2 ,
421
+ client_dc_state_changed_events[ 2 ]
422
+ . timestamp
423
+ . duration_since_start( )
324
424
) ;
325
- assert_eq ! ( rtt * 2 , client_events[ 2 ] . timestamp. duration_since_start( ) ) ;
326
425
327
- Ok ( ( ) )
426
+ Ok ( ( client_events , server_events ) )
328
427
}
329
428
330
429
fn assert_dc_complete ( events : & [ DcStateChangedEvent ] ) {
@@ -358,21 +457,22 @@ struct DcStateChangedEvent {
358
457
}
359
458
360
459
#[ derive( Clone , Default ) ]
361
- struct DcStateChanged {
362
- pub events : Arc < Mutex < Vec < DcStateChangedEvent > > > ,
460
+ struct DcRecorder {
461
+ pub dc_state_changed_events : Arc < Mutex < Vec < DcStateChangedEvent > > > ,
462
+ pub endpoint_datagram_dropped_events : Arc < Mutex < Vec < EndpointDatagramDropped > > > ,
363
463
}
364
- impl DcStateChanged {
464
+ impl DcRecorder {
365
465
pub fn new ( ) -> Self {
366
466
Self :: default ( )
367
467
}
368
468
369
- pub fn events ( & self ) -> Arc < Mutex < Vec < DcStateChangedEvent > > > {
370
- self . events . clone ( )
469
+ pub fn dc_state_changed_events ( & self ) -> Arc < Mutex < Vec < DcStateChangedEvent > > > {
470
+ self . dc_state_changed_events . clone ( )
371
471
}
372
472
}
373
473
374
- impl events:: Subscriber for DcStateChanged {
375
- type ConnectionContext = DcStateChanged ;
474
+ impl events:: Subscriber for DcRecorder {
475
+ type ConnectionContext = DcRecorder ;
376
476
377
477
fn create_connection_context (
378
478
& mut self ,
@@ -394,7 +494,45 @@ impl events::Subscriber for DcStateChanged {
394
494
state : event. state . clone ( ) ,
395
495
} ) ;
396
496
} ;
397
- let mut buffer = context. events . lock ( ) . unwrap ( ) ;
497
+ let mut buffer = context. dc_state_changed_events . lock ( ) . unwrap ( ) ;
398
498
store ( event, & mut buffer) ;
399
499
}
500
+
501
+ fn on_endpoint_datagram_dropped (
502
+ & mut self ,
503
+ _meta : & EndpointMeta ,
504
+ event : & EndpointDatagramDropped ,
505
+ ) {
506
+ self . endpoint_datagram_dropped_events
507
+ . lock ( )
508
+ . unwrap ( )
509
+ . push ( event. clone ( ) ) ;
510
+ }
511
+ }
512
+
513
+ /// Replace the first short packet payload with a randomized short packet
514
+ #[ derive( Default ) ]
515
+ struct RandomShort ( bool ) ;
516
+
517
+ impl Interceptor for RandomShort {
518
+ #[ inline]
519
+ fn intercept_rx_datagram < ' a > (
520
+ & mut self ,
521
+ _subject : & Subject ,
522
+ _datagram : & Datagram ,
523
+ payload : DecoderBufferMut < ' a > ,
524
+ ) -> DecoderBufferMut < ' a > {
525
+ let payload = payload. into_less_safe_slice ( ) ;
526
+
527
+ if let 0b0100u8 ..=0b0111u8 = payload[ 0 ] >> 4 {
528
+ if !self . 0 {
529
+ // randomize everything after the short header tag
530
+ rand:: fill_bytes ( & mut payload[ 1 ..] ) ;
531
+ // only change the first short packet
532
+ self . 0 = true ;
533
+ }
534
+ }
535
+
536
+ DecoderBufferMut :: new ( payload)
537
+ }
400
538
}
0 commit comments