aboutsummaryrefslogtreecommitdiff
path: root/src/lib/protocols
diff options
context:
space:
mode:
authorLuca <deri@ntop.org>2019-08-12 14:16:28 +0200
committerLuca <deri@ntop.org>2019-08-12 14:16:28 +0200
commitfdeecf5d41cd05bb831b7ccc377a6aff7ec18ec2 (patch)
treea912f558a56a82263f4b1d37f4a1394d09533e8a /src/lib/protocols
parent51ac583d83da16a5216f346d1834e156f639859e (diff)
Implemented STUN cache to enhance matching of STUN-based protocols
Diffstat (limited to 'src/lib/protocols')
-rw-r--r--src/lib/protocols/hangout.c28
-rw-r--r--src/lib/protocols/http.c22
-rw-r--r--src/lib/protocols/ookla.c4
-rw-r--r--src/lib/protocols/stun.c89
4 files changed, 111 insertions, 32 deletions
diff --git a/src/lib/protocols/hangout.c b/src/lib/protocols/hangout.c
index 99bf879cb..c96b36018 100644
--- a/src/lib/protocols/hangout.c
+++ b/src/lib/protocols/hangout.c
@@ -22,8 +22,12 @@
#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_HANGOUT_DUO
+/* #define DEBUG_LRU 1 */
+
#include "ndpi_api.h"
+/* stun.c */
+extern u_int32_t get_stun_lru_key(struct ndpi_flow_struct *flow);
/* https://support.google.com/a/answer/1279090?hl=en */
#define HANGOUT_UDP_LOW_PORT 19302
@@ -85,11 +89,29 @@ void ndpi_search_hangout(struct ndpi_detection_module_struct *ndpi_struct,
if((packet->payload_packet_len > 24) && is_google_flow(ndpi_struct, flow)) {
if(
- ((packet->udp != NULL) && (isHangoutUDPPort(ntohs(packet->udp->source)) || isHangoutUDPPort(ntohs(packet->udp->dest))))
+ ((packet->udp != NULL) && (isHangoutUDPPort(ntohs(packet->udp->source))
+ || isHangoutUDPPort(ntohs(packet->udp->dest))))
||
- ((packet->tcp != NULL) && (isHangoutTCPPort(ntohs(packet->tcp->source)) || isHangoutTCPPort(ntohs(packet->tcp->dest))))) {
+ ((packet->tcp != NULL) && (isHangoutTCPPort(ntohs(packet->tcp->source))
+ || isHangoutTCPPort(ntohs(packet->tcp->dest))))) {
NDPI_LOG_INFO(ndpi_struct, "found Hangout\n");
- ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_HANGOUT_DUO, NDPI_PROTOCOL_UNKNOWN);
+
+ /* Hangout is over STUN hence the LRU cache is shared */
+ if(ndpi_struct->stun_cache == NULL)
+ ndpi_struct->stun_cache = ndpi_lru_cache_init(1024);
+
+ if(ndpi_struct->stun_cache && flow->packet.iph && flow->packet.udp) {
+ u_int32_t key = get_stun_lru_key(flow);
+
+#ifdef DEBUG_LRU
+ printf("[LRU] ADDING %u / %u.%u\n", key, NDPI_PROTOCOL_STUN, NDPI_PROTOCOL_HANGOUT_DUO);
+#endif
+
+ ndpi_lru_add_to_cache(ndpi_struct->stun_cache, key, NDPI_PROTOCOL_HANGOUT_DUO);
+ }
+
+ ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_HANGOUT_DUO,
+ NDPI_PROTOCOL_STUN);
return;
}
}
diff --git a/src/lib/protocols/http.c b/src/lib/protocols/http.c
index 1e066c3ac..cd5f193db 100644
--- a/src/lib/protocols/http.c
+++ b/src/lib/protocols/http.c
@@ -35,7 +35,7 @@ static void ndpi_int_http_add_connection(struct ndpi_detection_module_struct *nd
printf("[%s] [http_dont_dissect_response: %u]->> %s\n", __FUNCTION__,
ndpi_struct->http_dont_dissect_response, flow->http.response_status_code);
#endif
-
+
if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) {
/* This is HTTP and it is not a sub protocol (e.g. skype or dropbox) */
@@ -157,7 +157,7 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_
#endif
/* Leave the statement below commented necessary in case of call to ndpi_get_partial_detection() */
-
+
/* if(!ndpi_struct->http_dont_dissect_response) */ {
if((flow->http.url == NULL)
&& (packet->http_url_name.len > 0)
@@ -320,7 +320,7 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_
/**
check result of host subprotocol detection
-
+
if "detected" in flow == 0 then "detected" = "guess"
else "guess" = "detected"
**/
@@ -338,7 +338,7 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_
if(flow->detected_protocol_stack[0] != flow->guessed_host_protocol_id)
flow->guessed_host_protocol_id = flow->detected_protocol_stack[0];
}
-
+
if((flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN)
&& ((ndpi_struct->http_dont_dissect_response) || flow->http_detected)
&& (packet->http_origin.len > 0)) {
@@ -480,17 +480,17 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct
if(packet->payload_packet_len >= 12) {
char buf[4];
-
+
/* Set server HTTP response code */
strncpy(buf, (char*)&packet->payload[9], 3);
buf[3] = '\0';
-
+
flow->http.response_status_code = atoi(buf);
/* https://en.wikipedia.org/wiki/List_of_HTTP_status_codes */
if((flow->http.response_status_code < 100) || (flow->http.response_status_code > 509))
flow->http.response_status_code = 0; /* Out of range */
}
-
+
ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP);
check_content_type_and_change_protocol(ndpi_struct, flow);
return;
@@ -533,14 +533,14 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct
if(ndpi_struct->ookla_cache == NULL)
ndpi_struct->ookla_cache = ndpi_lru_cache_init(1024);
-
+
if(packet->iph != NULL && ndpi_struct->ookla_cache != NULL) {
if(packet->tcp->source == htons(8080))
- ndpi_lru_add_to_cache(ndpi_struct->ookla_cache, packet->iph->saddr);
+ ndpi_lru_add_to_cache(ndpi_struct->ookla_cache, packet->iph->saddr, 1 /* dummy */);
else
- ndpi_lru_add_to_cache(ndpi_struct->ookla_cache, packet->iph->daddr);
+ ndpi_lru_add_to_cache(ndpi_struct->ookla_cache, packet->iph->daddr, 1 /* dummy */);
}
-
+
return;
}
diff --git a/src/lib/protocols/ookla.c b/src/lib/protocols/ookla.c
index 44746fbd3..f3c2108bc 100644
--- a/src/lib/protocols/ookla.c
+++ b/src/lib/protocols/ookla.c
@@ -38,7 +38,9 @@ void ndpi_search_ookla(struct ndpi_detection_module_struct* ndpi_struct, struct
goto ookla_exclude;
if(ndpi_struct->ookla_cache != NULL) {
- if(ndpi_lru_find_cache(ndpi_struct->ookla_cache, addr, 0 /* Don't remove it as it can be used for other connections */)) {
+ u_int16_t dummy;
+
+ if(ndpi_lru_find_cache(ndpi_struct->ookla_cache, addr, &dummy, 0 /* Don't remove it as it can be used for other connections */)) {
NDPI_LOG_INFO(ndpi_struct, "found ookla tcp connection\n");
ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OOKLA, NDPI_PROTOCOL_UNKNOWN);
return;
diff --git a/src/lib/protocols/stun.c b/src/lib/protocols/stun.c
index 2536d0567..8334c667a 100644
--- a/src/lib/protocols/stun.c
+++ b/src/lib/protocols/stun.c
@@ -32,6 +32,8 @@
/* #define DEBUG_STUN 1 */
+/* #define DEBUG_LRU 1 */
+
struct stun_packet_header {
u_int16_t msg_type, msg_len;
u_int32_t cookie;
@@ -40,9 +42,41 @@ struct stun_packet_header {
/* ************************************************************ */
+u_int32_t get_stun_lru_key(struct ndpi_flow_struct *flow) {
+ return(flow->packet.iph->saddr + flow->packet.udp->source);
+}
+
+/* ************************************************************ */
+
static void ndpi_int_stun_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
- u_int proto, struct ndpi_flow_struct *flow) {
- ndpi_set_detected_protocol(ndpi_struct, flow, proto, NDPI_PROTOCOL_UNKNOWN);
+ struct ndpi_flow_struct *flow,
+ u_int app_proto, u_int proto) {
+ if(ndpi_struct->stun_cache == NULL)
+ ndpi_struct->stun_cache = ndpi_lru_cache_init(1024);
+
+ if(ndpi_struct->stun_cache
+ && flow->packet.iph
+ && flow->packet.udp
+ && (app_proto != NDPI_PROTOCOL_UNKNOWN)
+ ) /* Cache flow sender info */ {
+ u_int32_t key = get_stun_lru_key(flow);
+ u_int16_t cached_proto;
+
+ if(ndpi_lru_find_cache(ndpi_struct->stun_cache, key, &cached_proto, 0 /* Don't remove it as it can be used for other connections */)) {
+#ifdef DEBUG_LRU
+ printf("[LRU] FOUND %u / %u: no need to cache %u.%u\n", key, cached_proto, proto, app_proto);
+#endif
+ app_proto = cached_proto, proto = NDPI_PROTOCOL_STUN;
+ } else {
+#ifdef DEBUG_LRU
+ printf("[LRU] ADDING %u / %u.%u\n", key, proto, app_proto);
+#endif
+
+ ndpi_lru_add_to_cache(ndpi_struct->stun_cache, key, app_proto);
+ }
+ }
+
+ ndpi_set_detected_protocol(ndpi_struct, flow, app_proto, proto);
}
typedef enum {
@@ -103,7 +137,7 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct *
*is_whatsapp = 0, *is_messenger = 0, *is_duo = 0;
if(payload_length < sizeof(struct stun_packet_header)) {
- /* This looks like an invlid packet */
+ /* This looks like an invalid packet */
if(flow->protos.stun_ssl.stun.num_udp_pkts > 0) {
*is_whatsapp = 1;
@@ -124,6 +158,28 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct *
if(msg_type > 0x000C)
return(NDPI_IS_NOT_STUN);
+ if(ndpi_struct->stun_cache) {
+ u_int16_t proto;
+ u_int32_t key = get_stun_lru_key(flow);
+
+ if(ndpi_lru_find_cache(ndpi_struct->stun_cache, key, &proto, 0 /* Don't remove it as it can be used for other connections */)) {
+#ifdef DEBUG_LRU
+ printf("[LRU] FOUND %u / %u\n", key, proto);
+#endif
+
+ flow->guessed_host_protocol_id = proto, flow->guessed_protocol_id = NDPI_PROTOCOL_STUN;
+ return(NDPI_IS_STUN);
+ } else {
+#ifdef DEBUG_LRU
+ printf("[LRU] NOT FOUND %u\n", key);
+#endif
+ }
+ } else {
+#ifdef DEBUG_LRU
+ printf("[LRU] NO/EMPTY CACHE\n");
+#endif
+ }
+
if(msg_type == 0x01 /* Binding Request */) {
flow->protos.stun_ssl.stun.num_binding_requests++;
@@ -229,7 +285,7 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct *
if(strstr((char*)flow->host_server_name, "google.com") != NULL) {
*is_duo = 1;
- flow->guessed_protocol_id = NDPI_PROTOCOL_HANGOUT_DUO;
+ flow->guessed_host_protocol_id = NDPI_PROTOCOL_HANGOUT_DUO, flow->guessed_protocol_id = NDPI_PROTOCOL_STUN;
return(NDPI_IS_STUN);
}
}
@@ -245,8 +301,7 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct *
*is_duo = 1;
if(1) {
- flow->guessed_host_protocol_id = NDPI_PROTOCOL_HANGOUT_DUO;
- flow->guessed_protocol_id = NDPI_PROTOCOL_STUN;
+ flow->guessed_host_protocol_id = NDPI_PROTOCOL_HANGOUT_DUO, flow->guessed_protocol_id = NDPI_PROTOCOL_STUN;
return(NDPI_IS_NOT_STUN); /* This case is found also with signal traffic */
} else
return(NDPI_IS_STUN);
@@ -386,20 +441,21 @@ void ndpi_search_stun(struct ndpi_detection_module_struct *ndpi_struct, struct n
if(flow->guessed_protocol_id == NDPI_PROTOCOL_UNKNOWN) flow->guessed_protocol_id = NDPI_PROTOCOL_STUN;
if(is_messenger) {
- ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_MESSENGER, NDPI_PROTOCOL_STUN);
+ ndpi_int_stun_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MESSENGER, NDPI_PROTOCOL_STUN);
return;
} else if(is_duo) {
- ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_HANGOUT_DUO, NDPI_PROTOCOL_STUN);
+ ndpi_int_stun_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HANGOUT_DUO, NDPI_PROTOCOL_STUN);
return;
} else if(flow->protos.stun_ssl.stun.is_skype) {
NDPI_LOG_INFO(ndpi_struct, "found Skype\n");
if((flow->protos.stun_ssl.stun.num_processed_pkts >= 8) || (flow->protos.stun_ssl.stun.num_binding_requests >= 4))
- ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SKYPE_CALL, NDPI_PROTOCOL_SKYPE);
+ ndpi_int_stun_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SKYPE_CALL, NDPI_PROTOCOL_SKYPE);
} else {
NDPI_LOG_INFO(ndpi_struct, "found UDP stun\n"); /* Ummmmm we're in the TCP branch. This code looks bad */
- ndpi_int_stun_add_connection(ndpi_struct,
- is_whatsapp ? (is_whatsapp == 1 ? NDPI_PROTOCOL_WHATSAPP_VOICE : NDPI_PROTOCOL_WHATSAPP_VIDEO) : NDPI_PROTOCOL_STUN, flow);
+ ndpi_int_stun_add_connection(ndpi_struct, flow,
+ is_whatsapp ? (is_whatsapp == 1 ? NDPI_PROTOCOL_WHATSAPP_VOICE : NDPI_PROTOCOL_WHATSAPP_VIDEO) : NDPI_PROTOCOL_STUN,
+ NDPI_PROTOCOL_UNKNOWN);
}
return;
@@ -414,23 +470,22 @@ void ndpi_search_stun(struct ndpi_detection_module_struct *ndpi_struct, struct n
if(flow->guessed_protocol_id == NDPI_PROTOCOL_UNKNOWN) flow->guessed_protocol_id = NDPI_PROTOCOL_STUN;
if(is_messenger) {
- ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_MESSENGER, NDPI_PROTOCOL_STUN);
+ ndpi_int_stun_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MESSENGER, NDPI_PROTOCOL_STUN);
return;
} else if(is_duo) {
- ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_HANGOUT_DUO, NDPI_PROTOCOL_STUN);
+ ndpi_int_stun_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HANGOUT_DUO, NDPI_PROTOCOL_STUN);
return;
} else if(flow->protos.stun_ssl.stun.is_skype) {
NDPI_LOG_INFO(ndpi_struct, "Found Skype\n");
/* flow->protos.stun_ssl.stun.num_binding_requests < 4) ? NDPI_PROTOCOL_SKYPE_CALL_IN : NDPI_PROTOCOL_SKYPE_CALL_OUT */
if((flow->protos.stun_ssl.stun.num_processed_pkts >= 8) || (flow->protos.stun_ssl.stun.num_binding_requests >= 4))
- ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SKYPE_CALL, NDPI_PROTOCOL_SKYPE);
+ ndpi_int_stun_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SKYPE_CALL, NDPI_PROTOCOL_SKYPE);
} else {
NDPI_LOG_INFO(ndpi_struct, "found UDP stun\n");
- ndpi_int_stun_add_connection(ndpi_struct,
+ ndpi_int_stun_add_connection(ndpi_struct, flow,
is_whatsapp ? (is_whatsapp == 1 ? NDPI_PROTOCOL_WHATSAPP_VOICE : NDPI_PROTOCOL_WHATSAPP_VIDEO)
- : NDPI_PROTOCOL_STUN,
- flow);
+ : NDPI_PROTOCOL_STUN, NDPI_PROTOCOL_UNKNOWN);
}
return;