Skip to content

Commit

Permalink
Implement Message Queue Limit to Prevent Memory Exhaustion in Embedde…
Browse files Browse the repository at this point in the history
…d Devices

The current network thread can produce unlimited messages to the queue
which is consumed by the event thread. In embedded devices, we have limited
memory, so a DDOS attack could exhaust the memory.

Fixes Issue: #626

To fix this issue, (when OC_DYNAMIC_ALLOCATION is enabled) we use the macro
OC_MAX_NUM_CONCURRENT_REQUESTS , which defines the maximum number
of messages in the queue per device.
The default value of OC_MAX_NUM_CONCURRENT_REQUESTS is 32.

If the number of messages reaches the limit, all file descriptors in the network
thread that produce oc_message_t are removed from select/poll. The file
descriptor for monitoring the control flow is always set and is used to wake up
from select() when the queue is ready to accept events again.
When more file descriptors are ready to be read than the number of available
queue slots, a subset is randomly selected to be pushed to the queue.

---------

Co-authored-by: sp-milos <[email protected]>
Co-authored-by: Daniel Adam <[email protected]>
  • Loading branch information
3 people authored Jun 20, 2024
1 parent 09b9743 commit 4a9fad5
Show file tree
Hide file tree
Showing 30 changed files with 1,337 additions and 363 deletions.
7 changes: 7 additions & 0 deletions .github/workflows/cmake-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ jobs:
cc: "gcc"
cxx: "g++"
build_testing: "ON"
- name: "MinGW-gcc debug-discovery-resource-observable-rep-realloc-concurrent-requests-1"
build_type: "Debug"
cc: "gcc"
cxx: "g++"
build_testing: "ON"
build_args: "-DOC_DISCOVERY_RESOURCE_OBSERVABLE_ENABLED=ON -DOC_REPRESENTATION_REALLOC_ENCODING_ENABLED=ON -DOC_DEVICE_MAX_NUM_CONCURRENT_REQUESTS=1"

steps:
- name: Checkout repository
Expand Down Expand Up @@ -93,6 +99,7 @@ jobs:
-D PLGD_DEV_TIME_ENABLED=ON
-D OC_ETAG_ENABLED=ON
-D OC_DEBUG_ENABLED=ON
${{ matrix.build_args }}
COMMAND_ERROR_IS_FATAL ANY
)
Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/plgd-device-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,14 @@ jobs:
args: "-DOC_TSAN_ENABLED=ON -DOC_RESOURCE_ACCESS_IN_RFOTM_ENABLED=ON"
docker_file: docker/apps/Dockerfile.cloud-server-debug-clang

- name: cloud-server-access-in-RFOTM-concurrent-requests-1
# same configuration as " cloud-server-access-in-RFOTM-concurrent-requests-1" in the SonarCloud scan job, skip for events that trigger both jobs
skip: ${{ github.event_name != 'workflow_dispatch' }}
args: "-DOC_RESOURCE_ACCESS_IN_RFOTM_ENABLED=ON -DOC_DEVICE_MAX_NUM_CONCURRENT_REQUESTS=1"
- name: cloud-server-access-in-RFOTM-concurrent-requests-1-tsan
args: "-DOC_TSAN_ENABLED=ON -DOC_RESOURCE_ACCESS_IN_RFOTM_ENABLED=ON -DOC_DEVICE_MAX_NUM_CONCURRENT_REQUESTS=1"
docker_file: docker/apps/Dockerfile.cloud-server-debug-clang

- name: cloud-server-discovery-resource-observable
args: "-DOC_DISCOVERY_RESOURCE_OBSERVABLE_ENABLED=ON"
- name: cloud-server-discovery-resource-observable-asan
Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/plgd-hub-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,14 @@ jobs:
build_args: "-DOC_DISCOVERY_RESOURCE_OBSERVABLE_ENABLED=ON -DOC_RESOURCE_ACCESS_IN_RFOTM_ENABLED=ON -DOC_REPRESENTATION_REALLOC_ENCODING_ENABLED=ON -DOC_TSAN_ENABLED=ON"
docker_file: docker/apps/Dockerfile.cloud-server-debug-clang

