mirror of
https://github.com/bol-van/zapret.git
synced 2025-05-06 18:50:51 +05:00
tpws: ipcache
This commit is contained in:
parent
c626d88f54
commit
9629ce5cb7
@ -20,6 +20,8 @@
|
|||||||
|
|
||||||
#define FIX_SEG_DEFAULT_MAX_WAIT 50
|
#define FIX_SEG_DEFAULT_MAX_WAIT 50
|
||||||
|
|
||||||
|
#define IPCACHE_LIFETIME 7200
|
||||||
|
|
||||||
enum bindll { unwanted=0, no, prefer, force };
|
enum bindll { unwanted=0, no, prefer, force };
|
||||||
|
|
||||||
#define MAX_BINDS 32
|
#define MAX_BINDS 32
|
||||||
@ -140,6 +142,10 @@ struct params_s
|
|||||||
bool tamper; // any tamper option is set
|
bool tamper; // any tamper option is set
|
||||||
bool tamper_lim; // tamper-start or tamper-cutoff set in any profile
|
bool tamper_lim; // tamper-start or tamper-cutoff set in any profile
|
||||||
struct desync_profile_list_head desync_profiles;
|
struct desync_profile_list_head desync_profiles;
|
||||||
|
|
||||||
|
unsigned int ipcache_lifetime;
|
||||||
|
bool cache_hostname;
|
||||||
|
ip_cache ipcache;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct params_s params;
|
extern struct params_s params;
|
||||||
|
275
tpws/pools.c
275
tpws/pools.c
@ -3,6 +3,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
#define DESTROY_STR_POOL(etype, ppool) \
|
#define DESTROY_STR_POOL(etype, ppool) \
|
||||||
etype *elem, *tmp; \
|
etype *elem, *tmp; \
|
||||||
@ -517,3 +518,277 @@ bool port_filters_deny_if_empty(struct port_filters_head *head)
|
|||||||
if (LIST_FIRST(head)) return true;
|
if (LIST_FIRST(head)) return true;
|
||||||
return pf_parse("0",&pf) && port_filter_add(head,&pf);
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
53
tpws/pools.h
53
tpws/pools.h
@ -3,6 +3,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <sys/queue.h>
|
#include <sys/queue.h>
|
||||||
|
#include <net/if.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
@ -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);
|
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_in_range(const struct port_filters_head *head, uint16_t port);
|
||||||
bool port_filters_deny_if_empty(struct port_filters_head *head);
|
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);
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "ipset.h"
|
#include "ipset.h"
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
|
#include "pools.h"
|
||||||
|
|
||||||
#define PKTDATA_MAXDUMP 32
|
#define PKTDATA_MAXDUMP 32
|
||||||
|
|
||||||
@ -90,6 +91,48 @@ static void TLSDebug(const uint8_t *tls,size_t sz)
|
|||||||
TLSDebugHandshake(tls+5,sz-5);
|
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)
|
static bool dp_match(struct desync_profile *dp, const struct sockaddr *dest, const char *hostname, t_l7proto l7proto)
|
||||||
{
|
{
|
||||||
bool bHostlistsEmpty;
|
bool bHostlistsEmpty;
|
||||||
@ -145,8 +188,17 @@ static struct desync_profile *dp_find(struct desync_profile_list_head *head, con
|
|||||||
VPRINT("desync profile not found\n");
|
VPRINT("desync profile not found\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void apply_desync_profile(t_ctrack *ctrack, const struct sockaddr *dest)
|
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);
|
ctrack->dp = dp_find(¶ms.desync_profiles, dest, ctrack->hostname, ctrack->l7proto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,7 +267,11 @@ void tamper_out(t_ctrack *ctrack, const struct sockaddr *dest, uint8_t *segment,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (bHaveHost)
|
if (bHaveHost)
|
||||||
|
{
|
||||||
VPRINT("request hostname: %s\n", 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))
|
||||||
|
DLOG_ERR("ipcache_put_hostname: out of memory");
|
||||||
|
}
|
||||||
|
|
||||||
bool bDiscoveredL7 = ctrack->l7proto==UNKNOWN && l7proto!=UNKNOWN;
|
bool bDiscoveredL7 = ctrack->l7proto==UNKNOWN && l7proto!=UNKNOWN;
|
||||||
if (bDiscoveredL7)
|
if (bDiscoveredL7)
|
||||||
@ -224,15 +280,17 @@ void tamper_out(t_ctrack *ctrack, const struct sockaddr *dest, uint8_t *segment,
|
|||||||
ctrack->l7proto=l7proto;
|
ctrack->l7proto=l7proto;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bDiscoveredHostname = bHaveHost && !ctrack->hostname;
|
bool bDiscoveredHostname = bHaveHost && !ctrack->hostname_discovered;
|
||||||
if (bDiscoveredHostname)
|
if (bDiscoveredHostname)
|
||||||
{
|
{
|
||||||
VPRINT("discovered hostname\n");
|
VPRINT("discovered hostname\n");
|
||||||
|
free(ctrack->hostname);
|
||||||
if (!(ctrack->hostname=strdup(Host)))
|
if (!(ctrack->hostname=strdup(Host)))
|
||||||
{
|
{
|
||||||
DLOG_ERR("strdup hostname : out of memory\n");
|
DLOG_ERR("strdup hostname : out of memory\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
ctrack->hostname_discovered = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bDiscoveredL7 || bDiscoveredHostname)
|
if (bDiscoveredL7 || bDiscoveredHostname)
|
||||||
|
@ -15,6 +15,7 @@ typedef struct
|
|||||||
t_l7proto l7proto;
|
t_l7proto l7proto;
|
||||||
bool bTamperInCutoff;
|
bool bTamperInCutoff;
|
||||||
bool b_host_checked,b_host_matches,b_ah_check;
|
bool b_host_checked,b_host_matches,b_ah_check;
|
||||||
|
bool hostname_discovered;
|
||||||
char *hostname;
|
char *hostname;
|
||||||
struct desync_profile *dp; // desync profile cache
|
struct desync_profile *dp; // desync profile cache
|
||||||
} t_ctrack;
|
} t_ctrack;
|
||||||
|
48
tpws/tpws.c
48
tpws/tpws.c
@ -88,6 +88,12 @@ static void onusr2(int sig)
|
|||||||
HostFailPoolDump(dpl->dp.hostlist_auto_fail_counters);
|
HostFailPoolDump(dpl->dp.hostlist_auto_fail_counters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (params.cache_hostname)
|
||||||
|
{
|
||||||
|
printf("\nIPCACHE\n");
|
||||||
|
ipcachePrint(¶ms.ipcache);
|
||||||
|
}
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,6 +221,8 @@ static void exithelp(void)
|
|||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
" --fix-seg=<int>\t\t\t; fix segmentation failures at the cost of possible slowdown. wait up to N msec (default %u)\n"
|
" --fix-seg=<int>\t\t\t; fix segmentation failures at the cost of possible slowdown. wait up to N msec (default %u)\n"
|
||||||
#endif
|
#endif
|
||||||
|
" --ipcache-lifetime=<int>\t\t; time in seconds to keep cached domain name (default %u). 0 = no expiration\n"
|
||||||
|
" --ipcache-hostname=[0|1]\t\t; 1 or no argument enables ip->hostname caching\n"
|
||||||
" --debug=0|1|2|syslog|@<filename>\t; 1 and 2 means log to console and set debug level. for other targets use --debug-level.\n"
|
" --debug=0|1|2|syslog|@<filename>\t; 1 and 2 means log to console and set debug level. for other targets use --debug-level.\n"
|
||||||
" --debug-level=0|1|2\t\t\t; specify debug level\n"
|
" --debug-level=0|1|2\t\t\t; specify debug level\n"
|
||||||
" --dry-run\t\t\t\t; verify parameters and exit with code 0 if successful\n"
|
" --dry-run\t\t\t\t; verify parameters and exit with code 0 if successful\n"
|
||||||
@ -272,6 +280,7 @@ static void exithelp(void)
|
|||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
FIX_SEG_DEFAULT_MAX_WAIT,
|
FIX_SEG_DEFAULT_MAX_WAIT,
|
||||||
#endif
|
#endif
|
||||||
|
IPCACHE_LIFETIME,
|
||||||
HOSTLIST_AUTO_FAIL_THRESHOLD_DEFAULT, HOSTLIST_AUTO_FAIL_TIME_DEFAULT
|
HOSTLIST_AUTO_FAIL_THRESHOLD_DEFAULT, HOSTLIST_AUTO_FAIL_TIME_DEFAULT
|
||||||
);
|
);
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -292,6 +301,7 @@ static void cleanup_params(void)
|
|||||||
|
|
||||||
hostlist_files_destroy(¶ms.hostlists);
|
hostlist_files_destroy(¶ms.hostlists);
|
||||||
ipset_files_destroy(¶ms.ipsets);
|
ipset_files_destroy(¶ms.ipsets);
|
||||||
|
ipcacheDestroy(¶ms.ipcache);
|
||||||
}
|
}
|
||||||
static void exithelp_clean(void)
|
static void exithelp_clean(void)
|
||||||
{
|
{
|
||||||
@ -628,6 +638,8 @@ enum opt_indices {
|
|||||||
IDX_MAXCONN,
|
IDX_MAXCONN,
|
||||||
IDX_MAXFILES,
|
IDX_MAXFILES,
|
||||||
IDX_MAX_ORPHAN_TIME,
|
IDX_MAX_ORPHAN_TIME,
|
||||||
|
IDX_IPCACHE_LIFETIME,
|
||||||
|
IDX_IPCACHE_HOSTNAME,
|
||||||
IDX_HOSTCASE,
|
IDX_HOSTCASE,
|
||||||
IDX_HOSTSPELL,
|
IDX_HOSTSPELL,
|
||||||
IDX_HOSTDOT,
|
IDX_HOSTDOT,
|
||||||
@ -718,6 +730,8 @@ static const struct option long_options[] = {
|
|||||||
[IDX_UID] = {"uid", required_argument, 0, 0},
|
[IDX_UID] = {"uid", required_argument, 0, 0},
|
||||||
[IDX_MAXCONN] = {"maxconn", required_argument, 0, 0},
|
[IDX_MAXCONN] = {"maxconn", required_argument, 0, 0},
|
||||||
[IDX_MAXFILES] = {"maxfiles", required_argument, 0, 0},
|
[IDX_MAXFILES] = {"maxfiles", required_argument, 0, 0},
|
||||||
|
[IDX_IPCACHE_LIFETIME] = {"ipcache-lifetime", required_argument, 0, 0},
|
||||||
|
[IDX_IPCACHE_HOSTNAME] = {"ipcache-hostname", optional_argument, 0, 0},
|
||||||
[IDX_MAX_ORPHAN_TIME] = {"max-orphan-time", required_argument, 0, 0},
|
[IDX_MAX_ORPHAN_TIME] = {"max-orphan-time", required_argument, 0, 0},
|
||||||
[IDX_HOSTCASE] = {"hostcase", no_argument, 0, 0},
|
[IDX_HOSTCASE] = {"hostcase", no_argument, 0, 0},
|
||||||
[IDX_HOSTSPELL] = {"hostspell", required_argument, 0, 0},
|
[IDX_HOSTSPELL] = {"hostspell", required_argument, 0, 0},
|
||||||
@ -804,6 +818,7 @@ void parse_params(int argc, char *argv[])
|
|||||||
params.maxconn = DEFAULT_MAX_CONN;
|
params.maxconn = DEFAULT_MAX_CONN;
|
||||||
params.max_orphan_time = DEFAULT_MAX_ORPHAN_TIME;
|
params.max_orphan_time = DEFAULT_MAX_ORPHAN_TIME;
|
||||||
params.binds_last = -1;
|
params.binds_last = -1;
|
||||||
|
params.ipcache_lifetime = IPCACHE_LIFETIME;
|
||||||
#if defined(__linux__) || defined(__APPLE__)
|
#if defined(__linux__) || defined(__APPLE__)
|
||||||
params.tcp_user_timeout_local = DEFAULT_TCP_USER_TIMEOUT_LOCAL;
|
params.tcp_user_timeout_local = DEFAULT_TCP_USER_TIMEOUT_LOCAL;
|
||||||
params.tcp_user_timeout_remote = DEFAULT_TCP_USER_TIMEOUT_REMOTE;
|
params.tcp_user_timeout_remote = DEFAULT_TCP_USER_TIMEOUT_REMOTE;
|
||||||
@ -976,6 +991,16 @@ void parse_params(int argc, char *argv[])
|
|||||||
exit_clean(1);
|
exit_clean(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case IDX_IPCACHE_LIFETIME:
|
||||||
|
if (sscanf(optarg, "%u", ¶ms.ipcache_lifetime)!=1)
|
||||||
|
{
|
||||||
|
DLOG_ERR("invalid ipcache-lifetime value\n");
|
||||||
|
exit_clean(1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case IDX_IPCACHE_HOSTNAME:
|
||||||
|
params.cache_hostname = !optarg || !!atoi(optarg);
|
||||||
|
break;
|
||||||
case IDX_HOSTCASE:
|
case IDX_HOSTCASE:
|
||||||
dp->hostcase = true;
|
dp->hostcase = true;
|
||||||
params.tamper = true;
|
params.tamper = true;
|
||||||
@ -1815,14 +1840,6 @@ int main(int argc, char *argv[])
|
|||||||
parse_params(argc, argv);
|
parse_params(argc, argv);
|
||||||
argv=NULL; argc=0;
|
argv=NULL; argc=0;
|
||||||
|
|
||||||
if (params.daemon) daemonize();
|
|
||||||
|
|
||||||
if (*params.pidfile && !writepid(params.pidfile))
|
|
||||||
{
|
|
||||||
DLOG_ERR("could not write pidfile\n");
|
|
||||||
goto exiterr;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&list, 0, sizeof(list));
|
memset(&list, 0, sizeof(list));
|
||||||
for(i=0;i<=params.binds_last;i++) listen_fd[i]=-1;
|
for(i=0;i<=params.binds_last;i++) listen_fd[i]=-1;
|
||||||
|
|
||||||
@ -2054,6 +2071,18 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (params.cache_hostname) VPRINT("ipcache lifetime %us\n", params.ipcache_lifetime);
|
||||||
|
DLOG_CONDUP(params.proxy_type==CONN_TYPE_SOCKS ? "socks mode\n" : "transparent proxy mode\n");
|
||||||
|
if (!params.tamper) DLOG_CONDUP("TCP proxy mode (no tampering)\n");
|
||||||
|
|
||||||
|
if (params.daemon) daemonize();
|
||||||
|
|
||||||
|
if (*params.pidfile && !writepid(params.pidfile))
|
||||||
|
{
|
||||||
|
DLOG_ERR("could not write pidfile\n");
|
||||||
|
goto exiterr;
|
||||||
|
}
|
||||||
|
|
||||||
set_ulimit();
|
set_ulimit();
|
||||||
sec_harden();
|
sec_harden();
|
||||||
if (params.droproot && !droproot(params.uid,params.gid))
|
if (params.droproot && !droproot(params.uid,params.gid))
|
||||||
@ -2074,9 +2103,6 @@ int main(int argc, char *argv[])
|
|||||||
goto exiterr;
|
goto exiterr;
|
||||||
}
|
}
|
||||||
|
|
||||||
DLOG_CONDUP(params.proxy_type==CONN_TYPE_SOCKS ? "socks mode\n" : "transparent proxy mode\n");
|
|
||||||
if (!params.tamper) DLOG_CONDUP("TCP proxy mode (no tampering)\n");
|
|
||||||
|
|
||||||
signal(SIGHUP, onhup);
|
signal(SIGHUP, onhup);
|
||||||
signal(SIGUSR2, onusr2);
|
signal(SIGUSR2, onusr2);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user