@@ -63,13 +63,20 @@ typedef struct {
63
63
tls_data_t tls_recv ; /**< TLS receive buffer */
64
64
uint32_t int_timer ; /**< TLS intermediate timer timeout */
65
65
uint32_t fin_timer ; /**< TLS final timer timeout */
66
+ bool fin_timer_timeout ; /**< TLS final timer has timeouted */
66
67
bool timer_running : 1 ; /**< TLS timer running */
67
68
bool finished : 1 ; /**< TLS finished */
68
69
bool calculating : 1 ; /**< TLS is calculating */
70
+ bool queued : 1 ; /**< TLS is queued */
69
71
bool library_init : 1 ; /**< TLS library has been initialized */
70
72
tls_sec_prot_lib_int_t * tls_sec_inst ; /**< TLS security library storage, SHALL BE THE LAST FIELD */
71
73
} tls_sec_prot_int_t ;
72
74
75
+ typedef struct {
76
+ ns_list_link_t link ; /**< Link */
77
+ sec_prot_t * prot ; /**< Protocol instance */
78
+ } tls_sec_prot_queue_t ;
79
+
73
80
static uint16_t tls_sec_prot_size (void );
74
81
static int8_t client_tls_sec_prot_init (sec_prot_t * prot );
75
82
static int8_t server_tls_sec_prot_init (sec_prot_t * prot );
@@ -93,8 +100,14 @@ static int8_t tls_sec_prot_tls_get_timer(void *handle);
93
100
94
101
static int8_t tls_sec_prot_tls_configure_and_connect (sec_prot_t * prot , bool is_server );
95
102
103
+ static bool tls_sec_prot_queue_check (sec_prot_t * prot );
104
+ static bool tls_sec_prot_queue_process (sec_prot_t * prot );
105
+ static void tls_sec_prot_queue_remove (sec_prot_t * prot );
106
+
96
107
#define tls_sec_prot_get (prot ) (tls_sec_prot_int_t *) &prot->data
97
108
109
+ static NS_LIST_DEFINE (tls_sec_prot_queue , tls_sec_prot_queue_t , link ) ;
110
+
98
111
int8_t client_tls_sec_prot_register (kmp_service_t * service )
99
112
{
100
113
if (!service ) {
@@ -148,8 +161,10 @@ static int8_t client_tls_sec_prot_init(sec_prot_t *prot)
148
161
eap_tls_sec_prot_lib_message_init (& data -> tls_send );
149
162
data -> int_timer = 0 ;
150
163
data -> fin_timer = 0 ;
164
+ data -> fin_timer_timeout = false;
151
165
data -> timer_running = false;
152
166
data -> calculating = false;
167
+ data -> queued = false;
153
168
data -> library_init = false;
154
169
return 0 ;
155
170
}
@@ -176,8 +191,10 @@ static int8_t server_tls_sec_prot_init(sec_prot_t *prot)
176
191
eap_tls_sec_prot_lib_message_init (& data -> tls_send );
177
192
data -> int_timer = 0 ;
178
193
data -> fin_timer = 0 ;
194
+ data -> fin_timer_timeout = false;
179
195
data -> timer_running = false;
180
196
data -> calculating = false;
197
+ data -> queued = false;
181
198
data -> library_init = false;
182
199
return 0 ;
183
200
}
@@ -190,6 +207,7 @@ static void tls_sec_prot_delete(sec_prot_t *prot)
190
207
if (data -> library_init ) {
191
208
tls_sec_prot_lib_free ((tls_security_t * ) & data -> tls_sec_inst );
192
209
}
210
+ tls_sec_prot_queue_remove (prot );
193
211
}
194
212
195
213
static void tls_sec_prot_create_request (sec_prot_t * prot , sec_prot_keys_t * sec_keys )
@@ -245,13 +263,22 @@ static void tls_sec_prot_timer_timeout(sec_prot_t *prot, uint16_t ticks)
245
263
if (data -> fin_timer > ticks ) {
246
264
data -> fin_timer -= ticks ;
247
265
} else {
248
- data -> fin_timer = 0 ;
249
- prot -> state_machine_call (prot );
266
+ if (data -> fin_timer > 0 ) {
267
+ data -> fin_timer_timeout = true;
268
+ data -> fin_timer = 0 ;
269
+ }
250
270
}
251
271
}
252
272
253
- if (data -> calculating ) {
254
- prot -> state_machine (prot );
273
+ /* Checks if TLS sessions queue is enabled, and if queue is enabled whether the
274
+ session is first in the queue i.e. allowed to process */
275
+ if (tls_sec_prot_queue_process (prot )) {
276
+ if (data -> fin_timer_timeout ) {
277
+ data -> fin_timer_timeout = false;
278
+ prot -> state_machine (prot );
279
+ } else if (data -> calculating || data -> queued ) {
280
+ prot -> state_machine (prot );
281
+ }
255
282
}
256
283
257
284
sec_prot_timer_timeout_handle (prot , & data -> common , NULL , ticks );
@@ -350,6 +377,7 @@ static void server_tls_sec_prot_state_machine(sec_prot_t *prot)
350
377
{
351
378
tls_sec_prot_int_t * data = tls_sec_prot_get (prot );
352
379
int8_t result ;
380
+ bool client_hello = false;
353
381
354
382
switch (sec_prot_state_get (& data -> common )) {
355
383
case TLS_STATE_INIT :
@@ -362,6 +390,7 @@ static void server_tls_sec_prot_state_machine(sec_prot_t *prot)
362
390
tr_debug ("TLS: start, eui-64: %s" , trace_array (sec_prot_remote_eui_64_addr_get (prot ), 8 ));
363
391
364
392
prot -> timer_start (prot );
393
+ client_hello = true;
365
394
366
395
sec_prot_state_set (prot , & data -> common , TLS_STATE_CREATE_RESP );
367
396
@@ -391,6 +420,14 @@ static void server_tls_sec_prot_state_machine(sec_prot_t *prot)
391
420
break ;
392
421
393
422
case TLS_STATE_PROCESS :
423
+ // If not client hello, reserves slot on TLS queue
424
+ if (!client_hello && !tls_sec_prot_queue_check (prot )) {
425
+ data -> queued = true;
426
+ return ;
427
+ } else {
428
+ data -> queued = false;
429
+ }
430
+
394
431
result = tls_sec_prot_lib_process ((tls_security_t * ) & data -> tls_sec_inst );
395
432
396
433
if (result == TLS_SEC_PROT_LIB_CALCULATING ) {
@@ -428,6 +465,7 @@ static void server_tls_sec_prot_state_machine(sec_prot_t *prot)
428
465
prot -> finished_ind (prot , sec_prot_result_get (& data -> common ), prot -> sec_keys );
429
466
sec_prot_state_set (prot , & data -> common , TLS_STATE_FINISHED );
430
467
468
+ tls_sec_prot_queue_remove (prot );
431
469
tls_sec_prot_lib_free ((tls_security_t * ) & data -> tls_sec_inst );
432
470
data -> library_init = false;
433
471
break ;
@@ -570,4 +608,69 @@ static int8_t tls_sec_prot_tls_configure_and_connect(sec_prot_t *prot, bool is_s
570
608
return 0 ;
571
609
}
572
610
611
+ static bool tls_sec_prot_queue_check (sec_prot_t * prot )
612
+ {
613
+ bool queue_add = true;
614
+ bool queue_continue = false;
615
+ bool first_entry = true;
616
+
617
+ // Checks if TLS queue is empty or this instance is the first entry
618
+ if (ns_list_is_empty (& tls_sec_prot_queue )) {
619
+ queue_continue = true;
620
+ } else {
621
+
622
+ ns_list_foreach (tls_sec_prot_queue_t , entry , & tls_sec_prot_queue ) {
623
+ if (entry -> prot == prot ) {
624
+ queue_add = false;
625
+ if (first_entry ) {
626
+ queue_continue = true;
627
+ break ;
628
+ } else {
629
+ queue_continue = false;
630
+ }
631
+ }
632
+ first_entry = false;
633
+ }
634
+ }
635
+
636
+ // Adds entry to queue if not there already
637
+ if (queue_add ) {
638
+ tr_debug ("TLS QUEUE add%s, eui-64: %s" , first_entry ? " first" : "" , trace_array (sec_prot_remote_eui_64_addr_get (prot ), 8 ));
639
+ tls_sec_prot_queue_t * entry = ns_dyn_mem_temporary_alloc (sizeof (tls_sec_prot_queue_t ));
640
+ if (entry ) {
641
+ entry -> prot = prot ;
642
+ ns_list_add_to_end (& tls_sec_prot_queue , entry );
643
+ }
644
+ }
645
+
646
+ return queue_continue ;
647
+ }
648
+
649
+ static bool tls_sec_prot_queue_process (sec_prot_t * prot )
650
+ {
651
+ if (ns_list_is_empty (& tls_sec_prot_queue )) {
652
+ return true;
653
+ }
654
+
655
+ ns_list_foreach (tls_sec_prot_queue_t , entry , & tls_sec_prot_queue ) {
656
+ if (entry -> prot == prot ) {
657
+ return true;
658
+ }
659
+ return false;
660
+ }
661
+
662
+ return false;
663
+ }
664
+
665
+ static void tls_sec_prot_queue_remove (sec_prot_t * prot )
666
+ {
667
+ ns_list_foreach_safe (tls_sec_prot_queue_t , entry , & tls_sec_prot_queue ) {
668
+ if (entry -> prot == prot ) {
669
+ ns_list_remove (& tls_sec_prot_queue , entry );
670
+ ns_dyn_mem_free (entry );
671
+ tr_debug ("TLS QUEUE remove%s, eui-64: %s" , ns_list_is_empty (& tls_sec_prot_queue ) ? " last" : "" , trace_array (sec_prot_remote_eui_64_addr_get (prot ), 8 ));
672
+ }
673
+ }
674
+ }
675
+
573
676
#endif /* HAVE_WS */
0 commit comments