10
10
#include "nsdynmemLIB.h"
11
11
#include "socket_api.h"
12
12
#include "net_interface.h"
13
- #include "eventOS_callback_timer .h"
13
+ #include "eventOS_event_timer .h"
14
14
15
15
#define TRACE_GROUP "ThCH"
16
16
@@ -35,17 +35,19 @@ typedef struct internal_socket_s {
35
35
36
36
static NS_LIST_DEFINE (socket_list , internal_socket_t , link ) ;
37
37
38
- static void timer_cb (int8_t timer_id , uint16_t slots );
39
- #define TIMER_FACTOR 20 /* mbedtls timer in ms, our timer in slots (50us), therefore 20 slots per ms */
38
+ static void timer_cb (void * param );
39
+
40
40
#define TIMER_STATE_CANCELLED -1 /* cancelled */
41
41
#define TIMER_STATE_NO_EXPIRY 0 /* none of the delays is expired */
42
42
#define TIMER_STATE_INT_EXPIRY 1 /* the intermediate delay only is expired */
43
43
#define TIMER_STATE_FIN_EXPIRY 2 /* the final delay is expired */
44
+
44
45
typedef struct secure_timer_s {
45
- int8_t id ;
46
+ uint8_t id ;
47
+ timeout_t * timer ;
46
48
int8_t state ;
47
- uint8_t cycles ;
48
- uint8_t cycle_count ;
49
+ uint32_t fin_ms ;
50
+ uint32_t int_ms ;
49
51
} secure_timer_t ;
50
52
51
53
typedef struct secure_session {
@@ -64,6 +66,18 @@ static int receive_from_socket(int8_t socket_id, unsigned char *buf, size_t len)
64
66
static void start_timer (int8_t timer_id , uint32_t int_ms , uint32_t fin_ms );
65
67
static int timer_status (int8_t timer_id );
66
68
69
+ static secure_session_t * secure_session_find_by_timer_id (int8_t timer_id )
70
+ {
71
+ secure_session_t * this = NULL ;
72
+ ns_list_foreach (secure_session_t , cur_ptr , & secure_session_list ) {
73
+ if (cur_ptr -> timer .id == timer_id ) {
74
+ this = cur_ptr ;
75
+ break ;
76
+ }
77
+ }
78
+ return this ;
79
+ }
80
+
67
81
static secure_session_t * secure_session_create (internal_socket_t * parent , uint8_t * address_ptr , uint16_t port )
68
82
{
69
83
secure_session_t * this = ns_dyn_mem_alloc (sizeof (secure_session_t ));
@@ -72,12 +86,16 @@ static secure_session_t *secure_session_create(internal_socket_t *parent, uint8_
72
86
}
73
87
memset (this , 0 , sizeof (secure_session_t ));
74
88
75
- this -> timer .id = eventOS_callback_timer_register (timer_cb );
76
- if (this -> timer .id == -1 ) {
77
- tr_error ("tasklet alloc failed" );
78
- ns_dyn_mem_free (this );
79
- return NULL ;
89
+ uint8_t timer_id = 1 ;
90
+
91
+ while (secure_session_find_by_timer_id (timer_id )){
92
+ if (timer_id == 0xff ){
93
+ ns_dyn_mem_free (this );
94
+ return NULL ;
95
+ }
96
+ timer_id ++ ;
80
97
}
98
+ this -> timer .id = timer_id ;
81
99
82
100
this -> sec_handler = coap_security_create (parent -> listen_socket , this -> timer .id , address_ptr , port , ECJPAKE ,
83
101
& send_to_socket , & receive_from_socket , & start_timer , & timer_status );
@@ -101,6 +119,9 @@ static void secure_session_delete(secure_session_t *this)
101
119
coap_security_destroy (this -> sec_handler );
102
120
this -> sec_handler = NULL ;
103
121
}
122
+ if (this -> timer .timer ){
123
+ eventOS_timeout_cancel (this -> timer .timer );
124
+ }
104
125
ns_dyn_mem_free (this );
105
126
this = NULL ;
106
127
}
@@ -119,32 +140,6 @@ static void clear_secure_sessions(internal_socket_t *this){
119
140
}
120
141
}
121
142
122
- static secure_session_t * secure_session_find_by_timer_id (int8_t timer_id )
123
- {
124
- secure_session_t * this = NULL ;
125
- ns_list_foreach (secure_session_t , cur_ptr , & secure_session_list ) {
126
- if (cur_ptr -> timer .id == timer_id ) {
127
- this = cur_ptr ;
128
- break ;
129
- }
130
- }
131
- return this ;
132
- }
133
-
134
- static secure_session_t * secure_session_find_by_parent (internal_socket_t * parent )
135
- {
136
- secure_session_t * this = NULL ;
137
- ns_list_foreach (secure_session_t , cur_ptr , & secure_session_list ) {
138
- if ( cur_ptr -> sec_handler ){
139
- if (cur_ptr -> parent == parent ) {
140
- this = cur_ptr ;
141
- break ;
142
- }
143
- }
144
- }
145
- return this ;
146
- }
147
-
148
143
static secure_session_t * secure_session_find (internal_socket_t * parent , uint8_t * address_ptr , uint16_t port )
149
144
{
150
145
secure_session_t * this = NULL ;
@@ -305,29 +300,36 @@ static int receive_from_socket(int8_t socket_id, unsigned char *buf, size_t len)
305
300
* TODO - might be better to use an event timer in conjunction with
306
301
* CoAP tasklet
307
302
*/
308
- static void timer_cb (int8_t timer_id , uint16_t slots )
303
+ static void timer_cb (void * param )
309
304
{
310
- (void )slots ; /* No need to look at slots */
311
-
312
- secure_session_t * sec = secure_session_find_by_timer_id (timer_id );
305
+ secure_session_t * sec = param ;
313
306
if ( sec ){
314
- if (++ sec -> timer .cycle_count == sec -> timer .cycles ) {
307
+ if (sec -> timer .fin_ms > sec -> timer .int_ms ){
308
+ /* Intermediate expiry */
309
+ sec -> timer .fin_ms -= sec -> timer .int_ms ;
310
+ sec -> timer .state = TIMER_STATE_INT_EXPIRY ;
311
+ int error = coap_security_handler_continue_connecting (sec -> sec_handler );
312
+ if (MBEDTLS_ERR_SSL_TIMEOUT == error ) {
313
+ //TODO: How do we handle timeouts?
314
+ secure_session_delete (sec );
315
+ }
316
+ else {
317
+ sec -> timer .timer = eventOS_timeout_ms (timer_cb , sec -> timer .int_ms , (void * )sec );
318
+ }
319
+ }
320
+ else {
315
321
/* We have counted the number of cycles - finish */
322
+ eventOS_timeout_cancel (sec -> timer .timer );
323
+ sec -> timer .fin_ms = 0 ;
324
+ sec -> timer .int_ms = 0 ;
325
+ sec -> timer .timer = NULL ;
316
326
sec -> timer .state = TIMER_STATE_FIN_EXPIRY ;
317
- /* Stop the timer as we no longer need it */
318
- (void )eventOS_callback_timer_stop (sec -> timer .id ); /* We can ignore return; ID is valid */
319
327
int error = coap_security_handler_continue_connecting (sec -> sec_handler );
320
328
if (MBEDTLS_ERR_SSL_TIMEOUT == error ) {
321
329
//TODO: How do we handle timeouts?
322
330
secure_session_delete (sec );
323
331
}
324
- } else {
325
- /* Intermediate expiry */
326
- sec -> timer .state = TIMER_STATE_INT_EXPIRY ;
327
332
}
328
- //TODO: In case of DTLS and count == 1 || 4 we must call continue connecting of security so
329
- //that mbedtls can handle timeout logic: resending etc...
330
- //Not done, because timer should be refactored to be platform specific!
331
333
}
332
334
}
333
335
@@ -336,15 +338,20 @@ static void start_timer(int8_t timer_id, uint32_t int_ms, uint32_t fin_ms)
336
338
secure_session_t * sec = secure_session_find_by_timer_id (timer_id );
337
339
if ( sec ){
338
340
if ((int_ms > 0 ) && (fin_ms > 0 )) {
339
- /* Note: as it stands, fin_ms is always 4 * int_ms, so cycles is always 4 but this may change */
340
- sec -> timer .cycles = fin_ms /int_ms ;
341
- sec -> timer .cycle_count = 0 ;
341
+ sec -> timer .int_ms = int_ms ;
342
+ sec -> timer .fin_ms = fin_ms ;
342
343
sec -> timer .state = TIMER_STATE_NO_EXPIRY ;
343
- eventOS_callback_timer_start (sec -> timer .id , int_ms * TIMER_FACTOR );
344
+ if (sec -> timer .timer ){
345
+ eventOS_timeout_cancel (sec -> timer .timer );
346
+ }
347
+ sec -> timer .timer = eventOS_timeout_ms (timer_cb , int_ms , sec );
344
348
} else if (fin_ms == 0 ) {
345
349
/* fin_ms == 0 means cancel the timer */
346
350
sec -> timer .state = TIMER_STATE_CANCELLED ;
347
- (void )eventOS_callback_timer_stop (sec -> timer .id ); /* We can ignore return; ID will be valid */
351
+ eventOS_timeout_cancel (sec -> timer .timer );
352
+ sec -> timer .fin_ms = 0 ;
353
+ sec -> timer .int_ms = 0 ;
354
+ sec -> timer .timer = NULL ;
348
355
}
349
356
}
350
357
}
@@ -390,17 +397,20 @@ static void secure_recv_sckt_msg(void *cb_res)
390
397
391
398
if ( sock && read_data (sckt_data , sock , & src_address ) == 0 ){
392
399
secure_session_t * session = secure_session_find (sock , src_address .address , src_address .identifier );
400
+
401
+ // Create session
393
402
if ( !session ){
394
403
memcpy ( sock -> dest_addr .address , src_address .address , 16 );
395
404
sock -> dest_addr .identifier = src_address .identifier ;
396
405
sock -> dest_addr .type = src_address .type ;
397
406
session = secure_session_create (sock , src_address .address , src_address .identifier );
398
407
}
399
-
400
408
if ( !session ){
401
409
tr_err ("secure_recv_sckt_msg session creation failed - OOM" );
402
410
return ;
403
411
}
412
+
413
+ // Start handshake
404
414
if ( !session -> sec_handler -> _is_started ){
405
415
uint8_t * pw = (uint8_t * )ns_dyn_mem_alloc (64 );
406
416
uint8_t pw_len ;
@@ -414,27 +424,34 @@ static void secure_recv_sckt_msg(void *cb_res)
414
424
}
415
425
ns_dyn_mem_free (pw );
416
426
}else {
427
+ //Continue handshake
417
428
if ( !session -> secure_done ){
418
- if ( coap_security_handler_continue_connecting (session -> sec_handler ) == 0 ){
429
+ int ret = coap_security_handler_continue_connecting (session -> sec_handler );
430
+ // Handshake done
431
+ if (ret == 0 ){
432
+ eventOS_timeout_cancel (session -> timer .timer );
433
+ session -> timer .timer = NULL ;
419
434
session -> secure_done = true;
420
435
if ( sock -> parent -> _security_done_cb ){
421
436
sock -> parent -> _security_done_cb (sock -> listen_socket , src_address .address ,
422
437
src_address .identifier ,
423
438
session -> sec_handler -> _keyblk .value );
424
439
}
425
440
}
426
- //TODO: error handling
441
+ else if (ret < 0 ){
442
+ // error handling
443
+ // TODO: here we also should clear CoAP retransmission buffer and inform that CoAP request sending is failed.
444
+ secure_session_delete (session );
445
+ }
446
+ //Session valid
427
447
}else {
428
448
unsigned char * data = ns_dyn_mem_temporary_alloc (sock -> data_len );
429
449
int len = 0 ;
430
450
len = coap_security_handler_read (session -> sec_handler , data , sock -> data_len );
431
451
if ( len < 0 ){
432
452
ns_dyn_mem_free (data );
433
453
if ( len == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY ){
434
- // if( sock->parent->sec_conn_closed_cb ){
435
- // sock->parent->sec_conn_closed_cb(sock->listen_socket);
436
454
secure_session_delete ( session );
437
- // }
438
455
}
439
456
}else {
440
457
if ( sock -> parent -> _recv_cb ){
@@ -512,7 +529,8 @@ int coap_connection_handler_virtual_recv(coap_conn_handler_t *handler, uint8_t a
512
529
}
513
530
}else {
514
531
if ( !session -> secure_done ){
515
- if ( coap_security_handler_continue_connecting (session -> sec_handler ) == 0 ){
532
+ int ret = coap_security_handler_continue_connecting (session -> sec_handler );
533
+ if (ret == 0 ){
516
534
session -> secure_done = true;
517
535
if ( handler -> _security_done_cb ){
518
536
handler -> _security_done_cb (sock -> listen_socket ,
@@ -521,6 +539,12 @@ int coap_connection_handler_virtual_recv(coap_conn_handler_t *handler, uint8_t a
521
539
}
522
540
return 0 ;
523
541
}
542
+ else if (ret < 0 )
543
+ {
544
+ // error handling
545
+ // TODO: here we also should clear CoAP retransmission buffer and inform that CoAP request sending is failed.
546
+ secure_session_delete (session );
547
+ }
524
548
//TODO: error handling
525
549
}else {
526
550
unsigned char * data = ns_dyn_mem_temporary_alloc (sock -> data_len );
0 commit comments