2011-03-30 12:46:40 +00:00
|
|
|
#include <u.h>
|
|
|
|
#include <libc.h>
|
|
|
|
#include <venti.h>
|
|
|
|
|
|
|
|
int ventidoublechecksha1 = 1;
|
|
|
|
|
|
|
|
static int
|
|
|
|
vtfcallrpc(VtConn *z, VtFcall *ou, VtFcall *in)
|
|
|
|
{
|
|
|
|
Packet *p;
|
|
|
|
|
|
|
|
p = vtfcallpack(ou);
|
|
|
|
if(p == nil)
|
|
|
|
return -1;
|
|
|
|
if((p = _vtrpc(z, p, ou)) == nil)
|
|
|
|
return -1;
|
|
|
|
if(vtfcallunpack(in, p) < 0){
|
|
|
|
packetfree(p);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if(chattyventi)
|
|
|
|
fprint(2, "%s <- %F\n", argv0, in);
|
|
|
|
if(in->msgtype == VtRerror){
|
2014-11-07 11:51:59 +00:00
|
|
|
werrstr("%s", in->error);
|
2011-03-30 12:46:40 +00:00
|
|
|
vtfcallclear(in);
|
|
|
|
packetfree(p);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if(in->msgtype != ou->msgtype+1){
|
|
|
|
werrstr("type mismatch: sent %c%d got %c%d",
|
|
|
|
"TR"[ou->msgtype&1], ou->msgtype>>1,
|
|
|
|
"TR"[in->msgtype&1], in->msgtype>>1);
|
|
|
|
vtfcallclear(in);
|
|
|
|
packetfree(p);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
packetfree(p);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
vthello(VtConn *z)
|
|
|
|
{
|
|
|
|
VtFcall tx, rx;
|
|
|
|
|
|
|
|
memset(&tx, 0, sizeof tx);
|
|
|
|
tx.msgtype = VtThello;
|
|
|
|
tx.version = z->version;
|
|
|
|
tx.uid = z->uid;
|
|
|
|
if(tx.uid == nil)
|
|
|
|
tx.uid = "anonymous";
|
|
|
|
if(vtfcallrpc(z, &tx, &rx) < 0)
|
|
|
|
return -1;
|
|
|
|
z->sid = rx.sid;
|
|
|
|
rx.sid = 0;
|
|
|
|
vtfcallclear(&rx);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Packet*
|
|
|
|
vtreadpacket(VtConn *z, uchar score[VtScoreSize], uint type, int n)
|
|
|
|
{
|
|
|
|
VtFcall tx, rx;
|
|
|
|
|
|
|
|
if(memcmp(score, vtzeroscore, VtScoreSize) == 0)
|
|
|
|
return packetalloc();
|
|
|
|
|
|
|
|
memset(&tx, 0, sizeof tx);
|
|
|
|
tx.msgtype = VtTread;
|
|
|
|
tx.blocktype = type;
|
|
|
|
tx.count = n;
|
|
|
|
memmove(tx.score, score, VtScoreSize);
|
|
|
|
if(vtfcallrpc(z, &tx, &rx) < 0)
|
|
|
|
return nil;
|
|
|
|
if(packetsize(rx.data) > n){
|
|
|
|
werrstr("read returned too much data");
|
|
|
|
packetfree(rx.data);
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
if(ventidoublechecksha1){
|
|
|
|
packetsha1(rx.data, tx.score);
|
|
|
|
if(memcmp(score, tx.score, VtScoreSize) != 0){
|
|
|
|
werrstr("read asked for %V got %V", score, tx.score);
|
|
|
|
packetfree(rx.data);
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return rx.data;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
vtread(VtConn *z, uchar score[VtScoreSize], uint type, uchar *buf, int n)
|
|
|
|
{
|
|
|
|
int nn;
|
|
|
|
Packet *p;
|
|
|
|
|
|
|
|
if((p = vtreadpacket(z, score, type, n)) == nil)
|
|
|
|
return -1;
|
|
|
|
nn = packetsize(p);
|
|
|
|
if(packetconsume(p, buf, nn) < 0)
|
|
|
|
abort();
|
|
|
|
packetfree(p);
|
|
|
|
return nn;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
vtwritepacket(VtConn *z, uchar score[VtScoreSize], uint type, Packet *p)
|
|
|
|
{
|
|
|
|
VtFcall tx, rx;
|
|
|
|
|
|
|
|
if(packetsize(p) == 0){
|
|
|
|
memmove(score, vtzeroscore, VtScoreSize);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
tx.msgtype = VtTwrite;
|
|
|
|
tx.blocktype = type;
|
|
|
|
tx.data = p;
|
|
|
|
if(ventidoublechecksha1)
|
|
|
|
packetsha1(p, score);
|
|
|
|
if(vtfcallrpc(z, &tx, &rx) < 0)
|
|
|
|
return -1;
|
|
|
|
if(ventidoublechecksha1){
|
|
|
|
if(memcmp(score, rx.score, VtScoreSize) != 0){
|
|
|
|
werrstr("sha1 hash mismatch: want %V got %V", score, rx.score);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}else
|
|
|
|
memmove(score, rx.score, VtScoreSize);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
vtwrite(VtConn *z, uchar score[VtScoreSize], uint type, uchar *buf, int n)
|
|
|
|
{
|
|
|
|
Packet *p;
|
|
|
|
int nn;
|
|
|
|
|
|
|
|
p = packetforeign(buf, n, 0, nil);
|
|
|
|
nn = vtwritepacket(z, score, type, p);
|
|
|
|
packetfree(p);
|
|
|
|
return nn;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
vtsync(VtConn *z)
|
|
|
|
{
|
|
|
|
VtFcall tx, rx;
|
|
|
|
|
|
|
|
tx.msgtype = VtTsync;
|
|
|
|
return vtfcallrpc(z, &tx, &rx);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
vtping(VtConn *z)
|
|
|
|
{
|
|
|
|
VtFcall tx, rx;
|
|
|
|
|
|
|
|
tx.msgtype = VtTping;
|
|
|
|
return vtfcallrpc(z, &tx, &rx);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
vtconnect(VtConn *z)
|
|
|
|
{
|
|
|
|
if(vtversion(z) < 0)
|
|
|
|
return -1;
|
|
|
|
if(vthello(z) < 0)
|
|
|
|
return -1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
vtgoodbye(VtConn *z)
|
|
|
|
{
|
|
|
|
VtFcall tx, rx;
|
|
|
|
|
|
|
|
tx.msgtype = VtTgoodbye;
|
|
|
|
vtfcallrpc(z, &tx, &rx); /* always fails: no VtRgoodbye */
|
|
|
|
return 0;
|
|
|
|
}
|