Replace session queue with kernel list
This commit is contained in:
@@ -3,7 +3,6 @@ add_library(session_manager
|
||||
session_pool.cpp
|
||||
session_table.cpp
|
||||
session_timer.cpp
|
||||
session_queue.cpp
|
||||
session_manager.cpp
|
||||
session_transition.cpp
|
||||
)
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include "session_pool.h"
|
||||
#include "session_table.h"
|
||||
#include "session_timer.h"
|
||||
#include "session_queue.h"
|
||||
#include "session_manager.h"
|
||||
#include "session_private.h"
|
||||
#include "session_transition.h"
|
||||
@@ -40,7 +39,7 @@ struct session_manager
|
||||
struct session_table *tcp_sess_table;
|
||||
struct session_table *udp_sess_table;
|
||||
struct session_timer *sess_timer;
|
||||
struct session_queue *sess_evicte_queue;
|
||||
struct list_head evicte_queue;
|
||||
|
||||
struct duplicated_packet_filter *dup_pkt_filter;
|
||||
struct evicted_session_filter *evicte_sess_filter;
|
||||
@@ -467,7 +466,7 @@ static void session_manager_evicte_session(struct session_manager *mgr, struct s
|
||||
|
||||
session_timer_del(mgr->sess_timer, sess);
|
||||
session_set_closing_reason(sess, CLOSING_BY_EVICTED);
|
||||
session_queue_push(mgr->sess_evicte_queue, sess);
|
||||
list_add_tail(&sess->evicte, &mgr->evicte_queue);
|
||||
|
||||
switch (session_get_type(sess))
|
||||
{
|
||||
@@ -725,14 +724,14 @@ struct session_manager *session_manager_new(struct session_manager_options *opts
|
||||
mgr->tcp_sess_table = session_table_new();
|
||||
mgr->udp_sess_table = session_table_new();
|
||||
mgr->sess_timer = session_timer_new();
|
||||
mgr->sess_evicte_queue = session_queue_new();
|
||||
mgr->dup_pkt_filter = duplicated_packet_filter_new(&duplicated_packet_filter_opts, now);
|
||||
mgr->evicte_sess_filter = evicted_session_filter_new(&evicted_session_filter_opts, now);
|
||||
if (mgr->sess_pool == NULL || mgr->tcp_sess_table == NULL || mgr->udp_sess_table == NULL || mgr->sess_timer == NULL || mgr->sess_evicte_queue == NULL || mgr->dup_pkt_filter == NULL || mgr->evicte_sess_filter == NULL)
|
||||
if (mgr->sess_pool == NULL || mgr->tcp_sess_table == NULL || mgr->udp_sess_table == NULL || mgr->sess_timer == NULL || mgr->dup_pkt_filter == NULL || mgr->evicte_sess_filter == NULL)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&mgr->evicte_queue);
|
||||
session_filter_init();
|
||||
session_transition_init();
|
||||
tcp_flags_idx = session_get_ex_new_index("tcp_flags", NULL, NULL);
|
||||
@@ -750,8 +749,10 @@ void session_manager_free(struct session_manager *mgr)
|
||||
if (mgr)
|
||||
{
|
||||
// free all evicted session
|
||||
while (mgr->sess_evicte_queue && (sess = session_manager_get_evicted_session(mgr)))
|
||||
while (!list_empty(&mgr->evicte_queue))
|
||||
{
|
||||
sess = list_first_entry(&mgr->evicte_queue, struct session, evicte);
|
||||
list_del(&sess->evicte);
|
||||
session_manager_free_session(mgr, sess);
|
||||
}
|
||||
// free all udp session
|
||||
@@ -766,7 +767,6 @@ void session_manager_free(struct session_manager *mgr)
|
||||
}
|
||||
evicted_session_filter_free(mgr->evicte_sess_filter);
|
||||
duplicated_packet_filter_free(mgr->dup_pkt_filter);
|
||||
session_queue_free(mgr->sess_evicte_queue);
|
||||
session_timer_free(mgr->sess_timer);
|
||||
session_table_free(mgr->udp_sess_table);
|
||||
session_table_free(mgr->tcp_sess_table);
|
||||
@@ -919,7 +919,17 @@ struct session *session_manager_get_expired_session(struct session_manager *mgr,
|
||||
|
||||
struct session *session_manager_get_evicted_session(struct session_manager *mgr)
|
||||
{
|
||||
return session_queue_pop(mgr->sess_evicte_queue);
|
||||
struct session *sess = NULL;
|
||||
if (list_empty(&mgr->evicte_queue))
|
||||
{
|
||||
return sess;
|
||||
}
|
||||
else
|
||||
{
|
||||
sess = list_first_entry(&mgr->evicte_queue, struct session, evicte);
|
||||
list_del(&sess->evicte);
|
||||
return sess;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t session_manager_get_expire_interval(struct session_manager *mgr)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
struct session_pool
|
||||
{
|
||||
uint64_t count;
|
||||
struct session *sess;
|
||||
struct list_head free_queue;
|
||||
};
|
||||
|
||||
struct session_pool *session_pool_new(uint64_t count)
|
||||
@@ -14,15 +14,15 @@ struct session_pool *session_pool_new(uint64_t count)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
INIT_LIST_HEAD(&pool->free_queue);
|
||||
|
||||
pool->count = count;
|
||||
pool->sess = (struct session *)(pool + 1);
|
||||
|
||||
struct session *array = (struct session *)(pool + 1);
|
||||
for (uint64_t i = 0; i < count; i++)
|
||||
{
|
||||
pool->sess[i].next_free_ptr = &pool->sess[i + 1];
|
||||
struct session *sess = &array[i];
|
||||
list_add_tail(&sess->free, &pool->free_queue);
|
||||
pool->count++;
|
||||
}
|
||||
pool->sess[count - 1].next_free_ptr = NULL;
|
||||
|
||||
return pool;
|
||||
}
|
||||
@@ -31,6 +31,13 @@ void session_pool_free(struct session_pool *pool)
|
||||
{
|
||||
if (pool)
|
||||
{
|
||||
while (!list_empty(&pool->free_queue))
|
||||
{
|
||||
struct session *sess = list_first_entry(&pool->free_queue, struct session, free);
|
||||
list_del(&sess->free);
|
||||
pool->count--;
|
||||
}
|
||||
|
||||
free(pool);
|
||||
pool = NULL;
|
||||
}
|
||||
@@ -43,14 +50,13 @@ struct session *session_pool_pop(struct session_pool *pool)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct session *sess = pool->sess;
|
||||
if (sess == NULL)
|
||||
if (list_empty(&pool->free_queue))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pool->sess = sess->next_free_ptr;
|
||||
sess->next_free_ptr = NULL;
|
||||
struct session *sess = list_first_entry(&pool->free_queue, struct session, free);
|
||||
list_del(&sess->free);
|
||||
pool->count--;
|
||||
|
||||
return sess;
|
||||
@@ -63,8 +69,7 @@ void session_pool_push(struct session_pool *pool, struct session *sess)
|
||||
return;
|
||||
}
|
||||
|
||||
sess->next_free_ptr = pool->sess;
|
||||
pool->sess = sess;
|
||||
list_add_tail(&sess->free, &pool->free_queue);
|
||||
pool->count++;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "list.h"
|
||||
#include "timeout.h"
|
||||
#include "uthash.h"
|
||||
#include "session.h"
|
||||
@@ -87,13 +88,6 @@ struct session
|
||||
void *expire_arg;
|
||||
uint64_t expire_abs_ts;
|
||||
|
||||
/******************************
|
||||
* Session Pool Zone
|
||||
******************************/
|
||||
|
||||
// session pool recycle handle
|
||||
struct session *next_free_ptr;
|
||||
|
||||
/******************************
|
||||
* Session Table Zone
|
||||
******************************/
|
||||
@@ -102,17 +96,16 @@ struct session
|
||||
struct tuple6 tuple;
|
||||
enum session_dir tuple_dir;
|
||||
|
||||
struct session *next_ptr;
|
||||
struct session *prev_ptr;
|
||||
|
||||
// session table handle
|
||||
UT_hash_handle hh;
|
||||
|
||||
/******************************
|
||||
* Session Queue Zone
|
||||
* Session Queue Node
|
||||
******************************/
|
||||
|
||||
struct session *next_ready_ptr;
|
||||
struct list_head evicte; // used for evicte queue
|
||||
struct list_head lru; // used for lru queue
|
||||
struct list_head free; // used for free queue
|
||||
};
|
||||
|
||||
#ifdef __cpluscplus
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
#include "session_queue.h"
|
||||
#include "session_private.h"
|
||||
|
||||
struct session_queue
|
||||
{
|
||||
struct session *head;
|
||||
struct session *tail;
|
||||
int count;
|
||||
};
|
||||
|
||||
struct session_queue *session_queue_new()
|
||||
{
|
||||
struct session_queue *queue = (struct session_queue *)calloc(1, sizeof(struct session_queue));
|
||||
if (queue == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return queue;
|
||||
}
|
||||
|
||||
void session_queue_free(struct session_queue *queue)
|
||||
{
|
||||
if (queue)
|
||||
{
|
||||
free(queue);
|
||||
queue = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void session_queue_push(struct session_queue *queue, struct session *sess)
|
||||
{
|
||||
if (queue == NULL || sess == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (queue->head == NULL)
|
||||
{
|
||||
queue->head = sess;
|
||||
queue->tail = sess;
|
||||
}
|
||||
else
|
||||
{
|
||||
queue->tail->next_ready_ptr = sess;
|
||||
queue->tail = sess;
|
||||
}
|
||||
sess->next_ready_ptr = NULL;
|
||||
queue->count++;
|
||||
}
|
||||
|
||||
struct session *session_queue_pop(struct session_queue *queue)
|
||||
{
|
||||
if (queue == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct session *sess = queue->head;
|
||||
if (sess == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (queue->head == queue->tail)
|
||||
{
|
||||
queue->head = NULL;
|
||||
queue->tail = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
queue->head = sess->next_ready_ptr;
|
||||
}
|
||||
sess->next_ready_ptr = NULL;
|
||||
queue->count--;
|
||||
|
||||
return sess;
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
#ifndef _SESSION_QUEUE_H
|
||||
#define _SESSION_QUEUE_H
|
||||
|
||||
#ifdef __cpluscplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "session.h"
|
||||
|
||||
struct session_queue;
|
||||
struct session_queue *session_queue_new();
|
||||
void session_queue_free(struct session_queue *queue);
|
||||
|
||||
void session_queue_push(struct session_queue *queue, struct session *sess);
|
||||
struct session *session_queue_pop(struct session_queue *queue);
|
||||
|
||||
#ifdef __cpluscplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -4,6 +4,7 @@
|
||||
#define HASH_KEYCMP(a, b, len) HASH_KEYCMP_OVERWRITE(a, b, len)
|
||||
#include "session_table.h"
|
||||
#include "session_private.h"
|
||||
#include "list.h"
|
||||
|
||||
struct session_table
|
||||
{
|
||||
@@ -12,8 +13,7 @@ struct session_table
|
||||
void *arg;
|
||||
uint64_t count;
|
||||
|
||||
struct session *head; // Least recently used
|
||||
struct session *tail; // Most recently used
|
||||
struct list_head lru_queue;
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
@@ -45,56 +45,6 @@ static int HASH_KEYCMP_OVERWRITE(const void *key_a, const void *key_b, size_t le
|
||||
return -1;
|
||||
}
|
||||
|
||||
// add session to the tail of the list
|
||||
static void add_session_to_list(struct session_table *table, struct session *sess)
|
||||
{
|
||||
if (table == NULL || sess == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sess->next_ptr = NULL;
|
||||
sess->prev_ptr = NULL;
|
||||
|
||||
if (table->head == NULL && table->tail == NULL)
|
||||
{
|
||||
table->head = sess;
|
||||
table->tail = sess;
|
||||
}
|
||||
else
|
||||
{
|
||||
table->tail->next_ptr = sess;
|
||||
sess->prev_ptr = table->tail;
|
||||
table->tail = sess;
|
||||
}
|
||||
}
|
||||
|
||||
static void del_session_from_list(struct session_table *table, struct session *sess)
|
||||
{
|
||||
if (table == NULL || sess == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (sess->prev_ptr)
|
||||
{
|
||||
sess->prev_ptr->next_ptr = sess->next_ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
table->head = sess->next_ptr;
|
||||
}
|
||||
|
||||
if (sess->next_ptr)
|
||||
{
|
||||
sess->next_ptr->prev_ptr = sess->prev_ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
table->tail = sess->prev_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Public API
|
||||
******************************************************************************/
|
||||
@@ -102,9 +52,13 @@ static void del_session_from_list(struct session_table *table, struct session *s
|
||||
struct session_table *session_table_new()
|
||||
{
|
||||
struct session_table *table = (struct session_table *)calloc(1, sizeof(struct session_table));
|
||||
if (table == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
table->count = 0;
|
||||
table->head = NULL;
|
||||
table->tail = NULL;
|
||||
INIT_LIST_HEAD(&table->lru_queue);
|
||||
|
||||
return table;
|
||||
}
|
||||
@@ -117,6 +71,7 @@ void session_table_free(struct session_table *table)
|
||||
struct session *tmp = NULL;
|
||||
HASH_ITER(hh, table->root, node, tmp)
|
||||
{
|
||||
list_del(&node->lru);
|
||||
HASH_DELETE(hh, table->root, node);
|
||||
if (table->free_cb && node)
|
||||
{
|
||||
@@ -161,8 +116,8 @@ int session_table_add(struct session_table *table, const struct tuple6 *tuple, s
|
||||
return -1;
|
||||
}
|
||||
|
||||
list_add_tail(&sess->lru, &table->lru_queue);
|
||||
HASH_ADD(hh, table->root, tuple, sizeof(sess->tuple), sess);
|
||||
add_session_to_list(table, sess);
|
||||
table->count++;
|
||||
|
||||
return 0;
|
||||
@@ -181,12 +136,12 @@ void session_table_del(struct session_table *table, const struct tuple6 *tuple)
|
||||
return;
|
||||
}
|
||||
|
||||
list_del(&sess->lru);
|
||||
HASH_DELETE(hh, table->root, sess);
|
||||
if (table->free_cb && sess)
|
||||
{
|
||||
table->free_cb(sess, table->arg);
|
||||
}
|
||||
del_session_from_list(table, sess);
|
||||
table->count--;
|
||||
}
|
||||
|
||||
@@ -209,8 +164,8 @@ struct session *session_table_find_tuple(struct session_table *table, const stru
|
||||
|
||||
if (sess)
|
||||
{
|
||||
del_session_from_list(table, sess);
|
||||
add_session_to_list(table, sess);
|
||||
list_del(&sess->lru);
|
||||
list_add_tail(&sess->lru, &table->lru_queue);
|
||||
}
|
||||
|
||||
return sess;
|
||||
@@ -223,15 +178,12 @@ struct session *session_table_find_lru(struct session_table *table)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return table->head;
|
||||
}
|
||||
|
||||
struct session *session_table_find_mru(struct session_table *table)
|
||||
{
|
||||
if (table == NULL)
|
||||
if (list_empty(&table->lru_queue))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return table->tail;
|
||||
else
|
||||
{
|
||||
return list_first_entry(&table->lru_queue, struct session, lru);
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,6 @@ int session_table_add(struct session_table *table, const struct tuple6 *tuple, s
|
||||
void session_table_del(struct session_table *table, const struct tuple6 *tuple);
|
||||
struct session *session_table_find_tuple(struct session_table *table, const struct tuple6 *tuple);
|
||||
struct session *session_table_find_lru(struct session_table *table);
|
||||
struct session *session_table_find_mru(struct session_table *table);
|
||||
|
||||
#ifdef __cpluscplus
|
||||
}
|
||||
|
||||
@@ -14,9 +14,6 @@ target_link_libraries(gtest_session_table session_manager gtest)
|
||||
add_executable(gtest_session_timer gtest_session_timer.cpp)
|
||||
target_link_libraries(gtest_session_timer session_manager gtest)
|
||||
|
||||
add_executable(gtest_session_queue gtest_session_queue.cpp)
|
||||
target_link_libraries(gtest_session_queue session_manager gtest)
|
||||
|
||||
###############################################################################
|
||||
# gtest state machine (TCP)
|
||||
###############################################################################
|
||||
@@ -106,7 +103,6 @@ gtest_discover_tests(gtest_session)
|
||||
gtest_discover_tests(gtest_session_pool)
|
||||
gtest_discover_tests(gtest_session_table)
|
||||
gtest_discover_tests(gtest_session_timer)
|
||||
gtest_discover_tests(gtest_session_queue)
|
||||
|
||||
gtest_discover_tests(gtest_state_tcp_init_to_opening)
|
||||
gtest_discover_tests(gtest_state_tcp_opening_to_active)
|
||||
|
||||
@@ -57,7 +57,7 @@ static void packet_set_tcp_src_addr(struct packet *pkt, uint32_t addr)
|
||||
}
|
||||
|
||||
#if 1
|
||||
TEST(TCP_OVERLOAD, EVICT_TCP_OLD_SESS)
|
||||
TEST(TCP_OVERLOAD, EVICT_OLD_SESS)
|
||||
{
|
||||
struct packet pkt;
|
||||
struct session_manager *mgr = NULL;
|
||||
@@ -97,7 +97,7 @@ TEST(TCP_OVERLOAD, EVICT_TCP_OLD_SESS)
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
TEST(TCP_OVERLOAD, EVICT_TCP_NEW_SESS)
|
||||
TEST(TCP_OVERLOAD, EVICT_NEW_SESS)
|
||||
{
|
||||
struct packet pkt;
|
||||
struct session_manager *mgr = NULL;
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "session_private.h"
|
||||
#include "session_queue.h"
|
||||
|
||||
TEST(SESSION_QUEUE, POP_PUSH)
|
||||
{
|
||||
struct session sess1;
|
||||
struct session sess2;
|
||||
struct session_queue *queue = NULL;
|
||||
|
||||
queue = session_queue_new();
|
||||
EXPECT_TRUE(queue != NULL);
|
||||
|
||||
EXPECT_TRUE(session_queue_pop(queue) == NULL);
|
||||
session_queue_push(queue, &sess1);
|
||||
session_queue_push(queue, &sess2);
|
||||
EXPECT_TRUE(session_queue_pop(queue) == &sess1);
|
||||
EXPECT_TRUE(session_queue_pop(queue) == &sess2);
|
||||
EXPECT_TRUE(session_queue_pop(queue) == NULL);
|
||||
|
||||
session_queue_free(queue);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@@ -148,7 +148,6 @@ TEST(SESSION_TABLE, FIND_OLDEST_NEWEST)
|
||||
// Add Session
|
||||
|
||||
EXPECT_TRUE(session_table_find_lru(sess_table) == NULL);
|
||||
EXPECT_TRUE(session_table_find_mru(sess_table) == NULL);
|
||||
|
||||
sess1 = session_pool_pop(sess_pool);
|
||||
EXPECT_TRUE(sess1 != NULL);
|
||||
@@ -156,7 +155,6 @@ TEST(SESSION_TABLE, FIND_OLDEST_NEWEST)
|
||||
session_set_key(sess1, &tuple_1);
|
||||
EXPECT_TRUE(session_table_add(sess_table, &tuple_1, sess1) == 0);
|
||||
EXPECT_TRUE(session_table_find_lru(sess_table) == sess1);
|
||||
EXPECT_TRUE(session_table_find_mru(sess_table) == sess1);
|
||||
|
||||
sess2 = session_pool_pop(sess_pool);
|
||||
EXPECT_TRUE(sess2 != NULL);
|
||||
@@ -164,7 +162,6 @@ TEST(SESSION_TABLE, FIND_OLDEST_NEWEST)
|
||||
session_set_key(sess2, &tuple_2);
|
||||
EXPECT_TRUE(session_table_add(sess_table, &tuple_2, sess2) == 0);
|
||||
EXPECT_TRUE(session_table_find_lru(sess_table) == sess1);
|
||||
EXPECT_TRUE(session_table_find_mru(sess_table) == sess2);
|
||||
|
||||
sess3 = session_pool_pop(sess_pool);
|
||||
EXPECT_TRUE(sess3 != NULL);
|
||||
@@ -172,21 +169,17 @@ TEST(SESSION_TABLE, FIND_OLDEST_NEWEST)
|
||||
session_set_key(sess3, &tuple_3);
|
||||
EXPECT_TRUE(session_table_add(sess_table, &tuple_3, sess3) == 0);
|
||||
EXPECT_TRUE(session_table_find_lru(sess_table) == sess1);
|
||||
EXPECT_TRUE(session_table_find_mru(sess_table) == sess3);
|
||||
|
||||
// Delete Session
|
||||
|
||||
session_table_del(sess_table, &tuple_1);
|
||||
EXPECT_TRUE(session_table_find_lru(sess_table) == sess2);
|
||||
EXPECT_TRUE(session_table_find_mru(sess_table) == sess3);
|
||||
|
||||
session_table_del(sess_table, &tuple_2);
|
||||
EXPECT_TRUE(session_table_find_lru(sess_table) == sess3);
|
||||
EXPECT_TRUE(session_table_find_mru(sess_table) == sess3);
|
||||
|
||||
session_table_del(sess_table, &tuple_3);
|
||||
EXPECT_TRUE(session_table_find_lru(sess_table) == NULL);
|
||||
EXPECT_TRUE(session_table_find_mru(sess_table) == NULL);
|
||||
|
||||
// Destroy
|
||||
session_table_free(sess_table);
|
||||
|
||||
Reference in New Issue
Block a user