ua_server.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  4. *
  5. * Copyright 2014-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
  6. * Copyright 2014-2017 (c) Florian Palm
  7. * Copyright 2015-2016 (c) Sten Grüner
  8. * Copyright 2015-2016 (c) Chris Iatrou
  9. * Copyright 2015 (c) LEvertz
  10. * Copyright 2015-2016 (c) Oleksiy Vasylyev
  11. * Copyright 2016 (c) Julian Grothoff
  12. * Copyright 2016-2017 (c) Stefan Profanter, fortiss GmbH
  13. * Copyright 2016 (c) Lorenz Haas
  14. * Copyright 2017 (c) frax2222
  15. * Copyright 2017 (c) Mark Giraud, Fraunhofer IOSB
  16. * Copyright 2018 (c) Hilscher Gesellschaft für Systemautomation mbH (Author: Martin Lang)
  17. * Copyright 2019 (c) Kalycito Infotech Private Limited
  18. */
  19. #include "ua_server_internal.h"
  20. #ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
  21. #include "ua_pubsub_ns0.h"
  22. #endif
  23. #ifdef UA_ENABLE_SUBSCRIPTIONS
  24. #include "ua_subscription.h"
  25. #endif
  26. #ifdef UA_ENABLE_VALGRIND_INTERACTIVE
  27. #include <valgrind/memcheck.h>
  28. #endif
  29. /**********************/
  30. /* Namespace Handling */
  31. /**********************/
  32. /*
  33. * The NS1 Uri can be changed by the user to some custom string.
  34. * This method is called to initialize the NS1 Uri if it is not set before to the default Application URI.
  35. *
  36. * This is done as soon as the Namespace Array is read or written via node value read / write services,
  37. * or UA_Server_addNamespace, UA_Server_getNamespaceByName or UA_Server_run_startup is called.
  38. *
  39. * Therefore one has to set the custom NS1 URI before one of the previously mentioned steps.
  40. */
  41. void setupNs1Uri(UA_Server *server) {
  42. if (!server->namespaces[1].data) {
  43. UA_String_copy(&server->config.applicationDescription.applicationUri, &server->namespaces[1]);
  44. }
  45. }
  46. UA_UInt16 addNamespace(UA_Server *server, const UA_String name) {
  47. /* ensure that the uri for ns1 is set up from the app description */
  48. setupNs1Uri(server);
  49. /* Check if the namespace already exists in the server's namespace array */
  50. for(UA_UInt16 i = 0; i < server->namespacesSize; ++i) {
  51. if(UA_String_equal(&name, &server->namespaces[i]))
  52. return i;
  53. }
  54. /* Make the array bigger */
  55. UA_String *newNS = (UA_String*)UA_realloc(server->namespaces,
  56. sizeof(UA_String) * (server->namespacesSize + 1));
  57. if(!newNS)
  58. return 0;
  59. server->namespaces = newNS;
  60. /* Copy the namespace string */
  61. UA_StatusCode retval = UA_String_copy(&name, &server->namespaces[server->namespacesSize]);
  62. if(retval != UA_STATUSCODE_GOOD)
  63. return 0;
  64. /* Announce the change (otherwise, the array appears unchanged) */
  65. ++server->namespacesSize;
  66. return (UA_UInt16)(server->namespacesSize - 1);
  67. }
  68. UA_UInt16 UA_Server_addNamespace(UA_Server *server, const char* name) {
  69. /* Override const attribute to get string (dirty hack) */
  70. UA_String nameString;
  71. nameString.length = strlen(name);
  72. nameString.data = (UA_Byte*)(uintptr_t)name;
  73. UA_LOCK(server->serviceMutex);
  74. UA_UInt16 retVal = addNamespace(server, nameString);
  75. UA_UNLOCK(server->serviceMutex);
  76. return retVal;
  77. }
  78. UA_ServerConfig*
  79. UA_Server_getConfig(UA_Server *server)
  80. {
  81. if(!server)
  82. return NULL;
  83. return &server->config;
  84. }
  85. UA_StatusCode
  86. UA_Server_getNamespaceByName(UA_Server *server, const UA_String namespaceUri,
  87. size_t* foundIndex) {
  88. UA_LOCK(server->serviceMutex);
  89. /* ensure that the uri for ns1 is set up from the app description */
  90. setupNs1Uri(server);
  91. for(size_t idx = 0; idx < server->namespacesSize; idx++) {
  92. if(!UA_String_equal(&server->namespaces[idx], &namespaceUri))
  93. continue;
  94. (*foundIndex) = idx;
  95. UA_UNLOCK(server->serviceMutex);
  96. return UA_STATUSCODE_GOOD;
  97. }
  98. UA_UNLOCK(server->serviceMutex);
  99. return UA_STATUSCODE_BADNOTFOUND;
  100. }
  101. UA_StatusCode
  102. UA_Server_forEachChildNodeCall(UA_Server *server, UA_NodeId parentNodeId,
  103. UA_NodeIteratorCallback callback, void *handle) {
  104. UA_LOCK(server->serviceMutex);
  105. const UA_Node *parent = UA_NODESTORE_GET(server, &parentNodeId);
  106. if(!parent) {
  107. UA_UNLOCK(server->serviceMutex);
  108. return UA_STATUSCODE_BADNODEIDINVALID;
  109. }
  110. /* TODO: We need to do an ugly copy of the references array since users may
  111. * delete references from within the callback. In single-threaded mode this
  112. * changes the same node we point at here. In multi-threaded mode, this
  113. * creates a new copy as nodes are truly immutable.
  114. * The callback could remove a node via the regular public API.
  115. * This can remove a member of the nodes-array we iterate over...
  116. * */
  117. UA_Node *parentCopy = UA_Node_copy_alloc(parent);
  118. if(!parentCopy) {
  119. UA_NODESTORE_RELEASE(server, parent);
  120. UA_UNLOCK(server->serviceMutex);
  121. return UA_STATUSCODE_BADUNEXPECTEDERROR;
  122. }
  123. UA_StatusCode retval = UA_STATUSCODE_GOOD;
  124. for(size_t i = parentCopy->referencesSize; i > 0; --i) {
  125. UA_NodeReferenceKind *ref = &parentCopy->references[i - 1];
  126. for(size_t j = 0; j<ref->refTargetsSize; j++) {
  127. UA_UNLOCK(server->serviceMutex);
  128. retval = callback(ref->refTargets[j].target.nodeId, ref->isInverse,
  129. ref->referenceTypeId, handle);
  130. UA_LOCK(server->serviceMutex);
  131. if(retval != UA_STATUSCODE_GOOD)
  132. goto cleanup;
  133. }
  134. }
  135. cleanup:
  136. UA_Node_clear(parentCopy);
  137. UA_free(parentCopy);
  138. UA_NODESTORE_RELEASE(server, parent);
  139. UA_UNLOCK(server->serviceMutex);
  140. return retval;
  141. }
  142. /********************/
  143. /* Server Lifecycle */
  144. /********************/
  145. /* The server needs to be stopped before it can be deleted */
  146. void UA_Server_delete(UA_Server *server) {
  147. /* Delete all internal data */
  148. UA_SecureChannelManager_deleteMembers(&server->secureChannelManager);
  149. UA_LOCK(server->serviceMutex);
  150. UA_SessionManager_deleteMembers(&server->sessionManager);
  151. UA_UNLOCK(server->serviceMutex);
  152. UA_Array_delete(server->namespaces, server->namespacesSize, &UA_TYPES[UA_TYPES_STRING]);
  153. #ifdef UA_ENABLE_SUBSCRIPTIONS
  154. UA_MonitoredItem *mon, *mon_tmp;
  155. LIST_FOREACH_SAFE(mon, &server->localMonitoredItems, listEntry, mon_tmp) {
  156. LIST_REMOVE(mon, listEntry);
  157. UA_LOCK(server->serviceMutex);
  158. UA_MonitoredItem_delete(server, mon);
  159. UA_UNLOCK(server->serviceMutex);
  160. }
  161. #endif
  162. #ifdef UA_ENABLE_PUBSUB
  163. UA_PubSubManager_delete(server, &server->pubSubManager);
  164. #endif
  165. #ifdef UA_ENABLE_DISCOVERY
  166. UA_DiscoveryManager_deleteMembers(&server->discoveryManager, server);
  167. #endif
  168. #if UA_MULTITHREADING >= 100
  169. UA_AsyncManager_clear(&server->asyncManager, server);
  170. #endif
  171. /* Clean up the Admin Session */
  172. UA_LOCK(server->serviceMutex);
  173. UA_Session_deleteMembersCleanup(&server->adminSession, server);
  174. UA_UNLOCK(server->serviceMutex);
  175. /* Clean up the work queue */
  176. UA_WorkQueue_cleanup(&server->workQueue);
  177. /* Delete the timed work */
  178. UA_Timer_deleteMembers(&server->timer);
  179. /* Clean up the config */
  180. UA_ServerConfig_clean(&server->config);
  181. #if UA_MULTITHREADING >= 100
  182. UA_LOCK_DESTROY(server->networkMutex)
  183. UA_LOCK_DESTROY(server->serviceMutex)
  184. #endif
  185. /* Delete the server itself */
  186. UA_free(server);
  187. }
  188. /* Recurring cleanup. Removing unused and timed-out channels and sessions */
  189. static void
  190. UA_Server_cleanup(UA_Server *server, void *_) {
  191. UA_LOCK(server->serviceMutex);
  192. UA_DateTime nowMonotonic = UA_DateTime_nowMonotonic();
  193. UA_SessionManager_cleanupTimedOut(&server->sessionManager, nowMonotonic);
  194. UA_SecureChannelManager_cleanupTimedOut(&server->secureChannelManager, nowMonotonic);
  195. #ifdef UA_ENABLE_DISCOVERY
  196. UA_Discovery_cleanupTimedOut(server, nowMonotonic);
  197. #endif
  198. UA_UNLOCK(server->serviceMutex);
  199. }
  200. /********************/
  201. /* Server Lifecycle */
  202. /********************/
  203. static UA_Server *
  204. UA_Server_init(UA_Server *server) {
  205. UA_StatusCode res = UA_STATUSCODE_GOOD;
  206. if(!server->config.nodestore.getNode) {
  207. UA_LOG_FATAL(&server->config.logger, UA_LOGCATEGORY_SERVER,
  208. "No Nodestore configured in the server");
  209. goto cleanup;
  210. }
  211. /* Init start time to zero, the actual start time will be sampled in
  212. * UA_Server_run_startup() */
  213. server->startTime = 0;
  214. /* Set a seed for non-cyptographic randomness */
  215. #ifndef UA_ENABLE_DETERMINISTIC_RNG
  216. UA_random_seed((UA_UInt64)UA_DateTime_now());
  217. #endif
  218. #if UA_MULTITHREADING >= 100
  219. UA_LOCK_INIT(server->networkMutex)
  220. UA_LOCK_INIT(server->serviceMutex)
  221. #endif
  222. /* Initialize the handling of repeated callbacks */
  223. UA_Timer_init(&server->timer);
  224. UA_WorkQueue_init(&server->workQueue);
  225. /* Initialize the adminSession */
  226. UA_Session_init(&server->adminSession);
  227. server->adminSession.sessionId.identifierType = UA_NODEIDTYPE_GUID;
  228. server->adminSession.sessionId.identifier.guid.data1 = 1;
  229. server->adminSession.validTill = UA_INT64_MAX;
  230. /* Create Namespaces 0 and 1
  231. * Ns1 will be filled later with the uri from the app description */
  232. server->namespaces = (UA_String *)UA_Array_new(2, &UA_TYPES[UA_TYPES_STRING]);
  233. if(!server->namespaces) {
  234. UA_Server_delete(server);
  235. return NULL;
  236. }
  237. server->namespaces[0] = UA_STRING_ALLOC("http://opcfoundation.org/UA/");
  238. server->namespaces[1] = UA_STRING_NULL;
  239. server->namespacesSize = 2;
  240. /* Initialized SecureChannel and Session managers */
  241. UA_SecureChannelManager_init(&server->secureChannelManager, server);
  242. UA_SessionManager_init(&server->sessionManager, server);
  243. #if UA_MULTITHREADING >= 100
  244. UA_AsyncManager_init(&server->asyncManager, server);
  245. #endif
  246. /* Add a regular callback for cleanup and maintenance. With a 10s interval. */
  247. UA_Server_addRepeatedCallback(server, (UA_ServerCallback)UA_Server_cleanup, NULL,
  248. 10000.0, NULL);
  249. /* Initialize namespace 0*/
  250. res = UA_Server_initNS0(server);
  251. if(res != UA_STATUSCODE_GOOD)
  252. goto cleanup;
  253. /* Build PubSub information model */
  254. #ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
  255. UA_Server_initPubSubNS0(server);
  256. #endif
  257. return server;
  258. cleanup:
  259. UA_Server_delete(server);
  260. return NULL;
  261. }
  262. UA_Server *
  263. UA_Server_newWithConfig(const UA_ServerConfig *config) {
  264. if(!config)
  265. return NULL;
  266. UA_Server *server = (UA_Server *)UA_calloc(1, sizeof(UA_Server));
  267. if(!server)
  268. return NULL;
  269. server->config = *config;
  270. return UA_Server_init(server);
  271. }
  272. /* Returns if the server should be shut down immediately */
  273. static UA_Boolean
  274. setServerShutdown(UA_Server *server) {
  275. if(server->endTime != 0)
  276. return false;
  277. if(server->config.shutdownDelay == 0)
  278. return true;
  279. UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_SERVER,
  280. "Shutting down the server with a delay of %i ms", (int)server->config.shutdownDelay);
  281. server->endTime = UA_DateTime_now() + (UA_DateTime)(server->config.shutdownDelay * UA_DATETIME_MSEC);
  282. return false;
  283. }
  284. /*******************/
  285. /* Timed Callbacks */
  286. /*******************/
  287. UA_StatusCode
  288. UA_Server_addTimedCallback(UA_Server *server, UA_ServerCallback callback,
  289. void *data, UA_DateTime date, UA_UInt64 *callbackId) {
  290. UA_LOCK(server->serviceMutex);
  291. UA_StatusCode retval = UA_Timer_addTimedCallback(&server->timer,
  292. (UA_ApplicationCallback)callback,
  293. server, data, date, callbackId);
  294. UA_UNLOCK(server->serviceMutex);
  295. return retval;
  296. }
  297. UA_StatusCode
  298. addRepeatedCallback(UA_Server *server, UA_ServerCallback callback,
  299. void *data, UA_Double interval_ms,
  300. UA_UInt64 *callbackId) {
  301. return UA_Timer_addRepeatedCallback(&server->timer,
  302. (UA_ApplicationCallback)callback,
  303. server, data, interval_ms, callbackId);
  304. }
  305. UA_StatusCode
  306. UA_Server_addRepeatedCallback(UA_Server *server, UA_ServerCallback callback,
  307. void *data, UA_Double interval_ms,
  308. UA_UInt64 *callbackId) {
  309. UA_LOCK(server->serviceMutex);
  310. UA_StatusCode retval = addRepeatedCallback(server, callback, data, interval_ms, callbackId);
  311. UA_UNLOCK(server->serviceMutex);
  312. return retval;
  313. }
  314. UA_StatusCode
  315. changeRepeatedCallbackInterval(UA_Server *server, UA_UInt64 callbackId,
  316. UA_Double interval_ms) {
  317. return UA_Timer_changeRepeatedCallbackInterval(&server->timer, callbackId,
  318. interval_ms);
  319. }
  320. UA_StatusCode
  321. UA_Server_changeRepeatedCallbackInterval(UA_Server *server, UA_UInt64 callbackId,
  322. UA_Double interval_ms) {
  323. UA_LOCK(server->serviceMutex);
  324. UA_StatusCode retval = changeRepeatedCallbackInterval(server, callbackId, interval_ms);
  325. UA_UNLOCK(server->serviceMutex);
  326. return retval;
  327. }
  328. void
  329. removeCallback(UA_Server *server, UA_UInt64 callbackId) {
  330. UA_Timer_removeCallback(&server->timer, callbackId);
  331. }
  332. void
  333. UA_Server_removeCallback(UA_Server *server, UA_UInt64 callbackId) {
  334. UA_LOCK(server->serviceMutex);
  335. removeCallback(server, callbackId);
  336. UA_UNLOCK(server->serviceMutex);
  337. }
  338. UA_StatusCode
  339. UA_Server_updateCertificate(UA_Server *server,
  340. const UA_ByteString *oldCertificate,
  341. const UA_ByteString *newCertificate,
  342. const UA_ByteString *newPrivateKey,
  343. UA_Boolean closeSessions,
  344. UA_Boolean closeSecureChannels) {
  345. if(!server || !oldCertificate || !newCertificate || !newPrivateKey)
  346. return UA_STATUSCODE_BADINTERNALERROR;
  347. if(closeSessions) {
  348. UA_SessionManager *sm = &server->sessionManager;
  349. session_list_entry *current;
  350. LIST_FOREACH(current, &sm->sessions, pointers) {
  351. if(UA_ByteString_equal(oldCertificate,
  352. &current->session.header.channel->securityPolicy->localCertificate)) {
  353. UA_LOCK(server->serviceMutex);
  354. UA_SessionManager_removeSession(sm, &current->session.header.authenticationToken);
  355. UA_UNLOCK(server->serviceMutex);
  356. }
  357. }
  358. }
  359. if(closeSecureChannels) {
  360. UA_SecureChannelManager *cm = &server->secureChannelManager;
  361. channel_entry *entry;
  362. TAILQ_FOREACH(entry, &cm->channels, pointers) {
  363. if(UA_ByteString_equal(&entry->channel.securityPolicy->localCertificate, oldCertificate)){
  364. UA_SecureChannelManager_close(cm, entry->channel.securityToken.channelId);
  365. }
  366. }
  367. }
  368. size_t i = 0;
  369. while(i < server->config.endpointsSize) {
  370. UA_EndpointDescription *ed = &server->config.endpoints[i];
  371. if(UA_ByteString_equal(&ed->serverCertificate, oldCertificate)) {
  372. UA_String_deleteMembers(&ed->serverCertificate);
  373. UA_String_copy(newCertificate, &ed->serverCertificate);
  374. UA_SecurityPolicy *sp = UA_SecurityPolicy_getSecurityPolicyByUri(server, &server->config.endpoints[i].securityPolicyUri);
  375. if(!sp)
  376. return UA_STATUSCODE_BADINTERNALERROR;
  377. sp->updateCertificateAndPrivateKey(sp, *newCertificate, *newPrivateKey);
  378. }
  379. i++;
  380. }
  381. return UA_STATUSCODE_GOOD;
  382. }
  383. /***************************/
  384. /* Server lookup functions */
  385. /***************************/
  386. UA_SecurityPolicy *
  387. UA_SecurityPolicy_getSecurityPolicyByUri(const UA_Server *server,
  388. const UA_ByteString *securityPolicyUri) {
  389. for(size_t i = 0; i < server->config.securityPoliciesSize; i++) {
  390. UA_SecurityPolicy *securityPolicyCandidate = &server->config.securityPolicies[i];
  391. if(UA_ByteString_equal(securityPolicyUri, &securityPolicyCandidate->policyUri))
  392. return securityPolicyCandidate;
  393. }
  394. return NULL;
  395. }
  396. #ifdef UA_ENABLE_ENCRYPTION
  397. /* The local ApplicationURI has to match the certificates of the
  398. * SecurityPolicies */
  399. static UA_StatusCode
  400. verifyServerApplicationURI(const UA_Server *server) {
  401. for(size_t i = 0; i < server->config.securityPoliciesSize; i++) {
  402. UA_SecurityPolicy *sp = &server->config.securityPolicies[i];
  403. if(!sp->certificateVerification)
  404. continue;
  405. UA_StatusCode retval =
  406. sp->certificateVerification->
  407. verifyApplicationURI(sp->certificateVerification->context,
  408. &sp->localCertificate,
  409. &server->config.applicationDescription.applicationUri);
  410. if(retval != UA_STATUSCODE_GOOD) {
  411. UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_SERVER,
  412. "The configured ApplicationURI does not match the URI "
  413. "specified in the certificate for the SecurityPolicy %.*s",
  414. (int)sp->policyUri.length, sp->policyUri.data);
  415. return retval;
  416. }
  417. }
  418. return UA_STATUSCODE_GOOD;
  419. }
  420. #endif
  421. /********************/
  422. /* Main Server Loop */
  423. /********************/
  424. #define UA_MAXTIMEOUT 50 /* Max timeout in ms between main-loop iterations */
  425. /* Start: Spin up the workers and the network layer and sample the server's
  426. * start time.
  427. * Iterate: Process repeated callbacks and events in the network layer. This
  428. * part can be driven from an external main-loop in an event-driven
  429. * single-threaded architecture.
  430. * Stop: Stop workers, finish all callbacks, stop the network layer, clean up */
  431. UA_StatusCode
  432. UA_Server_run_startup(UA_Server *server) {
  433. /* ensure that the uri for ns1 is set up from the app description */
  434. setupNs1Uri(server);
  435. /* write ServerArray with same ApplicationURI value as NamespaceArray */
  436. UA_StatusCode retVal = writeNs0VariableArray(server, UA_NS0ID_SERVER_SERVERARRAY,
  437. &server->config.applicationDescription.applicationUri,
  438. 1, &UA_TYPES[UA_TYPES_STRING]);
  439. if(retVal != UA_STATUSCODE_GOOD)
  440. return retVal;
  441. if(server->state > UA_SERVERLIFECYCLE_FRESH)
  442. return UA_STATUSCODE_GOOD;
  443. /* At least one endpoint has to be configured */
  444. if(server->config.endpointsSize == 0) {
  445. UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_SERVER,
  446. "There has to be at least one endpoint.");
  447. }
  448. /* Initialized discovery */
  449. #ifdef UA_ENABLE_DISCOVERY
  450. UA_DiscoveryManager_init(&server->discoveryManager, server);
  451. #endif
  452. /* Does the ApplicationURI match the local certificates? */
  453. #ifdef UA_ENABLE_ENCRYPTION
  454. retVal = verifyServerApplicationURI(server);
  455. if(retVal != UA_STATUSCODE_GOOD)
  456. return retVal;
  457. #endif
  458. /* Sample the start time and set it to the Server object */
  459. server->startTime = UA_DateTime_now();
  460. UA_Variant var;
  461. UA_Variant_init(&var);
  462. UA_Variant_setScalar(&var, &server->startTime, &UA_TYPES[UA_TYPES_DATETIME]);
  463. UA_Server_writeValue(server,
  464. UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_STARTTIME),
  465. var);
  466. /* Start the networklayers */
  467. UA_StatusCode result = UA_STATUSCODE_GOOD;
  468. for(size_t i = 0; i < server->config.networkLayersSize; ++i) {
  469. UA_ServerNetworkLayer *nl = &server->config.networkLayers[i];
  470. result |= nl->start(nl, &server->config.customHostname);
  471. }
  472. /* Update the application description to match the previously added discovery urls.
  473. * We can only do this after the network layer is started since it inits the discovery url */
  474. if(server->config.applicationDescription.discoveryUrlsSize != 0) {
  475. UA_Array_delete(server->config.applicationDescription.discoveryUrls,
  476. server->config.applicationDescription.discoveryUrlsSize,
  477. &UA_TYPES[UA_TYPES_STRING]);
  478. server->config.applicationDescription.discoveryUrlsSize = 0;
  479. }
  480. server->config.applicationDescription.discoveryUrls = (UA_String *)
  481. UA_Array_new(server->config.networkLayersSize, &UA_TYPES[UA_TYPES_STRING]);
  482. if(!server->config.applicationDescription.discoveryUrls)
  483. return UA_STATUSCODE_BADOUTOFMEMORY;
  484. server->config.applicationDescription.discoveryUrlsSize = server->config.networkLayersSize;
  485. for(size_t i = 0; i < server->config.applicationDescription.discoveryUrlsSize; i++) {
  486. UA_ServerNetworkLayer *nl = &server->config.networkLayers[i];
  487. UA_String_copy(&nl->discoveryUrl, &server->config.applicationDescription.discoveryUrls[i]);
  488. }
  489. /* Spin up the worker threads */
  490. #if UA_MULTITHREADING >= 200
  491. UA_LOG_INFO(&server->config.logger, UA_LOGCATEGORY_SERVER,
  492. "Spinning up %u worker thread(s)", server->config.nThreads);
  493. UA_WorkQueue_start(&server->workQueue, server->config.nThreads);
  494. #endif
  495. /* Start the multicast discovery server */
  496. #ifdef UA_ENABLE_DISCOVERY_MULTICAST
  497. if(server->config.discovery.mdnsEnable)
  498. startMulticastDiscoveryServer(server);
  499. #endif
  500. server->state = UA_SERVERLIFECYCLE_FRESH;
  501. return result;
  502. }
  503. static void
  504. serverExecuteRepeatedCallback(UA_Server *server, UA_ApplicationCallback cb,
  505. void *callbackApplication, void *data) {
  506. #if UA_MULTITHREADING >= 200
  507. UA_WorkQueue_enqueue(&server->workQueue, cb, callbackApplication, data);
  508. #else
  509. cb(callbackApplication, data);
  510. #endif
  511. }
  512. UA_UInt16
  513. UA_Server_run_iterate(UA_Server *server, UA_Boolean waitInternal) {
  514. /* Process repeated work */
  515. UA_DateTime now = UA_DateTime_nowMonotonic();
  516. UA_DateTime nextRepeated = UA_Timer_process(&server->timer, now,
  517. (UA_TimerExecutionCallback)serverExecuteRepeatedCallback, server);
  518. UA_DateTime latest = now + (UA_MAXTIMEOUT * UA_DATETIME_MSEC);
  519. if(nextRepeated > latest)
  520. nextRepeated = latest;
  521. UA_UInt16 timeout = 0;
  522. /* round always to upper value to avoid timeout to be set to 0
  523. * if(nextRepeated - now) < (UA_DATETIME_MSEC/2) */
  524. if(waitInternal)
  525. timeout = (UA_UInt16)(((nextRepeated - now) + (UA_DATETIME_MSEC - 1)) / UA_DATETIME_MSEC);
  526. /* Listen on the networklayer */
  527. for(size_t i = 0; i < server->config.networkLayersSize; ++i) {
  528. UA_ServerNetworkLayer *nl = &server->config.networkLayers[i];
  529. nl->listen(nl, server, timeout);
  530. }
  531. #if defined(UA_ENABLE_PUBSUB_MQTT)
  532. /* Listen on the pubsublayer, but only if the yield function is set */
  533. UA_PubSubConnection *connection;
  534. TAILQ_FOREACH(connection, &server->pubSubManager.connections, listEntry){
  535. UA_PubSubConnection *ps = connection;
  536. if(ps && ps->channel->yield){
  537. ps->channel->yield(ps->channel, timeout);
  538. }
  539. }
  540. #endif
  541. #if defined(UA_ENABLE_DISCOVERY_MULTICAST) && (UA_MULTITHREADING < 200)
  542. if(server->config.discovery.mdnsEnable) {
  543. // TODO multicastNextRepeat does not consider new input data (requests)
  544. // on the socket. It will be handled on the next call. if needed, we
  545. // need to use select with timeout on the multicast socket
  546. // server->mdnsSocket (see example in mdnsd library) on higher level.
  547. UA_DateTime multicastNextRepeat = 0;
  548. UA_StatusCode hasNext =
  549. iterateMulticastDiscoveryServer(server, &multicastNextRepeat, true);
  550. if(hasNext == UA_STATUSCODE_GOOD && multicastNextRepeat < nextRepeated)
  551. nextRepeated = multicastNextRepeat;
  552. }
  553. #endif
  554. #if UA_MULTITHREADING < 200
  555. UA_WorkQueue_manuallyProcessDelayed(&server->workQueue);
  556. #endif
  557. now = UA_DateTime_nowMonotonic();
  558. timeout = 0;
  559. if(nextRepeated > now)
  560. timeout = (UA_UInt16)((nextRepeated - now) / UA_DATETIME_MSEC);
  561. return timeout;
  562. }
  563. UA_StatusCode
  564. UA_Server_run_shutdown(UA_Server *server) {
  565. /* Stop the netowrk layer */
  566. for(size_t i = 0; i < server->config.networkLayersSize; ++i) {
  567. UA_ServerNetworkLayer *nl = &server->config.networkLayers[i];
  568. nl->stop(nl, server);
  569. }
  570. #if UA_MULTITHREADING >= 200
  571. /* Shut down the workers */
  572. UA_LOG_INFO(&server->config.logger, UA_LOGCATEGORY_SERVER,
  573. "Shutting down %u worker thread(s)",
  574. (UA_UInt32)server->workQueue.workersSize);
  575. UA_WorkQueue_stop(&server->workQueue);
  576. #endif
  577. #ifdef UA_ENABLE_DISCOVERY_MULTICAST
  578. /* Stop multicast discovery */
  579. if(server->config.discovery.mdnsEnable)
  580. stopMulticastDiscoveryServer(server);
  581. #endif
  582. /* Execute all delayed callbacks */
  583. UA_WorkQueue_cleanup(&server->workQueue);
  584. return UA_STATUSCODE_GOOD;
  585. }
  586. static UA_Boolean
  587. testShutdownCondition(UA_Server *server) {
  588. if(server->endTime == 0)
  589. return false;
  590. return (UA_DateTime_now() > server->endTime);
  591. }
  592. UA_StatusCode
  593. UA_Server_run(UA_Server *server, const volatile UA_Boolean *running) {
  594. UA_StatusCode retval = UA_Server_run_startup(server);
  595. if(retval != UA_STATUSCODE_GOOD)
  596. return retval;
  597. #ifdef UA_ENABLE_VALGRIND_INTERACTIVE
  598. size_t loopCount = 0;
  599. #endif
  600. while(!testShutdownCondition(server)) {
  601. #ifdef UA_ENABLE_VALGRIND_INTERACTIVE
  602. if(loopCount == 0) {
  603. VALGRIND_DO_LEAK_CHECK;
  604. }
  605. ++loopCount;
  606. loopCount %= UA_VALGRIND_INTERACTIVE_INTERVAL;
  607. #endif
  608. UA_Server_run_iterate(server, true);
  609. if(!*running) {
  610. if(setServerShutdown(server))
  611. break;
  612. }
  613. }
  614. return UA_Server_run_shutdown(server);
  615. }
  616. #ifdef UA_ENABLE_HISTORIZING
  617. /* Allow insert of historical data */
  618. UA_Boolean
  619. UA_Server_AccessControl_allowHistoryUpdateUpdateData(UA_Server *server,
  620. const UA_NodeId *sessionId, void *sessionContext,
  621. const UA_NodeId *nodeId,
  622. UA_PerformUpdateType performInsertReplace,
  623. const UA_DataValue *value) {
  624. if(server->config.accessControl.allowHistoryUpdateUpdateData &&
  625. !server->config.accessControl.allowHistoryUpdateUpdateData(server, &server->config.accessControl,
  626. sessionId, sessionContext, nodeId,
  627. performInsertReplace, value)) {
  628. return false;
  629. }
  630. return true;
  631. }
  632. /* Allow delete of historical data */
  633. UA_Boolean
  634. UA_Server_AccessControl_allowHistoryUpdateDeleteRawModified(UA_Server *server,
  635. const UA_NodeId *sessionId, void *sessionContext,
  636. const UA_NodeId *nodeId,
  637. UA_DateTime startTimestamp,
  638. UA_DateTime endTimestamp,
  639. bool isDeleteModified) {
  640. if(server->config.accessControl.allowHistoryUpdateDeleteRawModified &&
  641. !server->config.accessControl.allowHistoryUpdateDeleteRawModified(server, &server->config.accessControl,
  642. sessionId, sessionContext, nodeId,
  643. startTimestamp, endTimestamp,
  644. isDeleteModified)) {
  645. return false;
  646. }
  647. return true;
  648. }
  649. #endif /* UA_ENABLE_HISTORIZING */