stun

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

auth.c (1725B)


      1 #include <poll.h>
      2 #include <stdint.h>
      3 #include <stdlib.h>
      4 
      5 #if defined(__linux__)
      6 #include <bsd/stdlib.h>
      7 #endif
      8 
      9 #include "warp.h"
     10 
     11 int
     12 challenge(int netfd)
     13 {
     14 	unsigned char buf[sizeof(uint64_t)];
     15 	unsigned long long outlen;
     16 	struct pollfd pfd[1];
     17 	uint64_t n, reply;
     18 	int ret;
     19 
     20 	arc4random_buf(&n, sizeof(buf));
     21 	pack64(buf, n);
     22 	if (netwrite(netfd, buf, sizeof(buf), &outlen) == PKTFAILED)
     23 		return -1;
     24 
     25 	pfd[0].fd = netfd;
     26 	pfd[0].events = POLLIN;
     27 	for (;;) {
     28 		ret = poll(pfd, 1, AUTHTIMEO * 1000);
     29 		if (ret < 0) {
     30 			logwarn("poll");
     31 			return -1;
     32 		} else if (ret == 0) {
     33 			logwarnx("challenge-response timed out");
     34 			return -1;
     35 		}
     36 
     37 		if (pfd[0].revents & (POLLIN | POLLHUP)) {
     38 			ret = netread(netfd, buf, sizeof(buf), &outlen);
     39 			if (ret == PKTFAILED)
     40 				return -1;
     41 			else if (ret == PKTPARTIAL)
     42 				continue;
     43 			if (outlen != sizeof(buf))
     44 				return -1;
     45 			reply = unpack64(buf);
     46 			if (n + 1 == reply)
     47 				return 0;
     48 		}
     49 	}
     50 	return -1;
     51 }
     52 
     53 int
     54 response(int netfd)
     55 {
     56 	unsigned char buf[sizeof(uint64_t)];
     57 	unsigned long long outlen;
     58 	struct pollfd pfd[1];
     59 	uint64_t reply;
     60 	int ret;
     61 
     62 	pfd[0].fd = netfd;
     63 	pfd[0].events = POLLIN;
     64 	for (;;) {
     65 		ret = poll(pfd, 1, AUTHTIMEO * 1000);
     66 		if (ret < 0) {
     67 			logwarn("poll");
     68 			return -1;
     69 		} else if (ret == 0) {
     70 			logwarnx("challenge-response timed out");
     71 			return -1;
     72 		}
     73 
     74 		if (pfd[0].revents & (POLLIN | POLLHUP)) {
     75 			ret = netread(netfd, buf, sizeof(buf), &outlen);
     76 			if (ret == PKTFAILED)
     77 				return -1;
     78 			else if (ret == PKTPARTIAL)
     79 				continue;
     80 			if (outlen != sizeof(buf))
     81 				return -1;
     82 			reply = unpack64(buf);
     83 			pack64(buf, reply + 1);
     84 			if (netwrite(netfd, buf, sizeof(buf), &outlen) == PKTFAILED)
     85 				return -1;
     86 			break;
     87 		}
     88 	}
     89 	return 0;
     90 }