mirror of
https://github.com/hufrea/byedpi.git
synced 2024-12-22 14:25:44 +00:00
Auto mode
This commit is contained in:
parent
4e28fbeaae
commit
19171cfeca
2
Makefile
2
Makefile
@ -1,7 +1,7 @@
|
|||||||
TARGET = ciadpi
|
TARGET = ciadpi
|
||||||
CC ?= gcc
|
CC ?= gcc
|
||||||
CFLAGS += -std=c99 -O2 -D_XOPEN_SOURCE=500
|
CFLAGS += -std=c99 -O2 -D_XOPEN_SOURCE=500
|
||||||
SOURCES = packets.c main.c conev.c proxy.c desync.c
|
SOURCES = packets.c main.c conev.c proxy.c desync.c mpool.c
|
||||||
|
|
||||||
all:
|
all:
|
||||||
$(CC) $(CFLAGS) $(SOURCES) -I . -o $(TARGET)
|
$(CC) $(CFLAGS) $(SOURCES) -I . -o $(TARGET)
|
||||||
|
18
conev.c
18
conev.c
@ -43,15 +43,11 @@ struct eval *add_event(struct poolhd *pool, enum eid type,
|
|||||||
if (pool->count >= pool->max)
|
if (pool->count >= pool->max)
|
||||||
return 0;
|
return 0;
|
||||||
struct eval *val = pool->links[pool->count];
|
struct eval *val = pool->links[pool->count];
|
||||||
|
memset(val, 0, sizeof(*val));
|
||||||
|
|
||||||
val->fd = fd;
|
val->fd = fd;
|
||||||
val->index = pool->count;
|
val->index = pool->count;
|
||||||
val->type = type;
|
val->type = type;
|
||||||
val->pair = 0;
|
|
||||||
val->tmpbuf = 0;
|
|
||||||
val->size = 0;
|
|
||||||
val->offset = 0;
|
|
||||||
val->flag = 0;
|
|
||||||
|
|
||||||
#ifndef NOEPOLL
|
#ifndef NOEPOLL
|
||||||
struct epoll_event ev = {
|
struct epoll_event ev = {
|
||||||
@ -79,9 +75,9 @@ void del_event(struct poolhd *pool, struct eval *val)
|
|||||||
if (!val->fd) {
|
if (!val->fd) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (val->tmpbuf) {
|
if (val->buff.data) {
|
||||||
free(val->tmpbuf);
|
free(val->buff.data);
|
||||||
val->tmpbuf = 0;
|
val->buff.data = 0;
|
||||||
}
|
}
|
||||||
close(val->fd);
|
close(val->fd);
|
||||||
val->fd = 0;
|
val->fd = 0;
|
||||||
@ -116,9 +112,9 @@ void destroy_pool(struct poolhd *pool)
|
|||||||
close(val->fd);
|
close(val->fd);
|
||||||
val->fd = 0;
|
val->fd = 0;
|
||||||
}
|
}
|
||||||
if (val->tmpbuf) {
|
if (val->buff.data) {
|
||||||
free(val->tmpbuf);
|
free(val->buff.data);
|
||||||
val->tmpbuf = 0;
|
val->buff.data = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pool->items) {
|
if (pool->items) {
|
||||||
|
18
conev.h
18
conev.h
@ -33,7 +33,8 @@ enum eid {
|
|||||||
EV_REQUEST,
|
EV_REQUEST,
|
||||||
EV_CONNECT,
|
EV_CONNECT,
|
||||||
EV_IGNORE,
|
EV_IGNORE,
|
||||||
EV_TUNNEL
|
EV_TUNNEL,
|
||||||
|
EV_DESYNC
|
||||||
};
|
};
|
||||||
|
|
||||||
#define FLAG_S4 1
|
#define FLAG_S4 1
|
||||||
@ -46,23 +47,30 @@ char *eid_name[] = {
|
|||||||
"EV_REQUEST",
|
"EV_REQUEST",
|
||||||
"EV_CONNECT",
|
"EV_CONNECT",
|
||||||
"EV_IGNORE",
|
"EV_IGNORE",
|
||||||
"EV_TUNNEL"
|
"EV_TUNNEL",
|
||||||
|
"EV_DESYNC"
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct buffer {
|
||||||
|
ssize_t size;
|
||||||
|
int offset;
|
||||||
|
char *data;
|
||||||
|
};
|
||||||
|
|
||||||
struct eval {
|
struct eval {
|
||||||
int fd;
|
int fd;
|
||||||
int index;
|
int index;
|
||||||
enum eid type;
|
enum eid type;
|
||||||
struct eval *pair;
|
struct eval *pair;
|
||||||
char *tmpbuf;
|
struct buffer buff;
|
||||||
ssize_t size;
|
|
||||||
int offset;
|
|
||||||
int flag;
|
int flag;
|
||||||
union {
|
union {
|
||||||
struct sockaddr_in in;
|
struct sockaddr_in in;
|
||||||
struct sockaddr_in6 in6;
|
struct sockaddr_in6 in6;
|
||||||
};
|
};
|
||||||
|
ssize_t recv_count;
|
||||||
|
int try_count;
|
||||||
#ifndef NOEPOLL
|
#ifndef NOEPOLL
|
||||||
uint32_t events;
|
uint32_t events;
|
||||||
#endif
|
#endif
|
||||||
|
24
desync.c
24
desync.c
@ -81,7 +81,7 @@ static inline void delay(long ms)
|
|||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
int send_fake(int sfd, char *buffer,
|
int send_fake(int sfd, char *buffer,
|
||||||
int cnt, long pos, int fa)
|
int cnt, long pos, int fa, int ttl)
|
||||||
{
|
{
|
||||||
struct packet pkt = cnt != IS_HTTP ? fake_tls : fake_http;
|
struct packet pkt = cnt != IS_HTTP ? fake_tls : fake_http;
|
||||||
size_t psz = pkt.size;
|
size_t psz = pkt.size;
|
||||||
@ -107,7 +107,7 @@ int send_fake(int sfd, char *buffer,
|
|||||||
}
|
}
|
||||||
memcpy(p, pkt.data, psz < pos ? psz : pos);
|
memcpy(p, pkt.data, psz < pos ? psz : pos);
|
||||||
|
|
||||||
if (setttl(sfd, params.ttl, fa) < 0) {
|
if (setttl(sfd, ttl, fa) < 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (_sendfile(sfd, ffd, 0, pos) < 0) {
|
if (_sendfile(sfd, ffd, 0, pos) < 0) {
|
||||||
@ -178,8 +178,10 @@ int send_disorder(int sfd,
|
|||||||
|
|
||||||
|
|
||||||
int desync(int sfd, char *buffer, size_t bfsize,
|
int desync(int sfd, char *buffer, size_t bfsize,
|
||||||
ssize_t n, struct sockaddr *dst)
|
ssize_t n, struct sockaddr *dst, int dp_c)
|
||||||
{
|
{
|
||||||
|
struct desync_params dp = params.dp[dp_c];
|
||||||
|
|
||||||
char *host = 0;
|
char *host = 0;
|
||||||
int len = 0, type = 0;
|
int len = 0, type = 0;
|
||||||
int fa = get_family(dst);
|
int fa = get_family(dst);
|
||||||
@ -195,17 +197,17 @@ int desync(int sfd, char *buffer, size_t bfsize,
|
|||||||
len, host, host - buffer);
|
len, host, host - buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == IS_HTTP && params.mod_http) {
|
if (type == IS_HTTP && dp.mod_http) {
|
||||||
LOG(LOG_S, "modify HTTP: n=%ld\n", n);
|
LOG(LOG_S, "modify HTTP: n=%ld\n", n);
|
||||||
if (mod_http(buffer, n, params.mod_http)) {
|
if (mod_http(buffer, n, dp.mod_http)) {
|
||||||
LOG(LOG_E, "mod http error\n");
|
LOG(LOG_E, "mod http error\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == IS_HTTPS && params.tlsrec_n) {
|
else if (type == IS_HTTPS && dp.tlsrec_n) {
|
||||||
long lp = 0;
|
long lp = 0;
|
||||||
for (int i = 0; i < params.tlsrec_n; i++) {
|
for (int i = 0; i < dp.tlsrec_n; i++) {
|
||||||
struct part part = params.tlsrec[i];
|
struct part part = dp.tlsrec[i];
|
||||||
|
|
||||||
long pos = part.pos + i * 5;
|
long pos = part.pos + i * 5;
|
||||||
if (part.flag == OFFSET_SNI) {
|
if (part.flag == OFFSET_SNI) {
|
||||||
@ -238,8 +240,8 @@ int desync(int sfd, char *buffer, size_t bfsize,
|
|||||||
|
|
||||||
if (!type && params.de_known) {
|
if (!type && params.de_known) {
|
||||||
}
|
}
|
||||||
else for (int i = 0; i < params.parts_n; i++) {
|
else for (int i = 0; i < dp.parts_n; i++) {
|
||||||
struct part part = params.parts[i];
|
struct part part = dp.parts[i];
|
||||||
|
|
||||||
long pos = part.pos;
|
long pos = part.pos;
|
||||||
if (part.flag == OFFSET_SNI) {
|
if (part.flag == OFFSET_SNI) {
|
||||||
@ -268,7 +270,7 @@ int desync(int sfd, char *buffer, size_t bfsize,
|
|||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
case DESYNC_FAKE:
|
case DESYNC_FAKE:
|
||||||
s = send_fake(sfd,
|
s = send_fake(sfd,
|
||||||
buffer + lp, type, pos - lp, fa);
|
buffer + lp, type, pos - lp, fa, dp.ttl);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case DESYNC_DISORDER:
|
case DESYNC_DISORDER:
|
||||||
|
2
desync.h
2
desync.h
@ -1 +1 @@
|
|||||||
int desync(int sfd, char *buffer, size_t bfsize, ssize_t n, struct sockaddr *dst);
|
int desync(int sfd, char *buffer, size_t bfsize, ssize_t n, struct sockaddr *dst, int dp_c);
|
||||||
|
58
main.c
58
main.c
@ -17,13 +17,16 @@
|
|||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
#define FAKE_SUPPORT 1
|
#define FAKE_SUPPORT 1
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#define close(fd) closesocket(fd)
|
#define close(fd) closesocket(fd)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define VERSION 5
|
#define VERSION 5
|
||||||
|
#define MPOOL_INC 16
|
||||||
|
|
||||||
|
|
||||||
struct packet fake_tls = {
|
struct packet fake_tls = {
|
||||||
@ -37,17 +40,10 @@ oob_data = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct params params = {
|
struct params params = {
|
||||||
.ttl = 8,
|
|
||||||
.parts_n = 0,
|
|
||||||
.parts = 0,
|
|
||||||
.sfdelay = 3,
|
.sfdelay = 3,
|
||||||
.def_ttl = 0,
|
.def_ttl = 0,
|
||||||
.custom_ttl = 0,
|
.custom_ttl = 0,
|
||||||
.mod_http = 0,
|
|
||||||
.tlsrec = 0,
|
|
||||||
.tlsrec_n = 0,
|
|
||||||
.de_known = 0,
|
.de_known = 0,
|
||||||
|
|
||||||
.ipv6 = 1,
|
.ipv6 = 1,
|
||||||
@ -72,6 +68,7 @@ const char help_text[] = {
|
|||||||
" -g, --def-ttl <num> TTL for all outgoing connections\n"
|
" -g, --def-ttl <num> TTL for all outgoing connections\n"
|
||||||
// desync options
|
// desync options
|
||||||
" -K, --desync-known Desync only HTTP and TLS with SNI\n"
|
" -K, --desync-known Desync only HTTP and TLS with SNI\n"
|
||||||
|
" -A, --auto Try desync params after this option\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"
|
||||||
@ -103,6 +100,7 @@ const struct option options[] = {
|
|||||||
{"debug", 1, 0, 'x'},
|
{"debug", 1, 0, 'x'},
|
||||||
|
|
||||||
{"desync-known ", 0, 0, 'K'},
|
{"desync-known ", 0, 0, 'K'},
|
||||||
|
{"auto", 0, 0, 'A'},
|
||||||
{"split", 1, 0, 's'},
|
{"split", 1, 0, 's'},
|
||||||
{"disorder", 1, 0, 'd'},
|
{"disorder", 1, 0, 'd'},
|
||||||
{"oob", 1, 0, 'o'},
|
{"oob", 1, 0, 'o'},
|
||||||
@ -229,6 +227,23 @@ int parse_offset(struct part *part, const char *str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct desync_params *add_dparams(
|
||||||
|
struct desync_params **root, int *n)
|
||||||
|
{
|
||||||
|
struct desync_params *p = realloc(
|
||||||
|
*root, sizeof(struct desync_params) * (*n + 1));
|
||||||
|
if (!p) {
|
||||||
|
uniperror("realloc");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
*root = p;
|
||||||
|
*n = *n + 1;
|
||||||
|
p = &((*root)[(*n) - 1]);
|
||||||
|
memset(p, 0, sizeof(*p));
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@ -268,6 +283,11 @@ int main(int argc, char **argv)
|
|||||||
char *end = 0;
|
char *end = 0;
|
||||||
uint16_t port = htons(1080);
|
uint16_t port = htons(1080);
|
||||||
|
|
||||||
|
struct desync_params *dp = add_dparams(
|
||||||
|
¶ms.dp, ¶ms.dp_count);
|
||||||
|
if (!dp) {
|
||||||
|
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) {
|
||||||
@ -333,13 +353,20 @@ int main(int argc, char **argv)
|
|||||||
params.de_known = 1;
|
params.de_known = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'A':
|
||||||
|
dp = add_dparams(¶ms.dp, ¶ms.dp_count);
|
||||||
|
if (!dp) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case 's':
|
case 's':
|
||||||
case 'd':
|
case 'd':
|
||||||
case 'o':
|
case 'o':
|
||||||
case 'f':
|
case 'f':
|
||||||
;
|
;
|
||||||
struct part *part = add_part(
|
struct part *part = add_part(
|
||||||
¶ms.parts, ¶ms.parts_n);
|
&dp->parts, &dp->parts_n);
|
||||||
if (!part) {
|
if (!part) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -363,7 +390,7 @@ int main(int argc, char **argv)
|
|||||||
if (val <= 0 || val > 255 || *end)
|
if (val <= 0 || val > 255 || *end)
|
||||||
invalid = 1;
|
invalid = 1;
|
||||||
else
|
else
|
||||||
params.ttl = val;
|
dp->ttl = val;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'n':
|
case 'n':
|
||||||
@ -403,13 +430,13 @@ int main(int argc, char **argv)
|
|||||||
while (end && !invalid) {
|
while (end && !invalid) {
|
||||||
switch (*end) {
|
switch (*end) {
|
||||||
case 'r':
|
case 'r':
|
||||||
params.mod_http |= MH_SPACE;
|
dp->mod_http |= MH_SPACE;
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
params.mod_http |= MH_HMIX;
|
dp->mod_http |= MH_HMIX;
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
params.mod_http |= MH_DMIX;
|
dp->mod_http |= MH_DMIX;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
invalid = 1;
|
invalid = 1;
|
||||||
@ -421,7 +448,7 @@ int main(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'r':
|
case 'r':
|
||||||
part = add_part(¶ms.tlsrec, ¶ms.tlsrec_n);
|
part = add_part(&dp->tlsrec, &dp->tlsrec_n);
|
||||||
if (!part) {
|
if (!part) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -476,6 +503,11 @@ int main(int argc, char **argv)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
params.mempool = mem_pool(MPOOL_INC);
|
||||||
|
if (!params.mempool) {
|
||||||
|
uniperror("mem_pool");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
int status = run(&s);
|
int status = run(&s);
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
|
89
mpool.c
Normal file
89
mpool.c
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <mpool.h>
|
||||||
|
|
||||||
|
|
||||||
|
struct mphdr *mem_pool(int count)
|
||||||
|
{
|
||||||
|
struct mphdr *hdr = malloc(sizeof(struct mphdr));
|
||||||
|
if (!hdr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
hdr->inc = count;
|
||||||
|
hdr->max = count;
|
||||||
|
hdr->count = 0;
|
||||||
|
|
||||||
|
hdr->values = malloc(sizeof(*hdr->values) * count);
|
||||||
|
if (!hdr->values) {
|
||||||
|
free(hdr);
|
||||||
|
hdr = 0;
|
||||||
|
}
|
||||||
|
return hdr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int mem_index(struct mphdr *hdr, char *str, int len)
|
||||||
|
{
|
||||||
|
if (!hdr->count) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
int s = 0, m, i;
|
||||||
|
int e = hdr->count - 1;
|
||||||
|
|
||||||
|
while (s <= e) {
|
||||||
|
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 max = hdr->max;
|
||||||
|
|
||||||
|
if (hdr->count >= max) {
|
||||||
|
max += hdr->inc;
|
||||||
|
struct elem **new = realloc(hdr->values, sizeof(*hdr->values) * max);
|
||||||
|
if (!new) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
hdr->max = max;
|
||||||
|
hdr->values = new;
|
||||||
|
}
|
||||||
|
int pos = mem_index(hdr, str, len);
|
||||||
|
if (pos >= 0) {
|
||||||
|
return hdr->values[pos];
|
||||||
|
}
|
||||||
|
pos = -pos - 2;
|
||||||
|
|
||||||
|
struct elem *val = malloc(sizeof(struct elem) + len);
|
||||||
|
if (!val) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
memset(val, 0, sizeof(*val));
|
||||||
|
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;
|
||||||
|
hdr->count++;
|
||||||
|
return val;
|
||||||
|
}
|
14
mpool.h
Normal file
14
mpool.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
struct elem {
|
||||||
|
int m;
|
||||||
|
int len;
|
||||||
|
char data[];
|
||||||
|
};
|
||||||
|
struct mphdr {
|
||||||
|
int max;
|
||||||
|
int inc;
|
||||||
|
int count;
|
||||||
|
struct elem **values;
|
||||||
|
};
|
||||||
|
struct mphdr *mem_pool(int count);
|
||||||
|
int mem_index(struct mphdr *hdr, char *str, int len);
|
||||||
|
struct elem *mem_add(struct mphdr *hdr, char *str, int len);
|
17
params.h
17
params.h
@ -1,4 +1,5 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <mpool.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
@ -23,17 +24,22 @@ struct part {
|
|||||||
long pos;
|
long pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct params {
|
struct desync_params {
|
||||||
char de_known;
|
|
||||||
int ttl;
|
int ttl;
|
||||||
int parts_n;
|
int parts_n;
|
||||||
struct part *parts;
|
struct part *parts;
|
||||||
long sfdelay;
|
|
||||||
int def_ttl;
|
|
||||||
char custom_ttl;
|
|
||||||
int mod_http;
|
int mod_http;
|
||||||
int tlsrec_n;
|
int tlsrec_n;
|
||||||
struct part *tlsrec;
|
struct part *tlsrec;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct params {
|
||||||
|
char de_known;
|
||||||
|
int dp_count;
|
||||||
|
struct desync_params *dp;
|
||||||
|
long sfdelay;
|
||||||
|
int def_ttl;
|
||||||
|
char custom_ttl;
|
||||||
|
|
||||||
char ipv6;
|
char ipv6;
|
||||||
char resolve;
|
char resolve;
|
||||||
@ -41,6 +47,7 @@ struct params {
|
|||||||
int debug;
|
int debug;
|
||||||
size_t bfsize;
|
size_t bfsize;
|
||||||
struct sockaddr_in6 baddr;
|
struct sockaddr_in6 baddr;
|
||||||
|
struct mphdr *mempool;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct params params;
|
extern struct params params;
|
||||||
|
218
proxy.c
218
proxy.c
@ -434,73 +434,31 @@ static inline int on_accept(struct poolhd *pool, struct eval *val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline int on_connect(struct poolhd *pool, struct eval *val,
|
|
||||||
char *buffer, size_t bfsize, int e)
|
|
||||||
{
|
|
||||||
if (val->flag == FLAG_CONN) {
|
|
||||||
int error = 0;
|
|
||||||
socklen_t len = sizeof(error);
|
|
||||||
if (e) {
|
|
||||||
if (getsockopt(val->fd, SOL_SOCKET,
|
|
||||||
SO_ERROR, (char *)&error, &len)) {
|
|
||||||
uniperror("getsockopt SO_ERROR");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (resp_error(val->pair->fd,
|
|
||||||
error, val->pair->flag) < 0) {
|
|
||||||
uniperror("send");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (e) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (mod_etype(pool, val, POLLOUT, 0)) {
|
|
||||||
uniperror("mod_etype");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
val->type = EV_TUNNEL;
|
|
||||||
val->pair->type = EV_CONNECT;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ssize_t n = recv(val->fd, buffer, bfsize, 0);
|
|
||||||
if (n <= 0) {
|
|
||||||
if (n) uniperror("recv data");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (desync(val->pair->fd, buffer, bfsize,
|
|
||||||
n, (struct sockaddr *)&val->pair->in6)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
val->type = EV_TUNNEL;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static inline int on_tunnel(struct poolhd *pool, struct eval *val,
|
static inline int on_tunnel(struct poolhd *pool, struct eval *val,
|
||||||
char *buffer, size_t bfsize, int out)
|
char *buffer, size_t bfsize, int out)
|
||||||
{
|
{
|
||||||
ssize_t n = 0;
|
ssize_t n = 0;
|
||||||
struct eval *pair = val->pair;
|
struct eval *pair = val->pair;
|
||||||
|
|
||||||
if (pair->tmpbuf && out) {
|
if (pair->buff.size && out) {
|
||||||
pair = val;
|
pair = val;
|
||||||
val = val->pair;
|
val = val->pair;
|
||||||
|
|
||||||
n = val->size - val->offset;
|
n = val->buff.size - val->buff.offset;
|
||||||
ssize_t sn = send(pair->fd, val->tmpbuf + val->offset, n, 0);
|
ssize_t sn = send(pair->fd,
|
||||||
|
val->buff.data + val->buff.offset, n, 0);
|
||||||
if (sn != n) {
|
if (sn != n) {
|
||||||
if (sn < 0 && get_e() != EAGAIN) {
|
if (sn < 0 && get_e() != EAGAIN) {
|
||||||
uniperror("send");
|
uniperror("send");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (sn > 0)
|
if (sn > 0)
|
||||||
val->offset += sn;
|
val->buff.offset += sn;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
free(val->tmpbuf);
|
free(val->buff.data);
|
||||||
val->tmpbuf = 0;
|
val->buff.data = 0;
|
||||||
|
val->buff.size = 0;
|
||||||
|
|
||||||
if (mod_etype(pool, val, POLLIN, 1) ||
|
if (mod_etype(pool, val, POLLIN, 1) ||
|
||||||
mod_etype(pool, pair, POLLOUT, 0)) {
|
mod_etype(pool, pair, POLLOUT, 0)) {
|
||||||
@ -516,6 +474,8 @@ static inline int on_tunnel(struct poolhd *pool, struct eval *val,
|
|||||||
if (n) uniperror("recv");
|
if (n) uniperror("recv");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
val->recv_count += n;
|
||||||
|
|
||||||
ssize_t sn = send(pair->fd, buffer, n, 0);
|
ssize_t sn = send(pair->fd, buffer, n, 0);
|
||||||
if (sn != n) {
|
if (sn != n) {
|
||||||
if (sn < 0) {
|
if (sn < 0) {
|
||||||
@ -527,12 +487,12 @@ static inline int on_tunnel(struct poolhd *pool, struct eval *val,
|
|||||||
}
|
}
|
||||||
LOG(LOG_S, "EAGAIN, set POLLOUT (fd: %d)\n", pair->fd);
|
LOG(LOG_S, "EAGAIN, set POLLOUT (fd: %d)\n", pair->fd);
|
||||||
|
|
||||||
val->size = n - sn;
|
val->buff.size = n - sn;
|
||||||
if (!(val->tmpbuf = malloc(val->size))) {
|
if (!(val->buff.data = malloc(val->buff.size))) {
|
||||||
uniperror("malloc");
|
uniperror("malloc");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
memcpy(val->tmpbuf, buffer + sn, val->size);
|
memcpy(val->buff.data, buffer + sn, val->buff.size);
|
||||||
|
|
||||||
if (mod_etype(pool, val, POLLIN, 0) ||
|
if (mod_etype(pool, val, POLLIN, 0) ||
|
||||||
mod_etype(pool, pair, POLLOUT, 1)) {
|
mod_etype(pool, pair, POLLOUT, 1)) {
|
||||||
@ -546,6 +506,150 @@ static inline int on_tunnel(struct poolhd *pool, struct eval *val,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int try_again(struct poolhd *pool, struct eval *val)
|
||||||
|
{
|
||||||
|
if (val->flag != FLAG_CONN) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (val->recv_count) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
struct eval *client = val->pair;
|
||||||
|
if (client->try_count >= params.dp_count) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
LOG(LOG_S, "try next params: %d\n", client->try_count + 1);
|
||||||
|
|
||||||
|
int e = create_conn(pool, client,
|
||||||
|
(struct sockaddr_ina *)&val->in6);
|
||||||
|
if (e) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
val->pair = 0;
|
||||||
|
del_event(pool, val);
|
||||||
|
|
||||||
|
client->type = EV_IGNORE;
|
||||||
|
client->try_count++;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int mode_add_get(struct sockaddr_ina *dst, int m)
|
||||||
|
{
|
||||||
|
char *data;
|
||||||
|
int len;
|
||||||
|
if (dst->sa.sa_family == AF_INET) {
|
||||||
|
data = (char *)(&dst->in.sin_addr);
|
||||||
|
len = sizeof(dst->in.sin_addr);
|
||||||
|
} else {
|
||||||
|
data = (char *)(&dst->in6.sin6_addr);
|
||||||
|
len = sizeof(dst->in6.sin6_addr);
|
||||||
|
}
|
||||||
|
struct elem *val;
|
||||||
|
if (m >= 0) {
|
||||||
|
val = mem_add(params.mempool, data, len);
|
||||||
|
if (!val) {
|
||||||
|
uniperror("mem_add");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
val->m = m;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int i = mem_index(params.mempool, data, len);
|
||||||
|
if (i < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
val = params.mempool->values[i];
|
||||||
|
return val->m;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int on_desync(struct poolhd *pool, struct eval *val,
|
||||||
|
char *buffer, size_t bfsize)
|
||||||
|
{
|
||||||
|
ssize_t n;
|
||||||
|
int m;
|
||||||
|
|
||||||
|
if (val->flag == FLAG_CONN) {
|
||||||
|
if (on_tunnel(pool, val, buffer, bfsize, 0)) {
|
||||||
|
return try_again(pool, val);
|
||||||
|
}
|
||||||
|
free(val->pair->buff.data);
|
||||||
|
val->pair->buff.data = 0;
|
||||||
|
val->pair->buff.size = 0;
|
||||||
|
|
||||||
|
m = val->pair->try_count;
|
||||||
|
return mode_add_get(
|
||||||
|
(struct sockaddr_ina *)&val->in6, m);
|
||||||
|
}
|
||||||
|
m = mode_add_get(
|
||||||
|
(struct sockaddr_ina *)&val->pair->in6, -1);
|
||||||
|
if (m < 0) {
|
||||||
|
m = val->try_count;
|
||||||
|
}
|
||||||
|
if (!val->buff.data) {
|
||||||
|
n = recv(val->fd, buffer, bfsize, 0);
|
||||||
|
if (n <= 0) {
|
||||||
|
if (n) uniperror("recv data");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
val->recv_count += n;
|
||||||
|
val->buff.size = n;
|
||||||
|
|
||||||
|
if (!(val->buff.data = malloc(n))) {
|
||||||
|
uniperror("malloc");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memcpy(val->buff.data, buffer, n);
|
||||||
|
} else {
|
||||||
|
n = val->buff.size;
|
||||||
|
memcpy(buffer, val->buff.data, n);
|
||||||
|
}
|
||||||
|
if (desync(val->pair->fd, buffer, bfsize, n,
|
||||||
|
(struct sockaddr *)&val->pair->in6, m)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
val->type = EV_TUNNEL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline int on_connect(struct poolhd *pool, struct eval *val,
|
||||||
|
char *buffer, size_t bfsize, int e)
|
||||||
|
{
|
||||||
|
int error = 0;
|
||||||
|
socklen_t len = sizeof(error);
|
||||||
|
if (e) {
|
||||||
|
if (getsockopt(val->fd, SOL_SOCKET,
|
||||||
|
SO_ERROR, (char *)&error, &len)) {
|
||||||
|
uniperror("getsockopt SO_ERROR");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!val->pair->try_count) {
|
||||||
|
if (resp_error(val->pair->fd,
|
||||||
|
error, val->pair->flag) < 0) {
|
||||||
|
uniperror("send");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (e) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (mod_etype(pool, val, POLLOUT, 0)) {
|
||||||
|
uniperror("mod_etype");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
val->type = EV_DESYNC;
|
||||||
|
val->pair->type = EV_DESYNC;
|
||||||
|
|
||||||
|
if (val->pair->try_count) {
|
||||||
|
return on_desync(pool, val->pair, buffer, bfsize);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int event_loop(int srvfd)
|
int event_loop(int srvfd)
|
||||||
{
|
{
|
||||||
size_t bfsize = params.bfsize;
|
size_t bfsize = params.bfsize;
|
||||||
@ -600,8 +704,9 @@ int event_loop(int srvfd)
|
|||||||
|
|
||||||
case EV_TUNNEL:
|
case EV_TUNNEL:
|
||||||
if (on_tunnel(pool, val,
|
if (on_tunnel(pool, val,
|
||||||
buffer, bfsize, etype & POLLOUT))
|
buffer, bfsize, etype & POLLOUT)) {
|
||||||
del_event(pool, val);
|
del_event(pool, val);
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case EV_CONNECT:
|
case EV_CONNECT:
|
||||||
@ -610,6 +715,11 @@ int event_loop(int srvfd)
|
|||||||
del_event(pool, val);
|
del_event(pool, val);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
case EV_DESYNC:
|
||||||
|
if (on_desync(pool, val, buffer, bfsize))
|
||||||
|
del_event(pool, val);
|
||||||
|
continue;
|
||||||
|
|
||||||
case EV_IGNORE:
|
case EV_IGNORE:
|
||||||
if (etype & (POLLHUP | POLLERR | POLLRDHUP))
|
if (etype & (POLLHUP | POLLERR | POLLRDHUP))
|
||||||
del_event(pool, val);
|
del_event(pool, val);
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
--------------
|
--------------
|
||||||
Использование:
|
Использование:
|
||||||
$ ./ciadpi --disorder 3+sni
|
$ ./ciadpi --disorder 3 -A --tlsrec 1+s
|
||||||
|
|
||||||
Описание аргументов:
|
Описание аргументов:
|
||||||
-i, --ip <ip>
|
-i, --ip <ip>
|
||||||
@ -35,6 +35,13 @@ $ ./ciadpi --disorder 3+sni
|
|||||||
Отключить запутывание для нераспознанных протоколов
|
Отключить запутывание для нераспознанных протоколов
|
||||||
Распознаваемые протоколы: HTTP и TLS с SNI
|
Распознаваемые протоколы: HTTP и TLS с SNI
|
||||||
|
|
||||||
|
-A, --auto
|
||||||
|
Автоматический режим
|
||||||
|
Если обнаружены признаки блокировки (соединение разорвано сразу после первого пакета),
|
||||||
|
то будут применены параметры обхода, следующие за данной опцией
|
||||||
|
Можно указывать несколько групп параметров, раделяя их данным флагом
|
||||||
|
Если соединение успешно прошло, то параметры будут сохранены для данного IP до следующего перезапуска
|
||||||
|
|
||||||
-s, --split <n[+s]>
|
-s, --split <n[+s]>
|
||||||
Разбить запрос по указанному смещению
|
Разбить запрос по указанному смещению
|
||||||
После числа можно добавить флаг:
|
После числа можно добавить флаг:
|
||||||
|
Loading…
Reference in New Issue
Block a user