Quellcode durchsuchen

Discovery: Add DiscoveryManager

Julius Pfrommer vor 6 Jahren
Ursprung
Commit
767093a63d

+ 6 - 2
CMakeLists.txt

@@ -586,6 +586,11 @@ if(UA_ENABLE_ENCRYPTION)
                                        ${PROJECT_SOURCE_DIR}/plugins/ua_securitypolicy_basic256sha256.c)
 endif()
 
+if(UA_ENABLE_DISCOVERY)
+    list(INSERT internal_headers 5 ${PROJECT_SOURCE_DIR}/src/server/ua_discovery_manager.h)
+    list(APPEND lib_sources ${PROJECT_SOURCE_DIR}/src/server/ua_discovery_manager.c)
+endif()
+
 if(UA_ENABLE_PUBSUB)
     list(APPEND default_plugin_headers ${PROJECT_SOURCE_DIR}/plugins/ua_network_pubsub_udp.h)
     list(APPEND default_plugin_sources ${PROJECT_SOURCE_DIR}/plugins/ua_network_pubsub_udp.c)
@@ -620,8 +625,7 @@ if(UA_ENABLE_DISCOVERY_MULTICAST)
                          ${PROJECT_SOURCE_DIR}/deps/mdnsd/libmdnsd/sdtxt.h
                          ${PROJECT_SOURCE_DIR}/deps/mdnsd/libmdnsd/mdnsd.h
                          ${internal_headers} )
-    list(APPEND internal_headers ${PROJECT_SOURCE_DIR}/src/server/ua_mdns_internal.h)
-    set(lib_sources ${PROJECT_SOURCE_DIR}/src/server/ua_mdns.c
+    set(lib_sources ${PROJECT_SOURCE_DIR}/src/server/ua_server_discovery_mdns.c
         ${PROJECT_SOURCE_DIR}/deps/mdnsd/libmdnsd/1035.c
         ${PROJECT_SOURCE_DIR}/deps/mdnsd/libmdnsd/xht.c
         ${PROJECT_SOURCE_DIR}/deps/mdnsd/libmdnsd/sdtxt.c

+ 171 - 0
src/server/ua_discovery_manager.c

@@ -0,0 +1,171 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ *    Copyright 2014-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
+ *    Copyright 2014, 2017 (c) Florian Palm
+ *    Copyright 2015-2016 (c) Sten Grüner
+ *    Copyright 2015 (c) Chris Iatrou
+ *    Copyright 2015-2016 (c) Oleksiy Vasylyev
+ *    Copyright 2016-2017 (c) Stefan Profanter, fortiss GmbH
+ *    Copyright 2017 (c) Julian Grothoff
+ */
+
+#include "ua_server_internal.h"
+
+#ifdef UA_ENABLE_DISCOVERY
+
+#ifdef UA_ENABLE_DISCOVERY_MULTICAST
+
+/* Create multicast 224.0.0.251:5353 socket */
+static UA_SOCKET
+discovery_createMulticastSocket(void) {
+    UA_SOCKET s;
+    int flag = 1, ittl = 255;
+    struct sockaddr_in in;
+    struct ip_mreq mc;
+    char ttl = (char)255; // publish to complete net, not only subnet. See:
+                          // https://docs.oracle.com/cd/E23824_01/html/821-1602/sockets-137.html
+
+    memset(&in, 0, sizeof(in));
+    in.sin_family = AF_INET;
+    in.sin_port = htons(5353);
+    in.sin_addr.s_addr = 0;
+
+    if((s = UA_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == UA_INVALID_SOCKET)
+        return UA_INVALID_SOCKET;
+
+#ifdef SO_REUSEPORT
+    UA_setsockopt(s, SOL_SOCKET, SO_REUSEPORT, (char *)&flag, sizeof(flag));
+#endif
+    UA_setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, sizeof(flag));
+    if(UA_bind(s, (struct sockaddr *)&in, sizeof(in))) {
+        UA_close(s);
+        return UA_INVALID_SOCKET;
+    }
+
+    mc.imr_multiaddr.s_addr = inet_addr("224.0.0.251");
+    mc.imr_interface.s_addr = htonl(INADDR_ANY);
+    UA_setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mc, sizeof(mc));
+    UA_setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&ttl, sizeof(ttl));
+    UA_setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&ittl, sizeof(ittl));
+
+    UA_socket_set_nonblocking(s); //TODO: check return value
+    return s;
+}
+
+static UA_StatusCode
+initMulticastDiscoveryServer(UA_DiscoveryManager *dm, UA_Server* server) {
+    server->discoveryManager.mdnsDaemon = mdnsd_new(QCLASS_IN, 1000);
+    UA_initialize_architecture_network();
+
+    if((server->discoveryManager.mdnsSocket = discovery_createMulticastSocket()) == UA_INVALID_SOCKET) {
+        UA_LOG_SOCKET_ERRNO_WRAP(
+                UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_SERVER,
+                     "Could not create multicast socket. Error: %s", errno_str));
+        return UA_STATUSCODE_BADUNEXPECTEDERROR;
+    }
+    mdnsd_register_receive_callback(server->discoveryManager.mdnsDaemon,
+                                    mdns_record_received, server);
+    return UA_STATUSCODE_GOOD;
+}
+
+static void
+destroyMulticastDiscoveryServer(UA_DiscoveryManager *dm) {
+    mdnsd_shutdown(dm->mdnsDaemon);
+    mdnsd_free(dm->mdnsDaemon);
+    if(dm->mdnsSocket != UA_INVALID_SOCKET) {
+        UA_close(dm->mdnsSocket);
+        dm->mdnsSocket = UA_INVALID_SOCKET;
+    }
+}
+
+#endif /* UA_ENABLE_DISCOVERY_MULTICAST */
+
+void
+UA_DiscoveryManager_init(UA_DiscoveryManager *dm, UA_Server *server) {
+    LIST_INIT(&dm->registeredServers);
+    dm->registeredServersSize = 0;
+    LIST_INIT(&dm->periodicServerRegisterCallbacks);
+    dm->registerServerCallback = NULL;
+    dm->registerServerCallbackData = NULL;
+
+#ifdef UA_ENABLE_DISCOVERY_MULTICAST
+    dm->mdnsDaemon = NULL;
+    dm->mdnsSocket = UA_INVALID_SOCKET;
+    dm->mdnsMainSrvAdded = false;
+    if(server->config.applicationDescription.applicationType == UA_APPLICATIONTYPE_DISCOVERYSERVER)
+        initMulticastDiscoveryServer(dm, server);
+
+    LIST_INIT(&dm->serverOnNetwork);
+    dm->serverOnNetworkSize = 0;
+    dm->serverOnNetworkRecordIdCounter = 0;
+    dm->serverOnNetworkRecordIdLastReset = UA_DateTime_now();
+    memset(dm->serverOnNetworkHash, 0,
+           sizeof(struct serverOnNetwork_hash_entry*) * SERVER_ON_NETWORK_HASH_PRIME);
+
+    LIST_INIT(&dm->mdnsHostnameToIp);
+    memset(dm->mdnsHostnameToIpHash, 0,
+           sizeof(struct mdnsHostnameToIp_hash_entry*) * MDNS_HOSTNAME_TO_IP_HASH_PRIME);
+
+    dm->serverOnNetworkCallback = NULL;
+    dm->serverOnNetworkCallbackData = NULL;
+#endif /* UA_ENABLE_DISCOVERY_MULTICAST */
+}
+
+void
+UA_DiscoveryManager_deleteMembers(UA_DiscoveryManager *dm, UA_Server *server) {
+    registeredServer_list_entry *rs, *rs_tmp;
+    LIST_FOREACH_SAFE(rs, &dm->registeredServers, pointers, rs_tmp) {
+        LIST_REMOVE(rs, pointers);
+        UA_RegisteredServer_deleteMembers(&rs->registeredServer);
+        UA_free(rs);
+    }
+    periodicServerRegisterCallback_entry *ps, *ps_tmp;
+    LIST_FOREACH_SAFE(ps, &dm->periodicServerRegisterCallbacks, pointers, ps_tmp) {
+        LIST_REMOVE(ps, pointers);
+        UA_free(ps->callback);
+        UA_free(ps);
+    }
+
+# ifdef UA_ENABLE_DISCOVERY_MULTICAST
+    if(server->config.applicationDescription.applicationType == UA_APPLICATIONTYPE_DISCOVERYSERVER)
+        destroyMulticastDiscoveryServer(dm);
+
+    serverOnNetwork_list_entry *son, *son_tmp;
+    LIST_FOREACH_SAFE(son, &dm->serverOnNetwork, pointers, son_tmp) {
+        LIST_REMOVE(son, pointers);
+        UA_ServerOnNetwork_deleteMembers(&son->serverOnNetwork);
+        if(son->pathTmp)
+            UA_free(son->pathTmp);
+        UA_free(son);
+    }
+
+    for(size_t i = 0; i < SERVER_ON_NETWORK_HASH_PRIME; i++) {
+        serverOnNetwork_hash_entry* currHash = dm->serverOnNetworkHash[i];
+        while(currHash) {
+            serverOnNetwork_hash_entry* nextHash = currHash->next;
+            UA_free(currHash);
+            currHash = nextHash;
+        }
+    }
+
+    mdnsHostnameToIp_list_entry *mhi, *mhi_tmp;
+    LIST_FOREACH_SAFE(mhi, &dm->mdnsHostnameToIp, pointers, mhi_tmp) {
+        LIST_REMOVE(mhi, pointers);
+        UA_String_deleteMembers(&mhi->mdnsHostname);
+        UA_free(mhi);
+    }
+
+    for(size_t i = 0; i < MDNS_HOSTNAME_TO_IP_HASH_PRIME; i++) {
+        mdnsHostnameToIp_hash_entry* currHash = dm->mdnsHostnameToIpHash[i];
+        while(currHash) {
+            mdnsHostnameToIp_hash_entry* nextHash = currHash->next;
+            UA_free(currHash);
+            currHash = nextHash;
+        }
+    }
+# endif /* UA_ENABLE_DISCOVERY_MULTICAST */
+}
+
+#endif /* UA_ENABLE_DISCOVERY */

+ 185 - 0
src/server/ua_discovery_manager.h

@@ -0,0 +1,185 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ *    Copyright 2014-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
+ *    Copyright 2014, 2017 (c) Florian Palm
+ *    Copyright 2015-2016 (c) Sten Grüner
+ *    Copyright 2015 (c) Chris Iatrou
+ *    Copyright 2015-2016 (c) Oleksiy Vasylyev
+ *    Copyright 2016-2017 (c) Stefan Profanter, fortiss GmbH
+ *    Copyright 2017 (c) Julian Grothoff
+ */
+
+#ifndef UA_DISCOVERY_MANAGER_H_
+#define UA_DISCOVERY_MANAGER_H_
+
+#include "ua_server.h"
+#include "../deps/queue.h"
+
+_UA_BEGIN_DECLS
+
+#ifdef UA_ENABLE_DISCOVERY
+
+typedef struct registeredServer_list_entry {
+#ifdef UA_ENABLE_MULTITHREADING
+    UA_DelayedCallback delayedCleanup;
+#endif
+    LIST_ENTRY(registeredServer_list_entry) pointers;
+    UA_RegisteredServer registeredServer;
+    UA_DateTime lastSeen;
+} registeredServer_list_entry;
+
+typedef struct periodicServerRegisterCallback_entry {
+#ifdef UA_ENABLE_MULTITHREADING
+    UA_DelayedCallback delayedCleanup;
+#endif
+    LIST_ENTRY(periodicServerRegisterCallback_entry) pointers;
+    struct PeriodicServerRegisterCallback *callback;
+} periodicServerRegisterCallback_entry;
+
+#ifdef UA_ENABLE_DISCOVERY_MULTICAST
+
+#include "mdnsd/libmdnsd/mdnsd.h"
+
+/**
+ * TXT record:
+ * [servername]-[hostname]._opcua-tcp._tcp.local. TXT path=/ caps=NA,DA,...
+ *
+ * A/AAAA record for all ip addresses:
+ * [servername]-[hostname]._opcua-tcp._tcp.local. A [ip].
+ * [hostname]. A [ip].
+ */
+
+typedef struct serverOnNetwork_list_entry {
+#ifdef UA_ENABLE_MULTITHREADING
+    UA_DelayedCallback delayedCleanup;
+#endif
+    LIST_ENTRY(serverOnNetwork_list_entry) pointers;
+    UA_ServerOnNetwork serverOnNetwork;
+    UA_DateTime created;
+    UA_DateTime lastSeen;
+    UA_Boolean txtSet;
+    UA_Boolean srvSet;
+    char* pathTmp;
+} serverOnNetwork_list_entry;
+
+#define SERVER_ON_NETWORK_HASH_PRIME 1009
+typedef struct serverOnNetwork_hash_entry {
+    serverOnNetwork_list_entry* entry;
+    struct serverOnNetwork_hash_entry* next;
+} serverOnNetwork_hash_entry;
+
+typedef struct mdnsHostnameToIp_list_entry {
+    LIST_ENTRY(mdnsHostnameToIp_list_entry) pointers;
+    UA_String mdnsHostname;
+    struct in_addr addr;
+} mdnsHostnameToIp_list_entry;
+
+#define MDNS_HOSTNAME_TO_IP_HASH_PRIME 1009
+typedef struct mdnsHostnameToIp_hash_entry {
+    mdnsHostnameToIp_list_entry* entry;
+    struct mdnsHostnameToIp_hash_entry* next;
+} mdnsHostnameToIp_hash_entry;
+
+#endif
+
+typedef struct {
+    LIST_HEAD(, periodicServerRegisterCallback_entry) periodicServerRegisterCallbacks;
+    LIST_HEAD(, registeredServer_list_entry) registeredServers;
+    size_t registeredServersSize;
+    UA_Server_registerServerCallback registerServerCallback;
+    void* registerServerCallbackData;
+
+# ifdef UA_ENABLE_DISCOVERY_MULTICAST
+    mdns_daemon_t *mdnsDaemon;
+    UA_SOCKET mdnsSocket;
+    UA_Boolean mdnsMainSrvAdded;
+
+    LIST_HEAD(, serverOnNetwork_list_entry) serverOnNetwork;
+    size_t serverOnNetworkSize;
+
+    UA_UInt32 serverOnNetworkRecordIdCounter;
+    UA_DateTime serverOnNetworkRecordIdLastReset;
+
+    /* hash mapping domain name to serverOnNetwork list entry */
+    struct serverOnNetwork_hash_entry* serverOnNetworkHash[SERVER_ON_NETWORK_HASH_PRIME];
+
+    UA_Server_serverOnNetworkCallback serverOnNetworkCallback;
+    void* serverOnNetworkCallbackData;
+
+    LIST_HEAD(, mdnsHostnameToIp_list_entry) mdnsHostnameToIp;
+    /* hash mapping hostname to ip */
+    struct mdnsHostnameToIp_hash_entry* mdnsHostnameToIpHash[MDNS_HOSTNAME_TO_IP_HASH_PRIME];
+#  ifdef UA_ENABLE_MULTITHREADING
+    pthread_t mdnsThread;
+    UA_Boolean mdnsRunning;
+#  endif
+# endif /* UA_ENABLE_DISCOVERY_MULTICAST */
+} UA_DiscoveryManager;
+
+void UA_DiscoveryManager_init(UA_DiscoveryManager *dm, UA_Server *server);
+void UA_DiscoveryManager_deleteMembers(UA_DiscoveryManager *dm, UA_Server *server);
+
+/* Checks if a registration timed out and removes that registration.
+ * Should be called periodically in main loop */
+void UA_Discovery_cleanupTimedOut(UA_Server *server, UA_DateTime nowMonotonic);
+
+#ifdef UA_ENABLE_DISCOVERY_MULTICAST
+
+void
+UA_Server_updateMdnsForDiscoveryUrl(UA_Server *server, const UA_String *serverName,
+                                    const UA_MdnsDiscoveryConfiguration *mdnsConfig,
+                                    const UA_String *discoveryUrl,
+                                    UA_Boolean isOnline, UA_Boolean updateTxt);
+
+void mdns_record_received(const struct resource *r, void *data);
+
+void mdns_create_txt(UA_Server *server, const char *fullServiceDomain,
+                     const char *path, const UA_String *capabilites,
+                     const size_t *capabilitiesSize,
+                     void (*conflict)(char *host, int type, void *arg));
+
+void mdns_set_address_record(UA_Server *server,
+                             const char *fullServiceDomain,
+                             const char *localDomain);
+
+mdns_record_t *
+mdns_find_record(mdns_daemon_t *mdnsDaemon, unsigned short type,
+                 const char *host, const char *rdname);
+
+void startMulticastDiscoveryServer(UA_Server *server);
+
+void stopMulticastDiscoveryServer(UA_Server *server);
+
+UA_StatusCode
+iterateMulticastDiscoveryServer(UA_Server* server, UA_DateTime *nextRepeat,
+                                UA_Boolean processIn);
+
+typedef enum {
+    UA_DISCOVERY_TCP,     /* OPC UA TCP mapping */
+    UA_DISCOVERY_TLS     /* OPC UA HTTPS mapping */
+} UA_DiscoveryProtocol;
+
+/* Send a multicast probe to find any other OPC UA server on the network through mDNS. */
+UA_StatusCode
+UA_Discovery_multicastQuery(UA_Server* server);
+
+UA_StatusCode
+UA_Discovery_addRecord(UA_Server *server, const UA_String *servername,
+                       const UA_String *hostname, UA_UInt16 port,
+                       const UA_String *path, const UA_DiscoveryProtocol protocol,
+                       UA_Boolean createTxt, const UA_String* capabilites,
+                       size_t *capabilitiesSize);
+UA_StatusCode
+UA_Discovery_removeRecord(UA_Server *server, const UA_String *servername,
+                          const UA_String *hostname, UA_UInt16 port,
+                          UA_Boolean removeTxt);
+
+#endif /* UA_ENABLE_DISCOVERY_MULTICAST */
+
+#endif /* UA_ENABLE_DISCOVERY */
+
+_UA_END_DECLS
+
+#endif /* UA_DISCOVERY_MANAGER_H_ */

+ 0 - 52
src/server/ua_mdns_internal.h

@@ -1,52 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. 
- *
- *    Copyright 2017 (c) Stefan Profanter, fortiss GmbH
- */
-
-#ifndef UA_MDNS_INTERNAL_H_
-#define UA_MDNS_INTERNAL_H_
-
-#include "ua_config.h"
-
-_UA_BEGIN_DECLS
-
-#ifdef UA_ENABLE_DISCOVERY_MULTICAST
-
-#include "mdnsd/libmdnsd/mdnsd.h"
-
-/**
- * TXT record:
- * [servername]-[hostname]._opcua-tcp._tcp.local. TXT path=/ caps=NA,DA,...
- *
- * A/AAAA record for all ip addresses:
- * [servername]-[hostname]._opcua-tcp._tcp.local. A [ip].
- * [hostname]. A [ip].
- */
-
-void mdns_record_received(const struct resource *r, void *data);
-
-void mdns_create_txt(UA_Server *server, const char *fullServiceDomain,
-                     const char *path, const UA_String *capabilites,
-                     const size_t *capabilitiesSize,
-                     void (*conflict)(char *host, int type, void *arg));
-
-void mdns_set_address_record(UA_Server *server, const char *fullServiceDomain,
-                             const char *localDomain);
-
-mdns_record_t *
-mdns_find_record(mdns_daemon_t *mdnsDaemon, unsigned short type,
-                 const char *host, const char *rdname);
-
-void
-UA_Discovery_update_MdnsForDiscoveryUrl(UA_Server *server, const UA_String *serverName,
-                                        const UA_MdnsDiscoveryConfiguration *mdnsConfig,
-                                        const UA_String *discoveryUrl,
-                                        UA_Boolean isOnline, UA_Boolean updateTxt);
-
-#endif /* UA_ENABLE_DISCOVERY_MULTICAST */
-
-_UA_END_DECLS
-
-#endif /* UA_MDNS_INTERNAL_H_ */

+ 4 - 82
src/server/ua_server.c

