mirror of
https://github.com/hufrea/byedpi.git
synced 2024-12-22 06:15:14 +00:00
Auto as tunnel hooks, --repeats
This commit is contained in:
parent
6dca571567
commit
6ce89b63aa
9
conev.h
9
conev.h
@ -37,9 +37,7 @@ enum eid {
|
||||
EV_CONNECT,
|
||||
EV_IGNORE,
|
||||
EV_TUNNEL,
|
||||
EV_PRE_TUNNEL,
|
||||
EV_UDP_TUNNEL,
|
||||
EV_DESYNC
|
||||
EV_UDP_TUNNEL
|
||||
};
|
||||
|
||||
#define FLAG_S4 1
|
||||
@ -53,9 +51,7 @@ char *eid_name[] = {
|
||||
"EV_CONNECT",
|
||||
"EV_IGNORE",
|
||||
"EV_TUNNEL",
|
||||
"EV_PRE_TUNNEL",
|
||||
"EV_UDP_TUNNEL",
|
||||
"EV_DESYNC"
|
||||
"EV_UDP_TUNNEL"
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -63,6 +59,7 @@ struct buffer {
|
||||
ssize_t size;
|
||||
int offset;
|
||||
char *data;
|
||||
char locked;
|
||||
};
|
||||
|
||||
struct eval {
|
||||
|
259
extend.c
259
extend.c
@ -153,16 +153,18 @@ int socket_mod(int fd, struct sockaddr *dst)
|
||||
|
||||
int reconnect(struct poolhd *pool, struct eval *val, int m)
|
||||
{
|
||||
assert(val->flag == FLAG_CONN);
|
||||
|
||||
struct eval *client = val->pair;
|
||||
|
||||
if (create_conn(pool, client,
|
||||
(struct sockaddr_ina *)&val->in6, EV_DESYNC)) {
|
||||
(struct sockaddr_ina *)&val->in6, EV_TUNNEL)) {
|
||||
return -1;
|
||||
}
|
||||
val->pair = 0;
|
||||
del_event(pool, val);
|
||||
|
||||
client->type = EV_IGNORE;
|
||||
//client->type = EV_IGNORE;
|
||||
client->attempt = m;
|
||||
client->cache = 1;
|
||||
client->buff.offset = 0;
|
||||
@ -269,7 +271,7 @@ int on_fin(struct poolhd *pool, struct eval *val)
|
||||
|
||||
ssl_err = is_tls_chello(req, qn);
|
||||
}
|
||||
else if (val->mark && val->round_count <= 1) {
|
||||
else if (val->pair->mark && val->round_count <= 1) {
|
||||
ssl_err = 1;
|
||||
}
|
||||
if (!ssl_err) {
|
||||
@ -328,156 +330,143 @@ int on_response(struct poolhd *pool, struct eval *val,
|
||||
}
|
||||
|
||||
|
||||
static inline void to_tunnel(struct eval *client)
|
||||
static inline void free_first_req(struct eval *client)
|
||||
{
|
||||
client->pair->type = EV_TUNNEL;
|
||||
client->type = EV_TUNNEL;
|
||||
|
||||
assert(client->buff.data);
|
||||
free(client->buff.data);
|
||||
client->buff.data = 0;
|
||||
client->buff.size = 0;
|
||||
client->buff.offset = 0;
|
||||
memset(&client->buff, 0, sizeof(client->buff));
|
||||
}
|
||||
|
||||
|
||||
int on_tunnel_check(struct poolhd *pool, struct eval *val,
|
||||
char *buffer, size_t bfsize, int out)
|
||||
ssize_t on_first_send(struct eval *client, char *buffer, ssize_t bfsize)
|
||||
{
|
||||
assert(!out);
|
||||
ssize_t n = recv(val->fd, buffer, bfsize, 0);
|
||||
if (n < 1) {
|
||||
if (!n) {
|
||||
return on_fin(pool, val);
|
||||
}
|
||||
uniperror("recv");
|
||||
switch (get_e()) {
|
||||
case ECONNRESET:
|
||||
case ECONNREFUSED:
|
||||
case ETIMEDOUT:
|
||||
return on_torst(pool, val);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
//
|
||||
if (on_response(pool, val, buffer, n) == 0) {
|
||||
return 0;
|
||||
}
|
||||
val->recv_count += n;
|
||||
val->round_count = 1;
|
||||
val->last_round = 1;
|
||||
struct eval *pair = val->pair;
|
||||
int m = client->attempt;
|
||||
|
||||
ssize_t sn = send(pair->fd, buffer, n, 0);
|
||||
if (n != sn) {
|
||||
uniperror("send");
|
||||
return -1;
|
||||
}
|
||||
if (params.auto_level > 0 && params.dp_count > 1) {
|
||||
val->mark = is_tls_chello(pair->buff.data, pair->buff.size);
|
||||
}
|
||||
to_tunnel(pair);
|
||||
|
||||
if (params.timeout && params.auto_level < 1 &&
|
||||
set_timeout(val->fd, 0)) {
|
||||
return -1;
|
||||
}
|
||||
int m = pair->attempt;
|
||||
|
||||
if (post_desync(val->fd, m)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!pair->cache) {
|
||||
return 0;
|
||||
}
|
||||
return mode_add_get((struct sockaddr_ina *)&val->in6, m);
|
||||
}
|
||||
|
||||
|
||||
int on_desync_again(struct poolhd *pool,
|
||||
struct eval *val, char *buffer, size_t bfsize)
|
||||
{
|
||||
if (val->flag == FLAG_CONN) {
|
||||
if (mod_etype(pool, val, POLLIN) ||
|
||||
mod_etype(pool, val->pair, POLLIN)) {
|
||||
uniperror("mod_etype");
|
||||
return -1;
|
||||
}
|
||||
val = val->pair;
|
||||
}
|
||||
int m = val->attempt;
|
||||
LOG((m ? LOG_S : LOG_L), "desync params index: %d\n", m);
|
||||
|
||||
ssize_t n = val->buff.size;
|
||||
assert(n > 0 && n <= params.bfsize);
|
||||
memcpy(buffer, val->buff.data, n);
|
||||
|
||||
if (params.timeout &&
|
||||
set_timeout(val->pair->fd, params.timeout)) {
|
||||
return -1;
|
||||
}
|
||||
ssize_t sn = desync(val->pair->fd, buffer, bfsize, n,
|
||||
val->buff.offset, (struct sockaddr *)&val->pair->in6, m);
|
||||
if (sn < 0) {
|
||||
return -1;
|
||||
}
|
||||
val->buff.offset += sn;
|
||||
if (sn < n) {
|
||||
if (mod_etype(pool, val->pair, POLLOUT)) {
|
||||
uniperror("mod_etype");
|
||||
return -1;
|
||||
}
|
||||
val->pair->type = EV_DESYNC;
|
||||
return 0;
|
||||
}
|
||||
val->pair->type = EV_PRE_TUNNEL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int on_desync(struct poolhd *pool, struct eval *val,
|
||||
char *buffer, size_t bfsize, int out)
|
||||
{
|
||||
if (out) {
|
||||
return on_desync_again(pool, val, buffer, bfsize);
|
||||
}
|
||||
if (val->buff.size == bfsize) {
|
||||
to_tunnel(val);
|
||||
return 0;
|
||||
}
|
||||
ssize_t n = recv(val->fd, buffer, bfsize - val->buff.size, 0);
|
||||
if (n <= 0) {
|
||||
if (n) uniperror("recv data");
|
||||
return -1;
|
||||
}
|
||||
val->buff.size += n;
|
||||
val->recv_count += n;
|
||||
val->round_count = 1;
|
||||
|
||||
val->buff.data = realloc(val->buff.data, val->buff.size);
|
||||
if (val->buff.data == 0) {
|
||||
uniperror("realloc");
|
||||
return -1;
|
||||
}
|
||||
memcpy(val->buff.data + val->buff.size - n, buffer, n);
|
||||
|
||||
int m = val->attempt;
|
||||
if (!m) for (; m < params.dp_count; m++) {
|
||||
struct desync_params *dp = ¶ms.dp[m];
|
||||
if (!dp->detect &&
|
||||
(!dp->pf[0] || check_port(dp->pf, &val->pair->in6)) &&
|
||||
(!dp->proto || check_proto_tcp(dp->proto, val)) &&
|
||||
(!dp->hosts || check_host(dp->hosts, val))) {
|
||||
(!dp->pf[0] || check_port(dp->pf, &client->pair->in6)) &&
|
||||
(!dp->proto || check_proto_tcp(dp->proto, client)) &&
|
||||
(!dp->hosts || check_host(dp->hosts, client))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (m >= params.dp_count) {
|
||||
return -1;
|
||||
}
|
||||
val->attempt = m;
|
||||
if (params.auto_level > 0 && params.dp_count > 1) {
|
||||
client->mark = is_tls_chello(client->buff.data, client->buff.size);
|
||||
}
|
||||
client->attempt = m;
|
||||
|
||||
return on_desync_again(pool, val, buffer, bfsize);
|
||||
if (params.timeout
|
||||
&& set_timeout(client->pair->fd, params.timeout)) {
|
||||
return -1;
|
||||
}
|
||||
assert(bfsize >= client->buff.size);
|
||||
memcpy(buffer, client->buff.data, client->buff.size);
|
||||
|
||||
return client->buff.size;
|
||||
}
|
||||
|
||||
|
||||
ssize_t tcp_send_hook(struct poolhd *pool, struct eval *remote,
|
||||
char *buffer, size_t bfsize, ssize_t n)
|
||||
{
|
||||
ssize_t sn = -1;
|
||||
|
||||
if (remote->flag != FLAG_CONN
|
||||
|| remote->pair->round_count > params.repeats) {
|
||||
sn = send(remote->fd, buffer, n, 0);
|
||||
if (sn < 0 && get_e() == EAGAIN) {
|
||||
return 0;
|
||||
}
|
||||
return sn;
|
||||
}
|
||||
struct eval *client = remote->pair;
|
||||
int m = client->attempt;
|
||||
|
||||
if (client->recv_count == n) {
|
||||
n = on_first_send(client, buffer, bfsize);
|
||||
if (n < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
LOG((m ? LOG_S : LOG_L), "desync params index: %d\n", m);
|
||||
|
||||
sn = desync(remote->fd, buffer, bfsize, n,
|
||||
0, (struct sockaddr *)&remote->in6, m);
|
||||
return sn;
|
||||
}
|
||||
|
||||
|
||||
ssize_t tcp_recv_hook(struct poolhd *pool, struct eval *val,
|
||||
char *buffer, size_t bfsize)
|
||||
{
|
||||
ssize_t n = recv(val->fd, buffer, bfsize, 0);
|
||||
if (n < 1) {
|
||||
if (!n) {
|
||||
if (val->flag != FLAG_CONN) {
|
||||
val = val->pair;
|
||||
}
|
||||
return on_fin(pool, val);
|
||||
}
|
||||
if (get_e() == EAGAIN) {
|
||||
return 0;
|
||||
}
|
||||
uniperror("recv");
|
||||
switch (get_e()) {
|
||||
case ECONNRESET:
|
||||
case ECONNREFUSED:
|
||||
case ETIMEDOUT:
|
||||
if (val->flag == FLAG_CONN)
|
||||
return on_torst(pool, val);
|
||||
else
|
||||
return on_fin(pool, val->pair);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (val->flag != FLAG_CONN && val->pair->recv_count == 0)
|
||||
{
|
||||
val->buff.size += n;
|
||||
|
||||
if (val->buff.size >= bfsize) {
|
||||
free_first_req(val);
|
||||
return n;
|
||||
}
|
||||
val->buff.locked = 1;
|
||||
val->buff.data = realloc(val->buff.data, val->buff.size);
|
||||
|
||||
if (val->buff.data == 0) {
|
||||
uniperror("realloc");
|
||||
return -1;
|
||||
}
|
||||
memcpy(val->buff.data + val->buff.size - n, buffer, n);
|
||||
}
|
||||
else if (val->recv_count == 0 && val->flag == FLAG_CONN)
|
||||
{
|
||||
if (val->pair->buff.locked) {
|
||||
if (on_response(pool, val, buffer, n) == 0) {
|
||||
return 0;
|
||||
}
|
||||
free_first_req(val->pair);
|
||||
}
|
||||
if (params.timeout && params.auto_level < 1 &&
|
||||
set_timeout(val->fd, 0)) {
|
||||
return -1;
|
||||
}
|
||||
int m = val->pair->attempt;
|
||||
|
||||
if (post_desync(val->fd, m)) {
|
||||
return -1;
|
||||
}
|
||||
if (val->pair->cache &&
|
||||
mode_add_get((struct sockaddr_ina *)&val->in6, m) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
|
16
extend.h
16
extend.h
@ -10,19 +10,15 @@ int socket_mod(int fd, struct sockaddr *dst);
|
||||
int connect_hook(struct poolhd *pool, struct eval *val,
|
||||
struct sockaddr_ina *dst, int next);
|
||||
|
||||
int on_tunnel_check(struct poolhd *pool, struct eval *val,
|
||||
char *buffer, size_t bfsize, int out);
|
||||
|
||||
int on_desync(struct poolhd *pool, struct eval *val,
|
||||
char *buffer, size_t bfsize, int out);
|
||||
|
||||
ssize_t tcp_send_hook(struct poolhd *pool, struct eval *val,
|
||||
char *buffer, size_t bfsize, ssize_t n);
|
||||
|
||||
ssize_t tcp_recv_hook(struct poolhd *pool, struct eval *val,
|
||||
char *buffer, size_t bfsize);
|
||||
|
||||
ssize_t udp_hook(struct eval *val,
|
||||
char *buffer, size_t bfsize, ssize_t n, struct sockaddr_ina *dst);
|
||||
|
||||
int on_torst(struct poolhd *pool, struct eval *val);
|
||||
|
||||
int on_fin(struct poolhd *pool, struct eval *val);
|
||||
|
||||
#ifdef __linux__
|
||||
int protect(int conn_fd, const char *path);
|
||||
#else
|
||||
|
16
main.c
16
main.c
@ -54,8 +54,9 @@ struct params params = {
|
||||
.laddr = {
|
||||
.sin6_family = AF_INET
|
||||
},
|
||||
.repeats = 1,
|
||||
.debug = 0,
|
||||
.auto_level = 0
|
||||
.auto_level = -1
|
||||
};
|
||||
|
||||
|
||||
@ -80,6 +81,7 @@ const char help_text[] = {
|
||||
" Detect: torst,redirect,ssl_err,none\n"
|
||||
" -L, --auto-mode <0|1> 1 - handle trigger after several packets\n"
|
||||
" -u, --cache-ttl <sec> Lifetime of cached desync params for IP\n"
|
||||
" -R, --repeats <num> Number of requests to which desync will be applied\n"
|
||||
#ifdef TIMEOUT_SUPPORT
|
||||
" -T, --timeout <sec> Timeout waiting for response, after which trigger auto\n"
|
||||
#endif
|
||||
@ -134,6 +136,7 @@ const struct option options[] = {
|
||||
#endif
|
||||
{"auto", 1, 0, 'A'},
|
||||
{"auto-mode", 1, 0, 'L'},
|
||||
{"repeats", 1, 0, 'R'},
|
||||
{"cache-ttl", 1, 0, 'u'},
|
||||
#ifdef TIMEOUT_SUPPORT
|
||||
{"timeout", 1, 0, 'T'},
|
||||
@ -616,6 +619,14 @@ int main(int argc, char **argv)
|
||||
params.auto_level = val;
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
val = strtol(optarg, &end, 0);
|
||||
if (val < 1 || val > INT_MAX || *end)
|
||||
invalid = 1;
|
||||
else
|
||||
params.repeats = val;
|
||||
break;
|
||||
|
||||
case 'A':
|
||||
if (!(dp->hosts || dp->proto || dp->pf[0] || dp->detect)) {
|
||||
all_limited = 0;
|
||||
@ -648,6 +659,9 @@ int main(int argc, char **argv)
|
||||
end = strchr(end, ',');
|
||||
if (end) end++;
|
||||
}
|
||||
if (dp->detect && params.auto_level == -1) {
|
||||
params.auto_level = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
|
2
params.h
2
params.h
@ -114,6 +114,8 @@ struct params {
|
||||
struct mphdr *mempool;
|
||||
|
||||
char *protect_path;
|
||||
|
||||
int repeats;
|
||||
};
|
||||
|
||||
extern struct params params;
|
||||
|
91
proxy.c
91
proxy.c
@ -424,7 +424,7 @@ int create_conn(struct poolhd *pool,
|
||||
pair->in6 = dst->in6;
|
||||
#endif
|
||||
pair->flag = FLAG_CONN;
|
||||
val->type = EV_IGNORE;
|
||||
//val->type = EV_IGNORE;
|
||||
|
||||
if (params.debug) {
|
||||
INIT_ADDR_STR((*dst));
|
||||
@ -641,17 +641,18 @@ int on_tunnel(struct poolhd *pool, struct eval *val,
|
||||
LOG(LOG_S, "pollout (fd=%d)\n", val->fd);
|
||||
val = pair;
|
||||
pair = val->pair;
|
||||
}
|
||||
if (val->buff.data) {
|
||||
assert(val->buff.data);
|
||||
|
||||
if (etype & POLLHUP) {
|
||||
return -1;
|
||||
}
|
||||
n = val->buff.size - val->buff.offset;
|
||||
|
||||
ssize_t sn = send(pair->fd,
|
||||
val->buff.data + val->buff.offset, n, 0);
|
||||
if (sn != n) {
|
||||
if (sn < 0 && get_e() != EAGAIN) {
|
||||
ssize_t sn = tcp_send_hook(pool, pair,
|
||||
val->buff.data + val->buff.offset, n, n);
|
||||
|
||||
if (sn < n) {
|
||||
if (sn < 0) {
|
||||
uniperror("send");
|
||||
return -1;
|
||||
}
|
||||
@ -659,10 +660,12 @@ int on_tunnel(struct poolhd *pool, struct eval *val,
|
||||
val->buff.offset += sn;
|
||||
return 0;
|
||||
}
|
||||
free(val->buff.data);
|
||||
val->buff.data = 0;
|
||||
val->buff.size = 0;
|
||||
val->buff.offset = 0;
|
||||
if (!val->buff.locked) {
|
||||
free(val->buff.data);
|
||||
val->buff.data = 0;
|
||||
val->buff.size = 0;
|
||||
val->buff.offset = 0;
|
||||
}
|
||||
|
||||
if (mod_etype(pool, val, POLLIN) ||
|
||||
mod_etype(pool, pair, POLLIN)) {
|
||||
@ -670,27 +673,16 @@ int on_tunnel(struct poolhd *pool, struct eval *val,
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (val->buff.data && !val->buff.locked) {
|
||||
return 0;
|
||||
}
|
||||
do {
|
||||
n = recv(val->fd, buffer, bfsize, 0);
|
||||
if (n < 0 && get_e() == EAGAIN) {
|
||||
n = tcp_recv_hook(pool, val, buffer, bfsize);
|
||||
//if (n < 0 && get_e() == EAGAIN) {
|
||||
if (n == 0) {
|
||||
break;
|
||||
}
|
||||
if (n == 0) {
|
||||
if (val->flag != FLAG_CONN)
|
||||
val = val->pair;
|
||||
on_fin(pool, val);
|
||||
return -1;
|
||||
}
|
||||
if (n < 0) {
|
||||
uniperror("recv");
|
||||
switch (get_e()) {
|
||||
case ECONNRESET:
|
||||
case ETIMEDOUT:
|
||||
if (val->flag == FLAG_CONN)
|
||||
on_torst(pool, val);
|
||||
else
|
||||
on_fin(pool, val->pair);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
val->recv_count += n;
|
||||
@ -700,25 +692,24 @@ int on_tunnel(struct poolhd *pool, struct eval *val,
|
||||
pair->last_round = 0;
|
||||
}
|
||||
|
||||
ssize_t sn = send(pair->fd, buffer, n, 0);
|
||||
if (sn != n) {
|
||||
ssize_t sn = tcp_send_hook(pool, pair, buffer, bfsize, n);
|
||||
if (sn < n) {
|
||||
if (sn < 0) {
|
||||
if (get_e() != EAGAIN) {
|
||||
uniperror("send");
|
||||
return -1;
|
||||
}
|
||||
sn = 0;
|
||||
}
|
||||
LOG(LOG_S, "send: %zd != %zd (fd: %d)\n", sn, n, pair->fd);
|
||||
assert(!(val->buff.size || val->buff.offset));
|
||||
|
||||
val->buff.size = n - sn;
|
||||
if (!(val->buff.data = malloc(n - sn))) {
|
||||
uniperror("malloc");
|
||||
uniperror("send");
|
||||
return -1;
|
||||
}
|
||||
memcpy(val->buff.data, buffer + sn, n - sn);
|
||||
LOG(LOG_S, "send: %zd != %zd (fd: %d)\n", sn, n, pair->fd);
|
||||
assert(val->buff.locked
|
||||
|| !(val->buff.size || val->buff.offset));
|
||||
|
||||
if (!val->buff.locked) {
|
||||
val->buff.size = n - sn;
|
||||
if (!(val->buff.data = malloc(n - sn))) {
|
||||
uniperror("malloc");
|
||||
return -1;
|
||||
}
|
||||
memcpy(val->buff.data, buffer + sn, n - sn);
|
||||
}
|
||||
if (mod_etype(pool, val, 0) ||
|
||||
mod_etype(pool, pair, POLLOUT)) {
|
||||
uniperror("mod_etype");
|
||||
@ -907,7 +898,7 @@ static inline int on_connect(struct poolhd *pool, struct eval *val, int e)
|
||||
return -1;
|
||||
}
|
||||
val->type = EV_TUNNEL;
|
||||
val->pair->type = EV_DESYNC;
|
||||
val->pair->type = EV_TUNNEL;
|
||||
}
|
||||
if (resp_error(val->pair->fd,
|
||||
error, val->pair->flag) < 0) {
|
||||
@ -977,12 +968,6 @@ int event_loop(int srvfd)
|
||||
close_conn(pool, val);
|
||||
continue;
|
||||
|
||||
case EV_PRE_TUNNEL:
|
||||
if (on_tunnel_check(pool, val,
|
||||
buffer, bfsize, etype & POLLOUT))
|
||||
close_conn(pool, val);
|
||||
continue;
|
||||
|
||||
case EV_TUNNEL:
|
||||
if (on_tunnel(pool, val, buffer, bfsize, etype))
|
||||
close_conn(pool, val);
|
||||
@ -998,12 +983,6 @@ int event_loop(int srvfd)
|
||||
close_conn(pool, val);
|
||||
continue;
|
||||
|
||||
case EV_DESYNC:
|
||||
if (on_desync(pool, val,
|
||||
buffer, bfsize, etype & POLLOUT))
|
||||
close_conn(pool, val);
|
||||
continue;
|
||||
|
||||
case EV_IGNORE:
|
||||
if (etype & (POLLHUP | POLLERR | POLLRDHUP))
|
||||
close_conn(pool, val);
|
||||
|
Loading…
Reference in New Issue
Block a user