libventi: protocol support for blocks larger than 64k
This commit is contained in:
parent
9cac97f2c5
commit
33b446b8bb
6 changed files with 79 additions and 23 deletions
|
|
@ -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 */
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
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,13 +171,26 @@ 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;
|
||||
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:
|
||||
f->data = packetalloc();
|
||||
|
|
|
|||
|
|
@ -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,6 +20,7 @@ _vtsend(VtConn *z, Packet *p)
|
|||
|
||||
/* add framing */
|
||||
n = packetsize(p);
|
||||
if(z->version[1] == '2') {
|
||||
if(n >= (1<<16)) {
|
||||
werrstr("packet too large");
|
||||
packetfree(p);
|
||||
|
|
@ -29,6 +30,14 @@ _vtsend(VtConn *z, Packet *p)
|
|||
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;
|
||||
}
|
||||
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;
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include <venti.h>
|
||||
|
||||
static char *okvers[] = {
|
||||
"04",
|
||||
"02",
|
||||
nil,
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue