From 4d98a16579fc167b1c4162cf8cff9c50c2f14787 Mon Sep 17 00:00:00 2001 From: angt Date: Thu, 22 Oct 2015 10:47:04 +0200 Subject: [PATCH] Setup fd for perf and always reconnect --- glorytun.c | 162 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 100 insertions(+), 62 deletions(-) diff --git a/glorytun.c b/glorytun.c index e98f66b..13214bc 100644 --- a/glorytun.c +++ b/glorytun.c @@ -18,60 +18,44 @@ volatile sig_atomic_t running; -static int gt_open_sock (char *host, char *port, int listener) +static void fd_set_nonblock (int fd) { - struct addrinfo hints = { - .ai_family = AF_UNSPEC, - .ai_socktype = SOCK_STREAM, - .ai_protocol = IPPROTO_TCP, - .ai_flags = AI_PASSIVE, - }; + int val, ret; - struct addrinfo *ai, *res = NULL; + do { + val = 1; + ret = ioctl(fd, FIONBIO, &val); + } while (ret==-1 && errno==EINTR); - if (getaddrinfo(host, port, &hints, &res)) { - printf("host not found\n"); - return -1; + if (ret==-1) + printf("ioctl FIONBIO: %m\n"); +} + +static void fd_set_nodelay (int fd) +{ + int val = 1; + + if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY , &val, sizeof(val))==-1) + printf("setsockopt TCP_NODELAY: %m\n"); +} + +static void fd_set_reuseaddr (int fd) +{ + int val = 1; + + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val))==-1) + printf("setsockopt SO_REUSEADDR: %m\n"); +} + +static int gt_open_sock (struct addrinfo *res) // bad +{ + for (struct addrinfo *ai=res; ai; ai=ai->ai_next) { + int fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if (fd!=-1) + return fd; } - int fd = -1; - - for (ai=res; ai; ai=ai->ai_next) { - fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - - if (fd==-1) - continue; - - int ret; - - if (listener) { - const int val = 1; - - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val))==-1) - printf("setsockopt: %m\n"); - - ret = bind(fd, ai->ai_addr, ai->ai_addrlen); - - if (!ret) - ret = listen(fd, 1); - } else { - ret = connect(fd, ai->ai_addr, ai->ai_addrlen); - } - - if (!ret) - break; - - if (errno) - printf("socket: %m\n"); - - close(fd); - - fd = -1; - } - - freeaddrinfo(res); - - return fd; + return -1; } static int gt_open_tun (char *name) @@ -240,19 +224,56 @@ int main (int argc, char **argv) if (option(argc, argv, COUNT(opts), opts)) return 1; + struct addrinfo hints = { + .ai_family = AF_UNSPEC, + .ai_socktype = SOCK_STREAM, + .ai_protocol = IPPROTO_TCP, + .ai_flags = AI_PASSIVE, + }; + + struct addrinfo *ai = NULL; + + if (getaddrinfo(host, port, &hints, &ai)) { + printf("host not found\n"); + return 1; + } + + int fd = -1; + + if (listener) { + fd = gt_open_sock(ai); + + if (fd==-1) + return 1; + + fd_set_reuseaddr(fd); + + int ret = bind(fd, ai->ai_addr, ai->ai_addrlen); + + if (ret==-1) { + printf("bind: %m\n"); + return 1; + } + + ret = listen(fd, 1); + + if (ret==-1) { + printf("listen: %m\n"); + return 1; + } + } + struct netio tun = { .fd = -1 }; struct netio sock = { .fd = -1 }; - int fd = gt_open_sock(host, port, listener); - - if (fd==-1) - return 1; - tun.fd = gt_open_tun(dev); if (tun.fd==-1) return 1; + buffer_setup(&tun.recv, NULL, GT_BUFFER_SIZE); + buffer_setup(&sock.recv, NULL, GT_BUFFER_SIZE); + while (running) { if (listener) { @@ -267,17 +288,28 @@ int main (int argc, char **argv) printf("accept: %m\n"); return 1; } - - // setup socket } else { - // reconnect - sock.fd = fd; + sock.fd = gt_open_sock(ai); + + if (sock.fd==-1) + return 1; + + int ret = connect(sock.fd, ai->ai_addr, ai->ai_addrlen); + + if (ret==-1) { // check errno + close(sock.fd); + sock.fd = -1; + continue; + } } + fd_set_nonblock(sock.fd); + fd_set_nodelay(sock.fd); + printf("running...\n"); - buffer_setup(&tun.recv, NULL, GT_BUFFER_SIZE); - buffer_setup(&sock.recv, NULL, GT_BUFFER_SIZE); + buffer_format(&tun.recv); + buffer_format(&sock.recv); while (running) { @@ -348,9 +380,15 @@ int main (int argc, char **argv) } restart: - free(tun.recv.data); - free(sock.recv.data); + close(sock.fd); + sock.fd = -1; } + if (ai) + freeaddrinfo(ai); + + free(tun.recv.data); + free(sock.recv.data); + return 0; }