command.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. /* Copyright 2001,2002 Roger Dingledine, Matej Pfajfar. */
  2. /* See LICENSE for licensing information */
  3. /* $Id$ */
  4. #include "or.h"
  5. void command_process_cell(cell_t *cell, connection_t *conn) {
  6. if(check_sane_cell(cell) < 0)
  7. return;
  8. switch(cell->command) {
  9. case CELL_PADDING:
  10. /* do nothing */
  11. break;
  12. case CELL_CREATE:
  13. command_process_create_cell(cell, conn);
  14. break;
  15. case CELL_DATA:
  16. command_process_data_cell(cell, conn);
  17. break;
  18. case CELL_DESTROY:
  19. command_process_destroy_cell(cell, conn);
  20. break;
  21. case CELL_SENDME:
  22. command_process_sendme_cell(cell, conn);
  23. break;
  24. default:
  25. log(LOG_DEBUG,"Cell of unknown type (%d) received. Dropping.", cell->command);
  26. break;
  27. }
  28. }
  29. void command_process_create_cell(cell_t *cell, connection_t *conn) {
  30. circuit_t *circ;
  31. connection_t *n_conn;
  32. unsigned char *cellbuf; /* array of cells */
  33. int cellbuflen; /* size of cellbuf in bytes */
  34. cell_t *tmpcell; /* pointer to an arbitrary cell */
  35. int retval, i;
  36. circ = circuit_get_by_aci_conn(cell->aci, conn);
  37. if(circ && circ->state != CIRCUIT_STATE_OPEN_WAIT) {
  38. log(LOG_DEBUG,"command_process_create_cell(): received CREATE cell, not in open_wait. Dropping.");
  39. return;
  40. }
  41. if(!circ) { /* if it's not there, create it */
  42. circ = circuit_new(cell->aci, conn);
  43. circ->state = CIRCUIT_STATE_OPEN_WAIT;
  44. circ->onionlen = ntohl(*(int*)cell->payload);
  45. log(LOG_DEBUG,"command_process_create_cell(): Onion length is %u.",circ->onionlen);
  46. if(circ->onionlen > 50000 || circ->onionlen < 1) { /* too big or too small */
  47. log(LOG_DEBUG,"That's ludicrous. Closing.");
  48. circuit_close(circ);
  49. return;
  50. }
  51. circ->onion = (unsigned char *)malloc(circ->onionlen);
  52. if(!circ->onion) {
  53. log(LOG_DEBUG,"command_process_create_cell(): Out of memory. Closing.");
  54. circuit_close(circ);
  55. return;
  56. }
  57. if(circ->onionlen < cell->length-4) { /* protect from buffer overflow */
  58. log(LOG_DEBUG,"command_process_create_cell(): Onion too small. Closing.");
  59. circuit_close(circ);
  60. return;
  61. }
  62. memcpy((void *)circ->onion,(void *)(cell->payload+4),cell->length-4);
  63. circ->recvlen = cell->length-4;
  64. log(LOG_DEBUG,"command_process_create_cell(): Primary create cell handled, have received %d of %d onion bytes.",
  65. circ->recvlen,circ->onionlen);
  66. } else { /* pull over as much of the onion as we can */
  67. if(cell->length + circ->recvlen > circ->onionlen) { /* protect from buffer overflow */
  68. log(LOG_DEBUG,"command_process_create_cell(): payload too big for onion. Closing.");
  69. circuit_close(circ);
  70. return;
  71. }
  72. memcpy((void *)(circ->onion+circ->recvlen),(void *)cell->payload,cell->length);
  73. circ->recvlen += cell->length;
  74. log(LOG_DEBUG,"command_process_create_cell(): Secondary create cell handled, have received %d of %d onion bytes.",
  75. circ->recvlen,circ->onionlen);
  76. }
  77. if(circ->recvlen != circ->onionlen) {
  78. log(LOG_DEBUG,"command_process_create_cell(): Onion not all here yet. Ok.");
  79. return;
  80. }
  81. /* we're all ready to go now. */
  82. circ->state = CIRCUIT_STATE_OPEN;
  83. if(process_onion(circ, conn) < 0) {
  84. log(LOG_DEBUG,"command_process_create_cell(): Onion processing failed. Closing.");
  85. circuit_close(circ);
  86. return;
  87. }
  88. if(circ->n_addr && circ->n_port) { /* must send create cells to the next router */
  89. n_conn = connection_twin_get_by_addr_port(circ->n_addr,circ->n_port);
  90. if(!n_conn || n_conn->type != CONN_TYPE_OR) {
  91. /* i've disabled making connections through OPs, but it's definitely
  92. * possible here. I'm not sure if it would be a bug or a feature. -RD
  93. */
  94. /* note also that this will close circuits where the onion has the same
  95. * router twice in a row in the path. i think that's ok. -RD
  96. */
  97. log(LOG_DEBUG,"command_process_create_cell(): Next router not connected. Closing.");
  98. circuit_close(circ);
  99. return;
  100. }
  101. circ->n_addr = n_conn->addr; /* these are different if we found a twin instead */
  102. circ->n_port = n_conn->port;
  103. circ->n_conn = n_conn;
  104. log(LOG_DEBUG,"command_process_create_cell(): n_conn is %s:%u",n_conn->address,ntohs(n_conn->port));
  105. /* send the CREATE cells on to the next hop */
  106. pad_onion(circ->onion,circ->onionlen, sizeof(onion_layer_t));
  107. log(LOG_DEBUG,"command_process_create_cell(): Padded the onion with random data.");
  108. retval = pack_create(circ->n_aci, circ->onion, circ->onionlen, &cellbuf, &cellbuflen);
  109. free((void *)circ->onion);
  110. circ->onion = NULL;
  111. if (retval == -1) /* pack_create() error */
  112. {
  113. log(LOG_DEBUG,"command_process_create_cell(): Could not pack the onion into CREATE cells. Closing the connection.");
  114. circuit_close(circ);
  115. return;
  116. }
  117. log(LOG_DEBUG,"command_process_create_cell(): Onion packed into CREATE cells. Buffering the cells.");
  118. /* queue the create cells for transmission to the next hop */
  119. tmpcell = (cell_t *)cellbuf;
  120. for (i=0;i<cellbuflen/sizeof(cell_t);i++)
  121. {
  122. retval = connection_write_cell_to_buf(tmpcell, n_conn);
  123. if (retval == -1) /* buffering failed, drop the connection */
  124. {
  125. log(LOG_DEBUG,"command_process_create_cell(): Could not buffer new create cells. Closing.");
  126. circuit_close(circ);
  127. return;
  128. }
  129. tmpcell++;
  130. }
  131. free((void *)cellbuf);
  132. return;
  133. } else { /* this is destined for an exit */
  134. log(LOG_DEBUG,"command_process_create_cell(): Creating new exit connection.");
  135. n_conn = connection_new(CONN_TYPE_EXIT);
  136. if(!n_conn) {
  137. log(LOG_DEBUG,"command_process_create_cell(): connection_new failed. Closing.");
  138. circuit_close(circ);
  139. return;
  140. }
  141. n_conn->state = EXIT_CONN_STATE_CONNECTING_WAIT;
  142. n_conn->receiver_bucket = -1; /* edge connections don't do receiver buckets */
  143. n_conn->bandwidth = -1;
  144. n_conn->s = -1; /* not yet valid */
  145. if(connection_add(n_conn) < 0) { /* no space, forget it */
  146. log(LOG_DEBUG,"command_process_create_cell(): connection_add failed. Closing.");
  147. connection_free(n_conn);
  148. circuit_close(circ);
  149. return;
  150. }
  151. circ->n_conn = n_conn;
  152. return;
  153. }
  154. }
  155. void command_process_sendme_cell(cell_t *cell, connection_t *conn) {
  156. circuit_t *circ;
  157. circ = circuit_get_by_aci_conn(cell->aci, conn);
  158. if(!circ) {
  159. log(LOG_DEBUG,"command_process_sendme_cell(): unknown circuit %d. Dropping.", cell->aci);
  160. return;
  161. }
  162. if(circ->state == CIRCUIT_STATE_OPEN_WAIT) {
  163. log(LOG_DEBUG,"command_process_sendme_cell(): circuit in open_wait. Dropping.");
  164. return;
  165. }
  166. if(circ->state == CIRCUIT_STATE_OR_WAIT) {
  167. log(LOG_DEBUG,"command_process_sendme_cell(): circuit in or_wait. Dropping.");
  168. return;
  169. }
  170. /* at this point both circ->n_conn and circ->p_conn are guaranteed to be set */
  171. assert(cell->length == RECEIVE_WINDOW_INCREMENT);
  172. if(cell->aci == circ->p_aci) { /* it's an outgoing cell */
  173. circ->n_receive_window += cell->length;
  174. log(LOG_DEBUG,"connection_process_sendme_cell(): n_receive_window for aci %d is %d.",circ->n_aci,circ->n_receive_window);
  175. if(circ->n_conn->type == CONN_TYPE_EXIT) {
  176. connection_start_reading(circ->n_conn);
  177. connection_package_raw_inbuf(circ->n_conn); /* handle whatever might still be on the inbuf */
  178. } else {
  179. cell->aci = circ->n_aci; /* switch it */
  180. if(connection_write_cell_to_buf(cell, circ->n_conn) < 0) { /* (clobbers cell) */
  181. circuit_close(circ);
  182. return;
  183. }
  184. }
  185. } else { /* it's an ingoing cell */
  186. circ->p_receive_window += cell->length;
  187. log(LOG_DEBUG,"connection_process_sendme_cell(): p_receive_window for aci %d is %d.",circ->p_aci,circ->p_receive_window);
  188. if(circ->p_conn->type == CONN_TYPE_AP) {
  189. connection_start_reading(circ->p_conn);
  190. connection_package_raw_inbuf(circ->p_conn); /* handle whatever might still be on the inbuf */
  191. } else {
  192. cell->aci = circ->p_aci; /* switch it */
  193. if(connection_write_cell_to_buf(cell, circ->p_conn) < 0) { /* (clobbers cell) */
  194. circuit_close(circ);
  195. return;
  196. }
  197. }
  198. }
  199. }
  200. void command_process_data_cell(cell_t *cell, connection_t *conn) {
  201. circuit_t *circ;
  202. circ = circuit_get_by_aci_conn(cell->aci, conn);
  203. if(!circ) {
  204. log(LOG_DEBUG,"command_process_data_cell(): unknown circuit %d. Dropping.", cell->aci);
  205. return;
  206. }
  207. if(circ->state == CIRCUIT_STATE_OPEN_WAIT) {
  208. log(LOG_DEBUG,"command_process_data_cell(): circuit in open_wait. Dropping data cell.");
  209. return;
  210. }
  211. if(circ->state == CIRCUIT_STATE_OR_WAIT) {
  212. log(LOG_DEBUG,"command_process_data_cell(): circuit in or_wait. Dropping data cell.");
  213. return;
  214. }
  215. /* at this point both circ->n_conn and circ->p_conn are guaranteed to be set */
  216. if(cell->aci == circ->p_aci) { /* it's an outgoing cell */
  217. cell->aci = circ->n_aci; /* switch it */
  218. if(--circ->p_receive_window < 0) { /* is it less than 0 after decrement? */
  219. log(LOG_DEBUG,"connection_process_data_cell(): Too many data cells on aci %d. Closing.", circ->p_aci);
  220. circuit_close(circ);
  221. return;
  222. }
  223. log(LOG_DEBUG,"connection_process_data_cell(): p_receive_window for aci %d is %d.",circ->p_aci,circ->p_receive_window);
  224. if(circuit_deliver_data_cell(cell, circ, circ->n_conn, 'd') < 0) {
  225. log(LOG_DEBUG,"command_process_data_cell(): circuit_deliver_data_cell (forward) failed. Closing.");
  226. circuit_close(circ);
  227. return;
  228. }
  229. } else { /* it's an ingoing cell */
  230. cell->aci = circ->p_aci; /* switch it */
  231. if(--circ->n_receive_window < 0) { /* is it less than 0 after decrement? */
  232. log(LOG_DEBUG,"connection_process_data_cell(): Too many data cells on aci %d. Closing.", circ->n_aci);
  233. circuit_close(circ);
  234. return;
  235. }
  236. log(LOG_DEBUG,"connection_process_data_cell(): n_receive_window for aci %d is %d.",circ->n_aci,circ->n_receive_window);
  237. if(circ->p_conn->type == CONN_TYPE_AP) { /* we want to decrypt, not encrypt */
  238. if(circuit_deliver_data_cell(cell, circ, circ->p_conn, 'd') < 0) {
  239. log(LOG_DEBUG,"command_process_data_cell(): circuit_deliver_data_cell (backward to AP) failed. Closing.");
  240. circuit_close(circ);
  241. return;
  242. }
  243. } else {
  244. if(circuit_deliver_data_cell(cell, circ, circ->p_conn, 'e') < 0) {
  245. log(LOG_DEBUG,"command_process_data_cell(): circuit_deliver_data_cell (backward) failed. Closing.");
  246. circuit_close(circ);
  247. return;
  248. }
  249. }
  250. }
  251. }
  252. void command_process_destroy_cell(cell_t *cell, connection_t *conn) {
  253. circuit_t *circ;
  254. circ = circuit_get_by_aci_conn(cell->aci, conn);
  255. if(!circ) {
  256. log(LOG_DEBUG,"command_process_destroy_cell(): unknown circuit %d. Dropping.", cell->aci);
  257. return;
  258. }
  259. log(LOG_DEBUG,"command_process_destroy_cell(): Received for aci %d.",cell->aci);
  260. circuit_remove(circ);
  261. if(cell->aci == circ->p_aci) /* the destroy came from behind */
  262. connection_send_destroy(circ->n_aci, circ->n_conn);
  263. if(cell->aci == circ->n_aci) /* the destroy came from ahead */
  264. connection_send_destroy(circ->p_aci, circ->p_conn);
  265. circuit_free(circ);
  266. }