Explorar o código

move subscription limits into the server config

Julius Pfrommer %!s(int64=9) %!d(string=hai) anos
pai
achega
6150efa166

+ 16 - 0
include/ua_server.h

@@ -83,6 +83,12 @@ typedef struct {
     UA_String password;
 } UA_UsernamePasswordLogin;
 
+typedef struct {
+    UA_UInt32 current;
+    UA_UInt32 min;
+    UA_UInt32 max;
+} UA_BoundedUInt32;
+
 typedef struct {
     UA_UInt16 nThreads; // only if multithreading is enabled
     UA_Logger logger;
@@ -91,13 +97,23 @@ typedef struct {
     UA_ApplicationDescription applicationDescription;
     UA_ByteString serverCertificate;
 
+    /* Networking */
     size_t networkLayersSize;
     UA_ServerNetworkLayer *networkLayers;
 
+    /* Login */
     UA_Boolean enableAnonymousLogin;
     UA_Boolean enableUsernamePasswordLogin;
     size_t usernamePasswordLoginsSize;
     UA_UsernamePasswordLogin* usernamePasswordLogins;
+
+    /* Limits for subscription settings */
+    UA_BoundedUInt32 publishingIntervalLimits;
+    UA_BoundedUInt32 lifeTimeCountLimits;
+    UA_BoundedUInt32 keepAliveCountLimits;
+    UA_BoundedUInt32 notificationsPerPublishLimits;
+    UA_BoundedUInt32 samplingIntervalLimits;
+    UA_BoundedUInt32 queueSizeLimits;
 } UA_ServerConfig;
 
 extern UA_EXPORT const UA_ServerConfig UA_ServerConfig_standard;

+ 8 - 1
src/server/ua_server.c

@@ -48,7 +48,14 @@ const UA_ServerConfig UA_ServerConfig_standard = {
     .enableAnonymousLogin = true,
     .enableUsernamePasswordLogin = true,
     .usernamePasswordLogins = usernamePasswords,
-    .usernamePasswordLoginsSize = 2
+    .usernamePasswordLoginsSize = 2,
+    
+    .publishingIntervalLimits = { .max = 10000, .min = 0, .current = 0 },
+    .lifeTimeCountLimits = { .max = 15000, .min = 0, .current = 0 },
+    .keepAliveCountLimits = { .max = 100, .min = 0, .current = 0 },
+    .notificationsPerPublishLimits = { .max = 1000, .min = 1, .current = 0 },
+    .samplingIntervalLimits = { .max = 1000, .min = 5, .current = 0 },
+    .queueSizeLimits = { .max = 100, .min = 0, .current = 0 }
 };
 
 #if defined(UA_ENABLE_MULTITHREADING) && !defined(NDEBUG)

+ 31 - 31
src/server/ua_services_subscription.c

@@ -4,8 +4,8 @@
 #include "ua_subscription.h"
 
 #define UA_BOUNDEDVALUE_SETWBOUNDS(BOUNDS, SRC, DST) { \
-    if(SRC > BOUNDS.maxValue) DST = BOUNDS.maxValue; \
-    else if(SRC < BOUNDS.minValue) DST = BOUNDS.minValue; \
+    if(SRC > BOUNDS.max) DST = BOUNDS.max; \
+    else if(SRC < BOUNDS.min) DST = BOUNDS.min; \
     else DST = SRC; \
     }
 
@@ -20,26 +20,26 @@ void Service_CreateSubscription(UA_Server *server, UA_Session *session,
     }
     
     /* set the publishing interval */
