diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/address.c | 18 | ||||
-rw-r--r-- | src/or/circuitbuild.c | 3 | ||||
-rw-r--r-- | src/or/connection_or.c | 3 | ||||
-rw-r--r-- | src/or/dirserv.c | 20 | ||||
-rw-r--r-- | src/or/policies.c | 2 | ||||
-rw-r--r-- | src/or/rephist.c | 75 | ||||
-rw-r--r-- | src/or/rephist.h | 3 | ||||
-rw-r--r-- | src/or/routerparse.c | 6 |
8 files changed, 101 insertions, 29 deletions
diff --git a/src/common/address.c b/src/common/address.c index 0e57528ae8..a2780fb051 100644 --- a/src/common/address.c +++ b/src/common/address.c @@ -1025,27 +1025,28 @@ get_interface_address6(int severity, sa_family_t family, tor_addr_t *addr) { int sock=-1, r=-1; struct sockaddr_storage my_addr, target_addr; - socklen_t my_addr_len; + socklen_t addr_len; tor_assert(addr); memset(addr, 0, sizeof(tor_addr_t)); memset(&target_addr, 0, sizeof(target_addr)); - my_addr_len = (socklen_t)sizeof(my_addr); - /* Use the "discard" service port */ - ((struct sockaddr_in*)&target_addr)->sin_port = 9; /* Don't worry: no packets are sent. We just need to use a real address * on the actual Internet. */ if (family == AF_INET6) { struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)&target_addr; + /* Use the "discard" service port */ + sin6->sin6_port = htons(9); sock = tor_open_socket(PF_INET6,SOCK_DGRAM,IPPROTO_UDP); - my_addr_len = (socklen_t)sizeof(struct sockaddr_in6); + addr_len = (socklen_t)sizeof(struct sockaddr_in6); sin6->sin6_family = AF_INET6; S6_ADDR16(sin6->sin6_addr)[0] = htons(0x2002); /* 2002:: */ } else if (family == AF_INET) { struct sockaddr_in *sin = (struct sockaddr_in*)&target_addr; + /* Use the "discard" service port */ + sin->sin_port = htons(9); sock = tor_open_socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP); - my_addr_len = (socklen_t)sizeof(struct sockaddr_in); + addr_len = (socklen_t)sizeof(struct sockaddr_in); sin->sin_family = AF_INET; sin->sin_addr.s_addr = htonl(0x12000001); /* 18.0.0.1 */ } else { @@ -1058,14 +1059,13 @@ get_interface_address6(int severity, sa_family_t family, tor_addr_t *addr) goto err; } - if (connect(sock,(struct sockaddr *)&target_addr, - (socklen_t)sizeof(target_addr))<0) { + if (connect(sock,(struct sockaddr *)&target_addr, addr_len) < 0) { int e = tor_socket_errno(sock); log_fn(severity, LD_NET, "connect() failed: %s", tor_socket_strerror(e)); goto err; } - if (getsockname(sock,(struct sockaddr*)&my_addr, &my_addr_len)) { + if (getsockname(sock,(struct sockaddr*)&my_addr, &addr_len)) { int e = tor_socket_errno(sock); log_fn(severity, LD_NET, "getsockname() to determine interface failed: %s", tor_socket_strerror(e)); diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index b3c9f0e1b5..6be27d29e7 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -4728,7 +4728,8 @@ any_pending_bridge_descriptor_fetches(void) conn->purpose == DIR_PURPOSE_FETCH_SERVERDESC && TO_DIR_CONN(conn)->router_purpose == ROUTER_PURPOSE_BRIDGE && !conn->marked_for_close && - conn->linked && !conn->linked_conn->marked_for_close) { + conn->linked && + conn->linked_conn && !conn->linked_conn->marked_for_close) { log_debug(LD_DIR, "found one: %s", conn->address); return 1; } diff --git a/src/or/connection_or.c b/src/or/connection_or.c index b93699ccc1..2d2444462d 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -1098,9 +1098,6 @@ connection_or_check_valid_tls_handshake(or_connection_t *conn, as_advertised = 0; } if (authdir_mode_tests_reachability(options)) { - /* We initiated this connection to address:port. Drop all routers - * with the same address:port and a different key. - */ dirserv_orconn_tls_done(conn->_base.address, conn->_base.port, digest_rcvd_out, as_advertised); } diff --git a/src/or/dirserv.c b/src/or/dirserv.c index 876698a2dc..aeeab45383 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -2970,6 +2970,8 @@ dirserv_get_routerdesc_fingerprints(smartlist_t *fps_out, const char *key, SMARTLIST_FOREACH(rl->routers, routerinfo_t *, r, smartlist_add(fps_out, tor_memdup(r->cache_info.identity_digest, DIGEST_LEN))); + /* Treat "all" requests as if they were unencrypted */ + for_unencrypted_conn = 1; } else if (!strcmp(key, "authority")) { routerinfo_t *ri = router_get_my_routerinfo(); if (ri) @@ -3114,19 +3116,27 @@ dirserv_orconn_tls_done(const char *address, tor_assert(address); tor_assert(digest_rcvd); - SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri, { + /* XXX023 Doing a loop like this is stupid. We should just look up the + * router by digest_rcvd, and see if address, orport, and as_advertised + * match up. -NM */ + SMARTLIST_FOREACH_BEGIN(rl->routers, routerinfo_t *, ri) { if (!strcasecmp(address, ri->address) && or_port == ri->or_port && as_advertised && !memcmp(ri->cache_info.identity_digest, digest_rcvd, DIGEST_LEN)) { /* correct digest. mark this router reachable! */ if (!bridge_auth || ri->purpose == ROUTER_PURPOSE_BRIDGE) { - log_info(LD_DIRSERV, "Found router %s to be reachable. Yay.", - ri->nickname); - rep_hist_note_router_reachable(digest_rcvd, now); + tor_addr_t addr, *addrp=NULL; + log_info(LD_DIRSERV, "Found router %s to be reachable at %s:%d. Yay.", + ri->nickname, address, ri->or_port ); + if (tor_addr_from_str(&addr, ri->address) != -1) + addrp = &addr; + else + log_warn(LD_BUG, "Couldn't parse IP address \"%s\"", ri->address); + rep_hist_note_router_reachable(digest_rcvd, addrp, or_port, now); ri->last_reachable = now; } } - }); + } SMARTLIST_FOREACH_END(ri); /* FFFF Maybe we should reinstate the code that dumps routers with the same * addr/port but with nonmatching keys, but instead of dumping, we should * skip testing. */ diff --git a/src/or/policies.c b/src/or/policies.c index 38c2f7c0fd..e48f42058f 100644 --- a/src/or/policies.c +++ b/src/or/policies.c @@ -888,6 +888,8 @@ exit_policy_is_general_exit_helper(smartlist_t *policy, int port) memset(subnet_status, 0, sizeof(subnet_status)); SMARTLIST_FOREACH(policy, addr_policy_t *, p, { + if (tor_addr_family(&p->addr) != AF_INET) + continue; /* IPv4 only for now */ if (p->prt_min > port || p->prt_max < port) continue; /* Doesn't cover our port. */ mask = 0; diff --git a/src/or/rephist.c b/src/or/rephist.c index 3f4a70418b..53214d61ef 100644 --- a/src/or/rephist.c +++ b/src/or/rephist.c @@ -14,6 +14,7 @@ #include "circuitlist.h" #include "circuituse.h" #include "config.h" +#include "networkstatus.h" #include "rephist.h" #include "router.h" #include "routerlist.h" @@ -73,6 +74,13 @@ typedef struct or_history_t { /** If nonzero, we have been unable to connect since this time. */ time_t down_since; + /** The address at which we most recently connected to this OR + * successfully. */ + tor_addr_t last_reached_addr; + + /** The port at which we most recently connected to this OR successfully */ + uint16_t last_reached_port; + /* === For MTBF tracking: */ /** Weighted sum total of all times that this router has been online. */ @@ -119,6 +127,7 @@ get_or_history(const char* id) rephist_total_num++; hist->link_history_map = digestmap_new(); hist->since = hist->changed = time(NULL); + tor_addr_make_unspec(&hist->last_reached_addr); digestmap_set(history_map, id, hist); } return hist; @@ -289,13 +298,20 @@ rep_hist_note_connection_died(const char* id, time_t when) /** We have just decided that this router with identity digest <b>id</b> is * reachable, meaning we will give it a "Running" flag for the next while. */ void -rep_hist_note_router_reachable(const char *id, time_t when) +rep_hist_note_router_reachable(const char *id, const tor_addr_t *at_addr, + const uint16_t at_port, time_t when) { or_history_t *hist = get_or_history(id); int was_in_run = 1; char tbuf[ISO_TIME_LEN+1]; + int addr_changed, port_changed; tor_assert(hist); + tor_assert((!at_addr && !at_port) || (at_addr && at_port)); + + addr_changed = at_addr && + tor_addr_compare(at_addr, &hist->last_reached_addr, CMP_EXACT) != 0; + port_changed = at_port && at_port != hist->last_reached_port; if (!started_tracking_stability) started_tracking_stability = time(NULL); @@ -315,6 +331,27 @@ rep_hist_note_router_reachable(const char *id, time_t when) down_length = when - hist->start_of_downtime; hist->total_weighted_time += down_length; hist->start_of_downtime = 0; + } else if (addr_changed || port_changed) { + /* If we're reachable, but the address changed, treat this as some + * downtime. */ + int penalty = get_options()->TestingTorNetwork ? 240 : 3600; + networkstatus_t *ns; + + if ((ns = networkstatus_get_latest_consensus())) { + int fresh_interval = (int)(ns->fresh_until - ns->valid_after); + int live_interval = (int)(ns->valid_until - ns->valid_after); + /* on average, a descriptor addr change takes .5 intervals to make it + * into a consensus, and half a liveness period to make it to + * clients. */ + penalty = (int)(fresh_interval + live_interval) / 2; + } + format_local_iso_time(tbuf, hist->start_of_run); + log_info(LD_HIST,"Router %s still seems Running, but its address appears " + "to have changed since the last time it was reachable. I'm " + "going to treat it as having been down for %d seconds", + hex_str(id, DIGEST_LEN), penalty); + rep_hist_note_router_unreachable(id, when-penalty); + rep_hist_note_router_reachable(id, NULL, 0, when); } else { format_local_iso_time(tbuf, hist->start_of_run); if (was_in_run) @@ -324,6 +361,10 @@ rep_hist_note_router_reachable(const char *id, time_t when) log_info(LD_HIST,"Router %s is now Running; it was previously untracked", hex_str(id, DIGEST_LEN)); } + if (at_addr) + tor_addr_copy(&hist->last_reached_addr, at_addr); + if (at_port) + hist->last_reached_port = at_port; } /** We have just decided that this router is unreachable, meaning @@ -344,12 +385,20 @@ rep_hist_note_router_unreachable(const char *id, time_t when) long run_length = when - hist->start_of_run; format_local_iso_time(tbuf, hist->start_of_run); - hist->weighted_run_length += run_length; hist->total_run_weights += 1.0; hist->start_of_run = 0; - hist->weighted_uptime += run_length; - hist->total_weighted_time += run_length; + if (run_length < 0) { + unsigned long penalty = -run_length; +#define SUBTRACT_CLAMPED(var, penalty) \ + do { (var) = (var) < (penalty) ? 0 : (var) - (penalty); } while (0) + SUBTRACT_CLAMPED(hist->weighted_run_length, penalty); + SUBTRACT_CLAMPED(hist->weighted_uptime, penalty); + } else { + hist->weighted_run_length += run_length; + hist->weighted_uptime += run_length; + hist->total_weighted_time += run_length; + } was_running = 1; log_info(LD_HIST, "Router %s is now non-Running: it had previously been " "Running since %s. Its total weighted uptime is %lu/%lu.", @@ -422,7 +471,7 @@ rep_hist_downrate_old_runs(time_t now) static double get_stability(or_history_t *hist, time_t when) { - unsigned long total = hist->weighted_run_length; + long total = hist->weighted_run_length; double total_weights = hist->total_run_weights; if (hist->start_of_run) { @@ -458,8 +507,8 @@ get_total_weighted_time(or_history_t *hist, time_t when) static double get_weighted_fractional_uptime(or_history_t *hist, time_t when) { - unsigned long total = hist->total_weighted_time; - unsigned long up = hist->weighted_uptime; + long total = hist->total_weighted_time; + long up = hist->weighted_uptime; if (hist->start_of_run) { long run_length = (when - hist->start_of_run); @@ -1602,18 +1651,24 @@ rep_hist_load_bwhist_state_section(bw_array_t *b, b->cur_obs_time = start; b->next_period = start + NUM_SECS_BW_SUM_INTERVAL; SMARTLIST_FOREACH_BEGIN(s_values, const char *, cp) { + const char *maxstr = NULL; v = tor_parse_uint64(cp, 10, 0, UINT64_MAX, &ok, NULL); if (have_maxima) { - const char *maxstr = smartlist_get(s_maxima, cp_sl_idx); + maxstr = smartlist_get(s_maxima, cp_sl_idx); mv = tor_parse_uint64(maxstr, 10, 0, UINT64_MAX, &ok_m, NULL); mv *= NUM_SECS_ROLLING_MEASURE; } else { /* No maxima known; guess average rate to be conservative. */ mv = v / s_interval; } - if (!ok || !ok_m) { + if (!ok) { + retval = -1; + log_notice(LD_HIST, "Could not parse value '%s' into a number.'",cp); + } + if (maxstr && !ok_m) { retval = -1; - log_notice(LD_HIST, "Could not parse '%s' into a number.'", cp); + log_notice(LD_HIST, "Could not parse maximum '%s' into a number.'", + maxstr); } if (start < now) { diff --git a/src/or/rephist.h b/src/or/rephist.h index 9a39070817..5f6b9f9b45 100644 --- a/src/or/rephist.h +++ b/src/or/rephist.h @@ -33,7 +33,8 @@ void rep_hist_update_state(or_state_t *state); int rep_hist_load_state(or_state_t *state, char **err); void rep_history_clean(time_t before); -void rep_hist_note_router_reachable(const char *id, time_t when); +void rep_hist_note_router_reachable(const char *id, const tor_addr_t *at_addr, + uint16_t at_port, time_t when); void rep_hist_note_router_unreachable(const char *id, time_t when); int rep_hist_record_mtbf_data(time_t now, int missing_means_down); int rep_hist_load_mtbf_data(time_t now); diff --git a/src/or/routerparse.c b/src/or/routerparse.c index db7161e3da..28ce97ebde 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -1505,6 +1505,12 @@ router_parse_entry_from_string(const char *s, const char *end, router->has_old_dnsworkers = 1; } + if (find_opt_by_keyword(tokens, K_REJECT6) || + find_opt_by_keyword(tokens, K_ACCEPT6)) { + log_warn(LD_DIR, "Rejecting router with reject6/accept6 line: they crash " + "older Tors."); + goto err; + } exit_policy_tokens = find_all_exitpolicy(tokens); if (!smartlist_len(exit_policy_tokens)) { log_warn(LD_DIR, "No exit policy tokens in descriptor."); |