mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-27 22:03:31 +01:00
Merge remote-tracking branch 'public/wide_circ_ids'
Conflicts: src/or/channel.h src/or/connection_or.c src/or/cpuworker.c
This commit is contained in:
commit
d6634001c9
@ -1045,28 +1045,34 @@ cell_command_is_var_length(uint8_t command, int linkproto)
|
||||
int
|
||||
fetch_var_cell_from_buf(buf_t *buf, var_cell_t **out, int linkproto)
|
||||
{
|
||||
char hdr[VAR_CELL_HEADER_SIZE];
|
||||
char hdr[VAR_CELL_MAX_HEADER_SIZE];
|
||||
var_cell_t *result;
|
||||
uint8_t command;
|
||||
uint16_t length;
|
||||
const int wide_circ_ids = linkproto >= MIN_LINK_PROTO_FOR_WIDE_CIRC_IDS;
|
||||
const int circ_id_len = get_circ_id_size(wide_circ_ids);
|
||||
const unsigned header_len = get_var_cell_header_size(wide_circ_ids);
|
||||
check();
|
||||
*out = NULL;
|
||||
if (buf->datalen < VAR_CELL_HEADER_SIZE)
|
||||
if (buf->datalen < header_len)
|
||||
return 0;
|
||||
peek_from_buf(hdr, sizeof(hdr), buf);
|
||||
|
||||
command = get_uint8(hdr+2);
|
||||
command = get_uint8(hdr + circ_id_len);
|
||||
if (!(cell_command_is_var_length(command, linkproto)))
|
||||
return 0;
|
||||
|
||||
length = ntohs(get_uint16(hdr+3));
|
||||
if (buf->datalen < (size_t)(VAR_CELL_HEADER_SIZE+length))
|
||||
length = ntohs(get_uint16(hdr + circ_id_len + 1));
|
||||
if (buf->datalen < (size_t)(header_len+length))
|
||||
return 1;
|
||||
result = var_cell_new(length);
|
||||
result->command = command;
|
||||
result->circ_id = ntohs(get_uint16(hdr));
|
||||
if (wide_circ_ids)
|
||||
result->circ_id = ntohl(get_uint32(hdr));
|
||||
else
|
||||
result->circ_id = ntohs(get_uint16(hdr));
|
||||
|
||||
buf_remove_from_front(buf, VAR_CELL_HEADER_SIZE);
|
||||
buf_remove_from_front(buf, header_len);
|
||||
peek_from_buf((char*) result->payload, length, buf);
|
||||
buf_remove_from_front(buf, length);
|
||||
check();
|
||||
@ -1125,30 +1131,36 @@ fetch_var_cell_from_evbuffer(struct evbuffer *buf, var_cell_t **out,
|
||||
uint16_t cell_length;
|
||||
var_cell_t *cell;
|
||||
int result = 0;
|
||||
const int wide_circ_ids = linkproto >= MIN_LINK_PROTO_FOR_WIDE_CIRC_IDS;
|
||||
const int circ_id_len = get_circ_id_size(wide_circ_ids);
|
||||
const unsigned header_len = get_var_cell_header_size(wide_circ_ids);
|
||||
|
||||
*out = NULL;
|
||||
buf_len = evbuffer_get_length(buf);
|
||||
if (buf_len < VAR_CELL_HEADER_SIZE)
|
||||
if (buf_len < header_len)
|
||||
return 0;
|
||||
|
||||
n = inspect_evbuffer(buf, &hdr, VAR_CELL_HEADER_SIZE, &free_hdr, NULL);
|
||||
tor_assert(n >= VAR_CELL_HEADER_SIZE);
|
||||
n = inspect_evbuffer(buf, &hdr, header_len, &free_hdr, NULL);
|
||||
tor_assert(n >= header_len);
|
||||
|
||||
command = get_uint8(hdr+2);
|
||||
command = get_uint8(hdr + circ_id_len);
|
||||
if (!(cell_command_is_var_length(command, linkproto))) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
cell_length = ntohs(get_uint16(hdr+3));
|
||||
if (buf_len < (size_t)(VAR_CELL_HEADER_SIZE+cell_length)) {
|
||||
cell_length = ntohs(get_uint16(hdr + circ_id_len + 1));
|
||||
if (buf_len < (size_t)(header_len+cell_length)) {
|
||||
result = 1; /* Not all here yet. */
|
||||
goto done;
|
||||
}
|
||||
|
||||
cell = var_cell_new(cell_length);
|
||||
cell->command = command;
|
||||
cell->circ_id = ntohs(get_uint16(hdr));
|
||||
evbuffer_drain(buf, VAR_CELL_HEADER_SIZE);
|
||||
if (wide_circ_ids)
|
||||
cell->circ_id = ntohl(get_uint32(hdr));
|
||||
else
|
||||
cell->circ_id = ntohs(get_uint16(hdr));
|
||||
evbuffer_drain(buf, header_len);
|
||||
evbuffer_remove(buf, cell->payload, cell_length);
|
||||
*out = cell;
|
||||
result = 1;
|
||||
|
@ -4068,9 +4068,10 @@ channel_num_circuits(channel_t *chan)
|
||||
* This is called when setting up a channel and replaces the old
|
||||
* connection_or_set_circid_type()
|
||||
*/
|
||||
|
||||
void
|
||||
channel_set_circid_type(channel_t *chan, crypto_pk_t *identity_rcvd)
|
||||
channel_set_circid_type(channel_t *chan,
|
||||
crypto_pk_t *identity_rcvd,
|
||||
int consider_identity)
|
||||
{
|
||||
int started_here;
|
||||
crypto_pk_t *our_identity;
|
||||
@ -4078,6 +4079,15 @@ channel_set_circid_type(channel_t *chan, crypto_pk_t *identity_rcvd)
|
||||
tor_assert(chan);
|
||||
|
||||
started_here = channel_is_outgoing(chan);
|
||||
|
||||
if (! consider_identity) {
|
||||
if (started_here)
|
||||
chan->circ_id_type = CIRC_ID_TYPE_HIGHER;
|
||||
else
|
||||
chan->circ_id_type = CIRC_ID_TYPE_LOWER;
|
||||
return;
|
||||
}
|
||||
|
||||
our_identity = started_here ?
|
||||
get_tlsclient_identity_key() : get_server_identity_key();
|
||||
|
||||
|
@ -143,6 +143,8 @@ struct channel_s {
|
||||
* space should we use?
|
||||
*/
|
||||
ENUM_BF(circ_id_type_t) circ_id_type:2;
|
||||
/** DOCDOC*/
|
||||
unsigned wide_circ_ids:1;
|
||||
/*
|
||||
* Which circ_id do we try to use next on this connection? This is
|
||||
* always in the range 0..1<<15-1.
|
||||
@ -447,7 +449,8 @@ int channel_matches_extend_info(channel_t *chan, extend_info_t *extend_info);
|
||||
int channel_matches_target_addr_for_extend(channel_t *chan,
|
||||
const tor_addr_t *target);
|
||||
unsigned int channel_num_circuits(channel_t *chan);
|
||||
void channel_set_circid_type(channel_t *chan, crypto_pk_t *identity_rcvd);
|
||||
void channel_set_circid_type(channel_t *chan, crypto_pk_t *identity_rcvd,
|
||||
int consider_identity);
|
||||
void channel_timestamp_client(channel_t *chan);
|
||||
|
||||
const char * channel_listener_describe_transport(channel_listener_t *chan_l);
|
||||
|
@ -600,12 +600,13 @@ channel_tls_write_packed_cell_method(channel_t *chan,
|
||||
packed_cell_t *packed_cell)
|
||||
{
|
||||
channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan);
|
||||
size_t cell_network_size = get_cell_network_size(chan->wide_circ_ids);
|
||||
|
||||
tor_assert(tlschan);
|
||||
tor_assert(packed_cell);
|
||||
tor_assert(tlschan->conn);
|
||||
|
||||
connection_write_to_buf(packed_cell->body, CELL_NETWORK_SIZE,
|
||||
connection_write_to_buf(packed_cell->body, cell_network_size,
|
||||
TO_CONN(tlschan->conn));
|
||||
|
||||
/* This is where the cell is finished; used to be done from relay.c */
|
||||
@ -893,7 +894,7 @@ channel_tls_handle_cell(cell_t *cell, or_connection_t *conn)
|
||||
}
|
||||
|
||||
if (conn->base_.state == OR_CONN_STATE_OR_HANDSHAKING_V3)
|
||||
or_handshake_state_record_cell(conn->handshake_state, cell, 1);
|
||||
or_handshake_state_record_cell(conn, conn->handshake_state, cell, 1);
|
||||
|
||||
switch (cell->command) {
|
||||
case CELL_PADDING:
|
||||
@ -1034,7 +1035,8 @@ channel_tls_handle_var_cell(var_cell_t *var_cell, or_connection_t *conn)
|
||||
break;
|
||||
case OR_CONN_STATE_OR_HANDSHAKING_V3:
|
||||
if (var_cell->command != CELL_AUTHENTICATE)
|
||||
or_handshake_state_record_var_cell(conn->handshake_state, var_cell, 1);
|
||||
or_handshake_state_record_var_cell(conn, conn->handshake_state,
|
||||
var_cell, 1);
|
||||
break; /* Everything is allowed */
|
||||
case OR_CONN_STATE_OPEN:
|
||||
if (conn->link_proto < 3) {
|
||||
@ -1154,7 +1156,8 @@ enter_v3_handshake_with_cell(var_cell_t *cell, channel_tls_t *chan)
|
||||
connection_or_close_for_error(chan->conn, 0);
|
||||
return -1;
|
||||
}
|
||||
or_handshake_state_record_var_cell(chan->conn->handshake_state, cell, 1);
|
||||
or_handshake_state_record_var_cell(chan->conn,
|
||||
chan->conn->handshake_state, cell, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1225,7 +1228,7 @@ channel_tls_process_versions_cell(var_cell_t *cell, channel_tls_t *chan)
|
||||
connection_or_close_for_error(chan->conn, 0);
|
||||
return;
|
||||
} else if (highest_supported_version < 3 &&
|
||||
chan->conn->base_.state == OR_CONN_STATE_OR_HANDSHAKING_V3) {
|
||||
chan->conn->base_.state == OR_CONN_STATE_OR_HANDSHAKING_V3) {
|
||||
log_fn(LOG_PROTOCOL_WARN, LD_OR,
|
||||
"Negotiated link protocol 2 or lower after doing a v3 TLS "
|
||||
"handshake. Closing connection.");
|
||||
@ -1294,6 +1297,13 @@ channel_tls_process_versions_cell(var_cell_t *cell, channel_tls_t *chan)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* We set this after sending the verions cell. */
|
||||
/*XXXXX symbolic const.*/
|
||||
chan->base_.wide_circ_ids =
|
||||
chan->conn->link_proto >= MIN_LINK_PROTO_FOR_WIDE_CIRC_IDS;
|
||||
chan->conn->wide_circ_ids = chan->base_.wide_circ_ids;
|
||||
|
||||
if (send_certs) {
|
||||
if (connection_or_send_certs_cell(chan->conn) < 0) {
|
||||
log_warn(LD_OR, "Couldn't send certs cell");
|
||||
@ -1375,7 +1385,8 @@ channel_tls_process_netinfo_cell(cell_t *cell, channel_tls_t *chan)
|
||||
tor_assert(tor_digest_is_zero(
|
||||
(const char*)(chan->conn->handshake_state->
|
||||
authenticated_peer_id)));
|
||||
channel_set_circid_type(TLS_CHAN_TO_BASE(chan), NULL);
|
||||
channel_set_circid_type(TLS_CHAN_TO_BASE(chan), NULL,
|
||||
chan->conn->link_proto < MIN_LINK_PROTO_FOR_WIDE_CIRC_IDS);
|
||||
|
||||
connection_or_init_conn_from_address(chan->conn,
|
||||
&(chan->conn->base_.addr),
|
||||
@ -1629,7 +1640,8 @@ channel_tls_process_certs_cell(var_cell_t *cell, channel_tls_t *chan)
|
||||
ERR("Internal error: Couldn't get RSA key from ID cert.");
|
||||
memcpy(chan->conn->handshake_state->authenticated_peer_id,
|
||||
id_digests->d[DIGEST_SHA1], DIGEST_LEN);
|
||||
channel_set_circid_type(TLS_CHAN_TO_BASE(chan), identity_rcvd);
|
||||
channel_set_circid_type(TLS_CHAN_TO_BASE(chan), identity_rcvd,
|
||||
chan->conn->link_proto < MIN_LINK_PROTO_FOR_WIDE_CIRC_IDS);
|
||||
crypto_pk_free(identity_rcvd);
|
||||
}
|
||||
|
||||
@ -1913,7 +1925,8 @@ channel_tls_process_authenticate_cell(var_cell_t *cell, channel_tls_t *chan)
|
||||
memcpy(chan->conn->handshake_state->authenticated_peer_id,
|
||||
id_digests->d[DIGEST_SHA1], DIGEST_LEN);
|
||||
|
||||
channel_set_circid_type(TLS_CHAN_TO_BASE(chan), identity_rcvd);
|
||||
channel_set_circid_type(TLS_CHAN_TO_BASE(chan), identity_rcvd,
|
||||
chan->conn->link_proto < MIN_LINK_PROTO_FOR_WIDE_CIRC_IDS);
|
||||
crypto_pk_free(identity_rcvd);
|
||||
|
||||
connection_or_init_conn_from_address(chan->conn,
|
||||
|
@ -100,7 +100,7 @@ get_unique_circ_id_by_chan(channel_t *chan)
|
||||
{
|
||||
circid_t test_circ_id;
|
||||
circid_t attempts=0;
|
||||
circid_t high_bit;
|
||||
circid_t high_bit, max_range;
|
||||
|
||||
tor_assert(chan);
|
||||
|
||||
@ -110,17 +110,17 @@ get_unique_circ_id_by_chan(channel_t *chan)
|
||||
"a client with no identity.");
|
||||
return 0;
|
||||
}
|
||||
high_bit =
|
||||
(chan->circ_id_type == CIRC_ID_TYPE_HIGHER) ? 1<<15 : 0;
|
||||
max_range = (chan->wide_circ_ids) ? (1u<<31) : (1u<<15);
|
||||
high_bit = (chan->circ_id_type == CIRC_ID_TYPE_HIGHER) ? max_range : 0;
|
||||
do {
|
||||
/* Sequentially iterate over test_circ_id=1...1<<15-1 until we find a
|
||||
/* Sequentially iterate over test_circ_id=1...max_range until we find a
|
||||
* circID such that (high_bit|test_circ_id) is not already used. */
|
||||
test_circ_id = chan->next_circ_id++;
|
||||
if (test_circ_id == 0 || test_circ_id >= 1<<15) {
|
||||
if (test_circ_id == 0 || test_circ_id >= max_range) {
|
||||
test_circ_id = 1;
|
||||
chan->next_circ_id = 2;
|
||||
}
|
||||
if (++attempts > 1<<15) {
|
||||
if (++attempts > max_range) {
|
||||
/* Make sure we don't loop forever if all circ_id's are used. This
|
||||
* matters because it's an external DoS opportunity.
|
||||
*/
|
||||
|
@ -71,7 +71,7 @@ chan_circid_entries_eq_(chan_circid_circuit_map_t *a,
|
||||
static INLINE unsigned int
|
||||
chan_circid_entry_hash_(chan_circid_circuit_map_t *a)
|
||||
{
|
||||
return (((unsigned)a->circ_id)<<8) ^ (unsigned)(uintptr_t)(a->chan);
|
||||
return ((unsigned)a->circ_id) ^ (unsigned)(uintptr_t)(a->chan);
|
||||
}
|
||||
|
||||
/** Map from [chan,circid] to circuit. */
|
||||
|
@ -231,7 +231,10 @@ command_process_create_cell(cell_t *cell, channel_t *chan)
|
||||
|
||||
/* If the high bit of the circuit ID is not as expected, close the
|
||||
* circ. */
|
||||
id_is_high = cell->circ_id & (1<<15);
|
||||
if (chan->wide_circ_ids)
|
||||
id_is_high = cell->circ_id & (1u<<31);
|
||||
else
|
||||
id_is_high = cell->circ_id & (1u<<15);
|
||||
if ((id_is_high &&
|
||||
chan->circ_id_type == CIRC_ID_TYPE_HIGHER) ||
|
||||
(!id_is_high &&
|
||||
|
@ -2223,8 +2223,7 @@ connection_bucket_round_robin(int base, int priority,
|
||||
static ssize_t
|
||||
connection_bucket_read_limit(connection_t *conn, time_t now)
|
||||
{
|
||||
int base = connection_speaks_cells(conn) ?
|
||||
CELL_NETWORK_SIZE : RELAY_PAYLOAD_SIZE;
|
||||
int base = RELAY_PAYLOAD_SIZE;
|
||||
int priority = conn->type != CONN_TYPE_DIR;
|
||||
int conn_bucket = -1;
|
||||
int global_bucket = global_read_bucket;
|
||||
@ -2233,6 +2232,7 @@ connection_bucket_read_limit(connection_t *conn, time_t now)
|
||||
or_connection_t *or_conn = TO_OR_CONN(conn);
|
||||
if (conn->state == OR_CONN_STATE_OPEN)
|
||||
conn_bucket = or_conn->read_bucket;
|
||||
base = get_cell_network_size(or_conn->wide_circ_ids);
|
||||
}
|
||||
|
||||
if (!connection_is_rate_limited(conn)) {
|
||||
@ -2252,8 +2252,7 @@ connection_bucket_read_limit(connection_t *conn, time_t now)
|
||||
ssize_t
|
||||
connection_bucket_write_limit(connection_t *conn, time_t now)
|
||||
{
|
||||
int base = connection_speaks_cells(conn) ?
|
||||
CELL_NETWORK_SIZE : RELAY_PAYLOAD_SIZE;
|
||||
int base = RELAY_PAYLOAD_SIZE;
|
||||
int priority = conn->type != CONN_TYPE_DIR;
|
||||
int conn_bucket = (int)conn->outbuf_flushlen;
|
||||
int global_bucket = global_write_bucket;
|
||||
@ -2271,6 +2270,7 @@ connection_bucket_write_limit(connection_t *conn, time_t now)
|
||||
if (or_conn->write_bucket < conn_bucket)
|
||||
conn_bucket = or_conn->write_bucket >= 0 ?
|
||||
or_conn->write_bucket : 0;
|
||||
base = get_cell_network_size(or_conn->wide_circ_ids);
|
||||
}
|
||||
|
||||
if (connection_counts_as_relayed_traffic(conn, now) &&
|
||||
|
@ -352,33 +352,56 @@ connection_or_get_num_circuits(or_connection_t *conn)
|
||||
* should set it or clear it as appropriate.
|
||||
*/
|
||||
void
|
||||
cell_pack(packed_cell_t *dst, const cell_t *src)
|
||||
cell_pack(packed_cell_t *dst, const cell_t *src, int wide_circ_ids)
|
||||
{
|
||||
char *dest = dst->body;
|
||||
set_uint16(dest, htons(src->circ_id));
|
||||
set_uint8(dest+2, src->command);
|
||||
memcpy(dest+3, src->payload, CELL_PAYLOAD_SIZE);
|
||||
if (wide_circ_ids) {
|
||||
set_uint32(dest, htonl(src->circ_id));
|
||||
dest += 4;
|
||||
} else {
|
||||
set_uint16(dest, htons(src->circ_id));
|
||||
dest += 2;
|
||||
memset(dest+CELL_MAX_NETWORK_SIZE-2, 0, 2); /*make sure it's clear */
|
||||
}
|
||||
set_uint8(dest, src->command);
|
||||
memcpy(dest+1, src->payload, CELL_PAYLOAD_SIZE);
|
||||
}
|
||||
|
||||
/** Unpack the network-order buffer <b>src</b> into a host-order
|
||||
* cell_t structure <b>dest</b>.
|
||||
*/
|
||||
static void
|
||||
cell_unpack(cell_t *dest, const char *src)
|
||||
cell_unpack(cell_t *dest, const char *src, int wide_circ_ids)
|
||||
{
|
||||
dest->circ_id = ntohs(get_uint16(src));
|
||||
dest->command = get_uint8(src+2);
|
||||
memcpy(dest->payload, src+3, CELL_PAYLOAD_SIZE);
|
||||
if (wide_circ_ids) {
|
||||
dest->circ_id = ntohl(get_uint32(src));
|
||||
src += 4;
|
||||
} else {
|
||||
dest->circ_id = ntohs(get_uint16(src));
|
||||
src += 2;
|
||||
}
|
||||
dest->command = get_uint8(src);
|
||||
memcpy(dest->payload, src+1, CELL_PAYLOAD_SIZE);
|
||||
}
|
||||
|
||||
/** Write the header of <b>cell</b> into the first VAR_CELL_HEADER_SIZE
|
||||
* bytes of <b>hdr_out</b>. */
|
||||
void
|
||||
var_cell_pack_header(const var_cell_t *cell, char *hdr_out)
|
||||
/** Write the header of <b>cell</b> into the first VAR_CELL_MAX_HEADER_SIZE
|
||||
* bytes of <b>hdr_out</b>. Returns number of bytes used. */
|
||||
int
|
||||
var_cell_pack_header(const var_cell_t *cell, char *hdr_out, int wide_circ_ids)
|
||||
{
|
||||
set_uint16(hdr_out, htons(cell->circ_id));
|
||||
set_uint8(hdr_out+2, cell->command);
|
||||
set_uint16(hdr_out+3, htons(cell->payload_len));
|
||||
int r;
|
||||
if (wide_circ_ids) {
|
||||
set_uint32(hdr_out, htonl(cell->circ_id));
|
||||
hdr_out += 4;
|
||||
r = VAR_CELL_MAX_HEADER_SIZE;
|
||||
} else {
|
||||
set_uint16(hdr_out, htons(cell->circ_id));
|
||||
hdr_out += 2;
|
||||
r = VAR_CELL_MAX_HEADER_SIZE - 2;
|
||||
}
|
||||
set_uint8(hdr_out, cell->command);
|
||||
set_uint16(hdr_out+1, htons(cell->payload_len));
|
||||
return r;
|
||||
}
|
||||
|
||||
/** Allocate and return a new var_cell_t with <b>payload_len</b> bytes of
|
||||
@ -498,6 +521,7 @@ connection_or_flushed_some(or_connection_t *conn)
|
||||
{
|
||||
size_t datalen, temp;
|
||||
ssize_t n, flushed;
|
||||
size_t cell_network_size = get_cell_network_size(conn->wide_circ_ids);
|
||||
|
||||
/* If we're under the low water mark, add cells until we're just over the
|
||||
* high water mark. */
|
||||
@ -505,7 +529,7 @@ connection_or_flushed_some(or_connection_t *conn)
|
||||
if (datalen < OR_CONN_LOWWATER) {
|
||||
while ((conn->chan) && channel_tls_more_to_flush(conn->chan)) {
|
||||
/* Compute how many more cells we want at most */
|
||||
n = CEIL_DIV(OR_CONN_HIGHWATER - datalen, CELL_NETWORK_SIZE);
|
||||
n = CEIL_DIV(OR_CONN_HIGHWATER - datalen, cell_network_size);
|
||||
/* Bail out if we don't want any more */
|
||||
if (n <= 0) break;
|
||||
/* We're still here; try to flush some more cells */
|
||||
@ -1533,7 +1557,8 @@ connection_or_check_valid_tls_handshake(or_connection_t *conn,
|
||||
}
|
||||
|
||||
tor_assert(conn->chan);
|
||||
channel_set_circid_type(TLS_CHAN_TO_BASE(conn->chan), identity_rcvd);
|
||||
channel_set_circid_type(TLS_CHAN_TO_BASE(conn->chan), identity_rcvd, 1);
|
||||
|
||||
crypto_pk_free(identity_rcvd);
|
||||
|
||||
if (started_here)
|
||||
@ -1739,10 +1764,12 @@ or_handshake_state_free(or_handshake_state_t *state)
|
||||
* authenticate cell.)
|
||||
*/
|
||||
void
|
||||
or_handshake_state_record_cell(or_handshake_state_t *state,
|
||||
or_handshake_state_record_cell(or_connection_t *conn,
|
||||
or_handshake_state_t *state,
|
||||
const cell_t *cell,
|
||||
int incoming)
|
||||
{
|
||||
size_t cell_network_size = get_cell_network_size(conn->wide_circ_ids);
|
||||
crypto_digest_t *d, **dptr;
|
||||
packed_cell_t packed;
|
||||
if (incoming) {
|
||||
@ -1764,8 +1791,8 @@ or_handshake_state_record_cell(or_handshake_state_t *state,
|
||||
d = *dptr;
|
||||
/* Re-packing like this is a little inefficient, but we don't have to do
|
||||
this very often at all. */
|
||||
cell_pack(&packed, cell);
|
||||
crypto_digest_add_bytes(d, packed.body, sizeof(packed.body));
|
||||
cell_pack(&packed, cell, conn->wide_circ_ids);
|
||||
crypto_digest_add_bytes(d, packed.body, cell_network_size);
|
||||
memwipe(&packed, 0, sizeof(packed));
|
||||
}
|
||||
|
||||
@ -1778,12 +1805,14 @@ or_handshake_state_record_cell(or_handshake_state_t *state,
|
||||
* authenticate cell.)
|
||||
*/
|
||||
void
|
||||
or_handshake_state_record_var_cell(or_handshake_state_t *state,
|
||||
or_handshake_state_record_var_cell(or_connection_t *conn,
|
||||
or_handshake_state_t *state,
|
||||
const var_cell_t *cell,
|
||||
int incoming)
|
||||
{
|
||||
crypto_digest_t *d, **dptr;
|
||||
char buf[VAR_CELL_HEADER_SIZE];
|
||||
int n;
|
||||
char buf[VAR_CELL_MAX_HEADER_SIZE];
|
||||
if (incoming) {
|
||||
if (!state->digest_received_data)
|
||||
return;
|
||||
@ -1797,8 +1826,8 @@ or_handshake_state_record_var_cell(or_handshake_state_t *state,
|
||||
|
||||
d = *dptr;
|
||||
|
||||
var_cell_pack_header(cell, buf);
|
||||
crypto_digest_add_bytes(d, buf, sizeof(buf));
|
||||
n = var_cell_pack_header(cell, buf, conn->wide_circ_ids);
|
||||
crypto_digest_add_bytes(d, buf, n);
|
||||
crypto_digest_add_bytes(d, (const char *)cell->payload, cell->payload_len);
|
||||
|
||||
memwipe(buf, 0, sizeof(buf));
|
||||
@ -1832,20 +1861,21 @@ void
|
||||
connection_or_write_cell_to_buf(const cell_t *cell, or_connection_t *conn)
|
||||
{
|
||||
packed_cell_t networkcell;
|
||||
size_t cell_network_size = get_cell_network_size(conn->wide_circ_ids);
|
||||
|
||||
tor_assert(cell);
|
||||
tor_assert(conn);
|
||||
|
||||
cell_pack(&networkcell, cell);
|
||||
cell_pack(&networkcell, cell, conn->wide_circ_ids);
|
||||
|
||||
connection_write_to_buf(networkcell.body, CELL_NETWORK_SIZE, TO_CONN(conn));
|
||||
connection_write_to_buf(networkcell.body, cell_network_size, TO_CONN(conn));
|
||||
|
||||
/* Touch the channel's active timestamp if there is one */
|
||||
if (conn->chan)
|
||||
channel_timestamp_active(TLS_CHAN_TO_BASE(conn->chan));
|
||||
|
||||
if (conn->base_.state == OR_CONN_STATE_OR_HANDSHAKING_V3)
|
||||
or_handshake_state_record_cell(conn->handshake_state, cell, 0);
|
||||
or_handshake_state_record_cell(conn, conn->handshake_state, cell, 0);
|
||||
|
||||
if (cell->command != CELL_PADDING)
|
||||
conn->timestamp_last_added_nonpadding = approx_time();
|
||||
@ -1859,15 +1889,16 @@ void
|
||||
connection_or_write_var_cell_to_buf(const var_cell_t *cell,
|
||||
or_connection_t *conn)
|
||||
{
|
||||
char hdr[VAR_CELL_HEADER_SIZE];
|
||||
int n;
|
||||
char hdr[VAR_CELL_MAX_HEADER_SIZE];
|
||||
tor_assert(cell);
|
||||
tor_assert(conn);
|
||||
var_cell_pack_header(cell, hdr);
|
||||
connection_write_to_buf(hdr, sizeof(hdr), TO_CONN(conn));
|
||||
n = var_cell_pack_header(cell, hdr, conn->wide_circ_ids);
|
||||
connection_write_to_buf(hdr, n, TO_CONN(conn));
|
||||
connection_write_to_buf((char*)cell->payload,
|
||||
cell->payload_len, TO_CONN(conn));
|
||||
if (conn->base_.state == OR_CONN_STATE_OR_HANDSHAKING_V3)
|
||||
or_handshake_state_record_var_cell(conn->handshake_state, cell, 0);
|
||||
or_handshake_state_record_var_cell(conn, conn->handshake_state, cell, 0);
|
||||
if (cell->command != CELL_PADDING)
|
||||
conn->timestamp_last_added_nonpadding = approx_time();
|
||||
|
||||
@ -1920,10 +1951,12 @@ connection_or_process_cells_from_inbuf(or_connection_t *conn)
|
||||
channel_tls_handle_var_cell(var_cell, conn);
|
||||
var_cell_free(var_cell);
|
||||
} else {
|
||||
char buf[CELL_NETWORK_SIZE];
|
||||
const int wide_circ_ids = conn->wide_circ_ids;
|
||||
size_t cell_network_size = get_cell_network_size(conn->wide_circ_ids);
|
||||
char buf[CELL_MAX_NETWORK_SIZE];
|
||||
cell_t cell;
|
||||
if (connection_get_inbuf_len(TO_CONN(conn))
|
||||
< CELL_NETWORK_SIZE) /* whole response available? */
|
||||
< cell_network_size) /* whole response available? */
|
||||
return 0; /* not yet */
|
||||
|
||||
/* Touch the channel's active timestamp if there is one */
|
||||
@ -1931,11 +1964,11 @@ connection_or_process_cells_from_inbuf(or_connection_t *conn)
|
||||
channel_timestamp_active(TLS_CHAN_TO_BASE(conn->chan));
|
||||
|
||||
circuit_build_times_network_is_live(&circ_times);
|
||||
connection_fetch_from_buf(buf, CELL_NETWORK_SIZE, TO_CONN(conn));
|
||||
connection_fetch_from_buf(buf, cell_network_size, TO_CONN(conn));
|
||||
|
||||
/* retrieve cell info from buf (create the host-order struct from the
|
||||
* network-order string) */
|
||||
cell_unpack(&cell, buf);
|
||||
cell_unpack(&cell, buf, wide_circ_ids);
|
||||
|
||||
channel_tls_handle_cell(&cell, conn);
|
||||
}
|
||||
@ -1943,7 +1976,7 @@ connection_or_process_cells_from_inbuf(or_connection_t *conn)
|
||||
}
|
||||
|
||||
/** Array of recognized link protocol versions. */
|
||||
static const uint16_t or_protocol_versions[] = { 1, 2, 3 };
|
||||
static const uint16_t or_protocol_versions[] = { 1, 2, 3, 4 };
|
||||
/** Number of versions in <b>or_protocol_versions</b>. */
|
||||
static const int n_or_protocol_versions =
|
||||
(int)( sizeof(or_protocol_versions)/sizeof(uint16_t) );
|
||||
|
@ -60,10 +60,12 @@ int connection_or_client_learned_peer_id(or_connection_t *conn,
|
||||
time_t connection_or_client_used(or_connection_t *conn);
|
||||
int connection_or_get_num_circuits(or_connection_t *conn);
|
||||
void or_handshake_state_free(or_handshake_state_t *state);
|
||||
void or_handshake_state_record_cell(or_handshake_state_t *state,
|
||||
void or_handshake_state_record_cell(or_connection_t *conn,
|
||||
or_handshake_state_t *state,
|
||||
const cell_t *cell,
|
||||
int incoming);
|
||||
void or_handshake_state_record_var_cell(or_handshake_state_t *state,
|
||||
void or_handshake_state_record_var_cell(or_connection_t *conn,
|
||||
or_handshake_state_t *state,
|
||||
const var_cell_t *cell,
|
||||
int incoming);
|
||||
|
||||
@ -84,10 +86,14 @@ int connection_or_send_authenticate_cell(or_connection_t *conn, int type);
|
||||
|
||||
int is_or_protocol_version_known(uint16_t version);
|
||||
|
||||
void cell_pack(packed_cell_t *dest, const cell_t *src);
|
||||
void var_cell_pack_header(const var_cell_t *cell, char *hdr_out);
|
||||
void cell_pack(packed_cell_t *dest, const cell_t *src, int wide_circ_ids);
|
||||
int var_cell_pack_header(const var_cell_t *cell, char *hdr_out,
|
||||
int wide_circ_ids);
|
||||
var_cell_t *var_cell_new(uint16_t payload_len);
|
||||
void var_cell_free(var_cell_t *cell);
|
||||
|
||||
/** DOCDOC */
|
||||
#define MIN_LINK_PROTO_FOR_WIDE_CIRC_IDS 4
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
#define MIN_CPUWORKERS 1
|
||||
|
||||
/** The tag specifies which circuit this onionskin was from. */
|
||||
#define TAG_LEN 10
|
||||
#define TAG_LEN 12
|
||||
|
||||
/** How many cpuworkers we have running right now. */
|
||||
static int num_cpuworkers=0;
|
||||
@ -72,7 +72,7 @@ tag_pack(uint8_t *tag, uint64_t chan_id, circid_t circ_id)
|
||||
/*XXXX RETHINK THIS WHOLE MESS !!!! !NM NM NM NM*/
|
||||
/*XXXX DOUBLEPLUSTHIS!!!! AS AS AS AS*/
|
||||
set_uint64(tag, chan_id);
|
||||
set_uint16(tag+8, circ_id);
|
||||
set_uint32(tag+8, circ_id);
|
||||
}
|
||||
|
||||
/** Unpack <b>tag</b> into addr, port, and circ_id.
|
||||
@ -81,7 +81,7 @@ static void
|
||||
tag_unpack(const uint8_t *tag, uint64_t *chan_id, circid_t *circ_id)
|
||||
{
|
||||
*chan_id = get_uint64(tag);
|
||||
*circ_id = get_uint16(tag+8);
|
||||
*circ_id = get_uint32(tag+8);
|
||||
}
|
||||
|
||||
/** Magic numbers to make sure our cpuworker_requests don't grow any
|
||||
|
31
src/or/or.h
31
src/or/or.h
@ -869,11 +869,29 @@ typedef enum {
|
||||
|
||||
/** Number of bytes in a cell, minus cell header. */
|
||||
#define CELL_PAYLOAD_SIZE 509
|
||||
/** Number of bytes in a cell transmitted over the network. */
|
||||
#define CELL_NETWORK_SIZE 512
|
||||
/** Number of bytes in a cell transmitted over the network, in the longest
|
||||
* form */
|
||||
#define CELL_MAX_NETWORK_SIZE 514
|
||||
|
||||
/** Length of a header on a variable-length cell. */
|
||||
#define VAR_CELL_HEADER_SIZE 5
|
||||
/** Maximum length of a header on a variable-length cell. */
|
||||
#define VAR_CELL_MAX_HEADER_SIZE 7
|
||||
|
||||
static int get_cell_network_size(int wide_circ_ids);
|
||||
static INLINE int get_cell_network_size(int wide_circ_ids)
|
||||
{
|
||||
return wide_circ_ids ? CELL_MAX_NETWORK_SIZE : CELL_MAX_NETWORK_SIZE - 2;
|
||||
}
|
||||
static int get_var_cell_header_size(int wide_circ_ids);
|
||||
static INLINE int get_var_cell_header_size(int wide_circ_ids)
|
||||
{
|
||||
return wide_circ_ids ? VAR_CELL_MAX_HEADER_SIZE :
|
||||
VAR_CELL_MAX_HEADER_SIZE - 2;
|
||||
}
|
||||
static int get_circ_id_size(int wide_circ_ids);
|
||||
static INLINE int get_circ_id_size(int wide_circ_ids)
|
||||
{
|
||||
return wide_circ_ids ? 4 : 2;
|
||||
}
|
||||
|
||||
/** Number of bytes in a relay cell's header (not including general cell
|
||||
* header). */
|
||||
@ -882,7 +900,7 @@ typedef enum {
|
||||
#define RELAY_PAYLOAD_SIZE (CELL_PAYLOAD_SIZE-RELAY_HEADER_SIZE)
|
||||
|
||||
/** Identifies a circuit on an or_connection */
|
||||
typedef uint16_t circid_t;
|
||||
typedef uint32_t circid_t;
|
||||
/** Identifies a stream on a circuit */
|
||||
typedef uint16_t streamid_t;
|
||||
|
||||
@ -1051,7 +1069,7 @@ typedef struct var_cell_t {
|
||||
/** A cell as packed for writing to the network. */
|
||||
typedef struct packed_cell_t {
|
||||
struct packed_cell_t *next; /**< Next cell queued on this circuit. */
|
||||
char body[CELL_NETWORK_SIZE]; /**< Cell as packed for network. */
|
||||
char body[CELL_MAX_NETWORK_SIZE]; /**< Cell as packed for network. */
|
||||
} packed_cell_t;
|
||||
|
||||
/** Number of cells added to a circuit queue including their insertion
|
||||
@ -1400,6 +1418,7 @@ typedef struct or_connection_t {
|
||||
/** True iff this is an outgoing connection. */
|
||||
unsigned int is_outgoing:1;
|
||||
unsigned int proxy_type:2; /**< One of PROXY_NONE...PROXY_SOCKS5 */
|
||||
unsigned int wide_circ_ids:1;
|
||||
uint8_t link_proto; /**< What protocol version are we using? 0 for
|
||||
* "none negotiated yet." */
|
||||
|
||||
|
@ -2064,10 +2064,10 @@ dump_cell_pool_usage(int severity)
|
||||
|
||||
/** Allocate a new copy of packed <b>cell</b>. */
|
||||
static INLINE packed_cell_t *
|
||||
packed_cell_copy(const cell_t *cell)
|
||||
packed_cell_copy(const cell_t *cell, int wide_circ_ids)
|
||||
{
|
||||
packed_cell_t *c = packed_cell_new();
|
||||
cell_pack(c, cell);
|
||||
cell_pack(c, cell, wide_circ_ids);
|
||||
c->next = NULL;
|
||||
return c;
|
||||
}
|
||||
@ -2089,9 +2089,10 @@ cell_queue_append(cell_queue_t *queue, packed_cell_t *cell)
|
||||
|
||||
/** Append a newly allocated copy of <b>cell</b> to the end of <b>queue</b> */
|
||||
void
|
||||
cell_queue_append_packed_copy(cell_queue_t *queue, const cell_t *cell)
|
||||
cell_queue_append_packed_copy(cell_queue_t *queue, const cell_t *cell,
|
||||
int wide_circ_ids)
|
||||
{
|
||||
packed_cell_t *copy = packed_cell_copy(cell);
|
||||
packed_cell_t *copy = packed_cell_copy(cell, wide_circ_ids);
|
||||
/* Remember the time when this cell was put in the queue. */
|
||||
if (get_options()->CellStatistics) {
|
||||
struct timeval now;
|
||||
@ -2423,7 +2424,7 @@ append_cell_to_circuit_queue(circuit_t *circ, channel_t *chan,
|
||||
streams_blocked = circ->streams_blocked_on_p_chan;
|
||||
}
|
||||
|
||||
cell_queue_append_packed_copy(queue, cell);
|
||||
cell_queue_append_packed_copy(queue, cell, chan->wide_circ_ids);
|
||||
|
||||
/* If we have too many cells on the circuit, we should stop reading from
|
||||
* the edge streams for a while. */
|
||||
|
@ -46,7 +46,8 @@ void packed_cell_free(packed_cell_t *cell);
|
||||
|
||||
void cell_queue_clear(cell_queue_t *queue);
|
||||
void cell_queue_append(cell_queue_t *queue, packed_cell_t *cell);
|
||||
void cell_queue_append_packed_copy(cell_queue_t *queue, const cell_t *cell);
|
||||
void cell_queue_append_packed_copy(cell_queue_t *queue, const cell_t *cell,
|
||||
int wide_circ_ids);
|
||||
|
||||
void append_cell_to_circuit_queue(circuit_t *circ, channel_t *chan,
|
||||
cell_t *cell, cell_direction_t direction,
|
||||
|
@ -1192,7 +1192,8 @@ router_dirport_found_reachable(void)
|
||||
void
|
||||
router_perform_bandwidth_test(int num_circs, time_t now)
|
||||
{
|
||||
int num_cells = (int)(get_options()->BandwidthRate * 10 / CELL_NETWORK_SIZE);
|
||||
int num_cells = (int)(get_options()->BandwidthRate * 10 /
|
||||
CELL_MAX_NETWORK_SIZE);
|
||||
int max_cells = num_cells < CIRCWINDOW_START ?
|
||||
num_cells : CIRCWINDOW_START;
|
||||
int cells_per_circuit = max_cells / num_circs;
|
||||
|
Loading…
Reference in New Issue
Block a user