sendme.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676
  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. #define SENDME_PRIVATE
  9. #include "core/or/or.h"
  10. #include "app/config/config.h"
  11. #include "core/crypto/relay_crypto.h"
  12. #include "core/mainloop/connection.h"
  13. #include "core/or/cell_st.h"
  14. #include "core/or/crypt_path.h"
  15. #include "core/or/circuitlist.h"
  16. #include "core/or/circuituse.h"
  17. #include "core/or/or_circuit_st.h"
  18. #include "core/or/relay.h"
  19. #include "core/or/sendme.h"
  20. #include "feature/nodelist/networkstatus.h"
  21. #include "lib/ctime/di_ops.h"
  22. #include "trunnel/sendme.h"
  23. /* Return the minimum version given by the consensus (if any) that should be
  24. * used when emitting a SENDME cell. */
  25. STATIC int
  26. get_emit_min_version(void)
  27. {
  28. return networkstatus_get_param(NULL, "sendme_emit_min_version",
  29. SENDME_EMIT_MIN_VERSION_DEFAULT,
  30. SENDME_EMIT_MIN_VERSION_MIN,
  31. SENDME_EMIT_MIN_VERSION_MAX);
  32. }
  33. /* Return the minimum version given by the consensus (if any) that should be
  34. * accepted when receiving a SENDME cell. */
  35. STATIC int
  36. get_accept_min_version(void)
  37. {
  38. return networkstatus_get_param(NULL, "sendme_accept_min_version",
  39. SENDME_ACCEPT_MIN_VERSION_DEFAULT,
  40. SENDME_ACCEPT_MIN_VERSION_MIN,
  41. SENDME_ACCEPT_MIN_VERSION_MAX);
  42. }
  43. /* Return true iff the given cell digest matches the first digest in the
  44. * circuit sendme list. */
  45. static bool
  46. v1_digest_matches(const circuit_t *circ, const uint8_t *cell_digest)
  47. {
  48. bool ret = false;
  49. uint8_t *circ_digest = NULL;
  50. tor_assert(circ);
  51. tor_assert(cell_digest);
  52. /* We shouldn't have received a SENDME if we have no digests. Log at
  53. * protocol warning because it can be tricked by sending many SENDMEs
  54. * without prior data cell. */
  55. if (circ->sendme_last_digests == NULL ||
  56. smartlist_len(circ->sendme_last_digests) == 0) {
  57. log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
  58. "We received a SENDME but we have no cell digests to match. "
  59. "Closing circuit.");
  60. goto no_match;
  61. }
  62. /* Pop the first element that was added (FIFO) and compare it. */
  63. circ_digest = smartlist_get(circ->sendme_last_digests, 0);
  64. smartlist_del_keeporder(circ->sendme_last_digests, 0);
  65. /* Compare the digest with the one in the SENDME. This cell is invalid
  66. * without a perfect match. */
  67. if (tor_memneq(circ_digest, cell_digest, TRUNNEL_SENDME_V1_DIGEST_LEN)) {
  68. log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
  69. "SENDME v1 cell digest do not match.");
  70. goto no_match;
  71. }
  72. /* Digests matches! */
  73. ret = true;
  74. no_match:
  75. /* This digest was popped from the circuit list. Regardless of what happens,
  76. * we have no more use for it. */
  77. tor_free(circ_digest);
  78. return ret;
  79. }
  80. /* Return true iff the given decoded SENDME version 1 cell is valid and
  81. * matches the expected digest on the circuit.
  82. *
  83. * Validation is done by comparing the digest in the cell from the previous
  84. * cell we saw which tells us that the other side has in fact seen that cell.
  85. * See proposal 289 for more details. */
  86. static bool
  87. cell_v1_is_valid(const sendme_cell_t *cell, const circuit_t *circ)
  88. {
  89. tor_assert(cell);
  90. tor_assert(circ);
  91. const uint8_t *cell_digest = sendme_cell_getconstarray_data_v1_digest(cell);
  92. return v1_digest_matches(circ, cell_digest);
  93. }
  94. /* Return true iff the given cell version can be handled or if the minimum
  95. * accepted version from the consensus is known to us. */
  96. STATIC bool
  97. cell_version_can_be_handled(uint8_t cell_version)
  98. {
  99. int accept_version = get_accept_min_version();
  100. /* We will first check if the consensus minimum accepted version can be
  101. * handled by us and if not, regardless of the cell version we got, we can't
  102. * continue. */
  103. if (accept_version > SENDME_MAX_SUPPORTED_VERSION) {
  104. log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
  105. "Unable to accept SENDME version %u (from consensus). "
  106. "We only support <= %u. Probably your tor is too old?",
  107. accept_version, SENDME_MAX_SUPPORTED_VERSION);
  108. goto invalid;
  109. }
  110. /* Then, is this version below the accepted version from the consensus? If
  111. * yes, we must not handle it. */
  112. if (cell_version < accept_version) {
  113. log_info(LD_PROTOCOL, "Unacceptable SENDME version %u. Only "
  114. "accepting %u (from consensus). Closing circuit.",
  115. cell_version, accept_version);
  116. goto invalid;
  117. }
  118. /* Is this cell version supported by us? */
  119. if (cell_version > SENDME_MAX_SUPPORTED_VERSION) {
  120. log_info(LD_PROTOCOL, "SENDME cell version %u is not supported by us. "
  121. "We only support <= %u",
  122. cell_version, SENDME_MAX_SUPPORTED_VERSION);
  123. goto invalid;
  124. }
  125. return true;
  126. invalid:
  127. return false;
  128. }
  129. /* Return true iff the encoded SENDME cell in cell_payload of length
  130. * cell_payload_len is valid. For each version:
  131. *
  132. * 0: No validation
  133. * 1: Authenticated with last cell digest.
  134. *
  135. * This is the main critical function to make sure we can continue to
  136. * send/recv cells on a circuit. If the SENDME is invalid, the circuit should
  137. * be mark for close. */
  138. STATIC bool
  139. sendme_is_valid(const circuit_t *circ, const uint8_t *cell_payload,
  140. size_t cell_payload_len)
  141. {
  142. uint8_t cell_version;
  143. sendme_cell_t *cell = NULL;
  144. tor_assert(circ);
  145. tor_assert(cell_payload);
  146. /* An empty payload means version 0 so skip trunnel parsing. We won't be
  147. * able to parse a 0 length buffer into a valid SENDME cell. */
  148. if (cell_payload_len == 0) {
  149. cell_version = 0;
  150. } else {
  151. /* First we'll decode the cell so we can get the version. */
  152. if (sendme_cell_parse(&cell, cell_payload, cell_payload_len) < 0) {
  153. log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
  154. "Unparseable SENDME cell received. Closing circuit.");
  155. goto invalid;
  156. }
  157. cell_version = sendme_cell_get_version(cell);
  158. }
  159. /* Validate that we can handle this cell version. */
  160. if (!cell_version_can_be_handled(cell_version)) {
  161. goto invalid;
  162. }
  163. /* Validate depending on the version now. */
  164. switch (cell_version) {
  165. case 0x01:
  166. if (!cell_v1_is_valid(cell, circ)) {
  167. goto invalid;
  168. }
  169. break;
  170. case 0x00:
  171. /* Version 0, there is no work to be done on the payload so it is
  172. * necessarily valid if we pass the version validation. */
  173. break;
  174. default:
  175. log_warn(LD_PROTOCOL, "Unknown SENDME cell version %d received.",
  176. cell_version);
  177. tor_assert_nonfatal_unreached();
  178. break;
  179. }
  180. /* Valid cell. */
  181. sendme_cell_free(cell);
  182. return true;
  183. invalid:
  184. sendme_cell_free(cell);
  185. return false;
  186. }
  187. /* Build and encode a version 1 SENDME cell into payload, which must be at
  188. * least of RELAY_PAYLOAD_SIZE bytes, using the digest for the cell data.
  189. *
  190. * Return the size in bytes of the encoded cell in payload. A negative value
  191. * is returned on encoding failure. */
  192. STATIC ssize_t
  193. build_cell_payload_v1(const uint8_t *cell_digest, uint8_t *payload)
  194. {
  195. ssize_t len = -1;
  196. sendme_cell_t *cell = NULL;
  197. tor_assert(cell_digest);
  198. tor_assert(payload);
  199. cell = sendme_cell_new();
  200. /* Building a payload for version 1. */
  201. sendme_cell_set_version(cell, 0x01);
  202. /* Set the data length field for v1. */
  203. sendme_cell_set_data_len(cell, TRUNNEL_SENDME_V1_DIGEST_LEN);
  204. /* Copy the digest into the data payload. */
  205. memcpy(sendme_cell_getarray_data_v1_digest(cell), cell_digest,
  206. sendme_cell_get_data_len(cell));
  207. /* Finally, encode the cell into the payload. */
  208. len = sendme_cell_encode(payload, RELAY_PAYLOAD_SIZE, cell);
  209. sendme_cell_free(cell);
  210. return len;
  211. }
  212. /* Send a circuit-level SENDME on the given circuit using the layer_hint if
  213. * not NULL. The digest is only used for version 1.
  214. *
  215. * Return 0 on success else a negative value and the circuit will be closed
  216. * because we failed to send the cell on it. */
  217. static int
  218. send_circuit_level_sendme(circuit_t *circ, crypt_path_t *layer_hint,
  219. const uint8_t *cell_digest)
  220. {
  221. uint8_t emit_version;
  222. uint8_t payload[RELAY_PAYLOAD_SIZE];
  223. ssize_t payload_len;
  224. tor_assert(circ);
  225. tor_assert(cell_digest);
  226. emit_version = get_emit_min_version();
  227. switch (emit_version) {
  228. case 0x01:
  229. payload_len = build_cell_payload_v1(cell_digest, payload);
  230. if (BUG(payload_len < 0)) {
  231. /* Unable to encode the cell, abort. We can recover from this by closing
  232. * the circuit but in theory it should never happen. */
  233. return -1;
  234. }
  235. log_debug(LD_PROTOCOL, "Emitting SENDME version 1 cell.");
  236. break;
  237. case 0x00:
  238. /* Fallthrough because default is to use v0. */
  239. default:
  240. /* Unknown version, fallback to version 0 meaning no payload. */
  241. payload_len = 0;
  242. break;
  243. }
  244. if (relay_send_command_from_edge(0, circ, RELAY_COMMAND_SENDME,
  245. (char *) payload, payload_len,
  246. layer_hint) < 0) {
  247. log_warn(LD_CIRC,
  248. "SENDME relay_send_command_from_edge failed. Circuit's closed.");
  249. return -1; /* the circuit's closed, don't continue */
  250. }
  251. return 0;
  252. }
  253. /* Record the cell digest only if the next cell is expected to be a SENDME. */
  254. static void
  255. record_cell_digest_on_circ(circuit_t *circ, const uint8_t *sendme_digest)
  256. {
  257. tor_assert(circ);
  258. tor_assert(sendme_digest);
  259. /* Add the digest to the last seen list in the circuit. */
  260. if (circ->sendme_last_digests == NULL) {
  261. circ->sendme_last_digests = smartlist_new();
  262. }
  263. smartlist_add(circ->sendme_last_digests,
  264. tor_memdup(sendme_digest, DIGEST_LEN));
  265. }
  266. /*
  267. * Public API
  268. */
  269. /** Return true iff the next cell for the given cell window is expected to be
  270. * a SENDME.
  271. *
  272. * We are able to know that because the package or deliver window value minus
  273. * one cell (the possible SENDME cell) should be a multiple of the increment
  274. * window value. */
  275. static bool
  276. circuit_sendme_cell_is_next(int window)
  277. {
  278. /* At the start of the window, no SENDME will be expected. */
  279. if (window == CIRCWINDOW_START) {
  280. return false;
  281. }
  282. /* Are we at the limit of the increment and if not, we don't expect next
  283. * cell is a SENDME.
  284. *
  285. * We test against the window minus 1 because when we are looking if the
  286. * next cell is a SENDME, the window (either package or deliver) hasn't been
  287. * decremented just yet so when this is called, we are currently processing
  288. * the "window - 1" cell.
  289. *
  290. * This function is used when recording a cell digest and this is done quite
  291. * low in the stack when decrypting or encrypting a cell. The window is only
  292. * updated once the cell is actually put in the outbuf. */
  293. if (((window - 1) % CIRCWINDOW_INCREMENT) != 0) {
  294. return false;
  295. }
  296. /* Next cell is expected to be a SENDME. */
  297. return true;
  298. }
  299. /** Called when we've just received a relay data cell, when we've just
  300. * finished flushing all bytes to stream <b>conn</b>, or when we've flushed
  301. * *some* bytes to the stream <b>conn</b>.
  302. *
  303. * If conn->outbuf is not too full, and our deliver window is low, send back a
  304. * suitable number of stream-level sendme cells.
  305. */
  306. void
  307. sendme_connection_edge_consider_sending(edge_connection_t *conn)
  308. {
  309. tor_assert(conn);
  310. int log_domain = TO_CONN(conn)->type == CONN_TYPE_AP ? LD_APP : LD_EXIT;
  311. /* Don't send it if we still have data to deliver. */
  312. if (connection_outbuf_too_full(TO_CONN(conn))) {
  313. goto end;
  314. }
  315. if (circuit_get_by_edge_conn(conn) == NULL) {
  316. /* This can legitimately happen if the destroy has already arrived and
  317. * torn down the circuit. */
  318. log_info(log_domain, "No circuit associated with edge connection. "
  319. "Skipping sending SENDME.");
  320. goto end;
  321. }
  322. while (conn->deliver_window <=
  323. (STREAMWINDOW_START - STREAMWINDOW_INCREMENT)) {
  324. log_debug(log_domain, "Outbuf %" TOR_PRIuSZ ", queuing stream SENDME.",
  325. TO_CONN(conn)->outbuf_flushlen);
  326. conn->deliver_window += STREAMWINDOW_INCREMENT;
  327. if (connection_edge_send_command(conn, RELAY_COMMAND_SENDME,
  328. NULL, 0) < 0) {
  329. log_warn(LD_BUG, "connection_edge_send_command failed while sending "
  330. "a SENDME. Circuit probably closed, skipping.");
  331. goto end; /* The circuit's closed, don't continue */
  332. }
  333. }
  334. end:
  335. return;
  336. }
  337. /** Check if the deliver_window for circuit <b>circ</b> (at hop
  338. * <b>layer_hint</b> if it's defined) is low enough that we should
  339. * send a circuit-level sendme back down the circuit. If so, send
  340. * enough sendmes that the window would be overfull if we sent any
  341. * more.
  342. */
  343. void
  344. sendme_circuit_consider_sending(circuit_t *circ, crypt_path_t *layer_hint)
  345. {
  346. const uint8_t *digest;
  347. while ((layer_hint ? layer_hint->deliver_window : circ->deliver_window) <=
  348. CIRCWINDOW_START - CIRCWINDOW_INCREMENT) {
  349. log_debug(LD_CIRC,"Queuing circuit sendme.");
  350. if (layer_hint) {
  351. layer_hint->deliver_window += CIRCWINDOW_INCREMENT;
  352. digest = cpath_get_sendme_digest(layer_hint);
  353. } else {
  354. circ->deliver_window += CIRCWINDOW_INCREMENT;
  355. digest = relay_crypto_get_sendme_digest(&TO_OR_CIRCUIT(circ)->crypto);
  356. }
  357. if (send_circuit_level_sendme(circ, layer_hint, digest) < 0) {
  358. return; /* The circuit's closed, don't continue */
  359. }
  360. }
  361. }
  362. /* Process a circuit-level SENDME cell that we just received. The layer_hint,
  363. * if not NULL, is the Exit hop of the connection which means that we are a
  364. * client. In that case, circ must be an origin circuit. The cell_body_len is
  365. * the length of the SENDME cell payload (excluding the header). The
  366. * cell_payload is the payload.
  367. *
  368. * Return 0 on success that is the SENDME is valid and the package window has
  369. * been updated properly.
  370. *
  371. * On error, a negative value is returned which indicate that the circuit must
  372. * be closed using the value as the reason for it. */
  373. int
  374. sendme_process_circuit_level(crypt_path_t *layer_hint,
  375. circuit_t *circ, const uint8_t *cell_payload,
  376. uint16_t cell_payload_len)
  377. {
  378. tor_assert(circ);
  379. tor_assert(cell_payload);
  380. /* Validate the SENDME cell. Depending on the version, different validation
  381. * can be done. An invalid SENDME requires us to close the circuit. */
  382. if (!sendme_is_valid(circ, cell_payload, cell_payload_len)) {
  383. return -END_CIRC_REASON_TORPROTOCOL;
  384. }
  385. /* If we are the origin of the circuit, we are the Client so we use the
  386. * layer hint (the Exit hop) for the package window tracking. */
  387. if (CIRCUIT_IS_ORIGIN(circ)) {
  388. /* If we are the origin of the circuit, it is impossible to not have a
  389. * cpath. Just in case, bug on it and close the circuit. */
  390. if (BUG(layer_hint == NULL)) {
  391. return -END_CIRC_REASON_TORPROTOCOL;
  392. }
  393. if ((layer_hint->package_window + CIRCWINDOW_INCREMENT) >
  394. CIRCWINDOW_START_MAX) {
  395. static struct ratelim_t exit_warn_ratelim = RATELIM_INIT(600);
  396. log_fn_ratelim(&exit_warn_ratelim, LOG_WARN, LD_PROTOCOL,
  397. "Unexpected sendme cell from exit relay. "
  398. "Closing circ.");
  399. return -END_CIRC_REASON_TORPROTOCOL;
  400. }
  401. layer_hint->package_window += CIRCWINDOW_INCREMENT;
  402. log_debug(LD_APP, "circ-level sendme at origin, packagewindow %d.",
  403. layer_hint->package_window);
  404. /* We count circuit-level sendme's as valid delivered data because they
  405. * are rate limited. */
  406. circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), cell_payload_len);
  407. } else {
  408. /* We aren't the origin of this circuit so we are the Exit and thus we
  409. * track the package window with the circuit object. */
  410. if ((circ->package_window + CIRCWINDOW_INCREMENT) >
  411. CIRCWINDOW_START_MAX) {
  412. static struct ratelim_t client_warn_ratelim = RATELIM_INIT(600);
  413. log_fn_ratelim(&client_warn_ratelim, LOG_PROTOCOL_WARN, LD_PROTOCOL,
  414. "Unexpected sendme cell from client. "
  415. "Closing circ (window %d).", circ->package_window);
  416. return -END_CIRC_REASON_TORPROTOCOL;
  417. }
  418. circ->package_window += CIRCWINDOW_INCREMENT;
  419. log_debug(LD_EXIT, "circ-level sendme at non-origin, packagewindow %d.",
  420. circ->package_window);
  421. }
  422. return 0;
  423. }
  424. /* Process a stream-level SENDME cell that we just received. The conn is the
  425. * edge connection (stream) that the circuit circ is associated with. The
  426. * cell_body_len is the length of the payload (excluding the header).
  427. *
  428. * Return 0 on success that is the SENDME is valid and the package window has
  429. * been updated properly.
  430. *
  431. * On error, a negative value is returned which indicate that the circuit must
  432. * be closed using the value as the reason for it. */
  433. int
  434. sendme_process_stream_level(edge_connection_t *conn, circuit_t *circ,
  435. uint16_t cell_body_len)
  436. {
  437. tor_assert(conn);
  438. tor_assert(circ);
  439. /* Don't allow the other endpoint to request more than our maximum (i.e.
  440. * initial) stream SENDME window worth of data. Well-behaved stock clients
  441. * will not request more than this max (as per the check in the while loop
  442. * of sendme_connection_edge_consider_sending()). */
  443. if ((conn->package_window + STREAMWINDOW_INCREMENT) >
  444. STREAMWINDOW_START_MAX) {
  445. static struct ratelim_t stream_warn_ratelim = RATELIM_INIT(600);
  446. log_fn_ratelim(&stream_warn_ratelim, LOG_PROTOCOL_WARN, LD_PROTOCOL,
  447. "Unexpected stream sendme cell. Closing circ (window %d).",
  448. conn->package_window);
  449. return -END_CIRC_REASON_TORPROTOCOL;
  450. }
  451. /* At this point, the stream sendme is valid */
  452. conn->package_window += STREAMWINDOW_INCREMENT;
  453. /* We count circuit-level sendme's as valid delivered data because they are
  454. * rate limited. */
  455. if (CIRCUIT_IS_ORIGIN(circ)) {
  456. circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), cell_body_len);
  457. }
  458. log_debug(CIRCUIT_IS_ORIGIN(circ) ? LD_APP : LD_EXIT,
  459. "stream-level sendme, package_window now %d.",
  460. conn->package_window);
  461. return 0;
  462. }
  463. /* Called when a relay DATA cell is received on the given circuit. If
  464. * layer_hint is NULL, this means we are the Exit end point else we are the
  465. * Client. Update the deliver window and return its new value. */
  466. int
  467. sendme_circuit_data_received(circuit_t *circ, crypt_path_t *layer_hint)
  468. {
  469. int deliver_window, domain;
  470. if (CIRCUIT_IS_ORIGIN(circ)) {
  471. tor_assert(layer_hint);
  472. --layer_hint->deliver_window;
  473. deliver_window = layer_hint->deliver_window;
  474. domain = LD_APP;
  475. } else {
  476. tor_assert(!layer_hint);
  477. --circ->deliver_window;
  478. deliver_window = circ->deliver_window;
  479. domain = LD_EXIT;
  480. }
  481. log_debug(domain, "Circuit deliver_window now %d.", deliver_window);
  482. return deliver_window;
  483. }
  484. /* Called when a relay DATA cell is received for the given edge connection
  485. * conn. Update the deliver window and return its new value. */
  486. int
  487. sendme_stream_data_received(edge_connection_t *conn)
  488. {
  489. tor_assert(conn);
  490. return --conn->deliver_window;
  491. }
  492. /* Called when a relay DATA cell is packaged on the given circuit. If
  493. * layer_hint is NULL, this means we are the Exit end point else we are the
  494. * Client. Update the package window and return its new value. */
  495. int
  496. sendme_note_circuit_data_packaged(circuit_t *circ, crypt_path_t *layer_hint)
  497. {
  498. int package_window, domain;
  499. tor_assert(circ);
  500. if (CIRCUIT_IS_ORIGIN(circ)) {
  501. /* Client side. */
  502. tor_assert(layer_hint);
  503. --layer_hint->package_window;
  504. package_window = layer_hint->package_window;
  505. domain = LD_APP;
  506. } else {
  507. /* Exit side. */
  508. tor_assert(!layer_hint);
  509. --circ->package_window;
  510. package_window = circ->package_window;
  511. domain = LD_EXIT;
  512. }
  513. log_debug(domain, "Circuit package_window now %d.", package_window);
  514. return package_window;
  515. }
  516. /* Called when a relay DATA cell is packaged for the given edge connection
  517. * conn. Update the package window and return its new value. */
  518. int
  519. sendme_note_stream_data_packaged(edge_connection_t *conn)
  520. {
  521. tor_assert(conn);
  522. log_debug(LD_APP, "Stream package_window now %d.", --conn->package_window);
  523. return conn->package_window;
  524. }
  525. /* Record the cell digest into the circuit sendme digest list depending on
  526. * which edge we are. The digest is recorded only if we expect the next cell
  527. * that we will receive is a SENDME so we can match the digest. */
  528. void
  529. sendme_record_cell_digest_on_circ(circuit_t *circ, crypt_path_t *cpath)
  530. {
  531. int package_window;
  532. uint8_t *sendme_digest;
  533. tor_assert(circ);
  534. package_window = circ->package_window;
  535. if (cpath) {
  536. package_window = cpath->package_window;
  537. }
  538. /* Is this the last cell before a SENDME? The idea is that if the
  539. * package_window reaches a multiple of the increment, after this cell, we
  540. * should expect a SENDME. */
  541. if (!circuit_sendme_cell_is_next(package_window)) {
  542. return;
  543. }
  544. /* Getting the digest is expensive so we only do it once we are certain to
  545. * record it on the circuit. */
  546. if (cpath) {
  547. sendme_digest = cpath_get_sendme_digest(cpath);
  548. } else {
  549. sendme_digest =
  550. relay_crypto_get_sendme_digest(&TO_OR_CIRCUIT(circ)->crypto);
  551. }
  552. record_cell_digest_on_circ(circ, sendme_digest);
  553. }
  554. /* Called once we decrypted a cell and recognized it. Record the cell digest
  555. * as the next sendme digest only if the next cell we'll send on the circuit
  556. * is expected to be a SENDME. */
  557. void
  558. sendme_record_received_cell_digest(circuit_t *circ, crypt_path_t *cpath)
  559. {
  560. tor_assert(circ);
  561. /* Only record if the next cell is expected to be a SENDME. */
  562. if (!circuit_sendme_cell_is_next(cpath ? cpath->deliver_window :
  563. circ->deliver_window)) {
  564. return;
  565. }
  566. if (cpath) {
  567. /* Record incoming digest. */
  568. cpath_sendme_record_cell_digest(cpath, false);
  569. } else {
  570. /* Record foward digest. */
  571. relay_crypto_record_sendme_digest(&TO_OR_CIRCUIT(circ)->crypto, true);
  572. }
  573. }
  574. /* Called once we encrypted a cell. Record the cell digest as the next sendme
  575. * digest only if the next cell we expect to receive is a SENDME so we can
  576. * match the digests. */
  577. void
  578. sendme_record_sending_cell_digest(circuit_t *circ, crypt_path_t *cpath)
  579. {
  580. tor_assert(circ);
  581. /* Only record if the next cell is expected to be a SENDME. */
  582. if (!circuit_sendme_cell_is_next(cpath ? cpath->package_window :
  583. circ->package_window)) {
  584. goto end;
  585. }
  586. if (cpath) {
  587. /* Record the forward digest. */
  588. cpath_sendme_record_cell_digest(cpath, true);
  589. } else {
  590. /* Record the incoming digest. */
  591. relay_crypto_record_sendme_digest(&TO_OR_CIRCUIT(circ)->crypto, false);
  592. }
  593. end:
  594. return;
  595. }