diff options
author | Ivan Nardi <12729895+IvanNardi@users.noreply.github.com> | 2023-04-29 11:09:23 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-29 11:09:23 +0200 |
commit | bb370f5ef0817d46791ba3091297c329e3d01211 (patch) | |
tree | 0c9b6c6abd76da8e6afa9bf10d71263b857b2439 /src | |
parent | 6b803f48dc34fe69bcc257b66fa05cac510e35b9 (diff) |
Make Bittorrent LRU cache IPv6 aware. (#1909)
It was the only remaining LRU cache without IPv6 support.
See 81e1ea545ca465cda064e7cc80333fe7f0ef2aff
Diffstat (limited to 'src')
-rw-r--r-- | src/include/ndpi_protocols.h | 2 | ||||
-rw-r--r-- | src/lib/ndpi_main.c | 43 | ||||
-rw-r--r-- | src/lib/protocols/bittorrent.c | 57 |
3 files changed, 65 insertions, 37 deletions
diff --git a/src/include/ndpi_protocols.h b/src/include/ndpi_protocols.h index b97726080..c9e247834 100644 --- a/src/include/ndpi_protocols.h +++ b/src/include/ndpi_protocols.h @@ -58,8 +58,6 @@ void init_armagetron_dissector(struct ndpi_detection_module_struct *ndpi_struct, void init_amqp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id); void init_bgp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id); void init_bittorrent_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id); -int ndpi_search_into_bittorrent_cache(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, - u_int32_t saddr, u_int16_t sport, u_int32_t daddr, u_int16_t dport); void init_lisp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id); void init_teredo_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id); void init_ciscovpn_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id); diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index 3a27ff740..d2c38fbc2 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -197,6 +197,8 @@ _Static_assert(sizeof(ndpi_known_risks) / sizeof(ndpi_risk_info) == NDPI_MAX_RIS extern void ndpi_unset_risk(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow, ndpi_risk_enum r); extern u_int32_t make_mining_key(struct ndpi_flow_struct *flow); +extern u_int32_t make_bittorrent_host_key(struct ndpi_flow_struct *flow, int client, int offset); +extern u_int32_t make_bittorrent_peers_key(struct ndpi_flow_struct *flow); extern int stun_search_into_zoom_cache(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); extern void ookla_add_to_cache(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); @@ -6103,42 +6105,37 @@ u_int32_t ndpi_ip_port_hash_funct(u_int32_t ip, u_int16_t port) { /* #define BITTORRENT_CACHE_DEBUG */ int ndpi_search_into_bittorrent_cache(struct ndpi_detection_module_struct *ndpi_struct, - struct ndpi_flow_struct *flow, - /* Parameters below need to be in network byte order */ - u_int32_t saddr, u_int16_t sport, u_int32_t daddr, u_int16_t dport) { + struct ndpi_flow_struct *flow) { #ifdef BITTORRENT_CACHE_DEBUG - printf("[%s:%u] ndpi_search_into_bittorrent_cache(%08X, %u, %08X, %u) [bt_check_performed=%d]\n", - __FILE__, __LINE__, saddr, sport, daddr, dport, - flow ? flow->bt_check_performed : -1); + printf("[%s:%u] ndpi_search_into_bittorrent_cache(%u, %u) [bt_check_performed=%d]\n", + __FILE__, __LINE__, ntohs(flow->c_port), ntohs(flow->s_port), + flow->bt_check_performed); #endif - if(flow && flow->bt_check_performed /* Do the check once */) + if(flow->bt_check_performed /* Do the check once */) return(0); if(ndpi_struct->bittorrent_cache) { u_int16_t cached_proto; u_int8_t found = 0; - u_int32_t key1, key2; + u_int32_t key, key1, key2; - if(flow) - flow->bt_check_performed = 1; + flow->bt_check_performed = 1; /* Check cached communications */ - key1 = ndpi_ip_port_hash_funct(saddr, sport), key2 = ndpi_ip_port_hash_funct(daddr, dport); + key = make_bittorrent_peers_key(flow); + key1 = make_bittorrent_host_key(flow, 1, 0), key2 = make_bittorrent_host_key(flow, 0, 0); found = - ndpi_lru_find_cache(ndpi_struct->bittorrent_cache, saddr+daddr, &cached_proto, 0 /* Don't remove it as it can be used for other connections */, ndpi_get_current_time(flow)) + ndpi_lru_find_cache(ndpi_struct->bittorrent_cache, key, &cached_proto, 0 /* Don't remove it as it can be used for other connections */, ndpi_get_current_time(flow)) || ndpi_lru_find_cache(ndpi_struct->bittorrent_cache, key1, &cached_proto, 0 /* Don't remove it as it can be used for other connections */, ndpi_get_current_time(flow)) || ndpi_lru_find_cache(ndpi_struct->bittorrent_cache, key2, &cached_proto, 0 /* Don't remove it as it can be used for other connections */, ndpi_get_current_time(flow)); #ifdef BITTORRENT_CACHE_DEBUG - if(ndpi_struct->packet.udp) - printf("[BitTorrent] *** [UDP] SEARCHING ports %u / %u [%u][%u][found: %u][packet_counter: %u]\n", - ntohs(sport), ntohs(dport), key1, key2, found, flow ? flow->packet_counter : 0); - else - printf("[BitTorrent] *** [TCP] SEARCHING ports %u / %u [%u][%u][found: %u][packet_counter: %u]\n", - ntohs(sport), ntohs(dport), key1, key2, found, flow ? flow->packet_counter : 0); + printf("[BitTorrent] *** [%s] SEARCHING ports %u / %u [%u][%u][%u][found: %u]\n", + flow->l4_proto == IPPROTO_UDP ? "UDP": "TCP", + ntohs(flow->c_port), ntohs(flow->s_port), key, key1, key2, found); #endif return(found); @@ -6268,9 +6265,7 @@ ndpi_protocol ndpi_detection_giveup(struct ndpi_detection_module_struct *ndpi_st /* Does it looks like BitTorrent? */ if(ret.app_protocol == NDPI_PROTOCOL_UNKNOWN && - ndpi_search_into_bittorrent_cache(ndpi_str, flow, - flow->c_address.v4, flow->c_port, - flow->s_address.v4, flow->s_port)) { + ndpi_search_into_bittorrent_cache(ndpi_str, flow)) { ndpi_set_detected_protocol(ndpi_str, flow, NDPI_PROTOCOL_BITTORRENT, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI_PARTIAL_CACHE); ret.app_protocol = flow->detected_protocol_stack[0]; } @@ -6736,6 +6731,7 @@ static ndpi_protocol ndpi_internal_detection_process_packet(struct ndpi_detectio } flow->num_processed_pkts++; + ndpi_str->current_ts = current_time_ms; /* Init default */ @@ -7911,10 +7907,7 @@ static ndpi_protocol ndpi_internal_guess_undetected_protocol(struct ndpi_detecti } if(ret.app_protocol == NDPI_PROTOCOL_UNKNOWN && - !flow->is_ipv6 && /* TODO */ - ndpi_search_into_bittorrent_cache(ndpi_str, flow, - flow->c_address.v4, flow->c_port, - flow->s_address.v4, flow->s_port)) { + ndpi_search_into_bittorrent_cache(ndpi_str, flow)) { /* This looks like BitTorrent */ ret.app_protocol = NDPI_PROTOCOL_BITTORRENT; } diff --git a/src/lib/protocols/bittorrent.c b/src/lib/protocols/bittorrent.c index 40268cb90..9e195691b 100644 --- a/src/lib/protocols/bittorrent.c +++ b/src/lib/protocols/bittorrent.c @@ -40,6 +40,9 @@ struct ndpi_utp_hdr { u_int16_t sequence_nr, ack_nr; }; +extern int ndpi_search_into_bittorrent_cache(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow); + /* Forward declaration */ static void ndpi_search_bittorrent(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); @@ -100,12 +103,45 @@ static void ndpi_search_bittorrent_hash(struct ndpi_detection_module_struct *ndp /* *********************************************** */ +u_int32_t make_bittorrent_host_key(struct ndpi_flow_struct *flow, int client, int offset) { + u_int32_t key; + + /* network byte order */ + if(flow->is_ipv6) { + if(client) + key = ndpi_ip_port_hash_funct(ndpi_quick_hash(flow->c_address.v6, 16), htons(ntohs(flow->c_port) + offset)); + else + key = ndpi_ip_port_hash_funct(ndpi_quick_hash(flow->s_address.v6, 16), flow->s_port); + } else { + if(client) + key = ndpi_ip_port_hash_funct(flow->c_address.v4, htons(ntohs(flow->c_port) + offset)); + else + key = ndpi_ip_port_hash_funct(flow->s_address.v4, flow->s_port); + } + + return key; +} + +/* *********************************************** */ + +u_int32_t make_bittorrent_peers_key(struct ndpi_flow_struct *flow) { + u_int32_t key; + + /* network byte order */ + if(flow->is_ipv6) + key = ndpi_quick_hash(flow->c_address.v6, 16) + ndpi_quick_hash(flow->s_address.v6, 16); + else + key = flow->c_address.v4 + flow->s_address.v4; + + return key; +} + +/* *********************************************** */ + static void ndpi_add_connection_as_bittorrent(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, int bt_offset, int check_hash, ndpi_confidence_t confidence) { - struct ndpi_packet_struct *packet = &ndpi_struct->packet; - if(check_hash) ndpi_search_bittorrent_hash(ndpi_struct, flow, bt_offset); @@ -118,23 +154,24 @@ static void ndpi_add_connection_as_bittorrent(struct ndpi_detection_module_struc flow->extra_packets_func = search_bittorrent_again; } - if(ndpi_struct->bittorrent_cache && packet->iph) { - u_int32_t key1, key2, i; + if(ndpi_struct->bittorrent_cache) { + u_int32_t key, key1, key2, i; + + key = make_bittorrent_peers_key(flow); + key1 = make_bittorrent_host_key(flow, 1, 0), key2 = make_bittorrent_host_key(flow, 0, 0); - key1 = ndpi_ip_port_hash_funct(flow->c_address.v4, flow->c_port), key2 = ndpi_ip_port_hash_funct(flow->s_address.v4, flow->s_port); - ndpi_lru_add_to_cache(ndpi_struct->bittorrent_cache, key1, NDPI_PROTOCOL_BITTORRENT, ndpi_get_current_time(flow)); ndpi_lru_add_to_cache(ndpi_struct->bittorrent_cache, key2, NDPI_PROTOCOL_BITTORRENT, ndpi_get_current_time(flow)); /* Now add hosts as twins */ ndpi_lru_add_to_cache(ndpi_struct->bittorrent_cache, - flow->c_address.v4 + flow->s_address.v4, + key, NDPI_PROTOCOL_BITTORRENT, ndpi_get_current_time(flow)); - + /* Also add +2 ports of the sender in order to catch additional sockets open by the same client */ for(i=0; i<2; i++) { - key1 = ndpi_ip_port_hash_funct(flow->c_address.v4, htons(ntohs(flow->c_port)+1+i)); + key1 = make_bittorrent_host_key(flow, 1, 1 + i); ndpi_lru_add_to_cache(ndpi_struct->bittorrent_cache, key1, NDPI_PROTOCOL_BITTORRENT, ndpi_get_current_time(flow)); } @@ -430,7 +467,7 @@ static u_int8_t is_port(u_int16_t a, u_int16_t b, u_int16_t what) { static void ndpi_skip_bittorrent(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, struct ndpi_packet_struct *packet) { - if(packet->iph && ndpi_search_into_bittorrent_cache(ndpi_struct, flow, flow->c_address.v4, flow->c_port, flow->s_address.v4, flow->s_port)) + if(ndpi_search_into_bittorrent_cache(ndpi_struct, flow)) ndpi_add_connection_as_bittorrent(ndpi_struct, flow, -1, 0, NDPI_CONFIDENCE_DPI_CACHE); else NDPI_EXCLUDE_PROTO(ndpi_struct, flow); |