connection_edge.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713
  1. /* Copyright 2001,2002 Roger Dingledine, Matej Pfajfar. */
  2. /* See LICENSE for licensing information */
  3. /* $Id$ */
  4. #include "or.h"
  5. extern or_options_t options; /* command-line and config-file options */
  6. static int connection_ap_handshake_process_socks(connection_t *conn);
  7. static int connection_ap_handshake_send_begin(connection_t *ap_conn, circuit_t *circ);
  8. static int connection_ap_handshake_socks_reply(connection_t *conn, char result);
  9. static int connection_exit_begin_conn(cell_t *cell, circuit_t *circ);
  10. int connection_edge_process_inbuf(connection_t *conn) {
  11. assert(conn);
  12. assert(conn->type == CONN_TYPE_AP || conn->type == CONN_TYPE_EXIT);
  13. if(conn->inbuf_reached_eof) {
  14. #ifdef HALF_OPEN
  15. /* eof reached; we're done reading, but we might want to write more. */
  16. conn->done_receiving = 1;
  17. shutdown(conn->s, 0); /* XXX check return, refactor NM */
  18. if (conn->done_sending)
  19. conn->marked_for_close = 1;
  20. /* XXX Factor out common logic here and in circuit_about_to_close NM */
  21. circ = circuit_get_by_conn(conn);
  22. if (!circ)
  23. return -1;
  24. memset(&cell, 0, sizeof(cell_t));
  25. cell.command = CELL_RELAY;
  26. cell.length = RELAY_HEADER_SIZE;
  27. SET_CELL_RELAY_COMMAND(cell, RELAY_COMMAND_END);
  28. SET_CELL_STREAM_ID(cell, conn->stream_id);
  29. cell.aci = circ->n_aci;
  30. if (circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION(conn->type), conn->cpath_layer) < 0) {
  31. log(LOG_DEBUG,"circuit_deliver_relay_cell failed. Closing.");
  32. circuit_close(circ);
  33. }
  34. return 0;
  35. #else
  36. /* eof reached, kill it. */
  37. log_fn(LOG_DEBUG,"conn reached eof. Closing.");
  38. return -1;
  39. #endif
  40. }
  41. switch(conn->state) {
  42. case AP_CONN_STATE_SOCKS_WAIT:
  43. return connection_ap_handshake_process_socks(conn);
  44. case AP_CONN_STATE_OPEN:
  45. case EXIT_CONN_STATE_OPEN:
  46. if(connection_package_raw_inbuf(conn) < 0)
  47. return -1;
  48. return 0;
  49. case EXIT_CONN_STATE_CONNECTING:
  50. log_fn(LOG_DEBUG,"text from server while in 'connecting' state at exit. Leaving it on buffer.");
  51. return 0;
  52. }
  53. return 0;
  54. }
  55. int connection_edge_send_command(connection_t *fromconn, circuit_t *circ, int relay_command) {
  56. cell_t cell;
  57. int cell_direction;
  58. if(!circ) {
  59. log_fn(LOG_DEBUG,"no circ. Closing.");
  60. return -1;
  61. }
  62. memset(&cell, 0, sizeof(cell_t));
  63. if(fromconn && fromconn->type == CONN_TYPE_AP) {
  64. cell.aci = circ->n_aci;
  65. cell_direction = CELL_DIRECTION_OUT;
  66. } else {
  67. /* NOTE: if !fromconn, we assume that it's heading towards the OP */
  68. cell.aci = circ->p_aci;
  69. cell_direction = CELL_DIRECTION_IN;
  70. }
  71. cell.command = CELL_RELAY;
  72. SET_CELL_RELAY_COMMAND(cell, relay_command);
  73. if(fromconn)
  74. SET_CELL_STREAM_ID(cell, fromconn->stream_id);
  75. else
  76. SET_CELL_STREAM_ID(cell, ZERO_STREAM);
  77. cell.length = RELAY_HEADER_SIZE;
  78. log_fn(LOG_INFO,"delivering %d cell %s.", relay_command, cell_direction == CELL_DIRECTION_OUT ? "forward" : "backward");
  79. if(circuit_deliver_relay_cell(&cell, circ, cell_direction, fromconn ? fromconn->cpath_layer : NULL) < 0) {
  80. log_fn(LOG_DEBUG,"circuit_deliver_relay_cell failed. Closing.");
  81. circuit_close(circ);
  82. return 0;
  83. }
  84. return 0;
  85. }
  86. /* an incoming relay cell has arrived. return -1 if you want to tear down the
  87. * circuit, else 0. */
  88. int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, connection_t *conn,
  89. int edge_type, crypt_path_t *layer_hint) {
  90. int relay_command;
  91. static int num_seen=0;
  92. assert(cell && circ);
  93. relay_command = CELL_RELAY_COMMAND(*cell);
  94. // log_fn(LOG_DEBUG,"command %d stream %d", relay_command, stream_id);
  95. num_seen++;
  96. log_fn(LOG_DEBUG,"Now seen %d relay cells here.", num_seen);
  97. /* either conn is NULL, in which case we've got a control cell, or else
  98. * conn points to the recognized stream. */
  99. if(conn && conn->state != AP_CONN_STATE_OPEN && conn->state != EXIT_CONN_STATE_OPEN) {
  100. if(conn->type == CONN_TYPE_EXIT && relay_command == RELAY_COMMAND_END) {
  101. log_fn(LOG_INFO,"Exit got end before we're connected. Marking for close.");
  102. conn->marked_for_close = 1;
  103. if(conn->state == EXIT_CONN_STATE_RESOLVING) {
  104. log_fn(LOG_INFO,"...and informing resolver we don't want the answer anymore.");
  105. dns_cancel_pending_resolve(conn->address, conn);
  106. }
  107. } else {
  108. log_fn(LOG_DEBUG,"Got an unexpected relay cell, not in 'open' state. Dropping.");
  109. }
  110. return 0;
  111. }
  112. switch(relay_command) {
  113. case RELAY_COMMAND_BEGIN:
  114. if(edge_type == EDGE_AP) {
  115. log_fn(LOG_INFO,"relay begin request unsupported. Dropping.");
  116. return 0;
  117. }
  118. if(conn) {
  119. log_fn(LOG_INFO,"begin cell for known stream. Dropping.");
  120. return 0;
  121. }
  122. return connection_exit_begin_conn(cell, circ);
  123. case RELAY_COMMAND_DATA:
  124. if((edge_type == EDGE_AP && --layer_hint->deliver_window < 0) ||
  125. (edge_type == EDGE_EXIT && --circ->deliver_window < 0)) {
  126. log_fn(LOG_DEBUG,"circ deliver_window below 0. Killing.");
  127. return -1;
  128. }
  129. log_fn(LOG_DEBUG,"circ deliver_window now %d.", edge_type == EDGE_AP ? layer_hint->deliver_window : circ->deliver_window);
  130. if(circuit_consider_sending_sendme(circ, edge_type, layer_hint) < 0)
  131. return -1;
  132. if(!conn) {
  133. log_fn(LOG_DEBUG,"relay cell dropped, unknown stream %d.",*(int*)conn->stream_id);
  134. return 0;
  135. }
  136. if(--conn->deliver_window < 0) { /* is it below 0 after decrement? */
  137. log_fn(LOG_DEBUG,"conn deliver_window below 0. Killing.");
  138. return -1; /* somebody's breaking protocol. kill the whole circuit. */
  139. }
  140. // printf("New text for buf (%d bytes): '%s'", cell->length - RELAY_HEADER_SIZE, cell->payload + RELAY_HEADER_SIZE);
  141. if(connection_write_to_buf(cell->payload + RELAY_HEADER_SIZE,
  142. cell->length - RELAY_HEADER_SIZE, conn) < 0) {
  143. conn->marked_for_close = 1;
  144. return 0;
  145. }
  146. if(connection_consider_sending_sendme(conn, edge_type) < 0)
  147. conn->marked_for_close = 1;
  148. return 0;
  149. case RELAY_COMMAND_END:
  150. if(!conn) {
  151. log_fn(LOG_DEBUG,"end cell dropped, unknown stream %d.",*(int*)conn->stream_id);
  152. return 0;
  153. }
  154. log_fn(LOG_DEBUG,"end cell for stream %d. Removing stream.",*(int*)conn->stream_id);
  155. #ifdef HALF_OPEN
  156. conn->done_sending = 1;
  157. shutdown(conn->s, 1); /* XXX check return; refactor NM */
  158. if (conn->done_receiving)
  159. conn->marked_for_close = 1;
  160. #endif
  161. conn->marked_for_close = 1;
  162. break;
  163. case RELAY_COMMAND_EXTEND:
  164. if(conn) {
  165. log_fn(LOG_INFO,"'extend' for non-zero stream. Dropping.");
  166. return 0;
  167. }
  168. return circuit_extend(cell, circ);
  169. case RELAY_COMMAND_EXTENDED:
  170. if(edge_type == EDGE_EXIT) {
  171. log_fn(LOG_INFO,"'extended' unsupported at exit. Dropping.");
  172. return 0;
  173. }
  174. log_fn(LOG_DEBUG,"Got an extended cell! Yay.");
  175. if(circuit_finish_handshake(circ, cell->payload+RELAY_HEADER_SIZE) < 0) {
  176. log_fn(LOG_INFO,"circuit_finish_handshake failed.");
  177. return -1;
  178. }
  179. return circuit_send_next_onion_skin(circ);
  180. case RELAY_COMMAND_TRUNCATE:
  181. if(edge_type == EDGE_AP) {
  182. log_fn(LOG_INFO,"'truncate' unsupported at AP. Dropping.");
  183. return 0;
  184. }
  185. if(circ->n_conn) {
  186. connection_send_destroy(circ->n_aci, circ->n_conn);
  187. circ->n_conn = NULL;
  188. }
  189. log_fn(LOG_DEBUG, "Processed 'truncate', replying.");
  190. return connection_edge_send_command(NULL, circ, RELAY_COMMAND_TRUNCATED);
  191. case RELAY_COMMAND_TRUNCATED:
  192. if(edge_type == EDGE_EXIT) {
  193. log_fn(LOG_INFO,"'truncated' unsupported at exit. Dropping.");
  194. return 0;
  195. }
  196. return circuit_truncated(circ, layer_hint);
  197. case RELAY_COMMAND_CONNECTED:
  198. if(edge_type == EDGE_EXIT) {
  199. log_fn(LOG_INFO,"'connected' unsupported at exit. Dropping.");
  200. return 0;
  201. }
  202. if(!conn) {
  203. log_fn(LOG_DEBUG,"connected cell dropped, unknown stream %d.",*(int*)conn->stream_id);
  204. break;
  205. }
  206. log_fn(LOG_DEBUG,"Connected! Notifying application.");
  207. if(connection_ap_handshake_socks_reply(conn, SOCKS4_REQUEST_GRANTED) < 0) {
  208. conn->marked_for_close = 1;
  209. }
  210. break;
  211. case RELAY_COMMAND_SENDME:
  212. if(!conn) {
  213. if(edge_type == EDGE_AP) {
  214. assert(layer_hint);
  215. layer_hint->package_window += CIRCWINDOW_INCREMENT;
  216. log_fn(LOG_DEBUG,"circ-level sendme at AP, packagewindow %d.", layer_hint->package_window);
  217. circuit_resume_edge_reading(circ, EDGE_AP, layer_hint);
  218. } else {
  219. assert(!layer_hint);
  220. circ->package_window += CIRCWINDOW_INCREMENT;
  221. log_fn(LOG_DEBUG,"circ-level sendme at exit, packagewindow %d.", circ->package_window);
  222. circuit_resume_edge_reading(circ, EDGE_EXIT, layer_hint);
  223. }
  224. return 0;
  225. }
  226. conn->package_window += STREAMWINDOW_INCREMENT;
  227. log_fn(LOG_DEBUG,"stream-level sendme, packagewindow now %d.", conn->package_window);
  228. connection_start_reading(conn);
  229. connection_package_raw_inbuf(conn); /* handle whatever might still be on the inbuf */
  230. break;
  231. default:
  232. log_fn(LOG_DEBUG,"unknown relay command %d.",relay_command);
  233. }
  234. return 0;
  235. }
  236. int connection_edge_finished_flushing(connection_t *conn) {
  237. int e, len=sizeof(e);
  238. assert(conn);
  239. assert(conn->type == CONN_TYPE_AP || conn->type == CONN_TYPE_EXIT);
  240. switch(conn->state) {
  241. case EXIT_CONN_STATE_CONNECTING:
  242. if (getsockopt(conn->s, SOL_SOCKET, SO_ERROR, (void*)&e, &len) < 0) { /* not yet */
  243. if(!ERRNO_CONN_EINPROGRESS(errno)) {
  244. /* yuck. kill it. */
  245. log_fn(LOG_DEBUG,"in-progress exit connect failed. Removing.");
  246. return -1;
  247. } else {
  248. log_fn(LOG_DEBUG,"in-progress exit connect still waiting.");
  249. return 0; /* no change, see if next time is better */
  250. }
  251. }
  252. /* the connect has finished. */
  253. log_fn(LOG_DEBUG,"Exit connection to %s:%u established.",
  254. conn->address,conn->port);
  255. conn->state = EXIT_CONN_STATE_OPEN;
  256. connection_watch_events(conn, POLLIN); /* stop writing, continue reading */
  257. if(connection_wants_to_flush(conn)) /* in case there are any queued relay cells */
  258. connection_start_writing(conn);
  259. return
  260. connection_edge_send_command(conn, circuit_get_by_conn(conn), RELAY_COMMAND_CONNECTED) || /* deliver a 'connected' relay cell back through the circuit. */
  261. connection_process_inbuf(conn); /* in case the server has written anything */
  262. case AP_CONN_STATE_OPEN:
  263. case EXIT_CONN_STATE_OPEN:
  264. connection_stop_writing(conn);
  265. return connection_consider_sending_sendme(conn, conn->type);
  266. default:
  267. log_fn(LOG_DEBUG,"BUG: called in unexpected state.");
  268. return 0;
  269. }
  270. return 0;
  271. }
  272. int connection_package_raw_inbuf(connection_t *conn) {
  273. int amount_to_process;
  274. cell_t cell;
  275. circuit_t *circ;
  276. assert(conn);
  277. assert(!connection_speaks_cells(conn));
  278. repeat_connection_package_raw_inbuf:
  279. circ = circuit_get_by_conn(conn);
  280. if(!circ) {
  281. log_fn(LOG_DEBUG,"conn has no circuits!");
  282. return -1;
  283. }
  284. if(circuit_consider_stop_edge_reading(circ, conn->type, conn->cpath_layer))
  285. return 0;
  286. if(conn->package_window <= 0) {
  287. log_fn(LOG_ERR,"called with package_window 0. Tell Roger.");
  288. connection_stop_reading(conn);
  289. return 0;
  290. }
  291. amount_to_process = conn->inbuf_datalen;
  292. if(!amount_to_process)
  293. return 0;
  294. /* Initialize the cell with 0's */
  295. memset(&cell, 0, sizeof(cell_t));
  296. if(amount_to_process > CELL_PAYLOAD_SIZE - RELAY_HEADER_SIZE) {
  297. cell.length = CELL_PAYLOAD_SIZE - RELAY_HEADER_SIZE;
  298. } else {
  299. cell.length = amount_to_process;
  300. }
  301. connection_fetch_from_buf(cell.payload+RELAY_HEADER_SIZE, cell.length, conn);
  302. log_fn(LOG_DEBUG,"(%d) Packaging %d bytes (%d waiting).",conn->s,cell.length, conn->inbuf_datalen);
  303. cell.command = CELL_RELAY;
  304. SET_CELL_RELAY_COMMAND(cell, RELAY_COMMAND_DATA);
  305. SET_CELL_STREAM_ID(cell, conn->stream_id);
  306. cell.length += RELAY_HEADER_SIZE;
  307. if(conn->type == CONN_TYPE_EXIT) {
  308. cell.aci = circ->p_aci;
  309. if(circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION_IN, NULL) < 0) {
  310. log_fn(LOG_DEBUG,"circuit_deliver_relay_cell (backward) failed. Closing.");
  311. circuit_close(circ);
  312. return 0;
  313. }
  314. assert(circ->package_window > 0);
  315. circ->package_window--;
  316. } else { /* send it forward. we're an AP */
  317. assert(conn->type == CONN_TYPE_AP);
  318. cell.aci = circ->n_aci;
  319. if(circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION_OUT, conn->cpath_layer) < 0) {
  320. log_fn(LOG_DEBUG,"circuit_deliver_relay_cell (forward) failed. Closing.");
  321. circuit_close(circ);
  322. return 0;
  323. }
  324. assert(conn->cpath_layer->package_window > 0);
  325. conn->cpath_layer->package_window--;
  326. }
  327. assert(conn->package_window > 0);
  328. if(--conn->package_window <= 0) { /* is it 0 after decrement? */
  329. connection_stop_reading(conn);
  330. log_fn(LOG_DEBUG,"conn->package_window reached 0.");
  331. circuit_consider_stop_edge_reading(circ, conn->type, conn->cpath_layer);
  332. return 0; /* don't process the inbuf any more */
  333. }
  334. log_fn(LOG_DEBUG,"conn->package_window is now %d",conn->package_window);
  335. /* handle more if there's more, or return 0 if there isn't */
  336. goto repeat_connection_package_raw_inbuf;
  337. }
  338. int connection_consider_sending_sendme(connection_t *conn, int edge_type) {
  339. circuit_t *circ;
  340. cell_t cell;
  341. if(connection_outbuf_too_full(conn))
  342. return 0;
  343. circ = circuit_get_by_conn(conn);
  344. if(!circ) {
  345. /* this can legitimately happen if the destroy has already arrived and torn down the circuit */
  346. log_fn(LOG_DEBUG,"No circuit associated with conn. Skipping.");
  347. return 0;
  348. }
  349. memset(&cell, 0, sizeof(cell_t));
  350. cell.command = CELL_RELAY;
  351. SET_CELL_RELAY_COMMAND(cell, RELAY_COMMAND_SENDME);
  352. SET_CELL_STREAM_ID(cell, conn->stream_id);
  353. cell.length += RELAY_HEADER_SIZE;
  354. if(edge_type == EDGE_EXIT)
  355. cell.aci = circ->p_aci;
  356. else
  357. cell.aci = circ->n_aci;
  358. while(conn->deliver_window < STREAMWINDOW_START - STREAMWINDOW_INCREMENT) {
  359. log_fn(LOG_DEBUG,"Outbuf %d, Queueing stream sendme.", conn->outbuf_flushlen);
  360. conn->deliver_window += STREAMWINDOW_INCREMENT;
  361. if(circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION(edge_type), conn->cpath_layer) < 0) {
  362. log_fn(LOG_DEBUG,"circuit_deliver_relay_cell failed. Closing.");
  363. circuit_close(circ);
  364. return 0;
  365. }
  366. }
  367. return 0;
  368. }
  369. static int connection_ap_handshake_process_socks(connection_t *conn) {
  370. socks4_t socks4_info;
  371. circuit_t *circ;
  372. char tmpbuf[512];
  373. int amt;
  374. assert(conn);
  375. log_fn(LOG_DEBUG,"entered.");
  376. if(!conn->socks_version) { /* try to pull it in */
  377. if(conn->inbuf_datalen < sizeof(socks4_t)) /* basic info available? */
  378. return 0; /* not yet */
  379. connection_fetch_from_buf((char *)&socks4_info,sizeof(socks4_t),conn);
  380. log_fn(LOG_DEBUG,"Successfully read socks info.");
  381. if(socks4_info.version != 4) {
  382. log_fn(LOG_NOTICE,"Unrecognized version %d.",socks4_info.version);
  383. connection_ap_handshake_socks_reply(conn, SOCKS4_REQUEST_REJECT);
  384. return -1;
  385. }
  386. conn->socks_version = socks4_info.version;
  387. if(socks4_info.command != 1) { /* not a connect? we don't support it. */
  388. log_fn(LOG_NOTICE,"command %d not '1'.",socks4_info.command);
  389. connection_ap_handshake_socks_reply(conn, SOCKS4_REQUEST_REJECT);
  390. return -1;
  391. }
  392. conn->dest_port = ntohs(*(uint16_t*)&socks4_info.destport);
  393. if(!conn->dest_port) {
  394. log_fn(LOG_NOTICE,"Port is zero.");
  395. connection_ap_handshake_socks_reply(conn, SOCKS4_REQUEST_REJECT);
  396. return -1;
  397. }
  398. log_fn(LOG_NOTICE,"Dest port is %d.",conn->dest_port);
  399. if(socks4_info.destip[0] ||
  400. socks4_info.destip[1] ||
  401. socks4_info.destip[2] ||
  402. !socks4_info.destip[3]) { /* not 0.0.0.x */
  403. log_fn(LOG_NOTICE,"destip not in form 0.0.0.x.");
  404. sprintf(tmpbuf, "%d.%d.%d.%d", socks4_info.destip[0],
  405. socks4_info.destip[1], socks4_info.destip[2], socks4_info.destip[3]);
  406. conn->dest_addr = strdup(tmpbuf);
  407. log_fn(LOG_DEBUG,"Successfully read destip (%s)", conn->dest_addr);
  408. }
  409. }
  410. if(!conn->read_username) { /* the socks spec says we've got to read stuff until we get a null */
  411. amt = connection_find_on_inbuf("\0", 1, conn);
  412. if(amt < 0) /* not there yet */
  413. return 0;
  414. if(amt > 500) {
  415. log_fn(LOG_NOTICE,"username too long.");
  416. connection_ap_handshake_socks_reply(conn, SOCKS4_REQUEST_REJECT);
  417. return -1;
  418. }
  419. connection_fetch_from_buf(tmpbuf,amt,conn);
  420. conn->read_username = 1;
  421. log_fn(LOG_DEBUG,"Successfully read username.");
  422. }
  423. if(!conn->dest_addr) { /* no dest_addr found yet */
  424. amt = connection_find_on_inbuf("\0", 1, conn);
  425. if(amt < 0) /* not there yet */
  426. return 0;
  427. if(amt > 500) {
  428. log_fn(LOG_NOTICE,"dest_addr too long.");
  429. connection_ap_handshake_socks_reply(conn, SOCKS4_REQUEST_REJECT);
  430. return -1;
  431. }
  432. connection_fetch_from_buf(tmpbuf,amt,conn);
  433. conn->dest_addr = strdup(tmpbuf);
  434. log_fn(LOG_NOTICE,"successfully read dest addr '%s'",
  435. conn->dest_addr);
  436. }
  437. /* find the circuit that we should use, if there is one. */
  438. circ = circuit_get_newest_ap();
  439. if(!circ) {
  440. log_fn(LOG_INFO,"No circuit ready. Closing.");
  441. return -1;
  442. }
  443. circ->dirty = 1;
  444. /* add it into the linked list of streams on this circuit */
  445. log_fn(LOG_DEBUG,"attaching new conn to circ. n_aci %d.", circ->n_aci);
  446. conn->next_stream = circ->p_streams;
  447. circ->p_streams = conn;
  448. assert(circ->cpath && circ->cpath->prev);
  449. assert(circ->cpath->prev->state == CPATH_STATE_OPEN);
  450. conn->cpath_layer = circ->cpath->prev;
  451. if(connection_ap_handshake_send_begin(conn, circ) < 0) {
  452. circuit_close(circ);
  453. return -1;
  454. }
  455. return 0;
  456. }
  457. int connection_ap_handshake_send_begin(connection_t *ap_conn, circuit_t *circ) {
  458. cell_t cell;
  459. memset(&cell, 0, sizeof(cell_t));
  460. /* deliver the dest_addr in a relay cell */
  461. cell.command = CELL_RELAY;
  462. cell.aci = circ->n_aci;
  463. SET_CELL_RELAY_COMMAND(cell, RELAY_COMMAND_BEGIN);
  464. if(crypto_pseudo_rand(STREAM_ID_SIZE, ap_conn->stream_id) < 0)
  465. return -1;
  466. /* FIXME check for collisions */
  467. SET_CELL_STREAM_ID(cell, ZERO_STREAM);
  468. memcpy(cell.payload+RELAY_HEADER_SIZE, ap_conn->stream_id, STREAM_ID_SIZE);
  469. cell.length =
  470. snprintf(cell.payload+RELAY_HEADER_SIZE+STREAM_ID_SIZE, CELL_PAYLOAD_SIZE-RELAY_HEADER_SIZE-STREAM_ID_SIZE,
  471. "%s:%d", ap_conn->dest_addr, ap_conn->dest_port) +
  472. 1 + STREAM_ID_SIZE + RELAY_HEADER_SIZE;
  473. log_fn(LOG_DEBUG,"Sending relay cell (id %d) to begin stream %d.", *(int *)(cell.payload+1),*(int *)ap_conn->stream_id);
  474. if(circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION_OUT, ap_conn->cpath_layer) < 0) {
  475. log_fn(LOG_DEBUG,"failed to deliver begin cell. Closing.");
  476. return -1;
  477. }
  478. ap_conn->package_window = STREAMWINDOW_START;
  479. ap_conn->deliver_window = STREAMWINDOW_START;
  480. ap_conn->state = AP_CONN_STATE_OPEN;
  481. log_fn(LOG_INFO,"Address/port sent, ap socket %d, n_aci %d",ap_conn->s,circ->n_aci);
  482. return 0;
  483. }
  484. int connection_ap_handshake_socks_reply(connection_t *conn, char result) {
  485. socks4_t socks4_info;
  486. assert(conn);
  487. socks4_info.version = 0;
  488. socks4_info.command = result;
  489. socks4_info.destport[0] = socks4_info.destport[1] = 0;
  490. socks4_info.destip[0] = socks4_info.destip[1] = socks4_info.destip[2] = socks4_info.destip[3] = 0;
  491. if(connection_write_to_buf((char *)&socks4_info, sizeof(socks4_t), conn) < 0)
  492. return -1;
  493. return connection_flush_buf(conn); /* try to flush it, in case we're about to close the conn */
  494. }
  495. static int connection_exit_begin_conn(cell_t *cell, circuit_t *circ) {
  496. connection_t *n_stream;
  497. char *colon;
  498. if(!memchr(cell->payload+RELAY_HEADER_SIZE+STREAM_ID_SIZE,0,cell->length-RELAY_HEADER_SIZE-STREAM_ID_SIZE)) {
  499. log_fn(LOG_WARNING,"relay begin cell has no \\0. Dropping.");
  500. return 0;
  501. }
  502. colon = strchr(cell->payload+RELAY_HEADER_SIZE+STREAM_ID_SIZE, ':');
  503. if(!colon) {
  504. log_fn(LOG_WARNING,"relay begin cell has no colon. Dropping.");
  505. return 0;
  506. }
  507. *colon = 0;
  508. if(!atoi(colon+1)) { /* bad port */
  509. log_fn(LOG_DEBUG,"relay begin cell has invalid port. Dropping.");
  510. return 0;
  511. }
  512. log_fn(LOG_DEBUG,"Creating new exit connection.");
  513. n_stream = connection_new(CONN_TYPE_EXIT);
  514. if(!n_stream) {
  515. log_fn(LOG_DEBUG,"connection_new failed. Dropping.");
  516. return 0;
  517. }
  518. memcpy(n_stream->stream_id, cell->payload + RELAY_HEADER_SIZE, STREAM_ID_SIZE);
  519. n_stream->address = strdup(cell->payload + RELAY_HEADER_SIZE + STREAM_ID_SIZE);
  520. n_stream->port = atoi(colon+1);
  521. n_stream->state = EXIT_CONN_STATE_RESOLVING;
  522. n_stream->receiver_bucket = -1; /* edge connections don't do receiver buckets */
  523. n_stream->bandwidth = -1;
  524. n_stream->s = -1; /* not yet valid */
  525. n_stream->package_window = STREAMWINDOW_START;
  526. n_stream->deliver_window = STREAMWINDOW_START;
  527. if(connection_add(n_stream) < 0) { /* no space, forget it */
  528. log_fn(LOG_DEBUG,"connection_add failed. Dropping.");
  529. connection_free(n_stream);
  530. return 0;
  531. }
  532. /* add it into the linked list of streams on this circuit */
  533. n_stream->next_stream = circ->n_streams;
  534. circ->n_streams = n_stream;
  535. /* send it off to the gethostbyname farm */
  536. switch(dns_resolve(n_stream)) {
  537. case 1: /* resolve worked */
  538. if(connection_exit_connect(n_stream) >= 0)
  539. return 0;
  540. /* else fall through */
  541. case -1: /* resolve failed */
  542. log_fn(LOG_DEBUG,"Couldn't queue resolve request.");
  543. connection_remove(n_stream);
  544. connection_free(n_stream);
  545. case 0: /* resolve added to pending list */
  546. ;
  547. }
  548. return 0;
  549. }
  550. int connection_exit_connect(connection_t *conn) {
  551. int s; /* for the new socket */
  552. struct sockaddr_in dest_addr;
  553. if(router_compare_to_exit_policy(conn) < 0) {
  554. log_fn(LOG_INFO,"%s:%d failed exit policy. Closing.", conn->address, conn->port);
  555. return -1;
  556. }
  557. /* all the necessary info is here. Start the connect() */
  558. s=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
  559. if (s < 0) {
  560. log_fn(LOG_ERR,"Error creating network socket.");
  561. return -1;
  562. }
  563. set_socket_nonblocking(s);
  564. memset((void *)&dest_addr,0,sizeof(dest_addr));
  565. dest_addr.sin_family = AF_INET;
  566. dest_addr.sin_port = htons(conn->port);
  567. dest_addr.sin_addr.s_addr = htonl(conn->addr);
  568. log_fn(LOG_DEBUG,"Connecting to %s:%u.",conn->address,conn->port);
  569. if(connect(s,(struct sockaddr *)&dest_addr,sizeof(dest_addr)) < 0) {
  570. if(!ERRNO_CONN_EINPROGRESS(errno)) {
  571. /* yuck. kill it. */
  572. perror("connect");
  573. log_fn(LOG_DEBUG,"Connect failed.");
  574. return -1;
  575. } else {
  576. /* it's in progress. set state appropriately and return. */
  577. conn->s = s;
  578. connection_set_poll_socket(conn);
  579. conn->state = EXIT_CONN_STATE_CONNECTING;
  580. log_fn(LOG_DEBUG,"connect in progress, socket %d.",s);
  581. connection_watch_events(conn, POLLOUT | POLLIN | POLLERR);
  582. /* writable indicates finish, readable indicates broken link,
  583. error indicates broken link in windowsland. */
  584. return 0;
  585. }
  586. }
  587. /* it succeeded. we're connected. */
  588. log_fn(LOG_DEBUG,"Connection to %s:%u established.",conn->address,conn->port);
  589. conn->s = s;
  590. connection_set_poll_socket(conn);
  591. conn->state = EXIT_CONN_STATE_OPEN;
  592. if(connection_wants_to_flush(conn)) { /* in case there are any queued data cells */
  593. log_fn(LOG_ERR,"tell roger: newly connected conn had data waiting!");
  594. // connection_start_writing(conn);
  595. }
  596. // connection_process_inbuf(conn);
  597. connection_watch_events(conn, POLLIN);
  598. /* also, deliver a 'connected' cell back through the circuit. */
  599. return connection_edge_send_command(conn, circuit_get_by_conn(conn), RELAY_COMMAND_CONNECTED);
  600. }
  601. /*
  602. Local Variables:
  603. mode:c
  604. indent-tabs-mode:nil
  605. c-basic-offset:2
  606. End:
  607. */