ua_server.c 31 KB

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