Commit Diff


commit - 9cac97f2c55efc9ffa9b3894127e049cc25852a3
commit + 33b446b8bbfea80552d462296d27ad4114fbd3fb
blob - 8a64c57ef02a8b9b43699af6c9b89e70e393c4c5
blob + 14627dcb724791420fdc97e45b4b2caf23309d1a
--- include/venti.h
+++ include/venti.h
@@ -292,7 +292,7 @@ struct VtFcall
 	uint	nauth;		/* TauthX, RauthX */
 	uchar	score[VtScoreSize];	/* Tread, Rwrite */
 	uchar	blocktype;		/* Tread, Twrite */
-	ushort	count;		/* Tread */
+	uint	count;		/* Tread */
 	Packet	*data;		/* Rread, Twrite */
 };
 
blob - ae8fa65c3ccf98b84a3fc20e4cbe3fc7b60f841f
blob + 6f5826eb47ba791daf529bb257a7922aa9ce5ca9
--- man/man7/venti.7
+++ man/man7/venti.7
@@ -441,6 +441,21 @@ message ends a session.  There is no
 upon receiving the
 .BR VtTgoodbye
 message, the server terminates up the connection.
+.PP
+Version
+.B 04
+of the Venti protocol is similar to version
+.B 02
+(described above)
+but has two changes to accomodates larger payloads.
+First, it replaces the leading 2-byte packet size with
+a 4-byte size.
+Second, the
+.I count
+in the
+.B VtTread
+packet may be either 2 or 4 bytes;
+the total packet length distinguishes the two cases.
 .SH SEE ALSO
 .IR venti (1),
 .IR venti (3),
