aboutsummaryrefslogtreecommitdiff
path: root/src/lib/protocols/dns.c
diff options
context:
space:
mode:
authorIvan Nardi <12729895+IvanNardi@users.noreply.github.com>2021-10-05 15:49:52 +0200
committerGitHub <noreply@github.com>2021-10-05 15:49:52 +0200
commit730c2360bd7c7df7c284f74cd0d56b52a553c03b (patch)
treea7cc73981b50590d3cee939512b0890f2052ff6a /src/lib/protocols/dns.c
parentf3fcf1e7c0c56224444897b321f698817f5129a0 (diff)
Remove `struct ndpi_packet_struct` from `struct ndpi_flow_struct` (#1319)
There are no real reasons to embed `struct ndpi_packet_struct` (i.e. "packet") in `struct ndpi_flow_struct` (i.e. "flow"). In other words, we can avoid saving dissection information of "current packet" into the "flow" state, i.e. in the flow management table. The nDPI detection module processes only one packet at the time, so it is safe to save packet dissection information in `struct ndpi_detection_module_struct`, reusing always the same "packet" instance and saving a huge amount of memory. Bottom line: we need only one copy of "packet" (for detection module), not one for each "flow". It is not clear how/why "packet" ended up in "flow" in the first place. It has been there since the beginning of the GIT history, but in the original OpenDPI code `struct ipoque_packet_struct` was embedded in `struct ipoque_detection_module_struct`, i.e. there was the same exact situation this commit wants to achieve. Most of the changes in this PR are some boilerplate to update something like "flow->packet" into something like "module->packet" throughout the code. Some attention has been paid to update `ndpi_init_packet()` since we need to reset some "packet" fields before starting to process another packet. There has been one important change, though, in ndpi_detection_giveup(). Nothing changed for the applications/users, but this function can't access "packet" anymore. The reason is that this function can be called "asynchronously" with respect to the data processing, i.e in context where there is no valid notion of "current packet"; for example ndpiReader calls it after having processed all the traffic, iterating the entire session table. Mining LRU stuff seems a bit odd (even before this patch): probably we need to rethink it, as a follow-up.
Diffstat (limited to 'src/lib/protocols/dns.c')
-rw-r--r--src/lib/protocols/dns.c86
1 files changed, 44 insertions, 42 deletions
diff --git a/src/lib/protocols/dns.c b/src/lib/protocols/dns.c
index fdc5cb5b0..a326b8b68 100644
--- a/src/lib/protocols/dns.c
+++ b/src/lib/protocols/dns.c
@@ -178,9 +178,10 @@ static int search_valid_dns(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow,
struct ndpi_dns_packet_header *dns_header,
int payload_offset, u_int8_t *is_query) {
+ struct ndpi_packet_struct *packet = &ndpi_struct->packet;
int x = payload_offset;
- memcpy(dns_header, (struct ndpi_dns_packet_header*)&flow->packet.payload[x],
+ memcpy(dns_header, (struct ndpi_dns_packet_header*)&packet->payload[x],
sizeof(struct ndpi_dns_packet_header));
dns_header->tr_id = ntohs(dns_header->tr_id);
@@ -211,10 +212,10 @@ static int search_valid_dns(struct ndpi_detection_module_struct *ndpi_struct,
|| ((dns_header->flags & 0xFCF0) == 0x00) /* Standard Query */
|| ((dns_header->num_answers == 0) && (dns_header->authority_rrs == 0)))) {
/* This is a good query */
- while(x+2 < flow->packet.payload_packet_len) {
- if(flow->packet.payload[x] == '\0') {
+ while(x+2 < packet->payload_packet_len) {
+ if(packet->payload[x] == '\0') {
x++;
- flow->protos.dns.query_type = get16(&x, flow->packet.payload);
+ flow->protos.dns.query_type = get16(&x, packet->payload);
#ifdef DNS_DEBUG
NDPI_LOG_DBG2(ndpi_struct, "query_type=%2d\n", flow->protos.dns.query_type);
printf("[DNS] [request] query_type=%d\n", flow->protos.dns.query_type);
@@ -241,9 +242,9 @@ static int search_valid_dns(struct ndpi_detection_module_struct *ndpi_struct,
/* Leave the statement below commented necessary in case of call to ndpi_get_partial_detection() */
x++;
- if(x < flow->packet.payload_packet_len && flow->packet.payload[x] != '\0') {
- while((x < flow->packet.payload_packet_len)
- && (flow->packet.payload[x] != '\0')) {
+ if(x < packet->payload_packet_len && packet->payload[x] != '\0') {
+ while((x < packet->payload_packet_len)
+ && (packet->payload[x] != '\0')) {
x++;
}
@@ -259,21 +260,21 @@ static int search_valid_dns(struct ndpi_detection_module_struct *ndpi_struct,
for(num = 0; num < dns_header->num_answers; num++) {
u_int16_t data_len;
- if((x+6) >= flow->packet.payload_packet_len) {
+ if((x+6) >= packet->payload_packet_len) {
break;
}
- if((data_len = getNameLength(x, flow->packet.payload,
- flow->packet.payload_packet_len)) == 0) {
+ if((data_len = getNameLength(x, packet->payload,
+ packet->payload_packet_len)) == 0) {
break;
} else
x += data_len;
- if((x+2) >= flow->packet.payload_packet_len) {
+ if((x+2) >= packet->payload_packet_len) {
break;
}
- rsp_type = get16(&x, flow->packet.payload);
+ rsp_type = get16(&x, packet->payload);
#ifdef DNS_DEBUG
printf("[DNS] [response] response_type=%d\n", rsp_type);
@@ -284,11 +285,11 @@ static int search_valid_dns(struct ndpi_detection_module_struct *ndpi_struct,
flow->protos.dns.rsp_type = rsp_type;
/* here x points to the response "class" field */
- if((x+12) <= flow->packet.payload_packet_len) {
+ if((x+12) <= packet->payload_packet_len) {
x += 6;
- data_len = get16(&x, flow->packet.payload);
+ data_len = get16(&x, packet->payload);
- if((x + data_len) <= flow->packet.payload_packet_len) {
+ if((x + data_len) <= packet->payload_packet_len) {
// printf("[rsp_type: %u][data_len: %u]\n", rsp_type, data_len);
if(rsp_type == 0x05 /* CNAME */) {
@@ -299,7 +300,7 @@ static int search_valid_dns(struct ndpi_detection_module_struct *ndpi_struct,
if((((rsp_type == 0x1) && (data_len == 4)) /* A */
|| ((rsp_type == 0x1c) && (data_len == 16)) /* AAAA */
)) {
- memcpy(&flow->protos.dns.rsp_addr, flow->packet.payload + x, data_len);
+ memcpy(&flow->protos.dns.rsp_addr, packet->payload + x, data_len);
}
}
}
@@ -314,7 +315,7 @@ static int search_valid_dns(struct ndpi_detection_module_struct *ndpi_struct,
// flow->extra_packets_func = NULL; /* Removed so the caller can keep dissecting DNS flows */
} else {
/* We missed the request */
- u_int16_t s_port = flow->packet.udp ? ntohs(flow->packet.udp->source) : ntohs(flow->packet.tcp->source);
+ u_int16_t s_port = packet->udp ? ntohs(packet->udp->source) : ntohs(packet->tcp->source);
ndpi_set_detected_protocol(ndpi_struct, flow, checkPort(s_port), NDPI_PROTOCOL_UNKNOWN);
}
@@ -338,19 +339,20 @@ static int search_dns_again(struct ndpi_detection_module_struct *ndpi_struct, st
/* *********************************************** */
static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &ndpi_struct->packet;
int payload_offset;
u_int8_t is_query;
u_int16_t s_port = 0, d_port = 0;
NDPI_LOG_DBG(ndpi_struct, "search DNS\n");
- if(flow->packet.udp != NULL) {
- s_port = ntohs(flow->packet.udp->source);
- d_port = ntohs(flow->packet.udp->dest);
+ if(packet->udp != NULL) {
+ s_port = ntohs(packet->udp->source);
+ d_port = ntohs(packet->udp->dest);
payload_offset = 0;
- } else if(flow->packet.tcp != NULL) /* pkt size > 512 bytes */ {
- s_port = ntohs(flow->packet.tcp->source);
- d_port = ntohs(flow->packet.tcp->dest);
+ } else if(packet->tcp != NULL) /* pkt size > 512 bytes */ {
+ s_port = ntohs(packet->tcp->source);
+ d_port = ntohs(packet->tcp->dest);
payload_offset = 2;
} else {
NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
@@ -360,7 +362,7 @@ static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, st
if(((s_port == DNS_PORT) || (d_port == DNS_PORT)
|| (s_port == MDNS_PORT) || (d_port == MDNS_PORT)
|| (d_port == LLMNR_PORT))
- && (flow->packet.payload_packet_len > sizeof(struct ndpi_dns_packet_header)+payload_offset)) {
+ && (packet->payload_packet_len > sizeof(struct ndpi_dns_packet_header)+payload_offset)) {
struct ndpi_dns_packet_header dns_header;
int j = 0, max_len, off;
int invalid = search_valid_dns(ndpi_struct, flow, &dns_header, payload_offset, &is_query);
@@ -380,11 +382,11 @@ static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, st
off = sizeof(struct ndpi_dns_packet_header) + payload_offset;
/* Before continuing let's dissect the following queries to see if they are valid */
- for(idx=off, num_queries=0; (num_queries < dns_header.num_queries) && (idx < flow->packet.payload_packet_len);) {
+ for(idx=off, num_queries=0; (num_queries < dns_header.num_queries) && (idx < packet->payload_packet_len);) {
u_int16_t i, tot_len = 0;
- for(i=idx; i<flow->packet.payload_packet_len;) {
- u_int8_t is_ptr = 0, name_len = flow->packet.payload[i]; /* Lenght of the individual name blocks aaa.bbb.com */
+ for(i=idx; i<packet->payload_packet_len;) {
+ u_int8_t is_ptr = 0, name_len = packet->payload[i]; /* Lenght of the individual name blocks aaa.bbb.com */
if(name_len == 0) {
tot_len++; /* \0 */
@@ -401,8 +403,8 @@ static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, st
int idx;
for(idx=0; idx<name_len; idx++)
- printf("%c", flow->packet.payload[i+1+idx]);
-
+ printf("%c", packet->payload[i+1+idx]);
+
printf("]\n");
}
}
@@ -416,13 +418,13 @@ static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, st
printf("[DNS] [tot_len: %u]\n\n", tot_len+4 /* type + class */);
#endif
- if(((i+4 /* Skip query type and class */) > flow->packet.payload_packet_len)
- || ((flow->packet.payload[i+1] == 0x0) && (flow->packet.payload[i+2] == 0x0)) /* Query type cannot be 0 */
+ if(((i+4 /* Skip query type and class */) > packet->payload_packet_len)
+ || ((packet->payload[i+1] == 0x0) && (packet->payload[i+2] == 0x0)) /* Query type cannot be 0 */
|| (tot_len > 253)
) {
/* Invalid */
#ifdef DNS_DEBUG
- printf("[DNS] Invalid query len [%u >= %u]\n", i+4, flow->packet.payload_packet_len);
+ printf("[DNS] Invalid query len [%u >= %u]\n", i+4, packet->payload_packet_len);
#endif
ndpi_set_risk(ndpi_struct, flow, NDPI_MALFORMED_PACKET);
break;
@@ -431,11 +433,11 @@ static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, st
}
} /* for */
- while((j < max_len) && (off < flow->packet.payload_packet_len) && (flow->packet.payload[off] != '\0')) {
- uint8_t c, cl = flow->packet.payload[off++];
+ while((j < max_len) && (off < packet->payload_packet_len) && (packet->payload[off] != '\0')) {
+ uint8_t c, cl = packet->payload[off++];
if(((cl & 0xc0) != 0) || // we not support compressed names in query
- (off + cl >= flow->packet.payload_packet_len)) {
+ (off + cl >= packet->payload_packet_len)) {
j = 0;
break;
}
@@ -445,7 +447,7 @@ static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, st
while((j < max_len) && (cl != 0)) {
u_int32_t shift;
- c = flow->packet.payload[off++];
+ c = packet->payload[off++];
shift = ((u_int32_t) 1) << (c & 0x1f);
flow->host_server_name[j++] = tolower((dns_validchar[c >> 5] & shift) ? c : '_');
cl--;
@@ -522,21 +524,21 @@ static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, st
if((flow->detected_protocol_stack[0] == NDPI_PROTOCOL_DNS)
|| (flow->detected_protocol_stack[1] == NDPI_PROTOCOL_DNS)) {
/* TODO: add support to RFC6891 to avoid some false positives */
- if(flow->packet.udp != NULL && flow->packet.payload_packet_len > PKT_LEN_ALERT)
+ if(packet->udp != NULL && packet->payload_packet_len > PKT_LEN_ALERT)
ndpi_set_risk(ndpi_struct, flow, NDPI_DNS_LARGE_PACKET);
- if(flow->packet.iph != NULL) {
+ if(packet->iph != NULL) {
/* IPv4 */
- u_int8_t flags = ((u_int8_t*)flow->packet.iph)[6];
+ u_int8_t flags = ((u_int8_t*)packet->iph)[6];
/* 0: fragmented; 1: not fragmented */
if((flags & 0x20)
- || (ndpi_iph_is_valid_and_not_fragmented(flow->packet.iph, flow->packet.l3_packet_len) == 0)) {
+ || (ndpi_iph_is_valid_and_not_fragmented(packet->iph, packet->l3_packet_len) == 0)) {
ndpi_set_risk(ndpi_struct, flow, NDPI_DNS_FRAGMENTED);
}
- } else if(flow->packet.iphv6 != NULL) {
+ } else if(packet->iphv6 != NULL) {
/* IPv6 */
- const struct ndpi_ip6_hdrctl *ip6_hdr = &flow->packet.iphv6->ip6_hdr;
+ const struct ndpi_ip6_hdrctl *ip6_hdr = &packet->iphv6->ip6_hdr;
if(ip6_hdr->ip6_un1_nxt == 0x2C /* Next Header: Fragment Header for IPv6 (44) */) {
ndpi_set_risk(ndpi_struct, flow, NDPI_DNS_FRAGMENTED);