Skip to content

Commit

Permalink
Distinguish Rend version 2 and 3 using the circuit handshake
Browse files Browse the repository at this point in the history
  • Loading branch information
teor2345 committed Jul 12, 2017
1 parent 2c0e36a commit ab0ee67
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 26 deletions.
25 changes: 19 additions & 6 deletions src/or/command.c
Expand Up @@ -363,21 +363,34 @@ command_process_create_cell(cell_t *cell, channel_t *chan)
circ->base_.purpose = CIRCUIT_PURPOSE_OR;
circuit_set_state(TO_CIRCUIT(circ), CIRCUIT_STATE_ONIONSKIN_PENDING);

if (options->EnablePrivCount) {
control_event_privcount_circuit_cell(chan, TO_CIRCUIT(circ), cell,
PRIVCOUNT_CELL_RECEIVED,
NULL, NULL);
}

create_cell = tor_malloc_zero(sizeof(create_cell_t));
if (create_cell_parse(create_cell, cell) < 0) {
tor_free(create_cell);
log_fn(LOG_PROTOCOL_WARN, LD_OR,
"Bogus/unrecognized create cell; closing.");
circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_TORPROTOCOL);

if (options->EnablePrivCount) {
control_event_privcount_circuit_cell(chan, TO_CIRCUIT(circ), cell,
PRIVCOUNT_CELL_RECEIVED,
NULL, NULL);
}

return;
}

/* PrivCount uses this flag to distinguish v2 and v3 rend circuits */
if (create_cell->handshake_type == ONION_HANDSHAKE_TYPE_FAST ||
create_cell->handshake_type == ONION_HANDSHAKE_TYPE_TAP) {
circ->used_legacy_circuit_handshake = 1;
}

if (options->EnablePrivCount) {
control_event_privcount_circuit_cell(chan, TO_CIRCUIT(circ), cell,
PRIVCOUNT_CELL_RECEIVED,
NULL, NULL);
}

if (create_cell->handshake_type != ONION_HANDSHAKE_TYPE_FAST) {
/* hand it off to the cpuworkers, and then return. */
if (connection_or_digest_is_known_relay(chan->identity_digest))
Expand Down
22 changes: 4 additions & 18 deletions src/or/control.c
Expand Up @@ -6164,9 +6164,6 @@ privcount_circuit_is_client_hs(const or_circuit_t *orcirc)
privcount_circuit_is_client_rend(orcirc));
}

/* Silence compiler unused function warnings */
#if 0

/* Is orcirc a service-side hidden service circuit that ends at this relay?
* NULL circuits are not classified as hidden service circuits. */
static int
Expand All @@ -6177,11 +6174,6 @@ privcount_circuit_is_service_hs(const or_circuit_t *orcirc)
privcount_circuit_is_service_rend(orcirc));
}

#endif

/* Silence compiler unused function warnings */
#if 0

/* Is orcirc a hidden service circuit that ends at this relay?
* NULL circuits are not classified as hidden service circuits. */
static int
Expand All @@ -6191,18 +6183,12 @@ privcount_circuit_is_hs(const or_circuit_t *orcirc)
privcount_circuit_is_service_hs(orcirc));
}

#endif

/* If orcirc is hidden service directory or intro circuit that ends at this
* relay, return the hidden service version number for this circuit.
* (Due to padding and cell encryption, it's not possible to tell the
* hidden service version number on rendezvous circuits.)
* Returns 0 for NULL circuits, rend circuits, and all other circuits. */
/* If orcirc is a hsdir, intro, or rend circuit that ends at this
* relay, return the hidden service version number for this circuit. */
static int
privcount_circuit_hs_version_number(const or_circuit_t *orcirc)
{
if (privcount_circuit_is_hsdir(orcirc) ||
privcount_circuit_is_intro(orcirc)) {
if (privcount_circuit_is_hs(orcirc)) {
return orcirc->privcount_hs_version_number;
} else {
return 0;
Expand Down Expand Up @@ -7600,7 +7586,7 @@ privcount_add_circuit_common_fields(smartlist_t *fields,
}

if (hs_version_number) {
/* If the circuit is HSDir or Intro, then
/* If the circuit is HSDir, Intro, or Rend, then
* we know the hidden service version */
smartlist_add_asprintf(fields, "%sHiddenServiceVersionNumber=%d",
prefix, hs_version_number);
Expand Down
4 changes: 4 additions & 0 deletions src/or/or.h
Expand Up @@ -3418,6 +3418,10 @@ typedef struct or_circuit_t {
* have to track whether PrivCount was enabled on the rend splice and
* intro tap before providing their information. */

/** True iff this circuit was made with a CREATE_FAST cell, or a CREATE[2]
* cell with a TAP handshake. We use this to tell Rend v2 from Rend v3. */
unsigned int used_legacy_circuit_handshake : 1;

/* We don't know the hidden service version unless we tag it ourselves.
* 0 means "unknown", valid versions are 2 and 3. */
unsigned int privcount_hs_version_number : 2;
Expand Down
13 changes: 11 additions & 2 deletions src/or/rendmid.c
Expand Up @@ -352,9 +352,18 @@ rend_mid_rendezvous(or_circuit_t *circ, const uint8_t *request,
/* We marked the client side circuit when it opened.
* We don't know the hidden service version on rend points, because v3
* services obscure the real size of HANDSHAKE_INFO by padding it to 168
* bytes, the size of the v2 handshake. We could identify *longer*
* handshakes if we wanted to. */
* bytes, the size of the v2 handshake.
* But TAP handshakes are used for v2 service rend circuits, and ntor
* handshakes are used for v3 service rend circuits.
* We can guess that CREATE_FAST is almost always used for v2 as well. */
circ->privcount_circuit_service_rend = 1;
if (circ->used_legacy_circuit_handshake) {
circ->privcount_hs_version_number = HS_VERSION_TWO;
rend_circ->privcount_hs_version_number = HS_VERSION_TWO;
} else {
circ->privcount_hs_version_number = HS_VERSION_THREE;
rend_circ->privcount_hs_version_number = HS_VERSION_THREE;
}

circuit_change_purpose(TO_CIRCUIT(circ), CIRCUIT_PURPOSE_REND_ESTABLISHED);
circuit_change_purpose(TO_CIRCUIT(rend_circ),
Expand Down

0 comments on commit ab0ee67

Please sign in to comment.