0
0
mirror of https://github.com/hufrea/byedpi.git synced 2025-06-29 18:21:14 +00:00

Use func ptr instead of switch in event loop

This commit is contained in:
ruti 2025-01-29 17:51:54 +03:00
parent 750999dcf3
commit e4f47f5c1a
7 changed files with 86 additions and 132 deletions

View File

@ -1,7 +1,7 @@
TARGET = ciadpi TARGET = ciadpi
CPPFLAGS = -D_DEFAULT_SOURCE CPPFLAGS = -D_DEFAULT_SOURCE
CFLAGS += -I. -std=c99 -O2 -Wall -Wno-unused -Wextra -pedantic CFLAGS += -I. -std=c99 -O2 -Wall -Wno-unused -Wextra -Wno-unused-parameter -pedantic
WIN_LDFLAGS = -lws2_32 -lmswsock WIN_LDFLAGS = -lws2_32 -lmswsock
HEADERS = conev.h desync.h error.h extend.h kavl.h mpool.h packets.h params.h proxy.h win_service.h HEADERS = conev.h desync.h error.h extend.h kavl.h mpool.h packets.h params.h proxy.h win_service.h

29
conev.c
View File

@ -43,7 +43,7 @@ struct poolhd *init_pool(int count)
} }
struct eval *add_event(struct poolhd *pool, enum eid type, struct eval *add_event(struct poolhd *pool, evcb_t cb,
int fd, int e) int fd, int e)
{ {
assert(fd > 0); assert(fd > 0);
@ -57,7 +57,7 @@ struct eval *add_event(struct poolhd *pool, enum eid type,
val->mod_iter = pool->iters; val->mod_iter = pool->iters;
val->fd = fd; val->fd = fd;
val->index = pool->count; val->index = pool->count;
val->type = type; val->cb = cb;
#ifndef NOEPOLL #ifndef NOEPOLL
struct epoll_event ev = { .events = EPOLLRDHUP | e, .data = {val} }; struct epoll_event ev = { .events = EPOLLRDHUP | e, .data = {val} };
@ -81,6 +81,9 @@ struct eval *add_event(struct poolhd *pool, enum eid type,
void del_event(struct poolhd *pool, struct eval *val) void del_event(struct poolhd *pool, struct eval *val)
{ {
assert(val->fd >= -1 && val->mod_iter <= pool->iters); assert(val->fd >= -1 && val->mod_iter <= pool->iters);
LOG(LOG_S, "close: fd=%d (pair=%d), recv: %zd, rounds: %d\n",
val->fd, val->pair ? val->pair->fd : -1,
val->recv_count, val->round_count);
if (val->fd == -1) { if (val->fd == -1) {
return; return;
} }
@ -117,7 +120,7 @@ void del_event(struct poolhd *pool, struct eval *val)
val->pair = 0; val->pair = 0;
del_event(pool, e); del_event(pool, e);
} }
assert(pool->count > 0); assert(pool->count >= 0);
} }
@ -214,6 +217,26 @@ int mod_etype(struct poolhd *pool, struct eval *val, int type)
#endif #endif
void loop_event(struct poolhd *pool)
{
struct eval *val;
int i = -1, etype;
while (!pool->brk) {
val = next_event(pool, &i, &etype);
if (!val) {
if (get_e() == EINTR)
continue;
uniperror("(e)poll");
break;
}
int ret = (*val->cb)(pool, val, etype);
if (ret < 0) {
del_event(pool, val);
}
}
}
struct buffer *buff_get(struct buffer *root, size_t size) struct buffer *buff_get(struct buffer *root, size_t size)
{ {
struct buffer *prev = root; struct buffer *prev = root;

34
conev.h
View File

@ -33,39 +33,21 @@
#define POLLRDHUP 0 #define POLLRDHUP 0
#endif #endif
struct poolhd;
struct eval;
typedef int (*evcb_t)(struct poolhd *, struct eval *, int);
union sockaddr_u { union sockaddr_u {
struct sockaddr sa; struct sockaddr sa;
struct sockaddr_in in; struct sockaddr_in in;
struct sockaddr_in6 in6; struct sockaddr_in6 in6;
}; };
enum eid {
EV_ACCEPT,
EV_REQUEST,
EV_CONNECT,
EV_IGNORE,
EV_TUNNEL,
EV_UDP_TUNNEL,
EV_FIRST_TUNNEL
};
#define FLAG_S4 1 #define FLAG_S4 1
#define FLAG_S5 2 #define FLAG_S5 2
#define FLAG_CONN 4 #define FLAG_CONN 4
#define FLAG_HTTP 8 #define FLAG_HTTP 8
#ifdef EID_STR
char *eid_name[] = {
"EV_ACCEPT",
"EV_REQUEST",
"EV_CONNECT",
"EV_IGNORE",
"EV_TUNNEL",
"EV_UDP_TUNNEL",
"EV_FIRST_TUNNEL"
};
#endif
struct buffer { struct buffer {
size_t size; size_t size;
unsigned int offset; unsigned int offset;
@ -78,7 +60,7 @@ struct eval {
int fd; int fd;
int index; int index;
unsigned long long mod_iter; unsigned long long mod_iter;
enum eid type; evcb_t cb;
struct eval *pair; struct eval *pair;
struct buffer *buff; struct buffer *buff;
int flag; int flag;
@ -103,12 +85,14 @@ struct poolhd {
struct pollfd *pevents; struct pollfd *pevents;
#endif #endif
unsigned long long iters; unsigned long long iters;
bool brk;
struct buffer *root_buff; struct buffer *root_buff;
}; };
struct poolhd *init_pool(int count); struct poolhd *init_pool(int count);
struct eval *add_event(struct poolhd *pool, enum eid type, int fd, int e); struct eval *add_event(struct poolhd *pool, evcb_t cb, int fd, int e);
struct eval *add_pair(struct poolhd *pool, struct eval *val, int sfd, int e); struct eval *add_pair(struct poolhd *pool, struct eval *val, int sfd, int e);
@ -120,6 +104,8 @@ 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);
void loop_event(struct poolhd *pool);
struct buffer *buff_get(struct buffer *root, size_t size); struct buffer *buff_get(struct buffer *root, size_t size);
void buff_destroy(struct buffer *root); void buff_destroy(struct buffer *root);

View File

@ -125,7 +125,7 @@ static int cache_add(const union sockaddr_u *dst, int m)
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, evcb_t next)
{ {
int m = cache_get(dst); int m = cache_get(dst);
val->cache = (m == 0); val->cache = (m == 0);
@ -155,7 +155,7 @@ 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, EV_FIRST_TUNNEL)) { if (create_conn(pool, client, &val->addr, &on_first_tunnel)) {
return -1; return -1;
} }
val->pair = 0; val->pair = 0;
@ -345,8 +345,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->type = EV_TUNNEL; client->cb = &on_tunnel;
client->pair->type = EV_TUNNEL; client->pair->cb = &on_tunnel;
client->buff->lock = 0; client->buff->lock = 0;
client->buff->offset = 0; client->buff->offset = 0;
} }
@ -429,7 +429,7 @@ int on_first_tunnel(struct poolhd *pool, struct eval *val, int etype)
uniperror("mod_etype"); uniperror("mod_etype");
return -1; return -1;
} }
val->pair->type = EV_FIRST_TUNNEL; val->pair->cb = &on_first_tunnel;
return send_saved_req(pool, val->pair); return send_saved_req(pool, val->pair);
} }
ssize_t n = tcp_recv_hook(pool, val, buff); ssize_t n = tcp_recv_hook(pool, val, buff);

