mirror of
https://github.com/hufrea/byedpi.git
synced 2025-07-04 21:14:18 +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);
|
epoll_ctl(pool->efd, EPOLL_CTL_DEL, val->fd, 0);
|
||||||
#endif
|
#endif
|
||||||
if (val->buff) {
|
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);
|
close(val->fd);
|
||||||
val->fd = -1;
|
val->fd = -1;
|
||||||
|
11
conev.h
11
conev.h
@ -53,7 +53,7 @@ union sockaddr_u {
|
|||||||
struct buffer {
|
struct buffer {
|
||||||
size_t size;
|
size_t size;
|
||||||
unsigned int offset;
|
unsigned int offset;
|
||||||
size_t lock;
|
ssize_t lock;
|
||||||
struct buffer *next;
|
struct buffer *next;
|
||||||
char data[];
|
char data[];
|
||||||
};
|
};
|
||||||
@ -68,7 +68,7 @@ struct eval {
|
|||||||
struct eval *tv_next, *tv_prev;
|
struct eval *tv_next, *tv_prev;
|
||||||
|
|
||||||
struct eval *pair;
|
struct eval *pair;
|
||||||
struct buffer *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;
|
||||||
@ -121,9 +121,8 @@ struct buffer *buff_get(struct buffer *root, size_t size);
|
|||||||
|
|
||||||
void buff_destroy(struct buffer *root);
|
void buff_destroy(struct buffer *root);
|
||||||
|
|
||||||
#define buff_unlock(val) \
|
#define buff_unlock(buff) \
|
||||||
val->buff->lock = 0; \
|
buff->lock = 0; \
|
||||||
val->buff->offset = 0; \
|
buff->offset = 0;
|
||||||
val->buff = 0;
|
|
||||||
|
|
||||||
#endif
|
#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)
|
const struct desync_params *dp, struct proto_info *info)
|
||||||
{
|
{
|
||||||
if (dp->mod_http && is_http(buffer, n)) {
|
if (dp->mod_http && is_http(buffer, *n)) {
|
||||||
LOG(LOG_S, "modify HTTP: n=%zd\n", n);
|
LOG(LOG_S, "modify HTTP: n=%zd\n", *n);
|
||||||
if (mod_http(buffer, n, dp->mod_http)) {
|
if (mod_http(buffer, *n, dp->mod_http)) {
|
||||||
LOG(LOG_E, "mod http error\n");
|
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;
|
long lp = 0;
|
||||||
struct part part;
|
struct part part;
|
||||||
int i = 0, r = 0, rc = 0;
|
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;
|
long pos = rc * 5;
|
||||||
pos += gen_offset(part.pos,
|
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) {
|
if (part.pos < 0 || part.flag) {
|
||||||
pos -= 5;
|
pos -= 5;
|
||||||
@ -508,21 +508,20 @@ static ssize_t tamp(char *buffer, size_t bfsize, ssize_t n,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!part_tls(buffer + lp,
|
if (!part_tls(buffer + lp,
|
||||||
bfsize - lp, n - lp, pos - lp)) {
|
bfsize - lp, *n - lp, pos - lp)) {
|
||||||
LOG(LOG_E, "tlsrec error: pos=%ld, n=%zd\n", pos, n);
|
LOG(LOG_E, "tlsrec error: pos=%ld, n=%zd\n", pos, *n);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
LOG(LOG_S, "tlsrec: pos=%ld, n=%zd\n", pos, n);
|
LOG(LOG_S, "tlsrec: pos=%ld, n=%zd\n", pos, *n);
|
||||||
n += 5;
|
*n += 5;
|
||||||
lp = pos + 5;
|
lp = pos + 5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ssize_t desync(struct poolhd *pool,
|
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 desync_params dp = params.dp[val->pair->attempt];
|
||||||
struct proto_info info = { 0 };
|
struct proto_info info = { 0 };
|
||||||
@ -533,18 +532,21 @@ ssize_t desync(struct poolhd *pool,
|
|||||||
ssize_t offset = buff->offset;
|
ssize_t offset = buff->offset;
|
||||||
ssize_t skip = val->pair->round_sent;
|
ssize_t skip = val->pair->round_sent;
|
||||||
|
|
||||||
if (!val->recv_count && params.debug) {
|
if (!skip && params.debug) {
|
||||||
init_proto_info(buffer, n, &info);
|
init_proto_info(buffer, *np, &info);
|
||||||
|
|
||||||
if (info.host_pos) {
|
if (info.host_pos) {
|
||||||
LOG(LOG_S, "host: %.*s (%d)\n",
|
LOG(LOG_S, "host: %.*s (%d)\n",
|
||||||
info.host_len, buffer + info.host_pos, info.host_pos);
|
info.host_len, buffer + info.host_pos, info.host_pos);
|
||||||
} else {
|
} else {
|
||||||
INIT_HEX_STR(buffer, (n > 16 ? 16 : n));
|
INIT_HEX_STR(buffer, (*np > 16 ? 16 : *np));
|
||||||
LOG(LOG_S, "bytes: %s (%zd)\n", HEX_STR, n);
|
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;
|
long lp = offset;
|
||||||
struct part part;
|
struct part part;
|
||||||
|
2
desync.h
2
desync.h
@ -12,7 +12,7 @@
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#endif
|
#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);
|
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;
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
val->pair = 0;
|
val->pair = 0;
|
||||||
del_event(pool, val);
|
del_event(pool, val);
|
||||||
|
|
||||||
|
client->cb = &on_tunnel;
|
||||||
client->attempt = m;
|
client->attempt = m;
|
||||||
client->cache = 1;
|
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->buff->offset = 0;
|
||||||
client->round_sent = 0;
|
client->round_sent = 0;
|
||||||
return 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;
|
int m = val->pair->attempt + 1;
|
||||||
|
|
||||||
struct buffer *pair_buff = val->pair->buff;
|
struct buffer *pair_buff = val->pair->sq_buff;
|
||||||
bool can_reconn = (
|
bool can_reconn = (
|
||||||
pair_buff && pair_buff->lock && !val->recv_count
|
pair_buff && pair_buff->lock && !val->recv_count
|
||||||
&& params.auto_level > AUTO_NOBUFF
|
&& 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;
|
int m = val->pair->attempt + 1;
|
||||||
|
|
||||||
char *req = val->pair->buff->data;
|
char *req = val->pair->sq_buff->data;
|
||||||
ssize_t qn = val->pair->buff->size;
|
ssize_t qn = val->pair->sq_buff->size;
|
||||||
|
|
||||||
for (; m < params.dp_count; m++) {
|
for (; m < params.dp_count; m++) {
|
||||||
struct desync_params *dp = ¶ms.dp[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)
|
static inline void free_first_req(struct eval *client)
|
||||||
{
|
{
|
||||||
client->cb = &on_tunnel;
|
buff_unlock(client->sq_buff);
|
||||||
client->pair->cb = &on_tunnel;
|
client->sq_buff = 0;
|
||||||
buff_unlock(client);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -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,
|
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;
|
ssize_t sn = -1;
|
||||||
int skip = remote->flag != FLAG_CONN;
|
int skip = remote->flag != FLAG_CONN;
|
||||||
@ -482,8 +412,8 @@ ssize_t tcp_send_hook(struct poolhd *pool,
|
|||||||
if (!skip) {
|
if (!skip) {
|
||||||
struct eval *client = remote->pair;
|
struct eval *client = remote->pair;
|
||||||
|
|
||||||
if (client->recv_count == n
|
if (client->recv_count == *n
|
||||||
&& setup_conn(client, buff->data, n) < 0) {
|
&& setup_conn(client, buff->data, *n) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int m = client->attempt, r = client->round_count;
|
int m = client->attempt, r = client->round_count;
|
||||||
@ -496,7 +426,7 @@ ssize_t tcp_send_hook(struct poolhd *pool,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (skip) {
|
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) {
|
if (sn < 0 && get_e() == EAGAIN) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -546,6 +476,40 @@ ssize_t tcp_recv_hook(struct poolhd *pool,
|
|||||||
return -1;
|
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;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
4
extend.h
4
extend.h
@ -11,7 +11,7 @@ int connect_hook(struct poolhd *pool, struct eval *val,
|
|||||||
const union sockaddr_u *dst, evcb_t next);
|
const union sockaddr_u *dst, evcb_t next);
|
||||||
|
|
||||||
ssize_t tcp_send_hook(struct poolhd *pool,
|
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,
|
ssize_t tcp_recv_hook(struct poolhd *pool,
|
||||||
struct eval *val, struct buffer *buff);
|
struct eval *val, struct buffer *buff);
|
||||||
@ -19,8 +19,6 @@ ssize_t tcp_recv_hook(struct poolhd *pool,
|
|||||||
ssize_t udp_hook(struct eval *val,
|
ssize_t udp_hook(struct eval *val,
|
||||||
char *buffer, ssize_t n, const union sockaddr_u *dst);
|
char *buffer, ssize_t n, const union sockaddr_u *dst);
|
||||||
|
|
||||||
int on_first_tunnel(struct poolhd *pool, struct eval *val, int etype);
|
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
static int protect(int conn_fd, const char *path);
|
static int protect(int conn_fd, const char *path);
|
||||||
#else
|
#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;
|
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) {
|
if (sn < 0) {
|
||||||
uniperror("send");
|
uniperror("send");
|
||||||
return -1;
|
return -1;
|
||||||
@ -671,7 +671,8 @@ int on_tunnel(struct poolhd *pool, struct eval *val, int etype)
|
|||||||
val->buff->offset += sn;
|
val->buff->offset += sn;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
buff_unlock(val);
|
buff_unlock(val->buff);
|
||||||
|
val->buff = 0;
|
||||||
|
|
||||||
if (mod_etype(pool, val, POLLIN) ||
|
if (mod_etype(pool, val, POLLIN) ||
|
||||||
mod_etype(pool, pair, POLLIN)) {
|
mod_etype(pool, pair, POLLIN)) {
|
||||||
@ -689,7 +690,7 @@ int on_tunnel(struct poolhd *pool, struct eval *val, int etype)
|
|||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
return -1;
|
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) {
|
if (sn < 0) {
|
||||||
uniperror("send");
|
uniperror("send");
|
||||||
return -1;
|
return -1;
|
||||||
@ -903,10 +904,8 @@ int on_connect(struct poolhd *pool, struct eval *val, int et)
|
|||||||
uniperror("mod_etype");
|
uniperror("mod_etype");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
evcb_t t = params.auto_level <= AUTO_NOBUFF
|
val->cb = &on_tunnel;
|
||||||
? &on_tunnel : &on_first_tunnel;
|
val->pair->cb = &on_tunnel;
|
||||||
val->cb = t;
|
|
||||||
val->pair->cb = t;
|
|
||||||
}
|
}
|
||||||
if (resp_error(val->pair->fd,
|
if (resp_error(val->pair->fd,
|
||||||
error, val->pair->flag) < 0) {
|
error, val->pair->flag) < 0) {
|
||||||
|
Loading…
Reference in New Issue
Block a user