Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make LRU caches ipv6 aware #1810

Merged
merged 1 commit into from
Dec 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 55 additions & 25 deletions src/lib/ndpi_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ static ndpi_risk_info ndpi_known_risks[] = {

extern void ndpi_unset_risk(struct ndpi_detection_module_struct *ndpi_str,
struct ndpi_flow_struct *flow, ndpi_risk_enum r);
extern u_int32_t make_mining_key(struct ndpi_flow_struct *flow);

/* Forward */
static void addDefaultPort(struct ndpi_detection_module_struct *ndpi_str,
Expand Down Expand Up @@ -5693,6 +5694,19 @@ u_int16_t ndpi_guess_host_protocol_id(struct ndpi_detection_module_struct *ndpi_

/* ********************************************************************************* */

static u_int32_t make_msteams_key(struct ndpi_flow_struct *flow) {
u_int32_t key;

if(flow->is_ipv6)
key = ndpi_quick_hash(flow->c_address.v6, 16);
else
key = ntohl(flow->c_address.v4);

return key;
}

/* ********************************************************************************* */

static void ndpi_reconcile_protocols(struct ndpi_detection_module_struct *ndpi_str,
struct ndpi_flow_struct *flow,
ndpi_protocol *ret) {
Expand All @@ -5715,12 +5729,12 @@ static void ndpi_reconcile_protocols(struct ndpi_detection_module_struct *ndpi_s
(MS Teams uses Skype as transport protocol for voice/video)
*/
case NDPI_PROTOCOL_MSTEAMS:
if(flow->is_ipv6 == 0 && flow->l4_proto == IPPROTO_TCP) {
if(flow->l4_proto == IPPROTO_TCP) {
// printf("====>> NDPI_PROTOCOL_MSTEAMS\n");

if(ndpi_str->msteams_cache)
ndpi_lru_add_to_cache(ndpi_str->msteams_cache,
ntohl(flow->c_address.v4),
make_msteams_key(flow),
(flow->last_packet_time_ms / 1000) & 0xFFFF /* 16 bit */);
}
break;
Expand All @@ -5740,12 +5754,11 @@ static void ndpi_reconcile_protocols(struct ndpi_detection_module_struct *ndpi_s

case NDPI_PROTOCOL_SKYPE_TEAMS:
case NDPI_PROTOCOL_SKYPE_TEAMS_CALL:
if(flow->is_ipv6 == 0
&& flow->l4_proto == IPPROTO_UDP
if(flow->l4_proto == IPPROTO_UDP
&& ndpi_str->msteams_cache) {
u_int16_t when;

if(ndpi_lru_find_cache(ndpi_str->msteams_cache, ntohl(flow->c_address.v4),
if(ndpi_lru_find_cache(ndpi_str->msteams_cache, make_msteams_key(flow),
&when, 0 /* Don't remove it as it can be used for other connections */)) {
u_int16_t tdiff = ((flow->last_packet_time_ms /1000) & 0xFFFF) - when;

Expand All @@ -5755,7 +5768,7 @@ static void ndpi_reconcile_protocols(struct ndpi_detection_module_struct *ndpi_s

/* Refresh cache */
ndpi_lru_add_to_cache(ndpi_str->msteams_cache,
ntohl(flow->c_address.v4),
make_msteams_key(flow),
(flow->last_packet_time_ms / 1000) & 0xFFFF /* 16 bit */);
}
}
Expand Down Expand Up @@ -5845,21 +5858,40 @@ int ndpi_search_into_bittorrent_cache(struct ndpi_detection_module_struct *ndpi_

/* #define ZOOM_CACHE_DEBUG */

static u_int8_t ndpi_search_into_zoom_cache(struct ndpi_detection_module_struct *ndpi_struct,
u_int32_t daddr /* Network byte order */) {

#ifdef ZOOM_CACHE_DEBUG
printf("[%s:%u] ndpi_search_into_zoom_cache(%08X, %u)\n",
__FILE__, __LINE__, daddr, dport);
#endif
static u_int32_t make_zoom_key(struct ndpi_flow_struct *flow, int server) {
u_int32_t key;

if(server) {
if(flow->is_ipv6)
key = ndpi_quick_hash(flow->s_address.v6, 16);
else
key = flow->s_address.v4;
} else {
if(flow->is_ipv6)
key = ndpi_quick_hash(flow->c_address.v6, 16);
else
key = flow->c_address.v4;
}

return key;
}

/* ********************************************************************************* */

static u_int8_t ndpi_search_into_zoom_cache(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow, int server) {

if(ndpi_struct->zoom_cache) {
u_int16_t cached_proto;
u_int8_t found = ndpi_lru_find_cache(ndpi_struct->zoom_cache, daddr, &cached_proto,
u_int32_t key;

key = make_zoom_key(flow, server);
u_int8_t found = ndpi_lru_find_cache(ndpi_struct->zoom_cache, key, &cached_proto,
0 /* Don't remove it as it can be used for other connections */);

#ifdef ZOOM_CACHE_DEBUG
printf("[Zoom] *** [TCP] SEARCHING host %u [found: %u]\n", daddr, found);
printf("[Zoom] *** [TCP] SEARCHING key %u [found: %u]\n", key, found);
#endif

return(found);
Expand All @@ -5871,9 +5903,9 @@ static u_int8_t ndpi_search_into_zoom_cache(struct ndpi_detection_module_struct
/* ********************************************************************************* */

static void ndpi_add_connection_as_zoom(struct ndpi_detection_module_struct *ndpi_struct,
u_int32_t daddr /* Network byte order */) {
struct ndpi_flow_struct *flow) {
if(ndpi_struct->zoom_cache)
ndpi_lru_add_to_cache(ndpi_struct->zoom_cache, daddr, NDPI_PROTOCOL_ZOOM);
ndpi_lru_add_to_cache(ndpi_struct->zoom_cache, make_zoom_key(flow, 1), NDPI_PROTOCOL_ZOOM);
}

/* ********************************************************************************* */
Expand Down Expand Up @@ -5901,10 +5933,10 @@ ndpi_protocol ndpi_detection_giveup(struct ndpi_detection_module_struct *ndpi_st

/* TODO: this lookup seems in the wrong place here...
Move it somewhere else (?) or setting flow->guessed_protocol_id directly in the mining dissector? */
if(ndpi_str->mining_cache && flow->is_ipv6 == 0) {
if(ndpi_str->mining_cache) {
u_int16_t cached_proto;

if(ndpi_lru_find_cache(ndpi_str->mining_cache, flow->c_address.v4 + flow->s_address.v4,
if(ndpi_lru_find_cache(ndpi_str->mining_cache, make_mining_key(flow),
&cached_proto, 0 /* Don't remove it as it can be used for other connections */)) {
ndpi_set_detected_protocol(ndpi_str, flow, cached_proto, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI_PARTIAL_CACHE);
ret.master_protocol = flow->detected_protocol_stack[1], ret.app_protocol = flow->detected_protocol_stack[0];
Expand Down Expand Up @@ -5982,10 +6014,9 @@ ndpi_protocol ndpi_detection_giveup(struct ndpi_detection_module_struct *ndpi_st
/* This looks like BitTorrent */
ndpi_set_detected_protocol(ndpi_str, flow, NDPI_PROTOCOL_BITTORRENT, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI_PARTIAL_CACHE);
ret.app_protocol = NDPI_PROTOCOL_BITTORRENT;
} else if((flow->l4_proto == IPPROTO_UDP) /* Zoom/UDP used for video */
&& (((ntohs(flow->c_port) == 8801 /* Zoom port */) && ndpi_search_into_zoom_cache(ndpi_str, flow->c_address.v4))
|| ((ntohs(flow->s_port) == 8801 /* Zoom port */) && ndpi_search_into_zoom_cache(ndpi_str, flow->s_address.v4))
)) {
} else if((flow->l4_proto == IPPROTO_UDP) && /* Zoom/UDP used for video */
((ntohs(flow->s_port) == 8801 && ndpi_search_into_zoom_cache(ndpi_str, flow, 1)) ||
(ntohs(flow->c_port) == 8801 && ndpi_search_into_zoom_cache(ndpi_str, flow, 0)))) {
/* This looks like Zoom */
ndpi_set_detected_protocol(ndpi_str, flow, NDPI_PROTOCOL_ZOOM, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI_PARTIAL_CACHE);
ret.app_protocol = NDPI_PROTOCOL_ZOOM;
Expand Down Expand Up @@ -6642,9 +6673,8 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct

/* Zoom cache */
if((ret.app_protocol == NDPI_PROTOCOL_ZOOM)
&& (flow->l4_proto == IPPROTO_TCP)
&& (ndpi_str->packet.iph != NULL))
ndpi_add_connection_as_zoom(ndpi_str, ndpi_str->packet.iph->daddr);
&& (flow->l4_proto == IPPROTO_TCP))
ndpi_add_connection_as_zoom(ndpi_str, flow);

return(ret);
}
Expand Down
2 changes: 1 addition & 1 deletion src/lib/protocols/hangout.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ void ndpi_search_hangout(struct ndpi_detection_module_struct *ndpi_struct,

/* Hangout is over STUN hence the LRU cache is shared */

if(ndpi_struct->stun_cache && packet->iph) {
if(ndpi_struct->stun_cache) {
u_int32_t key = get_stun_lru_key(flow, !matched_src);

#ifdef DEBUG_LRU
Expand Down
34 changes: 22 additions & 12 deletions src/lib/protocols/mining.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,27 @@
#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_MINING
#include "ndpi_api.h"


/* ************************************************************************** */

u_int32_t make_mining_key(struct ndpi_flow_struct *flow) {
u_int32_t key;

/* network byte order */
if(flow->is_ipv6)
key = ndpi_quick_hash(flow->c_address.v6, 16) + ndpi_quick_hash(flow->s_address.v6, 16);
else
key = flow->c_address.v4 + flow->s_address.v4;

return key;
}

/* ************************************************************************** */

static void cacheMiningHostTwins(struct ndpi_detection_module_struct *ndpi_struct,
u_int32_t host_keys /* network byte order */) {
struct ndpi_flow_struct *flow) {
if(ndpi_struct->mining_cache)
ndpi_lru_add_to_cache(ndpi_struct->mining_cache, host_keys, NDPI_PROTOCOL_MINING);
ndpi_lru_add_to_cache(ndpi_struct->mining_cache, make_mining_key(flow), NDPI_PROTOCOL_MINING);
}

/* ************************************************************************** */
Expand Down Expand Up @@ -59,8 +74,7 @@ static void ndpi_search_mining_udp(struct ndpi_detection_module_struct *ndpi_str
else {
ndpi_snprintf(flow->flow_extra_info, sizeof(flow->flow_extra_info), "%s", "ETH");
ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_MINING, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
if(packet->iph) /* TODO: ipv6 */
cacheMiningHostTwins(ndpi_struct, packet->iph->saddr + packet->iph->daddr);
cacheMiningHostTwins(ndpi_struct, flow);
return;
}
}
Expand Down Expand Up @@ -96,8 +110,7 @@ static void ndpi_search_mining_tcp(struct ndpi_detection_module_struct *ndpi_str
if((*to_match == magic) || (*to_match == magic1)) {
ndpi_snprintf(flow->flow_extra_info, sizeof(flow->flow_extra_info), "%s", "ETH");
ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_MINING, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
if(packet->iph) /* TODO: ipv6 */
cacheMiningHostTwins(ndpi_struct, packet->iph->saddr + packet->iph->daddr);
cacheMiningHostTwins(ndpi_struct, flow);
return;
}
}
Expand All @@ -108,8 +121,7 @@ static void ndpi_search_mining_tcp(struct ndpi_detection_module_struct *ndpi_str
if(isEthPort(ntohs(packet->tcp->dest)) /* Ethereum port */) {
ndpi_snprintf(flow->flow_extra_info, sizeof(flow->flow_extra_info), "%s", "ETH");
ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_MINING, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
if(packet->iph) /* TODO: ipv6 */
cacheMiningHostTwins(ndpi_struct, packet->iph->saddr + packet->iph->daddr);
cacheMiningHostTwins(ndpi_struct, flow);
return;
}
} else if(ndpi_strnstr((const char *)packet->payload, "{", packet->payload_packet_len)
Expand All @@ -127,8 +139,7 @@ static void ndpi_search_mining_tcp(struct ndpi_detection_module_struct *ndpi_str
*/
ndpi_snprintf(flow->flow_extra_info, sizeof(flow->flow_extra_info), "%s", "ETH");
ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_MINING, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
if(packet->iph) /* TODO: ipv6 */
cacheMiningHostTwins(ndpi_struct, packet->iph->saddr + packet->iph->daddr);
cacheMiningHostTwins(ndpi_struct, flow);
return;
} else if(ndpi_strnstr((const char *)packet->payload, "{", packet->payload_packet_len)
&& (ndpi_strnstr((const char *)packet->payload, "\"method\":", packet->payload_packet_len)
Expand All @@ -151,8 +162,7 @@ static void ndpi_search_mining_tcp(struct ndpi_detection_module_struct *ndpi_str
*/
ndpi_snprintf(flow->flow_extra_info, sizeof(flow->flow_extra_info), "%s", "ZCash/Monero");
ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_MINING, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
if(packet->iph) /* TODO: ipv6 */
cacheMiningHostTwins(ndpi_struct, packet->iph->saddr + packet->iph->daddr);
cacheMiningHostTwins(ndpi_struct, flow);
return;
}
}
Expand Down
19 changes: 12 additions & 7 deletions src/lib/protocols/stun.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,24 @@
/* ************************************************************ */

u_int32_t get_stun_lru_key(struct ndpi_flow_struct *flow, u_int8_t rev) {
if(rev)
return(ntohl(flow->s_address.v4) + ntohs(flow->s_port));
else
return(ntohl(flow->c_address.v4) + ntohs(flow->c_port));
if(rev) {
if(flow->is_ipv6)
return ndpi_quick_hash(flow->s_address.v6, 16) + ntohs(flow->s_port);
else
return ntohl(flow->s_address.v4) + ntohs(flow->s_port);
} else {
if(flow->is_ipv6)
return ndpi_quick_hash(flow->c_address.v6, 16) + ntohs(flow->c_port);
else
return ntohl(flow->c_address.v4) + ntohs(flow->c_port);
}
}

/* ************************************************************ */

static void ndpi_int_stun_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow,
u_int app_proto) {
struct ndpi_packet_struct *packet = &ndpi_struct->packet;
ndpi_confidence_t confidence = NDPI_CONFIDENCE_DPI;

if(app_proto == NDPI_PROTOCOL_UNKNOWN) {
Expand All @@ -59,7 +65,6 @@ static void ndpi_int_stun_add_connection(struct ndpi_detection_module_struct *nd
}

if(ndpi_struct->stun_cache
&& packet->iph
&& (app_proto != NDPI_PROTOCOL_UNKNOWN)
) /* Cache flow sender info */ {
u_int32_t key = get_stun_lru_key(flow, 0);
Expand Down Expand Up @@ -182,7 +187,7 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct *
return(NDPI_IS_NOT_STUN);
}

if(ndpi_struct->stun_cache && packet->iph) { /* TODO: ipv6 */
if(ndpi_struct->stun_cache) {
u_int16_t proto;
u_int32_t key = get_stun_lru_key(flow, 0);
int rc = ndpi_lru_find_cache(ndpi_struct->stun_cache, key, &proto,
Expand Down
49 changes: 41 additions & 8 deletions src/lib/protocols/tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,42 @@ static int extractRDNSequence(struct ndpi_packet_struct *packet,

/* **************************************** */

static u_int32_t make_tls_cert_key(struct ndpi_packet_struct *packet, int is_from_client)
{
u_int32_t key;

/* Server ip/port */
if(packet->iphv6 == NULL) {
if(packet->tcp) {
if(is_from_client)
key = packet->iph->daddr + packet->tcp->dest;
else
key = packet->iph->saddr + packet->tcp->source;
} else {
if(is_from_client)
key = packet->iph->daddr + packet->udp->dest;
else
key = packet->iph->saddr + packet->udp->source;
}
} else {
if(packet->tcp) {
if(is_from_client)
key = ndpi_quick_hash((unsigned char *)&packet->iphv6->ip6_dst, 16) + packet->tcp->dest;
else
key = ndpi_quick_hash((unsigned char *)&packet->iphv6->ip6_src, 16) + packet->tcp->source;
} else {
if(is_from_client)
key = ndpi_quick_hash((unsigned char *)&packet->iphv6->ip6_dst, 16) + packet->udp->dest;
else
key = ndpi_quick_hash((unsigned char *)&packet->iphv6->ip6_src, 16) + packet->udp->source;
}
}

return key;
}

/* **************************************** */

static void checkTLSSubprotocol(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow,
int is_from_client) {
Expand All @@ -298,14 +334,11 @@ static void checkTLSSubprotocol(struct ndpi_detection_module_struct *ndpi_struct
if(flow->detected_protocol_stack[1] == NDPI_PROTOCOL_UNKNOWN) {
/* Subprotocol not yet set */

if(ndpi_struct->tls_cert_cache && packet->iph && packet->tcp) {
u_int32_t key; /* Server ip/port */
if(ndpi_struct->tls_cert_cache) {
u_int16_t cached_proto;
u_int32_t key;

if(is_from_client)
key = packet->iph->daddr + packet->tcp->dest;
else
key = packet->iph->saddr + packet->tcp->source;
key = make_tls_cert_key(packet, is_from_client);

if(ndpi_lru_find_cache(ndpi_struct->tls_cert_cache, key,
&cached_proto, 0 /* Don't remove it as it can be used for other connections */)) {
Expand Down Expand Up @@ -695,8 +728,8 @@ static void processCertificateElements(struct ndpi_detection_module_struct *ndpi
flow->category = ndpi_get_proto_category(ndpi_struct, ret);
ndpi_check_subprotocol_risk(ndpi_struct, flow, proto_id);

if(ndpi_struct->tls_cert_cache && packet->iph && packet->tcp) {
u_int32_t key = packet->iph->saddr + packet->tcp->source; /* Server */
if(ndpi_struct->tls_cert_cache) {
u_int32_t key = make_tls_cert_key(packet, 0 /* from the server */);

ndpi_lru_add_to_cache(ndpi_struct->tls_cert_cache, key, proto_id);
}
Expand Down
Binary file added tests/pcap/lru_ipv6_caches.pcapng
Binary file not shown.
2 changes: 1 addition & 1 deletion tests/result/1kxun.pcap.out
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ LRU cache bittorrent: 0/45/0 (insert/search/found)
LRU cache zoom: 0/0/0 (insert/search/found)
LRU cache stun: 0/0/0 (insert/search/found)
LRU cache tls_cert: 0/8/0 (insert/search/found)
LRU cache mining: 0/16/0 (insert/search/found)
LRU cache mining: 0/20/0 (insert/search/found)
LRU cache msteams: 0/0/0 (insert/search/found)
Automa host: 164/72 (search/found)
Automa domain: 156/0 (search/found)
Expand Down
2 changes: 1 addition & 1 deletion tests/result/6in4tunnel.pcap.out
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ 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/0/0 (insert/search/found)
LRU cache tls_cert: 0/0/0 (insert/search/found)
LRU cache tls_cert: 0/2/0 (insert/search/found)
LRU cache mining: 0/0/0 (insert/search/found)
LRU cache msteams: 0/0/0 (insert/search/found)
Automa host: 9/5 (search/found)
Expand Down
Loading