warp-vpn

point to point VPN implementation
git clone git://git.2f30.org/warp-vpn.git
Log | Files | Refs | README

commit 1681468b80bca10e20b57d795598298d1149ac56
parent c068ba6ba9eb642e238f2a88007a5ae04ad9c95b
Author: sin <sin@2f30.org>
Date:   Tue, 12 Apr 2016 11:38:08 +0100

factor our net code

Diffstat:
Makefile | 6+++---
net.c | 85+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
stun.c | 80-------------------------------------------------------------------------------
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 *);