diff options
Diffstat (limited to 'src/or')
35 files changed, 328 insertions, 292 deletions
diff --git a/src/or/buffers.c b/src/or/buffers.c index e54751db2..033f86288 100644 --- a/src/or/buffers.c +++ b/src/or/buffers.c @@ -62,25 +62,8 @@ static int parse_socks_client(const uint8_t *data, size_t datalen, int state, char **reason, ssize_t *drain_out); -#define DEBUG_CHUNK_ALLOC - /* Chunk manipulation functions */ -/** A single chunk on a buffer or in a freelist. */ -typedef struct chunk_t { - struct chunk_t *next; /**< The next chunk on the buffer or freelist. */ - size_t datalen; /**< The number of bytes stored in this chunk */ - size_t memlen; /**< The number of usable bytes of storage in <b>mem</b>. */ -#ifdef DEBUG_CHUNK_ALLOC - size_t DBG_alloc; -#endif - char *data; /**< A pointer to the first byte of data stored in <b>mem</b>. */ - uint32_t inserted_time; /**< Timestamp in truncated ms since epoch - * when this chunk was inserted. */ - char mem[FLEXIBLE_ARRAY_MEMBER]; /**< The actual memory used for storage in - * this chunk. */ -} chunk_t; - #define CHUNK_HEADER_LEN STRUCT_OFFSET(chunk_t, mem[0]) /** Return the number of bytes needed to allocate a chunk to hold @@ -407,19 +390,6 @@ buf_dump_freelist_sizes(int severity) #endif } -/** Magic value for buf_t.magic, to catch pointer errors. */ -#define BUFFER_MAGIC 0xB0FFF312u -/** A resizeable buffer, optimized for reading and writing. */ -struct buf_t { - uint32_t magic; /**< Magic cookie for debugging: Must be set to - * BUFFER_MAGIC. */ - size_t datalen; /**< How many bytes is this buffer holding right now? */ - size_t default_chunk_size; /**< Don't allocate any chunks smaller than - * this for this buffer. */ - chunk_t *head; /**< First chunk in the list, or NULL for none. */ - chunk_t *tail; /**< Last chunk in the list, or NULL for none. */ -}; - /** Collapse data from the first N chunks from <b>buf</b> into buf->head, * growing it as necessary, until buf->head has the first <b>bytes</b> bytes * of data from the buffer, or until buf->head has all the data in <b>buf</b>. @@ -2507,6 +2477,7 @@ write_to_buf_zlib(buf_t *buf, tor_zlib_state_t *state, char *next; size_t old_avail, avail; int over = 0; + do { int need_new_chunk = 0; if (!buf->tail || ! CHUNK_REMAINING_CAPACITY(buf->tail)) { diff --git a/src/or/buffers.h b/src/or/buffers.h index a201282da..c90e14750 100644 --- a/src/or/buffers.h +++ b/src/or/buffers.h @@ -106,6 +106,35 @@ void assert_buf_ok(buf_t *buf); STATIC int buf_find_string_offset(const buf_t *buf, const char *s, size_t n); STATIC void buf_pullup(buf_t *buf, size_t bytes, int nulterminate); void buf_get_first_chunk_data(const buf_t *buf, const char **cp, size_t *sz); + +#define DEBUG_CHUNK_ALLOC +/** A single chunk on a buffer or in a freelist. */ +typedef struct chunk_t { + struct chunk_t *next; /**< The next chunk on the buffer or freelist. */ + size_t datalen; /**< The number of bytes stored in this chunk */ + size_t memlen; /**< The number of usable bytes of storage in <b>mem</b>. */ +#ifdef DEBUG_CHUNK_ALLOC + size_t DBG_alloc; +#endif + char *data; /**< A pointer to the first byte of data stored in <b>mem</b>. */ + uint32_t inserted_time; /**< Timestamp in truncated ms since epoch + * when this chunk was inserted. */ + char mem[FLEXIBLE_ARRAY_MEMBER]; /**< The actual memory used for storage in + * this chunk. */ +} chunk_t; + +/** Magic value for buf_t.magic, to catch pointer errors. */ +#define BUFFER_MAGIC 0xB0FFF312u +/** A resizeable buffer, optimized for reading and writing. */ +struct buf_t { + uint32_t magic; /**< Magic cookie for debugging: Must be set to + * BUFFER_MAGIC. */ + size_t datalen; /**< How many bytes is this buffer holding right now? */ + size_t default_chunk_size; /**< Don't allocate any chunks smaller than + * this for this buffer. */ + chunk_t *head; /**< First chunk in the list, or NULL for none. */ + chunk_t *tail; /**< Last chunk in the list, or NULL for none. */ +}; #endif #endif diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index cd92326b3..9d06759de 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -9,6 +9,8 @@ * \brief The actual details of building circuits. **/ +#define CIRCUITBUILD_PRIVATE + #include "or.h" #include "channel.h" #include "circpathbias.h" @@ -83,7 +85,7 @@ channel_connect_for_circuit(const tor_addr_t *addr, uint16_t port, * * Return it, or 0 if can't get a unique circ_id. */ -static circid_t +STATIC circid_t get_unique_circ_id_by_chan(channel_t *chan) { /* This number is chosen somewhat arbitrarily; see comment below for more diff --git a/src/or/circuitbuild.h b/src/or/circuitbuild.h index ebcb22c45..71caea94e 100644 --- a/src/or/circuitbuild.h +++ b/src/or/circuitbuild.h @@ -58,5 +58,9 @@ const char *build_state_get_exit_nickname(cpath_build_state_t *state); const node_t *choose_good_entry_server(uint8_t purpose, cpath_build_state_t *state); +#ifdef CIRCUITBUILD_PRIVATE +STATIC circid_t get_unique_circ_id_by_chan(channel_t *chan); +#endif + #endif diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c index e482fa535..6238e08e1 100644 --- a/src/or/circuitlist.c +++ b/src/or/circuitlist.c @@ -76,7 +76,15 @@ 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) ^ (unsigned)(uintptr_t)(a->chan); + /* Try to squeze the siphash input into 8 bytes to save any extra siphash + * rounds. This hash function is in the critical path. */ + uintptr_t chan = (uintptr_t) (void*) a->chan; + uint32_t array[2]; + array[0] = a->circ_id; + /* The low bits of the channel pointer are uninteresting, since the channel + * is a pretty big structure. */ + array[1] = (uint32_t) (chan >> 6); + return (unsigned) siphash24g(array, sizeof(array)); } /** Map from [chan,circid] to circuit. */ @@ -1821,7 +1829,7 @@ circuit_max_queued_cell_age(const circuit_t *c, uint32_t now) age = now - cell->inserted_time; if (! CIRCUIT_IS_ORIGIN(c)) { - const or_circuit_t *orcirc = TO_OR_CIRCUIT((circuit_t*)c); + const or_circuit_t *orcirc = CONST_TO_OR_CIRCUIT(c); if (NULL != (cell = TOR_SIMPLEQ_FIRST(&orcirc->p_chan_cells.head))) { uint32_t age2 = now - cell->inserted_time; if (age2 > age) @@ -1863,10 +1871,10 @@ circuit_max_queued_data_age(const circuit_t *c, uint32_t now) { if (CIRCUIT_IS_ORIGIN(c)) { return circuit_get_streams_max_data_age( - TO_ORIGIN_CIRCUIT((circuit_t*)c)->p_streams, now); + CONST_TO_ORIGIN_CIRCUIT(c)->p_streams, now); } else { return circuit_get_streams_max_data_age( - TO_OR_CIRCUIT((circuit_t*)c)->n_streams, now); + CONST_TO_OR_CIRCUIT(c)->n_streams, now); } } @@ -2059,15 +2067,10 @@ assert_circuit_ok(const circuit_t *c) tor_assert(c->purpose >= CIRCUIT_PURPOSE_MIN_ && c->purpose <= CIRCUIT_PURPOSE_MAX_); - { - /* Having a separate variable for this pleases GCC 4.2 in ways I hope I - * never understand. -NM. */ - circuit_t *nonconst_circ = (circuit_t*) c; - if (CIRCUIT_IS_ORIGIN(c)) - origin_circ = TO_ORIGIN_CIRCUIT(nonconst_circ); - else - or_circ = TO_OR_CIRCUIT(nonconst_circ); - } + if (CIRCUIT_IS_ORIGIN(c)) + origin_circ = CONST_TO_ORIGIN_CIRCUIT(c); + else + or_circ = CONST_TO_OR_CIRCUIT(c); if (c->n_chan) { tor_assert(!c->n_hop); diff --git a/src/or/circuituse.c b/src/or/circuituse.c index d10430668..467bef652 100644 --- a/src/or/circuituse.c +++ b/src/or/circuituse.c @@ -296,7 +296,7 @@ circuit_get_best(const entry_connection_t *conn, } if (!circuit_is_acceptable(origin_circ,conn,must_be_open,purpose, - need_uptime,need_internal,now.tv_sec)) + need_uptime,need_internal, (time_t)now.tv_sec)) continue; /* now this is an acceptable circ to hand back. but that doesn't @@ -683,9 +683,9 @@ circuit_expire_building(void) victim->purpose, circuit_purpose_to_string(victim->purpose)); } else if (circuit_build_times_count_close( - get_circuit_build_times_mutable(), - first_hop_succeeded, - victim->timestamp_created.tv_sec)) { + get_circuit_build_times_mutable(), + first_hop_succeeded, + (time_t)victim->timestamp_created.tv_sec)) { circuit_build_times_set_timeout(get_circuit_build_times_mutable()); } } @@ -783,6 +783,64 @@ circuit_expire_building(void) } } +/** + * As a diagnostic for bug 8387, log information about how many one-hop + * circuits we have around that have been there for at least <b>age</b> + * seconds. Log a few of them. + */ +void +circuit_log_ancient_one_hop_circuits(int age) +{ +#define MAX_ANCIENT_ONEHOP_CIRCUITS_TO_LOG 10 + time_t cutoff = time(NULL) - age; + int n_found = 0; + smartlist_t *log_these = smartlist_new(); + const circuit_t *circ; + + TOR_LIST_FOREACH(circ, circuit_get_global_list(), head) { + const origin_circuit_t *ocirc; + if (! CIRCUIT_IS_ORIGIN(circ)) + continue; + if (circ->timestamp_created.tv_sec >= cutoff) + continue; + ocirc = CONST_TO_ORIGIN_CIRCUIT(circ); + + if (ocirc->build_state && ocirc->build_state->onehop_tunnel) { + ++n_found; + + if (smartlist_len(log_these) < MAX_ANCIENT_ONEHOP_CIRCUITS_TO_LOG) + smartlist_add(log_these, (origin_circuit_t*) ocirc); + } + } + + if (n_found == 0) + goto done; + + log_notice(LD_HEARTBEAT, + "Diagnostic for issue 8387: Found %d one-hop circuits more " + "than %d seconds old! Logging %d...", + n_found, age, smartlist_len(log_these)); + + SMARTLIST_FOREACH_BEGIN(log_these, const origin_circuit_t *, ocirc) { + char created[ISO_TIME_LEN+1]; + circ = TO_CIRCUIT(ocirc); + format_local_iso_time(created, + (time_t)circ->timestamp_created.tv_sec); + + log_notice(LD_HEARTBEAT, " #%d created at %s. %s, %s. %s for close. " + "%s for new conns.", + ocirc_sl_idx, + created, + circuit_state_to_string(circ->state), + circuit_purpose_to_string(circ->purpose), + circ->marked_for_close ? "Marked" : "Not marked", + ocirc->unusable_for_new_conns ? "Not usable" : "usable"); + } SMARTLIST_FOREACH_END(ocirc); + + done: + smartlist_free(log_these); +} + /** Remove any elements in <b>needed_ports</b> that are handled by an * open or in-progress circuit. */ diff --git a/src/or/circuituse.h b/src/or/circuituse.h index 11e5a6416..f228a6758 100644 --- a/src/or/circuituse.h +++ b/src/or/circuituse.h @@ -16,6 +16,7 @@ void circuit_expire_building(void); void circuit_remove_handled_ports(smartlist_t *needed_ports); int circuit_stream_is_being_handled(entry_connection_t *conn, uint16_t port, int min); +void circuit_log_ancient_one_hop_circuits(int age); #if 0 int circuit_conforms_to_options(const origin_circuit_t *circ, const or_options_t *options); diff --git a/src/or/config.c b/src/or/config.c index 7850e5227..0f7b1d2a2 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -357,7 +357,7 @@ static config_var_t option_vars_[] = { V(OptimisticData, AUTOBOOL, "auto"), V(PortForwarding, BOOL, "0"), V(PortForwardingHelper, FILENAME, "tor-fw-helper"), - V(PreferTunneledDirConns, BOOL, "1"), + OBSOLETE("PreferTunneledDirConns"), V(ProtocolWarnings, BOOL, "0"), V(PublishServerDescriptor, CSV, "1"), V(PublishHidServDescriptors, BOOL, "1"), @@ -412,7 +412,7 @@ static config_var_t option_vars_[] = { V(TransListenAddress, LINELIST, NULL), VPORT(TransPort, LINELIST, NULL), V(TransProxyType, STRING, "default"), - V(TunnelDirConns, BOOL, "1"), + OBSOLETE("TunnelDirConns"), V(UpdateBridgesFromAuthority, BOOL, "0"), V(UseBridges, BOOL, "0"), V(UseEntryGuards, BOOL, "1"), @@ -536,9 +536,11 @@ static int options_transition_affects_descriptor( const or_options_t *old_options, const or_options_t *new_options); static int check_nickname_list(char **lst, const char *name, char **msg); -static int parse_client_transport_line(const char *line, int validate_only); +static int parse_client_transport_line(const or_options_t *options, + const char *line, int validate_only); -static int parse_server_transport_line(const char *line, int validate_only); +static int parse_server_transport_line(const or_options_t *options, + const char *line, int validate_only); static char *get_bindaddr_from_transport_listen_line(const char *line, const char *transport); static int parse_dir_authority_line(const char *line, @@ -1141,13 +1143,11 @@ options_act_reversible(const or_options_t *old_options, char **msg) if (!running_tor) goto commit; - if (!sandbox_is_active()) { - mark_logs_temp(); /* Close current logs once new logs are open. */ - logs_marked = 1; - if (options_init_logs(options, 0)<0) { /* Configure the tor_log(s) */ - *msg = tor_strdup("Failed to init Log options. See logs for details."); - goto rollback; - } + mark_logs_temp(); /* Close current logs once new logs are open. */ + logs_marked = 1; + if (options_init_logs(options, 0)<0) { /* Configure the tor_log(s) */ + *msg = tor_strdup("Failed to init Log options. See logs for details."); + goto rollback; } commit: @@ -1426,7 +1426,7 @@ options_act(const or_options_t *old_options) pt_prepare_proxy_list_for_config_read(); if (options->ClientTransportPlugin) { for (cl = options->ClientTransportPlugin; cl; cl = cl->next) { - if (parse_client_transport_line(cl->value, 0)<0) { + if (parse_client_transport_line(options, cl->value, 0)<0) { log_warn(LD_BUG, "Previously validated ClientTransportPlugin line " "could not be added!"); @@ -1437,7 +1437,7 @@ options_act(const or_options_t *old_options) if (options->ServerTransportPlugin && server_mode(options)) { for (cl = options->ServerTransportPlugin; cl; cl = cl->next) { - if (parse_server_transport_line(cl->value, 0)<0) { + if (parse_server_transport_line(options, cl->value, 0)<0) { log_warn(LD_BUG, "Previously validated ServerTransportPlugin line " "could not be added!"); @@ -3029,6 +3029,11 @@ options_validate(or_options_t *old_options, or_options_t *options, if (options->KeepalivePeriod < 1) REJECT("KeepalivePeriod option must be positive."); + if (options->PortForwarding && options->Sandbox) { + REJECT("PortForwarding is not compatible with Sandbox; at most one can " + "be set"); + } + if (ensure_bandwidth_cap(&options->BandwidthRate, "BandwidthRate", msg) < 0) return -1; @@ -3275,8 +3280,6 @@ options_validate(or_options_t *old_options, or_options_t *options, if (options->UseBridges && !options->Bridges) REJECT("If you set UseBridges, you must specify at least one bridge."); - if (options->UseBridges && !options->TunnelDirConns) - REJECT("If you set UseBridges, you must set TunnelDirConns."); for (cl = options->Bridges; cl; cl = cl->next) { bridge_line_t *bridge_line = parse_bridge_line(cl->value); @@ -3286,13 +3289,13 @@ options_validate(or_options_t *old_options, or_options_t *options, } for (cl = options->ClientTransportPlugin; cl; cl = cl->next) { - if (parse_client_transport_line(cl->value, 1)<0) - REJECT("Transport line did not parse. See logs for details."); + if (parse_client_transport_line(options, cl->value, 1)<0) + REJECT("Invalid client transport line. See logs for details."); } for (cl = options->ServerTransportPlugin; cl; cl = cl->next) { - if (parse_server_transport_line(cl->value, 1)<0) - REJECT("Server transport line did not parse. See logs for details."); + if (parse_server_transport_line(options, cl->value, 1)<0) + REJECT("Invalid server transport line. See logs for details."); } if (options->ServerTransportPlugin && !server_mode(options)) { @@ -3389,15 +3392,6 @@ options_validate(or_options_t *old_options, or_options_t *options, AF_INET6, 1, msg)<0) return -1; - if (options->PreferTunneledDirConns && !options->TunnelDirConns) - REJECT("Must set TunnelDirConns if PreferTunneledDirConns is set."); - - if ((options->Socks4Proxy || options->Socks5Proxy) && - !options->HTTPProxy && !options->PreferTunneledDirConns) - REJECT("When Socks4Proxy or Socks5Proxy is configured, " - "PreferTunneledDirConns and TunnelDirConns must both be " - "set to 1, or HTTPProxy must be configured."); - if (options->AutomapHostsSuffixes) { SMARTLIST_FOREACH(options->AutomapHostsSuffixes, char *, suf, { @@ -3751,6 +3745,11 @@ options_transition_allowed(const or_options_t *old, "Sandbox is active"); return -1; } + if (! opt_streq(old->DirPortFrontPage, new_val->DirPortFrontPage)) { + *msg = tor_strdup("Can't change DirPortFrontPage" + " while Sandbox is active"); + return -1; + } } return 0; @@ -4745,7 +4744,8 @@ parse_bridge_line(const char *line) * our internal transport list. * - If it's a managed proxy line, launch the managed proxy. */ static int -parse_client_transport_line(const char *line, int validate_only) +parse_client_transport_line(const or_options_t *options, + const char *line, int validate_only) { smartlist_t *items = NULL; int r; @@ -4812,6 +4812,12 @@ parse_client_transport_line(const char *line, int validate_only) goto err; } + if (is_managed && options->Sandbox) { + log_warn(LD_CONFIG, "Managed proxies are not compatible with Sandbox mode." + "(ClientTransportPlugin line was %s)", escaped(line)); + goto err; + } + if (is_managed) { /* managed */ if (!validate_only && is_useless_proxy) { log_notice(LD_GENERAL, "Pluggable transport proxy (%s) does not provide " @@ -5038,7 +5044,8 @@ get_options_for_server_transport(const char *transport) * If <b>validate_only</b> is 0, the line is well-formed, and it's a * managed proxy line, launch the managed proxy. */ static int -parse_server_transport_line(const char *line, int validate_only) +parse_server_transport_line(const or_options_t *options, + const char *line, int validate_only) { smartlist_t *items = NULL; int r; @@ -5093,6 +5100,12 @@ parse_server_transport_line(const char *line, int validate_only) goto err; } + if (is_managed && options->Sandbox) { + log_warn(LD_CONFIG, "Managed proxies are not compatible with Sandbox mode." + "(ServerTransportPlugin line was %s)", escaped(line)); + goto err; + } + if (is_managed) { /* managed */ if (!validate_only) { proxy_argc = line_length-2; diff --git a/src/or/connection.c b/src/or/connection.c index 3cc4e09fb..cef9172ff 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -1017,7 +1017,7 @@ connection_listener_new(const struct sockaddr *listensockaddr, tor_socket_t s = TOR_INVALID_SOCKET; /* the socket we're going to make */ or_options_t const *options = get_options(); #if defined(HAVE_PWD_H) && defined(HAVE_SYS_UN_H) - struct passwd *pw = NULL; + const struct passwd *pw = NULL; #endif uint16_t usePort = 0, gotPort = 0; int start_reading = 0; @@ -1157,7 +1157,7 @@ connection_listener_new(const struct sockaddr *listensockaddr, } #ifdef HAVE_PWD_H if (options->User) { - pw = getpwnam(options->User); + pw = tor_getpwnam(options->User); if (pw == NULL) { log_warn(LD_NET,"Unable to chown() %s socket: user %s not found.", address, options->User); diff --git a/src/or/control.c b/src/or/control.c index d571900ac..2865d7832 100755 --- a/src/or/control.c +++ b/src/or/control.c @@ -1492,7 +1492,7 @@ getinfo_helper_misc(control_connection_t *conn, const char *question, *answer = tor_strdup(""); #else int myUid = geteuid(); - struct passwd *myPwEntry = getpwuid(myUid); + const struct passwd *myPwEntry = tor_getpwuid(myUid); if (myPwEntry) { *answer = tor_strdup(myPwEntry->pw_name); diff --git a/src/or/cpuworker.c b/src/or/cpuworker.c index 6b6a68afe..61b2c29b3 100644 --- a/src/or/cpuworker.c +++ b/src/or/cpuworker.c @@ -528,7 +528,12 @@ spawn_cpuworker(void) tor_assert(SOCKET_OK(fdarray[1])); fd = fdarray[0]; - spawn_func(cpuworker_main, (void*)fdarray); + if (spawn_func(cpuworker_main, (void*)fdarray) < 0) { + tor_close_socket(fdarray[0]); + tor_close_socket(fdarray[1]); + tor_free(fdarray); + return -1; + } log_debug(LD_OR,"just spawned a cpu worker."); #ifndef TOR_IS_MULTITHREADED tor_close_socket(fdarray[1]); /* don't need the worker's side of the pipe */ diff --git a/src/or/directory.c b/src/or/directory.c index 8070a76a5..22ba056ee 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -261,7 +261,7 @@ directory_post_to_dirservers(uint8_t dir_purpose, uint8_t router_purpose, size_t payload_len, size_t extrainfo_len) { const or_options_t *options = get_options(); - int post_via_tor; + dir_indirection_t indirection; const smartlist_t *dirservers = router_get_trusted_dir_servers(); int found = 0; const int exclude_self = (dir_purpose == DIR_PURPOSE_UPLOAD_VOTE || @@ -305,11 +305,19 @@ directory_post_to_dirservers(uint8_t dir_purpose, uint8_t router_purpose, (int) extrainfo_len); } tor_addr_from_ipv4h(&ds_addr, ds->addr); - post_via_tor = purpose_needs_anonymity(dir_purpose, router_purpose) || - !fascist_firewall_allows_address_dir(&ds_addr, ds->dir_port); + if (purpose_needs_anonymity(dir_purpose, router_purpose)) { + indirection = DIRIND_ANONYMOUS; + } else if (!fascist_firewall_allows_address_dir(&ds_addr,ds->dir_port)) { + if (fascist_firewall_allows_address_or(&ds_addr,ds->or_port)) + indirection = DIRIND_ONEHOP; + else + indirection = DIRIND_ANONYMOUS; + } else { + indirection = DIRIND_DIRECT_CONN; + } directory_initiate_command_routerstatus(rs, dir_purpose, router_purpose, - post_via_tor, + indirection, NULL, payload, upload_len, 0); } SMARTLIST_FOREACH_END(ds); if (!found) { @@ -338,8 +346,6 @@ should_use_directory_guards(const or_options_t *options) if (options->DownloadExtraInfo || options->FetchDirInfoEarly || options->FetchDirInfoExtraEarly || options->FetchUselessDescriptors) return 0; - if (! options->PreferTunneledDirConns) - return 0; return 1; } @@ -834,6 +840,7 @@ directory_command_should_use_begindir(const or_options_t *options, int or_port, uint8_t router_purpose, dir_indirection_t indirection) { + (void) router_purpose; if (!or_port) return 0; /* We don't know an ORPort -- no chance. */ if (indirection == DIRIND_DIRECT_CONN || indirection == DIRIND_ANON_DIRPORT) @@ -842,9 +849,6 @@ directory_command_should_use_begindir(const or_options_t *options, if (!fascist_firewall_allows_address_or(addr, or_port) || directory_fetches_from_authorities(options)) return 0; /* We're firewalled or are acting like a relay -- also no. */ - if (!options->TunnelDirConns && - router_purpose != ROUTER_PURPOSE_BRIDGE) - return 0; /* We prefer to avoid using begindir conns. Fine. */ return 1; } @@ -2303,7 +2307,7 @@ write_http_response_header_impl(dir_connection_t *conn, ssize_t length, } if (cache_lifetime > 0) { char expbuf[RFC1123_TIME_LEN+1]; - format_rfc1123_time(expbuf, now + cache_lifetime); + format_rfc1123_time(expbuf, (time_t)(now + cache_lifetime)); /* We could say 'Cache-control: max-age=%d' here if we start doing * http/1.1 */ tor_snprintf(cp, sizeof(tmp)-(cp-tmp), @@ -3069,22 +3073,6 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers, goto done; } - if (!strcmp(url,"/tor/dbg-stability.txt")) { - const char *stability; - size_t len; - if (options->BridgeAuthoritativeDir || - ! authdir_mode_tests_reachability(options) || - ! (stability = rep_hist_get_router_stability_doc(time(NULL)))) { - write_http_status_line(conn, 404, "Not found."); - goto done; - } - - len = strlen(stability); - write_http_response_header(conn, len, 0, 0); - connection_write_to_buf(stability, len, TO_CONN(conn)); - goto done; - } - #if defined(EXPORTMALLINFO) && defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO) #define ADD_MALLINFO_LINE(x) do { \ smartlist_add_asprintf(lines, "%s %d\n", #x, mi.x); \ diff --git a/src/or/dirserv.c b/src/or/dirserv.c index f5994e031..aedd09252 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -2507,7 +2507,7 @@ dirserv_read_measured_bandwidths(const char *from_file, } line[strlen(line)-1] = '\0'; - file_time = tor_parse_ulong(line, 10, 0, ULONG_MAX, &ok, NULL); + file_time = (time_t)tor_parse_ulong(line, 10, 0, ULONG_MAX, &ok, NULL); if (!ok) { log_warn(LD_DIRSERV, "Non-integer time in bandwidth file: %s", escaped(line)); @@ -3296,8 +3296,6 @@ connection_dirserv_add_servers_to_outbuf(dir_connection_t *conn) } body = signed_descriptor_get_body(sd); if (conn->zlib_state) { - /* XXXX024 This 'last' business should actually happen on the last - * routerinfo, not on the last fingerprint. */ int last = ! smartlist_len(conn->fingerprint_stack); connection_write_to_buf_zlib(body, sd->signed_descriptor_len, conn, last); @@ -3314,6 +3312,11 @@ connection_dirserv_add_servers_to_outbuf(dir_connection_t *conn) if (!smartlist_len(conn->fingerprint_stack)) { /* We just wrote the last one; finish up. */ + if (conn->zlib_state) { + connection_write_to_buf_zlib("", 0, conn, 1); + tor_zlib_free(conn->zlib_state); + conn->zlib_state = NULL; + } conn->dir_spool_src = DIR_SPOOL_NONE; smartlist_free(conn->fingerprint_stack); conn->fingerprint_stack = NULL; @@ -3339,8 +3342,6 @@ connection_dirserv_add_microdescs_to_outbuf(dir_connection_t *conn) if (!md || !md->body) continue; if (conn->zlib_state) { - /* XXXX024 This 'last' business should actually happen on the last - * routerinfo, not on the last fingerprint. */ int last = !smartlist_len(conn->fingerprint_stack); connection_write_to_buf_zlib(md->body, md->bodylen, conn, last); if (last) { @@ -3352,6 +3353,11 @@ connection_dirserv_add_microdescs_to_outbuf(dir_connection_t *conn) } } if (!smartlist_len(conn->fingerprint_stack)) { + if (conn->zlib_state) { + connection_write_to_buf_zlib("", 0, conn, 1); + tor_zlib_free(conn->zlib_state); + conn->zlib_state = NULL; + } conn->dir_spool_src = DIR_SPOOL_NONE; smartlist_free(conn->fingerprint_stack); conn->fingerprint_stack = NULL; diff --git a/src/or/dirvote.c b/src/or/dirvote.c index 4d3ee9cdb..c7be343ca 100644 --- a/src/or/dirvote.c +++ b/src/or/dirvote.c @@ -3588,6 +3588,12 @@ dirvote_create_microdescriptor(const routerinfo_t *ri, int consensus_method) tor_free(p6); } + if (consensus_method >= MIN_METHOD_FOR_ID_HASH_IN_MD) { + char idbuf[BASE64_DIGEST_LEN+1]; + digest_to_base64(idbuf, ri->cache_info.identity_digest); + smartlist_add_asprintf(chunks, "id rsa1024 %s\n", idbuf); + } + output = smartlist_join_strings(chunks, "", 0, NULL); { @@ -3657,7 +3663,8 @@ static const struct consensus_method_range_t { {MIN_METHOD_FOR_MICRODESC, MIN_METHOD_FOR_A_LINES - 1}, {MIN_METHOD_FOR_A_LINES, MIN_METHOD_FOR_P6_LINES - 1}, {MIN_METHOD_FOR_P6_LINES, MIN_METHOD_FOR_NTOR_KEY - 1}, - {MIN_METHOD_FOR_NTOR_KEY, MAX_SUPPORTED_CONSENSUS_METHOD}, + {MIN_METHOD_FOR_NTOR_KEY, MIN_METHOD_FOR_ID_HASH_IN_MD - 1}, + {MIN_METHOD_FOR_ID_HASH_IN_MD, MAX_SUPPORTED_CONSENSUS_METHOD}, {-1, -1} }; diff --git a/src/or/dirvote.h b/src/or/dirvote.h index 3a4951a95..4c57e4366 100644 --- a/src/or/dirvote.h +++ b/src/or/dirvote.h @@ -22,7 +22,7 @@ #define MIN_VOTE_INTERVAL 300 /** The highest consensus method that we currently support. */ -#define MAX_SUPPORTED_CONSENSUS_METHOD 17 +#define MAX_SUPPORTED_CONSENSUS_METHOD 18 /** Lowest consensus method that contains a 'directory-footer' marker */ #define MIN_METHOD_FOR_FOOTER 9 @@ -61,6 +61,10 @@ * Unmeasured=1 flag for unmeasured bandwidths */ #define MIN_METHOD_TO_CLIP_UNMEASURED_BW 17 +/** Lowest consensus method where authorities may include an "id" line in + * microdescriptors. */ +#define MIN_METHOD_FOR_ID_HASH_IN_MD 18 + /** Default bandwidth to clip unmeasured bandwidths to using method >= * MIN_METHOD_TO_CLIP_UNMEASURED_BW */ #define DEFAULT_MAX_UNMEASURED_BW_KB 20 diff --git a/src/or/dns.c b/src/or/dns.c index 36271939b..a9c431865 100644 --- a/src/or/dns.c +++ b/src/or/dns.c @@ -2174,7 +2174,7 @@ static void assert_cache_ok_(void) { cached_resolve_t **resolve; - int bad_rep = _cache_map_HT_REP_IS_BAD(&cache_root); + int bad_rep = HT_REP_IS_BAD_(cache_map, &cache_root); if (bad_rep) { log_err(LD_BUG, "Bad rep type %d on dns cache hash table", bad_rep); tor_assert(!bad_rep); diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c index 70587bd75..957217ac6 100644 --- a/src/or/entrynodes.c +++ b/src/or/entrynodes.c @@ -378,7 +378,7 @@ 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_FOR_GUARD); + PDS_FOR_GUARD); if (!rs) return NULL; node = node_get_by_id(rs->identity_digest); diff --git a/src/or/main.c b/src/or/main.c index e5a48cf98..1168f43c9 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -1757,7 +1757,7 @@ refill_callback(periodic_timer_t *timer, void *arg) accounting_add_bytes(bytes_read, bytes_written, seconds_rolled_over); if (milliseconds_elapsed > 0) - connection_bucket_refill(milliseconds_elapsed, now.tv_sec); + connection_bucket_refill(milliseconds_elapsed, (time_t)now.tv_sec); stats_prev_global_read_bucket = global_read_bucket; stats_prev_global_write_bucket = global_write_bucket; @@ -2554,6 +2554,9 @@ tor_free_all(int postfork) #endif /* ENABLE_MEMPOOLS */ if (!postfork) { tor_tls_free_all(); +#ifndef _WIN32 + tor_getpwnam(NULL); +#endif } /* stuff in main.c */ @@ -2825,6 +2828,16 @@ sandbox_init_filter(void) NULL, 0 ); + { + smartlist_t *logfiles = smartlist_new(); + tor_log_get_logfile_names(logfiles); + SMARTLIST_FOREACH(logfiles, char *, logfile_name, { + /* steals reference */ + sandbox_cfg_allow_open_filename(&cfg, logfile_name); + }); + smartlist_free(logfiles); + } + // orport if (server_mode(get_options())) { sandbox_cfg_allow_open_filename_array(&cfg, @@ -2837,6 +2850,10 @@ sandbox_init_filter(void) get_datadir_fname2("keys", "secret_onion_key_ntor.old"), get_datadir_fname2("keys", "secret_onion_key.tmp"), get_datadir_fname2("keys", "secret_id_key.tmp"), + get_datadir_fname2("stats", "bridge-stats"), + get_datadir_fname2("stats", "bridge-stats.tmp"), + get_datadir_fname2("stats", "dirreq-stats"), + get_datadir_fname2("stats", "dirreq-stats.tmp"), get_datadir_fname("fingerprint"), get_datadir_fname("fingerprint.tmp"), get_datadir_fname("hashed-fingerprint"), @@ -2847,12 +2864,19 @@ sandbox_init_filter(void) NULL, 0 ); + if (options->DirPortFrontPage) { + sandbox_cfg_allow_open_filename(&cfg, + tor_strdup(options->DirPortFrontPage)); + } + RENAME_SUFFIX("fingerprint", ".tmp"); RENAME_SUFFIX2("keys", "secret_onion_key_ntor", ".tmp"); RENAME_SUFFIX2("keys", "secret_id_key", ".tmp"); RENAME_SUFFIX2("keys", "secret_id_key.old", ".tmp"); RENAME_SUFFIX2("keys", "secret_onion_key", ".tmp"); RENAME_SUFFIX2("keys", "secret_onion_key.old", ".tmp"); + RENAME_SUFFIX2("stats", "bridge-stats", ".tmp"); + RENAME_SUFFIX2("stats", "dirreq-stats", ".tmp"); RENAME_SUFFIX("hashed-fingerprint", ".tmp"); RENAME_SUFFIX("router-stability", ".tmp"); @@ -2865,7 +2889,7 @@ sandbox_init_filter(void) sandbox_cfg_allow_stat_filename_array(&cfg, get_datadir_fname("keys"), - get_datadir_fname("stats/dirreq-stats"), + get_datadir_fname2("stats", "dirreq-stats"), NULL, 0 ); } @@ -2944,7 +2968,7 @@ tor_main(int argc, char *argv[]) if (tor_init(argc, argv)<0) return -1; - if (get_options()->Sandbox) { + if (get_options()->Sandbox && get_options()->command == CMD_RUN_TOR) { sandbox_cfg_t* cfg = sandbox_init_filter(); if (sandbox_init(cfg)) { diff --git a/src/or/microdesc.c b/src/or/microdesc.c index ec85de0d6..fdb549a9a 100644 --- a/src/or/microdesc.c +++ b/src/or/microdesc.c @@ -386,18 +386,21 @@ microdesc_cache_clean(microdesc_cache_t *cache, time_t cutoff, int force) smartlist_t *nodes = nodelist_find_nodes_with_microdesc(*mdp); const networkstatus_t *ns = networkstatus_get_latest_consensus(); long networkstatus_age = -1; + const int ht_badness = HT_REP_IS_BAD_(microdesc_map, &cache->map); if (ns) { networkstatus_age = now - ns->valid_after; } log_warn(LD_BUG, "Microdescriptor seemed very old " "(last listed %d hours ago vs %d hour cutoff), but is still " "marked as being held by %d node(s). I found %d node(s) " - "holding it. Current networkstatus is %ld hours old.", + "holding it. Current networkstatus is %ld hours old. " + "Hashtable badness is %d.", (int)((now - (*mdp)->last_listed) / 3600), (int)((now - cutoff) / 3600), held_by_nodes, smartlist_len(nodes), - networkstatus_age / 3600); + networkstatus_age / 3600, + ht_badness); SMARTLIST_FOREACH_BEGIN(nodes, const node_t *, node) { const char *rs_match = "No RS"; @@ -664,8 +667,10 @@ microdesc_free_(microdesc_t *md, const char *fname, int lineno) tor_fragile_assert(); } if (md->held_by_nodes) { + microdesc_cache_t *cache = get_microdesc_cache(); int found=0; const smartlist_t *nodes = nodelist_get_list(); + const int ht_badness = HT_REP_IS_BAD_(microdesc_map, &cache->map); SMARTLIST_FOREACH(nodes, node_t *, node, { if (node->md == md) { ++found; @@ -674,12 +679,13 @@ microdesc_free_(microdesc_t *md, const char *fname, int lineno) }); if (found) { log_warn(LD_BUG, "microdesc_free() called from %s:%d, but md was still " - "referenced %d node(s); held_by_nodes == %u", - fname, lineno, found, md->held_by_nodes); + "referenced %d node(s); held_by_nodes == %u, ht_badness == %d", + fname, lineno, found, md->held_by_nodes, ht_badness); } else { log_warn(LD_BUG, "microdesc_free() called from %s:%d with held_by_nodes " - "set to %u, but md was not referenced by any nodes", - fname, lineno, md->held_by_nodes); + "set to %u, but md was not referenced by any nodes. " + "ht_badness == %d", + fname, lineno, md->held_by_nodes, ht_badness); } tor_fragile_assert(); } diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c index ef450073e..890da0ad1 100644 --- a/src/or/networkstatus.c +++ b/src/or/networkstatus.c @@ -10,6 +10,7 @@ * client or cache. */ +#define NETWORKSTATUS_PRIVATE #include "or.h" #include "channel.h" #include "circuitmux.h" @@ -183,7 +184,7 @@ router_reload_consensus_networkstatus(void) } /** Free all storage held by the vote_routerstatus object <b>rs</b>. */ -static void +STATIC void vote_routerstatus_free(vote_routerstatus_t *rs) { vote_microdesc_hash_t *h, *next; @@ -829,7 +830,7 @@ update_consensus_networkstatus_fetch_time_impl(time_t now, int flav) if (directory_fetches_dir_info_early(options)) { /* We want to cache the next one at some point after this one * is no longer fresh... */ - start = c->fresh_until + min_sec_before_caching; + start = (time_t)(c->fresh_until + min_sec_before_caching); /* Some clients may need the consensus sooner than others. */ if (options->FetchDirInfoExtraEarly || authdir_mode_v3(options)) { dl_interval = 60; @@ -842,7 +843,7 @@ update_consensus_networkstatus_fetch_time_impl(time_t now, int flav) } else { /* We're an ordinary client or a bridge. Give all the caches enough * time to download the consensus. */ - start = c->fresh_until + (interval*3)/4; + start = (time_t)(c->fresh_until + (interval*3)/4); /* But download the next one well before this one is expired. */ dl_interval = ((c->valid_until - start) * 7 )/ 8; @@ -850,7 +851,7 @@ update_consensus_networkstatus_fetch_time_impl(time_t now, int flav) * to choose the rest of the interval *after* them. */ if (directory_fetches_dir_info_later(options)) { /* Give all the *clients* enough time to download the consensus. */ - start = start + dl_interval + min_sec_before_caching; + start = (time_t)(start + dl_interval + min_sec_before_caching); /* But try to get it before ours actually expires. */ dl_interval = (c->valid_until - start) - min_sec_before_caching; } diff --git a/src/or/networkstatus.h b/src/or/networkstatus.h index 1659818f0..be0a86cdd 100644 --- a/src/or/networkstatus.h +++ b/src/or/networkstatus.h @@ -99,5 +99,9 @@ document_signature_t *document_signature_dup(const document_signature_t *sig); void networkstatus_free_all(void); int networkstatus_get_weight_scale_param(networkstatus_t *ns); +#ifdef NETWORKSTATUS_PRIVATE +STATIC void vote_routerstatus_free(vote_routerstatus_t *rs); +#endif + #endif diff --git a/src/or/nodelist.c b/src/or/nodelist.c index a38a6d499..09232f9f9 100644 --- a/src/or/nodelist.c +++ b/src/or/nodelist.c @@ -1510,8 +1510,8 @@ update_router_have_minimum_dir_info(void) } if (should_delay_dir_fetches(get_options(), &delay_fetches_msg)) { - log_notice(LD_DIR, "Delaying dir fetches: %s", delay_fetches_msg); - strlcpy(dir_info_status, "%s", sizeof(dir_info_status)); + log_notice(LD_DIR, "Delaying directory fetches: %s", delay_fetches_msg); + strlcpy(dir_info_status, delay_fetches_msg, sizeof(dir_info_status)); res = 0; goto done; } diff --git a/src/or/onion.c b/src/or/onion.c index 72571b7bd..ae39f451f 100644 --- a/src/or/onion.c +++ b/src/or/onion.c @@ -554,8 +554,10 @@ onion_skin_client_handshake(int type, switch (type) { case ONION_HANDSHAKE_TYPE_TAP: - if (reply_len != TAP_ONIONSKIN_REPLY_LEN) + if (reply_len != TAP_ONIONSKIN_REPLY_LEN) { + log_warn(LD_CIRC, "TAP reply was not of the correct length."); return -1; + } if (onion_skin_TAP_client_handshake(handshake_state->u.tap, (const char*)reply, (char *)keys_out, keys_out_len) < 0) @@ -565,8 +567,10 @@ onion_skin_client_handshake(int type, return 0; case ONION_HANDSHAKE_TYPE_FAST: - if (reply_len != CREATED_FAST_LEN) + if (reply_len != CREATED_FAST_LEN) { + log_warn(LD_CIRC, "CREATED_FAST reply was not of the correct length."); return -1; + } if (fast_client_handshake(handshake_state->u.fast, reply, keys_out, keys_out_len) < 0) return -1; @@ -575,8 +579,10 @@ onion_skin_client_handshake(int type, return 0; #ifdef CURVE25519_ENABLED case ONION_HANDSHAKE_TYPE_NTOR: - if (reply_len < NTOR_REPLY_LEN) + if (reply_len < NTOR_REPLY_LEN) { + log_warn(LD_CIRC, "ntor reply was not of the correct length."); return -1; + } { size_t keys_tmp_len = keys_out_len + DIGEST_LEN; uint8_t *keys_tmp = tor_malloc(keys_tmp_len); diff --git a/src/or/onion_fast.c b/src/or/onion_fast.c index 8e778dbc6..38b62decc 100644 --- a/src/or/onion_fast.c +++ b/src/or/onion_fast.c @@ -104,6 +104,7 @@ fast_client_handshake(const fast_handshake_state_t *handshake_state, out_len = key_out_len+DIGEST_LEN; out = tor_malloc(out_len); if (crypto_expand_key_material_TAP(tmp, sizeof(tmp), out, out_len)) { + log_warn(LD_CIRC, "Failed to expand key material"); goto done; } if (tor_memneq(out, handshake_reply_out+DIGEST_LEN, DIGEST_LEN)) { diff --git a/src/or/onion_ntor.c b/src/or/onion_ntor.c index 9cf7d5dd6..ef501f69d 100644 --- a/src/or/onion_ntor.c +++ b/src/or/onion_ntor.c @@ -256,7 +256,7 @@ onion_skin_ntor_client_handshake( si += CURVE25519_OUTPUT_LEN; curve25519_handshake(si, &handshake_state->seckey_x, &handshake_state->pubkey_B); - bad |= safe_mem_is_zero(si, CURVE25519_OUTPUT_LEN); + bad |= (safe_mem_is_zero(si, CURVE25519_OUTPUT_LEN) << 1); si += CURVE25519_OUTPUT_LEN; APPEND(si, handshake_state->router_id, DIGEST_LEN); APPEND(si, handshake_state->pubkey_B.public_key, CURVE25519_PUBKEY_LEN); @@ -281,7 +281,7 @@ onion_skin_ntor_client_handshake( /* Compute auth */ h_tweak(s.auth, s.auth_input, sizeof(s.auth_input), T->t_mac); - bad |= tor_memneq(s.auth, auth_candidate, DIGEST256_LEN); + bad |= (tor_memneq(s.auth, auth_candidate, DIGEST256_LEN) << 2); crypto_expand_key_material_rfc5869_sha256( s.secret_input, sizeof(s.secret_input), @@ -290,6 +290,11 @@ onion_skin_ntor_client_handshake( key_out, key_out_len); memwipe(&s, 0, sizeof(s)); + + if (bad) { + log_warn(LD_PROTOCOL, "Invalid result from curve25519 handshake: %d", bad); + } + return bad ? -1 : 0; } diff --git a/src/or/onion_tap.c b/src/or/onion_tap.c index 3782e75ab..9a9f374b9 100644 --- a/src/or/onion_tap.c +++ b/src/or/onion_tap.c @@ -194,8 +194,10 @@ onion_skin_TAP_client_handshake(crypto_dh_t *handshake_state, len = crypto_dh_compute_secret(LOG_PROTOCOL_WARN, handshake_state, handshake_reply, DH_KEY_LEN, key_material, key_material_len); - if (len < 0) + if (len < 0) { + log_warn(LD_PROTOCOL,"DH computation failed."); goto err; + } if (tor_memneq(key_material, handshake_reply+DH_KEY_LEN, DIGEST_LEN)) { /* H(K) does *not* match. Something fishy. */ diff --git a/src/or/or.h b/src/or/or.h index 701877c64..6aa6b59e8 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -3231,20 +3231,33 @@ typedef struct or_circuit_rendinfo_s { /** Convert a circuit_t* to a pointer to the enclosing or_circuit_t. Assert * if the cast is impossible. */ static or_circuit_t *TO_OR_CIRCUIT(circuit_t *); +static const or_circuit_t *CONST_TO_OR_CIRCUIT(const circuit_t *); /** Convert a circuit_t* to a pointer to the enclosing origin_circuit_t. * Assert if the cast is impossible. */ static origin_circuit_t *TO_ORIGIN_CIRCUIT(circuit_t *); +static const origin_circuit_t *CONST_TO_ORIGIN_CIRCUIT(const circuit_t *); static INLINE or_circuit_t *TO_OR_CIRCUIT(circuit_t *x) { tor_assert(x->magic == OR_CIRCUIT_MAGIC); return DOWNCAST(or_circuit_t, x); } +static INLINE const or_circuit_t *CONST_TO_OR_CIRCUIT(const circuit_t *x) +{ + tor_assert(x->magic == OR_CIRCUIT_MAGIC); + return DOWNCAST(or_circuit_t, x); +} static INLINE origin_circuit_t *TO_ORIGIN_CIRCUIT(circuit_t *x) { tor_assert(x->magic == ORIGIN_CIRCUIT_MAGIC); return DOWNCAST(origin_circuit_t, x); } +static INLINE const origin_circuit_t *CONST_TO_ORIGIN_CIRCUIT( + const circuit_t *x) +{ + tor_assert(x->magic == ORIGIN_CIRCUIT_MAGIC); + return DOWNCAST(origin_circuit_t, x); +} /** Bitfield type: things that we're willing to use invalid routers for. */ typedef enum invalid_router_usage_t { @@ -3873,10 +3886,6 @@ typedef struct { * testing our DNS server. */ int EnforceDistinctSubnets; /**< If true, don't allow multiple routers in the * same network zone in the same circuit. */ - int TunnelDirConns; /**< If true, use BEGIN_DIR rather than BEGIN when - * possible. */ - int PreferTunneledDirConns; /**< If true, avoid dirservers that don't - * support BEGIN_DIR, when possible. */ int PortForwarding; /**< If true, use NAT-PMP or UPnP to automatically * forward the DirPort and ORPort on the NAT device */ char *PortForwardingHelper; /** < Filename or full path of the port @@ -4961,8 +4970,6 @@ typedef struct dir_server_t { * 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 * routerlist_sl_choose_by_bandwidth() for more information.*/ typedef enum bandwidth_weight_rule_t { diff --git a/src/or/rephist.c b/src/or/rephist.c index 70be39e23..5446c25e3 100644 --- a/src/or/rephist.c +++ b/src/or/rephist.c @@ -879,126 +879,6 @@ rep_hist_record_mtbf_data(time_t now, int missing_means_down) return -1; } -/** Format the current tracked status of the router in <b>hist</b> at time - * <b>now</b> for analysis; return it in a newly allocated string. */ -static char * -rep_hist_format_router_status(or_history_t *hist, time_t now) -{ - char sor_buf[ISO_TIME_LEN+1]; - char sod_buf[ISO_TIME_LEN+1]; - double wfu; - double mtbf; - int up = 0, down = 0; - char *cp = NULL; - - if (hist->start_of_run) { - format_iso_time(sor_buf, hist->start_of_run); - up = 1; - } - if (hist->start_of_downtime) { - format_iso_time(sod_buf, hist->start_of_downtime); - down = 1; - } - - wfu = get_weighted_fractional_uptime(hist, now); - mtbf = get_stability(hist, now); - tor_asprintf(&cp, - "%s%s%s" - "%s%s%s" - "wfu %0.3f\n" - " weighted-time %lu\n" - " weighted-uptime %lu\n" - "mtbf %0.1f\n" - " weighted-run-length %lu\n" - " total-run-weights %f\n", - up?"uptime-started ":"", up?sor_buf:"", up?" UTC\n":"", - down?"downtime-started ":"", down?sod_buf:"", down?" UTC\n":"", - wfu, - hist->total_weighted_time, - hist->weighted_uptime, - mtbf, - hist->weighted_run_length, - hist->total_run_weights - ); - return cp; -} - -/** The last stability analysis document that we created, or NULL if we never - * have created one. */ -static char *last_stability_doc = NULL; -/** The last time we created a stability analysis document, or 0 if we never - * have created one. */ -static time_t built_last_stability_doc_at = 0; -/** Shortest allowable time between building two stability documents. */ -#define MAX_STABILITY_DOC_BUILD_RATE (3*60) - -/** Return a pointer to a NUL-terminated document describing our view of the - * stability of the routers we've been tracking. Return NULL on failure. */ -const char * -rep_hist_get_router_stability_doc(time_t now) -{ - char *result; - smartlist_t *chunks; - if (built_last_stability_doc_at + MAX_STABILITY_DOC_BUILD_RATE > now) - return last_stability_doc; - - if (!history_map) - return NULL; - - tor_free(last_stability_doc); - chunks = smartlist_new(); - - if (rep_hist_have_measured_enough_stability()) { - smartlist_add(chunks, tor_strdup("we-have-enough-measurements\n")); - } else { - smartlist_add(chunks, tor_strdup("we-do-not-have-enough-measurements\n")); - } - - DIGESTMAP_FOREACH(history_map, id, or_history_t *, hist) { - const node_t *node; - char dbuf[BASE64_DIGEST_LEN+1]; - char *info; - digest_to_base64(dbuf, id); - node = node_get_by_id(id); - if (node) { - char ip[INET_NTOA_BUF_LEN+1]; - char tbuf[ISO_TIME_LEN+1]; - time_t published = node_get_published_on(node); - node_get_address_string(node,ip,sizeof(ip)); - if (published > 0) - format_iso_time(tbuf, published); - else - strlcpy(tbuf, "???", sizeof(tbuf)); - smartlist_add_asprintf(chunks, - "router %s %s %s\n" - "published %s\n" - "relevant-flags %s%s%s\n" - "declared-uptime %ld\n", - dbuf, node_get_nickname(node), ip, - tbuf, - node->is_running ? "Running " : "", - node->is_valid ? "Valid " : "", - node->ri && node->ri->is_hibernating ? "Hibernating " : "", - node_get_declared_uptime(node)); - } else { - smartlist_add_asprintf(chunks, - "router %s {no descriptor}\n", dbuf); - } - info = rep_hist_format_router_status(hist, now); - if (info) - smartlist_add(chunks, info); - - } DIGESTMAP_FOREACH_END; - - result = smartlist_join_strings(chunks, "", 0, NULL); - SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp)); - smartlist_free(chunks); - - last_stability_doc = result; - built_last_stability_doc_at = time(NULL); - return result; -} - /** Helper: return the first j >= i such that !strcmpstart(sl[j], prefix) and * such that no line sl[k] with i <= k < j starts with "R ". Return -1 if no * such line exists. */ @@ -1051,7 +931,7 @@ correct_time(time_t t, time_t now, time_t stored_at, time_t started_measuring) return 0; else { long run_length = stored_at - t; - t = now - run_length; + t = (time_t)(now - run_length); if (t < started_measuring) t = started_measuring; return t; @@ -1212,7 +1092,7 @@ rep_hist_load_mtbf_data(time_t now) hist->start_of_run = correct_time(start_of_run, now, stored_at, tracked_since); if (hist->start_of_run < latest_possible_start + wrl) - latest_possible_start = hist->start_of_run - wrl; + latest_possible_start = (time_t)(hist->start_of_run - wrl); hist->weighted_run_length = wrl; hist->total_run_weights = trw; @@ -2431,7 +2311,7 @@ rep_hist_buffer_stats_add_circ(circuit_t *circ, time_t end_of_interval) return; start_of_interval = (circ->timestamp_created.tv_sec > start_of_buffer_stats_interval) ? - circ->timestamp_created.tv_sec : + (time_t)circ->timestamp_created.tv_sec : start_of_buffer_stats_interval; interval_length = (int) (end_of_interval - start_of_interval); if (interval_length <= 0) @@ -3041,11 +2921,9 @@ rep_hist_free_all(void) tor_free(write_array); tor_free(dir_read_array); tor_free(dir_write_array); - tor_free(last_stability_doc); tor_free(exit_bytes_read); tor_free(exit_bytes_written); tor_free(exit_streams); - built_last_stability_doc_at = 0; predicted_ports_free(); bidi_map_free(); diff --git a/src/or/rephist.h b/src/or/rephist.h index df01ae6cb..cd6231e6e 100644 --- a/src/or/rephist.h +++ b/src/or/rephist.h @@ -47,7 +47,6 @@ double rep_hist_get_stability(const char *id, time_t when); double rep_hist_get_weighted_fractional_uptime(const char *id, time_t when); long rep_hist_get_weighted_time_known(const char *id, time_t when); int rep_hist_have_measured_enough_stability(void); -const char *rep_hist_get_router_stability_doc(time_t now); void rep_hist_note_used_port(time_t now, uint16_t port); smartlist_t *rep_hist_get_predicted_ports(time_t now); diff --git a/src/or/router.c b/src/or/router.c index 86cefc9a6..2cdbb0c8b 100755 --- a/src/or/router.c +++ b/src/or/router.c @@ -1267,7 +1267,8 @@ router_perform_bandwidth_test(int num_circs, time_t now) } /** Return true iff our network is in some sense disabled: either we're - * hibernating, entering hibernation, or */ + * hibernating, entering hibernation, or the network is turned off with + * DisableNetwork. */ int net_is_disabled(void) { diff --git a/src/or/routerlist.c b/src/or/routerlist.c index c15274e99..8f3477a4a 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -1282,8 +1282,6 @@ const routerstatus_t * router_pick_directory_server(dirinfo_type_t type, int flags) { const routerstatus_t *choice; - if (get_options()->PreferTunneledDirConns) - flags |= PDS_PREFER_TUNNELED_DIR_CONNS_; if (!routerlist) return NULL; @@ -1385,8 +1383,6 @@ router_pick_dirserver_generic(smartlist_t *sourcelist, { const routerstatus_t *choice; int busy = 0; - if (get_options()->PreferTunneledDirConns) - flags |= PDS_PREFER_TUNNELED_DIR_CONNS_; choice = router_pick_trusteddirserver_impl(sourcelist, type, flags, &busy); if (choice || !(flags & PDS_RETRY_IF_NO_SERVERS)) @@ -1411,10 +1407,7 @@ router_pick_dirserver_generic(smartlist_t *sourcelist, /** Pick a random running valid directory server/mirror from our * routerlist. Arguments are as for router_pick_directory_server(), except - * that RETRY_IF_NO_SERVERS is ignored, and: - * - * If the PDS_PREFER_TUNNELED_DIR_CONNS_ flag is set, prefer directory servers - * that we can use with BEGINDIR. + * that RETRY_IF_NO_SERVERS is ignored. */ static const routerstatus_t * router_pick_directory_server_impl(dirinfo_type_t type, int flags) @@ -1428,7 +1421,6 @@ router_pick_directory_server_impl(dirinfo_type_t type, int flags) const networkstatus_t *consensus = networkstatus_get_latest_consensus(); 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; @@ -1481,8 +1473,7 @@ router_pick_directory_server_impl(dirinfo_type_t type, int flags) is_overloaded = status->last_dir_503_at + DIR_503_TIMEOUT > now; - if (prefer_tunnel && - (!fascistfirewall || + if ((!fascistfirewall || fascist_firewall_allows_address_or(&addr, status->or_port))) smartlist_add(is_trusted ? trusted_tunnel : is_overloaded ? overloaded_tunnel : tunnel, (void*)node); @@ -1569,7 +1560,6 @@ router_pick_trusteddirserver_impl(const smartlist_t *sourcelist, time_t now = time(NULL); const int requireother = ! (flags & PDS_ALLOW_SELF); const int fascistfirewall = ! (flags & PDS_IGNORE_FASCISTFIREWALL); - const int prefer_tunnel = (flags & PDS_PREFER_TUNNELED_DIR_CONNS_); const int no_serverdesc_fetching =(flags & PDS_NO_EXISTING_SERVERDESC_FETCH); const int no_microdesc_fetching =(flags & PDS_NO_EXISTING_MICRODESC_FETCH); const double auth_weight = (sourcelist == fallback_dir_servers) ? @@ -1630,8 +1620,7 @@ router_pick_trusteddirserver_impl(const smartlist_t *sourcelist, } } - if (prefer_tunnel && - d->or_port && + if (d->or_port && (!fascistfirewall || fascist_firewall_allows_address_or(&addr, d->or_port))) smartlist_add(is_overloaded ? overloaded_tunnel : tunnel, (void*)d); diff --git a/src/or/routerparse.c b/src/or/routerparse.c index 14f800e7b..5add728d6 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -4129,11 +4129,13 @@ microdescs_parse_from_string(const char *s, const char *eos, microdesc_free(md); md = NULL; + SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t)); memarea_clear(area); smartlist_clear(tokens); s = start_of_next_microdesc; } + SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t)); memarea_drop_all(area); smartlist_free(tokens); diff --git a/src/or/statefile.c b/src/or/statefile.c index da3134171..7b9998fc1 100644 --- a/src/or/statefile.c +++ b/src/or/statefile.c @@ -294,6 +294,16 @@ or_state_save_broken(char *fname) tor_free(fname2); } +STATIC or_state_t * +or_state_new(void) +{ + or_state_t *new_state = tor_malloc_zero(sizeof(or_state_t)); + new_state->magic_ = OR_STATE_MAGIC; + config_init(&state_format, new_state); + + return new_state; +} + /** Reload the persistent state from disk, generating a new state as needed. * Return 0 on success, less than 0 on failure. */ @@ -321,9 +331,7 @@ or_state_load(void) log_warn(LD_GENERAL,"State file \"%s\" is not a file? Failing.", fname); goto done; } - new_state = tor_malloc_zero(sizeof(or_state_t)); - new_state->magic_ = OR_STATE_MAGIC; - config_init(&state_format, new_state); + new_state = or_state_new(); if (contents) { config_line_t *lines=NULL; int assign_retval; @@ -358,9 +366,7 @@ or_state_load(void) tor_free(contents); config_free(&state_format, new_state); - new_state = tor_malloc_zero(sizeof(or_state_t)); - new_state->magic_ = OR_STATE_MAGIC; - config_init(&state_format, new_state); + new_state = or_state_new(); } else if (contents) { log_info(LD_GENERAL, "Loaded state from \"%s\"", fname); } else { @@ -625,10 +631,19 @@ save_transport_to_state(const char *transport, tor_free(transport_addrport); } +STATIC void +or_state_free(or_state_t *state) +{ + if (!state) + return; + + config_free(&state_format, state); +} + void or_state_free_all(void) { - config_free(&state_format, global_state); + or_state_free(global_state); global_state = NULL; } diff --git a/src/or/statefile.h b/src/or/statefile.h index c1413ff95..15bb0b4aa 100644 --- a/src/or/statefile.h +++ b/src/or/statefile.h @@ -20,6 +20,8 @@ void or_state_free_all(void); #ifdef STATEFILE_PRIVATE STATIC config_line_t *get_transport_in_state_by_name(const char *transport); +STATIC void or_state_free(or_state_t *state); +STATIC or_state_t *or_state_new(void); #endif #endif diff --git a/src/or/status.c b/src/or/status.c index 7e2afbce8..afaa9de84 100644 --- a/src/or/status.c +++ b/src/or/status.c @@ -9,6 +9,7 @@ #define STATUS_PRIVATE #include "or.h" +#include "circuituse.h" #include "config.h" #include "status.h" #include "nodelist.h" @@ -135,6 +136,8 @@ log_heartbeat(time_t now) if (public_server_mode(options)) rep_hist_log_circuit_handshake_stats(now); + circuit_log_ancient_one_hop_circuits(1800); + tor_free(uptime); tor_free(bw_sent); tor_free(bw_rcvd); |