Kaynağa Gözat

add limits for session and securechannel to the server config

Julius Pfrommer 8 yıl önce
ebeveyn
işleme
1950b61849

+ 20 - 11
include/ua_server.h

@@ -38,7 +38,7 @@ extern "C" {
  * are never called in parallel but only sequentially from the server's main
  * loop. So the network layer does not need to be thread-safe. */
 struct UA_ServerNetworkLayer;
-typedef struct UA_ServerNetworkLayer UA_ServerNetworkLayer;    
+typedef struct UA_ServerNetworkLayer UA_ServerNetworkLayer;
 
 struct UA_ServerNetworkLayer {
     void *handle; // pointer to internal data
@@ -89,14 +89,15 @@ typedef struct {
 } UA_UInt32Range;
 
 typedef struct {
-	UA_Double min;
-	UA_Double max;
+    UA_Double min;
+    UA_Double max;
 } UA_DoubleRange;
 
 typedef struct {
-    UA_UInt16 nThreads; // only if multithreading is enabled
+    UA_UInt16 nThreads; /* only if multithreading is enabled */
     UA_Logger logger;
 
+    /* Server Description */
     UA_BuildInfo buildInfo;
     UA_ApplicationDescription applicationDescription;
     UA_ByteString serverCertificate;
@@ -111,15 +112,23 @@ typedef struct {
     size_t usernamePasswordLoginsSize;
     UA_UsernamePasswordLogin* usernamePasswordLogins;
 
-    /* Limits for subscription settings */
-	UA_DoubleRange publishingIntervalLimits;
-	UA_UInt32Range lifeTimeCountLimits;
-	UA_UInt32Range keepAliveCountLimits;
-	UA_UInt32 maxNotificationsPerPublish;
+    /* Limits for SecureChannels */
+    UA_UInt16 maxSecureChannels;
+    UA_UInt32 maxSecurityTokenLifetime; /* in ms */
 
-	/* Limits for monitoreditem settings */
+    /* Limits for Sessions */
+    UA_UInt16 maxSessions;
+    UA_Double maxSessionTimeout; /* in ms */
+
+    /* Limits for Subscriptions */
+    UA_DoubleRange publishingIntervalLimits;
+    UA_UInt32Range lifeTimeCountLimits;
+    UA_UInt32Range keepAliveCountLimits;
+    UA_UInt32 maxNotificationsPerPublish;
+
+    /* Limits for MonitoredItems */
     UA_DoubleRange samplingIntervalLimits;
-	UA_UInt32Range queueSizeLimits;
+    UA_UInt32Range queueSizeLimits;
 } UA_ServerConfig;
 
 /**

+ 14 - 0
plugins/ua_config_standard.c

@@ -17,6 +17,7 @@ const UA_ServerConfig UA_ServerConfig_standard = {
     .nThreads = 1,
     .logger = Logger_Stdout,
 
+    /* Server Description */
     .buildInfo = {
         .productUri = UA_STRING_STATIC(PRODUCT_URI),
         .manufacturerName = UA_STRING_STATIC(MANUFACTURER_NAME),
@@ -36,18 +37,31 @@ const UA_ServerConfig UA_ServerConfig_standard = {
         .discoveryUrls = NULL },
     .serverCertificate = UA_STRING_STATIC_NULL,
 
+    /* Networking */
     .networkLayersSize = 0,
     .networkLayers = NULL,
 
+    /* Login */
     .enableAnonymousLogin = true,
     .enableUsernamePasswordLogin = true,
     .usernamePasswordLogins = usernamePasswords,
     .usernamePasswordLoginsSize = 2,
 
+    /* Limits for SecureChannels */
+    .maxSecureChannels = 100,
+    .maxSecurityTokenLifetime = 10 * 60 * 1000, /* 10 minutes */
+
+    /* Limits for Sessions */
+    .maxSessions = 100,
+    .maxSessionTimeout = 60.0 * 60.0 * 1000.0, /* 1h */
+
+    /* Limits for Subscriptions */
     .publishingIntervalLimits = { .min = 100.0, .max = 3600.0 * 1000.0 },
     .lifeTimeCountLimits = { .max = 15000, .min = 3 },
     .keepAliveCountLimits = { .max = 100, .min = 1 },
     .maxNotificationsPerPublish = 1000,
+
+    /* Limits for MonitoredItems */
     .samplingIntervalLimits = { .min = 50.0, .max = 24.0 * 3600.0 * 1000.0 },
     .queueSizeLimits = { .max = 100, .min = 1 }
 };

+ 15 - 17
src/server/ua_securechannel_manager.c

@@ -2,15 +2,14 @@
 #include "ua_session.h"
 #include "ua_server_internal.h"
 
+#define STARTCHANNELID 1
+#define STARTTOKENID 1
+
 UA_StatusCode
-UA_SecureChannelManager_init(UA_SecureChannelManager *cm, size_t maxChannelCount,
-                             UA_UInt32 tokenLifetime, UA_UInt32 startChannelId,
-                             UA_UInt32 startTokenId, UA_Server *server) {
+UA_SecureChannelManager_init(UA_SecureChannelManager *cm, UA_Server *server) {
     LIST_INIT(&cm->channels);
-    cm->lastChannelId = startChannelId;
-    cm->lastTokenId = startTokenId;
-    cm->maxChannelLifetime = tokenLifetime;
-    cm->maxChannelCount = maxChannelCount;
+    cm->lastChannelId = STARTCHANNELID;
+    cm->lastTokenId = STARTTOKENID;
     cm->currentChannelCount = 0;
     cm->server = server;
     return UA_STATUSCODE_GOOD;
@@ -56,7 +55,7 @@ UA_SecureChannelManager_open(UA_SecureChannelManager *cm, UA_Connection *conn,
                              UA_OpenSecureChannelResponse *response) {
     if(request->securityMode != UA_MESSAGESECURITYMODE_NONE)
         return UA_STATUSCODE_BADSECURITYMODEREJECTED;
-    if(cm->currentChannelCount >= cm->maxChannelCount)
+    if(cm->currentChannelCount >= cm->server->config.maxSecureChannels)
         return UA_STATUSCODE_BADOUTOFMEMORY;
     channel_list_entry *entry = UA_malloc(sizeof(channel_list_entry));
     if(!entry)
@@ -76,11 +75,11 @@ UA_SecureChannelManager_open(UA_SecureChannelManager *cm, UA_Connection *conn,
     entry->channel.securityToken.tokenId = cm->lastTokenId++;
     entry->channel.securityToken.createdAt = UA_DateTime_now();
     entry->channel.securityToken.revisedLifetime =
-            (request->requestedLifetime > cm->maxChannelLifetime) ?
-                    cm->maxChannelLifetime : request->requestedLifetime;
-    /* pragmatic workaround to get clients requesting lifetime of 0 working */
+        (request->requestedLifetime > cm->server->config.maxSecurityTokenLifetime) ?
+        cm->server->config.maxSecurityTokenLifetime : request->requestedLifetime;
+    /* lifetime 0 -> set the maximum possible */
     if(entry->channel.securityToken.revisedLifetime == 0)
-        entry->channel.securityToken.revisedLifetime = cm->maxChannelLifetime;
+        entry->channel.securityToken.revisedLifetime = cm->server->config.maxSecurityTokenLifetime;
 
     UA_ByteString_copy(&request->clientNonce, &entry->channel.clientNonce);
     entry->channel.serverAsymAlgSettings.securityPolicyUri = UA_STRING_ALLOC(
@@ -112,12 +111,11 @@ UA_SecureChannelManager_renew(UA_SecureChannelManager *cm, UA_Connection *conn,
         //channel->nextSecurityToken.tokenId = channel->securityToken.tokenId;
         channel->nextSecurityToken.createdAt = UA_DateTime_now();
         channel->nextSecurityToken.revisedLifetime =
-                (request->requestedLifetime > cm->maxChannelLifetime) ?
-                        cm->maxChannelLifetime : request->requestedLifetime;
-
-        /* pragmatic workaround to get clients requesting lifetime of 0 working */
+                (request->requestedLifetime > cm->server->config.maxSecurityTokenLifetime) ?
+                        cm->server->config.maxSecurityTokenLifetime : request->requestedLifetime;
+        /* lifetime 0 -> return the max lifetime */
         if(channel->nextSecurityToken.revisedLifetime == 0)
-            channel->nextSecurityToken.revisedLifetime = cm->maxChannelLifetime;
+            channel->nextSecurityToken.revisedLifetime = cm->server->config.maxSecurityTokenLifetime;
     }
 
     if(channel->clientNonce.data)

+ 1 - 7
src/server/ua_securechannel_manager.h

@@ -13,20 +13,14 @@ typedef struct channel_list_entry {
 
 typedef struct UA_SecureChannelManager {
     LIST_HEAD(channel_list, channel_list_entry) channels; // doubly-linked list of channels
-    size_t maxChannelCount;
     size_t currentChannelCount;
-    UA_UInt32 maxChannelLifetime;
-    UA_MessageSecurityMode securityMode;
-    UA_DateTime channelLifeTime;
     UA_UInt32 lastChannelId;
     UA_UInt32 lastTokenId;
     UA_Server *server;
 } UA_SecureChannelManager;
 
 UA_StatusCode
-UA_SecureChannelManager_init(UA_SecureChannelManager *cm, size_t maxChannelCount,
-                             UA_UInt32 tokenLifetime, UA_UInt32 startChannelId,
-                             UA_UInt32 startTokenId, UA_Server *server);
+UA_SecureChannelManager_init(UA_SecureChannelManager *cm, UA_Server *server);
 
 void UA_SecureChannelManager_deleteMembers(UA_SecureChannelManager *cm);
 

+ 4 - 18
src/server/ua_server.c

@@ -437,32 +437,18 @@ UA_Server * UA_Server_new(const UA_ServerConfig config) {
            EndpointDescription */
         UA_String_copy(&server->config.serverCertificate, &endpoint->serverCertificate);
         UA_ApplicationDescription_copy(&server->config.applicationDescription, &endpoint->server);
-        
+
         /* copy the discovery url only once the networlayer has been started */
         // UA_String_copy(&server->config.networkLayers[i].discoveryUrl, &endpoint->endpointUrl);
-    } 
-
-#define MAXCHANNELCOUNT 100
-#define STARTCHANNELID 1
-#define TOKENLIFETIME 600000 //this is in milliseconds //600000 seems to be the minimal allowet time for UaExpert
-#define STARTTOKENID 1
-    UA_SecureChannelManager_init(&server->secureChannelManager, MAXCHANNELCOUNT,
-                                 TOKENLIFETIME, STARTCHANNELID, STARTTOKENID, server);
+    }
 
-#define MAXSESSIONCOUNT 1000
-#define MAXSESSIONLIFETIME 3600000
-#define STARTSESSIONID 1
-    UA_SessionManager_init(&server->sessionManager, MAXSESSIONCOUNT, MAXSESSIONLIFETIME,
-                           STARTSESSIONID, server);
+    UA_SecureChannelManager_init(&server->secureChannelManager, server);
+    UA_SessionManager_init(&server->sessionManager, server);
 
     UA_Job cleanup = {.type = UA_JOBTYPE_METHODCALL,
                       .job.methodCall = {.method = UA_Server_cleanup, .data = NULL} };
     UA_Server_addRepeatedJob(server, cleanup, 10000, NULL);
 
-    /**********************/
-    /* Server Information */
-    /**********************/
-
     server->startTime = UA_DateTime_now();
 
     /**************/

+ 7 - 9
src/server/ua_session_manager.c

@@ -1,14 +1,12 @@
 #include "ua_session_manager.h"
 #include "ua_server_internal.h"
 
+#define STARTSESSIONID 1
+
 UA_StatusCode
-UA_SessionManager_init(UA_SessionManager *sm, UA_UInt32 maxSessionCount,
-                       UA_UInt32 maxSessionLifeTime, UA_UInt32 startSessionId,
-                       UA_Server *server) {
+UA_SessionManager_init(UA_SessionManager *sm, UA_Server *server) {
     LIST_INIT(&sm->sessions);
-    sm->maxSessionCount = maxSessionCount;
-    sm->lastSessionId   = startSessionId;
-    sm->maxSessionLifeTime  = maxSessionLifeTime;
+    sm->lastSessionId = STARTSESSIONID;
     sm->currentSessionCount = 0;
     sm->server = server;
     return UA_STATUSCODE_GOOD;
@@ -65,7 +63,7 @@ UA_SessionManager_getSession(UA_SessionManager *sm, const UA_NodeId *token) {
 UA_StatusCode
 UA_SessionManager_createSession(UA_SessionManager *sm, UA_SecureChannel *channel,
                                 const UA_CreateSessionRequest *request, UA_Session **session) {
-    if(sm->currentSessionCount >= sm->maxSessionCount)
+    if(sm->currentSessionCount >= sm->server->config.maxSessions)
         return UA_STATUSCODE_BADTOOMANYSESSIONS;
 
     session_list_entry *newentry = UA_malloc(sizeof(session_list_entry));
@@ -77,11 +75,11 @@ UA_SessionManager_createSession(UA_SessionManager *sm, UA_SecureChannel *channel
     newentry->session.sessionId = UA_NODEID_NUMERIC(1, sm->lastSessionId++);
     newentry->session.authenticationToken = UA_NODEID_GUID(1, UA_Guid_random());
 
-    if(request->requestedSessionTimeout <= sm->maxSessionLifeTime &&
+    if(request->requestedSessionTimeout <= sm->server->config.maxSessionTimeout &&
        request->requestedSessionTimeout > 0)
         newentry->session.timeout = request->requestedSessionTimeout;
     else
-        newentry->session.timeout = sm->maxSessionLifeTime; // todo: remove when the CTT is fixed
+        newentry->session.timeout = sm->server->config.maxSessionTimeout;
 
     UA_Session_updateLifetime(&newentry->session);
     LIST_INSERT_HEAD(&sm->sessions, newentry, pointers);

+ 1 - 4
src/server/ua_session_manager.h

@@ -13,16 +13,13 @@ typedef struct session_list_entry {
 
 typedef struct UA_SessionManager {
     LIST_HEAD(session_list, session_list_entry) sessions; // doubly-linked list of sessions
-    UA_UInt32 maxSessionCount;
     UA_UInt32 lastSessionId;
     UA_UInt32 currentSessionCount;
-    UA_UInt32 maxSessionLifeTime;    // time in [ms]
     UA_Server *server;
 } UA_SessionManager;
 
 UA_StatusCode
-UA_SessionManager_init(UA_SessionManager *sessionManager, UA_UInt32 maxSessionCount,
-                       UA_UInt32 maxSessionLifeTime, UA_UInt32 startSessionId, UA_Server *server);
+UA_SessionManager_init(UA_SessionManager *sm, UA_Server *server);
 
 void UA_SessionManager_deleteMembers(UA_SessionManager *sessionManager);