View File

@ -8,7 +8,7 @@
int socket_mod(int fd); 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, 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);

127
proxy.c
View File

@ -1,5 +1,3 @@
#define EID_STR
#include "proxy.h" #include "proxy.h"
#include <stdint.h> #include <stdint.h>
@ -43,10 +41,10 @@
#endif #endif
int NOT_EXIT = 1; int server_fd;
static void on_cancel(int sig) { static void on_cancel(int sig) {
if (sig) NOT_EXIT = 0; shutdown(server_fd, SHUT_RDWR);
} }
@ -401,7 +399,7 @@ static int remote_sock(union sockaddr_u *dst, int type)
int create_conn(struct poolhd *pool, int create_conn(struct poolhd *pool,
struct eval *val, const union sockaddr_u *dst, int next) struct eval *val, const union sockaddr_u *dst, evcb_t next)
{ {
union sockaddr_u addr = *dst; union sockaddr_u addr = *dst;
@ -466,7 +464,7 @@ int create_conn(struct poolhd *pool,
pair->addr = *dst; pair->addr = *dst;
#endif #endif
pair->flag = FLAG_CONN; pair->flag = FLAG_CONN;
val->type = EV_IGNORE; val->cb = &on_ignore;
return 0; return 0;
} }
@ -480,7 +478,7 @@ static int udp_associate(struct poolhd *pool,
if (ufd < 0) { if (ufd < 0) {
return -1; return -1;
} }
struct eval *pair = add_event(pool, EV_UDP_TUNNEL, ufd, POLLIN); struct eval *pair = add_event(pool, &on_udp_tunnel, ufd, POLLIN);
if (!pair) { if (!pair) {
close(ufd); close(ufd);
return -1; return -1;
@ -514,7 +512,7 @@ static int udp_associate(struct poolhd *pool,
close(cfd); close(cfd);
return -1; return -1;
} }
struct eval *client = add_event(pool, EV_UDP_TUNNEL, cfd, POLLIN); struct eval *client = add_event(pool, &on_udp_tunnel, cfd, POLLIN);
if (!client) { if (!client) {
del_event(pool, pair); del_event(pool, pair);
close(cfd); close(cfd);
@ -525,7 +523,7 @@ static int udp_associate(struct poolhd *pool,
LOG(LOG_S, "udp associate: fds=%d,%d,%d addr=%s:%d\n", LOG(LOG_S, "udp associate: fds=%d,%d,%d addr=%s:%d\n",
ufd, cfd, val->fd, ADDR_STR, ntohs(dst->in.sin_port)); ufd, cfd, val->fd, ADDR_STR, ntohs(dst->in.sin_port));
} }
val->type = EV_IGNORE; val->cb = &on_ignore;
val->pair = client; val->pair = client;
client->pair = pair; client->pair = pair;
pair->pair = val; pair->pair = val;
@ -581,7 +579,7 @@ static inline int transp_conn(struct poolhd *pool, struct eval *val)
LOG(LOG_E, "connect to self, ignore\n"); LOG(LOG_E, "connect to self, ignore\n");
return -1; return -1;
} }
int error = connect_hook(pool, val, &remote, EV_CONNECT); int error = connect_hook(pool, val, &remote, &on_connect);
if (error) { if (error) {
uniperror("connect_hook"); uniperror("connect_hook");
return -1; return -1;
@ -590,7 +588,7 @@ static inline int transp_conn(struct poolhd *pool, struct eval *val)
} }
#endif #endif
static int on_accept(struct poolhd *pool, const struct eval *val) static int on_accept(struct poolhd *pool, struct eval *val, int et)
{ {
union sockaddr_u client; union sockaddr_u client;
struct eval *rval; struct eval *rval;
@ -607,6 +605,7 @@ static int on_accept(struct poolhd *pool, const struct eval *val)
get_e() == EINPROGRESS) get_e() == EINPROGRESS)
break; break;
uniperror("accept"); uniperror("accept");
pool->brk = 1;
return -1; return -1;
} }
LOG(LOG_S, "accept: fd=%d\n", c); LOG(LOG_S, "accept: fd=%d\n", c);
@ -630,7 +629,7 @@ static int on_accept(struct poolhd *pool, const struct eval *val)
close(c); close(c);
continue; continue;
} }
if (!(rval = add_event(pool, EV_REQUEST, c, POLLIN))) { if (!(rval = add_event(pool, &on_request, c, POLLIN))) {
close(c); close(c);
continue; continue;
} }
@ -646,7 +645,7 @@ static int on_accept(struct poolhd *pool, const struct eval *val)
} }
static int on_tunnel(struct poolhd *pool, struct eval *val, int etype) int on_tunnel(struct poolhd *pool, struct eval *val, int etype)
{ {
ssize_t n = 0; ssize_t n = 0;
struct eval *pair = val->pair; struct eval *pair = val->pair;
@ -714,7 +713,7 @@ static int on_tunnel(struct poolhd *pool, struct eval *val, int etype)
} }
static int on_udp_tunnel(struct poolhd *pool, struct eval *val) int on_udp_tunnel(struct poolhd *pool, struct eval *val, int et)
{ {
struct buffer *buff = buff_get(pool->root_buff, params.bfsize); struct buffer *buff = buff_get(pool->root_buff, params.bfsize);
@ -800,7 +799,7 @@ static int on_udp_tunnel(struct poolhd *pool, struct eval *val)
} }
static inline int on_request(struct poolhd *pool, struct eval *val) int on_request(struct poolhd *pool, struct eval *val, int et)
{ {
union sockaddr_u dst = {0}; union sockaddr_u dst = {0};
struct buffer *buff = buff_get(pool->root_buff, params.bfsize); struct buffer *buff = buff_get(pool->root_buff, params.bfsize);
@ -830,7 +829,7 @@ static inline int on_request(struct poolhd *pool, struct eval *val)
case S_CMD_CONN: case S_CMD_CONN:
s5e = s5_get_addr(buff->data, 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, &on_connect);
} }
break; break;
case S_CMD_AUDP: case S_CMD_AUDP:
@ -861,7 +860,7 @@ static inline int on_request(struct poolhd *pool, struct eval *val)
uniperror("send"); uniperror("send");
return -1; return -1;
} }
error = connect_hook(pool, val, &dst, EV_CONNECT); error = connect_hook(pool, val, &dst, &on_connect);
} }
else if (params.http_connect else if (params.http_connect
&& n > 7 && !memcmp(buff->data, "CONNECT", 7)) { && n > 7 && !memcmp(buff->data, "CONNECT", 7)) {
@ -870,7 +869,7 @@ static inline int on_request(struct poolhd *pool, struct eval *val)
if (http_get_addr(buff->data, 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, &on_connect);
} }
else { else {
LOG(LOG_E, "ss: invalid version: 0x%x (%zd)\n", *buff->data, n); LOG(LOG_E, "ss: invalid version: 0x%x (%zd)\n", *buff->data, n);
@ -887,11 +886,11 @@ static inline int on_request(struct poolhd *pool, struct eval *val)
} }
static inline int on_connect(struct poolhd *pool, struct eval *val, int e) int on_connect(struct poolhd *pool, struct eval *val, int et)
{ {
int error = 0; int error = 0;
socklen_t len = sizeof(error); socklen_t len = sizeof(error);
if (e) { if (et & POLLERR) {
if (getsockopt(val->fd, SOL_SOCKET, if (getsockopt(val->fd, SOL_SOCKET,
SO_ERROR, (char *)&error, &len)) { SO_ERROR, (char *)&error, &len)) {
uniperror("getsockopt SO_ERROR"); uniperror("getsockopt SO_ERROR");
@ -904,43 +903,36 @@ static inline int on_connect(struct poolhd *pool, struct eval *val, int e)
uniperror("mod_etype"); uniperror("mod_etype");
return -1; return -1;
} }
int t = params.auto_level <= AUTO_NOBUFF evcb_t t = params.auto_level <= AUTO_NOBUFF
? EV_TUNNEL : EV_FIRST_TUNNEL; ? &on_tunnel : &on_first_tunnel;
val->type = t; val->cb = t;
val->pair->type = 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) {
uniperror("send"); uniperror("send");
return -1; return -1;
} }
return e ? -1 : 0; return error ? -1 : 0;
} }
static void close_conn(struct poolhd *pool, struct eval *val) int on_ignore(struct poolhd *pool, struct eval *val, int etype)
{ {
struct eval *cval = val; return (etype & (POLLHUP | POLLERR)) ? -1 : 0;
do {
LOG(LOG_S, "close: fd=%d (pair=%d), recv: %zd, rounds: %d\n",
cval->fd, cval->pair ? cval->pair->fd : -1,
cval->recv_count, cval->round_count);
cval = cval->pair;
} while (cval && cval != val);
del_event(pool, val);
} }
int event_loop(int srvfd) int start_event_loop(int srvfd)
{ {
size_t bfsize = params.bfsize; server_fd = srvfd;
struct poolhd *pool = init_pool(params.max_open * 2 + 1); struct poolhd *pool = init_pool(params.max_open * 2 + 1);
if (!pool) { if (!pool) {
close(srvfd); close(srvfd);
return -1; return -1;
} }
if (!add_event(pool, EV_ACCEPT, srvfd, POLLIN)) { if (!add_event(pool, &on_accept, srvfd, POLLIN)) {
destroy_pool(pool); destroy_pool(pool);
close(srvfd); close(srvfd);
return -1; return -1;
@ -950,65 +942,8 @@ int event_loop(int srvfd)
destroy_pool(pool); destroy_pool(pool);
return -1; return -1;
} }
loop_event(pool);
struct eval *val;
int i = -1, etype;
while (NOT_EXIT) {
val = next_event(pool, &i, &etype);
if (!val) {
if (get_e() == EINTR)
continue;
uniperror("(e)poll");
break;
}
assert(val->type >= 0
&& val->type < sizeof(eid_name)/sizeof(*eid_name));
LOG(LOG_L, "new event: fd: %d, evt: %s, mod_iter: %llu\n", val->fd, eid_name[val->type], val->mod_iter);
switch (val->type) {
case EV_ACCEPT:
if ((etype & POLLHUP) ||
on_accept(pool, val))
NOT_EXIT = 0;
continue;
case EV_REQUEST:
if ((etype & POLLHUP) ||
on_request(pool, val))
close_conn(pool, val);
continue;
case EV_FIRST_TUNNEL:
if (on_first_tunnel(pool, val, etype))
close_conn(pool, val);
continue;
case EV_TUNNEL:
if (on_tunnel(pool, val, etype))
close_conn(pool, val);
continue;
case EV_UDP_TUNNEL:
if (on_udp_tunnel(pool, val))
close_conn(pool, val);
continue;
case EV_CONNECT:
if (on_connect(pool, val, etype & POLLERR))
close_conn(pool, val);
continue;
case EV_IGNORE:
if (etype & (POLLHUP | POLLERR | POLLRDHUP))
close_conn(pool, val);
continue;
default:
LOG(LOG_E, "???\n");
NOT_EXIT = 0;
}
}
LOG(LOG_S, "exit\n"); LOG(LOG_S, "exit\n");
destroy_pool(pool); destroy_pool(pool);
return 0; return 0;
@ -1056,5 +991,5 @@ int run(const union sockaddr_u *srv)
if (fd < 0) { if (fd < 0) {
return -1; return -1;
} }
return event_loop(fd); return start_event_loop(fd);
} }

14
proxy.h
View File

@ -87,11 +87,21 @@ struct s5_rep {
void map_fix(union sockaddr_u *addr, char f6); void map_fix(union sockaddr_u *addr, char f6);
int create_conn(struct poolhd *pool, int create_conn(struct poolhd *pool,
struct eval *val, const union sockaddr_u *dst, int next); struct eval *val, const union sockaddr_u *dst, evcb_t next);
int listen_socket(const union sockaddr_u *srv); int listen_socket(const union sockaddr_u *srv);
int event_loop(int srvfd); int on_tunnel(struct poolhd *pool, struct eval *val, int etype);
int on_udp_tunnel(struct poolhd *pool, struct eval *val, int et);
int on_request(struct poolhd *pool, struct eval *val, int et);
int on_connect(struct poolhd *pool, struct eval *val, int et);
int on_ignore(struct poolhd *pool, struct eval *val, int etype);
int start_event_loop(int srvfd);
int run(const union sockaddr_u *srv); int run(const union sockaddr_u *srv);