aboutsummaryrefslogtreecommitdiff
path: root/src/lib/protocols/dns.c
diff options
context:
space:
mode:
authorIvan Nardi <12729895+IvanNardi@users.noreply.github.com>2021-11-24 10:46:48 +0100
committerGitHub <noreply@github.com>2021-11-24 10:46:48 +0100
commita8ffcd8bb0273d59600c6310a80b81206096c113 (patch)
tree2a62911824363509ea5e7c69afa189e98556e495 /src/lib/protocols/dns.c
parentfd02e1b3043eecc5711eb8254aadaa3f43ca7503 (diff)
Rework how hostname/SNI info is saved (#1330)
Looking at `struct ndpi_flow_struct` the two bigger fields are `host_server_name[240]` (mainly for HTTP hostnames and DNS domains) and `protos.tls_quic.client_requested_server_name[256]` (for TLS/QUIC SNIs). This commit aims to reduce `struct ndpi_flow_struct` size, according to two simple observations: 1) maximum one of these two fields is used for each flow. So it seems safe to merge them; 2) even if hostnames/SNIs might be very long, in practice they are rarely longer than a fews tens of bytes. So, using a (single) large buffer is a waste of memory for all kinds of flows. If we need to truncate the name, we keep the *last* characters, easing domain matching. Analyzing some real traffic, it seems safe to assume that the vast majority of hostnames/SNIs is shorter than 80 bytes. Hostnames/SNIs are always converted to lowercase. Attention was given so as to be sure that unit-tests outputs are not affected by this change. Because of a bug, TLS/QUIC SNI were always truncated to 64 bytes (the *first* 64 ones): as a consequence, there were some "Suspicious DGA domain name" and "TLS Certificate Mismatch" false positives.
Diffstat (limited to 'src/lib/protocols/dns.c')
-rw-r--r--src/lib/protocols/dns.c54
1 files changed, 29 insertions, 25 deletions
diff --git a/src/lib/protocols/dns.c b/src/lib/protocols/dns.c
index 98c6bf142..eb5af5a34 100644
--- a/src/lib/protocols/dns.c
+++ b/src/lib/protocols/dns.c
@@ -368,6 +368,7 @@ static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, st
int invalid = search_valid_dns(ndpi_struct, flow, &dns_header, payload_offset, &is_query);
ndpi_protocol ret;
u_int num_queries, idx;
+ char _hostname[256];
ret.master_protocol = NDPI_PROTOCOL_UNKNOWN;
ret.app_protocol = (d_port == LLMNR_PORT) ? NDPI_PROTOCOL_LLMNR : ((d_port == MDNS_PORT) ? NDPI_PROTOCOL_MDNS : NDPI_PROTOCOL_DNS);
@@ -378,7 +379,6 @@ static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, st
}
/* extract host name server */
- max_len = sizeof(flow->host_server_name)-1;
off = sizeof(struct ndpi_dns_packet_header) + payload_offset;
/* Before continuing let's dissect the following queries to see if they are valid */
@@ -434,6 +434,7 @@ static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, st
} /* for */
u_int8_t hostname_is_valid = 1;
+ max_len = sizeof(_hostname)-1;
while((j < max_len) && (off < packet->payload_packet_len) && (packet->payload[off] != '\0')) {
uint8_t c, cl = packet->payload[off++];
@@ -443,40 +444,43 @@ static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, st
break;
}
- if(j && (j < max_len)) flow->host_server_name[j++] = '.';
-
- while((j < max_len) && (cl != 0)) {
- u_int32_t shift;
-
- c = packet->payload[off++];
- shift = ((u_int32_t) 1) << (c & 0x1f);
- if ((dns_validchar[c >> 5] & shift)) {
- flow->host_server_name[j++] = tolower(c);
- } else {
- if (isprint(c) == 0) {
- hostname_is_valid = 0;
- flow->host_server_name[j++] = '?';
- } else {
- flow->host_server_name[j++] = '_';
- }
- }
- cl--;
- }
+ if(j && (j < max_len)) _hostname[j++] = '.';
+
+ while((j < max_len) && (cl != 0)) {
+ u_int32_t shift;
+
+ c = packet->payload[off++];
+ shift = ((u_int32_t) 1) << (c & 0x1f);
+ if((dns_validchar[c >> 5] & shift)) {
+ _hostname[j++] = tolower(c);
+ } else {
+ if (isprint(c) == 0) {
+ hostname_is_valid = 0;
+ _hostname[j++] = '?';
+ } else {
+ _hostname[j++] = '_';
+ }
+ }
+ cl--;
+ }
}
+
+ _hostname[j] = '\0';
+
+ ndpi_hostname_sni_set(flow, (const u_int8_t *)_hostname, j);
+
if (hostname_is_valid == 0) {
ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS);
}
- flow->host_server_name[j] = '\0';
-
if(j > 0) {
ndpi_protocol_match_result ret_match;
- ndpi_check_dga_name(ndpi_struct, flow, (char*)flow->host_server_name, 1);
+ ndpi_check_dga_name(ndpi_struct, flow, flow->host_server_name, 1);
ret.app_protocol = ndpi_match_host_subprotocol(ndpi_struct, flow,
- (char *)flow->host_server_name,
- strlen((const char*)flow->host_server_name),
+ flow->host_server_name,
+ strlen(flow->host_server_name),
&ret_match,
NDPI_PROTOCOL_DNS);