ua_session_manager.c 4.2 KB

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