predict_ports.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. /* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  2. * Copyright (c) 2007-2019, The Tor Project, Inc. */
  3. /* See LICENSE for licensing information */
  4. /**
  5. * \file predict_ports.c
  6. * \brief Remember what ports we've needed so we can have circuits ready.
  7. *
  8. * Predicted ports are used by clients to remember how long it's been
  9. * since they opened an exit connection to each given target
  10. * port. Clients use this information in order to try to keep circuits
  11. * open to exit nodes that can connect to the ports that they care
  12. * about. (The predicted ports mechanism also handles predicted circuit
  13. * usage that _isn't_ port-specific, such as resolves, internal circuits,
  14. * and so on.)
  15. **/
  16. #include "core/or/or.h"
  17. #include "app/config/config.h"
  18. #include "core/or/channelpadding.h"
  19. #include "core/or/circuituse.h"
  20. #include "feature/relay/routermode.h"
  21. #include "feature/relay/selftest.h"
  22. #include "feature/stats/predict_ports.h"
  23. #include "lib/container/bitarray.h"
  24. #include "lib/time/tvdiff.h"
  25. static size_t predicted_ports_total_alloc = 0;
  26. static void predicted_ports_alloc(void);
  27. /** A single predicted port: used to remember which ports we've made
  28. * connections to, so that we can try to keep making circuits that can handle
  29. * those ports. */
  30. typedef struct predicted_port_t {
  31. /** The port we connected to */
  32. uint16_t port;
  33. /** The time at which we last used it */
  34. time_t time;
  35. } predicted_port_t;
  36. /** A list of port numbers that have been used recently. */
  37. static smartlist_t *predicted_ports_list=NULL;
  38. /** How long do we keep predicting circuits? */
  39. static time_t prediction_timeout=0;
  40. /** When was the last time we added a prediction entry (HS or port) */
  41. static time_t last_prediction_add_time=0;
  42. /**
  43. * How much time left until we stop predicting circuits?
  44. */
  45. int
  46. predicted_ports_prediction_time_remaining(time_t now)
  47. {
  48. time_t seconds_waited;
  49. time_t seconds_left;
  50. /* Protect against overflow of return value. This can happen if the clock
  51. * jumps backwards in time. Update the last prediction time (aka last
  52. * active time) to prevent it. This update is preferable to using monotonic
  53. * time because it prevents clock jumps into the past from simply causing
  54. * very long idle timeouts while the monotonic time stands still. */
  55. seconds_waited = time_diff(last_prediction_add_time, now);
  56. if (seconds_waited == TIME_MAX) {
  57. last_prediction_add_time = now;
  58. seconds_waited = 0;
  59. }
  60. /* Protect against underflow of the return value. This can happen for very
  61. * large periods of inactivity/system sleep. */
  62. if (seconds_waited > prediction_timeout)
  63. return 0;
  64. seconds_left = time_diff(seconds_waited, prediction_timeout);
  65. if (BUG(seconds_left == TIME_MAX))
  66. return INT_MAX;
  67. return (int)(seconds_left);
  68. }
  69. /** We just got an application request for a connection with
  70. * port <b>port</b>. Remember it for the future, so we can keep
  71. * some circuits open that will exit to this port.
  72. */
  73. static void
  74. add_predicted_port(time_t now, uint16_t port)
  75. {
  76. predicted_port_t *pp = tor_malloc(sizeof(predicted_port_t));
  77. // If the list is empty, re-randomize predicted ports lifetime
  78. if (!any_predicted_circuits(now)) {
  79. prediction_timeout =
  80. (time_t)channelpadding_get_circuits_available_timeout();
  81. }
  82. last_prediction_add_time = now;
  83. log_info(LD_CIRC,
  84. "New port prediction added. Will continue predictive circ building "
  85. "for %d more seconds.",
  86. predicted_ports_prediction_time_remaining(now));
  87. pp->port = port;
  88. pp->time = now;
  89. predicted_ports_total_alloc += sizeof(*pp);
  90. smartlist_add(predicted_ports_list, pp);
  91. }
  92. /** Remember that <b>port</b> has been asked for as of time <b>now</b>.
  93. * This is used for predicting what sorts of streams we'll make in the
  94. * future and making exit circuits to anticipate that.
  95. */
  96. void
  97. rep_hist_note_used_port(time_t now, uint16_t port)
  98. {
  99. tor_assert(predicted_ports_list);
  100. if (!port) /* record nothing */
  101. return;
  102. SMARTLIST_FOREACH_BEGIN(predicted_ports_list, predicted_port_t *, pp) {
  103. if (pp->port == port) {
  104. pp->time = now;
  105. last_prediction_add_time = now;
  106. log_info(LD_CIRC,
  107. "New port prediction added. Will continue predictive circ "
  108. "building for %d more seconds.",
  109. predicted_ports_prediction_time_remaining(now));
  110. return;
  111. }
  112. } SMARTLIST_FOREACH_END(pp);
  113. /* it's not there yet; we need to add it */
  114. add_predicted_port(now, port);
  115. }
  116. /** Return a newly allocated pointer to a list of uint16_t * for ports that
  117. * are likely to be asked for in the near future.
  118. */
  119. smartlist_t *
  120. rep_hist_get_predicted_ports(time_t now)
  121. {
  122. int predicted_circs_relevance_time;
  123. smartlist_t *out = smartlist_new();
  124. tor_assert(predicted_ports_list);
  125. predicted_circs_relevance_time = (int)prediction_timeout;
  126. /* clean out obsolete entries */
  127. SMARTLIST_FOREACH_BEGIN(predicted_ports_list, predicted_port_t *, pp) {
  128. if (pp->time + predicted_circs_relevance_time < now) {
  129. log_debug(LD_CIRC, "Expiring predicted port %d", pp->port);
  130. predicted_ports_total_alloc -= sizeof(predicted_port_t);
  131. tor_free(pp);
  132. SMARTLIST_DEL_CURRENT(predicted_ports_list, pp);
  133. } else {
  134. smartlist_add(out, tor_memdup(&pp->port, sizeof(uint16_t)));
  135. }
  136. } SMARTLIST_FOREACH_END(pp);
  137. return out;
  138. }
  139. /**
  140. * Take a list of uint16_t *, and remove every port in the list from the
  141. * current list of predicted ports.
  142. */
  143. void
  144. rep_hist_remove_predicted_ports(const smartlist_t *rmv_ports)
  145. {
  146. /* Let's do this on O(N), not O(N^2). */
  147. bitarray_t *remove_ports = bitarray_init_zero(UINT16_MAX);
  148. SMARTLIST_FOREACH(rmv_ports, const uint16_t *, p,
  149. bitarray_set(remove_ports, *p));
  150. SMARTLIST_FOREACH_BEGIN(predicted_ports_list, predicted_port_t *, pp) {
  151. if (bitarray_is_set(remove_ports, pp->port)) {
  152. tor_free(pp);
  153. predicted_ports_total_alloc -= sizeof(*pp);
  154. SMARTLIST_DEL_CURRENT(predicted_ports_list, pp);
  155. }
  156. } SMARTLIST_FOREACH_END(pp);
  157. bitarray_free(remove_ports);
  158. }
  159. /** The user asked us to do a resolve. Rather than keeping track of
  160. * timings and such of resolves, we fake it for now by treating
  161. * it the same way as a connection to port 80. This way we will continue
  162. * to have circuits lying around if the user only uses Tor for resolves.
  163. */
  164. void
  165. rep_hist_note_used_resolve(time_t now)
  166. {
  167. rep_hist_note_used_port(now, 80);
  168. }
  169. /** The last time at which we needed an internal circ. */
  170. static time_t predicted_internal_time = 0;
  171. /** The last time we needed an internal circ with good uptime. */
  172. static time_t predicted_internal_uptime_time = 0;
  173. /** The last time we needed an internal circ with good capacity. */
  174. static time_t predicted_internal_capacity_time = 0;
  175. /** Remember that we used an internal circ at time <b>now</b>. */
  176. void
  177. rep_hist_note_used_internal(time_t now, int need_uptime, int need_capacity)
  178. {
  179. // If the list is empty, re-randomize predicted ports lifetime
  180. if (!any_predicted_circuits(now)) {
  181. prediction_timeout = channelpadding_get_circuits_available_timeout();
  182. }
  183. last_prediction_add_time = now;
  184. log_info(LD_CIRC,
  185. "New port prediction added. Will continue predictive circ building "
  186. "for %d more seconds.",
  187. predicted_ports_prediction_time_remaining(now));
  188. predicted_internal_time = now;
  189. if (need_uptime)
  190. predicted_internal_uptime_time = now;
  191. if (need_capacity)
  192. predicted_internal_capacity_time = now;
  193. }
  194. /** Return 1 if we've used an internal circ recently; else return 0. */
  195. int
  196. rep_hist_get_predicted_internal(time_t now, int *need_uptime,
  197. int *need_capacity)
  198. {
  199. int predicted_circs_relevance_time;
  200. predicted_circs_relevance_time = (int)prediction_timeout;
  201. if (!predicted_internal_time) { /* initialize it */
  202. predicted_internal_time = now;
  203. predicted_internal_uptime_time = now;
  204. predicted_internal_capacity_time = now;
  205. }
  206. if (predicted_internal_time + predicted_circs_relevance_time < now)
  207. return 0; /* too long ago */
  208. if (predicted_internal_uptime_time + predicted_circs_relevance_time >= now)
  209. *need_uptime = 1;
  210. // Always predict that we need capacity.
  211. *need_capacity = 1;
  212. return 1;
  213. }
  214. /** Any ports used lately? These are pre-seeded if we just started
  215. * up or if we're running a hidden service. */
  216. int
  217. any_predicted_circuits(time_t now)
  218. {
  219. int predicted_circs_relevance_time;
  220. predicted_circs_relevance_time = (int)prediction_timeout;
  221. return smartlist_len(predicted_ports_list) ||
  222. predicted_internal_time + predicted_circs_relevance_time >= now;
  223. }
  224. /** Return 1 if we have no need for circuits currently, else return 0. */
  225. int
  226. rep_hist_circbuilding_dormant(time_t now)
  227. {
  228. const or_options_t *options = get_options();
  229. if (any_predicted_circuits(now))
  230. return 0;
  231. /* see if we'll still need to build testing circuits */
  232. if (server_mode(options) &&
  233. (!check_whether_orport_reachable(options) ||
  234. !circuit_enough_testing_circs()))
  235. return 0;
  236. if (!check_whether_dirport_reachable(options))
  237. return 0;
  238. return 1;
  239. }
  240. /**
  241. * Allocate whatever memory and structs are needed for predicting
  242. * which ports will be used. Also seed it with port 80, so we'll build
  243. * circuits on start-up.
  244. */
  245. static void
  246. predicted_ports_alloc(void)
  247. {
  248. predicted_ports_list = smartlist_new();
  249. }
  250. void
  251. predicted_ports_init(void)
  252. {
  253. predicted_ports_alloc();
  254. add_predicted_port(time(NULL), 443); // Add a port to get us started
  255. }
  256. /** Free whatever memory is needed for predicting which ports will
  257. * be used.
  258. */
  259. void
  260. predicted_ports_free_all(void)
  261. {
  262. if (!predicted_ports_list)
  263. return;
  264. predicted_ports_total_alloc -=
  265. smartlist_len(predicted_ports_list)*sizeof(predicted_port_t);
  266. SMARTLIST_FOREACH(predicted_ports_list, predicted_port_t *,
  267. pp, tor_free(pp));
  268. smartlist_free(predicted_ports_list);
  269. }