stun

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

commit afd1610117af1b3e4a669b21d1821b059c75f071
parent 9304dd3be2fde7c9ebc83df00aefa405a6900af9
Author: sin <sin@2f30.org>
Date:   Thu, 24 Mar 2016 11:35:32 +0000

add timeout when challenging

a bad client could set the header length to whatever but send
less data. the server would block in read forever.

thanks rain1

Diffstat:
Mstun.c | 39++++++++++++++++++++++++++++++---------
1 file changed, 30 insertions(+), 9 deletions(-)

diff --git a/stun.c b/stun.c @@ -28,6 +28,7 @@ #include <stdlib.h> #include <string.h> #include <syslog.h> +#include <time.h> #include <unistd.h> #include <openssl/aes.h> @@ -40,8 +41,8 @@ #define explicit_bzero bzero #endif -#define CHALLENGETIMEO 1000 /* in ms */ -#define RECONNECTTIMEO 60 /* in seconds */ +#define CHALLENGETIMEO 1 /* in seconds */ +#define RECONNECTTIMEO 60 /* in seconds */ #define HDRLEN 2 #define MTU 1440 @@ -420,6 +421,20 @@ readnet(int fd, unsigned char *buf, int len) } int +setrcvtimeo(int netfd, time_t sec) +{ + struct timeval tv; + int ret; + + tv.tv_sec = sec; + tv.tv_usec = 0; + ret = setsockopt(netfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); + if (ret < 0) + logwarn("failed to set timeout on socket"); + return ret; +} + +int challenge(int netfd) { unsigned char buf[sizeof(uint32_t)]; @@ -427,29 +442,35 @@ challenge(int netfd) uint32_t n, reply; int ret; + ret = setrcvtimeo(netfd, CHALLENGETIMEO); + if (ret < 0) + return -1; pack32(buf, n = arc4random()); if (writenet(netfd, buf, sizeof(buf)) <= 0) - return -1; + goto err; pfd[0].fd = netfd; pfd[0].events = POLLIN; - ret = poll(pfd, 1, CHALLENGETIMEO); + ret = poll(pfd, 1, CHALLENGETIMEO * 1000); switch (ret) { case -1: logwarn("poll failed"); - return -1; + goto err; case 0: logwarn("challenge-response timed out"); - return -1; + goto err; default: if (pfd[0].revents & (POLLIN | POLLHUP)) { if (readnet(netfd, buf, sizeof(buf)) <= 0) - return -1; + goto err; reply = unpack32(buf); - if (n + 1 == reply) + if (n + 1 == reply) { + setrcvtimeo(netfd, 0); return 0; - return -1; + } } } +err: + setrcvtimeo(netfd, 0); return -1; }