client.c (3366B)
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 if(z == nil){ 69 werrstr("not connected"); 70 return nil; 71 } 72 73 if(z->version[1] == '2' && n >= (1<<16)) { 74 werrstr("read count too large for protocol"); 75 return nil; 76 } 77 memset(&tx, 0, sizeof tx); 78 tx.msgtype = VtTread; 79 tx.blocktype = type; 80 tx.count = n; 81 memmove(tx.score, score, VtScoreSize); 82 if(vtfcallrpc(z, &tx, &rx) < 0) 83 return nil; 84 if(packetsize(rx.data) > n){ 85 werrstr("read returned too much data"); 86 packetfree(rx.data); 87 return nil; 88 } 89 if(ventidoublechecksha1){ 90 packetsha1(rx.data, tx.score); 91 if(memcmp(score, tx.score, VtScoreSize) != 0){ 92 werrstr("read asked for %V got %V", score, tx.score); 93 packetfree(rx.data); 94 return nil; 95 } 96 } 97 return rx.data; 98 } 99 100 int 101 vtread(VtConn *z, uchar score[VtScoreSize], uint type, uchar *buf, int n) 102 { 103 int nn; 104 Packet *p; 105 106 if((p = vtreadpacket(z, score, type, n)) == nil) 107 return -1; 108 nn = packetsize(p); 109 if(packetconsume(p, buf, nn) < 0) 110 abort(); 111 packetfree(p); 112 return nn; 113 } 114 115 int 116 vtwritepacket(VtConn *z, uchar score[VtScoreSize], uint type, Packet *p) 117 { 118 VtFcall tx, rx; 119 120 if(packetsize(p) == 0){ 121 memmove(score, vtzeroscore, VtScoreSize); 122 return 0; 123 } 124 tx.msgtype = VtTwrite; 125 tx.blocktype = type; 126 tx.data = p; 127 if(ventidoublechecksha1) 128 packetsha1(p, score); 129 if(vtfcallrpc(z, &tx, &rx) < 0) 130 return -1; 131 if(ventidoublechecksha1){ 132 if(memcmp(score, rx.score, VtScoreSize) != 0){ 133 werrstr("sha1 hash mismatch: want %V got %V", score, rx.score); 134 return -1; 135 } 136 }else 137 memmove(score, rx.score, VtScoreSize); 138 return 0; 139 } 140 141 int 142 vtwrite(VtConn *z, uchar score[VtScoreSize], uint type, uchar *buf, int n) 143 { 144 Packet *p; 145 int nn; 146 147 p = packetforeign(buf, n, 0, nil); 148 nn = vtwritepacket(z, score, type, p); 149 packetfree(p); 150 return nn; 151 } 152 153 int 154 vtsync(VtConn *z) 155 { 156 VtFcall tx, rx; 157 158 tx.msgtype = VtTsync; 159 return vtfcallrpc(z, &tx, &rx); 160 } 161 162 int 163 vtping(VtConn *z) 164 { 165 VtFcall tx, rx; 166 167 tx.msgtype = VtTping; 168 return vtfcallrpc(z, &tx, &rx); 169 } 170 171 int 172 vtconnect(VtConn *z) 173 { 174 if(vtversion(z) < 0) 175 return -1; 176 if(vthello(z) < 0) 177 return -1; 178 return 0; 179 } 180 181 int 182 vtgoodbye(VtConn *z) 183 { 184 VtFcall tx, rx; 185 186 tx.msgtype = VtTgoodbye; 187 vtfcallrpc(z, &tx, &rx); /* always fails: no VtRgoodbye */ 188 return 0; 189 }