@@ -27,13 +27,12 @@ typedef struct internal_socket_s {
27
27
uint32_t timeout_min ;
28
28
uint32_t timeout_max ;
29
29
30
- uint16_t listen_port ;
31
- int8_t listen_socket ;
30
+ uint16_t listen_port ; // 0 for ephemeral-port sockets
32
31
33
- ns_address_t dest_addr ;
34
32
int16_t data_len ;
35
33
uint8_t * data ;
36
34
35
+ int8_t socket ;
37
36
bool real_socket ;
38
37
uint8_t usage_counter ;
39
38
bool is_secure ;
@@ -64,8 +63,9 @@ typedef struct secure_session {
64
63
coap_security_t * sec_handler ; //owned
65
64
internal_socket_t * parent ; //not owned
66
65
67
- uint8_t remote_address [16 ];
68
- uint16_t remote_port ;
66
+ ns_address_t remote_host ;
67
+ uint8_t local_address [16 ];
68
+ // local port is fixed by socket
69
69
70
70
secure_timer_t timer ;
71
71
@@ -75,8 +75,8 @@ typedef struct secure_session {
75
75
} secure_session_t ;
76
76
77
77
static NS_LIST_DEFINE (secure_session_list , secure_session_t , link ) ;
78
- static int send_to_socket (int8_t socket_id , void * handle , const void * buf , size_t len );
79
- static int receive_from_socket (int8_t socket_id , unsigned char * buf , size_t len );
78
+ static int secure_session_sendto (int8_t socket_id , void * handle , const void * buf , size_t len );
79
+ static int secure_session_recvfrom (int8_t socket_id , unsigned char * buf , size_t len );
80
80
static void start_timer (int8_t timer_id , uint32_t int_ms , uint32_t fin_ms );
81
81
static int timer_status (int8_t timer_id );
82
82
@@ -95,7 +95,7 @@ static secure_session_t *secure_session_find_by_timer_id(int8_t timer_id)
95
95
static void secure_session_delete (secure_session_t * this )
96
96
{
97
97
if (this ) {
98
- transactions_delete_all (this -> parent -> dest_addr .address , this -> parent -> dest_addr .identifier );
98
+ transactions_delete_all (this -> remote_host .address , this -> remote_host .identifier );
99
99
ns_list_remove (& secure_session_list , this );
100
100
if ( this -> sec_handler ){
101
101
coap_security_destroy (this -> sec_handler );
@@ -150,11 +150,12 @@ static secure_session_t *secure_session_create(internal_socket_t *parent, const
150
150
timer_id ++ ;
151
151
}
152
152
this -> timer .id = timer_id ;
153
- memcpy (this -> remote_address , address_ptr , 16 );
154
- this -> remote_port = port ;
153
+ this -> remote_host .type = ADDRESS_IPV6 ;
154
+ memcpy (this -> remote_host .address , address_ptr , 16 );
155
+ this -> remote_host .identifier = port ;
155
156
156
- this -> sec_handler = coap_security_create (parent -> listen_socket , this -> timer .id , this , ECJPAKE ,
157
- & send_to_socket , & receive_from_socket , & start_timer , & timer_status );
157
+ this -> sec_handler = coap_security_create (parent -> socket , this -> timer .id , this , ECJPAKE ,
158
+ & secure_session_sendto , & secure_session_recvfrom , & start_timer , & timer_status );
158
159
if ( !this -> sec_handler ){
159
160
ns_dyn_mem_free (this );
160
161
return NULL ;
@@ -184,10 +185,9 @@ static secure_session_t *secure_session_find(internal_socket_t *parent, const ui
184
185
secure_session_t * this = NULL ;
185
186
ns_list_foreach (secure_session_t , cur_ptr , & secure_session_list ) {
186
187
if ( cur_ptr -> sec_handler ){
187
- if (cur_ptr -> parent == parent && cur_ptr -> remote_port == port &&
188
- memcmp (cur_ptr -> remote_address , address_ptr , 16 ) == 0 ) {
188
+ if (cur_ptr -> parent == parent && cur_ptr -> remote_host . identifier == port &&
189
+ memcmp (cur_ptr -> remote_host . address , address_ptr , 16 ) == 0 ) {
189
190
this = cur_ptr ;
190
- // hack_save_remote_address(address_ptr, port);
191
191
break ;
192
192
}
193
193
}
@@ -217,36 +217,36 @@ static internal_socket_t *int_socket_create(uint16_t listen_port, bool use_ephem
217
217
this -> listen_port = listen_port ;
218
218
this -> real_socket = real_socket ;
219
219
this -> bypass_link_sec = bypassSec ;
220
- this -> listen_socket = -1 ;
220
+ this -> socket = -1 ;
221
221
if ( real_socket ){
222
222
if ( use_ephemeral_port ){ //socket_api creates ephemeral port if the one provided is 0
223
223
listen_port = 0 ;
224
224
}
225
225
if ( !is_secure ){
226
- this -> listen_socket = socket_open (SOCKET_UDP , listen_port , recv_sckt_msg );
226
+ this -> socket = socket_open (SOCKET_UDP , listen_port , recv_sckt_msg );
227
227
}else {
228
228
#ifdef COAP_SECURITY_AVAILABLE
229
- this -> listen_socket = socket_open (SOCKET_UDP , listen_port , secure_recv_sckt_msg );
229
+ this -> socket = socket_open (SOCKET_UDP , listen_port , secure_recv_sckt_msg );
230
230
#else
231
231
tr_err ("Secure CoAP unavailable - SSL library not configured, possibly due to lack of entropy source" );
232
232
#endif
233
233
}
234
234
// Socket create failed
235
- if (this -> listen_socket < 0 ){
235
+ if (this -> socket < 0 ){
236
236
ns_dyn_mem_free (this );
237
237
return NULL ;
238
238
}
239
239
240
- socket_setsockopt (this -> listen_socket , SOCKET_IPPROTO_IPV6 , SOCKET_LINK_LAYER_SECURITY , & (const int8_t ) {bypassSec ? 0 : 1 }, sizeof (int8_t ));
240
+ socket_setsockopt (this -> socket , SOCKET_IPPROTO_IPV6 , SOCKET_LINK_LAYER_SECURITY , & (const int8_t ) {bypassSec ? 0 : 1 }, sizeof (int8_t ));
241
241
242
242
// XXX API for this? May want to get clever to do recommended first query = 1 hop, retries = whole PAN
243
- socket_setsockopt (this -> listen_socket , SOCKET_IPPROTO_IPV6 , SOCKET_IPV6_MULTICAST_HOPS , & (const int16_t ) {16 }, sizeof (int16_t ));
243
+ socket_setsockopt (this -> socket , SOCKET_IPPROTO_IPV6 , SOCKET_IPV6_MULTICAST_HOPS , & (const int16_t ) {16 }, sizeof (int16_t ));
244
244
245
245
// Set socket option to receive packet info
246
- socket_setsockopt (this -> listen_socket , SOCKET_IPPROTO_IPV6 , SOCKET_IPV6_RECVPKTINFO , & (const bool ) {1 }, sizeof (bool ));
246
+ socket_setsockopt (this -> socket , SOCKET_IPPROTO_IPV6 , SOCKET_IPV6_RECVPKTINFO , & (const bool ) {1 }, sizeof (bool ));
247
247
248
248
}else {
249
- this -> listen_socket = -1 ;
249
+ this -> socket = -1 ;
250
250
}
251
251
252
252
ns_list_add_to_start (& socket_list , this );
@@ -259,7 +259,7 @@ static void int_socket_delete(internal_socket_t *this)
259
259
this -> usage_counter -- ;
260
260
if (this -> usage_counter == 0 ){
261
261
clear_secure_sessions (this );
262
- socket_free (this -> listen_socket );
262
+ socket_free (this -> socket );
263
263
ns_list_remove (& socket_list , this );
264
264
if ( this -> data ){
265
265
ns_dyn_mem_free (this -> data );
@@ -277,7 +277,7 @@ static internal_socket_t *int_socket_find_by_socket_id(int8_t id)
277
277
{
278
278
internal_socket_t * this = NULL ;
279
279
ns_list_foreach (internal_socket_t , cur_ptr , & socket_list ) {
280
- if ( cur_ptr -> listen_socket == id ) {
280
+ if ( cur_ptr -> socket == id ) {
281
281
this = cur_ptr ;
282
282
break ;
283
283
}
@@ -339,7 +339,7 @@ static int8_t send_to_real_socket(int8_t socket_id, const ns_address_t *address,
339
339
return socket_sendmsg (socket_id , & msghdr , 0 );
340
340
}
341
341
342
- static int send_to_socket (int8_t socket_id , void * handle , const void * buf , size_t len )
342
+ static int secure_session_sendto (int8_t socket_id , void * handle , const void * buf , size_t len )
343
343
{
344
344
secure_session_t * session = handle ;
345
345
internal_socket_t * sock = int_socket_find_by_socket_id (socket_id );
@@ -348,7 +348,7 @@ static int send_to_socket(int8_t socket_id, void *handle, const void *buf, size_
348
348
}
349
349
if (!sock -> real_socket ){
350
350
// Send to virtual socket cb
351
- int ret = sock -> parent -> _send_cb (sock -> listen_socket , session -> remote_address , session -> remote_port , buf , len );
351
+ int ret = sock -> parent -> _send_cb (sock -> socket , session -> remote_host . address , session -> remote_host . identifier , buf , len );
352
352
if ( ret < 0 )
353
353
return ret ;
354
354
return len ;
@@ -359,19 +359,19 @@ static int send_to_socket(int8_t socket_id, void *handle, const void *buf, size_
359
359
if (sock -> bypass_link_sec ) {
360
360
securityLinkLayer = 0 ;
361
361
}
362
- socket_setsockopt (sock -> listen_socket , SOCKET_IPPROTO_IPV6 , SOCKET_IPV6_ADDR_PREFERENCES , & opt_name , sizeof (int ));
363
- socket_setsockopt (sock -> listen_socket , SOCKET_IPPROTO_IPV6 , SOCKET_LINK_LAYER_SECURITY , & securityLinkLayer , sizeof (int8_t ));
362
+ socket_setsockopt (sock -> socket , SOCKET_IPPROTO_IPV6 , SOCKET_IPV6_ADDR_PREFERENCES , & opt_name , sizeof (int ));
363
+ socket_setsockopt (sock -> socket , SOCKET_IPPROTO_IPV6 , SOCKET_LINK_LAYER_SECURITY , & securityLinkLayer , sizeof (int8_t ));
364
364
//For some reason socket_sendto returns 0 in success, while other socket impls return number of bytes sent!!!
365
365
//TODO: check if address_ptr is valid and use that instead if it is
366
366
367
- int8_t ret = send_to_real_socket (sock -> listen_socket , & sock -> dest_addr , session -> remote_address , buf , len );
367
+ int8_t ret = send_to_real_socket (sock -> socket , & session -> remote_host , session -> local_address , buf , len );
368
368
if (ret < 0 ) {
369
369
return ret ;
370
370
}
371
371
return len ;
372
372
}
373
373
374
- static int receive_from_socket (int8_t socket_id , unsigned char * buf , size_t len )
374
+ static int secure_session_recvfrom (int8_t socket_id , unsigned char * buf , size_t len )
375
375
{
376
376
(void )len ;
377
377
internal_socket_t * sock = int_socket_find_by_socket_id (socket_id );
@@ -537,21 +537,23 @@ static void secure_recv_sckt_msg(void *cb_res)
537
537
538
538
// Create session
539
539
if (!session ) {
540
- memcpy ( sock -> dest_addr .address , src_address .address , 16 );
541
- sock -> dest_addr .identifier = src_address .identifier ;
542
- sock -> dest_addr .type = src_address .type ;
543
540
session = secure_session_create (sock , src_address .address , src_address .identifier );
544
541
}
545
542
if (!session ) {
546
543
tr_err ("secure_recv_sckt_msg session creation failed - OOM" );
547
544
return ;
548
545
}
546
+ // Record the destination. We are not strict on local address - all
547
+ // session_find calls match only on remote address and port. But we
548
+ // record the last-used destination address to use it as the source of
549
+ // outgoing packets.
550
+ memcpy (session -> local_address , dst_address , 16 );
549
551
session -> last_contact_time = coap_service_get_internal_timer_ticks ();
550
552
// Start handshake
551
553
if (!coap_security_handler_is_started (session -> sec_handler ) ){
552
554
uint8_t * pw = ns_dyn_mem_alloc (64 );
553
555
uint8_t pw_len ;
554
- if ( sock -> parent -> _get_password_cb && 0 == sock -> parent -> _get_password_cb (sock -> listen_socket , src_address .address , src_address .identifier , pw , & pw_len )){
556
+ if ( sock -> parent -> _get_password_cb && 0 == sock -> parent -> _get_password_cb (sock -> socket , src_address .address , src_address .identifier , pw , & pw_len )){
555
557
//TODO: get_password_cb should support certs and PSK also
556
558
coap_security_keys_t keys ;
557
559
keys ._priv = pw ;
@@ -570,7 +572,7 @@ static void secure_recv_sckt_msg(void *cb_res)
570
572
session -> timer .timer = NULL ;
571
573
session -> session_state = SECURE_SESSION_OK ;
572
574
if ( sock -> parent -> _security_done_cb ){
573
- sock -> parent -> _security_done_cb (sock -> listen_socket , src_address .address ,
575
+ sock -> parent -> _security_done_cb (sock -> socket , src_address .address ,
574
576
src_address .identifier ,
575
577
(void * )coap_security_handler_keyblock (session -> sec_handler ));
576
578
}
@@ -592,7 +594,7 @@ static void secure_recv_sckt_msg(void *cb_res)
592
594
ns_dyn_mem_free (data );
593
595
} else {
594
596
if (sock -> parent -> _recv_cb ) {
595
- sock -> parent -> _recv_cb (sock -> listen_socket , src_address .address , src_address .identifier , dst_address , data , len );
597
+ sock -> parent -> _recv_cb (sock -> socket , src_address .address , src_address .identifier , dst_address , data , len );
596
598
}
597
599
ns_dyn_mem_free (data );
598
600
}
@@ -610,7 +612,7 @@ static void recv_sckt_msg(void *cb_res)
610
612
611
613
if (sock && read_data (sckt_data , sock , & src_address , dst_address ) == 0 ) {
612
614
if (sock -> parent && sock -> parent -> _recv_cb ) {
613
- sock -> parent -> _recv_cb (sock -> listen_socket , src_address .address , src_address .identifier , dst_address , sock -> data , sock -> data_len );
615
+ sock -> parent -> _recv_cb (sock -> socket , src_address .address , src_address .identifier , dst_address , sock -> data , sock -> data_len );
614
616
}
615
617
ns_dyn_mem_free (sock -> data );
616
618
sock -> data = NULL ;
@@ -656,7 +658,7 @@ int coap_connection_handler_virtual_recv(coap_conn_handler_t *handler, uint8_t a
656
658
if (!coap_security_handler_is_started (session -> sec_handler )) {
657
659
uint8_t * pw = ns_dyn_mem_alloc (64 );
658
660
uint8_t pw_len ;
659
- if (sock -> parent -> _get_password_cb && 0 == sock -> parent -> _get_password_cb (sock -> listen_socket , address , port , pw , & pw_len )) {
661
+ if (sock -> parent -> _get_password_cb && 0 == sock -> parent -> _get_password_cb (sock -> socket , address , port , pw , & pw_len )) {
660
662
//TODO: get_password_cb should support certs and PSK also
661
663
coap_security_keys_t keys ;
662
664
keys ._priv = pw ;
@@ -675,7 +677,7 @@ int coap_connection_handler_virtual_recv(coap_conn_handler_t *handler, uint8_t a
675
677
if (ret == 0 ){
676
678
session -> session_state = SECURE_SESSION_OK ;
677
679
if ( handler -> _security_done_cb ){
678
- handler -> _security_done_cb (sock -> listen_socket ,
680
+ handler -> _security_done_cb (sock -> socket ,
679
681
address , port ,
680
682
(void * )coap_security_handler_keyblock (session -> sec_handler ));
681
683
}
@@ -700,7 +702,7 @@ int coap_connection_handler_virtual_recv(coap_conn_handler_t *handler, uint8_t a
700
702
return 0 ;
701
703
} else {
702
704
if (sock -> parent -> _recv_cb ) {
703
- sock -> parent -> _recv_cb (sock -> listen_socket , address , port , ns_in6addr_any , data , len );
705
+ sock -> parent -> _recv_cb (sock -> socket , address , port , ns_in6addr_any , data , len );
704
706
}
705
707
ns_dyn_mem_free (data );
706
708
data = NULL ;
@@ -711,7 +713,7 @@ int coap_connection_handler_virtual_recv(coap_conn_handler_t *handler, uint8_t a
711
713
} else {
712
714
/* unsecure*/
713
715
if (sock -> parent -> _recv_cb ) {
714
- sock -> parent -> _recv_cb (sock -> listen_socket , address , port , ns_in6addr_any , sock -> data , sock -> data_len );
716
+ sock -> parent -> _recv_cb (sock -> socket , address , port , ns_in6addr_any , sock -> data , sock -> data_len );
715
717
}
716
718
if (sock -> data ) {
717
719
ns_dyn_mem_free (sock -> data );
@@ -757,7 +759,7 @@ void connection_handler_close_secure_connection( coap_conn_handler_t *handler, u
757
759
{
758
760
if (handler ) {
759
761
if (handler -> socket && handler -> socket -> is_secure ) {
760
- secure_session_t * session = secure_session_find ( handler -> socket , destination_addr_ptr , port );
762
+ secure_session_t * session = secure_session_find ( handler -> socket , destination_addr_ptr , port );
761
763
if (session ) {
762
764
coap_security_send_close_alert ( session -> sec_handler );
763
765
session -> session_state = SECURE_SESSION_CLOSED ;
@@ -806,26 +808,20 @@ int coap_connection_handler_send_data(coap_conn_handler_t *handler, const ns_add
806
808
}
807
809
if (handler -> socket -> is_secure ) {
808
810
handler -> socket -> bypass_link_sec = bypass_link_sec ;
809
- memcpy (handler -> socket -> dest_addr .address , dest_addr -> address , 16 );
810
- handler -> socket -> dest_addr .identifier = dest_addr -> identifier ;
811
- handler -> socket -> dest_addr .type = dest_addr -> type ;
812
811
secure_session_t * session = secure_session_find (handler -> socket , dest_addr -> address , dest_addr -> identifier );
813
812
if (!session ) {
814
813
session = secure_session_create (handler -> socket , dest_addr -> address , dest_addr -> identifier );
815
814
if (!session ) {
816
815
return -1 ;
817
816
}
818
817
session -> last_contact_time = coap_service_get_internal_timer_ticks ();
819
- memcpy ( handler -> socket -> dest_addr .address , dest_addr -> address , 16 );
820
- handler -> socket -> dest_addr .identifier = dest_addr -> identifier ;
821
- handler -> socket -> dest_addr .type = dest_addr -> type ;
822
818
uint8_t * pw = ns_dyn_mem_alloc (64 );
823
819
if (!pw ) {
824
820
//todo: free secure session?
825
821
return -1 ;
826
822
}
827
823
uint8_t pw_len ;
828
- if (handler -> _get_password_cb && 0 == handler -> _get_password_cb (handler -> socket -> listen_socket , (uint8_t * )dest_addr -> address , dest_addr -> identifier , pw , & pw_len )) {
824
+ if (handler -> _get_password_cb && 0 == handler -> _get_password_cb (handler -> socket -> socket , (uint8_t * )dest_addr -> address , dest_addr -> identifier , pw , & pw_len )) {
829
825
//TODO: get_password_cb should support certs and PSK also
830
826
coap_security_keys_t keys ;
831
827
keys ._priv = pw ;
@@ -847,18 +843,18 @@ int coap_connection_handler_send_data(coap_conn_handler_t *handler, const ns_add
847
843
return -1 ;
848
844
}else {
849
845
if (!handler -> socket -> real_socket && handler -> _send_cb ) {
850
- return handler -> _send_cb ((int8_t )handler -> socket -> listen_socket , dest_addr -> address , dest_addr -> identifier , data_ptr , data_len );
846
+ return handler -> _send_cb ((int8_t )handler -> socket -> socket , dest_addr -> address , dest_addr -> identifier , data_ptr , data_len );
851
847
}
852
848
int opt_name = SOCKET_IPV6_PREFER_SRC_6LOWPAN_SHORT ;
853
849
int8_t securityLinkLayer = 1 ;
854
850
if (bypass_link_sec ) {
855
851
securityLinkLayer = 0 ;
856
852
}
857
853
858
- socket_setsockopt (handler -> socket -> listen_socket , SOCKET_IPPROTO_IPV6 , SOCKET_IPV6_ADDR_PREFERENCES , & opt_name , sizeof (int ));
859
- socket_setsockopt (handler -> socket -> listen_socket , SOCKET_IPPROTO_IPV6 , SOCKET_LINK_LAYER_SECURITY , & securityLinkLayer , sizeof (int8_t ));
854
+ socket_setsockopt (handler -> socket -> socket , SOCKET_IPPROTO_IPV6 , SOCKET_IPV6_ADDR_PREFERENCES , & opt_name , sizeof (int ));
855
+ socket_setsockopt (handler -> socket -> socket , SOCKET_IPPROTO_IPV6 , SOCKET_LINK_LAYER_SECURITY , & securityLinkLayer , sizeof (int8_t ));
860
856
861
- return send_to_real_socket (handler -> socket -> listen_socket , dest_addr , src_address , data_ptr , data_len );
857
+ return send_to_real_socket (handler -> socket -> socket , dest_addr , src_address , data_ptr , data_len );
862
858
}
863
859
}
864
860
@@ -868,7 +864,7 @@ bool coap_connection_handler_socket_belongs_to(coap_conn_handler_t *handler, int
868
864
return false;
869
865
}
870
866
871
- if ( handler -> socket -> listen_socket == socket_id ){
867
+ if ( handler -> socket -> socket == socket_id ){
872
868
return true;
873
869
}
874
870
return false;
0 commit comments