From 476c5bac56a8d6a87d1af05dce3f25c7262dc13a Mon Sep 17 00:00:00 2001 From: luwenpeng Date: Wed, 24 Apr 2024 11:39:15 +0800 Subject: [PATCH] session table can search session by tuple6 or tuple4 or id --- src/session/session_manager.cpp | 4 +- src/session/session_priv.h | 6 +- src/session/session_table.cpp | 125 ++++++++++---- src/session/session_table.h | 4 +- src/session/test/gtest_session_table.cpp | 199 +++++++++++++++-------- 5 files changed, 233 insertions(+), 105 deletions(-) diff --git a/src/session/session_manager.cpp b/src/session/session_manager.cpp index 0dc3bbf..efb0c86 100644 --- a/src/session/session_manager.cpp +++ b/src/session/session_manager.cpp @@ -953,9 +953,9 @@ struct session *session_manager_lookup_session(struct session_manager *mgr, cons switch (key.ip_proto) { case IPPROTO_UDP: - return session_table_find_tuple(mgr->udp_sess_table, &key); + return session_table_find_tuple6(mgr->udp_sess_table, &key); case IPPROTO_TCP: - return session_table_find_tuple(mgr->tcp_sess_table, &key); + return session_table_find_tuple6(mgr->tcp_sess_table, &key); default: return NULL; } diff --git a/src/session/session_priv.h b/src/session/session_priv.h index aecf699..5ec619d 100644 --- a/src/session/session_priv.h +++ b/src/session/session_priv.h @@ -39,7 +39,7 @@ struct tcp_half * * session memory usage = 128 * (50000 + 50000) * 1024 = 13107200000 bytes = 12.2 GB */ -struct session // 1024 bytes +struct session { uint64_t id; // 8 bytes uint64_t stats[MAX_DIRECTION][MAX_STAT]; // 480 bytes @@ -49,7 +49,9 @@ struct session // 1024 bytes struct list_head lru; // 16 bytes -- used for lru queue struct list_head free; // 16 bytes -- used for free queue struct list_head evicte; // 16 bytes -- used for evicte queue - UT_hash_handle hh; // 56 bytes -- used for hash table + UT_hash_handle hh1; // 56 bytes -- used for hash table (tuple6) + UT_hash_handle hh2; // 56 bytes -- used for hash table (tuple4) + UT_hash_handle hh3; // 56 bytes -- used for hash table (session id) struct tuple6 tuple; // 56 bytes char tuple_str[TUPLE6_STR_SIZE]; // 108 bytes const struct packet *first_pkt[MAX_DIRECTION]; // 16 bytes diff --git a/src/session/session_table.cpp b/src/session/session_table.cpp index 24b83e8..4d478b3 100644 --- a/src/session/session_table.cpp +++ b/src/session/session_table.cpp @@ -6,7 +6,9 @@ struct session_table { - struct session *root; + struct session *root_tuple6; + struct session *root_tuple4; + struct session *root_sessid; session_free_cb free_cb; void *arg; uint64_t count; @@ -18,29 +20,62 @@ struct session_table * Private API ******************************************************************************/ -static void HASH_FUNCTION_OVERWRITE(const struct tuple6 *tuple, unsigned int keylen, uint32_t *hashv) +static void HASH_FUNCTION_OVERWRITE(const void *keyptr, unsigned int keylen, uint32_t *hashv) { - *hashv = tuple6_hash(tuple); + switch (keylen) + { + case sizeof(struct tuple6): + *hashv = tuple6_hash((const struct tuple6 *)keyptr); + break; + case sizeof(struct tuple4): + *hashv = tuple4_hash((const struct tuple4 *)keyptr); + break; + case sizeof(uint64_t): + HASH_JEN(keyptr, keylen, *hashv); + break; + default: + assert(0); + break; + } } static int HASH_KEYCMP_OVERWRITE(const void *key_a, const void *key_b, size_t len) { - struct tuple6 *tuple_a = (struct tuple6 *)key_a; - struct tuple6 *tuple_b = (struct tuple6 *)key_b; - - if (tuple6_cmp(tuple_a, tuple_b) == 0) + if (len == sizeof(struct tuple6)) { - return 0; + if (tuple6_cmp((const struct tuple6 *)key_a, (const struct tuple6 *)key_b) == -1) + { + struct tuple6 rev; + tuple6_reverse((const struct tuple6 *)key_b, &rev); + return tuple6_cmp((const struct tuple6 *)key_a, &rev); + } + else + { + return 0; + } } - - struct tuple6 reversed; - tuple6_reverse(tuple_b, &reversed); - if (tuple6_cmp(tuple_a, &reversed) == 0) + else if (len == sizeof(struct tuple4)) { - return 0; + if (tuple4_cmp((const struct tuple4 *)key_a, (const struct tuple4 *)key_b) == -1) + { + struct tuple4 rev; + tuple4_reverse((const struct tuple4 *)key_b, &rev); + return tuple4_cmp((const struct tuple4 *)key_a, &rev); + } + else + { + return 0; + } + } + else if (len == sizeof(uint64_t)) + { + return memcmp(key_a, key_b, len); + } + else + { + assert(0); + return -1; } - - return -1; } /****************************************************************************** @@ -67,10 +102,12 @@ void session_table_free(struct session_table *table) { struct session *node = NULL; struct session *tmp = NULL; - HASH_ITER(hh, table->root, node, tmp) + HASH_ITER(hh1, table->root_tuple6, node, tmp) { list_del(&node->lru); - HASH_DELETE(hh, table->root, node); + HASH_DELETE(hh1, table->root_tuple6, node); + HASH_DELETE(hh2, table->root_tuple4, node); + HASH_DELETE(hh3, table->root_sessid, node); if (table->free_cb && node) { table->free_cb(node, table->arg); @@ -109,13 +146,15 @@ int session_table_add(struct session_table *table, const struct tuple6 *tuple, s return -1; } - if (session_table_find_tuple(table, tuple)) + if (session_table_find_tuple6(table, tuple)) { return -1; } + HASH_ADD(hh1, table->root_tuple6, tuple, sizeof(struct tuple6), sess); + HASH_ADD(hh2, table->root_tuple4, tuple, sizeof(struct tuple4), sess); + HASH_ADD(hh3, table->root_sessid, id, sizeof(uint64_t), sess); list_add_tail(&sess->lru, &table->lru_queue); - HASH_ADD(hh, table->root, tuple, sizeof(sess->tuple), sess); table->count++; return 0; @@ -128,14 +167,16 @@ void session_table_del(struct session_table *table, const struct tuple6 *tuple) return; } - struct session *sess = session_table_find_tuple(table, tuple); + struct session *sess = session_table_find_tuple6(table, tuple); if (sess == NULL) { return; } list_del(&sess->lru); - HASH_DELETE(hh, table->root, sess); + HASH_DELETE(hh1, table->root_tuple6, sess); + HASH_DELETE(hh2, table->root_tuple4, sess); + HASH_DELETE(hh3, table->root_sessid, sess); if (table->free_cb && sess) { table->free_cb(sess, table->arg); @@ -143,7 +184,7 @@ void session_table_del(struct session_table *table, const struct tuple6 *tuple) table->count--; } -struct session *session_table_find_tuple(struct session_table *table, const struct tuple6 *tuple) +struct session *session_table_find_sessid(struct session_table *table, uint64_t id) { if (table == NULL) { @@ -151,15 +192,43 @@ struct session *session_table_find_tuple(struct session_table *table, const stru } struct session *sess = NULL; - HASH_FIND(hh, table->root, tuple, sizeof(struct tuple6), sess); - if (sess == NULL) + HASH_FIND(hh3, table->root_sessid, &id, sizeof(uint64_t), sess); + if (sess) { - struct tuple6 out; - memset(&out, 0, sizeof(struct tuple6)); - tuple6_reverse(tuple, &out); - HASH_FIND(hh, table->root, &out, sizeof(struct tuple6), sess); + list_del(&sess->lru); + list_add_tail(&sess->lru, &table->lru_queue); } + return sess; +} + +struct session *session_table_find_tuple6(struct session_table *table, const struct tuple6 *tuple) +{ + if (table == NULL) + { + return NULL; + } + + struct session *sess = NULL; + HASH_FIND(hh1, table->root_tuple6, tuple, sizeof(struct tuple6), sess); + if (sess) + { + list_del(&sess->lru); + list_add_tail(&sess->lru, &table->lru_queue); + } + + return sess; +} + +struct session *session_table_find_tuple4(struct session_table *table, const struct tuple4 *tuple) +{ + if (table == NULL) + { + return NULL; + } + + struct session *sess = NULL; + HASH_FIND(hh2, table->root_tuple4, tuple, sizeof(struct tuple4), sess); if (sess) { list_del(&sess->lru); diff --git a/src/session/session_table.h b/src/session/session_table.h index da10178..bb485e6 100644 --- a/src/session/session_table.h +++ b/src/session/session_table.h @@ -19,7 +19,9 @@ void session_table_set_freecb(struct session_table *table, session_free_cb free_ // return -1: failed int session_table_add(struct session_table *table, const struct tuple6 *tuple, struct session *sess); 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_sessid(struct session_table *table, uint64_t id); +struct session *session_table_find_tuple6(struct session_table *table, const struct tuple6 *tuple); +struct session *session_table_find_tuple4(struct session_table *table, const struct tuple4 *tuple); struct session *session_table_find_lru(struct session_table *table); #ifdef __cplusplus diff --git a/src/session/test/gtest_session_table.cpp b/src/session/test/gtest_session_table.cpp index 5fa6b29..72972af 100644 --- a/src/session/test/gtest_session_table.cpp +++ b/src/session/test/gtest_session_table.cpp @@ -3,38 +3,51 @@ #include "session_pool.h" #include "session_table.h" -#define SESSION_KEY_IPV4_TCP(name) \ - struct tuple6 name; \ - memset(&name, 0, sizeof(struct tuple6)); \ - (name).ip_type = IP_TYPE_V4; \ - (name).src_addr.v4.s_addr = inet_addr("192.168.1.2"); \ - (name).dst_addr.v4.s_addr = inet_addr("192.168.1.3"); \ - (name).src_port = htons(1234); \ - (name).dst_port = htons(5678); \ - (name).ip_proto = IPPROTO_TCP; \ - (name).domain = 0; +#define TUPLE6_SET_V4_TCP(t6) \ + { \ + memset(&t6, 0, sizeof(struct tuple6)); \ + (t6).ip_type = IP_TYPE_V4; \ + (t6).src_addr.v4.s_addr = inet_addr("192.168.1.2"); \ + (t6).dst_addr.v4.s_addr = inet_addr("192.168.1.3"); \ + (t6).src_port = htons(1234); \ + (t6).dst_port = htons(5678); \ + (t6).ip_proto = IPPROTO_TCP; \ + (t6).domain = 123; \ + } -#define SESSION_KEY_IPV6_UDP(name) \ - struct tuple6 name; \ - memset(&name, 0, sizeof(struct tuple6)); \ - (name).ip_type = IP_TYPE_V6; \ - inet_pton(AF_INET6, "2001:db8:0:0:0:ff00:42:8329", &(name).src_addr.v6); \ - inet_pton(AF_INET6, "2001:db8:0:0:0:ff00:42:832a", &(name).dst_addr.v6); \ - (name).src_port = htons(1234); \ - (name).dst_port = htons(5678); \ - (name).ip_proto = IPPROTO_UDP; \ - (name).domain = 0; +#define TUPLE6_SET_V6_UDP(t6) \ + { \ + memset(&t6, 0, sizeof(struct tuple6)); \ + (t6).ip_type = IP_TYPE_V6; \ + inet_pton(AF_INET6, "2001:db8:0:0:0:ff00:42:8329", &(t6).src_addr.v6); \ + inet_pton(AF_INET6, "2001:db8:0:0:0:ff00:42:832a", &(t6).dst_addr.v6); \ + (t6).src_port = htons(2345); \ + (t6).dst_port = htons(6789); \ + (t6).ip_proto = IPPROTO_UDP; \ + (t6).domain = 456; \ + } -#define SESSION_KEY_IPV6_TCP(name) \ - struct tuple6 name; \ - memset(&name, 0, sizeof(struct tuple6)); \ - (name).ip_type = IP_TYPE_V6; \ - inet_pton(AF_INET6, "2001:db8:0:0:0:ff00:42:8329", &(name).src_addr.v6); \ - inet_pton(AF_INET6, "2001:db8:0:0:0:ff00:42:832a", &(name).dst_addr.v6); \ - (name).src_port = htons(1234); \ - (name).dst_port = htons(5678); \ - (name).ip_proto = IPPROTO_TCP; \ - (name).domain = 0; +#define TUPLE6_SET_V6_TCP(t6) \ + { \ + memset(&t6, 0, sizeof(struct tuple6)); \ + (t6).ip_type = IP_TYPE_V6; \ + inet_pton(AF_INET6, "2001:db8:0:0:0:ff00:42:8329", &(t6).src_addr.v6); \ + inet_pton(AF_INET6, "2001:db8:0:0:0:ff00:42:832a", &(t6).dst_addr.v6); \ + (t6).src_port = htons(3456); \ + (t6).dst_port = htons(7890); \ + (t6).ip_proto = IPPROTO_TCP; \ + (t6).domain = 789; \ + } + +#define TUPLE6_TO_TUPLE4(t6, t4) \ + { \ + memset(&(t4), 0, sizeof(struct tuple4)); \ + (t4).ip_type = (t6).ip_type; \ + (t4).src_addr = (t6).src_addr; \ + (t4).dst_addr = (t6).dst_addr; \ + (t4).src_port = (t6).src_port; \ + (t4).dst_port = (t6).dst_port; \ + } static void session_free_callback(struct session *sess, void *arg) { @@ -46,25 +59,47 @@ static void session_free_callback(struct session *sess, void *arg) } } +#if 1 TEST(SESSION_TABLE, OP_SESSION) { struct session *sess1 = NULL; struct session *sess2 = NULL; struct session *sess3 = NULL; + + struct tuple4 sess1_tup4; + struct tuple4 sess2_tup4; + struct tuple4 sess3_tup4; + + struct tuple4 sess1_rev_tup4; + struct tuple4 sess2_rev_tup4; + struct tuple4 sess3_rev_tup4; + + struct tuple6 sess1_tup6; + struct tuple6 sess2_tup6; + struct tuple6 sess3_tup6; + + struct tuple6 sess1_rev_tup6; + struct tuple6 sess2_rev_tup6; + struct tuple6 sess3_rev_tup6; + struct session_pool *sess_pool = NULL; struct session_table *sess_table = NULL; - SESSION_KEY_IPV4_TCP(tuple_1); - SESSION_KEY_IPV6_UDP(tuple_2); - SESSION_KEY_IPV6_TCP(tuple_3); + TUPLE6_SET_V4_TCP(sess1_tup6); + TUPLE6_SET_V6_UDP(sess2_tup6); + TUPLE6_SET_V6_TCP(sess3_tup6); - struct tuple6 reversed_tuple_1; - struct tuple6 reversed_tuple_2; - struct tuple6 reversed_tuple_3; + TUPLE6_TO_TUPLE4(sess1_tup6, sess1_tup4); + TUPLE6_TO_TUPLE4(sess2_tup6, sess2_tup4); + TUPLE6_TO_TUPLE4(sess3_tup6, sess3_tup4); - tuple6_reverse(&tuple_1, &reversed_tuple_1); - tuple6_reverse(&tuple_2, &reversed_tuple_2); - tuple6_reverse(&tuple_3, &reversed_tuple_3); + tuple4_reverse(&sess1_tup4, &sess1_rev_tup4); + tuple4_reverse(&sess2_tup4, &sess2_rev_tup4); + tuple4_reverse(&sess3_tup4, &sess3_rev_tup4); + + tuple6_reverse(&sess1_tup6, &sess1_rev_tup6); + tuple6_reverse(&sess2_tup6, &sess2_rev_tup6); + tuple6_reverse(&sess3_tup6, &sess3_rev_tup6); // Create sess_pool = session_pool_new(3); @@ -77,66 +112,85 @@ TEST(SESSION_TABLE, OP_SESSION) sess1 = session_pool_pop(sess_pool); EXPECT_TRUE(sess1 != NULL); session_set_id(sess1, 1); - session_set_tuple(sess1, &tuple_1); + session_set_tuple(sess1, &sess1_tup6); sess2 = session_pool_pop(sess_pool); EXPECT_TRUE(sess2 != NULL); session_set_id(sess2, 2); - session_set_tuple(sess2, &tuple_2); + session_set_tuple(sess2, &sess2_tup6); sess3 = session_pool_pop(sess_pool); EXPECT_TRUE(sess3 != NULL); session_set_id(sess3, 3); - session_set_tuple(sess3, &tuple_3); + session_set_tuple(sess3, &sess3_tup6); - EXPECT_TRUE(session_table_add(sess_table, &tuple_1, sess1) == 0); + EXPECT_TRUE(session_table_add(sess_table, &sess1_tup6, sess1) == 0); EXPECT_TRUE(session_table_get_count(sess_table) == 1); - EXPECT_TRUE(session_table_add(sess_table, &tuple_2, sess2) == 0); + EXPECT_TRUE(session_table_add(sess_table, &sess2_tup6, sess2) == 0); EXPECT_TRUE(session_table_get_count(sess_table) == 2); - EXPECT_TRUE(session_table_add(sess_table, &tuple_3, sess3) == 0); + EXPECT_TRUE(session_table_add(sess_table, &sess3_tup6, sess3) == 0); EXPECT_TRUE(session_table_get_count(sess_table) == 3); // Search - EXPECT_TRUE(session_table_find_tuple(sess_table, &tuple_1) == sess1); - EXPECT_TRUE(session_table_find_tuple(sess_table, &tuple_2) == sess2); - EXPECT_TRUE(session_table_find_tuple(sess_table, &tuple_3) == sess3); + EXPECT_TRUE(session_table_find_sessid(sess_table, 1) == sess1); + EXPECT_TRUE(session_table_find_sessid(sess_table, 2) == sess2); + EXPECT_TRUE(session_table_find_sessid(sess_table, 3) == sess3); - EXPECT_TRUE(session_table_find_tuple(sess_table, &reversed_tuple_1) == sess1); - EXPECT_TRUE(session_table_find_tuple(sess_table, &reversed_tuple_2) == sess2); - EXPECT_TRUE(session_table_find_tuple(sess_table, &reversed_tuple_3) == sess3); + EXPECT_TRUE(session_table_find_tuple4(sess_table, &sess1_tup4) == sess1); + EXPECT_TRUE(session_table_find_tuple4(sess_table, &sess2_tup4) == sess2); + EXPECT_TRUE(session_table_find_tuple4(sess_table, &sess3_tup4) == sess3); + + EXPECT_TRUE(session_table_find_tuple4(sess_table, &sess1_rev_tup4) == sess1); + EXPECT_TRUE(session_table_find_tuple4(sess_table, &sess2_rev_tup4) == sess2); + EXPECT_TRUE(session_table_find_tuple4(sess_table, &sess3_rev_tup4) == sess3); + + EXPECT_TRUE(session_table_find_tuple6(sess_table, &sess1_tup6) == sess1); + EXPECT_TRUE(session_table_find_tuple6(sess_table, &sess2_tup6) == sess2); + EXPECT_TRUE(session_table_find_tuple6(sess_table, &sess3_tup6) == sess3); + + EXPECT_TRUE(session_table_find_tuple6(sess_table, &sess1_rev_tup6) == sess1); + EXPECT_TRUE(session_table_find_tuple6(sess_table, &sess2_rev_tup6) == sess2); + EXPECT_TRUE(session_table_find_tuple6(sess_table, &sess3_rev_tup6) == sess3); // Delete - session_table_del(sess_table, &tuple_1); + session_table_del(sess_table, &sess1_tup6); EXPECT_TRUE(session_table_get_count(sess_table) == 2); - EXPECT_TRUE(session_table_find_tuple(sess_table, &tuple_1) == NULL); - EXPECT_TRUE(session_table_find_tuple(sess_table, &reversed_tuple_1) == NULL); + EXPECT_TRUE(session_table_find_tuple6(sess_table, &sess1_tup6) == NULL); + EXPECT_TRUE(session_table_find_tuple6(sess_table, &sess1_rev_tup6) == NULL); - session_table_del(sess_table, &reversed_tuple_2); + session_table_del(sess_table, &sess2_rev_tup6); EXPECT_TRUE(session_table_get_count(sess_table) == 1); - EXPECT_TRUE(session_table_find_tuple(sess_table, &tuple_2) == NULL); - EXPECT_TRUE(session_table_find_tuple(sess_table, &reversed_tuple_2) == NULL); + EXPECT_TRUE(session_table_find_tuple6(sess_table, &sess2_tup6) == NULL); + EXPECT_TRUE(session_table_find_tuple6(sess_table, &sess2_rev_tup6) == NULL); - session_table_del(sess_table, &tuple_3); + session_table_del(sess_table, &sess3_tup6); EXPECT_TRUE(session_table_get_count(sess_table) == 0); - EXPECT_TRUE(session_table_find_tuple(sess_table, &tuple_3) == NULL); - EXPECT_TRUE(session_table_find_tuple(sess_table, &reversed_tuple_3) == NULL); + EXPECT_TRUE(session_table_find_tuple6(sess_table, &sess3_tup6) == NULL); + EXPECT_TRUE(session_table_find_tuple6(sess_table, &sess3_rev_tup6) == NULL); // Destroy session_table_free(sess_table); session_pool_free(sess_pool); } +#endif +#if 1 TEST(SESSION_TABLE, FIND_OLDEST_NEWEST) { struct session *sess1 = NULL; struct session *sess2 = NULL; struct session *sess3 = NULL; + + struct tuple6 sess1_tup6; + struct tuple6 sess2_tup6; + struct tuple6 sess3_tup6; + struct session_pool *sess_pool = NULL; struct session_table *sess_table = NULL; - SESSION_KEY_IPV4_TCP(tuple_1); - SESSION_KEY_IPV6_UDP(tuple_2); - SESSION_KEY_IPV6_TCP(tuple_3); + TUPLE6_SET_V4_TCP(sess1_tup6); + TUPLE6_SET_V6_UDP(sess2_tup6); + TUPLE6_SET_V6_TCP(sess3_tup6); // Create sess_pool = session_pool_new(3); @@ -152,39 +206,40 @@ TEST(SESSION_TABLE, FIND_OLDEST_NEWEST) sess1 = session_pool_pop(sess_pool); EXPECT_TRUE(sess1 != NULL); session_set_id(sess1, 1); - session_set_tuple(sess1, &tuple_1); - EXPECT_TRUE(session_table_add(sess_table, &tuple_1, sess1) == 0); + session_set_tuple(sess1, &sess1_tup6); + EXPECT_TRUE(session_table_add(sess_table, &sess1_tup6, sess1) == 0); EXPECT_TRUE(session_table_find_lru(sess_table) == sess1); sess2 = session_pool_pop(sess_pool); EXPECT_TRUE(sess2 != NULL); session_set_id(sess2, 2); - session_set_tuple(sess2, &tuple_2); - EXPECT_TRUE(session_table_add(sess_table, &tuple_2, sess2) == 0); + session_set_tuple(sess2, &sess2_tup6); + EXPECT_TRUE(session_table_add(sess_table, &sess2_tup6, sess2) == 0); EXPECT_TRUE(session_table_find_lru(sess_table) == sess1); sess3 = session_pool_pop(sess_pool); EXPECT_TRUE(sess3 != NULL); session_set_id(sess3, 3); - session_set_tuple(sess3, &tuple_3); - EXPECT_TRUE(session_table_add(sess_table, &tuple_3, sess3) == 0); + session_set_tuple(sess3, &sess3_tup6); + EXPECT_TRUE(session_table_add(sess_table, &sess3_tup6, sess3) == 0); EXPECT_TRUE(session_table_find_lru(sess_table) == sess1); // Delete Session - session_table_del(sess_table, &tuple_1); + session_table_del(sess_table, &sess1_tup6); EXPECT_TRUE(session_table_find_lru(sess_table) == sess2); - session_table_del(sess_table, &tuple_2); + session_table_del(sess_table, &sess2_tup6); EXPECT_TRUE(session_table_find_lru(sess_table) == sess3); - session_table_del(sess_table, &tuple_3); + session_table_del(sess_table, &sess3_tup6); EXPECT_TRUE(session_table_find_lru(sess_table) == NULL); // Destroy session_table_free(sess_table); session_pool_free(sess_pool); } +#endif int main(int argc, char **argv) {