diff options
Diffstat (limited to 'src/or')
-rw-r--r-- | src/or/relay.c | 14 | ||||
-rw-r--r-- | src/or/routerlist.c | 31 | ||||
-rw-r--r-- | src/or/routerparse.c | 2 |
3 files changed, 38 insertions, 9 deletions
diff --git a/src/or/relay.c b/src/or/relay.c index 3e418ea13f..3d261c2650 100644 --- a/src/or/relay.c +++ b/src/or/relay.c @@ -1265,11 +1265,25 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, case RELAY_COMMAND_SENDME: if (!rh.stream_id) { if (layer_hint) { + if (layer_hint->package_window + CIRCWINDOW_INCREMENT > + CIRCWINDOW_START_MAX) { + log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, + "Bug/attack: unexpected sendme cell from exit relay. " + "Closing circ."); + return -END_CIRC_REASON_TORPROTOCOL; + } layer_hint->package_window += CIRCWINDOW_INCREMENT; log_debug(LD_APP,"circ-level sendme at origin, packagewindow %d.", layer_hint->package_window); circuit_resume_edge_reading(circ, layer_hint); } else { + if (circ->package_window + CIRCWINDOW_INCREMENT > + CIRCWINDOW_START_MAX) { + log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, + "Bug/attack: unexpected sendme cell from client. " + "Closing circ."); + return -END_CIRC_REASON_TORPROTOCOL; + } circ->package_window += CIRCWINDOW_INCREMENT; log_debug(LD_APP, "circ-level sendme at non-origin, packagewindow %d.", diff --git a/src/or/routerlist.c b/src/or/routerlist.c index de1a66ce16..4979b933ad 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -1709,6 +1709,8 @@ smartlist_choose_node_by_bandwidth_weights(smartlist_t *sl, double *bandwidths; double tmp = 0; unsigned int i; + unsigned int i_chosen; + unsigned int i_has_been_chosen; int have_unknown = 0; /* true iff sl contains element not in consensus. */ /* Can't choose exit and guard at same time */ @@ -1871,12 +1873,17 @@ smartlist_choose_node_by_bandwidth_weights(smartlist_t *sl, * from 1 below. See bug 1203 for details. */ /* Last, count through sl until we get to the element we picked */ + i_chosen = (unsigned)smartlist_len(sl); + i_has_been_chosen = 0; tmp = 0.0; for (i=0; i < (unsigned)smartlist_len(sl); i++) { tmp += bandwidths[i]; - if (tmp >= rand_bw) - break; + if (tmp >= rand_bw && !i_has_been_chosen) { + i_chosen = i; + i_has_been_chosen = 1; + } } + i = i_chosen; if (i == (unsigned)smartlist_len(sl)) { /* This was once possible due to round-off error, but shouldn't be able @@ -1909,7 +1916,9 @@ static const node_t * smartlist_choose_node_by_bandwidth(smartlist_t *sl, bandwidth_weight_rule_t rule) { - unsigned i; + unsigned int i; + unsigned int i_chosen; + unsigned int i_has_been_chosen; int32_t *bandwidths; int is_exit; int is_guard; @@ -1983,9 +1992,10 @@ smartlist_choose_node_by_bandwidth(smartlist_t *sl, if (is_guard) bitarray_set(guard_bits, i); if (is_known) { - bandwidths[i] = (int32_t) this_bw; // safe since MAX_BELIEVABLE<INT32_MAX - // XXX this is no longer true! We don't always cap the bw anymore. Can - // a consensus make us overflow?-sh + bandwidths[i] = (int32_t) this_bw; + /* Casting this_bw to int32_t is safe because both kb_to_bytes + and bridge_get_advertised_bandwidth_bounded limit it to below + INT32_MAX. */ tor_assert(bandwidths[i] >= 0); if (is_guard) total_guard_bw += this_bw; @@ -2108,6 +2118,8 @@ smartlist_choose_node_by_bandwidth(smartlist_t *sl, /* Last, count through sl until we get to the element we picked */ tmp = 0; + i_chosen = (unsigned)smartlist_len(sl); + i_has_been_chosen = 0; for (i=0; i < (unsigned)smartlist_len(sl); i++) { is_exit = bitarray_is_set(exit_bits, i); is_guard = bitarray_is_set(guard_bits, i); @@ -2122,9 +2134,12 @@ smartlist_choose_node_by_bandwidth(smartlist_t *sl, else tmp += bandwidths[i]; - if (tmp >= rand_bw) - break; + if (tmp >= rand_bw && !i_has_been_chosen) { + i_chosen = i; + i_has_been_chosen = 1; + } } + i = i_chosen; if (i == (unsigned)smartlist_len(sl)) { /* This was once possible due to round-off error, but shouldn't be able * to occur any longer. */ diff --git a/src/or/routerparse.c b/src/or/routerparse.c index 4231a17c67..970353a43c 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -2853,7 +2853,7 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out, int flavor = networkstatus_parse_flavor_name(tok->args[1]); if (flavor < 0) { log_warn(LD_DIR, "Can't parse document with unknown flavor %s", - escaped(tok->args[2])); + escaped(tok->args[1])); goto err; } ns->flavor = flav = flavor; |