Skip to content

Commit

Permalink
PlgdTime: Fetch time from endpoint (iotivity#408)
Browse files Browse the repository at this point in the history
* plgd/time: fetch time from endpoint

Add plgd_time_fetch to plgd_time feature to retrieve time from
an endpoint.

For TLS/DTLS if a session to the endpoint is not yet
established then the feature tries to create a new session.
However, since the device might have a desynchronized time
the certificate verification functions are overriden to
ignore time validity. This might be a security risk, so once
a response is received this connection is scheduled to be
closed.
The client might be required to wait for the session to
disconnect before reconnecting to the endpoint. This can be
achieved using the sessions_events API.
  • Loading branch information
Danielius1922 authored Apr 19, 2023
1 parent 0772309 commit 42676ae
Show file tree
Hide file tree
Showing 28 changed files with 903 additions and 234 deletions.
24 changes: 12 additions & 12 deletions .github/workflows/cmake-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
fail-fast: false
matrix:
include:
# default (secure on, pki on, dynamic allocation on, tcp off, oscore on, cloud off, maintenance resource off, software update off, well-known core resource off)
# default (secure on, pki on, dynamic allocation on, tcp off, oscore on, cloud off, maintenance resource on, software update on, well-known core resource on, push notifications on, plgd-time on)
- args: ""
# ipv4 on
- args: "-DOC_IPV4_ENABLED=ON"
Expand All @@ -49,24 +49,24 @@ jobs:
# ipv4 on, tcp on, pki off
- args: "-DOC_IPV4_ENABLED=ON -DOC_TCP_ENABLED=ON -DOC_PKI_ENABLED=OFF"
# cloud on (ipv4+tcp on), collections create on, maintenance resource on
- args: "-DOC_CLOUD_ENABLED=ON -DOC_COLLECTIONS_IF_CREATE_ENABLED=ON -DOC_MNT_ENABLED=ON"
# debug on, cloud on (ipv4+tcp on), software update on
- args: "-DOC_DEBUG_ENABLED=ON -DOC_CLOUD_ENABLED=ON -DOC_SOFTWARE_UPDATE_ENABLED=ON"
- args: "-DOC_CLOUD_ENABLED=ON -DOC_COLLECTIONS_IF_CREATE_ENABLED=ON "
# debug on, well-known core resource on
- args: "-DOC_DEBUG_ENABLED=ON -DOC_WKCORE_ENABLED=ON"
- args: "-DOC_DEBUG_ENABLED=ON"
# debug on, cloud on (ipv4+tcp on)
- args: "-DOC_CLOUD_ENABLED=ON -DOC_DEBUG_ENABLED=ON "
# secure off, ipv4 on
- args: "-DOC_SECURITY_ENABLED=OFF -DOC_IPV4_ENABLED=ON"
# secure off, tcp on
- args: "-DOC_SECURITY_ENABLED=OFF -DOC_TCP_ENABLED=ON"
# secure off, ipv4 on, tcp on
- args: "-DOC_SECURITY_ENABLED=OFF -DOC_TCP_ENABLED=ON -DOC_IPV4_ENABLED=ON"
# collection create if on, push notification on
- args: "-DOC_COLLECTIONS_IF_CREATE_ENABLED=ON -DOC_PUSH_ENABLED=ON"
# everything off (dynamic allocation off, secure off, pki off, idd off, oscore off)
- args: "-DOC_DYNAMIC_ALLOCATION_ENABLED=OFF -DOC_SECURITY_ENABLED=OFF -DOC_PKI_ENABLED=OFF -DOC_IDD_API_ENABLED=OFF -DOC_OSCORE_ENABLED=OFF"
- args: "-DOC_COLLECTIONS_IF_CREATE_ENABLED=ON"
# everything off (dynamic allocation off, secure off, pki off, idd off, oscore off, well-known core resource off, software update off, push notifications off, plgd-time off)
- args: "-DOC_DYNAMIC_ALLOCATION_ENABLED=OFF -DOC_SECURITY_ENABLED=OFF -DOC_PKI_ENABLED=OFF -DOC_IDD_API_ENABLED=OFF -DOC_OSCORE_ENABLED=OFF -DOC_WKCORE_ENABLED=OFF -DOC_SOFTWARE_UPDATE_ENABLED=OFF -DOC_MNT_ENABLED=OFF -DOC_PUSH_ENABLED=OFF -DPLGD_DEV_TIME_ENABLED=OFF"
uses: ./.github/workflows/unit-test-with-cfg.yml
with:
build_args: ${{ matrix.args }}
build_args: -DOC_WKCORE_ENABLED=ON -DOC_SOFTWARE_UPDATE_ENABLED=ON -DOC_MNT_ENABLED=ON -DOC_PUSH_ENABLED=ON -DPLGD_DEV_TIME_ENABLED=ON ${{ matrix.args }}
build_type: Debug
clang: ${{ github.event_name == 'workflow_dispatch' && inputs.clang }}
coverage: false
Expand All @@ -76,8 +76,8 @@ jobs:
cmake_linux_preinstalled:
uses: ./.github/workflows/unit-test-with-cfg.yml
with:
# cloud on (ipv4+tcp on), collections create on, maintenance resource on, well-known core resource on, software update on, push notification on
build_args: -DOC_CLOUD_ENABLED=ON -DOC_COLLECTIONS_IF_CREATE_ENABLED=ON -DOC_MNT_ENABLED=ON -DOC_WKCORE_ENABLED=ON -DOC_SOFTWARE_UPDATE_ENABLED=ON -DOC_PUSH_ENABLED=ON
# cloud on (ipv4+tcp on), collections create on, maintenance resource on, well-known core resource on, software update on, push notification on, plgd-time on
build_args: -DOC_CLOUD_ENABLED=ON -DOC_COLLECTIONS_IF_CREATE_ENABLED=ON -DOC_MNT_ENABLED=ON -DOC_WKCORE_ENABLED=ON -DOC_SOFTWARE_UPDATE_ENABLED=ON -DOC_PUSH_ENABLED=ON -DPLGD_DEV_TIME_ENABLED=ON
build_type: Debug
clang: ${{ github.event_name == 'workflow_dispatch' && inputs.clang }}
coverage: false
Expand All @@ -101,7 +101,7 @@ jobs:
# - args: -DOC_MSAN_ENABLED=ON
uses: ./.github/workflows/unit-test-with-cfg.yml
with:
build_args: -DOC_CLOUD_ENABLED=ON -DOC_COLLECTIONS_IF_CREATE_ENABLED=ON -DOC_MNT_ENABLED=ON -DOC_WKCORE_ENABLED=ON -DOC_SOFTWARE_UPDATE_ENABLED=ON -DOC_PUSH_ENABLED=ON -DOC_RESOURCE_ACCESS_IN_RFOTM_ENABLED=ON ${{ matrix.args }}
build_args: -DOC_CLOUD_ENABLED=ON -DOC_COLLECTIONS_IF_CREATE_ENABLED=ON -DOC_MNT_ENABLED=ON -DOC_WKCORE_ENABLED=ON -DOC_SOFTWARE_UPDATE_ENABLED=ON -DOC_PUSH_ENABLED=ON -DOC_RESOURCE_ACCESS_IN_RFOTM_ENABLED=ON -DPLGD_DEV_TIME_ENABLED=ON ${{ matrix.args }}
build_type: Debug
clang: ${{ github.event_name == 'workflow_dispatch' && inputs.clang }}
coverage: false
Expand Down
10 changes: 4 additions & 6 deletions api/cloud/unittest/cloud_access_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,13 @@

#ifndef OC_SECURITY

#include <gtest/gtest.h>

#include "oc_api.h"
#include "oc_cloud_access.h"
#include "oc_cloud_internal.h"
#include "oc_endpoint.h"
#include "tests/gtest/Endpoint.h"

#include <gtest/gtest.h>

class TestCloudAccess : public testing::Test {
public:
Expand Down Expand Up @@ -57,10 +58,7 @@ class TestCloudAccess : public testing::Test {
int ret = oc_main_init(&s_handler);
ASSERT_EQ(0, ret);

oc_string_t ep_str;
oc_new_string(&ep_str, "coap://224.0.1.187:5683", 23);
oc_string_to_endpoint(&ep_str, &s_endpoint, nullptr);
oc_free_string(&ep_str);
s_endpoint = oc::endpoint::FromString("coap://224.0.1.187:5683");
}

static void TearDownTestCase() { oc_main_shutdown(); }
Expand Down
10 changes: 4 additions & 6 deletions api/cloud/unittest/rd_client_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@
*
******************************************************************/

#include <gtest/gtest.h>

#include "oc_api.h"
#include "oc_endpoint.h"
#include "rd_client.h"
#include "tests/gtest/Endpoint.h"

#include <gtest/gtest.h>

class TestRDClient : public testing::Test {
public:
Expand Down Expand Up @@ -54,10 +55,7 @@ class TestRDClient : public testing::Test {
int ret = oc_main_init(&s_handler);
ASSERT_EQ(0, ret);

oc_string_t ep_str;
oc_new_string(&ep_str, "coap://224.0.1.187:5683", 23);
oc_string_to_endpoint(&ep_str, &s_endpoint, nullptr);
oc_free_string(&ep_str);
s_endpoint = oc::endpoint::FromString("coap://224.0.1.187:5683");
}

static void TearDownTestCase() { oc_main_shutdown(); }
Expand Down
41 changes: 18 additions & 23 deletions api/oc_endpoint.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,16 @@
****************************************************************************/

#include "oc_endpoint.h"
#include "oc_endpoint_internal.h"
#include "oc_core_res.h"
#include "port/oc_connectivity.h"
#include "port/oc_network_event_handler_internal.h"
#include "util/oc_macros.h"
#include "util/oc_memb.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define OC_SCHEME_COAP "coap://"
#define OC_SCHEME_COAP_LEN (sizeof(OC_SCHEME_COAP) - 1)
#define OC_SCHEME_COAPS "coaps://"
#define OC_SCHEME_COAPS_LEN (sizeof(OC_SCHEME_COAPS) - 1)
#define OC_SCHEME_COAP_TCP "coap+tcp://"
#define OC_SCHEME_COAP_TCP_LEN (sizeof(OC_SCHEME_COAP_TCP) - 1)
#define OC_SCHEME_COAPS_TCP "coaps+tcp://"
#define OC_SCHEME_COAPS_TCP_LEN (sizeof(OC_SCHEME_COAPS_TCP) - 1)

#define OC_IPV6_ADDRSTRLEN (46)
#define OC_IPV4_ADDRSTRLEN (16)
#define OC_IPV6_ADDRLEN (16)
Expand Down Expand Up @@ -68,8 +61,8 @@ oc_endpoint_set_di(oc_endpoint_t *endpoint, const oc_uuid_t *di)
memcpy(endpoint->di.id, di->id, sizeof(di->id));
}

static const char *
oc_endpoint_flags_to_scheme(transport_flags flags)
const char *
oc_endpoint_flags_to_scheme(unsigned flags)
{
#ifdef OC_TCP
if ((flags & TCP) != 0) {
Expand Down Expand Up @@ -374,21 +367,23 @@ parse_endpoint_flags(const oc_string_t *endpoint_str)
const char *ep = oc_string(*endpoint_str);
size_t ep_len = oc_string_len(*endpoint_str);
#ifdef OC_TCP
if (ep_len > OC_SCHEME_COAPS_TCP_LEN &&
memcmp(OC_SCHEME_COAPS_TCP, ep, OC_SCHEME_COAPS_TCP_LEN) == 0) {
if (ep_len > OC_CHAR_ARRAY_LEN(OC_SCHEME_COAPS_TCP) &&
memcmp(OC_SCHEME_COAPS_TCP, ep, OC_CHAR_ARRAY_LEN(OC_SCHEME_COAPS_TCP)) ==
0) {
return TCP | SECURED;
}
if (ep_len > OC_SCHEME_COAP_TCP_LEN &&
memcmp(OC_SCHEME_COAP_TCP, ep, OC_SCHEME_COAP_TCP_LEN) == 0) {
if (ep_len > OC_CHAR_ARRAY_LEN(OC_SCHEME_COAP_TCP) &&
memcmp(OC_SCHEME_COAP_TCP, ep, OC_CHAR_ARRAY_LEN(OC_SCHEME_COAP_TCP)) ==
0) {
return TCP;
}
#endif /* OC_TCP */
if (ep_len > OC_SCHEME_COAPS_LEN &&
memcmp(OC_SCHEME_COAPS, ep, OC_SCHEME_COAPS_LEN) == 0) {
if (ep_len > OC_CHAR_ARRAY_LEN(OC_SCHEME_COAPS) &&
memcmp(OC_SCHEME_COAPS, ep, OC_CHAR_ARRAY_LEN(OC_SCHEME_COAPS)) == 0) {
return SECURED;
}
if (ep_len > OC_SCHEME_COAP_LEN &&
memcmp(OC_SCHEME_COAP, ep, OC_SCHEME_COAP_LEN) == 0) {
if (ep_len > OC_CHAR_ARRAY_LEN(OC_SCHEME_COAP) &&
memcmp(OC_SCHEME_COAP, ep, OC_CHAR_ARRAY_LEN(OC_SCHEME_COAP)) == 0) {
return 0;
}
return -1;
Expand All @@ -410,17 +405,17 @@ parse_endpoint_uri(const oc_string_t *endpoint_str,
switch (flags) {
#ifdef OC_TCP
case TCP | SECURED:
address = ep + OC_SCHEME_COAPS_TCP_LEN;
address = ep + OC_CHAR_ARRAY_LEN(OC_SCHEME_COAPS_TCP);
break;
case TCP:
address = ep + OC_SCHEME_COAP_TCP_LEN;
address = ep + OC_CHAR_ARRAY_LEN(OC_SCHEME_COAP_TCP);
break;
#endif /* OC_TCP */
case SECURED:
address = ep + OC_SCHEME_COAPS_LEN;
address = ep + OC_CHAR_ARRAY_LEN(OC_SCHEME_COAPS);
break;
case 0:
address = ep + OC_SCHEME_COAP_LEN;
address = ep + OC_CHAR_ARRAY_LEN(OC_SCHEME_COAP);
break;
default:
OC_ERR("invalid endpoint(%s) uri scheme: %d", ep != NULL ? ep : "", flags);
Expand Down
38 changes: 38 additions & 0 deletions api/oc_endpoint_internal.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/****************************************************************************
*
* Copyright (c) 2022 Daniel Adam, All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"),
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the License.
*
****************************************************************************/

#ifndef OC_ENDPOINT_INTERNAL_H
#define OC_ENDPOINT_INTERNAL_H

#ifdef __cplusplus
extern "C" {
#endif

#define OC_SCHEME_COAP "coap://"
#define OC_SCHEME_COAPS "coaps://"
#define OC_SCHEME_COAP_TCP "coap+tcp://"
#define OC_SCHEME_COAPS_TCP "coaps+tcp://"

/** @brief Get scheme string for transport flags */
const char *oc_endpoint_flags_to_scheme(unsigned flags);

#ifdef __cplusplus
}
#endif

#endif /* OC_ENDPOINT_INTERNAL_H */
55 changes: 43 additions & 12 deletions api/oc_ri.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
#include "api/oc_session_events_internal.h"
#endif /* OC_TCP */

#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
#include <string.h>
Expand Down Expand Up @@ -680,6 +681,17 @@ oc_ri_has_timed_event_callback(const void *cb_data, oc_trigger_t event_callback,
return false;
}

bool
oc_timed_event_callback_is_currently_processed(const void *cb_data,
oc_trigger_t event_callback)
{
if (g_currently_processed_event_cb == NULL) {
return false;
}
return g_currently_processed_event_cb->callback == event_callback &&
g_currently_processed_event_cb->data == cb_data;
}

void
oc_ri_remove_timed_event_callback_by_filter(
oc_trigger_t cb, oc_ri_timed_event_filter_t filter, const void *filter_data,
Expand Down Expand Up @@ -1611,7 +1623,15 @@ free_client_cb(oc_client_cb_t *cb)
if (!cb) {
return;
}
oc_list_remove(g_client_cbs, cb);
// assert that we don't leave a dangling pointer
assert(!oc_ri_is_client_cb_valid(cb));
assert(oc_timed_event_callback_is_currently_processed(
cb, oc_ri_remove_client_cb) ||
!oc_ri_has_timed_event_callback(cb, oc_ri_remove_client_cb, false));
assert(oc_timed_event_callback_is_currently_processed(
cb, oc_ri_remove_client_cb_with_notify_timeout_async) ||
!oc_ri_has_timed_event_callback(
cb, oc_ri_remove_client_cb_with_notify_timeout_async, false));
#ifdef OC_BLOCK_WISE
oc_blockwise_scrub_buffers_for_client_cb(cb);
#endif /* OC_BLOCK_WISE */
Expand All @@ -1620,24 +1640,39 @@ free_client_cb(oc_client_cb_t *cb)
oc_memb_free(&g_client_cbs_s, cb);
}

static void
ri_remove_client_cb_from_lists(oc_client_cb_t *cb)
{
oc_ri_remove_timed_event_callback(cb, &oc_ri_remove_client_cb);
oc_ri_remove_timed_event_callback(
cb, &oc_ri_remove_client_cb_with_notify_timeout_async);
oc_list_remove(g_client_cbs, cb);
}

oc_event_callback_retval_t
oc_ri_remove_client_cb(void *data)
{
oc_ri_remove_timed_event_callback(
data, &oc_ri_remove_client_cb_with_notify_timeout_async);
oc_client_cb_t *cb = (oc_client_cb_t *)data;
ri_remove_client_cb_from_lists(cb);
free_client_cb(data);
return OC_EVENT_DONE;
}

bool
oc_ri_client_cb_terminated(oc_status_t code)
{
return code == OC_PING_TIMEOUT || code == OC_REQUEST_TIMEOUT ||
code == OC_CONNECTION_CLOSED || code == OC_TRANSACTION_TIMEOUT ||
code == OC_CANCELLED;
}

static void
notify_client_cb_with_code(oc_client_cb_t *cb, oc_status_t code)
{
OC_DBG("notify_client_cb_with_code - calling handler with request timeout "
"for %d %s",
cb->method, oc_string(cb->uri));
oc_ri_remove_timed_event_callback(cb, &oc_ri_remove_client_cb);
oc_ri_remove_timed_event_callback(
cb, &oc_ri_remove_client_cb_with_notify_timeout_async);
ri_remove_client_cb_from_lists(cb);

oc_client_response_t client_response;
memset(&client_response, 0, sizeof(oc_client_response_t));
Expand Down Expand Up @@ -1826,9 +1861,7 @@ oc_ri_client_cb_set_observe_seq(oc_client_cb_t *cb, int observe_seq,
oc_endpoint_compare(&dup_cb->endpoint, endpoint) == 0) {
OC_DBG("Freeing cb %s, token 0x%02X%02X", uri, dup_cb->token[0],
dup_cb->token[1]);
oc_ri_remove_timed_event_callback(dup_cb, &oc_ri_remove_client_cb);
oc_ri_remove_timed_event_callback(
dup_cb, &oc_ri_remove_client_cb_with_notify_timeout_async);
ri_remove_client_cb_from_lists(dup_cb);
free_client_cb(dup_cb);
break;
}
Expand Down Expand Up @@ -1957,9 +1990,7 @@ oc_ri_invoke_client_cb(void *response, oc_client_cb_t *cb,
oc_ri_free_client_cbs_by_mid_v1(mid, OC_CANCELLED);
}
} else {
oc_ri_remove_timed_event_callback(cb, &oc_ri_remove_client_cb);
oc_ri_remove_timed_event_callback(
cb, &oc_ri_remove_client_cb_with_notify_timeout_async);
ri_remove_client_cb_from_lists(cb);
free_client_cb(cb);
}
#ifdef OC_BLOCK_WISE
Expand Down
13 changes: 13 additions & 0 deletions api/oc_ri_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
#include "oc_endpoint.h"
#include "oc_ri.h"

#include <stdbool.h>
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif
Expand Down Expand Up @@ -54,6 +57,11 @@ extern "C" {
#define OC_BASELINE_PROP_TAG_POS_DESC "tag-pos-desc"
#define OC_BASELINE_PROP_FUNC_DESC "tag-func-desc"

/** Check if the code is one of the internal terminating code while
* automatically deallocate the client_cb via the notify_client_cb_with_code
* mechanism */
bool oc_ri_client_cb_terminated(oc_status_t code);

/**
* @brief removes the client callback. This is silent remove client without
* trigger 'cb.handler'.
Expand All @@ -73,6 +81,11 @@ oc_event_callback_retval_t oc_ri_remove_client_cb(void *cb);
oc_event_callback_retval_t oc_ri_remove_client_cb_with_notify_timeout_async(
void *cb);

/** @brief The callback and data pair is currently being processed by
* poll_event_callback_timers */
bool oc_timed_event_callback_is_currently_processed(
const void *cb_data, oc_trigger_t event_callback);

#ifdef OC_BLOCK_WISE
extern bool oc_ri_invoke_coap_entity_handler(
void *request, void *response, oc_blockwise_state_t **request_state,
Expand Down
Loading

0 comments on commit 42676ae

Please sign in to comment.