client.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <venti.h>
  4. #include "session.h"
  5. static char EProtocolBotch[] = "venti protocol botch";
  6. static char ELumpSize[] = "illegal lump size";
  7. static char ENotConnected[] = "not connected to venti server";
  8. static Packet *vtRPC(VtSession *z, int op, Packet *p);
  9. VtSession *
  10. vtClientAlloc(void)
  11. {
  12. VtSession *z = vtAlloc();
  13. return z;
  14. }
  15. VtSession *
  16. vtDial(char *host, int canfail)
  17. {
  18. VtSession *z;
  19. int fd;
  20. char *na;
  21. char e[ERRMAX];
  22. if(host == nil)
  23. host = getenv("venti");
  24. if(host == nil)
  25. host = "$venti";
  26. na = netmkaddr(host, 0, "venti");
  27. fd = dial(na, 0, 0, 0);
  28. if(fd < 0){
  29. rerrstr(e, sizeof e);
  30. if(!canfail){
  31. vtSetError("%s", e);
  32. return nil;
  33. }
  34. }
  35. z = vtClientAlloc();
  36. if(fd < 0)
  37. strcpy(z->fderror, e);
  38. vtSetFd(z, fd);
  39. return z;
  40. }
  41. int
  42. vtRedial(VtSession *z, char *host)
  43. {
  44. int fd;
  45. char *na;
  46. if(host == nil)
  47. host = getenv("venti");
  48. if(host == nil)
  49. host = "$venti";
  50. na = netmkaddr(host, 0, "venti");
  51. fd = dial(na, 0, 0, 0);
  52. if(fd < 0){
  53. vtOSError();
  54. return 0;
  55. }
  56. vtReset(z);
  57. vtSetFd(z, fd);
  58. return 1;
  59. }
  60. VtSession *
  61. vtStdioServer(char *server)
  62. {
  63. int pfd[2];
  64. VtSession *z;
  65. if(server == nil)
  66. return nil;
  67. if(access(server, AEXEC) < 0) {
  68. vtOSError();
  69. return nil;
  70. }
  71. if(pipe(pfd) < 0) {
  72. vtOSError();
  73. return nil;
  74. }
  75. switch(fork()) {
  76. case -1:
  77. close(pfd[0]);
  78. close(pfd[1]);
  79. vtOSError();
  80. return nil;
  81. case 0:
  82. close(pfd[0]);
  83. dup(pfd[1], 0);
  84. dup(pfd[1], 1);
  85. execl(server, "ventiserver", "-i", nil);
  86. exits("exec failed");
  87. }
  88. close(pfd[1]);
  89. z = vtClientAlloc();
  90. vtSetFd(z, pfd[0]);
  91. return z;
  92. }
  93. int
  94. vtPing(VtSession *z)
  95. {
  96. Packet *p = packetAlloc();
  97. p = vtRPC(z, VtQPing, p);
  98. if(p == nil)
  99. return 0;
  100. packetFree(p);
  101. return 1;
  102. }
  103. int
  104. vtHello(VtSession *z)
  105. {
  106. Packet *p;
  107. uchar buf[10];
  108. char *sid;
  109. int crypto, codec;
  110. sid = nil;
  111. p = packetAlloc();
  112. if(!vtAddString(p, vtGetVersion(z)))
  113. goto Err;
  114. if(!vtAddString(p, vtGetUid(z)))
  115. goto Err;
  116. buf[0] = vtGetCryptoStrength(z);
  117. buf[1] = 0;
  118. buf[2] = 0;
  119. packetAppend(p, buf, 3);
  120. p = vtRPC(z, VtQHello, p);
  121. if(p == nil)
  122. return 0;
  123. if(!vtGetString(p, &sid))
  124. goto Err;
  125. if(!packetConsume(p, buf, 2))
  126. goto Err;
  127. if(packetSize(p) != 0) {
  128. vtSetError(EProtocolBotch);
  129. goto Err;
  130. }
  131. crypto = buf[0];
  132. codec = buf[1];
  133. USED(crypto);
  134. USED(codec);
  135. packetFree(p);
  136. vtLock(z->lk);
  137. z->sid = sid;
  138. z->auth.state = VtAuthOK;
  139. vtSha1Free(z->inHash);
  140. z->inHash = nil;
  141. vtSha1Free(z->outHash);
  142. z->outHash = nil;
  143. vtUnlock(z->lk);
  144. return 1;
  145. Err:
  146. packetFree(p);
  147. vtMemFree(sid);
  148. return 0;
  149. }
  150. int
  151. vtSync(VtSession *z)
  152. {
  153. Packet *p = packetAlloc();
  154. p = vtRPC(z, VtQSync, p);
  155. if(p == nil)
  156. return 0;
  157. if(packetSize(p) != 0){
  158. vtSetError(EProtocolBotch);
  159. goto Err;
  160. }
  161. packetFree(p);
  162. return 1;
  163. Err:
  164. packetFree(p);
  165. return 0;
  166. }
  167. int
  168. vtWrite(VtSession *z, uchar score[VtScoreSize], int type, uchar *buf, int n)
  169. {
  170. Packet *p = packetAlloc();
  171. packetAppend(p, buf, n);
  172. return vtWritePacket(z, score, type, p);
  173. }
  174. int
  175. vtWritePacket(VtSession *z, uchar score[VtScoreSize], int type, Packet *p)
  176. {
  177. int n = packetSize(p);
  178. uchar *hdr;
  179. if(n > VtMaxLumpSize || n < 0) {
  180. vtSetError(ELumpSize);
  181. goto Err;
  182. }
  183. if(n == 0) {
  184. memmove(score, vtZeroScore, VtScoreSize);
  185. return 1;
  186. }
  187. hdr = packetHeader(p, 4);
  188. hdr[0] = type;
  189. hdr[1] = 0; /* pad */
  190. hdr[2] = 0; /* pad */
  191. hdr[3] = 0; /* pad */
  192. p = vtRPC(z, VtQWrite, p);
  193. if(p == nil)
  194. return 0;
  195. if(!packetConsume(p, score, VtScoreSize))
  196. goto Err;
  197. if(packetSize(p) != 0) {
  198. vtSetError(EProtocolBotch);
  199. goto Err;
  200. }
  201. packetFree(p);
  202. return 1;
  203. Err:
  204. packetFree(p);
  205. return 0;
  206. }
  207. int
  208. vtRead(VtSession *z, uchar score[VtScoreSize], int type, uchar *buf, int n)
  209. {
  210. Packet *p;
  211. p = vtReadPacket(z, score, type, n);
  212. if(p == nil)
  213. return -1;
  214. n = packetSize(p);
  215. packetCopy(p, buf, 0, n);
  216. packetFree(p);
  217. return n;
  218. }
  219. Packet *
  220. vtReadPacket(VtSession *z, uchar score[VtScoreSize], int type, int n)
  221. {
  222. Packet *p;
  223. uchar buf[10];
  224. if(n < 0 || n > VtMaxLumpSize) {
  225. vtSetError(ELumpSize);
  226. return nil;
  227. }
  228. p = packetAlloc();
  229. if(memcmp(score, vtZeroScore, VtScoreSize) == 0)
  230. return p;
  231. packetAppend(p, score, VtScoreSize);
  232. buf[0] = type;
  233. buf[1] = 0; /* pad */
  234. buf[2] = n >> 8;
  235. buf[3] = n;
  236. packetAppend(p, buf, 4);
  237. return vtRPC(z, VtQRead, p);
  238. }
  239. static Packet *
  240. vtRPC(VtSession *z, int op, Packet *p)
  241. {
  242. uchar *hdr, buf[2];
  243. char *err;
  244. if(z == nil){
  245. vtSetError(ENotConnected);
  246. return nil;
  247. }
  248. /*
  249. * single threaded for the momment
  250. */
  251. vtLock(z->lk);
  252. if(z->cstate != VtStateConnected){
  253. vtSetError(ENotConnected);
  254. goto Err;
  255. }
  256. hdr = packetHeader(p, 2);
  257. hdr[0] = op; /* op */
  258. hdr[1] = 0; /* tid */
  259. vtDebug(z, "client send: ");
  260. vtDebugMesg(z, p, "\n");
  261. if(!vtSendPacket(z, p)) {
  262. p = nil;
  263. goto Err;
  264. }
  265. p = vtRecvPacket(z);
  266. if(p == nil)
  267. goto Err;
  268. vtDebug(z, "client recv: ");
  269. vtDebugMesg(z, p, "\n");
  270. if(!packetConsume(p, buf, 2))
  271. goto Err;
  272. if(buf[0] == VtRError) {
  273. if(!vtGetString(p, &err)) {
  274. vtSetError(EProtocolBotch);
  275. goto Err;
  276. }
  277. vtSetError(err);
  278. vtMemFree(err);
  279. packetFree(p);
  280. vtUnlock(z->lk);
  281. return nil;
  282. }
  283. if(buf[0] != op+1 || buf[1] != 0) {
  284. vtSetError(EProtocolBotch);
  285. goto Err;
  286. }
  287. vtUnlock(z->lk);
  288. return p;
  289. Err:
  290. vtDebug(z, "vtRPC failed: %s\n", vtGetError());
  291. if(p != nil)
  292. packetFree(p);
  293. vtUnlock(z->lk);
  294. vtDisconnect(z, 1);
  295. return nil;
  296. }