client.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  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 <venti.h>
  12. int ventidoublechecksha1 = 1;
  13. static int
  14. vtfcallrpc(VtConn *z, VtFcall *ou, VtFcall *in)
  15. {
  16. Packet *p;
  17. p = vtfcallpack(ou);
  18. if(p == nil)
  19. return -1;
  20. if((p = _vtrpc(z, p, ou)) == nil)
  21. return -1;
  22. if(vtfcallunpack(in, p) < 0){
  23. packetfree(p);
  24. return -1;
  25. }
  26. if(chattyventi)
  27. fprint(2, "%s <- %F\n", argv0, in);
  28. if(in->msgtype == VtRerror){
  29. werrstr(in->error);
  30. vtfcallclear(in);
  31. packetfree(p);
  32. return -1;
  33. }
  34. if(in->msgtype != ou->msgtype+1){
  35. werrstr("type mismatch: sent %c%d got %c%d",
  36. "TR"[ou->msgtype&1], ou->msgtype>>1,
  37. "TR"[in->msgtype&1], in->msgtype>>1);
  38. vtfcallclear(in);
  39. packetfree(p);
  40. return -1;
  41. }
  42. packetfree(p);
  43. return 0;
  44. }
  45. int
  46. vthello(VtConn *z)
  47. {
  48. VtFcall tx, rx;
  49. memset(&tx, 0, sizeof tx);
  50. tx.msgtype = VtThello;
  51. tx.version = z->version;
  52. tx.uid = z->uid;
  53. if(tx.uid == nil)
  54. tx.uid = "anonymous";
  55. if(vtfcallrpc(z, &tx, &rx) < 0)
  56. return -1;
  57. z->sid = rx.sid;
  58. rx.sid = 0;
  59. vtfcallclear(&rx);
  60. return 0;
  61. }
  62. Packet*
  63. vtreadpacket(VtConn *z, uint8_t score[VtScoreSize], uint type, int n)
  64. {
  65. VtFcall tx, rx;
  66. if(memcmp(score, vtzeroscore, VtScoreSize) == 0)
  67. return packetalloc();
  68. memset(&tx, 0, sizeof tx);
  69. tx.msgtype = VtTread;
  70. tx.blocktype = type;
  71. tx.count = n;
  72. memmove(tx.score, score, VtScoreSize);
  73. if(vtfcallrpc(z, &tx, &rx) < 0)
  74. return nil;
  75. if(packetsize(rx.data) > n){
  76. werrstr("read returned too much data");
  77. packetfree(rx.data);
  78. return nil;
  79. }
  80. if(ventidoublechecksha1){
  81. packetsha1(rx.data, tx.score);
  82. if(memcmp(score, tx.score, VtScoreSize) != 0){
  83. werrstr("read asked for %V got %V", score, tx.score);
  84. packetfree(rx.data);
  85. return nil;
  86. }
  87. }
  88. return rx.data;
  89. }
  90. int
  91. vtread(VtConn *z, uint8_t score[VtScoreSize], uint type, uint8_t *buf,
  92. int n)
  93. {
  94. int nn;
  95. Packet *p;
  96. if((p = vtreadpacket(z, score, type, n)) == nil)
  97. return -1;
  98. nn = packetsize(p);
  99. if(packetconsume(p, buf, nn) < 0)
  100. abort();
  101. packetfree(p);
  102. return nn;
  103. }
  104. int
  105. vtwritepacket(VtConn *z, uint8_t score[VtScoreSize], uint type, Packet *p)
  106. {
  107. VtFcall tx, rx;
  108. if(packetsize(p) == 0){
  109. memmove(score, vtzeroscore, VtScoreSize);
  110. return 0;
  111. }
  112. tx.msgtype = VtTwrite;
  113. tx.blocktype = type;
  114. tx.data = p;
  115. if(ventidoublechecksha1)
  116. packetsha1(p, score);
  117. if(vtfcallrpc(z, &tx, &rx) < 0)
  118. return -1;
  119. if(ventidoublechecksha1){
  120. if(memcmp(score, rx.score, VtScoreSize) != 0){
  121. werrstr("sha1 hash mismatch: want %V got %V", score, rx.score);
  122. return -1;
  123. }
  124. }else
  125. memmove(score, rx.score, VtScoreSize);
  126. return 0;
  127. }
  128. int
  129. vtwrite(VtConn *z, uint8_t score[VtScoreSize], uint type, uint8_t *buf,
  130. int n)
  131. {
  132. Packet *p;
  133. int nn;
  134. p = packetforeign(buf, n, 0, nil);
  135. nn = vtwritepacket(z, score, type, p);
  136. packetfree(p);
  137. return nn;
  138. }
  139. int
  140. vtsync(VtConn *z)
  141. {
  142. VtFcall tx, rx;
  143. tx.msgtype = VtTsync;
  144. return vtfcallrpc(z, &tx, &rx);
  145. }
  146. int
  147. vtping(VtConn *z)
  148. {
  149. VtFcall tx, rx;
  150. tx.msgtype = VtTping;
  151. return vtfcallrpc(z, &tx, &rx);
  152. }
  153. int
  154. vtconnect(VtConn *z)
  155. {
  156. if(vtversion(z) < 0)
  157. return -1;
  158. if(vthello(z) < 0)
  159. return -1;
  160. return 0;
  161. }
  162. int
  163. vtgoodbye(VtConn *z)
  164. {
  165. VtFcall tx, rx;
  166. tx.msgtype = VtTgoodbye;
  167. vtfcallrpc(z, &tx, &rx); /* always fails: no VtRgoodbye */
  168. return 0;
  169. }