10 #define SENDME_PRIVATE
21 #include "core/or/or_circuit_st.h"
26 #include "trunnel/sendme_cell.h"
31 get_emit_min_version(
void)
34 SENDME_EMIT_MIN_VERSION_DEFAULT,
35 SENDME_EMIT_MIN_VERSION_MIN,
36 SENDME_EMIT_MIN_VERSION_MAX);
42 get_accept_min_version(
void)
45 SENDME_ACCEPT_MIN_VERSION_DEFAULT,
46 SENDME_ACCEPT_MIN_VERSION_MIN,
47 SENDME_ACCEPT_MIN_VERSION_MAX);
56 pop_first_cell_digest(
const circuit_t *circ)
82 v1_digest_matches(
const uint8_t *circ_digest,
const uint8_t *cell_digest)
89 if (
tor_memneq(circ_digest, cell_digest, TRUNNEL_SENDME_V1_DIGEST_LEN)) {
91 "SENDME v1 cell digest do not match.");
106 cell_v1_is_valid(
const sendme_cell_t *cell,
const uint8_t *circ_digest)
111 const uint8_t *cell_digest = sendme_cell_getconstarray_data_v1_digest(cell);
112 return v1_digest_matches(circ_digest, cell_digest);
118 cell_version_can_be_handled(uint8_t cell_version)
120 int accept_version = get_accept_min_version();
125 if (accept_version > SENDME_MAX_SUPPORTED_VERSION) {
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);
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);
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);
165 sendme_is_valid(
const circuit_t *circ,
const uint8_t *cell_payload,
166 size_t cell_payload_len)
168 uint8_t cell_version;
169 uint8_t *circ_digest = NULL;
170 sendme_cell_t *cell = NULL;
177 if (cell_payload_len == 0) {
181 if (sendme_cell_parse(&cell, cell_payload, cell_payload_len) < 0) {
183 "Unparseable SENDME cell received. Closing circuit.");
186 cell_version = sendme_cell_get_version(cell);
190 if (!cell_version_can_be_handled(cell_version)) {
197 circ_digest = pop_first_cell_digest(circ);
198 if (circ_digest == NULL) {
203 "We received a SENDME but we have no cell digests to match. "
209 switch (cell_version) {
211 if (!cell_v1_is_valid(cell, circ_digest)) {
220 log_warn(
LD_PROTOCOL,
"Unknown SENDME cell version %d received.",
227 sendme_cell_free(cell);
231 sendme_cell_free(cell);
242 build_cell_payload_v1(
const uint8_t *cell_digest, uint8_t *payload)
245 sendme_cell_t *cell = NULL;
250 cell = sendme_cell_new();
253 sendme_cell_set_version(cell, 0x01);
255 sendme_cell_set_data_len(cell, TRUNNEL_SENDME_V1_DIGEST_LEN);
258 memcpy(sendme_cell_getarray_data_v1_digest(cell), cell_digest,
259 sendme_cell_get_data_len(cell));
264 sendme_cell_free(cell);
275 const uint8_t *cell_digest)
277 uint8_t emit_version;
284 emit_version = get_emit_min_version();
285 switch (emit_version) {
287 payload_len = build_cell_payload_v1(cell_digest, payload);
288 if (BUG(payload_len < 0)) {
293 log_debug(
LD_PROTOCOL,
"Emitting SENDME version 1 cell.");
300 log_debug(
LD_PROTOCOL,
"Emitting SENDME version 0 cell. "
301 "Consensus emit version is %d", emit_version);
305 if (relay_send_command_from_edge(0, circ, RELAY_COMMAND_SENDME,
306 (
char *) payload, payload_len,
309 "SENDME relay_send_command_from_edge failed. Circuit's closed.");
317 record_cell_digest_on_circ(
circuit_t *circ,
const uint8_t *sendme_digest)
389 log_info(log_domain,
"No circuit associated with edge connection. "
390 "Skipping sending SENDME.");
396 log_debug(log_domain,
"Outbuf %" TOR_PRIuSZ
", queuing stream SENDME.",
401 log_debug(
LD_CIRC,
"connection_edge_send_command failed while sending "
402 "a SENDME. Circuit probably closed, skipping.");
420 bool sent_one_sendme =
false;
421 const uint8_t *digest;
425 log_debug(
LD_CIRC,
"Queuing circuit sendme.");
433 if (send_circuit_level_sendme(circ, layer_hint, digest) < 0) {
440 tor_assert_nonfatal(!sent_one_sendme);
441 sent_one_sendme =
true;
458 circuit_t *circ,
const uint8_t *cell_payload,
459 uint16_t cell_payload_len)
466 if (!sendme_is_valid(circ, cell_payload, cell_payload_len)) {
467 return -END_CIRC_REASON_TORPROTOCOL;
475 if (BUG(layer_hint == NULL)) {
476 return -END_CIRC_REASON_TORPROTOCOL;
479 CIRCWINDOW_START_MAX) {
480 static struct ratelim_t exit_warn_ratelim = RATELIM_INIT(600);
482 "Unexpected sendme cell from exit relay. "
484 return -END_CIRC_REASON_TORPROTOCOL;
487 log_debug(
LD_APP,
"circ-level sendme at origin, packagewindow %d.",
497 CIRCWINDOW_START_MAX) {
498 static struct ratelim_t client_warn_ratelim = RATELIM_INIT(600);
500 "Unexpected sendme cell from client. "
502 return -END_CIRC_REASON_TORPROTOCOL;
505 log_debug(LD_EXIT,
"circ-level sendme at non-origin, packagewindow %d.",
523 uint16_t cell_body_len)
533 STREAMWINDOW_START_MAX) {
534 static struct ratelim_t stream_warn_ratelim = RATELIM_INIT(600);
536 "Unexpected stream sendme cell. Closing circ (window %d).",
538 return -END_CIRC_REASON_TORPROTOCOL;
550 "stream-level sendme, package_window now %d.",
561 int deliver_window, domain;
575 log_debug(domain,
"Circuit deliver_window now %d.", deliver_window);
576 return deliver_window;
594 int package_window, domain;
612 log_debug(domain,
"Circuit package_window now %d.", package_window);
613 return package_window;
635 uint8_t *sendme_digest;
660 record_cell_digest_on_circ(circ, sendme_digest);
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_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 connection_outbuf_too_full(connection_t *conn)
Header file for connection.c.
uint8_t * cpath_get_sendme_digest(crypt_path_t *cpath)
void cpath_sendme_record_cell_digest(crypt_path_t *cpath, bool is_foward_digest)
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 RELAY_PAYLOAD_SIZE
#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.
void relay_crypto_record_sendme_digest(relay_crypto_t *crypto, bool is_foward_digest)
uint8_t * relay_crypto_get_sendme_digest(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 circuit_sendme_cell_is_next(int window)
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
#define tor_assert_nonfatal_unreached()