diff options
| author | lijia <[email protected]> | 2024-11-07 09:52:08 +0800 |
|---|---|---|
| committer | lijia <[email protected]> | 2024-11-18 11:10:22 +0800 |
| commit | a3d3efc5490c59684036a794b8f63f81b59685ea (patch) | |
| tree | e4283d083e1172b814412f3af826f1cf1784068e /decoders/ftp/ftp_decoder_hash.c | |
| parent | d0a868591470a4a9d71a65a5d540058e72c8d92c (diff) | |
ftp decoder rebase develop-2.0dev-ftp-v2.0
Diffstat (limited to 'decoders/ftp/ftp_decoder_hash.c')
| -rw-r--r-- | decoders/ftp/ftp_decoder_hash.c | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/decoders/ftp/ftp_decoder_hash.c b/decoders/ftp/ftp_decoder_hash.c new file mode 100644 index 0000000..3a03368 --- /dev/null +++ b/decoders/ftp/ftp_decoder_hash.c @@ -0,0 +1,138 @@ +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "ftp_decoder_inner.h" +#include "ftp_decoder_hash.h" +#include "ftp_decoder_util.h" +#include <arpa/inet.h> +#include <netinet/tcp.h> +#include <netinet/ip.h> +#include <netinet/ip6.h> +#include "uthash/uthash.h" +#include "uthash/utlist.h" + + static __thread struct ftp_datalink_htable *__thread_local_ftp_datalink_htable = NULL; + static __thread struct ftp_datalink_htable *__thread_local_ftp_datalink_htable_fifo_head = NULL; + static __thread char __ftp_hash_string_buf[FTP_HASH_STRING_BUF_SIZE]; + static __thread int ftp_local_thread_idx; + static __thread struct ftp_decoder *ftp_local_env; + + static void ftp_del_hash_item(struct ftp_datalink_htable *item) + { + ftp_decoder_stat_incrby(ftp_local_thread_idx, ftp_local_env, FTPD_STAT_DATA_LINK_HTABLE_ITEMS, -1); + HASH_DEL(__thread_local_ftp_datalink_htable, item); + DL_DELETE(__thread_local_ftp_datalink_htable_fifo_head, item); + ftp_decoder_do_exdata_free(item->ftp_ext, ftp_local_env); + free(item); // only free hash item, but not free ftp_ext + } + + static void ftp_hash_cleanup_timeout(void) + { + struct ftp_datalink_htable *to_del, *tmp; + time_t now = time(NULL); + DL_FOREACH_SAFE(__thread_local_ftp_datalink_htable_fifo_head, to_del, tmp) + { + if (now - to_del->insert_htable_time > FTP_HASH_ITEM_TIMEOUT) + { + ftp_del_hash_item(to_del); + } + } + } + + int ftp_hash_add(const ftp_hash_key_t *key, u_int32_t key_len, struct ftp_datalink_htable *new_item) + { + ftp_hash_cleanup_timeout(); + struct ftp_datalink_htable *in_hash_item = NULL; + HASH_FIND(hh, __thread_local_ftp_datalink_htable, key, key_len, in_hash_item); + if (in_hash_item != NULL) + { + return -1; // duplicate + } + HASH_ADD(hh, __thread_local_ftp_datalink_htable, hkey, key_len, new_item); + DL_APPEND(__thread_local_ftp_datalink_htable_fifo_head, new_item); + return 0; + } + + void ftp_hash_del(const ftp_hash_key_t *key) + { + struct ftp_datalink_htable *tmp = NULL; + HASH_FIND(hh, __thread_local_ftp_datalink_htable, key, sizeof(ftp_hash_key_t), tmp); + if (tmp) + { + ftp_del_hash_item(tmp); + } + } + + void ftp_make_hkey_v4(ftp_hash_key_t *keyv4, uint32_t sip_net, uint32_t dip_net, uint16_t dip_port_net) + { + memset(keyv4, 0, sizeof(ftp_hash_key_t)); + keyv4->af_inet = AF_INET; + keyv4->saddr4 = sip_net; + keyv4->daddr4 = dip_net; + keyv4->sport = 0; + keyv4->dport = dip_port_net; + } + + void ftp_make_hkey_v6(ftp_hash_key_t *keyv6, const struct in6_addr *sip, const struct in6_addr *dip, uint16_t dip_port_net) + { + memset(keyv6, 0, sizeof(ftp_hash_key_t)); + keyv6->af_inet = AF_INET6; + memcpy(&keyv6->saddr6, sip, sizeof(struct in6_addr)); + memcpy(&keyv6->daddr6, dip, sizeof(struct in6_addr)); + keyv6->sport = 0; + keyv6->dport = dip_port_net; + } + + struct ftp_datalink_htable *ftp_hash_search(const ftp_hash_key_t *key) + { + ftp_hash_cleanup_timeout(); + struct ftp_datalink_htable *tmp = NULL; + HASH_FIND(hh, __thread_local_ftp_datalink_htable, key, sizeof(ftp_hash_key_t), tmp); + return tmp; + } + + const char *ftp_hash_key_to_str(const ftp_hash_key_t *hkey) + { + char sip_str[INET6_ADDRSTRLEN], dip_str[INET6_ADDRSTRLEN]; + unsigned short sport_host, dport_host; + if (AF_INET == hkey->af_inet) + { + inet_ntop(AF_INET, &hkey->saddr4, sip_str, INET_ADDRSTRLEN); + inet_ntop(AF_INET, &hkey->daddr4, dip_str, INET_ADDRSTRLEN); + sport_host = ntohs(hkey->sport); + dport_host = ntohs(hkey->dport); + } + else + { + inet_ntop(AF_INET6, &hkey->saddr6, sip_str, INET6_ADDRSTRLEN); + inet_ntop(AF_INET6, &hkey->daddr6, dip_str, INET6_ADDRSTRLEN); + sport_host = ntohs(hkey->sport); + dport_host = ntohs(hkey->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; + } + + struct module *ftp_on_thread_init(UNUSED struct module_manager *mod_mgr, UNUSED int thread_id, struct module *mod) + { + ftp_local_thread_idx = thread_id; + __thread_local_ftp_datalink_htable = NULL; + ftp_local_env = (struct ftp_decoder *)module_get_ctx(mod); + return mod; + } + + void ftp_on_thread_exit(UNUSED struct module_manager *mod_mgr, UNUSED int thread_id, UNUSED struct module *mod) + { + struct ftp_datalink_htable *item, *tmp; + HASH_ITER(hh, __thread_local_ftp_datalink_htable, item, tmp) + { + ftp_del_hash_item(item); + } + HASH_CLEAR(hh, __thread_local_ftp_datalink_htable); + } + +#ifdef __cplusplus +} +#endif |
