client.c 5.4 KB

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