From 33b446b8bbfea80552d462296d27ad4114fbd3fb Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Mon, 25 May 2009 00:30:17 -0700 Subject: libventi: protocol support for blocks larger than 64k --- include/venti.h | 2 +- man/man7/venti.7 | 15 +++++++++++++++ src/libventi/client.c | 4 ++++ src/libventi/fcall.c | 33 +++++++++++++++++++++++++++------ src/libventi/send.c | 47 +++++++++++++++++++++++++++++++---------------- src/libventi/version.c | 1 + 6 files changed, 79 insertions(+), 23 deletions(-) diff --git a/include/venti.h b/include/venti.h index 8a64c57e..14627dcb 100644 --- a/include/venti.h +++ b/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 */ }; diff --git a/man/man7/venti.7 b/man/man7/venti.7 index ae8fa65c..6f5826eb 100644 --- a/man/man7/venti.7 +++ b/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), diff --git a/src/libventi/client.c b/src/libventi/client.c index 40ee8517..9f200f48 100644 --- a/src/libventi/client.c +++ b/src/libventi/client.c @@ -65,6 +65,10 @@ vtreadpacket(VtConn *z, uchar score[VtScoreSize], uint type, int n) 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; diff --git a/src/libventi/fcall.c b/src/libventi/fcall.c index 65ee2d17..f2a03753 100644 --- a/src/libventi/fcall.c +++ b/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: diff --git a/src/libventi/send.c b/src/libventi/send.c index 2b88818d..4dbe115f 100644 --- a/src/libventi/send.c +++ b/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; diff --git a/src/libventi/version.c b/src/libventi/version.c index fd1e2389..655dcb36 100644 --- a/src/libventi/version.c +++ b/src/libventi/version.c @@ -3,6 +3,7 @@ #include static char *okvers[] = { + "04", "02", nil, }; -- cgit v1.2.3