Loading nfq/conntrack.c +1 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ void ConntrackClearHostname(t_ctrack *track) { free(track->hostname); track->hostname = NULL; track->hostname_is_ip = false; } static void ConntrackClearTrack(t_ctrack *track) { Loading nfq/conntrack.h +1 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,7 @@ typedef struct t_l7proto l7proto; bool l7proto_discovered; char *hostname; bool hostname_is_ip; bool hostname_discovered; bool hostname_ah_check; // should perform autohostlist checks Loading nfq/desync.c +41 −27 Original line number Diff line number Diff line Loading @@ -223,7 +223,7 @@ enum dpi_desync_mode desync_mode_from_string(const char *s) static bool dp_match( struct desync_profile *dp, uint8_t l3proto, const struct sockaddr *dest, const char *hostname, t_l7proto l7proto, const char *ssid, uint8_t l3proto, const struct sockaddr *dest, const char *hostname, bool bNoSubdom, t_l7proto l7proto, const char *ssid, bool *bCheckDone, bool *bCheckResult, bool *bExcluded) { bool bHostlistsEmpty; Loading Loading @@ -267,7 +267,7 @@ static bool dp_match( { if (bCheckDone) *bCheckDone = true; bool b; b = HostlistCheck(dp, hostname, bExcluded, true); b = HostlistCheck(dp, hostname, bNoSubdom, bExcluded, true); if (bCheckResult) *bCheckResult = b; return b; } Loading @@ -276,7 +276,7 @@ static bool dp_match( } static struct desync_profile *dp_find( struct desync_profile_list_head *head, uint8_t l3proto, const struct sockaddr *dest, const char *hostname, t_l7proto l7proto, const char *ssid, uint8_t l3proto, const struct sockaddr *dest, const char *hostname, bool bNoSubdom, t_l7proto l7proto, const char *ssid, bool *bCheckDone, bool *bCheckResult, bool *bExcluded) { struct desync_profile_list *dpl; Loading @@ -289,7 +289,7 @@ static struct desync_profile *dp_find( if (bCheckDone) *bCheckDone = false; LIST_FOREACH(dpl, head, next) { if (dp_match(&dpl->dp,l3proto,dest,hostname,l7proto,ssid,bCheckDone,bCheckResult,bExcluded)) if (dp_match(&dpl->dp,l3proto,dest,hostname,bNoSubdom,l7proto,ssid,bCheckDone,bCheckResult,bExcluded)) { DLOG("desync profile %d matches\n",dpl->dp.n); return &dpl->dp; Loading Loading @@ -418,7 +418,7 @@ static bool auto_hostlist_retrans(t_ctrack *ctrack, uint8_t l4proto, int thresho } return false; } static void auto_hostlist_failed(struct desync_profile *dp, const char *hostname, const char *client_ip_port, t_l7proto l7proto) static void auto_hostlist_failed(struct desync_profile *dp, const char *hostname, bool bNoSubdom, const char *client_ip_port, t_l7proto l7proto) { hostfail_pool *fail_counter; Loading @@ -442,7 +442,7 @@ static void auto_hostlist_failed(struct desync_profile *dp, const char *hostname DLOG("auto hostlist (profile %d) : rechecking %s to avoid duplicates\n", dp->n, hostname); bool bExcluded=false; if (!HostlistCheck(dp, hostname, &bExcluded, false) && !bExcluded) if (!HostlistCheck(dp, hostname, bNoSubdom, &bExcluded, false) && !bExcluded) { DLOG("auto hostlist (profile %d) : adding %s to %s\n", dp->n, hostname, dp->hostlist_auto->filename); HOSTLIST_DEBUGLOG_APPEND("%s : profile %d : client %s : proto %s : adding to %s", hostname, dp->n, client_ip_port, l7proto_str(l7proto), dp->hostlist_auto->filename); Loading Loading @@ -477,7 +477,7 @@ static void process_retrans_fail(t_ctrack *ctrack, uint8_t proto, const struct s if (ctrack && ctrack->dp && ctrack->hostname && auto_hostlist_retrans(ctrack, proto, ctrack->dp->hostlist_auto_retrans_threshold, client_ip_port, ctrack->l7proto)) { HOSTLIST_DEBUGLOG_APPEND("%s : profile %d : client %s : proto %s : retrans threshold reached", ctrack->hostname, ctrack->dp->n, client_ip_port, l7proto_str(ctrack->l7proto)); auto_hostlist_failed(ctrack->dp, ctrack->hostname, client_ip_port, ctrack->l7proto); auto_hostlist_failed(ctrack->dp, ctrack->hostname, ctrack->hostname_is_ip, client_ip_port, ctrack->l7proto); } } Loading Loading @@ -783,7 +783,7 @@ static void autottl_rediscover(t_ctrack *ctrack, const struct in_addr *a4, const } } static bool ipcache_put_hostname(const struct in_addr *a4, const struct in6_addr *a6, const char *hostname) static bool ipcache_put_hostname(const struct in_addr *a4, const struct in6_addr *a6, const char *hostname, bool hostname_is_ip) { if (!params.cache_hostname) return true; Loading @@ -801,11 +801,12 @@ static bool ipcache_put_hostname(const struct in_addr *a4, const struct in6_addr DLOG_ERR("ipcache_put_hostname: out of memory\n"); return false; } DLOG("hostname cached: %s\n", hostname); ipc->hostname_is_ip = hostname_is_ip; DLOG("hostname cached (is_ip=%u): %s\n", hostname_is_ip, hostname); } return true; } static bool ipcache_get_hostname(const struct in_addr *a4, const struct in6_addr *a6, char *hostname, size_t hostname_buf_len) static bool ipcache_get_hostname(const struct in_addr *a4, const struct in6_addr *a6, char *hostname, size_t hostname_buf_len, bool *hostname_is_ip) { if (!params.cache_hostname) { Loading @@ -820,8 +821,9 @@ static bool ipcache_get_hostname(const struct in_addr *a4, const struct in6_addr } if (ipc->hostname) { DLOG("got cached hostname: %s\n", ipc->hostname); DLOG("got cached hostname (is_ip=%u): %s\n", ipc->hostname_is_ip, ipc->hostname); snprintf(hostname,hostname_buf_len,"%s",ipc->hostname); if (hostname_is_ip) *hostname_is_ip = ipc->hostname_is_ip; } else *hostname = 0; Loading Loading @@ -1140,11 +1142,11 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint { if (!ctrack_replay->hostname && !bReverse) { if (ipcache_get_hostname(dis->ip ? &dis->ip->ip_dst : NULL,dis->ip6 ? &dis->ip6->ip6_dst : NULL , host, sizeof(host)) && *host) if (ipcache_get_hostname(dis->ip ? &dis->ip->ip_dst : NULL,dis->ip6 ? &dis->ip6->ip6_dst : NULL , host, sizeof(host), &ctrack_replay->hostname_is_ip) && *host) if (!(ctrack_replay->hostname = strdup(host))) DLOG_ERR("strdup(host): out of memory\n"); } dp = ctrack_replay->dp = dp_find(¶ms.desync_profiles, IPPROTO_TCP, (struct sockaddr *)&dst, ctrack_replay->hostname, ctrack_replay->l7proto, ssid, NULL, NULL, NULL); dp = ctrack_replay->dp = dp_find(¶ms.desync_profiles, IPPROTO_TCP, (struct sockaddr *)&dst, ctrack_replay->hostname, ctrack_replay->hostname_is_ip, ctrack_replay->l7proto, ssid, NULL, NULL, NULL); ctrack_replay->dp_search_complete = true; } if (!dp) Loading Loading @@ -1176,17 +1178,19 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint else if (!ctrack || !ctrack->dp_search_complete) { const char *hostname = NULL; bool hostname_is_ip = false; if (ctrack) { hostname = ctrack->hostname; hostname_is_ip = ctrack->hostname_is_ip; if (!hostname && !bReverse) { if (ipcache_get_hostname(dis->ip ? &dis->ip->ip_dst : NULL,dis->ip6 ? &dis->ip6->ip6_dst : NULL , host, sizeof(host)) && *host) if (ipcache_get_hostname(dis->ip ? &dis->ip->ip_dst : NULL,dis->ip6 ? &dis->ip6->ip6_dst : NULL , host, sizeof(host), &hostname_is_ip) && *host) if (!(hostname = ctrack_replay->hostname = strdup(host))) DLOG_ERR("strdup(host): out of memory\n"); } } dp = dp_find(¶ms.desync_profiles, IPPROTO_TCP, (struct sockaddr *)&dst, hostname, ctrack ? ctrack->l7proto : UNKNOWN, ssid, NULL, NULL, NULL); dp = dp_find(¶ms.desync_profiles, IPPROTO_TCP, (struct sockaddr *)&dst, hostname, hostname_is_ip, ctrack ? ctrack->l7proto : UNKNOWN, ssid, NULL, NULL, NULL); if (ctrack) { ctrack->dp = dp; Loading Loading @@ -1268,7 +1272,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint } } if (bFail) auto_hostlist_failed(dp, ctrack->hostname, client_ip_port, ctrack->l7proto); auto_hostlist_failed(dp, ctrack->hostname, ctrack->hostname_is_ip, client_ip_port, ctrack->l7proto); else if (dis->len_payload) auto_hostlist_reset_fail_counter(dp, ctrack->hostname, client_ip_port, ctrack->l7proto); Loading Loading @@ -1426,7 +1430,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint int multisplit_count; int i; uint16_t ip_id; bool bHaveHost=false; bool bHaveHost=false, bHostIsIp=false; t_l7proto l7proto = UNKNOWN; if (replay) Loading Loading @@ -1458,6 +1462,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint DLOG("not applying tampering to HTTP without Host:\n"); goto send_orig; } bHostIsIp=strip_host_to_ip(host); if (ctrack) { // we do not reassemble http Loading @@ -1479,6 +1484,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint if (bReqFull) TLSDebug(rdata_payload,rlen_payload); bHaveHost=TLSHelloExtractHost(rdata_payload,rlen_payload,host,sizeof(host),TLS_PARTIALS_ENABLE); if (bHaveHost) bHostIsIp=strip_host_to_ip(host); if (ctrack) { Loading Loading @@ -1567,6 +1573,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint { free(ctrack_replay->hostname); ctrack_replay->hostname=strdup(host); ctrack_replay->hostname_is_ip=bHostIsIp; if (!ctrack_replay->hostname) { DLOG_ERR("hostname dup : out of memory"); Loading @@ -1574,7 +1581,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint goto send_orig; } ctrack_replay->hostname_discovered=true; if (!ipcache_put_hostname(dis->ip ? &dis->ip->ip_dst : NULL,dis->ip6 ? &dis->ip6->ip6_dst : NULL , host)) if (!ipcache_put_hostname(dis->ip ? &dis->ip->ip_dst : NULL,dis->ip6 ? &dis->ip6->ip6_dst : NULL , host, bHostIsIp)) { reasm_orig_cancel(ctrack); goto send_orig; Loading @@ -1590,6 +1597,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint dp = dp_find(¶ms.desync_profiles, IPPROTO_TCP, (struct sockaddr *)&dst, ctrack_replay ? ctrack_replay->hostname : bHaveHost ? host : NULL, ctrack_replay ? ctrack_replay->hostname_is_ip : bHostIsIp, ctrack_replay ? ctrack_replay->l7proto : l7proto, ssid, &bCheckDone, &bCheckResult, &bCheckExcluded); if (ctrack_replay) Loading Loading @@ -1638,7 +1646,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint if (bHaveHost && !PROFILE_HOSTLISTS_EMPTY(dp)) { if (!bCheckDone) bCheckResult = HostlistCheck(dp, host, &bCheckExcluded, false); bCheckResult = HostlistCheck(dp, host, bHostIsIp, &bCheckExcluded, false); if (bCheckResult) ctrack_stop_retrans_counter(ctrack_replay); else Loading Loading @@ -2409,11 +2417,11 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint { if (!ctrack_replay->hostname && !bReverse) { if (ipcache_get_hostname(dis->ip ? &dis->ip->ip_dst : NULL,dis->ip6 ? &dis->ip6->ip6_dst : NULL , host, sizeof(host)) && *host) if (ipcache_get_hostname(dis->ip ? &dis->ip->ip_dst : NULL,dis->ip6 ? &dis->ip6->ip6_dst : NULL , host, sizeof(host), &ctrack_replay->hostname_is_ip) && *host) if (!(ctrack_replay->hostname = strdup(host))) DLOG_ERR("strdup(host): out of memory\n"); } dp = ctrack_replay->dp = dp_find(¶ms.desync_profiles, IPPROTO_UDP, (struct sockaddr *)&dst, ctrack_replay->hostname, ctrack_replay->l7proto, ssid, NULL, NULL, NULL); dp = ctrack_replay->dp = dp_find(¶ms.desync_profiles, IPPROTO_UDP, (struct sockaddr *)&dst, ctrack_replay->hostname, ctrack_replay->hostname_is_ip, ctrack_replay->l7proto, ssid, NULL, NULL, NULL); ctrack_replay->dp_search_complete = true; } if (!dp) Loading Loading @@ -2445,17 +2453,19 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint else if (!ctrack || !ctrack->dp_search_complete) { const char *hostname = NULL; bool hostname_is_ip = false; if (ctrack) { hostname = ctrack->hostname; hostname_is_ip = ctrack->hostname_is_ip; if (!hostname && !bReverse) { if (ipcache_get_hostname(dis->ip ? &dis->ip->ip_dst : NULL,dis->ip6 ? &dis->ip6->ip6_dst : NULL , host, sizeof(host)) && *host) if (ipcache_get_hostname(dis->ip ? &dis->ip->ip_dst : NULL,dis->ip6 ? &dis->ip6->ip6_dst : NULL , host, sizeof(host), &hostname_is_ip) && *host) if (!(hostname = ctrack_replay->hostname = strdup(host))) DLOG_ERR("strdup(host): out of memory\n"); } } dp = dp_find(¶ms.desync_profiles, IPPROTO_UDP, (struct sockaddr *)&dst, hostname, ctrack ? ctrack->l7proto : UNKNOWN, ssid, NULL, NULL, NULL); dp = dp_find(¶ms.desync_profiles, IPPROTO_UDP, (struct sockaddr *)&dst, hostname, hostname_is_ip, ctrack ? ctrack->l7proto : UNKNOWN, ssid, NULL, NULL, NULL); if (ctrack) { ctrack->dp = dp; Loading Loading @@ -2503,7 +2513,7 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint if (dis->len_payload) { struct blob_collection_head *fake; bool bHaveHost=false; bool bHaveHost=false, bHostIsIp=false; uint16_t ip_id; if (IsQUICInitial(dis->data_payload,dis->len_payload)) Loading Loading @@ -2594,7 +2604,9 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint if (bIsHello) { bHaveHost = TLSHelloExtractHostFromHandshake(defrag + hello_offset, hello_len, host, sizeof(host), TLS_PARTIALS_ENABLE); if (!bHaveHost && dp->desync_skip_nosni) if (bHaveHost) bHostIsIp=strip_host_to_ip(host); else if (dp->desync_skip_nosni) { reasm_orig_cancel(ctrack); DLOG("not applying tampering to QUIC ClientHello without hostname in the SNI\n"); Loading Loading @@ -2711,12 +2723,13 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint ctrack_replay->hostname_discovered=true; free(ctrack_replay->hostname); ctrack_replay->hostname=strdup(host); ctrack_replay->hostname_is_ip = bHostIsIp; if (!ctrack_replay->hostname) { DLOG_ERR("hostname dup : out of memory"); goto send_orig; } if (!ipcache_put_hostname(dis->ip ? &dis->ip->ip_dst : NULL,dis->ip6 ? &dis->ip6->ip6_dst : NULL , host)) if (!ipcache_put_hostname(dis->ip ? &dis->ip->ip_dst : NULL,dis->ip6 ? &dis->ip6->ip6_dst : NULL , host, bHostIsIp)) goto send_orig; } } Loading @@ -2728,6 +2741,7 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint dp = dp_find(¶ms.desync_profiles, IPPROTO_UDP, (struct sockaddr *)&dst, ctrack_replay ? ctrack_replay->hostname : bHaveHost ? host : NULL, ctrack_replay ? ctrack_replay->hostname_is_ip : bHostIsIp, ctrack_replay ? ctrack_replay->l7proto : l7proto, ssid, &bCheckDone, &bCheckResult, &bCheckExcluded); if (ctrack_replay) Loading Loading @@ -2772,7 +2786,7 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint if (bHaveHost && !PROFILE_HOSTLISTS_EMPTY(dp)) { if (!bCheckDone) bCheckResult = HostlistCheck(dp, host, &bCheckExcluded, false); bCheckResult = HostlistCheck(dp, host, bHostIsIp, &bCheckExcluded, false); if (bCheckResult) ctrack_stop_retrans_counter(ctrack_replay); else Loading nfq/helpers.c +53 −0 Original line number Diff line number Diff line Loading @@ -124,6 +124,59 @@ void expand_bits(void *target, const void *source, unsigned int source_bitlen, u if ((bitlen &= 7)) ((uint8_t*)target)[bytelen] = ((uint8_t*)source)[bytelen] & (~((1 << (8-bitlen)) - 1)); } // " [fd00::1]" // "[fd00::1]:8000" // "127.0.0.1" // " 127.0.0.1:8000" bool strip_host_to_ip(char *host) { size_t l; char *h,*p; uint8_t addr[16]; for (h = host ; *h==' ' || *h=='\t' ; h++); l = strlen(h); if (l>=2) { if (*h=='[') { // ipv6 ? for (p=++h ; *p && *p!=']' ; p++); if (*p==']') { l = p-h; memmove(host,h,l); host[l]=0; return inet_pton(AF_INET6, host, addr)>0; } } else { if (inet_pton(AF_INET6, h, addr)>0) { // ipv6 ? if (host!=h) { l = strlen(h); memmove(host,h,l); host[l]=0; } return true; } else { // ipv4 ? for (p=h ; *p && *p!=':' ; p++); l = p-h; if (host!=h) memmove(host,h,l); host[l]=0; return inet_pton(AF_INET, host, addr)>0; } } } return false; } void ntop46(const struct sockaddr *sa, char *str, size_t len) { if (!len) return; Loading nfq/helpers.h +2 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,8 @@ bool append_to_list_file(const char *filename, const char *s); void expand_bits(void *target, const void *source, unsigned int source_bitlen, unsigned int target_bytelen); bool strip_host_to_ip(char *host); void print_sockaddr(const struct sockaddr *sa); void ntop46(const struct sockaddr *sa, char *str, size_t len); void ntop46_port(const struct sockaddr *sa, char *str, size_t len); Loading Loading
nfq/conntrack.c +1 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ void ConntrackClearHostname(t_ctrack *track) { free(track->hostname); track->hostname = NULL; track->hostname_is_ip = false; } static void ConntrackClearTrack(t_ctrack *track) { Loading
nfq/conntrack.h +1 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,7 @@ typedef struct t_l7proto l7proto; bool l7proto_discovered; char *hostname; bool hostname_is_ip; bool hostname_discovered; bool hostname_ah_check; // should perform autohostlist checks Loading
nfq/desync.c +41 −27 Original line number Diff line number Diff line Loading @@ -223,7 +223,7 @@ enum dpi_desync_mode desync_mode_from_string(const char *s) static bool dp_match( struct desync_profile *dp, uint8_t l3proto, const struct sockaddr *dest, const char *hostname, t_l7proto l7proto, const char *ssid, uint8_t l3proto, const struct sockaddr *dest, const char *hostname, bool bNoSubdom, t_l7proto l7proto, const char *ssid, bool *bCheckDone, bool *bCheckResult, bool *bExcluded) { bool bHostlistsEmpty; Loading Loading @@ -267,7 +267,7 @@ static bool dp_match( { if (bCheckDone) *bCheckDone = true; bool b; b = HostlistCheck(dp, hostname, bExcluded, true); b = HostlistCheck(dp, hostname, bNoSubdom, bExcluded, true); if (bCheckResult) *bCheckResult = b; return b; } Loading @@ -276,7 +276,7 @@ static bool dp_match( } static struct desync_profile *dp_find( struct desync_profile_list_head *head, uint8_t l3proto, const struct sockaddr *dest, const char *hostname, t_l7proto l7proto, const char *ssid, uint8_t l3proto, const struct sockaddr *dest, const char *hostname, bool bNoSubdom, t_l7proto l7proto, const char *ssid, bool *bCheckDone, bool *bCheckResult, bool *bExcluded) { struct desync_profile_list *dpl; Loading @@ -289,7 +289,7 @@ static struct desync_profile *dp_find( if (bCheckDone) *bCheckDone = false; LIST_FOREACH(dpl, head, next) { if (dp_match(&dpl->dp,l3proto,dest,hostname,l7proto,ssid,bCheckDone,bCheckResult,bExcluded)) if (dp_match(&dpl->dp,l3proto,dest,hostname,bNoSubdom,l7proto,ssid,bCheckDone,bCheckResult,bExcluded)) { DLOG("desync profile %d matches\n",dpl->dp.n); return &dpl->dp; Loading Loading @@ -418,7 +418,7 @@ static bool auto_hostlist_retrans(t_ctrack *ctrack, uint8_t l4proto, int thresho } return false; } static void auto_hostlist_failed(struct desync_profile *dp, const char *hostname, const char *client_ip_port, t_l7proto l7proto) static void auto_hostlist_failed(struct desync_profile *dp, const char *hostname, bool bNoSubdom, const char *client_ip_port, t_l7proto l7proto) { hostfail_pool *fail_counter; Loading @@ -442,7 +442,7 @@ static void auto_hostlist_failed(struct desync_profile *dp, const char *hostname DLOG("auto hostlist (profile %d) : rechecking %s to avoid duplicates\n", dp->n, hostname); bool bExcluded=false; if (!HostlistCheck(dp, hostname, &bExcluded, false) && !bExcluded) if (!HostlistCheck(dp, hostname, bNoSubdom, &bExcluded, false) && !bExcluded) { DLOG("auto hostlist (profile %d) : adding %s to %s\n", dp->n, hostname, dp->hostlist_auto->filename); HOSTLIST_DEBUGLOG_APPEND("%s : profile %d : client %s : proto %s : adding to %s", hostname, dp->n, client_ip_port, l7proto_str(l7proto), dp->hostlist_auto->filename); Loading Loading @@ -477,7 +477,7 @@ static void process_retrans_fail(t_ctrack *ctrack, uint8_t proto, const struct s if (ctrack && ctrack->dp && ctrack->hostname && auto_hostlist_retrans(ctrack, proto, ctrack->dp->hostlist_auto_retrans_threshold, client_ip_port, ctrack->l7proto)) { HOSTLIST_DEBUGLOG_APPEND("%s : profile %d : client %s : proto %s : retrans threshold reached", ctrack->hostname, ctrack->dp->n, client_ip_port, l7proto_str(ctrack->l7proto)); auto_hostlist_failed(ctrack->dp, ctrack->hostname, client_ip_port, ctrack->l7proto); auto_hostlist_failed(ctrack->dp, ctrack->hostname, ctrack->hostname_is_ip, client_ip_port, ctrack->l7proto); } } Loading Loading @@ -783,7 +783,7 @@ static void autottl_rediscover(t_ctrack *ctrack, const struct in_addr *a4, const } } static bool ipcache_put_hostname(const struct in_addr *a4, const struct in6_addr *a6, const char *hostname) static bool ipcache_put_hostname(const struct in_addr *a4, const struct in6_addr *a6, const char *hostname, bool hostname_is_ip) { if (!params.cache_hostname) return true; Loading @@ -801,11 +801,12 @@ static bool ipcache_put_hostname(const struct in_addr *a4, const struct in6_addr DLOG_ERR("ipcache_put_hostname: out of memory\n"); return false; } DLOG("hostname cached: %s\n", hostname); ipc->hostname_is_ip = hostname_is_ip; DLOG("hostname cached (is_ip=%u): %s\n", hostname_is_ip, hostname); } return true; } static bool ipcache_get_hostname(const struct in_addr *a4, const struct in6_addr *a6, char *hostname, size_t hostname_buf_len) static bool ipcache_get_hostname(const struct in_addr *a4, const struct in6_addr *a6, char *hostname, size_t hostname_buf_len, bool *hostname_is_ip) { if (!params.cache_hostname) { Loading @@ -820,8 +821,9 @@ static bool ipcache_get_hostname(const struct in_addr *a4, const struct in6_addr } if (ipc->hostname) { DLOG("got cached hostname: %s\n", ipc->hostname); DLOG("got cached hostname (is_ip=%u): %s\n", ipc->hostname_is_ip, ipc->hostname); snprintf(hostname,hostname_buf_len,"%s",ipc->hostname); if (hostname_is_ip) *hostname_is_ip = ipc->hostname_is_ip; } else *hostname = 0; Loading Loading @@ -1140,11 +1142,11 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint { if (!ctrack_replay->hostname && !bReverse) { if (ipcache_get_hostname(dis->ip ? &dis->ip->ip_dst : NULL,dis->ip6 ? &dis->ip6->ip6_dst : NULL , host, sizeof(host)) && *host) if (ipcache_get_hostname(dis->ip ? &dis->ip->ip_dst : NULL,dis->ip6 ? &dis->ip6->ip6_dst : NULL , host, sizeof(host), &ctrack_replay->hostname_is_ip) && *host) if (!(ctrack_replay->hostname = strdup(host))) DLOG_ERR("strdup(host): out of memory\n"); } dp = ctrack_replay->dp = dp_find(¶ms.desync_profiles, IPPROTO_TCP, (struct sockaddr *)&dst, ctrack_replay->hostname, ctrack_replay->l7proto, ssid, NULL, NULL, NULL); dp = ctrack_replay->dp = dp_find(¶ms.desync_profiles, IPPROTO_TCP, (struct sockaddr *)&dst, ctrack_replay->hostname, ctrack_replay->hostname_is_ip, ctrack_replay->l7proto, ssid, NULL, NULL, NULL); ctrack_replay->dp_search_complete = true; } if (!dp) Loading Loading @@ -1176,17 +1178,19 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint else if (!ctrack || !ctrack->dp_search_complete) { const char *hostname = NULL; bool hostname_is_ip = false; if (ctrack) { hostname = ctrack->hostname; hostname_is_ip = ctrack->hostname_is_ip; if (!hostname && !bReverse) { if (ipcache_get_hostname(dis->ip ? &dis->ip->ip_dst : NULL,dis->ip6 ? &dis->ip6->ip6_dst : NULL , host, sizeof(host)) && *host) if (ipcache_get_hostname(dis->ip ? &dis->ip->ip_dst : NULL,dis->ip6 ? &dis->ip6->ip6_dst : NULL , host, sizeof(host), &hostname_is_ip) && *host) if (!(hostname = ctrack_replay->hostname = strdup(host))) DLOG_ERR("strdup(host): out of memory\n"); } } dp = dp_find(¶ms.desync_profiles, IPPROTO_TCP, (struct sockaddr *)&dst, hostname, ctrack ? ctrack->l7proto : UNKNOWN, ssid, NULL, NULL, NULL); dp = dp_find(¶ms.desync_profiles, IPPROTO_TCP, (struct sockaddr *)&dst, hostname, hostname_is_ip, ctrack ? ctrack->l7proto : UNKNOWN, ssid, NULL, NULL, NULL); if (ctrack) { ctrack->dp = dp; Loading Loading @@ -1268,7 +1272,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint } } if (bFail) auto_hostlist_failed(dp, ctrack->hostname, client_ip_port, ctrack->l7proto); auto_hostlist_failed(dp, ctrack->hostname, ctrack->hostname_is_ip, client_ip_port, ctrack->l7proto); else if (dis->len_payload) auto_hostlist_reset_fail_counter(dp, ctrack->hostname, client_ip_port, ctrack->l7proto); Loading Loading @@ -1426,7 +1430,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint int multisplit_count; int i; uint16_t ip_id; bool bHaveHost=false; bool bHaveHost=false, bHostIsIp=false; t_l7proto l7proto = UNKNOWN; if (replay) Loading Loading @@ -1458,6 +1462,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint DLOG("not applying tampering to HTTP without Host:\n"); goto send_orig; } bHostIsIp=strip_host_to_ip(host); if (ctrack) { // we do not reassemble http Loading @@ -1479,6 +1484,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint if (bReqFull) TLSDebug(rdata_payload,rlen_payload); bHaveHost=TLSHelloExtractHost(rdata_payload,rlen_payload,host,sizeof(host),TLS_PARTIALS_ENABLE); if (bHaveHost) bHostIsIp=strip_host_to_ip(host); if (ctrack) { Loading Loading @@ -1567,6 +1573,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint { free(ctrack_replay->hostname); ctrack_replay->hostname=strdup(host); ctrack_replay->hostname_is_ip=bHostIsIp; if (!ctrack_replay->hostname) { DLOG_ERR("hostname dup : out of memory"); Loading @@ -1574,7 +1581,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint goto send_orig; } ctrack_replay->hostname_discovered=true; if (!ipcache_put_hostname(dis->ip ? &dis->ip->ip_dst : NULL,dis->ip6 ? &dis->ip6->ip6_dst : NULL , host)) if (!ipcache_put_hostname(dis->ip ? &dis->ip->ip_dst : NULL,dis->ip6 ? &dis->ip6->ip6_dst : NULL , host, bHostIsIp)) { reasm_orig_cancel(ctrack); goto send_orig; Loading @@ -1590,6 +1597,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint dp = dp_find(¶ms.desync_profiles, IPPROTO_TCP, (struct sockaddr *)&dst, ctrack_replay ? ctrack_replay->hostname : bHaveHost ? host : NULL, ctrack_replay ? ctrack_replay->hostname_is_ip : bHostIsIp, ctrack_replay ? ctrack_replay->l7proto : l7proto, ssid, &bCheckDone, &bCheckResult, &bCheckExcluded); if (ctrack_replay) Loading Loading @@ -1638,7 +1646,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint if (bHaveHost && !PROFILE_HOSTLISTS_EMPTY(dp)) { if (!bCheckDone) bCheckResult = HostlistCheck(dp, host, &bCheckExcluded, false); bCheckResult = HostlistCheck(dp, host, bHostIsIp, &bCheckExcluded, false); if (bCheckResult) ctrack_stop_retrans_counter(ctrack_replay); else Loading Loading @@ -2409,11 +2417,11 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint { if (!ctrack_replay->hostname && !bReverse) { if (ipcache_get_hostname(dis->ip ? &dis->ip->ip_dst : NULL,dis->ip6 ? &dis->ip6->ip6_dst : NULL , host, sizeof(host)) && *host) if (ipcache_get_hostname(dis->ip ? &dis->ip->ip_dst : NULL,dis->ip6 ? &dis->ip6->ip6_dst : NULL , host, sizeof(host), &ctrack_replay->hostname_is_ip) && *host) if (!(ctrack_replay->hostname = strdup(host))) DLOG_ERR("strdup(host): out of memory\n"); } dp = ctrack_replay->dp = dp_find(¶ms.desync_profiles, IPPROTO_UDP, (struct sockaddr *)&dst, ctrack_replay->hostname, ctrack_replay->l7proto, ssid, NULL, NULL, NULL); dp = ctrack_replay->dp = dp_find(¶ms.desync_profiles, IPPROTO_UDP, (struct sockaddr *)&dst, ctrack_replay->hostname, ctrack_replay->hostname_is_ip, ctrack_replay->l7proto, ssid, NULL, NULL, NULL); ctrack_replay->dp_search_complete = true; } if (!dp) Loading Loading @@ -2445,17 +2453,19 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint else if (!ctrack || !ctrack->dp_search_complete) { const char *hostname = NULL; bool hostname_is_ip = false; if (ctrack) { hostname = ctrack->hostname; hostname_is_ip = ctrack->hostname_is_ip; if (!hostname && !bReverse) { if (ipcache_get_hostname(dis->ip ? &dis->ip->ip_dst : NULL,dis->ip6 ? &dis->ip6->ip6_dst : NULL , host, sizeof(host)) && *host) if (ipcache_get_hostname(dis->ip ? &dis->ip->ip_dst : NULL,dis->ip6 ? &dis->ip6->ip6_dst : NULL , host, sizeof(host), &hostname_is_ip) && *host) if (!(hostname = ctrack_replay->hostname = strdup(host))) DLOG_ERR("strdup(host): out of memory\n"); } } dp = dp_find(¶ms.desync_profiles, IPPROTO_UDP, (struct sockaddr *)&dst, hostname, ctrack ? ctrack->l7proto : UNKNOWN, ssid, NULL, NULL, NULL); dp = dp_find(¶ms.desync_profiles, IPPROTO_UDP, (struct sockaddr *)&dst, hostname, hostname_is_ip, ctrack ? ctrack->l7proto : UNKNOWN, ssid, NULL, NULL, NULL); if (ctrack) { ctrack->dp = dp; Loading Loading @@ -2503,7 +2513,7 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint if (dis->len_payload) { struct blob_collection_head *fake; bool bHaveHost=false; bool bHaveHost=false, bHostIsIp=false; uint16_t ip_id; if (IsQUICInitial(dis->data_payload,dis->len_payload)) Loading Loading @@ -2594,7 +2604,9 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint if (bIsHello) { bHaveHost = TLSHelloExtractHostFromHandshake(defrag + hello_offset, hello_len, host, sizeof(host), TLS_PARTIALS_ENABLE); if (!bHaveHost && dp->desync_skip_nosni) if (bHaveHost) bHostIsIp=strip_host_to_ip(host); else if (dp->desync_skip_nosni) { reasm_orig_cancel(ctrack); DLOG("not applying tampering to QUIC ClientHello without hostname in the SNI\n"); Loading Loading @@ -2711,12 +2723,13 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint ctrack_replay->hostname_discovered=true; free(ctrack_replay->hostname); ctrack_replay->hostname=strdup(host); ctrack_replay->hostname_is_ip = bHostIsIp; if (!ctrack_replay->hostname) { DLOG_ERR("hostname dup : out of memory"); goto send_orig; } if (!ipcache_put_hostname(dis->ip ? &dis->ip->ip_dst : NULL,dis->ip6 ? &dis->ip6->ip6_dst : NULL , host)) if (!ipcache_put_hostname(dis->ip ? &dis->ip->ip_dst : NULL,dis->ip6 ? &dis->ip6->ip6_dst : NULL , host, bHostIsIp)) goto send_orig; } } Loading @@ -2728,6 +2741,7 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint dp = dp_find(¶ms.desync_profiles, IPPROTO_UDP, (struct sockaddr *)&dst, ctrack_replay ? ctrack_replay->hostname : bHaveHost ? host : NULL, ctrack_replay ? ctrack_replay->hostname_is_ip : bHostIsIp, ctrack_replay ? ctrack_replay->l7proto : l7proto, ssid, &bCheckDone, &bCheckResult, &bCheckExcluded); if (ctrack_replay) Loading Loading @@ -2772,7 +2786,7 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint if (bHaveHost && !PROFILE_HOSTLISTS_EMPTY(dp)) { if (!bCheckDone) bCheckResult = HostlistCheck(dp, host, &bCheckExcluded, false); bCheckResult = HostlistCheck(dp, host, bHostIsIp, &bCheckExcluded, false); if (bCheckResult) ctrack_stop_retrans_counter(ctrack_replay); else Loading
nfq/helpers.c +53 −0 Original line number Diff line number Diff line Loading @@ -124,6 +124,59 @@ void expand_bits(void *target, const void *source, unsigned int source_bitlen, u if ((bitlen &= 7)) ((uint8_t*)target)[bytelen] = ((uint8_t*)source)[bytelen] & (~((1 << (8-bitlen)) - 1)); } // " [fd00::1]" // "[fd00::1]:8000" // "127.0.0.1" // " 127.0.0.1:8000" bool strip_host_to_ip(char *host) { size_t l; char *h,*p; uint8_t addr[16]; for (h = host ; *h==' ' || *h=='\t' ; h++); l = strlen(h); if (l>=2) { if (*h=='[') { // ipv6 ? for (p=++h ; *p && *p!=']' ; p++); if (*p==']') { l = p-h; memmove(host,h,l); host[l]=0; return inet_pton(AF_INET6, host, addr)>0; } } else { if (inet_pton(AF_INET6, h, addr)>0) { // ipv6 ? if (host!=h) { l = strlen(h); memmove(host,h,l); host[l]=0; } return true; } else { // ipv4 ? for (p=h ; *p && *p!=':' ; p++); l = p-h; if (host!=h) memmove(host,h,l); host[l]=0; return inet_pton(AF_INET, host, addr)>0; } } } return false; } void ntop46(const struct sockaddr *sa, char *str, size_t len) { if (!len) return; Loading
nfq/helpers.h +2 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,8 @@ bool append_to_list_file(const char *filename, const char *s); void expand_bits(void *target, const void *source, unsigned int source_bitlen, unsigned int target_bytelen); bool strip_host_to_ip(char *host); void print_sockaddr(const struct sockaddr *sa); void ntop46(const struct sockaddr *sa, char *str, size_t len); void ntop46_port(const struct sockaddr *sa, char *str, size_t len); Loading