0
0
mirror of https://github.com/hufrea/byedpi.git synced 2025-06-30 02:31:15 +00:00

Dont restore sock options while there are unsent, mix disorder with split

This commit is contained in:
ruti 2025-05-25 09:17:07 +03:00
parent 1c13f9ae94
commit c4a9c85f30
5 changed files with 135 additions and 157 deletions

View File

@ -100,6 +100,12 @@ void del_event(struct poolhd *pool, struct eval *val)
buff_push(pool, val->sq_buff); buff_push(pool, val->sq_buff);
val->sq_buff = 0; val->sq_buff = 0;
} }
#ifndef _WIN32
if (val->restore_fake) {
munmap(val->restore_fake, val->restore_fake_len);
val->restore_fake = 0;
}
#endif
close(val->fd); close(val->fd);
val->fd = -1; val->fd = -1;
val->mod_iter = pool->iters; val->mod_iter = pool->iters;

13
conev.h
View File

@ -4,6 +4,7 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#ifndef __linux__ #ifndef __linux__
#define NOEPOLL #define NOEPOLL
#endif #endif
@ -17,6 +18,7 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <unistd.h> #include <unistd.h>
#include <time.h> #include <time.h>
#include <sys/mman.h>
#ifndef NOEPOLL #ifndef NOEPOLL
#include <sys/epoll.h> #include <sys/epoll.h>
@ -78,13 +80,22 @@ struct eval {
struct buffer *buff, *sq_buff; struct buffer *buff, *sq_buff;
int flag; int flag;
union sockaddr_u addr; union sockaddr_u addr;
ssize_t recv_count; ssize_t recv_count;
ssize_t round_sent; ssize_t round_sent;
unsigned int round_count; unsigned int round_count;
int attempt; int attempt;
unsigned int part_sent;
bool cache; bool cache;
bool mark; // bool mark; //
bool restore_ttl;
bool restore_md5;
char *restore_fake;
size_t restore_fake_len;
const char *restore_orig;
size_t restore_orig_len;
unsigned int part_sent;
}; };
struct poolhd { struct poolhd {

266
desync.c
View File

@ -102,12 +102,10 @@ static char *alloc_pktd(size_t n)
char *p = mmap(0, n, PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); char *p = mmap(0, n, PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
return p == MAP_FAILED ? 0 : p; return p == MAP_FAILED ? 0 : p;
} }
#define free_pktd(p, n) munmap(p, n)
#else #else
#define sock_has_notsent(sfd) 0 #define sock_has_notsent(sfd) 0
#define alloc_pktd(n) malloc(n) #define alloc_pktd(n) malloc(n)
#define free_pktd(p, n) free(p)
#endif #endif
@ -125,43 +123,37 @@ static struct packet get_tcp_fake(const char *buffer, ssize_t n,
} }
pkt = info->type == IS_HTTP ? fake_http : fake_tls; pkt = info->type == IS_HTTP ? fake_http : fake_tls;
} }
if (info->type != IS_HTTP ssize_t ps = n > pkt.size ? n : pkt.size;
&& (opt->fake_mod || opt->fake_sni_count)) do {
ssize_t ps = n > pkt.size ? n : pkt.size; char *p = alloc_pktd(ps);
char *p = alloc_pktd(ps); if (!p) {
if (!p) { uniperror("malloc/mmap");
uniperror("malloc/mmap"); pkt.data = 0; return pkt;
break; }
} const char *sni = 0;
const char *sni = 0; if (opt->fake_sni_count) {
if (opt->fake_sni_count) { sni = opt->fake_sni_list[rand() % opt->fake_sni_count];
sni = opt->fake_sni_list[rand() % opt->fake_sni_count]; }
} do {
do { if ((opt->fake_mod & FM_ORIG) && info->type == IS_HTTPS) {
if ((opt->fake_mod & FM_ORIG) && info->type == IS_HTTPS) { memcpy(p, buffer, n);
memcpy(p, buffer, n);
if (!sni || !change_tls_sni(sni, p, n, n)) {
if (!sni || !change_tls_sni(sni, p, n, n)) {
break;
}
LOG(LOG_E, "change sni error\n");
}
memcpy(p, pkt.data, pkt.size);
if (sni && change_tls_sni(sni, p, pkt.size, n) < 0) {
free_pktd(p, ps);
p = 0;
break; break;
} }
} while(0); LOG(LOG_E, "change sni error\n");
if (p) {
if (opt->fake_mod & FM_RAND) {
randomize_tls(p, ps);
}
pkt.data = p;
pkt.size = ps;
pkt.dynamic = 1;
} }
} while (0); memcpy(p, pkt.data, pkt.size);
if (sni && change_tls_sni(sni, p, pkt.size, n) < 0) {
break;
}
} while(0);
if (opt->fake_mod & FM_RAND) {
randomize_tls(p, ps);
}
pkt.data = p;
pkt.size = ps;
if (opt->fake_offset.m) { if (opt->fake_offset.m) {
pkt.off = gen_offset(opt->fake_offset.pos, pkt.off = gen_offset(opt->fake_offset.pos,
@ -196,7 +188,7 @@ static int set_md5sig(int sfd, unsigned short key_len)
} }
static ssize_t send_fake(int sfd, const char *buffer, static ssize_t send_fake(struct eval *val, const char *buffer,
long pos, const struct desync_params *opt, struct packet pkt) long pos, const struct desync_params *opt, struct packet pkt)
{ {
int fds[2]; int fds[2];
@ -204,56 +196,41 @@ static ssize_t send_fake(int sfd, const char *buffer,
uniperror("pipe"); uniperror("pipe");
return -1; return -1;
} }
char *p = 0;
size_t ms = pos > pkt.size ? pos : pkt.size; size_t ms = pos > pkt.size ? pos : pkt.size;
ssize_t ret = -1; ssize_t ret = -1;
val->restore_orig = buffer;
val->restore_orig_len = pos;
while (1) { while (1) {
if (pkt.dynamic) { char *p = pkt.data + pkt.off;
p = pkt.data; val->restore_fake = p;
} val->restore_fake_len = pkt.size;
else {
p = mmap(0, ms, if (setttl(val->fd, opt->ttl ? opt->ttl : DEFAULT_TTL) < 0) {
PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
if (p == MAP_FAILED) {
uniperror("mmap");
p = 0;
break;
}
memcpy(p, pkt.data, pkt.size);
}
if (setttl(sfd, opt->ttl ? opt->ttl : DEFAULT_TTL) < 0) {
break; break;
} }
if (opt->md5sig && set_md5sig(sfd, 5)) { val->restore_ttl = 1;
if (opt->md5sig && set_md5sig(val->fd, 5)) {
break; break;
} }
struct iovec vec = { .iov_base = p + pkt.off, .iov_len = pos }; val->restore_md5 = opt->md5sig;
struct iovec vec = { .iov_base = p, .iov_len = pos };
ssize_t len = vmsplice(fds[1], &vec, 1, SPLICE_F_GIFT); ssize_t len = vmsplice(fds[1], &vec, 1, SPLICE_F_GIFT);
if (len < 0) { if (len < 0) {
uniperror("vmsplice"); uniperror("vmsplice");
break; break;
} }
len = splice(fds[0], 0, sfd, 0, len, 0); len = splice(fds[0], 0, val->fd, 0, len, 0);
if (len < 0) { if (len < 0) {
uniperror("splice"); uniperror("splice");
break; break;
} }
memcpy(p + pkt.off, buffer, pos);
if (setttl(sfd, params.def_ttl) < 0) {
break;
}
if (opt->md5sig && set_md5sig(sfd, 0)) {
break;
}
ret = len; ret = len;
break; break;
} }
if (!pkt.dynamic && p) {
munmap(p, ms);
}
close(fds[0]); close(fds[0]);
close(fds[1]); close(fds[1]);
return ret; return ret;
@ -319,7 +296,7 @@ static HANDLE openTempFile(void)
} }
static ssize_t send_fake(int sfd, const char *buffer, static ssize_t send_fake(struct eval *val, const char *buffer,
long pos, const struct desync_params *opt, struct packet pkt) long pos, const struct desync_params *opt, struct packet pkt)
{ {
struct tf_s *s = getTFE(); struct tf_s *s = getTFE();
@ -353,7 +330,7 @@ static ssize_t send_fake(int sfd, const char *buffer,
uniperror("SetFilePointer"); uniperror("SetFilePointer");
break; break;
} }
if (setttl(sfd, opt->ttl ? opt->ttl : DEFAULT_TTL) < 0) { if (setttl(val->fd, opt->ttl ? opt->ttl : DEFAULT_TTL) < 0) {
break; break;
} }
s->ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); s->ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
@ -361,7 +338,7 @@ static ssize_t send_fake(int sfd, const char *buffer,
uniperror("CreateEvent"); uniperror("CreateEvent");
break; break;
} }
if (!TransmitFile(sfd, s->tfile, pos, pos, &s->ov, if (!TransmitFile(val->fd, s->tfile, pos, pos, &s->ov,
NULL, TF_USE_KERNEL_APC | TF_WRITE_BEHIND)) { NULL, TF_USE_KERNEL_APC | TF_WRITE_BEHIND)) {
if ((GetLastError() != ERROR_IO_PENDING) if ((GetLastError() != ERROR_IO_PENDING)
&& (WSAGetLastError() != WSA_IO_PENDING)) { && (WSAGetLastError() != WSA_IO_PENDING)) {
@ -377,7 +354,7 @@ static ssize_t send_fake(int sfd, const char *buffer,
uniperror("WriteFile"); uniperror("WriteFile");
break; break;
} }
if (setttl(sfd, params.def_ttl) < 0) { if (setttl(val->fd, params.def_ttl) < 0) {
break; break;
} }
len = pos; len = pos;
@ -392,6 +369,27 @@ static ssize_t send_fake(int sfd, const char *buffer,
} }
#endif #endif
static void restore_state(struct eval *val)
{
#ifdef __linux__
if (val->restore_fake) {
memcpy(val->restore_fake,
val->restore_orig, val->restore_orig_len);
munmap(val->restore_fake, val->restore_fake_len);
val->restore_fake = 0;
}
if (val->restore_md5) {
set_md5sig(val->fd, 0);
val->restore_md5 = 0;
}
#endif
if (val->restore_ttl) {
setttl(val->fd, params.def_ttl);
val->restore_ttl = 0;
}
}
static ssize_t send_oob(int sfd, char *buffer, static ssize_t send_oob(int sfd, char *buffer,
ssize_t n, long pos, const char *c) ssize_t n, long pos, const char *c)
{ {
@ -417,44 +415,6 @@ static ssize_t send_oob(int sfd, char *buffer,
} }
static ssize_t send_disorder(int sfd,
const char *buffer, long pos)
{
int bttl = 1;
if (setttl(sfd, bttl) < 0) {
return -1;
}
ssize_t len = send(sfd, buffer, pos, 0);
if (len < 0) {
uniperror("send");
}
if (setttl(sfd, params.def_ttl) < 0) {
return -1;
}
return len;
}
static ssize_t send_late_oob(int sfd, char *buffer,
ssize_t n, long pos, const char *c)
{
int bttl = 1;
if (setttl(sfd, bttl) < 0) {
return -1;
}
ssize_t len = send_oob(sfd, buffer, n, pos, c);
if (len < 0) {
uniperror("send");
}
if (setttl(sfd, params.def_ttl) < 0) {
return -1;
}
return len;
}
static void init_proto_info( static void init_proto_info(
const char *buffer, size_t n, struct proto_info *info) const char *buffer, size_t n, struct proto_info *info)
{ {
@ -556,9 +516,11 @@ ssize_t desync(struct poolhd *pool,
struct proto_info info = { 0 }; struct proto_info info = { 0 };
int sfd = val->fd; int sfd = val->fd;
char *buffer = buff->data; char *buffer = buff->data;
size_t bfsize = buff->size; size_t bfsize = buff->size;
ssize_t offset = buff->offset; ssize_t offset = buff->offset;
ssize_t skip = val->pair->round_sent; ssize_t skip = val->pair->round_sent;
unsigned int part_skip = val->pair->part_sent; unsigned int part_skip = val->pair->part_sent;
@ -580,9 +542,9 @@ ssize_t desync(struct poolhd *pool,
long lp = offset; long lp = offset;
struct part part; struct part part;
int i = 0, r = 0; int i = 0, r = 0;
unsigned int curr_part = 0; unsigned int curr_part = 0;
bool need_wait = false;
for (; r > 0 || i < dp.parts_n; r--) { for (; r > 0 || i < dp.parts_n; r--) {
if (r <= 0) { if (r <= 0) {
@ -590,12 +552,12 @@ ssize_t desync(struct poolhd *pool,
r = part.r; i++; r = part.r; i++;
} }
curr_part++; curr_part++;
long pos = gen_offset(part.pos, part.flag, buffer, n, lp, &info); long pos = gen_offset(part.pos, part.flag, buffer, n, lp, &info);
pos += (long )part.s * (part.r - r); pos += (long )part.s * (part.r - r);
if ((skip && pos <= skip) if (((skip && pos < skip)
&& curr_part <= part_skip && !(part.flag & OFFSET_START)) { || curr_part < part_skip) && !(part.flag & OFFSET_START)) {
continue; continue;
} }
if (offset && pos < offset) { if (offset && pos < offset) {
@ -605,46 +567,46 @@ ssize_t desync(struct poolhd *pool,
LOG(LOG_E, "split cancel: pos=%ld-%ld, n=%zd\n", lp, pos, n); LOG(LOG_E, "split cancel: pos=%ld-%ld, n=%zd\n", lp, pos, n);
break; break;
} }
if (need_wait) {
set_timer(pool, val, params.await_int);
*wait = true;
return lp - offset;
}
ssize_t s = 0; ssize_t s = 0;
if (sock_has_notsent(sfd)) { if (curr_part == part_skip) {
LOG(LOG_S, "sock_has_notsent\n"); ;
s = ERR_WAIT; } else
} {
else switch (part.m) { switch (part.m) {
#ifdef FAKE_SUPPORT #ifdef FAKE_SUPPORT
case DESYNC_FAKE:; case DESYNC_FAKE:;
struct packet pkt = get_tcp_fake(buffer, n, &info, &dp); struct packet pkt = get_tcp_fake(buffer, n, &info, &dp);
if (!pkt.data) {
if (pos != lp) s = send_fake(sfd, return -1;
}
if (pos != lp) s = send_fake(val,
buffer + lp, pos - lp, &dp, pkt); buffer + lp, pos - lp, &dp, pkt);
#ifndef __linux
if (pkt.dynamic) free(pkt.data);
free_pktd(pkt.data, pkt.size); #endif
break; break;
#endif #endif
case DESYNC_DISORDER: case DESYNC_DISORDER:
s = send_disorder(sfd, case DESYNC_DISOOB:
buffer + lp, pos - lp); if (!((part.r - r) % 2)
&& setttl(sfd, 1) < 0) {
s = -1;
break;
}
val->restore_ttl = 1;
if (part.m == DESYNC_DISOOB)
s = send_oob(sfd,
buffer + lp, bfsize - lp, pos - lp, dp.oob_char);
else
s = send(sfd, buffer + lp, pos - lp, 0);
if (s < 0) {
uniperror("send");
}
break; break;
case DESYNC_OOB:
s = send_oob(sfd,
buffer + lp, bfsize - lp, pos - lp, dp.oob_char);
break;
case DESYNC_DISOOB:
s = send_late_oob(sfd,
buffer + lp, bfsize - lp, pos - lp, dp.oob_char);
break;
case DESYNC_SPLIT: case DESYNC_SPLIT:
case DESYNC_NONE: case DESYNC_NONE:
default: default:
@ -652,6 +614,7 @@ ssize_t desync(struct poolhd *pool,
break; break;
} }
LOG(LOG_S, "split: pos=%ld-%ld (%zd), m: %s\n", lp, pos, s, demode_str[part.m]); LOG(LOG_S, "split: pos=%ld-%ld (%zd), m: %s\n", lp, pos, s, demode_str[part.m]);
}
val->pair->part_sent = curr_part; val->pair->part_sent = curr_part;
if (s == ERR_WAIT) { if (s == ERR_WAIT) {
@ -669,18 +632,17 @@ ssize_t desync(struct poolhd *pool,
LOG(LOG_E, "%zd != %ld\n", s, pos - lp); LOG(LOG_E, "%zd != %ld\n", s, pos - lp);
return lp + s - offset; return lp + s - offset;
} }
lp = pos;
if (sock_has_notsent(sfd)
if (params.wait_send) { || (params.wait_send
if (lp < n) { && curr_part > part_skip)) {
set_timer(pool, val, params.await_int); set_timer(pool, val, params.await_int);
*wait = true; *wait = true;
return lp - offset; return pos - offset;
}
else {
need_wait = true;
}
} }
restore_state(val);
lp = pos;
} }
// send all/rest // send all/rest
if (lp < n) { if (lp < n) {

6
main.c
View File

@ -32,13 +32,13 @@ ASSERT(sizeof(struct in6_addr) == 16)
struct packet fake_tls = { struct packet fake_tls = {
sizeof(tls_data), tls_data, 0, 0 sizeof(tls_data), tls_data, 0,
}, },
fake_http = { fake_http = {
sizeof(http_data), http_data, 0, 0 sizeof(http_data), http_data, 0,
}, },
fake_udp = { fake_udp = {
sizeof(udp_data), udp_data, 0, 0 sizeof(udp_data), udp_data, 0,
}; };

View File

@ -71,7 +71,6 @@ struct packet {
ssize_t size; ssize_t size;
char *data; char *data;
ssize_t off; ssize_t off;
bool dynamic;
}; };
struct desync_params { struct desync_params {