aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosé Bollo <jose.bollo@iot.bzh>2017-11-07 19:25:15 +0100
committerJosé Bollo <jose.bollo@iot.bzh>2017-11-07 19:25:15 +0100
commit9fcc6c5d9cb59065e57fa24a80a8912516c8c20c (patch)
treea61d92e690b739dcf8114fe32233d7826f2ef950
parentef3d8bddfd976643620f56471a4711cd0daa197f (diff)
afb-stub-ws: manage closed sessions
Change-Id: I16620f12719c222c0da03caf330a865149fe9051 Signed-off-by: José Bollo <jose.bollo@iot.bzh>
-rw-r--r--src/afb-session.c86
-rw-r--r--src/afb-session.h2
-rw-r--r--src/afb-stub-ws.c35
3 files changed, 76 insertions, 47 deletions
diff --git a/src/afb-session.c b/src/afb-session.c
index 43e08d48..1cb1d8d8 100644
--- a/src/afb-session.c
+++ b/src/afb-session.c
@@ -36,7 +36,10 @@
#define COOKEYCOUNT 8
#define COOKEYMASK (COOKEYCOUNT - 1)
-#define NOW (time(NULL))
+#define _MAXEXP_ ((time_t)(~(time_t)0))
+#define _MAXEXP2_ ((time_t)((((unsigned long long)_MAXEXP_) >> 1)))
+#define MAX_EXPIRATION (_MAXEXP_ >= 0 ? _MAXEXP_ : _MAXEXP2_)
+#define NOW (time(NULL))
struct cookie
{
@@ -175,20 +178,6 @@ static void destroy (struct afb_session *session)
pthread_mutex_unlock(&sessions.mutex);
}
-// Check if context timeout or not
-static int is_expired (struct afb_session *ctx, time_t now)
-{
- assert (ctx != NULL);
- return ctx->expiration < now;
-}
-
-// Check if context is active or not
-static int is_active (struct afb_session *ctx, time_t now)
-{
- assert (ctx != NULL);
- return ctx->uuid[0] != 0 && ctx->expiration >= now;
-}
-
// Loop on every entry and remove old context sessions.hash
static time_t cleanup ()
{
@@ -202,7 +191,7 @@ static time_t cleanup ()
session = sessions.heads[idx];
while (session) {
next = session->next;
- if (is_expired(session, now))
+ if (session->expiration < now)
afb_session_close(session);
session = next;
}
@@ -210,10 +199,35 @@ static time_t cleanup ()
return now;
}
+static void update_timeout(struct afb_session *session, time_t now, int timeout)
+{
+ time_t expiration;
+
+ /* compute expiration */
+ if (timeout == AFB_SESSION_TIMEOUT_INFINITE)
+ expiration = MAX_EXPIRATION;
+ else {
+ if (timeout == AFB_SESSION_TIMEOUT_DEFAULT)
+ expiration = now + sessions.timeout;
+ else
+ expiration = now + timeout;
+ if (expiration < 0)
+ expiration = MAX_EXPIRATION;
+ }
+
+ /* record the values */
+ session->timeout = timeout;
+ session->expiration = expiration;
+}
+
+static void update_expiration(struct afb_session *session, time_t now)
+{
+ update_timeout(session, now, session->timeout);
+}
+
static struct afb_session *add_session (const char *uuid, int timeout, time_t now, int idx)
{
struct afb_session *session;
- time_t expiration;
/* check arguments */
if (!AFB_SESSION_TIMEOUT_IS_VALID(timeout)
@@ -228,16 +242,6 @@ static struct afb_session *add_session (const char *uuid, int timeout, time_t no
return NULL;
}
- /* compute expiration */
- if (timeout == AFB_SESSION_TIMEOUT_DEFAULT)
- timeout = sessions.timeout;
- expiration = now + timeout;
- if (timeout == AFB_SESSION_TIMEOUT_INFINITE || expiration < 0) {
- expiration = (time_t)(~(time_t)0);
- if (expiration < 0)
- expiration = (time_t)(((unsigned long long)expiration) >> 1);
- }
-
/* allocates a new one */
session = calloc(1, sizeof *session);
if (session == NULL) {
@@ -250,8 +254,7 @@ static struct afb_session *add_session (const char *uuid, int timeout, time_t no
session->refcount = 1;
strcpy(session->uuid, uuid);
strcpy(session->token, sessions.initok);
- session->timeout = timeout;
- session->expiration = expiration;
+ update_timeout(session, now, timeout);
/* link */
session->idx = (char)idx;
@@ -363,7 +366,7 @@ void afb_session_unref(struct afb_session *session)
}
}
-// Free Client Session Context
+// close Client Session Context
void afb_session_close (struct afb_session *session)
{
assert(session != NULL);
@@ -380,14 +383,30 @@ void afb_session_close (struct afb_session *session)
pthread_mutex_unlock(&session->mutex);
}
+// is the session active?
+int afb_session_is_active (struct afb_session *session)
+{
+ assert(session != NULL);
+ return !!session->uuid[0];
+}
+
+// is the session closed?
+int afb_session_is_closed (struct afb_session *session)
+{
+ assert(session != NULL);
+ return !session->uuid[0];
+}
+
// Sample Generic Ping Debug API
int afb_session_check_token (struct afb_session *session, const char *token)
{
assert(session != NULL);
assert(token != NULL);
- // compare current token with previous one
- if (!is_active (session, NOW))
+ if (!session->uuid[0])
+ return 0;
+
+ if (session->expiration < NOW)
return 0;
if (session->token[0] && strcmp (token, session->token) != 0)
@@ -405,8 +424,7 @@ void afb_session_new_token (struct afb_session *session)
new_uuid(session->token);
// keep track of time for session timeout and further clean up
- if (session->timeout != 0)
- session->expiration = NOW + session->timeout;
+ update_expiration(session, NOW);
}
/* Returns the uuid of 'session' */
diff --git a/src/afb-session.h b/src/afb-session.h
index 37cbeeeb..b27cbc80 100644
--- a/src/afb-session.h
+++ b/src/afb-session.h
@@ -35,6 +35,8 @@ extern struct afb_session *afb_session_addref(struct afb_session *session);
extern void afb_session_unref(struct afb_session *session);
extern void afb_session_close(struct afb_session *session);
+extern int afb_session_is_active (struct afb_session *session);
+extern int afb_session_is_closed (struct afb_session *session);
extern int afb_session_check_token(struct afb_session *session, const char *token);
extern void afb_session_new_token(struct afb_session *session);
diff --git a/src/afb-stub-ws.c b/src/afb-stub-ws.c
index ce5b8058..d5355ff8 100644
--- a/src/afb-stub-ws.c
+++ b/src/afb-stub-ws.c
@@ -474,30 +474,39 @@ static void on_subcall(void *closure, struct afb_proto_ws_subcall *subcall, void
static void record_session(struct afb_stub_ws *stubws, struct afb_session *session)
{
- struct server_session *iter;
+ struct server_session *s, **prv;
/* search */
- for (iter = stubws->sessions ; iter ; iter = iter->next)
- if (iter->session == session)
+ prv = &stubws->sessions;
+ while ((s = *prv)) {
+ if (s->session == session)
return;
+ if (afb_session_is_active(s->session))
+ prv = &s->next;
+ else {
+ *prv = s->next;
+ afb_session_addref(s->session);
+ free(s);
+ }
+ }
/* create */
- iter = malloc(sizeof *iter);
- if (iter) {
- iter->session = afb_session_addref(session);
- iter->next = stubws->sessions;
- stubws->sessions = iter;
+ s = malloc(sizeof *s);
+ if (s) {
+ s->session = afb_session_addref(session);
+ s->next = stubws->sessions;
+ stubws->sessions = s;
}
}
static void release_sessions(struct afb_stub_ws *stubws)
{
- struct server_session *iter;
+ struct server_session *s;
- while((iter = stubws->sessions)) {
- stubws->sessions = iter->next;
- afb_session_unref(iter->session);
- free(iter);
+ while((s = stubws->sessions)) {
+ stubws->sessions = s->next;
+ afb_session_unref(s->session);
+ free(s);
}
}