diff --git a/src/session/gtest_session_table.cpp b/src/session/gtest_session_table.cpp index 4539098..ddc174f 100644 --- a/src/session/gtest_session_table.cpp +++ b/src/session/gtest_session_table.cpp @@ -85,11 +85,11 @@ TEST(SESSION_TABLE, OP_SESSION) session_set_id(sess3, 3); session_set_address(sess3, &sess3_addr); - session_table_add_session(sess_table, sess1); + EXPECT_TRUE(session_table_add_session(sess_table, sess1) == 0); EXPECT_TRUE(session_table_get_count(sess_table) == 1); - session_table_add_session(sess_table, sess2); + EXPECT_TRUE(session_table_add_session(sess_table, sess2) == 0); EXPECT_TRUE(session_table_get_count(sess_table) == 2); - session_table_add_session(sess_table, sess3); + EXPECT_TRUE(session_table_add_session(sess_table, sess3) == 0); EXPECT_TRUE(session_table_get_count(sess_table) == 3); // Search session with id @@ -125,6 +125,73 @@ TEST(SESSION_TABLE, OP_SESSION) session_pool_destroy(sess_pool); } +TEST(SESSION_TABLE, FIND_OLDEST_NEWEST) +{ + struct session *sess1 = NULL; + struct session *sess2 = NULL; + struct session *sess3 = NULL; + struct session_pool *sess_pool = NULL; + struct session_table *sess_table = NULL; + + SESSION_ADDRESS_IPV4_TCP(sess1_addr); + SESSION_ADDRESS_IPV6_UDP(sess2_addr); + SESSION_ADDRESS_IPV4_UDP_IPV6_TCP(sess3_addr); + + // Create + sess_pool = session_pool_create(3); + EXPECT_TRUE(sess_pool != NULL); + sess_table = session_table_create(); + EXPECT_TRUE(sess_table != NULL); + session_table_set_freecb(sess_table, session_free_callback, sess_pool); + + // Add Session + + EXPECT_TRUE(session_table_find_oldest_session(sess_table) == NULL); + EXPECT_TRUE(session_table_find_newest_session(sess_table) == NULL); + + sess1 = session_pool_alloc(sess_pool); + EXPECT_TRUE(sess1 != NULL); + session_set_id(sess1, 1); + session_set_address(sess1, &sess1_addr); + EXPECT_TRUE(session_table_add_session(sess_table, sess1) == 0); + EXPECT_TRUE(session_table_find_oldest_session(sess_table) == sess1); + EXPECT_TRUE(session_table_find_newest_session(sess_table) == sess1); + + sess2 = session_pool_alloc(sess_pool); + EXPECT_TRUE(sess2 != NULL); + session_set_id(sess2, 2); + session_set_address(sess2, &sess2_addr); + EXPECT_TRUE(session_table_add_session(sess_table, sess2) == 0); + EXPECT_TRUE(session_table_find_oldest_session(sess_table) == sess1); + EXPECT_TRUE(session_table_find_newest_session(sess_table) == sess2); + + sess3 = session_pool_alloc(sess_pool); + EXPECT_TRUE(sess3 != NULL); + session_set_id(sess3, 3); + session_set_address(sess3, &sess3_addr); + EXPECT_TRUE(session_table_add_session(sess_table, sess3) == 0); + EXPECT_TRUE(session_table_find_oldest_session(sess_table) == sess1); + EXPECT_TRUE(session_table_find_newest_session(sess_table) == sess3); + + // Delete Session + + session_table_delete_session_by_id(sess_table, 1); + EXPECT_TRUE(session_table_find_oldest_session(sess_table) == sess2); + EXPECT_TRUE(session_table_find_newest_session(sess_table) == sess3); + + session_table_delete_session_by_id(sess_table, 2); + EXPECT_TRUE(session_table_find_oldest_session(sess_table) == sess3); + EXPECT_TRUE(session_table_find_newest_session(sess_table) == sess3); + + session_table_delete_session_by_id(sess_table, 3); + EXPECT_TRUE(session_table_find_oldest_session(sess_table) == NULL); + EXPECT_TRUE(session_table_find_newest_session(sess_table) == NULL); + + // Destroy + session_table_destroy(sess_table); + session_pool_destroy(sess_pool); +} + int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); diff --git a/src/session/session.h b/src/session/session.h index a43acd3..cdb2c0c 100644 --- a/src/session/session.h +++ b/src/session/session.h @@ -8,29 +8,31 @@ extern "C" #include +#include "session_address.h" + enum session_state { + SESSION_STATE_NONE = 0, SESSION_STATE_OPENING, SESSION_STATE_ACTIVE, - SESSION_STATE_DISCARD, SESSION_STATE_CLOSING, - SESSION_STATE_CLOSED, - SESSION_STATE_FREE, + SESSION_STATE_DISCARD, }; enum session_type { + SESSION_TYPE_NONE = 0, SESSION_TYPE_TCP, - SESSION_TYPE_TCP_STREAM, // A TCP stream session is derived from the original TCP session SESSION_TYPE_UDP, }; enum session_event { SESSION_EVENT_NONE = 0, - SESSION_EVENT_OPEN, - SESSION_EVENT_DATA, - SESSION_EVENT_CLOSE, + SESSION_EVENT_OPENING, + SESSION_EVENT_ACTIVE, + SESSION_EVENT_CLOSING, + SESSION_EVENT_DISCARD, SESSION_EVENT_TIMEOUT, // Add new event before SESSION_EVENT_MAX @@ -46,7 +48,7 @@ struct metadata struct session; /****************************************************************************** - * session + * session base info ******************************************************************************/ void session_init(struct session *sess); @@ -84,11 +86,14 @@ struct metadata *session_get0_s2c_1st_md(struct session *sess); // session timestamp void session_set_create_time(struct session *sess, uint64_t timestamp); void session_set_last_time(struct session *sess, uint64_t timestamp); -void session_set_expire_time(struct session *sess, uint64_t timestamp); uint64_t session_get_create_time(struct session *sess); uint64_t session_get_last_time(struct session *sess); uint64_t session_get_expire_time(struct session *sess); +/****************************************************************************** + * session event + ******************************************************************************/ + // session event bool session_push_event(struct session *sess, uint32_t event); bool session_pop_event(struct session *sess, uint32_t *event); diff --git a/src/session/session_address.h b/src/session/session_address.h index 5b45465..b57f4ff 100644 --- a/src/session/session_address.h +++ b/src/session/session_address.h @@ -8,6 +8,8 @@ extern "C" #include +#include "packet.h" + #define SESSION_ADDR_MAX_LAYER 8 enum layer_type diff --git a/src/session/session_pool.cpp b/src/session/session_pool.cpp index b5847a6..1fe3d66 100644 --- a/src/session/session_pool.cpp +++ b/src/session/session_pool.cpp @@ -20,9 +20,9 @@ struct session_pool *session_pool_create(uint64_t count) for (uint64_t i = 0; i < count; i++) { - pool->sess[i].next = &pool->sess[i + 1]; + pool->sess[i].next_free_ptr = &pool->sess[i + 1]; } - pool->sess[count - 1].next = NULL; + pool->sess[count - 1].next_free_ptr = NULL; return pool; } @@ -49,8 +49,8 @@ struct session *session_pool_alloc(struct session_pool *pool) return NULL; } - pool->sess = sess->next; - sess->next = NULL; + pool->sess = sess->next_free_ptr; + sess->next_free_ptr = NULL; pool->count--; return sess; @@ -63,7 +63,7 @@ void session_pool_free(struct session_pool *pool, struct session *sess) return; } - sess->next = pool->sess; + sess->next_free_ptr = pool->sess; pool->sess = sess; pool->count++; } diff --git a/src/session/session_private.h b/src/session/session_private.h index 5138e3f..d478d83 100644 --- a/src/session/session_private.h +++ b/src/session/session_private.h @@ -79,7 +79,7 @@ struct session ******************************/ // session pool recycle handle - struct session *next; + struct session *next_free_ptr; /****************************** * Session Table Zone @@ -89,9 +89,18 @@ struct session uint64_t id; struct session_address addr; + struct session *next_ptr; + struct session *prev_ptr; + // session table handle UT_hash_handle hh1; /* handle for root_id hash table */ UT_hash_handle hh2; /* handle for root_addr hash table */ + + /****************************** + * Session Manager Zone + ******************************/ + + struct session *next_ready_ptr; }; #ifdef __cpluscplus diff --git a/src/session/session_table.cpp b/src/session/session_table.cpp index c76e23e..4e87a9f 100644 --- a/src/session/session_table.cpp +++ b/src/session/session_table.cpp @@ -10,12 +10,71 @@ struct session_table session_free_cb free_cb; void *arg; uint64_t count; + + struct session *oldest_ptr; + struct session *newest_ptr; }; +static void session_table_add_session_to_linklist(struct session_table *table, struct session *sess) +{ + if (table == NULL || sess == NULL) + { + return; + } + + if (table->newest_ptr == NULL) + { + table->oldest_ptr = sess; + table->newest_ptr = sess; + sess->prev_ptr = NULL; + sess->next_ptr = NULL; + } + else + { + sess->next_ptr = table->newest_ptr; + table->newest_ptr->prev_ptr = sess; + sess->prev_ptr = NULL; + table->newest_ptr = sess; + } +} + +static void session_table_del_session_from_linklist(struct session_table *table, struct session *sess) +{ + if (table == NULL || sess == NULL) + { + return; + } + + if (sess->prev_ptr == NULL && sess->next_ptr == NULL) + { + table->oldest_ptr = NULL; + table->newest_ptr = NULL; + } + else if (sess->prev_ptr == NULL && sess->next_ptr != NULL) + { + table->newest_ptr = sess->next_ptr; + sess->next_ptr->prev_ptr = NULL; + } + else if (sess->prev_ptr != NULL && sess->next_ptr == NULL) + { + table->oldest_ptr = sess->prev_ptr; + sess->prev_ptr->next_ptr = NULL; + } + else + { + sess->prev_ptr->next_ptr = sess->next_ptr; + sess->next_ptr->prev_ptr = sess->prev_ptr; + } + sess->prev_ptr = NULL; + sess->next_ptr = NULL; +} + struct session_table *session_table_create() { struct session_table *table = (struct session_table *)calloc(1, sizeof(struct session_table)); table->count = 0; + table->oldest_ptr = NULL; + table->newest_ptr = NULL; return table; } @@ -63,11 +122,16 @@ void session_table_set_freecb(struct session_table *table, session_free_cb free_ } } -void session_table_add_session(struct session_table *table, struct session *sess) +int session_table_add_session(struct session_table *table, struct session *sess) { if (table == NULL || sess == NULL) { - return; + return -1; + } + + if (session_table_find_session_by_id(table, sess->id) || session_table_find_session_by_addr(table, &sess->addr)) + { + return -1; } if (session_address_selfcmp(&sess->addr) > 0) @@ -78,7 +142,11 @@ void session_table_add_session(struct session_table *table, struct session *sess HASH_ADD(hh1, table->root_id, id, sizeof(sess->id), sess); HASH_ADD(hh2, table->root_addr, addr, sizeof(sess->addr), sess); + session_table_add_session_to_linklist(table, sess); + table->count++; + + return 0; } void session_table_delete_session_by_id(struct session_table *table, uint64_t id) @@ -102,6 +170,8 @@ void session_table_delete_session_by_id(struct session_table *table, uint64_t id table->free_cb(sess, table->arg); } + session_table_del_session_from_linklist(table, sess); + table->count--; } @@ -126,6 +196,8 @@ void session_table_delete_session_by_addr(struct session_table *table, struct se table->free_cb(sess, table->arg); } + session_table_del_session_from_linklist(table, sess); + table->count--; } @@ -159,3 +231,23 @@ struct session *session_table_find_session_by_addr(struct session_table *table, return sess; } + +struct session *session_table_find_oldest_session(struct session_table *table) +{ + if (table == NULL) + { + return NULL; + } + + return table->oldest_ptr; +} + +struct session *session_table_find_newest_session(struct session_table *table) +{ + if (table == NULL) + { + return NULL; + } + + return table->newest_ptr; +} \ No newline at end of file diff --git a/src/session/session_table.h b/src/session/session_table.h index 10c607d..680e0f9 100644 --- a/src/session/session_table.h +++ b/src/session/session_table.h @@ -15,16 +15,15 @@ uint64_t session_table_get_count(struct session_table *table); typedef void (*session_free_cb)(struct session *sess, void *arg); void session_table_set_freecb(struct session_table *table, session_free_cb free_cb, void *arg); -/* - * Before add session: - * user must set session id and session address. - * must not add session with same id or same address. - */ -void session_table_add_session(struct session_table *table, struct session *sess); +// return 0: success +// return -1: failed +int session_table_add_session(struct session_table *table, struct session *sess); void session_table_delete_session_by_id(struct session_table *table, uint64_t id); void session_table_delete_session_by_addr(struct session_table *table, struct session_address *addr); struct session *session_table_find_session_by_id(struct session_table *table, uint64_t id); struct session *session_table_find_session_by_addr(struct session_table *table, struct session_address *addr); +struct session *session_table_find_oldest_session(struct session_table *table); +struct session *session_table_find_newest_session(struct session_table *table); #ifdef __cpluscplus }