aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Nardi <12729895+IvanNardi@users.noreply.github.com>2024-09-03 12:35:45 +0200
committerGitHub <noreply@github.com>2024-09-03 12:35:45 +0200
commit338eedd05b034991f1960898ca7680e65d7901f6 (patch)
tree3f09e5d966c97382803c707abcf94f221e05aa24
parent2d040247a77c96a8411477e8ad38c0e07a5e1b54 (diff)
HTTP, QUIC, TLS: allow to disable sub-classification (#2533)
-rw-r--r--doc/configuration_parameters.md3
-rw-r--r--fuzz/fuzz_config.cpp15
-rw-r--r--src/include/ndpi_private.h4
-rw-r--r--src/lib/ndpi_main.c4
-rw-r--r--src/lib/protocols/http.c5
-rw-r--r--src/lib/protocols/tls.c23
-rw-r--r--tests/cfgs/dns_subclassification_disable/config.txt1
-rw-r--r--tests/cfgs/subclassification_disable/config.txt1
l---------tests/cfgs/subclassification_disable/pcap/anydesk.pcapng1
l---------tests/cfgs/subclassification_disable/pcap/dns.pcap (renamed from tests/cfgs/dns_subclassification_disable/pcap/dns.pcap)0
l---------tests/cfgs/subclassification_disable/pcap/http.pcapng1
l---------tests/cfgs/subclassification_disable/pcap/quic-mvfst-27.pcapng1
l---------tests/cfgs/subclassification_disable/pcap/tls_ech.pcapng1
-rw-r--r--tests/cfgs/subclassification_disable/result/anydesk.pcapng.out44
-rw-r--r--tests/cfgs/subclassification_disable/result/dns.pcap.out (renamed from tests/cfgs/dns_subclassification_disable/result/dns.pcap.out)0
-rw-r--r--tests/cfgs/subclassification_disable/result/http.pcapng.out27
-rw-r--r--tests/cfgs/subclassification_disable/result/quic-mvfst-27.pcapng.out32
-rw-r--r--tests/cfgs/subclassification_disable/result/tls_ech.pcapng.out32
18 files changed, 187 insertions, 8 deletions
diff --git a/doc/configuration_parameters.md b/doc/configuration_parameters.md
index 590526868..207c0a3c4 100644
--- a/doc/configuration_parameters.md
+++ b/doc/configuration_parameters.md
@@ -29,6 +29,8 @@ TODO
| "tls" | "metadata.ja3c_fingerprint" | enable | NULL | NULL | Enable/disable computation and export of JA3C fingerprint for TLS flows. Note that if it is disable, the flow risk `NDPI_MALICIOUS_JA3` is not checked |
| "tls" | "metadata.ja3s_fingerprint" | enable | NULL | NULL | Enable/disable computation and export of JA3S fingerprint for TLS flows |
| "tls" | "metadata.ja4c_fingerprint" | enable | NULL | NULL | Enable/disable computation and export of JA4C fingerprint for TLS flows |
+| "tls" | "subclassification" | enable | NULL | NULL | Enable/disable sub-classification of TLS/DTLS flows |
+| "quic" | "subclassification" | enable | NULL | NULL | Enable/disable sub-classification of QUIC flows |
| "smtp" | "tls_dissection" | enable | NULL | NULL | Enable/disable dissection of TLS packets in cleartext SMTP flows (because of opportunistic TLS, via STARTTLS msg) |
| "imap" | "tls_dissection" | enable | NULL | NULL | Enable/disable dissection of TLS packets in cleartext IMAP flows (because of opportunistic TLS, via STARTTLS msg) |
| "pop" | "tls_dissection" | enable | NULL | NULL | Enable/disable dissection of TLS packets in cleartext POP flows (because of opportunistic TLS, via STARTTLS msg) |
@@ -43,6 +45,7 @@ TODO
| "dns" | "subclassification" | enable | NULL | NULL | Enable/disable sub-classification of DNS flows (via query/response domain name). If disabled, some flow risks are not checked |
| "dns" | "process_response" | enable | NULL | NULL | Enable/disable processing of DNS responses. By default, DNS flows are fully classified after the first request/response pair (or after the first response, if the request is missing). If this parameter is disabled, the flows are fully classified after the first packet, i.e. usually after the first request; in that case, some flow risks are not checked and some metadata are not exported |
| "http" | "process_response" | enable | NULL | NULL | Enable/disable processing of HTTP responses. By default, HTTP flows are usually fully classified after the first request/response pair. If this parameter is disabled, the flows are fully classified after the first request (or after the first response, if the request is missing); in that case, some flow risks are not checked and some metadata are not exported |
+| "http" | "subclassification" | enable | NULL | NULL | Enable/disable sub-classification of HTTP flows |
| "ookla" | "dpi.aggressiveness", | 0x01 | 0x00 | 0x01 | Detection aggressiveness for Ookla. The value is a bitmask. Values: 0x0 = disabled; 0x01 = enable heuristic for detection over TLS (via Ookla LRU cache) |
| "zoom" | "max_packets_extra_dissection" | 4 | 0 | 255 | After a flow has been classified has Zoom, nDPI might analyse more packets to look for a sub-classification or for metadata. This parameter set the upper limit on the number of these packets |
| "rtp" | "search_for_stun" | disable | NULL | NULL | After a flow has been classified as RTP or RTCP, nDPI might analyse more packets to look for STUN/DTLS packets, i.e. to try to tell if this flow is a "pure" RTP/RTCP flow or if the RTP/RTCP packets are multiplexed with STUN/DTLS. Useful for proper (sub)classification when the beginning of the flows are not captured or if there are lost packets in the the captured traffic. If enabled, nDPI requires more packets to process for each RTP/RTCP flow. |
diff --git a/fuzz/fuzz_config.cpp b/fuzz/fuzz_config.cpp
index e9a69739c..647ee4a7b 100644
--- a/fuzz/fuzz_config.cpp
+++ b/fuzz/fuzz_config.cpp
@@ -151,6 +151,16 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if(fuzzed_data.ConsumeBool()) {
value = fuzzed_data.ConsumeIntegralInRange(0, 1 + 1);
snprintf(cfg_value, sizeof(cfg_value), "%d", value);
+ ndpi_set_config(ndpi_info_mod, "tls", "subclassification", cfg_value);
+ }
+ if(fuzzed_data.ConsumeBool()) {
+ value = fuzzed_data.ConsumeIntegralInRange(0, 1 + 1);
+ snprintf(cfg_value, sizeof(cfg_value), "%d", value);
+ ndpi_set_config(ndpi_info_mod, "quic", "subclassification", cfg_value);
+ }
+ if(fuzzed_data.ConsumeBool()) {
+ value = fuzzed_data.ConsumeIntegralInRange(0, 1 + 1);
+ snprintf(cfg_value, sizeof(cfg_value), "%d", value);
ndpi_set_config(ndpi_info_mod, "smtp", "tls_dissection", cfg_value);
}
if(fuzzed_data.ConsumeBool()) {
@@ -209,6 +219,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
ndpi_set_config(ndpi_info_mod, "http", "process_response", cfg_value);
}
if(fuzzed_data.ConsumeBool()) {
+ value = fuzzed_data.ConsumeIntegralInRange(0, 1 + 1);
+ snprintf(cfg_value, sizeof(cfg_value), "%d", value);
+ ndpi_set_config(ndpi_info_mod, "http", "subclassification", cfg_value);
+ }
+ if(fuzzed_data.ConsumeBool()) {
value = fuzzed_data.ConsumeIntegralInRange(0, 0x01 + 1);
snprintf(cfg_value, sizeof(cfg_value), "%d", value);
ndpi_set_config(ndpi_info_mod, "ookla", "dpi.aggressiveness", cfg_value);
diff --git a/src/include/ndpi_private.h b/src/include/ndpi_private.h
index 4001e9bbc..3688061ca 100644
--- a/src/include/ndpi_private.h
+++ b/src/include/ndpi_private.h
@@ -236,6 +236,9 @@ struct ndpi_detection_module_config_struct {
int tls_ja3c_fingerprint_enabled;
int tls_ja3s_fingerprint_enabled;
int tls_ja4c_fingerprint_enabled;
+ int tls_subclassification_enabled;
+
+ int quic_subclassification_enabled;
int smtp_opportunistic_tls_enabled;
@@ -257,6 +260,7 @@ struct ndpi_detection_module_config_struct {
int dns_parse_response_enabled;
int http_parse_response_enabled;
+ int http_subclassification_enabled;
int ookla_aggressiveness;
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c
index 18e941fab..d74afa61a 100644
--- a/src/lib/ndpi_main.c
+++ b/src/lib/ndpi_main.c
@@ -11386,6 +11386,9 @@ static const struct cfg_param {
{ "tls", "metadata.ja3c_fingerprint", "enable", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(tls_ja3c_fingerprint_enabled), NULL },
{ "tls", "metadata.ja3s_fingerprint", "enable", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(tls_ja3s_fingerprint_enabled), NULL },
{ "tls", "metadata.ja4c_fingerprint", "enable", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(tls_ja4c_fingerprint_enabled), NULL },
+ { "tls", "subclassification", "enable", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(tls_subclassification_enabled), NULL },
+
+ { "quic", "subclassification", "enable", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(quic_subclassification_enabled), NULL },
{ "smtp", "tls_dissection", "enable", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(smtp_opportunistic_tls_enabled), NULL },
@@ -11407,6 +11410,7 @@ static const struct cfg_param {
{ "dns", "process_response", "enable", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(dns_parse_response_enabled), NULL },
{ "http", "process_response", "enable", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(http_parse_response_enabled), NULL },
+ { "http", "subclassification", "enable", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(http_subclassification_enabled), NULL },
{ "ookla", "dpi.aggressiveness", "0x01", "0", "1", CFG_PARAM_INT, __OFF(ookla_aggressiveness), NULL },
diff --git a/src/lib/protocols/http.c b/src/lib/protocols/http.c
index bf365c46f..bf26467da 100644
--- a/src/lib/protocols/http.c
+++ b/src/lib/protocols/http.c
@@ -466,6 +466,11 @@ static void ndpi_http_parse_subprotocol(struct ndpi_detection_module_struct *ndp
u_int16_t master_protocol;
struct ndpi_packet_struct *packet = &ndpi_struct->packet;
+ if(!ndpi_struct->cfg.http_subclassification_enabled) {
+ NDPI_LOG_DBG2(ndpi_struct, "Skip sub-protocol check because subclassification is disabled\n");
+ return;
+ }
+
master_protocol = NDPI_PROTOCOL_HTTP;
if(flow->detected_protocol_stack[1] != NDPI_PROTOCOL_UNKNOWN)
master_protocol = flow->detected_protocol_stack[1];
diff --git a/src/lib/protocols/tls.c b/src/lib/protocols/tls.c
index 88f92d0d5..0bdcf216b 100644
--- a/src/lib/protocols/tls.c
+++ b/src/lib/protocols/tls.c
@@ -337,7 +337,8 @@ static void checkTLSSubprotocol(struct ndpi_detection_module_struct *ndpi_struct
int is_from_client) {
struct ndpi_packet_struct *packet = &ndpi_struct->packet;
- if(flow->detected_protocol_stack[1] == NDPI_PROTOCOL_UNKNOWN) {
+ if(ndpi_struct->cfg.tls_subclassification_enabled &&
+ flow->detected_protocol_stack[1] == NDPI_PROTOCOL_UNKNOWN) {
/* Subprotocol not yet set */
if(ndpi_struct->tls_cert_cache) {
@@ -689,11 +690,13 @@ void processCertificateElements(struct ndpi_detection_module_struct *ndpi_struct
}
}
- if(!flow->protos.tls_quic.subprotocol_detected)
+ if(ndpi_struct->cfg.tls_subclassification_enabled &&
+ !flow->protos.tls_quic.subprotocol_detected) {
if(ndpi_match_hostname_protocol(ndpi_struct, flow, __get_master(ndpi_struct, flow), dNSName, dNSName_len)) {
flow->protos.tls_quic.subprotocol_detected = 1;
ndpi_unset_risk(flow, NDPI_NUMERIC_IP_HOST);
}
+ }
i += len;
} else {
@@ -726,7 +729,8 @@ void processCertificateElements(struct ndpi_detection_module_struct *ndpi_struct
if(rdn_len && (flow->protos.tls_quic.subjectDN == NULL)) {
flow->protos.tls_quic.subjectDN = ndpi_strdup(rdnSeqBuf);
- if(flow->detected_protocol_stack[1] == NDPI_PROTOCOL_UNKNOWN) {
+ if(ndpi_struct->cfg.tls_subclassification_enabled &&
+ flow->detected_protocol_stack[1] == NDPI_PROTOCOL_UNKNOWN) {
/* No idea what is happening behind the scenes: let's check the certificate */
u_int32_t val;
int rc = ndpi_match_string_value(ndpi_struct->tls_cert_subject_automa.ac_automa,
@@ -2325,10 +2329,12 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct,
}
if(!is_quic) {
- if(ndpi_match_hostname_protocol(ndpi_struct, flow, __get_master(ndpi_struct, flow), sni, sni_len))
+ if(ndpi_struct->cfg.tls_subclassification_enabled &&
+ ndpi_match_hostname_protocol(ndpi_struct, flow, __get_master(ndpi_struct, flow), sni, sni_len))
flow->protos.tls_quic.subprotocol_detected = 1;
} else {
- if(ndpi_match_hostname_protocol(ndpi_struct, flow, NDPI_PROTOCOL_QUIC, sni, sni_len))
+ if(ndpi_struct->cfg.quic_subclassification_enabled &&
+ ndpi_match_hostname_protocol(ndpi_struct, flow, NDPI_PROTOCOL_QUIC, sni, sni_len))
flow->protos.tls_quic.subprotocol_detected = 1;
}
@@ -2614,8 +2620,11 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct,
/* Without SNI matching we can try to sub-classify the flow via ALPN.
Note that this happens only on very rare cases, not the common ones
("h2", "http/1.1", ...). Usefull for asymmetric traffic */
- if(!flow->protos.tls_quic.subprotocol_detected)
- tls_subclassify_by_alpn(ndpi_struct, flow);
+ if(!flow->protos.tls_quic.subprotocol_detected) {
+ if((is_quic && ndpi_struct->cfg.quic_subclassification_enabled) ||
+ (!is_quic && ndpi_struct->cfg.tls_subclassification_enabled))
+ tls_subclassify_by_alpn(ndpi_struct, flow);
+ }
}
}
diff --git a/tests/cfgs/dns_subclassification_disable/config.txt b/tests/cfgs/dns_subclassification_disable/config.txt
deleted file mode 100644
index 0d07d9860..000000000
--- a/tests/cfgs/dns_subclassification_disable/config.txt
+++ /dev/null
@@ -1 +0,0 @@
---cfg=dns,subclassification,0
diff --git a/tests/cfgs/subclassification_disable/config.txt b/tests/cfgs/subclassification_disable/config.txt
new file mode 100644
index 000000000..3359e07b4
--- /dev/null
+++ b/tests/cfgs/subclassification_disable/config.txt
@@ -0,0 +1 @@
+--cfg=dns,subclassification,0 --cfg=http,subclassification,0 --cfg=quic,subclassification,0 --cfg=tls,subclassification,0
diff --git a/tests/cfgs/subclassification_disable/pcap/anydesk.pcapng b/tests/cfgs/subclassification_disable/pcap/anydesk.pcapng
new file mode 120000
index 000000000..1a646a724
--- /dev/null
+++ b/tests/cfgs/subclassification_disable/pcap/anydesk.pcapng
@@ -0,0 +1 @@
+../../default/pcap/anydesk.pcapng \ No newline at end of file
diff --git a/tests/cfgs/dns_subclassification_disable/pcap/dns.pcap b/tests/cfgs/subclassification_disable/pcap/dns.pcap
index aea7db12b..aea7db12b 120000
--- a/tests/cfgs/dns_subclassification_disable/pcap/dns.pcap
+++ b/tests/cfgs/subclassification_disable/pcap/dns.pcap
diff --git a/tests/cfgs/subclassification_disable/pcap/http.pcapng b/tests/cfgs/subclassification_disable/pcap/http.pcapng
new file mode 120000
index 000000000..9e909a49d
--- /dev/null
+++ b/tests/cfgs/subclassification_disable/pcap/http.pcapng
@@ -0,0 +1 @@
+../../default/pcap/http.pcapng \ No newline at end of file
diff --git a/tests/cfgs/subclassification_disable/pcap/quic-mvfst-27.pcapng b/tests/cfgs/subclassification_disable/pcap/quic-mvfst-27.pcapng
new file mode 120000
index 000000000..9b3b1ade4
--- /dev/null
+++ b/tests/cfgs/subclassification_disable/pcap/quic-mvfst-27.pcapng
@@ -0,0 +1 @@
+../../default/pcap/quic-mvfst-27.pcapng \ No newline at end of file
diff --git a/tests/cfgs/subclassification_disable/pcap/tls_ech.pcapng b/tests/cfgs/subclassification_disable/pcap/tls_ech.pcapng
new file mode 120000
index 000000000..a1efdd315
--- /dev/null
+++ b/tests/cfgs/subclassification_disable/pcap/tls_ech.pcapng
@@ -0,0 +1 @@
+../../default/pcap/tls_ech.pcapng \ No newline at end of file
diff --git a/tests/cfgs/subclassification_disable/result/anydesk.pcapng.out b/tests/cfgs/subclassification_disable/result/anydesk.pcapng.out
new file mode 100644
index 000000000..b1da5157d
--- /dev/null
+++ b/tests/cfgs/subclassification_disable/result/anydesk.pcapng.out
@@ -0,0 +1,44 @@
+DPI Packets (TCP): 34 (6.80 pkts/flow)
+DPI Packets (UDP): 4 (2.00 pkts/flow)
+Confidence DPI : 7 (flows)
+Num dissector calls: 15 (2.14 diss/flow)
+LRU cache ookla: 0/0/0 (insert/search/found)
+LRU cache bittorrent: 0/0/0 (insert/search/found)
+LRU cache stun: 0/0/0 (insert/search/found)
+LRU cache tls_cert: 0/0/0 (insert/search/found)
+LRU cache mining: 0/0/0 (insert/search/found)
+LRU cache msteams: 0/0/0 (insert/search/found)
+LRU cache fpc_dns: 0/4/0 (insert/search/found)
+Automa host: 0/0 (search/found)
+Automa domain: 0/0 (search/found)
+Automa tls cert: 0/0 (search/found)
+Automa risk mask: 2/0 (search/found)
+Automa common alpns: 1/0 (search/found)
+Patricia risk mask: 14/0 (search/found)
+Patricia risk mask IPv6: 0/0 (search/found)
+Patricia risk: 0/0 (search/found)
+Patricia risk IPv6: 0/0 (search/found)
+Patricia protocols: 12/2 (search/found)
+Patricia protocols IPv6: 0/0 (search/found)
+
+DNS 4 392 2
+TLS 170 45725 5
+
+Safe 170 45725 5
+Acceptable 4 392 2
+
+JA3 Host Stats:
+ IP Address # JA3C
+ 1 192.168.1.178 1
+ 2 192.168.1.187 1
+ 3 192.168.1.128 1
+ 4 192.168.149.129 1
+
+
+ 1 TCP 192.168.149.129:43535 <-> 51.83.238.219:80 [proto: 91/TLS][IP: 252/AnyDesk][Encrypted][Confidence: DPI][FPC: 252/AnyDesk, Confidence: IP address][DPI packets: 8][cat: Web/5][19 pkts/6843 bytes <-> 22 pkts/9152 bytes][Goodput ratio: 85/86][10.60 sec][bytes ratio: -0.144 (Mixed)][IAT c2s/s2c min/avg/max/stddev: 0/0 624/488 7028/7028 1803/1610][Pkt Len c2s/s2c min/avg/max/stddev: 54/60 360/416 1514/1514 525/549][Risk: ** Known Proto on Non Std Port **** TLS (probably) Not Carrying HTTPS **** Missing SNI TLS Extn **][Risk Score: 110][Risk Info: No ALPN / SNI should always be present / Expected on port 443][TLSv1.2][JA3C: 201999283915cc31cee6b15472ef3332][JA4: t12d640500_9197985d2161_a1e935682795][JA3S: 107030a763c7224285717ff1569a17f3][Issuer: CN=AnyNet Root CA, O=philandro Software GmbH, C=DE][Subject: C=DE, O=philandro Software GmbH, CN=AnyNet Relay][Certificate SHA-1: 9E:08:D2:58:A9:02:CD:4F:E2:4A:26:B8:48:5C:43:0B:81:29:99:E3][Firefox][Validity: 2018-11-18 02:14:23 - 2028-11-15 02:14:23][Cipher: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384][Plen Bins: 4,13,13,9,9,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,4,4,0,4,0,0,9,0,0,0,0,18,0,0]
+ 2 TCP 192.168.1.128:48260 <-> 195.181.174.176:443 [proto: 91/TLS][IP: 0/Unknown][Encrypted][Confidence: DPI][FPC: 0/Unknown, Confidence: Unknown][DPI packets: 8][cat: Web/5][27 pkts/7693 bytes <-> 27 pkts/4853 bytes][Goodput ratio: 77/63][58.81 sec][(Advertised) ALPNs: anydesk/6.2.0/linux][bytes ratio: 0.226 (Upload)][IAT c2s/s2c min/avg/max/stddev: 0/0 2284/1898 10210/10228 4074/3857][Pkt Len c2s/s2c min/avg/max/stddev: 66/66 285/180 1514/1514 460/331][Risk: ** Missing SNI TLS Extn **** Uncommon TLS ALPN **][Risk Score: 100][Risk Info: anydesk/6.2.0/linu / SNI should always be present][TLSv1.2][JA3C: 29b5a018fa5992fe23560c16af0dc9fc][JA4: t12d6406an_9197985d2161_a1e935682795][JA3S: e58f0b3c1e9eefb8ee4f92aeceee5858][Issuer: CN=AnyNet Root CA, O=philandro Software GmbH, C=DE][Subject: C=DE, O=philandro Software GmbH, CN=AnyNet Relay][Certificate SHA-1: 9E:08:D2:58:A9:02:CD:4F:E2:4A:26:B8:48:5C:43:0B:81:29:99:E3][Firefox][Validity: 2018-11-18 02:14:23 - 2028-11-15 02:14:23][Cipher: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384][Plen Bins: 0,35,20,0,10,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,5,0,0,0,0,0,0,15,0,0]
+ 3 TCP 192.168.1.187:54164 <-> 192.168.1.178:7070 [proto: 91/TLS][IP: 0/Unknown][Encrypted][Confidence: DPI][FPC: 0/Unknown, Confidence: Unknown][DPI packets: 7][cat: Web/5][19 pkts/7324 bytes <-> 21 pkts/3951 bytes][Goodput ratio: 86/69][7.29 sec][bytes ratio: 0.299 (Upload)][IAT c2s/s2c min/avg/max/stddev: 0/0 481/137 2966/1753 831/422][Pkt Len c2s/s2c min/avg/max/stddev: 54/60 385/188 3980/1514 894/354][Risk: ** Known Proto on Non Std Port **** TLS (probably) Not Carrying HTTPS **** Missing SNI TLS Extn **][Risk Score: 110][Risk Info: No ALPN / SNI should always be present][TLSv1.2][JA3C: 3f2fba0262b1a22b739126dfb2fe7a7d][JA4: t12d550500_168bb377f8c8_a1e935682795][JA3S: ee644a8a34c434abca4b737ec1d9efad][Subject: CN=AnyDesk Client, CN=AnyDesk Client][Certificate SHA-1: F8:4E:27:4E:F9:33:35:2F:1A:69:71:D5:02:6B:B8:72:EF:B7:BA:B0][Firefox][Cipher: TLS_DHE_RSA_WITH_AES_256_GCM_SHA384][Plen Bins: 0,45,15,5,5,0,0,5,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,5,0,5]
+ 4 TCP 192.168.1.178:52039 <-> 192.168.1.187:7070 [proto: 91/TLS][IP: 0/Unknown][Encrypted][Confidence: DPI][FPC: 0/Unknown, Confidence: Unknown][DPI packets: 6][cat: Web/5][8 pkts/2035 bytes <-> 7 pkts/2157 bytes][Goodput ratio: 76/82][0.56 sec][bytes ratio: -0.029 (Mixed)][IAT c2s/s2c min/avg/max/stddev: 0/0 92/40 406/85 150/33][Pkt Len c2s/s2c min/avg/max/stddev: 60/54 254/308 1340/968 419/387][Risk: ** Known Proto on Non Std Port **** Weak TLS Cipher **** TLS (probably) Not Carrying HTTPS **** Missing SNI TLS Extn **][Risk Score: 210][Risk Info: No ALPN / SNI should always be present / Cipher TLS_RSA_WITH_AES_256_GCM_SHA384][TLSv1.2][JA3C: 201999283915cc31cee6b15472ef3332][JA4: t12d640500_9197985d2161_a1e935682795][JA3S: 4b505adfb4a921c5a3a39d293b0811e1 (WEAK)][Subject: CN=AnyDesk Client, CN=AnyDesk Client][Certificate SHA-1: 86:4F:2A:9F:24:71:FD:0D:6A:35:56:AC:D8:7B:3A:19:E8:03:CA:2E][Firefox][Cipher: TLS_RSA_WITH_AES_256_GCM_SHA384][Plen Bins: 0,20,0,0,0,0,0,0,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20,0,0,20,0,0,0,0,0,0,0,0,0,0,0,20,0,0,0,0,0,0,0]
+ 5 TCP 192.168.149.129:36351 <-> 51.83.239.144:80 [proto: 91/TLS][IP: 252/AnyDesk][Encrypted][Confidence: DPI][FPC: 91/TLS, Confidence: DPI][DPI packets: 5][cat: Web/5][10 pkts/792 bytes <-> 10 pkts/925 bytes][Goodput ratio: 32/38][45.83 sec][bytes ratio: -0.077 (Mixed)][IAT c2s/s2c min/avg/max/stddev: 32/31 5700/5700 15000/15001 7162/7162][Pkt Len c2s/s2c min/avg/max/stddev: 54/60 79/92 105/213 25/45][Risk: ** Known Proto on Non Std Port **][Risk Score: 50][Risk Info: Expected on port 443][Plen Bins: 0,90,0,0,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
+ 6 UDP 192.168.1.187:55376 <-> 192.168.1.1:53 [proto: 5/DNS][IP: 0/Unknown][ClearText][Confidence: DPI][FPC: 5/DNS, Confidence: DPI][DPI packets: 2][cat: Network/14][1 pkts/90 bytes <-> 1 pkts/106 bytes][Goodput ratio: 53/60][0.01 sec][Hostname/SNI: relay-9b6827f2.net.anydesk.com][138.199.36.115][PLAIN TEXT (anydesk)][Plen Bins: 0,50,50,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
+ 7 UDP 192.168.1.187:59511 <-> 192.168.1.1:53 [proto: 5/DNS][IP: 0/Unknown][ClearText][Confidence: DPI][FPC: 5/DNS, Confidence: DPI][DPI packets: 2][cat: Network/14][1 pkts/90 bytes <-> 1 pkts/106 bytes][Goodput ratio: 53/60][0.01 sec][Hostname/SNI: relay-3185a847.net.anydesk.com][37.61.223.15][PLAIN TEXT (anydesk)][Plen Bins: 0,50,50,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
diff --git a/tests/cfgs/dns_subclassification_disable/result/dns.pcap.out b/tests/cfgs/subclassification_disable/result/dns.pcap.out
index 5309ccd6b..5309ccd6b 100644
--- a/tests/cfgs/dns_subclassification_disable/result/dns.pcap.out
+++ b/tests/cfgs/subclassification_disable/result/dns.pcap.out
diff --git a/tests/cfgs/subclassification_disable/result/http.pcapng.out b/tests/cfgs/subclassification_disable/result/http.pcapng.out
new file mode 100644
index 000000000..0f9dc56ac
--- /dev/null
+++ b/tests/cfgs/subclassification_disable/result/http.pcapng.out
@@ -0,0 +1,27 @@
+DPI Packets (TCP): 6 (6.00 pkts/flow)
+Confidence DPI : 1 (flows)
+Num dissector calls: 15 (15.00 diss/flow)
+LRU cache ookla: 0/0/0 (insert/search/found)
+LRU cache bittorrent: 0/0/0 (insert/search/found)
+LRU cache stun: 0/0/0 (insert/search/found)
+LRU cache tls_cert: 0/0/0 (insert/search/found)
+LRU cache mining: 0/0/0 (insert/search/found)
+LRU cache msteams: 0/0/0 (insert/search/found)
+LRU cache fpc_dns: 0/1/0 (insert/search/found)
+Automa host: 0/0 (search/found)
+Automa domain: 0/0 (search/found)
+Automa tls cert: 0/0 (search/found)
+Automa risk mask: 0/0 (search/found)
+Automa common alpns: 0/0 (search/found)
+Patricia risk mask: 0/0 (search/found)
+Patricia risk mask IPv6: 0/0 (search/found)
+Patricia risk: 0/0 (search/found)
+Patricia risk IPv6: 0/0 (search/found)
+Patricia protocols: 1/1 (search/found)
+Patricia protocols IPv6: 0/0 (search/found)
+
+HTTP 10 1278 1
+
+Acceptable 10 1278 1
+
+ 1 TCP 192.168.1.128:42170 <-> 216.58.208.142:80 [proto: 7/HTTP][IP: 126/Google][ClearText][Confidence: DPI][FPC: 126/Google, Confidence: IP address][DPI packets: 6][cat: Web/5][6 pkts/478 bytes <-> 4 pkts/800 bytes][Goodput ratio: 15/66][0.04 sec][Hostname/SNI: google.com][bytes ratio: -0.252 (Download)][IAT c2s/s2c min/avg/max/stddev: 0/7 8/14 28/20 10/6][Pkt Len c2s/s2c min/avg/max/stddev: 66/66 80/200 140/594 27/227][URL: google.com/][StatusCode: 301][Content-Type: text/html][Server: gws][User-Agent: curl/7.68.0][PLAIN TEXT (GET / HTTP/1.1)][Plen Bins: 0,0,50,0,0,0,0,0,0,0,0,0,0,0,0,0,50,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
diff --git a/tests/cfgs/subclassification_disable/result/quic-mvfst-27.pcapng.out b/tests/cfgs/subclassification_disable/result/quic-mvfst-27.pcapng.out
new file mode 100644
index 000000000..ef7a9656f
--- /dev/null
+++ b/tests/cfgs/subclassification_disable/result/quic-mvfst-27.pcapng.out
@@ -0,0 +1,32 @@
+DPI Packets (UDP): 1 (1.00 pkts/flow)
+Confidence DPI : 1 (flows)
+Num dissector calls: 1 (1.00 diss/flow)
+LRU cache ookla: 0/0/0 (insert/search/found)
+LRU cache bittorrent: 0/0/0 (insert/search/found)
+LRU cache stun: 0/0/0 (insert/search/found)
+LRU cache tls_cert: 0/0/0 (insert/search/found)
+LRU cache mining: 0/0/0 (insert/search/found)
+LRU cache msteams: 0/0/0 (insert/search/found)
+LRU cache fpc_dns: 0/0/0 (insert/search/found)
+Automa host: 0/0 (search/found)
+Automa domain: 0/0 (search/found)
+Automa tls cert: 0/0 (search/found)
+Automa risk mask: 0/0 (search/found)
+Automa common alpns: 1/1 (search/found)
+Patricia risk mask: 2/0 (search/found)
+Patricia risk mask IPv6: 0/0 (search/found)
+Patricia risk: 0/0 (search/found)
+Patricia risk IPv6: 0/0 (search/found)
+Patricia protocols: 1/1 (search/found)
+Patricia protocols IPv6: 0/0 (search/found)
+
+QUIC 20 11399 1
+
+Acceptable 20 11399 1
+
+JA3 Host Stats:
+ IP Address # JA3C
+ 1 10.0.2.15 1
+
+
+ 1 UDP 10.0.2.15:35957 <-> 69.171.250.15:443 [proto: 188/QUIC][IP: 119/Facebook][Encrypted][Confidence: DPI][FPC: 188/QUIC, Confidence: DPI][DPI packets: 1][cat: Web/5][7 pkts/3196 bytes <-> 13 pkts/8203 bytes][Goodput ratio: 79/85][8.96 sec][Hostname/SNI: graph.facebook.com][(Advertised) ALPNs: h3-fb-05][TLS Supported Versions: TLSv1.3;TLSv1.3 (draft)][bytes ratio: -0.439 (Download)][IAT c2s/s2c min/avg/max/stddev: 0/0 1782/811 8808/8827 3513/2535][Pkt Len c2s/s2c min/avg/max/stddev: 128/115 457/631 1326/1346 492/540][TLSv1.3][QUIC ver: MVFST-27][JA3C: 61d8a93ff379660087082a82411f19a2][JA4: q00d0108h3_0f2cb44170f4_f4b4187450f5][PLAIN TEXT (Xic gcl)][Plen Bins: 20,25,10,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,5,0,0,0,0,5,0,0,0,0,0,5,20,0,0,0,0,0,0,0,0]
diff --git a/tests/cfgs/subclassification_disable/result/tls_ech.pcapng.out b/tests/cfgs/subclassification_disable/result/tls_ech.pcapng.out
new file mode 100644
index 000000000..982910ffa
--- /dev/null
+++ b/tests/cfgs/subclassification_disable/result/tls_ech.pcapng.out
@@ -0,0 +1,32 @@
+DPI Packets (TCP): 6 (6.00 pkts/flow)
+Confidence DPI : 1 (flows)
+Num dissector calls: 1 (1.00 diss/flow)
+LRU cache ookla: 0/0/0 (insert/search/found)
+LRU cache bittorrent: 0/0/0 (insert/search/found)
+LRU cache stun: 0/0/0 (insert/search/found)
+LRU cache tls_cert: 0/0/0 (insert/search/found)
+LRU cache mining: 0/0/0 (insert/search/found)
+LRU cache msteams: 0/0/0 (insert/search/found)
+LRU cache fpc_dns: 0/1/0 (insert/search/found)
+Automa host: 0/0 (search/found)
+Automa domain: 0/0 (search/found)
+Automa tls cert: 0/0 (search/found)
+Automa risk mask: 0/0 (search/found)
+Automa common alpns: 2/2 (search/found)
+Patricia risk mask: 0/0 (search/found)
+Patricia risk mask IPv6: 0/0 (search/found)
+Patricia risk: 0/0 (search/found)
+Patricia risk IPv6: 1/0 (search/found)
+Patricia protocols: 0/0 (search/found)
+Patricia protocols IPv6: 1/1 (search/found)
+
+TLS 10 4226 1
+
+Safe 10 4226 1
+
+JA3 Host Stats:
+ IP Address # JA3C
+ 1 2001:b07:a3d:c112:ce16:b409:3d0a:9177 1
+
+
+ 1 TCP [2001:b07:a3d:c112:ce16:b409:3d0a:9177]:47460 <-> [2606:4700::6812:1e4e]:443 [proto: 91/TLS][IP: 220/Cloudflare][Encrypted][Confidence: DPI][FPC: 220/Cloudflare, Confidence: IP address][DPI packets: 6][cat: Web/5][6 pkts/1172 bytes <-> 4 pkts/3054 bytes][Goodput ratio: 55/88][0.07 sec][Hostname/SNI: performance.radar.cloudflare.com][(Advertised) ALPNs: h2;http/1.1][TLS Supported Versions: GREASE;TLSv1.3;TLSv1.2][bytes ratio: -0.445 (Download)][IAT c2s/s2c min/avg/max/stddev: 0/3 13/5 49/7 18/2][Pkt Len c2s/s2c min/avg/max/stddev: 86/86 195/764 670/2260 213/890][TLSv1.3][JA3C: 6820f114cf3b0809ffdcb30cb277848a][JA4: t13d1516h2_8daaf6152771_02713d6af862][JA3S: eb1d94daa7e0344597e756a1fb6e7054][ECH: version 0xfe0d][Chrome][Cipher: TLS_AES_128_GCM_SHA256][Plen Bins: 0,0,25,0,0,0,0,0,0,0,0,0,0,0,0,0,25,0,25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25]