|
|
@ -91,7 +91,7 @@ static void TLSDebug(const uint8_t *tls,size_t sz) |
|
|
|
TLSDebugHandshake(tls+5,sz-5); |
|
|
|
} |
|
|
|
|
|
|
|
bool ipcache_put_hostname(const struct in_addr *a4, const struct in6_addr *a6, const char *hostname) |
|
|
|
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; |
|
|
|
|
|
|
@ -109,11 +109,12 @@ bool ipcache_put_hostname(const struct in_addr *a4, const struct in6_addr *a6, c |
|
|
|
DLOG_ERR("ipcache_put_hostname: out of memory\n"); |
|
|
|
return false; |
|
|
|
} |
|
|
|
VPRINT("hostname cached: %s\n", hostname); |
|
|
|
ipc->hostname_is_ip = hostname_is_ip; |
|
|
|
VPRINT("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) |
|
|
|
{ |
|
|
@ -128,15 +129,16 @@ static bool ipcache_get_hostname(const struct in_addr *a4, const struct in6_addr |
|
|
|
} |
|
|
|
if (ipc->hostname) |
|
|
|
{ |
|
|
|
VPRINT("got cached hostname: %s\n", ipc->hostname); |
|
|
|
VPRINT("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; |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
static bool dp_match(struct desync_profile *dp, const struct sockaddr *dest, const char *hostname, t_l7proto l7proto) |
|
|
|
static bool dp_match(struct desync_profile *dp, const struct sockaddr *dest, const char *hostname, bool bNoSubdom, t_l7proto l7proto) |
|
|
|
{ |
|
|
|
bool bHostlistsEmpty; |
|
|
|
|
|
|
@ -167,11 +169,11 @@ static bool dp_match(struct desync_profile *dp, const struct sockaddr *dest, con |
|
|
|
return true; |
|
|
|
else if (hostname) |
|
|
|
// if hostlists are present profile matches only if hostname is known and satisfy profile hostlists
|
|
|
|
return HostlistCheck(dp, hostname, NULL, true); |
|
|
|
return HostlistCheck(dp, hostname, bNoSubdom, NULL, true); |
|
|
|
|
|
|
|
return false; |
|
|
|
} |
|
|
|
static struct desync_profile *dp_find(struct desync_profile_list_head *head, const struct sockaddr *dest, const char *hostname, t_l7proto l7proto) |
|
|
|
static struct desync_profile *dp_find(struct desync_profile_list_head *head, const struct sockaddr *dest, const char *hostname, bool bNoSubdom, t_l7proto l7proto) |
|
|
|
{ |
|
|
|
struct desync_profile_list *dpl; |
|
|
|
if (params.debug) |
|
|
@ -182,7 +184,7 @@ static struct desync_profile *dp_find(struct desync_profile_list_head *head, con |
|
|
|
} |
|
|
|
LIST_FOREACH(dpl, head, next) |
|
|
|
{ |
|
|
|
if (dp_match(&dpl->dp,dest,hostname,l7proto)) |
|
|
|
if (dp_match(&dpl->dp,dest,hostname,bNoSubdom,l7proto)) |
|
|
|
{ |
|
|
|
VPRINT("desync profile %d matches\n",dpl->dp.n); |
|
|
|
return &dpl->dp; |
|
|
@ -198,11 +200,11 @@ void apply_desync_profile(t_ctrack *ctrack, const struct sockaddr *dest) |
|
|
|
if (!ctrack->hostname) |
|
|
|
{ |
|
|
|
char host[256]; |
|
|
|
if (ipcache_get_hostname(dest->sa_family==AF_INET ? &((struct sockaddr_in*)dest)->sin_addr : NULL, dest->sa_family==AF_INET6 ? &((struct sockaddr_in6*)dest)->sin6_addr : NULL , host, sizeof(host)) && *host) |
|
|
|
if (ipcache_get_hostname(dest->sa_family==AF_INET ? &((struct sockaddr_in*)dest)->sin_addr : NULL, dest->sa_family==AF_INET6 ? &((struct sockaddr_in6*)dest)->sin6_addr : NULL , host, sizeof(host), &ctrack->hostname_is_ip) && *host) |
|
|
|
if (!(ctrack->hostname=strdup(host))) |
|
|
|
DLOG_ERR("hostname dup : out of memory"); |
|
|
|
} |
|
|
|
ctrack->dp = dp_find(¶ms.desync_profiles, dest, ctrack->hostname, ctrack->l7proto); |
|
|
|
ctrack->dp = dp_find(¶ms.desync_profiles, dest, ctrack->hostname, ctrack->hostname_is_ip, ctrack->l7proto); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -213,7 +215,7 @@ void tamper_out(t_ctrack *ctrack, const struct sockaddr *dest, uint8_t *segment, |
|
|
|
uint8_t *p, *pp, *pHost = NULL; |
|
|
|
size_t method_len = 0, pos, tpos, orig_size=*size; |
|
|
|
const char *method; |
|
|
|
bool bHaveHost = false; |
|
|
|
bool bHaveHost = false, bHostIsIp = false; |
|
|
|
char *pc, Host[256]; |
|
|
|
t_l7proto l7proto; |
|
|
|
|
|
|
@ -271,8 +273,9 @@ void tamper_out(t_ctrack *ctrack, const struct sockaddr *dest, uint8_t *segment, |
|
|
|
|
|
|
|
if (bHaveHost) |
|
|
|
{ |
|
|
|
bHostIsIp = strip_host_to_ip(Host); |
|
|
|
VPRINT("request hostname: %s\n", Host); |
|
|
|
if (!ipcache_put_hostname(dest->sa_family==AF_INET ? &((struct sockaddr_in*)dest)->sin_addr : NULL, dest->sa_family==AF_INET6 ? &((struct sockaddr_in6*)dest)->sin6_addr : NULL , Host)) |
|
|
|
if (!ipcache_put_hostname(dest->sa_family==AF_INET ? &((struct sockaddr_in*)dest)->sin_addr : NULL, dest->sa_family==AF_INET6 ? &((struct sockaddr_in6*)dest)->sin6_addr : NULL , Host, bHostIsIp)) |
|
|
|
DLOG_ERR("ipcache_put_hostname: out of memory"); |
|
|
|
} |
|
|
|
|
|
|
@ -293,6 +296,7 @@ void tamper_out(t_ctrack *ctrack, const struct sockaddr *dest, uint8_t *segment, |
|
|
|
DLOG_ERR("strdup hostname : out of memory\n"); |
|
|
|
return; |
|
|
|
} |
|
|
|
ctrack->hostname_is_ip = bHostIsIp; |
|
|
|
ctrack->hostname_discovered = true; |
|
|
|
} |
|
|
|
|
|
|
@ -312,7 +316,7 @@ void tamper_out(t_ctrack *ctrack, const struct sockaddr *dest, uint8_t *segment, |
|
|
|
if (bHaveHost && !ctrack->b_host_checked) |
|
|
|
{ |
|
|
|
bool bHostExcluded; |
|
|
|
ctrack->b_host_matches = HostlistCheck(ctrack->dp, Host, &bHostExcluded, false); |
|
|
|
ctrack->b_host_matches = HostlistCheck(ctrack->dp, Host, bHostIsIp, &bHostExcluded, false); |
|
|
|
ctrack->b_host_checked = true; |
|
|
|
if (!ctrack->b_host_matches) |
|
|
|
ctrack->b_ah_check = !bHostExcluded; |
|
|
@ -542,7 +546,7 @@ static void auto_hostlist_reset_fail_counter(struct desync_profile *dp, const ch |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
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; |
|
|
|
|
|
|
@ -566,7 +570,7 @@ static void auto_hostlist_failed(struct desync_profile *dp, const char *hostname |
|
|
|
|
|
|
|
VPRINT("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) |
|
|
|
{ |
|
|
|
VPRINT("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); |
|
|
@ -626,7 +630,7 @@ void tamper_in(t_ctrack *ctrack, const struct sockaddr *client, uint8_t *segment |
|
|
|
// received not http reply. do not monitor this connection anymore
|
|
|
|
VPRINT("incoming unknown HTTP data detected for hostname %s\n", ctrack->hostname); |
|
|
|
} |
|
|
|
if (bFail) auto_hostlist_failed(ctrack->dp, ctrack->hostname, client_ip_port, ctrack->l7proto); |
|
|
|
if (bFail) auto_hostlist_failed(ctrack->dp, ctrack->hostname, ctrack->hostname_is_ip, client_ip_port, ctrack->l7proto); |
|
|
|
} |
|
|
|
if (!bFail) auto_hostlist_reset_fail_counter(ctrack->dp, ctrack->hostname, client_ip_port, ctrack->l7proto); |
|
|
|
} |
|
|
@ -651,7 +655,7 @@ void rst_in(t_ctrack *ctrack, const struct sockaddr *client) |
|
|
|
{ |
|
|
|
VPRINT("incoming RST detected for hostname %s\n", ctrack->hostname); |
|
|
|
HOSTLIST_DEBUGLOG_APPEND("%s : profile %d : client %s : proto %s : incoming RST", 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); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -674,7 +678,7 @@ void hup_out(t_ctrack *ctrack, const struct sockaddr *client) |
|
|
|
// local leg dropped connection after first request. probably due to timeout.
|
|
|
|
VPRINT("local leg closed connection after first request (timeout ?). hostname: %s\n", ctrack->hostname); |
|
|
|
HOSTLIST_DEBUGLOG_APPEND("%s : profile %d : client %s : proto %s : client closed connection without server reply", 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); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|