mirror of
https://github.com/hufrea/byedpi.git
synced 2025-06-30 18:43:04 +00:00
Fix tamper after timeout/pollout
This commit is contained in:
parent
764136eaad
commit
d1f1ae0918
7
conev.c
7
conev.c
@ -93,7 +93,12 @@ void del_event(struct poolhd *pool, struct eval *val)
|
||||
epoll_ctl(pool->efd, EPOLL_CTL_DEL, val->fd, 0);
|
||||
#endif
|
||||
if (val->buff) {
|
||||
buff_unlock(val);
|
||||
buff_unlock(val->buff);
|
||||
val->buff = 0;
|
||||
}
|
||||
if (val->sq_buff) {
|
||||
buff_unlock(val->sq_buff);
|
||||
val->sq_buff = 0;
|
||||
}
|
||||
close(val->fd);
|
||||
val->fd = -1;
|
||||
|
11
conev.h
11
conev.h
@ -53,7 +53,7 @@ union sockaddr_u {
|
||||
struct buffer {
|
||||
size_t size;
|
||||
unsigned int offset;
|
||||
size_t lock;
|
||||
ssize_t lock;
|
||||
struct buffer *next;
|
||||
char data[];
|
||||
};
|
||||
@ -68,7 +68,7 @@ struct eval {
|
||||
struct eval *tv_next, *tv_prev;
|
||||
|
||||
struct eval *pair;
|
||||
struct buffer *buff;
|
||||
struct buffer *buff, *sq_buff;
|
||||
int flag;
|
||||
union sockaddr_u addr;
|
||||
ssize_t recv_count;
|
||||
@ -121,9 +121,8 @@ struct buffer *buff_get(struct buffer *root, size_t size);
|
||||
|
||||
void buff_destroy(struct buffer *root);
|
||||
|
||||
#define buff_unlock(val) \
|
||||
val->buff->lock = 0; \
|
||||
val->buff->offset = 0; \
|
||||
val->buff = 0;
|
||||
#define buff_unlock(buff) \
|
||||
buff->lock = 0; \
|
||||
buff->offset = 0;
|
||||
|
||||
#endif
|
||||
|
36
desync.c
36
desync.c
@ -476,16 +476,16 @@ static long gen_offset(long pos, int flag,
|
||||
}
|
||||
|
||||
|
||||
static ssize_t tamp(char *buffer, size_t bfsize, ssize_t n,
|
||||
static void tamp(char *buffer, size_t bfsize, ssize_t *n,
|
||||
const struct desync_params *dp, struct proto_info *info)
|
||||
{
|
||||
if (dp->mod_http && is_http(buffer, n)) {
|
||||
LOG(LOG_S, "modify HTTP: n=%zd\n", n);
|
||||
if (mod_http(buffer, n, dp->mod_http)) {
|
||||
if (dp->mod_http && is_http(buffer, *n)) {
|
||||
LOG(LOG_S, "modify HTTP: n=%zd\n", *n);
|
||||
if (mod_http(buffer, *n, dp->mod_http)) {
|
||||
LOG(LOG_E, "mod http error\n");
|
||||
}
|
||||
}
|
||||
else if (dp->tlsrec_n && is_tls_chello(buffer, n)) {
|
||||
else if (dp->tlsrec_n && is_tls_chello(buffer, *n)) {
|
||||
long lp = 0;
|
||||
struct part part;
|
||||
int i = 0, r = 0, rc = 0;
|
||||
@ -497,7 +497,7 @@ static ssize_t tamp(char *buffer, size_t bfsize, ssize_t n,
|
||||
}
|
||||
long pos = rc * 5;
|
||||
pos += gen_offset(part.pos,
|
||||
part.flag, buffer, n - pos, lp, info);
|
||||
part.flag, buffer, *n - pos, lp, info);
|
||||
|
||||
if (part.pos < 0 || part.flag) {
|
||||
pos -= 5;
|
||||
@ -508,21 +508,20 @@ static ssize_t tamp(char *buffer, size_t bfsize, ssize_t n,
|
||||
break;
|
||||
}
|
||||
if (!part_tls(buffer + lp,
|
||||
bfsize - lp, n - lp, pos - lp)) {
|
||||
LOG(LOG_E, "tlsrec error: pos=%ld, n=%zd\n", pos, n);
|
||||
bfsize - lp, *n - lp, pos - lp)) {
|
||||
LOG(LOG_E, "tlsrec error: pos=%ld, n=%zd\n", pos, *n);
|
||||
break;
|
||||
}
|
||||
LOG(LOG_S, "tlsrec: pos=%ld, n=%zd\n", pos, n);
|
||||
n += 5;
|
||||
LOG(LOG_S, "tlsrec: pos=%ld, n=%zd\n", pos, *n);
|
||||
*n += 5;
|
||||
lp = pos + 5;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
ssize_t desync(struct poolhd *pool,
|
||||
struct eval *val, struct buffer *buff, ssize_t n)
|
||||
struct eval *val, struct buffer *buff, ssize_t *np)
|
||||
{
|
||||
struct desync_params dp = params.dp[val->pair->attempt];
|
||||
struct proto_info info = { 0 };
|
||||
@ -533,18 +532,21 @@ ssize_t desync(struct poolhd *pool,
|
||||
ssize_t offset = buff->offset;
|
||||
ssize_t skip = val->pair->round_sent;
|
||||
|
||||
if (!val->recv_count && params.debug) {
|
||||
init_proto_info(buffer, n, &info);
|
||||
if (!skip && params.debug) {
|
||||
init_proto_info(buffer, *np, &info);
|
||||
|
||||
if (info.host_pos) {
|
||||
LOG(LOG_S, "host: %.*s (%d)\n",
|
||||
info.host_len, buffer + info.host_pos, info.host_pos);
|
||||
} else {
|
||||
INIT_HEX_STR(buffer, (n > 16 ? 16 : n));
|
||||
LOG(LOG_S, "bytes: %s (%zd)\n", HEX_STR, n);
|
||||
INIT_HEX_STR(buffer, (*np > 16 ? 16 : *np));
|
||||
LOG(LOG_S, "bytes: %s (%zd)\n", HEX_STR, *np);
|
||||
}
|
||||
}
|
||||
n = tamp(buffer, bfsize, n, &dp, &info);
|
||||
if (!skip) {
|
||||
tamp(buffer, bfsize, np, &dp, &info);
|
||||
}
|
||||
ssize_t n = *np;
|
||||
|
||||
long lp = offset;
|
||||
struct part part;
|
||||
|
2
desync.h
2
desync.h
@ -12,7 +12,7 @@
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
ssize_t desync(struct poolhd *pool, struct eval *val, struct buffer *buff, ssize_t n);
|
||||
ssize_t desync(struct poolhd *pool, struct eval *val, struct buffer *buff, ssize_t *n);
|
||||
|
||||
ssize_t desync_udp(int sfd, char *buffer, ssize_t n, const struct sockaddr *dst, int dp_c);
|
||||
|
||||
|
138
extend.c
138
extend.c
@ -155,14 +155,21 @@ static int reconnect(struct poolhd *pool, struct eval *val, int m)
|
||||
|
||||
struct eval *client = val->pair;
|
||||
|
||||
if (create_conn(pool, client, &val->addr, &on_first_tunnel)) {
|
||||
if (create_conn(pool, client, &val->addr, &on_tunnel)) {
|
||||
return -1;
|
||||
}
|
||||
val->pair = 0;
|
||||
del_event(pool, val);
|
||||
|
||||
client->cb = &on_tunnel;
|
||||
client->attempt = m;
|
||||
client->cache = 1;
|
||||
|
||||
struct buffer *buff = buff_get(pool->root_buff, client->sq_buff->size);
|
||||
buff->lock = client->sq_buff->lock;
|
||||
memcpy(buff->data, client->sq_buff->data, buff->lock);
|
||||
|
||||
client->buff = buff;
|
||||
client->buff->offset = 0;
|
||||
client->round_sent = 0;
|
||||
return 0;
|
||||
@ -257,7 +264,7 @@ static int on_trigger(int type, struct poolhd *pool, struct eval *val)
|
||||
{
|
||||
int m = val->pair->attempt + 1;
|
||||
|
||||
struct buffer *pair_buff = val->pair->buff;
|
||||
struct buffer *pair_buff = val->pair->sq_buff;
|
||||
bool can_reconn = (
|
||||
pair_buff && pair_buff->lock && !val->recv_count
|
||||
&& params.auto_level > AUTO_NOBUFF
|
||||
@ -317,8 +324,8 @@ static int on_response(struct poolhd *pool, struct eval *val,
|
||||
{
|
||||
int m = val->pair->attempt + 1;
|
||||
|
||||
char *req = val->pair->buff->data;
|
||||
ssize_t qn = val->pair->buff->size;
|
||||
char *req = val->pair->sq_buff->data;
|
||||
ssize_t qn = val->pair->sq_buff->size;
|
||||
|
||||
for (; m < params.dp_count; m++) {
|
||||
struct desync_params *dp = ¶ms.dp[m];
|
||||
@ -344,9 +351,8 @@ static int on_response(struct poolhd *pool, struct eval *val,
|
||||
|
||||
static inline void free_first_req(struct eval *client)
|
||||
{
|
||||
client->cb = &on_tunnel;
|
||||
client->pair->cb = &on_tunnel;
|
||||
buff_unlock(client);
|
||||
buff_unlock(client->sq_buff);
|
||||
client->sq_buff = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -396,84 +402,8 @@ static int cancel_setup(struct eval *remote)
|
||||
}
|
||||
|
||||
|
||||
static int send_saved_req(struct poolhd *pool, struct eval *client)
|
||||
{
|
||||
struct buffer *buff = buff_get(pool->root_buff, params.bfsize),
|
||||
*cb = client->buff;
|
||||
|
||||
ssize_t n = cb->lock - cb->offset;
|
||||
memcpy(buff->data, cb->data, cb->lock);
|
||||
buff->offset = cb->offset;
|
||||
|
||||
ssize_t sn = tcp_send_hook(pool, client->pair, buff, cb->lock);
|
||||
if (sn < 0) {
|
||||
return -1;
|
||||
}
|
||||
cb->offset += sn;
|
||||
if (sn < n) {
|
||||
if (mod_etype(pool, client->pair, !client->pair->tv_ms ? POLLOUT : 0) ||
|
||||
mod_etype(pool, client, 0)) {
|
||||
uniperror("mod_etype");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
buff->offset = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int on_first_tunnel(struct poolhd *pool, struct eval *val, int etype)
|
||||
{
|
||||
struct buffer *buff = buff_get(pool->root_buff, params.bfsize);
|
||||
|
||||
if (val->flag == FLAG_CONN
|
||||
&& ((etype & POLLOUT) || etype == POLLTIMEOUT)) {
|
||||
if (mod_etype(pool, val, POLLIN) ||
|
||||
mod_etype(pool, val->pair, POLLIN)) {
|
||||
uniperror("mod_etype");
|
||||
return -1;
|
||||
}
|
||||
val->pair->cb = &on_first_tunnel;
|
||||
return send_saved_req(pool, val->pair);
|
||||
}
|
||||
ssize_t n = tcp_recv_hook(pool, val, buff);
|
||||
if (n < 1) {
|
||||
return n;
|
||||
}
|
||||
if (val->flag != FLAG_CONN) {
|
||||
if (!val->buff) {
|
||||
val->buff = buff;
|
||||
}
|
||||
val->buff->lock += n;
|
||||
if (val->buff->lock >= val->buff->size) {
|
||||
free_first_req(val);
|
||||
}
|
||||
else {
|
||||
if (buff != val->buff)
|
||||
memcpy(val->buff->data + val->buff->lock - n, buff->data, n);
|
||||
return send_saved_req(pool, val);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (on_response(pool, val, buff->data, n) == 0) {
|
||||
return 0;
|
||||
}
|
||||
free_first_req(val->pair);
|
||||
int m = val->pair->attempt;
|
||||
|
||||
if (val->pair->cache && cache_add(&val->addr, m) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (tcp_send_hook(pool, val->pair, buff, n) < n) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
ssize_t tcp_send_hook(struct poolhd *pool,
|
||||
struct eval *remote, struct buffer *buff, ssize_t n)
|
||||
struct eval *remote, struct buffer *buff, ssize_t *n)
|
||||
{
|
||||
ssize_t sn = -1;
|
||||
int skip = remote->flag != FLAG_CONN;
|
||||
@ -482,8 +412,8 @@ ssize_t tcp_send_hook(struct poolhd *pool,
|
||||
if (!skip) {
|
||||
struct eval *client = remote->pair;
|
||||
|
||||
if (client->recv_count == n
|
||||
&& setup_conn(client, buff->data, n) < 0) {
|
||||
if (client->recv_count == *n
|
||||
&& setup_conn(client, buff->data, *n) < 0) {
|
||||
return -1;
|
||||
}
|
||||
int m = client->attempt, r = client->round_count;
|
||||
@ -496,7 +426,7 @@ ssize_t tcp_send_hook(struct poolhd *pool,
|
||||
}
|
||||
}
|
||||
if (skip) {
|
||||
sn = send(remote->fd, buff->data + off, n - off, 0);
|
||||
sn = send(remote->fd, buff->data + off, *n - off, 0);
|
||||
if (sn < 0 && get_e() == EAGAIN) {
|
||||
return 0;
|
||||
}
|
||||
@ -546,6 +476,40 @@ ssize_t tcp_recv_hook(struct poolhd *pool,
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
//
|
||||
if (val->flag != FLAG_CONN
|
||||
&& !val->pair->recv_count
|
||||
&& params.auto_level > AUTO_NOBUFF
|
||||
&& (val->sq_buff || val->recv_count == n))
|
||||
{
|
||||
if (!val->sq_buff) {
|
||||
buff->lock = 1;
|
||||
{
|
||||
struct buffer *b = buff_get(pool->root_buff, buff->size);
|
||||
val->sq_buff = b;
|
||||
}
|
||||
buff->lock = 0;
|
||||
}
|
||||
val->sq_buff->lock += n;
|
||||
|
||||
if ((size_t )val->sq_buff->lock >= val->sq_buff->size) {
|
||||
free_first_req(val);
|
||||
}
|
||||
else {
|
||||
memcpy(val->sq_buff->data + val->sq_buff->lock - n, buff->data, n);
|
||||
}
|
||||
}
|
||||
else if (val->pair->sq_buff) {
|
||||
if (on_response(pool, val, buff->data, n) == 0) {
|
||||
return 0;
|
||||
}
|
||||
free_first_req(val->pair);
|
||||
int m = val->pair->attempt;
|
||||
|
||||
if (val->pair->cache && cache_add(&val->addr, m) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
6
extend.h
6
extend.h
@ -11,16 +11,14 @@ int connect_hook(struct poolhd *pool, struct eval *val,
|
||||
const union sockaddr_u *dst, evcb_t next);
|
||||
|
||||
ssize_t tcp_send_hook(struct poolhd *pool,
|
||||
struct eval *remote, struct buffer *buff, ssize_t n);
|
||||
struct eval *remote, struct buffer *buff, ssize_t *n);
|
||||
|
||||
ssize_t tcp_recv_hook(struct poolhd *pool,
|
||||
struct eval *val, struct buffer *buff);
|
||||
|
||||
ssize_t udp_hook(struct eval *val,
|
||||
char *buffer, ssize_t n, const union sockaddr_u *dst);
|
||||
|
||||
int on_first_tunnel(struct poolhd *pool, struct eval *val, int etype);
|
||||
|
||||
|
||||
#ifdef __linux__
|
||||
static int protect(int conn_fd, const char *path);
|
||||
#else
|
||||
|
13
proxy.c
13
proxy.c
@ -662,7 +662,7 @@ int on_tunnel(struct poolhd *pool, struct eval *val, int etype)
|
||||
}
|
||||
n = val->buff->lock - val->buff->offset;
|
||||
|
||||
ssize_t sn = tcp_send_hook(pool, pair, val->buff, val->buff->lock);
|
||||
ssize_t sn = tcp_send_hook(pool, pair, val->buff, &val->buff->lock);
|
||||
if (sn < 0) {
|
||||
uniperror("send");
|
||||
return -1;
|
||||
@ -671,7 +671,8 @@ int on_tunnel(struct poolhd *pool, struct eval *val, int etype)
|
||||
val->buff->offset += sn;
|
||||
return 0;
|
||||
}
|
||||
buff_unlock(val);
|
||||
buff_unlock(val->buff);
|
||||
val->buff = 0;
|
||||
|
||||
if (mod_etype(pool, val, POLLIN) ||
|
||||
mod_etype(pool, pair, POLLIN)) {
|
||||
@ -689,7 +690,7 @@ int on_tunnel(struct poolhd *pool, struct eval *val, int etype)
|
||||
if (n < 0) {
|
||||
return -1;
|
||||
}
|
||||
ssize_t sn = tcp_send_hook(pool, pair, buff, n);
|
||||
ssize_t sn = tcp_send_hook(pool, pair, buff, &n);
|
||||
if (sn < 0) {
|
||||
uniperror("send");
|
||||
return -1;
|
||||
@ -903,10 +904,8 @@ int on_connect(struct poolhd *pool, struct eval *val, int et)
|
||||
uniperror("mod_etype");
|
||||
return -1;
|
||||
}
|
||||
evcb_t t = params.auto_level <= AUTO_NOBUFF
|
||||
? &on_tunnel : &on_first_tunnel;
|
||||
val->cb = t;
|
||||
val->pair->cb = t;
|
||||
val->cb = &on_tunnel;
|
||||
val->pair->cb = &on_tunnel;
|
||||
}
|
||||
if (resp_error(val->pair->fd,
|
||||
error, val->pair->flag) < 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user