Bug 29085: Refactor non-padding accounting out of token removal.
[tor.git] / src / core / or / sendme.c
blobe7c65d99e23357e0116696668f954859702930fa
1 /* Copyright (c) 2019, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
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 */
10 #define SENDME_PRIVATE
12 #include "core/or/or.h"
14 #include "app/config/config.h"
15 #include "core/crypto/relay_crypto.h"
16 #include "core/mainloop/connection.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"
24 #include "feature/nodelist/networkstatus.h"
25 #include "lib/ctime/di_ops.h"
26 #include "trunnel/sendme.h"
28 /* The maximum supported version. Above that value, the cell can't be
29 * recognized as a valid SENDME. */
30 #define SENDME_MAX_SUPPORTED_VERSION 1
32 /* The cell version constants for when emitting a cell. */
33 #define SENDME_EMIT_MIN_VERSION_DEFAULT 0
34 #define SENDME_EMIT_MIN_VERSION_MIN 0
35 #define SENDME_EMIT_MIN_VERSION_MAX UINT8_MAX
37 /* The cell version constants for when accepting a cell. */
38 #define SENDME_ACCEPT_MIN_VERSION_DEFAULT 0
39 #define SENDME_ACCEPT_MIN_VERSION_MIN 0
40 #define SENDME_ACCEPT_MIN_VERSION_MAX UINT8_MAX
42 /* Return the minimum version given by the consensus (if any) that should be
43 * used when emitting a SENDME cell. */
44 STATIC int
45 get_emit_min_version(void)
47 return networkstatus_get_param(NULL, "sendme_emit_min_version",
48 SENDME_EMIT_MIN_VERSION_DEFAULT,
49 SENDME_EMIT_MIN_VERSION_MIN,
50 SENDME_EMIT_MIN_VERSION_MAX);
53 /* Return the minimum version given by the consensus (if any) that should be
54 * accepted when receiving a SENDME cell. */
55 STATIC int
56 get_accept_min_version(void)
58 return networkstatus_get_param(NULL, "sendme_accept_min_version",
59 SENDME_ACCEPT_MIN_VERSION_DEFAULT,
60 SENDME_ACCEPT_MIN_VERSION_MIN,
61 SENDME_ACCEPT_MIN_VERSION_MAX);
64 /* Return true iff the given cell digest matches the first digest in the
65 * circuit sendme list. */
66 static bool
67 v1_digest_matches(const circuit_t *circ, const uint8_t *cell_digest)
69 bool ret = false;
70 uint8_t *circ_digest = NULL;
72 tor_assert(circ);
73 tor_assert(cell_digest);
75 /* We shouldn't have received a SENDME if we have no digests. Log at
76 * protocol warning because it can be tricked by sending many SENDMEs
77 * without prior data cell. */
78 if (circ->sendme_last_digests == NULL ||
79 smartlist_len(circ->sendme_last_digests) == 0) {
80 log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
81 "We received a SENDME but we have no cell digests to match. "
82 "Closing circuit.");
83 goto no_match;
86 /* Pop the first element that was added (FIFO) and compare it. */
87 circ_digest = smartlist_get(circ->sendme_last_digests, 0);
88 smartlist_del_keeporder(circ->sendme_last_digests, 0);
90 /* Compare the digest with the one in the SENDME. This cell is invalid
91 * without a perfect match. */
92 if (tor_memneq(circ_digest, cell_digest, TRUNNEL_SENDME_V1_DIGEST_LEN)) {
93 log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
94 "SENDME v1 cell digest do not match.");
95 goto no_match;
97 /* Digests matches! */
98 ret = true;
100 no_match:
101 /* This digest was popped from the circuit list. Regardless of what happens,
102 * we have no more use for it. */
103 tor_free(circ_digest);
104 return ret;
107 /* Return true iff the given decoded SENDME version 1 cell is valid and
108 * matches the expected digest on the circuit.
110 * Validation is done by comparing the digest in the cell from the previous
111 * cell we saw which tells us that the other side has in fact seen that cell.
112 * See proposal 289 for more details. */
113 static bool
114 cell_v1_is_valid(const sendme_cell_t *cell, const circuit_t *circ)
116 tor_assert(cell);
117 tor_assert(circ);
119 const uint8_t *cell_digest = sendme_cell_getconstarray_data_v1_digest(cell);
120 return v1_digest_matches(circ, cell_digest);
123 /* Return true iff the given cell version can be handled or if the minimum
124 * accepted version from the consensus is known to us. */
125 STATIC bool
126 cell_version_is_valid(uint8_t cell_version)
128 int accept_version = get_accept_min_version();
130 /* Can we handle this version? */
131 if (accept_version > SENDME_MAX_SUPPORTED_VERSION) {
132 log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
133 "Unable to accept SENDME version %u (from consensus). "
134 "We only support <= %d. Probably your tor is too old?",
135 accept_version, cell_version);
136 goto invalid;
139 /* We only accept a SENDME cell from what the consensus tells us. */
140 if (cell_version < accept_version) {
141 log_info(LD_PROTOCOL, "Unacceptable SENDME version %d. Only "
142 "accepting %u (from consensus). Closing circuit.",
143 cell_version, accept_version);
144 goto invalid;
147 return 1;
148 invalid:
149 return 0;
152 /* Return true iff the encoded SENDME cell in cell_payload of length
153 * cell_payload_len is valid. For each version:
155 * 0: No validation
156 * 1: Authenticated with last cell digest.
158 * This is the main critical function to make sure we can continue to
159 * send/recv cells on a circuit. If the SENDME is invalid, the circuit should
160 * be mark for close. */
161 STATIC bool
162 sendme_is_valid(const circuit_t *circ, const uint8_t *cell_payload,
163 size_t cell_payload_len)
165 uint8_t cell_version;
166 sendme_cell_t *cell = NULL;
168 tor_assert(circ);
169 tor_assert(cell_payload);
171 /* An empty payload means version 0 so skip trunnel parsing. We won't be
172 * able to parse a 0 length buffer into a valid SENDME cell. */
173 if (cell_payload_len == 0) {
174 cell_version = 0;
175 } else {
176 /* First we'll decode the cell so we can get the version. */
177 if (sendme_cell_parse(&cell, cell_payload, cell_payload_len) < 0) {
178 log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
179 "Unparseable SENDME cell received. Closing circuit.");
180 goto invalid;
182 cell_version = sendme_cell_get_version(cell);
185 /* Validate that we can handle this cell version. */
186 if (!cell_version_is_valid(cell_version)) {
187 goto invalid;
190 /* Validate depending on the version now. */
191 switch (cell_version) {
192 case 0x01:
193 if (!cell_v1_is_valid(cell, circ)) {
194 goto invalid;
196 break;
197 case 0x00:
198 /* Fallthrough. Version 0, there is no work to be done on the payload so
199 * it is necessarily valid if we pass the version validation. */
200 default:
201 /* Unknown version means we can't handle it so fallback to version 0. */
202 break;
205 /* Valid cell. */
206 sendme_cell_free(cell);
207 return 1;
208 invalid:
209 sendme_cell_free(cell);
210 return 0;
213 /* Build and encode a version 1 SENDME cell into payload, which must be at
214 * least of RELAY_PAYLOAD_SIZE bytes, using the digest for the cell data.
216 * Return the size in bytes of the encoded cell in payload. A negative value
217 * is returned on encoding failure. */
218 STATIC ssize_t
219 build_cell_payload_v1(const uint8_t *cell_digest, uint8_t *payload)
221 ssize_t len = -1;
222 sendme_cell_t *cell = NULL;
224 tor_assert(cell_digest);
225 tor_assert(payload);
227 cell = sendme_cell_new();
229 /* Building a payload for version 1. */
230 sendme_cell_set_version(cell, 0x01);
231 /* Set the data length field for v1. */
232 sendme_cell_set_data_len(cell, TRUNNEL_SENDME_V1_DIGEST_LEN);
234 /* Copy the digest into the data payload. */
235 memcpy(sendme_cell_getarray_data_v1_digest(cell), cell_digest,
236 sendme_cell_get_data_len(cell));
238 /* Finally, encode the cell into the payload. */
239 len = sendme_cell_encode(payload, RELAY_PAYLOAD_SIZE, cell);
241 sendme_cell_free(cell);
242 return len;
245 /* Send a circuit-level SENDME on the given circuit using the layer_hint if
246 * not NULL. The digest is only used for version 1.
248 * Return 0 on success else a negative value and the circuit will be closed
249 * because we failed to send the cell on it. */
250 static int
251 send_circuit_level_sendme(circuit_t *circ, crypt_path_t *layer_hint,
252 const uint8_t *cell_digest)
254 uint8_t emit_version;
255 uint8_t payload[RELAY_PAYLOAD_SIZE];
256 ssize_t payload_len;
258 tor_assert(circ);
259 tor_assert(cell_digest);
261 emit_version = get_emit_min_version();
262 switch (emit_version) {
263 case 0x01:
264 payload_len = build_cell_payload_v1(cell_digest, payload);
265 if (BUG(payload_len < 0)) {
266 /* Unable to encode the cell, abort. We can recover from this by closing
267 * the circuit but in theory it should never happen. */
268 return -1;
270 log_debug(LD_PROTOCOL, "Emitting SENDME version 1 cell.");
271 break;
272 case 0x00:
273 /* Fallthrough because default is to use v0. */
274 default:
275 /* Unknown version, fallback to version 0 meaning no payload. */
276 payload_len = 0;
277 break;
280 if (relay_send_command_from_edge(0, circ, RELAY_COMMAND_SENDME,
281 (char *) payload, payload_len,
282 layer_hint) < 0) {
283 log_warn(LD_CIRC,
284 "SENDME relay_send_command_from_edge failed. Circuit's closed.");
285 return -1; /* the circuit's closed, don't continue */
287 return 0;
291 * Public API
294 /** Keep the current inbound cell digest for the next SENDME digest. This part
295 * is only done by the client as the circuit came back from the Exit. */
296 void
297 sendme_circuit_record_outbound_cell(or_circuit_t *or_circ)
299 tor_assert(or_circ);
300 relay_crypto_record_sendme_digest(&or_circ->crypto);
303 /** Return true iff the next cell for the given cell window is expected to be
304 * a SENDME.
306 * We are able to know that because the package or deliver window value minus
307 * one cell (the possible SENDME cell) should be a multiple of the increment
308 * window value. */
309 bool
310 sendme_circuit_cell_is_next(int window)
312 /* Is this the last cell before a SENDME? The idea is that if the package or
313 * deliver window reaches a multiple of the increment, after this cell, we
314 * should expect a SENDME. */
315 if (((window - 1) % CIRCWINDOW_INCREMENT) != 0) {
316 return false;
318 /* Next cell is expected to be a SENDME. */
319 return true;
322 /** Called when we've just received a relay data cell, when we've just
323 * finished flushing all bytes to stream <b>conn</b>, or when we've flushed
324 * *some* bytes to the stream <b>conn</b>.
326 * If conn->outbuf is not too full, and our deliver window is low, send back a
327 * suitable number of stream-level sendme cells.
329 void
330 sendme_connection_edge_consider_sending(edge_connection_t *conn)
332 tor_assert(conn);
334 int log_domain = TO_CONN(conn)->type == CONN_TYPE_AP ? LD_APP : LD_EXIT;
336 /* Don't send it if we still have data to deliver. */
337 if (connection_outbuf_too_full(TO_CONN(conn))) {
338 goto end;
341 if (circuit_get_by_edge_conn(conn) == NULL) {
342 /* This can legitimately happen if the destroy has already arrived and
343 * torn down the circuit. */
344 log_info(log_domain, "No circuit associated with edge connection. "
345 "Skipping sending SENDME.");
346 goto end;
349 while (conn->deliver_window <=
350 (STREAMWINDOW_START - STREAMWINDOW_INCREMENT)) {
351 log_debug(log_domain, "Outbuf %" TOR_PRIuSZ ", queuing stream SENDME.",
352 TO_CONN(conn)->outbuf_flushlen);
353 conn->deliver_window += STREAMWINDOW_INCREMENT;
354 if (connection_edge_send_command(conn, RELAY_COMMAND_SENDME,
355 NULL, 0) < 0) {
356 log_warn(LD_BUG, "connection_edge_send_command failed while sending "
357 "a SENDME. Circuit probably closed, skipping.");
358 goto end; /* The circuit's closed, don't continue */
362 end:
363 return;
366 /** Check if the deliver_window for circuit <b>circ</b> (at hop
367 * <b>layer_hint</b> if it's defined) is low enough that we should
368 * send a circuit-level sendme back down the circuit. If so, send
369 * enough sendmes that the window would be overfull if we sent any
370 * more.
372 void
373 sendme_circuit_consider_sending(circuit_t *circ, crypt_path_t *layer_hint)
375 const uint8_t *digest;
377 while ((layer_hint ? layer_hint->deliver_window : circ->deliver_window) <=
378 CIRCWINDOW_START - CIRCWINDOW_INCREMENT) {
379 log_debug(LD_CIRC,"Queuing circuit sendme.");
380 if (layer_hint) {
381 layer_hint->deliver_window += CIRCWINDOW_INCREMENT;
382 digest = cpath_get_sendme_digest(layer_hint);
383 } else {
384 circ->deliver_window += CIRCWINDOW_INCREMENT;
385 digest = relay_crypto_get_sendme_digest(&TO_OR_CIRCUIT(circ)->crypto);
387 if (send_circuit_level_sendme(circ, layer_hint, digest) < 0) {
388 return; /* The circuit's closed, don't continue */
393 /* Process a circuit-level SENDME cell that we just received. The layer_hint,
394 * if not NULL, is the Exit hop of the connection which means that we are a
395 * client. In that case, circ must be an origin circuit. The cell_body_len is
396 * the length of the SENDME cell payload (excluding the header). The
397 * cell_payload is the payload.
399 * Return 0 on success that is the SENDME is valid and the package window has
400 * been updated properly.
402 * On error, a negative value is returned which indicate that the circuit must
403 * be closed using the value as the reason for it. */
405 sendme_process_circuit_level(crypt_path_t *layer_hint,
406 circuit_t *circ, const uint8_t *cell_payload,
407 uint16_t cell_payload_len)
409 tor_assert(circ);
410 tor_assert(cell_payload);
412 /* If we are the origin of the circuit, we are the Client so we use the
413 * layer hint (the Exit hop) for the package window tracking. */
414 if (CIRCUIT_IS_ORIGIN(circ)) {
415 /* If we are the origin of the circuit, it is impossible to not have a
416 * cpath. Just in case, bug on it and close the circuit. */
417 if (BUG(layer_hint == NULL)) {
418 return -END_CIRC_REASON_TORPROTOCOL;
420 if ((layer_hint->package_window + CIRCWINDOW_INCREMENT) >
421 CIRCWINDOW_START_MAX) {
422 static struct ratelim_t exit_warn_ratelim = RATELIM_INIT(600);
423 log_fn_ratelim(&exit_warn_ratelim, LOG_WARN, LD_PROTOCOL,
424 "Unexpected sendme cell from exit relay. "
425 "Closing circ.");
426 return -END_CIRC_REASON_TORPROTOCOL;
428 layer_hint->package_window += CIRCWINDOW_INCREMENT;
429 log_debug(LD_APP, "circ-level sendme at origin, packagewindow %d.",
430 layer_hint->package_window);
432 /* We count circuit-level sendme's as valid delivered data because they
433 * are rate limited. */
434 circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), cell_payload_len);
435 } else {
436 /* Validate the SENDME cell. Depending on the version, different
437 * validation can be done. An invalid SENDME requires us to close the
438 * circuit. It is only done if we are the Exit of the circuit. */
439 if (!sendme_is_valid(circ, cell_payload, cell_payload_len)) {
440 return -END_CIRC_REASON_TORPROTOCOL;
443 /* We aren't the origin of this circuit so we are the Exit and thus we
444 * track the package window with the circuit object. */
445 if ((circ->package_window + CIRCWINDOW_INCREMENT) >
446 CIRCWINDOW_START_MAX) {
447 static struct ratelim_t client_warn_ratelim = RATELIM_INIT(600);
448 log_fn_ratelim(&client_warn_ratelim, LOG_PROTOCOL_WARN, LD_PROTOCOL,
449 "Unexpected sendme cell from client. "
450 "Closing circ (window %d).", circ->package_window);
451 return -END_CIRC_REASON_TORPROTOCOL;
453 circ->package_window += CIRCWINDOW_INCREMENT;
454 log_debug(LD_EXIT, "circ-level sendme at non-origin, packagewindow %d.",
455 circ->package_window);
458 return 0;
461 /* Process a stream-level SENDME cell that we just received. The conn is the
462 * edge connection (stream) that the circuit circ is associated with. The
463 * cell_body_len is the length of the payload (excluding the header).
465 * Return 0 on success that is the SENDME is valid and the package window has
466 * been updated properly.
468 * On error, a negative value is returned which indicate that the circuit must
469 * be closed using the value as the reason for it. */
471 sendme_process_stream_level(edge_connection_t *conn, circuit_t *circ,
472 uint16_t cell_body_len)
474 tor_assert(conn);
475 tor_assert(circ);
477 /* Don't allow the other endpoint to request more than our maximum (i.e.
478 * initial) stream SENDME window worth of data. Well-behaved stock clients
479 * will not request more than this max (as per the check in the while loop
480 * of sendme_connection_edge_consider_sending()). */
481 if ((conn->package_window + STREAMWINDOW_INCREMENT) >
482 STREAMWINDOW_START_MAX) {
483 static struct ratelim_t stream_warn_ratelim = RATELIM_INIT(600);
484 log_fn_ratelim(&stream_warn_ratelim, LOG_PROTOCOL_WARN, LD_PROTOCOL,
485 "Unexpected stream sendme cell. Closing circ (window %d).",
486 conn->package_window);
487 return -END_CIRC_REASON_TORPROTOCOL;
489 /* At this point, the stream sendme is valid */
490 conn->package_window += STREAMWINDOW_INCREMENT;
492 /* We count circuit-level sendme's as valid delivered data because they are
493 * rate limited. */
494 if (CIRCUIT_IS_ORIGIN(circ)) {
495 circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), cell_body_len);
498 log_debug(CIRCUIT_IS_ORIGIN(circ) ? LD_APP : LD_EXIT,
499 "stream-level sendme, package_window now %d.",
500 conn->package_window);
501 return 0;
504 /* Called when a relay DATA cell is received on the given circuit. If
505 * layer_hint is NULL, this means we are the Exit end point else we are the
506 * Client. Update the deliver window and return its new value. */
508 sendme_circuit_data_received(circuit_t *circ, crypt_path_t *layer_hint)
510 int deliver_window, domain;
512 if (CIRCUIT_IS_ORIGIN(circ)) {
513 tor_assert(layer_hint);
514 --layer_hint->deliver_window;
515 deliver_window = layer_hint->deliver_window;
516 domain = LD_APP;
517 } else {
518 tor_assert(!layer_hint);
519 --circ->deliver_window;
520 deliver_window = circ->deliver_window;
521 domain = LD_EXIT;
524 log_debug(domain, "Circuit deliver_window now %d.", deliver_window);
525 return deliver_window;
528 /* Called when a relay DATA cell is received for the given edge connection
529 * conn. Update the deliver window and return its new value. */
531 sendme_stream_data_received(edge_connection_t *conn)
533 tor_assert(conn);
534 return --conn->deliver_window;
537 /* Called when a relay DATA cell is packaged on the given circuit. If
538 * layer_hint is NULL, this means we are the Exit end point else we are the
539 * Client. Update the package window and return its new value. */
541 sendme_note_circuit_data_packaged(circuit_t *circ, crypt_path_t *layer_hint)
543 int package_window, domain;
545 tor_assert(circ);
547 if (CIRCUIT_IS_ORIGIN(circ)) {
548 /* Client side. */
549 tor_assert(layer_hint);
550 --layer_hint->package_window;
551 package_window = layer_hint->package_window;
552 domain = LD_APP;
553 } else {
554 /* Exit side. */
555 tor_assert(!layer_hint);
556 --circ->package_window;
557 package_window = circ->package_window;
558 domain = LD_EXIT;
561 log_debug(domain, "Circuit package_window now %d.", package_window);
562 return package_window;
565 /* Called when a relay DATA cell is packaged for the given edge connection
566 * conn. Update the package window and return its new value. */
568 sendme_note_stream_data_packaged(edge_connection_t *conn)
570 tor_assert(conn);
571 return --conn->package_window;
574 /* Note the cell digest in the circuit sendme last digests FIFO if applicable.
575 * It is safe to pass a circuit that isn't meant to track those digests. */
576 void
577 sendme_record_cell_digest(circuit_t *circ)
579 const uint8_t *digest;
581 tor_assert(circ);
583 /* We only keep the cell digest if we are the Exit on that circuit and if
584 * this cell is the last one before the client should send a SENDME. */
585 if (CIRCUIT_IS_ORIGIN(circ)) {
586 return;
588 /* Is this the last cell before a SENDME? The idea is that if the
589 * package_window reaches a multiple of the increment, after this cell, we
590 * should expect a SENDME. */
591 if (!sendme_circuit_cell_is_next(circ->package_window)) {
592 return;
595 /* Add the digest to the last seen list in the circuit. */
596 digest = relay_crypto_get_sendme_digest(&TO_OR_CIRCUIT(circ)->crypto);
597 if (circ->sendme_last_digests == NULL) {
598 circ->sendme_last_digests = smartlist_new();
600 smartlist_add(circ->sendme_last_digests, tor_memdup(digest, DIGEST_LEN));