Template
1
0
mirror of https://github.com/bol-van/zapret2.git synced 2026-03-14 06:13:09 +00:00

12 Commits

Author SHA1 Message Date
bol-van
181395be87 nfqws2: compile compat 2026-02-04 15:14:49 +03:00
bol-van
fb71a41ea5 nfqws2: compile compat 2026-02-04 15:12:23 +03:00
bol-van
7f8f64a355 nfqws2: compile compat 2026-02-04 15:04:59 +03:00
bol-van
7e31dc9d89 update docs 2026-02-04 14:24:34 +03:00
bol-van
4a9072a949 nfqws2: unblocked bcryptorandom, --new=name, AI fixes 2026-02-04 14:24:10 +03:00
bol-van
4b0e3af020 update docs 2026-02-03 22:42:03 +03:00
bol-van
d442a38774 update docs 2026-02-03 22:40:48 +03:00
bol-van
ede3515fa3 update docs 2026-02-03 22:37:59 +03:00
bol-van
831cf02ad5 update docs 2026-02-03 22:33:10 +03:00
bol-van
c436470b18 nfqws2: type field in stat table 2026-02-03 22:32:57 +03:00
bol-van
56b4ce0b2a nfqws2: clock_getfloattime() 2026-02-03 22:03:56 +03:00
bol-van
18b33008af nfqws2: stat luacall 2026-02-03 21:58:14 +03:00
14 changed files with 415 additions and 156 deletions

View File

@@ -214,3 +214,10 @@ v0.8.1
* nfqws2: conntrack_feed
* winws2: use windivert bulk mode
* nfqws2: template free import
0.9.1
* nfqws2: 'stat', 'clock_getfloattime' luacalls
* nfqws2: bcryptorandom normalize behavior when system entropy is low. prevent blocks
* nfqws2: --new[=name]
* winws2: fix not setting signal handlers

View File

