aboutsummaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorLuca Deri <deri@ntop.org>2021-12-07 21:49:00 +0100
committerLuca Deri <deri@ntop.org>2021-12-07 21:49:00 +0100
commit8e512ff50331e2750d13b3d983f3b3216134ad18 (patch)
tree3af2c0f55005906adfdd2a9c088f4915df3000c5 /src/lib
parent519d70fa04d3ce4c2a370d56e7e2ec44015dc0e5 (diff)
Improved BitTorrent classification
Diffstat (limited to 'src/lib')
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;
}