Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ports: Enhance TCP Client Disconnect Notifications in TLS Handling #627

Merged
merged 4 commits into from
Jun 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 1 addition & 13 deletions api/cloud/oc_cloud.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,19 +132,7 @@ void
oc_cloud_close_endpoint(const oc_endpoint_t *ep)
{
OC_CLOUD_DBG("oc_cloud_close_endpoint");
#ifdef OC_SECURITY
const oc_tls_peer_t *peer = oc_tls_get_peer(ep);
if (peer != NULL) {
OC_CLOUD_DBG("oc_cloud_close_endpoint: oc_tls_close_connection");
oc_tls_close_connection(ep);
} else
#endif /* OC_SECURITY */
{
#ifdef OC_TCP
OC_CLOUD_DBG("oc_cloud_close_endpoint: oc_connectivity_end_session");
oc_connectivity_end_session(ep);
#endif /* OC_TCP */
}
oc_close_session(ep);
}

void
Expand Down
38 changes: 28 additions & 10 deletions api/oc_client_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@

#include "oc_config.h"

#include "oc_api.h"
#include "oc_endpoint.h"

#ifdef OC_TCP
#include "api/oc_session_events_internal.h"
#include "port/oc_connectivity_internal.h"
#endif /* OC_TCP */

#ifdef OC_SECURITY
#include "security/oc_tls_internal.h"
#endif /* OC_SECURITY */

#ifdef OC_CLIENT

#include "api/client/oc_client_cb_internal.h"
Expand All @@ -38,10 +50,6 @@
#include "messaging/coap/signal_internal.h"
#endif /* OC_TCP */

#ifdef OC_SECURITY
#include "security/oc_tls_internal.h"
#endif /* OC_SECURITY */

#include <assert.h>

typedef struct oc_dispatch_context_t
Expand Down Expand Up @@ -948,18 +956,28 @@ oc_do_ip_discovery_at_endpoint(const char *rt, oc_discovery_handler_t handler,
return status;
}

#endif /* OC_CLIENT */

void
oc_close_session(const oc_endpoint_t *endpoint)
{
if (endpoint->flags & SECURED) {
#ifdef OC_SECURITY
if ((endpoint->flags & SECURED) != 0) {
oc_tls_close_connection(endpoint);
return;
}
#endif /* OC_SECURITY */
} else if (endpoint->flags & TCP) {
#ifdef OC_TCP
oc_connectivity_end_session(endpoint);
#endif /* OC_TCP */
if ((endpoint->flags & TCP) != 0) {
oc_endpoint_t session_endpoint;
while (oc_connectivity_end_session_v1(endpoint, false, &session_endpoint)) {
oc_handle_session(&session_endpoint, OC_SESSION_DISCONNECTED);
}
return;
}
}
#endif /* OC_TCP */

#endif /* OC_CLIENT */
#if !defined(OC_TCP) && !defined(OC_SECURITY)
(void)endpoint;
#endif /* !OC_TCP && !OC_SECURITY */
}
Danielius1922 marked this conversation as resolved.
Show resolved Hide resolved
23 changes: 22 additions & 1 deletion api/oc_endpoint.c
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,18 @@ oc_endpoint_compare_address(const oc_endpoint_t *ep1, const oc_endpoint_t *ep2)
return -1;
}

#ifdef OC_TCP
static int
oc_endpoint_compare_session_ids(const oc_endpoint_t *ep1,
const oc_endpoint_t *ep2)
{
if (ep1->session_id == 0 || ep2->session_id == 0) {
return 0; // session_id == 0 means any
}
return ep1->session_id == ep2->session_id ? 0 : -1;
}
#endif /* OC_TCP */

int
oc_endpoint_compare(const oc_endpoint_t *ep1, const oc_endpoint_t *ep2)
{
Expand All @@ -690,19 +702,28 @@ oc_endpoint_compare(const oc_endpoint_t *ep1, const oc_endpoint_t *ep2)
if (ep1->flags & IPV6) {
if (memcmp(ep1->addr.ipv6.address, ep2->addr.ipv6.address, 16) == 0 &&
ep1->addr.ipv6.port == ep2->addr.ipv6.port) {
#ifdef OC_TCP
return oc_endpoint_compare_session_ids(ep1, ep2);
#else /* OC_TCP */
return 0;
#endif /* !OC_TCP */
}
return -1;
}
#ifdef OC_IPV4
else if (ep1->flags & IPV4) {
if (ep1->flags & IPV4) {
if (memcmp(ep1->addr.ipv4.address, ep2->addr.ipv4.address, 4) == 0 &&
ep1->addr.ipv4.port == ep2->addr.ipv4.port) {
#ifdef OC_TCP
return oc_endpoint_compare_session_ids(ep1, ep2);
#else /* OC_TCP */
return 0;
#endif /* !OC_TCP */
}
return -1;
}
#endif /* OC_IPV4 */

// TODO: Add support for other endpoint types
return -1;
}
Expand Down
8 changes: 7 additions & 1 deletion api/oc_session_events.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,9 @@ oc_session_start_event(const oc_endpoint_t *endpoint)
return;
}