blob - 40ee85175cb73d830cf53e64e0bdd4dba448ac19
blob + 9f200f48c2e8f60061c902534fb084c4cc60fbf4
--- src/libventi/client.c
+++ src/libventi/client.c
@@ -65,6 +65,10 @@ vtreadpacket(VtConn *z, uchar score[VtScoreSize], uint
 	if(memcmp(score, vtzeroscore, VtScoreSize) == 0)
 		return packetalloc();
 
+	if(z->version[1] == '2' && n >= (1<<16)) {
+		werrstr("read count too large for protocol");
+		return nil;
+	}
 	memset(&tx, 0, sizeof tx);
 	tx.msgtype = VtTread;
 	tx.blocktype = type;
blob - 65ee2d17837cdc74600d8027e7b02c200a1d616a
blob + f2a03753de4d0b3f38db091192e931b62a242295
--- src/libventi/fcall.c
+++ src/libventi/fcall.c
@@ -5,7 +5,7 @@
 Packet*
 vtfcallpack(VtFcall *f)
 {
-	uchar buf[4];
+	uchar buf[10];
 	Packet *p;
 
 	p = packetalloc();
@@ -60,9 +60,17 @@ vtfcallpack(VtFcall *f)
 		if(~buf[0] == 0)
 			goto Err;
 		buf[1] = 0;
-		buf[2] = f->count >> 8;
-		buf[3] = f->count;
-		packetappend(p, buf, 4);
+		if(f->count >= (1<<16)) {
+			buf[2] = f->count >> 24;
+			buf[3] = f->count >> 16;
+			buf[4] = f->count >> 8;
+			buf[5] = f->count;
+			packetappend(p, buf, 6);
+		} else {
+			buf[2] = f->count >> 8;
+			buf[3] = f->count;
+			packetappend(p, buf, 4);
+		}
 		break;
 
 	case VtRread:
@@ -163,12 +171,25 @@ vtfcallunpack(VtFcall *f, Packet *p)
 
 	case VtTread:
 		if(packetconsume(p, f->score, VtScoreSize) < 0
-		|| packetconsume(p, buf, 4) < 0)
+		|| packetconsume(p, buf, 2) < 0)
 			goto Err;
 		f->blocktype = vtfromdisktype(buf[0]);
 		if(~f->blocktype == 0)
 			goto Err;
-		f->count = (buf[2] << 8) | buf[3];
+		switch(packetsize(p)) {
+		default:
+			goto Err;
+		case 2:
+			if(packetconsume(p, buf, 2) < 0)
+				goto Err;
+			f->count = (buf[2] << 8) | buf[3];
+			break;
+		case 4:
+			if(packetconsume(p, buf, 4) < 0)
+				goto Err;
+			f->count = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
+			break;
+		}
 		break;
 
 	case VtRread:
blob - 2b88818dad2833bbd646b705a098b076e082b1ab
blob + 4dbe115f30d7f172b103c715619d3f0ce99c3d67
--- src/libventi/send.c
+++ src/libventi/send.c
@@ -11,7 +11,7 @@ _vtsend(VtConn *z, Packet *p)
 {
 	IOchunk ioc;
 	int n, tot;
-	uchar buf[2];
+	uchar buf[4];
 
 	if(z->state != VtStateConnected) {
 		werrstr("session not connected");
@@ -20,15 +20,24 @@ _vtsend(VtConn *z, Packet *p)
 
 	/* add framing */
 	n = packetsize(p);
-	if(n >= (1<<16)) {
-		werrstr("packet too large");
-		packetfree(p);
-		return -1;
+	if(z->version[1] == '2') {
+		if(n >= (1<<16)) {
+			werrstr("packet too large");
+			packetfree(p);
+			return -1;
+		}
+		buf[0] = n>>8;
+		buf[1] = n;
+		packetprefix(p, buf, 2);
+		ventisendbytes += n+2;
+	} else {
+		buf[0] = n>>24;
+		buf[1] = n>>16;
+		buf[2] = n>>8;
+		buf[3] = n;
+		packetprefix(p, buf, 4);
+		ventisendbytes += n+4;
 	}
-	buf[0] = n>>8;
-	buf[1] = n;
-	packetprefix(p, buf, 2);
-	ventisendbytes += n+2;
 	ventisendpackets++;
 
 	tot = 0;
@@ -63,7 +72,7 @@ static Packet*
 _vtrecv(VtConn *z)
 {
 	uchar buf[10], *b;
-	int n;
+	int n, need;
 	Packet *p;
 	int size, len;
 
@@ -75,11 +84,12 @@ _vtrecv(VtConn *z)
 	p = z->part;
 	/* get enough for head size */
 	size = packetsize(p);
-	while(size < 2) {
-		b = packettrailer(p, 2);
+	need = z->version[1] - '0';	// 2 or 4
+	while(size < need) {
+		b = packettrailer(p, need);
 		assert(b != nil);
 		if(0) fprint(2, "%d read hdr\n", getpid());
-		n = read(z->infd, b, 2);
+		n = read(z->infd, b, need);
 		if(0) fprint(2, "%d got %d (%r)\n", getpid(), n);
 		if(n==0 || (n<0 && !interrupted()))
 			goto Err;
@@ -87,10 +97,15 @@ _vtrecv(VtConn *z)
 		packettrim(p, 0, size);
 	}
 
-	if(packetconsume(p, buf, 2) < 0)
+	if(packetconsume(p, buf, need) < 0)
 		goto Err;
-	len = (buf[0] << 8) | buf[1];
-	size -= 2;
+	if(z->version[1] == '2') {
+		len = (buf[0] << 8) | buf[1];
+		size -= 2;
+	} else {
+		len = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
+		size -= 4;
+	}
 
 	while(size < len) {
 		n = len - size;
blob - fd1e2389ab4ebffc8d5d925e5a74631e0b36fada
blob + 655dcb36bdc94985f06c21b7342751976e0867c1
--- src/libventi/version.c
+++ src/libventi/version.c
@@ -3,6 +3,7 @@
 #include <venti.h>
 
 static char *okvers[] = {
+	"04",
 	"02",
 	nil,
 };