commit 1f6a67becbfda9dd710fbff590dbc295979f0c7f
parent 2418a494cd09bbe4d42553c1cc941c1a0004913a
Author: sin <sin@2f30.org>
Date: Mon, 21 Mar 2016 10:14:38 +0000
cleanup
Diffstat:
M | README | | | 2 | -- |
M | stun.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;
}