command.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  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. }
  22. }
  23. void command_process_create_cell(cell_t *cell, connection_t *conn) {
  24. circuit_t *circ;
  25. connection_t *n_conn;
  26. unsigned char *cellbuf; /* array of cells */
  27. int cellbuflen; /* size of cellbuf in bytes */
  28. cell_t *tmpcell; /* pointer to an arbitrary cell */
  29. int retval, i;
  30. circ = circuit_get_by_aci_conn(cell->aci, conn);
  31. if(circ && circ->state != CIRCUIT_STATE_OPEN_WAIT) {
  32. log(LOG_DEBUG,"command_process_create_cell(): received CREATE cell, not in open_wait. Dropping.");
  33. return;
  34. }
  35. if(!circ) { /* if it's not there, create it */
  36. circ = circuit_new(cell->aci, conn);
  37. circ->state = CIRCUIT_STATE_OPEN_WAIT;
  38. circ->onionlen = ntohl(*(int*)cell->payload);
  39. log(LOG_DEBUG,"command_process_create_cell(): Onion length is %u.",circ->onionlen);
  40. if(circ->onionlen > 50000 || circ->onionlen < 1) { /* too big or too small */
  41. log(LOG_DEBUG,"That's ludicrous. Closing.");
  42. circuit_close(circ);
  43. return;
  44. }
  45. circ->onion = (unsigned char *)malloc(circ->onionlen);
  46. if(!circ->onion) {
  47. log(LOG_DEBUG,"command_process_create_cell(): Out of memory. Closing.");
  48. circuit_close(circ);
  49. return;
  50. }
  51. if(circ->onionlen < cell->length-4) { /* protect from buffer overflow */
  52. log(LOG_DEBUG,"command_process_create_cell(): Onion too small. Closing.");
  53. circuit_close(circ);
  54. return;
  55. }
  56. memcpy((void *)circ->onion,(void *)(cell->payload+4),cell->length-4);
  57. circ->recvlen = cell->length-4;
  58. log(LOG_DEBUG,"command_process_create_cell(): Primary create cell handled, have received %d of %d onion bytes.",
  59. circ->recvlen,circ->onionlen);
  60. } else { /* pull over as much of the onion as we can */
  61. if(cell->length + circ->recvlen > circ->onionlen) { /* protect from buffer overflow */
  62. log(LOG_DEBUG,"command_process_create_cell(): payload too big for onion. Closing.");
  63. circuit_close(circ);
  64. return;
  65. }
  66. memcpy((void *)(circ->onion+circ->recvlen),(void *)cell->payload,cell->length);
  67. circ->recvlen += cell->length;
  68. log(LOG_DEBUG,"command_process_create_cell(): Secondary create cell handled, have received %d of %d onion bytes.",
  69. circ->recvlen,circ->onionlen);
  70. }
  71. if(circ->recvlen != circ->onionlen) {
  72. log(LOG_DEBUG,"command_process_create_cell(): Onion not all here yet. Ok.");
  73. return;
  74. }
  75. /* we're all ready to go now. */
  76. circ->state = CIRCUIT_STATE_OPEN;
  77. if(process_onion(circ, conn) < 0) {
  78. log(LOG_DEBUG,"command_process_create_cell(): Onion processing failed. Closing.");
  79. circuit_close(circ);
  80. return;
  81. }
  82. if(circ->n_addr && circ->n_port) { /* must send create cells to the next router */
  83. n_conn = connection_twin_get_by_addr_port(circ->n_addr,circ->n_port);
  84. if(!n_conn || n_conn->type != CONN_TYPE_OR) {
  85. /* i've disabled making connections through OPs, but it's definitely
  86. * possible here. I'm not sure if it would be a bug or a feature. -RD
  87. */
  88. /* note also that this will close circuits where the onion has the same
  89. * router twice in a row in the path. i think that's ok. -RD
  90. */
  91. log(LOG_DEBUG,"command_process_create_cell(): Next router not connected. Closing.");
  92. circuit_close(circ);
  93. return;
  94. }
  95. circ->n_conn = n_conn;
  96. log(LOG_DEBUG,"command_process_create_cell(): n_conn is %s:%u",n_conn->address,ntohs(n_conn->port));
  97. /* send the CREATE cells on to the next hop */
  98. pad_onion(circ->onion,circ->onionlen, sizeof(onion_layer_t));
  99. log(LOG_DEBUG,"command_process_create_cell(): Padded the onion with random data.");
  100. retval = pack_create(circ->n_aci, circ->onion, circ->onionlen, &cellbuf, &cellbuflen);
  101. free((void *)circ->onion);
  102. circ->onion = NULL;
  103. if (retval == -1) /* pack_create() error */
  104. {
  105. log(LOG_DEBUG,"command_process_create_cell(): Could not pack the onion into CREATE cells. Closing the connection.");
  106. circuit_close(circ);
  107. return;
  108. }
  109. log(LOG_DEBUG,"command_process_create_cell(): Onion packed into CREATE cells. Buffering the cells.");
  110. /* queue the create cells for transmission to the next hop */
  111. tmpcell = (cell_t *)cellbuf;
  112. for (i=0;i<cellbuflen/sizeof(cell_t);i++)
  113. {
  114. retval = connection_write_cell_to_buf(tmpcell, n_conn);
  115. if (retval == -1) /* buffering failed, drop the connection */
  116. {
  117. log(LOG_DEBUG,"command_process_create_cell(): Could not buffer new create cells. Closing.");
  118. circuit_close(circ);
  119. return;
  120. }
  121. tmpcell++;
  122. }
  123. free((void *)cellbuf);
  124. return;
  125. } else { /* this is destined for an exit */
  126. log(LOG_DEBUG,"command_process_create_cell(): Creating new exit connection.");
  127. n_conn = connection_new(CONN_TYPE_EXIT);
  128. if(!n_conn) {
  129. log(LOG_DEBUG,"command_process_create_cell(): connection_new failed. Closing.");
  130. circuit_close(circ);
  131. return;
  132. }
  133. n_conn->state = EXIT_CONN_STATE_CONNECTING_WAIT;
  134. n_conn->s = -1; /* not yet valid */
  135. if(connection_add(n_conn) < 0) { /* no space, forget it */
  136. log(LOG_DEBUG,"command_process_create_cell(): connection_add failed. Closing.");
  137. connection_free(n_conn);
  138. circuit_close(circ);
  139. return;
  140. }
  141. circ->n_conn = n_conn;
  142. return;
  143. }
  144. }
  145. void command_process_data_cell(cell_t *cell, connection_t *conn) {
  146. circuit_t *circ;
  147. /* FIXME do something with 'close' state, here */
  148. circ = circuit_get_by_aci_conn(cell->aci, conn);
  149. if(!circ) {
  150. log(LOG_DEBUG,"command_process_data_cell(): received DATA cell for unknown circuit. Dropping.");
  151. return;
  152. }
  153. if(circ->state == CIRCUIT_STATE_OPEN_WAIT) {
  154. log(LOG_DEBUG,"command_process_data_cell(): circuit in open_wait. Dropping data cell.");
  155. return;
  156. }
  157. if(circ->state == CIRCUIT_STATE_OR_WAIT) {
  158. log(LOG_DEBUG,"command_process_data_cell(): circuit in or_wait. Dropping data cell.");
  159. return;
  160. }
  161. /* at this point both circ->n_conn and circ->p_conn are guaranteed to be set */
  162. if(cell->aci == circ->p_aci) { /* it's an outgoing cell */
  163. cell->aci = circ->n_aci; /* switch it */
  164. if(circuit_deliver_data_cell(cell, circ, circ->n_conn, 'd') < 0) {
  165. log(LOG_DEBUG,"command_process_data_cell(): circuit_deliver_data_cell (forward) failed. Closing.");
  166. circuit_close(circ);
  167. return;
  168. }
  169. } else { /* it's an ingoing cell */
  170. cell->aci = circ->p_aci; /* switch it */
  171. if(circ->p_conn->type == CONN_TYPE_AP) { /* we want to decrypt, not encrypt */
  172. if(circuit_deliver_data_cell(cell, circ, circ->p_conn, 'd') < 0) {
  173. log(LOG_DEBUG,"command_process_data_cell(): circuit_deliver_data_cell (backward to AP) failed. Closing.");
  174. circuit_close(circ);
  175. return;
  176. }
  177. } else {
  178. if(circuit_deliver_data_cell(cell, circ, circ->p_conn, 'e') < 0) {
  179. log(LOG_DEBUG,"command_process_data_cell(): circuit_deliver_data_cell (backward) failed. Closing.");
  180. circuit_close(circ);
  181. return;
  182. }
  183. }
  184. }
  185. }
  186. void command_process_destroy_cell(cell_t *cell, connection_t *conn) {
  187. circuit_t *circ;
  188. circ = circuit_get_by_aci_conn(cell->aci, conn);
  189. if(!circ) {
  190. log(LOG_DEBUG,"command_process_destroy_cell(): received DESTROY cell for unknown circuit. Dropping.");
  191. return;
  192. }
  193. log(LOG_DEBUG,"command_process_destroy_cell(): Received for aci %d.",cell->aci);
  194. circuit_remove(circ);
  195. if(cell->aci == circ->p_aci) /* the destroy came from behind */
  196. connection_send_destroy(circ->n_aci, circ->n_conn);
  197. if(cell->aci == circ->n_aci) /* the destroy came from ahead */
  198. connection_send_destroy(circ->p_aci, circ->p_conn);
  199. circuit_free(circ);
  200. }