client.c 5.8 KB

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