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