-    UA_BOUNDEDVALUE_SETWBOUNDS(session->subscriptionManager.globalPublishingInterval,
+    UA_BOUNDEDVALUE_SETWBOUNDS(server->config.publishingIntervalLimits,
                                request->requestedPublishingInterval, response->revisedPublishingInterval);
     newSubscription->publishingInterval = response->revisedPublishingInterval;
     
     /* set the subscription lifetime (deleted when no publish requests arrive within this time) */
-    UA_BOUNDEDVALUE_SETWBOUNDS(session->subscriptionManager.globalLifeTimeCount,
+    UA_BOUNDEDVALUE_SETWBOUNDS(server->config.lifeTimeCountLimits,
                                request->requestedLifetimeCount, response->revisedLifetimeCount);
-    newSubscription->lifeTime = (UA_UInt32_BoundedValue)  {
-        .minValue=session->subscriptionManager.globalLifeTimeCount.minValue,
-        .maxValue=session->subscriptionManager.globalLifeTimeCount.maxValue,
-        .currentValue=response->revisedLifetimeCount};
+    newSubscription->lifeTime = (UA_BoundedUInt32)  {
+        .min = server->config.lifeTimeCountLimits.min,
+        .max = server->config.lifeTimeCountLimits.max,
+        .current=response->revisedLifetimeCount};
     
     /* set the keepalive count. the server sends an empty notification when
        nothin has happened for n publishing intervals */
-    UA_BOUNDEDVALUE_SETWBOUNDS(session->subscriptionManager.globalKeepAliveCount,
+    UA_BOUNDEDVALUE_SETWBOUNDS(server->config.keepAliveCountLimits,
                                request->requestedMaxKeepAliveCount, response->revisedMaxKeepAliveCount);
-    newSubscription->keepAliveCount = (UA_UInt32_BoundedValue)  {
-        .minValue=session->subscriptionManager.globalKeepAliveCount.minValue,
-        .maxValue=session->subscriptionManager.globalKeepAliveCount.maxValue,
-        .currentValue=response->revisedMaxKeepAliveCount};
+    newSubscription->keepAliveCount = (UA_BoundedUInt32)  {
+        .min = server->config.keepAliveCountLimits.min,
+        .max = server->config.keepAliveCountLimits.max,
+        .current = response->revisedMaxKeepAliveCount};
     
     newSubscription->notificationsPerPublish = request->maxNotificationsPerPublish;
     newSubscription->publishingMode          = request->publishingEnabled;
@@ -79,18 +79,18 @@ createMonitoredItems(UA_Server *server, UA_Session *session, UA_Subscription *su
     newMon->clientHandle = request->requestedParameters.clientHandle;
 
     /* set the sampling interval */
-    UA_BOUNDEDVALUE_SETWBOUNDS(session->subscriptionManager.globalSamplingInterval,
+    UA_BOUNDEDVALUE_SETWBOUNDS(server->config.samplingIntervalLimits,
                                request->requestedParameters.samplingInterval,
                                result->revisedSamplingInterval);
     newMon->samplingInterval = (UA_UInt32)result->revisedSamplingInterval;
 
     /* set the queue size */
-    UA_BOUNDEDVALUE_SETWBOUNDS(session->subscriptionManager.globalQueueSize,
+    UA_BOUNDEDVALUE_SETWBOUNDS(server->config.queueSizeLimits,
                                request->requestedParameters.queueSize,
                                result->revisedQueueSize);
-    newMon->queueSize = (UA_UInt32_BoundedValue) {
-        .maxValue=(result->revisedQueueSize) + 1,
-        .minValue=0, .currentValue=0 };
+    newMon->queueSize = (UA_BoundedUInt32) {
+        .max=(result->revisedQueueSize) + 1,
+        .min=0, .current=0 };
 
     newMon->attributeID = request->itemToMonitor.attributeId;
     newMon->monitoredItemType = MONITOREDITEM_TYPE_CHANGENOTIFY;
@@ -210,7 +210,7 @@ Service_Publish(UA_Server *server, UA_Session *session,
         sub = LIST_FIRST(&manager->serverSubscriptions);
         if(sub) {
             response.subscriptionId = sub->subscriptionID;
-            sub->keepAliveCount.currentValue=sub->keepAliveCount.minValue;
+            sub->keepAliveCount.current=sub->keepAliveCount.min;
             Subscription_generateKeepAlive(sub);
             Subscription_copyNotificationMessage(&response.notificationMessage,
                                                  LIST_FIRST(&sub->unpublishedNotifications));
@@ -235,23 +235,23 @@ Service_ModifySubscription(UA_Server *server, UA_Session *session, const UA_Modi
         return;
     }
     
-    UA_BOUNDEDVALUE_SETWBOUNDS(session->subscriptionManager.globalPublishingInterval,
+    UA_BOUNDEDVALUE_SETWBOUNDS(server->config.publishingIntervalLimits,
                                request->requestedPublishingInterval, response->revisedPublishingInterval);
     sub->publishingInterval = response->revisedPublishingInterval;
     
-    UA_BOUNDEDVALUE_SETWBOUNDS(session->subscriptionManager.globalLifeTimeCount,
+    UA_BOUNDEDVALUE_SETWBOUNDS(server->config.lifeTimeCountLimits,
                                request->requestedLifetimeCount, response->revisedLifetimeCount);
-    sub->lifeTime = (UA_UInt32_BoundedValue)  {
-        .minValue=session->subscriptionManager.globalLifeTimeCount.minValue,
-        .maxValue=session->subscriptionManager.globalLifeTimeCount.maxValue,
-        .currentValue=response->revisedLifetimeCount};
+    sub->lifeTime = (UA_BoundedUInt32)  {
+        .min = server->config.lifeTimeCountLimits.min,
+        .max = server->config.lifeTimeCountLimits.max,
+        .current=response->revisedLifetimeCount};
         
-    UA_BOUNDEDVALUE_SETWBOUNDS(session->subscriptionManager.globalKeepAliveCount,
-                                request->requestedMaxKeepAliveCount, response->revisedMaxKeepAliveCount);
-    sub->keepAliveCount = (UA_UInt32_BoundedValue)  {
-        .minValue=session->subscriptionManager.globalKeepAliveCount.minValue,
-        .maxValue=session->subscriptionManager.globalKeepAliveCount.maxValue,
-        .currentValue=response->revisedMaxKeepAliveCount};
+    UA_BOUNDEDVALUE_SETWBOUNDS(server->config.keepAliveCountLimits,
+                               request->requestedMaxKeepAliveCount, response->revisedMaxKeepAliveCount);
+    sub->keepAliveCount = (UA_BoundedUInt32)  {
+        .min = server->config.keepAliveCountLimits.min,
+        .max = server->config.keepAliveCountLimits.max,
+        .current=response->revisedMaxKeepAliveCount};
         
     sub->notificationsPerPublish = request->maxNotificationsPerPublish;
     sub->priority                = request->priority;

+ 15 - 15
src/server/ua_subscription.c

@@ -45,8 +45,8 @@ void UA_Subscription_deleteMembers(UA_Subscription *subscription, UA_Server *ser
 }
 
 void Subscription_generateKeepAlive(UA_Subscription *subscription) {
-    if(subscription->keepAliveCount.currentValue > subscription->keepAliveCount.minValue &&
-       subscription->keepAliveCount.currentValue <= subscription->keepAliveCount.maxValue)
+    if(subscription->keepAliveCount.current > subscription->keepAliveCount.min &&
+       subscription->keepAliveCount.current <= subscription->keepAliveCount.max)
         return;
 
     UA_unpublishedNotification *msg = UA_calloc(1,sizeof(UA_unpublishedNotification));
@@ -59,7 +59,7 @@ void Subscription_generateKeepAlive(UA_Subscription *subscription) {
     msg->notification.notificationDataSize = 0;
     LIST_INSERT_HEAD(&subscription->unpublishedNotifications, msg, listEntry);
     subscription->unpublishedNotificationsSize += 1;
-    subscription->keepAliveCount.currentValue = subscription->keepAliveCount.maxValue;
+    subscription->keepAliveCount.current = subscription->keepAliveCount.max;
 }
 
 void Subscription_updateNotifications(UA_Subscription *subscription) {
@@ -79,11 +79,11 @@ void Subscription_updateNotifications(UA_Subscription *subscription) {
         if(!TAILQ_FIRST(&mon->queue))
             continue;
         if((mon->monitoredItemType & MONITOREDITEM_TYPE_CHANGENOTIFY) != 0)
-            monItemsChangeT+=mon->queueSize.currentValue;
+            monItemsChangeT+=mon->queueSize.current;
 	    else if((mon->monitoredItemType & MONITOREDITEM_TYPE_STATUSNOTIFY) != 0)
-            monItemsStatusT+=mon->queueSize.currentValue;
+            monItemsStatusT+=mon->queueSize.current;
 	    else if((mon->monitoredItemType & MONITOREDITEM_TYPE_EVENTNOTIFY)  != 0)
-            monItemsEventT+=mon->queueSize.currentValue;
+            monItemsEventT+=mon->queueSize.current;
     }
     
     // FIXME: This is hardcoded to 100 because it is not covered by the spec but we need to protect the server!
@@ -94,9 +94,9 @@ void Subscription_updateNotifications(UA_Subscription *subscription) {
     
     if(monItemsChangeT == 0 && monItemsEventT == 0 && monItemsStatusT == 0) {
         // Decrement KeepAlive
-        subscription->keepAliveCount.currentValue--;
+        subscription->keepAliveCount.current--;
         // +- Generate KeepAlive msg if counter overruns
-        if (subscription->keepAliveCount.currentValue < subscription->keepAliveCount.minValue)
+        if (subscription->keepAliveCount.current < subscription->keepAliveCount.min)
           Subscription_generateKeepAlive(subscription);
         
         return;
@@ -258,7 +258,7 @@ UA_StatusCode Subscription_unregisterUpdateJob(UA_Server *server, UA_Subscriptio
 
 UA_MonitoredItem * UA_MonitoredItem_new() {
     UA_MonitoredItem *new = (UA_MonitoredItem *) UA_malloc(sizeof(UA_MonitoredItem));
-    new->queueSize   = (UA_UInt32_BoundedValue) { .minValue = 0, .maxValue = 0, .currentValue = 0};
+    new->queueSize   = (UA_BoundedUInt32) { .min = 0, .max = 0, .current = 0};
     new->lastSampled = 0;
     // FIXME: This is currently hardcoded;
     new->monitoredItemType = MONITOREDITEM_TYPE_CHANGENOTIFY;
@@ -287,7 +287,7 @@ UA_UInt32 MonitoredItem_QueueToDataChangeNotifications(UA_MonitoredItemNotificat
     UA_UInt32 queueSize = 0;
     MonitoredItem_queuedValue *queueItem;
   
-    // Count instead of relying on the items currentValue
+    // Count instead of relying on the items current
     TAILQ_FOREACH(queueItem, &monitoredItem->queue, listEntry) {
         dst[queueSize].clientHandle = monitoredItem->clientHandle;
         UA_DataValue_copy(&queueItem->value, &dst[queueSize].value);
@@ -310,7 +310,7 @@ void MonitoredItem_ClearQueue(UA_MonitoredItem *monitoredItem) {
         UA_DataValue_deleteMembers(&val->value);
         UA_free(val);
     }
-    monitoredItem->queueSize.currentValue = 0;
+    monitoredItem->queueSize.current = 0;
 }
 
 UA_Boolean MonitoredItem_CopyMonitoredValueToVariant(UA_UInt32 attributeID, const UA_Node *src,
@@ -451,7 +451,7 @@ void MonitoredItem_QueuePushDataValue(UA_Server *server, UA_MonitoredItem *monit
         return;
     }
   
-    if(monitoredItem->queueSize.currentValue >= monitoredItem->queueSize.maxValue) {
+    if(monitoredItem->queueSize.current >= monitoredItem->queueSize.max) {
         if(monitoredItem->discardOldest != true) {
             // We cannot remove the oldest value and theres no queue space left. We're done here.
             UA_DataValue_deleteMembers(&newvalue->value);
@@ -461,7 +461,7 @@ void MonitoredItem_QueuePushDataValue(UA_Server *server, UA_MonitoredItem *monit
         MonitoredItem_queuedValue *queueItem = TAILQ_LAST(&monitoredItem->queue, QueueOfQueueDataValues);
         TAILQ_REMOVE(&monitoredItem->queue, queueItem, listEntry);
         UA_free(queueItem);
-        monitoredItem->queueSize.currentValue--;
+        monitoredItem->queueSize.current--;
     }
   
     // encode the data to find if its different to the previous
@@ -484,7 +484,7 @@ void MonitoredItem_QueuePushDataValue(UA_Server *server, UA_MonitoredItem *monit
     if(!monitoredItem->lastSampledValue.data) { 
         UA_ByteString_copy(&newValueAsByteString, &monitoredItem->lastSampledValue);
         TAILQ_INSERT_HEAD(&monitoredItem->queue, newvalue, listEntry);
-        monitoredItem->queueSize.currentValue++;
+        monitoredItem->queueSize.current++;
         monitoredItem->lastSampled = UA_DateTime_now();
         UA_free(newValueAsByteString.data);
     } else {
@@ -497,7 +497,7 @@ void MonitoredItem_QueuePushDataValue(UA_Server *server, UA_MonitoredItem *monit
         UA_ByteString_deleteMembers(&monitoredItem->lastSampledValue);
         monitoredItem->lastSampledValue = newValueAsByteString;
         TAILQ_INSERT_HEAD(&monitoredItem->queue, newvalue, listEntry);
-        monitoredItem->queueSize.currentValue++;
+        monitoredItem->queueSize.current++;
         monitoredItem->lastSampled = UA_DateTime_now();
     }
 }

+ 3 - 15
src/server/ua_subscription.h

@@ -10,18 +10,6 @@
 /* MonitoredItem */
 /*****************/
 
-typedef struct {
-    UA_Int32 currentValue;
-    UA_Int32 minValue;
-    UA_Int32 maxValue;
-} UA_Int32_BoundedValue;
-
-typedef struct {
-    UA_UInt32 currentValue;
-    UA_UInt32 minValue;
-    UA_UInt32 maxValue;
-} UA_UInt32_BoundedValue;
-
 typedef enum {
     MONITOREDITEM_TYPE_CHANGENOTIFY = 1,
     MONITOREDITEM_TYPE_STATUSNOTIFY = 2,
@@ -43,7 +31,7 @@ typedef struct UA_MonitoredItem {
     UA_UInt32 attributeID;
     UA_UInt32 clientHandle;
     UA_UInt32 samplingInterval; // [ms]
-    UA_UInt32_BoundedValue queueSize;
+    UA_BoundedUInt32 queueSize;
     UA_Boolean discardOldest;
     UA_DateTime lastSampled;
     UA_ByteString lastSampledValue;
@@ -73,8 +61,8 @@ typedef struct UA_unpublishedNotification {
 
 typedef struct UA_Subscription {
     LIST_ENTRY(UA_Subscription) listEntry;
-    UA_UInt32_BoundedValue lifeTime;
-    UA_UInt32_BoundedValue keepAliveCount;
+    UA_BoundedUInt32 lifeTime;
+    UA_BoundedUInt32 keepAliveCount;
     UA_Double publishingInterval;     // [ms] 
     UA_DateTime lastPublished;
     UA_UInt32 subscriptionID;

+ 0 - 9
src/server/ua_subscription_manager.c

@@ -5,15 +5,6 @@
 
 void SubscriptionManager_init(UA_Session *session) {
     UA_SubscriptionManager *manager = &(session->subscriptionManager);
-
-    /* FIXME: These init values are empirical. Maybe they should be part
-     *        of the server config? */
-    manager->globalPublishingInterval = (UA_UInt32_BoundedValue) { .maxValue = 10000, .minValue = 0, .currentValue=0 };
-    manager->globalLifeTimeCount = (UA_UInt32_BoundedValue) { .maxValue = 15000, .minValue = 0, .currentValue=0 };
-    manager->globalKeepAliveCount = (UA_UInt32_BoundedValue) { .maxValue = 100, .minValue = 0, .currentValue=0 };
-    manager->globalNotificationsPerPublish = (UA_UInt32_BoundedValue)  { .maxValue = 1000, .minValue = 1, .currentValue=0 };
-    manager->globalSamplingInterval = (UA_UInt32_BoundedValue) { .maxValue = 1000, .minValue = 5, .currentValue=0 };
-    manager->globalQueueSize = (UA_UInt32_BoundedValue) { .maxValue = 100, .minValue = 0, .currentValue=0 };
     LIST_INIT(&manager->serverSubscriptions);
     manager->lastSessionID = (UA_UInt32) UA_DateTime_now();
     manager->lastJobGuid = UA_Guid_random();

+ 0 - 6
src/server/ua_subscription_manager.h

@@ -8,12 +8,6 @@
 #include "ua_subscription.h"
 
 typedef struct UA_SubscriptionManager {
-    UA_UInt32_BoundedValue globalPublishingInterval;
-    UA_UInt32_BoundedValue globalLifeTimeCount;
-    UA_UInt32_BoundedValue globalKeepAliveCount;
-    UA_UInt32_BoundedValue globalNotificationsPerPublish;
-    UA_UInt32_BoundedValue globalSamplingInterval;
-    UA_UInt32_BoundedValue globalQueueSize;
     UA_UInt32 lastSessionID;
     UA_Guid lastJobGuid;
     LIST_HEAD(UA_ListOfUASubscriptions, UA_Subscription) serverSubscriptions;