diff --git a/example/ndpiReader.c b/example/ndpiReader.c index ed7fa0ec6df..518ca34499f 100644 --- a/example/ndpiReader.c +++ b/example/ndpiReader.c @@ -563,7 +563,7 @@ void ndpiCheckHostStringMatch(char *testChar) { detected_protocol.proto.app_protocol, detected_protocol.breed, detected_protocol.category, - ndpi_protocol2name(ndpi_str, detected_protocol, appBufStr, + ndpi_protocol2name(ndpi_str, detected_protocol.proto, appBufStr, sizeof(appBufStr)), ndpi_get_proto_breed_name(detected_protocol.breed), ndpi_category_get_name(ndpi_str, detected_protocol.category)); @@ -640,7 +640,7 @@ void ndpiCheckHostsFileStringMatch(const char *domains_file) { printf("Domain [%s] -> %s %s %s\n", line, - ndpi_protocol2name(ndpi_str, detected_protocol, appBufStr, + ndpi_protocol2name(ndpi_str, detected_protocol.proto, appBufStr, sizeof(appBufStr)), ndpi_get_proto_breed_name(detected_protocol.breed), ndpi_category_get_name(ndpi_str, detected_protocol.category)); @@ -725,7 +725,7 @@ static void ndpiCheckIPMatch(char *testChar) { memset(&detected_protocol, 0, sizeof(ndpi_protocol)); detected_protocol.proto.app_protocol = ndpi_map_ndpi_id_to_user_proto_id(ndpi_str, ret); - ndpi_protocol2name(ndpi_str, detected_protocol, appBufStr, + ndpi_protocol2name(ndpi_str, detected_protocol.proto, appBufStr, sizeof(appBufStr)); printf("Match Found for IP %s, port %d -> %s (%d)\n", @@ -1947,11 +1947,11 @@ static void printFlow(u_int32_t id, struct ndpi_flow_info *flow, u_int16_t threa ); fprintf(csv_fp, "%s|", - ndpi_protocol2id(flow->detected_protocol, buf, sizeof(buf))); + ndpi_protocol2id(flow->detected_protocol.proto, buf, sizeof(buf))); fprintf(csv_fp, "%s|%s|%s|%s|", ndpi_protocol2name(ndpi_thread_info[thread_id].workflow->ndpi_struct, - flow->detected_protocol, buf, sizeof(buf)), + flow->detected_protocol.proto, buf, sizeof(buf)), ndpi_stack2str(ndpi_thread_info[thread_id].workflow->ndpi_struct, &flow->detected_protocol.protocol_stack, buf2, sizeof(buf2)), ndpi_get_proto_name(ndpi_thread_info[thread_id].workflow->ndpi_struct, @@ -2090,7 +2090,7 @@ static void printFlow(u_int32_t id, struct ndpi_flow_info *flow, u_int16_t threa flow->detected_protocol.proto.master_protocol, flow->detected_protocol.proto.app_protocol, ndpi_protocol2name(ndpi_thread_info[thread_id].workflow->ndpi_struct, - flow->detected_protocol, buf1, sizeof(buf1)) + flow->detected_protocol.proto, buf1, sizeof(buf1)) ); } } @@ -2132,14 +2132,14 @@ static void printFlow(u_int32_t id, struct ndpi_flow_info *flow, u_int16_t threa #ifdef NDPI_EXTENDED_SANITY_CHECKS /* Be sure new stack logic is compatible with legacy code */ - assert(ndpi_stack_get_upper_proto(&flow->detected_protocol.protocol_stack) == ndpi_get_upper_proto(flow->detected_protocol)); - assert(ndpi_stack_get_lower_proto(&flow->detected_protocol.protocol_stack) == ndpi_get_lower_proto(flow->detected_protocol)); + assert(ndpi_stack_get_upper_proto(&flow->detected_protocol.protocol_stack) == ndpi_get_upper_proto(flow->detected_protocol.proto)); + assert(ndpi_stack_get_lower_proto(&flow->detected_protocol.protocol_stack) == ndpi_get_lower_proto(flow->detected_protocol.proto)); #endif fprintf(out, "%s/%s][Stack: %s][IP: %u/%s]", - ndpi_protocol2id(flow->detected_protocol, buf, sizeof(buf)), + ndpi_protocol2id(flow->detected_protocol.proto, buf, sizeof(buf)), ndpi_protocol2name(ndpi_thread_info[thread_id].workflow->ndpi_struct, - flow->detected_protocol, buf1, sizeof(buf1)), + flow->detected_protocol.proto, buf1, sizeof(buf1)), ndpi_stack2str(ndpi_thread_info[thread_id].workflow->ndpi_struct, &flow->detected_protocol.protocol_stack, buf2, sizeof(buf2)), flow->detected_protocol.protocol_by_ip, @@ -2173,7 +2173,7 @@ static void printFlow(u_int32_t id, struct ndpi_flow_info *flow, u_int16_t threa fprintf(out, "[%s]", ndpi_is_encrypted_proto(ndpi_thread_info[thread_id].workflow->ndpi_struct, - flow->detected_protocol) ? "Encrypted" : "ClearText"); + flow->detected_protocol.proto) ? "Encrypted" : "ClearText"); fprintf(out, "[Confidence: %s]", ndpi_confidence_get_name(flow->confidence)); @@ -2738,14 +2738,13 @@ static void node_proto_guess_walker(const void *node, ndpi_VISIT which, int dept if((which == ndpi_preorder) || (which == ndpi_leaf)) { /* Avoid walking the same node multiple times */ if((!flow->detection_completed) && flow->ndpi_flow) { - u_int8_t proto_guessed; malloc_size_stats = 1; flow->detected_protocol = ndpi_detection_giveup(ndpi_thread_info[thread_id].workflow->ndpi_struct, - flow->ndpi_flow, &proto_guessed); + flow->ndpi_flow); malloc_size_stats = 0; - if(proto_guessed) ndpi_thread_info[thread_id].workflow->stats.guessed_flow_protocols++; + if(flow->ndpi_flow->protocol_was_guessed) ndpi_thread_info[thread_id].workflow->stats.guessed_flow_protocols++; } process_ndpi_collected_info(ndpi_thread_info[thread_id].workflow, flow); @@ -3147,7 +3146,7 @@ static void port_stats_walker(const void *node, ndpi_VISIT which, int depth, voi /* get app level protocol */ if(flow->detected_protocol.proto.master_protocol) { ndpi_protocol2name(ndpi_thread_info[thread_id].workflow->ndpi_struct, - flow->detected_protocol, proto, sizeof(proto)); + flow->detected_protocol.proto, proto, sizeof(proto)); } else { strncpy(proto, ndpi_get_proto_name(ndpi_thread_info[thread_id].workflow->ndpi_struct, flow->detected_protocol.proto.app_protocol),sizeof(proto) - 1); @@ -3255,7 +3254,7 @@ static void dump_realtime_protocol(struct ndpi_workflow * workflow, struct ndpi_ snprintf(dstip, sizeof(dstip), "[%s]", flow->dst_name ? flow->dst_name : ""); } - ndpi_protocol2name(workflow->ndpi_struct, flow->detected_protocol, app_name, sizeof(app_name)); + ndpi_protocol2name(workflow->ndpi_struct, flow->detected_protocol.proto, app_name, sizeof(app_name)); if (ret == 1) { fprintf(out, "Detected Realtime protocol %s --> [%s] %s:%d <--> %s:%d app=%s <%s>\n", @@ -4104,7 +4103,7 @@ static void printFlowsStats() { fprintf(out, "\t%u\t%-10s\t%s:%u <-> %s:%u\t[", i, ndpi_protocol2name(ndpi_thread_info[0].workflow->ndpi_struct, - all_flows[i].flow->detected_protocol, buf, sizeof(buf)), + all_flows[i].flow->detected_protocol.proto, buf, sizeof(buf)), all_flows[i].flow->src_name ? all_flows[i].flow->src_name : "", ntohs(all_flows[i].flow->src_port), all_flows[i].flow->dst_name ? all_flows[i].flow->dst_name : "", @@ -5103,7 +5102,7 @@ static void ndpi_process_packet(u_char *args, } trailer->flow_risk_info[sizeof(trailer->flow_risk_info) - 1] = '\0'; trailer->proto.master_protocol = htons(p.proto.master_protocol), trailer->proto.app_protocol = htons(p.proto.app_protocol); - ndpi_protocol2name(ndpi_thread_info[thread_id].workflow->ndpi_struct, p, trailer->name, sizeof(trailer->name)); + ndpi_protocol2name(ndpi_thread_info[thread_id].workflow->ndpi_struct, p.proto, trailer->name, sizeof(trailer->name)); /* Metadata */ /* Metadata are (all) available in `flow` only after nDPI completed its work! diff --git a/example/ndpiSimpleIntegration.c b/example/ndpiSimpleIntegration.c index f526e1d2648..beb4e8b13d9 100644 --- a/example/ndpiSimpleIntegration.c +++ b/example/ndpiSimpleIntegration.c @@ -876,12 +876,10 @@ static void ndpi_process_packet(uint8_t * const args, return; } else if (flow_to_process->ndpi_flow->num_processed_pkts == 0xFE) { /* last chance to guess something, better then nothing */ - uint8_t protocol_was_guessed = 0; flow_to_process->guessed_protocol = ndpi_detection_giveup(workflow->ndpi_struct, - flow_to_process->ndpi_flow, - &protocol_was_guessed); - if (protocol_was_guessed != 0) { + flow_to_process->ndpi_flow); + if (flow_to_process->ndpi_flow->protocol_was_guessed != 0) { printf("[%8llu, %d, %4d][GUESSED] protocol: %s | app protocol: %s | category: %s\n", workflow->packets_captured, reader_thread->array_index, diff --git a/example/reader_util.c b/example/reader_util.c index 85a7ebe5984..1f06e6e1562 100644 --- a/example/reader_util.c +++ b/example/reader_util.c @@ -1118,7 +1118,7 @@ static void dump_flow_fingerprint(struct ndpi_workflow * workflow, ndpi_serialize_string_uint32(&serializer, "srv_port", ntohs(flow->dst_port)); ndpi_serialize_string_string(&serializer, "proto", ndpi_protocol2name(workflow->ndpi_struct, - flow->detected_protocol, + flow->detected_protocol.proto, buf, sizeof(buf))); if(flow->server_hostname) @@ -1165,7 +1165,7 @@ static void process_ndpi_monitoring_info(struct ndpi_flow_info *flow) { return; if(flow->monitoring_state == 0 && - flow->ndpi_flow->monitoring) { + flow->ndpi_flow->state == NDPI_STATE_MONITORING) { /* We just moved to monitoring state */ flow->monitoring_state = 1; flow->num_packets_before_monitoring = flow->ndpi_flow->packet_direction_complete_counter[0] + flow->ndpi_flow->packet_direction_complete_counter[1]; @@ -1675,7 +1675,7 @@ void process_ndpi_collected_info(struct ndpi_workflow * workflow, struct ndpi_fl ndpi_serialize_string_uint32(&flow->ndpi_flow_serializer, "detection_completed", flow->detection_completed); ndpi_serialize_string_uint32(&flow->ndpi_flow_serializer, "check_extra_packets", flow->check_extra_packets); - if(flow->ndpi_flow->monitoring) { + if(flow->ndpi_flow->state == NDPI_STATE_MONITORING) { serialize_monitoring_metadata(flow); } @@ -1989,26 +1989,19 @@ static struct ndpi_proto packet_processing(struct ndpi_workflow * workflow, ipsize, time_ms, &input_info); if(monitoring_enabled) process_ndpi_monitoring_info(flow); - enough_packets |= ndpi_flow->fail_with_unknown; - if(enough_packets || (flow->detected_protocol.proto.app_protocol != NDPI_PROTOCOL_UNKNOWN)) { - if((!enough_packets) - && ndpi_extra_dissection_possible(workflow->ndpi_struct, ndpi_flow)) - ; /* Wait for further metadata */ - else { - /* New protocol detected or give up */ - flow->detection_completed = 1; - - if(flow->detected_protocol.proto.app_protocol == NDPI_PROTOCOL_UNKNOWN) { - u_int8_t proto_guessed; - - flow->detected_protocol = ndpi_detection_giveup(workflow->ndpi_struct, flow->ndpi_flow, - &proto_guessed); - if(proto_guessed) workflow->stats.guessed_flow_protocols++; - } + if(flow->detected_protocol.state == NDPI_STATE_CLASSIFIED || + enough_packets) { + + flow->detection_completed = 1; - process_ndpi_collected_info(workflow, flow); + if(flow->detected_protocol.state != NDPI_STATE_CLASSIFIED) { + flow->detected_protocol = ndpi_detection_giveup(workflow->ndpi_struct, flow->ndpi_flow); } + + if(flow->ndpi_flow->protocol_was_guessed) workflow->stats.guessed_flow_protocols++; + process_ndpi_collected_info(workflow, flow); } + /* Let's try to save client-server direction */ flow->current_pkt_from_client_to_server = input_info.in_pkt_dir; diff --git a/fuzz/fuzz_config.cpp b/fuzz/fuzz_config.cpp index 45c1253ab76..66308977bef 100644 --- a/fuzz/fuzz_config.cpp +++ b/fuzz/fuzz_config.cpp @@ -12,7 +12,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { FuzzedDataProvider fuzzed_data(data, size); struct ndpi_detection_module_struct *ndpi_info_mod; struct ndpi_flow_struct flow; - u_int8_t protocol_was_guessed, unused; + u_int8_t unused; u_int32_t i, ret; u_int16_t bool_value; struct ndpi_lru_cache_stats lru_stats; @@ -833,15 +833,15 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { ndpi_detection_get_l4(pkt.data(), pkt.size(), &l4_return, &l4_len_return, &l4_protocol_return, NDPI_DETECTION_ONLY_IPV4); ndpi_detection_process_packet(ndpi_info_mod, &flow, pkt.data(), pkt.size(), 0, &input_info); - p = ndpi_detection_giveup(ndpi_info_mod, &flow, &protocol_was_guessed); + p = ndpi_detection_giveup(ndpi_info_mod, &flow); assert(p.proto.master_protocol == ndpi_get_flow_masterprotocol(&flow)); assert(p.proto.app_protocol == ndpi_get_flow_appprotocol(&flow)); assert(p.category == ndpi_get_flow_category(&flow)); ndpi_is_master_only_protocol(ndpi_info_mod, p.proto.app_protocol); ndpi_normalize_protocol(ndpi_info_mod, &p.proto); - assert(ndpi_stack_get_upper_proto(&p.protocol_stack) == ndpi_get_upper_proto(p)); - assert(ndpi_stack_get_lower_proto(&p.protocol_stack) == ndpi_get_lower_proto(p)); + assert(ndpi_stack_get_upper_proto(&p.protocol_stack) == ndpi_get_upper_proto(p.proto)); + assert(ndpi_stack_get_lower_proto(&p.protocol_stack) == ndpi_get_lower_proto(p.proto)); ndpi_get_flow_error_code(&flow); ndpi_get_flow_risk_info(&flow, out, sizeof(out), 1); ndpi_get_flow_ndpi_proto(&flow, &p2); diff --git a/fuzz/fuzz_ndpi_reader.c b/fuzz/fuzz_ndpi_reader.c index cb390040d9b..a0087327636 100644 --- a/fuzz/fuzz_ndpi_reader.c +++ b/fuzz/fuzz_ndpi_reader.c @@ -47,10 +47,8 @@ static void node_cleanup_walker(const void *node, ndpi_VISIT which, int depth, v if((which == ndpi_preorder) || (which == ndpi_leaf)) { /* Avoid walking the same node multiple times */ if((!flow->detection_completed) && flow->ndpi_flow) { - u_int8_t proto_guessed; - flow->detected_protocol = ndpi_detection_giveup(workflow->ndpi_struct, - flow->ndpi_flow, &proto_guessed); + flow->ndpi_flow); } process_ndpi_collected_info(workflow, flow); diff --git a/fuzz/fuzz_process_packet.c b/fuzz/fuzz_process_packet.c index c570c3fd6f8..4f5453dda41 100644 --- a/fuzz/fuzz_process_packet.c +++ b/fuzz/fuzz_process_packet.c @@ -10,8 +10,6 @@ static ndpi_serializer json_serializer = {}; static ndpi_serializer csv_serializer = {}; int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { - uint8_t protocol_was_guessed; - if (ndpi_info_mod == NULL) { fuzz_init_detection_module(&ndpi_info_mod, NULL); @@ -22,19 +20,12 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { memset(&ndpi_flow, 0, SIZEOF_FLOW_STRUCT); ndpi_protocol detected_protocol = ndpi_detection_process_packet(ndpi_info_mod, &ndpi_flow, Data, Size, 0, NULL); - ndpi_protocol guessed_protocol = - ndpi_detection_giveup(ndpi_info_mod, &ndpi_flow, &protocol_was_guessed); + detected_protocol = ndpi_detection_giveup(ndpi_info_mod, &ndpi_flow); ndpi_reset_serializer(&json_serializer); ndpi_reset_serializer(&csv_serializer); - if (protocol_was_guessed == 0) - { - ndpi_dpi2json(ndpi_info_mod, &ndpi_flow, detected_protocol, &json_serializer); - ndpi_dpi2json(ndpi_info_mod, &ndpi_flow, detected_protocol, &csv_serializer); - } else { - ndpi_dpi2json(ndpi_info_mod, &ndpi_flow, guessed_protocol, &json_serializer); - ndpi_dpi2json(ndpi_info_mod, &ndpi_flow, guessed_protocol, &csv_serializer); - } + ndpi_dpi2json(ndpi_info_mod, &ndpi_flow, detected_protocol, &json_serializer); + ndpi_dpi2json(ndpi_info_mod, &ndpi_flow, detected_protocol, &csv_serializer); ndpi_free_flow_data(&ndpi_flow); return 0; diff --git a/python/ndpi/ndpi.py b/python/ndpi/ndpi.py index 6d074d3826b..6705893595f 100644 --- a/python/ndpi/ndpi.py +++ b/python/ndpi/ndpi.py @@ -59,8 +59,7 @@ def process_packet(self, flow, packet, packet_time_ms, input_info): def giveup(self, flow): p = lib.ndpi_detection_giveup(self._detection_module, - flow.C, - ffi.new("uint8_t*", 0)) + flow.C) return ndpi_protocol(C=p, master_protocol=p.proto.master_protocol, app_protocol=p.proto.app_protocol, diff --git a/python/ndpi/ndpi_build.py b/python/ndpi/ndpi_build.py index 24e9772ae49..94b5c396956 100644 --- a/python/ndpi/ndpi_build.py +++ b/python/ndpi/ndpi_build.py @@ -56,11 +56,10 @@ const u_int64_t packet_time_ms, struct ndpi_flow_input_info *input_info); ndpi_protocol ndpi_detection_giveup(struct ndpi_detection_module_struct *ndpi_struct, - struct ndpi_flow_struct *flow, - u_int8_t *protocol_was_guessed); + struct ndpi_flow_struct *flow); void ndpi_py_setup_detection_module(struct ndpi_detection_module_struct *mod); struct ndpi_flow_struct * ndpi_py_initialize_flow(void); -char* ndpi_protocol2name(struct ndpi_detection_module_struct *ndpi_mod, ndpi_protocol proto, char *buf, u_int buf_len); +char* ndpi_protocol2name(struct ndpi_detection_module_struct *ndpi_mod, ndpi_master_app_protocol proto, char *buf, u_int buf_len); const char* ndpi_category_get_name(struct ndpi_detection_module_struct *ndpi_mod, ndpi_protocol_category_t category); const char* ndpi_confidence_get_name(ndpi_confidence_t confidence); """ diff --git a/python/ndpi_example.py b/python/ndpi_example.py index f3f07a879fa..9908b98cef8 100644 --- a/python/ndpi_example.py +++ b/python/ndpi_example.py @@ -151,8 +151,8 @@ def parse_arguments(): flow.detected_protocol = nDPI.giveup(flow.ndpi_flow) # We try to guess it (port matching, LRU, etc.) FLOW_EXPORT = FLOW_STR.format(flow.index, key, - nDPI.protocol_name(flow.detected_protocol), - nDPI.protocol_category_name(flow.detected_protocol), + nDPI.protocol_name(flow.detected_protocol.proto), + nDPI.protocol_category_name(flow.detected_protocol.proto), flow.ndpi_flow.confidence.name, flow.pkts, flow.bytes) diff --git a/src/include/ndpi_api.h b/src/include/ndpi_api.h index 53bd1c9fb4d..5fccb3b7041 100644 --- a/src/include/ndpi_api.h +++ b/src/include/ndpi_api.h @@ -307,13 +307,11 @@ extern "C" { * * @par ndpi_struct = the detection module * @par flow = the flow given for the detection module - * @par protocol_was_guessed = 1 if the protocol was guessed (requires enable_guess = 1), 0 otherwise * @return the detected protocol even if the flow is not completed; * */ ndpi_protocol ndpi_detection_giveup(struct ndpi_detection_module_struct *ndpi_struct, - struct ndpi_flow_struct *flow, - u_int8_t *protocol_was_guessed); + struct ndpi_flow_struct *flow); /** * Processes one packet and returns the ID of the detected protocol. @@ -499,26 +497,26 @@ extern "C" { * Write the protocol name in the buffer -buf- as master_protocol.protocol * * @par ndpi_mod = the detection module - * @par proto = the struct ndpi_protocol contain the protocols name + * @par proto = the struct ndpi_master_app_protocol contain the protocols name * @par buf = the buffer to write the name of the protocols * @par buf_len = the length of the buffer * @return the buffer contains the master_protocol and protocol name * */ char* ndpi_protocol2name(struct ndpi_detection_module_struct *ndpi_mod, - ndpi_protocol proto, char *buf, u_int buf_len); + ndpi_master_app_protocol proto, char *buf, u_int buf_len); /** * Same as ndpi_protocol2name() with the difference that the numeric protocol * name is returned * - * @par proto = the struct ndpi_protocol contain the protocols name + * @par proto = the struct ndpi_master_app_protocol contain the protocols name * @par buf = the buffer to write the name of the protocols * @par buf_len = the length of the buffer * @return the buffer contains the master_protocol and protocol name * */ - char* ndpi_protocol2id(ndpi_protocol proto, char *buf, u_int buf_len); + char* ndpi_protocol2id(ndpi_master_app_protocol proto, char *buf, u_int buf_len); /** * Find out if a given category is custom/user-defined @@ -1059,8 +1057,8 @@ extern "C" { ndpi_l4_proto_info ndpi_get_l4_proto_info(struct ndpi_detection_module_struct *ndpi_struct, u_int16_t ndpi_proto_id); const char* ndpi_get_l4_proto_name(ndpi_l4_proto_info proto); - u_int16_t ndpi_get_lower_proto(ndpi_protocol proto); - u_int16_t ndpi_get_upper_proto(ndpi_protocol proto); + u_int16_t ndpi_get_lower_proto(ndpi_master_app_protocol proto); + u_int16_t ndpi_get_upper_proto(ndpi_master_app_protocol proto); bool ndpi_is_proto(ndpi_master_app_protocol proto, u_int16_t p); bool ndpi_is_proto_unknown(ndpi_master_app_protocol proto); bool ndpi_is_proto_equals(ndpi_master_app_protocol to_check, ndpi_master_app_protocol to_match, bool exact_match_only); @@ -1196,8 +1194,6 @@ extern "C" { int ndpi_flowv6_flow_hash(u_int8_t l4_proto, const struct ndpi_in6_addr *src_ip, const struct ndpi_in6_addr *dst_ip, u_int16_t src_port, u_int16_t dst_port, u_int8_t icmp_type, u_int8_t icmp_code, u_char *hash_buf, u_int8_t hash_buf_len); - u_int8_t ndpi_extra_dissection_possible(struct ndpi_detection_module_struct *ndpi_str, - struct ndpi_flow_struct *flow); u_int8_t ndpi_is_safe_ssl_cipher(u_int32_t cipher); const char* ndpi_cipher2str(u_int32_t cipher, char unknown_cipher[8]); const char* ndpi_tunnel2str(ndpi_packet_tunnel tt); @@ -1290,7 +1286,7 @@ extern "C" { u_int8_t ndpi_is_public_ipv4(u_int32_t a /* host byte order */); u_int64_t ndpi_htonll(u_int64_t v); u_int64_t ndpi_ntohll(u_int64_t v); - u_int8_t ndpi_is_encrypted_proto(struct ndpi_detection_module_struct *ndpi_str, ndpi_protocol proto); + u_int8_t ndpi_is_encrypted_proto(struct ndpi_detection_module_struct *ndpi_str, ndpi_master_app_protocol proto); /* DGA */ int ndpi_check_dga_name(struct ndpi_detection_module_struct *ndpi_str, diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h index 769e991c4d7..c2e4237bd50 100644 --- a/src/include/ndpi_typedefs.h +++ b/src/include/ndpi_typedefs.h @@ -1297,6 +1297,17 @@ typedef struct ndpi_proto_stack { u_int16_t protos_num; } ndpi_proto_stack; +/* Flow classification state */ +typedef enum ndpi_classification_state { + NDPI_STATE_INSPECTING = 0, /* Initial state; work in progress: nDPI is trying to get a proper classification and all metadata */ + NDPI_STATE_PARTIAL, /* Work in progress: we have a partial/temporary classification that can change/improve later. + More metadata might be extracted */ + NDPI_STATE_MONITORING, /* Classification is final, but nDPI will keep processing all the flow packets to extract more metadata. + Note that a flow in this state will never move to classified state */ + NDPI_STATE_CLASSIFIED, /* Job done; the flow is fully classified and all metadata have been extracted. nDPI doesn't want/need more packets for this flow */ + +} ndpi_classification_state; + typedef struct ndpi_proto { ndpi_master_app_protocol proto; struct ndpi_proto_stack protocol_stack; @@ -1305,6 +1316,7 @@ typedef struct ndpi_proto { ndpi_protocol_breed_t breed; struct ndpi_fpc_info fpc; void *custom_category_userdata; + ndpi_classification_state state; } ndpi_protocol; @@ -1398,14 +1410,15 @@ struct rtp_info { struct ndpi_flow_struct { u_int16_t detected_protocol_stack[NDPI_PROTOCOL_SIZE]; struct ndpi_proto_stack protocol_stack; + ndpi_classification_state state; u_int16_t guessed_protocol_id; /* Classification by-port. Set with the first pkt and never updated */ u_int16_t guessed_protocol_id_by_ip; /* Classification by-ip. Set with the first pkt and never updated */ u_int16_t fast_callback_protocol_id; /* Partial/incomplete classification. Used internally as first callback when iterating all the protocols */ u_int16_t guessed_header_category; - u_int8_t l4_proto, protocol_id_already_guessed:1, fail_with_unknown:1, - init_finished:1, client_packet_direction:1, packet_direction:1, is_ipv6:1, first_pkt_fully_encrypted:1, skip_entropy_check: 1; - u_int8_t monitoring:1, already_gaveup:1, _pad:6; + u_int8_t l4_proto, protocol_id_already_guessed:1, + init_finished:1, client_packet_direction:1, packet_direction:1, is_ipv6:1, first_pkt_fully_encrypted:1, skip_entropy_check: 1, protocol_was_guessed:1; + u_int8_t already_gaveup:1, _pad:6; void *custom_category_userdata; u_int16_t num_dissector_calls; diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index d2d782af16b..5c25a1077f4 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -9233,6 +9233,7 @@ static ndpi_protocol create_public_results(struct ndpi_detection_module_struct * ret.fpc.proto.master_protocol = ndpi_map_ndpi_id_to_user_proto_id(ndpi_str, flow->fpc.proto.master_protocol); ret.fpc.proto.app_protocol = ndpi_map_ndpi_id_to_user_proto_id(ndpi_str, flow->fpc.proto.app_protocol); ret.fpc.confidence = flow->fpc.confidence; + ret.state = flow->state; return ret; } @@ -9243,7 +9244,7 @@ static void internal_giveup(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { if(flow->already_gaveup) { - NDPI_LOG_INFO(ndpi_struct, "Already called!\n"); /* We shoudn't be here ...*/ + NDPI_LOG_ERR(ndpi_struct, "Already called!\n"); /* We shoudn't be here ...*/ return; } flow->already_gaveup = 1; @@ -9424,16 +9425,23 @@ static void internal_giveup(struct ndpi_detection_module_struct *ndpi_struct, ndpi_set_risk(ndpi_struct, flow, NDPI_MISMATCHING_PROTOCOL_WITH_IP, "nDPI protocol does not match the server IP address"); } + + if(flow->state == NDPI_STATE_CLASSIFIED) { + NDPI_LOG_ERR(ndpi_struct, "Already classified!\n"); /* We shoudn't be here ...*/ + } + flow->state = NDPI_STATE_CLASSIFIED; } /* ********************************************************************************* */ -static void ndpi_internal_detection_giveup(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow, - u_int8_t *protocol_was_guessed) { +static void ndpi_internal_detection_giveup(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow) { u_int16_t cached_proto; /* *** We can't access ndpi_str->packet from this function!! *** */ + if(flow->state == NDPI_STATE_CLASSIFIED) + return; + /* Ensure that we don't change our mind if detection is already complete */ if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN) { /* Reason: public "ndpi_detection_giveup", already classified */ @@ -9506,7 +9514,7 @@ static void ndpi_internal_detection_giveup(struct ndpi_detection_module_struct * } if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN) { - *protocol_was_guessed = 1; + flow->protocol_was_guessed = 1; fill_protocol_category_and_breed(ndpi_str, flow); } @@ -9518,20 +9526,17 @@ static void ndpi_internal_detection_giveup(struct ndpi_detection_module_struct * /* ********************************************************************************* */ -ndpi_protocol ndpi_detection_giveup(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow, - u_int8_t *protocol_was_guessed) { +ndpi_protocol ndpi_detection_giveup(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow) { /* *** We can't access ndpi_str->packet from this function!! *** */ - *protocol_was_guessed = 0; - if(!ndpi_str || !flow) { ndpi_protocol p; memset(&p, '\0', sizeof(p)); return(p); } - ndpi_internal_detection_giveup(ndpi_str, flow, protocol_was_guessed); + ndpi_internal_detection_giveup(ndpi_str, flow); return create_public_results(ndpi_str, flow); } @@ -9545,7 +9550,7 @@ static void process_extra_packet(struct ndpi_detection_module_struct *ndpi_str, /* Workaround: safety check to skip non TCP/UDP packets sent to extra dissectors (see #2762) */ if(((packet->udp != NULL) || (packet->tcp != NULL))) { if((flow->extra_packets_func(ndpi_str, flow) == 0) || - (!flow->monitoring && ++flow->num_extra_packets_checked == flow->max_extra_packets_to_check)) { + (flow->state != NDPI_STATE_MONITORING && ++flow->num_extra_packets_checked == flow->max_extra_packets_to_check)) { flow->extra_packets_func = NULL; /* Done */ } } @@ -10329,11 +10334,6 @@ static void ndpi_internal_detection_process_packet(struct ndpi_detection_module_ if(flow->monit) memset(flow->monit, '\0', sizeof(*flow->monit)); - if(flow->fail_with_unknown) { - // printf("%s(): FAIL_WITH_UNKNOWN\n", __FUNCTION__); - return; - } - if(ndpi_init_packet(ndpi_str, flow, current_time_ms, packet_data, packetlen, input_info) != 0) return; @@ -10343,12 +10343,12 @@ static void ndpi_internal_detection_process_packet(struct ndpi_detection_module_ if(ndpi_str->cfg.max_packets_to_process > 0 && flow->num_processed_pkts >= ndpi_str->cfg.max_packets_to_process && - !flow->monitoring) { - flow->extra_packets_func = NULL; /* To allow ndpi_extra_dissection_possible() to fail */ - flow->fail_with_unknown = 1; + flow->state != NDPI_STATE_MONITORING) { /* Reason: too many packets */ - internal_giveup(ndpi_str, flow); + /* We are stopping and we might not have a proper classification: + this is the reason we call ndpi_internal_detection_giveup() instead of internal_giveup() */ + ndpi_internal_detection_giveup(ndpi_str, flow); return; /* Avoid spending too much time with this flow */ } @@ -10503,11 +10503,6 @@ static void ndpi_internal_detection_process_packet(struct ndpi_detection_module_ flow->tree_risk_checked = 1; } - /* It is common to don't trigger any dissectors for pure TCP ACKs - and for for retransmissions */ - if(num_calls == 0 && - (packet->tcp_retransmission == 0 && packet->payload_packet_len != 0)) - flow->fail_with_unknown = 1; flow->num_dissector_calls += num_calls; if(ndpi_str->cfg.fully_encrypted_heuristic && @@ -10551,6 +10546,16 @@ static void ndpi_internal_detection_process_packet(struct ndpi_detection_module_ /* Reason: "normal" classification, without extra dissection */ internal_giveup(ndpi_str, flow); } + + if(num_calls == 0 && + /* It is common to don't trigger any dissectors for pure TCP ACKs + and for for retransmissions */ + (packet->tcp_retransmission == 0 && packet->payload_packet_len != 0)) { + /* Reason: no more dissector and no extra dissection */ + /* We are stopping and we might not have a proper classification: + this is the reason we call ndpi_internal_detection_giveup() instead of internal_giveup() */ + ndpi_internal_detection_giveup(ndpi_str, flow); + } } /* ********************************************************************************* */ @@ -10560,7 +10565,7 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct const unsigned short packetlen, const u_int64_t current_time_ms, struct ndpi_flow_input_info *input_info) { - if(!flow || !ndpi_str || ndpi_str->finalized != 1) { + if(!flow || !ndpi_str || ndpi_str->finalized != 1 || flow->state == NDPI_STATE_CLASSIFIED) { ndpi_protocol ret; memset(&ret, 0, sizeof(ret)); return(ret); @@ -10994,7 +10999,8 @@ void ndpi_set_detected_protocol_keeping_master(struct ndpi_detection_module_stru void ndpi_set_detected_protocol(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow, u_int16_t upper_detected_protocol, u_int16_t lower_detected_protocol, ndpi_confidence_t confidence) { - if(flow->monitoring) { + + if(flow->state == NDPI_STATE_MONITORING) { NDPI_LOG_ERR(ndpi_str, "Impossible to update classification while in monitoring state! %d/%d->%d/%d\n", flow->detected_protocol_stack[1], flow->detected_protocol_stack[0], upper_detected_protocol, lower_detected_protocol); @@ -11005,6 +11011,8 @@ void ndpi_set_detected_protocol(struct ndpi_detection_module_struct *ndpi_str, s ndpi_reconcile_protocols(ndpi_str, flow); proto_stack_update(&flow->protocol_stack, flow->detected_protocol_stack[1], flow->detected_protocol_stack[0]); + + flow->state = NDPI_STATE_PARTIAL; } /* ********************************************************************************* */ @@ -11365,14 +11373,14 @@ bool ndpi_is_proto_equals(ndpi_master_app_protocol to_check, /* ****************************************************** */ -u_int16_t ndpi_get_lower_proto(ndpi_protocol proto) { - return((proto.proto.master_protocol != NDPI_PROTOCOL_UNKNOWN) ? proto.proto.master_protocol : proto.proto.app_protocol); +u_int16_t ndpi_get_lower_proto(ndpi_master_app_protocol proto) { + return((proto.master_protocol != NDPI_PROTOCOL_UNKNOWN) ? proto.master_protocol : proto.app_protocol); } /* ****************************************************** */ -u_int16_t ndpi_get_upper_proto(ndpi_protocol proto) { - return((proto.proto.app_protocol != NDPI_PROTOCOL_UNKNOWN) ? proto.proto.app_protocol : proto.proto.master_protocol); +u_int16_t ndpi_get_upper_proto(ndpi_master_app_protocol proto) { + return((proto.app_protocol != NDPI_PROTOCOL_UNKNOWN) ? proto.app_protocol : proto.master_protocol); } /* ****************************************************** */ @@ -11493,14 +11501,14 @@ ndpi_protocol ndpi_guess_undetected_protocol(struct ndpi_detection_module_struct /* ****************************************************** */ -char *ndpi_protocol2id(ndpi_protocol proto, char *buf, u_int buf_len) { - if((proto.proto.master_protocol != NDPI_PROTOCOL_UNKNOWN) && (proto.proto.master_protocol != proto.proto.app_protocol)) { - if(proto.proto.app_protocol != NDPI_PROTOCOL_UNKNOWN) - ndpi_snprintf(buf, buf_len, "%u.%u", proto.proto.master_protocol, proto.proto.app_protocol); +char *ndpi_protocol2id(ndpi_master_app_protocol proto, char *buf, u_int buf_len) { + if((proto.master_protocol != NDPI_PROTOCOL_UNKNOWN) && (proto.master_protocol != proto.app_protocol)) { + if(proto.app_protocol != NDPI_PROTOCOL_UNKNOWN) + ndpi_snprintf(buf, buf_len, "%u.%u", proto.master_protocol, proto.app_protocol); else - ndpi_snprintf(buf, buf_len, "%u", proto.proto.master_protocol); + ndpi_snprintf(buf, buf_len, "%u", proto.master_protocol); } else - ndpi_snprintf(buf, buf_len, "%u", proto.proto.app_protocol); + ndpi_snprintf(buf, buf_len, "%u", proto.app_protocol); return(buf); } @@ -11508,15 +11516,15 @@ char *ndpi_protocol2id(ndpi_protocol proto, char *buf, u_int buf_len) { /* ****************************************************** */ char *ndpi_protocol2name(struct ndpi_detection_module_struct *ndpi_str, - ndpi_protocol proto, char *buf, u_int buf_len) { - if((proto.proto.master_protocol != NDPI_PROTOCOL_UNKNOWN) && (proto.proto.master_protocol != proto.proto.app_protocol)) { - if(proto.proto.app_protocol != NDPI_PROTOCOL_UNKNOWN) - ndpi_snprintf(buf, buf_len, "%s.%s", ndpi_get_proto_name(ndpi_str, proto.proto.master_protocol), - ndpi_get_proto_name(ndpi_str, proto.proto.app_protocol)); + ndpi_master_app_protocol proto, char *buf, u_int buf_len) { + if((proto.master_protocol != NDPI_PROTOCOL_UNKNOWN) && (proto.master_protocol != proto.app_protocol)) { + if(proto.app_protocol != NDPI_PROTOCOL_UNKNOWN) + ndpi_snprintf(buf, buf_len, "%s.%s", ndpi_get_proto_name(ndpi_str, proto.master_protocol), + ndpi_get_proto_name(ndpi_str, proto.app_protocol)); else - ndpi_snprintf(buf, buf_len, "%s", ndpi_get_proto_name(ndpi_str, proto.proto.master_protocol)); + ndpi_snprintf(buf, buf_len, "%s", ndpi_get_proto_name(ndpi_str, proto.master_protocol)); } else - ndpi_snprintf(buf, buf_len, "%s", ndpi_get_proto_name(ndpi_str, proto.proto.app_protocol)); + ndpi_snprintf(buf, buf_len, "%s", ndpi_get_proto_name(ndpi_str, proto.app_protocol)); return(buf); } @@ -12335,27 +12343,6 @@ u_int32_t ndpi_get_current_time(struct ndpi_flow_struct *flow) /* ******************************************************************** */ -/* - This function tells if it's possible to further dissect a given flow - 0 - All possible dissection has been completed - 1 - Additional dissection is possible -*/ -u_int8_t ndpi_extra_dissection_possible(struct ndpi_detection_module_struct *ndpi_str, - struct ndpi_flow_struct *flow) { - NDPI_LOG_DBG2(ndpi_str, "Protos (%u.%u): %d\n", - flow->detected_protocol_stack[0], - flow->detected_protocol_stack[1], - !!flow->extra_packets_func); - - if(!flow->extra_packets_func) { - return(0); - } - - return(1); -} - -/* ******************************************************************** */ - const char *ndpi_get_l4_proto_name(ndpi_l4_proto_info proto) { switch(proto) { case ndpi_l4_proto_unknown: diff --git a/src/lib/ndpi_utils.c b/src/lib/ndpi_utils.c index 2268c1a5248..ee50e512075 100644 --- a/src/lib/ndpi_utils.c +++ b/src/lib/ndpi_utils.c @@ -1193,12 +1193,12 @@ void ndpi_serialize_proto(struct ndpi_detection_module_struct *ndpi_struct, ndpi_serialize_risk(serializer, risk); ndpi_serialize_confidence(serializer, confidence); - ndpi_serialize_string_string(serializer, "proto", ndpi_protocol2name(ndpi_struct, l7_protocol, buf, sizeof(buf))); - ndpi_serialize_string_string(serializer, "proto_id", ndpi_protocol2id(l7_protocol, buf, sizeof(buf))); + ndpi_serialize_string_string(serializer, "proto", ndpi_protocol2name(ndpi_struct, l7_protocol.proto, buf, sizeof(buf))); + ndpi_serialize_string_string(serializer, "proto_id", ndpi_protocol2id(l7_protocol.proto, buf, sizeof(buf))); ndpi_serialize_string_string(serializer, "proto_by_ip", ndpi_get_proto_name(ndpi_struct, l7_protocol.protocol_by_ip)); ndpi_serialize_string_uint32(serializer, "proto_by_ip_id", l7_protocol.protocol_by_ip); - ndpi_serialize_string_uint32(serializer, "encrypted", ndpi_is_encrypted_proto(ndpi_struct, l7_protocol)); + ndpi_serialize_string_uint32(serializer, "encrypted", ndpi_is_encrypted_proto(ndpi_struct, l7_protocol.proto)); ndpi_serialize_string_string(serializer, "breed", ndpi_get_proto_breed_name(l7_protocol.breed)); ndpi_serialize_string_uint32(serializer, "category_id", l7_protocol.category); ndpi_serialize_string_string(serializer, "category", ndpi_category_get_name(ndpi_struct, l7_protocol.category)); @@ -3617,16 +3617,16 @@ u_int8_t ndpi_is_valid_protoId(const struct ndpi_detection_module_struct *ndpi_s /* ******************************************* */ u_int8_t ndpi_is_encrypted_proto(struct ndpi_detection_module_struct *ndpi_str, - ndpi_protocol proto) { - if(proto.proto.master_protocol == NDPI_PROTOCOL_UNKNOWN && ndpi_is_valid_protoId(ndpi_str, proto.proto.app_protocol)) { - return(!ndpi_str->proto_defaults[proto.proto.app_protocol].isClearTextProto); - } else if(ndpi_is_valid_protoId(ndpi_str, proto.proto.master_protocol) && ndpi_is_valid_protoId(ndpi_str, proto.proto.app_protocol)) { - if(ndpi_str->proto_defaults[proto.proto.master_protocol].isClearTextProto - && (!ndpi_str->proto_defaults[proto.proto.app_protocol].isClearTextProto)) + ndpi_master_app_protocol proto) { + if(proto.master_protocol == NDPI_PROTOCOL_UNKNOWN && ndpi_is_valid_protoId(ndpi_str, proto.app_protocol)) { + return(!ndpi_str->proto_defaults[proto.app_protocol].isClearTextProto); + } else if(ndpi_is_valid_protoId(ndpi_str, proto.master_protocol) && ndpi_is_valid_protoId(ndpi_str, proto.app_protocol)) { + if(ndpi_str->proto_defaults[proto.master_protocol].isClearTextProto + && (!ndpi_str->proto_defaults[proto.app_protocol].isClearTextProto)) return(0); else - return((ndpi_str->proto_defaults[proto.proto.master_protocol].isClearTextProto - && ndpi_str->proto_defaults[proto.proto.app_protocol].isClearTextProto) ? 0 : 1); + return((ndpi_str->proto_defaults[proto.master_protocol].isClearTextProto + && ndpi_str->proto_defaults[proto.app_protocol].isClearTextProto) ? 0 : 1); } else return(0); } diff --git a/src/lib/protocols/stun.c b/src/lib/protocols/stun.c index 4b9fca0a8b4..7710a9e9f50 100644 --- a/src/lib/protocols/stun.c +++ b/src/lib/protocols/stun.c @@ -727,13 +727,13 @@ static int keep_extra_dissection(struct ndpi_detection_module_struct *ndpi_struc } } - if(flow->monitoring) + if(flow->state == NDPI_STATE_MONITORING) return 1; if(flow->num_extra_packets_checked + 1 == flow->max_extra_packets_to_check) { if(is_monitoring_enabled(ndpi_struct, NDPI_PROTOCOL_STUN)) { NDPI_LOG_DBG(ndpi_struct, "Enabling monitoring (end extra dissection)\n"); - flow->monitoring = 1; + flow->state = NDPI_STATE_MONITORING; return 1; } } @@ -758,7 +758,7 @@ static int keep_extra_dissection(struct ndpi_detection_module_struct *ndpi_struc (flow->stun.other_address.port || !ndpi_struct->cfg.stun_other_address_enabled)) { if(is_monitoring_enabled(ndpi_struct, NDPI_PROTOCOL_STUN)) { NDPI_LOG_DBG(ndpi_struct, "Enabling monitoring (found all metadata)\n"); - flow->monitoring = 1; + flow->state = NDPI_STATE_MONITORING; return 1; } return 0; @@ -771,7 +771,7 @@ static int keep_extra_dissection(struct ndpi_detection_module_struct *ndpi_struc (flow->stun.relayed_address.port || !ndpi_struct->cfg.stun_relayed_address_enabled)) { if(is_monitoring_enabled(ndpi_struct, NDPI_PROTOCOL_STUN)) { NDPI_LOG_DBG(ndpi_struct, "Enabling monitor (found all metadata; wa case)\n"); - flow->monitoring = 1; + flow->state = NDPI_STATE_MONITORING; return 1; } return 0; @@ -781,7 +781,7 @@ static int keep_extra_dissection(struct ndpi_detection_module_struct *ndpi_struc if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_ZOOM) { if(is_monitoring_enabled(ndpi_struct, NDPI_PROTOCOL_STUN)) { NDPI_LOG_DBG(ndpi_struct, "Enabling monitor (zoom case)\n"); - flow->monitoring = 1; + flow->state = NDPI_STATE_MONITORING; return 1; } return 0; @@ -818,7 +818,7 @@ static int stun_search_again(struct ndpi_detection_module_struct *ndpi_struct, NDPI_LOG_DBG2(ndpi_struct, "Packet counter %d protos %d/%d Monitoring? %d\n", flow->packet_counter, flow->detected_protocol_stack[0], flow->detected_protocol_stack[1], - flow->monitoring); + flow->state == NDPI_STATE_MONITORING); /* TODO: check TCP support. We need to pay some attention because: * multiple msg in the same TCP segment @@ -878,7 +878,7 @@ static int stun_search_again(struct ndpi_detection_module_struct *ndpi_struct, if(flow->tls_quic.certificate_processed == 1) { NDPI_LOG_DBG(ndpi_struct, "Interesting DTLS stuff already processed. Ignoring\n"); - } else if(!flow->monitoring) { + } else if(flow->state != NDPI_STATE_MONITORING) { NDPI_LOG_DBG(ndpi_struct, "Switch to DTLS (%d/%d)\n", flow->detected_protocol_stack[0], flow->detected_protocol_stack[1]); @@ -1012,7 +1012,7 @@ static int stun_search_again(struct ndpi_detection_module_struct *ndpi_struct, flow->detected_protocol_stack[1] == NDPI_PROTOCOL_UNKNOWN) { /* From RTP dissector; if we have RTP and RTCP multiplexed together (but not STUN, yet) we always use RTP, as we do in RTP dissector */ - if(!flow->monitoring) + if(flow->state != NDPI_STATE_MONITORING) ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_RTP, NDPI_CONFIDENCE_DPI); else NDPI_LOG_DBG(ndpi_struct, "Skip RTP packet because in monitoring\n"); @@ -1076,7 +1076,7 @@ static int stun_telegram_search_again(struct ndpi_detection_module_struct *ndpi_ NDPI_LOG_DBG2(ndpi_struct, "[T] Packet counter %d protos %d/%d Monitoring? %d\n", flow->packet_counter, flow->detected_protocol_stack[0], flow->detected_protocol_stack[1], - flow->monitoring); + flow->state == NDPI_STATE_MONITORING); /* For SOME of its STUN flows, Telegram uses a custom encapsulation There is no documentation. It seems: @@ -1156,7 +1156,7 @@ static void ndpi_int_stun_add_connection(struct ndpi_detection_module_struct *nd u_int16_t new_app_proto; /* In monitoring the classification can't change again */ - if(flow->monitoring) + if(flow->state == NDPI_STATE_MONITORING) return; NDPI_LOG_DBG(ndpi_struct, "Wanting %d/%d\n", master_proto, app_proto);