diff options
| author | lijia <[email protected]> | 2024-07-22 10:34:56 +0800 |
|---|---|---|
| committer | lijia <[email protected]> | 2024-07-22 13:35:54 +0800 |
| commit | 2ee4770462185daec28e8bb424c8e188e194c996 (patch) | |
| tree | c4394242f00311d4d7d7c84011672364c851c691 /src/ftp_decoder_hash.cpp | |
| parent | 6e906a14fee875eff1cac600710f2cedcaaef9b6 (diff) | |
Diffstat (limited to 'src/ftp_decoder_hash.cpp')
| -rw-r--r-- | src/ftp_decoder_hash.cpp | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/src/ftp_decoder_hash.cpp b/src/ftp_decoder_hash.cpp new file mode 100644 index 0000000..752505c --- /dev/null +++ b/src/ftp_decoder_hash.cpp @@ -0,0 +1,169 @@ +#include "ftp_decoder_inner.h" +#include "ftp_decoder_hash.h" +#include "ftp_decoder_util.h" +#include <MESA_htable.h> +#include <cstdint> +#include <arpa/inet.h> + +static thread_local char __ftp_hash_string_buf[1024]; + +void ftp_declare_datalink_free(void *data) +{ + struct ftp_context *fctx = (struct ftp_context *)data; + ftp_parse_result_free(&fctx->parse_result); + free(fctx); +} + +static void ftp_declare_datalink_free_only_key(void *data) +{ + return; // do nothing +} + +int ftp_hash_add(void *handle, const void *key, u_int32_t key_len, void *value) +{ + if (MESA_htable_add(handle, (const uint8_t *)key, key_len, value) < 0) + { + ftp_declare_datalink_free(value); + return -1; + } + return 0; +} + +void ftp_hash_del(void *handle, const struct ftp_link_key *hkey) +{ + const void *key; + u_int32_t key_len; + if (SESSION_ADDR_TYPE_IPV4_TCP == hkey->addr_type || SESSION_ADDR_TYPE_IPV4_UDP == hkey->addr_type) + { + key = &hkey->tuplev4; + key_len = sizeof(struct session_addr_ipv4); + } + else + { + key = &hkey->tuplev6; + key_len = sizeof(struct session_addr_ipv6); + } + MESA_htable_del(handle, (const uint8_t *)key, key_len, ftp_declare_datalink_free_only_key); +} + +void ftp_make_hkey_v4(struct session_addr_ipv4 *keyv4, uint32_t sip_net, uint32_t dip_net, uint16_t dip_port_net) +{ + memset(keyv4, 0, sizeof(struct session_addr_ipv4)); + keyv4->saddr = sip_net; + keyv4->daddr = dip_net; + keyv4->sport = 0; + keyv4->dport = dip_port_net; +} + +void ftp_make_hkey_v6(struct session_addr_ipv6 *keyv6, const struct in6_addr *sip, const struct in6_addr *dip, uint16_t dip_port_net) +{ + memset(keyv6, 0, sizeof(struct session_addr_ipv6)); + memcpy(keyv6->saddr, sip, IPV6_ADDR_LEN); + memcpy(keyv6->daddr, dip, IPV6_ADDR_LEN); + keyv6->sport = 0; + keyv6->dport = dip_port_net; +} + +int ftp_build_hashkey_from_session(struct session *sess, struct ftp_link_key *hkey) +{ + enum session_addr_type saddr_type; + struct session_addr *saddr = session_get0_addr(sess, &saddr_type); + hkey->addr_type = saddr_type; + if (SESSION_ADDR_TYPE_IPV4_TCP == saddr_type) + { + ftp_make_hkey_v4(&hkey->tuplev4, saddr->ipv4.saddr, saddr->ipv4.daddr, saddr->ipv4.dport); + } + else if (SESSION_ADDR_TYPE_IPV6_TCP == saddr_type) + { + ftp_make_hkey_v6(&hkey->tuplev6, (struct in6_addr *)saddr->ipv6.saddr, (struct in6_addr *)saddr->ipv6.daddr, saddr->ipv6.dport); + } + else + { + return -1; + } + return 0; +} + +void *ftp_hash_search(void *handle, const struct ftp_link_key *hkey) +{ + const void *key; + u_int32_t key_len; + if (SESSION_ADDR_TYPE_IPV4_TCP == hkey->addr_type || SESSION_ADDR_TYPE_IPV4_UDP == hkey->addr_type) + { + key = &hkey->tuplev4; + key_len = sizeof(struct session_addr_ipv4); + } + else + { + key = &hkey->tuplev6; + key_len = sizeof(struct session_addr_ipv6); + } + return MESA_htable_search(handle, (const uint8_t *)key, key_len); +} + +const char *ftp_hash_key_to_str(const struct ftp_link_key *hkey) +{ + char sip_str[INET6_ADDRSTRLEN], dip_str[INET6_ADDRSTRLEN]; + unsigned short sport_host, dport_host; + if (SESSION_ADDR_TYPE_IPV4_TCP == hkey->addr_type || SESSION_ADDR_TYPE_IPV4_UDP == hkey->addr_type) + { + inet_ntop(AF_INET, &hkey->tuplev4.saddr, sip_str, INET_ADDRSTRLEN); + inet_ntop(AF_INET, &hkey->tuplev4.daddr, dip_str, INET_ADDRSTRLEN); + sport_host = ntohs(hkey->tuplev4.sport); + dport_host = ntohs(hkey->tuplev4.dport); + } + else + { + inet_ntop(AF_INET, hkey->tuplev6.saddr, sip_str, INET6_ADDRSTRLEN); + inet_ntop(AF_INET, hkey->tuplev6.daddr, dip_str, INET6_ADDRSTRLEN); + sport_host = ntohs(hkey->tuplev6.sport); + dport_host = ntohs(hkey->tuplev6.dport); + } + snprintf(__ftp_hash_string_buf, sizeof(__ftp_hash_string_buf), "%s:%u -> %s:%u", sip_str, sport_host, dip_str, dport_host); + return __ftp_hash_string_buf; +} + +int ftp_hash_table_create(struct ftp_decoder_env *fenv) +{ + int opt, opt_len; + fenv->data_link_table = (void **)calloc(fenv->thread_count, sizeof(void *)); + for (int i = 0; i < fenv->thread_count; i++) + { + fenv->data_link_table[i] = MESA_htable_born(); + assert(fenv->data_link_table[i]); + + opt = 4096; + opt_len = sizeof(int); + MESA_htable_set_opt(fenv->data_link_table[i], MHO_HASH_SLOT_SIZE, &opt, opt_len); + + opt = 0; + opt_len = sizeof(int); + MESA_htable_set_opt(fenv->data_link_table[i], MHO_THREAD_SAFE, &opt, opt_len); + + opt = 0; + opt_len = sizeof(int); + MESA_htable_set_opt(fenv->data_link_table[i], MHO_SCREEN_PRINT_CTRL, &opt, opt_len); + + opt = 10; + opt_len = sizeof(int); + MESA_htable_set_opt(fenv->data_link_table[i], MHO_EXPIRE_TIME, &opt, opt_len); + MESA_htable_set_opt(fenv->data_link_table[i], MHO_CBFUN_DATA_FREE, (void *)&ftp_declare_datalink_free, sizeof(void *)); + MESA_htable_mature(fenv->data_link_table[i]); + } + return 0; +} + +void ftp_hash_table_destroy(struct ftp_decoder_env *fenv) +{ + unsigned int remain_items; + for (int i = 0; i < fenv->thread_count; i++) + { + remain_items = MESA_htable_get_elem_num(fenv->data_link_table[0]); + if (remain_items > 0) + { + ftp_runtime_log(RLOG_LV_DEBUG, "ftp_hash_table_destroy(): thread:%d declare datalink table remain items:%u\n", i, remain_items); + } + MESA_htable_destroy(fenv->data_link_table[i], ftp_declare_datalink_free); + } + free(fenv->data_link_table); +}
\ No newline at end of file |
