From 95abad41b5c2807c2532f2cb465a6245db8b5fd5 Mon Sep 17 00:00:00 2001 From: luwenpeng Date: Tue, 28 Nov 2023 16:36:58 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E9=80=9A=E8=BF=87?= =?UTF-8?q?=E5=9B=9B=E5=85=83=E7=BB=84=E6=9F=A5=E8=AF=A2=E6=B5=81=E8=A1=A8?= =?UTF-8?q?=E7=9A=84=E5=AE=9E=E7=8E=B0=EF=BC=88=E6=9F=A5=E8=A1=A8=E5=89=8D?= =?UTF-8?q?=E5=85=88=E6=A0=B9=E6=8D=AE=E7=AB=AF=E5=8F=A3=E9=A2=84=E5=88=A4?= =?UTF-8?q?=E6=98=AF=E5=90=A6=E9=9C=80=E8=A6=81=E7=BF=BB=E8=BD=AC=E5=9B=9B?= =?UTF-8?q?=E5=85=83=E7=BB=84=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/include/session_table.h | 35 ++--- common/src/session_table.cpp | 214 ++++++++++++++++------------ common/test/gtest_session_table.cpp | 50 +++---- platform/src/packet_io.cpp | 22 ++- 4 files changed, 167 insertions(+), 154 deletions(-) diff --git a/common/include/session_table.h b/common/include/session_table.h index 5df6be6..422c016 100644 --- a/common/include/session_table.h +++ b/common/include/session_table.h @@ -9,47 +9,32 @@ extern "C" #include #include -#include "uthash.h" #include "tuple.h" -// Note: session_addr must be initialized by memset(0) before use !!! - typedef void fn_free_cb(void *args); -struct session_node -{ - uint64_t session_id; /* first key */ - struct four_tuple session_addr; /* second key */ - - void *value; - fn_free_cb *value_free_cb; - - UT_hash_handle hh1; /* handle for first hash table */ - UT_hash_handle hh2; /* handle for second hash table */ -}; - struct session_table; - struct session_table *session_table_create(); void session_table_destory(struct session_table *table); void session_table_reset(struct session_table *table); uint64_t session_table_count(struct session_table *table); -// session_addr : deep copy -// value : shallow copy (malloc by user, free by value_free_cb) +// addr : deep copy +// value : shallow copy (malloc by user, free by free_cb) +// Note : addr must be initialized by memset(0) before use !!! // return 0 : suceess // return -1 : key exists -int session_table_insert(struct session_table *table, uint64_t session_id, const struct four_tuple *session_addr, void *value, const fn_free_cb *value_free_cb); +int session_table_insert(struct session_table *table, uint64_t id, const struct four_tuple *addr, void *value, const fn_free_cb *free_cb); // return 0 : success // return -1 : key not exists -int session_table_delete_by_id(struct session_table *table, uint64_t session_id); -int session_table_delete_by_addr(struct session_table *table, const struct four_tuple *session_addr); +int session_table_delete_by_id(struct session_table *table, uint64_t id); +int session_table_delete_by_addr(struct session_table *table, const struct four_tuple *addr); -// return NULL : key not exists -// return UnNULL : success -struct session_node *session_table_search_by_id(struct session_table *table, uint64_t session_id); -struct session_node *session_table_search_by_addr(struct session_table *table, const struct four_tuple *session_addr); +// return NULL : key not exists +// return value : success +void *session_table_search_by_id(struct session_table *table, uint64_t id); +void *session_table_search_by_addr(struct session_table *table, const struct four_tuple *addr); #ifdef __cpluscplus } diff --git a/common/src/session_table.cpp b/common/src/session_table.cpp index f8592dc..2cafb8c 100644 --- a/common/src/session_table.cpp +++ b/common/src/session_table.cpp @@ -3,20 +3,32 @@ #include "session_table.h" #include "utils.h" -struct session_table +struct session_node { - struct session_node *root_by_id; - struct session_node *root_by_addr; - uint64_t session_node_count; + uint64_t id; /* first key */ + struct four_tuple addr; /* second key */ + + void *value; + fn_free_cb *free_cb; + + UT_hash_handle hh1; /* handle for first hash table */ + UT_hash_handle hh2; /* handle for second hash table */ }; -// Note: session_addr must be initialized by memset(0) before use !!! +struct session_table +{ + struct session_node *root_id; + struct session_node *root_addr; + uint64_t count; +}; + +static struct session_node *search_node_by_addr(struct session_table *table, const struct four_tuple *addr); struct session_table *session_table_create() { struct session_table *table = (struct session_table *)calloc(1, sizeof(struct session_table)); assert(table); - table->session_node_count = 0; + table->count = 0; return table; } @@ -25,21 +37,7 @@ void session_table_destory(struct session_table *table) { if (table) { - struct session_node *temp = NULL; - struct session_node *node = NULL; - HASH_ITER(hh1, table->root_by_id, node, temp) - { - HASH_DELETE(hh1, table->root_by_id, node); - HASH_DELETE(hh2, table->root_by_addr, node); - - if (node->value_free_cb && node->value) - { - node->value_free_cb(node->value); - } - - free(node); - node = NULL; - } + session_table_reset(table); free(table); table = NULL; @@ -52,20 +50,20 @@ void session_table_reset(struct session_table *table) { struct session_node *temp = NULL; struct session_node *node = NULL; - HASH_ITER(hh1, table->root_by_id, node, temp) + HASH_ITER(hh1, table->root_id, node, temp) { - HASH_DELETE(hh1, table->root_by_id, node); - HASH_DELETE(hh2, table->root_by_addr, node); + HASH_DELETE(hh1, table->root_id, node); + HASH_DELETE(hh2, table->root_addr, node); - if (node->value_free_cb && node->value) + if (node->free_cb && node->value) { - node->value_free_cb(node->value); + node->free_cb(node->value); } free(node); node = NULL; - table->session_node_count--; + table->count--; } } } @@ -74,7 +72,7 @@ uint64_t session_table_count(struct session_table *table) { if (table) { - return table->session_node_count; + return table->count; } else { @@ -82,117 +80,151 @@ uint64_t session_table_count(struct session_table *table) } } -// session_addr : deep copy -// value : shallow copy (malloc by user, free by value_free_cb) -int session_table_insert(struct session_table *table, uint64_t session_id, const struct four_tuple *session_addr, void *value, const fn_free_cb *value_free_cb) +// addr : deep copy +// value : shallow copy (malloc by user, free by free_cb) +// Note : addr must be initialized by memset(0) before use !!! +int session_table_insert(struct session_table *table, uint64_t id, const struct four_tuple *addr, void *value, const fn_free_cb *free_cb) { - struct session_node *temp = NULL; - HASH_FIND(hh1, table->root_by_id, &session_id, sizeof(session_id), temp); - if (temp) + struct session_node *node = NULL; + HASH_FIND(hh1, table->root_id, &id, sizeof(id), node); + if (node) { return -1; } - temp = (struct session_node *)calloc(1, sizeof(struct session_node)); - assert(temp); + node = (struct session_node *)calloc(1, sizeof(struct session_node)); + assert(node); - temp->session_id = session_id; - memcpy(&temp->session_addr, session_addr, sizeof(struct four_tuple)); - temp->value = value; - temp->value_free_cb = value_free_cb; + node->id = id; + node->value = value; + node->free_cb = free_cb; - HASH_ADD(hh1, table->root_by_id, session_id, sizeof(temp->session_id), temp); - HASH_ADD(hh2, table->root_by_addr, session_addr, sizeof(temp->session_addr), temp); + if (addr->src_port < addr->dst_port) + { + memcpy(&node->addr, addr, sizeof(struct four_tuple)); + } + else + { + four_tuple_reverse(addr, &node->addr); + } - table->session_node_count++; + HASH_ADD(hh1, table->root_id, id, sizeof(node->id), node); + HASH_ADD(hh2, table->root_addr, addr, sizeof(node->addr), node); + + table->count++; return 0; } -int session_table_delete_by_id(struct session_table *table, uint64_t session_id) +int session_table_delete_by_id(struct session_table *table, uint64_t id) { - struct session_node *temp = NULL; - HASH_FIND(hh1, table->root_by_id, &session_id, sizeof(session_id), temp); - if (!temp) + struct session_node *node = NULL; + HASH_FIND(hh1, table->root_id, &id, sizeof(id), node); + if (!node) { return -1; } - HASH_DELETE(hh1, table->root_by_id, temp); - HASH_DELETE(hh2, table->root_by_addr, temp); + HASH_DELETE(hh1, table->root_id, node); + HASH_DELETE(hh2, table->root_addr, node); - if (temp->value_free_cb && temp->value) + if (node->free_cb && node->value) { - temp->value_free_cb(temp->value); - temp->value = NULL; + node->free_cb(node->value); + node->value = NULL; } - free(temp); - temp = NULL; + free(node); + node = NULL; - table->session_node_count--; + table->count--; return 0; } -int session_table_delete_by_addr(struct session_table *table, const struct four_tuple *session_addr) +int session_table_delete_by_addr(struct session_table *table, const struct four_tuple *addr) { - struct session_node *temp = NULL; - HASH_FIND(hh2, table->root_by_addr, session_addr, sizeof(struct four_tuple), temp); - if (!temp) + struct session_node *node = search_node_by_addr(table, addr); + if (node == NULL) { - struct four_tuple reverse_addr; - four_tuple_reverse(session_addr, &reverse_addr); - HASH_FIND(hh2, table->root_by_addr, &reverse_addr, sizeof(struct four_tuple), temp); - if (!temp) - { - return -1; - } + return -1; } - HASH_DELETE(hh1, table->root_by_id, temp); - HASH_DELETE(hh2, table->root_by_addr, temp); + HASH_DELETE(hh1, table->root_id, node); + HASH_DELETE(hh2, table->root_addr, node); - if (temp->value_free_cb && temp->value) + if (node->free_cb && node->value) { - temp->value_free_cb(temp->value); - temp->value = NULL; + node->free_cb(node->value); + node->value = NULL; } - free(temp); - temp = NULL; + free(node); + node = NULL; - table->session_node_count--; + table->count--; return 0; } -struct session_node *session_table_search_by_id(struct session_table *table, uint64_t session_id) +void *session_table_search_by_id(struct session_table *table, uint64_t id) { - struct session_node *temp = NULL; - HASH_FIND(hh1, table->root_by_id, &session_id, sizeof(session_id), temp); - if (!temp) + struct session_node *node = NULL; + HASH_FIND(hh1, table->root_id, &id, sizeof(id), node); + if (!node) { return NULL; } - return temp; + return node->value; } -struct session_node *session_table_search_by_addr(struct session_table *table, const struct four_tuple *session_addr) +void *session_table_search_by_addr(struct session_table *table, const struct four_tuple *addr) { - struct session_node *temp = NULL; - HASH_FIND(hh2, table->root_by_addr, session_addr, sizeof(struct four_tuple), temp); - if (!temp) + struct session_node *node = search_node_by_addr(table, addr); + if (!node) { - struct four_tuple reverse_addr; - four_tuple_reverse(session_addr, &reverse_addr); - HASH_FIND(hh2, table->root_by_addr, &reverse_addr, sizeof(struct four_tuple), temp); - if (!temp) - { - return NULL; - } + return NULL; } - return temp; + return node->value; } + +static struct session_node *search_node_by_addr(struct session_table *table, const struct four_tuple *addr) +{ + struct session_node *node = NULL; + const struct four_tuple *first = NULL; + const struct four_tuple *second = NULL; + struct four_tuple reverse_addr; + + if (addr->src_port < addr->dst_port) + { + first = addr; + second = NULL; + } + else + { + four_tuple_reverse(addr, &reverse_addr); + first = &reverse_addr; + second = addr; + } + + HASH_FIND(hh2, table->root_addr, first, sizeof(struct four_tuple), node); + if (node) + { + return node; + } + + if (second == NULL) + { + four_tuple_reverse(addr, &reverse_addr); + second = &reverse_addr; + } + HASH_FIND(hh2, table->root_addr, second, sizeof(struct four_tuple), node); + if (node) + { + return node; + } + + return NULL; +} \ No newline at end of file diff --git a/common/test/gtest_session_table.cpp b/common/test/gtest_session_table.cpp index e5a1a50..f38e8c5 100644 --- a/common/test/gtest_session_table.cpp +++ b/common/test/gtest_session_table.cpp @@ -50,15 +50,15 @@ TEST(STREAM_TABLE, SEARCH_BY_ID) EXPECT_TRUE(session_table_count(table) == 2); // TEST Search By Session ID - struct session_node *node = NULL; - node = session_table_search_by_id(table, 1); - EXPECT_TRUE(node != nullptr); - EXPECT_STREQ((const char *)node->value, "HELLO"); - node = session_table_search_by_id(table, 2); - EXPECT_TRUE(node != nullptr); - EXPECT_STREQ((const char *)node->value, "WORLD"); - node = session_table_search_by_id(table, 3); - EXPECT_TRUE(node == nullptr); + char *val = NULL; + val = (char *)session_table_search_by_id(table, 1); + EXPECT_TRUE(val != nullptr); + EXPECT_STREQ((const char *)val, "HELLO"); + val = (char *)session_table_search_by_id(table, 2); + EXPECT_TRUE(val != nullptr); + EXPECT_STREQ((const char *)val, "WORLD"); + val = (char *)session_table_search_by_id(table, 3); + EXPECT_TRUE(val == nullptr); // TEST Destory session_table_destory(table); @@ -85,15 +85,15 @@ TEST(STREAM_TABLE, SEARCH_BY_ADDR) EXPECT_TRUE(session_table_count(table) == 2); // TEST Search By Session Addr - struct session_node *node = NULL; - node = session_table_search_by_addr(table, &addr1); - EXPECT_TRUE(node != nullptr); - EXPECT_STREQ((const char *)node->value, "HELLO"); - node = session_table_search_by_addr(table, &addr2); - EXPECT_TRUE(node != nullptr); - EXPECT_STREQ((const char *)node->value, "WORLD"); - node = session_table_search_by_addr(table, &addr3); - EXPECT_TRUE(node == nullptr); + char *val = NULL; + val = (char *)session_table_search_by_addr(table, &addr1); + EXPECT_TRUE(val != nullptr); + EXPECT_STREQ((const char *)val, "HELLO"); + val = (char *)session_table_search_by_addr(table, &addr2); + EXPECT_TRUE(val != nullptr); + EXPECT_STREQ((const char *)val, "WORLD"); + val = (char *)session_table_search_by_addr(table, &addr3); + EXPECT_TRUE(val == nullptr); // TEST Destory session_table_destory(table); @@ -122,13 +122,13 @@ TEST(STREAM_TABLE, SEARCH_BY_REVERSE_ADDR) EXPECT_TRUE(session_table_count(table) == 2); // TEST Search By Session Reverse Addr - struct session_node *node = NULL; - node = session_table_search_by_addr(table, &addr1_reverse); - EXPECT_TRUE(node != nullptr); - EXPECT_STREQ((const char *)node->value, "HELLO"); - node = session_table_search_by_addr(table, &addr2_reverse); - EXPECT_TRUE(node != nullptr); - EXPECT_STREQ((const char *)node->value, "WORLD"); + char *val = NULL; + val = (char *)session_table_search_by_addr(table, &addr1_reverse); + EXPECT_TRUE(val != nullptr); + EXPECT_STREQ((const char *)val, "HELLO"); + val = (char *)session_table_search_by_addr(table, &addr2_reverse); + EXPECT_TRUE(val != nullptr); + EXPECT_STREQ((const char *)val, "WORLD"); // TEST Destory session_table_destory(table); diff --git a/platform/src/packet_io.cpp b/platform/src/packet_io.cpp index b62f330..1896799 100644 --- a/platform/src/packet_io.cpp +++ b/platform/src/packet_io.cpp @@ -377,13 +377,12 @@ static struct session_ctx *data_packet_search_session(struct session_table *tabl sce_packet_get_innermost_tuple(&data_pkt, &inner_addr); four_tuple_reverse(&inner_addr, &reverse_addr); - struct session_node *node = session_table_search_by_id(table, session_id); - if (node == NULL) + struct session_ctx *session_ctx = (struct session_ctx *)session_table_search_by_id(table, session_id); + if (session_ctx == NULL) { return NULL; } - struct session_ctx *session_ctx = (struct session_ctx *)node->value; if (memcmp(&session_ctx->inner_tuple4, &inner_addr, sizeof(struct four_tuple)) != 0 && memcmp(&session_ctx->inner_tuple4, &reverse_addr, sizeof(struct four_tuple)) != 0) { char *addr_str = four_tuple_tostring(&inner_addr); @@ -405,8 +404,8 @@ static struct session_ctx *inject_packet_search_session(struct session_table *ta packet_parse(&data_pkt, raw_data, raw_len); sce_packet_get_innermost_tuple(&data_pkt, &inner_addr); - struct session_node *node = session_table_search_by_addr(table, &inner_addr); - if (node == NULL) + struct session_ctx *session_ctx = (struct session_ctx *)session_table_search_by_addr(table, &inner_addr); + if (session_ctx == NULL) { char *addr_str = four_tuple_tostring(&inner_addr); LOG_ERROR("%s: unexpected inject packet, unable to find session %s from session table, drop !!!", LOG_TAG_PKTIO, addr_str); @@ -414,7 +413,7 @@ static struct session_ctx *inject_packet_search_session(struct session_table *ta return NULL; } - return (struct session_ctx *)node->value; + return session_ctx; } /****************************************************************************** @@ -951,10 +950,9 @@ static void handle_session_closing(struct metadata *meta, struct control_packet struct thread_metrics *thread_metrics = &thread_ctx->thread_metrics; struct session_table *session_table = thread_ctx->session_table; - struct session_node *node = session_table_search_by_id(session_table, meta->session_id); - if (node) + struct session_ctx *s_ctx = (struct session_ctx *)session_table_search_by_id(session_table, meta->session_id); + if (s_ctx) { - struct session_ctx *s_ctx = (struct session_ctx *)node->value; LOG_INFO("%s: session %lu %s closing", LOG_TAG_PKTIO, s_ctx->session_id, s_ctx->session_addr); dump_sf_metrics(s_ctx, s_ctx->chaining_raw); @@ -972,11 +970,9 @@ static void handle_session_active(struct metadata *meta, struct control_packet * struct policy_enforcer *enforcer = thread_ctx->ref_enforcer; struct sce_ctx *sce_ctx = thread_ctx->ref_sce_ctx; - struct session_node *node = session_table_search_by_id(session_table, meta->session_id); - if (node) + struct session_ctx *session_ctx = (struct session_ctx *)session_table_search_by_id(session_table, meta->session_id); + if (session_ctx) { - struct session_ctx *session_ctx = (struct session_ctx *)node->value; - struct packet data_pkt; const char *payload = packet_parse(&data_pkt, meta->raw_data, meta->raw_len); uint16_t real_offset = payload - meta->raw_data;