diff --git a/Makefile b/Makefile index ad18a59..10668ff 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -CFLAGS=-std=c99 -fsanitize=address -fno-omit-frame-pointer +CFLAGS=-std=c99 -g -fsanitize=address -fno-omit-frame-pointer glorytun: diff --git a/common.h b/common.h index 73b9cc4..fcb4507 100644 --- a/common.h +++ b/common.h @@ -4,22 +4,113 @@ #define _GNU_SOURCE #endif +#include +#include #include #include #define COUNT(x) (sizeof(x)/sizeof(x[0])) -static inline size_t str_cpy (char *dst, char *src, size_t n) +#define ALIGN_SIZE (1<<4) +#define ALIGN_MASK (ALIGN_SIZE-1) + +#define ALIGN(x) (((x)+ALIGN_MASK)&~ALIGN_MASK) +#define ALIGN_DOWN(x) ((x)&~ALIGN_MASK) + +#define PALIGN(x) ((void *)ALIGN((size_t)(x))) +#define PALIGN_DOWN(x) ((void *)ALIGN_DOWN((size_t)(x))) + +static inline void byte_set (void *dst, const char value, size_t size) +{ + if (!dst) + return; + + char *restrict d = dst; + + while (size--) + *d++ = value; +} + +static inline void byte_copy (void *dst, const void *src, size_t size) +{ + if (!dst || !src) + return; + + char *restrict d = dst; + const char *restrict s = src; + + while (size--) + *d++ = *s++; +} + +static inline size_t str_cpy (char *dst, const char *src, size_t len) { if (!dst || !src) return 0; size_t i; - for (i=0; idata = data; + buffer->read = data; + buffer->write = data; + buffer->end = data; + buffer->end += size; +} + +static inline void buffer_format (buffer_t *buffer) +{ + buffer->write = buffer->data; + buffer->read = buffer->data; +} + +static inline size_t buffer_size (buffer_t *buffer) +{ + return buffer->end-buffer->data; +} + +static inline size_t buffer_write_size (buffer_t *buffer) +{ + return buffer->end-buffer->write; +} + +static inline size_t buffer_read_size (buffer_t *buffer) +{ + return buffer->write-buffer->read; +} + +static inline void buffer_shift (buffer_t *buffer) +{ + if (buffer->read==buffer->write) { + buffer_format(buffer); + } else { + const uint8_t *src = PALIGN_DOWN(buffer->read); + const size_t size = ALIGN(buffer->write-src); + if (buffer->data+sizedata, src, size); + buffer->read -= src-buffer->data; + buffer->write -= src-buffer->data; + } + } +} diff --git a/glorytun.c b/glorytun.c index 540ee8c..beddff3 100644 --- a/glorytun.c +++ b/glorytun.c @@ -42,7 +42,8 @@ static int gt_open_tun (char *name) return fd; } -static void gt_sa_stop (int sig) { +static void gt_sa_stop (int sig) +{ switch (sig) { case SIGINT: case SIGTERM: @@ -65,6 +66,54 @@ static int gt_set_signal (void) sigaction(SIGPIPE, &sa, NULL); } +static inline int buffer_read_fd (buffer_t *buffer, int fd) +{ + buffer_shift(buffer); + + size_t size = buffer_write_size(buffer); + + if (!size) + return -1; + + ssize_t ret = read(fd, buffer->write, size); + + if (ret==-1) { + if (errno==EAGAIN || errno==EINTR) + return -1; + if (errno) + printf("read: %m\n"); + return 0; + } + + buffer->write += ret; + + return 1; +} + +static inline int buffer_write_fd (buffer_t *buffer, int fd) +{ + size_t size = buffer_read_size(buffer); + + if (!size) + return -1; + + ssize_t ret = write(fd, buffer->read, size); + + if (ret==-1) { + if (errno==EAGAIN || errno==EINTR) + return -1; + if (errno) + printf("read: %m\n"); + return 0; + } + + buffer->read += ret; + + buffer_shift(buffer); + + return 1; +} + int main (int argc, char **argv) { gt_set_signal(); @@ -78,6 +127,9 @@ int main (int argc, char **argv) { .fd = tun_fd, .events = POLLIN }, }; + buffer_t input; + buffer_setup(&input, NULL, 256*1024); + while (running) { int ret = poll(fds, COUNT(fds), 0); @@ -92,9 +144,13 @@ int main (int argc, char **argv) continue; if (fds[0].revents & POLLIN) { - printf("POLLIN!\n"); + int read_ret = buffer_read_fd(&input, fds[0].fd); + printf("read %zu\n", buffer_read_size(&input)); + buffer_format(&input); } } + free(input.data); + return 0; }