ua_session_manager.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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. #include "ua_session_manager.h"
  5. #include "ua_server_internal.h"
  6. UA_StatusCode
  7. UA_SessionManager_init(UA_SessionManager *sm, UA_Server *server) {
  8. LIST_INIT(&sm->sessions);
  9. sm->currentSessionCount = 0;
  10. sm->server = server;
  11. return UA_STATUSCODE_GOOD;
  12. }
  13. void UA_SessionManager_deleteMembers(UA_SessionManager *sm) {
  14. session_list_entry *current, *temp;
  15. LIST_FOREACH_SAFE(current, &sm->sessions, pointers, temp) {
  16. LIST_REMOVE(current, pointers);
  17. UA_Session_deleteMembersCleanup(&current->session, sm->server);
  18. UA_free(current);
  19. }
  20. }
  21. static void
  22. removeSessionEntry(UA_SessionManager *sm, session_list_entry *sentry) {
  23. LIST_REMOVE(sentry, pointers);
  24. UA_atomic_add(&sm->currentSessionCount, (UA_UInt32)-1);
  25. UA_Session_deleteMembersCleanup(&sentry->session, sm->server);
  26. #ifndef UA_ENABLE_MULTITHREADING
  27. UA_free(sentry);
  28. #else
  29. UA_Server_delayedFree(sm->server, sentry);
  30. #endif
  31. }
  32. void UA_SessionManager_cleanupTimedOut(UA_SessionManager *sm, UA_DateTime nowMonotonic) {
  33. session_list_entry *sentry, *temp;
  34. LIST_FOREACH_SAFE(sentry, &sm->sessions, pointers, temp) {
  35. if(sentry->session.validTill < nowMonotonic) {
  36. UA_LOG_DEBUG(sm->server->config.logger, UA_LOGCATEGORY_SESSION,
  37. "Session with token %i has timed out and is removed",
  38. sentry->session.sessionId.identifier.numeric);
  39. removeSessionEntry(sm, sentry);
  40. }
  41. }
  42. }
  43. UA_Session *
  44. UA_SessionManager_getSession(UA_SessionManager *sm, const UA_NodeId *token) {
  45. session_list_entry *current = NULL;
  46. LIST_FOREACH(current, &sm->sessions, pointers) {
  47. if(UA_NodeId_equal(&current->session.authenticationToken, token)) {
  48. if(UA_DateTime_nowMonotonic() > current->session.validTill) {
  49. UA_LOG_DEBUG(sm->server->config.logger, UA_LOGCATEGORY_SESSION,
  50. "Try to use Session with token " UA_PRINTF_GUID_FORMAT ", but has timed out",
  51. UA_PRINTF_GUID_DATA(token->identifier.guid));
  52. return NULL;
  53. }
  54. return &current->session;
  55. }
  56. }
  57. UA_LOG_DEBUG(sm->server->config.logger, UA_LOGCATEGORY_SESSION,
  58. "Try to use Session with token " UA_PRINTF_GUID_FORMAT " but is not found",
  59. UA_PRINTF_GUID_DATA(token->identifier.guid));
  60. return NULL;
  61. }
  62. /* Creates and adds a session. But it is not yet attached to a secure channel. */
  63. UA_StatusCode
  64. UA_SessionManager_createSession(UA_SessionManager *sm, UA_SecureChannel *channel,
  65. const UA_CreateSessionRequest *request, UA_Session **session) {
  66. if(sm->currentSessionCount >= sm->server->config.maxSessions)
  67. return UA_STATUSCODE_BADTOOMANYSESSIONS;
  68. session_list_entry *newentry = (session_list_entry *)UA_malloc(sizeof(session_list_entry));
  69. if(!newentry)
  70. return UA_STATUSCODE_BADOUTOFMEMORY;
  71. UA_atomic_add(&sm->currentSessionCount, 1);
  72. UA_Session_init(&newentry->session);
  73. newentry->session.sessionId = UA_NODEID_GUID(1, UA_Guid_random());
  74. newentry->session.authenticationToken = UA_NODEID_GUID(1, UA_Guid_random());
  75. if(request->requestedSessionTimeout <= sm->server->config.maxSessionTimeout &&
  76. request->requestedSessionTimeout > 0)
  77. newentry->session.timeout = request->requestedSessionTimeout;
  78. else
  79. newentry->session.timeout = sm->server->config.maxSessionTimeout;
  80. UA_Session_updateLifetime(&newentry->session);
  81. LIST_INSERT_HEAD(&sm->sessions, newentry, pointers);
  82. *session = &newentry->session;
  83. return UA_STATUSCODE_GOOD;
  84. }
  85. UA_StatusCode
  86. UA_SessionManager_removeSession(UA_SessionManager *sm, const UA_NodeId *token) {
  87. session_list_entry *current;
  88. LIST_FOREACH(current, &sm->sessions, pointers) {
  89. if(UA_NodeId_equal(&current->session.authenticationToken, token))
  90. break;
  91. }
  92. if(!current)
  93. return UA_STATUSCODE_BADSESSIONIDINVALID;
  94. removeSessionEntry(sm, current);
  95. return UA_STATUSCODE_GOOD;
  96. }