From 3f243081d85ca02188ccdd61ae3476ed9df933e1 Mon Sep 17 00:00:00 2001 From: Curtis McEnroe Date: Fri, 25 Oct 2019 02:27:05 -0400 Subject: Implement client reading from ring buffer It's still messy but it works!! --- bounce.c | 31 ++++++++++++++++++++++--------- bounce.h | 12 +++++++----- client.c | 21 +++++++++++++++++++++ 3 files changed, 50 insertions(+), 14 deletions(-) diff --git a/bounce.c b/bounce.c index 6de5e5d..c771bbe 100644 --- a/bounce.c +++ b/bounce.c @@ -140,17 +140,30 @@ int main(int argc, char *argv[]) { struct tls *tls; int fd = listenAccept(&tls, event.fds[i].fd); eventAdd(fd, clientAlloc(tls)); - } else if (!event.clients[i]) { + continue; + } + if (!event.clients[i]) { serverRecv(); + continue; + } + short revents = event.fds[i].revents; + struct Client *client = event.clients[i]; + if (revents & POLLIN) clientRecv(client); + if (revents & POLLOUT) clientRead(client); + if (clientError(client) || revents & (POLLHUP | POLLERR)) { + clientFree(client); + close(event.fds[i].fd); + eventRemove(i); + break; + } + } + + for (size_t i = 0; i < event.len; ++i) { + if (!event.clients[i]) continue; + if (clientDiff(event.clients[i])) { + event.fds[i].events |= POLLOUT; } else { - struct Client *client = event.clients[i]; - if (event.fds[i].revents & POLLIN) clientRecv(client); - if (event.fds[i].revents & ~POLLIN || clientError(client)) { - clientFree(client); - close(event.fds[i].fd); - eventRemove(i); - break; - } + event.fds[i].events &= ~POLLOUT; } } } diff --git a/bounce.h b/bounce.h index d81acf9..d4ec916 100644 --- a/bounce.h +++ b/bounce.h @@ -53,6 +53,11 @@ static inline struct Message parse(char *line) { return msg; } +void ringWrite(const char *line); +size_t ringReader(const char *name); +size_t ringDiff(size_t reader); +const char *ringRead(time_t *time, size_t reader); + void listenConfig(const char *cert, const char *priv); size_t listenBind(int fds[], size_t cap, const char *host, const char *port); int listenAccept(struct tls **client, int fd); @@ -76,12 +81,9 @@ void clientRecv(struct Client *client); void clientSend(struct Client *client, const char *ptr, size_t len); void clientFormat(struct Client *client, const char *format, ...) __attribute__((format(printf, 2, 3))); +size_t clientDiff(const struct Client *client); +void clientRead(struct Client *client); bool stateReady(void); void stateParse(char *line); void stateSync(struct Client *client); - -void ringWrite(const char *line); -size_t ringReader(const char *name); -size_t ringDiff(size_t reader); -const char *ringRead(time_t *time, size_t reader); diff --git a/client.c b/client.c index 4bb1f54..cdf0009 100644 --- a/client.c +++ b/client.c @@ -119,6 +119,7 @@ static void handleUser(struct Client *client, struct Message msg) { } static void handlePass(struct Client *client, struct Message msg) { + if (!clientPass) return; if (!msg.params[0] || strcmp(clientPass, msg.params[0])) { passRequired(client); } else { @@ -227,3 +228,23 @@ void clientRecv(struct Client *client) { client->len -= line - client->buf; memmove(client->buf, line, client->len); } + +size_t clientDiff(const struct Client *client) { + if (client->need) return 0; + return ringDiff(client->reader); +} + +// TODO: Read several lines based on LOWAT for POLLOUT? +void clientRead(struct Client *client) { + time_t time; + const char *line = ringRead(&time, client->reader); + if (!line) return; + if (client->serverTime) { + char ts[sizeof("YYYY-MM-DDThh:mm:ss.sssZ")]; + struct tm *tm = gmtime(&time); + strftime(ts, sizeof(ts), "%FT%T.000Z", tm); + clientFormat(client, "@time=%s %s\r\n", ts, line); + } else { + clientFormat(client, "%s\r\n", line); + } +} -- cgit 1.4.1