sendme.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. /* Copyright (c) 2019, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. /**
  4. * \file sendme.c
  5. * \brief Code that is related to SENDME cells both in terms of
  6. * creating/parsing cells and handling the content.
  7. */
  8. #include "core/or/or.h"
  9. #include "app/config/config.h"
  10. #include "core/mainloop/connection.h"
  11. #include "core/or/circuitlist.h"
  12. #include "core/or/circuituse.h"
  13. #include "core/or/relay.h"
  14. #include "core/or/sendme.h"
  15. #include "feature/nodelist/networkstatus.h"
  16. /* The cell version constants for when emitting a cell. */
  17. #define SENDME_EMIT_MIN_VERSION_DEFAULT 0
  18. #define SENDME_EMIT_MIN_VERSION_MIN 0
  19. #define SENDME_EMIT_MIN_VERSION_MAX UINT8_MAX
  20. /* The cell version constants for when accepting a cell. */
  21. #define SENDME_ACCEPT_MIN_VERSION_DEFAULT 0
  22. #define SENDME_ACCEPT_MIN_VERSION_MIN 0
  23. #define SENDME_ACCEPT_MIN_VERSION_MAX UINT8_MAX
  24. /* Return the minimum version given by the consensus (if any) that should be
  25. * used when emitting a SENDME cell. */
  26. static int
  27. get_emit_min_version(void)
  28. {
  29. return networkstatus_get_param(NULL, "sendme_emit_min_version",
  30. SENDME_EMIT_MIN_VERSION_DEFAULT,
  31. SENDME_EMIT_MIN_VERSION_MIN,
  32. SENDME_EMIT_MIN_VERSION_MAX);
  33. }
  34. /* Return the minimum version given by the consensus (if any) that should be
  35. * accepted when receiving a SENDME cell. */
  36. static int
  37. get_accept_min_version(void)
  38. {
  39. return networkstatus_get_param(NULL, "sendme_accept_min_version",
  40. SENDME_ACCEPT_MIN_VERSION_DEFAULT,
  41. SENDME_ACCEPT_MIN_VERSION_MIN,
  42. SENDME_ACCEPT_MIN_VERSION_MAX);
  43. }
  44. /** Called when we've just received a relay data cell, when we've just
  45. * finished flushing all bytes to stream <b>conn</b>, or when we've flushed
  46. * *some* bytes to the stream <b>conn</b>.
  47. *
  48. * If conn->outbuf is not too full, and our deliver window is low, send back a
  49. * suitable number of stream-level sendme cells.
  50. */
  51. void
  52. sendme_connection_edge_consider_sending(edge_connection_t *conn)
  53. {
  54. tor_assert(conn);
  55. int log_domain = TO_CONN(conn)->type == CONN_TYPE_AP ? LD_APP : LD_EXIT;
  56. /* Don't send it if we still have data to deliver. */
  57. if (connection_outbuf_too_full(TO_CONN(conn))) {
  58. goto end;
  59. }
  60. if (circuit_get_by_edge_conn(conn) == NULL) {
  61. /* This can legitimately happen if the destroy has already arrived and
  62. * torn down the circuit. */
  63. log_info(log_domain, "No circuit associated with edge connection. "
  64. "Skipping sending SENDME.");
  65. goto end;
  66. }
  67. while (conn->deliver_window <=
  68. (STREAMWINDOW_START - STREAMWINDOW_INCREMENT)) {
  69. log_debug(log_domain, "Outbuf %" TOR_PRIuSZ ", queuing stream SENDME.",
  70. TO_CONN(conn)->outbuf_flushlen);
  71. conn->deliver_window += STREAMWINDOW_INCREMENT;
  72. if (connection_edge_send_command(conn, RELAY_COMMAND_SENDME,
  73. NULL, 0) < 0) {
  74. log_warn(LD_BUG, "connection_edge_send_command failed while sending "
  75. "a SENDME. Circuit probably closed, skipping.");
  76. goto end; /* The circuit's closed, don't continue */
  77. }
  78. }
  79. end:
  80. return;
  81. }
  82. /** Check if the deliver_window for circuit <b>circ</b> (at hop
  83. * <b>layer_hint</b> if it's defined) is low enough that we should
  84. * send a circuit-level sendme back down the circuit. If so, send
  85. * enough sendmes that the window would be overfull if we sent any
  86. * more.
  87. */
  88. void
  89. sendme_circuit_consider_sending(circuit_t *circ, crypt_path_t *layer_hint)
  90. {
  91. while ((layer_hint ? layer_hint->deliver_window : circ->deliver_window) <=
  92. CIRCWINDOW_START - CIRCWINDOW_INCREMENT) {
  93. log_debug(LD_CIRC,"Queuing circuit sendme.");
  94. if (layer_hint)
  95. layer_hint->deliver_window += CIRCWINDOW_INCREMENT;
  96. else
  97. circ->deliver_window += CIRCWINDOW_INCREMENT;
  98. if (relay_send_command_from_edge(0, circ, RELAY_COMMAND_SENDME,
  99. NULL, 0, layer_hint) < 0) {
  100. log_warn(LD_CIRC,
  101. "relay_send_command_from_edge failed. Circuit's closed.");
  102. return; /* the circuit's closed, don't continue */
  103. }
  104. }
  105. }
  106. /* Process a circuit-level SENDME cell that we just received. The layer_hint,
  107. * if not NULL, is the Exit hop of the connection which means that we are a
  108. * client. In that case, circ must be an origin circuit. The cell_body_len is
  109. * the length of the SENDME cell payload (excluding the header).
  110. *
  111. * Return 0 on success that is the SENDME is valid and the package window has
  112. * been updated properly.
  113. *
  114. * On error, a negative value is returned which indicate that the circuit must
  115. * be closed using the value as the reason for it. */
  116. int
  117. sendme_process_circuit_level(crypt_path_t *layer_hint,
  118. circuit_t *circ, uint16_t cell_body_len)
  119. {
  120. tor_assert(circ);
  121. /* If we are the origin of the circuit, we are the Client so we use the
  122. * layer hint (the Exit hop) for the package window tracking. */
  123. if (CIRCUIT_IS_ORIGIN(circ)) {
  124. if ((layer_hint->package_window + CIRCWINDOW_INCREMENT) >
  125. CIRCWINDOW_START_MAX) {
  126. static struct ratelim_t exit_warn_ratelim = RATELIM_INIT(600);
  127. log_fn_ratelim(&exit_warn_ratelim, LOG_WARN, LD_PROTOCOL,
  128. "Unexpected sendme cell from exit relay. "
  129. "Closing circ.");
  130. return -END_CIRC_REASON_TORPROTOCOL;
  131. }
  132. layer_hint->package_window += CIRCWINDOW_INCREMENT;
  133. log_debug(LD_APP, "circ-level sendme at origin, packagewindow %d.",
  134. layer_hint->package_window);
  135. /* We count circuit-level sendme's as valid delivered data because they
  136. * are rate limited. */
  137. circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), cell_body_len);
  138. } else {
  139. /* We aren't the origin of this circuit so we are the Exit and thus we
  140. * track the package window with the circuit object. */
  141. if ((circ->package_window + CIRCWINDOW_INCREMENT) >
  142. CIRCWINDOW_START_MAX) {
  143. static struct ratelim_t client_warn_ratelim = RATELIM_INIT(600);
  144. log_fn_ratelim(&client_warn_ratelim, LOG_PROTOCOL_WARN, LD_PROTOCOL,
  145. "Unexpected sendme cell from client. "
  146. "Closing circ (window %d).", circ->package_window);
  147. return -END_CIRC_REASON_TORPROTOCOL;
  148. }
  149. circ->package_window += CIRCWINDOW_INCREMENT;
  150. log_debug(LD_EXIT, "circ-level sendme at non-origin, packagewindow %d.",
  151. circ->package_window);
  152. }
  153. return 0;
  154. }
  155. /* Process a stream-level SENDME cell that we just received. The conn is the
  156. * edge connection (stream) that the circuit circ is associated with. The
  157. * cell_body_len is the length of the payload (excluding the header).
  158. *
  159. * Return 0 on success that is the SENDME is valid and the package window has
  160. * been updated properly.
  161. *
  162. * On error, a negative value is returned which indicate that the circuit must
  163. * be closed using the value as the reason for it. */
  164. int
  165. sendme_process_stream_level(edge_connection_t *conn, circuit_t *circ,
  166. uint16_t cell_body_len)
  167. {
  168. tor_assert(conn);
  169. tor_assert(circ);
  170. /* Don't allow the other endpoint to request more than our maximum (i.e.
  171. * initial) stream SENDME window worth of data. Well-behaved stock clients
  172. * will not request more than this max (as per the check in the while loop
  173. * of sendme_connection_edge_consider_sending()). */
  174. if ((conn->package_window + STREAMWINDOW_INCREMENT) >
  175. STREAMWINDOW_START_MAX) {
  176. static struct ratelim_t stream_warn_ratelim = RATELIM_INIT(600);
  177. log_fn_ratelim(&stream_warn_ratelim, LOG_PROTOCOL_WARN, LD_PROTOCOL,
  178. "Unexpected stream sendme cell. Closing circ (window %d).",
  179. conn->package_window);
  180. return -END_CIRC_REASON_TORPROTOCOL;
  181. }
  182. /* At this point, the stream sendme is valid */
  183. conn->package_window += STREAMWINDOW_INCREMENT;
  184. /* We count circuit-level sendme's as valid delivered data because they are
  185. * rate limited. */
  186. if (CIRCUIT_IS_ORIGIN(circ)) {
  187. circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), cell_body_len);
  188. }
  189. log_debug(CIRCUIT_IS_ORIGIN(circ) ? LD_APP : LD_EXIT,
  190. "stream-level sendme, package_window now %d.",
  191. conn->package_window);
  192. return 0;
  193. }
  194. /* Called when a relay DATA cell is received on the given circuit. If
  195. * layer_hint is NULL, this means we are the Exit end point else we are the
  196. * Client. Update the deliver window and return its new value. */
  197. int
  198. sendme_circuit_data_received(circuit_t *circ, crypt_path_t *layer_hint)
  199. {
  200. int deliver_window, domain;
  201. if (CIRCUIT_IS_ORIGIN(circ)) {
  202. tor_assert(layer_hint);
  203. --layer_hint->deliver_window;
  204. deliver_window = layer_hint->deliver_window;
  205. domain = LD_APP;
  206. } else {
  207. tor_assert(!layer_hint);
  208. --circ->deliver_window;
  209. deliver_window = circ->deliver_window;
  210. domain = LD_EXIT;
  211. }
  212. log_debug(domain, "Circuit deliver_window now %d.", deliver_window);
  213. return deliver_window;
  214. }
  215. /* Called when a relay DATA cell is received for the given edge connection
  216. * conn. Update the deliver window and return its new value. */
  217. int
  218. sendme_stream_data_received(edge_connection_t *conn)
  219. {
  220. tor_assert(conn);
  221. return --conn->deliver_window;
  222. }
  223. /* Called when a relay DATA cell is packaged on the given circuit. If
  224. * layer_hint is NULL, this means we are the Exit end point else we are the
  225. * Client. Update the package window and return its new value. */
  226. int
  227. sendme_circuit_data_packaged(circuit_t *circ, crypt_path_t *layer_hint)
  228. {
  229. int package_window, domain;
  230. tor_assert(circ);
  231. if (CIRCUIT_IS_ORIGIN(circ)) {
  232. /* Client side. */
  233. tor_assert(layer_hint);
  234. --layer_hint->package_window;
  235. package_window = layer_hint->package_window;
  236. domain = LD_APP;
  237. } else {
  238. /* Exit side. */
  239. tor_assert(!layer_hint);
  240. --circ->package_window;
  241. package_window = circ->package_window;
  242. domain = LD_EXIT;
  243. }
  244. log_debug(domain, "Circuit package_window now %d.", package_window);
  245. return package_window;
  246. }
  247. /* Called when a relay DATA cell is packaged for the given edge connection
  248. * conn. Update the package window and return its new value. */
  249. int
  250. sendme_stream_data_packaged(edge_connection_t *conn)
  251. {
  252. tor_assert(conn);
  253. return --conn->package_window;
  254. }