diff options
Diffstat (limited to 'src/or')
38 files changed, 620 insertions, 321 deletions
diff --git a/src/or/channel.c b/src/or/channel.c index f8afc405e6..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); } diff --git a/src/or/channeltls.c b/src/or/channeltls.c index 1035a14127..60693daeb2 100644 --- a/src/or/channeltls.c +++ b/src/or/channeltls.c @@ -1208,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; diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index 5097f19e9d..8e768e76f5 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -523,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)); @@ -3398,6 +3398,7 @@ choose_good_entry_server(uint8_t purpose, cpath_build_state_t *state) }); } /* and exclude current entry guards and their families, if applicable */ + /*XXXX025 use the using_as_guard flag to accomplish this.*/ if (options->UseEntryGuards) { SMARTLIST_FOREACH(get_entry_guards(), const entry_guard_t *, entry, { diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c index d1720b983d..6c7629c7ba 100644 --- a/src/or/circuitlist.c +++ b/src/or/circuitlist.c @@ -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 7ee58fc5fe..4d1065bbd8 100644 --- a/src/or/circuituse.c +++ b/src/or/circuituse.c @@ -699,9 +699,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; @@ -717,9 +717,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; @@ -732,7 +732,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, @@ -741,7 +741,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); @@ -1081,9 +1082,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 */ @@ -1164,8 +1166,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); } @@ -1907,8 +1909,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; @@ -2132,8 +2134,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); @@ -2158,7 +2160,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 @@ -2179,9 +2181,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; } @@ -2193,10 +2195,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; } @@ -2206,16 +2208,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 */ @@ -2239,10 +2242,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 dfe4f65916..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()) { @@ -240,8 +239,8 @@ command_process_create_cell(cell_t *cell, channel_t *chan) (!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; @@ -250,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, @@ -341,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; } @@ -412,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; } @@ -447,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; @@ -487,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 c98c81a00c..0ebf3b6942 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), @@ -299,6 +300,7 @@ static config_var_t option_vars_[] = { V(MaxClientCircuitsPending, UINT, "32"), OBSOLETE("MaxOnionsPending"), V(MaxOnionQueueDelay, MSEC_INTERVAL, "1750 msec"), + V(MinMeasuredBWsForAuthToIgnoreAdvertised, INT, "500"), OBSOLETE("MonthlyAccountingStart"), V(MyFamily, STRING, NULL), V(NewCircuitPeriod, INTERVAL, "30 seconds"), @@ -379,6 +381,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"), @@ -2379,6 +2382,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); @@ -2595,9 +2602,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/connection.c b/src/or/connection.c index c659e65fe5..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); diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 76c5f6a9f4..9c39c25219 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); @@ -1843,8 +1843,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 */ @@ -1939,13 +1939,14 @@ connection_ap_handshake_send_resolve(entry_connection_t *ap_conn) string_addr, payload_len) < 0) return -1; /* circuit is closed, don't continue */ - tor_free(base_conn->address); /* Maybe already set by dnsserv. */ - base_conn->address = tor_strdup("(Tor_internal)"); + if (!base_conn->address) { + /* This might be unnecessary. XXXX */ + base_conn->address = tor_dup_addr(&base_conn->addr); + } 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); - control_event_stream_status(ap_conn, STREAM_EVENT_NEW, 0); + ", n_circ_id %u", + base_conn->s, (unsigned)circ->base_.n_circ_id); control_event_stream_status(ap_conn, STREAM_EVENT_SENT_RESOLVE, 0); return 0; } @@ -2195,9 +2196,11 @@ connection_ap_handshake_socks_reply(entry_connection_t *conn, char *reply, tor_assert(conn->socks_request); /* make sure it's an AP stream */ - control_event_stream_status(conn, - status==SOCKS5_SUCCEEDED ? STREAM_EVENT_SUCCEEDED : STREAM_EVENT_FAILED, - endreason); + if (!SOCKS_COMMAND_IS_RESOLVE(conn->socks_request->command)) { + control_event_stream_status(conn, status==SOCKS5_SUCCEEDED ? + STREAM_EVENT_SUCCEEDED : STREAM_EVENT_FAILED, + endreason); + } /* Flag this stream's circuit as having completed a stream successfully * (for path bias) */ diff --git a/src/or/connection_or.c b/src/or/connection_or.c index c4415c5f88..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" /* diff --git a/src/or/control.c b/src/or/control.c index 03e5d79c8e..2a68464189 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -2939,7 +2939,7 @@ handle_control_resolve(control_connection_t *conn, uint32_t len, failed = smartlist_new(); SMARTLIST_FOREACH(args, const char *, arg, { if (!is_keyval_pair(arg)) { - if (dnsserv_launch_request(arg, is_reverse)<0) + if (dnsserv_launch_request(arg, is_reverse, conn)<0) smartlist_add(failed, (char*)arg); } }); @@ -3742,7 +3742,7 @@ control_event_stream_status(entry_connection_t *conn, stream_status_event_t tp, } } - if (tp == STREAM_EVENT_NEW) { + if (tp == STREAM_EVENT_NEW || tp == STREAM_EVENT_NEW_RESOLVE) { tor_snprintf(addrport_buf,sizeof(addrport_buf), " SOURCE_ADDR=%s:%d", ENTRY_TO_CONN(conn)->address, ENTRY_TO_CONN(conn)->port); } else { @@ -3752,11 +3752,7 @@ control_event_stream_status(entry_connection_t *conn, stream_status_event_t tp, if (tp == STREAM_EVENT_NEW_RESOLVE) { purpose = " PURPOSE=DNS_REQUEST"; } else if (tp == STREAM_EVENT_NEW) { - if (ENTRY_TO_EDGE_CONN(conn)->is_dns_request || - (conn->socks_request && - SOCKS_COMMAND_IS_RESOLVE(conn->socks_request->command))) - purpose = " PURPOSE=DNS_REQUEST"; - else if (conn->use_begindir) { + if (conn->use_begindir) { connection_t *linked = ENTRY_TO_CONN(conn)->linked_conn; int linked_dir_purpose = -1; if (linked && linked->type == CONN_TYPE_DIR) diff --git a/src/or/cpuworker.c b/src/or/cpuworker.c index af5f91a623..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" @@ -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 6b61fc6a99..38a423cb8e 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -2805,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 badacd683d..8e8f79a171 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -66,6 +66,13 @@ static cached_dir_t *the_directory = NULL; /** For authoritative directories: the current (v1) network status. */ static cached_dir_t the_runningrouters; +/** Total number of routers with measured bandwidth; this is set by + * dirserv_count_measured_bws() before the loop in + * dirserv_generate_networkstatus_vote_obj() and checked by + * dirserv_get_credible_bandwidth() and + * dirserv_compute_performance_thresholds() */ +static int routers_with_measured_bw = 0; + static void directory_remove_invalid(void); static cached_dir_t *dirserv_regenerate_directory(void); static char *format_versions_list(config_line_t *ln); @@ -85,9 +92,8 @@ static const signed_descriptor_t *get_signed_descriptor_by_fp( time_t publish_cutoff); static was_router_added_t dirserv_add_extrainfo(extrainfo_t *ei, const char **msg); - -/************** Measured Bandwidth parsing code ******/ -#define MAX_MEASUREMENT_AGE (3*24*60*60) /* 3 days */ +static uint32_t dirserv_get_bandwidth_for_router(const routerinfo_t *ri); +static uint32_t dirserv_get_credible_bandwidth(const routerinfo_t *ri); /************** Fingerprint handling code ************/ @@ -1824,7 +1830,7 @@ dirserv_thinks_router_is_unreliable(time_t now, } } if (need_capacity) { - uint32_t bw = router_get_advertised_bandwidth(router); + uint32_t bw = dirserv_get_bandwidth_for_router(router); if (bw < fast_bandwidth) return 1; } @@ -1876,15 +1882,23 @@ dirserv_thinks_router_is_hs_dir(const routerinfo_t *router, #define ABSOLUTE_MIN_BW_VALUE_TO_CONSIDER 4096 /** Helper for dirserv_compute_performance_thresholds(): Decide whether to - * include a router in our calculations, and return true iff we should. */ + * include a router in our calculations, and return true iff we should; the + * require_mbw parameter is passed in by + * dirserv_compute_performance_thresholds() and controls whether we ever + * count routers with only advertised bandwidths */ static int router_counts_toward_thresholds(const node_t *node, time_t now, - const digestmap_t *omit_as_sybil) + const digestmap_t *omit_as_sybil, + int require_mbw) { + /* Have measured bw? */ + int have_mbw = + dirserv_has_measured_bw(node->ri->cache_info.identity_digest); + return node->ri && router_is_active(node->ri, node, now) && !digestmap_get(omit_as_sybil, node->ri->cache_info.identity_digest) && - (router_get_advertised_bandwidth(node->ri) >= - ABSOLUTE_MIN_BW_VALUE_TO_CONSIDER); + (dirserv_get_credible_bandwidth(node->ri) >= + ABSOLUTE_MIN_BW_VALUE_TO_CONSIDER) && (have_mbw || !require_mbw); } /** Look through the routerlist, the Mean Time Between Failure history, and @@ -1906,6 +1920,11 @@ dirserv_compute_performance_thresholds(routerlist_t *rl, time_t now = time(NULL); const or_options_t *options = get_options(); + /* Require mbw? */ + int require_mbw = + (routers_with_measured_bw > + options->MinMeasuredBWsForAuthToIgnoreAdvertised) ? 1 : 0; + /* initialize these all here, in case there are no routers */ stable_uptime = 0; stable_mtbf = 0; @@ -1938,7 +1957,8 @@ dirserv_compute_performance_thresholds(routerlist_t *rl, /* Now, fill in the arrays. */ SMARTLIST_FOREACH_BEGIN(nodelist_get_list(), node_t *, node) { - if (router_counts_toward_thresholds(node, now, omit_as_sybil)) { + if (router_counts_toward_thresholds(node, now, omit_as_sybil, + require_mbw)) { routerinfo_t *ri = node->ri; const char *id = ri->cache_info.identity_digest; uint32_t bw; @@ -1947,7 +1967,7 @@ dirserv_compute_performance_thresholds(routerlist_t *rl, uptimes[n_active] = (uint32_t)real_uptime(ri, now); mtbfs[n_active] = rep_hist_get_stability(id, now); tks [n_active] = rep_hist_get_weighted_time_known(id, now); - bandwidths[n_active] = bw = router_get_advertised_bandwidth(ri); + bandwidths[n_active] = bw = dirserv_get_credible_bandwidth(ri); total_bandwidth += bw; if (node->is_exit && !node->is_bad_exit) { total_exit_bandwidth += bw; @@ -2003,7 +2023,8 @@ dirserv_compute_performance_thresholds(routerlist_t *rl, n_familiar = 0; SMARTLIST_FOREACH_BEGIN(nodelist_get_list(), node_t *, node) { - if (router_counts_toward_thresholds(node, now, omit_as_sybil)) { + if (router_counts_toward_thresholds(node, now, + omit_as_sybil, require_mbw)) { routerinfo_t *ri = node->ri; const char *id = ri->cache_info.identity_digest; long tk = rep_hist_get_weighted_time_known(id, now); @@ -2046,6 +2067,203 @@ dirserv_compute_performance_thresholds(routerlist_t *rl, tor_free(wfus); } +/** Measured bandwidth cache entry */ +typedef struct mbw_cache_entry_s { + long mbw; + time_t as_of; +} mbw_cache_entry_t; + +/** Measured bandwidth cache - keys are identity_digests, values are + * mbw_cache_entry_t *. */ +static digestmap_t *mbw_cache = NULL; + +/** Store a measured bandwidth cache entry when reading the measured + * bandwidths file. */ +void +dirserv_cache_measured_bw(const measured_bw_line_t *parsed_line, + time_t as_of) +{ + mbw_cache_entry_t *e = NULL; + + tor_assert(parsed_line); + + /* Allocate a cache if we need */ + if (!mbw_cache) mbw_cache = digestmap_new(); + + /* Check if we have an existing entry */ + e = digestmap_get(mbw_cache, parsed_line->node_id); + /* If we do, we can re-use it */ + if (e) { + /* Check that we really are newer, and update */ + if (as_of > e->as_of) { + e->mbw = parsed_line->bw; + e->as_of = as_of; + } + } else { + /* We'll have to insert a new entry */ + e = tor_malloc(sizeof(*e)); + e->mbw = parsed_line->bw; + e->as_of = as_of; + digestmap_set(mbw_cache, parsed_line->node_id, e); + } +} + +/** Clear and free the measured bandwidth cache */ +void +dirserv_clear_measured_bw_cache(void) +{ + if (mbw_cache) { + /* Free the map and all entries */ + digestmap_free(mbw_cache, tor_free_); + mbw_cache = NULL; + } +} + +/** Scan the measured bandwidth cache and remove expired entries */ +void +dirserv_expire_measured_bw_cache(time_t now) +{ + + if (mbw_cache) { + /* Iterate through the cache and check each entry */ + DIGESTMAP_FOREACH_MODIFY(mbw_cache, k, mbw_cache_entry_t *, e) { + if (now > e->as_of + MAX_MEASUREMENT_AGE) { + tor_free(e); + MAP_DEL_CURRENT(k); + } + } DIGESTMAP_FOREACH_END; + + /* Check if we cleared the whole thing and free if so */ + if (digestmap_size(mbw_cache) == 0) { + digestmap_free(mbw_cache, tor_free_); + mbw_cache = 0; + } + } +} + +/** Get the current size of the measured bandwidth cache */ +int +dirserv_get_measured_bw_cache_size(void) +{ + if (mbw_cache) return digestmap_size(mbw_cache); + else return 0; +} + +/** Query the cache by identity digest, return value indicates whether + * we found it. The bw_out and as_of_out pointers receive the cached + * bandwidth value and the time it was cached if not NULL. */ +int +dirserv_query_measured_bw_cache(const char *node_id, long *bw_out, + time_t *as_of_out) +{ + mbw_cache_entry_t *v = NULL; + int rv = 0; + + if (mbw_cache && node_id) { + v = digestmap_get(mbw_cache, node_id); + if (v) { + /* Found something */ + rv = 1; + if (bw_out) *bw_out = v->mbw; + if (as_of_out) *as_of_out = v->as_of; + } + } + + return rv; +} + +/** Predicate wrapper for dirserv_query_measured_bw_cache() */ +int +dirserv_has_measured_bw(const char *node_id) +{ + return dirserv_query_measured_bw_cache(node_id, NULL, NULL); +} + +/** Get the best estimate of a router's bandwidth for dirauth purposes, + * preferring measured to advertised values if available. */ + +static uint32_t +dirserv_get_bandwidth_for_router(const routerinfo_t *ri) +{ + uint32_t bw = 0; + /* + * Yeah, measured bandwidths in measured_bw_line_t are (implicitly + * signed) longs and the ones router_get_advertised_bandwidth() returns + * are uint32_t. + */ + long mbw = 0; + + if (ri) { + /* + * * First try to see if we have a measured bandwidth; don't bother with + * as_of_out here, on the theory that a stale measured bandwidth is still + * better to trust than an advertised one. + */ + if (dirserv_query_measured_bw_cache(ri->cache_info.identity_digest, + &mbw, NULL)) { + /* Got one! */ + bw = (uint32_t)mbw; + } else { + /* If not, fall back to advertised */ + bw = router_get_advertised_bandwidth(ri); + } + } + + return bw; +} + +/** Look through the routerlist, and using the measured bandwidth cache count + * how many measured bandwidths we know. This is used to decide whether we + * ever trust advertised bandwidths for purposes of assigning flags. */ +static void +dirserv_count_measured_bws(routerlist_t *rl) +{ + /* Initialize this first */ + routers_with_measured_bw = 0; + + tor_assert(rl); + tor_assert(rl->routers); + + /* Iterate over the routerlist and count measured bandwidths */ + SMARTLIST_FOREACH_BEGIN(rl->routers, routerinfo_t *, ri) { + /* Check if we know a measured bandwidth for this one */ + if (dirserv_has_measured_bw(ri->cache_info.identity_digest)) { + ++routers_with_measured_bw; + } + } SMARTLIST_FOREACH_END(ri); +} + +/** Return the bandwidth we believe for assigning flags; prefer measured + * over advertised, and if we have above a threshold quantity of measured + * bandwidths, we don't want to ever give flags to unmeasured routers, so + * return 0. */ +static uint32_t +dirserv_get_credible_bandwidth(const routerinfo_t *ri) +{ + int threshold; + uint32_t bw = 0; + long mbw; + + tor_assert(ri); + /* Check if we have a measured bandwidth, and check the threshold if not */ + if (!(dirserv_query_measured_bw_cache(ri->cache_info.identity_digest, + &mbw, NULL))) { + threshold = get_options()->MinMeasuredBWsForAuthToIgnoreAdvertised; + if (routers_with_measured_bw > threshold) { + /* Return zero for unmeasured bandwidth if we are above threshold */ + bw = 0; + } else { + /* Return an advertised bandwidth otherwise */ + bw = router_get_advertised_bandwidth(ri); + } + } else { + /* We have the measured bandwidth in mbw */ + bw = (uint32_t)mbw; + } + + return bw; +} + /** Give a statement of our current performance thresholds for inclusion * in a vote document. */ char * @@ -2216,9 +2434,10 @@ routerstatus_format_entry(char *buf, size_t buf_len, return -1; } - /* This assert can fire for the control port, because + /* This assert could fire for the control port, because * it can request NS documents before all descriptors - * have been fetched. */ + * have been fetched. Therefore, we only do this test when + * format != NS_CONTROL_PORT. */ if (tor_memneq(desc->cache_info.signed_descriptor_digest, rs->descriptor_digest, DIGEST_LEN)) { @@ -2327,8 +2546,8 @@ compare_routerinfo_by_ip_and_bw_(const void **a, const void **b) else if (!first_is_running && second_is_running) return 1; - bw_first = router_get_advertised_bandwidth(first); - bw_second = router_get_advertised_bandwidth(second); + bw_first = dirserv_get_bandwidth_for_router(first); + bw_second = dirserv_get_bandwidth_for_router(second); if (bw_first > bw_second) return -1; @@ -2468,7 +2687,7 @@ set_routerstatus_from_routerinfo(routerstatus_t *rs, int listbaddirs, int vote_on_hsdirs) { const or_options_t *options = get_options(); - uint32_t routerbw = router_get_advertised_bandwidth(ri); + uint32_t routerbw = dirserv_get_credible_bandwidth(ri); memset(rs, 0, sizeof(routerstatus_t)); @@ -2670,8 +2889,9 @@ dirserv_read_measured_bandwidths(const char *from_file, char line[256]; FILE *fp = tor_fopen_cloexec(from_file, "r"); int applied_lines = 0; - time_t file_time; + time_t file_time, now; int ok; + if (fp == NULL) { log_warn(LD_CONFIG, "Can't open bandwidth file at configured location: %s", from_file); @@ -2695,7 +2915,8 @@ dirserv_read_measured_bandwidths(const char *from_file, return -1; } - if ((time(NULL) - file_time) > MAX_MEASUREMENT_AGE) { + now = time(NULL); + if ((now - file_time) > MAX_MEASUREMENT_AGE) { log_warn(LD_DIRSERV, "Bandwidth measurement file stale. Age: %u", (unsigned)(time(NULL) - file_time)); fclose(fp); @@ -2709,12 +2930,17 @@ dirserv_read_measured_bandwidths(const char *from_file, measured_bw_line_t parsed_line; if (fgets(line, sizeof(line), fp) && strlen(line)) { if (measured_bw_line_parse(&parsed_line, line) != -1) { + /* Also cache the line for dirserv_get_bandwidth_for_router() */ + dirserv_cache_measured_bw(&parsed_line, file_time); if (measured_bw_line_apply(&parsed_line, routerstatuses) > 0) applied_lines++; } } } + /* Now would be a nice time to clean the cache, too */ + dirserv_expire_measured_bw_cache(now); + fclose(fp); log_info(LD_DIRSERV, "Bandwidth measurement file successfully read. " @@ -2778,6 +3004,22 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key, if (!contact) contact = "(none)"; + /* + * Do this so dirserv_compute_performance_thresholds() and + * set_routerstatus_from_routerinfo() see up-to-date bandwidth info. + */ + if (options->V3BandwidthsFile) { + dirserv_read_measured_bandwidths(options->V3BandwidthsFile, NULL); + } else { + /* + * No bandwidths file; clear the measured bandwidth cache in case we had + * one last time around. + */ + if (dirserv_get_measured_bw_cache_size() > 0) { + dirserv_clear_measured_bw_cache(); + } + } + /* precompute this part, since we need it to decide what "stable" * means. */ SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri, { @@ -2794,6 +3036,10 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key, rep_hist_make_router_pessimal(sybil_id, now); } DIGESTMAP_FOREACH_END; + /* Count how many have measured bandwidths so we know how to assign flags; + * this must come before dirserv_compute_performance_thresholds() */ + dirserv_count_measured_bws(rl); + dirserv_compute_performance_thresholds(rl, omit_as_sybil); routerstatuses = smartlist_new(); @@ -2838,9 +3084,18 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key, smartlist_free(routers); digestmap_free(omit_as_sybil, NULL); + /* This pass through applies the measured bw lines to the routerstatuses */ if (options->V3BandwidthsFile) { dirserv_read_measured_bandwidths(options->V3BandwidthsFile, routerstatuses); + } else { + /* + * No bandwidths file; clear the measured bandwidth cache in case we had + * one last time around. + */ + if (dirserv_get_measured_bw_cache_size() > 0) { + dirserv_clear_measured_bw_cache(); + } } v3_out = tor_malloc_zero(sizeof(networkstatus_t)); @@ -3908,5 +4163,7 @@ dirserv_free_all(void) cached_v2_networkstatus = NULL; strmap_free(cached_consensuses, free_cached_dir_); cached_consensuses = NULL; + + dirserv_clear_measured_bw_cache(); } diff --git a/src/or/dirserv.h b/src/or/dirserv.h index 0caf55f830..a84ae964c9 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); @@ -138,10 +137,23 @@ void cached_dir_decref(cached_dir_t *d); cached_dir_t *new_cached_dir(char *s, time_t published); #ifdef DIRSERV_PRIVATE + +/* Put the MAX_MEASUREMENT_AGE #define here so unit tests can see it */ +#define MAX_MEASUREMENT_AGE (3*24*60*60) /* 3 days */ + int measured_bw_line_parse(measured_bw_line_t *out, const char *line); int measured_bw_line_apply(measured_bw_line_t *parsed_line, smartlist_t *routerstatuses); + +void dirserv_cache_measured_bw(const measured_bw_line_t *parsed_line, + time_t as_of); +void dirserv_clear_measured_bw_cache(void); +void dirserv_expire_measured_bw_cache(time_t now); +int dirserv_get_measured_bw_cache_size(void); +int dirserv_query_measured_bw_cache(const char *node_id, long *bw_out, + time_t *as_of_out); +int dirserv_has_measured_bw(const char *node_id); #endif int dirserv_read_measured_bandwidths(const char *from_file, diff --git a/src/or/dnsserv.c b/src/or/dnsserv.c index 7032b58145..a1275cf2b3 100644 --- a/src/or/dnsserv.c +++ b/src/or/dnsserv.c @@ -147,7 +147,7 @@ evdns_server_callback(struct evdns_server_request *req, void *data_) return; } - control_event_stream_status(entry_conn, STREAM_EVENT_NEW, 0); + control_event_stream_status(entry_conn, STREAM_EVENT_NEW_RESOLVE, 0); /* Now, unless a controller asked us to leave streams unattached, * throw the connection over to get rewritten (which will @@ -170,7 +170,8 @@ evdns_server_callback(struct evdns_server_request *req, void *data_) * response; -1 if we couldn't launch the request. */ int -dnsserv_launch_request(const char *name, int reverse) +dnsserv_launch_request(const char *name, int reverse, + control_connection_t *control_conn) { entry_connection_t *entry_conn; edge_connection_t *conn; @@ -181,6 +182,10 @@ dnsserv_launch_request(const char *name, int reverse) conn = ENTRY_TO_EDGE_CONN(entry_conn); conn->base_.state = AP_CONN_STATE_RESOLVE_WAIT; + tor_addr_copy(&TO_CONN(conn)->addr, &control_conn->base_.addr); + TO_CONN(conn)->port = control_conn->base_.port; + TO_CONN(conn)->address = tor_dup_addr(&control_conn->base_.addr); + if (reverse) entry_conn->socks_request->command = SOCKS_COMMAND_RESOLVE_PTR; else @@ -203,6 +208,8 @@ dnsserv_launch_request(const char *name, int reverse) return -1; } + control_event_stream_status(entry_conn, STREAM_EVENT_NEW_RESOLVE, 0); + /* Now, unless a controller asked us to leave streams unattached, * throw the connection over to get rewritten (which will * answer it immediately if it's in the cache, or completely bogus, or diff --git a/src/or/dnsserv.h b/src/or/dnsserv.h index 6bdb98de70..687a77e59e 100644 --- a/src/or/dnsserv.h +++ b/src/or/dnsserv.h @@ -20,7 +20,8 @@ void dnsserv_resolved(entry_connection_t *conn, const char *answer, int ttl); void dnsserv_reject_request(entry_connection_t *conn); -int dnsserv_launch_request(const char *name, int is_reverse); +int dnsserv_launch_request(const char *name, int is_reverse, + control_connection_t *control_conn); #endif diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c index 51c3a56742..e92c0c166d 100644 --- a/src/or/entrynodes.c +++ b/src/or/entrynodes.c @@ -133,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; @@ -354,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) { @@ -363,13 +367,22 @@ add_an_entry_guard(const node_t *chosen, int reset_status, int prepend, } else { const routerstatus_t *rs; rs = router_pick_directory_server(MICRODESC_DIRINFO|V3_DIRINFO, - PDS_PREFER_TUNNELED_DIR_CONNS_); + PDS_PREFER_TUNNELED_DIR_CONNS_|PDS_FOR_GUARD); if (!rs) return NULL; node = node_get_by_id(rs->identity_digest); if (!node) return NULL; } + if (node->using_as_guard) + return NULL; + if (entry_guard_get_by_id_digest(node->identity) != NULL) { + log_info(LD_CIRC, "I was about to add a duplicate entry guard."); + /* This can happen if we choose a guard, then the node goes away, then + * comes back. */ + ((node_t*) node)->using_as_guard = 1; + return NULL; + } entry = tor_malloc_zero(sizeof(entry_guard_t)); log_info(LD_CIRC, "Chose %s as new entry guard.", node_describe(node)); @@ -377,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 @@ -385,6 +400,7 @@ add_an_entry_guard(const node_t *chosen, int reset_status, int prepend, * this guard. For details, see the Jan 2010 or-dev thread. */ entry->chosen_on_date = time(NULL) - crypto_rand_int(3600*24*30); entry->chosen_by_version = tor_strdup(VERSION); + ((node_t*)node)->using_as_guard = 1; if (prepend) smartlist_insert(entry_guards, 0, entry); else @@ -724,6 +740,21 @@ entry_nodes_should_be_added(void) should_add_entry_nodes = 1; } +/** Update the using_as_guard fields of all the nodes. We do this after we + * remove entry guards from the list: This is the only function that clears + * the using_as_guard field. */ +static void +update_node_guard_status(void) +{ + smartlist_t *nodes = nodelist_get_list(); + SMARTLIST_FOREACH(nodes, node_t *, node, node->using_as_guard = 0); + SMARTLIST_FOREACH_BEGIN(entry_guards, entry_guard_t *, entry) { + node_t *node = node_get_mutable_by_id(entry->identity); + if (node) + node->using_as_guard = 1; + } SMARTLIST_FOREACH_END(entry); +} + /** Adjust the entry guards list so that it only contains entries from * EntryNodes, adding new entries from EntryNodes to the list as needed. */ static void @@ -808,6 +839,8 @@ entry_guards_set_from_config(const or_options_t *options) SMARTLIST_FOREACH(old_entry_guards_not_on_list, entry_guard_t *, e, entry_guard_free(e)); + update_node_guard_status(); + smartlist_free(entry_nodes); smartlist_free(worse_entry_nodes); smartlist_free(entry_fps); @@ -1263,6 +1296,8 @@ entry_guards_parse_state(or_state_t *state, int set, char **msg) * few lines, so we don't have to re-dirty it */ if (remove_obsolete_entry_guards(now)) entry_guards_dirty = 1; + + update_node_guard_status(); } digestmap_free(added_by, tor_free_); return *msg ? -1 : 0; 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 5add6a0552..fd8b6cf674 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. diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c index c63c76fccd..8846cd0634 100644 --- a/src/or/networkstatus.c +++ b/src/or/networkstatus.c @@ -1432,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 * diff --git a/src/or/networkstatus.h b/src/or/networkstatus.h index b64e4b8e1a..761f8e7f0e 100644 --- a/src/or/networkstatus.h +++ b/src/or/networkstatus.h @@ -75,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 e5c60452fc..08b32d5ec3 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. */ @@ -1419,8 +1417,8 @@ typedef struct or_connection_t { 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." */ + uint16_t link_proto; /**< What protocol version are we using? 0 for + * "none negotiated yet." */ or_handshake_state_t *handshake_state; /**< If we are setting this connection * up, state information to do so. */ @@ -2251,6 +2249,9 @@ typedef struct node_t { /** Local info: we treat this node as if it rejects everything */ unsigned int rejects_all:1; + /** Local info: this node is in our list of guards */ + unsigned int using_as_guard:1; + /* Local info: derived. */ /** True if the IPv6 OR port is preferred over the IPv4 OR port. */ @@ -3874,6 +3875,10 @@ typedef struct { * consensus vote on the 'params' line. */ char *ConsensusParams; + /** Authority only: minimum number of measured bandwidths we must see + * before we only beliee measured bandwidths to assign flags. */ + int MinMeasuredBWsForAuthToIgnoreAdvertised; + /** The length of time that we think an initial consensus should be fresh. * Only altered on testing networks. */ int TestingV3AuthInitialVotingInterval; @@ -4003,6 +4008,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. */ @@ -4456,15 +4476,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. @@ -4784,6 +4795,10 @@ typedef struct dir_server_t { #define PDS_NO_EXISTING_SERVERDESC_FETCH (1<<3) #define PDS_NO_EXISTING_MICRODESC_FETCH (1<<4) +/** This node is to be chosen as a directory guard, so don't choose any + * node that's currently a guard. */ +#define PDS_FOR_GUARD (1<<5) + #define PDS_PREFER_TUNNELED_DIR_CONNS_ (1<<16) /** Possible ways to weight routers when choosing one randomly. See diff --git a/src/or/relay.c b/src/or/relay.c index fb15141ef5..ef37c32810 100644 --- a/src/or/relay.c +++ b/src/or/relay.c @@ -1397,6 +1397,14 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, "'truncate' unsupported at origin. Dropping."); return 0; } + if (circ->n_hop) { + if (circ->n_chan) + log_warn(LD_BUG, "n_chan and n_hop set on the same circuit!"); + extend_info_free(circ->n_hop); + circ->n_hop = NULL; + tor_free(circ->n_chan_create_cell); + circuit_set_state(circ, CIRCUIT_STATE_OPEN); + } if (circ->n_chan) { uint8_t trunc_reason = get_uint8(cell->payload + RELAY_HEADER_SIZE); circuit_clear_cell_queue(circ, circ->n_chan); 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 a066e02024..a8f63ddf66 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -1126,8 +1126,8 @@ rend_service_introduce(origin_circuit_t *circuit, const uint8_t *request, /* 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; } @@ -1161,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; @@ -1177,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); } @@ -1187,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); } @@ -1223,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); } @@ -1233,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); } @@ -1243,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; @@ -1393,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); @@ -2417,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; } @@ -2461,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; @@ -2496,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; } @@ -2539,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); @@ -2549,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 */ @@ -2597,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 @@ -3339,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/router.c b/src/or/router.c index 95aa70a9c4..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. @@ -2966,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 2f08167f18..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; @@ -1153,6 +1150,7 @@ router_pick_directory_server_impl(dirinfo_type_t type, int flags) int requireother = ! (flags & PDS_ALLOW_SELF); int fascistfirewall = ! (flags & PDS_IGNORE_FASCISTFIREWALL); int prefer_tunnel = (flags & PDS_PREFER_TUNNELED_DIR_CONNS_); + int for_guard = (flags & PDS_FOR_GUARD); int try_excluding = 1, n_excluded = 0; if (!consensus) @@ -1192,6 +1190,8 @@ router_pick_directory_server_impl(dirinfo_type_t type, int flags) if ((type & MICRODESC_DIRINFO) && !is_trusted && !node->rs->version_supports_microdesc_cache) continue; + if (for_guard && node->using_as_guard) + continue; /* Don't make the same node a guard twice. */ if (try_excluding && routerset_contains_routerstatus(options->ExcludeNodes, status, country)) { @@ -1462,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. */ @@ -2312,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. */ @@ -4052,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 ce2cd5c513..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]); 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; } |