aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Nardi <12729895+IvanNardi@users.noreply.github.com>2024-04-04 18:16:40 +0200
committerGitHub <noreply@github.com>2024-04-04 18:16:40 +0200
commitc0d3f8a92eb229a42c99373864059558483e7fbd (patch)
tree4dd0e8f17f266ab772cbb4a229b5a44397f12c6d
parent6e61368cd609899048560405ad792705fffb1f1a (diff)
STUN: rework sub-classification (#2361)
The main goal is to have the "real" application (if any; i.e. Signal/Whatsapp/Telegram/...) always as "application" protocol and not as "master" one
-rw-r--r--src/lib/protocols/stun.c157
-rw-r--r--tests/cfgs/default/result/stun_classic.pcap.out6
-rw-r--r--tests/cfgs/default/result/stun_dtls_rtp_unidir.pcapng.out2
-rw-r--r--tests/cfgs/stun_extra_dissection/result/stun_dtls_rtp_unidir.pcapng.out10
4 files changed, 120 insertions, 55 deletions
diff --git a/src/lib/protocols/stun.c b/src/lib/protocols/stun.c
index d0397a590..4e77cc532 100644
--- a/src/lib/protocols/stun.c
+++ b/src/lib/protocols/stun.c
@@ -55,11 +55,73 @@ static u_int64_t get_stun_lru_key_raw4(u_int32_t ip, u_int16_t port);
static u_int64_t get_stun_lru_key_raw6(u_int8_t *ip, u_int16_t port);
static void ndpi_int_stun_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow,
- u_int app_proto);
+ u_int16_t app_proto,
+ u_int16_t master_proto);
static int stun_search_again(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow);
+/* Valid classifications:
+ * STUN, DTLS, STUN/RTP, DTLS/SRTP
+ * STUN/APP, DTLS/APP, SRTP/APP ["real" sub-classification]
+ The idea is:
+ * the specific "real" application (WA/FB/Signal/...), if present, should
+ be always set as "app" protocol, with STUN or DTLS or SRTP as "master" protocol
+ * every "real" application that we handle, if it uses RTP, it is
+ encrypted --> SRTP
+ * keep STUN/RTP for the generic case without sub-classification [because
+ nDPI uses SRTP only when it is sure that there is encryption]
+*/
+
+static int is_subclassification_real_by_proto(u_int16_t proto)
+{
+ if(proto == NDPI_PROTOCOL_UNKNOWN ||
+ proto == NDPI_PROTOCOL_STUN ||
+ proto == NDPI_PROTOCOL_RTP ||
+ proto == NDPI_PROTOCOL_SRTP ||
+ proto == NDPI_PROTOCOL_DTLS)
+ return 0;
+ return 1;
+}
+
+static int is_subclassification_real(struct ndpi_flow_struct *flow)
+{
+ /* No previous subclassification */
+ if(flow->detected_protocol_stack[1] == NDPI_PROTOCOL_UNKNOWN)
+ return 0;
+ return is_subclassification_real_by_proto(flow->detected_protocol_stack[0]);
+}
+
+static int is_new_subclassification_better(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
+ u_int16_t new_app_proto)
+{
+ NDPI_LOG_DBG(ndpi_struct, "%d/%d -> %d\n",
+ flow->detected_protocol_stack[1], flow->detected_protocol_stack[0],
+ new_app_proto);
+
+ /* If we don't have a real subclassification, we might want to lookup into the cache again
+ (even if new_app_proto == NDPI_PROTOCOL_UNKNOWN) */
+
+ if(is_subclassification_real(flow) &&
+ new_app_proto == NDPI_PROTOCOL_UNKNOWN)
+ return 0;
+
+ /* Debug */
+ if(new_app_proto != NDPI_PROTOCOL_UNKNOWN &&
+ is_subclassification_real(flow) &&
+ new_app_proto != flow->detected_protocol_stack[0]) {
+ NDPI_LOG_ERR(ndpi_struct, "Incoherent sub-classification change %d/%d->%d \n",
+ flow->detected_protocol_stack[1],
+ flow->detected_protocol_stack[0], new_app_proto);
+ }
+
+ if(new_app_proto != flow->detected_protocol_stack[0])
+ return 1;
+ return 0;
+}
+
+
static u_int16_t search_into_cache(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow)
{
@@ -111,11 +173,7 @@ static void add_to_caches(struct ndpi_detection_module_struct *ndpi_struct,
{
u_int64_t key, key_rev;
- if(ndpi_struct->stun_cache &&
- app_proto != NDPI_PROTOCOL_STUN &&
- app_proto != NDPI_PROTOCOL_UNKNOWN) {
- /* No sense to add STUN, but only subprotocols */
-
+ if(ndpi_struct->stun_cache) {
key = get_stun_lru_key(flow, 0);
ndpi_lru_add_to_cache(ndpi_struct->stun_cache, key, app_proto, ndpi_get_current_time(flow));
key_rev = get_stun_lru_key(flow, 1);
@@ -292,8 +350,8 @@ int is_stun(struct ndpi_detection_module_struct *ndpi_struct,
inet_ntop(AF_INET, &ip, buf, sizeof(buf)), port,
flow->detected_protocol_stack[0]);
- if(1 /* TODO: enable/disable */ &&
- ndpi_struct->stun_cache) {
+ if(ndpi_struct->stun_cache &&
+ is_subclassification_real(flow)) {
u_int64_t key = get_stun_lru_key_raw4(ip, port);
ndpi_lru_add_to_cache(ndpi_struct->stun_cache, key,
@@ -316,8 +374,8 @@ int is_stun(struct ndpi_detection_module_struct *ndpi_struct,
inet_ntop(AF_INET6, &ip, buf, sizeof(buf)), port,
flow->detected_protocol_stack[0]);
- if(1 /* TODO: enable/disable */ &&
- ndpi_struct->stun_cache) {
+ if(ndpi_struct->stun_cache &&
+ is_subclassification_real(flow)) {
u_int64_t key = get_stun_lru_key_raw6((u_int8_t *)ip, port);
ndpi_lru_add_to_cache(ndpi_struct->stun_cache, key,
@@ -436,14 +494,9 @@ int is_stun(struct ndpi_detection_module_struct *ndpi_struct,
static int keep_extra_dissection(struct ndpi_flow_struct *flow)
{
- if(flow->detected_protocol_stack[1] == NDPI_PROTOCOL_UNKNOWN /* No subclassification */)
+ if(!is_subclassification_real(flow))
return 1;
- /* We have a sub-classification */
-
- if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_RTP)
- return 0;
-
/* Looking for XOR-PEER-ADDRESS metadata; TODO: other protocols? */
if((flow->detected_protocol_stack[0] == NDPI_PROTOCOL_TELEGRAM_VOIP)
|| (flow->detected_protocol_stack[0] == NDPI_PROTOCOL_WHATSAPP_CALL))
@@ -486,9 +539,10 @@ static int stun_search_again(struct ndpi_detection_module_struct *ndpi_struct,
/* RFC9443 */
if(first_byte <= 3) {
NDPI_LOG_DBG(ndpi_struct, "Still STUN\n");
- if(is_stun(ndpi_struct, flow, &app_proto) /* To extract other metadata */ &&
- flow->detected_protocol_stack[1] == NDPI_PROTOCOL_UNKNOWN /* No previous subclassification */) {
- ndpi_int_stun_add_connection(ndpi_struct, flow, app_proto);
+ if(is_stun(ndpi_struct, flow, &app_proto)) { /* To extract other metadata */
+ if(is_new_subclassification_better(ndpi_struct, flow, app_proto)) {
+ ndpi_int_stun_add_connection(ndpi_struct, flow, app_proto, __get_master(flow));
+ }
}
} else if(first_byte <= 15) {
NDPI_LOG_DBG(ndpi_struct, "DROP range. Unexpected\n");
@@ -562,10 +616,10 @@ static int stun_search_again(struct ndpi_detection_module_struct *ndpi_struct,
flow->stun.maybe_dtls = 0;
flow->max_extra_packets_to_check -= 10;
-
- NDPI_LOG_DBG(ndpi_struct, "(%d/%d)\n",
- flow->detected_protocol_stack[0], flow->detected_protocol_stack[1]);
}
+
+ NDPI_LOG_DBG(ndpi_struct, "(%d/%d)\n",
+ flow->detected_protocol_stack[0], flow->detected_protocol_stack[1]);
}
}
}
@@ -613,23 +667,25 @@ static int stun_search_again(struct ndpi_detection_module_struct *ndpi_struct,
rtp_get_stream_type(packet->payload[1] & 0x7F, &flow->flow_multimedia_type);
- if(flow->detected_protocol_stack[1] != NDPI_PROTOCOL_UNKNOWN) {
- if(flow->detected_protocol_stack[1] == NDPI_PROTOCOL_DTLS) {
- /* Keep DTLS/SUBPROTO since we already wrote to flow->protos.tls_quic */
+ if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_RTP &&
+ flow->detected_protocol_stack[1] != NDPI_PROTOCOL_SRTP) {
+
+ if(flow->detected_protocol_stack[1] != NDPI_PROTOCOL_UNKNOWN) {
+ if(flow->detected_protocol_stack[1] == NDPI_PROTOCOL_DTLS) {
+ /* Keep DTLS/SUBPROTO since we already wrote to flow->protos.tls_quic */
+ } else {
+ /* STUN/SUBPROTO -> SRTP/SUBPROTO */
+ ndpi_int_stun_add_connection(ndpi_struct, flow,
+ flow->detected_protocol_stack[0], NDPI_PROTOCOL_SRTP);
+ }
} else {
- /* STUN/SUBPROTO -> SUBPROTO/RTP */
- ndpi_set_detected_protocol(ndpi_struct, flow,
- NDPI_PROTOCOL_RTP, flow->detected_protocol_stack[0],
- NDPI_CONFIDENCE_DPI);
+ /* STUN -> STUN/RTP, or
+ DTLS -> DTLS/SRTP */
+ ndpi_int_stun_add_connection(ndpi_struct, flow,
+ __get_master(flow) == NDPI_PROTOCOL_STUN ? NDPI_PROTOCOL_RTP: NDPI_PROTOCOL_SRTP,
+ __get_master(flow));
}
- } else {
- /* STUN -> STUN/RTP, or
- DTLS -> DTLS/RTP */
- ndpi_set_detected_protocol(ndpi_struct, flow,
- NDPI_PROTOCOL_RTP, __get_master(flow),
- NDPI_CONFIDENCE_DPI);
}
- return 0; /* Stop */
} else if(rtp_rtcp == IS_RTCP) {
NDPI_LOG_DBG(ndpi_struct, "RTCP\n");
} else {
@@ -700,8 +756,12 @@ int stun_search_into_zoom_cache(struct ndpi_detection_module_struct *ndpi_struct
static void ndpi_int_stun_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow,
- u_int app_proto) {
+ u_int16_t app_proto,
+ u_int16_t master_proto) {
ndpi_confidence_t confidence = NDPI_CONFIDENCE_DPI;
+ u_int16_t new_app_proto;
+
+ NDPI_LOG_DBG(ndpi_struct, "Wanting %d/%d\n", master_proto, app_proto);
if(app_proto == NDPI_PROTOCOL_UNKNOWN) {
/* https://support.google.com/a/answer/1279090?hl=en */
@@ -734,23 +794,28 @@ static void ndpi_int_stun_add_connection(struct ndpi_detection_module_struct *nd
}
}
- if(app_proto == NDPI_PROTOCOL_UNKNOWN) {
- app_proto = search_into_cache(ndpi_struct, flow);
- if(app_proto != NDPI_PROTOCOL_UNKNOWN)
+ if(!is_subclassification_real_by_proto(app_proto)) {
+ new_app_proto = search_into_cache(ndpi_struct, flow);
+ if(new_app_proto != NDPI_PROTOCOL_UNKNOWN) {
confidence = NDPI_CONFIDENCE_DPI_CACHE;
+ if(app_proto == NDPI_PROTOCOL_RTP)
+ master_proto = NDPI_PROTOCOL_SRTP; /* STUN/RTP --> SRTP/APP */
+ app_proto = new_app_proto;
+ }
}
- if(app_proto != NDPI_PROTOCOL_UNKNOWN)
+ /* Adding only real subclassifications */
+ if(is_subclassification_real_by_proto(app_proto))
add_to_caches(ndpi_struct, flow, app_proto);
if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN ||
app_proto != NDPI_PROTOCOL_UNKNOWN) {
- NDPI_LOG_DBG(ndpi_struct, "Setting %d\n", app_proto);
- ndpi_set_detected_protocol(ndpi_struct, flow, app_proto, __get_master(flow), confidence);
+ NDPI_LOG_DBG(ndpi_struct, "Setting %d/%d\n", master_proto, app_proto);
+ ndpi_set_detected_protocol(ndpi_struct, flow, app_proto, master_proto, confidence);
/* In "normal" data-path the generic code in `ndpi_internal_detection_process_packet()`
takes care of setting the category */
if(flow->extra_packets_func) {
- ndpi_protocol ret = { __get_master(flow), app_proto, NDPI_PROTOCOL_UNKNOWN /* unused */, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED, NULL};
+ ndpi_protocol ret = { master_proto, app_proto, NDPI_PROTOCOL_UNKNOWN /* unused */, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED, NULL};
flow->category = ndpi_get_proto_category(ndpi_struct, ret);
}
}
@@ -762,7 +827,7 @@ static void ndpi_int_stun_add_connection(struct ndpi_detection_module_struct *nd
(to find all XOR-PEER-ADDRESS attributes)
*/
if(!flow->extra_packets_func) {
- if(flow->detected_protocol_stack[1] == NDPI_PROTOCOL_UNKNOWN /* No-subclassification */ ||
+ if(!is_subclassification_real(flow) ||
flow->detected_protocol_stack[0] == NDPI_PROTOCOL_TELEGRAM_VOIP /* Metadata. TODO: other protocols? */) {
NDPI_LOG_DBG(ndpi_struct, "Enabling extra dissection\n");
flow->max_extra_packets_to_check = ndpi_struct->cfg.stun_max_packets_extra_dissection;
@@ -791,7 +856,7 @@ static void ndpi_search_stun(struct ndpi_detection_module_struct *ndpi_struct, s
}
if(is_stun(ndpi_struct, flow, &app_proto)) {
- ndpi_int_stun_add_connection(ndpi_struct, flow, app_proto);
+ ndpi_int_stun_add_connection(ndpi_struct, flow, app_proto, __get_master(flow));
return;
}
diff --git a/tests/cfgs/default/result/stun_classic.pcap.out b/tests/cfgs/default/result/stun_classic.pcap.out
index 904c92789..af05263d9 100644
--- a/tests/cfgs/default/result/stun_classic.pcap.out
+++ b/tests/cfgs/default/result/stun_classic.pcap.out
@@ -1,10 +1,10 @@
-DPI Packets (UDP): 3 (3.00 pkts/flow)
+DPI Packets (UDP): 5 (5.00 pkts/flow)
Confidence DPI : 1 (flows)
Num dissector calls: 6 (6.00 diss/flow)
LRU cache ookla: 0/0/0 (insert/search/found)
LRU cache bittorrent: 0/0/0 (insert/search/found)
LRU cache zoom: 0/0/0 (insert/search/found)
-LRU cache stun: 0/4/0 (insert/search/found)
+LRU cache stun: 0/6/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)
@@ -25,4 +25,4 @@ RTP 22 1624 1
Acceptable 22 1624 1
- 1 UDP 172.16.63.224:55050 <-> 172.16.63.21:13958 [proto: 78.87/STUN.RTP][IP: 0/Unknown][ClearText][Confidence: DPI][DPI packets: 3][cat: Network/14][9 pkts/662 bytes <-> 13 pkts/962 bytes][Goodput ratio: 43/43][0.23 sec][bytes ratio: -0.185 (Mixed)][IAT c2s/s2c min/avg/max/stddev: 4/0 32/17 101/42 32/11][Pkt Len c2s/s2c min/avg/max/stddev: 70/74 74/74 74/74 1/0][Risk: ** Known Proto on Non Std Port **][Risk Score: 50][Plen Bins: 4,95,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,0]
+ 1 UDP 172.16.63.224:55050 <-> 172.16.63.21:13958 [proto: 78.87/STUN.RTP][IP: 0/Unknown][ClearText][Confidence: DPI][DPI packets: 5][cat: Media/1][9 pkts/662 bytes <-> 13 pkts/962 bytes][Goodput ratio: 43/43][0.23 sec][bytes ratio: -0.185 (Mixed)][IAT c2s/s2c min/avg/max/stddev: 4/0 32/17 101/42 32/11][Pkt Len c2s/s2c min/avg/max/stddev: 70/74 74/74 74/74 1/0][Risk: ** Known Proto on Non Std Port **][Risk Score: 50][Plen Bins: 4,95,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,0]
diff --git a/tests/cfgs/default/result/stun_dtls_rtp_unidir.pcapng.out b/tests/cfgs/default/result/stun_dtls_rtp_unidir.pcapng.out
index 30fb52b8b..784028f5a 100644
--- a/tests/cfgs/default/result/stun_dtls_rtp_unidir.pcapng.out
+++ b/tests/cfgs/default/result/stun_dtls_rtp_unidir.pcapng.out
@@ -4,7 +4,7 @@ Num dissector calls: 12 (6.00 diss/flow)
LRU cache ookla: 0/0/0 (insert/search/found)
LRU cache bittorrent: 0/0/0 (insert/search/found)
LRU cache zoom: 0/0/0 (insert/search/found)
-LRU cache stun: 6/28/0 (insert/search/found)
+LRU cache stun: 0/28/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)
diff --git a/tests/cfgs/stun_extra_dissection/result/stun_dtls_rtp_unidir.pcapng.out b/tests/cfgs/stun_extra_dissection/result/stun_dtls_rtp_unidir.pcapng.out
index 5ced24b59..9d690016f 100644
--- a/tests/cfgs/stun_extra_dissection/result/stun_dtls_rtp_unidir.pcapng.out
+++ b/tests/cfgs/stun_extra_dissection/result/stun_dtls_rtp_unidir.pcapng.out
@@ -1,10 +1,10 @@
-DPI Packets (UDP): 36 (18.00 pkts/flow)
+DPI Packets (UDP): 43 (21.50 pkts/flow)
Confidence DPI : 2 (flows)
Num dissector calls: 12 (6.00 diss/flow)
LRU cache ookla: 0/0/0 (insert/search/found)
LRU cache bittorrent: 0/0/0 (insert/search/found)
LRU cache zoom: 0/0/0 (insert/search/found)
-LRU cache stun: 32/98/0 (insert/search/found)
+LRU cache stun: 0/120/0 (insert/search/found)
LRU cache tls_cert: 0/5/0 (insert/search/found)
LRU cache mining: 0/0/0 (insert/search/found)
LRU cache msteams: 0/0/0 (insert/search/found)
@@ -21,7 +21,7 @@ Patricia risk IPv6: 0/0 (search/found)
Patricia protocols: 4/0 (search/found)
Patricia protocols IPv6: 0/0 (search/found)
-RTP 43 10358 2
+SRTP 43 10358 2
Acceptable 43 10358 2
@@ -30,5 +30,5 @@ JA3 Host Stats:
1 10.10.0.1 1
- 1 UDP 10.1.0.3:5853 -> 10.10.0.1:2808 [proto: 30.87/DTLS.RTP][IP: 0/Unknown][Encrypted][Confidence: DPI][DPI packets: 15][cat: Network/14][18 pkts/5384 bytes -> 0 pkts/0 bytes][Goodput ratio: 86/0][7.17 sec][bytes ratio: 1.000 (Upload)][IAT c2s/s2c min/avg/max/stddev: 0/0 386/0 4001/0 979/0][Pkt Len c2s/s2c min/avg/max/stddev: 102/0 299/0 750/0 221/0][Risk: ** Self-signed Cert **][Risk Score: 100][Risk Info: CN=8][DTLSv1.0][JA3S: 1cfcbe58451407e23669f1dd08565519][Issuer: CN=8][Subject: CN=8][Certificate SHA-1: 94:8C:6F:C3:00:6A:A1:63:F1:52:7E:7F:1F:A7:93:90:46:3B:B1:2D][Validity: 2015-12-10 05:41:43 - 2016-01-10 05:41:43][Cipher: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA][PLAIN TEXT (Coturn)][Plen Bins: 0,5,5,5,34,22,0,0,0,5,0,0,0,0,0,5,0,0,0,0,0,0,16,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]
- 2 UDP 10.10.0.1:65226 -> 10.1.0.3:57730 [proto: 30.87/DTLS.RTP][IP: 0/Unknown][Encrypted][Confidence: DPI][DPI packets: 21][cat: Network/14][25 pkts/4974 bytes -> 0 pkts/0 bytes][Goodput ratio: 79/0][7.16 sec][bytes ratio: 1.000 (Upload)][IAT c2s/s2c min/avg/max/stddev: 0/0 324/0 4001/0 904/0][Pkt Len c2s/s2c min/avg/max/stddev: 78/0 199/0 478/0 92/0][DTLSv1.0][JA3C: fd8faf73d274d5614a51dae82304be0a][JA4: t00d250500_c70d7c76d4be_255c854b9f77][PLAIN TEXT (username1)][Plen Bins: 0,8,16,16,32,0,4,8,0,12,0,0,0,4,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]
+ 1 UDP 10.1.0.3:5853 -> 10.10.0.1:2808 [proto: 30.338/DTLS.SRTP][IP: 0/Unknown][Encrypted][Confidence: DPI][DPI packets: 18][cat: Media/1][18 pkts/5384 bytes -> 0 pkts/0 bytes][Goodput ratio: 86/0][7.17 sec][bytes ratio: 1.000 (Upload)][IAT c2s/s2c min/avg/max/stddev: 0/0 386/0 4001/0 979/0][Pkt Len c2s/s2c min/avg/max/stddev: 102/0 299/0 750/0 221/0][Risk: ** Self-signed Cert **** Unidirectional Traffic **][Risk Score: 110][Risk Info: No server to client traffic / CN=8][DTLSv1.0][JA3S: 1cfcbe58451407e23669f1dd08565519][Issuer: CN=8][Subject: CN=8][Certificate SHA-1: 94:8C:6F:C3:00:6A:A1:63:F1:52:7E:7F:1F:A7:93:90:46:3B:B1:2D][Validity: 2015-12-10 05:41:43 - 2016-01-10 05:41:43][Cipher: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA][PLAIN TEXT (Coturn)][Plen Bins: 0,5,5,5,34,22,0,0,0,5,0,0,0,0,0,5,0,0,0,0,0,0,16,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]
+ 2 UDP 10.10.0.1:65226 -> 10.1.0.3:57730 [proto: 30.338/DTLS.SRTP][IP: 0/Unknown][Encrypted][Confidence: DPI][DPI packets: 25][cat: Media/1][25 pkts/4974 bytes -> 0 pkts/0 bytes][Goodput ratio: 79/0][7.16 sec][bytes ratio: 1.000 (Upload)][IAT c2s/s2c min/avg/max/stddev: 0/0 324/0 4001/0 904/0][Pkt Len c2s/s2c min/avg/max/stddev: 78/0 199/0 478/0 92/0][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][DTLSv1.0][JA3C: fd8faf73d274d5614a51dae82304be0a][JA4: t00d250500_c70d7c76d4be_255c854b9f77][PLAIN TEXT (username1)][Plen Bins: 0,8,16,16,32,0,4,8,0,12,0,0,0,4,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]