1 #include <u.h> 2 #include <libc.h> 3 #include <venti.h> 4 5 int ventidoublechecksha1 = 1; 6 7 static int 8 vtfcallrpc(VtConn *z, VtFcall *ou, VtFcall *in) 9 { 10 Packet *p; 11 12 p = vtfcallpack(ou); 13 if(p == nil) 14 return -1; 15 if((p = _vtrpc(z, p, ou)) == nil) 16 return -1; 17 if(vtfcallunpack(in, p) < 0){ 18 packetfree(p); 19 return -1; 20 } 21 if(chattyventi) 22 fprint(2, "%s <- %F\n", argv0, in); 23 if(in->msgtype == VtRerror){ 24 werrstr(in->error); 25 vtfcallclear(in); 26 packetfree(p); 27 return -1; 28 } 29 if(in->msgtype != ou->msgtype+1){ 30 werrstr("type mismatch: sent %c%d got %c%d", 31 "TR"[ou->msgtype&1], ou->msgtype>>1, 32 "TR"[in->msgtype&1], in->msgtype>>1); 33 vtfcallclear(in); 34 packetfree(p); 35 return -1; 36 } 37 packetfree(p); 38 return 0; 39 } 40 41 int 42 vthello(VtConn *z) 43 { 44 VtFcall tx, rx; 45 46 memset(&tx, 0, sizeof tx); 47 tx.msgtype = VtThello; 48 tx.version = z->version; 49 tx.uid = z->uid; 50 if(tx.uid == nil) 51 tx.uid = "anonymous"; 52 if(vtfcallrpc(z, &tx, &rx) < 0) 53 return -1; 54 z->sid = rx.sid; 55 rx.sid = 0; 56 vtfcallclear(&rx); 57 return 0; 58 } 59 60 Packet* 61 vtreadpacket(VtConn *z, uchar score[VtScoreSize], uint type, int n) 62 { 63 VtFcall tx, rx; 64 65 if(memcmp(score, vtzeroscore, VtScoreSize) == 0) 66 return packetalloc(); 67 68 memset(&tx, 0, sizeof tx); 69 tx.msgtype = VtTread; 70 tx.blocktype = type; 71 tx.count = n; 72 memmove(tx.score, score, VtScoreSize); 73 if(vtfcallrpc(z, &tx, &rx) < 0) 74 return nil; 75 if(packetsize(rx.data) > n){ 76 werrstr("read returned too much data"); 77 packetfree(rx.data); 78 return nil; 79 } 80 if(ventidoublechecksha1){ 81 packetsha1(rx.data, tx.score); 82 if(memcmp(score, tx.score, VtScoreSize) != 0){ 83 werrstr("read asked for %V got %V", score, tx.score); 84 packetfree(rx.data); 85 return nil; 86 } 87 } 88 return rx.data; 89 } 90 91 int 92 vtread(VtConn *z, uchar score[VtScoreSize], uint type, uchar *buf, int n) 93 { 94 int nn; 95 Packet *p; 96 97 if((p = vtreadpacket(z, score, type, n)) == nil) 98 return -1; 99 nn = packetsize(p); 100 if(packetconsume(p, buf, nn) < 0) 101 abort(); 102 packetfree(p); 103 return nn; 104 } 105 106 int 107 vtwritepacket(VtConn *z, uchar score[VtScoreSize], uint type, Packet *p) 108 { 109 VtFcall tx, rx; 110 111 if(packetsize(p) == 0){ 112 memmove(score, vtzeroscore, VtScoreSize); 113 return 0; 114 } 115 tx.msgtype = VtTwrite; 116 tx.blocktype = type; 117 tx.data = p; 118 if(ventidoublechecksha1) 119 packetsha1(p, score); 120 if(vtfcallrpc(z, &tx, &rx) < 0) 121 return -1; 122 if(ventidoublechecksha1){ 123 if(memcmp(score, rx.score, VtScoreSize) != 0){ 124 werrstr("sha1 hash mismatch: want %V got %V", score, rx.score); 125 return -1; 126 } 127 }else 128 memmove(score, rx.score, VtScoreSize); 129 return 0; 130 } 131 132 int 133 vtwrite(VtConn *z, uchar score[VtScoreSize], uint type, uchar *buf, int n) 134 { 135 Packet *p; 136 int nn; 137 138 p = packetforeign(buf, n, 0, nil); 139 nn = vtwritepacket(z, score, type, p); 140 packetfree(p); 141 return nn; 142 } 143 144 int 145 vtsync(VtConn *z) 146 { 147 VtFcall tx, rx; 148 149 tx.msgtype = VtTsync; 150 return vtfcallrpc(z, &tx, &rx); 151 } 152 153 int 154 vtping(VtConn *z) 155 { 156 VtFcall tx, rx; 157 158 tx.msgtype = VtTping; 159 return vtfcallrpc(z, &tx, &rx); 160 } 161 162 int 163 vtconnect(VtConn *z) 164 { 165 if(vtversion(z) < 0) 166 return -1; 167 if(vthello(z) < 0) 168 return -1; 169 return 0; 170 } 171 172 int 173 vtgoodbye(VtConn *z) 174 { 175 VtFcall tx, rx; 176 177 tx.msgtype = VtTgoodbye; 178 vtfcallrpc(z, &tx, &rx); /* always fails: no VtRgoodbye */ 179 return 0; 180 } 181