@@ -75,6 +75,7 @@
- [uname](#uname)
- [clock\_gettime](#clock_gettime)
- [getpid](#getpid)
- [stat](#stat)
- [Packet handling options](#packet-handling-options)
- [standard reconstruct](#standard-reconstruct)
- [standard rawsend](#standard-rawsend)
@@ -648,10 +649,10 @@ DESYNC ENGINE INIT:
--lua-gc=<int> ; Lua garbage collector invocation interval in seconds. 0 disables periodic calls.
MULTI-STRATEGY:
--new ; start a new profile
--new[=name] ; start a new profile. optionally assign a name
--skip ; ignore the profile
--name=<name> ; set the profile name
--template[=<name>] ; use the profile as a template and assign a name
--template[=<name>] ; use the profile as a template and optionally assign a name
--cookie[=<string>] ; set the value of the "desync.cookie" Lua variable passed to each instance of this profile
--import=<name> ; copy settings from a template into the current profile, overwriting all existing settings
--filter-l3=ipv4|ipv6 ; profile filter: IP protocol version
@@ -1827,8 +1828,10 @@ function bcryptorandom(size)
```
Generates a raw string containing a cryptographically secure block of random data of the specified size. The source is `/dev/random`.
If the entropy pool is exhausted, this function may cause the process to hang (block). To prevent this, install `haveged` or `rngd`.
This should not be used for random data that does not require cryptographic security.
Random data source - getrandom() (Linux), getentropy() (BSD), `/dev/random`.
`/dev/urandom` is used as a fallback if the previous sources failed or block.
lack of entropy pool is typical Android problem.
#### bxor,bor,band
@@ -1954,9 +1957,11 @@ On Windows, it returns a string starting with "CYGWIN" followed by the version.
```
function clock_gettime()
function clock_getfloattime()
```
Retrieves the precise time. Returns two values: Unix time in seconds and the nanosecond component. The built-in `os.time()` function does not provide nanoseconds.
clock_gettime retrieves the precise time. Returns two values: Unix time in seconds and the nanosecond component. The built-in `os.time()` function does not provide nanoseconds.
clock_getfloattime returns unixtime in the floating point format. Nanoseconds go to the fractional part.
#### getpid
@@ -1968,6 +1973,24 @@ function gettid()
- `getpid()` returns the current process identifier (PID).
- `gettid()` returns the current thread identifier (TID).
#### stat
```
function stat(filename)
```
If successful returns the following table :
| Field | Type | Description |
| :------- | :----- | :---------- |
| type | string | file type : file, dir, socket, blockdev, chardev, fifo, unknown |
| size | number | file size |
| mtime | number | modification unixtime in floating point format |
| inode | number | inode. In Windows doesn't fit into number datatype of luajit but fits into integer datatype of Lua5.3+ |
| dev | number | device id |
In case of error returns 3 values : nil, error string, error number (errno).
### Packet handling options
The following functions use standard sets of options: `rawsend` and `reconstruct`.

View File

@@ -72,6 +72,7 @@
- [uname](#uname)
- [clock\_gettime](#clock_gettime)
- [getpid](#getpid)
- [stat](#stat)
- [Опции по работе с пакетами](#опции-по-работе-с-пакетами)
- [standard reconstruct](#standard-reconstruct)
- [standard rawsend](#standard-rawsend)
@@ -707,7 +708,7 @@ DESYNC ENGINE INIT:
--lua-gc=<int> ; интервал вызова сборщика мусора Lua в секундах. 0 отключает периодический вызов.
MULTI-STRATEGY:
--new ; начало нового профиля
--new[=name] ; начало нового профиля. опционально установка имени профиля
--skip ; игнорировать профиль
--name=<name> ; установить имя профиля
--template[=<name>] ; использовать профиль как шаблон, задать имя
@@ -1973,9 +1974,10 @@ nfqws2 не использует никакие криптобиблиотеки
function bcryptorandom(size)
```
Генерирует raw строку - криптографически стойкий блок случайных данных указанного размера. Источник - `/dev/random`.
Если пул энтропии исчерпывается, может вызывать зависания. Чтобы этого не было - установите haveged или rngd.
Не стоит использовать для получения случайных данных, не требующих крипто-стойкости.
Генерирует raw строку - криптографически стойкий блок случайных данных указанного размера.
Источник - getrandom() (Linux), getentropy() (BSD), `/dev/random`.
`/dev/urandom` используется как fallback, если остальные варианты не работают или блокируют.
Отсутствие данных в `/dev/random` - типичная проблема для Android.
#### bxor,bor,band
@@ -2101,9 +2103,11 @@ function uname()
```
function clock_gettime()
function clock_getfloattime()
```
Узнать точное время. Возвращает 2 значения - unixtime в секундах и наносекунды. Встроенная функция `os.time()` не выдает наносекунды.
Узнать точное время. clock_gettime возвращает 2 значения - unixtime в секундах и наносекунды. Встроенная функция `os.time()` не выдает наносекунды.
clock_getfloattime возвращает unixtime в формате с плавающей точкой. Наносекунды идут в дробную часть.
#### getpid
@@ -2115,6 +2119,25 @@ function gettid()
- getpid() возвращает идентификатор текущего процесса - PID
- gettid() возвращает идентификатор текущего потока - TID
#### stat
```
function stat(filename)
```
В случае успеха возвращает таблицу :
| Поле | Тип | Описание |
| :------- | :----- | :---------- |
| type | string | тип файла : file, dir, socket, blockdev, chardev, fifo, unknown |
| size | number | размер файла |
| mtime | number | unixtime время модификации в формате с плавающей точкой |
| inode | number | inode. на Windows не влезает в тип number luajit, но влезает в integer Lua 5.3+ |
| dev | number | device id |
В случае неудачи возвращает 3 значения : nil, строка ошибки, код ошибки errno.
### Опции по работе с пакетами
В следующих функциях будут использоваться стандартные наборы опций - rawsend и reconstruct.

View File

@@ -1,3 +1,4 @@
#define _GNU_SOURCE
#include "conntrack.h"
#include "darkmagic.h"
#include <arpa/inet.h>
@@ -66,7 +67,7 @@ void ConntrackPoolInit(t_conntrack *p, time_t purge_interval, uint32_t timeout_s
p->timeout_fin = timeout_fin;
p->timeout_udp = timeout_udp;
p->t_purge_interval = purge_interval;
time(&p->t_last_purge);
p->t_last_purge = boottime();
p->pool = NULL;
}
@@ -215,7 +216,7 @@ static void ConntrackFeedPacket(t_ctrack *t, bool bReverse, const struct dissect
ConntrackApplyPos(t, bReverse, dis);
}
clock_gettime(CLOCK_REALTIME, &t->pos.t_last);
clock_gettime(CLOCK_BOOT_OR_UPTIME, &t->pos.t_last);
// make sure t_start gets exactly the same value as first t_last
if (!t->t_start.tv_sec) t->t_start = t->pos.t_last;
}
@@ -314,14 +315,14 @@ bool ConntrackPoolDrop(t_conntrack *p, const struct dissect *dis)
void ConntrackPoolPurge(t_conntrack *p)
{
time_t tidle;
struct timespec tnow;
time_t tnow;
t_conntrack_pool *t, *tmp;
if (clock_gettime(CLOCK_REALTIME, &tnow)) return;
if ((tnow.tv_sec - p->t_last_purge) >= p->t_purge_interval)
if (!(tnow=boottime())) return;
if ((tnow - p->t_last_purge) >= p->t_purge_interval)
{
HASH_ITER(hh, p->pool, t, tmp) {
tidle = tnow.tv_sec - t->track.pos.t_last.tv_sec;
tidle = tnow - t->track.pos.t_last.tv_sec;
if (t->track.b_cutoff ||
(t->conn.l4proto == IPPROTO_TCP && (
(t->track.pos.state == SYN && tidle >= p->timeout_syn) ||
@@ -333,7 +334,7 @@ void ConntrackPoolPurge(t_conntrack *p)
HASH_DEL(p->pool, t); ConntrackFreeElem(t);
}
}
p->t_last_purge = tnow.tv_sec;
p->t_last_purge = tnow;
}
}
@@ -345,10 +346,10 @@ static void taddr2str(uint8_t l3proto, const t_addr *a, char *buf, size_t bufsiz
void ConntrackPoolDump(const t_conntrack *p)
{
t_conntrack_pool *t, *tmp;
struct timespec tnow;
time_t tnow;
char sa1[40], sa2[40];
if (clock_gettime(CLOCK_REALTIME, &tnow)) return;
if (!(tnow=boottime())) return;
HASH_ITER(hh, p->pool, t, tmp) {
taddr2str(t->conn.l3proto, &t->conn.src, sa1, sizeof(sa1));
taddr2str(t->conn.l3proto, &t->conn.dst, sa2, sizeof(sa2));
@@ -356,7 +357,7 @@ void ConntrackPoolDump(const t_conntrack *p)
proto_name(t->conn.l4proto),
sa1, t->conn.sport, sa2, t->conn.dport,
t->conn.l4proto == IPPROTO_TCP ? connstate_s[t->track.pos.state] : "-",
(unsigned long long)t->track.t_start.tv_sec, (unsigned long long)(t->track.pos.t_last.tv_sec - t->track.t_start.tv_sec), (unsigned long long)(tnow.tv_sec - t->track.pos.t_last.tv_sec),
(unsigned long long)t->track.t_start.tv_sec, (unsigned long long)(t->track.pos.t_last.tv_sec - t->track.t_start.tv_sec), (unsigned long long)(tnow - t->track.pos.t_last.tv_sec),
(unsigned long long)t->track.pos.client.pdcounter, (unsigned long long)t->track.pos.client.pcounter, (unsigned long long)t->track.pos.client.pbcounter,
(unsigned long long)t->track.pos.server.pdcounter, (unsigned long long)t->track.pos.server.pcounter, (unsigned long long)t->track.pos.server.pbcounter);
if (t->conn.l4proto == IPPROTO_TCP)
@@ -418,7 +419,7 @@ bool ReasmFeed(t_reassemble *reasm, uint32_t seq, const void *payload, size_t le
if ((reasm->size_present - neg_overlap + szcopy) > reasm->size)
return false; // buffer overflow
// in case of seq overlap new data replaces old - unix behavior
memcpy(reasm->packet + reasm->size_present - neg_overlap, payload + szignore, szcopy);
memcpy(reasm->packet + reasm->size_present - neg_overlap, (const uint8_t*)payload + szignore, szcopy);
if (szcopy>neg_overlap)
{
reasm->size_present += szcopy - neg_overlap;

View File

@@ -2169,7 +2169,7 @@ static time_t wlan_info_last = 0;
static bool wlan_info_rate_limited(struct mnl_socket* nl, uint16_t wlan_family_id, struct wlan_interface_collection* w)
{
bool bres = true;
time_t now = time(NULL);
time_t now = boottime();
// do not purge too often to save resources
if (wlan_info_last != now)

View File

@@ -1,6 +1,7 @@
#define _GNU_SOURCE
#include "helpers.h"
#include "random.h"
#include <stdio.h>
#include <string.h>
@@ -9,6 +10,7 @@
#include <ctype.h>
#include <libgen.h>
#include <errno.h>
#include <sys/param.h>
#define UNIQ_SORT \
{ \
@@ -472,14 +474,72 @@ void fill_random_az09(uint8_t *p,size_t sz)
p[k] = rnd<10 ? rnd+'0' : 'a'+rnd-10;
}
}
#if defined(__FreeBSD__) && __FreeBSD_version <= 1200000
#include <sys/sysctl.h>
int getentropy(void *buf, size_t len)
{
int mib[2];
size_t size = len;
// Check for reasonable length (getentropy limits to 256)
if (len > 256) {
errno = EIO;
return -1;
}
mib[0] = CTL_KERN;
mib[1] = KERN_ARND;
if (sysctl(mib, 2, buf, &size, NULL, 0) == -1) {
return -1;
}
return (size == len) ? 0 : -1;
}
#endif
bool fill_crypto_random_bytes(uint8_t *p,size_t sz)
{
bool b;
FILE *F = fopen("/dev/random","rb");
if (!F) return false;
b = fread(p,sz,1,F)==1;
fclose(F);
return b;
ssize_t rd;
int fd;
#if defined(__linux__) || defined(__CYGWIN__)
for(; sz && (rd=getrandom(p,sz,GRND_NONBLOCK))>0 ; p+=rd, sz-=rd);
if (sz)
#elif defined(BSD)
while(sz)
{
rd = sz<256 ? sz : 256; // BSD limitation
if (getentropy(p,rd)) break;
p+=rd; sz-=rd;
}
if (sz)
#endif
{
if ((fd = open("/dev/random",O_NONBLOCK))>=0)
{
do
{
if ((rd=read(fd,p,sz))>0)
{
p+=rd; sz-=rd;
}
} while(sz && rd>0);
close(fd);
}
if (sz && (fd = open("/dev/urandom",0))>=0)
{
do
{
if ((rd=read(fd,p,sz))>0)
{
p+=rd; sz-=rd;
}
} while(sz && rd>0);
close(fd);
}
}
return !sz;
}
#if defined(__GNUC__) && !defined(__llvm__)
@@ -581,3 +641,9 @@ const struct in6_addr *mask_from_bitcount6(uint32_t zct)
{
return ip6_mask+zct;
}
time_t boottime(void)
{
struct timespec ts;
return clock_gettime(CLOCK_BOOT_OR_UPTIME, &ts) ? 0 : ts.tv_sec;
}

View File

@@ -85,6 +85,10 @@ time_t file_mod_time(const char *filename);
bool file_size(const char *filename, off_t *size);
bool file_open_test(const char *filename, int flags);
#if defined(__FreeBSD__) && __FreeBSD_version <= 1200000
int getentropy(void *buf, size_t len);
#endif
void fill_random_bytes(uint8_t *p,size_t sz);
void fill_random_az(uint8_t *p,size_t sz);
void fill_random_az09(uint8_t *p,size_t sz);
@@ -104,3 +108,13 @@ bool parse_int16(const char *p, int16_t *v);
uint32_t mask_from_bitcount(uint32_t zct);
void mask_from_bitcount6_prepare(void);
const struct in6_addr *mask_from_bitcount6(uint32_t zct);
#ifdef CLOCK_BOOTTIME
#define CLOCK_BOOT_OR_UPTIME CLOCK_BOOTTIME
#elif defined(CLOCK_UPTIME)
#define CLOCK_BOOT_OR_UPTIME CLOCK_UPTIME
#else
#define CLOCK_BOOT_OR_UPTIME CLOCK_MONOTINIC
#endif
time_t boottime(void);

View File

@@ -465,41 +465,41 @@ static int luacall_divint(lua_State *L)
static int luacall_brandom(lua_State *L)
{
lua_check_argc(L,"brandom",1);
LUA_STACK_GUARD_ENTER(L)
lua_Integer len = luaL_checkinteger(L,1);
if (len<0) luaL_error(L, "brandom: invalid arg");
uint8_t *p = malloc(len);
if (!p) luaL_error(L, "out of memory");
uint8_t *p = lua_newuserdata(L, len);
fill_random_bytes(p,len);
// in out of memory condition this will leave p unfreed
lua_pushlstring(L,(char*)p,len);
free(p);
return 1;
lua_remove(L,-2);
LUA_STACK_GUARD_RETURN(L,1)
}
static int luacall_brandom_az(lua_State *L)
{
lua_check_argc(L,"brandom_az",1);
LUA_STACK_GUARD_ENTER(L)
lua_Integer len = luaL_checkinteger(L,1);
if (len<0) luaL_error(L, "brandom_az: invalid arg");
uint8_t *p = malloc(len);
if (!p) luaL_error(L, "out of memory");
if (len<0) luaL_error(L, "brandom: invalid arg");
uint8_t *p = lua_newuserdata(L, len);
fill_random_az(p,len);
// in out of memory condition this will leave p unfreed
lua_pushlstring(L,(char*)p,len);
free(p);
return 1;
lua_remove(L,-2);
LUA_STACK_GUARD_RETURN(L,1)
}
static int luacall_brandom_az09(lua_State *L)
{
lua_check_argc(L,"brandom_az09",1);
LUA_STACK_GUARD_ENTER(L)
lua_Integer len = luaL_checkinteger(L,1);
if (len<0) luaL_error(L, "brandom_az09: invalid arg");
uint8_t *p = malloc(len);
if (!p) luaL_error(L, "out of memory");
if (len<0) luaL_error(L, "brandom: invalid arg");
uint8_t *p = lua_newuserdata(L, len);
fill_random_az09(p,len);
// in out of memory condition this will leave p unfreed
lua_pushlstring(L,(char*)p,len);
free(p);
return 1;
lua_remove(L,-2);
LUA_STACK_GUARD_RETURN(L,1)
}
// hacky function. breaks immutable string behavior.
@@ -537,16 +537,14 @@ static int luacall_parse_hex(lua_State *L)
const char *hex = lua_reqlstring(L,1,&l);
if ((l&1)) goto err;
l>>=1;
uint8_t *p = malloc(l);
if (!p) goto err;
uint8_t *p = lua_newuserdata(L, l);
if (!parse_hex_str(hex,p,&l))
{
free(p);
lua_pop(L,1);
goto err;
}
// in out of memory condition this will leave p unfreed
lua_pushlstring(L,(char*)p,l);
free(p);
lua_remove(L,-2);
ex:
LUA_STACK_GUARD_RETURN(L,1)
err:
@@ -577,18 +575,15 @@ static int luacall_bcryptorandom(lua_State *L)
lua_Integer len = luaL_checkinteger(L,1);
if (len<0) luaL_error(L, "bcryptorandom: invalid arg");
uint8_t *p = malloc(len);
if (!p) luaL_error(L, "out of memory");
uint8_t *p = lua_newuserdata(L, len);
if (!fill_crypto_random_bytes(p,len))
{
free(p);
// this is fatal. they expect us to give them crypto secure random blob
luaL_error(L, "could not read random data from /dev/random");
luaL_error(L, "could not get entropy bytes");
}
lua_pushlstring(L,(char*)p,len);
free(p);
lua_remove(L,-2);
LUA_STACK_GUARD_RETURN(L,1)
}
@@ -603,13 +598,12 @@ static int luac_bop(lua_State *L, const char *name, void (*op)(const uint8_t *x1
const uint8_t *d1 = (const uint8_t*)lua_reqlstring(L,1,&sz1);
const uint8_t *d2 = (const uint8_t*)lua_reqlstring(L,2,&sz2);
if (sz1!=sz2) luaL_error(L, "string lengths must be the same\n");
uint8_t *d3 = malloc(sz1);
if (!d3) luaL_error(L, "out of memory");
uint8_t *d3 = lua_newuserdata(L, sz1);
op(d1,d2,d3,sz1);
lua_pushlstring(L,(char*)d3,sz1);
free(d3);
lua_remove(L,-2);
LUA_STACK_GUARD_RETURN(L,1)
}
@@ -699,8 +693,7 @@ static int luacall_aes_gcm(lua_State *L)
const uint8_t *add = lua_isnoneornil(L,5) ? NULL : (uint8_t*)lua_reqlstring(L,5,&add_len);
uint8_t atag[16];
uint8_t *output = malloc(input_len);
if (!output) luaL_error(L, "out of memory");
uint8_t *output = lua_newuserdata(L, input_len);
if (aes_gcm_crypt(bEncrypt, output, input, input_len, key, key_len, iv, iv_len, add, add_len, atag, sizeof(atag)))
{
@@ -712,7 +705,7 @@ static int luacall_aes_gcm(lua_State *L)
lua_pushlstring(L,(const char*)output,input_len);
lua_pushlstring(L,(const char*)atag,sizeof(atag));
}
free(output);
lua_remove(L,-3);
LUA_STACK_GUARD_RETURN(L,2)
}
@@ -737,14 +730,14 @@ static int luacall_aes_ctr(lua_State *L)
size_t input_len;
const uint8_t *input = (uint8_t*)luaL_checklstring(L,3,&input_len);
uint8_t *output = malloc(input_len);
if (!output) luaL_error(L, "out of memory");
uint8_t *output = lua_newuserdata(L, input_len);
if (aes_ctr_crypt(key, key_len, iv, input, input_len, output))
lua_pushnil(L);
else
lua_pushlstring(L,(const char*)output,input_len);
free(output);
lua_remove(L,-2);
LUA_STACK_GUARD_RETURN(L,1)
}
@@ -768,15 +761,14 @@ static int luacall_hkdf(lua_State *L)
lua_Integer okm_len = luaL_checkinteger(L,5);
if (okm_len<0) luaL_error(L, "hkdf: invalid arg");
uint8_t *okm = malloc(okm_len);
if (!okm) luaL_error(L, "out of memory");
uint8_t *okm = lua_newuserdata(L, okm_len);
if (hkdf(sha_ver, salt, salt_len, ikm, ikm_len, info, info_len, okm, okm_len))
lua_pushnil(L);
else
lua_pushlstring(L,(const char*)okm, okm_len);
free(okm);
lua_remove(L,-2);
LUA_STACK_GUARD_RETURN(L,1)
}
@@ -846,8 +838,23 @@ static int luacall_clock_gettime(lua_State *L)
lua_pushlint(L, ts.tv_sec);
lua_pushinteger(L, ts.tv_nsec);
}
LUA_STACK_GUARD_RETURN(L,2)
}
static int luacall_clock_getfloattime(lua_State *L)
{
lua_check_argc(L,"clock_getfloattime", 0);
LUA_STACK_GUARD_ENTER(L)
struct timespec ts;
if (clock_gettime(CLOCK_REALTIME, &ts))
lua_pushnil(L);
else
lua_pushnumber(L, ts.tv_sec + ts.tv_nsec/1000000000.);
LUA_STACK_GUARD_RETURN(L,1)
}
static void lua_mt_init_desync_ctx(lua_State *L)
{
@@ -2653,8 +2660,7 @@ static int luacall_csum_tcp_fix(lua_State *L)
luaL_error(L, "invalid payload length");
size_t l_tpl = l_tcp + l_pl;
uint8_t *tpl = malloc(l_tpl);
if (!tpl) luaL_error(L, "out of memory");
uint8_t *tpl = lua_newuserdata(L, l_tpl);
memcpy(tpl, b_tcp, l_tcp);
memcpy(tpl+l_tcp, b_pl, l_pl);
@@ -2662,7 +2668,7 @@ static int luacall_csum_tcp_fix(lua_State *L)
tcp_fix_checksum(tcp, l_tpl, ip, ip6);
lua_pushlstring(L,(char*)tpl,l_tcp);
free(tpl);
lua_remove(L,-2);
LUA_STACK_GUARD_RETURN(L,1)
}
@@ -2696,8 +2702,7 @@ static int luacall_csum_udp_fix(lua_State *L)
luaL_error(L, "invalid payload length");
size_t l_tpl = l_udp + l_pl;
uint8_t *tpl = malloc(l_tpl);
if (!tpl) luaL_error(L, "out of memory");
uint8_t *tpl = lua_newuserdata(L, l_tpl);
memcpy(tpl, b_udp, l_udp);
memcpy(tpl+l_udp, b_pl, l_pl);
@@ -2705,7 +2710,7 @@ static int luacall_csum_udp_fix(lua_State *L)
udp_fix_checksum(udp, l_tpl, ip, ip6);
lua_pushlstring(L,(char*)tpl,l_udp);
free(tpl);
lua_remove(L,-2);
LUA_STACK_GUARD_RETURN(L,1)
}
@@ -2739,8 +2744,7 @@ static int luacall_csum_icmp_fix(lua_State *L)
luaL_error(L, "invalid payload length");
size_t l_tpl = l_icmp + l_pl;
uint8_t *tpl = malloc(l_tpl);
if (!tpl) luaL_error(L, "out of memory");
uint8_t *tpl = lua_newuserdata(L, l_tpl);
memcpy(tpl, b_icmp, l_icmp);
memcpy(tpl+l_icmp, b_pl, l_pl);
@@ -2748,7 +2752,7 @@ static int luacall_csum_icmp_fix(lua_State *L)
icmp_fix_checksum(icmp, l_tpl, ip6);
lua_pushlstring(L,(char*)tpl,l_icmp);
free(tpl);
lua_remove(L,-2);
LUA_STACK_GUARD_RETURN(L,1)
}
@@ -2999,74 +3003,71 @@ static int lua_get_ifaddrs(lua_State *L)
ULONG Size=0;
if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAGS, NULL, NULL, &Size)==ERROR_BUFFER_OVERFLOW)
{
PIP_ADAPTER_ADDRESSES pip, pips = (PIP_ADAPTER_ADDRESSES)malloc(Size);
if (pips)
PIP_ADAPTER_ADDRESSES pip, pips = (PIP_ADAPTER_ADDRESSES)lua_newuserdata(L, Size);
if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAGS, NULL, pips, &Size)==ERROR_SUCCESS)
{
if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAGS, NULL, pips, &Size)==ERROR_SUCCESS)
lua_newtable(L);
for(pip=pips; pip ; pip=pip->Next)
{
lua_newtable(L);
for(pip=pips; pip ; pip=pip->Next)
if (!pip->FirstUnicastAddress || pip->OperStatus!=IfOperStatusUp) continue; // disconnected ?
char ifname[16];
snprintf(ifname,sizeof(ifname),"%u.0",pip->IfIndex);
lua_pushf_table(L,ifname);
lua_getfield(L,-1,ifname);
lua_pushf_str(L, "guid", pip->AdapterName);
if (pip->PhysicalAddressLength) lua_pushf_lstr(L, "phys", pip->PhysicalAddress, pip->PhysicalAddressLength);
lua_pushf_int(L, "index", pip->IfIndex);
lua_pushf_int(L, "index6", pip->Ipv6IfIndex);
lua_pushf_int(L, "flags", pip->Flags);
lua_pushf_lint(L, "mtu", pip->Mtu);
lua_pushf_int(L, "iftype", pip->IfType);
lua_pushf_lint(L, "speed_xmit", pip->TransmitLinkSpeed);
lua_pushf_lint(L, "speed_recv", pip->ReceiveLinkSpeed);
lua_pushf_lint(L, "metric4", pip->Ipv4Metric);
lua_pushf_lint(L, "metric6", pip->Ipv6Metric);
lua_pushf_lint(L, "conntype", pip->ConnectionType);
lua_pushf_lint(L, "tunneltype", pip->TunnelType);
lua_pushf_table(L,"addr");
lua_getfield(L,-1,"addr");
int n;
uint32_t a4,a44;
PIP_ADAPTER_UNICAST_ADDRESS_LH pa;
for(pa=pip->FirstUnicastAddress, n=1; pa ; pa=pa->Next, n++)
{
if (!pip->FirstUnicastAddress || pip->OperStatus!=IfOperStatusUp) continue; // disconnected ?
char ifname[16];
snprintf(ifname,sizeof(ifname),"%u.0",pip->IfIndex);
lua_pushf_table(L,ifname);
lua_getfield(L,-1,ifname);
lua_pushf_str(L, "guid", pip->AdapterName);
if (pip->PhysicalAddressLength) lua_pushf_lstr(L, "phys", pip->PhysicalAddress, pip->PhysicalAddressLength);
lua_pushf_int(L, "index", pip->IfIndex);
lua_pushf_int(L, "index6", pip->Ipv6IfIndex);
lua_pushf_int(L, "flags", pip->Flags);
lua_pushf_lint(L, "mtu", pip->Mtu);
lua_pushf_int(L, "iftype", pip->IfType);
lua_pushf_lint(L, "speed_xmit", pip->TransmitLinkSpeed);
lua_pushf_lint(L, "speed_recv", pip->ReceiveLinkSpeed);
lua_pushf_lint(L, "metric4", pip->Ipv4Metric);
lua_pushf_lint(L, "metric6", pip->Ipv6Metric);
lua_pushf_lint(L, "conntype", pip->ConnectionType);
lua_pushf_lint(L, "tunneltype", pip->TunnelType);
lua_pushf_table(L,"addr");
lua_getfield(L,-1,"addr");
int n;
uint32_t a4,a44;
PIP_ADAPTER_UNICAST_ADDRESS_LH pa;
for(pa=pip->FirstUnicastAddress, n=1; pa ; pa=pa->Next, n++)
lua_pushi_table(L, n);
lua_rawgeti(L, -1, n);
lua_pushf_ipaddr(L, "addr", pa->Address.lpSockaddr);
switch(pa->Address.lpSockaddr->sa_family)
{
lua_pushi_table(L, n);
lua_rawgeti(L, -1, n);
lua_pushf_ipaddr(L, "addr", pa->Address.lpSockaddr);
switch(pa->Address.lpSockaddr->sa_family)
{
case AF_INET:
if (pa->OnLinkPrefixLength<=32)
{
a44 = mask_from_bitcount(pa->OnLinkPrefixLength);
a4 = ~a44;
lua_pushf_lstr(L, "netmask", (const char*)&a4, 4);
a4 &= ((struct sockaddr_in*)pa->Address.lpSockaddr)->sin_addr.s_addr;
a4 |= a44;
lua_pushf_lstr(L, "broadcast", (const char*)&a4, 4);
}
break;
case AF_INET6:
if (pa->OnLinkPrefixLength<=128)
{
lua_pushf_lstr(L, "netmask", (const char*)mask_from_bitcount6(128 - pa->OnLinkPrefixLength), 16);
}
break;
}
lua_pushf_ipaddr(L, "addr", pa->Address.lpSockaddr);
lua_pop(L,1);
case AF_INET:
if (pa->OnLinkPrefixLength<=32)
{
a44 = mask_from_bitcount(pa->OnLinkPrefixLength);
a4 = ~a44;
lua_pushf_lstr(L, "netmask", (const char*)&a4, 4);
a4 &= ((struct sockaddr_in*)pa->Address.lpSockaddr)->sin_addr.s_addr;
a4 |= a44;
lua_pushf_lstr(L, "broadcast", (const char*)&a4, 4);
}
break;
case AF_INET6:
if (pa->OnLinkPrefixLength<=128)
{
lua_pushf_lstr(L, "netmask", (const char*)mask_from_bitcount6(128 - pa->OnLinkPrefixLength), 16);
}
break;
}
lua_pop(L,2);
lua_pushf_ipaddr(L, "addr", pa->Address.lpSockaddr);
lua_pop(L,1);
}
lua_pop(L,2);
}
free (pips);
lua_remove(L,-2);
goto ok;
}
lua_remove(L,-1);
}
lua_pushnil(L);
@@ -3294,14 +3295,14 @@ static int luacall_tls_mod(lua_State *L)
if (mod.mod)
{
size_t newlen = fake_tls_len, maxlen = fake_tls_len + sizeof(mod.sni) + 4;
uint8_t *newtls = malloc(maxlen);
if (!newtls) luaL_error(L, "out of memory");
uint8_t *newtls = lua_newuserdata(L, maxlen);
memcpy(newtls, fake_tls, newlen);
bRes = TLSMod(&mod, payload, payload_len, newtls, &newlen, maxlen);
lua_pushlstring(L,(char*)newtls,newlen);
free(newtls);
lua_remove(L,-2);
}
else
{
@@ -3568,6 +3569,51 @@ zerr:
goto end;
}
static int luacall_stat(lua_State *L)
{
// stat(filename) return stat_table or nil,strerror,errno
lua_check_argc(L,"stat",1);
int n=1;
struct stat st;
if (stat(luaL_checkstring(L,1), &st))
{
lua_pushnil(L);
const char *err = strerror(errno);
if (err)
{
lua_pushstring(L,err);
lua_pushinteger(L,errno);
return 3;
}
}
else
{
lua_createtable(L, 0, 5);
lua_pushf_lint(L,"dev", st.st_dev);
lua_pushf_lint(L,"inode", st.st_ino);
lua_pushf_lint(L,"size", st.st_size);
lua_pushf_number(L,"mtime", st.st_mtim.tv_sec + st.st_mtim.tv_nsec/1000000000.);
const char *ftype;
switch(st.st_mode & S_IFMT)
{
case S_IFREG: ftype="file"; break;
case S_IFDIR: ftype="dir"; break;
case S_IFLNK: ftype="symlink"; break;
case S_IFSOCK: ftype="socket"; break;
case S_IFBLK: ftype="blockdev"; break;
case S_IFCHR: ftype="chardev"; break;
case S_IFIFO: ftype="fifo"; break;
default: ftype="unknown"; break;
}
lua_pushf_str(L, "type", ftype);
}
return 1;
}
// ----------------------------------------
void lua_cleanup(lua_State *L)
@@ -4029,7 +4075,6 @@ static void lua_init_const(void)
{"ICMP6_PARAMPROB_HEADER",ICMP6_PARAMPROB_HEADER},
{"ICMP6_PARAMPROB_NEXTHEADER",ICMP6_PARAMPROB_NEXTHEADER},
{"ICMP6_PARAMPROB_OPTION",ICMP6_PARAMPROB_OPTION}
};
DLOG("\nLUA NUMERIC:");
for (int i=0;i<sizeof(cuint)/sizeof(*cuint);i++)
@@ -4161,6 +4206,7 @@ static void lua_init_functions(void)
// system functions
{"uname",luacall_uname},
{"clock_gettime",luacall_clock_gettime},
{"clock_getfloattime",luacall_clock_getfloattime},
{"getpid",luacall_getpid},
{"gettid",luacall_gettid},
@@ -4209,7 +4255,10 @@ static void lua_init_functions(void)
// gzip compress
{"gzip_init",luacall_gzip_init},
{"gzip_end",luacall_gzip_end},
{"gzip_deflate",luacall_gzip_deflate}
{"gzip_deflate",luacall_gzip_deflate},
// stat() - file size, mod time
{"stat",luacall_stat}
};
for(int i=0;i<(sizeof(lfunc)/sizeof(*lfunc));i++)
lua_register(params.L,lfunc[i].name,lfunc[i].f);

