49
49
#include "getopt_s.h" /* for local getopt() */
50
50
51
51
#include "srtp_priv.h"
52
+ #include "stream_list_priv.h"
52
53
#include "util.h"
53
54
54
55
#ifdef HAVE_NETINET_IN_H
@@ -124,6 +125,8 @@ char *srtp_packet_to_string(srtp_hdr_t *hdr, int packet_len);
124
125
125
126
double mips_estimate (int num_trials , int * ignore );
126
127
128
+ srtp_err_status_t srtp_stream_list_test (void );
129
+
127
130
#define TEST_MKI_ID_SIZE 4
128
131
129
132
extern uint8_t test_key [46 ];
@@ -153,15 +156,17 @@ srtp_master_key_t *test_keys[2] = {
153
156
154
157
void usage (char * prog_name )
155
158
{
156
- printf ("usage: %s [ -t ][ -c ][ -v ][ -o ][-d <debug_module> ]* [ -l ]\n"
157
- " -t run timing test\n"
158
- " -r run rejection timing test\n"
159
- " -c run codec timing test\n"
160
- " -v run validation tests\n"
161
- " -o output logging to stdout\n"
162
- " -d <mod> turn on debugging module <mod>\n"
163
- " -l list debugging modules\n" ,
164
- prog_name );
159
+ printf (
160
+ "usage: %s [ -t ][ -c ][ -v ][ -s ][ -o ][-d <debug_module> ]* [ -l ]\n"
161
+ " -t run timing test\n"
162
+ " -r run rejection timing test\n"
163
+ " -c run codec timing test\n"
164
+ " -v run validation tests\n"
165
+ " -s run stream list tests only\n"
166
+ " -o output logging to stdout\n"
167
+ " -d <mod> turn on debugging module <mod>\n"
168
+ " -l list debugging modules\n" ,
169
+ prog_name );
165
170
exit (1 );
166
171
}
167
172
@@ -217,6 +222,7 @@ int main(int argc, char *argv[])
217
222
unsigned do_rejection_test = 0 ;
218
223
unsigned do_codec_timing = 0 ;
219
224
unsigned do_validation = 0 ;
225
+ unsigned do_stream_list = 0 ;
220
226
unsigned do_list_mods = 0 ;
221
227
unsigned do_log_stdout = 0 ;
222
228
srtp_err_status_t status ;
@@ -251,7 +257,7 @@ int main(int argc, char *argv[])
251
257
252
258
/* process input arguments */
253
259
while (1 ) {
254
- q = getopt_s (argc , argv , "trcvold :" );
260
+ q = getopt_s (argc , argv , "trcvsold :" );
255
261
if (q == -1 ) {
256
262
break ;
257
263
}
@@ -267,6 +273,10 @@ int main(int argc, char *argv[])
267
273
break ;
268
274
case 'v' :
269
275
do_validation = 1 ;
276
+ do_stream_list = 1 ;
277
+ break ;
278
+ case 's' :
279
+ do_stream_list = 1 ;
270
280
break ;
271
281
case 'o' :
272
282
do_log_stdout = 1 ;
@@ -287,7 +297,7 @@ int main(int argc, char *argv[])
287
297
}
288
298
289
299
if (!do_validation && !do_timing_test && !do_codec_timing &&
290
- !do_list_mods && !do_rejection_test ) {
300
+ !do_list_mods && !do_rejection_test && ! do_stream_list ) {
291
301
usage (argv [0 ]);
292
302
}
293
303
@@ -597,6 +607,16 @@ int main(int argc, char *argv[])
597
607
}
598
608
}
599
609
610
+ if (do_stream_list ) {
611
+ printf ("testing srtp_stream_list..." );
612
+ if (srtp_stream_list_test () == srtp_err_status_ok ) {
613
+ printf ("passed\n" );
614
+ } else {
615
+ printf ("failed\n" );
616
+ exit (1 );
617
+ }
618
+ }
619
+
600
620
if (do_timing_test ) {
601
621
const srtp_policy_t * * policy = policy_array ;
602
622
@@ -1467,13 +1487,75 @@ srtp_err_status_t srtcp_test(const srtp_policy_t *policy, int mki_index)
1467
1487
return srtp_err_status_ok ;
1468
1488
}
1469
1489
1490
+ struct srtp_session_print_stream_data {
1491
+ // set by callback to indicate failure
1492
+ srtp_err_status_t status ;
1493
+ // indicates if it is the template stream or a regular stream
1494
+ int is_template ;
1495
+ };
1496
+
1497
+ int srtp_session_print_stream (srtp_stream_t stream , void * raw_data )
1498
+ {
1499
+ static const char * serv_descr [4 ] = { "none" , "confidentiality" ,
1500
+ "authentication" ,
1501
+ "confidentiality and authentication" };
1502
+ static const char * direction [3 ] = { "unknown" , "outbound" , "inbound" };
1503
+
1504
+ struct srtp_session_print_stream_data * data =
1505
+ (struct srtp_session_print_stream_data * )raw_data ;
1506
+ srtp_session_keys_t * session_keys = & stream -> session_keys [0 ];
1507
+ char ssrc_text [32 ];
1508
+
1509
+ if (!data -> is_template && stream -> rtp_services > sec_serv_conf_and_auth ) {
1510
+ data -> status = srtp_err_status_bad_param ;
1511
+ return 1 ;
1512
+ }
1513
+
1514
+ if (data -> is_template ) {
1515
+ snprintf (ssrc_text , sizeof (ssrc_text ), "any %s" ,
1516
+ direction [stream -> direction ]);
1517
+ } else {
1518
+ snprintf (ssrc_text , sizeof (ssrc_text ), "0x%08x" , stream -> ssrc );
1519
+ }
1520
+
1521
+ printf ("# SSRC: %s\r\n"
1522
+ "# rtp cipher: %s\r\n"
1523
+ "# rtp auth: %s\r\n"
1524
+ "# rtp services: %s\r\n"
1525
+ "# rtcp cipher: %s\r\n"
1526
+ "# rtcp auth: %s\r\n"
1527
+ "# rtcp services: %s\r\n"
1528
+ "# window size: %lu\r\n"
1529
+ "# tx rtx allowed:%s\r\n" ,
1530
+ ssrc_text , session_keys -> rtp_cipher -> type -> description ,
1531
+ session_keys -> rtp_auth -> type -> description ,
1532
+ serv_descr [stream -> rtp_services ],
1533
+ session_keys -> rtcp_cipher -> type -> description ,
1534
+ session_keys -> rtcp_auth -> type -> description ,
1535
+ serv_descr [stream -> rtcp_services ],
1536
+ srtp_rdbx_get_window_size (& stream -> rtp_rdbx ),
1537
+ stream -> allow_repeat_tx ? "true" : "false" );
1538
+
1539
+ printf ("# Encrypted extension headers: " );
1540
+ if (stream -> enc_xtn_hdr && stream -> enc_xtn_hdr_count > 0 ) {
1541
+ int * enc_xtn_hdr = stream -> enc_xtn_hdr ;
1542
+ int count = stream -> enc_xtn_hdr_count ;
1543
+ while (count > 0 ) {
1544
+ printf ("%d " , * enc_xtn_hdr );
1545
+ enc_xtn_hdr ++ ;
1546
+ count -- ;
1547
+ }
1548
+ printf ("\n" );
1549
+ } else {
1550
+ printf ("none\n" );
1551
+ }
1552
+
1553
+ return 0 ;
1554
+ }
1555
+
1470
1556
srtp_err_status_t srtp_session_print_policy (srtp_t srtp )
1471
1557
{
1472
- char * serv_descr [4 ] = { "none" , "confidentiality" , "authentication" ,
1473
- "confidentiality and authentication" };
1474
- char * direction [3 ] = { "unknown" , "outbound" , "inbound" };
1475
- srtp_stream_t stream ;
1476
- srtp_session_keys_t * session_keys = NULL ;
1558
+ struct srtp_session_print_stream_data data = { srtp_err_status_ok , 0 };
1477
1559
1478
1560
/* sanity checking */
1479
1561
if (srtp == NULL ) {
@@ -1482,86 +1564,16 @@ srtp_err_status_t srtp_session_print_policy(srtp_t srtp)
1482
1564
1483
1565
/* if there's a template stream, print it out */
1484
1566
if (srtp -> stream_template != NULL ) {
1485
- stream = srtp -> stream_template ;
1486
- session_keys = & stream -> session_keys [0 ];
1487
- printf ("# SSRC: any %s\r\n"
1488
- "# rtp cipher: %s\r\n"
1489
- "# rtp auth: %s\r\n"
1490
- "# rtp services: %s\r\n"
1491
- "# rtcp cipher: %s\r\n"
1492
- "# rtcp auth: %s\r\n"
1493
- "# rtcp services: %s\r\n"
1494
- "# window size: %lu\r\n"
1495
- "# tx rtx allowed:%s\r\n" ,
1496
- direction [stream -> direction ],
1497
- session_keys -> rtp_cipher -> type -> description ,
1498
- session_keys -> rtp_auth -> type -> description ,
1499
- serv_descr [stream -> rtp_services ],
1500
- session_keys -> rtcp_cipher -> type -> description ,
1501
- session_keys -> rtcp_auth -> type -> description ,
1502
- serv_descr [stream -> rtcp_services ],
1503
- srtp_rdbx_get_window_size (& stream -> rtp_rdbx ),
1504
- stream -> allow_repeat_tx ? "true" : "false" );
1505
-
1506
- printf ("# Encrypted extension headers: " );
1507
- if (stream -> enc_xtn_hdr && stream -> enc_xtn_hdr_count > 0 ) {
1508
- int * enc_xtn_hdr = stream -> enc_xtn_hdr ;
1509
- int count = stream -> enc_xtn_hdr_count ;
1510
- while (count > 0 ) {
1511
- printf ("%d " , * enc_xtn_hdr );
1512
- enc_xtn_hdr ++ ;
1513
- count -- ;
1514
- }
1515
- printf ("\n" );
1516
- } else {
1517
- printf ("none\n" );
1518
- }
1567
+ data .is_template = 1 ;
1568
+ srtp_session_print_stream (srtp -> stream_template , & data );
1519
1569
}
1520
1570
1521
1571
/* loop over streams in session, printing the policy of each */
1522
- stream = srtp -> stream_list ;
1523
- while (stream != NULL ) {
1524
- if (stream -> rtp_services > sec_serv_conf_and_auth ) {
1525
- return srtp_err_status_bad_param ;
1526
- }
1527
- session_keys = & stream -> session_keys [0 ];
1528
-
1529
- printf ("# SSRC: 0x%08x\r\n"
1530
- "# rtp cipher: %s\r\n"
1531
- "# rtp auth: %s\r\n"
1532
- "# rtp services: %s\r\n"
1533
- "# rtcp cipher: %s\r\n"
1534
- "# rtcp auth: %s\r\n"
1535
- "# rtcp services: %s\r\n"
1536
- "# window size: %lu\r\n"
1537
- "# tx rtx allowed:%s\r\n" ,
1538
- stream -> ssrc , session_keys -> rtp_cipher -> type -> description ,
1539
- session_keys -> rtp_auth -> type -> description ,
1540
- serv_descr [stream -> rtp_services ],
1541
- session_keys -> rtcp_cipher -> type -> description ,
1542
- session_keys -> rtcp_auth -> type -> description ,
1543
- serv_descr [stream -> rtcp_services ],
1544
- srtp_rdbx_get_window_size (& stream -> rtp_rdbx ),
1545
- stream -> allow_repeat_tx ? "true" : "false" );
1546
-
1547
- printf ("# Encrypted extension headers: " );
1548
- if (stream -> enc_xtn_hdr && stream -> enc_xtn_hdr_count > 0 ) {
1549
- int * enc_xtn_hdr = stream -> enc_xtn_hdr ;
1550
- int count = stream -> enc_xtn_hdr_count ;
1551
- while (count > 0 ) {
1552
- printf ("%d " , * enc_xtn_hdr );
1553
- enc_xtn_hdr ++ ;
1554
- count -- ;
1555
- }
1556
- printf ("\n" );
1557
- } else {
1558
- printf ("none\n" );
1559
- }
1572
+ data .is_template = 0 ;
1573
+ srtp_stream_list_for_each (srtp -> stream_list , srtp_session_print_stream ,
1574
+ & data );
1560
1575
1561
- /* advance to next stream in the list */
1562
- stream = stream -> next ;
1563
- }
1564
- return srtp_err_status_ok ;
1576
+ return data .status ;
1565
1577
}
1566
1578
1567
1579
srtp_err_status_t srtp_print_policy (const srtp_policy_t * policy )
@@ -4287,3 +4299,240 @@ const srtp_policy_t wildcard_policy = {
4287
4299
0 , /* list of encrypted extension headers is empty */
4288
4300
NULL
4289
4301
};
4302
+
4303
+ static srtp_stream_t stream_list_test_create_stream (uint32_t ssrc )
4304
+ {
4305
+ srtp_stream_t stream = malloc (sizeof (srtp_stream_ctx_t ));
4306
+ stream -> ssrc = ssrc ;
4307
+ return stream ;
4308
+ }
4309
+
4310
+ static void stream_list_test_free_stream (srtp_stream_t stream )
4311
+ {
4312
+ free (stream );
4313
+ }
4314
+
4315
+ int stream_list_test_count_cb (srtp_stream_t stream , void * data )
4316
+ {
4317
+ int * count = (int * )data ;
4318
+ (* count )++ ;
4319
+ (void )stream ;
4320
+ return 0 ;
4321
+ }
4322
+
4323
+ struct remove_one_data {
4324
+ uint32_t ssrc ;
4325
+ srtp_stream_list_t list ;
4326
+ };
4327
+
4328
+ int stream_list_test_remove_one_cb (srtp_stream_t stream , void * data )
4329
+ {
4330
+ struct remove_one_data * d = (struct remove_one_data * )data ;
4331
+ if (stream -> ssrc == d -> ssrc ) {
4332
+ srtp_stream_list_remove (d -> list , stream );
4333
+ stream_list_test_free_stream (stream );
4334
+ return 1 ;
4335
+ }
4336
+ return 0 ;
4337
+ }
4338
+
4339
+ int stream_list_test_remove_all_cb (srtp_stream_t stream , void * data )
4340
+ {
4341
+ srtp_stream_list_t * list = (srtp_stream_list_t * )data ;
4342
+ srtp_stream_list_remove (* list , stream );
4343
+ stream_list_test_free_stream (stream );
4344
+ return 0 ;
4345
+ }
4346
+
4347
+ srtp_err_status_t srtp_stream_list_test (void )
4348
+ {
4349
+ srtp_stream_list_t list ;
4350
+
4351
+ if (srtp_stream_list_alloc (& list )) {
4352
+ return srtp_err_status_fail ;
4353
+ }
4354
+
4355
+ /* add 4 streams*/
4356
+ if (srtp_stream_list_insert (list , stream_list_test_create_stream (1 ))) {
4357
+ return srtp_err_status_fail ;
4358
+ }
4359
+ if (srtp_stream_list_insert (list , stream_list_test_create_stream (2 ))) {
4360
+ return srtp_err_status_fail ;
4361
+ }
4362
+ if (srtp_stream_list_insert (list , stream_list_test_create_stream (3 ))) {
4363
+ return srtp_err_status_fail ;
4364
+ }
4365
+ if (srtp_stream_list_insert (list , stream_list_test_create_stream (4 ))) {
4366
+ return srtp_err_status_fail ;
4367
+ }
4368
+
4369
+ /* find */
4370
+ if (srtp_stream_list_get (list , 3 ) == NULL ) {
4371
+ return srtp_err_status_fail ;
4372
+ }
4373
+ if (srtp_stream_list_get (list , 1 ) == NULL ) {
4374
+ return srtp_err_status_fail ;
4375
+ }
4376
+ if (srtp_stream_list_get (list , 2 ) == NULL ) {
4377
+ return srtp_err_status_fail ;
4378
+ }
4379
+ if (srtp_stream_list_get (list , 4 ) == NULL ) {
4380
+ return srtp_err_status_fail ;
4381
+ }
4382
+
4383
+ /* find not in list */
4384
+ if (srtp_stream_list_get (list , 5 )) {
4385
+ return srtp_err_status_fail ;
4386
+ }
4387
+
4388
+ /* for each */
4389
+ int count = 0 ;
4390
+ srtp_stream_list_for_each (list , stream_list_test_count_cb , & count );
4391
+ if (count != 4 ) {
4392
+ return srtp_err_status_fail ;
4393
+ }
4394
+
4395
+ /* remove */
4396
+ srtp_stream_t stream = srtp_stream_list_get (list , 3 );
4397
+ if (stream == NULL ) {
4398
+ return srtp_err_status_fail ;
4399
+ }
4400
+ srtp_stream_list_remove (list , stream );
4401
+ stream_list_test_free_stream (stream );
4402
+
4403
+ /* find after remove */
4404
+ if (srtp_stream_list_get (list , 3 )) {
4405
+ return srtp_err_status_fail ;
4406
+ }
4407
+
4408
+ /* recount */
4409
+ count = 0 ;
4410
+ srtp_stream_list_for_each (list , stream_list_test_count_cb , & count );
4411
+ if (count != 3 ) {
4412
+ return srtp_err_status_fail ;
4413
+ }
4414
+
4415
+ /* remove one in for each */
4416
+ struct remove_one_data data = { 2 , list };
4417
+ srtp_stream_list_for_each (list , stream_list_test_remove_one_cb , & data );
4418
+
4419
+ /* find after remove */
4420
+ if (srtp_stream_list_get (list , 2 )) {
4421
+ return srtp_err_status_fail ;
4422
+ }
4423
+
4424
+ /* recount */
4425
+ count = 0 ;
4426
+ srtp_stream_list_for_each (list , stream_list_test_count_cb , & count );
4427
+ if (count != 2 ) {
4428
+ return srtp_err_status_fail ;
4429
+ }
4430
+
4431
+ /* destroy non empty list */
4432
+ if (srtp_stream_list_dealloc (list ) == srtp_err_status_ok ) {
4433
+ return srtp_err_status_fail ;
4434
+ }
4435
+
4436
+ /* remove all in for each */
4437
+ srtp_stream_list_for_each (list , stream_list_test_remove_all_cb , & list );
4438
+
4439
+ /* recount */
4440
+ count = 0 ;
4441
+ srtp_stream_list_for_each (list , stream_list_test_count_cb , & count );
4442
+ if (count != 0 ) {
4443
+ return srtp_err_status_fail ;
4444
+ }
4445
+
4446
+ /* destroy empty list */
4447
+ if (srtp_stream_list_dealloc (list )) {
4448
+ return srtp_err_status_fail ;
4449
+ }
4450
+
4451
+ return srtp_err_status_ok ;
4452
+ }
4453
+
4454
+ #ifdef SRTP_USE_TEST_STREAM_LIST
4455
+
4456
+ /*
4457
+ * A srtp_stream_list_ctx_t implementation using a single linked list
4458
+ * that does not use the internal next / prev fields.
4459
+ */
4460
+
4461
+ struct test_list_node {
4462
+ srtp_stream_t stream ;
4463
+ struct test_list_node * next ;
4464
+ };
4465
+ struct srtp_stream_list_ctx_t_ {
4466
+ struct test_list_node * head ;
4467
+ };
4468
+
4469
+ srtp_err_status_t srtp_stream_list_alloc (srtp_stream_list_t * list_ptr )
4470
+ {
4471
+ struct srtp_stream_list_ctx_t_ * l =
4472
+ malloc (sizeof (struct srtp_stream_list_ctx_t_ ));
4473
+ l -> head = NULL ;
4474
+ * list_ptr = l ;
4475
+ return srtp_err_status_ok ;
4476
+ }
4477
+
4478
+ srtp_err_status_t srtp_stream_list_dealloc (srtp_stream_list_t list )
4479
+ {
4480
+ struct test_list_node * node = list -> head ;
4481
+ if (node ) {
4482
+ return srtp_err_status_fail ;
4483
+ }
4484
+ free (list );
4485
+
4486
+ return srtp_err_status_ok ;
4487
+ }
4488
+
4489
+ srtp_err_status_t srtp_stream_list_insert (srtp_stream_list_t list ,
4490
+ srtp_stream_t stream )
4491
+ {
4492
+ struct test_list_node * node = malloc (sizeof (struct test_list_node ));
4493
+ node -> stream = stream ;
4494
+ node -> next = list -> head ;
4495
+ list -> head = node ;
4496
+
4497
+ return srtp_err_status_ok ;
4498
+ }
4499
+
4500
+ srtp_stream_t srtp_stream_list_get (srtp_stream_list_t list , uint32_t ssrc )
4501
+ {
4502
+ struct test_list_node * node = list -> head ;
4503
+ while (node != NULL ) {
4504
+ if (node -> stream -> ssrc == ssrc )
4505
+ return node -> stream ;
4506
+ node = node -> next ;
4507
+ }
4508
+ return NULL ;
4509
+ }
4510
+
4511
+ void srtp_stream_list_remove (srtp_stream_list_t list , srtp_stream_t stream )
4512
+ {
4513
+ struct test_list_node * * node = & (list -> head );
4514
+ while ((* node ) != NULL ) {
4515
+ if ((* node )-> stream -> ssrc == stream -> ssrc ) {
4516
+ struct test_list_node * tmp = (* node );
4517
+ (* node ) = tmp -> next ;
4518
+ free (tmp );
4519
+ return ;
4520
+ }
4521
+ node = & (* node )-> next ;
4522
+ }
4523
+ }
4524
+
4525
+ void srtp_stream_list_for_each (srtp_stream_list_t list ,
4526
+ int (* callback )(srtp_stream_t , void * ),
4527
+ void * data )
4528
+ {
4529
+ struct test_list_node * node = list -> head ;
4530
+ while (node != NULL ) {
4531
+ struct test_list_node * tmp = node ;
4532
+ node = node -> next ;
4533
+ if (callback (tmp -> stream , data ))
4534
+ break ;
4535
+ }
4536
+ }
4537
+
4538
+ #endif
0 commit comments