[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [tor/main] Handle other places that use onion handshake type values
commit a0eeadfba2c1d7d33214286ef7697971120cbe16
Author: Mike Perry <mikeperry-git@xxxxxxxxxxxxxx>
Date: Fri Nov 5 20:50:39 2021 +0000
Handle other places that use onion handshake type values
We want ntor and ntorv3 to use the same queues and stats.
---
src/core/crypto/onion_crypto.c | 1 -
src/core/or/onion.c | 14 +++++++++
src/core/or/or.h | 2 +-
src/feature/relay/onion_queue.c | 64 ++++++++++++++++++++++++++++-------------
src/feature/stats/rephist.c | 59 ++++++++++++++++++-------------------
src/feature/stats/rephist.h | 8 ++++--
6 files changed, 95 insertions(+), 53 deletions(-)
diff --git a/src/core/crypto/onion_crypto.c b/src/core/crypto/onion_crypto.c
index 13f8f54b35..4a83a73dab 100644
--- a/src/core/crypto/onion_crypto.c
+++ b/src/core/crypto/onion_crypto.c
@@ -49,7 +49,6 @@
#include "core/or/extend_info_st.h"
#include "trunnel/circ_params.h"
-/* TODO-324: Add this to the specification! */
static const uint8_t NTOR3_CIRC_VERIFICATION[] = "circuit extend";
static const size_t NTOR3_CIRC_VERIFICATION_LEN = 14;
diff --git a/src/core/or/onion.c b/src/core/or/onion.c
index 62ad7af3fe..0bdd2a6d35 100644
--- a/src/core/or/onion.c
+++ b/src/core/or/onion.c
@@ -88,6 +88,10 @@ check_create_cell(const create_cell_t *cell, int unknown_ok)
if (cell->handshake_len != NTOR_ONIONSKIN_LEN)
return -1;
break;
+ case ONION_HANDSHAKE_TYPE_NTOR_V3:
+ /* ntor v3 has variable length fields that are checked
+ * elsewhere. Fall through to always valid here. */
+ break;
default:
if (! unknown_ok)
return -1;
@@ -521,6 +525,11 @@ create_cell_format_impl(cell_t *cell_out, const create_cell_t *cell_in,
switch (cell_in->cell_type) {
case CELL_CREATE:
+ if (BUG(cell_in->handshake_type == ONION_HANDSHAKE_TYPE_NTOR_V3)) {
+ log_warn(LD_BUG, "Create cells cannot contain ntorv3.");
+ return -1;
+ }
+
if (cell_in->handshake_type == ONION_HANDSHAKE_TYPE_NTOR) {
memcpy(p, NTOR_CREATE_MAGIC, 16);
p += 16;
@@ -619,6 +628,11 @@ extend_cell_format(uint8_t *command_out, uint16_t *len_out,
switch (cell_in->cell_type) {
case RELAY_COMMAND_EXTEND:
{
+ if (BUG(cell_in->create_cell.handshake_type ==
+ ONION_HANDSHAKE_TYPE_NTOR_V3)) {
+ log_warn(LD_BUG, "Extend cells cannot contain ntorv3!");
+ return -1;
+ }
*command_out = RELAY_COMMAND_EXTEND;
*len_out = 6 + TAP_ONIONSKIN_CHALLENGE_LEN + DIGEST_LEN;
set_uint32(p, tor_addr_to_ipv4n(&cell_in->orport_ipv4.addr));
diff --git a/src/core/or/or.h b/src/core/or/or.h
index 885c0e8b11..dc8f516f0a 100644
--- a/src/core/or/or.h
+++ b/src/core/or/or.h
@@ -793,7 +793,7 @@ typedef enum {
#define ONION_HANDSHAKE_TYPE_TAP 0x0000
#define ONION_HANDSHAKE_TYPE_FAST 0x0001
#define ONION_HANDSHAKE_TYPE_NTOR 0x0002
-#define ONION_HANDSHAKE_TYPE_NTOR_V3 0x0003 /* TODO-324: Add to spec */
+#define ONION_HANDSHAKE_TYPE_NTOR_V3 0x0003
#define MAX_ONION_HANDSHAKE_TYPE 0x0003
typedef struct onion_handshake_state_t onion_handshake_state_t;
diff --git a/src/feature/relay/onion_queue.c b/src/feature/relay/onion_queue.c
index c09f4d5b9b..b0bb71a084 100644
--- a/src/feature/relay/onion_queue.c
+++ b/src/feature/relay/onion_queue.c
@@ -42,7 +42,7 @@
typedef struct onion_queue_t {
TOR_TAILQ_ENTRY(onion_queue_t) next;
or_circuit_t *circ;
- uint16_t handshake_type;
+ uint16_t queue_idx;
create_cell_t *onionskin;
time_t when_added;
} onion_queue_t;
@@ -53,20 +53,41 @@ typedef struct onion_queue_t {
TOR_TAILQ_HEAD(onion_queue_head_t, onion_queue_t);
typedef struct onion_queue_head_t onion_queue_head_t;
+/** We have 3 queues: tap, fast, and ntor. (ntorv3 goes into ntor queue). */
+#define MAX_QUEUE_IDX ONION_HANDSHAKE_TYPE_NTOR
+
/** Array of queues of circuits waiting for CPU workers. An element is NULL
* if that queue is empty.*/
-static onion_queue_head_t ol_list[MAX_ONION_HANDSHAKE_TYPE+1] =
+static onion_queue_head_t ol_list[MAX_QUEUE_IDX+1] =
{ TOR_TAILQ_HEAD_INITIALIZER(ol_list[0]), /* tap */
TOR_TAILQ_HEAD_INITIALIZER(ol_list[1]), /* fast */
TOR_TAILQ_HEAD_INITIALIZER(ol_list[2]), /* ntor */
};
/** Number of entries of each type currently in each element of ol_list[]. */
-static int ol_entries[MAX_ONION_HANDSHAKE_TYPE+1];
+static int ol_entries[MAX_QUEUE_IDX+1];
static int num_ntors_per_tap(void);
static void onion_queue_entry_remove(onion_queue_t *victim);
+/**
+ * We combine ntorv3 and ntor into the same queue, so we must
+ * use this function to covert the cell type to a queue index.
+ */
+static inline uint16_t
+onionskin_type_to_queue(uint16_t type)
+{
+ if (type == ONION_HANDSHAKE_TYPE_NTOR_V3) {
+ return ONION_HANDSHAKE_TYPE_NTOR;
+ }
+
+ if (BUG(type > MAX_QUEUE_IDX)) {
+ return MAX_QUEUE_IDX; // use ntor if out of range
+ }
+
+ return type;
+}
+
/* XXXX Check lengths vs MAX_ONIONSKIN_{CHALLENGE,REPLY}_LEN.
*
* (By which I think I meant, "make sure that no
@@ -144,6 +165,7 @@ onion_pending_add(or_circuit_t *circ, create_cell_t *onionskin)
{
onion_queue_t *tmp;
time_t now = time(NULL);
+ uint16_t queue_idx = 0;
if (onionskin->handshake_type > MAX_ONION_HANDSHAKE_TYPE) {
/* LCOV_EXCL_START
@@ -154,18 +176,20 @@ onion_pending_add(or_circuit_t *circ, create_cell_t *onionskin)
/* LCOV_EXCL_STOP */
}
+ queue_idx = onionskin_type_to_queue(onionskin->handshake_type);
+
tmp = tor_malloc_zero(sizeof(onion_queue_t));
tmp->circ = circ;
- tmp->handshake_type = onionskin->handshake_type;
+ tmp->queue_idx = queue_idx;
tmp->onionskin = onionskin;
tmp->when_added = now;
- if (!have_room_for_onionskin(onionskin->handshake_type)) {
+ if (!have_room_for_onionskin(queue_idx)) {
#define WARN_TOO_MANY_CIRC_CREATIONS_INTERVAL (60)
static ratelim_t last_warned =
RATELIM_INIT(WARN_TOO_MANY_CIRC_CREATIONS_INTERVAL);
- rep_hist_note_circuit_handshake_dropped(onionskin->handshake_type);
- if (onionskin->handshake_type == ONION_HANDSHAKE_TYPE_NTOR) {
+ rep_hist_note_circuit_handshake_dropped(queue_idx);
+ if (queue_idx == ONION_HANDSHAKE_TYPE_NTOR) {
char *m;
/* Note this ntor onionskin drop as an overload */
rep_hist_note_overload(OVERLOAD_GENERAL);
@@ -183,18 +207,18 @@ onion_pending_add(or_circuit_t *circ, create_cell_t *onionskin)
return -1;
}
- ++ol_entries[onionskin->handshake_type];
+ ++ol_entries[queue_idx];
log_info(LD_OR, "New create (%s). Queues now ntor=%d and tap=%d.",
- onionskin->handshake_type == ONION_HANDSHAKE_TYPE_NTOR ? "ntor" : "tap",
+ queue_idx == ONION_HANDSHAKE_TYPE_NTOR ? "ntor" : "tap",
ol_entries[ONION_HANDSHAKE_TYPE_NTOR],
ol_entries[ONION_HANDSHAKE_TYPE_TAP]);
circ->onionqueue_entry = tmp;
- TOR_TAILQ_INSERT_TAIL(&ol_list[onionskin->handshake_type], tmp, next);
+ TOR_TAILQ_INSERT_TAIL(&ol_list[queue_idx], tmp, next);
/* cull elderly requests. */
while (1) {
- onion_queue_t *head = TOR_TAILQ_FIRST(&ol_list[onionskin->handshake_type]);
+ onion_queue_t *head = TOR_TAILQ_FIRST(&ol_list[queue_idx]);
if (now - head->when_added < (time_t)ONIONQUEUE_WAIT_CUTOFF)
break;
@@ -282,15 +306,15 @@ onion_next_task(create_cell_t **onionskin_out)
return NULL; /* no onions pending, we're done */
tor_assert(head->circ);
- tor_assert(head->handshake_type <= MAX_ONION_HANDSHAKE_TYPE);
+ tor_assert(head->queue_idx <= MAX_QUEUE_IDX);
// tor_assert(head->circ->p_chan); /* make sure it's still valid */
/* XXX I only commented out the above line to make the unit tests
* more manageable. That's probably not good long-term. -RD */
circ = head->circ;
if (head->onionskin)
- --ol_entries[head->handshake_type];
+ --ol_entries[head->queue_idx];
log_info(LD_OR, "Processing create (%s). Queues now ntor=%d and tap=%d.",
- head->handshake_type == ONION_HANDSHAKE_TYPE_NTOR ? "ntor" : "tap",
+ head->queue_idx == ONION_HANDSHAKE_TYPE_NTOR ? "ntor" : "tap",
ol_entries[ONION_HANDSHAKE_TYPE_NTOR],
ol_entries[ONION_HANDSHAKE_TYPE_TAP]);
@@ -306,7 +330,7 @@ onion_next_task(create_cell_t **onionskin_out)
int
onion_num_pending(uint16_t handshake_type)
{
- return ol_entries[handshake_type];
+ return ol_entries[onionskin_type_to_queue(handshake_type)];
}
/** Go through ol_list, find the onion_queue_t element which points to
@@ -332,23 +356,23 @@ onion_pending_remove(or_circuit_t *circ)
static void
onion_queue_entry_remove(onion_queue_t *victim)
{
- if (victim->handshake_type > MAX_ONION_HANDSHAKE_TYPE) {
+ if (victim->queue_idx > MAX_QUEUE_IDX) {
/* LCOV_EXCL_START
* We should have rejected this far before this point */
log_warn(LD_BUG, "Handshake %d out of range! Dropping.",
- victim->handshake_type);
+ victim->queue_idx);
/* XXX leaks */
return;
/* LCOV_EXCL_STOP */
}
- TOR_TAILQ_REMOVE(&ol_list[victim->handshake_type], victim, next);
+ TOR_TAILQ_REMOVE(&ol_list[victim->queue_idx], victim, next);
if (victim->circ)
victim->circ->onionqueue_entry = NULL;
if (victim->onionskin)
- --ol_entries[victim->handshake_type];
+ --ol_entries[victim->queue_idx];
tor_free(victim->onionskin);
tor_free(victim);
@@ -360,7 +384,7 @@ clear_pending_onions(void)
{
onion_queue_t *victim, *next;
int i;
- for (i=0; i<=MAX_ONION_HANDSHAKE_TYPE; i++) {
+ for (i=0; i<=MAX_QUEUE_IDX; i++) {
for (victim = TOR_TAILQ_FIRST(&ol_list[i]); victim; victim = next) {
next = TOR_TAILQ_NEXT(victim,next);
onion_queue_entry_remove(victim);
diff --git a/src/feature/stats/rephist.c b/src/feature/stats/rephist.c
index 5ff4ef1d2e..11a75bbb14 100644
--- a/src/feature/stats/rephist.c
+++ b/src/feature/stats/rephist.c
@@ -2053,21 +2053,38 @@ rep_hist_note_desc_served(const char * desc)
*
* They are reset at every heartbeat.
* @{ */
-STATIC int onion_handshakes_requested[MAX_ONION_HANDSHAKE_TYPE+1] = {0};
-STATIC int onion_handshakes_assigned[MAX_ONION_HANDSHAKE_TYPE+1] = {0};
+STATIC int onion_handshakes_requested[MAX_ONION_STAT_TYPE+1] = {0};
+STATIC int onion_handshakes_assigned[MAX_ONION_STAT_TYPE+1] = {0};
/**@}*/
/** Counters keeping the same stats as above but for the entire duration of the
* process (not reset). */
-static uint64_t stats_n_onionskin_assigned[MAX_ONION_HANDSHAKE_TYPE+1] = {0};
-static uint64_t stats_n_onionskin_dropped[MAX_ONION_HANDSHAKE_TYPE+1] = {0};
+static uint64_t stats_n_onionskin_assigned[MAX_ONION_STAT_TYPE+1] = {0};
+static uint64_t stats_n_onionskin_dropped[MAX_ONION_STAT_TYPE+1] = {0};
+
+/**
+ * We combine ntorv3 and ntor into the same stat, so we must
+ * use this function to covert the cell type to a stat index.
+ */
+static inline uint16_t
+onionskin_type_to_stat(uint16_t type)
+{
+ if (type == ONION_HANDSHAKE_TYPE_NTOR_V3) {
+ return ONION_HANDSHAKE_TYPE_NTOR;
+ }
+
+ if (BUG(type > MAX_ONION_STAT_TYPE)) {
+ return MAX_ONION_STAT_TYPE; // use ntor if out of range
+ }
+
+ return type;
+}
/** A new onionskin (using the <b>type</b> handshake) has arrived. */
void
rep_hist_note_circuit_handshake_requested(uint16_t type)
{
- if (type <= MAX_ONION_HANDSHAKE_TYPE)
- onion_handshakes_requested[type]++;
+ onion_handshakes_requested[onionskin_type_to_stat(type)]++;
}
/** We've sent an onionskin (using the <b>type</b> handshake) to a
@@ -2075,10 +2092,8 @@ rep_hist_note_circuit_handshake_requested(uint16_t type)
void
rep_hist_note_circuit_handshake_assigned(uint16_t type)
{
- if (type <= MAX_ONION_HANDSHAKE_TYPE) {
- onion_handshakes_assigned[type]++;
- stats_n_onionskin_assigned[type]++;
- }
+ onion_handshakes_assigned[onionskin_type_to_stat(type)]++;
+ stats_n_onionskin_assigned[onionskin_type_to_stat(type)]++;
}
/** We've just drop an onionskin (using the <b>type</b> handshake) due to being
@@ -2086,49 +2101,35 @@ rep_hist_note_circuit_handshake_assigned(uint16_t type)
void
rep_hist_note_circuit_handshake_dropped(uint16_t type)
{
- if (type <= MAX_ONION_HANDSHAKE_TYPE) {
- stats_n_onionskin_dropped[type]++;
- }
+ stats_n_onionskin_dropped[onionskin_type_to_stat(type)]++;
}
/** Get the circuit handshake value that is requested. */
MOCK_IMPL(int,
rep_hist_get_circuit_handshake_requested, (uint16_t type))
{
- if (BUG(type > MAX_ONION_HANDSHAKE_TYPE)) {
- return 0;
- }
- return onion_handshakes_requested[type];
+ return onion_handshakes_requested[onionskin_type_to_stat(type)];
}
/** Get the circuit handshake value that is assigned. */
MOCK_IMPL(int,
rep_hist_get_circuit_handshake_assigned, (uint16_t type))
{
- if (BUG(type > MAX_ONION_HANDSHAKE_TYPE)) {
- return 0;
- }
- return onion_handshakes_assigned[type];
+ return onion_handshakes_assigned[onionskin_type_to_stat(type)];
}
/** Get the total number of circuit handshake value that is assigned. */
MOCK_IMPL(uint64_t,
rep_hist_get_circuit_n_handshake_assigned, (uint16_t type))
{
- if (BUG(type > MAX_ONION_HANDSHAKE_TYPE)) {
- return 0;
- }
- return stats_n_onionskin_assigned[type];
+ return stats_n_onionskin_assigned[onionskin_type_to_stat(type)];
}
/** Get the total number of circuit handshake value that is dropped. */
MOCK_IMPL(uint64_t,
rep_hist_get_circuit_n_handshake_dropped, (uint16_t type))
{
- if (BUG(type > MAX_ONION_HANDSHAKE_TYPE)) {
- return 0;
- }
- return stats_n_onionskin_dropped[type];
+ return stats_n_onionskin_dropped[onionskin_type_to_stat(type)];
}
/** Log our onionskin statistics since the last time we were called. */
diff --git a/src/feature/stats/rephist.h b/src/feature/stats/rephist.h
index 7f414de4c8..2fb24a10a7 100644
--- a/src/feature/stats/rephist.h
+++ b/src/feature/stats/rephist.h
@@ -89,11 +89,15 @@ uint64_t rep_hist_get_n_dns_request(int type);
void rep_hist_note_dns_request(int type);
void rep_hist_note_dns_error(int type, uint8_t error);
+/** We combine ntor and ntorv3 stats, so we have 3 stat types:
+ * tap, fast, and ntor. The max type is ntor (2) */
+#define MAX_ONION_STAT_TYPE ONION_HANDSHAKE_TYPE_NTOR
+
extern uint64_t rephist_total_alloc;
extern uint32_t rephist_total_num;
#ifdef TOR_UNIT_TESTS
-extern int onion_handshakes_requested[MAX_ONION_HANDSHAKE_TYPE+1];
-extern int onion_handshakes_assigned[MAX_ONION_HANDSHAKE_TYPE+1];
+extern int onion_handshakes_requested[MAX_ONION_STAT_TYPE+1];
+extern int onion_handshakes_assigned[MAX_ONION_STAT_TYPE+1];
#endif
#ifdef REPHIST_PRIVATE
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits