[CONPRO-1429] 100% CPU usage by iotivity stack 44/208344/1
authorsourav bhuwalka <s.bhuwalka@samsung.com>
Mon, 3 Jun 2019 07:16:47 +0000 (12:46 +0530)
committerDoHyun Pyun <dh79.pyun@samsung.com>
Mon, 24 Jun 2019 00:49:39 +0000 (09:49 +0900)
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 <dh79.pyun@samsung.com>
resource/c_common/ocrandom/include/ocrandom.h
resource/c_common/ocrandom/src/ocrandom.c
resource/csdk/stack/include/internal/ocobserve.h
resource/csdk/stack/include/octypes.h
resource/csdk/stack/src/ocobserve.c
service/notification/src/provider/NSProviderNotification.c
service/notification/src/provider/NSProviderTopic.c

index d4af634..a531c70 100644 (file)
@@ -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
index c7c7e09..1c43edb 100644 (file)
@@ -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;
index f5fc6c1..018ee7c 100644 (file)
@@ -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);
 
index a7e6dbf..8187b88 100644 (file)
@@ -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,
index 18de8c6..7495f2b 100644 (file)
 
 #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);
index 0119116..74708df 100644 (file)
@@ -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;
 
index f6aa8e9..9a6dee9 100644 (file)
@@ -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;