ua_session_manager.c 3.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. #include "ua_session_manager.h"
  2. #include "ua_statuscodes.h"
  3. #include "ua_util.h"
  4. UA_StatusCode UA_SessionManager_init(UA_SessionManager *sessionManager, UA_UInt32 maxSessionCount,
  5. UA_UInt32 maxSessionLifeTime, UA_UInt32 startSessionId) {
  6. LIST_INIT(&sessionManager->sessions);
  7. sessionManager->maxSessionCount = maxSessionCount;
  8. sessionManager->lastSessionId = startSessionId;
  9. sessionManager->maxSessionLifeTime = maxSessionLifeTime;
  10. sessionManager->currentSessionCount = 0;
  11. return UA_STATUSCODE_GOOD;
  12. }
  13. void UA_SessionManager_deleteMembers(UA_SessionManager *sessionManager) {
  14. session_list_entry *current;
  15. while((current = LIST_FIRST(&sessionManager->sessions))) {
  16. LIST_REMOVE(current, pointers);
  17. UA_Session_deleteMembersCleanup(&current->session);
  18. UA_free(current);
  19. }
  20. }
  21. void UA_SessionManager_cleanupTimedOut(UA_SessionManager *sessionManager, UA_DateTime now) {
  22. session_list_entry *sentry = LIST_FIRST(&sessionManager->sessions);
  23. while(sentry) {
  24. if(sentry->session.validTill < now) {
  25. session_list_entry *next = LIST_NEXT(sentry, pointers);
  26. LIST_REMOVE(sentry, pointers);
  27. UA_Session_deleteMembersCleanup(&sentry->session);
  28. UA_free(sentry);
  29. sessionManager->currentSessionCount--;
  30. sentry = next;
  31. } else {
  32. sentry = LIST_NEXT(sentry, pointers);
  33. }
  34. }
  35. }
  36. UA_Session * UA_SessionManager_getSession(UA_SessionManager *sessionManager, const UA_NodeId *token) {
  37. session_list_entry *current = UA_NULL;
  38. LIST_FOREACH(current, &sessionManager->sessions, pointers) {
  39. if(UA_NodeId_equal(&current->session.authenticationToken, token))
  40. break;
  41. }
  42. if(!current || UA_DateTime_now() > current->session.validTill)
  43. return UA_NULL;
  44. return &current->session;
  45. }
  46. /** Creates and adds a session. But it is not yet attached to a secure channel. */
  47. UA_StatusCode UA_SessionManager_createSession(UA_SessionManager *sessionManager, UA_SecureChannel *channel,
  48. const UA_CreateSessionRequest *request, UA_Session **session) {
  49. if(sessionManager->currentSessionCount >= sessionManager->maxSessionCount)
  50. return UA_STATUSCODE_BADTOOMANYSESSIONS;
  51. session_list_entry *newentry = UA_malloc(sizeof(session_list_entry));
  52. if(!newentry)
  53. return UA_STATUSCODE_BADOUTOFMEMORY;
  54. sessionManager->currentSessionCount++;
  55. UA_Session_init(&newentry->session);
  56. newentry->session.sessionId = UA_NODEID_NUMERIC(1, sessionManager->lastSessionId++);
  57. UA_UInt32 randSeed = sessionManager->lastSessionId;
  58. newentry->session.authenticationToken = UA_NODEID_GUID(1, UA_Guid_random(&randSeed));
  59. if(request->requestedSessionTimeout <= sessionManager->maxSessionLifeTime &&
  60. request->requestedSessionTimeout > 0)
  61. newentry->session.timeout = request->requestedSessionTimeout;
  62. else
  63. newentry->session.timeout = sessionManager->maxSessionLifeTime; // todo: remove when the CTT is fixed
  64. UA_Session_updateLifetime(&newentry->session);
  65. LIST_INSERT_HEAD(&sessionManager->sessions, newentry, pointers);
  66. *session = &newentry->session;
  67. return UA_STATUSCODE_GOOD;
  68. }
  69. UA_StatusCode UA_SessionManager_removeSession(UA_SessionManager *sessionManager, const UA_NodeId *token) {
  70. session_list_entry *current;
  71. LIST_FOREACH(current, &sessionManager->sessions, pointers) {
  72. if(UA_NodeId_equal(&current->session.authenticationToken, token))
  73. break;
  74. }
  75. if(!current)
  76. return UA_STATUSCODE_BADSESSIONIDINVALID;
  77. LIST_REMOVE(current, pointers);
  78. UA_Session_deleteMembersCleanup(&current->session);
  79. UA_free(current);
  80. sessionManager->currentSessionCount--;
  81. return UA_STATUSCODE_GOOD;
  82. }