@@ -156,58 +156,7 @@ void UA_Server_delete(UA_Server *server) {
 #endif
 
 #ifdef UA_ENABLE_DISCOVERY
-    registeredServer_list_entry *rs, *rs_tmp;
-    LIST_FOREACH_SAFE(rs, &server->registeredServers, pointers, rs_tmp) {
-        LIST_REMOVE(rs, pointers);
-        UA_RegisteredServer_deleteMembers(&rs->registeredServer);
-        UA_free(rs);
-    }
-    periodicServerRegisterCallback_entry *ps, *ps_tmp;
-    LIST_FOREACH_SAFE(ps, &server->periodicServerRegisterCallbacks, pointers, ps_tmp) {
-        LIST_REMOVE(ps, pointers);
-        UA_free(ps->callback);
-        UA_free(ps);
-    }
-
-# ifdef UA_ENABLE_DISCOVERY_MULTICAST
-    if(server->config.applicationDescription.applicationType == UA_APPLICATIONTYPE_DISCOVERYSERVER)
-        destroyMulticastDiscoveryServer(server);
-
-    serverOnNetwork_list_entry *son, *son_tmp;
-    LIST_FOREACH_SAFE(son, &server->serverOnNetwork, pointers, son_tmp) {
-        LIST_REMOVE(son, pointers);
-        UA_ServerOnNetwork_deleteMembers(&son->serverOnNetwork);
-        if(son->pathTmp)
-            UA_free(son->pathTmp);
-        UA_free(son);
-    }
-
-    for(size_t i = 0; i < SERVER_ON_NETWORK_HASH_PRIME; i++) {
-        serverOnNetwork_hash_entry* currHash = server->serverOnNetworkHash[i];
-        while(currHash) {
-            serverOnNetwork_hash_entry* nextHash = currHash->next;
-            UA_free(currHash);
-            currHash = nextHash;
-        }
-    }
-
-    mdnsHostnameToIp_list_entry *mhi, *mhi_tmp;
-    LIST_FOREACH_SAFE(mhi, &server->mdnsHostnameToIp, pointers, mhi_tmp) {
-        LIST_REMOVE(mhi, pointers);
-        UA_String_deleteMembers(&mhi->mdnsHostname);
-        UA_free(mhi);
-    }
-
-    for(size_t i = 0; i < MDNS_HOSTNAME_TO_IP_HASH_PRIME; i++) {
-        mdnsHostnameToIp_hash_entry* currHash = server->mdnsHostnameToIpHash[i];
-        while(currHash) {
-            mdnsHostnameToIp_hash_entry* nextHash = currHash->next;
-            UA_free(currHash);
-            currHash = nextHash;
-        }
-    }
-# endif
-
+    UA_DiscoveryManager_deleteMembers(&server->discoveryManager, server);
 #endif
 
     /* Clean up the Admin Session */
@@ -286,37 +235,9 @@ UA_Server_new(const UA_ServerConfig *config) {
     UA_Server_addRepeatedCallback(server, (UA_ServerCallback)UA_Server_cleanup, NULL,
                                   10000, NULL);
 
-    /* Initialized discovery database */
+    /* Initialized discovery */
 #ifdef UA_ENABLE_DISCOVERY
-    LIST_INIT(&server->registeredServers);
-    server->registeredServersSize = 0;
-    LIST_INIT(&server->periodicServerRegisterCallbacks);
-    server->registerServerCallback = NULL;
-    server->registerServerCallbackData = NULL;
-#endif
-
-    /* Initialize multicast discovery */
-#if defined(UA_ENABLE_DISCOVERY) && defined(UA_ENABLE_DISCOVERY_MULTICAST)
-    server->mdnsDaemon = NULL;
-    server->mdnsSocket = UA_INVALID_SOCKET;
-    server->mdnsMainSrvAdded = false;
-    if(server->config.applicationDescription.applicationType == UA_APPLICATIONTYPE_DISCOVERYSERVER)
-        initMulticastDiscoveryServer(server);
-
-    LIST_INIT(&server->serverOnNetwork);
-    server->serverOnNetworkSize = 0;
-    server->serverOnNetworkRecordIdCounter = 0;
-    server->serverOnNetworkRecordIdLastReset = UA_DateTime_now();
-    memset(server->serverOnNetworkHash, 0,
-           sizeof(struct serverOnNetwork_hash_entry*) * SERVER_ON_NETWORK_HASH_PRIME);
-
-
-    LIST_INIT(&server->mdnsHostnameToIp);
-    memset(server->mdnsHostnameToIpHash, 0,
-           sizeof(struct mdnsHostnameToIp_hash_entry*) * MDNS_HOSTNAME_TO_IP_HASH_PRIME);
-
-    server->serverOnNetworkCallback = NULL;
-    server->serverOnNetworkCallbackData = NULL;
+    UA_DiscoveryManager_init(&server->discoveryManager, server);
 #endif
 
     /* Initialize namespace 0*/
@@ -329,6 +250,7 @@ UA_Server_new(const UA_ServerConfig *config) {
         UA_Server_delete(server);
         return NULL;
     }
+
     /* Build PubSub information model */
 #ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
     UA_Server_initPubSubNS0(server);

+ 60 - 54
src/server/ua_mdns.c

@@ -7,7 +7,6 @@
  */
 
 #include "ua_server_internal.h"
-#include "ua_mdns_internal.h"
 #include "ua_util.h"
 
 #ifdef UA_ENABLE_DISCOVERY_MULTICAST
@@ -51,7 +50,8 @@ static char *ua_strdup(const char *s) {
  * This function uses the ELF hashing algorithm as reprinted in
  * Andrew Binstock, "Hashing Rehashed," Dr. Dobb's Journal, April 1996.
  */
-static int mdns_hash_record(const char *s) {
+static int
+mdns_hash_record(const char *s) {
     /* ELF hash uses unsigned chars and unsigned arithmetic for portability */
     const unsigned char *name = (const unsigned char *) s;
     unsigned long h = 0;
@@ -66,10 +66,10 @@ static int mdns_hash_record(const char *s) {
 }
 
 static struct serverOnNetwork_list_entry *
-mdns_record_add_or_get(UA_Server *server, const char *record, const char *serverName,
+mdns_record_add_or_get(UA_DiscoveryManager *dm, const char *record, const char *serverName,
                        size_t serverNameLen, UA_Boolean createNew) {
     int hashIdx = mdns_hash_record(record) % SERVER_ON_NETWORK_HASH_PRIME;
-    struct serverOnNetwork_hash_entry *hash_entry = server->serverOnNetworkHash[hashIdx];
+    struct serverOnNetwork_hash_entry *hash_entry = dm->serverOnNetworkHash[hashIdx];
 
     while(hash_entry) {
         size_t maxLen;
@@ -96,33 +96,33 @@ mdns_record_add_or_get(UA_Server *server, const char *record, const char *server
     listEntry->txtSet = false;
     listEntry->srvSet = false;
     UA_ServerOnNetwork_init(&listEntry->serverOnNetwork);
-    listEntry->serverOnNetwork.recordId = server->serverOnNetworkRecordIdCounter;
+    listEntry->serverOnNetwork.recordId = dm->serverOnNetworkRecordIdCounter;
     listEntry->serverOnNetwork.serverName.length = serverNameLen;
     /* todo: malloc may fail: return a statuscode */
     listEntry->serverOnNetwork.serverName.data = (UA_Byte*)UA_malloc(serverNameLen);
     memcpy(listEntry->serverOnNetwork.serverName.data, serverName, serverNameLen);
-    UA_atomic_addUInt32(&server->serverOnNetworkRecordIdCounter, 1);
-    if(server->serverOnNetworkRecordIdCounter == 0)
-        server->serverOnNetworkRecordIdLastReset = UA_DateTime_now();
+    UA_atomic_addUInt32(&dm->serverOnNetworkRecordIdCounter, 1);
+    if(dm->serverOnNetworkRecordIdCounter == 0)
+        dm->serverOnNetworkRecordIdLastReset = UA_DateTime_now();
 
     /* add to hash */
     /* todo: malloc may fail: return a statuscode */
     struct serverOnNetwork_hash_entry *newHashEntry = (struct serverOnNetwork_hash_entry*)
         UA_malloc(sizeof(struct serverOnNetwork_hash_entry));
-    newHashEntry->next = server->serverOnNetworkHash[hashIdx];
-    server->serverOnNetworkHash[hashIdx] = newHashEntry;
+    newHashEntry->next = dm->serverOnNetworkHash[hashIdx];
+    dm->serverOnNetworkHash[hashIdx] = newHashEntry;
     newHashEntry->entry = listEntry;
 
-    LIST_INSERT_HEAD(&server->serverOnNetwork, listEntry, pointers);
+    LIST_INSERT_HEAD(&dm->serverOnNetwork, listEntry, pointers);
 
     return listEntry;
 }
 
 static struct mdnsHostnameToIp_list_entry *
-mdns_hostname_add_or_get(UA_Server *server, const char *hostname,
+mdns_hostname_add_or_get(UA_DiscoveryManager *dm, const char *hostname,
                          struct in_addr addr, UA_Boolean createNew) {
     int hashIdx = mdns_hash_record(hostname) % MDNS_HOSTNAME_TO_IP_HASH_PRIME;
-    struct mdnsHostnameToIp_hash_entry *hash_entry = server->mdnsHostnameToIpHash[hashIdx];
+    struct mdnsHostnameToIp_hash_entry *hash_entry = dm->mdnsHostnameToIpHash[hashIdx];
 
     size_t hostnameLen = strlen(hostname);
     if (hostnameLen == 0)
@@ -164,10 +164,10 @@ mdns_hostname_add_or_get(UA_Server *server, const char *hostname,
         UA_free(listEntry);
         return NULL;
     }
-    newHashEntry->next = server->mdnsHostnameToIpHash[hashIdx];
-    server->mdnsHostnameToIpHash[hashIdx] = newHashEntry;
+    newHashEntry->next = dm->mdnsHostnameToIpHash[hashIdx];
+    dm->mdnsHostnameToIpHash[hashIdx] = newHashEntry;
     newHashEntry->entry = listEntry;
-    LIST_INSERT_HEAD(&server->mdnsHostnameToIp, listEntry, pointers);
+    LIST_INSERT_HEAD(&dm->mdnsHostnameToIp, listEntry, pointers);
     return listEntry;
 }
 
@@ -336,8 +336,6 @@ mdns_is_self_announce(UA_Server *server, struct serverOnNetwork_list_entry *entr
             break;
     }
 
-
-
 #ifdef _WIN32
     /* Cleanup */
     UA_free(adapter_addresses);
@@ -346,21 +344,23 @@ mdns_is_self_announce(UA_Server *server, struct serverOnNetwork_list_entry *entr
     /* Clean up */
     freeifaddrs(ifaddr);
 #endif
-    return isSelf;
 
+    return isSelf;
 }
 
 static void
 mdns_record_remove(UA_Server *server, const char *record,
                    struct serverOnNetwork_list_entry *entry) {
+    UA_DiscoveryManager *dm = &server->discoveryManager;
+    
     /* remove from hash */
     int hashIdx = mdns_hash_record(record) % SERVER_ON_NETWORK_HASH_PRIME;
-    struct serverOnNetwork_hash_entry *hash_entry = server->serverOnNetworkHash[hashIdx];
+    struct serverOnNetwork_hash_entry *hash_entry = dm->serverOnNetworkHash[hashIdx];
     struct serverOnNetwork_hash_entry *prevEntry = hash_entry;
     while(hash_entry) {
         if(hash_entry->entry == entry) {
-            if(server->serverOnNetworkHash[hashIdx] == hash_entry)
-                server->serverOnNetworkHash[hashIdx] = hash_entry->next;
+            if(dm->serverOnNetworkHash[hashIdx] == hash_entry)
+                dm->serverOnNetworkHash[hashIdx] = hash_entry->next;
             else if(prevEntry)
                 prevEntry->next = hash_entry->next;
             break;
@@ -370,10 +370,9 @@ mdns_record_remove(UA_Server *server, const char *record,
     }
     UA_free(hash_entry);
 
-    if(server->serverOnNetworkCallback &&
-       !mdns_is_self_announce(server, entry))
-        server->serverOnNetworkCallback(&entry->serverOnNetwork, false,
-                                        entry->txtSet, server->serverOnNetworkCallbackData);
+    if(dm->serverOnNetworkCallback && !mdns_is_self_announce(server, entry))
+        dm->serverOnNetworkCallback(&entry->serverOnNetwork, false,
+                                    entry->txtSet, dm->serverOnNetworkCallbackData);
 
     /* remove from list */
     LIST_REMOVE(entry, pointers);
@@ -382,10 +381,10 @@ mdns_record_remove(UA_Server *server, const char *record,
         UA_free(entry->pathTmp);
 
 #ifndef UA_ENABLE_MULTITHREADING
-    server->serverOnNetworkSize--;
+    dm->serverOnNetworkSize--;
     UA_free(entry);
 #else
-    UA_atomic_subSize(&server->serverOnNetworkSize, 1);
+    UA_atomic_subSize(&dm->serverOnNetworkSize, 1);
     entry->delayedCleanup.callback = NULL; /* Only free the structure */
     UA_WorkQueue_enqueueDelayed(&server->workQueue, &entry->delayedCleanup);
 #endif
@@ -471,7 +470,8 @@ setSrv(UA_Server *server, const struct resource *r,
     struct in_addr tmp = {0};
 
     mdnsHostnameToIp_list_entry *hostnameEntry =
-        mdns_hostname_add_or_get(server, r->known.srv.name, tmp, false);
+        mdns_hostname_add_or_get(&server->discoveryManager,
+                                 r->known.srv.name, tmp, false);
 
     char *newUrl;
     if (hostnameEntry) {
@@ -530,17 +530,18 @@ setSrv(UA_Server *server, const struct resource *r,
 /* [servername]-[hostname]._opcua-tcp._tcp.local. 86400 IN SRV 0 5 port [hostname]. */
 static void
 setAddress(UA_Server *server, const struct resource *r) {
-    if (r->type != QTYPE_A)
+    if(r->type != QTYPE_A)
         return;
 
-    if (!mdns_hostname_add_or_get(server, r->name, r->known.a.ip, true)) {
+    if(!mdns_hostname_add_or_get(&server->discoveryManager,
+                                 r->name, r->known.a.ip, true)) {
         /* should we log an error? */
     }
 }
 
-
 /* This will be called by the mDNS library on every record which is received */
-void mdns_record_received(const struct resource *r, void *data) {
+void
+mdns_record_received(const struct resource *r, void *data) {
     UA_Server *server = (UA_Server *) data;
     /* we only need SRV and TXT records */
     /* TODO: remove magic number */
@@ -566,7 +567,8 @@ void mdns_record_received(const struct resource *r, void *data) {
 
     /* Get entry */
     struct serverOnNetwork_list_entry *entry =
-            mdns_record_add_or_get(server, r->name, r->name, servernameLen, r->ttl > 0);
+            mdns_record_add_or_get(&server->discoveryManager, r->name, r->name,
+                                   servernameLen, r->ttl > 0);
     if(!entry)
         return;
 
@@ -594,17 +596,19 @@ void mdns_record_received(const struct resource *r, void *data) {
         setSrv(server, r, entry);
 
     /* Call callback to announce a new server */
-    if(entry->srvSet && server->serverOnNetworkCallback &&
+    if(entry->srvSet && server->discoveryManager.serverOnNetworkCallback &&
        !mdns_is_self_announce(server, entry))
-        server->serverOnNetworkCallback(&entry->serverOnNetwork, true,
-                                        entry->txtSet, server->serverOnNetworkCallbackData);
+        server->discoveryManager.
+            serverOnNetworkCallback(&entry->serverOnNetwork, true, entry->txtSet,
+                                    server->discoveryManager.serverOnNetworkCallbackData);
 }
 
-void mdns_create_txt(UA_Server *server, const char *fullServiceDomain, const char *path,
-                     const UA_String *capabilites, const size_t *capabilitiesSize,
-                     void (*conflict)(char *host, int type, void *arg)) {
-    mdns_record_t *r = mdnsd_unique(server->mdnsDaemon, fullServiceDomain, QTYPE_TXT,
-                                    600, conflict, server);
+void
+mdns_create_txt(UA_Server *server, const char *fullServiceDomain, const char *path,
+                const UA_String *capabilites, const size_t *capabilitiesSize,
+                void (*conflict)(char *host, int type, void *arg)) {
+    mdns_record_t *r = mdnsd_unique(server->discoveryManager.mdnsDaemon, fullServiceDomain,
+                                    QTYPE_TXT, 600, conflict, server);
     xht_t *h = xht_new(11);
     char *allocPath = NULL;
     if(!path || strlen(path) == 0) {
@@ -656,7 +660,8 @@ void mdns_create_txt(UA_Server *server, const char *fullServiceDomain, const cha
     if(caps)
         UA_free(caps);
     xht_free(h);
-    mdnsd_set_raw(server->mdnsDaemon, r, (char *) packet, (unsigned short) txtRecordLength);
+    mdnsd_set_raw(server->discoveryManager.mdnsDaemon, r, (char *) packet,
+                  (unsigned short) txtRecordLength);
     UA_free(packet);
 }
 
@@ -679,15 +684,15 @@ mdns_find_record(mdns_daemon_t *mdnsDaemon, unsigned short type,
 
 /* set record in the given interface */
 static void
-mdns_set_address_record_if(UA_Server *server, const char *fullServiceDomain,
+mdns_set_address_record_if(UA_DiscoveryManager *dm, const char *fullServiceDomain,
                            const char *localDomain, char *addr, UA_UInt16 addr_len) {
     /* [servername]-[hostname]._opcua-tcp._tcp.local. A [ip]. */
-    mdns_record_t *r = mdnsd_shared(server->mdnsDaemon, fullServiceDomain, QTYPE_A, 600);
-    mdnsd_set_raw(server->mdnsDaemon, r, addr, addr_len);
+    mdns_record_t *r = mdnsd_shared(dm->mdnsDaemon, fullServiceDomain, QTYPE_A, 600);
+    mdnsd_set_raw(dm->mdnsDaemon, r, addr, addr_len);
 
     /* [hostname]. A [ip]. */
-    r = mdnsd_shared(server->mdnsDaemon, localDomain, QTYPE_A, 600);
-    mdnsd_set_raw(server->mdnsDaemon, r, addr, addr_len);
+    r = mdnsd_shared(dm->mdnsDaemon, localDomain, QTYPE_A, 600);
+    mdnsd_set_raw(dm->mdnsDaemon, r, addr, addr_len);
 }
 
 /* Loop over network interfaces and run set_address_record on each */
@@ -712,8 +717,8 @@ void mdns_set_address_record(UA_Server *server, const char *fullServiceDomain,
             int family = address->Address.lpSockaddr->sa_family;
             if(AF_INET == family) {
                 SOCKADDR_IN* ipv4 = (SOCKADDR_IN*)(address->Address.lpSockaddr); /* IPv4 */
-                mdns_set_address_record_if(server, fullServiceDomain, localDomain,
-                                           (char *)&ipv4->sin_addr, 4);
+                mdns_set_address_record_if(&server->discoveryManager, fullServiceDomain,
+                                           localDomain, (char *)&ipv4->sin_addr, 4);
             } else if(AF_INET6 == family) {
                 /* IPv6 */
 #if 0
@@ -750,8 +755,9 @@ void mdns_set_address_record(UA_Server *server, const char *fullServiceDomain,
 
 #else /* _WIN32 */
 
-void mdns_set_address_record(UA_Server *server, const char *fullServiceDomain,
-                             const char *localDomain) {
+void
+mdns_set_address_record(UA_Server *server, const char *fullServiceDomain,
+                        const char *localDomain) {
     struct ifaddrs *ifaddr, *ifa;
     if(getifaddrs(&ifaddr) == -1) {
         UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_SERVER,
@@ -773,8 +779,8 @@ void mdns_set_address_record(UA_Server *server, const char *fullServiceDomain,
         /* IPv4 */
         if(ifa->ifa_addr->sa_family == AF_INET) {
             struct sockaddr_in* sa = (struct sockaddr_in*) ifa->ifa_addr;
-            mdns_set_address_record_if(server, fullServiceDomain, localDomain,
-                                       (char*)&sa->sin_addr.s_addr, 4);
+            mdns_set_address_record_if(&server->discoveryManager, fullServiceDomain,
+                                       localDomain, (char*)&sa->sin_addr.s_addr, 4);
         }
 
         /* IPv6 not implemented yet */

+ 14 - 137
src/server/ua_server_internal.h

@@ -29,6 +29,10 @@ _UA_BEGIN_DECLS
 #include "ua_pubsub_manager.h"
 #endif
 
+#ifdef UA_ENABLE_DISCOVERY
+#include "ua_discovery_manager.h"
+#endif
+
 #ifdef UA_ENABLE_SUBSCRIPTIONS
 #include "ua_subscription.h"
 
@@ -43,65 +47,9 @@ typedef struct {
 
 #endif
 
-#ifdef UA_ENABLE_DISCOVERY
-
-typedef struct registeredServer_list_entry {
-#ifdef UA_ENABLE_MULTITHREADING
-    UA_DelayedCallback delayedCleanup;
-#endif
-    LIST_ENTRY(registeredServer_list_entry) pointers;
-    UA_RegisteredServer registeredServer;
-    UA_DateTime lastSeen;
-} registeredServer_list_entry;
-
-typedef struct periodicServerRegisterCallback_entry {
-#ifdef UA_ENABLE_MULTITHREADING
-    UA_DelayedCallback delayedCleanup;
-#endif
-    LIST_ENTRY(periodicServerRegisterCallback_entry) pointers;
-    struct PeriodicServerRegisterCallback *callback;
-} periodicServerRegisterCallback_entry;
-
-#ifdef UA_ENABLE_DISCOVERY_MULTICAST
-
-#include "mdnsd/libmdnsd/mdnsd.h"
-
-typedef struct serverOnNetwork_list_entry {
-#ifdef UA_ENABLE_MULTITHREADING
-    UA_DelayedCallback delayedCleanup;
-#endif
-    LIST_ENTRY(serverOnNetwork_list_entry) pointers;
-    UA_ServerOnNetwork serverOnNetwork;
-    UA_DateTime created;
-    UA_DateTime lastSeen;
-    UA_Boolean txtSet;
-    UA_Boolean srvSet;
-    char* pathTmp;
-} serverOnNetwork_list_entry;
-
-#define SERVER_ON_NETWORK_HASH_PRIME 1009
-typedef struct serverOnNetwork_hash_entry {
-    serverOnNetwork_list_entry* entry;
-    struct serverOnNetwork_hash_entry* next;
-} serverOnNetwork_hash_entry;
-
-typedef struct mdnsHostnameToIp_list_entry {
-    LIST_ENTRY(mdnsHostnameToIp_list_entry) pointers;
-    UA_String mdnsHostname;
-    struct in_addr addr;
-} mdnsHostnameToIp_list_entry;
-
-#define MDNS_HOSTNAME_TO_IP_HASH_PRIME 1009
-typedef struct mdnsHostnameToIp_hash_entry {
-    mdnsHostnameToIp_list_entry* entry;
-    struct mdnsHostnameToIp_hash_entry* next;
-} mdnsHostnameToIp_hash_entry;
-
-#endif /* UA_ENABLE_DISCOVERY_MULTICAST */
-#endif /* UA_ENABLE_DISCOVERY */
-
 struct UA_Server {
-    /* Meta */
+    /* Config */
+    UA_ServerConfig config;
     UA_DateTime startTime;
 
     /* Security */
@@ -111,40 +59,6 @@ struct UA_Server {
                               * maintenance) uses this Session with all possible
                               * access rights (Session Id: 1) */
 
-#ifdef UA_ENABLE_DISCOVERY
-    /* Discovery */
-    LIST_HEAD(registeredServer_list, registeredServer_list_entry) registeredServers; // doubly-linked list of registered servers
-    size_t registeredServersSize;
-    LIST_HEAD(periodicServerRegisterCallback_list, periodicServerRegisterCallback_entry) periodicServerRegisterCallbacks; // doubly-linked list of current register callbacks
-    UA_Server_registerServerCallback registerServerCallback;
-    void* registerServerCallbackData;
-# ifdef UA_ENABLE_DISCOVERY_MULTICAST
-    mdns_daemon_t *mdnsDaemon;
-    UA_SOCKET mdnsSocket;
-    UA_Boolean mdnsMainSrvAdded;
-#  ifdef UA_ENABLE_MULTITHREADING
-    pthread_t mdnsThread;
-    UA_Boolean mdnsRunning;
-#  endif
-
-    LIST_HEAD(serverOnNetwork_list, serverOnNetwork_list_entry) serverOnNetwork; // doubly-linked list of servers on the network (from mDNS)
-    size_t serverOnNetworkSize;
-    UA_UInt32 serverOnNetworkRecordIdCounter;
-    UA_DateTime serverOnNetworkRecordIdLastReset;
-    // hash mapping domain name to serverOnNetwork list entry
-    struct serverOnNetwork_hash_entry* serverOnNetworkHash[SERVER_ON_NETWORK_HASH_PRIME];
-
-    UA_Server_serverOnNetworkCallback serverOnNetworkCallback;
-    void* serverOnNetworkCallbackData;
-
-
-    LIST_HEAD(mdnsHostnameToIp_list, mdnsHostnameToIp_list_entry) mdnsHostnameToIp; // doubly-linked list of hostname to IP mapping (from mDNS)
-    // hash mapping hostname to ip
-    struct mdnsHostnameToIp_hash_entry* mdnsHostnameToIpHash[MDNS_HOSTNAME_TO_IP_HASH_PRIME];
-
-# endif
-#endif
-
     /* Namespaces */
     size_t namespacesSize;
     UA_String *namespaces;
@@ -152,25 +66,29 @@ struct UA_Server {
     /* Callbacks with a repetition interval */
     UA_Timer timer;
 
+    /* WorkQueue and worker threads */
     UA_WorkQueue workQueue;
 
     /* For bootstrapping, omit some consistency checks, creating a reference to
      * the parent and member instantiation */
     UA_Boolean bootstrapNS0;
 
+    /* Discovery */
+#ifdef UA_ENABLE_DISCOVERY
+    UA_DiscoveryManager discoveryManager;
+#endif
+
+    /* Local MonitoredItems */
 #ifdef UA_ENABLE_SUBSCRIPTIONS
     /* To be cast to UA_LocalMonitoredItem to get the callback and context */
     LIST_HEAD(LocalMonitoredItems, UA_MonitoredItem) localMonitoredItems;
     UA_UInt32 lastLocalMonitoredItemId;
 #endif
 
+    /* Publish/Subscribe */
 #ifdef UA_ENABLE_PUBSUB
-    /* Publish/Subscribe toplevel container */
     UA_PubSubManager pubSubManager;
 #endif
-
-    /* Config */
-    UA_ServerConfig config;
 };
 
 /*****************/
@@ -340,47 +258,6 @@ UA_Server_readWithSession(UA_Server *server, UA_Session *session,
                           const UA_ReadValueId *item,
                           UA_TimestampsToReturn timestampsToReturn);
 
-/* Checks if a registration timed out and removes that registration.
- * Should be called periodically in main loop */
-void UA_Discovery_cleanupTimedOut(UA_Server *server, UA_DateTime nowMonotonic);
-
-# ifdef UA_ENABLE_DISCOVERY_MULTICAST
-
-UA_StatusCode
-initMulticastDiscoveryServer(UA_Server* server);
-
-void startMulticastDiscoveryServer(UA_Server *server);
-
-void stopMulticastDiscoveryServer(UA_Server *server);
-
-UA_StatusCode
-iterateMulticastDiscoveryServer(UA_Server* server, UA_DateTime *nextRepeat,
-                                UA_Boolean processIn);
-
-void destroyMulticastDiscoveryServer(UA_Server* server);
-
-typedef enum {
-    UA_DISCOVERY_TCP,     /* OPC UA TCP mapping */
-    UA_DISCOVERY_TLS     /* OPC UA HTTPS mapping */
-} UA_DiscoveryProtocol;
-
-/* Send a multicast probe to find any other OPC UA server on the network through mDNS. */
-UA_StatusCode
-UA_Discovery_multicastQuery(UA_Server* server);
-
-UA_StatusCode
-UA_Discovery_addRecord(UA_Server *server, const UA_String *servername,
-                       const UA_String *hostname, UA_UInt16 port,
-                       const UA_String *path, const UA_DiscoveryProtocol protocol,
-                       UA_Boolean createTxt, const UA_String* capabilites,
-                       size_t *capabilitiesSize);
-UA_StatusCode
-UA_Discovery_removeRecord(UA_Server *server, const UA_String *servername,
-                          const UA_String *hostname, UA_UInt16 port,
-                          UA_Boolean removeTxt);
-
-# endif
-
 /*****************************/
 /* AddNodes Begin and Finish */
 /*****************************/

+ 27 - 23
src/server/ua_services_discovery.c

@@ -13,7 +13,6 @@
 
 #include "ua_server_internal.h"
 #include "ua_services.h"
-#include "ua_mdns_internal.h"
 
 #ifdef UA_ENABLE_DISCOVERY
 
@@ -160,10 +159,10 @@ void Service_FindServers(UA_Server *server, UA_Session *session,
     /* Temporarily store all the pointers which we found to avoid reiterating
      * through the list */
     size_t foundServersSize = 0;
-    UA_STACKARRAY(UA_RegisteredServer*, foundServers, server->registeredServersSize+1);
+    UA_STACKARRAY(UA_RegisteredServer*, foundServers, server->discoveryManager.registeredServersSize+1);
 
     registeredServer_list_entry* current;
-    LIST_FOREACH(current, &server->registeredServers, pointers) {
+    LIST_FOREACH(current, &server->discoveryManager.registeredServers, pointers) {
         if(request->serverUrisSize) {
             /* If client only requested a specific set of servers */
             for(size_t i = 0; i < request->serverUrisSize; i++) {
@@ -314,7 +313,7 @@ process_RegisterServer(UA_Server *server, UA_Session *session,
     /* Find the server from the request in the registered list */
     registeredServer_list_entry* current;
     registeredServer_list_entry *registeredServer_entry = NULL;
-    LIST_FOREACH(current, &server->registeredServers, pointers) {
+    LIST_FOREACH(current, &server->discoveryManager.registeredServers, pointers) {
         if(UA_String_equal(&current->registeredServer.serverUri, &requestServer->serverUri)) {
             registeredServer_entry = current;
             break;
@@ -392,9 +391,9 @@ process_RegisterServer(UA_Server *server, UA_Session *session,
             /* create TXT if is online and first index, delete TXT if is offline and last index */
             UA_Boolean updateTxt = (requestServer->isOnline && i==0) ||
                 (!requestServer->isOnline && i==requestServer->discoveryUrlsSize);
-            UA_Discovery_update_MdnsForDiscoveryUrl(server, mdnsServerName, mdnsConfig,
-                                                    &requestServer->discoveryUrls[i],
-                                                    requestServer->isOnline, updateTxt);
+            UA_Server_updateMdnsForDiscoveryUrl(server, mdnsServerName, mdnsConfig,
+                                                &requestServer->discoveryUrls[i],
+                                                requestServer->isOnline, updateTxt);
         }
     }
 #endif
@@ -410,17 +409,19 @@ process_RegisterServer(UA_Server *server, UA_Session *session,
             return;
         }
 
-        if(server->registerServerCallback)
-            server->registerServerCallback(requestServer, server->registerServerCallbackData);
+        if(server->discoveryManager.registerServerCallback)
+            server->discoveryManager.
+                registerServerCallback(requestServer,
+                                       server->discoveryManager.registerServerCallbackData);
 
         // server found, remove from list
         LIST_REMOVE(registeredServer_entry, pointers);
         UA_RegisteredServer_deleteMembers(&registeredServer_entry->registeredServer);
 #ifndef UA_ENABLE_MULTITHREADING
         UA_free(registeredServer_entry);
-        server->registeredServersSize--;
+        server->discoveryManager.registeredServersSize--;
 #else
-        UA_atomic_subSize(&server->registeredServersSize, 1);
+        UA_atomic_subSize(&server->discoveryManager.registeredServersSize, 1);
         registeredServer_entry->delayedCleanup.callback = NULL; /* only free the structure */
         UA_WorkQueue_enqueueDelayed(&server->workQueue, &registeredServer_entry->delayedCleanup);
 #endif
@@ -441,15 +442,17 @@ process_RegisterServer(UA_Server *server, UA_Session *session,
             return;
         }
 
-        LIST_INSERT_HEAD(&server->registeredServers, registeredServer_entry, pointers);
+        LIST_INSERT_HEAD(&server->discoveryManager.registeredServers, registeredServer_entry, pointers);
 #ifndef UA_ENABLE_MULTITHREADING
-        server->registeredServersSize++;
+        server->discoveryManager.registeredServersSize++;
 #else
-        UA_atomic_addSize(&server->registeredServersSize, 1);
+        UA_atomic_addSize(&server->discoveryManager.registeredServersSize, 1);
 #endif
 
-        if(server->registerServerCallback)
-            server->registerServerCallback(requestServer, server->registerServerCallbackData);
+        if(server->discoveryManager.registerServerCallback)
+            server->discoveryManager.
+                registerServerCallback(requestServer,
+                                       server->discoveryManager.registerServerCallbackData);
     } else {
         UA_RegisteredServer_deleteMembers(&registeredServer_entry->registeredServer);
     }
@@ -493,7 +496,7 @@ void UA_Discovery_cleanupTimedOut(UA_Server *server, UA_DateTime nowMonotonic) {
         timedOut -= server->config.discoveryCleanupTimeout*UA_DATETIME_SEC;
 
     registeredServer_list_entry* current, *temp;
-    LIST_FOREACH_SAFE(current, &server->registeredServers, pointers, temp) {
+    LIST_FOREACH_SAFE(current, &server->discoveryManager.registeredServers, pointers, temp) {
         UA_Boolean semaphoreDeleted = false;
 
 #ifdef UA_ENABLE_DISCOVERY_SEMAPHORE
@@ -535,9 +538,9 @@ void UA_Discovery_cleanupTimedOut(UA_Server *server, UA_DateTime nowMonotonic) {
             UA_RegisteredServer_deleteMembers(&current->registeredServer);
 #ifndef UA_ENABLE_MULTITHREADING
             UA_free(current);
-            server->registeredServersSize--;
+            server->discoveryManager.registeredServersSize--;
 #else
-            UA_atomic_subSize(&server->registeredServersSize, 1);
+            UA_atomic_subSize(&server->discoveryManager.registeredServersSize, 1);
             current->delayedCleanup.callback = NULL; /* Only free the structure */
             UA_WorkQueue_enqueueDelayed(&server->workQueue, &current->delayedCleanup);
 #endif
@@ -653,7 +656,8 @@ UA_Server_addPeriodicServerRegisterCallback(UA_Server *server,
     /* check if we are already registering with the given discovery url and remove the old periodic call */
     {
         periodicServerRegisterCallback_entry *rs, *rs_tmp;
-        LIST_FOREACH_SAFE(rs, &server->periodicServerRegisterCallbacks, pointers, rs_tmp) {
+        LIST_FOREACH_SAFE(rs, &server->discoveryManager.
+                          periodicServerRegisterCallbacks, pointers, rs_tmp) {
             if(strcmp(rs->callback->discovery_server_url, discoveryServerUrl) == 0) {
                 UA_LOG_INFO(server->config.logger, UA_LOGCATEGORY_SERVER,
                             "There is already a register callback for '%s' in place. Removing the older one.", discoveryServerUrl);
@@ -706,7 +710,7 @@ UA_Server_addPeriodicServerRegisterCallback(UA_Server *server,
         return UA_STATUSCODE_BADOUTOFMEMORY;
     }
     newEntry->callback = cb;
-    LIST_INSERT_HEAD(&server->periodicServerRegisterCallbacks, newEntry, pointers);
+    LIST_INSERT_HEAD(&server->discoveryManager.periodicServerRegisterCallbacks, newEntry, pointers);
 #endif
 
     if(periodicCallbackId)
@@ -718,8 +722,8 @@ void
 UA_Server_setRegisterServerCallback(UA_Server *server,
                                     UA_Server_registerServerCallback cb,
                                     void* data) {
-    server->registerServerCallback = cb;
-    server->registerServerCallbackData = data;
+    server->discoveryManager.registerServerCallback = cb;
+    server->discoveryManager.registerServerCallbackData = data;
 }
 
 #endif /* UA_ENABLE_DISCOVERY */

+ 42 - 102
src/server/ua_services_discovery_multicast.c

@@ -9,7 +9,6 @@
 
 #include "ua_server_internal.h"
 #include "ua_services.h"
-#include "ua_mdns_internal.h"
 
 #if defined(UA_ENABLE_DISCOVERY) && defined(UA_ENABLE_DISCOVERY_MULTICAST)
 
@@ -18,20 +17,20 @@
 static void *
 multicastWorkerLoop(UA_Server *server) {
     struct timeval next_sleep = {.tv_sec = 0, .tv_usec = 0};
-    volatile UA_Boolean *running = &server->mdnsRunning;
+    volatile UA_Boolean *running = &server->discoveryManager.mdnsRunning;
     fd_set fds;
 
     while(*running) {
         FD_ZERO(&fds);
-        UA_fd_set(server->mdnsSocket, &fds);
-        select(server->mdnsSocket + 1, &fds, 0, 0, &next_sleep);
+        UA_fd_set(server->discoveryManager.mdnsSocket, &fds);
+        select(server->discoveryManager.mdnsSocket + 1, &fds, 0, 0, &next_sleep);
 
         if(!*running)
             break;
 
         unsigned short retVal =
-            mdnsd_step(server->mdnsDaemon, server->mdnsSocket,
-                       FD_ISSET(server->mdnsSocket, &fds), true, &next_sleep);
+            mdnsd_step(server->discoveryManager.mdnsDaemon, server->discoveryManager.mdnsSocket,
+                       FD_ISSET(server->discoveryManager.mdnsSocket, &fds), true, &next_sleep);
         if(retVal == 1) {
             UA_LOG_SOCKET_ERRNO_WRAP(
                 UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_SERVER,
@@ -49,7 +48,7 @@ multicastWorkerLoop(UA_Server *server) {
 
 static UA_StatusCode
 multicastListenStart(UA_Server* server) {
-    int err = pthread_create(&server->mdnsThread, NULL,
+    int err = pthread_create(&server->discoveryManager.mdnsThread, NULL,
                              (void* (*)(void*))multicastWorkerLoop, server);
     if(err != 0) {
         UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_SERVER,
@@ -61,10 +60,10 @@ multicastListenStart(UA_Server* server) {
 
 static UA_StatusCode
 multicastListenStop(UA_Server* server) {
-    mdnsd_shutdown(server->mdnsDaemon);
+    mdnsd_shutdown(server->discoveryManager.mdnsDaemon);
     // wake up select
-    if(write(server->mdnsSocket, "\0", 1)){}; //TODO: move to arch?
-    if(pthread_join(server->mdnsThread, NULL)) {
+    if(write(server->discoveryManager.mdnsSocket, "\0", 1)){}; //TODO: move to arch?
+    if(pthread_join(server->discoveryManager.mdnsThread, NULL)) {
         UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_SERVER,
                      "Multicast error: Can not stop thread.");
         return UA_STATUSCODE_BADUNEXPECTEDERROR;
@@ -108,7 +107,8 @@ void startMulticastDiscoveryServer(UA_Server *server) {
 # endif
 }
 
-void stopMulticastDiscoveryServer(UA_Server *server) {
+void
+stopMulticastDiscoveryServer(UA_Server *server) {
     char hostname[256];
     if(UA_gethostname(hostname, 255) == 0) {
         UA_String hnString = UA_STRING(hostname);
@@ -144,13 +144,14 @@ void Service_FindServersOnNetwork(UA_Server *server, UA_Session *session,
                                   const UA_FindServersOnNetworkRequest *request,
                                   UA_FindServersOnNetworkResponse *response) {
     /* Set LastCounterResetTime */
-    UA_DateTime_copy(&server->serverOnNetworkRecordIdLastReset,
+    UA_DateTime_copy(&server->discoveryManager.serverOnNetworkRecordIdLastReset,
                      &response->lastCounterResetTime);
 
     /* Compute the max number of records to return */
     UA_UInt32 recordCount = 0;
-    if(request->startingRecordId < server->serverOnNetworkRecordIdCounter)
-        recordCount = server->serverOnNetworkRecordIdCounter - request->startingRecordId;
+    if(request->startingRecordId < server->discoveryManager.serverOnNetworkRecordIdCounter)
+        recordCount = server->discoveryManager.serverOnNetworkRecordIdCounter -
+            request->startingRecordId;
     if(request->maxRecordsToReturn && recordCount > request->maxRecordsToReturn)
         recordCount = UA_MIN(recordCount, request->maxRecordsToReturn);
     if(recordCount == 0) {
@@ -162,7 +163,7 @@ void Service_FindServersOnNetwork(UA_Server *server, UA_Session *session,
     UA_UInt32 filteredCount = 0;
     UA_STACKARRAY(UA_ServerOnNetwork*, filtered, recordCount);
     serverOnNetwork_list_entry* current;
-    LIST_FOREACH(current, &server->serverOnNetwork, pointers) {
+    LIST_FOREACH(current, &server->discoveryManager.serverOnNetwork, pointers) {
         if(filteredCount >= recordCount)
             break;
         if(current->serverOnNetwork.recordId < request->startingRecordId)
@@ -191,10 +192,10 @@ void Service_FindServersOnNetwork(UA_Server *server, UA_Session *session,
 }
 
 void
-UA_Discovery_update_MdnsForDiscoveryUrl(UA_Server *server, const UA_String *serverName,
-                                        const UA_MdnsDiscoveryConfiguration *mdnsConfig,
-                                        const UA_String *discoveryUrl,
-                                        UA_Boolean isOnline, UA_Boolean updateTxt) {
+UA_Server_updateMdnsForDiscoveryUrl(UA_Server *server, const UA_String *serverName,
+                                    const UA_MdnsDiscoveryConfiguration *mdnsConfig,
+                                    const UA_String *discoveryUrl,
+                                    UA_Boolean isOnline, UA_Boolean updateTxt) {
     UA_String hostname = UA_STRING_NULL;
     UA_UInt16 port = 4840;
     UA_String path = UA_STRING_NULL;
@@ -238,70 +239,8 @@ void
 UA_Server_setServerOnNetworkCallback(UA_Server *server,
                                      UA_Server_serverOnNetworkCallback cb,
                                      void* data) {
-    server->serverOnNetworkCallback = cb;
-    server->serverOnNetworkCallbackData = data;
-}
-
-/* Create multicast 224.0.0.251:5353 socket */
-static UA_SOCKET discovery_createMulticastSocket(void) {
-    UA_SOCKET s;
-    int flag = 1, ittl = 255;
-    struct sockaddr_in in;
-    struct ip_mreq mc;
-    char ttl = (char)255; // publish to complete net, not only subnet. See:
-                          // https://docs.oracle.com/cd/E23824_01/html/821-1602/sockets-137.html
-
-    memset(&in, 0, sizeof(in));
-    in.sin_family = AF_INET;
-    in.sin_port = htons(5353);
-    in.sin_addr.s_addr = 0;
-
-    if((s = UA_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == UA_INVALID_SOCKET)
-        return UA_INVALID_SOCKET;
-
-#ifdef SO_REUSEPORT
-    UA_setsockopt(s, SOL_SOCKET, SO_REUSEPORT, (char *)&flag, sizeof(flag));
-#endif
-    UA_setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, sizeof(flag));
-    if(UA_bind(s, (struct sockaddr *)&in, sizeof(in))) {
-        UA_close(s);
-        return UA_INVALID_SOCKET;
-    }
-
-    mc.imr_multiaddr.s_addr = inet_addr("224.0.0.251");
-    mc.imr_interface.s_addr = htonl(INADDR_ANY);
-    UA_setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mc, sizeof(mc));
-    UA_setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&ttl, sizeof(ttl));
-    UA_setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&ittl, sizeof(ittl));
-
-    UA_socket_set_nonblocking(s); //TODO: check return value
-    return s;
-}
-
-
-UA_StatusCode
-initMulticastDiscoveryServer(UA_Server* server) {
-    server->mdnsDaemon = mdnsd_new(QCLASS_IN, 1000);
-    UA_initialize_architecture_network();
-
-    if((server->mdnsSocket = discovery_createMulticastSocket()) == UA_INVALID_SOCKET) {
-        UA_LOG_SOCKET_ERRNO_WRAP(
-                UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_SERVER,
-                     "Could not create multicast socket. Error: %s", errno_str));
-        return UA_STATUSCODE_BADUNEXPECTEDERROR;
-    }
-    mdnsd_register_receive_callback(server->mdnsDaemon,
-                                    mdns_record_received, server);
-    return UA_STATUSCODE_GOOD;
-}
-
-void destroyMulticastDiscoveryServer(UA_Server* server) {
-    mdnsd_shutdown(server->mdnsDaemon);
-    mdnsd_free(server->mdnsDaemon);
-    if(server->mdnsSocket != UA_INVALID_SOCKET) {
-        UA_close(server->mdnsSocket);
-        server->mdnsSocket = UA_INVALID_SOCKET;
-    }
+    server->discoveryManager.serverOnNetworkCallback = cb;
+    server->discoveryManager.serverOnNetworkCallbackData = data;
 }
 
 static void
@@ -353,7 +292,7 @@ static UA_Boolean
 UA_Discovery_recordExists(UA_Server* server, const char* fullServiceDomain,
                           unsigned short port, const UA_DiscoveryProtocol protocol) {
     // [servername]-[hostname]._opcua-tcp._tcp.local. 86400 IN SRV 0 5 port [hostname].
-    mdns_record_t *r  = mdnsd_get_published(server->mdnsDaemon, fullServiceDomain);
+    mdns_record_t *r  = mdnsd_get_published(server->discoveryManager.mdnsDaemon, fullServiceDomain);
     while(r) {
         const mdns_answer_t *data = mdnsd_record_data(r);
         if(data->type == QTYPE_SRV && (port == 0 || data->srv.port == port))
@@ -378,22 +317,22 @@ discovery_multicastQueryAnswer(mdns_answer_t *a, void *arg) {
     if(exists == true)
         return 0;
 
-    if(mdnsd_has_query(server->mdnsDaemon, a->rdname))
+    if(mdnsd_has_query(server->discoveryManager.mdnsDaemon, a->rdname))
         return 0;
 
     UA_LOG_DEBUG(server->config.logger, UA_LOGCATEGORY_SERVER,
                  "mDNS send query for: %s SRV&TXT %s", a->name, a->rdname);
 
-    mdnsd_query(server->mdnsDaemon, a->rdname, QTYPE_SRV,
+    mdnsd_query(server->discoveryManager.mdnsDaemon, a->rdname, QTYPE_SRV,
                 discovery_multicastQueryAnswer, server);
-    mdnsd_query(server->mdnsDaemon, a->rdname, QTYPE_TXT,
+    mdnsd_query(server->discoveryManager.mdnsDaemon, a->rdname, QTYPE_TXT,
                 discovery_multicastQueryAnswer, server);
     return 0;
 }
 
 UA_StatusCode
 UA_Discovery_multicastQuery(UA_Server* server) {
-    mdnsd_query(server->mdnsDaemon, "_opcua-tcp._tcp.local.",
+    mdnsd_query(server->discoveryManager.mdnsDaemon, "_opcua-tcp._tcp.local.",
                 QTYPE_PTR,discovery_multicastQueryAnswer, server);
     return UA_STATUSCODE_GOOD;
 }
@@ -424,12 +363,12 @@ UA_Discovery_addRecord(UA_Server *server, const UA_String *servername,
                        "It will be truncated.");
     }
 
-    if(!server->mdnsMainSrvAdded) {
+    if(!server->discoveryManager.mdnsMainSrvAdded) {
         mdns_record_t *r =
-            mdnsd_shared(server->mdnsDaemon, "_services._dns-sd._udp.local.",
+            mdnsd_shared(server->discoveryManager.mdnsDaemon, "_services._dns-sd._udp.local.",
                          QTYPE_PTR, 600);
-        mdnsd_set_host(server->mdnsDaemon, r, "_opcua-tcp._tcp.local.");
-        server->mdnsMainSrvAdded = true;
+        mdnsd_set_host(server->discoveryManager.mdnsDaemon, r, "_opcua-tcp._tcp.local.");
+        server->discoveryManager.mdnsMainSrvAdded = true;
     }
 
     // [servername]-[hostname]._opcua-tcp._tcp.local.
@@ -448,11 +387,11 @@ UA_Discovery_addRecord(UA_Server *server, const UA_String *servername,
     // check if there is already a PTR entry for the given service.
 
     // _opcua-tcp._tcp.local. PTR [servername]-[hostname]._opcua-tcp._tcp.local.
-    mdns_record_t *r = mdns_find_record(server->mdnsDaemon, QTYPE_PTR,
+    mdns_record_t *r = mdns_find_record(server->discoveryManager.mdnsDaemon, QTYPE_PTR,
                                         "_opcua-tcp._tcp.local.", fullServiceDomain);
     if(!r) {
-        r = mdnsd_shared(server->mdnsDaemon, "_opcua-tcp._tcp.local.", QTYPE_PTR, 600);
-        mdnsd_set_host(server->mdnsDaemon, r, fullServiceDomain);
+        r = mdnsd_shared(server->discoveryManager.mdnsDaemon, "_opcua-tcp._tcp.local.", QTYPE_PTR, 600);
+        mdnsd_set_host(server->discoveryManager.mdnsDaemon, r, fullServiceDomain);
     }
 
     /* The first 63 characters of the hostname (or less) */
@@ -463,9 +402,9 @@ UA_Discovery_addRecord(UA_Server *server, const UA_String *servername,
     localDomain[maxHostnameLen+1] = '\0';
 
     // [servername]-[hostname]._opcua-tcp._tcp.local. 86400 IN SRV 0 5 port [hostname].
-    r = mdnsd_unique(server->mdnsDaemon, fullServiceDomain, QTYPE_SRV, 600,
+    r = mdnsd_unique(server->discoveryManager.mdnsDaemon, fullServiceDomain, QTYPE_SRV, 600,
                      UA_Discovery_multicastConflict, server);
-    mdnsd_set_srv(server->mdnsDaemon, r, 0, 0, port, localDomain);
+    mdnsd_set_srv(server->discoveryManager.mdnsDaemon, r, 0, 0, port, localDomain);
 
     // A/AAAA record for all ip addresses.
     // [servername]-[hostname]._opcua-tcp._tcp.local. A [ip].
@@ -509,7 +448,7 @@ UA_Discovery_removeRecord(UA_Server *server, const UA_String *servername,
                 "Multicast DNS: remove record for domain: %s", fullServiceDomain);
 
     // _opcua-tcp._tcp.local. PTR [servername]-[hostname]._opcua-tcp._tcp.local.
-    mdns_record_t *r = mdns_find_record(server->mdnsDaemon, QTYPE_PTR,
+    mdns_record_t *r = mdns_find_record(server->discoveryManager.mdnsDaemon, QTYPE_PTR,
                                         "_opcua-tcp._tcp.local.", fullServiceDomain);
     if(!r) {
         UA_LOG_WARNING(server->config.logger, UA_LOGCATEGORY_SERVER,
@@ -517,12 +456,12 @@ UA_Discovery_removeRecord(UA_Server *server, const UA_String *servername,
                        "PTR Record not found for domain: %s", fullServiceDomain);
         return UA_STATUSCODE_BADNOTHINGTODO;
     }
-    mdnsd_done(server->mdnsDaemon, r);
+    mdnsd_done(server->discoveryManager.mdnsDaemon, r);
 
     // looks for [servername]-[hostname]._opcua-tcp._tcp.local. 86400 IN SRV 0 5 port hostname.local.
     // and TXT record: [servername]-[hostname]._opcua-tcp._tcp.local. TXT path=/ caps=NA,DA,...
     // and A record: [servername]-[hostname]._opcua-tcp._tcp.local. A [ip]
-    mdns_record_t *r2 = mdnsd_get_published(server->mdnsDaemon, fullServiceDomain);
+    mdns_record_t *r2 = mdnsd_get_published(server->discoveryManager.mdnsDaemon, fullServiceDomain);
     if(!r2) {
         UA_LOG_WARNING(server->config.logger, UA_LOGCATEGORY_SERVER,
                        "Multicast DNS: could not remove record. Record not "
@@ -536,7 +475,7 @@ UA_Discovery_removeRecord(UA_Server *server, const UA_String *servername,
         if((removeTxt && data->type == QTYPE_TXT) ||
            (removeTxt && data->type == QTYPE_A) ||
            data->srv.port == port) {
-            mdnsd_done(server->mdnsDaemon, r2);
+            mdnsd_done(server->discoveryManager.mdnsDaemon, r2);
         }
         r2 = next;
     }
@@ -548,7 +487,8 @@ UA_StatusCode
 iterateMulticastDiscoveryServer(UA_Server* server, UA_DateTime *nextRepeat,
                                 UA_Boolean processIn) {
     struct timeval next_sleep = { 0, 0 };
-    unsigned short retval = mdnsd_step(server->mdnsDaemon, server->mdnsSocket,
+    unsigned short retval = mdnsd_step(server->discoveryManager.mdnsDaemon,
+                                       server->discoveryManager.mdnsSocket,
                                        processIn, true, &next_sleep);
     if(retval == 1) {
         UA_LOG_SOCKET_ERRNO_WRAP(