0
0
mirror of https://github.com/hufrea/byedpi.git synced 2025-08-22 19:28:40 +00:00

avl, --hosts, --dst

This commit is contained in:
ruti 2024-04-16 20:55:41 +03:00
parent 38d44ec1ca
commit 3b65b275b1
7 changed files with 296 additions and 163 deletions

View File

@ -73,6 +73,7 @@ struct eval {
}; };
ssize_t recv_count; ssize_t recv_count;
int attempt; int attempt;
char cache;
#ifndef NOEPOLL #ifndef NOEPOLL
uint32_t events; uint32_t events;
#endif #endif

109
main.c
View File

@ -17,12 +17,13 @@
#include <netdb.h> #include <netdb.h>
#include <fcntl.h> #include <fcntl.h>
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <sys/mman.h>
#else #else
#include <ws2tcpip.h> #include <ws2tcpip.h>
#define close(fd) closesocket(fd) #define close(fd) closesocket(fd)
#endif #endif
#define VERSION "8.1" #define VERSION "10"
#define MPOOL_INC 16 #define MPOOL_INC 16
@ -71,12 +72,15 @@ const char help_text[] = {
#ifdef TCP_FASTOPEN_CONNECT #ifdef TCP_FASTOPEN_CONNECT
" -F, --tfo Enable TCP Fast Open\n" " -F, --tfo Enable TCP Fast Open\n"
#endif #endif
" -A, --auto[=t,r,c,s,a] Try desync params after this option\n" " -L, --late-conn Waiting for request before connecting\n"
" Detect: torst,redirect,cl_err,sid_inv,alert\n" " -A, --auto[=t,r,c,s,a,n] Try desync params after this option\n"
" Detect: torst,redirect,cl_err,sid_inv,alert,nop\n"
" -u, --cache-ttl <sec> Lifetime of cached desync params for IP\n" " -u, --cache-ttl <sec> Lifetime of cached desync params for IP\n"
#ifdef TIMEOUT_SUPPORT #ifdef TIMEOUT_SUPPORT
" -T, --timeout <sec> Timeout waiting for response, after which trigger auto\n" " -T, --timeout <sec> Timeout waiting for response, after which trigger auto\n"
#endif #endif
" -H, --hosts <file|:str> Hosts whitelist\n"
" -D, --dst <addr> Custom destination IP\n"
" -s, --split <n[+s]> Split packet at n\n" " -s, --split <n[+s]> Split packet at n\n"
" +s - add SNI offset\n" " +s - add SNI offset\n"
" +h - add HTTP Host offset\n" " +h - add HTTP Host offset\n"
@ -115,11 +119,14 @@ const struct option options[] = {
#ifdef TCP_FASTOPEN_CONNECT #ifdef TCP_FASTOPEN_CONNECT
{"tfo ", 0, 0, 'F'}, {"tfo ", 0, 0, 'F'},
#endif #endif
{"late-conn", 0, 0, 'L'},
{"auto", 2, 0, 'A'}, {"auto", 2, 0, 'A'},
{"cache-ttl", 1, 0, 'u'}, {"cache-ttl", 1, 0, 'u'},
#ifdef TIMEOUT_SUPPORT #ifdef TIMEOUT_SUPPORT
{"timeout", 1, 0, 'T'}, {"timeout", 1, 0, 'T'},
#endif #endif
{"hosts", 1, 0, 'H'},
{"dst", 1, 0, 'D'},
{"split", 1, 0, 's'}, {"split", 1, 0, 's'},
{"disorder", 1, 0, 'd'}, {"disorder", 1, 0, 'd'},
{"oob", 1, 0, 'o'}, {"oob", 1, 0, 'o'},
@ -195,16 +202,27 @@ char *ftob(const char *str, ssize_t *sl)
long size; long size;
FILE *file = fopen(str, "rb"); FILE *file = fopen(str, "rb");
if (!file) if (!file) {
return 0; return 0;
}
do { do {
if (fseek(file, 0, SEEK_END)) { if (fseek(file, 0, SEEK_END)) {
break; break;
} }
size = ftell(file); size = ftell(file);
if (!size || fseek(file, 0, SEEK_SET)) { if (size <= 0) {
break; break;
} }
if (fseek(file, 0, SEEK_SET)) {
break;
}
#ifndef _WIN32
buffer = mmap(0, size, PROT_READ, MAP_PRIVATE, fileno(file), 0);
if (buffer == MAP_FAILED) {
buffer = 0;
break;
}
#else
if (!(buffer = malloc(size))) { if (!(buffer = malloc(size))) {
break; break;
} }
@ -212,6 +230,7 @@ char *ftob(const char *str, ssize_t *sl)
free(buffer); free(buffer);
buffer = 0; buffer = 0;
} }
#endif
} while (0); } while (0);
if (buffer) { if (buffer) {
*sl = size; *sl = size;
@ -221,6 +240,33 @@ char *ftob(const char *str, ssize_t *sl)
} }
struct mphdr *parse_hosts(char *buffer, size_t size)
{
struct mphdr *hdr = mem_pool(1);
if (!hdr) {
return 0;
}
char *end = buffer + size;
char *e = buffer, *s = buffer;
for (; e <= end; e++) {
if (*e != ' ' && *e != '\n' && e != end) {
continue;
}
if (s == e) {
s++;
continue;
}
if (mem_add(hdr, s, e - s) == 0) {
free(hdr);
return 0;
}
s = e + 1;
}
return hdr;
}
int get_addr(const char *str, struct sockaddr_ina *addr) int get_addr(const char *str, struct sockaddr_ina *addr)
{ {
struct addrinfo hints = {0}, *res = 0; struct addrinfo hints = {0}, *res = 0;
@ -284,18 +330,23 @@ int parse_offset(struct part *part, const char *str)
void *add(void **root, int *n, size_t ss) void *add(void **root, int *n, size_t ss)
{ {
void *p = realloc(*root, ss * (*n + 1)); char *p = realloc(*root, ss * (*n + 1));
if (!p) { if (!p) {
uniperror("realloc"); uniperror("realloc");
return 0; return 0;
} }
*root = p; *root = p;
p = ((*root) + ((*n) * ss)); p = (p + ((*n) * ss));
memset(p, 0, ss); memset(p, 0, ss);
*n = *n + 1; *n = *n + 1;
return p; return p;
} }
#ifndef _WIN32
#define FREE(p, s) munmap(p, s)
#else
#define FREE(p, s) free(p)
#endif
void clear_params(void) void clear_params(void)
{ {
@ -322,15 +373,15 @@ void clear_params(void)
params.dp = 0; params.dp = 0;
} }
if (fake_tls.data != tls_data) { if (fake_tls.data != tls_data) {
free(fake_tls.data); FREE(fake_tls.data, fake_tls.size);
fake_tls.data = tls_data; fake_tls.data = tls_data;
} }
if (fake_http.data != http_data) { if (fake_http.data != http_data) {
free(fake_http.data); FREE(fake_http.data, fake_http.size);
fake_http.data = http_data; fake_http.data = http_data;
} }
if (oob_data.data != oob_char) { if (oob_data.data != oob_char) {
free(oob_data.data); FREE(oob_data.data, oob_data.size);
oob_data.data = oob_char; oob_data.data = oob_char;
} }
} }
@ -382,6 +433,7 @@ int main(int argc, char **argv)
clear_params(); clear_params();
return -1; return -1;
} }
while (!invalid && (rez = getopt_long_only( while (!invalid && (rez = getopt_long_only(
argc, argv, opt, options, 0)) != -1) { argc, argv, opt, options, 0)) != -1) {
switch (rez) { switch (rez) {
@ -445,6 +497,10 @@ int main(int argc, char **argv)
// desync options // desync options
case 'L':
params.late_conn = 1;
break;
case 'K': case 'K':
params.de_known = 1; params.de_known = 1;
break; break;
@ -482,6 +538,8 @@ int main(int argc, char **argv)
case 'a': case 'a':
dp->detect |= DETECT_TLS_ALERT; dp->detect |= DETECT_TLS_ALERT;
break; break;
case 'n':
break;
default: default:
invalid = 1; invalid = 1;
continue; continue;
@ -512,6 +570,27 @@ int main(int argc, char **argv)
params.timeout = val; params.timeout = val;
break; break;
case 'H':;
char *data = ftob(optarg, &val);
if (!data) {
uniperror("read/parse");
invalid = 1;
}
dp->hosts = parse_hosts(data, val);
if (!dp->hosts) {
perror("parse_hosts");
clear_params();
return -1;
}
break;
case 'D':
if (get_addr(optarg, (struct sockaddr_ina *)&dp->addr) < 0)
invalid = 1;
else
dp->to_ip = 2;
break;
case 's': case 's':
case 'd': case 'd':
case 'o': case 'o':
@ -671,6 +750,14 @@ int main(int argc, char **argv)
clear_params(); clear_params();
return -1; return -1;
} }
if (dp->hosts) {
dp = add((void *)&params.dp,
&params.dp_count, sizeof(struct desync_params));
if (!dp) {
clear_params();
return -1;
}
}
s.in.sin_port = port; s.in.sin_port = port;
b.in.sin_port = 0; b.in.sin_port = 0;
@ -683,7 +770,7 @@ int main(int argc, char **argv)
return -1; return -1;
} }
} }
params.mempool = mem_pool(MPOOL_INC); params.mempool = mem_pool(0);
if (!params.mempool) { if (!params.mempool) {
uniperror("mem_pool"); uniperror("mem_pool");
clear_params(); clear_params();

147
mpool.c
View File

@ -3,129 +3,98 @@
#include <mpool.h> #include <mpool.h>
struct mphdr *mem_pool(int count) static inline int scmp(const struct elem *p, const struct elem *q)
{ {
struct mphdr *hdr = malloc(sizeof(struct mphdr)); if (p->len != q ->len) {
if (!hdr) { return p->len < q->len ? -1 : 1;
return 0; }
return memcmp(p->data, q->data, p->len);
} }
hdr->inc = count;
hdr->max = count;
hdr->count = 0;
hdr->values = malloc(sizeof(*hdr->values) * count); KAVL_INIT(my, struct elem, head, scmp)
if (!hdr->values) {
free(hdr);
hdr = 0; struct mphdr *mem_pool(bool cst)
{
struct mphdr *hdr = calloc(sizeof(struct mphdr), 1);
if (hdr) {
hdr->stat = cst;
} }
return hdr; return hdr;
} }
int mem_index(struct mphdr *hdr, char *str, int len) struct elem *mem_get(struct mphdr *hdr, char *str, int len)
{ {
if (!hdr->count) { struct {
return -2; int len;
} char *data;
int s = 0, m, i; } temp = { .len = len, .data = str };
int e = hdr->count - 1;
while (s <= e) { return kavl_find(my, hdr->root, (struct elem *)&temp, 0);
m = s + (e - s) / 2;
struct elem *val = hdr->values[m];
if (val->len != len)
i = len < val->len ? -1 : 1;
else
i = memcmp(str, val->data, len);
if (i > 0)
s = m + 1;
else if (i < 0)
e = m - 1;
else
return m;
}
return -(m + 2 + (i > 0 ? 1 : 0));
} }
struct elem *mem_add(struct mphdr *hdr, char *str, int len, int pos) struct elem *mem_add(struct mphdr *hdr, char *str, int len)
{ {
int max = hdr->max; struct elem *v, *e = malloc(sizeof(struct elem));
if (!e) {
if (hdr->count >= max) {
max += hdr->inc;
struct elem **new = realloc(hdr->values, sizeof(*hdr->values) * max);
if (!new) {
return 0; return 0;
} }
hdr->max = max; e->len = len;
hdr->values = new; if (!hdr->stat) {
} e->data = malloc(len);
if (pos >= 0) { if (!e->data) {
return hdr->values[pos]; free(e);
}
pos = -pos - 2;
struct elem *val = malloc(sizeof(struct elem) + len);
if (!val) {
return 0; return 0;
} }
memset(val, 0, sizeof(*val)); memcpy(e->data, str, len);
memcpy(val->data, str, len);
val->len = len;
if (pos < hdr->count) {
void *p = &hdr->values[pos];
void *n = &hdr->values[pos + 1];
void *e = &hdr->values[hdr->count];
memmove(n, p, e - p);
} }
hdr->values[pos] = val; else {
hdr->count++; e->data = str;
return val; }
v = kavl_insert(my, &hdr->root, e, 0);
if (e != v) {
if (!hdr->stat) {
free(e->data);
}
free(e);
}
return v;
} }
void mem_delete(struct mphdr *hdr, int pos) void mem_delete(struct mphdr *hdr, char *str, int len)
{ {
int max = hdr->max; struct {
if (!hdr->count) { int len;
char *data;
} temp = { .len = len, .data = str };
struct elem *e = kavl_erase(my, &hdr->root, (struct elem *)&temp, 0);
if (!e) {
return; return;
} }
if (max > hdr->inc && if (!hdr->stat) {
(max - hdr->count) > hdr->inc * 2) { free(e->data);
max -= hdr->inc; e->data = 0;
struct elem **new = realloc(hdr->values, sizeof(*hdr->values) * max);
if (new) {
hdr->max = max;
hdr->values = new;
} }
} free(e);
free(hdr->values[pos]);
if (pos < hdr->count) {
void *p = &hdr->values[pos];
void *n = &hdr->values[pos + 1];
void *e = &hdr->values[hdr->count];
memmove(p, n, e - n);
}
hdr->count--;
} }
void mem_destroy(struct mphdr *hdr) void mem_destroy(struct mphdr *hdr)
{ {
for (int i = 0; i < hdr->count && hdr->values; i++) { while (hdr->root) {
struct elem *e = hdr->values[i]; struct elem *e = kavl_erase_first(my, &hdr->root);
if (!e) { if (!e) {
continue; break;
} }
if (!hdr->stat && e->data) {
free(e->data);
}
e->data = 0;
free(e); free(e);
hdr->values[i] = 0;
} }
free(hdr->values);
memset(hdr, 0, sizeof(*hdr));
free(hdr); free(hdr);
} }

27
mpool.h
View File

@ -1,19 +1,26 @@
#include <stdbool.h>
#include <time.h> #include <time.h>
#include "kavl.h"
struct elem { struct elem {
int len;
char *data;
int m; int m;
time_t time; time_t time;
int len; KAVL_HEAD(struct elem) head;
char data[];
}; };
struct mphdr { struct mphdr {
int max; bool stat;
int inc; struct elem *root;
int count;
struct elem **values;
}; };
struct mphdr *mem_pool(int count);
int mem_index(struct mphdr *hdr, char *str, int len); struct mphdr *mem_pool(bool cst);
struct elem *mem_add(struct mphdr *hdr, char *str, int len, int pos);
void mem_delete(struct mphdr *hdr, int pos); struct elem *mem_get(struct mphdr *hdr, char *str, int len);
struct elem *mem_add(struct mphdr *hdr, char *str, int len);
void mem_delete(struct mphdr *hdr, char *str, int len);
void mem_destroy(struct mphdr *hdr); void mem_destroy(struct mphdr *hdr);

View File

@ -56,6 +56,10 @@ struct desync_params {
int tlsrec_n; int tlsrec_n;
struct part *tlsrec; struct part *tlsrec;
int detect; int detect;
struct mphdr *hosts;
char to_ip;
struct sockaddr_in6 addr;
}; };
struct params { struct params {
@ -67,6 +71,7 @@ struct params {
int def_ttl; int def_ttl;
char custom_ttl; char custom_ttl;
char late_conn;
char tfo; char tfo;
unsigned int timeout; unsigned int timeout;
long cache_ttl; long cache_ttl;

127
proxy.c
View File

@ -497,34 +497,26 @@ static inline int on_tunnel(struct poolhd *pool, struct eval *val,
int mode_add_get(struct sockaddr_ina *dst, int m) int mode_add_get(struct sockaddr_ina *dst, int m)
{ {
// m < 0: get, m > 0: set, m == 0: delete // m < 0: get, m > 0: set, m == 0: delete
int len;
time_t t; time_t t;
struct elem *val; struct elem *val;
char *str = (char *)&dst->in;
struct { int len = sizeof(dst->sa.sa_family);
uint16_t port;
union {
struct in_addr ip4;
struct in6_addr ip6;
};
} str = { .port = dst->in.sin_port };
if (dst->sa.sa_family == AF_INET) { if (dst->sa.sa_family == AF_INET) {
str.ip4 = dst->in.sin_addr; len = sizeof(dst->in);
len = sizeof(str.port) + sizeof(str.ip4);
} }
else { else {
str.ip6 = dst->in6.sin6_addr; len = sizeof(dst->in6) - sizeof(dst->in6.sin6_scope_id);
len = sizeof(str);
} }
int i = mem_index(params.mempool, (char *)&str, len); len -= sizeof(dst->sa.sa_family);
if (m == 0 && i >= 0) {
mem_delete(params.mempool, i); if (m == 0) {
mem_delete(params.mempool, str, len);
return 0; return 0;
} }
else if (m > 0) { else if (m > 0) {
time(&t); time(&t);
val = mem_add(params.mempool, (char *)&str, len, i); val = mem_add(params.mempool, str, len);
if (!val) { if (!val) {
uniperror("mem_add"); uniperror("mem_add");
return -1; return -1;
@ -533,10 +525,10 @@ int mode_add_get(struct sockaddr_ina *dst, int m)
val->time = t; val->time = t;
return 0; return 0;
} }
if (i < 0) { val = mem_get(params.mempool, str, len);
if (!val) {
return -1; return -1;
} }
val = params.mempool->values[i];
time(&t); time(&t);
if (t > val->time + params.cache_ttl) { if (t > val->time + params.cache_ttl) {
LOG(LOG_S, "time=%ld, now=%ld, ignore\n", val->time, t); LOG(LOG_S, "time=%ld, now=%ld, ignore\n", val->time, t);
@ -546,6 +538,19 @@ int mode_add_get(struct sockaddr_ina *dst, int m)
} }
int ext_connect(struct poolhd *pool, struct eval *val,
struct sockaddr_ina *dst, int next, int m)
{
struct desync_params *dp = &params.dp[m];
if (dp->to_ip == 2) {
struct sockaddr_ina addr = { .in6 = dp->addr };
addr.in.sin_port = dst->in.sin_port;
return create_conn(pool, val, &addr, next);
}
return create_conn(pool, val, dst, next);
}
static inline int on_request(struct poolhd *pool, struct eval *val, static inline int on_request(struct poolhd *pool, struct eval *val,
char *buffer, size_t bfsize) char *buffer, size_t bfsize)
{ {
@ -584,18 +589,26 @@ static inline int on_request(struct poolhd *pool, struct eval *val,
} }
return -1; return -1;
} }
error = create_conn(pool, val, &dst, EV_CONNECT); if (params.late_conn) {
val->type = EV_DESYNC;
if (resp_error(val->fd, 0, val->flag) < 0) {
perror("send");
return -1;
}
val->in6 = dst.in6;
return 0;
}
int m = mode_add_get(&dst, -1);
val->cache = (m == 0);
val->attempt = m < 0 ? 0 : m;
error = ext_connect(pool, val, &dst, EV_CONNECT, m);
if (error) { if (error) {
int en = get_e(); int en = get_e();
if (resp_error(val->fd, en ? en : error, val->flag) < 0) if (resp_error(val->fd, en ? en : error, val->flag) < 0)
uniperror("send"); uniperror("send");
return -1; return -1;
} }
int m = mode_add_get(&dst, -1);
if (m >= 0) {
val->attempt = m;
}
val->pair->attempt = m;
val->type = EV_IGNORE; val->type = EV_IGNORE;
return 0; return 0;
} }
@ -605,8 +618,8 @@ int reconnect(struct poolhd *pool, struct eval *val, int m)
{ {
struct eval *client = val->pair; struct eval *client = val->pair;
if (create_conn(pool, client, if (ext_connect(pool, client,
(struct sockaddr_ina *)&val->in6, EV_DESYNC)) { (struct sockaddr_ina *)&val->in6, EV_DESYNC, m)) {
return -1; return -1;
} }
val->pair = 0; val->pair = 0;
@ -614,20 +627,35 @@ int reconnect(struct poolhd *pool, struct eval *val, int m)
client->type = EV_IGNORE; client->type = EV_IGNORE;
client->attempt = m; client->attempt = m;
client->cache = 1;
return 0; return 0;
} }
bool check_host(struct mphdr *hosts, struct eval *val)
{
char *host;
int len;
if (!(len = parse_tls(val->buff.data, val->buff.size, &host))) {
len = parse_http(val->buff.data, val->buff.size, &host, 0);
}
return mem_get(hosts, host, len) != 0;
}
int on_torst(struct poolhd *pool, struct eval *val) int on_torst(struct poolhd *pool, struct eval *val)
{ {
int m = val->pair->attempt + 1; int m = val->pair->attempt + 1;
for (; m < params.dp_count; m++) { for (; m < params.dp_count; m++) {
struct desync_params dp = params.dp[m]; struct desync_params *dp = &params.dp[m];
if (dp.detect == 0 if (!(dp->detect & DETECT_TORST)) {
|| (dp.detect & DETECT_TORST)) continue;
}
if (!dp->hosts || check_host(dp->hosts, val->pair)) {
break; break;
} }
}
if (m >= params.dp_count) { if (m >= params.dp_count) {
mode_add_get( mode_add_get(
(struct sockaddr_ina *)&val->in6, 0); (struct sockaddr_ina *)&val->in6, 0);
@ -646,26 +674,35 @@ int on_response(struct poolhd *pool, struct eval *val,
ssize_t qn = val->pair->buff.size; ssize_t qn = val->pair->buff.size;
for (; m < params.dp_count; m++) { for (; m < params.dp_count; m++) {
struct desync_params dp = params.dp[m]; struct desync_params *dp = &params.dp[m];
if ((dp.detect & DETECT_HTTP_LOCAT) switch (0) {
default:
if ((dp->detect & DETECT_HTTP_LOCAT)
&& is_http_redirect(req, qn, resp, sn)) { && is_http_redirect(req, qn, resp, sn)) {
break; break;
} }
if ((dp.detect & DETECT_TLS_INVSID) else if ((dp->detect & DETECT_TLS_INVSID)
&& neq_tls_sid(req, qn, resp, sn)) { && neq_tls_sid(req, qn, resp, sn)
&& !neq_tls_sid(
fake_tls.data, fake_tls.size, resp, sn)) {
break; break;
} }
if ((dp.detect & DETECT_TLS_ALERT) else if ((dp->detect & DETECT_TLS_ALERT)
&& is_tls_alert(resp, sn)) { && is_tls_alert(resp, sn)) {
break; break;
} }
if (dp.detect & DETECT_HTTP_CLERR) { else if (dp->detect & DETECT_HTTP_CLERR) {
int code = get_http_code(resp, sn); int code = get_http_code(resp, sn);
if (code > 400 && code < 451 && code != 429) { if (code > 400 && code < 451 && code != 429) {
break; break;
} }
} }
continue;
}
if (!dp->hosts || check_host(dp->hosts, val->pair)) {
break;
}
} }
if (m < params.dp_count) { if (m < params.dp_count) {
return reconnect(pool, val, m); return reconnect(pool, val, m);
@ -715,8 +752,7 @@ int on_tunnel_check(struct poolhd *pool, struct eval *val,
} }
int m = pair->attempt; int m = pair->attempt;
if ((m == 0 && val->attempt < 0) if (!pair->cache) {
|| (m && m == val->attempt)) {
return 0; return 0;
} }
if (m == 0) { if (m == 0) {
@ -757,6 +793,21 @@ int on_desync(struct poolhd *pool, struct eval *val,
return -1; return -1;
} }
memcpy(val->buff.data, buffer, n); memcpy(val->buff.data, buffer, n);
if (!m) for (; m < params.dp_count; m++) {
struct desync_params *dp = &params.dp[m];
if (!dp->detect &&
(!dp->hosts || check_host(dp->hosts, val))) {
break;
}
}
if (m >= params.dp_count) return -1;
val->attempt = m;
if (params.late_conn) {
return ext_connect(pool, val,
(struct sockaddr_ina *)&val->in6, EV_DESYNC, m);
}
} }
else { else {
n = val->buff.size; n = val->buff.size;

View File

@ -40,7 +40,11 @@ $ ./ciadpi --disorder 3 -A --tlsrec 1+s
Если сервер его поддерживает, то первый пакет будет отправлен сразу вместе с SYN Если сервер его поддерживает, то первый пакет будет отправлен сразу вместе с SYN
Поддерживается только в Linux (4.11+) Поддерживается только в Linux (4.11+)
-A, --auto[=t,r,c,s,a] -L, --late-conn
Выполнять настоящее подключение только после получения первого пакета от клиента
Полезно при сочетании --hosts с --dst
-A, --auto[=t,r,c,s,a,n]
Автоматический режим Автоматический режим
Если произошло событие, похожее на блокировку или поломку, Если произошло событие, похожее на блокировку или поломку,
то будут применены параметры обхода, следующие за данной опцией то будут применены параметры обхода, следующие за данной опцией
@ -50,11 +54,12 @@ $ ./ciadpi --disorder 3 -A --tlsrec 1+s
cl_err : HTTP ответ, код которого равен 40x, но не 429 cl_err : HTTP ответ, код которого равен 40x, но не 429
sid_inv : session_id в TLS ServerHello и ClientHello не совпадают sid_inv : session_id в TLS ServerHello и ClientHello не совпадают
alert : TLS Error Alert в ответе alert : TLS Error Alert в ответе
nop : Предыдущая группа пропущена, например из-за ограничения по hosts
По умолчанию обрабатывается только torst По умолчанию обрабатывается только torst
Можно указывать несколько групп опций, раделяя их данным параметром Можно указывать несколько групп опций, раделяя их данным параметром
Если соединение успешно прошло, то параметры для данного IP будут закешированны Если соединение успешно прошло, то параметры для данного IP будут закешированны
Параметры, которые можно вынести в отдельную группу: Параметры, которые можно вынести в отдельную группу:
split, disorder, oob, fake, ttl, ip-opt, md5sig, mod-http, tlsrec hosts, dst, split, disorder, oob, fake, ttl, ip-opt, md5sig, mod-http, tlsrec
Пример: Пример:
--auto=redirect --split=1+h --auto=torst --fake -1 --auto=sid_inv,alert --tlsrec 1+s --auto=redirect --split=1+h --auto=torst --fake -1 --auto=sid_inv,alert --tlsrec 1+s
@ -66,6 +71,14 @@ $ ./ciadpi --disorder 3 -A --tlsrec 1+s
В Linux переводится в миллисекунды, поэтому можно указать дробное число В Linux переводится в миллисекунды, поэтому можно указать дробное число
Истечение таймаута будет обработано --auto Истечение таймаута будет обработано --auto
-H, --hosts <file|:string>
Ограничить область действия параметров списком доменов
Домены должны быть разделены новой строкой или пробелом
-D, --dst <ip>
Заменить адрес назначения из запроса на указанный
Полезно совмещать с --auto и --hosts
-s, --split <n[+s]> -s, --split <n[+s]>
Разбить запрос по указанному смещению Разбить запрос по указанному смещению
После числа можно добавить флаг: После числа можно добавить флаг: