@@ -25,6 +25,31 @@ removeSessionCallback(UA_Server *server, session_list_entry *entry) {
2525 UA_free (entry );
2626}
2727
28+ static void removeReference (UA_Server * server , session_list_entry * sentry ) {
29+ UA_assert (NULL != server );
30+ UA_assert (NULL != sentry );
31+ UA_LOCK_ASSERT (& server -> serviceMutex , 1 );
32+
33+ if (0 == -- sentry -> nReferences ) {
34+ /* Add a delayed callback to remove the session when the currently
35+ * scheduled jobs have completed */
36+ sentry -> cleanupCallback .callback = (UA_Callback )removeSessionCallback ;
37+ sentry -> cleanupCallback .application = server ;
38+ sentry -> cleanupCallback .context = sentry ;
39+ UA_EventLoop * el = server -> config .eventLoop ;
40+ el -> addDelayedCallback (el , & sentry -> cleanupCallback );
41+ }
42+ }
43+
44+ static void addReference (UA_Server * server , session_list_entry * sentry ) {
45+ UA_assert (NULL != server );
46+ UA_assert (NULL != sentry );
47+ UA_LOCK_ASSERT (& server -> serviceMutex , 1 );
48+
49+ UA_assert (0 < sentry -> nReferences );
50+ ++ sentry -> nReferences ;
51+ }
52+
2853void
2954UA_Server_removeSession (UA_Server * server , session_list_entry * sentry ,
3055 UA_ShutdownReason shutdownReason ) {
@@ -46,12 +71,6 @@ UA_Server_removeSession(UA_Server *server, session_list_entry *sentry,
4671 }
4772#endif
4873
49- /* Callback into userland access control */
50- if (server -> config .accessControl .closeSession ) {
51- server -> config .accessControl .
52- closeSession (server , & server -> config .accessControl ,
53- & session -> sessionId , session -> sessionHandle );
54- }
5574
5675 /* Detach the Session from the SecureChannel */
5776 UA_Session_detachFromSecureChannel (session );
@@ -88,13 +107,7 @@ UA_Server_removeSession(UA_Server *server, session_list_entry *sentry,
88107 break ;
89108 }
90109
91- /* Add a delayed callback to remove the session when the currently
92- * scheduled jobs have completed */
93- sentry -> cleanupCallback .callback = (UA_Callback )removeSessionCallback ;
94- sentry -> cleanupCallback .application = server ;
95- sentry -> cleanupCallback .context = sentry ;
96- UA_EventLoop * el = server -> config .eventLoop ;
97- el -> addDelayedCallback (el , & sentry -> cleanupCallback );
110+ removeReference (server , sentry );
98111}
99112
100113UA_StatusCode
@@ -152,6 +165,40 @@ getSessionByToken(UA_Server *server, const UA_NodeId *token) {
152165 return NULL ;
153166}
154167
168+ session_list_entry * acquireSessionEntryById (UA_Server * server , const UA_NodeId * sessionId , UA_Session * * pSession ) {
169+ UA_assert (NULL != server );
170+ UA_assert (NULL != sessionId );
171+ UA_assert (NULL != pSession );
172+ UA_LOCK_ASSERT (& server -> serviceMutex , 1 );
173+
174+ session_list_entry * current = NULL ;
175+ LIST_FOREACH (current , & server -> sessions , pointers ) {
176+ /* Token does not match */
177+ if (!UA_NodeId_equal (& current -> session .sessionId , sessionId ))
178+ continue ;
179+
180+ /* Session has timed out */
181+ if (UA_DateTime_nowMonotonic () > current -> session .validTill ) {
182+ UA_LOG_INFO_SESSION (server -> config .logging , & current -> session ,
183+ "Client tries to use a session that has timed out" );
184+ return NULL ;
185+ }
186+
187+ addReference (server , current );
188+ * pSession = & current -> session ;
189+ return current ;
190+ }
191+
192+ return NULL ;
193+ }
194+
195+ void releaseSessionEntry (UA_Server * server , session_list_entry * sentry ) {
196+ UA_LOCK_ASSERT (& server -> serviceMutex , 1 );
197+ UA_assert (NULL != server );
198+ UA_assert (NULL != sentry );
199+ removeReference (server , sentry );
200+ }
201+
155202UA_Session *
156203getSessionById (UA_Server * server , const UA_NodeId * sessionId ) {
157204 UA_LOCK_ASSERT (& server -> serviceMutex , 1 );
@@ -238,6 +285,7 @@ UA_Server_createSession(UA_Server *server, UA_SecureChannel *channel,
238285
239286 /* Initialize the Session */
240287 UA_Session_init (& newentry -> session );
288+ newentry -> nReferences = 1 ;
241289 newentry -> session .sessionId = UA_NODEID_GUID (1 , UA_Guid_random ());
242290 newentry -> session .header .authenticationToken = UA_NODEID_GUID (1 , UA_Guid_random ());
243291
@@ -249,6 +297,7 @@ UA_Server_createSession(UA_Server *server, UA_SecureChannel *channel,
249297 /* Attach the session to the channel. But don't activate for now. */
250298 if (channel )
251299 UA_Session_attachToSecureChannel (& newentry -> session , channel );
300+
252301 UA_Session_updateLifetime (& newentry -> session );
253302
254303 /* Add to the server */
0 commit comments