server.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <oventi.h>
  4. #include "session.h"
  5. static char EAuthState[] = "bad authentication state";
  6. static char ENotServer[] = "not a server session";
  7. static char EVersion[] = "incorrect version number";
  8. static char EProtocolBotch[] = "venti protocol botch";
  9. VtSession *
  10. vtServerAlloc(VtServerVtbl *vtbl)
  11. {
  12. VtSession *z = vtAlloc();
  13. z->vtbl = vtMemAlloc(sizeof(VtServerVtbl));
  14. setmalloctag(z->vtbl, getcallerpc(&vtbl));
  15. *z->vtbl = *vtbl;
  16. return z;
  17. }
  18. static int
  19. srvHello(VtSession *z, char *version, char *uid, int , uchar *, int , uchar *, int )
  20. {
  21. vtLock(z->lk);
  22. if(z->auth.state != VtAuthHello) {
  23. vtSetError(EAuthState);
  24. goto Err;
  25. }
  26. if(strcmp(version, vtGetVersion(z)) != 0) {
  27. vtSetError(EVersion);
  28. goto Err;
  29. }
  30. vtMemFree(z->uid);
  31. z->uid = vtStrDup(uid);
  32. z->auth.state = VtAuthOK;
  33. vtUnlock(z->lk);
  34. return 1;
  35. Err:
  36. z->auth.state = VtAuthFailed;
  37. vtUnlock(z->lk);
  38. return 0;
  39. }
  40. static int
  41. dispatchHello(VtSession *z, Packet **pkt)
  42. {
  43. char *version, *uid;
  44. uchar *crypto, *codec;
  45. uchar buf[10];
  46. int ncrypto, ncodec, cryptoStrength;
  47. int ret;
  48. Packet *p;
  49. p = *pkt;
  50. version = nil;
  51. uid = nil;
  52. crypto = nil;
  53. codec = nil;
  54. ret = 0;
  55. if(!vtGetString(p, &version))
  56. goto Err;
  57. if(!vtGetString(p, &uid))
  58. goto Err;
  59. if(!packetConsume(p, buf, 2))
  60. goto Err;
  61. cryptoStrength = buf[0];
  62. ncrypto = buf[1];
  63. crypto = vtMemAlloc(ncrypto);
  64. if(!packetConsume(p, crypto, ncrypto))
  65. goto Err;
  66. if(!packetConsume(p, buf, 1))
  67. goto Err;
  68. ncodec = buf[0];
  69. codec = vtMemAlloc(ncodec);
  70. if(!packetConsume(p, codec, ncodec))
  71. goto Err;
  72. if(packetSize(p) != 0) {
  73. vtSetError(EProtocolBotch);
  74. goto Err;
  75. }
  76. if(!srvHello(z, version, uid, cryptoStrength, crypto, ncrypto, codec, ncodec)) {
  77. packetFree(p);
  78. *pkt = nil;
  79. } else {
  80. if(!vtAddString(p, vtGetSid(z)))
  81. goto Err;
  82. buf[0] = vtGetCrypto(z);
  83. buf[1] = vtGetCodec(z);
  84. packetAppend(p, buf, 2);
  85. }
  86. ret = 1;
  87. Err:
  88. vtMemFree(version);
  89. vtMemFree(uid);
  90. vtMemFree(crypto);
  91. vtMemFree(codec);
  92. return ret;
  93. }
  94. static int
  95. dispatchRead(VtSession *z, Packet **pkt)
  96. {
  97. Packet *p;
  98. int type, n;
  99. uchar score[VtScoreSize], buf[4];
  100. p = *pkt;
  101. if(!packetConsume(p, score, VtScoreSize))
  102. return 0;
  103. if(!packetConsume(p, buf, 4))
  104. return 0;
  105. type = buf[0];
  106. n = (buf[2]<<8) | buf[3];
  107. if(packetSize(p) != 0) {
  108. vtSetError(EProtocolBotch);
  109. return 0;
  110. }
  111. packetFree(p);
  112. *pkt = (*z->vtbl->read)(z, score, type, n);
  113. return 1;
  114. }
  115. static int
  116. dispatchWrite(VtSession *z, Packet **pkt)
  117. {
  118. Packet *p;
  119. int type;
  120. uchar score[VtScoreSize], buf[4];
  121. p = *pkt;
  122. if(!packetConsume(p, buf, 4))
  123. return 0;
  124. type = buf[0];
  125. if(!(z->vtbl->write)(z, score, type, p)) {
  126. *pkt = 0;
  127. } else {
  128. *pkt = packetAlloc();
  129. packetAppend(*pkt, score, VtScoreSize);
  130. }
  131. return 1;
  132. }
  133. static int
  134. dispatchSync(VtSession *z, Packet **pkt)
  135. {
  136. (z->vtbl->sync)(z);
  137. if(packetSize(*pkt) != 0) {
  138. vtSetError(EProtocolBotch);
  139. return 0;
  140. }
  141. return 1;
  142. }
  143. int
  144. vtExport(VtSession *z)
  145. {
  146. Packet *p;
  147. uchar buf[10], *hdr;
  148. int op, tid, clean;
  149. if(z->vtbl == nil) {
  150. vtSetError(ENotServer);
  151. return 0;
  152. }
  153. /* fork off slave */
  154. switch(rfork(RFNOWAIT|RFMEM|RFPROC)){
  155. case -1:
  156. vtOSError();
  157. return 0;
  158. case 0:
  159. break;
  160. default:
  161. return 1;
  162. }
  163. p = nil;
  164. clean = 0;
  165. vtAttach();
  166. if(!vtConnect(z, nil))
  167. goto Exit;
  168. vtDebug(z, "server connected!\n");
  169. if(0) vtSetDebug(z, 1);
  170. for(;;) {
  171. p = vtRecvPacket(z);
  172. if(p == nil) {
  173. break;
  174. }
  175. vtDebug(z, "server recv: ");
  176. vtDebugMesg(z, p, "\n");
  177. if(!packetConsume(p, buf, 2)) {
  178. vtSetError(EProtocolBotch);
  179. break;
  180. }
  181. op = buf[0];
  182. tid = buf[1];
  183. switch(op) {
  184. default:
  185. vtSetError(EProtocolBotch);
  186. goto Exit;
  187. case VtQPing:
  188. break;
  189. case VtQGoodbye:
  190. clean = 1;
  191. goto Exit;
  192. case VtQHello:
  193. if(!dispatchHello(z, &p))
  194. goto Exit;
  195. break;
  196. case VtQRead:
  197. if(!dispatchRead(z, &p))
  198. goto Exit;
  199. break;
  200. case VtQWrite:
  201. if(!dispatchWrite(z, &p))
  202. goto Exit;
  203. break;
  204. case VtQSync:
  205. if(!dispatchSync(z, &p))
  206. goto Exit;
  207. break;
  208. }
  209. if(p != nil) {
  210. hdr = packetHeader(p, 2);
  211. hdr[0] = op+1;
  212. hdr[1] = tid;
  213. } else {
  214. p = packetAlloc();
  215. hdr = packetHeader(p, 2);
  216. hdr[0] = VtRError;
  217. hdr[1] = tid;
  218. if(!vtAddString(p, vtGetError()))
  219. goto Exit;
  220. }
  221. vtDebug(z, "server send: ");
  222. vtDebugMesg(z, p, "\n");
  223. if(!vtSendPacket(z, p)) {
  224. p = nil;
  225. goto Exit;
  226. }
  227. }
  228. Exit:
  229. if(p != nil)
  230. packetFree(p);
  231. if(z->vtbl->closing)
  232. z->vtbl->closing(z, clean);
  233. vtClose(z);
  234. vtFree(z);
  235. vtDetach();
  236. exits(0);
  237. return 0; /* never gets here */
  238. }