mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-27 13:53:31 +01:00
r17323@aud-055: nickm | 2008-07-23 17:58:25 +0200
Implement most of proposal 110. svn:r16156
This commit is contained in:
parent
2748afe609
commit
ea95ce25b6
@ -3,6 +3,13 @@ Changes in version 0.2.1.3-alpha - 2008-07-xx
|
||||
- Send a bootstrap problem "warn" event on the first problem if the
|
||||
reason is NO_ROUTE (that is, our network is down).
|
||||
|
||||
o Major features:
|
||||
- Implements most of proposal 110: The first K cells to be send
|
||||
along a circuit are marked as special "early" cells; only K
|
||||
"early" cells will be allowed. Once this code is universal, we
|
||||
can block certain kinds of DOS attack by only allowing EXTEND
|
||||
commands in these cells.
|
||||
|
||||
o Major bugfixes:
|
||||
- Try to attach connections immediately upon receiving a RENDEZVOUS2
|
||||
or RENDEZVOUS_ESTABLISHED cell. This can save a second or two
|
||||
|
2
doc/TODO
2
doc/TODO
@ -214,7 +214,7 @@ R d Setting DirPort when acting as bridge will give false Warnings
|
||||
|
||||
For 0.2.1.x:
|
||||
- Proposals to do:
|
||||
- 110: avoid infinite-length circuits
|
||||
o 110: avoid infinite-length circuits
|
||||
R d 128: families of private bridges
|
||||
- 134: handle authority fragmentation.
|
||||
|
||||
|
@ -6,9 +6,11 @@ Author: Roger Dingledine
|
||||
Created: 13-Mar-2007
|
||||
Status: Accepted
|
||||
Target: 0.2.1.x
|
||||
Implemented-In: 0.2.1.3-alpha
|
||||
|
||||
History:
|
||||
|
||||
Revised 28 July 2008 by nickm: set K.
|
||||
Revised 3 July 2008 by nickm: rename from relay_extend to
|
||||
relay_early. Revise to current migration plan. Allow K cells
|
||||
over circuit lifetime, not just at start.
|
||||
@ -85,17 +87,22 @@ Migration:
|
||||
is not speaking the v2 link protocol, the server relays the cell as
|
||||
a RELAY cell.
|
||||
|
||||
In 0.2.1.x, clients begin using RELAY_EARLY cells on v2 connections.
|
||||
This functionality can be safely backported to 0.2.0.x. Clients
|
||||
should pick a random number betweeen (say) 8 and 10 to send.
|
||||
In 0.2.1.3-alpha, clients begin using RELAY_EARLY cells on v2
|
||||
connections. This functionality can be safely backported to
|
||||
0.2.0.x. Clients should pick a random number betweeen (say) K and
|
||||
K-2 to send.
|
||||
|
||||
In 0.2.1.x, servers close any circuit in which more than K
|
||||
In 0.2.1.3-alpha, servers close any circuit in which more than K
|
||||
relay_early cells are sent.
|
||||
|
||||
Once all versions the do not send RELAY_EARLY cells are obsolete,
|
||||
servers can begin to reject any EXTEND requests not sent in a
|
||||
RELAY_EARLY cell.
|
||||
|
||||
Parameters:
|
||||
|
||||
Let K = 8, for no terribly good reason.
|
||||
|
||||
Spec:
|
||||
|
||||
[We can formalize this part once we think the design is a good one.]
|
||||
|
@ -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;
|
||||
|
@ -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.",
|
||||
|
20
src/or/or.h
20
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;
|
||||
|
@ -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.");
|
||||
|
Loading…
Reference in New Issue
Block a user