- name: cloud-server-discovery-resource-observable-access-in-RFOTM-rep-realloc-concurrent-requests-1
# same configuration as "cloud-server-discovery-resource-observable-access-in-RFOTM-rep-realloc-concurrent-requests-1" in the SonarCloud scan job, skip for events that trigger both jobs
skip: ${{ github.event_name != 'workflow_dispatch' }}
build_args: "-DOC_DISCOVERY_RESOURCE_OBSERVABLE_ENABLED=ON -DOC_RESOURCE_ACCESS_IN_RFOTM_ENABLED=ON -DOC_REPRESENTATION_REALLOC_ENCODING_ENABLED=ON -DOC_DEVICE_MAX_NUM_CONCURRENT_REQUESTS=1"
- name: cloud-server-discovery-resource-observable-access-in-RFOTM-rep-realloc-concurrent-requests-1-tsan
build_args: "-DOC_DISCOVERY_RESOURCE_OBSERVABLE_ENABLED=ON -DOC_RESOURCE_ACCESS_IN_RFOTM_ENABLED=ON -DOC_REPRESENTATION_REALLOC_ENCODING_ENABLED=ON -DOC_DEVICE_MAX_NUM_CONCURRENT_REQUESTS=1 -DOC_TSAN_ENABLED=ON"
docker_file: docker/apps/Dockerfile.cloud-server-debug-clang

# ports
- name: cloud-server-tcp-disabled
args: "--udp-port 61234 --udp-port4 61234 --dtls-port 61235 --dtls-port4 61235 --tcp-port -1 --tcp-port4 -1 --tls-port -1 --tls-port4 -1"
Expand Down
8 changes: 6 additions & 2 deletions .github/workflows/sonar-cloud-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ jobs:
include:
# cloud (ipv4+tcp) on, collection create on, push on, rfotm on
- build_args: "-DOC_CLOUD_ENABLED=ON -DOC_COLLECTIONS_IF_CREATE_ENABLED=ON -DOC_PUSH_ENABLED=ON -DOC_RESOURCE_ACCESS_IN_RFOTM_ENABLED=ON"
# security off, ipv4 on, collection create on, push on
- build_args: "-DOC_SECURITY_ENABLED=OFF -DOC_IPV4_ENABLED=ON -DOC_COLLECTIONS_IF_CREATE_ENABLED=ON -DOC_PUSH_ENABLED=ON"
# security off, ipv4 on, collection create on, push on, max num concurrent requests=1
- build_args: "-DOC_SECURITY_ENABLED=OFF -DOC_IPV4_ENABLED=ON -DOC_COLLECTIONS_IF_CREATE_ENABLED=ON -DOC_PUSH_ENABLED=ON -DOC_DEVICE_MAX_NUM_CONCURRENT_REQUESTS=1"
# ipv6 dns on, oscore off, rep realloc on, json encoder on, introspection IDD off
- build_args: "-DOC_DNS_LOOKUP_IPV6_ENABLED=ON -DOC_OSCORE_ENABLED=OFF -DOC_REPRESENTATION_REALLOC_ENCODING_ENABLED=ON -DOC_JSON_ENCODER_ENABLED=ON -DOC_IDD_API_ENABLED=OFF"
# cloud (ipv4+tcp) on, dynamic allocation off, rfotm on, push off (because it forces dynamic allocation)
Expand All @@ -51,6 +51,8 @@ jobs:
include:
- name: cloud-server
build_args: ""
- name: cloud-server-access-in-RFOTM-concurrent-requests-1
build_args: "-DOC_RESOURCE_ACCESS_IN_RFOTM_ENABLED=ON -DOC_DEVICE_MAX_NUM_CONCURRENT_REQUESTS=1"
- name: cloud-server-discovery-resource-observable-access-in-RFOTM-rep-realloc
build_args: "-DOC_DISCOVERY_RESOURCE_OBSERVABLE_ENABLED=ON -DOC_RESOURCE_ACCESS_IN_RFOTM_ENABLED=ON -DOC_REPRESENTATION_REALLOC_ENCODING_ENABLED=ON"
# try with SHA384
Expand All @@ -72,6 +74,8 @@ jobs:
include:
- name: cloud-server-discovery-resource-observable-access-in-RFOTM
build_args: "-DOC_DISCOVERY_RESOURCE_OBSERVABLE_ENABLED=ON -DOC_RESOURCE_ACCESS_IN_RFOTM_ENABLED=ON"
- name: cloud-server-discovery-resource-observable-access-in-RFOTM-rep-realloc-concurrent-requests-1
build_args: "-DOC_DISCOVERY_RESOURCE_OBSERVABLE_ENABLED=ON -DOC_RESOURCE_ACCESS_IN_RFOTM_ENABLED=ON -DOC_REPRESENTATION_REALLOC_ENCODING_ENABLED=ON -DOC_DEVICE_MAX_NUM_CONCURRENT_REQUESTS=1"
- name: dtls-cloud-server-rep-realloc
build_args: "-DOC_REPRESENTATION_REALLOC_ENCODING_ENABLED=ON"
hub_args: "-e COAP_GATEWAY_UDP_ENABLED=true"
Expand Down
101 changes: 59 additions & 42 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ if(BUILD_TESTING AND UNIX AND (OC_COMPILER_IS_GCC OR OC_COMPILER_IS_CLANG))
endif()

