diff options
author | Luca Deri <deri@ntop.org> | 2021-12-07 21:49:00 +0100 |
---|---|---|
committer | Luca Deri <deri@ntop.org> | 2021-12-07 21:49:00 +0100 |
commit | 8e512ff50331e2750d13b3d983f3b3216134ad18 (patch) | |
tree | 3af2c0f55005906adfdd2a9c088f4915df3000c5 /src/lib | |
parent | 519d70fa04d3ce4c2a370d56e7e2ec44015dc0e5 (diff) |
Improved BitTorrent classification
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/ndpi_main.c | 65 | ||||
-rw-r--r-- | src/lib/protocols/bittorrent.c | 68 |
2 files changed, 79 insertions, 54 deletions
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index 807b178e2..ed47ef5ea 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -4501,10 +4501,9 @@ void ndpi_connection_tracking(struct ndpi_detection_module_struct *ndpi_str, } flow->is_ipv6 = (packet->iphv6 != NULL); - if(flow->is_ipv6 == 0) { - flow->saddr = packet->iph->saddr; - flow->daddr = packet->iph->daddr; - } + if(flow->is_ipv6 == 0) + flow->saddr = packet->iph->saddr, flow->daddr = packet->iph->daddr; /* See (*#*) */ + flow->last_packet_time_ms = packet->current_time_ms; packet->packet_lines_parsed_complete = 0; @@ -4518,6 +4517,8 @@ void ndpi_connection_tracking(struct ndpi_detection_module_struct *ndpi_str, /* reset retried bytes here before setting it */ packet->num_retried_bytes = 0; + flow->sport = tcph->source, flow->dport = tcph->dest; /* (*#*) */ + if(!ndpi_str->direction_detect_disable) packet->packet_direction = (ntohs(tcph->source) < ntohs(tcph->dest)) ? 1 : 0; @@ -4590,6 +4591,8 @@ void ndpi_connection_tracking(struct ndpi_detection_module_struct *ndpi_str, flow->next_tcp_seq_nr[1] = 0; } } else if(udph != NULL) { + flow->sport = udph->source, flow->dport = udph->dest; /* (*#*) */ + if(!ndpi_str->direction_detect_disable) packet->packet_direction = (htons(udph->source) < htons(udph->dest)) ? 1 : 0; } @@ -4874,6 +4877,46 @@ static void ndpi_reconcile_protocols(struct ndpi_detection_module_struct *ndpi_s /* ********************************************************************************* */ +u_int32_t ndpi_bittorrent_hash_funct(u_int32_t ip, u_int16_t port) { + return(ip + 3 * port); +} + +/* ********************************************************************************* */ + +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) { + if((!flow->bittorrent.bt_check_performed /* Do the check once */) && ndpi_struct->bittorrent_cache) { + u_int16_t cached_proto; + u_int8_t found = 0; + u_int32_t key1, key2; + + flow->bittorrent.bt_check_performed = 1; + + /* Check cached communications */ + key1 = ndpi_bittorrent_hash_funct(saddr, sport), key2 = ndpi_bittorrent_hash_funct(daddr, dport); + + found = 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_lru_find_cache(ndpi_struct->bittorrent_cache, key2, &cached_proto, 0 /* Don't remove it as it can be used for other connections */); + +#ifdef BITTORRENT_CACHE_DEBUG + if(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->packet_counter); + else + printf("[BitTorrent] *** [TCP] SEARCHING ports %u / %u [%u][%u][found: %u][packet_counter: %u]\n", + ntohs(sport), ntohs(dport), key1, key2, found, flow->packet_counter); +#endif + + return(found); + } + + return(0); +} + +/* ********************************************************************************* */ + ndpi_protocol ndpi_detection_giveup(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow, u_int8_t enable_guess, u_int8_t *protocol_was_guessed) { ndpi_protocol ret = {NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED}; @@ -4985,8 +5028,7 @@ ndpi_protocol ndpi_detection_giveup(struct ndpi_detection_module_struct *ndpi_st if((flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) && (flow->guessed_protocol_id == NDPI_PROTOCOL_STUN)) { check_stun_export: - /* if(flow->protos.stun.num_processed_pkts || flow->protos.stun.num_udp_pkts) */ - { + /* if(flow->protos.stun.num_processed_pkts || flow->protos.stun.num_udp_pkts) */ { // if(/* (flow->protos.stun.num_processed_pkts >= NDPI_MIN_NUM_STUN_DETECTION) */ *protocol_was_guessed = 1; ndpi_set_detected_protocol(ndpi_str, flow, flow->guessed_host_protocol_id, NDPI_PROTOCOL_STUN); @@ -5008,6 +5050,17 @@ ndpi_protocol ndpi_detection_giveup(struct ndpi_detection_module_struct *ndpi_st } } + if((ret.master_protocol == NDPI_PROTOCOL_UNKNOWN) + && (ret.app_protocol == NDPI_PROTOCOL_UNKNOWN)) { + /* Last resort */ + if(ndpi_search_into_bittorrent_cache(ndpi_str, flow, + flow->saddr, flow->sport, + flow->daddr, flow->dport)) { + /* This looks like BitTorrent */ + ret.app_protocol = NDPI_PROTOCOL_BITTORRENT; + } + } + if(ret.app_protocol != NDPI_PROTOCOL_UNKNOWN) { *protocol_was_guessed = 1; ndpi_fill_protocol_category(ndpi_str, flow, &ret); diff --git a/src/lib/protocols/bittorrent.c b/src/lib/protocols/bittorrent.c index 6f5fd3884..69377cea7 100644 --- a/src/lib/protocols/bittorrent.c +++ b/src/lib/protocols/bittorrent.c @@ -37,7 +37,7 @@ #define BITTORRENT_PROTO_STRING "BitTorrent protocol" -//#define CACHE_DEBUG 1 +// #define BITTORRENT_CACHE_DEBUG 1 struct ndpi_utp_hdr { u_int8_t h_version:4, h_type:4, next_extension; @@ -65,12 +65,6 @@ static int search_bittorrent_again(struct ndpi_detection_module_struct *ndpi_str /* *********************************************** */ -static inline u_int32_t bt_hash_funct(u_int32_t ip, u_int16_t port) { - return(ip + 3 * port); -} - -/* *********************************************** */ - static u_int8_t is_utpv1_pkt(const u_int8_t *payload, u_int payload_len) { struct ndpi_utp_hdr *h = (struct ndpi_utp_hdr*)payload; @@ -140,14 +134,14 @@ static void ndpi_add_connection_as_bittorrent(struct ndpi_detection_module_struc u_int32_t key1, key2; if(packet->udp) - key1 = bt_hash_funct(packet->iph->saddr, packet->udp->source), key2 = bt_hash_funct(packet->iph->daddr, packet->udp->dest); + key1 = ndpi_bittorrent_hash_funct(packet->iph->saddr, packet->udp->source), key2 = ndpi_bittorrent_hash_funct(packet->iph->daddr, packet->udp->dest); else - key1 = bt_hash_funct(packet->iph->saddr, packet->tcp->source), key2 = bt_hash_funct(packet->iph->daddr, packet->tcp->dest); + key1 = ndpi_bittorrent_hash_funct(packet->iph->saddr, packet->tcp->source), key2 = ndpi_bittorrent_hash_funct(packet->iph->daddr, packet->tcp->dest); ndpi_lru_add_to_cache(ndpi_struct->bittorrent_cache, key1, NDPI_PROTOCOL_BITTORRENT); ndpi_lru_add_to_cache(ndpi_struct->bittorrent_cache, key2, NDPI_PROTOCOL_BITTORRENT); -#ifdef CACHE_DEBUG +#ifdef BITTORRENT_CACHE_DEBUG if(packet->udp) printf("[BitTorrent] [UDP] *** ADDED ports %u / %u [%u][%u]\n", ntohs(packet->udp->source), ntohs(packet->udp->dest), key1, key2); else @@ -462,46 +456,17 @@ static u_int8_t is_port(u_int16_t a, u_int16_t b, u_int16_t what) { /* ************************************* */ -static int search_into_bittorrent_cache(struct ndpi_detection_module_struct *ndpi_struct, - struct ndpi_flow_struct *flow, - struct ndpi_packet_struct *packet) { - if((!flow->bittorrent.bt_check_performed /* Do the check once */) && ndpi_struct->bittorrent_cache) { - u_int16_t cached_proto; - u_int8_t found = 0; - u_int32_t key1, key2; - - flow->bittorrent.bt_check_performed = 1; - - /* Check cached communications */ - if(packet->udp) - key1 = bt_hash_funct(packet->iph->saddr, packet->udp->source), key2 = bt_hash_funct(packet->iph->daddr, packet->udp->dest); - else - key1 = bt_hash_funct(packet->iph->saddr, packet->tcp->source), key2 = bt_hash_funct(packet->iph->daddr, packet->tcp->dest); - - found = 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_lru_find_cache(ndpi_struct->bittorrent_cache, key2, &cached_proto, 0 /* Don't remove it as it can be used for other connections */); - -#ifdef CACHE_DEBUG - if(packet->udp) - printf("[BitTorrent] *** [UDP] SEARCHING ports %u / %u [%u][%u][found: %u][packet_counter: %u]\n", - ntohs(packet->udp->source), ntohs(packet->udp->dest), key1, key2, found, flow->packet_counter); - else - printf("[BitTorrent] *** [TCP] SEARCHING ports %u / %u [%u][%u][found: %u][packet_counter: %u]\n", - ntohs(packet->tcp->source), ntohs(packet->tcp->dest), key1, key2, found, flow->packet_counter); -#endif - - return(found); - } - - return(0); -} - -/* ************************************* */ - static void ndpi_skip_bittorrent(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, struct ndpi_packet_struct *packet) { - if(search_into_bittorrent_cache(ndpi_struct, flow, packet)) + u_int16_t sport, dport; + + if(packet->udp) + sport = packet->udp->source, dport = packet->udp->dest; + else + sport = packet->tcp->source, dport = packet->tcp->dest; + + if(ndpi_search_into_bittorrent_cache(ndpi_struct, flow, packet->iph->saddr, sport, packet->iph->daddr, dport)) ndpi_add_connection_as_bittorrent(ndpi_struct, flow, -1, 0, NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION); else @@ -536,7 +501,14 @@ static void ndpi_search_bittorrent(struct ndpi_detection_module_struct *ndpi_str /* check for tcp retransmission here */ #ifdef EXCLUDE_BITTORRENT_QUICKLY - if(search_into_bittorrent_cache(ndpi_struct, flow, packet)) { + u_int16_t sport, dport; + + if(packet->udp) + sport = packet->udp->source, dport = packet->udp->dest; + else + sport = packet->tcp->source, dport = packet->tcp->dest; + + if(ndpi_search_into_bittorrent_cache(ndpi_struct, flow, packet->iph->saddr, sport, packet->iph->daddr, dport)) { ndpi_search_bittorrent_hash(ndpi_struct, flow, -1); goto bittorrent_found; } |