command.c 11 KB

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