From 4e5cc853a90507c788e30c2a5dfe19f71305c9bb Mon Sep 17 00:00:00 2001 From: sourav bhuwalka Date: Mon, 3 Jun 2019 12:46:47 +0530 Subject: [PATCH] 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 ++++++ resource/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 +-- .../notification/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 d4af634..a531c70 100644 --- a/resource/c_common/ocrandom/include/ocrandom.h +++ b/resource/c_common/ocrandom/include/ocrandom.h @@ -67,6 +67,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 * memory location to start filling with random bytes diff --git a/resource/c_common/ocrandom/src/ocrandom.c b/resource/c_common/ocrandom/src/ocrandom.c index c7c7e09..1c43edb 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 f5fc6c1..018ee7c 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 a7e6dbf..8187b88 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 18de8c6..7495f2b 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 0119116..74708df 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 f6aa8e9..9a6dee9 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.7.4