aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorlns <matzeton@googlemail.com>2018-08-07 16:53:29 +0200
committerlns <matzeton@googlemail.com>2018-08-07 16:53:29 +0200
commitf8497db5d14eb139820173dccba58989c4f9ca5c (patch)
tree3677066a9f8b4aa55e7ba826e2a1e514adc666e1 /src
parentb247c23d23dc646749872423f9ebc6d5c165566d (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.c21
-rw-r--r--src/pevent.c128
-rw-r--r--src/pevent.h17
-rw-r--r--src/redirector.c20
4 files changed, 134 insertions, 52 deletions
diff --git a/src/jail.c b/src/jail.c
index 1b35cc7..e449c97 100644
--- a/src/jail.c
+++ b/src/jail.c
@@ -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;