From 29c1fca0c716c0d5846d97ca3c05deefe8c7ef47 Mon Sep 17 00:00:00 2001 From: sourav bhuwalka Date: Mon, 3 Jun 2019 12:46:47 +0530 Subject: [PATCH] [CONPRO-1429] 100% CPU usage by iotivity stack Here before the max number of observers was 255 and when more than 255 observers were there an infinite loop was running. Increasing the number of observers and changing the logic so that infinite loop should not be run when observer count reaches max number of observers. https://github.sec.samsung.net/RS7-IOTIVITY/IoTivity/commit/3f9cb8af60cd5ed929ed876d95e82f2650309f9c (cherry picked from 3f9cb8af60cd5ed929ed876d95e82f2650309f9c) Change-Id: Ib0bb86817d2dbf8c2d5f5806cb49ffa2e002cd21 Signed-off-by: DoHyun Pyun --- resource/c_common/ocrandom/include/ocrandom.h | 6 +++ resource/c_common/ocrandom/src/ocrandom.c | 10 +++++ .../csdk/stack/include/internal/ocobserve.h | 2 +- resource/csdk/stack/include/octypes.h | 4 +- resource/csdk/stack/src/ocobserve.c | 41 ++++++++++++++----- .../src/provider/NSProviderNotification.c | 4 +- .../src/provider/NSProviderTopic.c | 2 +- 7 files changed, 52 insertions(+), 17 deletions(-) diff --git a/resource/c_common/ocrandom/include/ocrandom.h b/resource/c_common/ocrandom/include/ocrandom.h index d4af63436..a531c7069 100644 --- a/resource/c_common/ocrandom/include/ocrandom.h +++ b/resource/c_common/ocrandom/include/ocrandom.h @@ -66,6 +66,12 @@ uint32_t OCGetRandom(); */ uint8_t OCGetRandomByte(void); +/** + * Generate a uniformly [0,2^16] distributed random number + * @retval On Success, it returns the random value, otherwise -1 for error. + */ +uint16_t OCGetRandomTwoByte(void); + /** * Generate a uniformly distributed 8-bit (byte) array random numbers * @param[out] location diff --git a/resource/c_common/ocrandom/src/ocrandom.c b/resource/c_common/ocrandom/src/ocrandom.c index c7c7e0901..1c43edbfe 100644 --- a/resource/c_common/ocrandom/src/ocrandom.c +++ b/resource/c_common/ocrandom/src/ocrandom.c @@ -227,6 +227,16 @@ uint8_t OCGetRandomByte(void) #endif } +uint16_t OCGetRandomTwoByte(void) +{ +#ifdef HAVE_SRANDOM + return random() & 0x00FFFF; +#else + return rand() & 0x00FFFF; +#endif +} + + uint32_t OCGetRandomRange(uint32_t firstBound, uint32_t secondBound) { uint32_t base; diff --git a/resource/csdk/stack/include/internal/ocobserve.h b/resource/csdk/stack/include/internal/ocobserve.h index f5fc6c1f6..018ee7cb8 100644 --- a/resource/csdk/stack/include/internal/ocobserve.h +++ b/resource/csdk/stack/include/internal/ocobserve.h @@ -150,7 +150,7 @@ OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr, * @return ::OC_STACK_OK on success, some other value upon failure. */ OCStackResult SendListObserverNotification (OCResource * resource, - OCObservationId *obsIdList, uint8_t numberOfIds, + OCObservationId *obsIdList, uint16_t numberOfIds, const OCRepPayload *payload, uint32_t maxAge, OCQualityOfService qos); diff --git a/resource/csdk/stack/include/octypes.h b/resource/csdk/stack/include/octypes.h index a7e6dbfcb..8187b884f 100644 --- a/resource/csdk/stack/include/octypes.h +++ b/resource/csdk/stack/include/octypes.h @@ -1063,9 +1063,9 @@ typedef uint32_t OCRequestHandle; * Unique identifier for each observation request. Used when observations are * registered or de-registered. Used by entity handler to signal specific * observers to be notified of resource changes. - * There can be maximum of 256 observations per server. + * There can be maximum of 3840 observations per server. */ -typedef uint8_t OCObservationId; +typedef uint16_t OCObservationId; /** * Sequence number is a 24 bit field, diff --git a/resource/csdk/stack/src/ocobserve.c b/resource/csdk/stack/src/ocobserve.c index 18de8c68b..7495f2b4b 100644 --- a/resource/csdk/stack/src/ocobserve.c +++ b/resource/csdk/stack/src/ocobserve.c @@ -43,9 +43,13 @@ #define VERIFY_NON_NULL(arg) { if (!arg) {OIC_LOG(FATAL, TAG, #arg " is NULL"); goto exit;} } +#define MAX_OBSERVERS 3840 + static struct ResourceObserver * g_serverObsList = NULL; static oc_mutex g_serverObsListMutex = NULL; +static int observer_count = 0; + static ResourceObserver* GetObserverUsingIdAsOwner (const OCObservationId observeId); static ResourceObserver* CloneObserverNode (ResourceObserver* observer) @@ -255,7 +259,7 @@ OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr, OCStackResult result = OC_STACK_ERROR; ResourceObserver * resourceObserver = NULL; - uint8_t numObs = 0; + uint16_t numObs = 0; OCServerRequest * request = NULL; bool observeErrorFlag = false; @@ -347,7 +351,7 @@ OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr, } OCStackResult SendListObserverNotification (OCResource * resource, - OCObservationId *obsIdList, uint8_t numberOfIds, + OCObservationId *obsIdList, uint16_t numberOfIds, const OCRepPayload *payload, uint32_t maxAge, OCQualityOfService qos) @@ -358,9 +362,9 @@ OCStackResult SendListObserverNotification (OCResource * resource, return OC_STACK_INVALID_PARAM; } - uint8_t numIds = numberOfIds; + uint16_t numIds = numberOfIds; ResourceObserver *observer = NULL; - uint8_t numSentNotification = 0; + uint16_t numSentNotification = 0; OCServerRequest * request = NULL; OCStackResult result = OC_STACK_ERROR; bool observeErrorFlag = false; @@ -464,19 +468,32 @@ OCStackResult GenerateObserverId (OCObservationId *observationId) OIC_LOG(INFO, TAG, "Entering GenerateObserverId"); VERIFY_NON_NULL (observationId); - do + oc_mutex_lock(g_serverObsListMutex); + + if (observer_count < MAX_OBSERVERS) { + oc_mutex_unlock(g_serverObsListMutex); do { - *observationId = OCGetRandomByte(); - } while (0 == *observationId); //Make sure *observationId is not 0 - // Check if observation Id already exists - found = IsObserverAvailable (*observationId); - } while (found); - + do + { + *observationId = OCGetRandomTwoByte(); + } while (0 == *observationId); //Make sure *observationId is not 0 + // Check if observation Id already exists + found = IsObserverAvailable (*observationId); + } while (found); OIC_LOG_V(INFO, TAG, "GeneratedObservation ID is %u", *observationId); + //oc_mutex_unlock(g_serverObsListMutex); return OC_STACK_OK; + } + else + { + OIC_LOG_V(ERROR, TAG, "No more observers can be added"); + oc_mutex_unlock(g_serverObsListMutex); + + return OC_STACK_ERROR; + } exit: return OC_STACK_ERROR; } @@ -547,6 +564,7 @@ OCStackResult AddObserver (const char *resUri, oc_mutex_lock(g_serverObsListMutex); LL_APPEND (g_serverObsList, obsNode); + observer_count++; oc_mutex_unlock(g_serverObsListMutex); return OC_STACK_OK; @@ -728,6 +746,7 @@ OCStackResult DeleteObserverUsingToken (CAToken_t token, uint8_t tokenLength) OIC_LOG_BUFFER(INFO, TAG, (const uint8_t *)obsNode->token, tokenLength); LL_DELETE (g_serverObsList, obsNode); + observer_count--; FreeObserver(obsNode); } oc_mutex_unlock(g_serverObsListMutex); diff --git a/service/notification/src/provider/NSProviderNotification.c b/service/notification/src/provider/NSProviderNotification.c index 01191164e..74708dff1 100644 --- a/service/notification/src/provider/NSProviderNotification.c +++ b/service/notification/src/provider/NSProviderNotification.c @@ -108,7 +108,7 @@ NSResult NSSendNotification(NSMessage *msg) NS_LOG(DEBUG, "NSSendMessage - IN"); OCResourceHandle rHandle; - OCObservationId obArray[255] = { 0, }; + OCObservationId obArray[3839] = { 0, }; int obCount = 0, i; if (NSPutMessageResource(msg, &rHandle) != NS_OK) @@ -232,7 +232,7 @@ NSResult NSSendSync(NSSyncInfo *sync) { NS_LOG(DEBUG, "NSSendSync - IN"); - OCObservationId obArray[255] = { 0, }; + OCObservationId obArray[3839] = { 0, }; int obCount = 0; int i; diff --git a/service/notification/src/provider/NSProviderTopic.c b/service/notification/src/provider/NSProviderTopic.c index f6aa8e941..9a6dee9a3 100644 --- a/service/notification/src/provider/NSProviderTopic.c +++ b/service/notification/src/provider/NSProviderTopic.c @@ -143,7 +143,7 @@ NSResult NSSendTopicUpdation() OCRepPayloadSetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, NS_TOPIC); OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, NSGetProviderInfo()->providerId); - OCObservationId obArray[255] = + OCObservationId obArray[3839] = { 0, }; int obCount = 0; -- 2.34.1