// only a specific session should be connected
assert(endpoint->session_id != 0);

oc_endpoint_t *ep = oc_new_endpoint();
memcpy(ep, endpoint, sizeof(oc_endpoint_t));
ep->next = NULL;
Expand All @@ -152,6 +155,9 @@ oc_session_end_event(const oc_endpoint_t *endpoint)
return;
}

// only a specific session should be disconnected
assert(endpoint->session_id != 0);

oc_endpoint_t *ep = oc_new_endpoint();
memcpy(ep, endpoint, sizeof(oc_endpoint_t));
ep->next = NULL;
Expand Down Expand Up @@ -332,7 +338,7 @@ handle_session_disconnected(const oc_endpoint_t *endpoint)
(void)endpoint;
#ifdef OC_SECURITY
if ((endpoint->flags & SECURED) != 0 && (endpoint->flags & TCP) != 0) {
oc_tls_remove_peer(endpoint);
oc_tls_remove_peer(endpoint, false);
}
#endif /* OC_SECURITY */
#ifdef OC_SERVER
Expand Down
63 changes: 36 additions & 27 deletions api/oc_session_events_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,22 @@
#include "oc_endpoint.h"
#include "oc_session_events.h"
#include "util/oc_process.h"
#include "util/oc_features.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
* @brief Invoke all session handlers associated with given endpoint
*
* @param endpoint endpoint of the session event (cannot be NULLL)
* @param state new session state
*/
void oc_handle_session(const oc_endpoint_t *endpoint, oc_session_state_t state);

#ifdef OC_SESSION_EVENTS

#define OC_SESSION_EVENT_API_V0 (0)
#define OC_SESSION_EVENT_API_V1 (1)

Expand Down Expand Up @@ -61,6 +72,30 @@ typedef struct oc_session_event_cb
void *user_data;
} oc_session_event_cb_t;

/**
* @brief Find first session event callback matching the input parameters.
*
* @param cb handler to match
* @param user_data match user data (only valid for v1 handlers)
* @param ignore_user_data ignore user data for match (only valid for v1
* handlers)
* @return oc_session_event_cb_t* first matched session event callback
* @return NULL if no match is found
*/
oc_session_event_cb_t *oc_session_event_callback_find(
session_event_versioned_handler_t cb, const void *user_data,
bool ignore_user_data);

/**
* @brief Remove all previously registered session event notifications
* callbacks.
*/
void oc_session_events_remove_all_callbacks(void);

#endif /* OC_SESSION_EVENTS */

#ifdef OC_TCP

OC_PROCESS_NAME(oc_session_events);

/**
Expand All @@ -77,14 +112,6 @@ void oc_session_start_event(const oc_endpoint_t *endpoint);
*/
void oc_session_end_event(const oc_endpoint_t *endpoint);

/**
* @brief Invoke all session handlers associated with given endpoint
*
* @param endpoint endpoint of the session event (cannot be NULLL)
* @param state new session state
*/
void oc_handle_session(const oc_endpoint_t *endpoint, oc_session_state_t state);

/**
* @brief Check if session events are currently in the process of being
* disconnected.
Expand All @@ -95,25 +122,7 @@ void oc_handle_session(const oc_endpoint_t *endpoint, oc_session_state_t state);
*/
bool oc_session_events_disconnect_is_ongoing(void);

/**
* @brief Find first session event callback matching the input parameters.
*
* @param cb handler to match
* @param user_data match user data (only valid for v1 handlers)
* @param ignore_user_data ignore user data for match (only valid for v1
* handlers)
* @return oc_session_event_cb_t* first matched session event callback
* @return NULL if no match is found
*/
oc_session_event_cb_t *oc_session_event_callback_find(
session_event_versioned_handler_t cb, const void *user_data,
bool ignore_user_data);

/**
* @brief Remove all previously registered session event notifications
* callbacks.
*/
void oc_session_events_remove_all_callbacks(void);
#endif /* OC_TCP */

#ifdef __cplusplus
}
Expand Down
10 changes: 10 additions & 0 deletions api/oc_tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "oc_endpoint.h"
#include "port/oc_connectivity.h"
#include "oc_tcp_internal.h"
#include "util/oc_atomic.h"
#ifdef OC_SECURITY
#include <mbedtls/ssl.h>
#ifdef OC_OSCORE
Expand Down Expand Up @@ -86,6 +87,15 @@ oc_tcp_on_connect_event_free(oc_tcp_on_connect_event_t *event)

#endif /* OC_HAS_FEATURE_TCP_ASYNC_CONNECT */

static OC_ATOMIC_UINT32_T g_tcp_session_id = 0;

uint32_t
oc_tcp_get_new_session_id(void)
{
uint32_t v = OC_ATOMIC_INCREMENT32(g_tcp_session_id);
return (v == 0) ? OC_ATOMIC_INCREMENT32(g_tcp_session_id) : v;
}

