commit 33b446b8bbfea80552d462296d27ad4114fbd3fb from: Russ Cox date: Mon May 25 07:30:17 2009 UTC libventi: protocol support for blocks larger than 64k 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 static char *okvers[] = { + "04", "02", nil, };