connection_edge.c 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154
  1. /* Copyright 2001 Matej Pfajfar, 2001-2004 Roger Dingledine. */
  2. /* See LICENSE for licensing information */
  3. /* $Id$ */
  4. /**
  5. * \file connection_edge.c
  6. * \brief Handle edge streams.
  7. **/
  8. #include "or.h"
  9. #include "tree.h"
  10. extern or_options_t options; /* command-line and config-file options */
  11. extern char *conn_state_to_string[][_CONN_TYPE_MAX+1]; /* from connection.c */
  12. static struct exit_policy_t *socks_policy = NULL;
  13. static int connection_ap_handshake_process_socks(connection_t *conn);
  14. static void parse_socks_policy(void);
  15. /** Handle new bytes on conn->inbuf, or notification of eof.
  16. *
  17. * If there was an EOF, then send an end and mark the connection
  18. * for close.
  19. *
  20. * Otherwise handle it based on state:
  21. * - If it's waiting for socks info, try to read another step of the
  22. * socks handshake out of conn->inbuf.
  23. * - If it's open, then package more relay cells from the stream.
  24. * - Else, leave the bytes on inbuf alone for now.
  25. *
  26. * Mark and return -1 if there was an unexpected error with the conn,
  27. * else return 0.
  28. */
  29. int connection_edge_process_inbuf(connection_t *conn) {
  30. tor_assert(conn);
  31. tor_assert(conn->type == CONN_TYPE_AP || conn->type == CONN_TYPE_EXIT);
  32. if(conn->inbuf_reached_eof) {
  33. #ifdef HALF_OPEN
  34. /* eof reached; we're done reading, but we might want to write more. */
  35. conn->done_receiving = 1;
  36. shutdown(conn->s, 0); /* XXX check return, refactor NM */
  37. if (conn->done_sending) {
  38. connection_edge_end(conn, END_STREAM_REASON_DONE, conn->cpath_layer);
  39. connection_mark_for_close(conn);
  40. } else {
  41. connection_edge_send_command(conn, circuit_get_by_conn(conn), RELAY_COMMAND_END,
  42. NULL, 0, conn->cpath_layer);
  43. }
  44. return 0;
  45. #else
  46. /* eof reached, kill it. */
  47. log_fn(LOG_INFO,"conn (fd %d) reached eof. Closing.", conn->s);
  48. connection_edge_end(conn, END_STREAM_REASON_DONE, conn->cpath_layer);
  49. connection_mark_for_close(conn);
  50. conn->hold_open_until_flushed = 1; /* just because we shouldn't read
  51. doesn't mean we shouldn't write */
  52. return 0;
  53. #endif
  54. }
  55. switch(conn->state) {
  56. case AP_CONN_STATE_SOCKS_WAIT:
  57. if(connection_ap_handshake_process_socks(conn) < 0) {
  58. conn->has_sent_end = 1; /* no circ yet */
  59. connection_mark_for_close(conn);
  60. conn->hold_open_until_flushed = 1;
  61. return -1;
  62. }
  63. return 0;
  64. case AP_CONN_STATE_OPEN:
  65. case EXIT_CONN_STATE_OPEN:
  66. if(conn->package_window <= 0) {
  67. /* XXX this is still getting called rarely :( */
  68. log_fn(LOG_WARN,"called with package_window %d. Tell Roger.", conn->package_window);
  69. return 0;
  70. }
  71. if(connection_edge_package_raw_inbuf(conn) < 0) {
  72. connection_edge_end(conn, END_STREAM_REASON_MISC, conn->cpath_layer);
  73. connection_mark_for_close(conn);
  74. return -1;
  75. }
  76. return 0;
  77. case EXIT_CONN_STATE_CONNECTING:
  78. case AP_CONN_STATE_RENDDESC_WAIT:
  79. case AP_CONN_STATE_CIRCUIT_WAIT:
  80. case AP_CONN_STATE_CONNECT_WAIT:
  81. log_fn(LOG_INFO,"data from edge while in '%s' state. Leaving it on buffer.",
  82. conn_state_to_string[conn->type][conn->state]);
  83. return 0;
  84. }
  85. log_fn(LOG_WARN,"Got unexpected state %d. Closing.",conn->state);
  86. connection_edge_end(conn, END_STREAM_REASON_MISC, conn->cpath_layer);
  87. connection_mark_for_close(conn);
  88. return -1;
  89. }
  90. /** This edge needs to be closed, because its circuit has closed.
  91. * Mark it for close and return 0.
  92. */
  93. int connection_edge_destroy(uint16_t circ_id, connection_t *conn) {
  94. tor_assert(conn->type == CONN_TYPE_AP || conn->type == CONN_TYPE_EXIT);
  95. if(conn->marked_for_close)
  96. return 0; /* already marked; probably got an 'end' */
  97. log_fn(LOG_INFO,"CircID %d: At an edge. Marking connection for close.",
  98. circ_id);
  99. conn->has_sent_end = 1; /* we're closing the circuit, nothing to send to */
  100. connection_mark_for_close(conn);
  101. conn->hold_open_until_flushed = 1;
  102. return 0;
  103. }
  104. /** Send a relay end cell from stream <b>conn</b> to conn's circuit,
  105. * with a destination of cpath_layer. (If cpath_layer is NULL, the
  106. * destination is the circuit's origin.) Mark the relay end cell as
  107. * closing because of <b>reason</b>.
  108. *
  109. * Return -1 if this function has already been called on this conn,
  110. * else return 0.
  111. */
  112. int
  113. connection_edge_end(connection_t *conn, char reason, crypt_path_t *cpath_layer)
  114. {
  115. char payload[5];
  116. int payload_len=1;
  117. circuit_t *circ;
  118. if(conn->has_sent_end) {
  119. log_fn(LOG_WARN,"It appears I've already sent the end. Are you calling me twice?");
  120. return -1;
  121. }
  122. payload[0] = reason;
  123. if(reason == END_STREAM_REASON_EXITPOLICY) {
  124. /* this is safe even for rend circs, because they never fail
  125. * because of exitpolicy */
  126. set_uint32(payload+1, htonl(conn->addr));
  127. payload_len += 4;
  128. }
  129. circ = circuit_get_by_conn(conn);
  130. if(circ && !circ->marked_for_close) {
  131. log_fn(LOG_DEBUG,"Marking conn (fd %d) and sending end.",conn->s);
  132. connection_edge_send_command(conn, circ, RELAY_COMMAND_END,
  133. payload, payload_len, cpath_layer);
  134. } else {
  135. log_fn(LOG_DEBUG,"Marking conn (fd %d); no circ to send end.",conn->s);
  136. }
  137. conn->has_sent_end = 1;
  138. return 0;
  139. }
  140. /** Connection <b>conn</b> has finished writing and has no bytes left on
  141. * its outbuf.
  142. *
  143. * If it's in state 'open', stop writing, consider responding with a
  144. * sendme, and return.
  145. * Otherwise, stop writing and return.
  146. *
  147. * If <b>conn</b> is broken, mark it for close and return -1, else
  148. * return 0.
  149. */
  150. int connection_edge_finished_flushing(connection_t *conn) {
  151. tor_assert(conn);
  152. tor_assert(conn->type == CONN_TYPE_AP || conn->type == CONN_TYPE_EXIT);
  153. switch(conn->state) {
  154. case AP_CONN_STATE_OPEN:
  155. case EXIT_CONN_STATE_OPEN:
  156. connection_stop_writing(conn);
  157. connection_edge_consider_sending_sendme(conn);
  158. return 0;
  159. case AP_CONN_STATE_SOCKS_WAIT:
  160. case AP_CONN_STATE_RENDDESC_WAIT:
  161. case AP_CONN_STATE_CIRCUIT_WAIT:
  162. case AP_CONN_STATE_CONNECT_WAIT:
  163. connection_stop_writing(conn);
  164. return 0;
  165. default:
  166. log_fn(LOG_WARN,"BUG: called in unexpected state %d.", conn->state);
  167. return -1;
  168. }
  169. return 0;
  170. }
  171. /** Connected handler for exit connections: start writing pending
  172. * data, deliver 'CONNECTED' relay cells as appropriate, and check
  173. * any pending data that may have been received. */
  174. int connection_edge_finished_connecting(connection_t *conn)
  175. {
  176. unsigned char connected_payload[4];
  177. tor_assert(conn);
  178. tor_assert(conn->type == CONN_TYPE_EXIT);
  179. tor_assert(conn->state == EXIT_CONN_STATE_CONNECTING);
  180. log_fn(LOG_INFO,"Exit connection to %s:%u established.",
  181. conn->address,conn->port);
  182. conn->state = EXIT_CONN_STATE_OPEN;
  183. connection_watch_events(conn, POLLIN); /* stop writing, continue reading */
  184. if(connection_wants_to_flush(conn)) /* in case there are any queued relay cells */
  185. connection_start_writing(conn);
  186. /* deliver a 'connected' relay cell back through the circuit. */
  187. if(connection_edge_is_rendezvous_stream(conn)) {
  188. if(connection_edge_send_command(conn, circuit_get_by_conn(conn),
  189. RELAY_COMMAND_CONNECTED, NULL, 0, conn->cpath_layer) < 0)
  190. return 0; /* circuit is closed, don't continue */
  191. } else {
  192. *(uint32_t*)connected_payload = htonl(conn->addr);
  193. if(connection_edge_send_command(conn, circuit_get_by_conn(conn),
  194. RELAY_COMMAND_CONNECTED, connected_payload, 4, conn->cpath_layer) < 0)
  195. return 0; /* circuit is closed, don't continue */
  196. }
  197. tor_assert(conn->package_window > 0);
  198. return connection_edge_process_inbuf(conn); /* in case the server has written anything */
  199. }
  200. /** How many times do we retry a general-purpose stream (detach it from
  201. * one circuit and try another, after we wait a while with no 'connected'
  202. * cell) before giving up?
  203. */
  204. #define MAX_STREAM_RETRIES 4
  205. /** Find all general-purpose AP streams in state connect_wait that sent
  206. * their begin cell >=15 seconds ago. Detach from their current circuit,
  207. * and mark their current circuit as unsuitable for new streams. Then call
  208. * connection_ap_handshake_attach_circuit() to attach to a new circuit (if
  209. * available) or launch a new one.
  210. *
  211. * For rendezvous streams, simply give up after 45 seconds (with no
  212. * retry attempt).
  213. */
  214. void connection_ap_expire_beginning(void) {
  215. connection_t **carray;
  216. connection_t *conn;
  217. circuit_t *circ;
  218. int n, i;
  219. time_t now = time(NULL);
  220. get_connection_array(&carray, &n);
  221. for (i = 0; i < n; ++i) {
  222. conn = carray[i];
  223. if (conn->type != CONN_TYPE_AP ||
  224. conn->state != AP_CONN_STATE_CONNECT_WAIT)
  225. continue;
  226. if (now - conn->timestamp_lastread < 15)
  227. continue;
  228. conn->num_retries++;
  229. circ = circuit_get_by_conn(conn);
  230. if(!circ) { /* it's vanished? */
  231. log_fn(LOG_INFO,"Conn is in connect-wait, but lost its circ.");
  232. connection_mark_for_close(conn);
  233. continue;
  234. }
  235. if(circ->purpose == CIRCUIT_PURPOSE_C_REND_JOINED) {
  236. if (now - conn->timestamp_lastread > 45) {
  237. log_fn(LOG_WARN,"Rend stream is %d seconds late. Giving up.",
  238. (int)(now - conn->timestamp_lastread));
  239. connection_edge_end(conn, END_STREAM_REASON_TIMEOUT, conn->cpath_layer);
  240. connection_mark_for_close(conn);
  241. }
  242. continue;
  243. }
  244. tor_assert(circ->purpose == CIRCUIT_PURPOSE_C_GENERAL);
  245. if(conn->num_retries >= MAX_STREAM_RETRIES) {
  246. log_fn(LOG_WARN,"Stream is %d seconds late. Giving up.",
  247. 15*conn->num_retries);
  248. circuit_log_path(LOG_WARN, circ);
  249. connection_edge_end(conn, END_STREAM_REASON_TIMEOUT, conn->cpath_layer);
  250. connection_mark_for_close(conn);
  251. } else {
  252. log_fn(LOG_WARN,"Stream is %d seconds late. Retrying.",
  253. (int)(now - conn->timestamp_lastread));
  254. circuit_log_path(LOG_WARN, circ);
  255. /* send an end down the circuit */
  256. connection_edge_end(conn, END_STREAM_REASON_TIMEOUT, conn->cpath_layer);
  257. /* un-mark it as ending, since we're going to reuse it */
  258. conn->has_sent_end = 0;
  259. /* move it back into 'pending' state. */
  260. conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
  261. circuit_detach_stream(circ, conn);
  262. /* kludge to make us not try this circuit again, yet to allow
  263. * current streams on it to survive if they can: make it
  264. * unattractive to use for new streams */
  265. tor_assert(circ->timestamp_dirty);
  266. circ->timestamp_dirty -= options.NewCircuitPeriod;
  267. /* give our stream another 15 seconds to try */
  268. conn->timestamp_lastread += 15;
  269. /* attaching to a dirty circuit is fine */
  270. if(connection_ap_handshake_attach_circuit(conn)<0) {
  271. /* it will never work */
  272. /* Don't need to send end -- we're not connected */
  273. conn->has_sent_end = 1;
  274. connection_mark_for_close(conn);
  275. }
  276. } /* end if max_retries */
  277. } /* end for */
  278. }
  279. /** Tell any AP streamss that are waiting for a new circuit that one is
  280. * available.
  281. */
  282. void connection_ap_attach_pending(void)
  283. {
  284. connection_t **carray;
  285. connection_t *conn;
  286. int n, i;
  287. get_connection_array(&carray, &n);
  288. for (i = 0; i < n; ++i) {
  289. conn = carray[i];
  290. if (conn->marked_for_close ||
  291. conn->type != CONN_TYPE_AP ||
  292. conn->state != AP_CONN_STATE_CIRCUIT_WAIT)
  293. continue;
  294. if(connection_ap_handshake_attach_circuit(conn) < 0) {
  295. /* -1 means it will never work */
  296. /* Don't send end; there is no 'other side' yet */
  297. conn->has_sent_end = 1;
  298. connection_mark_for_close(conn);
  299. }
  300. }
  301. }
  302. /** connection_edge_process_inbuf() found a conn in state
  303. * socks_wait. See if conn->inbuf has the right bytes to proceed with
  304. * the socks handshake.
  305. *
  306. * If the handshake is complete, and it's for a general circuit, then
  307. * try to attach it to a circuit (or launch one as needed). If it's for
  308. * a rendezvous circuit, then fetch a rendezvous descriptor first (or
  309. * attach/launch a circuit if the rendezvous descriptor is already here
  310. * and fresh enough).
  311. *
  312. * Return -1 if an unexpected error with conn (and it should be marked
  313. * for close), else return 0.
  314. */
  315. static int connection_ap_handshake_process_socks(connection_t *conn) {
  316. socks_request_t *socks;
  317. int sockshere;
  318. tor_assert(conn);
  319. tor_assert(conn->type == CONN_TYPE_AP);
  320. tor_assert(conn->state == AP_CONN_STATE_SOCKS_WAIT);
  321. tor_assert(conn->socks_request);
  322. socks = conn->socks_request;
  323. log_fn(LOG_DEBUG,"entered.");
  324. sockshere = fetch_from_buf_socks(conn->inbuf, socks);
  325. if(sockshere == -1 || sockshere == 0) {
  326. if(socks->replylen) { /* we should send reply back */
  327. log_fn(LOG_DEBUG,"reply is already set for us. Using it.");
  328. connection_ap_handshake_socks_reply(conn, socks->reply, socks->replylen, 0);
  329. } else if(sockshere == -1) { /* send normal reject */
  330. log_fn(LOG_WARN,"Fetching socks handshake failed. Closing.");
  331. connection_ap_handshake_socks_reply(conn, NULL, 0, 0);
  332. } else {
  333. log_fn(LOG_DEBUG,"socks handshake not all here yet.");
  334. }
  335. if (sockshere == -1)
  336. socks->has_finished = 1;
  337. return sockshere;
  338. } /* else socks handshake is done, continue processing */
  339. if (socks->command == SOCKS_COMMAND_RESOLVE) {
  340. uint32_t answer;
  341. /* Reply to resolves immediately if we can. */
  342. if (strlen(socks->address) > RELAY_PAYLOAD_SIZE) {
  343. connection_ap_handshake_socks_resolved(conn,RESOLVED_TYPE_ERROR,0,NULL);
  344. conn->socks_request->has_finished = 1;
  345. conn->has_sent_end = 1;
  346. connection_mark_for_close(conn);
  347. return 0;
  348. }
  349. answer = htonl(client_dns_lookup_entry(socks->address));
  350. if (answer) {
  351. connection_ap_handshake_socks_resolved(conn,RESOLVED_TYPE_IPV4,4,
  352. (char*)&answer);
  353. conn->socks_request->has_finished = 1;
  354. conn->has_sent_end = 1;
  355. connection_mark_for_close(conn);
  356. return 0;
  357. }
  358. }
  359. /* this call _modifies_ socks->address iff it's a hidden-service request */
  360. if (rend_parse_rendezvous_address(socks->address) < 0) {
  361. /* normal request */
  362. conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
  363. return connection_ap_handshake_attach_circuit(conn);
  364. } else {
  365. /* it's a hidden-service request */
  366. /* XXX008 what does it mean to socks-resolve a hidden service? should
  367. * we fail those right here? */
  368. rend_cache_entry_t *entry;
  369. int r;
  370. strcpy(conn->rend_query, socks->address); /* this strcpy is safe -RD */
  371. log_fn(LOG_INFO,"Got a hidden service request for ID '%s'", conn->rend_query);
  372. /* see if we already have it cached */
  373. r = rend_cache_lookup_entry(conn->rend_query, &entry);
  374. if(r<0) {
  375. log_fn(LOG_WARN,"Invalid service descriptor %s", conn->rend_query);
  376. return -1;
  377. }
  378. if(r==0) {
  379. conn->state = AP_CONN_STATE_RENDDESC_WAIT;
  380. log_fn(LOG_INFO, "Unknown descriptor %s. Fetching.", conn->rend_query);
  381. rend_client_refetch_renddesc(conn->rend_query);
  382. return 0;
  383. }
  384. if(r>0) {
  385. #define NUM_SECONDS_BEFORE_REFETCH (60*15)
  386. if(time(NULL) - entry->received < NUM_SECONDS_BEFORE_REFETCH) {
  387. conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
  388. log_fn(LOG_INFO, "Descriptor is here and fresh enough. Great.");
  389. return connection_ap_handshake_attach_circuit(conn);
  390. } else {
  391. conn->state = AP_CONN_STATE_RENDDESC_WAIT;
  392. log_fn(LOG_INFO, "Stale descriptor %s. Refetching.", conn->rend_query);
  393. rend_client_refetch_renddesc(conn->rend_query);
  394. return 0;
  395. }
  396. }
  397. }
  398. return 0;
  399. }
  400. /** Iterate over the two bytes of stream_id until we get one that is not
  401. * already in use; return it. Return 0 if can't get a unique stream_id.
  402. */
  403. static uint16_t get_unique_stream_id_by_circ(circuit_t *circ) {
  404. connection_t *tmpconn;
  405. uint16_t test_stream_id;
  406. uint32_t attempts=0;
  407. again:
  408. test_stream_id = circ->next_stream_id++;
  409. if(++attempts > 1<<16) {
  410. /* Make sure we don't loop forever if all stream_id's are used. */
  411. log_fn(LOG_WARN,"No unused stream IDs. Failing.");
  412. return 0;
  413. }
  414. if (test_stream_id == 0)
  415. goto again;
  416. for(tmpconn = circ->p_streams; tmpconn; tmpconn=tmpconn->next_stream)
  417. if(tmpconn->stream_id == test_stream_id)
  418. goto again;
  419. return test_stream_id;
  420. }
  421. /** Write a relay begin cell, using destaddr and destport from ap_conn's
  422. * socks_request field, and send it down circ.
  423. *
  424. * If ap_conn is broken, mark it for close and return -1. Else return 0.
  425. */
  426. int connection_ap_handshake_send_begin(connection_t *ap_conn, circuit_t *circ)
  427. {
  428. char payload[CELL_PAYLOAD_SIZE];
  429. int payload_len;
  430. struct in_addr in;
  431. const char *string_addr;
  432. tor_assert(ap_conn->type == CONN_TYPE_AP);
  433. tor_assert(ap_conn->state == AP_CONN_STATE_CIRCUIT_WAIT);
  434. tor_assert(ap_conn->socks_request);
  435. ap_conn->stream_id = get_unique_stream_id_by_circ(circ);
  436. if (ap_conn->stream_id==0) {
  437. /* Don't send end: there is no 'other side' yet */
  438. ap_conn->has_sent_end = 1;
  439. connection_mark_for_close(ap_conn);
  440. circuit_mark_for_close(circ);
  441. return -1;
  442. }
  443. if(circ->purpose == CIRCUIT_PURPOSE_C_GENERAL) {
  444. in.s_addr = htonl(client_dns_lookup_entry(ap_conn->socks_request->address));
  445. string_addr = in.s_addr ? inet_ntoa(in) : NULL;
  446. snprintf(payload,RELAY_PAYLOAD_SIZE,
  447. "%s:%d",
  448. string_addr ? string_addr : ap_conn->socks_request->address,
  449. ap_conn->socks_request->port);
  450. } else {
  451. snprintf(payload,RELAY_PAYLOAD_SIZE,
  452. ":%d", ap_conn->socks_request->port);
  453. }
  454. payload_len = strlen(payload)+1;
  455. log_fn(LOG_DEBUG,"Sending relay cell to begin stream %d.",ap_conn->stream_id);
  456. if(connection_edge_send_command(ap_conn, circ, RELAY_COMMAND_BEGIN,
  457. payload, payload_len, ap_conn->cpath_layer) < 0)
  458. return -1; /* circuit is closed, don't continue */
  459. ap_conn->package_window = STREAMWINDOW_START;
  460. ap_conn->deliver_window = STREAMWINDOW_START;
  461. ap_conn->state = AP_CONN_STATE_CONNECT_WAIT;
  462. log_fn(LOG_INFO,"Address/port sent, ap socket %d, n_circ_id %d",ap_conn->s,circ->n_circ_id);
  463. return 0;
  464. }
  465. /** Write a relay resolve cell, using destaddr and destport from ap_conn's
  466. * socks_request field, and send it down circ.
  467. *
  468. * If ap_conn is broken, mark it for close and return -1. Else return 0.
  469. */
  470. int connection_ap_handshake_send_resolve(connection_t *ap_conn, circuit_t *circ)
  471. {
  472. int payload_len;
  473. const char *string_addr;
  474. tor_assert(ap_conn->type == CONN_TYPE_AP);
  475. tor_assert(ap_conn->state == AP_CONN_STATE_CIRCUIT_WAIT);
  476. tor_assert(ap_conn->socks_request);
  477. tor_assert(ap_conn->socks_request->command == SOCKS_COMMAND_RESOLVE);
  478. tor_assert(circ->purpose == CIRCUIT_PURPOSE_C_GENERAL);
  479. ap_conn->stream_id = get_unique_stream_id_by_circ(circ);
  480. if (ap_conn->stream_id==0) {
  481. /* Don't send end: there is no 'other side' yet */
  482. ap_conn->has_sent_end = 1;
  483. connection_mark_for_close(ap_conn);
  484. circuit_mark_for_close(circ);
  485. return -1;
  486. }
  487. string_addr = ap_conn->socks_request->address;
  488. payload_len = strlen(string_addr);
  489. tor_assert(strlen(string_addr) <= RELAY_PAYLOAD_SIZE);
  490. log_fn(LOG_DEBUG,"Sending relay cell to begin stream %d.",ap_conn->stream_id);
  491. if(connection_edge_send_command(ap_conn, circ, RELAY_COMMAND_RESOLVE,
  492. string_addr, payload_len, ap_conn->cpath_layer) < 0)
  493. return -1; /* circuit is closed, don't continue */
  494. ap_conn->state = AP_CONN_STATE_RESOLVE_WAIT;
  495. log_fn(LOG_INFO,"Address sent for resolve, ap socket %d, n_circ_id %d",ap_conn->s,circ->n_circ_id);
  496. return 0;
  497. }
  498. /** Make an AP connection_t, do a socketpair and attach one side
  499. * to the conn, connection_add it, initialize it to circuit_wait,
  500. * and call connection_ap_handshake_attach_circuit(conn) on it.
  501. *
  502. * Return the other end of the socketpair, or -1 if error.
  503. */
  504. int connection_ap_make_bridge(char *address, uint16_t port) {
  505. int fd[2];
  506. connection_t *conn;
  507. log_fn(LOG_INFO,"Making AP bridge to %s:%d ...",address,port);
  508. if(tor_socketpair(AF_UNIX, SOCK_STREAM, 0, fd) < 0) {
  509. log(LOG_WARN,"Couldn't construct socketpair (%s). Network down? Delaying.",
  510. tor_socket_strerror(tor_socket_errno(-1)));
  511. return -1;
  512. }
  513. set_socket_nonblocking(fd[0]);
  514. set_socket_nonblocking(fd[1]);
  515. conn = connection_new(CONN_TYPE_AP);
  516. conn->s = fd[0];
  517. /* populate conn->socks_request */
  518. /* leave version at zero, so the socks_reply is empty */
  519. conn->socks_request->socks_version = 0;
  520. conn->socks_request->has_finished = 0; /* waiting for 'connected' */
  521. strcpy(conn->socks_request->address, address);
  522. conn->socks_request->port = port;
  523. conn->socks_request->command = SOCKS_COMMAND_CONNECT;
  524. conn->address = tor_strdup("(local bridge)");
  525. conn->addr = ntohs(0);
  526. conn->port = 0;
  527. if(connection_add(conn) < 0) { /* no space, forget it */
  528. connection_free(conn); /* this closes fd[0] */
  529. tor_close_socket(fd[1]);
  530. return -1;
  531. }
  532. conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
  533. connection_start_reading(conn);
  534. /* attaching to a dirty circuit is fine */
  535. if (connection_ap_handshake_attach_circuit(conn) < 0) {
  536. conn->has_sent_end = 1; /* no circ to send to */
  537. connection_mark_for_close(conn);
  538. tor_close_socket(fd[1]);
  539. return -1;
  540. }
  541. log_fn(LOG_INFO,"... AP bridge created and connected.");
  542. return fd[1];
  543. }
  544. void connection_ap_handshake_socks_resolved(connection_t *conn,
  545. int answer_type,
  546. int answer_len,
  547. const char *answer)
  548. {
  549. char buf[256];
  550. int replylen;
  551. if (answer_type == RESOLVED_TYPE_IPV4) {
  552. uint32_t a = get_uint32(answer);
  553. client_dns_set_entry(conn->socks_request->address, ntohl(a));
  554. }
  555. if (conn->socks_request->socks_version == 4) {
  556. buf[0] = 0x00; /* version */
  557. if (answer_type == RESOLVED_TYPE_IPV4 && answer_len == 4) {
  558. buf[1] = 90; /* "Granted" */
  559. set_uint16(buf+2, 0);
  560. memcpy(buf+4, answer, 4); /* address */
  561. replylen = SOCKS4_NETWORK_LEN;
  562. } else {
  563. buf[1] = 91; /* "error" */
  564. memset(buf+2, 0, 6);
  565. replylen = SOCKS4_NETWORK_LEN;
  566. }
  567. } else {
  568. /* SOCKS5 */
  569. buf[0] = 0x05; /* version */
  570. if (answer_type == RESOLVED_TYPE_IPV4 && answer_len == 4) {
  571. buf[1] = 0; /* succeeded */
  572. buf[2] = 0; /* reserved */
  573. buf[3] = 0x01; /* IPv4 address type */
  574. memcpy(buf+4, answer, 4); /* address */
  575. set_uint16(buf+8, 0); /* port == 0. */
  576. replylen = 10;
  577. } else if (answer_type == RESOLVED_TYPE_IPV6 && answer_len == 16) {
  578. buf[1] = 0; /* succeeded */
  579. buf[2] = 0; /* reserved */
  580. buf[3] = 0x04; /* IPv6 address type */
  581. memcpy(buf+4, answer, 16); /* address */
  582. set_uint16(buf+20, 0); /* port == 0. */
  583. replylen = 22;
  584. } else {
  585. buf[1] = 0x04; /* host unreachable */
  586. memset(buf+2, 0, 8);
  587. replylen = 10;
  588. }
  589. }
  590. connection_ap_handshake_socks_reply(conn, buf, replylen,
  591. answer_type == RESOLVED_TYPE_IPV4 ||
  592. answer_type == RESOLVED_TYPE_IPV6);
  593. }
  594. /** Send a socks reply to stream <b>conn</b>, using the appropriate
  595. * socks version, etc.
  596. *
  597. * If <b>reply</b> is defined, then write <b>replylen</b> bytes of it
  598. * to conn and return.
  599. *
  600. * Otherwise, send back a reply based on whether <b>success</b> is 1 or 0.
  601. */
  602. void connection_ap_handshake_socks_reply(connection_t *conn, char *reply,
  603. int replylen, int success) {
  604. char buf[256];
  605. if(replylen) { /* we already have a reply in mind */
  606. connection_write_to_buf(reply, replylen, conn);
  607. return;
  608. }
  609. tor_assert(conn->socks_request);
  610. if(conn->socks_request->socks_version == 4) {
  611. memset(buf,0,SOCKS4_NETWORK_LEN);
  612. #define SOCKS4_GRANTED 90
  613. #define SOCKS4_REJECT 91
  614. buf[1] = (success ? SOCKS4_GRANTED : SOCKS4_REJECT);
  615. /* leave version, destport, destip zero */
  616. connection_write_to_buf(buf, SOCKS4_NETWORK_LEN, conn);
  617. }
  618. if(conn->socks_request->socks_version == 5) {
  619. buf[0] = 5; /* version 5 */
  620. #define SOCKS5_SUCCESS 0
  621. #define SOCKS5_GENERIC_ERROR 1
  622. buf[1] = success ? SOCKS5_SUCCESS : SOCKS5_GENERIC_ERROR;
  623. buf[2] = 0;
  624. buf[3] = 1; /* ipv4 addr */
  625. memset(buf+4,0,6); /* Set external addr/port to 0.
  626. The spec doesn't seem to say what to do here. -RD */
  627. connection_write_to_buf(buf,10,conn);
  628. }
  629. /* If socks_version isn't 4 or 5, don't send anything.
  630. * This can happen in the case of AP bridges. */
  631. return;
  632. }
  633. /** A relay 'begin' cell has arrived, and either we are an exit hop
  634. * for the circuit, or we are the origin and it is a rendezvous begin.
  635. *
  636. * Launch a new exit connection and initialize things appropriately.
  637. *
  638. * If it's a rendezvous stream, call connection_exit_connect() on
  639. * it.
  640. *
  641. * For general streams, call dns_resolve() on it first, and only call
  642. * connection_exit_connect() if the dns answer is already known.
  643. *
  644. * Note that we don't call connection_add() on the new stream! We wait
  645. * for connection_exit_connect() to do that.
  646. *
  647. * Return -1 if we want to tear down <b>circ</b>. Else return 0.
  648. */
  649. int connection_exit_begin_conn(cell_t *cell, circuit_t *circ) {
  650. connection_t *n_stream;
  651. relay_header_t rh;
  652. char *colon;
  653. assert_circuit_ok(circ);
  654. relay_header_unpack(&rh, cell->payload);
  655. /* XXX currently we don't send an end cell back if we drop the
  656. * begin because it's malformed.
  657. */
  658. if(!memchr(cell->payload+RELAY_HEADER_SIZE, 0, rh.length)) {
  659. log_fn(LOG_WARN,"relay begin cell has no \\0. Dropping.");
  660. return 0;
  661. }
  662. colon = strchr(cell->payload+RELAY_HEADER_SIZE, ':');
  663. if(!colon) {
  664. log_fn(LOG_WARN,"relay begin cell has no colon. Dropping.");
  665. return 0;
  666. }
  667. *colon = 0;
  668. if(!atoi(colon+1)) { /* bad port */
  669. log_fn(LOG_WARN,"relay begin cell has invalid port. Dropping.");
  670. return 0;
  671. }
  672. log_fn(LOG_DEBUG,"Creating new exit connection.");
  673. n_stream = connection_new(CONN_TYPE_EXIT);
  674. n_stream->purpose = EXIT_PURPOSE_CONNECT;
  675. n_stream->stream_id = rh.stream_id;
  676. n_stream->port = atoi(colon+1);
  677. /* leave n_stream->s at -1, because it's not yet valid */
  678. n_stream->package_window = STREAMWINDOW_START;
  679. n_stream->deliver_window = STREAMWINDOW_START;
  680. if(circ->purpose == CIRCUIT_PURPOSE_S_REND_JOINED) {
  681. log_fn(LOG_DEBUG,"begin is for rendezvous. configuring stream.");
  682. n_stream->address = tor_strdup("(rendezvous)");
  683. n_stream->state = EXIT_CONN_STATE_CONNECTING;
  684. strcpy(n_stream->rend_query, circ->rend_query);
  685. tor_assert(n_stream->rend_query[0]);
  686. assert_circuit_ok(circ);
  687. if(rend_service_set_connection_addr_port(n_stream, circ) < 0) {
  688. log_fn(LOG_INFO,"Didn't find rendezvous service (port %d)",n_stream->port);
  689. connection_edge_end(n_stream, END_STREAM_REASON_EXITPOLICY, n_stream->cpath_layer);
  690. connection_free(n_stream);
  691. circuit_mark_for_close(circ); /* knock the whole thing down, somebody screwed up */
  692. return 0;
  693. }
  694. assert_circuit_ok(circ);
  695. log_fn(LOG_DEBUG,"Finished assigning addr/port");
  696. n_stream->cpath_layer = circ->cpath->prev; /* link it */
  697. /* add it into the linked list of n_streams on this circuit */
  698. n_stream->next_stream = circ->n_streams;
  699. circ->n_streams = n_stream;
  700. assert_circuit_ok(circ);
  701. connection_exit_connect(n_stream);
  702. return 0;
  703. }
  704. n_stream->address = tor_strdup(cell->payload + RELAY_HEADER_SIZE);
  705. n_stream->state = EXIT_CONN_STATE_RESOLVEFAILED;
  706. /* default to failed, change in dns_resolve if it turns out not to fail */
  707. /* send it off to the gethostbyname farm */
  708. switch(dns_resolve(n_stream)) {
  709. case 1: /* resolve worked */
  710. /* add it into the linked list of n_streams on this circuit */
  711. n_stream->next_stream = circ->n_streams;
  712. circ->n_streams = n_stream;
  713. assert_circuit_ok(circ);
  714. connection_exit_connect(n_stream);
  715. return 0;
  716. case -1: /* resolve failed */
  717. log_fn(LOG_INFO,"Resolve failed (%s).", n_stream->address);
  718. connection_edge_end(n_stream, END_STREAM_REASON_RESOLVEFAILED, n_stream->cpath_layer);
  719. connection_free(n_stream);
  720. break;
  721. case 0: /* resolve added to pending list */
  722. /* add it into the linked list of resolving_streams on this circuit */
  723. n_stream->next_stream = circ->resolving_streams;
  724. circ->resolving_streams = n_stream;
  725. assert_circuit_ok(circ);
  726. ;
  727. }
  728. return 0;
  729. }
  730. /**
  731. * Called when we receive a RELAY_RESOLVE cell 'cell' along the circuit 'circ';
  732. * begin resolving the hostname, and (eventually) reply with a RESOLVED cell.
  733. */
  734. int connection_exit_begin_resolve(cell_t *cell, circuit_t *circ) {
  735. connection_t *dummy_conn;
  736. relay_header_t rh;
  737. assert_circuit_ok(circ);
  738. relay_header_unpack(&rh, cell->payload);
  739. /* This 'dummy_conn' only exists to remember the stream ID
  740. * associated with the resolve request; and to make the
  741. * implementation of dns.c more uniform. (We really only need to
  742. * remember the circuit, the stream ID, and the hostname to be
  743. * resolved; but if we didn't store them in a connection like this,
  744. * the housekeeping in dns.c would get way more complicated.)
  745. */
  746. dummy_conn = connection_new(CONN_TYPE_EXIT);
  747. dummy_conn->stream_id = rh.stream_id;
  748. dummy_conn->address = tor_strndup(cell->payload+RELAY_HEADER_SIZE,
  749. rh.length);
  750. dummy_conn->port = 0;
  751. dummy_conn->state = EXIT_CONN_STATE_RESOLVEFAILED;
  752. dummy_conn->purpose = EXIT_PURPOSE_RESOLVE;
  753. /* send it off to the gethostbyname farm */
  754. switch(dns_resolve(dummy_conn)) {
  755. case 1: /* resolve worked; resolved cell was sent. */
  756. connection_free(dummy_conn);
  757. return 0;
  758. case -1: /* resolve failed; resolved cell was sent. */
  759. log_fn(LOG_INFO,"Resolve failed (%s).",dummy_conn->address);
  760. connection_free(dummy_conn);
  761. break;
  762. case 0: /* resolve added to pending list */
  763. /* add it into the linked list of resolving_streams on this circuit */
  764. dummy_conn->next_stream = circ->resolving_streams;
  765. circ->resolving_streams = dummy_conn;
  766. assert_circuit_ok(circ);
  767. ;
  768. }
  769. return 0;
  770. }
  771. /** Connect to conn's specified addr and port. If it worked, conn
  772. * has now been added to the connection_array.
  773. *
  774. * Send back a connected cell. Include the resolved IP of the destination
  775. * address, but <em>only</em> if it's a general exit stream. (Rendezvous
  776. * streams must not reveal what IP they connected to.)
  777. */
  778. void connection_exit_connect(connection_t *conn) {
  779. unsigned char connected_payload[4];
  780. if (!connection_edge_is_rendezvous_stream(conn) &&
  781. router_compare_to_my_exit_policy(conn) == ADDR_POLICY_REJECTED) {
  782. log_fn(LOG_INFO,"%s:%d failed exit policy. Closing.", conn->address, conn->port);
  783. connection_edge_end(conn, END_STREAM_REASON_EXITPOLICY, conn->cpath_layer);
  784. circuit_detach_stream(circuit_get_by_conn(conn), conn);
  785. connection_free(conn);
  786. return;
  787. }
  788. log_fn(LOG_DEBUG,"about to try connecting");
  789. switch(connection_connect(conn, conn->address, conn->addr, conn->port)) {
  790. case -1:
  791. connection_edge_end(conn, END_STREAM_REASON_CONNECTFAILED, conn->cpath_layer);
  792. circuit_detach_stream(circuit_get_by_conn(conn), conn);
  793. connection_free(conn);
  794. return;
  795. case 0:
  796. conn->state = EXIT_CONN_STATE_CONNECTING;
  797. connection_watch_events(conn, POLLOUT | POLLIN | POLLERR);
  798. /* writable indicates finish, readable indicates broken link,
  799. error indicates broken link in windowsland. */
  800. return;
  801. /* case 1: fall through */
  802. }
  803. conn->state = EXIT_CONN_STATE_OPEN;
  804. if(connection_wants_to_flush(conn)) { /* in case there are any queued data cells */
  805. log_fn(LOG_WARN,"tell roger: newly connected conn had data waiting!");
  806. // connection_start_writing(conn);
  807. }
  808. // connection_process_inbuf(conn);
  809. connection_watch_events(conn, POLLIN);
  810. /* also, deliver a 'connected' cell back through the circuit. */
  811. if(connection_edge_is_rendezvous_stream(conn)) { /* rendezvous stream */
  812. /* don't send an address back! */
  813. connection_edge_send_command(conn, circuit_get_by_conn(conn), RELAY_COMMAND_CONNECTED,
  814. NULL, 0, conn->cpath_layer);
  815. } else { /* normal stream */
  816. *(uint32_t*)connected_payload = htonl(conn->addr);
  817. connection_edge_send_command(conn, circuit_get_by_conn(conn), RELAY_COMMAND_CONNECTED,
  818. connected_payload, 4, conn->cpath_layer);
  819. }
  820. }
  821. /** Return 1 if <b>conn</b> is a rendezvous stream, or 0 if
  822. * it is a general stream.
  823. */
  824. int connection_edge_is_rendezvous_stream(connection_t *conn) {
  825. tor_assert(conn);
  826. if(*conn->rend_query) /* XXX */
  827. return 1;
  828. return 0;
  829. }
  830. /** Return 1 if router <b>exit</b> might allow stream <b>conn</b>
  831. * to exit from it, or 0 if it definitely will not allow it.
  832. * (We might be uncertain if conn's destination address has not yet been
  833. * resolved.)
  834. */
  835. int connection_ap_can_use_exit(connection_t *conn, routerinfo_t *exit)
  836. {
  837. uint32_t addr;
  838. tor_assert(conn);
  839. tor_assert(conn->type == CONN_TYPE_AP);
  840. tor_assert(conn->socks_request);
  841. log_fn(LOG_DEBUG,"considering nickname %s, for address %s / port %d:",
  842. exit->nickname, conn->socks_request->address,
  843. conn->socks_request->port);
  844. if (conn->socks_request->command == SOCKS_COMMAND_RESOLVE) {
  845. /* 0.0.7 servers and earlier don't support DNS resolution. There are no
  846. * ORs running code before 0.0.7, so we only worry about 0.0.7. Once all
  847. * servers are running 0.0.8, remove this check. XXX */
  848. return strncmp(exit->platform, "Tor 0.0.7", 9) ? 1 : 0;
  849. }
  850. addr = client_dns_lookup_entry(conn->socks_request->address);
  851. if(router_compare_addr_to_exit_policy(addr,
  852. conn->socks_request->port, exit->exit_policy) < 0)
  853. return 0;
  854. return 1;
  855. }
  856. /** A helper function for socks_policy_permits_address() below.
  857. *
  858. * Parse options.SocksPolicy in the same way that the exit policy
  859. * is parsed, and put the processed version in &socks_policy.
  860. * Ignore port specifiers.
  861. */
  862. static void parse_socks_policy(void)
  863. {
  864. struct exit_policy_t *n;
  865. if (socks_policy) {
  866. exit_policy_free(socks_policy);
  867. socks_policy = NULL;
  868. }
  869. config_parse_exit_policy(options.SocksPolicy, &socks_policy);
  870. /* ports aren't used. */
  871. for (n=socks_policy; n; n = n->next) {
  872. n->prt_min = 1;
  873. n->prt_max = 65535;
  874. }
  875. }
  876. /** Return 1 if <b>addr</b> is permitted to connect to our socks port,
  877. * based on <b>socks_policy</b>. Else return 0.
  878. */
  879. int socks_policy_permits_address(uint32_t addr)
  880. {
  881. int a;
  882. if (options.SocksPolicy && !socks_policy)
  883. parse_socks_policy();
  884. a = router_compare_addr_to_exit_policy(addr, 1, socks_policy);
  885. if (a==-1)
  886. return 0;
  887. else if (a==0)
  888. return 1;
  889. tor_assert(a==1);
  890. log_fn(LOG_WARN, "Got unexpected 'maybe' answer from socks policy");
  891. return 0;
  892. }
  893. /* ***** Client DNS code ***** */
  894. /* XXX Perhaps this should get merged with the dns.c code somehow. */
  895. /* XXX But we can't just merge them, because then nodes that act as
  896. * both OR and OP could be attacked: people could rig the dns cache
  897. * by answering funny things to stream begin requests, and later
  898. * other clients would reuse those funny addr's. Hm.
  899. */
  900. /** A client-side struct to remember the resolved IP (addr) for
  901. * a given address. These structs make up a tree, with client_dns_map
  902. * below as its root.
  903. */
  904. struct client_dns_entry {
  905. uint32_t addr; /**< The resolved IP of this entry. */
  906. time_t expires; /**< At what second does addr expire? */
  907. int n_failures; /**< How many times has this entry failed to resolve so far? */
  908. };
  909. /** How many elements are in the client dns cache currently? */
  910. static int client_dns_size = 0;
  911. /** The tree of client-side cached DNS resolves. */
  912. static strmap_t *client_dns_map = NULL;
  913. /** Initialize client_dns_map and client_dns_size. */
  914. void client_dns_init(void) {
  915. client_dns_map = strmap_new();
  916. client_dns_size = 0;
  917. }
  918. /** Return the client_dns_entry that corresponds to <b>address</b>.
  919. * If it's not there, allocate and return a new entry for <b>address</b>.
  920. */
  921. static struct client_dns_entry *
  922. _get_or_create_ent(const char *address)
  923. {
  924. struct client_dns_entry *ent;
  925. ent = strmap_get_lc(client_dns_map,address);
  926. if (!ent) {
  927. ent = tor_malloc_zero(sizeof(struct client_dns_entry));
  928. ent->expires = time(NULL)+MAX_DNS_ENTRY_AGE;
  929. strmap_set_lc(client_dns_map,address,ent);
  930. ++client_dns_size;
  931. }
  932. return ent;
  933. }
  934. /** Return the IP associated with <b>address</b>, if we know it
  935. * and it's still fresh enough. Otherwise return 0.
  936. */
  937. uint32_t client_dns_lookup_entry(const char *address)
  938. {
  939. struct client_dns_entry *ent;
  940. struct in_addr in;
  941. time_t now;
  942. tor_assert(address);
  943. if (tor_inet_aton(address, &in)) {
  944. log_fn(LOG_DEBUG, "Using static address %s (%08lX)", address,
  945. (unsigned long)ntohl(in.s_addr));
  946. return ntohl(in.s_addr);
  947. }
  948. ent = strmap_get_lc(client_dns_map,address);
  949. if (!ent || !ent->addr) {
  950. log_fn(LOG_DEBUG, "No entry found for address %s", address);
  951. return 0;
  952. } else {
  953. now = time(NULL);
  954. if (ent->expires < now) {
  955. log_fn(LOG_DEBUG, "Expired entry found for address %s", address);
  956. strmap_remove_lc(client_dns_map,address);
  957. tor_free(ent);
  958. --client_dns_size;
  959. return 0;
  960. }
  961. in.s_addr = htonl(ent->addr);
  962. log_fn(LOG_DEBUG, "Found cached entry for address %s: %s", address,
  963. inet_ntoa(in));
  964. return ent->addr;
  965. }
  966. }
  967. /** An attempt to resolve <b>address</b> failed at some OR.
  968. * Increment the number of resolve failures we have on record
  969. * for it, and then return that number.
  970. */
  971. int client_dns_incr_failures(const char *address)
  972. {
  973. struct client_dns_entry *ent;
  974. ent = _get_or_create_ent(address);
  975. ++ent->n_failures;
  976. log_fn(LOG_DEBUG,"Address %s now has %d resolve failures.",
  977. address, ent->n_failures);
  978. return ent->n_failures;
  979. }
  980. /** Record the fact that <b>address</b> resolved to <b>val</b>.
  981. * We can now use this in subsequent streams in client_dns_lookup_entry(),
  982. * so we can more correctly choose a router that will allow <b>address</b>
  983. * to exit from him.
  984. */
  985. void client_dns_set_entry(const char *address, uint32_t val)
  986. {
  987. struct client_dns_entry *ent;
  988. struct in_addr in;
  989. time_t now;
  990. tor_assert(address);
  991. tor_assert(val);
  992. if (tor_inet_aton(address, &in))
  993. return;
  994. now = time(NULL);
  995. ent = _get_or_create_ent(address);
  996. in.s_addr = htonl(val);
  997. log_fn(LOG_DEBUG, "Updating entry for address %s: %s", address,
  998. inet_ntoa(in));
  999. ent->addr = val;
  1000. ent->expires = now+MAX_DNS_ENTRY_AGE;
  1001. ent->n_failures = 0;
  1002. }
  1003. /** A helper function for client_dns_clean() below. If ent is too old,
  1004. * then remove it from the tree and return NULL, else return ent.
  1005. */
  1006. static void* _remove_if_expired(const char *addr,
  1007. struct client_dns_entry *ent,
  1008. time_t *nowp)
  1009. {
  1010. if (ent->expires < *nowp) {
  1011. --client_dns_size;
  1012. tor_free(ent);
  1013. return NULL;
  1014. } else {
  1015. return ent;
  1016. }
  1017. }
  1018. /** Clean out entries from the client-side DNS cache that were
  1019. * resolved long enough ago that they are no longer valid.
  1020. */
  1021. void client_dns_clean(void)
  1022. {
  1023. time_t now;
  1024. if(!client_dns_size)
  1025. return;
  1026. now = time(NULL);
  1027. strmap_foreach(client_dns_map, (strmap_foreach_fn)_remove_if_expired, &now);
  1028. }
  1029. /*
  1030. Local Variables:
  1031. mode:c
  1032. indent-tabs-mode:nil
  1033. c-basic-offset:2
  1034. End:
  1035. */