mirror of
https://github.com/bol-van/zapret.git
synced 2025-08-10 01:02:03 +03:00
nfqws: special case for ip looking hostnames
This commit is contained in:
@@ -29,6 +29,7 @@ void ConntrackClearHostname(t_ctrack *track)
|
|||||||
{
|
{
|
||||||
free(track->hostname);
|
free(track->hostname);
|
||||||
track->hostname = NULL;
|
track->hostname = NULL;
|
||||||
|
track->hostname_is_ip = false;
|
||||||
}
|
}
|
||||||
static void ConntrackClearTrack(t_ctrack *track)
|
static void ConntrackClearTrack(t_ctrack *track)
|
||||||
{
|
{
|
||||||
|
@@ -86,6 +86,7 @@ typedef struct
|
|||||||
t_l7proto l7proto;
|
t_l7proto l7proto;
|
||||||
bool l7proto_discovered;
|
bool l7proto_discovered;
|
||||||
char *hostname;
|
char *hostname;
|
||||||
|
bool hostname_is_ip;
|
||||||
bool hostname_discovered;
|
bool hostname_discovered;
|
||||||
bool hostname_ah_check; // should perform autohostlist checks
|
bool hostname_ah_check; // should perform autohostlist checks
|
||||||
|
|
||||||
|
68
nfq/desync.c
68
nfq/desync.c
@@ -223,7 +223,7 @@ enum dpi_desync_mode desync_mode_from_string(const char *s)
|
|||||||
|
|
||||||
static bool dp_match(
|
static bool dp_match(
|
||||||
struct desync_profile *dp,
|
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 *bCheckDone, bool *bCheckResult, bool *bExcluded)
|
||||||
{
|
{
|
||||||
bool bHostlistsEmpty;
|
bool bHostlistsEmpty;
|
||||||
@@ -267,7 +267,7 @@ static bool dp_match(
|
|||||||
{
|
{
|
||||||
if (bCheckDone) *bCheckDone = true;
|
if (bCheckDone) *bCheckDone = true;
|
||||||
bool b;
|
bool b;
|
||||||
b = HostlistCheck(dp, hostname, bExcluded, true);
|
b = HostlistCheck(dp, hostname, bNoSubdom, bExcluded, true);
|
||||||
if (bCheckResult) *bCheckResult = b;
|
if (bCheckResult) *bCheckResult = b;
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
@@ -276,7 +276,7 @@ static bool dp_match(
|
|||||||
}
|
}
|
||||||
static struct desync_profile *dp_find(
|
static struct desync_profile *dp_find(
|
||||||
struct desync_profile_list_head *head,
|
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)
|
bool *bCheckDone, bool *bCheckResult, bool *bExcluded)
|
||||||
{
|
{
|
||||||
struct desync_profile_list *dpl;
|
struct desync_profile_list *dpl;
|
||||||
@@ -289,7 +289,7 @@ static struct desync_profile *dp_find(
|
|||||||
if (bCheckDone) *bCheckDone = false;
|
if (bCheckDone) *bCheckDone = false;
|
||||||
LIST_FOREACH(dpl, head, next)
|
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);
|
DLOG("desync profile %d matches\n",dpl->dp.n);
|
||||||
return &dpl->dp;
|
return &dpl->dp;
|
||||||
@@ -418,7 +418,7 @@ static bool auto_hostlist_retrans(t_ctrack *ctrack, uint8_t l4proto, int thresho
|
|||||||
}
|
}
|
||||||
return false;
|
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;
|
hostfail_pool *fail_counter;
|
||||||
|
|
||||||
@@ -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);
|
DLOG("auto hostlist (profile %d) : rechecking %s to avoid duplicates\n", dp->n, hostname);
|
||||||
bool bExcluded=false;
|
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);
|
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);
|
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);
|
||||||
@@ -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))
|
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));
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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;
|
if (!params.cache_hostname) return true;
|
||||||
|
|
||||||
@@ -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");
|
DLOG_ERR("ipcache_put_hostname: out of memory\n");
|
||||||
return false;
|
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;
|
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)
|
if (!params.cache_hostname)
|
||||||
{
|
{
|
||||||
@@ -820,8 +821,9 @@ static bool ipcache_get_hostname(const struct in_addr *a4, const struct in6_addr
|
|||||||
}
|
}
|
||||||
if (ipc->hostname)
|
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);
|
snprintf(hostname,hostname_buf_len,"%s",ipc->hostname);
|
||||||
|
if (hostname_is_ip) *hostname_is_ip = ipc->hostname_is_ip;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
*hostname = 0;
|
*hostname = 0;
|
||||||
@@ -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 (!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)))
|
if (!(ctrack_replay->hostname = strdup(host)))
|
||||||
DLOG_ERR("strdup(host): out of memory\n");
|
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;
|
ctrack_replay->dp_search_complete = true;
|
||||||
}
|
}
|
||||||
if (!dp)
|
if (!dp)
|
||||||
@@ -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)
|
else if (!ctrack || !ctrack->dp_search_complete)
|
||||||
{
|
{
|
||||||
const char *hostname = NULL;
|
const char *hostname = NULL;
|
||||||
|
bool hostname_is_ip = false;
|
||||||
if (ctrack)
|
if (ctrack)
|
||||||
{
|
{
|
||||||
hostname = ctrack->hostname;
|
hostname = ctrack->hostname;
|
||||||
|
hostname_is_ip = ctrack->hostname_is_ip;
|
||||||
if (!hostname && !bReverse)
|
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)))
|
if (!(hostname = ctrack_replay->hostname = strdup(host)))
|
||||||
DLOG_ERR("strdup(host): out of memory\n");
|
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)
|
if (ctrack)
|
||||||
{
|
{
|
||||||
ctrack->dp = dp;
|
ctrack->dp = dp;
|
||||||
@@ -1268,7 +1272,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bFail)
|
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
|
else
|
||||||
if (dis->len_payload)
|
if (dis->len_payload)
|
||||||
auto_hostlist_reset_fail_counter(dp, ctrack->hostname, client_ip_port, ctrack->l7proto);
|
auto_hostlist_reset_fail_counter(dp, ctrack->hostname, client_ip_port, ctrack->l7proto);
|
||||||
@@ -1426,7 +1430,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
int multisplit_count;
|
int multisplit_count;
|
||||||
int i;
|
int i;
|
||||||
uint16_t ip_id;
|
uint16_t ip_id;
|
||||||
bool bHaveHost=false;
|
bool bHaveHost=false, bHostIsIp=false;
|
||||||
t_l7proto l7proto = UNKNOWN;
|
t_l7proto l7proto = UNKNOWN;
|
||||||
|
|
||||||
if (replay)
|
if (replay)
|
||||||
@@ -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");
|
DLOG("not applying tampering to HTTP without Host:\n");
|
||||||
goto send_orig;
|
goto send_orig;
|
||||||
}
|
}
|
||||||
|
bHostIsIp=strip_host_to_ip(host);
|
||||||
if (ctrack)
|
if (ctrack)
|
||||||
{
|
{
|
||||||
// we do not reassemble http
|
// we do not reassemble http
|
||||||
@@ -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);
|
if (bReqFull) TLSDebug(rdata_payload,rlen_payload);
|
||||||
|
|
||||||
bHaveHost=TLSHelloExtractHost(rdata_payload,rlen_payload,host,sizeof(host),TLS_PARTIALS_ENABLE);
|
bHaveHost=TLSHelloExtractHost(rdata_payload,rlen_payload,host,sizeof(host),TLS_PARTIALS_ENABLE);
|
||||||
|
if (bHaveHost) bHostIsIp=strip_host_to_ip(host);
|
||||||
|
|
||||||
if (ctrack)
|
if (ctrack)
|
||||||
{
|
{
|
||||||
@@ -1567,6 +1573,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
{
|
{
|
||||||
free(ctrack_replay->hostname);
|
free(ctrack_replay->hostname);
|
||||||
ctrack_replay->hostname=strdup(host);
|
ctrack_replay->hostname=strdup(host);
|
||||||
|
ctrack_replay->hostname_is_ip=bHostIsIp;
|
||||||
if (!ctrack_replay->hostname)
|
if (!ctrack_replay->hostname)
|
||||||
{
|
{
|
||||||
DLOG_ERR("hostname dup : out of memory");
|
DLOG_ERR("hostname dup : out of memory");
|
||||||
@@ -1574,7 +1581,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
goto send_orig;
|
goto send_orig;
|
||||||
}
|
}
|
||||||
ctrack_replay->hostname_discovered=true;
|
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);
|
reasm_orig_cancel(ctrack);
|
||||||
goto send_orig;
|
goto send_orig;
|
||||||
@@ -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,
|
dp = dp_find(¶ms.desync_profiles, IPPROTO_TCP, (struct sockaddr *)&dst,
|
||||||
ctrack_replay ? ctrack_replay->hostname : bHaveHost ? host : NULL,
|
ctrack_replay ? ctrack_replay->hostname : bHaveHost ? host : NULL,
|
||||||
|
ctrack_replay ? ctrack_replay->hostname_is_ip : bHostIsIp,
|
||||||
ctrack_replay ? ctrack_replay->l7proto : l7proto, ssid,
|
ctrack_replay ? ctrack_replay->l7proto : l7proto, ssid,
|
||||||
&bCheckDone, &bCheckResult, &bCheckExcluded);
|
&bCheckDone, &bCheckResult, &bCheckExcluded);
|
||||||
if (ctrack_replay)
|
if (ctrack_replay)
|
||||||
@@ -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 (bHaveHost && !PROFILE_HOSTLISTS_EMPTY(dp))
|
||||||
{
|
{
|
||||||
if (!bCheckDone)
|
if (!bCheckDone)
|
||||||
bCheckResult = HostlistCheck(dp, host, &bCheckExcluded, false);
|
bCheckResult = HostlistCheck(dp, host, bHostIsIp, &bCheckExcluded, false);
|
||||||
if (bCheckResult)
|
if (bCheckResult)
|
||||||
ctrack_stop_retrans_counter(ctrack_replay);
|
ctrack_stop_retrans_counter(ctrack_replay);
|
||||||
else
|
else
|
||||||
@@ -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 (!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)))
|
if (!(ctrack_replay->hostname = strdup(host)))
|
||||||
DLOG_ERR("strdup(host): out of memory\n");
|
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;
|
ctrack_replay->dp_search_complete = true;
|
||||||
}
|
}
|
||||||
if (!dp)
|
if (!dp)
|
||||||
@@ -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)
|
else if (!ctrack || !ctrack->dp_search_complete)
|
||||||
{
|
{
|
||||||
const char *hostname = NULL;
|
const char *hostname = NULL;
|
||||||
|
bool hostname_is_ip = false;
|
||||||
if (ctrack)
|
if (ctrack)
|
||||||
{
|
{
|
||||||
hostname = ctrack->hostname;
|
hostname = ctrack->hostname;
|
||||||
|
hostname_is_ip = ctrack->hostname_is_ip;
|
||||||
if (!hostname && !bReverse)
|
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)))
|
if (!(hostname = ctrack_replay->hostname = strdup(host)))
|
||||||
DLOG_ERR("strdup(host): out of memory\n");
|
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)
|
if (ctrack)
|
||||||
{
|
{
|
||||||
ctrack->dp = dp;
|
ctrack->dp = dp;
|
||||||
@@ -2503,7 +2513,7 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
if (dis->len_payload)
|
if (dis->len_payload)
|
||||||
{
|
{
|
||||||
struct blob_collection_head *fake;
|
struct blob_collection_head *fake;
|
||||||
bool bHaveHost=false;
|
bool bHaveHost=false, bHostIsIp=false;
|
||||||
uint16_t ip_id;
|
uint16_t ip_id;
|
||||||
|
|
||||||
if (IsQUICInitial(dis->data_payload,dis->len_payload))
|
if (IsQUICInitial(dis->data_payload,dis->len_payload))
|
||||||
@@ -2594,7 +2604,9 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
if (bIsHello)
|
if (bIsHello)
|
||||||
{
|
{
|
||||||
bHaveHost = TLSHelloExtractHostFromHandshake(defrag + hello_offset, hello_len, host, sizeof(host), TLS_PARTIALS_ENABLE);
|
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);
|
reasm_orig_cancel(ctrack);
|
||||||
DLOG("not applying tampering to QUIC ClientHello without hostname in the SNI\n");
|
DLOG("not applying tampering to QUIC ClientHello without hostname in the SNI\n");
|
||||||
@@ -2711,12 +2723,13 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
ctrack_replay->hostname_discovered=true;
|
ctrack_replay->hostname_discovered=true;
|
||||||
free(ctrack_replay->hostname);
|
free(ctrack_replay->hostname);
|
||||||
ctrack_replay->hostname=strdup(host);
|
ctrack_replay->hostname=strdup(host);
|
||||||
|
ctrack_replay->hostname_is_ip = bHostIsIp;
|
||||||
if (!ctrack_replay->hostname)
|
if (!ctrack_replay->hostname)
|
||||||
{
|
{
|
||||||
DLOG_ERR("hostname dup : out of memory");
|
DLOG_ERR("hostname dup : out of memory");
|
||||||
goto send_orig;
|
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;
|
goto send_orig;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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,
|
dp = dp_find(¶ms.desync_profiles, IPPROTO_UDP, (struct sockaddr *)&dst,
|
||||||
ctrack_replay ? ctrack_replay->hostname : bHaveHost ? host : NULL,
|
ctrack_replay ? ctrack_replay->hostname : bHaveHost ? host : NULL,
|
||||||
|
ctrack_replay ? ctrack_replay->hostname_is_ip : bHostIsIp,
|
||||||
ctrack_replay ? ctrack_replay->l7proto : l7proto, ssid,
|
ctrack_replay ? ctrack_replay->l7proto : l7proto, ssid,
|
||||||
&bCheckDone, &bCheckResult, &bCheckExcluded);
|
&bCheckDone, &bCheckResult, &bCheckExcluded);
|
||||||
if (ctrack_replay)
|
if (ctrack_replay)
|
||||||
@@ -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 (bHaveHost && !PROFILE_HOSTLISTS_EMPTY(dp))
|
||||||
{
|
{
|
||||||
if (!bCheckDone)
|
if (!bCheckDone)
|
||||||
bCheckResult = HostlistCheck(dp, host, &bCheckExcluded, false);
|
bCheckResult = HostlistCheck(dp, host, bHostIsIp, &bCheckExcluded, false);
|
||||||
if (bCheckResult)
|
if (bCheckResult)
|
||||||
ctrack_stop_retrans_counter(ctrack_replay);
|
ctrack_stop_retrans_counter(ctrack_replay);
|
||||||
else
|
else
|
||||||
|
@@ -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));
|
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)
|
void ntop46(const struct sockaddr *sa, char *str, size_t len)
|
||||||
{
|
{
|
||||||
if (!len) return;
|
if (!len) return;
|
||||||
|
@@ -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);
|
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 print_sockaddr(const struct sockaddr *sa);
|
||||||
void ntop46(const struct sockaddr *sa, char *str, size_t len);
|
void ntop46(const struct sockaddr *sa, char *str, size_t len);
|
||||||
void ntop46_port(const struct sockaddr *sa, char *str, size_t len);
|
void ntop46_port(const struct sockaddr *sa, char *str, size_t len);
|
||||||
|
@@ -170,7 +170,7 @@ bool LoadAllHostLists()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static bool SearchHostList(hostlist_pool *hostlist, const char *host)
|
static bool SearchHostList(hostlist_pool *hostlist, const char *host, bool no_match_subdomains)
|
||||||
{
|
{
|
||||||
if (hostlist)
|
if (hostlist)
|
||||||
{
|
{
|
||||||
@@ -195,6 +195,7 @@ static bool SearchHostList(hostlist_pool *hostlist, const char *host)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
DLOG("negative\n");
|
DLOG("negative\n");
|
||||||
|
if (no_match_subdomains) break;
|
||||||
p = strchr(p, '.');
|
p = strchr(p, '.');
|
||||||
if (p) p++;
|
if (p) p++;
|
||||||
bHostFull = false;
|
bHostFull = false;
|
||||||
@@ -220,7 +221,7 @@ bool HostlistsReloadCheckForProfile(const struct desync_profile *dp)
|
|||||||
return HostlistsReloadCheck(&dp->hl_collection) && HostlistsReloadCheck(&dp->hl_collection_exclude);
|
return HostlistsReloadCheck(&dp->hl_collection) && HostlistsReloadCheck(&dp->hl_collection_exclude);
|
||||||
}
|
}
|
||||||
// return : true = apply fooling, false = do not apply
|
// return : true = apply fooling, false = do not apply
|
||||||
static bool HostlistCheck_(const struct hostlist_collection_head *hostlists, const struct hostlist_collection_head *hostlists_exclude, const char *host, bool *excluded, bool bSkipReloadCheck)
|
static bool HostlistCheck_(const struct hostlist_collection_head *hostlists, const struct hostlist_collection_head *hostlists_exclude, const char *host, bool no_match_subdomains, bool *excluded, bool bSkipReloadCheck)
|
||||||
{
|
{
|
||||||
struct hostlist_item *item;
|
struct hostlist_item *item;
|
||||||
|
|
||||||
@@ -233,7 +234,7 @@ static bool HostlistCheck_(const struct hostlist_collection_head *hostlists, con
|
|||||||
LIST_FOREACH(item, hostlists_exclude, next)
|
LIST_FOREACH(item, hostlists_exclude, next)
|
||||||
{
|
{
|
||||||
DLOG("[%s] exclude ", item->hfile->filename ? item->hfile->filename : "fixed");
|
DLOG("[%s] exclude ", item->hfile->filename ? item->hfile->filename : "fixed");
|
||||||
if (SearchHostList(item->hfile->hostlist, host))
|
if (SearchHostList(item->hfile->hostlist, host, no_match_subdomains))
|
||||||
{
|
{
|
||||||
if (excluded) *excluded = true;
|
if (excluded) *excluded = true;
|
||||||
return false;
|
return false;
|
||||||
@@ -245,7 +246,7 @@ static bool HostlistCheck_(const struct hostlist_collection_head *hostlists, con
|
|||||||
LIST_FOREACH(item, hostlists, next)
|
LIST_FOREACH(item, hostlists, next)
|
||||||
{
|
{
|
||||||
DLOG("[%s] include ", item->hfile->filename ? item->hfile->filename : "fixed");
|
DLOG("[%s] include ", item->hfile->filename ? item->hfile->filename : "fixed");
|
||||||
if (SearchHostList(item->hfile->hostlist, host))
|
if (SearchHostList(item->hfile->hostlist, host, no_match_subdomains))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -255,10 +256,10 @@ static bool HostlistCheck_(const struct hostlist_collection_head *hostlists, con
|
|||||||
|
|
||||||
|
|
||||||
// return : true = apply fooling, false = do not apply
|
// return : true = apply fooling, false = do not apply
|
||||||
bool HostlistCheck(const struct desync_profile *dp, const char *host, bool *excluded, bool bSkipReloadCheck)
|
bool HostlistCheck(const struct desync_profile *dp, const char *host, bool no_match_subdomains, bool *excluded, bool bSkipReloadCheck)
|
||||||
{
|
{
|
||||||
DLOG("* hostlist check for profile %d\n",dp->n);
|
DLOG("* hostlist check for profile %d\n",dp->n);
|
||||||
return HostlistCheck_(&dp->hl_collection, &dp->hl_collection_exclude, host, excluded, bSkipReloadCheck);
|
return HostlistCheck_(&dp->hl_collection, &dp->hl_collection_exclude, host, no_match_subdomains, excluded, bSkipReloadCheck);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -9,7 +9,7 @@ bool AppendHostList(hostlist_pool **hostlist, const char *filename);
|
|||||||
bool LoadAllHostLists();
|
bool LoadAllHostLists();
|
||||||
bool NonEmptyHostlist(hostlist_pool **hostlist);
|
bool NonEmptyHostlist(hostlist_pool **hostlist);
|
||||||
// return : true = apply fooling, false = do not apply
|
// return : true = apply fooling, false = do not apply
|
||||||
bool HostlistCheck(const struct desync_profile *dp,const char *host, bool *excluded, bool bSkipReloadCheck);
|
bool HostlistCheck(const struct desync_profile *dp,const char *host, bool no_match_subdomains, bool *excluded, bool bSkipReloadCheck);
|
||||||
struct hostlist_file *RegisterHostlist(struct desync_profile *dp, bool bExclude, const char *filename);
|
struct hostlist_file *RegisterHostlist(struct desync_profile *dp, bool bExclude, const char *filename);
|
||||||
bool HostlistsReloadCheckForProfile(const struct desync_profile *dp);
|
bool HostlistsReloadCheckForProfile(const struct desync_profile *dp);
|
||||||
void HostlistsDebug();
|
void HostlistsDebug();
|
||||||
|
@@ -629,6 +629,7 @@ static void ipcache_item_init(ip_cache_item *item)
|
|||||||
{
|
{
|
||||||
ipcache_item_touch(item);
|
ipcache_item_touch(item);
|
||||||
item->hostname = NULL;
|
item->hostname = NULL;
|
||||||
|
item->hostname_is_ip = false;
|
||||||
item->hops = 0;
|
item->hops = 0;
|
||||||
}
|
}
|
||||||
static void ipcache_item_destroy(ip_cache_item *item)
|
static void ipcache_item_destroy(ip_cache_item *item)
|
||||||
@@ -690,7 +691,7 @@ static void ipcache4Print(ip_cache4 *ipcache)
|
|||||||
{
|
{
|
||||||
*s_ip=0;
|
*s_ip=0;
|
||||||
inet_ntop(AF_INET, &ipc->key.addr, s_ip, sizeof(s_ip));
|
inet_ntop(AF_INET, &ipc->key.addr, s_ip, sizeof(s_ip));
|
||||||
printf("%s iface=%s : hops %u hostname=%s now=last+%llu\n", s_ip, ipc->key.iface, ipc->data.hops, ipc->data.hostname ? ipc->data.hostname : "", (unsigned long long)(now-ipc->data.last));
|
printf("%s iface=%s : hops %u hostname=%s hostname_is_ip=%u now=last+%llu\n", s_ip, ipc->key.iface, ipc->data.hops, ipc->data.hostname ? ipc->data.hostname : "", ipc->data.hostname_is_ip, (unsigned long long)(now-ipc->data.last));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -182,6 +182,7 @@ typedef struct ip_cache_item
|
|||||||
{
|
{
|
||||||
time_t last;
|
time_t last;
|
||||||
char *hostname;
|
char *hostname;
|
||||||
|
bool hostname_is_ip;
|
||||||
uint8_t hops;
|
uint8_t hops;
|
||||||
} ip_cache_item;
|
} ip_cache_item;
|
||||||
typedef struct ip_cache4
|
typedef struct ip_cache4
|
||||||
|
Reference in New Issue
Block a user