2023-01-11 11:21:55 +08:00
|
|
|
#include <assert.h>
|
|
|
|
|
|
|
|
|
|
#include "session_table.h"
|
2023-02-10 14:22:40 +08:00
|
|
|
#include "utils.h"
|
2023-01-11 11:21:55 +08:00
|
|
|
|
|
|
|
|
struct session_table
|
|
|
|
|
{
|
|
|
|
|
struct session_node *root_by_id;
|
|
|
|
|
struct session_node *root_by_addr;
|
|
|
|
|
uint64_t session_node_count;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Note: session_addr must be initialized by memset(0) before use !!!
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
return table;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
2023-03-14 16:10:44 +08:00
|
|
|
if (node->value_free_cb && node->value)
|
2023-01-11 11:21:55 +08:00
|
|
|
{
|
2023-03-14 16:10:44 +08:00
|
|
|
node->value_free_cb(node->value);
|
2023-01-11 11:21:55 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free(node);
|
|
|
|
|
node = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free(table);
|
|
|
|
|
table = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-17 17:45:39 +08:00
|
|
|
void session_table_reset(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);
|
|
|
|
|
|
2023-03-14 16:10:44 +08:00
|
|
|
if (node->value_free_cb && node->value)
|
2023-02-17 17:45:39 +08:00
|
|
|
{
|
2023-03-14 16:10:44 +08:00
|
|
|
node->value_free_cb(node->value);
|
2023-02-17 17:45:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free(node);
|
|
|
|
|
node = NULL;
|
|
|
|
|
|
|
|
|
|
table->session_node_count--;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-11 11:21:55 +08:00
|
|
|
uint64_t session_table_count(struct session_table *table)
|
|
|
|
|
{
|
|
|
|
|
if (table)
|
|
|
|
|
{
|
|
|
|
|
return table->session_node_count;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// session_addr : deep copy
|
2023-03-14 16:10:44 +08:00
|
|
|
// value : shallow copy (malloc by user, free by value_free_cb)
|
2023-11-08 10:20:27 +08:00
|
|
|
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)
|
2023-01-11 11:21:55 +08:00
|
|
|
{
|
|
|
|
|
struct session_node *temp = NULL;
|
|
|
|
|
HASH_FIND(hh1, table->root_by_id, &session_id, sizeof(session_id), temp);
|
|
|
|
|
if (temp)
|
|
|
|
|
{
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
temp = (struct session_node *)calloc(1, sizeof(struct session_node));
|
|
|
|
|
assert(temp);
|
|
|
|
|
|
|
|
|
|
temp->session_id = session_id;
|
2023-11-08 10:20:27 +08:00
|
|
|
memcpy(&temp->session_addr, session_addr, sizeof(struct four_tuple));
|
2023-03-14 16:10:44 +08:00
|
|
|
temp->value = value;
|
|
|
|
|
temp->value_free_cb = value_free_cb;
|
2023-01-11 11:21:55 +08:00
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
table->session_node_count++;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int session_table_delete_by_id(struct session_table *table, uint64_t session_id)
|
|
|
|
|
{
|
|
|
|
|
struct session_node *temp = NULL;
|
|
|
|
|
HASH_FIND(hh1, table->root_by_id, &session_id, sizeof(session_id), temp);
|
|
|
|
|
if (!temp)
|
|
|
|
|
{
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HASH_DELETE(hh1, table->root_by_id, temp);
|
|
|
|
|
HASH_DELETE(hh2, table->root_by_addr, temp);
|
|
|
|
|
|
2023-03-14 16:10:44 +08:00
|
|
|
if (temp->value_free_cb && temp->value)
|
2023-01-11 11:21:55 +08:00
|
|
|
{
|
2023-03-14 16:10:44 +08:00
|
|
|
temp->value_free_cb(temp->value);
|
|
|
|
|
temp->value = NULL;
|
2023-01-11 11:21:55 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free(temp);
|
|
|
|
|
temp = NULL;
|
|
|
|
|
|
|
|
|
|
table->session_node_count--;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-08 10:20:27 +08:00
|
|
|
int session_table_delete_by_addr(struct session_table *table, const struct four_tuple *session_addr)
|
2023-01-11 11:21:55 +08:00
|
|
|
{
|
|
|
|
|
struct session_node *temp = NULL;
|
2023-11-08 10:20:27 +08:00
|
|
|
HASH_FIND(hh2, table->root_by_addr, session_addr, sizeof(struct four_tuple), temp);
|
2023-01-11 11:21:55 +08:00
|
|
|
if (!temp)
|
|
|
|
|
{
|
2023-11-08 10:20:27 +08:00
|
|
|
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);
|
2023-01-11 11:21:55 +08:00
|
|
|
if (!temp)
|
|
|
|
|
{
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HASH_DELETE(hh1, table->root_by_id, temp);
|
|
|
|
|
HASH_DELETE(hh2, table->root_by_addr, temp);
|
|
|
|
|
|
2023-03-14 16:10:44 +08:00
|
|
|
if (temp->value_free_cb && temp->value)
|
2023-01-11 11:21:55 +08:00
|
|
|
{
|
2023-03-14 16:10:44 +08:00
|
|
|
temp->value_free_cb(temp->value);
|
|
|
|
|
temp->value = NULL;
|
2023-01-11 11:21:55 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free(temp);
|
|
|
|
|
temp = NULL;
|
|
|
|
|
|
|
|
|
|
table->session_node_count--;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct session_node *session_table_search_by_id(struct session_table *table, uint64_t session_id)
|
|
|
|
|
{
|
|
|
|
|
struct session_node *temp = NULL;
|
|
|
|
|
HASH_FIND(hh1, table->root_by_id, &session_id, sizeof(session_id), temp);
|
|
|
|
|
if (!temp)
|
|
|
|
|
{
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return temp;
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-08 10:20:27 +08:00
|
|
|
struct session_node *session_table_search_by_addr(struct session_table *table, const struct four_tuple *session_addr)
|
2023-01-11 11:21:55 +08:00
|
|
|
{
|
|
|
|
|
struct session_node *temp = NULL;
|
2023-11-08 10:20:27 +08:00
|
|
|
HASH_FIND(hh2, table->root_by_addr, session_addr, sizeof(struct four_tuple), temp);
|
2023-01-11 11:21:55 +08:00
|
|
|
if (!temp)
|
|
|
|
|
{
|
2023-11-08 10:20:27 +08:00
|
|
|
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);
|
2023-01-11 11:21:55 +08:00
|
|
|
if (!temp)
|
|
|
|
|
{
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return temp;
|
|
|
|
|
}
|