commit 1681468b80bca10e20b57d795598298d1149ac56
parent c068ba6ba9eb642e238f2a88007a5ae04ad9c95b
Author: sin <sin@2f30.org>
Date: Tue, 12 Apr 2016 11:38:08 +0100
factor our net code
Diffstat:
M | Makefile | | | 6 | +++--- |
A | net.c | | | 85 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | stun.c | | | 80 | ------------------------------------------------------------------------------- |
M | stun.h | | | 4 | ++++ |
4 files changed, 92 insertions(+), 83 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,9 +1,9 @@
include config.mk
DISTFILES = Makefile README WHATSNEW UNLICENSE arg.h \
- config.mk crypto.c dev_bsd.c dev_linux.c log.c stun.8 stun.c \
- stun.h util.c
-OBJ = $(EXTRAOBJ) crypto.o log.o stun.o util.o
+ config.mk crypto.c dev_bsd.c dev_linux.c log.c \
+ net.c stun.8 stun.c stun.h util.c
+OBJ = $(EXTRAOBJ) crypto.o log.o net.o stun.o util.o
BIN = stun
all: $(BIN)
diff --git a/net.c b/net.c
@@ -0,0 +1,85 @@
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#if defined(__linux__)
+#include <bsd/stdlib.h>
+#endif
+
+#include "stun.h"
+
+int
+writenet(int fd, unsigned char *pt, int ptlen)
+{
+ unsigned char *pkt;
+ size_t noncelen = cryptononcelen();
+ size_t taglen = cryptotaglen();
+ size_t pktlen = noncelen + HDRLEN + ptlen + taglen;
+ size_t outlen;
+ int n;
+
+ if (!(pkt = malloc(pktlen)))
+ return -1;
+
+ arc4random_buf(pkt, noncelen);
+ pack16(&pkt[noncelen], ptlen);
+ if (!cryptoseal(&pkt[noncelen + HDRLEN], &outlen,
+ ptlen + taglen, pkt, noncelen,
+ pt, ptlen, &pkt[noncelen], HDRLEN)) {
+ free(pkt);
+ logwarn("cryptoseal failed");
+ return -1;
+ }
+
+ n = writeall(fd, pkt, pktlen);
+ free(pkt);
+ return n;
+}
+
+/*
+ * Read one complete packet off the network. If the payload
+ * length has been tampered with the tag will either not match
+ * or the read will timeout after RCVTIMEO ms. Timing out is
+ * necessary to make sure the two ends synchronize again.
+ */
+int
+readnet(int fd, unsigned char *pt, int ptlen)
+{
+ unsigned char *pkt;
+ size_t noncelen = cryptononcelen();
+ size_t taglen = cryptotaglen();
+ size_t pktlen = noncelen + HDRLEN + ptlen + taglen;
+ size_t outlen;
+ int n, ctlen;
+
+ if (!(pkt = malloc(pktlen)))
+ return -1;
+
+ if ((n = readall(fd, pkt, noncelen)) <= 0)
+ goto err;
+ if ((n = readall(fd, &pkt[noncelen], HDRLEN)) <= 0)
+ goto err;
+ /* if payload len is bogus cap it */
+ if ((ctlen = unpack16(&pkt[noncelen])) > ptlen)
+ ctlen = ptlen;
+ if ((n = readall(fd, &pkt[noncelen + HDRLEN], ctlen + taglen)) <= 0)
+ goto err;
+
+ if (!cryptoopen(pt, &outlen, ptlen, pkt, noncelen,
+ &pkt[noncelen + HDRLEN], ctlen + taglen,
+ &pkt[noncelen], HDRLEN)) {
+ free(pkt);
+ logwarn("cryptoopen failed");
+ return BADPKT;
+ }
+
+ free(pkt);
+ return outlen;
+err:
+ free(pkt);
+ if (n == 0)
+ return 0;
+ if (errno != EWOULDBLOCK)
+ return -1;
+ return BADPKT;
+}
diff --git a/stun.c b/stun.c
@@ -62,10 +62,6 @@
#include <time.h>
#include <unistd.h>
-#if defined(__linux__)
-#include <bsd/stdlib.h>
-#endif
-
#include "stun.h"
char *argv0;
@@ -79,82 +75,6 @@ int foreground;
int sflag;
int
-writenet(int fd, unsigned char *pt, int ptlen)
-{
- unsigned char *pkt;
- size_t noncelen = cryptononcelen();
- size_t taglen = cryptotaglen();
- size_t pktlen = noncelen + HDRLEN + ptlen + taglen;
- size_t outlen;
- int n;
-
- if (!(pkt = malloc(pktlen)))
- return -1;
-
- arc4random_buf(pkt, noncelen);
- pack16(&pkt[noncelen], ptlen);
- if (!cryptoseal(&pkt[noncelen + HDRLEN], &outlen,
- ptlen + taglen, pkt, noncelen,
- pt, ptlen, &pkt[noncelen], HDRLEN)) {
- free(pkt);
- logwarn("cryptoseal failed");
- return -1;
- }
-
- n = writeall(fd, pkt, pktlen);
- free(pkt);
- return n;
-}
-
-/*
- * Read one complete packet off the network. If the payload
- * length has been tampered with the tag will either not match
- * or the read will timeout after RCVTIMEO ms. Timing out is
- * necessary to make sure the two ends synchronize again.
- */
-int
-readnet(int fd, unsigned char *pt, int ptlen)
-{
- unsigned char *pkt;
- size_t noncelen = cryptononcelen();
- size_t taglen = cryptotaglen();
- size_t pktlen = noncelen + HDRLEN + ptlen + taglen;
- size_t outlen;
- int n, ctlen;
-
- if (!(pkt = malloc(pktlen)))
- return -1;
-
- if ((n = readall(fd, pkt, noncelen)) <= 0)
- goto err;
- if ((n = readall(fd, &pkt[noncelen], HDRLEN)) <= 0)
- goto err;
- /* if payload len is bogus cap it */
- if ((ctlen = unpack16(&pkt[noncelen])) > ptlen)
- ctlen = ptlen;
- if ((n = readall(fd, &pkt[noncelen + HDRLEN], ctlen + taglen)) <= 0)
- goto err;
-
- if (!cryptoopen(pt, &outlen, ptlen, pkt, noncelen,
- &pkt[noncelen + HDRLEN], ctlen + taglen,
- &pkt[noncelen], HDRLEN)) {
- free(pkt);
- logwarn("cryptoopen failed");
- return BADPKT;
- }
-
- free(pkt);
- return outlen;
-err:
- free(pkt);
- if (n == 0)
- return 0;
- if (errno != EWOULDBLOCK)
- return -1;
- return BADPKT;
-}
-
-int
challenge(int netfd)
{
unsigned char buf[sizeof(uint64_t)];
diff --git a/stun.h b/stun.h
@@ -42,6 +42,10 @@ void logdbg(char *, ...);
void logwarn(char *, ...);
void logerr(char *, ...);
+/* net.c */
+int writenet(int, unsigned char *, int);
+int readnet(int, unsigned char *, int);
+
/* util.c */
void pack16(unsigned char *, uint16_t);
uint16_t unpack16(unsigned char *);