changeset 41:54d28a81ca99

Small updates in preparation for stateful protocols
author Ivo Smits <Ivo@UCIS.nl>
date Thu, 16 May 2013 01:15:01 +0200
parents ed9581189d6b
children c8d176154d7c
files src/common.c src/proto.nacl0.c src/proto.nacltai.c
diffstat 3 files changed, 33 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/src/common.c	Mon May 06 23:58:25 2013 +0200
+++ b/src/common.c	Thu May 16 01:15:01 2013 +0200
@@ -62,6 +62,7 @@
 	int (*decode)(struct qtsession* sess, char* enc, char* raw, int len);
 	int (*init)(struct qtsession* sess);
 	int protocol_data_size;
+	void (*idle)(struct qtsession* sess);
 };
 struct qtsession {
 	struct qtproto protocol;
@@ -71,6 +72,8 @@
 	int remote_float;
 	struct sockaddr_in remote_addr;
 	int use_pi;
+	int poll_timeout;
+	void (*sendnetworkpacket)(struct qtsession* sess, char* msg, int len);
 };
 
 #ifdef COMBINED_BINARY
@@ -101,7 +104,7 @@
 	fprintf(stderr, "More information: http://wiki.ucis.nl/QuickTun\n");
 }
 
-int init_udp(struct qtsession* session) {
+static int init_udp(struct qtsession* session) {
 	char* envval;
 	fprintf(stderr, "Initializing UDP socket...\n");
 	int sfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
@@ -146,7 +149,7 @@
 	return sfd;
 }
 
-int init_tuntap(struct qtsession* session) {
+static int init_tuntap(struct qtsession* session) {
 	char* envval;
 	fprintf(stderr, "Initializing tun/tap device...\n");
 	int ttfd; //Tap device file descriptor
@@ -204,7 +207,7 @@
 	}
 }
 
-int drop_privileges() {
+static int drop_privileges() {
 	char* envval;
 	if (envval = getconf("SETUID")) {
 		if (setgroups(0, NULL) == -1) return errorexitp("setgroups");
@@ -216,14 +219,25 @@
 	chdir("/");
 }
 
+static void qtsendnetworkpacket(struct qtsession* session, char* msg, int len) {
+	if (session->remote_float == 0) {
+		len = write(session->fd_socket, msg, len);
+	} else if (session->remote_float == 2) {
+		len = sendto(session->fd_socket, msg, len, 0, (struct sockaddr*)&session->remote_addr, sizeof(struct sockaddr_in));
+	}
+}
+
 int qtrun(struct qtproto* p) {
 	if (getconf("DEBUG")) debug = 1;
 	struct qtsession session;
+	session.poll_timeout = -1;
 	session.protocol = *p;
 
 	if (init_udp(&session) < 0) return -1;
 	int sfd = session.fd_socket;
 
+	session.sendnetworkpacket = qtsendnetworkpacket;
+
 	if (init_tuntap(&session) < 0) return -1;
 	int ttfd = session.fd_dev;
 
@@ -253,21 +267,19 @@
 	char* buffer_enc = buffer_enc_a;
 
 	while (1) {
-		int len = poll(fds, 2, -1);
+		int len = poll(fds, 2, session.poll_timeout);
 		if (len < 0) return errorexitp("poll error");
 		else if (fds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) return errorexit("poll error on tap device");
 		else if (fds[1].revents & (POLLHUP | POLLNVAL)) return errorexit("poll error on udp socket");
+		if (len == 0 && p->idle) p->idle(&session);
 		if (fds[0].revents & POLLIN) {
 			len = read(ttfd, buffer_raw + p->offset_raw, p->buffersize_raw + pi_length);
 			if (len < pi_length) errorexit("read packet smaller than header from tun device");
 			if (session.remote_float == 0 || session.remote_float == 2) {
 				len = p->encode(&session, buffer_raw + pi_length, buffer_enc, len - pi_length);
 				if (len < 0) return len;
-				if (session.remote_float == 0) {
-					len = write(sfd, buffer_enc + p->offset_enc, len);
-				} else {
-					len = sendto(sfd, buffer_enc + p->offset_enc, len, 0, (struct sockaddr*)&session.remote_addr, sizeof(session.remote_addr));
-				}
+				if (len == 0) continue; //encoding is not yet possible
+				qtsendnetworkpacket(&session, buffer_enc + p->offset_enc, len);
 			}
 		}
 		if (fds[1].revents & POLLERR) {
@@ -287,18 +299,17 @@
 				long long out;
 				len = sizeof(out);
 				getsockopt(sfd, SOL_SOCKET, SO_ERROR, &out, &len);
-				fprintf(stderr, "Received end of file on udp socket (error %d)\n", out);
+				fprintf(stderr, "Received end of file on udp socket (error %lld)\n", out);
 			} else {
 				len = p->decode(&session, buffer_enc, buffer_raw + pi_length, len);
-				if (len < 0) return len;
-				if (len != 0 && session.remote_float != 0 && (session.remote_addr.sin_addr.s_addr != recvaddr.sin_addr.s_addr || session.remote_addr.sin_port != recvaddr.sin_port)) {
+				if (len < 0) continue;
+				if (session.remote_float != 0 && (session.remote_addr.sin_addr.s_addr != recvaddr.sin_addr.s_addr || session.remote_addr.sin_port != recvaddr.sin_port)) {
 					fprintf(stderr, "Remote endpoint has changed to %08X:%d\n", ntohl(recvaddr.sin_addr.s_addr), ntohs(recvaddr.sin_port));
 					session.remote_addr = recvaddr;
 					session.remote_float = 2;
 				}
-				if (session.use_pi == 2) {
-					int ipver = 0;
-					if (len >= 1) ipver = (buffer_raw[p->offset_raw + pi_length] >> 4) & 0xf;
+				if (len > 0 && session.use_pi == 2) {
+					int ipver = (buffer_raw[p->offset_raw + pi_length] >> 4) & 0xf;
 					int pihdr = 0;
 #if defined linux
 					if (ipver == 4) pihdr = 0x0000 | (0x0008 << 16); //little endian: flags and protocol are swapped
@@ -309,14 +320,14 @@
 #endif
 					*(int*)(buffer_raw + p->offset_raw) = ipver;
 				}
-				write(ttfd, buffer_raw + p->offset_raw, len + pi_length);
+				if (len > 0) write(ttfd, buffer_raw + p->offset_raw, len + pi_length);
 			}
 		}
 	}
 	return 0;
 }
 
-char* getconfcmdargs(const char* name) {
+static char* getconfcmdargs(const char* name) {
 	int i;
 	for (i = 1; i < gargc - 2; i++) {
 		if (strcmp(gargv[i], "-c")) continue;
--- a/src/proto.nacl0.c	Mon May 06 23:58:25 2013 +0200
+++ b/src/proto.nacl0.c	Thu May 16 01:15:01 2013 +0200
@@ -42,13 +42,13 @@
 	int i;
 	if (len < crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES) {
 		fprintf(stderr, "Short packet received: %d\n", len);
-		return 0;
+		return -1;
 	}
 	len -= crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES;
 	memset(enc, 0, crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES);
 	if (i = crypto_box_curve25519xsalsa20poly1305_open_afternm(raw, enc, len+crypto_box_curve25519xsalsa20poly1305_ZEROBYTES, d->cnonce, d->cbefore)) {
 		fprintf(stderr, "Decryption failed len=%d result=%d\n", len, i);
-		return 0;
+		return -1;
 	}
 	return len;
 }
--- a/src/proto.nacltai.c	Mon May 06 23:58:25 2013 +0200
+++ b/src/proto.nacltai.c	Thu May 16 01:15:01 2013 +0200
@@ -137,19 +137,19 @@
 	int i;
 	if (len < overhead) {
 		fprintf(stderr, "Short packet received: %d\n", len);
-		return 0;
+		return -1;
 	}
 	len -= overhead;
 	taia_unpack((char*)(enc + crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES - noncelength), &cdtaic);
 	if (cdtaic.sec.x <= d->cdtaip.sec.x && cdtaic.nano <= d->cdtaip.nano && cdtaic.atto <= d->cdtaip.atto) {
 		fprintf(stderr, "Timestamp going back, ignoring packet\n");
-		return 0;
+		return -1;
 	}
 	memcpy(d->cdnonce + nonceoffset, enc + crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES - noncelength, noncelength);
 	memset(enc, 0, crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES);
 	if (i = crypto_box_curve25519xsalsa20poly1305_open_afternm(raw, enc, len + crypto_box_curve25519xsalsa20poly1305_ZEROBYTES, d->cdnonce, d->cbefore)) {
 		fprintf(stderr, "Decryption failed len=%d result=%d\n", len, i);
-		return 0;
+		return -1;
 	}
 	d->cdtaip = cdtaic;
 	if (debug) fprintf(stderr, "Decoded packet of %d bytes from %p to %p\n", len, enc, raw);