aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2008-07-23 15:58:38 +0000
committerNick Mathewson <nickm@torproject.org>2008-07-23 15:58:38 +0000
commitea95ce25b63e6a291d9c816308919caf887fa7ea (patch)
tree46fcdd336a7197acf4b3fb6b861d9c9068be3ef3 /src
parent2748afe60961596791bceb842dce2385c5b4db7e (diff)
downloadtor-ea95ce25b63e6a291d9c816308919caf887fa7ea.tar
tor-ea95ce25b63e6a291d9c816308919caf887fa7ea.tar.gz
r17323@aud-055: nickm | 2008-07-23 17:58:25 +0200
Implement most of proposal 110. svn:r16156
Diffstat (limited to 'src')
-rw-r--r--src/or/circuitlist.c4
-rw-r--r--src/or/command.c28
-rw-r--r--src/or/or.h20
-rw-r--r--src/or/relay.c17
4 files changed, 63 insertions, 6 deletions
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c
index 25cafb9e6..a090aefa5 100644
--- a/src/or/circuitlist.c
+++ b/src/or/circuitlist.c
@@ -347,6 +347,8 @@ origin_circuit_new(void)
circ->next_stream_id = crypto_rand_int(1<<16);
circ->global_identifier = n_circuits_allocated++;
+ circ->remaining_relay_early_cells = MAX_RELAY_EARLY_CELLS_PER_CIRCUIT;
+ circ->remaining_relay_early_cells -= crypto_rand_int(2);
init_circuit_base(TO_CIRCUIT(circ));
@@ -367,6 +369,8 @@ or_circuit_new(circid_t p_circ_id, or_connection_t *p_conn)
if (p_conn)
circuit_set_p_circid_orconn(circ, p_circ_id, p_conn);
+ circ->remaining_relay_early_cells = MAX_RELAY_EARLY_CELLS_PER_CIRCUIT;
+
init_circuit_base(TO_CIRCUIT(circ));
return circ;
diff --git a/src/or/command.c b/src/or/command.c
index 4a0884239..89bc72ef1 100644
--- a/src/or/command.c
+++ b/src/or/command.c
@@ -353,8 +353,8 @@ command_process_created_cell(cell_t *cell, or_connection_t *conn)
}
}
-/** Process a 'relay' <b>cell</b> that just arrived from <b>conn</b>. Make sure
- * it came in with a recognized circ_id. Pass it on to
+/** Process a 'relay' or 'relay_early' <b>cell</b> that just arrived from
+ * <b>conn</b>. Make sure it came in with a recognized circ_id. Pass it on to
* circuit_receive_relay_cell() for actual processing.
*/
static void
@@ -390,6 +390,30 @@ command_process_relay_cell(cell_t *cell, or_connection_t *conn)
else
direction = CELL_DIRECTION_IN;
+ /* If we have a relay_early cell, make sure that it's outbound, and we've
+ * gotten no more than MAX_RELAY_EARLY_CELLS_PER_CIRCUIT of them. */
+ if (cell->command == CELL_RELAY_EARLY) {
+ if (direction == CELL_DIRECTION_IN) {
+ log_fn(LOG_PROTOCOL_WARN, LD_OR,
+ "Received an inbound RELAY_EARLY cell on circuit %d from %s:%d."
+ " Closing circuit.",
+ cell->circ_id, conn->_base.address, conn->_base.port);
+ circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL);
+ return;
+ } else {
+ or_circuit_t *or_circ = TO_OR_CIRCUIT(circ);
+ if (or_circ->remaining_relay_early_cells == 0) {
+ log_fn(LOG_PROTOCOL_WARN, LD_OR,
+ "Received too many RELAY_EARLY cells on circ %d from %s:%d."
+ " Closing circuit.",
+ cell->circ_id, safe_str(conn->_base.address), conn->_base.port);
+ circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL);
+ return;
+ }
+ --or_circ->remaining_relay_early_cells;
+ }
+ }
+
if ((reason = circuit_receive_relay_cell(cell, circ, direction)) < 0) {
log_fn(LOG_PROTOCOL_WARN,LD_PROTOCOL,"circuit_receive_relay_cell "
"(%s) failed. Closing.",
diff --git a/src/or/or.h b/src/or/or.h
index f8ee695fa..398d4b6b6 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -1828,6 +1828,10 @@ typedef struct circuit_t {
struct circuit_t *next; /**< Next circuit in linked list of all circuits. */
} circuit_t;
+/** Largest number of relay_early cells that we can send on a given
+ * circuit. */
+#define MAX_RELAY_EARLY_CELLS_PER_CIRCUIT 8
+
/** An origin_circuit_t holds data necessary to build and use a circuit.
*/
typedef struct origin_circuit_t {
@@ -1870,15 +1874,19 @@ typedef struct origin_circuit_t {
*/
uint8_t rend_desc_version;
- /* The intro key replaces the hidden service's public key if purpose is
- * S_ESTABLISH_INTRO or S_INTRO, provided that no unversioned rendezvous
- * descriptor is used. */
- crypto_pk_env_t *intro_key;
+ /** How many more relay_early cells can we send on this circuit, according
+ * to the specification? */
+ unsigned int remaining_relay_early_cells : 4;
/** The next stream_id that will be tried when we're attempting to
* construct a new AP stream originating at this circuit. */
streamid_t next_stream_id;
+ /* The intro key replaces the hidden service's public key if purpose is
+ * S_ESTABLISH_INTRO or S_INTRO, provided that no unversioned rendezvous
+ * descriptor is used. */
+ crypto_pk_env_t *intro_key;
+
/** Quasi-global identifier for this circuit; used for control.c */
/* XXXX NM This can get re-used after 2**32 circuits. */
uint32_t global_identifier;
@@ -1946,6 +1954,10 @@ typedef struct or_circuit_t {
/* ???? move to a subtype or adjunct structure? Wastes 20 bytes -NM */
char handshake_digest[DIGEST_LEN]; /**< Stores KH for the handshake. */
+ /** How many more relay_early cells can we send on this circuit, according
+ * to the specification? */
+ unsigned int remaining_relay_early_cells : 4;
+
/** True iff this circuit was made with a CREATE_FAST cell. */
unsigned int is_first_hop : 1;
} or_circuit_t;
diff --git a/src/or/relay.c b/src/or/relay.c
index 40a5ee010..155f06669 100644
--- a/src/or/relay.c
+++ b/src/or/relay.c
@@ -338,6 +338,7 @@ circuit_package_relay_cell(cell_t *cell, circuit_t *circ,
log_warn(LD_BUG,"outgoing relay cell has n_conn==NULL. Dropping.");
return 0; /* just drop it */
}
+
relay_set_digest(layer_hint->f_digest, cell);
thishop = layer_hint;
@@ -506,6 +507,22 @@ relay_send_command_from_edge(uint16_t stream_id, circuit_t *circ,
circ->n_conn->client_used = time(NULL);
}
+ if (cell_direction == CELL_DIRECTION_OUT) {
+ origin_circuit_t *origin_circ = TO_ORIGIN_CIRCUIT(circ);
+ if (origin_circ->remaining_relay_early_cells > 0) {
+ /* If we've got any relay_early cells left, use one. Don't worry
+ * about the conn protocol version: append_cell_to_circuit_queue will
+ * fix it up. */
+ cell.command = CELL_RELAY_EARLY;
+ --origin_circ->remaining_relay_early_cells;
+ log_debug(LD_OR, "Sending a RELAY_EARLY cell; %d remaining.",
+ (int)origin_circ->remaining_relay_early_cells);
+ } else if (relay_command == RELAY_COMMAND_EXTEND) {
+ log_warn(LD_BUG, "Uh-oh. We're sending a RELAY_COMMAND_EXTEND cell, "
+ "but we have run out of RELAY_EARLY cells on that circuit.");
+ }
+ }
+
if (circuit_package_relay_cell(&cell, circ, cell_direction, cpath_layer)
< 0) {
log_warn(LD_BUG,"circuit_package_relay_cell failed. Closing.");