diff options
Diffstat (limited to 'src/or')
47 files changed, 667 insertions, 460 deletions
diff --git a/src/or/buffers.c b/src/or/buffers.c index 73c25579d6..b54584fb4a 100644 --- a/src/or/buffers.c +++ b/src/or/buffers.c @@ -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); + peek_from_buf(hdr, header_len, 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; diff --git a/src/or/channel.c b/src/or/channel.c index 104b018cf4..82db061af9 100644 --- a/src/or/channel.c +++ b/src/or/channel.c @@ -2607,17 +2607,17 @@ channel_send_destroy(circid_t circ_id, channel_t *chan, int reason) cell.command = CELL_DESTROY; cell.payload[0] = (uint8_t) reason; log_debug(LD_OR, - "Sending destroy (circID %d) on channel %p " + "Sending destroy (circID %u) on channel %p " "(global ID " U64_FORMAT ")", - circ_id, chan, + (unsigned)circ_id, chan, U64_PRINTF_ARG(chan->global_identifier)); channel_write_cell(chan, &cell); } else { log_warn(LD_BUG, - "Someone called channel_send_destroy() for circID %d " + "Someone called channel_send_destroy() for circID %u " "on a channel " U64_FORMAT " at %p in state %s (%d)", - circ_id, U64_PRINTF_ARG(chan->global_identifier), + (unsigned)circ_id, U64_PRINTF_ARG(chan->global_identifier), chan, channel_state_to_string(chan->state), chan->state); } @@ -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(); diff --git a/src/or/channel.h b/src/or/channel.h index ec79888063..0933ec8d39 100644 --- a/src/or/channel.h +++ b/src/or/channel.h @@ -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); diff --git a/src/or/channeltls.c b/src/or/channeltls.c index e3dfdcc25e..60693daeb2 100644 --- a/src/or/channeltls.c +++ b/src/or/channeltls.c @@ -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; } @@ -1205,7 +1208,7 @@ channel_tls_process_versions_cell(var_cell_t *cell, channel_tls_t *chan) tor_assert(chan->conn->handshake_state); end = cell->payload + cell->payload_len; - for (cp = cell->payload; cp+1 < end; ++cp) { + for (cp = cell->payload; cp+1 < end; cp += 2) { uint16_t v = ntohs(get_uint16(cp)); if (is_or_protocol_version_known(v) && v > highest_supported_version) highest_supported_version = v; @@ -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, diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index c2f395338d..bb5b253c83 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -25,6 +25,7 @@ #include "directory.h" #include "entrynodes.h" #include "main.h" +#include "microdesc.h" #include "networkstatus.h" #include "nodelist.h" #include "onion.h" @@ -99,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); @@ -109,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. */ @@ -522,7 +523,7 @@ circuit_deliver_create_cell(circuit_t *circ, const create_cell_t *create_cell, log_warn(LD_CIRC,"failed to get unique circID."); return -1; } - log_debug(LD_CIRC,"Chosen circID %u.", id); + log_debug(LD_CIRC,"Chosen circID %u.", (unsigned)id); circuit_set_n_circid_chan(circ, id, circ->n_chan); memset(&cell, 0, sizeof(cell_t)); @@ -1268,7 +1269,7 @@ pathbias_get_scale_use_threshold(const or_options_t *options) /** * Convert a Guard's path state to string. */ -static const char * +const char * pathbias_state_to_string(path_state_t state) { switch (state) { diff --git a/src/or/circuitbuild.h b/src/or/circuitbuild.h index 3ca8d1531d..a3091707e8 100644 --- a/src/or/circuitbuild.h +++ b/src/or/circuitbuild.h @@ -66,6 +66,7 @@ int pathbias_check_probe_response(circuit_t *circ, const cell_t *cell); void pathbias_count_use_attempt(origin_circuit_t *circ); void pathbias_mark_use_success(origin_circuit_t *circ); void pathbias_mark_use_rollback(origin_circuit_t *circ); +const char *pathbias_state_to_string(path_state_t state); #endif diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c index 6987dc42fd..d4c07fc82b 100644 --- a/src/or/circuitlist.c +++ b/src/or/circuitlist.c @@ -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. */ @@ -531,6 +531,9 @@ circuit_purpose_to_string(uint8_t purpose) case CIRCUIT_PURPOSE_CONTROLLER: return "Circuit made by controller"; + case CIRCUIT_PURPOSE_PATH_BIAS_TESTING: + return "Path-bias testing circuit"; + default: tor_snprintf(buf, sizeof(buf), "UNKNOWN_%d", (int)purpose); return buf; @@ -780,13 +783,13 @@ circuit_dump_conn_details(int severity, circuit_t *circ, int conn_array_index, const char *type, - int this_circid, - int other_circid) + circid_t this_circid, + circid_t other_circid) { - tor_log(severity, LD_CIRC, "Conn %d has %s circuit: circID %d " - "(other side %d), state %d (%s), born %ld:", - conn_array_index, type, this_circid, other_circid, circ->state, - circuit_state_to_string(circ->state), + tor_log(severity, LD_CIRC, "Conn %d has %s circuit: circID %u " + "(other side %u), state %d (%s), born %ld:", + conn_array_index, type, (unsigned)this_circid, (unsigned)other_circid, + circ->state, circuit_state_to_string(circ->state), (long)circ->timestamp_began.tv_sec); if (CIRCUIT_IS_ORIGIN(circ)) { /* circ starts at this node */ circuit_log_path(severity, LD_CIRC, TO_ORIGIN_CIRCUIT(circ)); @@ -843,12 +846,12 @@ circuit_dump_chan_details(int severity, circuit_t *circ, channel_t *chan, const char *type, - int this_circid, - int other_circid) + circid_t this_circid, + circid_t other_circid) { - tor_log(severity, LD_CIRC, "Conn %p has %s circuit: circID %d " - "(other side %d), state %d (%s), born %ld:", - chan, type, this_circid, other_circid, circ->state, + tor_log(severity, LD_CIRC, "Conn %p has %s circuit: circID %u " + "(other side %u), state %d (%s), born %ld:", + chan, type, (unsigned)this_circid, (unsigned)other_circid, circ->state, circuit_state_to_string(circ->state), (long)circ->timestamp_began.tv_sec); if (CIRCUIT_IS_ORIGIN(circ)) { /* circ starts at this node */ @@ -943,16 +946,16 @@ circuit_get_by_circid_channel_impl(circid_t circ_id, channel_t *chan) if (found && found->circuit) { log_debug(LD_CIRC, "circuit_get_by_circid_channel_impl() returning circuit %p for" - " circ_id %d, channel ID " U64_FORMAT " (%p)", - found->circuit, circ_id, + " circ_id %u, channel ID " U64_FORMAT " (%p)", + found->circuit, (unsigned)circ_id, U64_PRINTF_ARG(chan->global_identifier), chan); return found->circuit; } log_debug(LD_CIRC, "circuit_get_by_circid_channel_impl() found nothing for" - " circ_id %d, channel ID " U64_FORMAT " (%p)", - circ_id, + " circ_id %u, channel ID " U64_FORMAT " (%p)", + (unsigned)circ_id, U64_PRINTF_ARG(chan->global_identifier), chan); return NULL; diff --git a/src/or/circuitmux.c b/src/or/circuitmux.c index dcc1901819..545cfd0650 100644 --- a/src/or/circuitmux.c +++ b/src/or/circuitmux.c @@ -425,9 +425,9 @@ circuitmux_detach_all_circuits(circuitmux_t *cmux) } else { /* Complain and move on */ log_warn(LD_CIRC, - "Circuit %d/channel " U64_FORMAT " had direction == " + "Circuit %u/channel " U64_FORMAT " had direction == " "CELL_DIRECTION_IN, but isn't an or_circuit_t", - to_remove->circ_id, + (unsigned)to_remove->circ_id, U64_PRINTF_ARG(to_remove->chan_id)); } @@ -449,16 +449,16 @@ circuitmux_detach_all_circuits(circuitmux_t *cmux) } else { /* Complain and move on */ log_warn(LD_CIRC, - "Couldn't find circuit %d (for channel " U64_FORMAT ")", - to_remove->circ_id, + "Couldn't find circuit %u (for channel " U64_FORMAT ")", + (unsigned)to_remove->circ_id, U64_PRINTF_ARG(to_remove->chan_id)); } } else { /* Complain and move on */ log_warn(LD_CIRC, - "Couldn't find channel " U64_FORMAT " (for circuit id %d)", + "Couldn't find channel " U64_FORMAT " (for circuit id %u)", U64_PRINTF_ARG(to_remove->chan_id), - to_remove->circ_id); + (unsigned)to_remove->circ_id); } /* Assert that we don't have un-freed policy data for this circuit */ @@ -905,7 +905,7 @@ circuitmux_attach_circuit(circuitmux_t *cmux, circuit_t *circ, log_info(LD_CIRC, "Circuit %u on channel " U64_FORMAT " was already attached to " "cmux %p (trying to attach to %p)", - circ_id, U64_PRINTF_ARG(channel_id), + (unsigned)circ_id, U64_PRINTF_ARG(channel_id), ((direction == CELL_DIRECTION_OUT) ? circ->n_mux : TO_OR_CIRCUIT(circ)->p_mux), cmux); @@ -938,7 +938,7 @@ circuitmux_attach_circuit(circuitmux_t *cmux, circuit_t *circ, */ log_debug(LD_CIRC, "Attaching circuit %u on channel " U64_FORMAT " to cmux %p", - circ_id, U64_PRINTF_ARG(channel_id), cmux); + (unsigned)circ_id, U64_PRINTF_ARG(channel_id), cmux); /* * Assert that the circuit doesn't already have a mux for this @@ -1138,8 +1138,8 @@ circuitmux_make_circuit_active(circuitmux_t *cmux, circuit_t *circ, /* If we're already active, log a warning and finish */ if (already_active) { log_warn(LD_CIRC, - "Circuit %d on channel " U64_FORMAT " was already active", - circ_id, U64_PRINTF_ARG(chan->global_identifier)); + "Circuit %u on channel " U64_FORMAT " was already active", + (unsigned)circ_id, U64_PRINTF_ARG(chan->global_identifier)); return; } @@ -1236,7 +1236,7 @@ circuitmux_make_circuit_inactive(circuitmux_t *cmux, circuit_t *circ, if (already_inactive) { log_warn(LD_CIRC, "Circuit %d on channel " U64_FORMAT " was already inactive", - circ_id, U64_PRINTF_ARG(chan->global_identifier)); + (unsigned)circ_id, U64_PRINTF_ARG(chan->global_identifier)); return; } diff --git a/src/or/circuituse.c b/src/or/circuituse.c index c0612039be..51d8716faa 100644 --- a/src/or/circuituse.c +++ b/src/or/circuituse.c @@ -695,9 +695,9 @@ circuit_expire_building(void) case CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT: case CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED: /* If we have reached this line, we want to spare the circ for now. */ - log_info(LD_CIRC,"Marking circ %d (state %d:%s, purpose %d) " + log_info(LD_CIRC,"Marking circ %u (state %d:%s, purpose %d) " "as timed-out HS circ", - victim->n_circ_id, + (unsigned)victim->n_circ_id, victim->state, circuit_state_to_string(victim->state), victim->purpose); TO_ORIGIN_CIRCUIT(victim)->hs_circ_has_timed_out = 1; @@ -713,9 +713,9 @@ circuit_expire_building(void) if (!(options->CloseHSServiceRendCircuitsImmediatelyOnTimeout) && !(TO_ORIGIN_CIRCUIT(victim)->hs_circ_has_timed_out) && victim->purpose == CIRCUIT_PURPOSE_S_CONNECT_REND) { - log_info(LD_CIRC,"Marking circ %d (state %d:%s, purpose %d) " + log_info(LD_CIRC,"Marking circ %u (state %d:%s, purpose %d) " "as timed-out HS circ; relaunching rendezvous attempt.", - victim->n_circ_id, + (unsigned)victim->n_circ_id, victim->state, circuit_state_to_string(victim->state), victim->purpose); TO_ORIGIN_CIRCUIT(victim)->hs_circ_has_timed_out = 1; @@ -728,7 +728,7 @@ circuit_expire_building(void) "Abandoning circ %u %s:%d (state %d,%d:%s, purpose %d, " "len %d)", TO_ORIGIN_CIRCUIT(victim)->global_identifier, channel_get_canonical_remote_descr(victim->n_chan), - victim->n_circ_id, + (unsigned)victim->n_circ_id, TO_ORIGIN_CIRCUIT(victim)->has_opened, victim->state, circuit_state_to_string(victim->state), victim->purpose, @@ -737,7 +737,8 @@ circuit_expire_building(void) log_info(LD_CIRC, "Abandoning circ %u %d (state %d,%d:%s, purpose %d, len %d)", TO_ORIGIN_CIRCUIT(victim)->global_identifier, - victim->n_circ_id, TO_ORIGIN_CIRCUIT(victim)->has_opened, + (unsigned)victim->n_circ_id, + TO_ORIGIN_CIRCUIT(victim)->has_opened, victim->state, circuit_state_to_string(victim->state), victim->purpose, TO_ORIGIN_CIRCUIT(victim)->build_state->desired_path_len); @@ -1070,9 +1071,10 @@ circuit_expire_old_circuits_clientside(void) circ->timestamp_dirty + get_options()->MaxCircuitDirtiness < now.tv_sec && !TO_ORIGIN_CIRCUIT(circ)->p_streams /* nothing attached */ ) { - log_debug(LD_CIRC, "Closing n_circ_id %d (dirty %ld sec ago, " + log_debug(LD_CIRC, "Closing n_circ_id %u (dirty %ld sec ago, " "purpose %d)", - circ->n_circ_id, (long)(now.tv_sec - circ->timestamp_dirty), + (unsigned)circ->n_circ_id, + (long)(now.tv_sec - circ->timestamp_dirty), circ->purpose); /* Don't do this magic for testing circuits. Their death is governed * by circuit_expire_building */ @@ -1153,8 +1155,8 @@ circuit_expire_old_circuits_serverside(time_t now) !or_circ->n_streams && !or_circ->resolving_streams && or_circ->p_chan && channel_when_last_xmit(or_circ->p_chan) <= cutoff) { - log_info(LD_CIRC, "Closing circ_id %d (empty %d secs ago)", - or_circ->p_circ_id, + log_info(LD_CIRC, "Closing circ_id %u (empty %d secs ago)", + (unsigned)or_circ->p_circ_id, (int)(now - channel_when_last_xmit(or_circ->p_chan))); circuit_mark_for_close(circ, END_CIRC_REASON_FINISHED); } @@ -1896,8 +1898,8 @@ link_apconn_to_circ(entry_connection_t *apconn, origin_circuit_t *circ, const node_t *exitnode; /* add it into the linked list of streams on this circuit */ - log_debug(LD_APP|LD_CIRC, "attaching new conn to circ. n_circ_id %d.", - circ->base_.n_circ_id); + log_debug(LD_APP|LD_CIRC, "attaching new conn to circ. n_circ_id %u.", + (unsigned)circ->base_.n_circ_id); /* reset it, so we can measure circ timeouts */ ENTRY_TO_CONN(apconn)->timestamp_lastread = time(NULL); ENTRY_TO_EDGE_CONN(apconn)->next_stream = circ->p_streams; @@ -2121,8 +2123,8 @@ connection_ap_handshake_attach_circuit(entry_connection_t *conn) return retval; log_debug(LD_APP|LD_CIRC, - "Attaching apconn to circ %d (stream %d sec old).", - circ->base_.n_circ_id, conn_age); + "Attaching apconn to circ %u (stream %d sec old).", + (unsigned)circ->base_.n_circ_id, conn_age); /* print the circ's path, so people can figure out which circs are * sucking. */ circuit_log_path(LOG_INFO,LD_APP|LD_CIRC,circ); @@ -2147,7 +2149,7 @@ connection_ap_handshake_attach_circuit(entry_connection_t *conn) log_info(LD_REND, "rend joined circ %d already here. attaching. " "(stream %d sec old)", - rendcirc->base_.n_circ_id, conn_age); + (unsigned)rendcirc->base_.n_circ_id, conn_age); /* Mark rendezvous circuits as 'newly dirty' every time you use * them, since the process of rebuilding a rendezvous circ is so * expensive. There is a tradeoff between linkability and @@ -2168,9 +2170,9 @@ connection_ap_handshake_attach_circuit(entry_connection_t *conn) if (rendcirc && (rendcirc->base_.purpose == CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED)) { log_info(LD_REND, - "pending-join circ %d already here, with intro ack. " + "pending-join circ %u already here, with intro ack. " "Stalling. (stream %d sec old)", - rendcirc->base_.n_circ_id, conn_age); + (unsigned)rendcirc->base_.n_circ_id, conn_age); return 0; } @@ -2182,10 +2184,10 @@ connection_ap_handshake_attach_circuit(entry_connection_t *conn) if (retval > 0) { /* one has already sent the intro. keep waiting. */ tor_assert(introcirc); - log_info(LD_REND, "Intro circ %d present and awaiting ack (rend %d). " + log_info(LD_REND, "Intro circ %u present and awaiting ack (rend %u). " "Stalling. (stream %d sec old)", - introcirc->base_.n_circ_id, - rendcirc ? rendcirc->base_.n_circ_id : 0, + (unsigned)introcirc->base_.n_circ_id, + rendcirc ? (unsigned)rendcirc->base_.n_circ_id : 0, conn_age); return 0; } @@ -2195,16 +2197,17 @@ connection_ap_handshake_attach_circuit(entry_connection_t *conn) if (rendcirc && introcirc && rendcirc->base_.purpose == CIRCUIT_PURPOSE_C_REND_READY) { log_info(LD_REND, - "ready rend circ %d already here (no intro-ack yet on " - "intro %d). (stream %d sec old)", - rendcirc->base_.n_circ_id, - introcirc->base_.n_circ_id, conn_age); + "ready rend circ %u already here (no intro-ack yet on " + "intro %u). (stream %d sec old)", + (unsigned)rendcirc->base_.n_circ_id, + (unsigned)introcirc->base_.n_circ_id, conn_age); tor_assert(introcirc->base_.purpose == CIRCUIT_PURPOSE_C_INTRODUCING); if (introcirc->base_.state == CIRCUIT_STATE_OPEN) { - log_info(LD_REND,"found open intro circ %d (rend %d); sending " + log_info(LD_REND,"found open intro circ %u (rend %u); sending " "introduction. (stream %d sec old)", - introcirc->base_.n_circ_id, rendcirc->base_.n_circ_id, + (unsigned)introcirc->base_.n_circ_id, + (unsigned)rendcirc->base_.n_circ_id, conn_age); switch (rend_client_send_introduction(introcirc, rendcirc)) { case 0: /* success */ @@ -2228,10 +2231,10 @@ connection_ap_handshake_attach_circuit(entry_connection_t *conn) } } - log_info(LD_REND, "Intro (%d) and rend (%d) circs are not both ready. " + log_info(LD_REND, "Intro (%u) and rend (%u) circs are not both ready. " "Stalling conn. (%d sec old)", - introcirc ? introcirc->base_.n_circ_id : 0, - rendcirc ? rendcirc->base_.n_circ_id : 0, conn_age); + introcirc ? (unsigned)introcirc->base_.n_circ_id : 0, + rendcirc ? (unsigned)rendcirc->base_.n_circ_id : 0, conn_age); return 0; } } diff --git a/src/or/command.c b/src/or/command.c index 09313b48a2..876ff526a6 100644 --- a/src/or/command.c +++ b/src/or/command.c @@ -16,7 +16,6 @@ * callbacks registered in command_setup_channel(), * called when channels are created in circuitbuild.c */ - #include "or.h" #include "channel.h" #include "circuitbuild.h" @@ -195,9 +194,9 @@ command_process_create_cell(cell_t *cell, channel_t *chan) tor_assert(chan); log_debug(LD_OR, - "Got a CREATE cell for circ_id %d on channel " U64_FORMAT + "Got a CREATE cell for circ_id %u on channel " U64_FORMAT " (%p)", - cell->circ_id, + (unsigned)cell->circ_id, U64_PRINTF_ARG(chan->global_identifier), chan); if (we_are_hibernating()) { @@ -231,14 +230,17 @@ 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 && chan->circ_id_type == CIRC_ID_TYPE_LOWER)) { log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, - "Received create cell with unexpected circ_id %d. Closing.", - cell->circ_id); + "Received create cell with unexpected circ_id %u. Closing.", + (unsigned)cell->circ_id); channel_send_destroy(cell->circ_id, chan, END_CIRC_REASON_TORPROTOCOL); return; @@ -247,9 +249,10 @@ command_process_create_cell(cell_t *cell, channel_t *chan) if (circuit_id_in_use_on_channel(cell->circ_id, chan)) { const node_t *node = node_get_by_id(chan->identity_digest); log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, - "Received CREATE cell (circID %d) for known circ. " + "Received CREATE cell (circID %u) for known circ. " "Dropping (age %d).", - cell->circ_id, (int)(time(NULL) - channel_when_created(chan))); + (unsigned)cell->circ_id, + (int)(time(NULL) - channel_when_created(chan))); if (node) { char *p = esc_for_log(node_get_platform(node)); log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, @@ -338,8 +341,8 @@ command_process_created_cell(cell_t *cell, channel_t *chan) if (!circ) { log_info(LD_OR, - "(circID %d) unknown circ (probably got a destroy earlier). " - "Dropping.", cell->circ_id); + "(circID %u) unknown circ (probably got a destroy earlier). " + "Dropping.", (unsigned)cell->circ_id); return; } @@ -409,8 +412,9 @@ command_process_relay_cell(cell_t *cell, channel_t *chan) if (!circ) { log_debug(LD_OR, - "unknown circuit %d on connection from %s. Dropping.", - cell->circ_id, channel_get_canonical_remote_descr(chan)); + "unknown circuit %u on connection from %s. Dropping.", + (unsigned)cell->circ_id, + channel_get_canonical_remote_descr(chan)); return; } @@ -444,9 +448,9 @@ command_process_relay_cell(cell_t *cell, channel_t *chan) 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." + "Received too many RELAY_EARLY cells on circ %u from %s." " Closing circuit.", - cell->circ_id, + (unsigned)cell->circ_id, safe_str(channel_get_canonical_remote_descr(chan))); circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL); return; @@ -484,11 +488,12 @@ command_process_destroy_cell(cell_t *cell, channel_t *chan) circ = circuit_get_by_circid_channel(cell->circ_id, chan); if (!circ) { - log_info(LD_OR,"unknown circuit %d on connection from %s. Dropping.", - cell->circ_id, channel_get_canonical_remote_descr(chan)); + log_info(LD_OR,"unknown circuit %u on connection from %s. Dropping.", + (unsigned)cell->circ_id, + channel_get_canonical_remote_descr(chan)); return; } - log_debug(LD_OR,"Received for circID %d.",cell->circ_id); + log_debug(LD_OR,"Received for circID %u.",(unsigned)cell->circ_id); reason = (uint8_t)cell->payload[0]; diff --git a/src/or/config.c b/src/or/config.c index 7ca20e46b4..2b94b8316f 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2001 Matej Pfajfar. + /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. * Copyright (c) 2007-2013, The Tor Project, Inc. */ @@ -213,6 +213,7 @@ static config_var_t option_vars_[] = { V(DisableAllSwap, BOOL, "0"), V(DisableDebuggerAttachment, BOOL, "1"), V(DisableIOCP, BOOL, "1"), + V(DisableV2DirectoryInfo_, BOOL, "0"), V(DynamicDHGroups, BOOL, "0"), VPORT(DNSPort, LINELIST, NULL), V(DNSListenAddress, LINELIST, NULL), @@ -379,6 +380,7 @@ static config_var_t option_vars_[] = { V(SocksPolicy, LINELIST, NULL), VPORT(SocksPort, LINELIST, NULL), V(SocksTimeout, INTERVAL, "2 minutes"), + V(SSLKeyLifetime, INTERVAL, "0"), OBSOLETE("StatusFetchPeriod"), V(StrictNodes, BOOL, "0"), OBSOLETE("SysLog"), @@ -1893,6 +1895,14 @@ list_torrc_options(void) /** Last value actually set by resolve_my_address. */ static uint32_t last_resolved_addr = 0; + +/** Accessor for last_resolved_addr from outside this file. */ +uint32_t +get_last_resolved_addr(void) +{ + return last_resolved_addr; +} + /** * Use <b>options-\>Address</b> to guess our public IP address. * @@ -2371,6 +2381,10 @@ options_validate(or_options_t *old_options, or_options_t *options, REJECT("TokenBucketRefillInterval must be between 1 and 1000 inclusive."); } + if (options->DisableV2DirectoryInfo_ && ! authdir_mode(options)) { + REJECT("DisableV2DirectoryInfo_ set, but we aren't an authority."); + } + if (options->ExcludeExitNodes || options->ExcludeNodes) { options->ExcludeExitNodesUnion_ = routerset_new(); routerset_union(options->ExcludeExitNodesUnion_,options->ExcludeExitNodes); @@ -2587,9 +2601,9 @@ options_validate(or_options_t *old_options, or_options_t *options, if (options->UseBridges && options->EntryNodes) REJECT("You cannot set both UseBridges and EntryNodes."); - if (options->EntryNodes && !options->UseEntryGuards) - log_warn(LD_CONFIG, "EntryNodes is set, but UseEntryGuards is disabled. " - "EntryNodes will be ignored."); + if (options->EntryNodes && !options->UseEntryGuards) { + REJECT("If EntryNodes is set, UseEntryGuards must be enabled."); + } options->AllowInvalid_ = 0; if (options->AllowInvalidNodes) { diff --git a/src/or/config.h b/src/or/config.h index e0748a07bf..ef4acac514 100644 --- a/src/or/config.h +++ b/src/or/config.h @@ -26,6 +26,7 @@ const char *get_short_version(void); setopt_err_t options_trial_assign(config_line_t *list, int use_defaults, int clear_first, char **msg); +uint32_t get_last_resolved_addr(void); int resolve_my_address(int warn_severity, const or_options_t *options, uint32_t *addr_out, const char **method_out, char **hostname_out); diff --git a/src/or/connection.c b/src/or/connection.c index 737da72923..622eadcff9 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -918,8 +918,11 @@ make_socket_reuseable(tor_socket_t sock) * right after somebody else has let it go. But REUSEADDR on win32 * means you can bind to the port _even when somebody else * already has it bound_. So, don't do that on Win32. */ - setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*) &one, - (socklen_t)sizeof(one)); + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*) &one, + (socklen_t)sizeof(one)) == -1) { + log_warn(LD_NET, "Error setting SO_REUSEADDR flag: %s", + tor_socket_strerror(errno)); + } #endif } @@ -1102,7 +1105,10 @@ connection_listener_new(const struct sockaddr *listensockaddr, tor_assert(0); } - set_socket_nonblocking(s); + if (set_socket_nonblocking(s) == -1) { + tor_close_socket(s); + goto err; + } lis_conn = listener_connection_new(type, listensockaddr->sa_family); conn = TO_CONN(lis_conn); @@ -1265,7 +1271,10 @@ connection_handle_listener_read(connection_t *conn, int new_type) (int)news,(int)conn->s); make_socket_reuseable(news); - set_socket_nonblocking(news); + if (set_socket_nonblocking(news) == -1) { + tor_close_socket(news); + return 0; + } if (options->ConstrainedSockets) set_constrained_socket_buffers(news, (int)options->ConstrainedSockSize); @@ -1494,7 +1503,11 @@ connection_connect(connection_t *conn, const char *address, } } - set_socket_nonblocking(s); + if (set_socket_nonblocking(s) == -1) { + *socket_error = tor_socket_errno(s); + tor_close_socket(s); + return -1; + } if (options->ConstrainedSockets) set_constrained_socket_buffers(s, (int)options->ConstrainedSockSize); @@ -2223,8 +2236,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 +2245,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 +2265,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 +2283,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) && diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index b4fa3e6fe2..84d556513c 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -218,8 +218,8 @@ int connection_edge_destroy(circid_t circ_id, edge_connection_t *conn) { if (!conn->base_.marked_for_close) { - log_info(LD_EDGE, - "CircID %d: At an edge. Marking connection for close.", circ_id); + log_info(LD_EDGE, "CircID %u: At an edge. Marking connection for close.", + (unsigned) circ_id); if (conn->base_.type == CONN_TYPE_AP) { entry_connection_t *entry_conn = EDGE_TO_ENTRY_CONN(conn); connection_mark_unattached_ap(entry_conn, END_STREAM_REASON_DESTROY); @@ -651,7 +651,16 @@ connection_ap_expire_beginning(void) } continue; } - tor_assert(circ->purpose == CIRCUIT_PURPOSE_C_GENERAL); + if (circ->purpose != CIRCUIT_PURPOSE_C_GENERAL) { + log_warn(LD_BUG, "circuit->purpose == CIRCUIT_PURPOSE_C_GENERAL failed. " + "The purpose on the circuit was %s; it was in state %s, " + "path_state %s.", + circuit_purpose_to_string(circ->purpose), + circuit_state_to_string(circ->state), + CIRCUIT_IS_ORIGIN(circ) ? + pathbias_state_to_string(TO_ORIGIN_CIRCUIT(circ)->path_state) : + "none"); + } log_fn(cutoff < 15 ? LOG_INFO : severity, LD_APP, "We tried for %d seconds to connect to '%s' using exit %s." " Retrying on a new circuit.", @@ -1838,8 +1847,8 @@ connection_ap_handshake_send_begin(entry_connection_t *ap_conn) edge_conn->deliver_window = STREAMWINDOW_START; base_conn->state = AP_CONN_STATE_CONNECT_WAIT; log_info(LD_APP,"Address/port sent, ap socket "TOR_SOCKET_T_FORMAT - ", n_circ_id %d", - base_conn->s, circ->base_.n_circ_id); + ", n_circ_id %u", + base_conn->s, (unsigned)circ->base_.n_circ_id); control_event_stream_status(ap_conn, STREAM_EVENT_SENT_CONNECT, 0); /* If there's queued-up data, send it now */ @@ -1940,8 +1949,8 @@ connection_ap_handshake_send_resolve(entry_connection_t *ap_conn) base_conn->address = tor_strdup("(Tor_internal)"); base_conn->state = AP_CONN_STATE_RESOLVE_WAIT; log_info(LD_APP,"Address sent for resolve, ap socket "TOR_SOCKET_T_FORMAT - ", n_circ_id %d", - base_conn->s, circ->base_.n_circ_id); + ", n_circ_id %u", + base_conn->s, (unsigned)circ->base_.n_circ_id); control_event_stream_status(ap_conn, STREAM_EVENT_NEW, 0); control_event_stream_status(ap_conn, STREAM_EVENT_SENT_RESOLVE, 0); return 0; diff --git a/src/or/connection_or.c b/src/or/connection_or.c index 5ec32d6324..3616363505 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -9,7 +9,6 @@ * \brief Functions to handle OR connections, TLS handshaking, and * cells on the network. **/ - #include "or.h" #include "buffers.h" /* @@ -352,33 +351,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 +520,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 +528,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 +1556,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 +1763,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 +1790,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 +1804,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 +1825,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 +1860,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 +1888,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 +1950,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 +1963,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 +1975,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) ); diff --git a/src/or/connection_or.h b/src/or/connection_or.h index 21178774a3..85e68f1a33 100644 --- a/src/or/connection_or.h +++ b/src/or/connection_or.h @@ -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 diff --git a/src/or/cpuworker.c b/src/or/cpuworker.c index 444f17cd41..61f9faa394 100644 --- a/src/or/cpuworker.c +++ b/src/or/cpuworker.c @@ -11,7 +11,6 @@ * * Right now, we only use this for processing onionskins. **/ - #include "or.h" #include "buffers.h" #include "channel.h" @@ -31,7 +30,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 +71,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 +80,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 @@ -341,8 +340,8 @@ connection_cpu_process_inbuf(connection_t *conn) circ = NULL; log_debug(LD_OR, "Unpacking cpuworker reply, chan_id is " U64_FORMAT - ", circ_id is %d", - U64_PRINTF_ARG(chan_id), circ_id); + ", circ_id is %u", + U64_PRINTF_ARG(chan_id), (unsigned)circ_id); p_chan = channel_find_by_global_id(chan_id); if (p_chan) @@ -536,13 +535,16 @@ spawn_cpuworker(void) conn = connection_new(CONN_TYPE_CPUWORKER, AF_UNIX); - set_socket_nonblocking(fd); - /* set up conn so it's got all the data we need to remember */ conn->s = fd; conn->address = tor_strdup("localhost"); tor_addr_make_unspec(&conn->addr); + if (set_socket_nonblocking(fd) == -1) { + connection_free(conn); /* this closes fd */ + return -1; + } + if (connection_add(conn) < 0) { /* no space, forget it */ log_warn(LD_NET,"connection_add for cpuworker failed. Giving up."); connection_free(conn); /* this closes fd */ diff --git a/src/or/directory.c b/src/or/directory.c index c101418446..38a423cb8e 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -472,12 +472,13 @@ directory_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose, if (options->UseBridges && type != BRIDGE_DIRINFO) { /* We want to ask a running bridge for which we have a descriptor. * - * Be careful here: we should only ask questions that we know our - * bridges can answer. So far we're solving that by backing off to - * the behavior supported by our oldest bridge; see for example - * any_bridges_dont_support_microdescriptors(). + * When we ask choose_random_entry() for a bridge, we specify what + * sort of dir fetch we'll be doing, so it won't return a bridge + * that can't answer our question. */ - const node_t *node = choose_random_entry(NULL); + /* XXX024 Not all bridges handle conditional consensus downloading, + * so, for now, never assume the server supports that. -PP */ + const node_t *node = choose_random_dirguard(type); if (node && node->ri) { /* every bridge has a routerinfo. */ tor_addr_t addr; @@ -2804,6 +2805,19 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers, const char *key = url + strlen("/tor/status/"); long lifetime = NETWORKSTATUS_CACHE_LIFETIME; + if (options->DisableV2DirectoryInfo_ && !is_v3) { + static ratelim_t reject_v2_ratelim = RATELIM_INIT(1800); + char *m; + write_http_status_line(conn, 404, "Not found"); + smartlist_free(dir_fps); + geoip_note_ns_response(GEOIP_REJECT_NOT_FOUND); + if ((m = rate_limit_log(&reject_v2_ratelim, approx_time()))) { + log_notice(LD_DIR, "Rejected a v2 networkstatus request.%s", m); + tor_free(m); + } + goto done; + } + if (!is_v3) { dirserv_get_networkstatus_v2_fingerprints(dir_fps, key); if (!strcmpstart(key, "fp/")) diff --git a/src/or/dirserv.c b/src/or/dirserv.c index 0819d4bd24..badacd683d 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -2101,13 +2101,15 @@ version_from_platform(const char *platform) * NS_V3_CONSENSUS - Output the first portion of a V3 NS consensus entry * NS_V3_CONSENSUS_MICRODESC - Output the first portion of a V3 microdesc * consensus entry. - * NS_V3_VOTE - Output a complete V3 NS vote + * NS_V3_VOTE - Output a complete V3 NS vote. If <b>vrs</b> is present, + * it contains additional information for the vote. * NS_CONTROL_PORT - Output a NS document for the control port */ int routerstatus_format_entry(char *buf, size_t buf_len, const routerstatus_t *rs, const char *version, - routerstatus_format_type_t format) + routerstatus_format_type_t format, + const vote_routerstatus_t *vrs) { int r; char *cp; @@ -2253,10 +2255,10 @@ routerstatus_format_entry(char *buf, size_t buf_len, return -1; } cp += strlen(cp); - if (format == NS_V3_VOTE && rs->has_measured_bw) { + if (format == NS_V3_VOTE && vrs && vrs->has_measured_bw) { *--cp = '\0'; /* Kill "\n" */ r = tor_snprintf(cp, buf_len - (cp-buf), - " Measured=%d\n", rs->measured_bw); + " Measured=%d\n", vrs->measured_bw); if (r<0) { log_warn(LD_BUG, "Not enough space in buffer for weight line."); return -1; @@ -2639,12 +2641,12 @@ int measured_bw_line_apply(measured_bw_line_t *parsed_line, smartlist_t *routerstatuses) { - routerstatus_t *rs = NULL; + vote_routerstatus_t *rs = NULL; if (!routerstatuses) return 0; rs = smartlist_bsearch(routerstatuses, parsed_line->node_id, - compare_digest_to_routerstatus_entry); + compare_digest_to_vote_routerstatus_entry); if (rs) { rs->has_measured_bw = 1; @@ -2659,7 +2661,7 @@ measured_bw_line_apply(measured_bw_line_t *parsed_line, /** * Read the measured bandwidth file and apply it to the list of - * routerstatuses. Returns -1 on error, 0 otherwise. + * vote_routerstatus_t. Returns -1 on error, 0 otherwise. */ int dirserv_read_measured_bandwidths(const char *from_file, @@ -2701,7 +2703,7 @@ dirserv_read_measured_bandwidths(const char *from_file, } if (routerstatuses) - smartlist_sort(routerstatuses, compare_routerstatus_entries); + smartlist_sort(routerstatuses, compare_vote_routerstatus_entries); while (!feof(fp)) { measured_bw_line_t parsed_line; @@ -3052,7 +3054,8 @@ generate_v2_networkstatus_opinion(void) if (digestmap_get(omit_as_sybil, ri->cache_info.identity_digest)) clear_status_flags_on_sybil(&rs); - if (routerstatus_format_entry(outp, endp-outp, &rs, version, NS_V2)) { + if (routerstatus_format_entry(outp, endp-outp, &rs, version, NS_V2, + NULL)) { log_warn(LD_BUG, "Unable to print router status."); tor_free(version); goto done; diff --git a/src/or/dirserv.h b/src/or/dirserv.h index add09f44a3..0f8cb4150e 100644 --- a/src/or/dirserv.h +++ b/src/or/dirserv.h @@ -76,7 +76,6 @@ int directory_fetches_from_authorities(const or_options_t *options); int directory_fetches_dir_info_early(const or_options_t *options); int directory_fetches_dir_info_later(const or_options_t *options); int directory_caches_v2_dir_info(const or_options_t *options); -#define directory_caches_v1_dir_info(o) directory_caches_v2_dir_info(o) int directory_caches_unknown_auth_certs(const or_options_t *options); int directory_caches_dir_info(const or_options_t *options); int directory_permits_begindir_requests(const or_options_t *options); @@ -131,7 +130,8 @@ size_t dirserv_estimate_microdesc_size(const smartlist_t *fps, int compressed); int routerstatus_format_entry(char *buf, size_t buf_len, const routerstatus_t *rs, const char *platform, - routerstatus_format_type_t format); + routerstatus_format_type_t format, + const vote_routerstatus_t *vrs); void dirserv_free_all(void); void cached_dir_decref(cached_dir_t *d); cached_dir_t *new_cached_dir(char *s, time_t published); diff --git a/src/or/dirvote.c b/src/or/dirvote.c index 358708b6c5..bcfe2b0698 100644 --- a/src/or/dirvote.c +++ b/src/or/dirvote.c @@ -212,7 +212,7 @@ format_networkstatus_vote(crypto_pk_t *private_signing_key, vrs) { vote_microdesc_hash_t *h; if (routerstatus_format_entry(outp, endp-outp, &vrs->status, - vrs->version, NS_V3_VOTE) < 0) { + vrs->version, NS_V3_VOTE, vrs) < 0) { log_warn(LD_BUG, "Unable to print router status."); goto err; } @@ -1388,6 +1388,7 @@ networkstatus_compute_consensus(smartlist_t *votes, char *client_versions = NULL, *server_versions = NULL; smartlist_t *flags; const char *flavor_name; + uint32_t max_unmeasured_bw = DEFAULT_MAX_UNMEASURED_BW; int64_t G=0, M=0, E=0, D=0, T=0; /* For bandwidth weights */ const routerstatus_format_type_t rs_format = flavor == FLAV_NS ? NS_V3_CONSENSUS : NS_V3_CONSENSUS_MICRODESC; @@ -1586,6 +1587,30 @@ networkstatus_compute_consensus(smartlist_t *votes, smartlist_free(dir_sources); } + if (consensus_method >= MIN_METHOD_TO_CLIP_UNMEASURED_BW) { + char *max_unmeasured_param = NULL; + /* XXXX Extract this code into a common function */ + if (params) { + if (strcmpstart(params, "maxunmeasuredbw=") == 0) + max_unmeasured_param = params; + else + max_unmeasured_param = strstr(params, " maxunmeasuredbw="); + } + if (max_unmeasured_param) { + int ok = 0; + char *eq = strchr(max_unmeasured_param, '='); + if (eq) { + max_unmeasured_bw = (uint32_t) + tor_parse_ulong(eq+1, 10, 1, UINT32_MAX, &ok, NULL); + if (!ok) { + log_warn(LD_DIR, "Bad element '%s' in max unmeasured bw param", + escaped(max_unmeasured_param)); + max_unmeasured_bw = DEFAULT_MAX_UNMEASURED_BW; + } + } + } + } + /* Add the actual router entries. */ { int *index; /* index[j] is the current index into votes[j]. */ @@ -1612,6 +1637,7 @@ networkstatus_compute_consensus(smartlist_t *votes, int *named_flag; /* Index of the flag "Named" for votes[j] */ int *unnamed_flag; /* Index of the flag "Unnamed" for votes[j] */ int chosen_named_idx; + int n_authorities_measuring_bandwidth; strmap_t *name_to_id_map = strmap_new(); char conflict[DIGEST_LEN]; @@ -1700,6 +1726,14 @@ networkstatus_compute_consensus(smartlist_t *votes, } SMARTLIST_FOREACH_END(v); } + /* We need to know how many votes measure bandwidth. */ + n_authorities_measuring_bandwidth = 0; + SMARTLIST_FOREACH(votes, networkstatus_t *, v, + if (v->has_measured_bws) { + ++n_authorities_measuring_bandwidth; + } + ); + /* Now go through all the votes */ flag_counts = tor_malloc(sizeof(int) * smartlist_len(flags)); while (1) { @@ -1769,8 +1803,8 @@ networkstatus_compute_consensus(smartlist_t *votes, } /* count bandwidths */ - if (rs->status.has_measured_bw) - measured_bws[num_mbws++] = rs->status.measured_bw; + if (rs->has_measured_bw) + measured_bws[num_mbws++] = rs->measured_bw; if (rs->status.has_bandwidth) bandwidths[num_bandwidths++] = rs->status.bandwidth; @@ -1863,10 +1897,19 @@ networkstatus_compute_consensus(smartlist_t *votes, /* Pick a bandwidth */ if (consensus_method >= 6 && num_mbws > 2) { rs_out.has_bandwidth = 1; + rs_out.bw_is_unmeasured = 0; rs_out.bandwidth = median_uint32(measured_bws, num_mbws); } else if (consensus_method >= 5 && num_bandwidths > 0) { rs_out.has_bandwidth = 1; + rs_out.bw_is_unmeasured = 1; rs_out.bandwidth = median_uint32(bandwidths, num_bandwidths); + if (consensus_method >= MIN_METHOD_TO_CLIP_UNMEASURED_BW && + n_authorities_measuring_bandwidth > 2) { + /* Cap non-measured bandwidths. */ + if (rs_out.bandwidth > max_unmeasured_bw) { + rs_out.bandwidth = max_unmeasured_bw; + } + } } /* Fix bug 2203: Do not count BadExit nodes as Exits for bw weights */ @@ -1987,7 +2030,7 @@ networkstatus_compute_consensus(smartlist_t *votes, /* Okay!! Now we can write the descriptor... */ /* First line goes into "buf". */ routerstatus_format_entry(buf, sizeof(buf), &rs_out, NULL, - rs_format); + rs_format, NULL); smartlist_add(chunks, tor_strdup(buf)); } /* Now an m line, if applicable. */ @@ -2008,7 +2051,10 @@ networkstatus_compute_consensus(smartlist_t *votes, smartlist_add(chunks, tor_strdup("\n")); /* Now the weight line. */ if (rs_out.has_bandwidth) { - smartlist_add_asprintf(chunks, "w Bandwidth=%d\n", rs_out.bandwidth); + int unmeasured = rs_out.bw_is_unmeasured && + consensus_method >= MIN_METHOD_TO_CLIP_UNMEASURED_BW; + smartlist_add_asprintf(chunks, "w Bandwidth=%d%s\n", rs_out.bandwidth, + unmeasured?" Unmeasured=1":""); } /* Now the exitpolicy summary line. */ @@ -2051,6 +2097,7 @@ networkstatus_compute_consensus(smartlist_t *votes, // Parse params, extract BW_WEIGHT_SCALE if present // DO NOT use consensus_param_bw_weight_scale() in this code! // The consensus is not formed yet! + /* XXXX Extract this code into a common function */ if (params) { if (strcmpstart(params, "bwweightscale=") == 0) bw_weight_param = params; diff --git a/src/or/dirvote.h b/src/or/dirvote.h index 366b7cf037..fbb61b652f 100644 --- a/src/or/dirvote.h +++ b/src/or/dirvote.h @@ -20,7 +20,7 @@ #define MIN_VOTE_INTERVAL 300 /** The highest consensus method that we currently support. */ -#define MAX_SUPPORTED_CONSENSUS_METHOD 16 +#define MAX_SUPPORTED_CONSENSUS_METHOD 17 /** Lowest consensus method that contains a 'directory-footer' marker */ #define MIN_METHOD_FOR_FOOTER 9 @@ -52,6 +52,14 @@ * line */ #define MIN_METHOD_FOR_NTOR_KEY 16 +/** Lowest consensus method that ensures that authorities output an + * Unmeasured=1 flag for unmeasured bandwidths */ +#define MIN_METHOD_TO_CLIP_UNMEASURED_BW 17 + +/** Default bandwidth to clip unmeasured bandwidths to using method >= + * MIN_METHOD_TO_CLIP_UNMEASURED_BW */ +#define DEFAULT_MAX_UNMEASURED_BW 20 + void dirvote_free_all(void); /* vote manipulation */ diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c index 5dd27905d6..de80e88628 100644 --- a/src/or/entrynodes.c +++ b/src/or/entrynodes.c @@ -23,6 +23,7 @@ #include "directory.h" #include "entrynodes.h" #include "main.h" +#include "microdesc.h" #include "nodelist.h" #include "policies.h" #include "router.h" @@ -132,6 +133,8 @@ entry_guard_set_status(entry_guard_t *e, const node_t *node, if (node) { int is_dir = node_is_dir(node) && node->rs && node->rs->version_supports_microdesc_cache; + if (options->UseBridges && node_is_a_configured_bridge(node)) + is_dir = 1; if (e->is_dir_cache != is_dir) { e->is_dir_cache = is_dir; changed = 1; @@ -353,6 +356,8 @@ add_an_entry_guard(const node_t *chosen, int reset_status, int prepend, } entry->is_dir_cache = node->rs && node->rs->version_supports_microdesc_cache; + if (get_options()->UseBridges && node_is_a_configured_bridge(node)) + entry->is_dir_cache = 1; return NULL; } } else if (!for_directory) { @@ -385,6 +390,8 @@ add_an_entry_guard(const node_t *chosen, int reset_status, int prepend, memcpy(entry->identity, node->identity, DIGEST_LEN); entry->is_dir_cache = node_is_dir(node) && node->rs && node->rs->version_supports_microdesc_cache; + if (get_options()->UseBridges && node_is_a_configured_bridge(node)) + entry->is_dir_cache = 1; /* Choose expiry time smudged over the past month. The goal here * is to a) spread out when Tor clients rotate their guards, so they @@ -856,11 +863,45 @@ entry_list_is_constrained(const or_options_t *options) return 0; } +/** Return true iff this node can answer directory questions about + * microdescriptors. */ +static int +node_understands_microdescriptors(const node_t *node) +{ + tor_assert(node); + if (node->rs && node->rs->version_supports_microdesc_cache) + return 1; + if (node->ri && tor_version_supports_microdescriptors(node->ri->platform)) + return 1; + return 0; +} + +/** Return true iff <b>node</b> is able to answer directory questions + * of type <b>dirinfo</b>. */ +static int +node_can_handle_dirinfo(const node_t *node, dirinfo_type_t dirinfo) +{ + /* Checking dirinfo for any type other than microdescriptors isn't required + yet, since we only choose directory guards that can support microdescs, + routerinfos, and networkstatuses, AND we don't use directory guards if + we're configured to do direct downloads of anything else. The only case + where we might have a guard that doesn't know about a type of directory + information is when we're retrieving directory information from a + bridge. */ + + if ((dirinfo & MICRODESC_DIRINFO) && + !node_understands_microdescriptors(node)) + return 0; + return 1; +} + /** Pick a live (up and listed) entry guard from entry_guards. If * <b>state</b> is non-NULL, this is for a specific circuit -- * make sure not to pick this circuit's exit or any node in the * exit's family. If <b>state</b> is NULL, we're looking for a random - * guard (likely a bridge). */ + * guard (likely a bridge). If <b>dirinfo</b> is not NO_DIRINFO, then + * only select from nodes that know how to answer directory questions + * of that type. */ const node_t * choose_random_entry(cpath_build_state_t *state) { @@ -893,12 +934,6 @@ choose_random_entry_impl(cpath_build_state_t *state, int for_directory, const int num_needed = for_directory ? options->NumDirectoryGuards : options->NumEntryGuards; - /* Checking dirinfo_type isn't required yet, since we only choose directory - guards that can support microdescs, routerinfos, and networkstatuses, AND - we don't use directory guards if we're configured to do direct downloads - of anything else. */ - (void) dirinfo_type; - if (chosen_exit) { nodelist_add_node_and_family(exit_family, chosen_exit); consider_exit_family = 1; @@ -930,6 +965,9 @@ choose_random_entry_impl(cpath_build_state_t *state, int for_directory, continue; /* don't pick the same node for entry and exit */ if (consider_exit_family && smartlist_contains(exit_family, node)) continue; /* avoid relays that are family members of our exit */ + if (dirinfo_type != NO_DIRINFO && + !node_can_handle_dirinfo(node, dirinfo_type)) + continue; /* this node won't be able to answer our dir questions */ #if 0 /* since EntryNodes is always strict now, this clause is moot */ if (options->EntryNodes && !routerset_contains_node(options->EntryNodes, node)) { @@ -2011,7 +2049,7 @@ int any_bridge_descriptors_known(void) { tor_assert(get_options()->UseBridges); - return choose_random_entry(NULL)!=NULL ? 1 : 0; + return choose_random_entry(NULL) != NULL; } /** Return 1 if there are any directory conns fetching bridge descriptors @@ -2093,29 +2131,24 @@ entries_retry_all(const or_options_t *options) entries_retry_helper(options, 1); } -/** Return true if we've ever had a bridge running a Tor version that can't - * provide microdescriptors to us. In that case fall back to asking for - * full descriptors. Eventually all bridges will support microdescriptors - * and we can take this check out; see bug 4013. */ +/** Return true if at least one of our bridges runs a Tor version that can + * provide microdescriptors to us. If not, we'll fall back to asking for + * full descriptors. */ int -any_bridges_dont_support_microdescriptors(void) +any_bridge_supports_microdescriptors(void) { const node_t *node; - static int ever_answered_yes = 0; if (!get_options()->UseBridges || !entry_guards) return 0; - if (ever_answered_yes) - return 1; /* if we ever answer 'yes', always answer 'yes' */ SMARTLIST_FOREACH_BEGIN(entry_guards, entry_guard_t *, e) { node = node_get_by_id(e->identity); - if (node && node->ri && + if (node && node->is_running && node_is_bridge(node) && node_is_a_configured_bridge(node) && - !tor_version_supports_microdescriptors(node->ri->platform)) { + node_understands_microdescriptors(node)) { /* This is one of our current bridges, and we know enough about - * it to know that it won't be able to answer our microdescriptor + * it to know that it will be able to answer our microdescriptor * questions. */ - ever_answered_yes = 1; - return 1; + return 1; } } SMARTLIST_FOREACH_END(e); return 0; diff --git a/src/or/entrynodes.h b/src/or/entrynodes.h index b673d02681..52b8dc00e4 100644 --- a/src/or/entrynodes.h +++ b/src/or/entrynodes.h @@ -108,7 +108,7 @@ int any_pending_bridge_descriptor_fetches(void); int entries_known_but_down(const or_options_t *options); void entries_retry_all(const or_options_t *options); -int any_bridges_dont_support_microdescriptors(void); +int any_bridge_supports_microdescriptors(void); void entry_guards_free_all(void); diff --git a/src/or/hibernate.c b/src/or/hibernate.c index 36af4d8f83..a412571331 100644 --- a/src/or/hibernate.c +++ b/src/or/hibernate.c @@ -506,10 +506,6 @@ accounting_run_housekeeping(time_t now) } } -/** When we have no idea how fast we are, how long do we assume it will take - * us to exhaust our bandwidth? */ -#define GUESS_TIME_TO_USE_BANDWIDTH (24*60*60) - /** Based on our interval and our estimated bandwidth, choose a * deterministic (but random-ish) time to wake up. */ static void diff --git a/src/or/main.c b/src/or/main.c index aa601e5a4f..75a0971534 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -158,10 +158,6 @@ int can_complete_circuit=0; /** How long do we let a directory connection stall before expiring it? */ #define DIR_CONN_MAX_STALL (5*60) -/** How long do we let OR connections handshake before we decide that - * they are obsolete? */ -#define TLS_HANDSHAKE_TIMEOUT (60) - /** Decides our behavior when no logs are configured/before any * logs have been configured. For 0, we log notice to stdout as normal. * For 1, we log warnings only. For 2, we log nothing. @@ -1157,7 +1153,6 @@ run_scheduled_events(time_t now) static time_t time_to_check_v3_certificate = 0; static time_t time_to_check_listeners = 0; static time_t time_to_check_descriptor = 0; - static time_t time_to_check_ipaddress = 0; static time_t time_to_shrink_memory = 0; static time_t time_to_try_getting_descriptors = 0; static time_t time_to_reset_descriptor_failures = 0; @@ -1403,11 +1398,10 @@ run_scheduled_events(time_t now) /** 2. Periodically, we consider force-uploading our descriptor * (if we've passed our internal checks). */ -/** How often do we check whether part of our router info has changed in a way - * that would require an upload? */ +/** How often do we check whether part of our router info has changed in a + * way that would require an upload? That includes checking whether our IP + * address has changed. */ #define CHECK_DESCRIPTOR_INTERVAL (60) -/** How often do we (as a router) check whether our IP address has changed? */ -#define CHECK_IPADDRESS_INTERVAL (15*60) /* 2b. Once per minute, regenerate and upload the descriptor if the old * one is inaccurate. */ @@ -1415,10 +1409,7 @@ run_scheduled_events(time_t now) static int dirport_reachability_count = 0; time_to_check_descriptor = now + CHECK_DESCRIPTOR_INTERVAL; check_descriptor_bandwidth_changed(now); - if (time_to_check_ipaddress < now) { - time_to_check_ipaddress = now + CHECK_IPADDRESS_INTERVAL; - check_descriptor_ipaddress_changed(now); - } + check_descriptor_ipaddress_changed(now); mark_my_descriptor_dirty_if_too_old(now); consider_publishable_server(0); /* also, check religiously for reachability, if it's within the first diff --git a/src/or/microdesc.c b/src/or/microdesc.c index e99b3ebe78..ac48930faf 100644 --- a/src/or/microdesc.c +++ b/src/or/microdesc.c @@ -730,9 +730,9 @@ we_use_microdescriptors_for_circuits(const or_options_t *options) int ret = options->UseMicrodescriptors; if (ret == -1) { /* UseMicrodescriptors is "auto"; we need to decide: */ - /* If we are configured to use bridges and one of our bridges doesn't + /* If we are configured to use bridges and none of our bridges * know what a microdescriptor is, the answer is no. */ - if (options->UseBridges && any_bridges_dont_support_microdescriptors()) + if (options->UseBridges && !any_bridge_supports_microdescriptors()) return 0; /* Otherwise, we decide that we'll use microdescriptors iff we are * not a server, and we're not autofetching everything. */ diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c index 71ac054f88..8846cd0634 100644 --- a/src/or/networkstatus.c +++ b/src/or/networkstatus.c @@ -937,6 +937,17 @@ compare_digest_to_routerstatus_entry(const void *_key, const void **_member) return tor_memcmp(key, rs->identity_digest, DIGEST_LEN); } +/** Helper for bsearching a list of routerstatus_t pointers: compare a + * digest in the key to the identity digest of a routerstatus_t. */ +int +compare_digest_to_vote_routerstatus_entry(const void *_key, + const void **_member) +{ + const char *key = _key; + const vote_routerstatus_t *vrs = *_member; + return tor_memcmp(key, vrs->status.identity_digest, DIGEST_LEN); +} + /** As networkstatus_v2_find_entry, but do not return a const pointer */ routerstatus_t * networkstatus_v2_find_mutable_entry(networkstatus_v2_t *ns, const char *digest) @@ -1421,18 +1432,6 @@ consensus_is_waiting_for_certs(void) ? 1 : 0; } -/** Return the network status with a given identity digest. */ -networkstatus_v2_t * -networkstatus_v2_get_by_digest(const char *digest) -{ - SMARTLIST_FOREACH(networkstatus_v2_list, networkstatus_v2_t *, ns, - { - if (tor_memeq(ns->identity_digest, digest, DIGEST_LEN)) - return ns; - }); - return NULL; -} - /** Return the most recent consensus that we have downloaded, or NULL if we * don't have one. */ networkstatus_t * @@ -2117,7 +2116,7 @@ char * networkstatus_getinfo_helper_single(const routerstatus_t *rs) { char buf[RS_ENTRY_LEN+1]; - routerstatus_format_entry(buf, sizeof(buf), rs, NULL, NS_CONTROL_PORT); + routerstatus_format_entry(buf, sizeof(buf), rs, NULL, NS_CONTROL_PORT, NULL); return tor_strdup(buf); } diff --git a/src/or/networkstatus.h b/src/or/networkstatus.h index b437c5ec2f..761f8e7f0e 100644 --- a/src/or/networkstatus.h +++ b/src/or/networkstatus.h @@ -38,6 +38,8 @@ int router_set_networkstatus_v2(const char *s, time_t arrived_at, void networkstatus_v2_list_clean(time_t now); int compare_digest_to_routerstatus_entry(const void *_key, const void **_member); +int compare_digest_to_vote_routerstatus_entry(const void *_key, + const void **_member); const routerstatus_t *networkstatus_v2_find_entry(networkstatus_v2_t *ns, const char *digest); const routerstatus_t *networkstatus_vote_find_entry(networkstatus_t *ns, @@ -73,7 +75,6 @@ void update_certificate_downloads(time_t now); int consensus_is_waiting_for_certs(void); int client_would_use_router(const routerstatus_t *rs, time_t now, const or_options_t *options); -networkstatus_v2_t *networkstatus_v2_get_by_digest(const char *digest); networkstatus_t *networkstatus_get_latest_consensus(void); networkstatus_t *networkstatus_get_latest_consensus_by_flavor( consensus_flavor_t f); diff --git a/src/or/or.h b/src/or/or.h index 1cb9ef2f0e..8acd7365e3 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -177,8 +177,6 @@ #define MIN_ONION_KEY_LIFETIME (7*24*60*60) /** How often do we rotate TLS contexts? */ #define MAX_SSL_KEY_LIFETIME_INTERNAL (2*60*60) -/** What expiry time shall we place on our SSL certs? */ -#define MAX_SSL_KEY_LIFETIME_ADVERTISED (365*24*60*60) /** How old do we allow a router to get before removing it * from the router list? In seconds. */ @@ -869,11 +867,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 +898,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 +1067,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 +1416,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." */ @@ -2072,9 +2089,8 @@ typedef struct routerstatus_t { unsigned int has_bandwidth:1; /**< The vote/consensus had bw info */ unsigned int has_exitsummary:1; /**< The vote/consensus had exit summaries */ - unsigned int has_measured_bw:1; /**< The vote/consensus had a measured bw */ - - uint32_t measured_bw; /**< Measured bandwidth (capacity) of the router */ + unsigned int bw_is_unmeasured:1; /**< This is a consensus entry, with + * the Unmeasured flag set. */ uint32_t bandwidth; /**< Bandwidth (capacity) of the router as reported in * the vote/consensus, in kilobytes/sec. */ @@ -2321,6 +2337,8 @@ typedef struct vote_routerstatus_t { * networkstatus_t.known_flags. */ char *version; /**< The version that the authority says this router is * running. */ + unsigned int has_measured_bw:1; /**< The vote had a measured bw */ + uint32_t measured_bw; /**< Measured bandwidth (capacity) of the router */ /** The hash or hashes that the authority claims this microdesc has. */ vote_microdesc_hash_t *microdesc; } vote_routerstatus_t; @@ -2386,6 +2404,9 @@ typedef enum { typedef struct networkstatus_t { ENUM_BF(networkstatus_type_t) type : 8; /**< Vote, consensus, or opinion? */ ENUM_BF(consensus_flavor_t) flavor : 8; /**< If a consensus, what kind? */ + unsigned int has_measured_bws : 1;/**< True iff this networkstatus contains + * measured= bandwidth values. */ + time_t published; /**< Vote only: Time when vote was written. */ time_t valid_after; /**< Time after which this vote or consensus applies. */ time_t fresh_until; /**< Time before which this is the most recent vote or @@ -3979,6 +4000,21 @@ typedef struct { /** Fraction: */ double PathsNeededToBuildCircuits; + + /** Do we serve v2 directory info at all? This is a temporary option, since + * we'd like to disable v2 directory serving entirely, but we need a way to + * make it temporarily disableable, in order to do fast testing and be + * able to turn it back on if it turns out to be non-workable. + * + * XXXX025 Make this always-on, or always-off. Right now, it's only + * enableable for authorities. + */ + int DisableV2DirectoryInfo_; + + /** What expiry time shall we place on our SSL certs? "0" means we + * should guess a suitable value. */ + int SSLKeyLifetime; + } or_options_t; /** Persistent state for an onion router, as saved to disk. */ @@ -4432,15 +4468,6 @@ typedef struct vote_timing_t { /********************************* geoip.c **************************/ -/** Round all GeoIP results to the next multiple of this value, to avoid - * leaking information. */ -#define DIR_RECORD_USAGE_GRANULARITY 8 -/** Time interval: Flush geoip data to disk this often. */ -#define DIR_ENTRY_RECORD_USAGE_RETAIN_IPS (24*60*60) -/** How long do we have to have observed per-country request history before - * we are willing to talk about it? */ -#define DIR_RECORD_USAGE_MIN_OBSERVATION_TIME (12*60*60) - /** Indicates an action that we might be noting geoip statistics on. * Note that if we're noticing CONNECT, we're a bridge, and if we're noticing * the others, we're not. diff --git a/src/or/relay.c b/src/or/relay.c index 22bc40d655..9ff9e1e1f4 100644 --- a/src/or/relay.c +++ b/src/or/relay.c @@ -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. */ diff --git a/src/or/relay.h b/src/or/relay.h index 9e2d8af1e9..7e59838f95 100644 --- a/src/or/relay.h +++ b/src/or/relay.h @@ -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, diff --git a/src/or/rendclient.c b/src/or/rendclient.c index 61e3b917e3..7115bf2080 100644 --- a/src/or/rendclient.c +++ b/src/or/rendclient.c @@ -111,14 +111,14 @@ rend_client_reextend_intro_circuit(origin_circuit_t *circ) // XXX: should we not re-extend if hs_circ_has_timed_out? if (circ->remaining_relay_early_cells) { log_info(LD_REND, - "Re-extending circ %d, this time to %s.", - circ->base_.n_circ_id, + "Re-extending circ %u, this time to %s.", + (unsigned)circ->base_.n_circ_id, safe_str_client(extend_info_describe(extend_info))); result = circuit_extend_to_new_exit(circ, extend_info); } else { log_info(LD_REND, - "Closing intro circ %d (out of RELAY_EARLY cells).", - circ->base_.n_circ_id); + "Closing intro circ %u (out of RELAY_EARLY cells).", + (unsigned)circ->base_.n_circ_id); circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_FINISHED); /* connection_ap_handshake_attach_circuit will launch a new intro circ. */ result = 0; @@ -386,8 +386,8 @@ rend_client_introduction_acked(origin_circuit_t *circ, if (circ->base_.purpose != CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT) { log_warn(LD_PROTOCOL, - "Received REND_INTRODUCE_ACK on unexpected circuit %d.", - circ->base_.n_circ_id); + "Received REND_INTRODUCE_ACK on unexpected circuit %u.", + (unsigned)circ->base_.n_circ_id); circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_TORPROTOCOL); return -1; } diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c index 79c1a724e4..2cfc364c3b 100644 --- a/src/or/rendcommon.c +++ b/src/or/rendcommon.c @@ -1452,13 +1452,6 @@ rend_process_relay_cell(circuit_t *circ, const crypt_path_t *layer_hint, command); } -/** Return the number of entries in our rendezvous descriptor cache. */ -int -rend_cache_size(void) -{ - return strmap_size(rend_cache); -} - /** Allocate and return a new rend_data_t with the same * contents as <b>query</b>. */ rend_data_t * diff --git a/src/or/rendcommon.h b/src/or/rendcommon.h index 189891b747..f476593d2b 100644 --- a/src/or/rendcommon.h +++ b/src/or/rendcommon.h @@ -49,7 +49,6 @@ int rend_cache_store(const char *desc, size_t desc_len, int published, int rend_cache_store_v2_desc_as_client(const char *desc, const rend_data_t *rend_query); int rend_cache_store_v2_desc_as_dir(const char *desc); -int rend_cache_size(void); int rend_encode_v2_descriptors(smartlist_t *descs_out, rend_service_descriptor_t *desc, time_t now, uint8_t period, rend_auth_type_t auth_type, diff --git a/src/or/rendmid.c b/src/or/rendmid.c index 1046ce3814..1bd11f6dc0 100644 --- a/src/or/rendmid.c +++ b/src/or/rendmid.c @@ -32,8 +32,8 @@ rend_mid_establish_intro(or_circuit_t *circ, const uint8_t *request, int reason = END_CIRC_REASON_INTERNAL; log_info(LD_REND, - "Received an ESTABLISH_INTRO request on circuit %d", - circ->p_circ_id); + "Received an ESTABLISH_INTRO request on circuit %u", + (unsigned) circ->p_circ_id); if (circ->base_.purpose != CIRCUIT_PURPOSE_OR || circ->base_.n_chan) { log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, @@ -114,8 +114,8 @@ rend_mid_establish_intro(or_circuit_t *circ, const uint8_t *request, memcpy(circ->rend_token, pk_digest, DIGEST_LEN); log_info(LD_REND, - "Established introduction point on circuit %d for service %s", - circ->p_circ_id, safe_str(serviceid)); + "Established introduction point on circuit %u for service %s", + (unsigned) circ->p_circ_id, safe_str(serviceid)); return 0; truncated: @@ -139,13 +139,13 @@ rend_mid_introduce(or_circuit_t *circ, const uint8_t *request, char serviceid[REND_SERVICE_ID_LEN_BASE32+1]; char nak_body[1]; - log_info(LD_REND, "Received an INTRODUCE1 request on circuit %d", - circ->p_circ_id); + log_info(LD_REND, "Received an INTRODUCE1 request on circuit %u", + (unsigned)circ->p_circ_id); if (circ->base_.purpose != CIRCUIT_PURPOSE_OR || circ->base_.n_chan) { log_warn(LD_PROTOCOL, - "Rejecting INTRODUCE1 on non-OR or non-edge circuit %d.", - circ->p_circ_id); + "Rejecting INTRODUCE1 on non-OR or non-edge circuit %u.", + (unsigned)circ->p_circ_id); goto err; } @@ -155,9 +155,9 @@ rend_mid_introduce(or_circuit_t *circ, const uint8_t *request, */ if (request_len < (DIGEST_LEN+(MAX_NICKNAME_LEN+1)+REND_COOKIE_LEN+ DH_KEY_LEN+CIPHER_KEY_LEN+PKCS1_OAEP_PADDING_OVERHEAD)) { - log_warn(LD_PROTOCOL, "Impossibly short INTRODUCE1 cell on circuit %d; " + log_warn(LD_PROTOCOL, "Impossibly short INTRODUCE1 cell on circuit %u; " "responding with nack.", - circ->p_circ_id); + (unsigned)circ->p_circ_id); goto err; } @@ -168,17 +168,17 @@ rend_mid_introduce(or_circuit_t *circ, const uint8_t *request, intro_circ = circuit_get_intro_point((char*)request); if (!intro_circ) { log_info(LD_REND, - "No intro circ found for INTRODUCE1 cell (%s) from circuit %d; " + "No intro circ found for INTRODUCE1 cell (%s) from circuit %u; " "responding with nack.", - safe_str(serviceid), circ->p_circ_id); + safe_str(serviceid), (unsigned)circ->p_circ_id); goto err; } log_info(LD_REND, "Sending introduction request for service %s " - "from circ %d to circ %d", - safe_str(serviceid), circ->p_circ_id, - intro_circ->p_circ_id); + "from circ %u to circ %u", + safe_str(serviceid), (unsigned)circ->p_circ_id, + (unsigned)intro_circ->p_circ_id); /* Great. Now we just relay the cell down the circuit. */ if (relay_send_command_from_edge(0, TO_CIRCUIT(intro_circ), @@ -221,8 +221,8 @@ rend_mid_establish_rendezvous(or_circuit_t *circ, const uint8_t *request, char hexid[9]; int reason = END_CIRC_REASON_TORPROTOCOL; - log_info(LD_REND, "Received an ESTABLISH_RENDEZVOUS request on circuit %d", - circ->p_circ_id); + log_info(LD_REND, "Received an ESTABLISH_RENDEZVOUS request on circuit %u", + (unsigned)circ->p_circ_id); if (circ->base_.purpose != CIRCUIT_PURPOSE_OR || circ->base_.n_chan) { log_warn(LD_PROTOCOL, @@ -256,8 +256,8 @@ rend_mid_establish_rendezvous(or_circuit_t *circ, const uint8_t *request, base16_encode(hexid,9,(char*)request,4); log_info(LD_REND, - "Established rendezvous point on circuit %d for cookie %s", - circ->p_circ_id, hexid); + "Established rendezvous point on circuit %u for cookie %s", + (unsigned)circ->p_circ_id, hexid); return 0; err: @@ -279,16 +279,16 @@ rend_mid_rendezvous(or_circuit_t *circ, const uint8_t *request, if (circ->base_.purpose != CIRCUIT_PURPOSE_OR || circ->base_.n_chan) { log_info(LD_REND, - "Tried to complete rendezvous on non-OR or non-edge circuit %d.", - circ->p_circ_id); + "Tried to complete rendezvous on non-OR or non-edge circuit %u.", + (unsigned)circ->p_circ_id); reason = END_CIRC_REASON_TORPROTOCOL; goto err; } if (request_len != REND_COOKIE_LEN+DH_KEY_LEN+DIGEST_LEN) { log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, - "Rejecting RENDEZVOUS1 cell with bad length (%d) on circuit %d.", - (int)request_len, circ->p_circ_id); + "Rejecting RENDEZVOUS1 cell with bad length (%d) on circuit %u.", + (int)request_len, (unsigned)circ->p_circ_id); reason = END_CIRC_REASON_TORPROTOCOL; goto err; } @@ -296,8 +296,8 @@ rend_mid_rendezvous(or_circuit_t *circ, const uint8_t *request, base16_encode(hexid, sizeof(hexid), (const char*)request, 4); log_info(LD_REND, - "Got request for rendezvous from circuit %d to cookie %s.", - circ->p_circ_id, hexid); + "Got request for rendezvous from circuit %u to cookie %s.", + (unsigned)circ->p_circ_id, hexid); rend_circ = circuit_get_rendezvous((char*)request); if (!rend_circ) { @@ -314,15 +314,15 @@ rend_mid_rendezvous(or_circuit_t *circ, const uint8_t *request, (char*)(request+REND_COOKIE_LEN), request_len-REND_COOKIE_LEN, NULL)) { log_warn(LD_GENERAL, - "Unable to send RENDEZVOUS2 cell to client on circuit %d.", - rend_circ->p_circ_id); + "Unable to send RENDEZVOUS2 cell to client on circuit %u.", + (unsigned)rend_circ->p_circ_id); goto err; } /* Join the circuits. */ log_info(LD_REND, - "Completing rendezvous: circuit %d joins circuit %d (cookie %s)", - circ->p_circ_id, rend_circ->p_circ_id, hexid); + "Completing rendezvous: circuit %u joins circuit %u (cookie %s)", + (unsigned)circ->p_circ_id, (unsigned)rend_circ->p_circ_id, hexid); circuit_change_purpose(TO_CIRCUIT(circ), CIRCUIT_PURPOSE_REND_ESTABLISHED); circuit_change_purpose(TO_CIRCUIT(rend_circ), diff --git a/src/or/rendservice.c b/src/or/rendservice.c index 10d232c039..a8f63ddf66 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -1119,19 +1119,15 @@ rend_service_introduce(origin_circuit_t *circuit, const uint8_t *request, crypt_path_t *cpath = NULL; char hexcookie[9]; int circ_needs_uptime; - char intro_key_digest[DIGEST_LEN]; - size_t auth_len = 0; - char auth_data[REND_DESC_COOKIE_LEN]; time_t now = time(NULL); - char diffie_hellman_hash[DIGEST_LEN]; time_t elapsed; int replay; /* Do some initial validation and logging before we parse the cell */ if (circuit->base_.purpose != CIRCUIT_PURPOSE_S_INTRO) { log_warn(LD_PROTOCOL, - "Got an INTRODUCE2 over a non-introduction circuit %d.", - circuit->base_.n_circ_id); + "Got an INTRODUCE2 over a non-introduction circuit %u.", + (unsigned) circuit->base_.n_circ_id); goto err; } @@ -1165,8 +1161,8 @@ rend_service_introduce(origin_circuit_t *circuit, const uint8_t *request, goto err; } - log_info(LD_REND, "Received INTRODUCE2 cell for service %s on circ %d.", - escaped(serviceid), circuit->base_.n_circ_id); + log_info(LD_REND, "Received INTRODUCE2 cell for service %s on circ %u.", + escaped(serviceid), (unsigned)circuit->base_.n_circ_id); /* use intro key instead of service key. */ intro_key = circuit->intro_key; @@ -1181,7 +1177,8 @@ rend_service_introduce(origin_circuit_t *circuit, const uint8_t *request, if (!parsed_req) { goto log_error; } else if (err_msg) { - log_info(LD_REND, "%s on circ %d.", err_msg, circuit->base_.n_circ_id); + log_info(LD_REND, "%s on circ %u.", err_msg, + (unsigned)circuit->base_.n_circ_id); tor_free(err_msg); } @@ -1191,7 +1188,8 @@ rend_service_introduce(origin_circuit_t *circuit, const uint8_t *request, if (result < 0) { goto log_error; } else if (err_msg) { - log_info(LD_REND, "%s on circ %d.", err_msg, circuit->base_.n_circ_id); + log_info(LD_REND, "%s on circ %u.", err_msg, + (unsigned)circuit->base_.n_circ_id); tor_free(err_msg); } @@ -1227,7 +1225,8 @@ rend_service_introduce(origin_circuit_t *circuit, const uint8_t *request, if (result < 0) { goto log_error; } else if (err_msg) { - log_info(LD_REND, "%s on circ %d.", err_msg, circuit->base_.n_circ_id); + log_info(LD_REND, "%s on circ %u.", err_msg, + (unsigned)circuit->base_.n_circ_id); tor_free(err_msg); } @@ -1237,7 +1236,8 @@ rend_service_introduce(origin_circuit_t *circuit, const uint8_t *request, if (result < 0) { goto log_error; } else if (err_msg) { - log_info(LD_REND, "%s on circ %d.", err_msg, circuit->base_.n_circ_id); + log_info(LD_REND, "%s on circ %u.", err_msg, + (unsigned)circuit->base_.n_circ_id); tor_free(err_msg); } @@ -1247,7 +1247,8 @@ rend_service_introduce(origin_circuit_t *circuit, const uint8_t *request, if (result < 0) { goto log_error; } else if (err_msg) { - log_info(LD_REND, "%s on circ %d.", err_msg, circuit->base_.n_circ_id); + log_info(LD_REND, "%s on circ %u.", err_msg, + (unsigned)circuit->base_.n_circ_id); tor_free(err_msg); } stage_descr = NULL; @@ -1296,8 +1297,9 @@ rend_service_introduce(origin_circuit_t *circuit, const uint8_t *request, /* If the service performs client authorization, check included auth data. */ if (service->clients) { - if (auth_len > 0) { - if (rend_check_authorization(service, auth_data)) { + if (parsed_req->version == 3 && parsed_req->u.v3.auth_len > 0) { + if (rend_check_authorization(service, + (const char*)parsed_req->u.v3.auth_data)) { log_info(LD_REND, "Authorization data in INTRODUCE2 cell are valid."); } else { log_info(LD_REND, "The authorization data that are contained in " @@ -1396,7 +1398,8 @@ rend_service_introduce(origin_circuit_t *circuit, const uint8_t *request, } } - log_warn(LD_REND, "%s on circ %d", err_msg, circuit->base_.n_circ_id); + log_warn(LD_REND, "%s on circ %u", err_msg, + (unsigned)circuit->base_.n_circ_id); err: status = -1; if (dh) crypto_dh_free(dh); @@ -1410,9 +1413,6 @@ rend_service_introduce(origin_circuit_t *circuit, const uint8_t *request, memwipe(buf, 0, sizeof(buf)); memwipe(serviceid, 0, sizeof(serviceid)); memwipe(hexcookie, 0, sizeof(hexcookie)); - memwipe(intro_key_digest, 0, sizeof(intro_key_digest)); - memwipe(auth_data, 0, sizeof(auth_data)); - memwipe(diffie_hellman_hash, 0, sizeof(diffie_hellman_hash)); /* Free the parsed cell */ if (parsed_req) { @@ -2423,8 +2423,8 @@ rend_service_intro_has_opened(origin_circuit_t *circuit) service = rend_service_get_by_pk_digest( circuit->rend_data->rend_pk_digest); if (!service) { - log_warn(LD_REND, "Unrecognized service ID %s on introduction circuit %d.", - serviceid, circuit->base_.n_circ_id); + log_warn(LD_REND, "Unrecognized service ID %s on introduction circuit %u.", + serviceid, (unsigned)circuit->base_.n_circ_id); reason = END_CIRC_REASON_NOSUCHSERVICE; goto err; } @@ -2467,8 +2467,8 @@ rend_service_intro_has_opened(origin_circuit_t *circuit) } log_info(LD_REND, - "Established circuit %d as introduction point for service %s", - circuit->base_.n_circ_id, serviceid); + "Established circuit %u as introduction point for service %s", + (unsigned)circuit->base_.n_circ_id, serviceid); /* Use the intro key instead of the service key in ESTABLISH_INTRO. */ intro_key = circuit->intro_key; @@ -2502,8 +2502,8 @@ rend_service_intro_has_opened(origin_circuit_t *circuit) RELAY_COMMAND_ESTABLISH_INTRO, buf, len, circuit->cpath->prev)<0) { log_info(LD_GENERAL, - "Couldn't send introduction request for service %s on circuit %d", - serviceid, circuit->base_.n_circ_id); + "Couldn't send introduction request for service %s on circuit %u", + serviceid, (unsigned)circuit->base_.n_circ_id); reason = END_CIRC_REASON_INTERNAL; goto err; } @@ -2545,8 +2545,8 @@ rend_service_intro_established(origin_circuit_t *circuit, service = rend_service_get_by_pk_digest( circuit->rend_data->rend_pk_digest); if (!service) { - log_warn(LD_REND, "Unknown service on introduction circuit %d.", - circuit->base_.n_circ_id); + log_warn(LD_REND, "Unknown service on introduction circuit %u.", + (unsigned)circuit->base_.n_circ_id); goto err; } service->desc_is_dirty = time(NULL); @@ -2555,8 +2555,8 @@ rend_service_intro_established(origin_circuit_t *circuit, base32_encode(serviceid, REND_SERVICE_ID_LEN_BASE32 + 1, circuit->rend_data->rend_pk_digest, REND_SERVICE_ID_LEN); log_info(LD_REND, - "Received INTRO_ESTABLISHED cell on circuit %d for service %s", - circuit->base_.n_circ_id, serviceid); + "Received INTRO_ESTABLISHED cell on circuit %u for service %s", + (unsigned)circuit->base_.n_circ_id, serviceid); /* Getting a valid INTRODUCE_ESTABLISHED means we've successfully * used the circ */ @@ -2603,9 +2603,9 @@ rend_service_rendezvous_has_opened(origin_circuit_t *circuit) circuit->rend_data->rend_pk_digest, REND_SERVICE_ID_LEN); log_info(LD_REND, - "Done building circuit %d to rendezvous with " + "Done building circuit %u to rendezvous with " "cookie %s for service %s", - circuit->base_.n_circ_id, hexcookie, serviceid); + (unsigned)circuit->base_.n_circ_id, hexcookie, serviceid); /* Clear the 'in-progress HS circ has timed out' flag for * consistency with what happens on the client side; this line has @@ -3345,8 +3345,8 @@ rend_service_set_connection_addr_port(edge_connection_t *conn, circ->rend_data->rend_pk_digest); if (!service) { log_warn(LD_REND, "Couldn't find any service associated with pk %s on " - "rendezvous circuit %d; closing.", - serviceid, circ->base_.n_circ_id); + "rendezvous circuit %u; closing.", + serviceid, (unsigned)circ->base_.n_circ_id); return -1; } matching_ports = smartlist_new(); diff --git a/src/or/rephist.c b/src/or/rephist.c index 1bee6459cc..55f321d5ff 100644 --- a/src/or/rephist.c +++ b/src/or/rephist.c @@ -310,9 +310,10 @@ rep_hist_note_router_reachable(const char *id, const tor_addr_t *at_addr, tor_assert(hist); tor_assert((!at_addr && !at_port) || (at_addr && at_port)); - addr_changed = at_addr && + addr_changed = at_addr && !tor_addr_is_null(&hist->last_reached_addr) && tor_addr_compare(at_addr, &hist->last_reached_addr, CMP_EXACT) != 0; - port_changed = at_port && at_port != hist->last_reached_port; + port_changed = at_port && hist->last_reached_port && + at_port != hist->last_reached_port; if (!started_tracking_stability) started_tracking_stability = time(NULL); diff --git a/src/or/router.c b/src/or/router.c index 4492ed271f..c8c9ce1a4f 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -650,6 +650,7 @@ router_initialize_tls_context(void) { unsigned int flags = 0; const or_options_t *options = get_options(); + int lifetime = options->SSLKeyLifetime; if (public_server_mode(options)) flags |= TOR_TLS_CTX_IS_PUBLIC_SERVER; if (options->TLSECGroup) { @@ -658,12 +659,28 @@ router_initialize_tls_context(void) else if (!strcasecmp(options->TLSECGroup, "P224")) flags |= TOR_TLS_CTX_USE_ECDHE_P224; } + if (!lifetime) { /* we should guess a good ssl cert lifetime */ + /* choose between 5 and 365 days, and round to the day */ + lifetime = 5*24*3600 + crypto_rand_int(361*24*3600); + lifetime -= lifetime % (24*3600); + + if (crypto_rand_int(2)) { + /* Half the time we expire at midnight, and half the time we expire + * one second before midnight. (Some CAs wobble their expiry times a + * bit in practice, perhaps to reduce collision attacks; see ticket + * 8443 for details about observed certs in the wild.) */ + lifetime--; + } + } + + /* It's ok to pass lifetime in as an unsigned int, since + * config_parse_interval() checked it. */ return tor_tls_context_init(flags, get_tlsclient_identity_key(), - server_mode(get_options()) ? + server_mode(options) ? get_server_identity_key() : NULL, - MAX_SSL_KEY_LIFETIME_ADVERTISED); + (unsigned int)lifetime); } /** Initialize all OR private keys, and the TLS context, as necessary. @@ -1192,7 +1209,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; @@ -1712,7 +1730,9 @@ static int router_guess_address_from_dir_headers(uint32_t *guess); int router_pick_published_address(const or_options_t *options, uint32_t *addr) { - if (resolve_my_address(LOG_INFO, options, addr, NULL, NULL) < 0) { + *addr = get_last_resolved_addr(); + if (!*addr && + resolve_my_address(LOG_INFO, options, addr, NULL, NULL) < 0) { log_info(LD_CONFIG, "Could not determine our address locally. " "Checking if directory headers provide any hints."); if (router_guess_address_from_dir_headers(addr) < 0) { @@ -2159,7 +2179,9 @@ router_new_address_suggestion(const char *suggestion, } /* XXXX ipv6 */ - if (resolve_my_address(LOG_INFO, options, &cur, NULL, NULL) >= 0) { + cur = get_last_resolved_addr(); + if (cur || + resolve_my_address(LOG_INFO, options, &cur, NULL, NULL) >= 0) { /* We're all set -- we already know our address. Great. */ tor_addr_from_ipv4h(&last_guessed_ip, cur); /* store it in case we need it later */ @@ -2710,7 +2732,9 @@ extrainfo_dump_to_string(char **s_out, extrainfo_t *extrainfo, return result; } -/** Return true iff <b>s</b> is a legally valid server nickname. */ +/** Return true iff <b>s</b> is a valid server nickname. (That is, a string + * containing between 1 and MAX_NICKNAME_LEN characters from + * LEGAL_NICKNAME_CHARACTERS.) */ int is_legal_nickname(const char *s) { @@ -2721,7 +2745,7 @@ is_legal_nickname(const char *s) strspn(s,LEGAL_NICKNAME_CHARACTERS) == len; } -/** Return true iff <b>s</b> is a legally valid server nickname or +/** Return true iff <b>s</b> is a valid server nickname or * hex-encoded identity-key digest. */ int is_legal_nickname_or_hexdigest(const char *s) @@ -2732,8 +2756,11 @@ is_legal_nickname_or_hexdigest(const char *s) return is_legal_hexdigest(s); } -/** Return true iff <b>s</b> is a legally valid hex-encoded identity-key - * digest. */ +/** Return true iff <b>s</b> is a valid hex-encoded identity-key + * digest. (That is, an optional $, followed by 40 hex characters, + * followed by either nothing, or = or ~ followed by a nickname, or + * a character other than =, ~, or a hex character.) + */ int is_legal_hexdigest(const char *s) { @@ -2956,23 +2983,6 @@ router_get_verbose_nickname(char *buf, const routerinfo_t *router) strlcpy(buf+1+HEX_DIGEST_LEN+1, router->nickname, MAX_NICKNAME_LEN+1); } -/** Set <b>buf</b> (which must have MAX_VERBOSE_NICKNAME_LEN+1 bytes) to the - * verbose representation of the identity of <b>router</b>. The format is: - * A dollar sign. - * The upper-case hexadecimal encoding of the SHA1 hash of router's identity. - * A "=" if the router is named; a "~" if it is not. - * The router's nickname. - **/ -void -routerstatus_get_verbose_nickname(char *buf, const routerstatus_t *router) -{ - buf[0] = '$'; - base16_encode(buf+1, HEX_DIGEST_LEN+1, router->identity_digest, - DIGEST_LEN); - buf[1+HEX_DIGEST_LEN] = router->is_named ? '=' : '~'; - strlcpy(buf+1+HEX_DIGEST_LEN+1, router->nickname, MAX_NICKNAME_LEN+1); -} - /** Forget that we have issued any router-related warnings, so that we'll * warn again if we see the same errors. */ void diff --git a/src/or/router.h b/src/or/router.h index fd2076af01..96749b53c0 100644 --- a/src/or/router.h +++ b/src/or/router.h @@ -132,8 +132,6 @@ const char *routerstatus_describe(const routerstatus_t *ri); const char *extend_info_describe(const extend_info_t *ei); void router_get_verbose_nickname(char *buf, const routerinfo_t *router); -void routerstatus_get_verbose_nickname(char *buf, - const routerstatus_t *router); void router_reset_warnings(void); void router_reset_reachability(void); void router_free_all(void); diff --git a/src/or/routerlist.c b/src/or/routerlist.c index 837245db3e..0c978e9d00 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -54,8 +54,6 @@ static const routerstatus_t *router_pick_dirserver_generic( smartlist_t *sourcelist, dirinfo_type_t type, int flags); static void mark_all_dirservers_up(smartlist_t *server_list); -static int router_nickname_matches(const routerinfo_t *router, - const char *nickname); static void dir_server_free(dir_server_t *ds); static int signed_desc_digest_is_recognized(signed_descriptor_t *desc); static const char *signed_descriptor_get_body_impl( @@ -339,7 +337,6 @@ trusted_dirs_remove_old_certs(void) time_t now = time(NULL); #define DEAD_CERT_LIFETIME (2*24*60*60) #define OLD_CERT_LIFETIME (7*24*60*60) -#define CERT_EXPIRY_SKEW (60*60) if (!trusted_dir_certs) return; @@ -1465,30 +1462,6 @@ routerlist_add_node_and_family(smartlist_t *sl, const routerinfo_t *router) nodelist_add_node_and_family(sl, node); } -/** Return 1 iff any member of the (possibly NULL) comma-separated list - * <b>list</b> is an acceptable nickname or hexdigest for <b>router</b>. Else - * return 0. - */ -int -router_nickname_is_in_list(const routerinfo_t *router, const char *list) -{ - smartlist_t *nickname_list; - int v = 0; - - if (!list) - return 0; /* definitely not */ - tor_assert(router); - - nickname_list = smartlist_new(); - smartlist_split_string(nickname_list, list, ",", - SPLIT_SKIP_SPACE|SPLIT_STRIP_SPACE|SPLIT_IGNORE_BLANK, 0); - SMARTLIST_FOREACH(nickname_list, const char *, cp, - if (router_nickname_matches(router, cp)) {v=1;break;}); - SMARTLIST_FOREACH(nickname_list, char *, cp, tor_free(cp)); - smartlist_free(nickname_list); - return v; -} - /** Add every suitable node from our nodelist to <b>sl</b>, so that * we can pick a node for a circuit. */ @@ -2315,18 +2288,6 @@ router_hex_digest_matches(const routerinfo_t *router, const char *hexdigest) router_is_named(router)); } -/** Return true if <b>router</b>'s nickname matches <b>nickname</b> - * (case-insensitive), or if <b>router's</b> identity key digest - * matches a hexadecimal value stored in <b>nickname</b>. Return - * false otherwise. */ -static int -router_nickname_matches(const routerinfo_t *router, const char *nickname) -{ - if (nickname[0]!='$' && !strcasecmp(router->nickname, nickname)) - return 1; - return router_hex_digest_matches(router, nickname); -} - /** Return true iff <b>digest</b> is the digest of the identity key of a * trusted directory matching at least one bit of <b>type</b>. If <b>type</b> * is zero, any authority is okay. */ @@ -3954,7 +3915,8 @@ trusted_dir_server_new(const char *nickname, const char *address, dir_server_t *result; if (!address) { /* The address is us; we should guess. */ - if (resolve_my_address(LOG_WARN, get_options(), &a, NULL, &hostname) < 0) { + if (resolve_my_address(LOG_WARN, get_options(), + &a, NULL, &hostname) < 0) { log_warn(LD_CONFIG, "Couldn't find a suitable address when adding ourself as a " "trusted directory server."); @@ -4054,17 +4016,6 @@ clear_dir_servers(void) router_dir_info_changed(); } -/** Return 1 if any trusted dir server supports v1 directories, - * else return 0. */ -int -any_trusted_dir_is_v1_authority(void) -{ - if (trusted_dir_servers) - return get_n_authorities(V1_DIRINFO) > 0; - - return 0; -} - /** For every current directory connection whose purpose is <b>purpose</b>, * and where the resource being downloaded begins with <b>prefix</b>, split * rest of the resource into base16 fingerprints (or base64 fingerprints if diff --git a/src/or/routerlist.h b/src/or/routerlist.h index 1849fff31c..28b2f58935 100644 --- a/src/or/routerlist.h +++ b/src/or/routerlist.h @@ -42,7 +42,6 @@ int router_get_my_share_of_directory_requests(double *v2_share_out, double *v3_share_out); void router_reset_status_download_failures(void); int routers_have_same_or_addrs(const routerinfo_t *r1, const routerinfo_t *r2); -int router_nickname_is_in_list(const routerinfo_t *router, const char *list); const routerinfo_t *routerlist_find_my_routerinfo(void); uint32_t router_get_advertised_bandwidth(const routerinfo_t *router); uint32_t router_get_advertised_bandwidth_capped(const routerinfo_t *router); @@ -146,7 +145,6 @@ void dir_server_add(dir_server_t *ent); void authority_cert_free(authority_cert_t *cert); void clear_dir_servers(void); -int any_trusted_dir_is_v1_authority(void); void update_consensus_router_descriptor_downloads(time_t now, int is_vote, networkstatus_t *consensus); void update_router_descriptor_downloads(time_t now); diff --git a/src/or/routerparse.c b/src/or/routerparse.c index 2a3de12c35..b86864b5ee 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -1953,7 +1953,7 @@ routerstatus_parse_entry_from_string(memarea_t *area, rs->version_supports_optimistic_data = tor_version_as_new_as(tok->args[0], "0.2.3.1-alpha"); rs->version_supports_extend2_cells = - tor_version_as_new_as(tok->args[0], "0.2.4.7-alpha"); + tor_version_as_new_as(tok->args[0], "0.2.4.8-alpha"); } if (vote_rs) { vote_rs->version = tor_strdup(tok->args[0]); @@ -1974,9 +1974,9 @@ routerstatus_parse_entry_from_string(memarea_t *area, goto err; } rs->has_bandwidth = 1; - } else if (!strcmpstart(tok->args[i], "Measured=")) { + } else if (!strcmpstart(tok->args[i], "Measured=") && vote_rs) { int ok; - rs->measured_bw = + vote_rs->measured_bw = (uint32_t)tor_parse_ulong(strchr(tok->args[i], '=')+1, 10, 0, UINT32_MAX, &ok, NULL); if (!ok) { @@ -1984,7 +1984,10 @@ routerstatus_parse_entry_from_string(memarea_t *area, escaped(tok->args[i])); goto err; } - rs->has_measured_bw = 1; + vote_rs->has_measured_bw = 1; + vote->has_measured_bws = 1; + } else if (!strcmpstart(tok->args[i], "Unmeasured=1")) { + rs->bw_is_unmeasured = 1; } } } @@ -2062,6 +2065,14 @@ compare_routerstatus_entries(const void **_a, const void **_b) return fast_memcmp(a->identity_digest, b->identity_digest, DIGEST_LEN); } +int +compare_vote_routerstatus_entries(const void **_a, const void **_b) +{ + const vote_routerstatus_t *a = *_a, *b = *_b; + return fast_memcmp(a->status.identity_digest, b->status.identity_digest, + DIGEST_LEN); +} + /** Helper: used in call to _smartlist_uniq to clear out duplicate entries. */ static void free_duplicate_routerstatus_entry_(void *e) diff --git a/src/or/routerparse.h b/src/or/routerparse.h index 4cc9bfd3ae..859a691e2a 100644 --- a/src/or/routerparse.h +++ b/src/or/routerparse.h @@ -52,6 +52,7 @@ void assert_addr_policy_ok(smartlist_t *t); void dump_distinct_digest_count(int severity); int compare_routerstatus_entries(const void **_a, const void **_b); +int compare_vote_routerstatus_entries(const void **_a, const void **_b); networkstatus_v2_t *networkstatus_v2_parse_from_string(const char *s); int networkstatus_verify_bw_weights(networkstatus_t *ns); networkstatus_t *networkstatus_parse_vote_from_string(const char *s, diff --git a/src/or/routerset.c b/src/or/routerset.c index 1eca5b6f6f..2e41f7f6c4 100644 --- a/src/or/routerset.c +++ b/src/or/routerset.c @@ -141,7 +141,7 @@ routerset_parse(routerset_t *target, const char *s, const char *description) log_debug(LD_CONFIG, "Adding address %s to %s", nick, description); smartlist_add(target->policies, p); } else { - log_warn(LD_CONFIG, "Entry '%s' in %s is misformed.", nick, + log_warn(LD_CONFIG, "Entry '%s' in %s is malformed.", nick, description); r = -1; tor_free(nick); diff --git a/src/or/tor_main.c b/src/or/tor_main.c index 806b5ebb38..05dc0bf0bf 100644 --- a/src/or/tor_main.c +++ b/src/or/tor_main.c @@ -3,9 +3,9 @@ * Copyright (c) 2007-2013, The Tor Project, Inc. */ /* See LICENSE for licensing information */ -/** String describing which Tor subversion repository version the source was - * built from. This string is generated by a bit of shell kludging int - * src/or/Makefile.am, and is usually right. +/** String describing which Tor Git repository version the source was + * built from. This string is generated by a bit of shell kludging in + * src/or/include.am, and is usually right. */ const char tor_git_revision[] = #ifndef _MSC_VER diff --git a/src/or/transports.c b/src/or/transports.c index 647b293168..b5a00c90ec 100644 --- a/src/or/transports.c +++ b/src/or/transports.c @@ -124,10 +124,6 @@ static INLINE void free_execve_args(char **arg); #define PROTO_CMETHODS_DONE "CMETHODS DONE" #define PROTO_SMETHODS_DONE "SMETHODS DONE" -/** Number of environment variables for managed proxy clients/servers. */ -#define ENVIRON_SIZE_CLIENT 3 -#define ENVIRON_SIZE_SERVER 7 /* XXX known to be too high, but that's ok */ - /** The first and only supported - at the moment - configuration protocol version. */ #define PROTO_VERSION_ONE 1 @@ -339,12 +335,12 @@ transport_add_from_config(const tor_addr_t *addr, uint16_t port, transport_free(t); return -1; case 1: - log_info(LD_GENERAL, "Succesfully registered transport %s at %s.", + log_info(LD_GENERAL, "Successfully registered transport %s at %s.", t->name, fmt_addrport(&t->addr, t->port)); transport_free(t); /* falling */ return 0; case 0: - log_info(LD_GENERAL, "Succesfully registered transport %s at %s.", + log_info(LD_GENERAL, "Successfully registered transport %s at %s.", t->name, fmt_addrport(&t->addr, t->port)); return 0; } @@ -676,10 +672,10 @@ register_client_proxy(const managed_proxy_t *mp) transport_free(transport_tmp); break; case 0: - log_info(LD_GENERAL, "Succesfully registered transport %s", t->name); + log_info(LD_GENERAL, "Successfully registered transport %s", t->name); break; case 1: - log_info(LD_GENERAL, "Succesfully registered transport %s", t->name); + log_info(LD_GENERAL, "Successfully registered transport %s", t->name); transport_free(transport_tmp); break; } |