Kaynağa Gözat

add custom hostname (#1382)

* add custom hostname

* Add unit test for set_customHostname
StalderT 7 yıl önce
ebeveyn
işleme
d5e71be17d

+ 3 - 0
examples/server.c

@@ -120,6 +120,9 @@ int main(int argc, char** argv) {
     UA_ServerConfig *config =
         UA_ServerConfig_new_minimal(4840, &certificate);
     UA_ByteString_deleteMembers(&certificate);
+    /* uncomment next line to add a custom hostname */
+    // UA_ServerConfig_set_customHostname(config, UA_STRING("custom"));
+    
     UA_Server *server = UA_Server_new(config);
 
     /* add a static variable node to the server */

+ 1 - 1
include/ua_plugin_network.h

@@ -151,7 +151,7 @@ struct UA_ServerNetworkLayer {
      *
      * @param nl The network layer
      * @return Returns UA_STATUSCODE_GOOD or an error code. */
-    UA_StatusCode (*start)(UA_ServerNetworkLayer *nl);
+    UA_StatusCode (*start)(UA_ServerNetworkLayer *nl, const UA_String *customHostname);
 
     /* Listen for new and closed connections and arriving packets. Calls
      * UA_Server_processBinaryMessage for the arriving packets. Closed

+ 2 - 1
include/ua_server_config.h

@@ -55,7 +55,8 @@ struct UA_ServerConfig {
     /* Networking */
     size_t networkLayersSize;
     UA_ServerNetworkLayer *networkLayers;
-
+    UA_String customHostname;
+    
     /* Available endpoints */
     size_t endpointsSize;
     UA_Endpoint *endpoints;

+ 12 - 1
plugins/ua_config_default.c

@@ -94,6 +94,14 @@ createSecurityPolicyNoneEndpoint(UA_ServerConfig *conf, UA_Endpoint *endpoint,
     return UA_STATUSCODE_GOOD;
 }
 
+void
+UA_ServerConfig_set_customHostname(UA_ServerConfig *config, const UA_String customHostname){
+    if(!config)
+        return;
+    UA_String_deleteMembers(&config->customHostname);
+    UA_String_copy(&customHostname, &config->customHostname);
+}
+
 UA_ServerConfig *
 UA_ServerConfig_new_minimal(UA_UInt16 portNumber,
                             const UA_ByteString *certificate) {
@@ -141,7 +149,8 @@ UA_ServerConfig_new_minimal(UA_UInt16 portNumber,
     /* Networking */
     /* conf->networkLayersSize = 0; */
     /* conf->networkLayers = NULL; */
-
+    /* conf->customHostname = UA_STRING_NULL; */
+ 
     /* Endpoints */
     /* conf->endpoints = {0, NULL}; */
 
@@ -260,6 +269,8 @@ UA_ServerConfig_delete(UA_ServerConfig *config) {
     UA_free(config->networkLayers);
     config->networkLayers = NULL;
     config->networkLayersSize = 0;
+    UA_String_deleteMembers(&config->customHostname);
+    config->customHostname = UA_STRING_NULL;
 
     for(size_t i = 0; i < config->endpointsSize; ++i) {
         UA_SecurityPolicy *policy = &config->endpoints[i].securityPolicy;

+ 9 - 0
plugins/ua_config_default.h

@@ -42,6 +42,15 @@ UA_ServerConfig_new_default(void) {
     return UA_ServerConfig_new_minimal(4840, NULL);
 }
 
+/* Set a custom hostname in server configuration
+ *
+ * @param config A valid server configuration
+ * @param customHostname The custom hostname used by the server */
+
+UA_EXPORT void
+UA_ServerConfig_set_customHostname(UA_ServerConfig *config,
+                                   const UA_String customHostname);
+  
 /* Frees allocated memory in the server config */
 UA_EXPORT void
 UA_ServerConfig_delete(UA_ServerConfig *config);

+ 24 - 7
plugins/ua_network_tcp.c

@@ -401,7 +401,7 @@ addServerSocket(ServerNetworkLayerTCP *layer, struct addrinfo *ai) {
 }
 
 static UA_StatusCode
-ServerNetworkLayerTCP_start(UA_ServerNetworkLayer *nl) {
+ServerNetworkLayerTCP_start(UA_ServerNetworkLayer *nl, const UA_String *customHostname) {
 #ifdef _WIN32
     WORD wVersionRequested = MAKEWORD(2, 2);
     WSADATA wsaData;
@@ -412,18 +412,35 @@ ServerNetworkLayerTCP_start(UA_ServerNetworkLayer *nl) {
 
     /* Get the discovery url from the hostname */
     UA_String du = UA_STRING_NULL;
-    char hostname[256];
-    if(gethostname(hostname, 255) == 0) {
+    if (customHostname->length) {
         char discoveryUrl[256];
 #ifndef _MSC_VER
-        du.length = (size_t)snprintf(discoveryUrl, 255, "opc.tcp://%s:%d/",
-                                     hostname, layer->port);
+        du.length = (size_t)snprintf(discoveryUrl, 255, "opc.tcp://%.*s:%d/",
+                                     (int)customHostname->length,
+                                     customHostname->data,
+                                     layer->port);
 #else
         du.length = (size_t)_snprintf_s(discoveryUrl, 255, _TRUNCATE,
-                                        "opc.tcp://%s:%d/", hostname,
-                    layer->port);
+                                        "opc.tcp://%.*s:%d/",
+                                        (int)customHostname->length,
+                                        customHostname->data,
+                                        layer->port);
 #endif
         du.data = (UA_Byte*)discoveryUrl;
+    }else{    
+        char hostname[256];
+        if(gethostname(hostname, 255) == 0) {
+            char discoveryUrl[256];
+#ifndef _MSC_VER
+            du.length = (size_t)snprintf(discoveryUrl, 255, "opc.tcp://%s:%d/",
+                                         hostname, layer->port);
+#else
+            du.length = (size_t)_snprintf_s(discoveryUrl, 255, _TRUNCATE,
+                                            "opc.tcp://%s:%d/", hostname,
+                                            layer->port);
+#endif
+            du.data = (UA_Byte*)discoveryUrl;
+        }
     }
     UA_String_copy(&du, &nl->discoveryUrl);
 

+ 1 - 1
src/server/ua_server_worker.c

@@ -282,7 +282,7 @@ UA_Server_run_startup(UA_Server *server) {
     /* Start the networklayers */
     for(size_t i = 0; i < server->config.networkLayersSize; ++i) {
         UA_ServerNetworkLayer *nl = &server->config.networkLayers[i];
-        result |= nl->start(nl);
+        result |= nl->start(nl, &server->config.customHostname);
     }
 
     /* Spin up the worker threads */

+ 29 - 0
tests/server/check_server_userspace.c

@@ -140,12 +140,41 @@ START_TEST(Server_forEachChildNodeCall) {
 } END_TEST
 
 
+START_TEST(Server_set_customHostname) {
+    UA_String customHost = UA_STRING("fancy-host");
+    UA_UInt16 port = 10042;
+
+    UA_ServerConfig *config = UA_ServerConfig_new_minimal(port, NULL);
+    UA_ServerConfig_set_customHostname(config, customHost);
+    UA_Server *server = UA_Server_new(config);
+    UA_StatusCode retval = UA_Server_run_startup(server);
+    ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
+
+    // TODO when we have more network layers, extend this
+    ck_assert_uint_ge(config->networkLayersSize, 1);
+
+
+    for (size_t i=0; i<config->networkLayersSize; i++) {
+        const UA_ServerNetworkLayer *nl = &config->networkLayers[i];
+        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(strncmp(discoveryUrl, (char*)nl->discoveryUrl.data, len)==0);
+    }
+
+    UA_Server_delete(server);
+    UA_ServerConfig_delete(config);
+}
+END_TEST
+
+
 static Suite* testSuite_ServerUserspace(void) {
     Suite *s = suite_create("ServerUserspace");
     TCase *tc_core = tcase_create("Core");
     tcase_add_test(tc_core, Server_addNamespace_ShallWork);
     tcase_add_test(tc_core, Server_addNamespace_writeService);
     tcase_add_test(tc_core, Server_forEachChildNodeCall);
+    tcase_add_test(tc_core, Server_set_customHostname);
 
     suite_add_tcase(s,tc_core);
     return s;