diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/include/ndpi_private.h | 17 | ||||
-rw-r--r-- | src/include/ndpi_typedefs.h | 2 | ||||
-rw-r--r-- | src/lib/ndpi_cache.c | 3 | ||||
-rw-r--r-- | src/lib/ndpi_main.c | 28 | ||||
-rw-r--r-- | src/lib/protocols/stun.c | 64 | ||||
-rw-r--r-- | src/lib/protocols/tls.c | 5 |
6 files changed, 115 insertions, 4 deletions
diff --git a/src/include/ndpi_private.h b/src/include/ndpi_private.h index fa8d570b6..815d193ce 100644 --- a/src/include/ndpi_private.h +++ b/src/include/ndpi_private.h @@ -190,6 +190,9 @@ struct ndpi_global_context { /* FPC DNS cache */ struct ndpi_lru_cache *fpc_dns_global_cache; + + /* Signal STUN cache */ + struct ndpi_lru_cache *signal_global_cache; }; #define CFG_MAX_LEN 256 @@ -251,7 +254,10 @@ struct ndpi_detection_module_config_struct { int fpc_dns_cache_num_entries; int fpc_dns_cache_ttl; int fpc_dns_cache_scope; - + int signal_cache_num_entries; + int signal_cache_ttl; + int signal_cache_scope; + /* Protocols */ int http_request_content_type_enabled; @@ -415,6 +421,9 @@ struct ndpi_detection_module_struct { /* NDPI_PROTOCOL_OOKLA */ struct ndpi_lru_cache *ookla_cache; + /* NDPI_PROTOCOL_SIGNAL */ + struct ndpi_lru_cache *signal_cache; + /* NDPI_PROTOCOL_BITTORRENT */ struct ndpi_lru_cache *bittorrent_cache; @@ -704,6 +713,12 @@ int ookla_search_into_cache(struct ndpi_detection_module_struct* ndpi_struct, void ookla_add_to_cache(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +/* SIGNAL */ +int signal_search_into_cache(struct ndpi_detection_module_struct* ndpi_struct, + struct ndpi_flow_struct* flow); +void signal_add_to_cache(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow); + /* QUIC */ int quic_len(const uint8_t *buf, uint64_t *value); int quic_len_buffer_still_required(uint8_t value); diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h index 7fdd90e2f..3342ba561 100644 --- a/src/include/ndpi_typedefs.h +++ b/src/include/ndpi_typedefs.h @@ -751,7 +751,7 @@ typedef enum { NDPI_LRUCACHE_MINING, NDPI_LRUCACHE_MSTEAMS, NDPI_LRUCACHE_FPC_DNS, /* FPC DNS cache */ - + NDPI_LRUCACHE_SIGNAL, NDPI_LRUCACHE_MAX /* Last one! */ } lru_cache_type; diff --git a/src/lib/ndpi_cache.c b/src/lib/ndpi_cache.c index b97bbcff3..b7d776105 100644 --- a/src/lib/ndpi_cache.c +++ b/src/lib/ndpi_cache.c @@ -206,6 +206,9 @@ int ndpi_get_lru_cache_stats(struct ndpi_global_context *g_ctx, case NDPI_LRUCACHE_FPC_DNS: ndpi_lru_get_stats(is_local ? ndpi_struct->fpc_dns_cache : g_ctx->fpc_dns_global_cache, stats); return 0; + case NDPI_LRUCACHE_SIGNAL: + ndpi_lru_get_stats(is_local ? ndpi_struct->signal_cache : g_ctx->signal_global_cache, stats); + return 0; default: return -1; } diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index 12a37a903..f821d681d 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -3481,6 +3481,8 @@ void ndpi_global_deinit(struct ndpi_global_context *g_ctx) { ndpi_lru_free_cache(g_ctx->msteams_global_cache); if(g_ctx->fpc_dns_global_cache) ndpi_lru_free_cache(g_ctx->fpc_dns_global_cache); + if(g_ctx->signal_global_cache) + ndpi_lru_free_cache(g_ctx->signal_global_cache); ndpi_free(g_ctx); } @@ -3976,6 +3978,24 @@ int ndpi_finalize_initialization(struct ndpi_detection_module_struct *ndpi_str) ndpi_str->cfg.ookla_cache_num_entries); } } + + if(ndpi_str->cfg.signal_cache_num_entries > 0) { + if(ndpi_str->cfg.signal_cache_scope == NDPI_LRUCACHE_SCOPE_GLOBAL) { + if(!ndpi_str->g_ctx->signal_global_cache) { + ndpi_str->g_ctx->signal_global_cache = ndpi_lru_cache_init(ndpi_str->cfg.signal_cache_num_entries, + ndpi_str->cfg.signal_cache_ttl, 1); + } + ndpi_str->signal_cache = ndpi_str->g_ctx->signal_global_cache; + } else { + ndpi_str->signal_cache = ndpi_lru_cache_init(ndpi_str->cfg.signal_cache_num_entries, + ndpi_str->cfg.signal_cache_ttl, 0); + } + if(!ndpi_str->signal_cache) { + NDPI_LOG_ERR(ndpi_str, "Error allocating lru cache (num_entries %u)\n", + ndpi_str->cfg.signal_cache_num_entries); + } + } + if(ndpi_str->cfg.bittorrent_cache_num_entries > 0) { if(ndpi_str->cfg.bittorrent_cache_scope == NDPI_LRUCACHE_SCOPE_GLOBAL) { if(!ndpi_str->g_ctx->bittorrent_global_cache) { @@ -4384,6 +4404,10 @@ void ndpi_exit_detection_module(struct ndpi_detection_module_struct *ndpi_str) { ndpi_str->ookla_cache) ndpi_lru_free_cache(ndpi_str->ookla_cache); + if(!ndpi_str->cfg.signal_cache_scope && + ndpi_str->signal_cache) + ndpi_lru_free_cache(ndpi_str->signal_cache); + if(!ndpi_str->cfg.bittorrent_cache_scope && ndpi_str->bittorrent_cache) ndpi_lru_free_cache(ndpi_str->bittorrent_cache); @@ -11998,6 +12022,10 @@ static const struct cfg_param { { NULL, "lru.fpc_dns.ttl", "60", "0", "16777215", CFG_PARAM_INT, __OFF(fpc_dns_cache_ttl), NULL }, { NULL, "lru.fpc_dns.scope", "0", "0", "1", CFG_PARAM_INT, __OFF(fpc_dns_cache_scope), clbk_only_with_global_ctx }, + { NULL, "lru.signal.size", "32768", "0", "16777215", CFG_PARAM_INT, __OFF(signal_cache_num_entries), NULL }, + { NULL, "lru.signal.ttl", "0", "0", "16777215", CFG_PARAM_INT, __OFF(signal_cache_ttl), NULL }, + { NULL, "lru.signal.scope", "0", "0", "1", CFG_PARAM_INT, __OFF(signal_cache_scope), clbk_only_with_global_ctx }, + { NULL, NULL, NULL, NULL, NULL, 0, -1, NULL }, }; diff --git a/src/lib/protocols/stun.c b/src/lib/protocols/stun.c index ac8cd8a47..6b7e78317 100644 --- a/src/lib/protocols/stun.c +++ b/src/lib/protocols/stun.c @@ -559,8 +559,8 @@ int is_stun(struct ndpi_detection_module_struct *ndpi_struct, bool valid = true; ndpi_hostname_sni_set(flow, payload + off + 4, ndpi_min(len, payload_length - off - 4), NDPI_HOSTNAME_NORM_ALL); - NDPI_LOG_DBG(ndpi_struct, "Realm [%s]\n", flow->host_server_name); - + NDPI_LOG_DBG(ndpi_struct, "Realm [%s]\n", flow->host_server_name); + /* Some Realm contain junk, so let's validate it */ for(i=0; flow->host_server_name[i] != '\0'; i++) { if(flow->host_server_name[i] == '?') { @@ -583,6 +583,11 @@ int is_stun(struct ndpi_detection_module_struct *ndpi_struct, *app_proto = NDPI_PROTOCOL_TELEGRAM_VOIP; } else if(strstr(flow->host_server_name, "viber") != NULL) { *app_proto = NDPI_PROTOCOL_VIBER_VOIP; + } else if(strstr(flow->host_server_name, "turn.cloudflare.com") != NULL) { + /* The latest signal implementations hide behind cloudflare */ + if(signal_search_into_cache(ndpi_struct, flow)) { + *app_proto = NDPI_PROTOCOL_SIGNAL_VOIP; + } } } else flow->host_server_name[0] = '\0'; @@ -1263,6 +1268,61 @@ static void ndpi_search_stun(struct ndpi_detection_module_struct *ndpi_struct, s NDPI_EXCLUDE_PROTO(ndpi_struct, flow); } +/* ************************************************************* */ + +static u_int64_t get_signal_key(struct ndpi_flow_struct *flow) +{ + if(flow->is_ipv6) + return ndpi_quick_hash64((const char *)flow->c_address.v6, 16); + else + return flow->c_address.v4; +} + +/* ************************************************************* */ + +int signal_search_into_cache(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) +{ + u_int64_t key; + u_int16_t dummy; + + if(ndpi_struct->signal_cache) { + key = get_signal_key(flow); + + if(ndpi_lru_find_cache(ndpi_struct->signal_cache, key, + &dummy, 0 /* Don't remove it as it can be used for other connections */, + ndpi_get_current_time(flow))) { +#ifdef DEBUG_SIGNAL_LRU + printf("[LRU SIGNAL] Found %lu [%u <-> %u]\n", key, ntohs(flow->c_port), ntohs(flow->s_port)); +#endif + return 1; + } else { +#ifdef DEBUG_SIGNAL_LRU + printf("[LRU SIGNAL] Not found %lu [%u <-> %u]\n", key, ntohs(flow->c_port), ntohs(flow->s_port)); +#endif + } + } + + return 0; +} + +/* ************************************************************* */ + +void signal_add_to_cache(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) +{ + u_int64_t key; + + if(ndpi_struct->signal_cache) { + key = get_signal_key(flow); +#ifdef DEBUG_SIGNAL_LRU + printf("[LRU SIGNAL] ADDING %lu [%u <-> %u]\n", key, ntohs(flow->c_port), ntohs(flow->s_port)); +#endif + ndpi_lru_add_to_cache(ndpi_struct->signal_cache, key, 1 /* dummy */, + ndpi_get_current_time(flow)); + } +} + /* ************************************************************ */ void init_stun_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id) { diff --git a/src/lib/protocols/tls.c b/src/lib/protocols/tls.c index c892c8961..c6d19775b 100644 --- a/src/lib/protocols/tls.c +++ b/src/lib/protocols/tls.c @@ -2860,6 +2860,11 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, ndpi_set_risk(ndpi_struct, flow, NDPI_NUMERIC_IP_HOST, sni); } + if(ndpi_str_endswith(sni, "signal.org")) { + /* printf("[SIGNAL] SNI: [%s]\n", sni); */ + signal_add_to_cache(ndpi_struct, flow); + } + if(ndpi_check_dga_name(ndpi_struct, flow, sni, 1, 0, 0)) { #ifdef DEBUG_TLS printf("[TLS] SNI: (DGA) [%s]\n", sni); |