Browse Source

fix(server): Correctly initialize application description discovery urls for custom hostname

fixes #3048
Stefan Profanter 4 years ago
parent
commit
a06a792fa8
4 changed files with 21 additions and 35 deletions
  1. 2 1
      arch/network_tcp.c
  2. 0 34
      plugins/ua_config_default.c
  3. 16 0
      src/server/ua_server.c
  4. 3 0
      tests/server/check_server_userspace.c

+ 2 - 1
arch/network_tcp.c

@@ -367,7 +367,6 @@ ServerNetworkLayerTCP_start(UA_ServerNetworkLayer *nl, const UA_String *customHo
     /* Get the discovery url from the hostname */
     UA_String du = UA_STRING_NULL;
     char discoveryUrlBuffer[256];
-    char hostnameBuffer[256];
     if (customHostname->length) {
         du.length = (size_t)UA_snprintf(discoveryUrlBuffer, 255, "opc.tcp://%.*s:%d/",
                                         (int)customHostname->length,
@@ -375,12 +374,14 @@ ServerNetworkLayerTCP_start(UA_ServerNetworkLayer *nl, const UA_String *customHo
                                         layer->port);
         du.data = (UA_Byte*)discoveryUrlBuffer;
     }else{
+        char hostnameBuffer[256];
         if(UA_gethostname(hostnameBuffer, 255) == 0) {
             du.length = (size_t)UA_snprintf(discoveryUrlBuffer, 255, "opc.tcp://%s:%d/",
                                             hostnameBuffer, layer->port);
             du.data = (UA_Byte*)discoveryUrlBuffer;
         } else {
             UA_LOG_ERROR(layer->logger, UA_LOGCATEGORY_NETWORK, "Could not get the hostname");
+            return UA_STATUSCODE_BADINTERNALERROR;
         }
     }
     UA_String_copy(&du, &nl->discoveryUrl);

+ 0 - 34
plugins/ua_config_default.c

@@ -229,28 +229,6 @@ addDefaultNetworkLayers(UA_ServerConfig *conf, UA_UInt16 portNumber,
     return UA_ServerConfig_addNetworkLayerTCP(conf, portNumber, sendBufferSize, recvBufferSize);
 }
 
-static UA_StatusCode
-addDiscoveryUrl(UA_ServerConfig *config, UA_UInt16 portNumber) {
-       config->applicationDescription.discoveryUrlsSize = 1;
-    UA_String *discurl = (UA_String *) UA_Array_new(1, &UA_TYPES[UA_TYPES_STRING]);
-    char discoveryUrlBuffer[220];
-    if (config->customHostname.length) {
-        UA_snprintf(discoveryUrlBuffer, 220, "opc.tcp://%.*s:%d/",
-                                                 (int)config->customHostname.length,
-                                                 config->customHostname.data,
-                                                 portNumber);
-    } else {
-    char hostnameBuffer[200];
-       if(UA_gethostname(hostnameBuffer, 200) == 0) {
-               UA_snprintf(discoveryUrlBuffer, 220, "opc.tcp://%s:%d/", hostnameBuffer, portNumber);
-       } else {
-            UA_LOG_ERROR(&config->logger, UA_LOGCATEGORY_NETWORK, "Could not get the hostname");
-        }
-    }
-    discurl[0] = UA_String_fromChars(discoveryUrlBuffer);
-    config->applicationDescription.discoveryUrls = discurl;
-    return UA_STATUSCODE_GOOD;
-}
 
 UA_EXPORT UA_StatusCode
 UA_ServerConfig_addNetworkLayerTCP(UA_ServerConfig *conf, UA_UInt16 portNumber,
@@ -394,12 +372,6 @@ UA_ServerConfig_setMinimalCustomBuffer(UA_ServerConfig *config, UA_UInt16 portNu
         UA_ServerConfig_clean(config);
         return retval;
     }
-    
-    retval = addDiscoveryUrl(config, portNumber);
-    if (retval != UA_STATUSCODE_GOOD) {
-        UA_ServerConfig_clean(config);
-        return retval;
-    }
 
     /* Allocate the SecurityPolicies */
     retval = UA_ServerConfig_addSecurityPolicyNone(config, certificate);
@@ -605,12 +577,6 @@ UA_ServerConfig_setDefaultWithSecurityPolicies(UA_ServerConfig *conf,
         return retval;
     }
 
-    retval = addDiscoveryUrl(conf, portNumber);
-    if (retval != UA_STATUSCODE_GOOD) {
-        UA_ServerConfig_clean(conf);
-        return retval;
-    }
-
     retval = UA_ServerConfig_addAllSecurityPolicies(conf, certificate, privateKey);
     if(retval != UA_STATUSCODE_GOOD) {
         UA_ServerConfig_clean(conf);

+ 16 - 0
src/server/ua_server.c

@@ -490,6 +490,22 @@ UA_Server_run_startup(UA_Server *server) {
         result |= nl->start(nl, &server->config.customHostname);
     }
 
+    /* Update the application description to match the previously added discovery urls.
+     * We can only do this after the network layer is started since it inits the discovery url */
+    if (server->config.applicationDescription.discoveryUrlsSize != 0) {
+        UA_Array_delete(server->config.applicationDescription.discoveryUrls, server->config.applicationDescription.discoveryUrlsSize, &UA_TYPES[UA_TYPES_STRING]);
+        server->config.applicationDescription.discoveryUrlsSize = 0;
+    }
+    server->config.applicationDescription.discoveryUrls = (UA_String *) UA_Array_new(server->config.networkLayersSize, &UA_TYPES[UA_TYPES_STRING]);
+    if (!server->config.applicationDescription.discoveryUrls) {
+        return UA_STATUSCODE_BADOUTOFMEMORY;
+    }
+    server->config.applicationDescription.discoveryUrlsSize = server->config.networkLayersSize;
+    for (size_t i=0; i< server->config.applicationDescription.discoveryUrlsSize; i++) {
+        UA_ServerNetworkLayer *nl = &server->config.networkLayers[i];
+        UA_String_copy(&nl->discoveryUrl, &server->config.applicationDescription.discoveryUrls[i]);
+    }
+
     /* Spin up the worker threads */
 #ifdef UA_ENABLE_MULTITHREADING
     UA_LOG_INFO(&server->config.logger, UA_LOGCATEGORY_SERVER,

+ 3 - 0
tests/server/check_server_userspace.c

@@ -146,6 +146,7 @@ START_TEST(Server_set_customHostname) {
 
     // TODO when we have more network layers, extend this
     ck_assert_uint_ge(config->networkLayersSize, 1);
+    ck_assert_uint_eq(config->applicationDescription.discoveryUrlsSize, config->networkLayersSize);
 
 
     for (size_t i=0; i<config->networkLayersSize; i++) {
@@ -153,7 +154,9 @@ START_TEST(Server_set_customHostname) {
         char discoveryUrl[256];
         int len = snprintf(discoveryUrl, 255, "opc.tcp://%.*s:%d/", (int)customHost.length, customHost.data, port);
         ck_assert_int_eq(nl->discoveryUrl.length, len);
+        ck_assert_int_eq(config->applicationDescription.discoveryUrls[i].length, len);
         ck_assert(strncmp(discoveryUrl, (char*)nl->discoveryUrl.data, len)==0);
+        ck_assert(strncmp(discoveryUrl, (char*)config->applicationDescription.discoveryUrls[i].data, len)==0);
     }
     UA_Server_run_shutdown(server);
     UA_Server_delete(server);