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