######## Build configuration options ########
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

set(BUILD_EXAMPLE_APPLICATIONS ON CACHE BOOL "Build example applications.")
set(BUILD_MBEDTLS ON CACHE BOOL "Build Mbed TLS library. When set to OFF, the Mbed TLS library with the OCF patches has to be provided.")
set(BUILD_MBEDTLS_FORCE_3_5_0 OFF CACHE BOOL "Force v3.5.0 of the MbedTLS library to be used (by default v3.1.0 is used by master)")
Expand Down Expand Up @@ -57,15 +59,6 @@ set(OC_PUSH_ENABLED OFF CACHE BOOL "Enable Push Notification.")
set(OC_PUSHDEBUG_ENABLED OFF CACHE BOOL "Enable debug messages for Push Notification.")
set(OC_RESOURCE_ACCESS_IN_RFOTM_ENABLED OFF CACHE BOOL "Enable resource access in RFOTM.")
set(OC_MEMORY_TRACE_ENABLED OFF CACHE BOOL "Enable memory tracing.")
if (OC_DEBUG_ENABLED)
set(OC_LOG_MAXIMUM_LOG_LEVEL "TRACE" CACHE STRING "Maximum supported log level in compile time.")
else()
set(OC_LOG_MAXIMUM_LOG_LEVEL "DISABLED" CACHE STRING "Maximum supported log level in compile time.")
endif()
set(OC_INOUT_BUFFER_SIZE "" CACHE STRING "Custom static buffer size for network messages.")
set(OC_INOUT_BUFFER_POOL "" CACHE STRING "Custom static pool size of network messages.")
set(OC_APP_DATA_BUFFER_SIZE "" CACHE STRING "Custom static buffer size for application messages.")
set(OC_APP_DATA_BUFFER_POOL "" CACHE STRING "Custom static size of application messages.")
set(OC_VERSION_1_1_0_ENABLED OFF CACHE BOOL "Enable OCF version 1.1")
set(OC_ETAG_ENABLED OFF CACHE BOOL "Enable Entity Tag (ETag) support.")
set(OC_JSON_ENCODER_ENABLED OFF CACHE BOOL "Enable JSON encoder/decoder support.")
Expand All @@ -75,7 +68,16 @@ if (BUILD_EXAMPLE_APPLICATIONS OR BUILD_TESTING)
endif()
set(PLGD_DEV_TIME_ENABLED OFF CACHE BOOL "Enable plgd time feature.")

