mirror of
https://github.com/hufrea/byedpi.git
synced 2025-06-30 02:31:15 +00:00
Lazy buffer alloc
This commit is contained in:
parent
0985f13d39
commit
750999dcf3
52
conev.c
52
conev.c
@ -89,10 +89,9 @@ void del_event(struct poolhd *pool, struct eval *val)
|
|||||||
#else
|
#else
|
||||||
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.data) {
|
if (val->buff && val->buff->lock) {
|
||||||
assert(val->buff.size);
|
val->buff->lock = 0;
|
||||||
free(val->buff.data);
|
val->buff->offset = 0;
|
||||||
val->buff.data = 0;
|
|
||||||
}
|
}
|
||||||
close(val->fd);
|
close(val->fd);
|
||||||
val->fd = -1;
|
val->fd = -1;
|
||||||
@ -130,10 +129,6 @@ void destroy_pool(struct poolhd *pool)
|
|||||||
close(val->fd);
|
close(val->fd);
|
||||||
val->fd = 0;
|
val->fd = 0;
|
||||||
}
|
}
|
||||||
if (val->buff.data) {
|
|
||||||
free(val->buff.data);
|
|
||||||
val->buff.data = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
free(pool->items);
|
free(pool->items);
|
||||||
free(pool->links);
|
free(pool->links);
|
||||||
@ -142,6 +137,7 @@ void destroy_pool(struct poolhd *pool)
|
|||||||
if (pool->efd)
|
if (pool->efd)
|
||||||
close(pool->efd);
|
close(pool->efd);
|
||||||
#endif
|
#endif
|
||||||
|
buff_destroy(pool->root_buff);
|
||||||
memset(pool, 0, sizeof(*pool));
|
memset(pool, 0, sizeof(*pool));
|
||||||
free(pool);
|
free(pool);
|
||||||
}
|
}
|
||||||
@ -216,3 +212,43 @@ int mod_etype(struct poolhd *pool, struct eval *val, int type)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
struct buffer *buff_get(struct buffer *root, size_t size)
|
||||||
|
{
|
||||||
|
struct buffer *prev = root;
|
||||||
|
|
||||||
|
while (root) {
|
||||||
|
if (!root->lock) {
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
prev = root;
|
||||||
|
root = root->next;
|
||||||
|
}
|
||||||
|
struct buffer *buff = malloc(sizeof(struct buffer) + size);
|
||||||
|
if (!buff) {
|
||||||
|
uniperror("malloc");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
LOG(LOG_S, "alloc new buffer\n");
|
||||||
|
|
||||||
|
memset(buff, 0, sizeof(struct buffer));
|
||||||
|
buff->data = (char *)buff + sizeof(struct buffer);
|
||||||
|
buff->size = size;
|
||||||
|
|
||||||
|
if (prev) {
|
||||||
|
prev->next = buff;
|
||||||
|
}
|
||||||
|
return buff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void buff_destroy(struct buffer *root)
|
||||||
|
{
|
||||||
|
while (root) {
|
||||||
|
struct buffer *c = root;
|
||||||
|
root = root->next;
|
||||||
|
free(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
8
conev.h
8
conev.h
@ -70,6 +70,8 @@ struct buffer {
|
|||||||
size_t size;
|
size_t size;
|
||||||
unsigned int offset;
|
unsigned int offset;
|
||||||
char *data;
|
char *data;
|
||||||
|
size_t lock;
|
||||||
|
struct buffer *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct eval {
|
struct eval {
|
||||||
@ -78,7 +80,7 @@ struct eval {
|
|||||||
unsigned long long mod_iter;
|
unsigned long long mod_iter;
|
||||||
enum eid type;
|
enum eid type;
|
||||||
struct eval *pair;
|
struct eval *pair;
|
||||||
struct buffer buff;
|
struct buffer *buff;
|
||||||
int flag;
|
int flag;
|
||||||
union sockaddr_u addr;
|
union sockaddr_u addr;
|
||||||
ssize_t recv_count;
|
ssize_t recv_count;
|
||||||
@ -101,6 +103,7 @@ struct poolhd {
|
|||||||
struct pollfd *pevents;
|
struct pollfd *pevents;
|
||||||
#endif
|
#endif
|
||||||
unsigned long long iters;
|
unsigned long long iters;
|
||||||
|
struct buffer *root_buff;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct poolhd *init_pool(int count);
|
struct poolhd *init_pool(int count);
|
||||||
@ -117,4 +120,7 @@ struct eval *next_event(struct poolhd *pool, int *offs, int *type);
|
|||||||
|
|
||||||
int mod_etype(struct poolhd *pool, struct eval *val, int type);
|
int mod_etype(struct poolhd *pool, struct eval *val, int type);
|
||||||
|
|
||||||
|
struct buffer *buff_get(struct buffer *root, size_t size);
|
||||||
|
|
||||||
|
void buff_destroy(struct buffer *root);
|
||||||
#endif
|
#endif
|
||||||
|
77
extend.c
77
extend.c
@ -164,7 +164,7 @@ static int reconnect(struct poolhd *pool, struct eval *val, int m)
|
|||||||
//client->type = EV_IGNORE;
|
//client->type = EV_IGNORE;
|
||||||
client->attempt = m;
|
client->attempt = m;
|
||||||
client->cache = 1;
|
client->cache = 1;
|
||||||
client->buff.offset = 0;
|
client->buff->offset = 0;
|
||||||
client->round_sent = 0;
|
client->round_sent = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -258,8 +258,9 @@ 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;
|
||||||
bool can_reconn = (
|
bool can_reconn = (
|
||||||
val->pair->buff.data && !val->recv_count
|
pair_buff && pair_buff->lock && !val->recv_count
|
||||||
&& params.auto_level > AUTO_NOBUFF
|
&& params.auto_level > AUTO_NOBUFF
|
||||||
);
|
);
|
||||||
if (!can_reconn && params.auto_level <= AUTO_NOSAVE) {
|
if (!can_reconn && params.auto_level <= AUTO_NOSAVE) {
|
||||||
@ -317,8 +318,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->buff->data;
|
||||||
ssize_t qn = val->pair->buff.size;
|
ssize_t qn = val->pair->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];
|
||||||
@ -346,9 +347,8 @@ static inline void free_first_req(struct eval *client)
|
|||||||
{
|
{
|
||||||
client->type = EV_TUNNEL;
|
client->type = EV_TUNNEL;
|
||||||
client->pair->type = EV_TUNNEL;
|
client->pair->type = EV_TUNNEL;
|
||||||
|
client->buff->lock = 0;
|
||||||
free(client->buff.data);
|
client->buff->offset = 0;
|
||||||
memset(&client->buff, 0, sizeof(client->buff));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -395,19 +395,19 @@ static int cancel_setup(struct eval *remote)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int send_saved_req(struct poolhd *pool,
|
static int send_saved_req(struct poolhd *pool, struct eval *client)
|
||||||
struct eval *client, char *buffer, ssize_t bfsize)
|
|
||||||
{
|
{
|
||||||
ssize_t offset = client->buff.offset;
|
struct buffer *buff = buff_get(pool->root_buff, params.bfsize);
|
||||||
ssize_t n = client->buff.size - offset;
|
|
||||||
assert(bfsize >= n);
|
|
||||||
memcpy(buffer, client->buff.data + offset, n);
|
|
||||||
|
|
||||||
ssize_t sn = tcp_send_hook(client->pair, buffer, bfsize, n);
|
ssize_t offset = client->buff->offset;
|
||||||
|
ssize_t n = client->buff->lock - offset;
|
||||||
|
memcpy(buff->data, client->buff->data + offset, n);
|
||||||
|
|
||||||
|
ssize_t sn = tcp_send_hook(pool, client->pair, buff, n);
|
||||||
if (sn < 0) {
|
if (sn < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
client->buff.offset += sn;
|
client->buff->offset += sn;
|
||||||
if (sn < n) {
|
if (sn < n) {
|
||||||
if (mod_etype(pool, client->pair, POLLOUT) ||
|
if (mod_etype(pool, client->pair, POLLOUT) ||
|
||||||
mod_etype(pool, client, 0)) {
|
mod_etype(pool, client, 0)) {
|
||||||
@ -419,9 +419,10 @@ static int send_saved_req(struct poolhd *pool,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int on_first_tunnel(struct poolhd *pool,
|
int on_first_tunnel(struct poolhd *pool, struct eval *val, int etype)
|
||||||
struct eval *val, char *buffer, size_t bfsize, int etype)
|
|
||||||
{
|
{
|
||||||
|
struct buffer *buff = buff_get(pool->root_buff, params.bfsize);
|
||||||
|
|
||||||
if ((etype & POLLOUT) && val->flag == FLAG_CONN) {
|
if ((etype & POLLOUT) && val->flag == FLAG_CONN) {
|
||||||
if (mod_etype(pool, val, POLLIN) ||
|
if (mod_etype(pool, val, POLLIN) ||
|
||||||
mod_etype(pool, val->pair, POLLIN)) {
|
mod_etype(pool, val->pair, POLLIN)) {
|
||||||
@ -429,31 +430,28 @@ int on_first_tunnel(struct poolhd *pool,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
val->pair->type = EV_FIRST_TUNNEL;
|
val->pair->type = EV_FIRST_TUNNEL;
|
||||||
return send_saved_req(pool, val->pair, buffer, bfsize);
|
return send_saved_req(pool, val->pair);
|
||||||
}
|
}
|
||||||
ssize_t n = tcp_recv_hook(pool, val, buffer, bfsize);
|
ssize_t n = tcp_recv_hook(pool, val, buff);
|
||||||
if (n < 1) {
|
if (n < 1) {
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
if (val->flag != FLAG_CONN) {
|
if (val->flag != FLAG_CONN) {
|
||||||
val->buff.size += n;
|
if (!val->buff) {
|
||||||
|
val->buff = buff;
|
||||||
if (val->buff.size >= bfsize) {
|
}
|
||||||
|
val->buff->lock += n;
|
||||||
|
if (val->buff->lock >= val->buff->size) {
|
||||||
free_first_req(val);
|
free_first_req(val);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
val->buff.data = realloc(val->buff.data, val->buff.size);
|
if (buff != val->buff)
|
||||||
|
memcpy(val->buff->data + val->buff->lock - n, buff->data, n);
|
||||||
if (val->buff.data == 0) {
|
return send_saved_req(pool, val);
|
||||||
uniperror("realloc");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
memcpy(val->buff.data + val->buff.size - n, buffer, n);
|
|
||||||
return send_saved_req(pool, val, buffer, bfsize);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (on_response(pool, val, buffer, n) == 0) {
|
if (on_response(pool, val, buff->data, n) == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
free_first_req(val->pair);
|
free_first_req(val->pair);
|
||||||
@ -463,24 +461,25 @@ int on_first_tunnel(struct poolhd *pool,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tcp_send_hook(val->pair, buffer, bfsize, n) < n) {
|
if (tcp_send_hook(pool, val->pair, buff, n) < n) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ssize_t tcp_send_hook(struct eval *remote,
|
ssize_t tcp_send_hook(struct poolhd *pool,
|
||||||
char *buffer, size_t bfsize, 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;
|
||||||
|
size_t off = buff->offset;
|
||||||
|
|
||||||
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, buffer, 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;
|
||||||
@ -494,11 +493,11 @@ ssize_t tcp_send_hook(struct eval *remote,
|
|||||||
if (!offset && remote->round_count) offset = -1;
|
if (!offset && remote->round_count) offset = -1;
|
||||||
|
|
||||||
sn = desync(remote->fd,
|
sn = desync(remote->fd,
|
||||||
buffer, bfsize, n, offset, m);
|
buff->data + off, buff->size - off, n, offset, m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (skip) {
|
if (skip) {
|
||||||
sn = send(remote->fd, buffer, n, 0);
|
sn = send(remote->fd, buff->data + off, n, 0);
|
||||||
if (sn < 0 && get_e() == EAGAIN) {
|
if (sn < 0 && get_e() == EAGAIN) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -509,9 +508,9 @@ ssize_t tcp_send_hook(struct eval *remote,
|
|||||||
|
|
||||||
|
|
||||||
ssize_t tcp_recv_hook(struct poolhd *pool,
|
ssize_t tcp_recv_hook(struct poolhd *pool,
|
||||||
struct eval *val, char *buffer, size_t bfsize)
|
struct eval *val, struct buffer *buff)
|
||||||
{
|
{
|
||||||
ssize_t n = recv(val->fd, buffer, bfsize, 0);
|
ssize_t n = recv(val->fd, buff->data, buff->size, 0);
|
||||||
if (n < 1) {
|
if (n < 1) {
|
||||||
if (!n) {
|
if (!n) {
|
||||||
if (val->flag != FLAG_CONN) {
|
if (val->flag != FLAG_CONN) {
|
||||||
|
11
extend.h
11
extend.h
@ -10,17 +10,16 @@ int socket_mod(int fd);
|
|||||||
int connect_hook(struct poolhd *pool, struct eval *val,
|
int connect_hook(struct poolhd *pool, struct eval *val,
|
||||||
const union sockaddr_u *dst, int next);
|
const union sockaddr_u *dst, int next);
|
||||||
|
|
||||||
ssize_t tcp_send_hook(struct eval *val,
|
ssize_t tcp_send_hook(struct poolhd *pool,
|
||||||
char *buffer, size_t bfsize, ssize_t n);
|
struct eval *remote, struct buffer *buff, ssize_t n);
|
||||||
|
|
||||||
ssize_t tcp_recv_hook(struct poolhd *pool, struct eval *val,
|
ssize_t tcp_recv_hook(struct poolhd *pool,
|
||||||
char *buffer, size_t bfsize);
|
struct eval *val, struct buffer *buff);
|
||||||
|
|
||||||
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,
|
int on_first_tunnel(struct poolhd *pool, struct eval *val, int etype);
|
||||||
struct eval *val, char *buffer, size_t bfsize, int etype);
|
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
static int protect(int conn_fd, const char *path);
|
static int protect(int conn_fd, const char *path);
|
||||||
|
85
proxy.c
85
proxy.c
@ -646,8 +646,7 @@ static int on_accept(struct poolhd *pool, const struct eval *val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int on_tunnel(struct poolhd *pool, struct eval *val,
|
static int on_tunnel(struct poolhd *pool, struct eval *val, int etype)
|
||||||
char *buffer, size_t bfsize, int etype)
|
|
||||||
{
|
{
|
||||||
ssize_t n = 0;
|
ssize_t n = 0;
|
||||||
struct eval *pair = val->pair;
|
struct eval *pair = val->pair;
|
||||||
@ -657,26 +656,23 @@ static int on_tunnel(struct poolhd *pool, struct eval *val,
|
|||||||
val = pair;
|
val = pair;
|
||||||
pair = val->pair;
|
pair = val->pair;
|
||||||
}
|
}
|
||||||
if (val->buff.data) {
|
if (val->buff && val->buff->lock) {
|
||||||
if (etype & POLLHUP) {
|
if (etype & POLLHUP) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
n = val->buff.size - val->buff.offset;
|
n = val->buff->lock - val->buff->offset;
|
||||||
|
|
||||||
ssize_t sn = tcp_send_hook(pair,
|
ssize_t sn = tcp_send_hook(pool, pair, val->buff, n);
|
||||||
val->buff.data + val->buff.offset, n, n);
|
|
||||||
if (sn < 0) {
|
if (sn < 0) {
|
||||||
uniperror("send");
|
uniperror("send");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (sn < n) {
|
if (sn < n) {
|
||||||
val->buff.offset += sn;
|
val->buff->offset += sn;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
free(val->buff.data);
|
val->buff->lock = 0;
|
||||||
val->buff.data = 0;
|
val->buff->offset = 0;
|
||||||
val->buff.size = 0;
|
|
||||||
val->buff.offset = 0;
|
|
||||||
|
|
||||||
if (mod_etype(pool, val, POLLIN) ||
|
if (mod_etype(pool, val, POLLIN) ||
|
||||||
mod_etype(pool, pair, POLLIN)) {
|
mod_etype(pool, pair, POLLIN)) {
|
||||||
@ -684,8 +680,9 @@ static int on_tunnel(struct poolhd *pool, struct eval *val,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
struct buffer *buff = buff_get(pool->root_buff, params.bfsize);
|
||||||
do {
|
do {
|
||||||
n = tcp_recv_hook(pool, val, buffer, bfsize);
|
n = tcp_recv_hook(pool, val, buff);
|
||||||
//if (n < 0 && get_e() == EAGAIN) {
|
//if (n < 0 && get_e() == EAGAIN) {
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
break;
|
break;
|
||||||
@ -693,21 +690,17 @@ static int on_tunnel(struct poolhd *pool, struct eval *val,
|
|||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ssize_t sn = tcp_send_hook(pair, buffer, bfsize, 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;
|
||||||
}
|
}
|
||||||
if (sn < n) {
|
if (sn < n) {
|
||||||
LOG(LOG_S, "send: %zd != %zd (fd=%d)\n", sn, n, pair->fd);
|
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;
|
val->buff = buff;
|
||||||
if (!(val->buff.data = malloc(n - sn))) {
|
buff->lock = n;
|
||||||
uniperror("malloc");
|
buff->offset = sn;
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
memcpy(val->buff.data, buffer + sn, n - sn);
|
|
||||||
|
|
||||||
if (mod_etype(pool, val, 0) ||
|
if (mod_etype(pool, val, 0) ||
|
||||||
mod_etype(pool, pair, POLLOUT)) {
|
mod_etype(pool, pair, POLLOUT)) {
|
||||||
@ -716,15 +709,17 @@ static int on_tunnel(struct poolhd *pool, struct eval *val,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (n == (ssize_t )bfsize);
|
} while (n == (ssize_t )buff->size);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int on_udp_tunnel(struct eval *val, char *buffer, size_t bfsize)
|
static int on_udp_tunnel(struct poolhd *pool, struct eval *val)
|
||||||
{
|
{
|
||||||
char *data = buffer;
|
struct buffer *buff = buff_get(pool->root_buff, params.bfsize);
|
||||||
size_t data_len = bfsize;
|
|
||||||
|
char *data = buff->data;
|
||||||
|
size_t data_len = buff->size;
|
||||||
|
|
||||||
if (val->flag != FLAG_CONN) {
|
if (val->flag != FLAG_CONN) {
|
||||||
data += S_SIZE_I6;
|
data += S_SIZE_I6;
|
||||||
@ -788,7 +783,7 @@ static int on_udp_tunnel(struct eval *val, char *buffer, size_t bfsize)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
map_fix(&addr, 0);
|
map_fix(&addr, 0);
|
||||||
memset(buffer, 0, S_SIZE_I6);
|
memset(buff->data, 0, S_SIZE_I6);
|
||||||
|
|
||||||
int offs = s5_set_addr(data, S_SIZE_I6, &addr, 1);
|
int offs = s5_set_addr(data, S_SIZE_I6, &addr, 1);
|
||||||
if (offs < 0 || offs > S_SIZE_I6) {
|
if (offs < 0 || offs > S_SIZE_I6) {
|
||||||
@ -805,21 +800,21 @@ static int on_udp_tunnel(struct eval *val, char *buffer, size_t bfsize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline int on_request(struct poolhd *pool, struct eval *val,
|
static inline int on_request(struct poolhd *pool, struct eval *val)
|
||||||
char *buffer, size_t bfsize)
|
|
||||||
{
|
{
|
||||||
union sockaddr_u dst = {0};
|
union sockaddr_u dst = {0};
|
||||||
|
struct buffer *buff = buff_get(pool->root_buff, params.bfsize);
|
||||||
|
|
||||||
ssize_t n = recv(val->fd, buffer, bfsize, 0);
|
ssize_t n = recv(val->fd, buff->data, buff->size, 0);
|
||||||
if (n < 1) {
|
if (n < 1) {
|
||||||
if (n) uniperror("ss recv");
|
if (n) uniperror("ss recv");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
if (*buffer == S_VER5) {
|
if (*buff->data == S_VER5) {
|
||||||
if (val->flag != FLAG_S5) {
|
if (val->flag != FLAG_S5) {
|
||||||
if (auth_socks5(val->fd, buffer, n)) {
|
if (auth_socks5(val->fd, buff->data, n)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
val->flag = FLAG_S5;
|
val->flag = FLAG_S5;
|
||||||
@ -829,18 +824,18 @@ static inline int on_request(struct poolhd *pool, struct eval *val,
|
|||||||
LOG(LOG_E, "ss: request too small (%zd)\n", n);
|
LOG(LOG_E, "ss: request too small (%zd)\n", n);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
struct s5_req *r = (struct s5_req *)buffer;
|
struct s5_req *r = (struct s5_req *)buff->data;
|
||||||
int s5e = 0;
|
int s5e = 0;
|
||||||
switch (r->cmd) {
|
switch (r->cmd) {
|
||||||
case S_CMD_CONN:
|
case S_CMD_CONN:
|
||||||
s5e = s5_get_addr(buffer, n, &dst, SOCK_STREAM);
|
s5e = s5_get_addr(buff->data, n, &dst, SOCK_STREAM);
|
||||||
if (s5e >= 0) {
|
if (s5e >= 0) {
|
||||||
error = connect_hook(pool, val, &dst, EV_CONNECT);
|
error = connect_hook(pool, val, &dst, EV_CONNECT);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case S_CMD_AUDP:
|
case S_CMD_AUDP:
|
||||||
if (params.udp) {
|
if (params.udp) {
|
||||||
s5e = s5_get_addr(buffer, n, &dst, SOCK_DGRAM);
|
s5e = s5_get_addr(buff->data, n, &dst, SOCK_DGRAM);
|
||||||
if (s5e >= 0) {
|
if (s5e >= 0) {
|
||||||
error = udp_associate(pool, val, &dst);
|
error = udp_associate(pool, val, &dst);
|
||||||
}
|
}
|
||||||
@ -857,10 +852,10 @@ static inline int on_request(struct poolhd *pool, struct eval *val,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (*buffer == S_VER4) {
|
else if (*buff->data == S_VER4) {
|
||||||
val->flag = FLAG_S4;
|
val->flag = FLAG_S4;
|
||||||
|
|
||||||
error = s4_get_addr(buffer, n, &dst);
|
error = s4_get_addr(buff->data, n, &dst);
|
||||||
if (error) {
|
if (error) {
|
||||||
if (resp_error(val->fd, error, FLAG_S4) < 0)
|
if (resp_error(val->fd, error, FLAG_S4) < 0)
|
||||||
uniperror("send");
|
uniperror("send");
|
||||||
@ -869,16 +864,16 @@ static inline int on_request(struct poolhd *pool, struct eval *val,
|
|||||||
error = connect_hook(pool, val, &dst, EV_CONNECT);
|
error = connect_hook(pool, val, &dst, EV_CONNECT);
|
||||||
}
|
}
|
||||||
else if (params.http_connect
|
else if (params.http_connect
|
||||||
&& n > 7 && !memcmp(buffer, "CONNECT", 7)) {
|
&& n > 7 && !memcmp(buff->data, "CONNECT", 7)) {
|
||||||
val->flag = FLAG_HTTP;
|
val->flag = FLAG_HTTP;
|
||||||
|
|
||||||
if (http_get_addr(buffer, n, &dst)) {
|
if (http_get_addr(buff->data, n, &dst)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
error = connect_hook(pool, val, &dst, EV_CONNECT);
|
error = connect_hook(pool, val, &dst, EV_CONNECT);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LOG(LOG_E, "ss: invalid version: 0x%x (%zd)\n", *buffer, n);
|
LOG(LOG_E, "ss: invalid version: 0x%x (%zd)\n", *buff->data, n);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
@ -950,9 +945,8 @@ int event_loop(int srvfd)
|
|||||||
close(srvfd);
|
close(srvfd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
char *buffer = malloc(params.bfsize);
|
pool->root_buff = buff_get(0, params.bfsize);
|
||||||
if (!buffer) {
|
if (!pool->root_buff) {
|
||||||
uniperror("malloc");
|
|
||||||
destroy_pool(pool);
|
destroy_pool(pool);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -981,22 +975,22 @@ int event_loop(int srvfd)
|
|||||||
|
|
||||||
case EV_REQUEST:
|
case EV_REQUEST:
|
||||||
if ((etype & POLLHUP) ||
|
if ((etype & POLLHUP) ||
|
||||||
on_request(pool, val, buffer, bfsize))
|
on_request(pool, val))
|
||||||
close_conn(pool, val);
|
close_conn(pool, val);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case EV_FIRST_TUNNEL:
|
case EV_FIRST_TUNNEL:
|
||||||
if (on_first_tunnel(pool, val, buffer, bfsize, etype))
|
if (on_first_tunnel(pool, val, etype))
|
||||||
close_conn(pool, val);
|
close_conn(pool, val);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case EV_TUNNEL:
|
case EV_TUNNEL:
|
||||||
if (on_tunnel(pool, val, buffer, bfsize, etype))
|
if (on_tunnel(pool, val, etype))
|
||||||
close_conn(pool, val);
|
close_conn(pool, val);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case EV_UDP_TUNNEL:
|
case EV_UDP_TUNNEL:
|
||||||
if (on_udp_tunnel(val, buffer, bfsize))
|
if (on_udp_tunnel(pool, val))
|
||||||
close_conn(pool, val);
|
close_conn(pool, val);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -1016,7 +1010,6 @@ int event_loop(int srvfd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOG(LOG_S, "exit\n");
|
LOG(LOG_S, "exit\n");
|
||||||
free(buffer);
|
|
||||||
destroy_pool(pool);
|
destroy_pool(pool);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user