stun

simple point to point tunnel
git clone git://git.2f30.org/stun
Log | Files | Refs | README

commit 1f6a67becbfda9dd710fbff590dbc295979f0c7f
parent 2418a494cd09bbe4d42553c1cc941c1a0004913a
Author: sin <sin@2f30.org>
Date:   Mon, 21 Mar 2016 10:14:38 +0000

cleanup

Diffstat:
MREADME | 2--
Mstun.c | 126+++++++++++++++++++++++++++++++++++++++++--------------------------------------
2 files changed, 65 insertions(+), 63 deletions(-)

diff --git a/README b/README @@ -14,13 +14,11 @@ Usage On the server: - ifconfig tun0 create ifconfig tun0 10.0.0.1 10.0.0.2 STUNPW="password" stun -s /dev/tun0 On the client: - ifconfig tun0 create ifconfig tun0 10.0.0.2 10.0.0.1 STUNPW="password" stun -h ip-of-server /dev/tun0 diff --git a/stun.c b/stun.c @@ -29,8 +29,8 @@ #define MTU 1440 EVP_CIPHER_CTX enc, dec; +struct sockaddr_in local, remote; char *argv0; -char *tundev; char *host; int port = 12080; int debug; @@ -233,13 +233,13 @@ loop(int netfd, int tunfd) { unsigned char buf[MTU + AES_BLOCK_SIZE + HDRLEN]; struct pollfd pfd[2]; - int n, ret; + int ret, n; pfd[0].fd = netfd; pfd[0].events = POLLIN; pfd[1].fd = tunfd; pfd[1].events = POLLIN; - while (1) { + for (;;) { ret = poll(pfd, 2, -1); if (ret < 0) err(1, "poll"); @@ -249,13 +249,64 @@ loop(int netfd, int tunfd) if (pfd[1].revents & (POLLIN | POLLHUP)) if ((n = readtun(tunfd, buf, MTU)) <= 0 || (n = writenet(netfd, buf, n)) <= 0) - return -1; + return 1; if (pfd[0].revents & (POLLIN | POLLHUP)) if ((n = readnet(netfd, buf, MTU)) <= 0 || (n = writetun(tunfd, buf, n)) <= 0) - return -1; + return 1; + } + return 0; +} + +int +serversetup(int tunfd) +{ + int ret, netfd, listenfd; + + listenfd = socket(AF_INET, SOCK_STREAM, 0); + if (listenfd < 0) + err(1, "socket"); + setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (int []){1}, sizeof(int)); + memset(&local, 0, sizeof(local)); + local.sin_family = AF_INET; + local.sin_addr.s_addr = htonl(INADDR_ANY); + local.sin_port = htons(port); + ret = bind(listenfd, (struct sockaddr *)&local, sizeof(local)); + if (ret < 0) + err(1, "bind"); + ret = listen(listenfd, 5); + if (ret < 0) + err(1, "listen"); + for (;;) { + netfd = accept(listenfd, (struct sockaddr *)&remote, + (socklen_t []){sizeof(remote)}); + if (ret < 0) + err(1, "accept"); + if (debug) + printf("client connected\n"); + setsockopt(netfd, IPPROTO_TCP, TCP_NODELAY, (int []){1}, sizeof(int)); + loop(netfd, tunfd); + close(netfd); } - return 0; /* unreachable */ +} + +int +clientsetup(int tunfd) +{ + int ret, netfd; + + netfd = socket(AF_INET, SOCK_STREAM, 0); + if (netfd < 0) + err(1, "socket"); + memset(&remote, 0, sizeof(remote)); + remote.sin_family = AF_INET; + remote.sin_addr.s_addr = inet_addr(host); + remote.sin_port = htons(port); + ret = connect(netfd, (struct sockaddr *)&remote, sizeof(remote)); + if (ret < 0) + err(1, "connect"); + setsockopt(netfd, IPPROTO_TCP, TCP_NODELAY, (int []){1}, sizeof(int)); + return loop(netfd, tunfd); } void @@ -268,10 +319,9 @@ usage(void) int main(int argc, char *argv[]) { - struct sockaddr_in local, remote; char *pw; const char *errstr; - int ret, tunfd, netfd = -1, listenfd; + int ret, tunfd; ARGBEGIN { case 'd': @@ -292,64 +342,18 @@ main(int argc, char *argv[]) usage(); } ARGEND - if (argc != 1) usage(); - tundev = argv[0]; - - tunfd = opentun(tundev); - + if (argc != 1 || (!sflag && !host)) + usage(); + tunfd = opentun(argv[0]); pw = getenv("STUNPW"); if (!pw) errx(1, "STUNPW is not set"); if (aesinit((unsigned char *)pw, strlen(pw), &enc, &dec) < 0) errx(1, "couldn't initialize AES cipher"); explicit_bzero(pw, strlen(pw)); - - if (sflag) { - /* server */ - listenfd = socket(AF_INET, SOCK_STREAM, 0); - if (listenfd < 0) - err(1, "socket"); - setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (int []){1}, sizeof(int)); - memset(&local, 0, sizeof(local)); - local.sin_family = AF_INET; - local.sin_addr.s_addr = htonl(INADDR_ANY); - local.sin_port = htons(port); - ret = bind(listenfd, (struct sockaddr *)&local, sizeof(local)); - if (ret < 0) - err(1, "bind"); - ret = listen(listenfd, 5); - if (ret < 0) - err(1, "listen"); - } else { - /* client */ - if (!host) - usage(); - netfd = socket(AF_INET, SOCK_STREAM, 0); - if (netfd < 0) - err(1, "socket"); - memset(&remote, 0, sizeof(remote)); - remote.sin_family = AF_INET; - remote.sin_addr.s_addr = inet_addr(host); - remote.sin_port = htons(port); - ret = connect(netfd, (struct sockaddr *)&remote, sizeof(remote)); - if (ret < 0) - err(1, "connect"); - } - -again: - if (sflag) { - if (netfd != -1) - close(netfd); - netfd = accept(listenfd, (struct sockaddr *)&remote, - (socklen_t []){sizeof(remote)}); - if (ret < 0) - err(1, "accept"); - if (debug) - printf("client connected\n"); - } - setsockopt(netfd, IPPROTO_TCP, TCP_NODELAY, (int []){1}, sizeof(int)); - if (loop(netfd, tunfd) < 0 && sflag) - goto again; + if (sflag) + return serversetup(tunfd); + ret = clientsetup(tunfd); warnx("connection dropped"); - exit(1); + return ret; }