set(CMAKE_POSITION_INDEPENDENT_CODE ON)
if (OC_DEBUG_ENABLED)
set(OC_LOG_MAXIMUM_LOG_LEVEL "TRACE" CACHE STRING "Maximum supported log level in compile time.")
else()
set(OC_LOG_MAXIMUM_LOG_LEVEL "DISABLED" CACHE STRING "Maximum supported log level in compile time.")
endif()
set(OC_INOUT_BUFFER_SIZE "" CACHE STRING "Custom static buffer size for network messages.")
set(OC_INOUT_BUFFER_POOL "" CACHE STRING "Custom static pool size of network messages.")
set(OC_APP_DATA_BUFFER_SIZE "" CACHE STRING "Custom static buffer size for application messages.")
set(OC_APP_DATA_BUFFER_POOL "" CACHE STRING "Custom static size of application messages.")
set(OC_DEVICE_MAX_NUM_CONCURRENT_REQUESTS "" CACHE STRING "Maximum number of messages in the network event queue for a device.")

set(OC_ASAN_ENABLED OFF CACHE BOOL "Enable address sanitizer build.")
set(OC_LSAN_ENABLED OFF CACHE BOOL "Enable leak sanitizer build.")
Expand Down Expand Up @@ -399,38 +401,6 @@ if(OC_MEMORY_TRACE_ENABLED)
list(APPEND TEST_COMPILE_DEFINITIONS "OC_MEMORY_TRACE")
endif()

if (NOT("${OC_INOUT_BUFFER_SIZE}" STREQUAL ""))
if(NOT OC_DYNAMIC_ALLOCATION_ENABLED)
message(FATAL_ERROR "Cannot set custom static buffer size for network messages without dynamic allocation")
endif()
list(APPEND PUBLIC_COMPILE_DEFINITIONS "OC_INOUT_BUFFER_SIZE=(${OC_INOUT_BUFFER_SIZE})")
list(APPEND MBEDTLS_COMPILE_DEFINITIONS "OC_INOUT_BUFFER_SIZE=(${OC_INOUT_BUFFER_SIZE})")
endif()

if (NOT("${OC_INOUT_BUFFER_POOL}" STREQUAL ""))
if(NOT OC_DYNAMIC_ALLOCATION_ENABLED)
message(FATAL_ERROR "Cannot set custom static pool size for network messages without dynamic allocation")
endif()
list(APPEND PUBLIC_COMPILE_DEFINITIONS "OC_INOUT_BUFFER_POOL=(${OC_INOUT_BUFFER_POOL})")
list(APPEND MBEDTLS_COMPILE_DEFINITIONS "OC_INOUT_BUFFER_POOL=(${OC_INOUT_BUFFER_POOL})")
endif()

if (NOT("${OC_APP_DATA_BUFFER_SIZE}" STREQUAL ""))
if(NOT OC_DYNAMIC_ALLOCATION_ENABLED)
message(FATAL_ERROR "Cannot set custom static buffer size for application messages without dynamic allocation")
endif()
list(APPEND PUBLIC_COMPILE_DEFINITIONS "OC_APP_DATA_BUFFER_SIZE=(${OC_APP_DATA_BUFFER_SIZE})")
list(APPEND MBEDTLS_COMPILE_DEFINITIONS "OC_APP_DATA_BUFFER_SIZE=(${OC_APP_DATA_BUFFER_SIZE})")
endif()

