summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorluwenpeng <[email protected]>2023-12-13 19:20:34 +0800
committerluwenpeng <[email protected]>2023-12-13 19:20:34 +0800
commit5620ac211be1d2ab9a9362b2dfc245214b838bbd (patch)
tree98489e5a889da38cbd405eb43b50552d577eb9a5
parent1aecef82d65f79325d821b4a0bf34af5757838ec (diff)
Add session manager
-rw-r--r--src/session/CMakeLists.txt4
-rw-r--r--src/session/gtest_session_timer.cpp24
-rw-r--r--src/session/session.cpp17
-rw-r--r--src/session/session.h4
-rw-r--r--src/session/session_manager.cpp252
-rw-r--r--src/session/session_manager.h36
-rw-r--r--src/session/session_private.h13
-rw-r--r--src/session/session_timer.cpp2
8 files changed, 320 insertions, 32 deletions
diff --git a/src/session/CMakeLists.txt b/src/session/CMakeLists.txt
index 48aae7e..cdecb25 100644
--- a/src/session/CMakeLists.txt
+++ b/src/session/CMakeLists.txt
@@ -7,11 +7,13 @@ add_library(session_manager
session_address.cpp
session_pool.cpp
session_table.cpp
- session_timer.cpp)
+ session_timer.cpp
+ session_manager.cpp)
target_include_directories(session_manager PUBLIC ${CMAKE_SOURCE_DIR}/deps/uthash)
target_include_directories(session_manager PUBLIC ${CMAKE_SOURCE_DIR}/deps/timeout)
target_include_directories(session_manager PUBLIC ${CMAKE_SOURCE_DIR}/src/packet)
target_include_directories(session_manager PUBLIC ${CMAKE_SOURCE_DIR}/src/session)
+target_include_directories(session_manager PUBLIC ${CMAKE_SOURCE_DIR}/src/timestamp)
target_link_libraries(session_manager timeout)
###############################################################################
diff --git a/src/session/gtest_session_timer.cpp b/src/session/gtest_session_timer.cpp
index 25acbc2..d0ac47b 100644
--- a/src/session/gtest_session_timer.cpp
+++ b/src/session/gtest_session_timer.cpp
@@ -3,7 +3,7 @@
#include "session_timer.h"
#include "session_private.h"
-static void session_expire(struct session *sess)
+static void session_expire(struct session *sess, void *arg)
{
printf("=== session %lu expired ===\n", session_get_id(sess));
}
@@ -16,7 +16,7 @@ TEST(SESSION_TIMER, ADD_DEL)
session_init(&sess);
session_set_id(&sess, 1);
- session_set_expirecb(&sess, session_expire, 1000);
+ session_set_expirecb(&sess, session_expire, NULL, 1000);
session_timer_add_session(timer, &sess);
session_timer_del_session(timer, &sess);
@@ -39,9 +39,9 @@ TEST(SESSION_TIMER, EXPIRE)
session_set_id(&sess1, 1);
session_set_id(&sess2, 2);
session_set_id(&sess3, 3);
- session_set_expirecb(&sess1, session_expire, 5);
- session_set_expirecb(&sess2, session_expire, 5);
- session_set_expirecb(&sess3, session_expire, 10);
+ session_set_expirecb(&sess1, session_expire, NULL, 5);
+ session_set_expirecb(&sess2, session_expire, NULL, 5);
+ session_set_expirecb(&sess3, session_expire, NULL, 10);
session_timer_add_session(timer, &sess1);
session_timer_add_session(timer, &sess2);
@@ -78,9 +78,9 @@ TEST(SESSION_TIMER, BEFORE_EXPIRE_DEL)
session_set_id(&sess1, 1);
session_set_id(&sess2, 2);
session_set_id(&sess3, 3);
- session_set_expirecb(&sess1, session_expire, 5);
- session_set_expirecb(&sess2, session_expire, 5);
- session_set_expirecb(&sess3, session_expire, 10);
+ session_set_expirecb(&sess1, session_expire, NULL, 5);
+ session_set_expirecb(&sess2, session_expire, NULL, 5);
+ session_set_expirecb(&sess3, session_expire, NULL, 10);
session_timer_add_session(timer, &sess1);
session_timer_add_session(timer, &sess2);
@@ -122,9 +122,9 @@ TEST(SESSION_TIMER, BEFORE_EXPIRE_UPDATE)
session_set_id(&sess1, 1);
session_set_id(&sess2, 2);
session_set_id(&sess3, 3);
- session_set_expirecb(&sess1, session_expire, 5);
- session_set_expirecb(&sess2, session_expire, 5);
- session_set_expirecb(&sess3, session_expire, 10);
+ session_set_expirecb(&sess1, session_expire, NULL, 5);
+ session_set_expirecb(&sess2, session_expire, NULL, 5);
+ session_set_expirecb(&sess3, session_expire, NULL, 10);
session_timer_add_session(timer, &sess1);
session_timer_add_session(timer, &sess2);
@@ -137,7 +137,7 @@ TEST(SESSION_TIMER, BEFORE_EXPIRE_UPDATE)
{
printf("update timer 2\n");
session_timer_del_session(timer, &sess2);
- session_set_expirecb(&sess2, session_expire, 8);
+ session_set_expirecb(&sess2, session_expire, NULL, 8);
session_timer_add_session(timer, &sess2);
}
do
diff --git a/src/session/session.cpp b/src/session/session.cpp
index 6dcf6e3..882c43e 100644
--- a/src/session/session.cpp
+++ b/src/session/session.cpp
@@ -300,13 +300,15 @@ void session_free_ex_data(struct session *sess, uint8_t idx)
******************************************************************************/
// session expire
-void session_set_expirecb(struct session *sess, session_expire_cb fn, uint64_t abs_expire_ts)
+void session_set_expirecb(struct session *sess, session_expire_cb expire_cb, void *expire_arg, uint64_t expire_abs_ts)
{
struct timeout *timeout = &sess->timeout;
timeout_init(timeout, TIMEOUT_ABS);
- timeout_setcb(timeout, fn, sess);
- sess->abs_expire_ts = abs_expire_ts;
+ timeout_setcb(timeout, NULL, sess);
+ sess->expire_cb = expire_cb;
+ sess->expire_arg = expire_arg;
+ sess->expire_abs_ts = expire_abs_ts;
}
void session_del_expirecb(struct session *sess)
@@ -314,14 +316,15 @@ void session_del_expirecb(struct session *sess)
struct timeout *timeout = &sess->timeout;
timeout_init(timeout, 0);
- sess->abs_expire_ts = 0;
+ sess->expire_cb = NULL;
+ sess->expire_arg = NULL;
+ sess->expire_abs_ts = 0;
}
void session_run_expirecb(struct session *sess)
{
- struct timeout *timeout = &sess->timeout;
- if (timeout->callback.fn)
+ if (sess->expire_cb)
{
- timeout->callback.fn(timeout->callback.arg);
+ sess->expire_cb(sess, sess->expire_arg);
}
} \ No newline at end of file
diff --git a/src/session/session.h b/src/session/session.h
index cdb2c0c..5d8e912 100644
--- a/src/session/session.h
+++ b/src/session/session.h
@@ -132,10 +132,10 @@ void session_free_ex_data(struct session *sess, uint8_t idx);
* session expire
******************************************************************************/
-typedef void (*session_expire_cb)(struct session *sess);
+typedef void (*session_expire_cb)(struct session *sess, void *arg);
// session timer
-void session_set_expirecb(struct session *sess, session_expire_cb fn, uint64_t abs_timeout_ts);
+void session_set_expirecb(struct session *sess, session_expire_cb expire_cb, void *expire_arg, uint64_t expire_abs_ts);
void session_del_expirecb(struct session *sess);
void session_run_expirecb(struct session *sess);
diff --git a/src/session/session_manager.cpp b/src/session/session_manager.cpp
new file mode 100644
index 0000000..67e1709
--- /dev/null
+++ b/src/session/session_manager.cpp
@@ -0,0 +1,252 @@
+#include <stdlib.h>
+#include <assert.h>
+
+#include "timestamp.h"
+#include "session_manager.h"
+#include "session_pool.h"
+#include "session_table.h"
+#include "session_timer.h"
+#include "session_private.h"
+
+struct session_manager
+{
+ struct session_pool *sess_pool;
+ struct session_table *sess_table;
+ struct session_timer *sess_timer;
+
+ session_event_cb event_cb;
+ void *arg;
+
+ struct session *queue_head_ptr;
+ struct session *queue_tail_ptr;
+};
+
+#define HANDSHAKE_TIMEOUT_MS (5 * 1000)
+#define DATA_TIMEOUT_MS (60 * 1000)
+
+/******************************************************************************
+ * private API
+ ******************************************************************************/
+
+static void session_manager_handle_new_session(struct session_manager *mgr, struct session *sess, const struct packet *pkt, struct session_address *addr)
+{
+ // TODO
+}
+
+static void session_manager_handle_old_session(struct session_manager *mgr, struct session *sess, const struct packet *pkt, struct session_address *addr)
+{
+ // TODO
+}
+
+// Enqueue ready session to queue tail
+static void session_manager_enqueue_ready_session(struct session_manager *mgr, struct session *sess)
+{
+ if (mgr == NULL || sess == NULL)
+ {
+ return;
+ }
+
+ if (mgr->queue_head_ptr == NULL)
+ {
+ mgr->queue_head_ptr = sess;
+ mgr->queue_tail_ptr = sess;
+ sess->next_ready_ptr = NULL;
+ }
+ else
+ {
+ mgr->queue_tail_ptr->next_ready_ptr = sess;
+ mgr->queue_tail_ptr = sess;
+ sess->next_ready_ptr = NULL;
+ }
+}
+
+// Dequeue ready session from queue head
+struct session *session_manager_ready_session_dequeue(struct session_manager *mgr)
+{
+ if (mgr == NULL)
+ {
+ return NULL;
+ }
+
+ struct session *sess = mgr->queue_head_ptr;
+ if (sess == NULL)
+ {
+ return NULL;
+ }
+
+ if (mgr->queue_head_ptr == mgr->queue_tail_ptr)
+ {
+ mgr->queue_head_ptr = NULL;
+ mgr->queue_tail_ptr = NULL;
+ }
+ else
+ {
+ mgr->queue_head_ptr = sess->next_ready_ptr;
+ }
+
+ sess->next_ready_ptr = NULL;
+ return sess;
+}
+
+// handshake expire set to discard
+static void handshake_expire_cb(struct session *sess, void *arg)
+{
+ struct session_manager *mgr = (struct session_manager *)arg;
+ assert(mgr != NULL);
+
+ session_set_state(sess, SESSION_STATE_DISCARD);
+ session_push_event(sess, SESSION_EVENT_DISCARD);
+ session_manager_enqueue_ready_session(mgr, sess);
+}
+
+// data expire set to closing
+static void data_expire_cb(struct session *sess, void *arg)
+{
+ struct session_manager *mgr = (struct session_manager *)arg;
+ assert(mgr != NULL);
+
+ session_set_state(sess, SESSION_STATE_CLOSING);
+ session_push_event(sess, SESSION_EVENT_CLOSING);
+ session_manager_enqueue_ready_session(mgr, sess);
+}
+
+/******************************************************************************
+ * public API
+ ******************************************************************************/
+
+struct session_manager *session_manager_create(uint64_t max_session_num)
+{
+ struct session_manager *mgr = (struct session_manager *)calloc(1, sizeof(struct session_manager));
+ if (mgr == NULL)
+ {
+ return NULL;
+ }
+
+ mgr->sess_pool = session_pool_create(max_session_num);
+ if (mgr->sess_pool == NULL)
+ {
+ goto error;
+ }
+
+ mgr->sess_table = session_table_create();
+ if (mgr->sess_table == NULL)
+ {
+ goto error;
+ }
+
+ mgr->sess_timer = session_timer_create();
+ if (mgr->sess_timer == NULL)
+ {
+ goto error;
+ }
+
+ mgr->queue_head_ptr = NULL;
+ mgr->queue_tail_ptr = NULL;
+
+ return mgr;
+
+error:
+ session_manager_destroy(mgr);
+ return NULL;
+}
+
+void session_manager_destroy(struct session_manager *mgr)
+{
+ if (mgr)
+ {
+ session_timer_destroy(mgr->sess_timer);
+ session_table_destroy(mgr->sess_table);
+ session_pool_destroy(mgr->sess_pool);
+ free(mgr);
+ mgr = NULL;
+ }
+}
+
+void session_manager_set_session_eventcb(struct session_manager *mgr, session_event_cb cb, void *arg)
+{
+ mgr->event_cb = cb;
+ mgr->arg = arg;
+}
+
+struct session *session_manager_find_session_by_id(struct session_manager *mgr, uint64_t id)
+{
+ struct session *sess = session_table_find_session_by_id(mgr->sess_table, id);
+ if (sess)
+ {
+ session_set_last_time(sess, timestamp_get_msec());
+ // TODO
+ }
+
+ return sess;
+}
+
+struct session *session_manager_find_session_by_packet(struct session_manager *mgr, const struct packet *pkt)
+{
+ struct session_address addr;
+ session_address_init(&addr, pkt);
+
+ struct session *sess = session_table_find_session_by_addr(mgr->sess_table, &addr);
+ if (sess == NULL)
+ {
+ if (session_pool_get_count(mgr->sess_pool) == 1)
+ {
+ struct session *oldest_sess = session_table_find_oldest_session(mgr->sess_table);
+ assert(oldest_sess == NULL);
+ session_set_state(oldest_sess, SESSION_STATE_DISCARD);
+ session_push_event(oldest_sess, SESSION_EVENT_DISCARD);
+ session_manager_enqueue_ready_session(mgr, oldest_sess);
+ }
+
+ sess = session_pool_alloc(mgr->sess_pool);
+ assert(sess != NULL);
+
+ session_manager_handle_new_session(mgr, sess, pkt, &addr);
+ }
+ else
+ {
+ session_manager_handle_old_session(mgr, sess, pkt, &addr);
+ }
+
+ return sess;
+}
+
+void session_manager_dispatch(struct session_manager *mgr)
+{
+ uint32_t event;
+ struct session *sess;
+
+ void *cb_arg = mgr->arg;
+ session_event_cb event_cb = mgr->event_cb;
+
+ while (1)
+ {
+ sess = session_timer_expire_session(mgr->sess_timer, timestamp_get_msec());
+ if (sess == NULL)
+ {
+ break;
+ }
+ session_run_expirecb(sess);
+ }
+
+ while (1)
+ {
+ sess = session_manager_ready_session_dequeue(mgr);
+ if (sess == NULL)
+ {
+ break;
+ }
+
+ while (1)
+ {
+ if (session_pop_event(sess, &event) == false)
+ {
+ break;
+ }
+
+ if (event_cb)
+ {
+ event_cb(sess, event, cb_arg);
+ }
+ }
+ };
+}
diff --git a/src/session/session_manager.h b/src/session/session_manager.h
new file mode 100644
index 0000000..c9c6b35
--- /dev/null
+++ b/src/session/session_manager.h
@@ -0,0 +1,36 @@
+#ifndef _SESSION_MANAGER_H
+#define _SESSION_MANAGER_H
+
+#ifdef __cpluscplus
+extern "C"
+{
+#endif
+
+#include "session.h"
+
+/*
+ * session manager = session pool + session table + session timer
+ *
+ * session pool : alloc and free session
+ * session table : find session by session id or session addr
+ * session timer : session timeout
+ * session manager: manage session pool, session table and session timer
+ */
+
+struct session_manager;
+struct session_manager *session_manager_create(uint64_t max_session_num);
+void session_manager_destroy(struct session_manager *mgr);
+
+typedef void (*session_event_cb)(struct session *sess, uint32_t event, void *arg);
+void session_manager_set_session_eventcb(struct session_manager *mgr, session_event_cb cb, void *arg);
+
+struct session *session_manager_find_session_by_id(struct session_manager *mgr, uint64_t id);
+struct session *session_manager_find_session_by_packet(struct session_manager *mgr, const struct packet *pkt);
+
+void session_manager_dispatch(struct session_manager *mgr);
+
+#ifdef __cpluscplus
+}
+#endif
+
+#endif
diff --git a/src/session/session_private.h b/src/session/session_private.h
index d478d83..3d8174e 100644
--- a/src/session/session_private.h
+++ b/src/session/session_private.h
@@ -10,18 +10,11 @@ extern "C"
{
#endif
+#include "timeout.h"
#include "uthash.h"
#include "session.h"
#include "session_address.h"
-#define TIMEOUT_CB_OVERRIDE
-struct timeout_cb
-{
- session_expire_cb fn;
- struct session *arg;
-};
-#include "timeout.h"
-
#define EX_DATA_MAX_COUNT 128
#define SESSION_EVENT_QUEUE_SIZE 256
@@ -72,7 +65,9 @@ struct session
// session timer
struct timeout timeout;
- uint64_t abs_expire_ts;
+ session_expire_cb expire_cb;
+ void *expire_arg;
+ uint64_t expire_abs_ts;
/******************************
* Session Pool Zone
diff --git a/src/session/session_timer.cpp b/src/session/session_timer.cpp
index 4938894..1bb7f23 100644
--- a/src/session/session_timer.cpp
+++ b/src/session/session_timer.cpp
@@ -45,7 +45,7 @@ void session_timer_destroy(struct session_timer *timer)
void session_timer_add_session(struct session_timer *timer, struct session *sess)
{
struct timeout *timeout = &sess->timeout;
- timeouts_add(timer->timeouts, timeout, sess->abs_expire_ts);
+ timeouts_add(timer->timeouts, timeout, sess->expire_abs_ts);
}
void session_timer_del_session(struct session_timer *timer, struct session *sess)