connection_edge.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930
  1. /* Copyright 2001,2002,2003 Roger Dingledine, Matej Pfajfar. */
  2. /* See LICENSE for licensing information */
  3. /* $Id$ */
  4. #include "or.h"
  5. #include "tree.h"
  6. extern or_options_t options; /* command-line and config-file options */
  7. static int connection_ap_handshake_process_socks(connection_t *conn);
  8. static int connection_ap_handshake_attach_circuit(connection_t *conn);
  9. static void connection_ap_handshake_send_begin(connection_t *ap_conn, circuit_t *circ);
  10. static int connection_ap_handshake_socks_reply(connection_t *conn, char *reply,
  11. int replylen, char success);
  12. static int connection_exit_begin_conn(cell_t *cell, circuit_t *circ);
  13. static void connection_edge_consider_sending_sendme(connection_t *conn);
  14. static uint32_t client_dns_lookup_entry(const char *address);
  15. static void client_dns_set_entry(const char *address, uint32_t val);
  16. int connection_edge_process_inbuf(connection_t *conn) {
  17. assert(conn);
  18. assert(conn->type == CONN_TYPE_AP || conn->type == CONN_TYPE_EXIT);
  19. if(conn->inbuf_reached_eof) {
  20. #ifdef HALF_OPEN
  21. /* eof reached; we're done reading, but we might want to write more. */
  22. conn->done_receiving = 1;
  23. shutdown(conn->s, 0); /* XXX check return, refactor NM */
  24. if (conn->done_sending) {
  25. connection_edge_end(conn, END_STREAM_REASON_DONE, conn->cpath_layer);
  26. } else {
  27. connection_edge_send_command(conn, circuit_get_by_conn(conn), RELAY_COMMAND_END,
  28. NULL, 0, conn->cpath_layer);
  29. }
  30. return 0;
  31. #else
  32. /* eof reached, kill it. */
  33. log_fn(LOG_INFO,"conn (fd %d) reached eof. Closing.", conn->s);
  34. connection_edge_end(conn, END_STREAM_REASON_DONE, conn->cpath_layer);
  35. return -1;
  36. #endif
  37. }
  38. switch(conn->state) {
  39. case AP_CONN_STATE_SOCKS_WAIT:
  40. if(connection_ap_handshake_process_socks(conn) < 0) {
  41. connection_edge_end(conn, END_STREAM_REASON_MISC, conn->cpath_layer);
  42. return -1;
  43. }
  44. return 0;
  45. case AP_CONN_STATE_OPEN:
  46. case EXIT_CONN_STATE_OPEN:
  47. if(connection_edge_package_raw_inbuf(conn) < 0) {
  48. connection_edge_end(conn, END_STREAM_REASON_MISC, conn->cpath_layer);
  49. return -1;
  50. }
  51. return 0;
  52. case EXIT_CONN_STATE_CONNECTING:
  53. log_fn(LOG_INFO,"text from server while in 'connecting' state at exit. Leaving it on buffer.");
  54. return 0;
  55. }
  56. return 0;
  57. }
  58. char *connection_edge_end_reason(char *payload, unsigned char length) {
  59. if(length < 1) {
  60. log_fn(LOG_WARN,"End cell arrived with length 0. Should be at least 1.");
  61. return "MALFORMED";
  62. }
  63. if(*payload < END_STREAM_REASON_MISC || *payload > END_STREAM_REASON_DONE) {
  64. log_fn(LOG_WARN,"Reason for ending (%d) not recognized.",*payload);
  65. return "MALFORMED";
  66. }
  67. switch(*payload) {
  68. case END_STREAM_REASON_MISC: return "misc error";
  69. case END_STREAM_REASON_RESOLVEFAILED: return "resolve failed";
  70. case END_STREAM_REASON_CONNECTFAILED: return "connect failed";
  71. case END_STREAM_REASON_EXITPOLICY: return "exit policy failed";
  72. case END_STREAM_REASON_DESTROY: return "destroyed";
  73. case END_STREAM_REASON_DONE: return "closed normally";
  74. }
  75. assert(0);
  76. return "";
  77. }
  78. void connection_edge_end(connection_t *conn, char reason, crypt_path_t *cpath_layer) {
  79. char payload[5];
  80. int payload_len=1;
  81. circuit_t *circ;
  82. if(conn->has_sent_end) {
  83. log_fn(LOG_WARN,"It appears I've already sent the end. Are you calling me twice?");
  84. return;
  85. }
  86. payload[0] = reason;
  87. if(reason == END_STREAM_REASON_EXITPOLICY) {
  88. *(uint32_t *)(payload+1) = htonl(conn->addr);
  89. payload_len += 4;
  90. }
  91. circ = circuit_get_by_conn(conn);
  92. if(circ) {
  93. log_fn(LOG_DEBUG,"Marking conn (fd %d) and sending end.",conn->s);
  94. connection_edge_send_command(conn, circ, RELAY_COMMAND_END,
  95. payload, payload_len, cpath_layer);
  96. }
  97. conn->marked_for_close = 1;
  98. conn->has_sent_end = 1;
  99. }
  100. int connection_edge_send_command(connection_t *fromconn, circuit_t *circ, int relay_command,
  101. void *payload, int payload_len, crypt_path_t *cpath_layer) {
  102. cell_t cell;
  103. int cell_direction;
  104. int is_control_cell=0;
  105. if(!circ) {
  106. log_fn(LOG_WARN,"no circ. Closing.");
  107. return 0;
  108. }
  109. if(!fromconn || relay_command == RELAY_COMMAND_BEGIN) /* XXX more */
  110. is_control_cell = 1;
  111. memset(&cell, 0, sizeof(cell_t));
  112. if(fromconn && fromconn->type == CONN_TYPE_AP) {
  113. cell.circ_id = circ->n_circ_id;
  114. cell_direction = CELL_DIRECTION_OUT;
  115. } else {
  116. /* NOTE: if !fromconn, we assume that it's heading towards the OP */
  117. cell.circ_id = circ->p_circ_id;
  118. cell_direction = CELL_DIRECTION_IN;
  119. }
  120. cell.command = CELL_RELAY;
  121. SET_CELL_RELAY_COMMAND(cell, relay_command);
  122. if(is_control_cell)
  123. SET_CELL_STREAM_ID(cell, ZERO_STREAM);
  124. else
  125. SET_CELL_STREAM_ID(cell, fromconn->stream_id);
  126. cell.length = RELAY_HEADER_SIZE + payload_len;
  127. if(payload_len) {
  128. memcpy(cell.payload+RELAY_HEADER_SIZE,payload,payload_len);
  129. }
  130. log_fn(LOG_DEBUG,"delivering %d cell %s.", relay_command,
  131. cell_direction == CELL_DIRECTION_OUT ? "forward" : "backward");
  132. if(circuit_deliver_relay_cell(&cell, circ, cell_direction, cpath_layer) < 0) {
  133. log_fn(LOG_WARN,"circuit_deliver_relay_cell failed. Closing.");
  134. circuit_close(circ);
  135. return -1;
  136. }
  137. return 0;
  138. }
  139. /* an incoming relay cell has arrived. return -1 if you want to tear down the
  140. * circuit, else 0. */
  141. int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, connection_t *conn,
  142. int edge_type, crypt_path_t *layer_hint) {
  143. int relay_command;
  144. static int num_seen=0;
  145. uint32_t addr;
  146. assert(cell && circ);
  147. relay_command = CELL_RELAY_COMMAND(*cell);
  148. // log_fn(LOG_DEBUG,"command %d stream %d", relay_command, stream_id);
  149. num_seen++;
  150. log_fn(LOG_DEBUG,"Now seen %d relay cells here.", num_seen);
  151. /* either conn is NULL, in which case we've got a control cell, or else
  152. * conn points to the recognized stream. */
  153. if(conn && conn->state != AP_CONN_STATE_OPEN && conn->state != EXIT_CONN_STATE_OPEN) {
  154. if(conn->type == CONN_TYPE_EXIT && relay_command == RELAY_COMMAND_END) {
  155. log_fn(LOG_INFO,"Exit got end (%s) before we're connected. Marking for close.",
  156. connection_edge_end_reason(cell->payload+RELAY_HEADER_SIZE, cell->length));
  157. if(conn->state == EXIT_CONN_STATE_RESOLVING) {
  158. log_fn(LOG_INFO,"...and informing resolver we don't want the answer anymore.");
  159. dns_cancel_pending_resolve(conn->address, conn);
  160. }
  161. conn->marked_for_close = 1;
  162. conn->has_sent_end = 1;
  163. return 0;
  164. } else {
  165. log_fn(LOG_WARN,"Got an unexpected relay cell, not in 'open' state. Closing.");
  166. connection_edge_end(conn, END_STREAM_REASON_MISC, conn->cpath_layer);
  167. return -1;
  168. }
  169. }
  170. switch(relay_command) {
  171. case RELAY_COMMAND_BEGIN:
  172. if(edge_type == EDGE_AP) {
  173. log_fn(LOG_WARN,"relay begin request unsupported at AP. Dropping.");
  174. return 0;
  175. }
  176. if(conn) {
  177. log_fn(LOG_WARN,"begin cell for known stream. Dropping.");
  178. return 0;
  179. }
  180. connection_exit_begin_conn(cell, circ);
  181. return 0;
  182. case RELAY_COMMAND_DATA:
  183. ++stats_n_data_cells_received;
  184. if((edge_type == EDGE_AP && --layer_hint->deliver_window < 0) ||
  185. (edge_type == EDGE_EXIT && --circ->deliver_window < 0)) {
  186. log_fn(LOG_WARN,"(relay data) circ deliver_window below 0. Killing.");
  187. connection_edge_end(conn, END_STREAM_REASON_MISC, conn->cpath_layer);
  188. return -1;
  189. }
  190. log_fn(LOG_DEBUG,"circ deliver_window now %d.", edge_type == EDGE_AP ? layer_hint->deliver_window : circ->deliver_window);
  191. if(circuit_consider_sending_sendme(circ, edge_type, layer_hint) < 0) {
  192. log_fn(LOG_WARN,"circuit_consider_sending_sendme() failed.");
  193. conn->has_sent_end = 1; /* we failed because conn is broken. can't send end. */
  194. return -1;
  195. }
  196. if(!conn) {
  197. log_fn(LOG_INFO,"relay cell dropped, unknown stream %d.",*(int*)conn->stream_id);
  198. return 0;
  199. }
  200. if(--conn->deliver_window < 0) { /* is it below 0 after decrement? */
  201. log_fn(LOG_WARN,"(relay data) conn deliver_window below 0. Killing.");
  202. return -1; /* somebody's breaking protocol. kill the whole circuit. */
  203. }
  204. // printf("New text for buf (%d bytes): '%s'", cell->length - RELAY_HEADER_SIZE, cell->payload + RELAY_HEADER_SIZE);
  205. stats_n_data_bytes_received += (cell->length - RELAY_HEADER_SIZE);
  206. connection_write_to_buf(cell->payload + RELAY_HEADER_SIZE,
  207. cell->length - RELAY_HEADER_SIZE, conn);
  208. connection_edge_consider_sending_sendme(conn);
  209. return 0;
  210. case RELAY_COMMAND_END:
  211. if(!conn) {
  212. log_fn(LOG_INFO,"end cell (%s) dropped, unknown stream %d.",
  213. connection_edge_end_reason(cell->payload+RELAY_HEADER_SIZE, cell->length),
  214. *(int*)conn->stream_id);
  215. return 0;
  216. }
  217. if(cell->length-RELAY_HEADER_SIZE >= 5 &&
  218. *(cell->payload+RELAY_HEADER_SIZE) == END_STREAM_REASON_EXITPOLICY) {
  219. /* No need to close the connection. We'll hold it open while
  220. * we try a new exit node.
  221. * cell->payload+RELAY_HEADER_SIZE+1 holds the destination addr.
  222. */
  223. addr = ntohl(*cell->payload+RELAY_HEADER_SIZE+1);
  224. client_dns_set_entry(conn->socks_request->address, addr);
  225. conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
  226. if(connection_ap_handshake_attach_circuit(conn) < 0)
  227. circuit_launch_new(); /* Build another circuit to handle this stream */
  228. return 0;
  229. }
  230. log_fn(LOG_INFO,"end cell (%s) for stream %d. Removing stream.",
  231. connection_edge_end_reason(cell->payload+RELAY_HEADER_SIZE, cell->length),
  232. *(int*)conn->stream_id);
  233. #ifdef HALF_OPEN
  234. conn->done_sending = 1;
  235. shutdown(conn->s, 1); /* XXX check return; refactor NM */
  236. if (conn->done_receiving) {
  237. conn->marked_for_close = 1;
  238. conn->has_sent_end = 1; /* no need to send end, we just got one! */
  239. }
  240. #else
  241. conn->marked_for_close = 1;
  242. conn->has_sent_end = 1; /* no need to send end, we just got one! */
  243. #endif
  244. return 0;
  245. case RELAY_COMMAND_EXTEND:
  246. if(conn) {
  247. log_fn(LOG_WARN,"'extend' for non-zero stream. Dropping.");
  248. return 0;
  249. }
  250. return circuit_extend(cell, circ);
  251. case RELAY_COMMAND_EXTENDED:
  252. if(edge_type == EDGE_EXIT) {
  253. log_fn(LOG_WARN,"'extended' unsupported at exit. Dropping.");
  254. return 0;
  255. }
  256. log_fn(LOG_DEBUG,"Got an extended cell! Yay.");
  257. if(circuit_finish_handshake(circ, cell->payload+RELAY_HEADER_SIZE) < 0) {
  258. log_fn(LOG_WARN,"circuit_finish_handshake failed.");
  259. return -1;
  260. }
  261. if (circuit_send_next_onion_skin(circ)<0) {
  262. log_fn(LOG_WARN,"circuit_send_next_onion_skin() failed.");
  263. return -1;
  264. }
  265. return 0;
  266. case RELAY_COMMAND_TRUNCATE:
  267. if(edge_type == EDGE_AP) {
  268. log_fn(LOG_WARN,"'truncate' unsupported at AP. Dropping.");
  269. return 0;
  270. }
  271. if(circ->n_conn) {
  272. connection_send_destroy(circ->n_circ_id, circ->n_conn);
  273. circ->n_conn = NULL;
  274. }
  275. log_fn(LOG_DEBUG, "Processed 'truncate', replying.");
  276. connection_edge_send_command(NULL, circ, RELAY_COMMAND_TRUNCATED,
  277. NULL, 0, NULL);
  278. return 0;
  279. case RELAY_COMMAND_TRUNCATED:
  280. if(edge_type == EDGE_EXIT) {
  281. log_fn(LOG_WARN,"'truncated' unsupported at exit. Dropping.");
  282. return 0;
  283. }
  284. circuit_truncated(circ, layer_hint);
  285. return 0;
  286. case RELAY_COMMAND_CONNECTED:
  287. if(edge_type == EDGE_EXIT) {
  288. log_fn(LOG_WARN,"'connected' unsupported at exit. Dropping.");
  289. return 0;
  290. }
  291. if(!conn) {
  292. log_fn(LOG_INFO,"connected cell dropped, unknown stream %d.",*(int*)conn->stream_id);
  293. return 0;
  294. }
  295. log_fn(LOG_INFO,"Connected! Notifying application.");
  296. if (cell->length-RELAY_HEADER_SIZE == 4) {
  297. addr = htonl(*(uint32_t*)(cell->payload + RELAY_HEADER_SIZE));
  298. client_dns_set_entry(conn->socks_request->address, addr);
  299. }
  300. if(connection_ap_handshake_socks_reply(conn, NULL, 0, 1) < 0) {
  301. log_fn(LOG_INFO,"Writing to socks-speaking application failed. Closing.");
  302. connection_edge_end(conn, END_STREAM_REASON_MISC, conn->cpath_layer);
  303. }
  304. return 0;
  305. case RELAY_COMMAND_SENDME:
  306. if(!conn) {
  307. if(edge_type == EDGE_AP) {
  308. assert(layer_hint);
  309. layer_hint->package_window += CIRCWINDOW_INCREMENT;
  310. log_fn(LOG_DEBUG,"circ-level sendme at AP, packagewindow %d.", layer_hint->package_window);
  311. circuit_resume_edge_reading(circ, EDGE_AP, layer_hint);
  312. } else {
  313. assert(!layer_hint);
  314. circ->package_window += CIRCWINDOW_INCREMENT;
  315. log_fn(LOG_DEBUG,"circ-level sendme at exit, packagewindow %d.", circ->package_window);
  316. circuit_resume_edge_reading(circ, EDGE_EXIT, layer_hint);
  317. }
  318. return 0;
  319. }
  320. conn->package_window += STREAMWINDOW_INCREMENT;
  321. log_fn(LOG_DEBUG,"stream-level sendme, packagewindow now %d.", conn->package_window);
  322. connection_start_reading(conn);
  323. connection_edge_package_raw_inbuf(conn); /* handle whatever might still be on the inbuf */
  324. return 0;
  325. default:
  326. log_fn(LOG_WARN,"unknown relay command %d.",relay_command);
  327. return -1;
  328. }
  329. assert(0);
  330. return -1;
  331. }
  332. int connection_edge_finished_flushing(connection_t *conn) {
  333. int e, len=sizeof(e);
  334. assert(conn);
  335. assert(conn->type == CONN_TYPE_AP || conn->type == CONN_TYPE_EXIT);
  336. switch(conn->state) {
  337. case EXIT_CONN_STATE_CONNECTING:
  338. if (getsockopt(conn->s, SOL_SOCKET, SO_ERROR, (void*)&e, &len) < 0) { /* not yet */
  339. if(!ERRNO_CONN_EINPROGRESS(errno)) {
  340. /* yuck. kill it. */
  341. log_fn(LOG_DEBUG,"in-progress exit connect failed. Removing.");
  342. return -1;
  343. } else {
  344. log_fn(LOG_DEBUG,"in-progress exit connect still waiting.");
  345. return 0; /* no change, see if next time is better */
  346. }
  347. }
  348. /* the connect has finished. */
  349. log_fn(LOG_INFO,"Exit connection to %s:%u established.",
  350. conn->address,conn->port);
  351. conn->state = EXIT_CONN_STATE_OPEN;
  352. connection_watch_events(conn, POLLIN); /* stop writing, continue reading */
  353. if(connection_wants_to_flush(conn)) /* in case there are any queued relay cells */
  354. connection_start_writing(conn);
  355. /* deliver a 'connected' relay cell back through the circuit. */
  356. if(connection_edge_send_command(conn, circuit_get_by_conn(conn),
  357. RELAY_COMMAND_CONNECTED, NULL, 0, conn->cpath_layer) < 0)
  358. return 0; /* circuit is closed, don't continue */
  359. return connection_process_inbuf(conn); /* in case the server has written anything */
  360. case AP_CONN_STATE_OPEN:
  361. case EXIT_CONN_STATE_OPEN:
  362. connection_stop_writing(conn);
  363. connection_edge_consider_sending_sendme(conn);
  364. return 0;
  365. case AP_CONN_STATE_SOCKS_WAIT:
  366. connection_stop_writing(conn);
  367. return 0;
  368. default:
  369. log_fn(LOG_WARN,"BUG: called in unexpected state: %d", conn->state);
  370. return -1;
  371. }
  372. return 0;
  373. }
  374. uint64_t stats_n_data_cells_packaged = 0;
  375. uint64_t stats_n_data_bytes_packaged = 0;
  376. uint64_t stats_n_data_cells_received = 0;
  377. uint64_t stats_n_data_bytes_received = 0;
  378. int connection_edge_package_raw_inbuf(connection_t *conn) {
  379. int amount_to_process, length;
  380. char payload[CELL_PAYLOAD_SIZE];
  381. circuit_t *circ;
  382. assert(conn);
  383. assert(!connection_speaks_cells(conn));
  384. repeat_connection_edge_package_raw_inbuf:
  385. circ = circuit_get_by_conn(conn);
  386. if(!circ) {
  387. log_fn(LOG_INFO,"conn has no circuits! Closing.");
  388. return -1;
  389. }
  390. if(circuit_consider_stop_edge_reading(circ, conn->type, conn->cpath_layer))
  391. return 0;
  392. if(conn->package_window <= 0) {
  393. log_fn(LOG_WARN,"called with package_window %d. Tell Roger.", conn->package_window);
  394. connection_stop_reading(conn);
  395. return 0;
  396. }
  397. amount_to_process = buf_datalen(conn->inbuf);
  398. if(!amount_to_process)
  399. return 0;
  400. if(amount_to_process > CELL_PAYLOAD_SIZE - RELAY_HEADER_SIZE) {
  401. length = CELL_PAYLOAD_SIZE - RELAY_HEADER_SIZE;
  402. } else {
  403. length = amount_to_process;
  404. }
  405. stats_n_data_bytes_packaged += length;
  406. stats_n_data_cells_packaged += 1;
  407. connection_fetch_from_buf(payload, length, conn);
  408. log_fn(LOG_DEBUG,"(%d) Packaging %d bytes (%d waiting).",conn->s,length,
  409. (int)buf_datalen(conn->inbuf));
  410. if(connection_edge_send_command(conn, circ, RELAY_COMMAND_DATA,
  411. payload, length, conn->cpath_layer) < 0)
  412. return 0; /* circuit is closed, don't continue */
  413. if(conn->type == CONN_TYPE_EXIT) {
  414. assert(circ->package_window > 0);
  415. circ->package_window--;
  416. } else { /* we're an AP */
  417. assert(conn->type == CONN_TYPE_AP);
  418. assert(conn->cpath_layer->package_window > 0);
  419. conn->cpath_layer->package_window--;
  420. }
  421. if(--conn->package_window <= 0) { /* is it 0 after decrement? */
  422. connection_stop_reading(conn);
  423. log_fn(LOG_DEBUG,"conn->package_window reached 0.");
  424. circuit_consider_stop_edge_reading(circ, conn->type, conn->cpath_layer);
  425. return 0; /* don't process the inbuf any more */
  426. }
  427. log_fn(LOG_DEBUG,"conn->package_window is now %d",conn->package_window);
  428. /* handle more if there's more, or return 0 if there isn't */
  429. goto repeat_connection_edge_package_raw_inbuf;
  430. }
  431. /* Tell any APs that are waiting for a new circuit that one is available */
  432. void connection_ap_attach_pending(void)
  433. {
  434. connection_t **carray;
  435. int n, i;
  436. get_connection_array(&carray, &n);
  437. for (i = 0; i < n; ++i) {
  438. if (carray[i]->type != CONN_TYPE_AP ||
  439. carray[i]->type != AP_CONN_STATE_CIRCUIT_WAIT)
  440. continue;
  441. if (connection_ap_handshake_attach_circuit(carray[i])<0) {
  442. if(!circuit_get_newest(carray[i], 0)) {
  443. /* if there are no acceptable clean or not-very-dirty circs on the way */
  444. circuit_launch_new();
  445. }
  446. }
  447. }
  448. }
  449. static void connection_edge_consider_sending_sendme(connection_t *conn) {
  450. circuit_t *circ;
  451. if(connection_outbuf_too_full(conn))
  452. return;
  453. circ = circuit_get_by_conn(conn);
  454. if(!circ) {
  455. /* this can legitimately happen if the destroy has already
  456. * arrived and torn down the circuit */
  457. log_fn(LOG_INFO,"No circuit associated with conn. Skipping.");
  458. return;
  459. }
  460. while(conn->deliver_window < STREAMWINDOW_START - STREAMWINDOW_INCREMENT) {
  461. log_fn(LOG_DEBUG,"Outbuf %d, Queueing stream sendme.", conn->outbuf_flushlen);
  462. conn->deliver_window += STREAMWINDOW_INCREMENT;
  463. if(connection_edge_send_command(conn, circ, RELAY_COMMAND_SENDME,
  464. NULL, 0, conn->cpath_layer) < 0) {
  465. log_fn(LOG_WARN,"connection_edge_send_command failed. Returning.");
  466. return; /* the circuit's closed, don't continue */
  467. }
  468. }
  469. }
  470. static int connection_ap_handshake_process_socks(connection_t *conn) {
  471. socks_request_t *socks;
  472. int sockshere;
  473. assert(conn);
  474. assert(conn->type == CONN_TYPE_AP);
  475. assert(conn->state == AP_CONN_STATE_SOCKS_WAIT);
  476. assert(conn->socks_request);
  477. socks = conn->socks_request;
  478. log_fn(LOG_DEBUG,"entered.");
  479. sockshere = fetch_from_buf_socks(conn->inbuf, socks);
  480. if(sockshere == -1 || sockshere == 0) {
  481. if(socks->replylen) { /* we should send reply back */
  482. log_fn(LOG_DEBUG,"reply is already set for us. Using it.");
  483. connection_ap_handshake_socks_reply(conn, socks->reply, socks->replylen, 0);
  484. } else if(sockshere == -1) { /* send normal reject */
  485. log_fn(LOG_WARN,"Fetching socks handshake failed. Closing.");
  486. connection_ap_handshake_socks_reply(conn, NULL, 0, 0);
  487. } else {
  488. log_fn(LOG_DEBUG,"socks handshake not all here yet.");
  489. }
  490. return sockshere;
  491. } /* else socks handshake is done, continue processing */
  492. conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
  493. if(connection_ap_handshake_attach_circuit(conn) < 0)
  494. circuit_launch_new(); /* Build another circuit to handle this stream */
  495. return 0;
  496. }
  497. /* Try to find a live circuit. If we don't find one, tell 'conn' to
  498. * stop reading and return 0. Otherwise, associate the CONN_TYPE_AP
  499. * connection 'conn' with a safe live circuit, start sending a
  500. * BEGIN cell down the circuit, and return 1.
  501. */
  502. static int connection_ap_handshake_attach_circuit(connection_t *conn) {
  503. circuit_t *circ;
  504. assert(conn);
  505. assert(conn->type == CONN_TYPE_AP);
  506. assert(conn->state == AP_CONN_STATE_CIRCUIT_WAIT);
  507. assert(conn->socks_request);
  508. /* find the circuit that we should use, if there is one. */
  509. circ = circuit_get_newest(conn, 1);
  510. if(!circ) {
  511. log_fn(LOG_INFO,"No safe circuit ready for edge connection; delaying.");
  512. connection_stop_reading(conn); /* don't read until the connected cell arrives */
  513. return -1;
  514. }
  515. connection_start_reading(conn);
  516. if(!circ->timestamp_dirty)
  517. circ->timestamp_dirty = time(NULL);
  518. /* add it into the linked list of streams on this circuit */
  519. log_fn(LOG_DEBUG,"attaching new conn to circ. n_circ_id %d.", circ->n_circ_id);
  520. conn->next_stream = circ->p_streams;
  521. circ->p_streams = conn;
  522. assert(circ->cpath && circ->cpath->prev);
  523. assert(circ->cpath->prev->state == CPATH_STATE_OPEN);
  524. conn->cpath_layer = circ->cpath->prev;
  525. connection_ap_handshake_send_begin(conn, circ);
  526. return 0;
  527. }
  528. /* deliver the destaddr:destport in a relay cell */
  529. static void connection_ap_handshake_send_begin(connection_t *ap_conn, circuit_t *circ)
  530. {
  531. char payload[CELL_PAYLOAD_SIZE];
  532. int payload_len;
  533. struct in_addr in;
  534. const char *string_addr;
  535. assert(ap_conn->type == CONN_TYPE_AP);
  536. assert(ap_conn->state == AP_CONN_STATE_CIRCUIT_WAIT);
  537. assert(ap_conn->socks_request);
  538. crypto_pseudo_rand(STREAM_ID_SIZE, ap_conn->stream_id);
  539. /* FIXME check for collisions */
  540. in.s_addr = htonl(client_dns_lookup_entry(ap_conn->socks_request->address));
  541. string_addr = in.s_addr ? inet_ntoa(in) : NULL;
  542. memcpy(payload, ap_conn->stream_id, STREAM_ID_SIZE);
  543. payload_len = STREAM_ID_SIZE + 1 +
  544. snprintf(payload+STREAM_ID_SIZE,CELL_PAYLOAD_SIZE-RELAY_HEADER_SIZE-STREAM_ID_SIZE,
  545. "%s:%d",
  546. string_addr ? string_addr : ap_conn->socks_request->address,
  547. ap_conn->socks_request->port);
  548. log_fn(LOG_DEBUG,"Sending relay cell to begin stream %d.",*(int *)ap_conn->stream_id);
  549. if(connection_edge_send_command(ap_conn, circ, RELAY_COMMAND_BEGIN,
  550. payload, payload_len, ap_conn->cpath_layer) < 0)
  551. return; /* circuit is closed, don't continue */
  552. ap_conn->package_window = STREAMWINDOW_START;
  553. ap_conn->deliver_window = STREAMWINDOW_START;
  554. ap_conn->state = AP_CONN_STATE_OPEN;
  555. /* XXX Right now, we rely on the socks client not to send us any data
  556. * XXX until we've sent back a socks reply. (If it does, we could wind
  557. * XXX up packaging that data and sending it to the exit, then later having
  558. * XXX the exit refuse us.)
  559. * XXX Perhaps we should grow an AP_CONN_STATE_CONNECTING state.
  560. */
  561. log_fn(LOG_INFO,"Address/port sent, ap socket %d, n_circ_id %d",ap_conn->s,circ->n_circ_id);
  562. return;
  563. }
  564. static int connection_ap_handshake_socks_reply(connection_t *conn, char *reply,
  565. int replylen, char success) {
  566. char buf[256];
  567. if(replylen) { /* we already have a reply in mind */
  568. connection_write_to_buf(reply, replylen, conn);
  569. return flush_buf(conn->s, conn->outbuf, &conn->outbuf_flushlen); /* try to flush it */
  570. }
  571. assert(conn->socks_request);
  572. if(conn->socks_request->socks_version == 4) {
  573. memset(buf,0,SOCKS4_NETWORK_LEN);
  574. #define SOCKS4_GRANTED 90
  575. #define SOCKS4_REJECT 91
  576. buf[1] = (success ? SOCKS4_GRANTED : SOCKS4_REJECT);
  577. /* leave version, destport, destip zero */
  578. connection_write_to_buf(buf, SOCKS4_NETWORK_LEN, conn);
  579. return flush_buf(conn->s, conn->outbuf, &conn->outbuf_flushlen); /* try to flush it */
  580. }
  581. if(conn->socks_request->socks_version == 5) {
  582. buf[0] = 5; /* version 5 */
  583. #define SOCKS5_SUCCESS 0
  584. #define SOCKS5_GENERIC_ERROR 1
  585. buf[1] = success ? SOCKS5_SUCCESS : SOCKS5_GENERIC_ERROR;
  586. buf[2] = 0;
  587. buf[3] = 1; /* ipv4 addr */
  588. memset(buf+4,0,6); /* Set external addr/port to 0.
  589. The spec doesn't seem to say what to do here. -RD */
  590. connection_write_to_buf(buf,10,conn);
  591. return flush_buf(conn->s, conn->outbuf, &conn->outbuf_flushlen); /* try to flush it */
  592. }
  593. return 0; /* if socks_version isn't 4 or 5, don't send anything */
  594. }
  595. static int connection_exit_begin_conn(cell_t *cell, circuit_t *circ) {
  596. connection_t *n_stream;
  597. char *colon;
  598. /* XXX currently we don't send an end cell back if we drop the
  599. * begin because it's malformed.
  600. */
  601. if(!memchr(cell->payload+RELAY_HEADER_SIZE+STREAM_ID_SIZE,0,
  602. cell->length-RELAY_HEADER_SIZE-STREAM_ID_SIZE)) {
  603. log_fn(LOG_WARN,"relay begin cell has no \\0. Dropping.");
  604. return 0;
  605. }
  606. colon = strchr(cell->payload+RELAY_HEADER_SIZE+STREAM_ID_SIZE, ':');
  607. if(!colon) {
  608. log_fn(LOG_WARN,"relay begin cell has no colon. Dropping.");
  609. return 0;
  610. }
  611. *colon = 0;
  612. if(!atoi(colon+1)) { /* bad port */
  613. log_fn(LOG_WARN,"relay begin cell has invalid port. Dropping.");
  614. return 0;
  615. }
  616. log_fn(LOG_DEBUG,"Creating new exit connection.");
  617. n_stream = connection_new(CONN_TYPE_EXIT);
  618. memcpy(n_stream->stream_id, cell->payload + RELAY_HEADER_SIZE, STREAM_ID_SIZE);
  619. n_stream->address = tor_strdup(cell->payload + RELAY_HEADER_SIZE + STREAM_ID_SIZE);
  620. n_stream->port = atoi(colon+1);
  621. n_stream->state = EXIT_CONN_STATE_RESOLVING;
  622. /* leave n_stream->s at -1, because it's not yet valid */
  623. n_stream->package_window = STREAMWINDOW_START;
  624. n_stream->deliver_window = STREAMWINDOW_START;
  625. if(connection_add(n_stream) < 0) { /* no space, forget it */
  626. log_fn(LOG_WARN,"connection_add failed. Dropping.");
  627. connection_free(n_stream);
  628. return 0;
  629. }
  630. /* add it into the linked list of streams on this circuit */
  631. n_stream->next_stream = circ->n_streams;
  632. circ->n_streams = n_stream;
  633. /* send it off to the gethostbyname farm */
  634. switch(dns_resolve(n_stream)) {
  635. case 1: /* resolve worked */
  636. connection_exit_connect(n_stream);
  637. return 0;
  638. case -1: /* resolve failed */
  639. log_fn(LOG_WARN,"Resolve failed (%s).", n_stream->address);
  640. connection_edge_end(n_stream, END_STREAM_REASON_RESOLVEFAILED, NULL);
  641. /* case 0, resolve added to pending list */
  642. }
  643. return 0;
  644. }
  645. void connection_exit_connect(connection_t *conn) {
  646. unsigned char connected_payload[4];
  647. if(router_compare_to_exit_policy(conn) < 0) {
  648. log_fn(LOG_INFO,"%s:%d failed exit policy. Closing.", conn->address, conn->port);
  649. connection_edge_end(conn, END_STREAM_REASON_EXITPOLICY, NULL);
  650. return;
  651. }
  652. switch(connection_connect(conn, conn->address, conn->addr, conn->port)) {
  653. case -1:
  654. connection_edge_end(conn, END_STREAM_REASON_CONNECTFAILED, NULL);
  655. return;
  656. case 0:
  657. connection_set_poll_socket(conn);
  658. conn->state = EXIT_CONN_STATE_CONNECTING;
  659. connection_watch_events(conn, POLLOUT | POLLIN | POLLERR);
  660. /* writable indicates finish, readable indicates broken link,
  661. error indicates broken link in windowsland. */
  662. return;
  663. /* case 1: fall through */
  664. }
  665. connection_set_poll_socket(conn);
  666. conn->state = EXIT_CONN_STATE_OPEN;
  667. if(connection_wants_to_flush(conn)) { /* in case there are any queued data cells */
  668. log_fn(LOG_WARN,"tell roger: newly connected conn had data waiting!");
  669. // connection_start_writing(conn);
  670. }
  671. // connection_process_inbuf(conn);
  672. connection_watch_events(conn, POLLIN);
  673. /* also, deliver a 'connected' cell back through the circuit. */
  674. *((uint32_t*) connected_payload) = htonl(conn->addr);
  675. connection_edge_send_command(conn, circuit_get_by_conn(conn), RELAY_COMMAND_CONNECTED,
  676. connected_payload, 4, conn->cpath_layer);
  677. }
  678. int connection_ap_can_use_exit(connection_t *conn, routerinfo_t *exit)
  679. {
  680. uint32_t addr;
  681. assert(conn);
  682. assert(conn->type == CONN_TYPE_AP);
  683. assert(conn->socks_request);
  684. addr = client_dns_lookup_entry(conn->socks_request->address);
  685. return router_supports_exit_address(addr, conn->port, exit);
  686. }
  687. /* ***** Client DNS code ***** */
  688. #define MAX_DNS_ENTRY_AGE 30*60
  689. /* XXX Perhaps this should get merged with the dns.c code somehow. */
  690. struct client_dns_entry {
  691. SPLAY_ENTRY(client_dns_entry) node;
  692. char *address;
  693. uint32_t addr;
  694. time_t expires;
  695. };
  696. static int client_dns_size = 0;
  697. static SPLAY_HEAD(client_dns_tree, client_dns_entry) client_dns_root;
  698. static int compare_client_dns_entries(struct client_dns_entry *a,
  699. struct client_dns_entry *b)
  700. {
  701. return strcasecmp(a->address, b->address);
  702. }
  703. static void client_dns_entry_free(struct client_dns_entry *ent)
  704. {
  705. tor_free(ent->address);
  706. tor_free(ent);
  707. }
  708. SPLAY_PROTOTYPE(client_dns_tree, client_dns_entry, node, compare_client_dns_entries);
  709. SPLAY_GENERATE(client_dns_tree, client_dns_entry, node, compare_client_dns_entries);
  710. void client_dns_init(void) {
  711. SPLAY_INIT(&client_dns_root);
  712. client_dns_size = 0;
  713. }
  714. static uint32_t client_dns_lookup_entry(const char *address)
  715. {
  716. struct client_dns_entry *ent;
  717. struct client_dns_entry search;
  718. struct in_addr in;
  719. time_t now;
  720. assert(address);
  721. if (inet_aton(address, &in)) {
  722. log_fn(LOG_DEBUG, "Using static address %s (%08X)", address,
  723. ntohl(in.s_addr));
  724. return ntohl(in.s_addr);
  725. }
  726. search.address = (char*)address;
  727. ent = SPLAY_FIND(client_dns_tree, &client_dns_root, &search);
  728. if (!ent) {
  729. log_fn(LOG_DEBUG, "No entry found for address %s", address);
  730. return 0;
  731. } else {
  732. now = time(NULL);
  733. if (ent->expires < now) {
  734. log_fn(LOG_DEBUG, "Expired entry found for address %s", address);
  735. SPLAY_REMOVE(client_dns_tree, &client_dns_root, ent);
  736. client_dns_entry_free(ent);
  737. --client_dns_size;
  738. return 0;
  739. }
  740. in.s_addr = htonl(ent->addr);
  741. log_fn(LOG_DEBUG, "Found cached entry for address %s: %s", address,
  742. inet_ntoa(in));
  743. return ent->addr;
  744. }
  745. }
  746. static void client_dns_set_entry(const char *address, uint32_t val)
  747. {
  748. struct client_dns_entry *ent;
  749. struct client_dns_entry search;
  750. struct in_addr in;
  751. time_t now;
  752. assert(address);
  753. assert(val);
  754. if (inet_aton(address, &in)) {
  755. if (ntohl(in.s_addr) == val)
  756. return;
  757. in.s_addr = htonl(val);
  758. log_fn(LOG_WARN,
  759. "Trying to store incompatible cached value %s for static address %s",
  760. inet_ntoa(in), address);
  761. return;
  762. }
  763. search.address = (char*) address;
  764. now = time(NULL);
  765. ent = SPLAY_FIND(client_dns_tree, &client_dns_root, &search);
  766. if (ent) {
  767. log_fn(LOG_DEBUG, "Updating entry for address %s", address);
  768. ent->addr = val;
  769. ent->expires = now+MAX_DNS_ENTRY_AGE;
  770. } else {
  771. in.s_addr = htonl(val);
  772. log_fn(LOG_DEBUG, "Caching result for address %s: %s", address,
  773. inet_ntoa(in));
  774. ent = tor_malloc(sizeof(struct client_dns_entry));
  775. ent->address = tor_strdup(address);
  776. ent->addr = val;
  777. ent->expires = now+MAX_DNS_ENTRY_AGE;
  778. SPLAY_INSERT(client_dns_tree, &client_dns_root, ent);
  779. ++client_dns_size;
  780. }
  781. }
  782. void client_dns_clean(void)
  783. {
  784. struct client_dns_entry **expired_entries;
  785. int n_expired_entries = 0;
  786. struct client_dns_entry *ent;
  787. time_t now;
  788. int i;
  789. if(!client_dns_size)
  790. return;
  791. expired_entries = tor_malloc(client_dns_size *
  792. sizeof(struct client_dns_entry *));
  793. now = time(NULL);
  794. SPLAY_FOREACH(ent, client_dns_tree, &client_dns_root) {
  795. if (ent->expires < now) {
  796. expired_entries[n_expired_entries++] = ent;
  797. }
  798. }
  799. for (i = 0; i < n_expired_entries; ++i) {
  800. SPLAY_REMOVE(client_dns_tree, &client_dns_root, expired_entries[i]);
  801. client_dns_entry_free(expired_entries[i]);
  802. }
  803. tor_free(expired_entries);
  804. }
  805. /*
  806. Local Variables:
  807. mode:c
  808. indent-tabs-mode:nil
  809. c-basic-offset:2
  810. End:
  811. */