View File

@@ -426,7 +426,10 @@ static int nfq_main(void)
if (r) DLOG_ERR("nfq_handle_packet error %d\n", r);
}
else
DLOG("recv from nfq returned 0 !\n");
{
DLOG_ERR("recv from nfq returned 0 !\n");
goto err;
}
}
if (errno==EINTR)
{
@@ -695,6 +698,8 @@ static int win_main()
res=ERROR_NOT_ENOUGH_MEMORY; goto ex;
}
catch_signals();
for (;;)
{
if (!logical_net_filter_match())
@@ -1676,7 +1681,7 @@ static void exithelp(void)
" --lua-init=@<filename>|<lua_text>\t\t\t; load LUA program from a file or string. if multiple parameters present order of execution is preserved. gzipped files are supported.\n"
" --lua-gc=<int>\t\t\t\t\t\t; forced garbage collection every N sec. default %u sec. triggers only when a packet arrives. 0 = disable.\n"
"\nMULTI-STRATEGY:\n"
" --new\t\t\t\t\t\t\t; begin new profile\n"
" --new[=<name>]\t\t\t\t\t\t\t; begin new profile. optionally set name\n"
" --skip\t\t\t\t\t\t\t; do not use this profile\n"
" --name=<name>\t\t\t\t\t\t; set profile name\n"
" --template[=<name>]\t\t\t\t\t; use this profile as template (must be named or will be useless)\n"
@@ -1926,7 +1931,7 @@ static const struct option long_options[] = {
[IDX_HOSTLIST_AUTO_UDP_IN] = {"hostlist-auto-udp-in", required_argument, 0, 0},
[IDX_HOSTLIST_AUTO_UDP_OUT] = {"hostlist-auto-udp-out", required_argument, 0, 0},
[IDX_HOSTLIST_AUTO_DEBUG] = {"hostlist-auto-debug", required_argument, 0, 0},
[IDX_NEW] = {"new", no_argument, 0, 0},
[IDX_NEW] = {"new", optional_argument, 0, 0},
[IDX_SKIP] = {"skip", no_argument, 0, 0},
[IDX_NAME] = {"name", required_argument, 0, 0},
[IDX_TEMPLATE] = {"template", optional_argument, 0, 0},
@@ -2486,6 +2491,11 @@ int main(int argc, char **argv)
dp = &dpl->dp;
dp->n = desync_profile_count;
}
if (optarg && !(dp->name = strdup(optarg)))
{
DLOG_ERR("out of memory\n");
exit_clean(1);
}
anon_hl = anon_hl_exclude = NULL;
anon_ips = anon_ips_exclude = NULL;
payload_type = 0;

View File

@@ -446,7 +446,7 @@ bool dp_copy(struct desync_profile *to, const struct desync_profile *from)
free(to->cookie);
if (!(to->cookie = strdup(from->cookie))) return false;
}
if (from->hostlist_auto)
if (from->hostlist_auto && from->hostlist_auto!=to->hostlist_auto)
{
if (to->hostlist_auto)
{

View File

@@ -86,7 +86,7 @@ hostfail_pool * HostFailPoolAdd(hostfail_pool **pp,const char *s,int fail_time)
{
size_t slen = strlen(s);
ADD_STR_POOL(hostfail_pool, pp, s, slen)
elem->expire = time(NULL) + fail_time;
elem->expire = boottime() + fail_time;
elem->counter = 0;
return elem;
}
@@ -105,7 +105,7 @@ void HostFailPoolDel(hostfail_pool **p, hostfail_pool *elem)
void HostFailPoolPurge(hostfail_pool **pp)
{
hostfail_pool *elem, *tmp;
time_t now = time(NULL);
time_t now = boottime();
HASH_ITER(hh, *pp, elem, tmp)
{
if (now >= elem->expire)
@@ -114,7 +114,7 @@ void HostFailPoolPurge(hostfail_pool **pp)
}
void HostFailPoolPurgeRateLimited(hostfail_pool **pp, time_t *purge_prev)
{
time_t now = time(NULL);
time_t now = boottime();
// do not purge too often to save resources
if (*purge_prev != now)
{
@@ -125,7 +125,7 @@ void HostFailPoolPurgeRateLimited(hostfail_pool **pp, time_t *purge_prev)
void HostFailPoolDump(hostfail_pool *p)
{
hostfail_pool *elem, *tmp;
time_t now = time(NULL);
time_t now = boottime();
HASH_ITER(hh, p, elem, tmp)
printf("host=%s counter=%d time_left=%lld\n",elem->str,elem->counter,(long long int)elem->expire-now);
}
@@ -966,7 +966,7 @@ struct blob_item *blob_collection_search_name(struct blob_collection_head *head,
static void ipcache_item_touch(ip_cache_item *item)
{
time(&item->last);
item->last = boottime();
}
static void ipcache_item_init(ip_cache_item *item)
{
@@ -1029,7 +1029,7 @@ static void ipcache4Print(ip_cache4 *ipcache)
time_t now;
ip_cache4 *ipc, *tmp;
time(&now);
now = boottime();
HASH_ITER(hh, ipcache , ipc, tmp)
{
*s_ip=0;
@@ -1087,7 +1087,7 @@ static void ipcache6Print(ip_cache6 *ipcache)
time_t now;
ip_cache6 *ipc, *tmp;
time(&now);
now = boottime();
HASH_ITER(hh, ipcache , ipc, tmp)
{
*s_ip=0;
@@ -1133,7 +1133,7 @@ ip_cache_item *ipcacheTouch(ip_cache *ipcache, const struct in_addr *a4, const s
static void ipcache4_purge(ip_cache4 **ipcache, time_t lifetime)
{
ip_cache4 *elem, *tmp;
time_t now = time(NULL);
time_t now = boottime();
HASH_ITER(hh, *ipcache, elem, tmp)
{
if (now >= (elem->data.last + lifetime))
@@ -1147,7 +1147,7 @@ static void ipcache4_purge(ip_cache4 **ipcache, time_t lifetime)
static void ipcache6_purge(ip_cache6 **ipcache, time_t lifetime)
{
ip_cache6 *elem, *tmp;
time_t now = time(NULL);
time_t now = boottime();
HASH_ITER(hh, *ipcache, elem, tmp)
{
if (now >= (elem->data.last + lifetime))
@@ -1169,7 +1169,7 @@ static void ipcache_purge(ip_cache *ipcache, time_t lifetime)
static time_t ipcache_purge_prev=0;
void ipcachePurgeRateLimited(ip_cache *ipcache, time_t lifetime)
{
time_t now = time(NULL);
time_t now = boottime();
// do not purge too often to save resources
if (ipcache_purge_prev != now)
{

View File

@@ -4,7 +4,6 @@
#include <ctype.h>
#include <sys/queue.h>
#include <net/if.h>
#include <time.h>
#include "helpers.h"
#include "filter.h"

36
nfq2/random.c Normal file
View File

@@ -0,0 +1,36 @@
#include "random.h"
#ifdef NEED_GETRANDOM
#include <unistd.h>
#ifndef SYS_getrandom
#if defined(__aarch64__)
#define SYS_getrandom 278
#elif defined(__arm__)
/* ARM EABI */
#define SYS_getrandom 384
#elif defined(__x86_64__)
#define SYS_getrandom 318
#elif defined(__i386__)
#define SYS_getrandom 355
#elif defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32
#define SYS_getrandom 4353
#else
#error "Unsupported architecture: SYS_getrandom not defined"
#endif
#endif
ssize_t getrandom(void *ptr, size_t len, unsigned int flags)
{
return syscall(SYS_getrandom, ptr, len, flags);
}
#endif

31
nfq2/random.h Normal file
View File

@@ -0,0 +1,31 @@
#pragma once
// shim for old NDK and old gcc linux compilers
#if defined(__linux__)
#include <sys/syscall.h>
#if defined(__ANDROID__) && __ANDROID_API__ < 28 || !defined(SYS_getrandom)
#define NEED_GETRANDOM
#include <sys/types.h>
/* getrandom flags */
#define GRND_NONBLOCK 1
#define GRND_RANDOM 2
ssize_t getrandom(void *ptr, size_t len, unsigned int flags);
#else
#include <sys/random.h>
#endif
#elif defined(__CYGWIN__)
#include <sys/random.h>
#endif