Browse Source

Stack: Add support for dynamic port assigning

Fixes #2416
Stefan Profanter 5 years ago
parent
commit
4a9bcf38c0

+ 1 - 0
arch/common/ua_lwip.h

@@ -55,6 +55,7 @@
 #define UA_setsockopt lwip_setsockopt
 #define UA_freeaddrinfo lwip_freeaddrinfo
 #define UA_gethostname gethostname_lwip
+#define UA_getsockname lwip_getsockname
 #define UA_getaddrinfo lwip_getaddrinfo
 
 #if UA_IPV6

+ 1 - 0
arch/eCos/ua_architecture.h

@@ -59,6 +59,7 @@
 #define UA_setsockopt setsockopt
 #define UA_freeaddrinfo freeaddrinfo
 #define UA_gethostname gethostname_ecos
+#define UA_getsockname getsockname
 #define UA_inet_pton(af,src,dst) inet_pton(af, src, (char*) dst)
 #if UA_IPV6
 # define UA_if_nametoindex if_nametoindex

+ 31 - 22
arch/network_tcp.c

@@ -324,7 +324,16 @@ addServerSocket(ServerNetworkLayerTCP *layer, struct addrinfo *ai) {
         return;
     }
 
-    layer->serverSockets[layer->serverSocketsSize] = newsock;
+	if (layer->port == 0) {
+		/* Port was automatically chosen. Read it from the OS */
+		struct sockaddr_in returned_addr;
+		memset(&returned_addr, 0, sizeof(returned_addr));
+		socklen_t len = sizeof(returned_addr);
+		UA_getsockname(newsock, (struct sockaddr *)&returned_addr, &len);
+		layer->port = ntohs(returned_addr.sin_port);
+	}
+
+	layer->serverSockets[layer->serverSocketsSize] = newsock;
     layer->serverSocketsSize++;
 }
 
@@ -334,27 +343,6 @@ ServerNetworkLayerTCP_start(UA_ServerNetworkLayer *nl, const UA_String *customHo
 
     ServerNetworkLayerTCP *layer = (ServerNetworkLayerTCP *)nl->handle;
 
-    /* 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,
-                                     customHostname->data,
-                                     layer->port);
-        du.data = (UA_Byte*)discoveryUrlBuffer;
-    }else{
-        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");
-        }
-    }
-    UA_String_copy(&du, &nl->discoveryUrl);
-
     /* Get addrinfo of the server and create server sockets */
     char portno[6];
     UA_snprintf(portno, 6, "%d", layer->port);
@@ -376,6 +364,27 @@ ServerNetworkLayerTCP_start(UA_ServerNetworkLayer *nl, const UA_String *customHo
         addServerSocket(layer, ai);
     UA_freeaddrinfo(res);
 
+	/* 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,
+										customHostname->data,
+										layer->port);
+		du.data = (UA_Byte*)discoveryUrlBuffer;
+	}else{
+		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");
+		}
+	}
+	UA_String_copy(&du, &nl->discoveryUrl);
+
     UA_LOG_INFO(layer->logger, UA_LOGCATEGORY_NETWORK,
                 "TCP network layer listening on %.*s",
                 (int)nl->discoveryUrl.length, nl->discoveryUrl.data);

+ 1 - 0
arch/posix/ua_architecture.h

@@ -104,6 +104,7 @@
 #define UA_setsockopt setsockopt
 #define UA_freeaddrinfo freeaddrinfo
 #define UA_gethostname gethostname
+#define UA_getsockname getsockname
 #define UA_inet_pton inet_pton
 #if UA_IPV6
 # define UA_if_nametoindex if_nametoindex

+ 1 - 0
arch/vxworks/ua_architecture.h

@@ -85,6 +85,7 @@
 #define UA_setsockopt setsockopt
 #define UA_freeaddrinfo freeaddrinfo
 #define UA_gethostname gethostname
+#define UA_getsockname getsockname
 #define UA_inet_pton inet_pton
 #if UA_IPV6
 # define UA_if_nametoindex if_nametoindex

+ 1 - 0
arch/wec7/ua_architecture.h

@@ -103,6 +103,7 @@ char *strerror(int errnum);
 #define UA_setsockopt(sockfd, level, optname, optval, optlen) setsockopt(sockfd, level, optname, (const char*) (optval), optlen)
 #define UA_freeaddrinfo freeaddrinfo
 #define UA_gethostname gethostname
+#define UA_getsockname getsockname
 #define UA_inet_pton InetPton
 
 #ifdef maxStringLength //defined in mingw64

+ 1 - 0
arch/win32/ua_architecture.h

@@ -104,6 +104,7 @@
 #define UA_setsockopt(sockfd, level, optname, optval, optlen) setsockopt(sockfd, level, optname, (const char*) (optval), optlen)
 #define UA_freeaddrinfo freeaddrinfo
 #define UA_gethostname gethostname
+#define UA_getsockname getsockname
 #define UA_inet_pton InetPton
 
 #if UA_IPV6

+ 2 - 1
examples/discovery/server_multicast.c

@@ -270,7 +270,8 @@ int main(int argc, char **argv) {
 
     UA_Server *server = UA_Server_new();
     UA_ServerConfig *config = UA_Server_getConfig(server);
-    UA_ServerConfig_setMinimal(config, 16600, NULL);
+    // use port 0 to dynamically assign port
+    UA_ServerConfig_setMinimal(config, 0, NULL);
 
     // To enable mDNS discovery, set application type to discovery server.
     config->applicationDescription.applicationType = UA_APPLICATIONTYPE_DISCOVERYSERVER;

+ 2 - 1
examples/discovery/server_register.c

@@ -66,7 +66,8 @@ int main(int argc, char **argv) {
 
     UA_Server *server = UA_Server_new();
     UA_ServerConfig *config = UA_Server_getConfig(server);
-    UA_ServerConfig_setMinimal(config, 4841, NULL);
+	// use port 0 to dynamically assign port
+    UA_ServerConfig_setMinimal(config, 0, NULL);
 
     UA_String_clear(&config->applicationDescription.applicationUri);
     config->applicationDescription.applicationUri =

+ 5 - 1
include/open62541/architecture_functions.h

@@ -170,7 +170,11 @@ void UA_freeaddrinfo(struct addrinfo *res);//equivalent to posix freeaddrinfo im
 #endif
 
 #ifndef UA_gethostname
-int UA_gethostname(char *name, size_t len);//equivalent to posix gethostname implementatio
+int UA_gethostname(char *name, size_t len);//equivalent to posix gethostname implementation
+#endif
+
+#ifndef UA_getsockname
+int UA_getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen);//equivalent to posix getsockname implementation
 #endif
 
 #ifndef UA_initialize_architecture_network