commit 8f63d8c81b156b241cc104fe15caae35a97a35c9
parent e53219cb5eb97b320b0d5e851ceaf16033155dfb
Author: sin <sin@2f30.org>
Date: Wed, 30 Mar 2016 19:38:01 +0100
try harder to recover from a bad header len
Diffstat:
M | stun.c | | | 21 | +++++++++++++++++---- |
1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/stun.c b/stun.c
@@ -200,7 +200,6 @@ writeall(int fd, void *buf, int len)
n = write(fd, p + total, len);
if (n < 0) {
logwarn("write failed");
- total = -1;
break;
} else if (n == 0) {
break;
@@ -221,7 +220,6 @@ readall(int fd, void *buf, int len)
n = read(fd, p + total, len);
if (n < 0) {
logwarn("read failed");
- total = -1;
break;
} else if (n == 0) {
break;
@@ -233,19 +231,32 @@ readall(int fd, void *buf, int len)
}
int
-setrcvtimeo(int netfd, time_t sec)
+setrcvtimeo(int fd, 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));
+ ret = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
if (ret < 0)
logwarn("failed to set timeout on socket");
return ret;
}
+int
+setnonblock(int fd, int mode)
+{
+ int flags;
+
+ flags = fcntl(fd, F_GETFL);
+ if (mode)
+ flags |= O_NONBLOCK;
+ else
+ flags &= ~O_NONBLOCK;
+ return fcntl(fd, F_SETFL, flags);
+}
+
void
revokeprivs(void)
{
@@ -504,6 +515,7 @@ readnet(int fd, unsigned char *pt, int len)
/* discard bad packets */
if (pktlen > sizeof(payload)) {
+ setnonblock(fd, 1);
while (pktlen) {
if (pktlen > sizeof(payload))
len = sizeof(payload);
@@ -514,6 +526,7 @@ readnet(int fd, unsigned char *pt, int len)
break;
pktlen -= n;
}
+ setnonblock(fd, 0);
return BADPKT;
}