stun

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

commit 5fff73417cc6756ae8c12921d19b6ef916dd0f88
parent 12e4ba80cf650809d6695974321d8f12bcb37c71
Author: sin <sin@2f30.org>
Date:   Mon, 21 Mar 2016 12:38:44 +0000

use getaddrinfo

Diffstat:
Mconfig.mk | 2+-
Mstun.c | 83++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
2 files changed, 56 insertions(+), 29 deletions(-)

diff --git a/config.mk b/config.mk @@ -14,7 +14,7 @@ RANLIB = ranlib #LDFLAGS = -lcrypto # optimized -CFLAGS = -O2 -std=c99 -Wall +CFLAGS = -O2 -std=c99 LDFLAGS = -lcrypto -s # optimized static diff --git a/stun.c b/stun.c @@ -30,10 +30,9 @@ #define MTU 1440 EVP_CIPHER_CTX enc, dec; -struct sockaddr_in local, remote; char *argv0; char *host; -int port = 12080; +char *port = "12080"; int debug; int sflag; @@ -325,21 +324,38 @@ loop(int netfd, int tunfd) int serversetup(int tunfd) { + struct addrinfo hints, *ai, *p; + struct sockaddr_in remote; int ret, netfd, listenfd; - listenfd = socket(AF_INET, SOCK_STREAM, 0); - if (listenfd < 0) - err(1, "socket"); + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; - setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (int []){1}, sizeof(int)); + ret = getaddrinfo(NULL, port, &hints, &ai); + if (ret != 0) + errx(1, "getaddrinfo: %s", gai_strerror(ret)); - 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"); + for (p = ai; p; p = p->ai_next) { + listenfd = socket(AF_INET, SOCK_STREAM, 0); + if (listenfd < 0) { + warn("socket"); + continue; + } + setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (int []){1}, + sizeof(int)); + ret = bind(listenfd, p->ai_addr, p->ai_addrlen); + if (ret < 0) { + warn("bind"); + close(listenfd); + continue; + } + break; + } + if (!p) + errx(1, "failed to bind socket"); + freeaddrinfo(ai); ret = listen(listenfd, 5); if (ret < 0) @@ -369,19 +385,33 @@ serversetup(int tunfd) int clientsetup(int tunfd) { + struct addrinfo hints, *ai, *p; 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"); + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + ret = getaddrinfo(host, port, &hints, &ai); + if (ret != 0) + errx(1, "getaddrinfo: %s", gai_strerror(ret)); + + for (p = ai; p; p = p->ai_next) { + netfd = socket(AF_INET, SOCK_STREAM, 0); + if (netfd < 0) { + warn("socket"); + continue; + } + ret = connect(netfd, p->ai_addr, p->ai_addrlen); + if (ret < 0) { + warn("connect"); + close(netfd); + continue; + } + break; + } + if (!p) + errx(1, "failed to connect to %s", host); + freeaddrinfo(ai); setsockopt(netfd, IPPROTO_TCP, TCP_NODELAY, (int []){1}, sizeof(int)); @@ -404,7 +434,6 @@ int main(int argc, char *argv[]) { char *pw; - const char *errstr; int ret, tunfd; ARGBEGIN { @@ -418,9 +447,7 @@ main(int argc, char *argv[]) host = EARGF(usage()); break; case 'p': - port = strtonum(EARGF(usage()), 1, 65535, &errstr); - if (errstr) - errx(1, "invalid port number"); + port = EARGF(usage()); break; default: usage();