12#define CRYPT_PATH_PRIVATE
23#include "core/or/or_circuit_st.h"
30#include "trunnel/sendme_cell.h"
44get_emit_min_version(
void)
47 SENDME_EMIT_MIN_VERSION_DEFAULT,
48 SENDME_EMIT_MIN_VERSION_MIN,
49 SENDME_EMIT_MIN_VERSION_MAX);
55get_accept_min_version(
void)
58 SENDME_ACCEPT_MIN_VERSION_DEFAULT,
59 SENDME_ACCEPT_MIN_VERSION_MIN,
60 SENDME_ACCEPT_MIN_VERSION_MAX);
69pop_first_cell_digest(
const circuit_t *circ)
88v1_tag_matches(
const uint8_t *circ_digest,
89 const uint8_t *cell_tag,
size_t tag_len)
96 if (
tor_memneq(circ_digest, cell_tag, tag_len)) {
98 "SENDME v1 cell digest do not match.");
113cell_v1_is_valid(
const sendme_cell_t *cell,
const uint8_t *circ_digest,
114 size_t circ_digest_len)
119 size_t tag_len = sendme_cell_get_data_len(cell);
122 if (sendme_cell_getlen_data_v1_digest(cell) < tag_len)
124 if (tag_len != circ_digest_len)
127 const uint8_t *cell_digest = sendme_cell_getconstarray_data_v1_digest(cell);
128 return v1_tag_matches(circ_digest, cell_digest, tag_len);
134cell_version_can_be_handled(uint8_t cell_version)
136 int accept_version = get_accept_min_version();
141 if (accept_version > SENDME_MAX_SUPPORTED_VERSION) {
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);
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);
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);
189 const uint8_t *cell_payload,
190 size_t cell_payload_len)
192 uint8_t cell_version;
193 uint8_t *circ_digest = NULL;
194 sendme_cell_t *cell = NULL;
201 if (cell_payload_len == 0) {
205 if (sendme_cell_parse(&cell, cell_payload, cell_payload_len) < 0) {
207 "Unparseable SENDME cell received. Closing circuit.");
210 cell_version = sendme_cell_get_version(cell);
214 if (!cell_version_can_be_handled(cell_version)) {
219 size_t circ_expects_tag_len;
221 circ_expects_tag_len =
224 const or_circuit_t *or_circ = CONST_TO_OR_CIRCUIT(circ);
234 circ_digest = pop_first_cell_digest(circ);
235 if (circ_digest == NULL) {
240 "We received a SENDME but we have no cell digests to match. "
244 switch (cell_version) {
246 if (!cell_v1_is_valid(cell, circ_digest, circ_expects_tag_len)) {
255 log_warn(
LD_PROTOCOL,
"Unknown SENDME cell version %d received.",
262 sendme_cell_free(cell);
266 sendme_cell_free(cell);
277build_cell_payload_v1(
const uint8_t *cell_tag,
const size_t tag_len,
281 sendme_cell_t *cell = NULL;
287 cell = sendme_cell_new();
290 sendme_cell_set_version(cell, 0x01);
292 sendme_cell_set_data_len(cell, tag_len);
293 sendme_cell_setlen_data_v1_digest(cell, tag_len);
296 memcpy(sendme_cell_getarray_data_v1_digest(cell), cell_tag, tag_len);
301 sendme_cell_free(cell);
312 const uint8_t *cell_tag,
size_t tag_len)
314 uint8_t emit_version;
321 emit_version = get_emit_min_version();
322 switch (emit_version) {
324 payload_len = build_cell_payload_v1(cell_tag, tag_len, payload);
325 if (BUG(payload_len < 0)) {
330 log_debug(
LD_PROTOCOL,
"Emitting SENDME version 1 cell.");
337 log_debug(
LD_PROTOCOL,
"Emitting SENDME version 0 cell. "
338 "Consensus emit version is %d", emit_version);
342 if (relay_send_command_from_edge(0, circ, RELAY_COMMAND_SENDME,
343 (
char *) payload, payload_len,
346 "SENDME relay_send_command_from_edge failed. Circuit's closed.");
354record_cell_digest_on_circ(
circuit_t *circ,
355 const uint8_t *sendme_tag,
370 memcpy(tag, sendme_tag, tag_len);
375 tor_assert_unreached();
411 log_info(log_domain,
"No circuit associated with edge connection. "
412 "Skipping sending SENDME.");
418 log_debug(log_domain,
"Outbuf %" TOR_PRIuSZ
", queuing stream SENDME.",
423 log_debug(
LD_CIRC,
"connection_edge_send_command failed while sending "
424 "a SENDME. Circuit probably closed, skipping.");
442 bool sent_one_sendme =
false;
449 log_debug(
LD_CIRC,
"Queuing circuit sendme.");
458 if (send_circuit_level_sendme(circ, layer_hint, tag, tag_len) < 0) {
465 tor_assert_nonfatal(!sent_one_sendme);
466 sent_one_sendme =
true;
486 circuit_t *circ,
const uint8_t *cell_payload,
487 uint16_t cell_payload_len)
495 if (!sendme_is_valid(circ, layer_hint, cell_payload, cell_payload_len)) {
496 return -END_CIRC_REASON_TORPROTOCOL;
534 if (BUG(layer_hint == NULL)) {
535 return -END_CIRC_REASON_TORPROTOCOL;
538 CIRCWINDOW_START_MAX) {
539 static struct ratelim_t exit_warn_ratelim = RATELIM_INIT(600);
541 "Unexpected sendme cell from exit relay. "
543 return -END_CIRC_REASON_TORPROTOCOL;
546 log_debug(
LD_APP,
"circ-level sendme at origin, packagewindow %d.",
552 CIRCWINDOW_START_MAX) {
553 static struct ratelim_t client_warn_ratelim = RATELIM_INIT(600);
555 "Unexpected sendme cell from client. "
557 return -END_CIRC_REASON_TORPROTOCOL;
560 log_debug(LD_EXIT,
"circ-level sendme at non-origin, packagewindow %d.",
578 uint16_t cell_body_len)
585 "Congestion control got stream sendme");
586 return -END_CIRC_REASON_TORPROTOCOL;
594 STREAMWINDOW_START_MAX) {
595 static struct ratelim_t stream_warn_ratelim = RATELIM_INIT(600);
597 "Unexpected stream sendme cell. Closing circ (window %d).",
599 return -END_CIRC_REASON_TORPROTOCOL;
611 "stream-level sendme, package_window now %d.",
622 int deliver_window, domain;
636 log_debug(domain,
"Circuit deliver_window now %d.", deliver_window);
637 return deliver_window;
660 int package_window, domain;
689 log_debug(domain,
"Circuit package_window now %d.", package_window);
722 const uint8_t *sendme_tag;
743 record_cell_digest_on_circ(circ, sendme_tag, tag_len);
size_t buf_datalen(const buf_t *buf)
Fixed-size cell structure.
circuit_t * circuit_get_by_edge_conn(edge_connection_t *conn)
origin_circuit_t * TO_ORIGIN_CIRCUIT(circuit_t *x)
or_circuit_t * TO_OR_CIRCUIT(circuit_t *x)
Header file for circuitlist.c.
#define CIRCUIT_IS_ORCIRC(c)
#define CIRCUIT_IS_ORIGIN(c)
void circuit_read_valid_data(origin_circuit_t *circ, uint16_t relay_body_len)
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)
Header file for connection.c.
const uint8_t * cpath_get_sendme_tag(crypt_path_t *cpath, size_t *len_out)
Header file for crypt_path.c.
#define tor_memneq(a, b, sz)
#define log_fn(severity, domain, args,...)
#define log_fn_ratelim(ratelim, severity, domain, args,...)
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
#define STREAMWINDOW_START
#define SENDME_TAG_LEN_TOR1
#define SENDME_TAG_LEN_CGO
#define RELAY_PAYLOAD_SIZE_MAX
#define CIRCWINDOW_INCREMENT
int connection_edge_send_command(edge_connection_t *fromconn, uint8_t relay_command, const char *payload, size_t payload_len)
Header for relay_crypto.c.
const uint8_t * relay_crypto_get_sendme_tag(relay_crypto_t *crypto, size_t *len_out)
size_t relay_crypto_sendme_tag_len(const relay_crypto_t *crypto)
void sendme_connection_edge_consider_sending(edge_connection_t *conn)
void sendme_circuit_consider_sending(circuit_t *circ, crypt_path_t *layer_hint)
static bool tag_len_ok(size_t tag_len)
int sendme_process_circuit_level_impl(crypt_path_t *layer_hint, circuit_t *circ)
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
struct congestion_control_t * ccontrol
struct congestion_control_t * ccontrol
#define tor_assert_nonfatal_unreached()