Skip to content

Commit

Permalink
KeepAlive: Better session cleanup after KeepAlive failure
Browse files Browse the repository at this point in the history
  • Loading branch information
mrdeep1 committed Feb 7, 2025
1 parent 0b41ee0 commit cfc7839
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 22 deletions.
10 changes: 10 additions & 0 deletions include/coap3/coap_session_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,16 @@ coap_session_t *coap_new_client_session_psk2_lkd(coap_context_t *ctx,
coap_session_t *coap_session_new_dtls_session(coap_session_t *session,
coap_tick_t now);

/**
* Clear down a session following a keepalive failure.
* The event handler will get notified of the failure.
* Note: the @p session cannot be used after this function is called.
*
* @param session Session to clear down.
*
*/
void coap_session_server_keepalive_failed(coap_session_t *session);

void coap_session_free(coap_session_t *session);
void coap_session_mfree(coap_session_t *session);

Expand Down
12 changes: 12 additions & 0 deletions include/coap3/coap_subscribe_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,18 @@ int coap_delete_observer_request(coap_resource_t *resource,
*/
void coap_delete_observers(coap_context_t *context, coap_session_t *session);

/**
* Removes specific subscription for @p session for @p resource and releases
* the allocated storage.
*
* @param resource The resource
* @param session The observer's session.
* @param subscription The observer's subscription.
*/
void coap_delete_observer_internal(coap_resource_t *resource,
coap_session_t *session,
coap_subscription_t *subscription);

/**
* Initiate the sending of an Observe packet for all observers of @p resource,
* optionally matching @p query if not NULL
Expand Down
11 changes: 1 addition & 10 deletions src/coap_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -1490,16 +1490,7 @@ coap_io_prepare_io_lkd(coap_context_t *ctx,
/* Some issue - not safe to continue processing */
continue;
if (s->last_ping > 0 && s->last_pong < s->last_ping) {
coap_handle_event_lkd(s->context, COAP_EVENT_KEEPALIVE_FAILURE, s);
coap_session_reference_lkd(s);
RESOURCES_ITER(s->context->resources, r) {
coap_cancel_all_messages(s->context, s, NULL);
coap_delete_observer(r, s, NULL);
}
coap_session_release_lkd(s);
/* Force session to go away */
coap_session_set_type_client_lkd(s);
coap_session_release_lkd(s);
coap_session_server_keepalive_failed(s);
/* check the next session */
continue;
}
Expand Down
12 changes: 9 additions & 3 deletions src/coap_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -763,9 +763,9 @@ coap_free_context_lkd(coap_context_t *context) {
#endif /* COAP_SERVER_SUPPORT */

coap_delete_all(context->sendqueue);
context->sendqueue = NULL;

#ifdef WITH_LWIP
context->sendqueue = NULL;
if (context->timer_configured) {
LOCK_TCPIP_CORE();
sys_untimeout(coap_io_process_timeout, (void *)context);
Expand Down Expand Up @@ -2167,8 +2167,14 @@ coap_retransmit(coap_context_t *context, coap_queue_t *node) {
#if COAP_SERVER_SUPPORT
/* Check if subscriptions exist that should be canceled after
COAP_OBS_MAX_FAIL */
if (COAP_RESPONSE_CLASS(node->pdu->code) >= 2) {
coap_handle_failed_notify(context, node->session, &node->pdu->actual_token);
if (COAP_RESPONSE_CLASS(node->pdu->code) >= 2 && node->session->ref_subscriptions) {
if (context->ping_timeout) {
coap_session_server_keepalive_failed(node->session);
coap_delete_node_lkd(node);
return COAP_INVALID_MID;
} else {
coap_handle_failed_notify(context, node->session, &node->pdu->actual_token);
}
}
#endif /* COAP_SERVER_SUPPORT */
if (node->session->con_active) {
Expand Down
12 changes: 3 additions & 9 deletions src/coap_resource.c
Original file line number Diff line number Diff line change
Expand Up @@ -513,13 +513,7 @@ coap_free_resource(coap_resource_t *resource) {

/* free all elements from resource->subscribers */
LL_FOREACH_SAFE(resource->subscribers, obs, otmp) {
if (resource->context->observe_deleted)
resource->context->observe_deleted(obs->session, obs,
resource->context->observe_user_data);
coap_session_release_lkd(obs->session);
coap_delete_pdu_lkd(obs->pdu);
coap_delete_cache_key(obs->cache_key);
coap_free_type(COAP_SUBSCRIPTION, obs);
coap_delete_observer_internal(resource, obs->session, obs);
}
if (resource->proxy_name_count && resource->proxy_name_list) {
size_t i;
Expand Down Expand Up @@ -996,7 +990,7 @@ coap_touch_observer(coap_context_t *context, coap_session_t *session,
}
}

static void
void
coap_delete_observer_internal(coap_resource_t *resource, coap_session_t *session,
coap_subscription_t *s) {
if (!s)
Expand All @@ -1022,9 +1016,9 @@ coap_delete_observer_internal(coap_resource_t *resource, coap_session_t *session

if (resource->subscribers) {
LL_DELETE(resource->subscribers, s);
coap_session_release_lkd(session);
assert(session->ref_subscriptions > 0);
session->ref_subscriptions--;
coap_session_release_lkd(session);
coap_delete_pdu_lkd(s->pdu);
coap_delete_cache_key(s->cache_key);
coap_free_type(COAP_SUBSCRIPTION, s);
Expand Down
22 changes: 22 additions & 0 deletions src/coap_session.c
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,28 @@ coap_session_free(coap_session_t *session) {
coap_free_type(COAP_SESSION, session);
}

#if COAP_SERVER_SUPPORT
void
coap_session_server_keepalive_failed(coap_session_t *session) {
coap_handle_event_lkd(session->context, COAP_EVENT_KEEPALIVE_FAILURE, session);
coap_session_reference_lkd(session);
coap_cancel_all_messages(session->context, session, NULL);
RESOURCES_ITER(session->context->resources, r) {
coap_delete_observer(r, session, NULL);
}
while (session->delayqueue) {
coap_queue_t *q = session->delayqueue;

session->delayqueue = q->next;
coap_delete_node_lkd(q);
}
coap_session_release_lkd(session);
/* Force session to go away */
coap_session_set_type_client_lkd(session);
coap_session_release_lkd(session);
}
#endif /* COAP_SERVER_SUPPORT */

static size_t
coap_session_max_pdu_size_internal(const coap_session_t *session,
size_t max_with_header) {
Expand Down

0 comments on commit cfc7839

Please sign in to comment.