diff options
author | lns <matzeton@googlemail.com> | 2018-08-07 16:53:29 +0200 |
---|---|---|
committer | lns <matzeton@googlemail.com> | 2018-08-07 16:53:29 +0200 |
commit | f8497db5d14eb139820173dccba58989c4f9ca5c (patch) | |
tree | 3677066a9f8b4aa55e7ba826e2a1e514adc666e1 /src | |
parent | b247c23d23dc646749872423f9ebc6d5c165566d (diff) |
use potd event buffer as epoll data instead of a fd
Signed-off-by: lns <matzeton@googlemail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/jail.c | 21 | ||||
-rw-r--r-- | src/pevent.c | 128 | ||||
-rw-r--r-- | src/pevent.h | 17 | ||||
-rw-r--r-- | src/redirector.c | 20 |
4 files changed, 134 insertions, 52 deletions
@@ -87,11 +87,13 @@ typedef struct client_event { static int jail_mainloop(event_ctx **ev_ctx, const jail_ctx *ctx[], size_t siz) __attribute__((noreturn)); -static int jail_accept_client(event_ctx *ev_ctx, int fd, void *user_data); +static int jail_accept_client(event_ctx *ev_ctx, event_buf *buf, + void *user_data); static int jail_childfn(prisoner_process *ctx) __attribute__((noreturn)); static int jail_socket_tty(prisoner_process *ctx, int tty_fd); -static int jail_socket_tty_io(event_ctx *ev_ctx, int src_fd, void *user_data); +static int jail_socket_tty_io(event_ctx *ev_ctx, event_buf *buf, + void *user_data); static int jail_log_input(event_ctx *ev_ctx, int src_fd, int dst_fd, char *buf, size_t siz, void *user_data); @@ -231,17 +233,20 @@ static int jail_mainloop(event_ctx **ev_ctx, const jail_ctx *ctx[], size_t siz) exit(rc); } -static int jail_accept_client(event_ctx *ev_ctx, int fd, void *user_data) +static int jail_accept_client(event_ctx *ev_ctx, event_buf *buf, + void *user_data) { size_t i, rc = 0; - int s; + int s, fd; pid_t prisoner_pid; - server_event *ev_jail = (server_event *) user_data; + server_event *ev_jail; static prisoner_process *args; const jail_ctx *jail_ctx; (void) ev_ctx; - assert(ev_jail); + assert(ev_ctx && buf && user_data); + ev_jail = (server_event *) user_data; + fd = buf->fd; for (i = 0; i < ev_jail->siz; ++i) { jail_ctx = ev_jail->jail_ctx[i]; @@ -553,9 +558,9 @@ finish: } static int -jail_socket_tty_io(event_ctx *ev_ctx, int src_fd, void *user_data) +jail_socket_tty_io(event_ctx *ev_ctx, event_buf *buf, void *user_data) { - int dest_fd; + int dest_fd, src_fd = buf->fd; client_event *ev_cli = (client_event *) user_data; forward_state fwd_state; diff --git a/src/pevent.c b/src/pevent.c index fb808af..224c805 100644 --- a/src/pevent.c +++ b/src/pevent.c @@ -43,6 +43,8 @@ #include "log.h" static int epoll_event_string(uint32_t event, char *buf, size_t siz); +static struct event_buf * +add_eventbuf(event_ctx *ctx); static int epoll_event_string(uint32_t event, char *buf, size_t siz) @@ -73,9 +75,19 @@ void event_init(event_ctx **ctx) void event_free(event_ctx **ctx) { + size_t i, max; + assert(ctx && *ctx); close((*ctx)->epoll_fd); + + if ((*ctx)->buffer_array) { + max = (*ctx)->buffer_used; + for (i = 0; i < max; ++i) { + close((*ctx)->buffer_array[i].fd); + } + free((*ctx)->buffer_array); + } free((*ctx)); *ctx = NULL; } @@ -91,14 +103,56 @@ int event_setup(event_ctx *ctx) return ctx->epoll_fd < 0; } +int event_validate_ctx(event_ctx *ctx) +{ + assert(ctx); + assert(ctx->active != ctx->has_error); + assert(ctx->epoll_fd >= 0); + assert(ctx->buffer_size > ctx->buffer_used); + + return 0; +} + +static struct event_buf * +add_eventbuf(event_ctx *ctx) +{ + size_t i, siz = ctx->buffer_size; + + if (siz < ctx->buffer_used + 1) { + siz += POTD_EVENTBUF_REALLOCSIZ; + + ctx->buffer_array = realloc(ctx->buffer_array, + sizeof(*ctx->buffer_array) * siz); + assert(ctx->buffer_array); + + memset(ctx->buffer_array + + sizeof(*ctx->buffer_array) * ctx->buffer_used, 0, + sizeof(*ctx->buffer_array) * (siz - ctx->buffer_used)); + + for (i = ctx->buffer_used; i < ctx->buffer_size; ++i) { + ctx->buffer_array[i].fd = -1; + } + + ctx->buffer_size = siz; + } + + ctx->buffer_used++; + return &ctx->buffer_array[ctx->buffer_used - 1]; +} + int event_add_sock(event_ctx *ctx, psocket *sock) { int s; struct epoll_event ev = {0,{0}}; + struct event_buf *eb; assert(ctx && sock); - ev.data.fd = sock->fd; + eb = add_eventbuf(ctx); + eb->fd = sock->fd; + assert(eb->buf_used == 0); + + ev.data.ptr = eb; ev.events = EPOLLIN /*| EPOLLET*/; /* EPOLLET: broken */ s = epoll_ctl(ctx->epoll_fd, EPOLL_CTL_ADD, sock->fd, &ev); if (s) @@ -111,10 +165,15 @@ int event_add_fd(event_ctx *ctx, int fd) { int s; struct epoll_event ev = {0,{0}}; + struct event_buf *eb; assert(ctx); - ev.data.fd = fd; + eb = add_eventbuf(ctx); + eb->fd = fd; + assert(eb->buf_used == 0); + + ev.data.ptr = eb; ev.events = EPOLLIN | EPOLLET; s = epoll_ctl(ctx->epoll_fd, EPOLL_CTL_ADD, fd, &ev); if (s) @@ -128,6 +187,7 @@ int event_loop(event_ctx *ctx, on_event_cb on_event, void *user_data) int n, i, saved_errno; char ev_err[16]; sigset_t eset; + event_buf *buf; assert(ctx && on_event); sigemptyset(&eset); @@ -147,6 +207,7 @@ int event_loop(event_ctx *ctx, on_event_cb on_event, void *user_data) for (i = 0; i < n; ++i) { ctx->current_event = i; + buf = (event_buf *) ctx->events[i].data.ptr; if ((ctx->events[i].events & EPOLLERR) || (ctx->events[i].events & EPOLLHUP) || @@ -155,19 +216,17 @@ int event_loop(event_ctx *ctx, on_event_cb on_event, void *user_data) { if (epoll_event_string(ctx->events[i].events, ev_err, sizeof ev_err)) { errno = saved_errno; - E_STRERR("Event for descriptor %d", - ctx->events[i].data.fd); + E_STRERR("Event for descriptor %d", buf->fd); } else { errno = saved_errno; - E_STRERR("Event [%s] for descriptor %d", - ev_err, ctx->events[i].data.fd); + E_STRERR("Event [%s] for descriptor %d", ev_err, buf->fd); } ctx->has_error = 1; } else { - if (!on_event(ctx, ctx->events[i].data.fd, user_data) && !ctx->has_error) + if (!on_event(ctx, ctx->events[i].data.ptr, user_data) && !ctx->has_error) W2("Event callback failed: [fd: %d , npoll: %d]", - ctx->events[i].data.fd, n); + buf->fd, n); } if (!ctx->active || ctx->has_error) @@ -183,26 +242,25 @@ event_forward_connection(event_ctx *ctx, int dest_fd, on_data_cb on_data, void *user_data) { int data_avail = 1; - int has_input; int saved_errno; forward_state rc = CON_OK; ssize_t siz; - char buf[BUFSIZ]; struct epoll_event *ev; + struct event_buf *ev_buf; assert(ctx->current_event >= 0 && ctx->current_event < POTD_MAXEVENTS); ev = &ctx->events[ctx->current_event]; + ev_buf = (event_buf *) ev->data.ptr; while (data_avail) { - has_input = 0; saved_errno = 0; siz = -1; if (ev->events & EPOLLIN) { - has_input = 1; errno = 0; - siz = read(ev->data.fd, &buf[0], BUFSIZ); + ev_buf->buf_used = 0; + siz = read(ev_buf->fd, ev_buf->buf, sizeof(ev_buf->buf)); saved_errno = errno; } else break; if (saved_errno == EAGAIN) @@ -210,7 +268,7 @@ event_forward_connection(event_ctx *ctx, int dest_fd, on_data_cb on_data, switch (siz) { case -1: - E_STRERR("Client read from fd %d", ev->data.fd); + E_STRERR("Client read from fd %d", ev_buf->fd); ctx->has_error = 1; rc = CON_IN_ERROR; break; @@ -218,7 +276,8 @@ event_forward_connection(event_ctx *ctx, int dest_fd, on_data_cb on_data, rc = CON_IN_TERMINATED; break; default: - D2("Read %zu bytes from fd %d", siz, ev->data.fd); + D2("Read %zu bytes from fd %d", siz, ev_buf->fd); + ev_buf->buf_used = siz; break; } @@ -226,30 +285,29 @@ event_forward_connection(event_ctx *ctx, int dest_fd, on_data_cb on_data, break; if (on_data && - on_data(ctx, ev->data.fd, dest_fd, buf, siz, user_data)) + on_data(ctx, ev_buf->fd, dest_fd, ev_buf->buf, ev_buf->buf_used, + user_data)) { W2("On data callback failed, not forwarding from %d to %d", - ev->data.fd, dest_fd); + ev_buf->fd, dest_fd); continue; } - if (has_input) { - errno = 0; - siz = write(dest_fd, &buf[0], siz); - - switch (siz) { - case -1: - ctx->has_error = 1; - rc = CON_OUT_ERROR; - break; - case 0: - rc = CON_OUT_TERMINATED; - break; - default: - D2("Written %zu bytes from fd %d to fd %d", - siz, ev->data.fd, dest_fd); - break; - } + errno = 0; + siz = write(dest_fd, ev_buf->buf, ev_buf->buf_used); + + switch (siz) { + case -1: + ctx->has_error = 1; + rc = CON_OUT_ERROR; + break; + case 0: + rc = CON_OUT_TERMINATED; + break; + default: + D2("Written %zu bytes from fd %d to fd %d", + siz, ev_buf->fd, dest_fd); + break; } if (rc != CON_OK) @@ -258,7 +316,7 @@ event_forward_connection(event_ctx *ctx, int dest_fd, on_data_cb on_data, D2("Connection state: %d", rc); if (rc != CON_OK) { - shutdown(ev->data.fd, SHUT_RDWR); + shutdown(ev_buf->fd, SHUT_RDWR); shutdown(dest_fd, SHUT_RDWR); } return rc; diff --git a/src/pevent.h b/src/pevent.h index b756505..0f387aa 100644 --- a/src/pevent.h +++ b/src/pevent.h @@ -40,12 +40,20 @@ #define POTD_MAXFD 32 #define POTD_MAXEVENTS 64 +#define POTD_EVENTBUF_REALLOCSIZ 5 typedef enum forward_state { CON_OK, CON_IN_TERMINATED, CON_OUT_TERMINATED, CON_IN_ERROR, CON_OUT_ERROR } forward_state; +typedef struct event_buf { + int fd; + + char buf[BUFSIZ]; + size_t buf_used; +} event_buf; + typedef struct event_ctx { int active; int has_error; @@ -53,9 +61,14 @@ typedef struct event_ctx { int epoll_fd; struct epoll_event events[POTD_MAXEVENTS]; int current_event; + + event_buf *buffer_array; + size_t buffer_size; + size_t buffer_used; } event_ctx; -typedef int (*on_event_cb) (event_ctx *ev_ctx, int fd, void *user_data); +typedef int (*on_event_cb) (event_ctx *ev_ctx, event_buf *buf, + void *user_data); typedef int (*on_data_cb) (event_ctx *ev_ctx, int src_fd, int dst_fd, char *buf, size_t siz, void *user_data); @@ -66,6 +79,8 @@ void event_free(event_ctx **ctx); int event_setup(event_ctx *ctx); +int event_validate_ctx(event_ctx *ctx); + int event_add_sock(event_ctx *ctx, psocket *sock); int event_add_fd(event_ctx *ctx, int fd); diff --git a/src/redirector.c b/src/redirector.c index 3c5acdc..e418224 100644 --- a/src/redirector.c +++ b/src/redirector.c @@ -76,10 +76,11 @@ fwd_state_string(const forward_state c_state, const client_thread *args, static int redirector_mainloop(event_ctx **ev_ctx, redirector_ctx *rdr_ctx[], size_t siz) __attribute__((noreturn)); -static int redirector_accept_client(event_ctx *ev_ctx, int fd, void *user_data); +static int redirector_accept_client(event_ctx *ev_ctx, event_buf *buf, + void *user_data); static void * client_mainloop(void *arg); -static int client_io(event_ctx *ev_ctx, int src_fd, void *user_data); +static int client_io(event_ctx *ev_ctx, event_buf *buf, void *user_data); static pthread_attr_t pattr; @@ -293,18 +294,21 @@ static int redirector_mainloop(event_ctx **ev_ctx, redirector_ctx *rdr_ctx[], si exit(rc); } -static int redirector_accept_client(event_ctx *ev_ctx, int fd, void *user_data) +static int redirector_accept_client(event_ctx *ev_ctx, event_buf *buf, + void *user_data) { size_t i; double d; - int s; + int s, fd; time_t t; - server_event *ev_srv = (server_event *) user_data; + server_event *ev_srv; client_thread *args; redirector_ctx *rdr_ctx; (void) ev_ctx; - assert(ev_srv); + assert(ev_ctx && buf && user_data); + ev_srv = (server_event *) user_data; + fd = buf->fd; for (i = 0; i < ev_srv->siz; ++i) { rdr_ctx = ev_srv->rdr_ctx[i]; @@ -451,9 +455,9 @@ finish: } static int -client_io(event_ctx *ev_ctx, int src_fd, void *user_data) +client_io(event_ctx *ev_ctx, event_buf *buf, void *user_data) { - int dest_fd; + int dest_fd, src_fd = buf->fd; client_event *ev_cli = (client_event *) user_data; const psocket *client_sock = &ev_cli->client_args->client_sock; forward_state fwd_state; |