Loading tpws/params.h +6 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ #define FIX_SEG_DEFAULT_MAX_WAIT 50 #define IPCACHE_LIFETIME 7200 enum bindll { unwanted=0, no, prefer, force }; #define MAX_BINDS 32 Loading Loading @@ -140,6 +142,10 @@ struct params_s bool tamper; // any tamper option is set bool tamper_lim; // tamper-start or tamper-cutoff set in any profile struct desync_profile_list_head desync_profiles; unsigned int ipcache_lifetime; bool cache_hostname; ip_cache ipcache; }; extern struct params_s params; Loading tpws/pools.c +275 −0 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ #include <string.h> #include <stdlib.h> #include <stdio.h> #include <arpa/inet.h> #define DESTROY_STR_POOL(etype, ppool) \ etype *elem, *tmp; \ Loading Loading @@ -517,3 +518,277 @@ bool port_filters_deny_if_empty(struct port_filters_head *head) if (LIST_FIRST(head)) return true; return pf_parse("0",&pf) && port_filter_add(head,&pf); } struct blob_item *blob_collection_add(struct blob_collection_head *head) { struct blob_item *entry = calloc(1,sizeof(struct blob_item)); if (entry) { // insert to the end struct blob_item *itemc,*iteml=LIST_FIRST(head); if (iteml) { while ((itemc=LIST_NEXT(iteml,next))) iteml = itemc; LIST_INSERT_AFTER(iteml, entry, next); } else LIST_INSERT_HEAD(head, entry, next); } return entry; } struct blob_item *blob_collection_add_blob(struct blob_collection_head *head, const void *data, size_t size, size_t size_reserve) { struct blob_item *entry = calloc(1,sizeof(struct blob_item)); if (!entry) return NULL; if (!(entry->data = malloc(size+size_reserve))) { free(entry); return NULL; } if (data) memcpy(entry->data,data,size); entry->size = size; entry->size_buf = size+size_reserve; // insert to the end struct blob_item *itemc,*iteml=LIST_FIRST(head); if (iteml) { while ((itemc=LIST_NEXT(iteml,next))) iteml = itemc; LIST_INSERT_AFTER(iteml, entry, next); } else LIST_INSERT_HEAD(head, entry, next); return entry; } void blob_collection_destroy(struct blob_collection_head *head) { struct blob_item *entry; while ((entry = LIST_FIRST(head))) { LIST_REMOVE(entry, next); free(entry->extra); free(entry->extra2); free(entry->data); free(entry); } } bool blob_collection_empty(const struct blob_collection_head *head) { return !LIST_FIRST(head); } static void ipcache_item_touch(ip_cache_item *item) { time(&item->last); } static void ipcache_item_init(ip_cache_item *item) { ipcache_item_touch(item); item->hostname = NULL; } static void ipcache_item_destroy(ip_cache_item *item) { free(item->hostname); } static void ipcache4Destroy(ip_cache4 **ipcache) { ip_cache4 *elem, *tmp; HASH_ITER(hh, *ipcache, elem, tmp) { HASH_DEL(*ipcache, elem); ipcache_item_destroy(&elem->data); free(elem); } } static void ipcache4Key(ip4if *key, const struct in_addr *a) { memset(key,0,sizeof(*key)); // make sure everything is zero key->addr = *a; } static ip_cache4 *ipcache4Find(ip_cache4 *ipcache, const struct in_addr *a) { ip_cache4 *entry; struct ip4if key; ipcache4Key(&key,a); HASH_FIND(hh, ipcache, &key, sizeof(key), entry); return entry; } static ip_cache4 *ipcache4Add(ip_cache4 **ipcache, const struct in_addr *a) { // avoid dups ip_cache4 *entry = ipcache4Find(*ipcache,a); if (entry) return entry; // already included entry = malloc(sizeof(ip_cache4)); if (!entry) return NULL; ipcache4Key(&entry->key,a); oom = false; HASH_ADD(hh, *ipcache, key, sizeof(entry->key), entry); if (oom) { free(entry); return NULL; } ipcache_item_init(&entry->data); return entry; } static void ipcache4Print(ip_cache4 *ipcache) { char s_ip[16]; time_t now; ip_cache4 *ipc, *tmp; time(&now); HASH_ITER(hh, ipcache , ipc, tmp) { *s_ip=0; inet_ntop(AF_INET, &ipc->key.addr, s_ip, sizeof(s_ip)); printf("%s : hostname=%s now=last+%llu\n", s_ip, ipc->data.hostname ? ipc->data.hostname : "", (unsigned long long)(now-ipc->data.last)); } } static void ipcache6Destroy(ip_cache6 **ipcache) { ip_cache6 *elem, *tmp; HASH_ITER(hh, *ipcache, elem, tmp) { HASH_DEL(*ipcache, elem); ipcache_item_destroy(&elem->data); free(elem); } } static void ipcache6Key(ip6if *key, const struct in6_addr *a) { memset(key,0,sizeof(*key)); // make sure everything is zero key->addr = *a; } static ip_cache6 *ipcache6Find(ip_cache6 *ipcache, const struct in6_addr *a) { ip_cache6 *entry; ip6if key; ipcache6Key(&key,a); HASH_FIND(hh, ipcache, &key, sizeof(key), entry); return entry; } static ip_cache6 *ipcache6Add(ip_cache6 **ipcache, const struct in6_addr *a) { // avoid dups ip_cache6 *entry = ipcache6Find(*ipcache,a); if (entry) return entry; // already included entry = malloc(sizeof(ip_cache6)); if (!entry) return NULL; ipcache6Key(&entry->key,a); oom = false; HASH_ADD(hh, *ipcache, key, sizeof(entry->key), entry); if (oom) { free(entry); return NULL; } ipcache_item_init(&entry->data); return entry; } static void ipcache6Print(ip_cache6 *ipcache) { char s_ip[40]; time_t now; ip_cache6 *ipc, *tmp; time(&now); HASH_ITER(hh, ipcache , ipc, tmp) { *s_ip=0; inet_ntop(AF_INET6, &ipc->key.addr, s_ip, sizeof(s_ip)); printf("%s : hostname=%s now=last+%llu\n", s_ip, ipc->data.hostname ? ipc->data.hostname : "", (unsigned long long)(now-ipc->data.last)); } } void ipcacheDestroy(ip_cache *ipcache) { ipcache4Destroy(&ipcache->ipcache4); ipcache6Destroy(&ipcache->ipcache6); } void ipcachePrint(ip_cache *ipcache) { ipcache4Print(ipcache->ipcache4); ipcache6Print(ipcache->ipcache6); } ip_cache_item *ipcacheTouch(ip_cache *ipcache, const struct in_addr *a4, const struct in6_addr *a6) { ip_cache4 *ipcache4; ip_cache6 *ipcache6; if (a4) { if ((ipcache4 = ipcache4Add(&ipcache->ipcache4,a4))) { ipcache_item_touch(&ipcache4->data); return &ipcache4->data; } } else if (a6) { if ((ipcache6 = ipcache6Add(&ipcache->ipcache6,a6))) { ipcache_item_touch(&ipcache6->data); return &ipcache6->data; } } return NULL; } static void ipcache4_purge(ip_cache4 **ipcache, time_t lifetime) { ip_cache4 *elem, *tmp; time_t now = time(NULL); HASH_ITER(hh, *ipcache, elem, tmp) { if (now >= (elem->data.last + lifetime)) { HASH_DEL(*ipcache, elem); ipcache_item_destroy(&elem->data); free(elem); } } } static void ipcache6_purge(ip_cache6 **ipcache, time_t lifetime) { ip_cache6 *elem, *tmp; time_t now = time(NULL); HASH_ITER(hh, *ipcache, elem, tmp) { if (now >= (elem->data.last + lifetime)) { HASH_DEL(*ipcache, elem); ipcache_item_destroy(&elem->data); free(elem); } } } static void ipcache_purge(ip_cache *ipcache, time_t lifetime) { if (lifetime) // 0 = no expire { ipcache4_purge(&ipcache->ipcache4, lifetime); ipcache6_purge(&ipcache->ipcache6, lifetime); } } static time_t ipcache_purge_prev=0; void ipcachePurgeRateLimited(ip_cache *ipcache, time_t lifetime) { time_t now = time(NULL); // do not purge too often to save resources if (ipcache_purge_prev != now) { ipcache_purge(ipcache, lifetime); ipcache_purge_prev = now; } } tpws/pools.h +53 −0 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ #include <stdbool.h> #include <ctype.h> #include <sys/queue.h> #include <net/if.h> #include <time.h> #include "helpers.h" Loading Loading @@ -146,3 +147,55 @@ bool port_filter_add(struct port_filters_head *head, const port_filter *pf); void port_filters_destroy(struct port_filters_head *head); bool port_filters_in_range(const struct port_filters_head *head, uint16_t port); bool port_filters_deny_if_empty(struct port_filters_head *head); struct blob_item { uint8_t *data; // main data blob size_t size; // main data blob size size_t size_buf;// main data blob allocated size void *extra; // any data without size void *extra2; // any data without size LIST_ENTRY(blob_item) next; }; LIST_HEAD(blob_collection_head, blob_item); struct blob_item *blob_collection_add(struct blob_collection_head *head); struct blob_item *blob_collection_add_blob(struct blob_collection_head *head, const void *data, size_t size, size_t size_reserve); void blob_collection_destroy(struct blob_collection_head *head); bool blob_collection_empty(const struct blob_collection_head *head); typedef struct ip4if { struct in_addr addr; } ip4if; typedef struct ip6if { struct in6_addr addr; } ip6if; typedef struct ip_cache_item { time_t last; char *hostname; } ip_cache_item; typedef struct ip_cache4 { ip4if key; ip_cache_item data; UT_hash_handle hh; /* makes this structure hashable */ } ip_cache4; typedef struct ip_cache6 { ip6if key; ip_cache_item data; UT_hash_handle hh; /* makes this structure hashable */ } ip_cache6; typedef struct ip_cache { ip_cache4 *ipcache4; ip_cache6 *ipcache6; } ip_cache; ip_cache_item *ipcacheTouch(ip_cache *ipcache, const struct in_addr *a4, const struct in6_addr *a6); void ipcachePurgeRateLimited(ip_cache *ipcache, time_t lifetime); void ipcacheDestroy(ip_cache *ipcache); void ipcachePrint(ip_cache *ipcache); tpws/tamper.c +59 −1 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ #include "ipset.h" #include "protocol.h" #include "helpers.h" #include "pools.h" #define PKTDATA_MAXDUMP 32 Loading Loading @@ -90,6 +91,48 @@ static void TLSDebug(const uint8_t *tls,size_t sz) TLSDebugHandshake(tls+5,sz-5); } static bool ipcache_put_hostname(const struct in_addr *a4, const struct in6_addr *a6, const char *hostname) { if (!params.cache_hostname) return true; ip_cache_item *ipc = ipcacheTouch(¶ms.ipcache,a4,a6); if (!ipc) { DLOG_ERR("ipcache_put_hostname: out of memory\n"); return false; } free(ipc->hostname); if (!(ipc->hostname = strdup(hostname))) { DLOG_ERR("ipcache_put_hostname: out of memory\n"); return false; } VPRINT("hostname cached: %s\n", 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) { if (!params.cache_hostname) { *hostname = 0; return true; } ip_cache_item *ipc = ipcacheTouch(¶ms.ipcache,a4,a6); if (!ipc) { DLOG_ERR("ipcache_get_hostname: out of memory\n"); return false; } if (ipc->hostname) { VPRINT("got cached hostname: %s\n", ipc->hostname); snprintf(hostname,hostname_buf_len,"%s",ipc->hostname); } else *hostname = 0; return true; } static bool dp_match(struct desync_profile *dp, const struct sockaddr *dest, const char *hostname, t_l7proto l7proto) { bool bHostlistsEmpty; Loading Loading @@ -145,8 +188,17 @@ static struct desync_profile *dp_find(struct desync_profile_list_head *head, con VPRINT("desync profile not found\n"); return NULL; } void apply_desync_profile(t_ctrack *ctrack, const struct sockaddr *dest) { ipcachePurgeRateLimited(¶ms.ipcache, params.ipcache_lifetime); 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 (!(ctrack->hostname=strdup(host))) DLOG_ERR("hostname dup : out of memory"); } ctrack->dp = dp_find(¶ms.desync_profiles, dest, ctrack->hostname, ctrack->l7proto); } Loading Loading @@ -215,7 +267,11 @@ void tamper_out(t_ctrack *ctrack, const struct sockaddr *dest, uint8_t *segment, } if (bHaveHost) { 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)) DLOG_ERR("ipcache_put_hostname: out of memory"); } bool bDiscoveredL7 = ctrack->l7proto==UNKNOWN && l7proto!=UNKNOWN; if (bDiscoveredL7) Loading @@ -224,15 +280,17 @@ void tamper_out(t_ctrack *ctrack, const struct sockaddr *dest, uint8_t *segment, ctrack->l7proto=l7proto; } bool bDiscoveredHostname = bHaveHost && !ctrack->hostname; bool bDiscoveredHostname = bHaveHost && !ctrack->hostname_discovered; if (bDiscoveredHostname) { VPRINT("discovered hostname\n"); free(ctrack->hostname); if (!(ctrack->hostname=strdup(Host))) { DLOG_ERR("strdup hostname : out of memory\n"); return; } ctrack->hostname_discovered = true; } if (bDiscoveredL7 || bDiscoveredHostname) Loading tpws/tamper.h +1 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ typedef struct t_l7proto l7proto; bool bTamperInCutoff; bool b_host_checked,b_host_matches,b_ah_check; bool hostname_discovered; char *hostname; struct desync_profile *dp; // desync profile cache } t_ctrack; Loading Loading
tpws/params.h +6 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ #define FIX_SEG_DEFAULT_MAX_WAIT 50 #define IPCACHE_LIFETIME 7200 enum bindll { unwanted=0, no, prefer, force }; #define MAX_BINDS 32 Loading Loading @@ -140,6 +142,10 @@ struct params_s bool tamper; // any tamper option is set bool tamper_lim; // tamper-start or tamper-cutoff set in any profile struct desync_profile_list_head desync_profiles; unsigned int ipcache_lifetime; bool cache_hostname; ip_cache ipcache; }; extern struct params_s params; Loading
tpws/pools.c +275 −0 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ #include <string.h> #include <stdlib.h> #include <stdio.h> #include <arpa/inet.h> #define DESTROY_STR_POOL(etype, ppool) \ etype *elem, *tmp; \ Loading Loading @@ -517,3 +518,277 @@ bool port_filters_deny_if_empty(struct port_filters_head *head) if (LIST_FIRST(head)) return true; return pf_parse("0",&pf) && port_filter_add(head,&pf); } struct blob_item *blob_collection_add(struct blob_collection_head *head) { struct blob_item *entry = calloc(1,sizeof(struct blob_item)); if (entry) { // insert to the end struct blob_item *itemc,*iteml=LIST_FIRST(head); if (iteml) { while ((itemc=LIST_NEXT(iteml,next))) iteml = itemc; LIST_INSERT_AFTER(iteml, entry, next); } else LIST_INSERT_HEAD(head, entry, next); } return entry; } struct blob_item *blob_collection_add_blob(struct blob_collection_head *head, const void *data, size_t size, size_t size_reserve) { struct blob_item *entry = calloc(1,sizeof(struct blob_item)); if (!entry) return NULL; if (!(entry->data = malloc(size+size_reserve))) { free(entry); return NULL; } if (data) memcpy(entry->data,data,size); entry->size = size; entry->size_buf = size+size_reserve; // insert to the end struct blob_item *itemc,*iteml=LIST_FIRST(head); if (iteml) { while ((itemc=LIST_NEXT(iteml,next))) iteml = itemc; LIST_INSERT_AFTER(iteml, entry, next); } else LIST_INSERT_HEAD(head, entry, next); return entry; } void blob_collection_destroy(struct blob_collection_head *head) { struct blob_item *entry; while ((entry = LIST_FIRST(head))) { LIST_REMOVE(entry, next); free(entry->extra); free(entry->extra2); free(entry->data); free(entry); } } bool blob_collection_empty(const struct blob_collection_head *head) { return !LIST_FIRST(head); } static void ipcache_item_touch(ip_cache_item *item) { time(&item->last); } static void ipcache_item_init(ip_cache_item *item) { ipcache_item_touch(item); item->hostname = NULL; } static void ipcache_item_destroy(ip_cache_item *item) { free(item->hostname); } static void ipcache4Destroy(ip_cache4 **ipcache) { ip_cache4 *elem, *tmp; HASH_ITER(hh, *ipcache, elem, tmp) { HASH_DEL(*ipcache, elem); ipcache_item_destroy(&elem->data); free(elem); } } static void ipcache4Key(ip4if *key, const struct in_addr *a) { memset(key,0,sizeof(*key)); // make sure everything is zero key->addr = *a; } static ip_cache4 *ipcache4Find(ip_cache4 *ipcache, const struct in_addr *a) { ip_cache4 *entry; struct ip4if key; ipcache4Key(&key,a); HASH_FIND(hh, ipcache, &key, sizeof(key), entry); return entry; } static ip_cache4 *ipcache4Add(ip_cache4 **ipcache, const struct in_addr *a) { // avoid dups ip_cache4 *entry = ipcache4Find(*ipcache,a); if (entry) return entry; // already included entry = malloc(sizeof(ip_cache4)); if (!entry) return NULL; ipcache4Key(&entry->key,a); oom = false; HASH_ADD(hh, *ipcache, key, sizeof(entry->key), entry); if (oom) { free(entry); return NULL; } ipcache_item_init(&entry->data); return entry; } static void ipcache4Print(ip_cache4 *ipcache) { char s_ip[16]; time_t now; ip_cache4 *ipc, *tmp; time(&now); HASH_ITER(hh, ipcache , ipc, tmp) { *s_ip=0; inet_ntop(AF_INET, &ipc->key.addr, s_ip, sizeof(s_ip)); printf("%s : hostname=%s now=last+%llu\n", s_ip, ipc->data.hostname ? ipc->data.hostname : "", (unsigned long long)(now-ipc->data.last)); } } static void ipcache6Destroy(ip_cache6 **ipcache) { ip_cache6 *elem, *tmp; HASH_ITER(hh, *ipcache, elem, tmp) { HASH_DEL(*ipcache, elem); ipcache_item_destroy(&elem->data); free(elem); } } static void ipcache6Key(ip6if *key, const struct in6_addr *a) { memset(key,0,sizeof(*key)); // make sure everything is zero key->addr = *a; } static ip_cache6 *ipcache6Find(ip_cache6 *ipcache, const struct in6_addr *a) { ip_cache6 *entry; ip6if key; ipcache6Key(&key,a); HASH_FIND(hh, ipcache, &key, sizeof(key), entry); return entry; } static ip_cache6 *ipcache6Add(ip_cache6 **ipcache, const struct in6_addr *a) { // avoid dups ip_cache6 *entry = ipcache6Find(*ipcache,a); if (entry) return entry; // already included entry = malloc(sizeof(ip_cache6)); if (!entry) return NULL; ipcache6Key(&entry->key,a); oom = false; HASH_ADD(hh, *ipcache, key, sizeof(entry->key), entry); if (oom) { free(entry); return NULL; } ipcache_item_init(&entry->data); return entry; } static void ipcache6Print(ip_cache6 *ipcache) { char s_ip[40]; time_t now; ip_cache6 *ipc, *tmp; time(&now); HASH_ITER(hh, ipcache , ipc, tmp) { *s_ip=0; inet_ntop(AF_INET6, &ipc->key.addr, s_ip, sizeof(s_ip)); printf("%s : hostname=%s now=last+%llu\n", s_ip, ipc->data.hostname ? ipc->data.hostname : "", (unsigned long long)(now-ipc->data.last)); } } void ipcacheDestroy(ip_cache *ipcache) { ipcache4Destroy(&ipcache->ipcache4); ipcache6Destroy(&ipcache->ipcache6); } void ipcachePrint(ip_cache *ipcache) { ipcache4Print(ipcache->ipcache4); ipcache6Print(ipcache->ipcache6); } ip_cache_item *ipcacheTouch(ip_cache *ipcache, const struct in_addr *a4, const struct in6_addr *a6) { ip_cache4 *ipcache4; ip_cache6 *ipcache6; if (a4) { if ((ipcache4 = ipcache4Add(&ipcache->ipcache4,a4))) { ipcache_item_touch(&ipcache4->data); return &ipcache4->data; } } else if (a6) { if ((ipcache6 = ipcache6Add(&ipcache->ipcache6,a6))) { ipcache_item_touch(&ipcache6->data); return &ipcache6->data; } } return NULL; } static void ipcache4_purge(ip_cache4 **ipcache, time_t lifetime) { ip_cache4 *elem, *tmp; time_t now = time(NULL); HASH_ITER(hh, *ipcache, elem, tmp) { if (now >= (elem->data.last + lifetime)) { HASH_DEL(*ipcache, elem); ipcache_item_destroy(&elem->data); free(elem); } } } static void ipcache6_purge(ip_cache6 **ipcache, time_t lifetime) { ip_cache6 *elem, *tmp; time_t now = time(NULL); HASH_ITER(hh, *ipcache, elem, tmp) { if (now >= (elem->data.last + lifetime)) { HASH_DEL(*ipcache, elem); ipcache_item_destroy(&elem->data); free(elem); } } } static void ipcache_purge(ip_cache *ipcache, time_t lifetime) { if (lifetime) // 0 = no expire { ipcache4_purge(&ipcache->ipcache4, lifetime); ipcache6_purge(&ipcache->ipcache6, lifetime); } } static time_t ipcache_purge_prev=0; void ipcachePurgeRateLimited(ip_cache *ipcache, time_t lifetime) { time_t now = time(NULL); // do not purge too often to save resources if (ipcache_purge_prev != now) { ipcache_purge(ipcache, lifetime); ipcache_purge_prev = now; } }
tpws/pools.h +53 −0 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ #include <stdbool.h> #include <ctype.h> #include <sys/queue.h> #include <net/if.h> #include <time.h> #include "helpers.h" Loading Loading @@ -146,3 +147,55 @@ bool port_filter_add(struct port_filters_head *head, const port_filter *pf); void port_filters_destroy(struct port_filters_head *head); bool port_filters_in_range(const struct port_filters_head *head, uint16_t port); bool port_filters_deny_if_empty(struct port_filters_head *head); struct blob_item { uint8_t *data; // main data blob size_t size; // main data blob size size_t size_buf;// main data blob allocated size void *extra; // any data without size void *extra2; // any data without size LIST_ENTRY(blob_item) next; }; LIST_HEAD(blob_collection_head, blob_item); struct blob_item *blob_collection_add(struct blob_collection_head *head); struct blob_item *blob_collection_add_blob(struct blob_collection_head *head, const void *data, size_t size, size_t size_reserve); void blob_collection_destroy(struct blob_collection_head *head); bool blob_collection_empty(const struct blob_collection_head *head); typedef struct ip4if { struct in_addr addr; } ip4if; typedef struct ip6if { struct in6_addr addr; } ip6if; typedef struct ip_cache_item { time_t last; char *hostname; } ip_cache_item; typedef struct ip_cache4 { ip4if key; ip_cache_item data; UT_hash_handle hh; /* makes this structure hashable */ } ip_cache4; typedef struct ip_cache6 { ip6if key; ip_cache_item data; UT_hash_handle hh; /* makes this structure hashable */ } ip_cache6; typedef struct ip_cache { ip_cache4 *ipcache4; ip_cache6 *ipcache6; } ip_cache; ip_cache_item *ipcacheTouch(ip_cache *ipcache, const struct in_addr *a4, const struct in6_addr *a6); void ipcachePurgeRateLimited(ip_cache *ipcache, time_t lifetime); void ipcacheDestroy(ip_cache *ipcache); void ipcachePrint(ip_cache *ipcache);
tpws/tamper.c +59 −1 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ #include "ipset.h" #include "protocol.h" #include "helpers.h" #include "pools.h" #define PKTDATA_MAXDUMP 32 Loading Loading @@ -90,6 +91,48 @@ static void TLSDebug(const uint8_t *tls,size_t sz) TLSDebugHandshake(tls+5,sz-5); } static bool ipcache_put_hostname(const struct in_addr *a4, const struct in6_addr *a6, const char *hostname) { if (!params.cache_hostname) return true; ip_cache_item *ipc = ipcacheTouch(¶ms.ipcache,a4,a6); if (!ipc) { DLOG_ERR("ipcache_put_hostname: out of memory\n"); return false; } free(ipc->hostname); if (!(ipc->hostname = strdup(hostname))) { DLOG_ERR("ipcache_put_hostname: out of memory\n"); return false; } VPRINT("hostname cached: %s\n", 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) { if (!params.cache_hostname) { *hostname = 0; return true; } ip_cache_item *ipc = ipcacheTouch(¶ms.ipcache,a4,a6); if (!ipc) { DLOG_ERR("ipcache_get_hostname: out of memory\n"); return false; } if (ipc->hostname) { VPRINT("got cached hostname: %s\n", ipc->hostname); snprintf(hostname,hostname_buf_len,"%s",ipc->hostname); } else *hostname = 0; return true; } static bool dp_match(struct desync_profile *dp, const struct sockaddr *dest, const char *hostname, t_l7proto l7proto) { bool bHostlistsEmpty; Loading Loading @@ -145,8 +188,17 @@ static struct desync_profile *dp_find(struct desync_profile_list_head *head, con VPRINT("desync profile not found\n"); return NULL; } void apply_desync_profile(t_ctrack *ctrack, const struct sockaddr *dest) { ipcachePurgeRateLimited(¶ms.ipcache, params.ipcache_lifetime); 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 (!(ctrack->hostname=strdup(host))) DLOG_ERR("hostname dup : out of memory"); } ctrack->dp = dp_find(¶ms.desync_profiles, dest, ctrack->hostname, ctrack->l7proto); } Loading Loading @@ -215,7 +267,11 @@ void tamper_out(t_ctrack *ctrack, const struct sockaddr *dest, uint8_t *segment, } if (bHaveHost) { 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)) DLOG_ERR("ipcache_put_hostname: out of memory"); } bool bDiscoveredL7 = ctrack->l7proto==UNKNOWN && l7proto!=UNKNOWN; if (bDiscoveredL7) Loading @@ -224,15 +280,17 @@ void tamper_out(t_ctrack *ctrack, const struct sockaddr *dest, uint8_t *segment, ctrack->l7proto=l7proto; } bool bDiscoveredHostname = bHaveHost && !ctrack->hostname; bool bDiscoveredHostname = bHaveHost && !ctrack->hostname_discovered; if (bDiscoveredHostname) { VPRINT("discovered hostname\n"); free(ctrack->hostname); if (!(ctrack->hostname=strdup(Host))) { DLOG_ERR("strdup hostname : out of memory\n"); return; } ctrack->hostname_discovered = true; } if (bDiscoveredL7 || bDiscoveredHostname) Loading
tpws/tamper.h +1 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ typedef struct t_l7proto l7proto; bool bTamperInCutoff; bool b_host_checked,b_host_matches,b_ah_check; bool hostname_discovered; char *hostname; struct desync_profile *dp; // desync profile cache } t_ctrack; Loading