if (NOT("${OC_APP_DATA_BUFFER_POOL}" STREQUAL ""))
if(NOT OC_DYNAMIC_ALLOCATION_ENABLED)
message(FATAL_ERROR "Cannot set custom static pool size for application messages without dynamic allocation")
endif()
list(APPEND PUBLIC_COMPILE_DEFINITIONS "OC_APP_DATA_BUFFER_POOL=(${OC_APP_DATA_BUFFER_POOL})")
list(APPEND MBEDTLS_COMPILE_DEFINITIONS "OC_APP_DATA_BUFFER_POOL=(${OC_APP_DATA_BUFFER_POOL})")
endif()

if(OC_VERSION_1_1_0_ENABLED)
list(APPEND PUBLIC_COMPILE_DEFINITIONS "OC_SPEC_VER_OIC")
endif()
Expand All @@ -454,6 +424,53 @@ if(PLGD_DEV_TIME_ENABLED)
endif()
endif()

if(NOT("${OC_INOUT_BUFFER_SIZE}" STREQUAL ""))
if(NOT OC_DYNAMIC_ALLOCATION_ENABLED)
message(FATAL_ERROR "Cannot OC_INOUT_BUFFER_SIZE without dynamic allocation")
endif()
list(APPEND PUBLIC_COMPILE_DEFINITIONS "OC_INOUT_BUFFER_SIZE=(${OC_INOUT_BUFFER_SIZE})")
if(BUILD_MBEDTLS)
list(APPEND MBEDTLS_COMPILE_DEFINITIONS "OC_INOUT_BUFFER_SIZE=(${OC_INOUT_BUFFER_SIZE})")
endif()
endif()

if(NOT("${OC_INOUT_BUFFER_POOL}" STREQUAL ""))
if(NOT OC_DYNAMIC_ALLOCATION_ENABLED)
message(FATAL_ERROR "Cannot set OC_INOUT_BUFFER_POOL without dynamic allocation")
endif()
list(APPEND PUBLIC_COMPILE_DEFINITIONS "OC_INOUT_BUFFER_POOL=(${OC_INOUT_BUFFER_POOL})")
if(BUILD_MBEDTLS)
list(APPEND MBEDTLS_COMPILE_DEFINITIONS "OC_INOUT_BUFFER_POOL=(${OC_INOUT_BUFFER_POOL})")
endif()
endif()

if(NOT("${OC_APP_DATA_BUFFER_SIZE}" STREQUAL ""))
if(NOT OC_DYNAMIC_ALLOCATION_ENABLED)
message(FATAL_ERROR "Cannot set OC_APP_DATA_BUFFER_SIZE without dynamic allocation")
endif()
list(APPEND PUBLIC_COMPILE_DEFINITIONS "OC_APP_DATA_BUFFER_SIZE=(${OC_APP_DATA_BUFFER_SIZE})")
if(BUILD_MBEDTLS)
list(APPEND MBEDTLS_COMPILE_DEFINITIONS "OC_APP_DATA_BUFFER_SIZE=(${OC_APP_DATA_BUFFER_SIZE})")
endif()
endif()

if(NOT("${OC_APP_DATA_BUFFER_POOL}" STREQUAL ""))
if(NOT OC_DYNAMIC_ALLOCATION_ENABLED)
message(FATAL_ERROR "Cannot OC_APP_DATA_BUFFER_POOL without dynamic allocation")
endif()
list(APPEND PUBLIC_COMPILE_DEFINITIONS "OC_APP_DATA_BUFFER_POOL=(${OC_APP_DATA_BUFFER_POOL})")
if(BUILD_MBEDTLS)
list(APPEND MBEDTLS_COMPILE_DEFINITIONS "OC_APP_DATA_BUFFER_POOL=(${OC_APP_DATA_BUFFER_POOL})")
endif()
endif()

