ua_session_manager.c 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #include "ua_session_manager.h"
  2. #include "ua_statuscodes.h"
  3. #include "ua_util.h"
  4. /**
  5. The functions in this file are not thread-safe. For multi-threaded access, a
  6. second implementation should be provided. See for example, how a nodestore
  7. implementation is choosen based on whether multithreading is enabled or not.
  8. */
  9. UA_StatusCode UA_SessionManager_init(UA_SessionManager *sessionManager, UA_UInt32 maxSessionCount,
  10. UA_UInt32 maxSessionLifeTime, UA_UInt32 startSessionId) {
  11. LIST_INIT(&sessionManager->sessions);
  12. sessionManager->maxSessionCount = maxSessionCount;
  13. sessionManager->lastSessionId = startSessionId;
  14. sessionManager->maxSessionLifeTime = maxSessionLifeTime;
  15. sessionManager->currentSessionCount = 0;
  16. return UA_STATUSCODE_GOOD;
  17. }
  18. void UA_SessionManager_deleteMembers(UA_SessionManager *sessionManager) {
  19. session_list_entry *current, *next = LIST_FIRST(&sessionManager->sessions);
  20. while(next) {
  21. current = next;
  22. next = LIST_NEXT(current, pointers);
  23. LIST_REMOVE(current, pointers);
  24. //if(current->session.channel)
  25. // current->session.channel->session = UA_NULL; // the channel is no longer attached to a session
  26. UA_Session_deleteMembers(&current->session);
  27. UA_free(current);
  28. }
  29. }
  30. UA_Session * UA_SessionManager_getSession(UA_SessionManager *sessionManager,
  31. const UA_NodeId *token) {
  32. session_list_entry *current = UA_NULL;
  33. LIST_FOREACH(current, &sessionManager->sessions, pointers) {
  34. if(UA_NodeId_equal(&current->session.authenticationToken, token))
  35. break;
  36. }
  37. if(!current || UA_DateTime_now() > current->session.validTill)
  38. return UA_NULL;
  39. return &current->session;
  40. }
  41. /** Creates and adds a session. */
  42. UA_StatusCode
  43. UA_SessionManager_createSession(UA_SessionManager *sessionManager, UA_SecureChannel *channel,
  44. const UA_CreateSessionRequest *request, UA_Session **session)
  45. {
  46. if(sessionManager->currentSessionCount >= sessionManager->maxSessionCount)
  47. return UA_STATUSCODE_BADTOOMANYSESSIONS;
  48. session_list_entry *newentry = UA_malloc(sizeof(session_list_entry));
  49. if(!newentry)
  50. return UA_STATUSCODE_BADOUTOFMEMORY;
  51. UA_Session_init(&newentry->session);
  52. newentry->session.sessionId = UA_NODEID_NUMERIC(1, sessionManager->lastSessionId++);
  53. newentry->session.authenticationToken = UA_NODEID_NUMERIC(1, sessionManager->lastSessionId);
  54. newentry->session.channel = channel;
  55. newentry->session.timeout =
  56. (request->requestedSessionTimeout <= sessionManager->maxSessionLifeTime &&
  57. request->requestedSessionTimeout>0) ?
  58. request->requestedSessionTimeout : sessionManager->maxSessionLifeTime;
  59. UA_Session_updateLifetime(&newentry->session);
  60. sessionManager->currentSessionCount++;
  61. LIST_INSERT_HEAD(&sessionManager->sessions, newentry, pointers);
  62. *session = &newentry->session;
  63. return UA_STATUSCODE_GOOD;
  64. }
  65. UA_StatusCode
  66. UA_SessionManager_removeSession(UA_SessionManager *sessionManager, const UA_NodeId *sessionId)
  67. {
  68. session_list_entry *current = UA_NULL;
  69. LIST_FOREACH(current, &sessionManager->sessions, pointers) {
  70. if(UA_NodeId_equal(&current->session.sessionId, sessionId))
  71. break;
  72. }
  73. if(!current)
  74. return UA_STATUSCODE_BADINTERNALERROR;
  75. LIST_REMOVE(current, pointers);
  76. UA_SecureChannel_detachSession(current->session.channel);
  77. UA_Session_deleteMembers(&current->session);
  78. UA_free(current);
  79. return UA_STATUSCODE_GOOD;
  80. }