Skip to content

Commit

Permalink
Limit number of ongoing handshakes (ARMmbed#77)
Browse files Browse the repository at this point in the history
* Limit number of ongoing handshakes

Set limit for ongoing handshakes to save memory during multiple simultaneous
handshake attempts.

* API to set handshake limits

Added API to change handshake limit parameters. Default values are defined in
coap_connection_handler.h

* Unittests updated
  • Loading branch information
Tero Heinonen authored Oct 23, 2017
1 parent 42c1169 commit 58f0ed5
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 6 deletions.
13 changes: 13 additions & 0 deletions coap-service/coap_service_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,19 @@ extern int8_t coap_service_request_delete(int8_t service_id, uint16_t msg_id);
*/
extern int8_t coap_service_set_handshake_timeout(int8_t service_id, uint32_t min, uint32_t max);

/**
* \brief Set DTLS handshake limit values
*
* Configures the limits for DTLS sessions. Values must be > 0.
*
* \param handshakes_max Maximum amount of simultaneous handshakes.
* \param connections_max Maximum amount of sessions.
*
* \return -1 For failure
*- 0 For success
*/
extern int8_t coap_service_handshake_limits_set(uint8_t handshakes_max, uint8_t connections_max);

/**
* \brief Set CoAP duplication message buffer size
*
Expand Down
37 changes: 32 additions & 5 deletions source/coap_connection_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ const uint8_t COAP_MULTICAST_ADDR_SITE_LOCAL[16] = { 0xff, 0x05, [15] = 0xfd };

static NS_LIST_DEFINE(socket_list, internal_socket_t, link);

static uint8_t max_handshakes = MAX_ONGOING_HANDSHAKES;
static uint8_t max_sessions = MAX_SECURE_SESSION_COUNT;

static void timer_cb(void* param);

static void recv_sckt_msg(void *cb_res);
Expand Down Expand Up @@ -143,11 +146,12 @@ static int8_t virtual_socket_id_allocate()

static secure_session_t *secure_session_create(internal_socket_t *parent, const uint8_t *address_ptr, uint16_t port, SecureConnectionMode secure_mode)
{
uint8_t handshakes = 0;
if(!address_ptr){
return NULL;
}

if(MAX_SECURE_SESSION_COUNT <= ns_list_count(&secure_session_list)){
if(max_sessions <= ns_list_count(&secure_session_list)){
// Seek & destroy oldest session where close notify have been sent
secure_session_t *to_be_removed = NULL;
ns_list_foreach(secure_session_t, cur_ptr, &secure_session_list) {
Expand All @@ -164,6 +168,16 @@ static secure_session_t *secure_session_create(internal_socket_t *parent, const
secure_session_delete(to_be_removed);
}

// Count for ongoing handshakes
ns_list_foreach(secure_session_t, cur_ptr, &secure_session_list) {
if(cur_ptr->session_state == SECURE_SESSION_HANDSHAKE_ONGOING){
handshakes++;
}
}
if(handshakes >= max_handshakes) {
return NULL;
}

secure_session_t *this = ns_dyn_mem_alloc(sizeof(secure_session_t));
if (!this) {
return NULL;
Expand Down Expand Up @@ -939,22 +953,35 @@ int8_t coap_connection_handler_set_timeout(coap_conn_handler_t *handler, uint32_
return 0;
}

int8_t coap_connection_handler_handshake_limits_set(uint8_t handshakes_limit, uint8_t connections_limit)
{
if (!handshakes_limit || !connections_limit) {
return -1;
}
max_handshakes = handshakes_limit;
max_sessions = connections_limit;

return 0;
}

/* No need to call every second - call rather like every minute (SECURE_SESSION_CLEAN_INTERVAL sets this) */
void coap_connection_handler_exec(uint32_t time)
{
if(ns_list_count(&secure_session_list)){
// Seek & destroy old sessions where close notify have been sent
ns_list_foreach(secure_session_t, cur_ptr, &secure_session_list) {
if(cur_ptr->session_state == SECURE_SESSION_CLOSED ||
cur_ptr->session_state == SECURE_SESSION_HANDSHAKE_ONGOING){
if(cur_ptr->session_state == SECURE_SESSION_CLOSED) {
if((cur_ptr->last_contact_time + CLOSED_SECURE_SESSION_TIMEOUT) <= time){
secure_session_delete(cur_ptr);
}
}
if(cur_ptr->session_state == SECURE_SESSION_OK){
} else if(cur_ptr->session_state == SECURE_SESSION_OK){
if((cur_ptr->last_contact_time + OPEN_SECURE_SESSION_TIMEOUT) <= time){
secure_session_delete(cur_ptr);
}
} else if(cur_ptr->session_state == SECURE_SESSION_HANDSHAKE_ONGOING){
if((cur_ptr->last_contact_time + ONGOING_HANDSHAKE_TIMEOUT) <= time){
secure_session_delete(cur_ptr);
}
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions source/coap_service_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,11 @@ int8_t coap_service_set_handshake_timeout(int8_t service_id, uint32_t min, uint3
return coap_connection_handler_set_timeout(this->conn_handler, min, max);
}

int8_t coap_service_handshake_limits_set(uint8_t handshakes_max, uint8_t connections_max)
{
return coap_connection_handler_handshake_limits_set(handshakes_max, connections_max);
}

int8_t coap_service_set_duplicate_message_buffer(int8_t service_id, uint8_t size)
{
(void) service_id;
Expand Down
6 changes: 5 additions & 1 deletion source/include/coap_connection_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@
#include "coap_security_handler.h"

#define MAX_SECURE_SESSION_COUNT 3
#define MAX_ONGOING_HANDSHAKES 2
#define CLOSED_SECURE_SESSION_TIMEOUT 3600 // Seconds
#define OPEN_SECURE_SESSION_TIMEOUT 18000 // Seconds
#define ONGOING_HANDSHAKE_TIMEOUT 600 // Seconds
#define OPEN_SECURE_SESSION_TIMEOUT 18000 // Seconds
#define SECURE_SESSION_CLEAN_INTERVAL 60 // Seconds

struct internal_socket_s;
Expand Down Expand Up @@ -71,6 +73,8 @@ bool coap_connection_handler_socket_belongs_to(coap_conn_handler_t *handler, int

int8_t coap_connection_handler_set_timeout(coap_conn_handler_t *handler, uint32_t min, uint32_t max);

int8_t coap_connection_handler_handshake_limits_set(uint8_t handshakes_limit, uint8_t connections_limit);

void coap_connection_handler_exec(uint32_t time);

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,8 @@ TEST(coap_service_api, test_coap_service_if_find_by_socket)
{
CHECK(test_coap_service_if_find_by_socket())
}

TEST(coap_service_api, test_coap_service_handshake_limit_set)
{
CHECK(test_coap_service_handshake_limit_set())
}
Original file line number Diff line number Diff line change
Expand Up @@ -567,3 +567,12 @@ bool test_coap_service_if_find_by_socket()

return true;
}

bool test_coap_service_handshake_limit_set()
{
if (0 != coap_service_handshake_limits_set(2, 2)) {
return false;
}

return true;
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ bool test_coap_service_get_internal_timer_ticks();

bool test_coap_service_if_find_by_socket();

bool test_coap_service_handshake_limit_set();


#ifdef __cplusplus
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ int8_t coap_connection_handler_set_timeout(coap_conn_handler_t *handler, uint32_
return 0;
}

int8_t coap_connection_handler_handshake_limits_set(uint8_t handshakes_limit, uint8_t connections_limit)
{
return 0;
}

void coap_connection_handler_exec(uint32_t time)
{

Expand Down

0 comments on commit 58f0ed5

Please sign in to comment.