11
11
#include "socket_api.h"
12
12
#include "net_interface.h"
13
13
#include "eventOS_event_timer.h"
14
+ #include "coap_service_api_internal.h"
14
15
15
16
#define TRACE_GROUP "ThCH"
16
17
18
+ typedef enum session_state_e {
19
+ SECURE_SESSION_HANDSHAKE_ONGOING = 0 ,
20
+ SECURE_SESSION_OK ,
21
+ SECURE_SESSION_ALERT_SENT
22
+ }session_state_t ;
23
+
17
24
typedef struct internal_socket_s {
18
25
coap_conn_handler_t * parent ;
19
26
@@ -59,7 +66,8 @@ typedef struct secure_session {
59
66
60
67
secure_timer_t timer ;
61
68
62
- bool secure_done ;
69
+ session_state_t session_state ;
70
+ uint32_t session_start_timestamp ;
63
71
ns_list_link_t link ;
64
72
} secure_session_t ;
65
73
@@ -81,10 +89,49 @@ static secure_session_t *secure_session_find_by_timer_id(int8_t timer_id)
81
89
return this ;
82
90
}
83
91
92
+ static void secure_session_delete (secure_session_t * this )
93
+ {
94
+ if (this ) {
95
+ ns_list_remove (& secure_session_list , this );
96
+ if ( this -> sec_handler ){
97
+ coap_security_destroy (this -> sec_handler );
98
+ this -> sec_handler = NULL ;
99
+ }
100
+ if (this -> timer .timer ){
101
+ eventOS_timeout_cancel (this -> timer .timer );
102
+ }
103
+ ns_dyn_mem_free (this );
104
+ this = NULL ;
105
+ }
106
+
107
+ return ;
108
+ }
109
+
84
110
static secure_session_t * secure_session_create (internal_socket_t * parent , uint8_t * address_ptr , uint16_t port )
85
111
{
112
+ if (!address_ptr ){
113
+ return NULL ;
114
+ }
115
+
116
+ if (MAX_SECURE_SESSION_COUNT <= ns_list_count (& secure_session_list )){
117
+ // Seek & destroy oldest session where close notify have been sent
118
+ secure_session_t * to_be_removed = NULL ;
119
+ ns_list_foreach (secure_session_t , cur_ptr , & secure_session_list ) {
120
+ if (cur_ptr -> session_state == SECURE_SESSION_ALERT_SENT ){
121
+ if (!to_be_removed || cur_ptr -> session_start_timestamp < to_be_removed -> session_start_timestamp ){
122
+ to_be_removed = cur_ptr ;
123
+ }
124
+ }
125
+ }
126
+ if (!to_be_removed ){
127
+ return NULL ;
128
+ }
129
+
130
+ secure_session_delete (to_be_removed );
131
+ }
132
+
86
133
secure_session_t * this = ns_dyn_mem_alloc (sizeof (secure_session_t ));
87
- if (!this || ! address_ptr ) {
134
+ if (!this ) {
88
135
return NULL ;
89
136
}
90
137
memset (this , 0 , sizeof (secure_session_t ));
@@ -108,29 +155,12 @@ static secure_session_t *secure_session_create(internal_socket_t *parent, uint8_
108
155
}
109
156
this -> parent = parent ;
110
157
111
- this -> secure_done = false ;
158
+ this -> session_state = SECURE_SESSION_HANDSHAKE_ONGOING ;
112
159
ns_list_add_to_start (& secure_session_list , this );
113
- // hack_save_remote_address(address_ptr, port); //TODO not bad hack
160
+
114
161
return this ;
115
162
}
116
163
117
- static void secure_session_delete (secure_session_t * this )
118
- {
119
- if (this ) {
120
- ns_list_remove (& secure_session_list , this );
121
- if ( this -> sec_handler ){
122
- coap_security_destroy (this -> sec_handler );
123
- this -> sec_handler = NULL ;
124
- }
125
- if (this -> timer .timer ){
126
- eventOS_timeout_cancel (this -> timer .timer );
127
- }
128
- ns_dyn_mem_free (this );
129
- this = NULL ;
130
- }
131
-
132
- return ;
133
- }
134
164
135
165
static void clear_secure_sessions (internal_socket_t * this ){
136
166
if ( this ){
@@ -220,12 +250,12 @@ static void int_socket_delete(internal_socket_t *this)
220
250
ns_dyn_mem_free (this -> data );
221
251
this -> data = NULL ;
222
252
}
253
+ if (this -> parent ){
254
+ ns_dyn_mem_free (this -> parent );
255
+ }
223
256
ns_dyn_mem_free (this );
224
- this = NULL ;
225
257
}
226
258
}
227
-
228
- return ;
229
259
}
230
260
231
261
static internal_socket_t * int_socket_find_by_socket_id (int8_t id )
@@ -414,7 +444,7 @@ static void secure_recv_sckt_msg(void *cb_res)
414
444
tr_err ("secure_recv_sckt_msg session creation failed - OOM" );
415
445
return ;
416
446
}
417
-
447
+ session -> session_start_timestamp = coap_service_get_internal_timer_ticks ();
418
448
// Start handshake
419
449
if ( !session -> sec_handler -> _is_started ){
420
450
uint8_t * pw = (uint8_t * )ns_dyn_mem_alloc (64 );
@@ -430,13 +460,13 @@ static void secure_recv_sckt_msg(void *cb_res)
430
460
ns_dyn_mem_free (pw );
431
461
}else {
432
462
//Continue handshake
433
- if ( ! session -> secure_done ){
463
+ if (session -> session_state == SECURE_SESSION_HANDSHAKE_ONGOING ){
434
464
int ret = coap_security_handler_continue_connecting (session -> sec_handler );
435
465
// Handshake done
436
466
if (ret == 0 ){
437
467
eventOS_timeout_cancel (session -> timer .timer );
438
468
session -> timer .timer = NULL ;
439
- session -> secure_done = true ;
469
+ session -> session_state = SECURE_SESSION_OK ;
440
470
if ( sock -> parent -> _security_done_cb ){
441
471
sock -> parent -> _security_done_cb (sock -> listen_socket , src_address .address ,
442
472
src_address .identifier ,
@@ -473,7 +503,7 @@ static void recv_sckt_msg(void *cb_res)
473
503
internal_socket_t * sock = int_socket_find_by_socket_id (sckt_data -> socket_id );
474
504
ns_address_t src_address ;
475
505
if ( sock && read_data (sckt_data , sock , & src_address ) == 0 ){
476
- if ( sock -> parent -> _recv_cb ){
506
+ if (sock -> parent && sock -> parent -> _recv_cb ){
477
507
sock -> parent -> _recv_cb (sock -> listen_socket , src_address .address , src_address .identifier , sock -> data , sock -> data_len );
478
508
}
479
509
ns_dyn_mem_free (sock -> data );
@@ -514,6 +544,9 @@ int coap_connection_handler_virtual_recv(coap_conn_handler_t *handler, uint8_t a
514
544
tr_err ("coap_connection_handler_virtual_recv session creation failed - OOM" );
515
545
return -1 ;
516
546
}
547
+
548
+ session -> session_start_timestamp = coap_service_get_internal_timer_ticks ();
549
+
517
550
if ( !session -> sec_handler -> _is_started ){
518
551
uint8_t * pw = (uint8_t * )ns_dyn_mem_alloc (64 );
519
552
uint8_t pw_len ;
@@ -531,10 +564,10 @@ int coap_connection_handler_virtual_recv(coap_conn_handler_t *handler, uint8_t a
531
564
return -1 ;
532
565
}
533
566
}else {
534
- if ( ! session -> secure_done ){
567
+ if (session -> session_state == SECURE_SESSION_HANDSHAKE_ONGOING ){
535
568
int ret = coap_security_handler_continue_connecting (session -> sec_handler );
536
569
if (ret == 0 ){
537
- session -> secure_done = true ;
570
+ session -> session_state = SECURE_SESSION_OK ;
538
571
if ( handler -> _security_done_cb ){
539
572
handler -> _security_done_cb (sock -> listen_socket ,
540
573
address , port ,
@@ -598,19 +631,16 @@ coap_conn_handler_t *connection_handler_create(receive_from_socket_cb *recv_from
598
631
handler -> _recv_cb = recv_from_cb ;
599
632
handler -> _send_cb = send_to_cb ;
600
633
601
- // handler->sec_conn_closed_cb = sec_conn_closed_cb;
602
634
handler -> _get_password_cb = pw_cb ;
603
635
handler -> _security_done_cb = done_cb ;
604
636
605
637
return handler ;
606
638
}
607
-
608
639
void connection_handler_destroy (coap_conn_handler_t * handler )
609
640
{
610
641
if (handler ){
611
- int_socket_delete (handler -> socket );
612
- handler -> socket = NULL ;
613
- ns_dyn_mem_free (handler );
642
+ int_socket_delete (handler -> socket );
643
+ ns_dyn_mem_free (handler );
614
644
}
615
645
}
616
646
@@ -621,6 +651,8 @@ void connection_handler_close_secure_connection( coap_conn_handler_t *handler, u
621
651
secure_session_t * session = secure_session_find ( handler -> socket , destination_addr_ptr , port );
622
652
if ( session ){
623
653
coap_security_send_close_alert ( session -> sec_handler );
654
+ session -> session_state = SECURE_SESSION_ALERT_SENT ;
655
+ session -> session_start_timestamp = coap_service_get_internal_timer_ticks ();
624
656
}
625
657
}
626
658
}
@@ -642,15 +674,18 @@ int coap_connection_handler_open_connection(coap_conn_handler_t *handler, uint16
642
674
internal_socket_t * current = !use_ephemeral_port ?int_socket_find (listen_port , is_secure , is_real_socket , bypassSec ):NULL ;
643
675
if (!current ){
644
676
handler -> socket = int_socket_create (listen_port , use_ephemeral_port , is_secure , is_real_socket , bypassSec );
645
- if ( !handler -> socket ){
677
+ if (!handler -> socket ){
678
+ return -1 ;
679
+ }
680
+ handler -> socket -> parent = ns_dyn_mem_alloc (sizeof (coap_conn_handler_t ));
681
+ if (!handler -> socket -> parent ){
682
+ int_socket_delete (handler -> socket );
646
683
return -1 ;
647
684
}
648
- handler -> socket -> parent = handler ;
685
+ * handler -> socket -> parent = * handler ;
649
686
}else {
650
687
current -> usage_counter ++ ;
651
688
handler -> socket = current ;
652
- //handler->parent cannot be set here!
653
- //this will be always problematic if 2 or more secure sockets try to share a same port!
654
689
}
655
690
return 0 ;
656
691
}
@@ -665,12 +700,13 @@ int coap_connection_handler_send_data(coap_conn_handler_t *handler, ns_address_t
665
700
memcpy (handler -> socket -> dest_addr .address , dest_addr -> address , 16 );
666
701
handler -> socket -> dest_addr .identifier = dest_addr -> identifier ;
667
702
handler -> socket -> dest_addr .type = dest_addr -> type ;
668
- secure_session_t * session = secure_session_find ( handler -> socket , dest_addr -> address , dest_addr -> identifier );
703
+ secure_session_t * session = secure_session_find (handler -> socket , dest_addr -> address , dest_addr -> identifier );
669
704
if ( !session ){
670
705
session = secure_session_create (handler -> socket , dest_addr -> address , dest_addr -> identifier );
671
706
if ( !session ){
672
707
return -1 ;
673
708
}
709
+ session -> session_start_timestamp = coap_service_get_internal_timer_ticks ();
674
710
memcpy ( handler -> socket -> dest_addr .address , dest_addr -> address , 16 );
675
711
handler -> socket -> dest_addr .identifier = dest_addr -> identifier ;
676
712
handler -> socket -> dest_addr .type = dest_addr -> type ;
@@ -693,8 +729,9 @@ int coap_connection_handler_send_data(coap_conn_handler_t *handler, ns_address_t
693
729
ns_dyn_mem_free (pw );
694
730
return -1 ;
695
731
}
696
- }else if ( session -> secure_done ){
732
+ }else if ( session -> session_state == SECURE_SESSION_OK ){
697
733
if ( coap_security_handler_send_message (session -> sec_handler , data_ptr , data_len ) > 0 ){
734
+ session -> session_start_timestamp = coap_service_get_internal_timer_ticks ();
698
735
return 0 ;
699
736
}
700
737
}
@@ -736,3 +773,24 @@ int8_t coap_connection_handler_set_timeout(coap_conn_handler_t *handler, uint32_
736
773
737
774
return 0 ;
738
775
}
776
+
777
+ /* No need to call every second - call rather like every minute (SECURE_SESSION_CLEAN_INTERVAL sets this) */
778
+ void coap_connection_handler_exec (uint32_t time )
779
+ {
780
+ if (ns_list_count (& secure_session_list )){
781
+ // Seek & destroy old sessions where close notify have been sent
782
+ ns_list_foreach (secure_session_t , cur_ptr , & secure_session_list ) {
783
+ if (cur_ptr -> session_state == SECURE_SESSION_ALERT_SENT ||
784
+ cur_ptr -> session_state == SECURE_SESSION_HANDSHAKE_ONGOING ){
785
+ if ((cur_ptr -> session_start_timestamp + CLOSED_SECURE_SESSION_TIMEOUT ) <= time ){
786
+ secure_session_delete (cur_ptr );
787
+ }
788
+ }
789
+ if (cur_ptr -> session_state == SECURE_SESSION_OK ){
790
+ if ((cur_ptr -> session_start_timestamp + OPEN_SECURE_SESSION_TIMEOUT ) <= time ){
791
+ secure_session_delete (cur_ptr );
792
+ }
793
+ }
794
+ }
795
+ }
796
+ }
0 commit comments