if(NOT("${OC_DEVICE_MAX_NUM_CONCURRENT_REQUESTS}" STREQUAL ""))
if(NOT OC_DYNAMIC_ALLOCATION_ENABLED)
message(FATAL_ERROR "Cannot set OC_DEVICE_MAX_NUM_CONCURRENT_REQUESTS without dynamic allocation")
endif()
list(APPEND PUBLIC_COMPILE_DEFINITIONS "OC_DEVICE_MAX_NUM_CONCURRENT_REQUESTS=(${OC_DEVICE_MAX_NUM_CONCURRENT_REQUESTS})")
endif()

if(BUILD_TESTING)
list(APPEND PRIVATE_COMPILE_DEFINITIONS "OC_TEST")
if(BUILD_MBEDTLS)
Expand Down
6 changes: 4 additions & 2 deletions api/cloud/unittest/rd_client_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,8 @@ TEST_F(TestRDClient, Publish_FailBadInput)
/*user_data*/ nullptr));
}

#if defined(OC_DYNAMIC_ALLOCATION) && !defined(OC_APP_DATA_BUFFER_SIZE)
#if defined(OC_DYNAMIC_ALLOCATION) && !defined(OC_APP_DATA_BUFFER_SIZE) && \
!defined(OC_REP_ENCODING_REALLOC)

TEST_F(TestRDClient, Publish_FailPayloadTooLarge)
{
Expand All @@ -228,7 +229,8 @@ TEST_F(TestRDClient, Publish_FailPayloadTooLarge)
oc_set_max_app_data_size(kDefaultSize);
}

#endif // OC_DYNAMIC_ALLOCATION && !OC_APP_DATA_BUFFER_SIZE
#endif // OC_DYNAMIC_ALLOCATION && !OC_APP_DATA_BUFFER_SIZE &&
// !OC_REP_ENCODING_REALLOC

#ifndef OC_DYNAMIC_ALLOCATION

Expand Down
2 changes: 1 addition & 1 deletion api/oc_core_res.c
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,7 @@ static bool
core_is_resource_uri(const char *uri, size_t uri_len, const char *r_uri,
size_t r_uri_len)
{
if (uri[0] == '/') {
if (uri_len > 0 && uri[0] == '/') {
uri = &uri[1];
--uri_len;
}
Expand Down
64 changes: 62 additions & 2 deletions api/oc_network_events.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,37 @@ static bool g_interface_up;
static bool g_interface_down;
#endif /* OC_NETWORK_MONITOR */

#ifdef OC_DYNAMIC_ALLOCATION
static size_t
get_events_queue_length(size_t device, oc_list_t events)
{
size_t msg_count = 0;
for (oc_message_t *msg = (oc_message_t *)oc_list_head(events); msg != NULL;
msg = msg->next) {
if (msg->endpoint.device == device) {
++msg_count;
}
}
return msg_count;
}

static void
send_wakeup_signal(oc_list_t events)
{
size_t msg_total = oc_list_length(events);

int deviceId = 0;
while (msg_total >= OC_DEVICE_MAX_NUM_CONCURRENT_REQUESTS) {
size_t msg_device_count = get_events_queue_length(deviceId, events);
if (msg_device_count >= OC_DEVICE_MAX_NUM_CONCURRENT_REQUESTS) {
oc_connectivity_wakeup(deviceId);
}
msg_total -= msg_device_count;
++deviceId; // advance to the next device
}
}
#endif /* OC_DYNAMIC_ALLOCATION */

static void
oc_process_network_event(void)
{
Expand All @@ -65,6 +96,11 @@ oc_process_network_event(void)
#endif /* OC_NETWORK_MONITOR */
oc_network_event_handler_mutex_unlock();

#ifdef OC_DYNAMIC_ALLOCATION
// send a wake-up signal in case the queue might reach the limit for a device
send_wakeup_signal(network_events);
#endif /* OC_DYNAMIC_ALLOCATION */

#ifdef OC_HAS_FEATURE_TCP_ASYNC_CONNECT
oc_tcp_on_connect_event_t *event =
(oc_tcp_on_connect_event_t *)oc_list_pop(network_tcp_connect_events);
Expand Down Expand Up @@ -153,10 +189,10 @@ oc_network_tcp_connect_event(oc_tcp_on_connect_event_t *event)
}
#endif /* OC_HAS_FEATURE_TCP_ASYNC_CONNECT */

int
size_t
oc_network_drop_receive_events(const oc_endpoint_t *endpoint)
{
int dropped = 0;
size_t dropped = 0;
oc_network_event_handler_mutex_lock();
for (oc_message_t *message = (oc_message_t *)oc_list_head(g_network_events);
message != NULL;) {
Expand All @@ -178,7 +214,20 @@ oc_network_drop_receive_events(const oc_endpoint_t *endpoint)
}
message = next;
}

#ifdef OC_DYNAMIC_ALLOCATION
size_t queue_len =
get_events_queue_length(endpoint->device, g_network_events);
// unlock mutex and send a wake-up signal in case the queue for the device was
// full
oc_network_event_handler_mutex_unlock();
if (queue_len + dropped >= OC_DEVICE_MAX_NUM_CONCURRENT_REQUESTS) {
oc_connectivity_wakeup(endpoint->device);
}
#else
oc_network_event_handler_mutex_unlock();
#endif /* OC_DYNAMIC_ALLOCATION */

return dropped;
}

Expand All @@ -204,3 +253,14 @@ oc_network_interface_event(oc_interface_event_t event)
_oc_signal_event_loop();
}
#endif /* OC_NETWORK_MONITOR */