bool
oc_tcp_is_valid_header(const uint8_t *data, size_t data_size, bool is_tls)
{
Expand Down
4 changes: 4 additions & 0 deletions api/oc_tcp_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "messaging/coap/constants.h"
#include "port/oc_connectivity.h"
#include "oc_endpoint.h"
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
Expand All @@ -34,6 +35,9 @@ extern "C" {
#define OC_TCP_DEFAULT_RECEIVE_SIZE \
(COAP_TCP_DEFAULT_HEADER_LEN + COAP_TCP_MAX_EXTENDED_LENGTH_LEN)

/** @brief Get new tcp session ID */
uint32_t oc_tcp_get_new_session_id(void);

#ifdef OC_HAS_FEATURE_TCP_ASYNC_CONNECT

typedef struct oc_tcp_on_connect_event_s
Expand Down
2 changes: 1 addition & 1 deletion api/plgd/plgd_time.c
Original file line number Diff line number Diff line change
Expand Up @@ -922,7 +922,7 @@ plgd_time_fetch(plgd_time_fetch_config_t fetch, unsigned *flags)
OC_ERR("failed to send fetch plgd-time request to endpoint");
#if defined(OC_SECURITY) && defined(OC_PKI)
if (add_insecure_peer) {
oc_tls_remove_peer(fetch.endpoint);
oc_tls_remove_peer(fetch.endpoint, true);
Danielius1922 marked this conversation as resolved.
Show resolved Hide resolved
}
#endif /* OC_SECURITY && OC_PKI */
oc_memb_free(&g_fetch_params_s, fetch_params);
Expand Down
2 changes: 1 addition & 1 deletion apps/client_multithread_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ pong_received_handler(oc_client_response_t *data)
ping_count++;
if (ping_count > PING_RETRY_COUNT) {
OC_PRINTF("retry over. close connection.\n");
oc_connectivity_end_session(data->endpoint);
oc_close_session(data->endpoint);
} else {
ping_timeout <<= 1;
OC_PRINTF("PING send again.[retry: %zd, time: %u]\n", ping_count,
Expand Down
6 changes: 5 additions & 1 deletion include/oc_endpoint.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,18 @@ typedef struct oc_endpoint_t
oc_ipv4_addr_t ipv4; ///< ipv4 address
oc_le_addr_t bt; ///< blue tooth address
} addr, addr_local;
unsigned interface_index; ///< interface index (valid intefaces are >0, 0
unsigned interface_index; ///< interface index (valid interfaces are >0, 0
///< means no index or error)
uint8_t priority; ///< priority
ocf_version_t version; ///< ocf version
#ifdef OC_OSCORE
uint8_t piv[OSCORE_PIV_LEN];
uint8_t piv_len;
#endif /* OC_OSCORE */
#ifdef OC_TCP
uint32_t session_id; ///< session id for pairing tls peer with tcp session - 0
///< means any
#endif
} oc_endpoint_t;

#define oc_make_ipv4_endpoint(__name__, __flags__, __port__, ...) \
Expand Down
2 changes: 1 addition & 1 deletion messaging/coap/engine.c
Original file line number Diff line number Diff line change
Expand Up @@ -1100,7 +1100,7 @@ coap_process_invalid_inbound_message(const coap_packet_t *packet,
#endif /* OC_SECURITY */
#ifdef OC_TCP
if ((msg->endpoint.flags & TCP) != 0) {
oc_connectivity_end_session(&msg->endpoint);
oc_close_session(&msg->endpoint);
return;
}
#endif /* OC_TCP */
Expand Down
3 changes: 2 additions & 1 deletion messaging/coap/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "log_internal.h"
#include "signal_internal.h"
#include "coap_internal.h"
#include "oc_api.h"
#include "transactions_internal.h"
#include <string.h>

Expand Down Expand Up @@ -223,7 +224,7 @@ coap_signal_handle_message(const coap_packet_t *packet,
if (packet->code == RELEASE_7_04) {
// alternative address
// hold off
oc_connectivity_end_session(endpoint);
oc_close_session(endpoint);
return COAP_SIGNAL_DONE;
}

Expand Down
14 changes: 13 additions & 1 deletion port/android/ipadapter.c
Original file line number Diff line number Diff line change
Expand Up @@ -1629,13 +1629,25 @@ oc_connectivity_shutdown(size_t device)
#ifdef OC_TCP
void
oc_connectivity_end_session(const oc_endpoint_t *endpoint)
{
while (oc_connectivity_end_session_v1(endpoint, true, NULL)) {
// no-op
}
}
Danielius1922 marked this conversation as resolved.
Show resolved Hide resolved

bool
oc_connectivity_end_session_v1(const oc_endpoint_t *endpoint,
bool notify_session_end,
oc_endpoint_t *session_endpoint)
{
if (endpoint->flags & TCP) {
ip_context_t *dev = get_ip_context_for_device(endpoint->device);
if (dev) {
oc_tcp_end_session(dev, endpoint);
return oc_tcp_end_session(dev, endpoint, notify_session_end,
session_endpoint);
}
}
return false;
}
#endif /* OC_TCP */

Expand Down
Loading
Loading