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