| tlibventi: protocol support for blocks larger than 64k - plan9port - [fork] Plan 9 from user space |
| git clone git://src.adamsgaard.dk/plan9port |
| Log |
| Files |
| Refs |
| README |
| LICENSE |
| --- |
| commit 33b446b8bbfea80552d462296d27ad4114fbd3fb |
| parent 9cac97f2c55efc9ffa9b3894127e049cc25852a3 |
| Author: Russ Cox |
| Date: Mon, 25 May 2009 00:30:17 -0700
libventi: protocol support for blocks larger than 64k
Diffstat:
M include/venti.h | 2 +-
M man/man7/venti.7 | 15 +++++++++++++++
M src/libventi/client.c | 4 ++++
M src/libventi/fcall.c | 33 +++++++++++++++++++++++++------
M src/libventi/send.c | 47 ++++++++++++++++++++-----------
M src/libventi/version.c | 1 +
6 files changed, 79 insertions(+), 23 deletions(-)
--- |
| diff --git a/include/venti.h b/include/venti.h |
| t@@ -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 |
| t@@ -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 |
| t@@ -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 |
| t@@ -5,7 +5,7 @@
Packet*
vtfcallpack(VtFcall *f)
{
- uchar buf[4];
+ uchar buf[10];
Packet *p;
p = packetalloc();
t@@ -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:
t@@ -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 |
| t@@ -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");
t@@ -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;
t@@ -63,7 +72,7 @@ static Packet*
_vtrecv(VtConn *z)
{
uchar buf[10], *b;
- int n;
+ int n, need;
Packet *p;
int size, len;
t@@ -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;
t@@ -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 |
| t@@ -3,6 +3,7 @@
#include
static char *okvers[] = {
+ "04",
"02",
nil,
}; |