#ifdef OC_DYNAMIC_ALLOCATION
size_t
oc_network_get_event_queue_length(size_t device)
{
oc_network_event_handler_mutex_lock();
size_t msg_count = get_events_queue_length(device, g_network_events);
oc_network_event_handler_mutex_unlock();
return msg_count;
}
#endif /* OC_DYNAMIC_ALLOCATION */
11 changes: 10 additions & 1 deletion api/oc_network_events_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ void oc_network_tcp_connect_event(oc_tcp_on_connect_event_t *event)
* @param endpoint the endpoint (cannot be NULL)
* @return number of events dropped
*/
int oc_network_drop_receive_events(const oc_endpoint_t *endpoint) OC_NONNULL();
size_t oc_network_drop_receive_events(const oc_endpoint_t *endpoint)
OC_NONNULL();

#ifdef OC_NETWORK_MONITOR
/**
Expand All @@ -78,6 +79,14 @@ typedef struct oc_network_interface_cb
void oc_network_interface_event(oc_interface_event_t event);
#endif /* OC_NETWORK_MONITOR */

/**
* @brief Returns the network event queue length for the device
*
* @param device valid device index
* @return number of events in the queue
*/
size_t oc_network_get_event_queue_length(size_t device);

#ifdef __cplusplus
}
#endif
Expand Down
7 changes: 7 additions & 0 deletions api/unittest/introspectiontest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,11 @@ TEST_F(TestIntrospectionWithServer, GetRequest)
// the IDD data is too large for non-dynamic allocation and byte pool gets
// exhausted

#ifndef OC_REP_ENCODING_REALLOC

// TODO: if the default application data size is too small, the introspection
// data should realloc the buffer to sufficient size

TEST_F(TestIntrospectionWithServer, GetDataRequest)
{
auto epOpt = oc::TestDevice::GetEndpoint(kDeviceID);
Expand All @@ -221,6 +226,8 @@ TEST_F(TestIntrospectionWithServer, GetDataRequest)
EXPECT_TRUE(invoked);
}

#endif /* !OC_REP_ENCODING_REALLOC */

TEST_F(TestIntrospectionWithServer, GetDataRequest_Fail)
{
oc::TestDevice::StopServer();
Expand Down
Loading

0 comments on commit 4a9fad5

Please sign in to comment.