mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-24 12:23:32 +01:00
Send out a burst of long-range drop cells after we've established that
we're reachable. Spread them over 4 circuits, so hopefully a few will be fast. This exercises our bandwidth and bootstraps us quicker. svn:r8399
This commit is contained in:
parent
ba091ae5d7
commit
769f9201a6
@ -220,7 +220,7 @@ circuit_close_all_marked(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the head of the global linked list of circuits. **/
|
/** Return the head of the global linked list of circuits. */
|
||||||
circuit_t *
|
circuit_t *
|
||||||
_circuit_get_global_list(void)
|
_circuit_get_global_list(void)
|
||||||
{
|
{
|
||||||
@ -650,8 +650,9 @@ circuit_get_by_rend_query_and_purpose(const char *rend_query, uint8_t purpose)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Return the first circuit in global_circuitlist after <b>start</b>
|
/** Return the first circuit in global_circuitlist after <b>start</b>
|
||||||
* whose rend_pk_digest field is <b>digest</b> and whose purpose is
|
* whose purpose is <b>purpose</b> is purpose, and (if set) whose
|
||||||
* <b>purpose</b>. Returns NULL if no circuit is found.
|
* <b>digest</b> matches the rend_pk_digest field. Return NULL if no
|
||||||
|
* circuit is found.
|
||||||
* If <b>start</b> is NULL, begin at the start of the list.
|
* If <b>start</b> is NULL, begin at the start of the list.
|
||||||
* DOCDOC origin.
|
* DOCDOC origin.
|
||||||
*/
|
*/
|
||||||
|
@ -583,8 +583,6 @@ circuit_expire_old_circuits(time_t now)
|
|||||||
log_debug(LD_CIRC, "Closing n_circ_id %d (dirty %d secs ago, purp %d)",
|
log_debug(LD_CIRC, "Closing n_circ_id %d (dirty %d secs ago, purp %d)",
|
||||||
circ->n_circ_id, (int)(now - circ->timestamp_dirty),
|
circ->n_circ_id, (int)(now - circ->timestamp_dirty),
|
||||||
circ->purpose);
|
circ->purpose);
|
||||||
/* (only general and purpose_c circs can get dirty) */
|
|
||||||
tor_assert(circ->purpose <= CIRCUIT_PURPOSE_C_REND_JOINED);
|
|
||||||
circuit_mark_for_close(circ, END_CIRC_AT_ORIGIN);
|
circuit_mark_for_close(circ, END_CIRC_AT_ORIGIN);
|
||||||
} else if (!circ->timestamp_dirty &&
|
} else if (!circ->timestamp_dirty &&
|
||||||
circ->state == CIRCUIT_STATE_OPEN &&
|
circ->state == CIRCUIT_STATE_OPEN &&
|
||||||
@ -599,14 +597,55 @@ circuit_expire_old_circuits(time_t now)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A testing circuit has completed. Take whatever stats we want. */
|
#define NUM_PARALLEL_TESTING_CIRCS 4
|
||||||
|
|
||||||
|
static int have_performed_bandwidth_test = 0;
|
||||||
|
|
||||||
|
/** Reset have_performed_bandwidth_test, so we'll start building
|
||||||
|
* testing circuits again so we can exercise our bandwidth. */
|
||||||
|
void
|
||||||
|
reset_bandwidth_test(void)
|
||||||
|
{
|
||||||
|
have_performed_bandwidth_test = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return 1 if we've already exercised our bandwidth, or if we
|
||||||
|
* have fewer than NUM_PARALLEL_TESTING_CIRCS testing circuits
|
||||||
|
* established or on the way. Else return 0.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
circuit_enough_testing_circs(void)
|
||||||
|
{
|
||||||
|
circuit_t *circ;
|
||||||
|
int num = 0;
|
||||||
|
|
||||||
|
if (have_performed_bandwidth_test)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
for (circ = global_circuitlist; circ; circ = circ->next) {
|
||||||
|
if (!circ->marked_for_close && CIRCUIT_IS_ORIGIN(circ) &&
|
||||||
|
circ->purpose == CIRCUIT_PURPOSE_TESTING &&
|
||||||
|
circ->state == CIRCUIT_STATE_OPEN)
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
return num >= NUM_PARALLEL_TESTING_CIRCS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A testing circuit has completed. Take whatever stats we want.
|
||||||
|
* Noticing reachability is taken care of in onionskin_answer(),
|
||||||
|
* so there's no need to record anything here. But if we still want
|
||||||
|
* to do the bandwidth test, and we now have enough testing circuits
|
||||||
|
* open, do it.
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
circuit_testing_opened(origin_circuit_t *circ)
|
circuit_testing_opened(origin_circuit_t *circ)
|
||||||
{
|
{
|
||||||
/* For now, we only use testing circuits to see if our ORPort is
|
if (have_performed_bandwidth_test) {
|
||||||
reachable. But we remember reachability in onionskin_answer(),
|
|
||||||
so there's no need to record anything here. Just close the circ. */
|
|
||||||
circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_AT_ORIGIN);
|
circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_AT_ORIGIN);
|
||||||
|
} else if (circuit_enough_testing_circs()) {
|
||||||
|
router_perform_bandwidth_test(NUM_PARALLEL_TESTING_CIRCS, time(NULL));
|
||||||
|
have_performed_bandwidth_test = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A testing circuit has failed to build. Take whatever stats we want. */
|
/** A testing circuit has failed to build. Take whatever stats we want. */
|
||||||
|
@ -1753,6 +1753,10 @@ int circuit_stream_is_being_handled(edge_connection_t *conn, uint16_t port,
|
|||||||
void circuit_build_needed_circs(time_t now);
|
void circuit_build_needed_circs(time_t now);
|
||||||
void circuit_detach_stream(circuit_t *circ, edge_connection_t *conn);
|
void circuit_detach_stream(circuit_t *circ, edge_connection_t *conn);
|
||||||
void circuit_about_to_close_connection(connection_t *conn);
|
void circuit_about_to_close_connection(connection_t *conn);
|
||||||
|
|
||||||
|
void reset_bandwidth_test(void);
|
||||||
|
int circuit_enough_testing_circs(void);
|
||||||
|
|
||||||
void circuit_has_opened(origin_circuit_t *circ);
|
void circuit_has_opened(origin_circuit_t *circ);
|
||||||
void circuit_build_failed(origin_circuit_t *circ);
|
void circuit_build_failed(origin_circuit_t *circ);
|
||||||
origin_circuit_t *circuit_launch_by_nickname(uint8_t purpose,
|
origin_circuit_t *circuit_launch_by_nickname(uint8_t purpose,
|
||||||
@ -2443,13 +2447,14 @@ void consider_testing_reachability(void);
|
|||||||
void router_orport_found_reachable(void);
|
void router_orport_found_reachable(void);
|
||||||
void router_dirport_found_reachable(void);
|
void router_dirport_found_reachable(void);
|
||||||
void server_has_changed_ip(void);
|
void server_has_changed_ip(void);
|
||||||
void consider_publishable_server(int force);
|
void router_perform_bandwidth_test(int num_circs, time_t now);
|
||||||
|
|
||||||
int authdir_mode(or_options_t *options);
|
int authdir_mode(or_options_t *options);
|
||||||
int clique_mode(or_options_t *options);
|
int clique_mode(or_options_t *options);
|
||||||
int server_mode(or_options_t *options);
|
int server_mode(or_options_t *options);
|
||||||
int advertised_server_mode(void);
|
int advertised_server_mode(void);
|
||||||
int proxy_mode(or_options_t *options);
|
int proxy_mode(or_options_t *options);
|
||||||
|
void consider_publishable_server(int force);
|
||||||
|
|
||||||
int router_is_clique_mode(routerinfo_t *router);
|
int router_is_clique_mode(routerinfo_t *router);
|
||||||
void router_upload_dir_desc_to_dirservers(int force);
|
void router_upload_dir_desc_to_dirservers(int force);
|
||||||
|
@ -439,11 +439,13 @@ void
|
|||||||
consider_testing_reachability(void)
|
consider_testing_reachability(void)
|
||||||
{
|
{
|
||||||
routerinfo_t *me = router_get_my_routerinfo();
|
routerinfo_t *me = router_get_my_routerinfo();
|
||||||
|
int orport_reachable = !check_whether_orport_reachable();
|
||||||
if (!me)
|
if (!me)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!check_whether_orport_reachable()) {
|
if (!orport_reachable || !circuit_enough_testing_circs()) {
|
||||||
log_info(LD_CIRC, "Testing reachability of my ORPort: %s:%d.",
|
log_info(LD_CIRC, "Testing %s of my ORPort: %s:%d.",
|
||||||
|
!orport_reachable ? "reachability" : "bandwidth",
|
||||||
me->address, me->or_port);
|
me->address, me->or_port);
|
||||||
circuit_launch_by_router(CIRCUIT_PURPOSE_TESTING, me, 0, 1, 1);
|
circuit_launch_by_router(CIRCUIT_PURPOSE_TESTING, me, 0, 1, 1);
|
||||||
}
|
}
|
||||||
@ -488,9 +490,38 @@ server_has_changed_ip(void)
|
|||||||
stats_n_seconds_working = 0;
|
stats_n_seconds_working = 0;
|
||||||
can_reach_or_port = 0;
|
can_reach_or_port = 0;
|
||||||
can_reach_dir_port = 0;
|
can_reach_dir_port = 0;
|
||||||
|
reset_bandwidth_test();
|
||||||
mark_my_descriptor_dirty();
|
mark_my_descriptor_dirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** We have enough testing circuit open. Send a bunch of "drop"
|
||||||
|
* cells down each of them, to exercise our bandwidth. */
|
||||||
|
void
|
||||||
|
router_perform_bandwidth_test(int num_circs, time_t now)
|
||||||
|
{
|
||||||
|
int num_cells = get_options()->BandwidthRate * 10 / CELL_NETWORK_SIZE;
|
||||||
|
int max_cells = num_cells < CIRCWINDOW_START ?
|
||||||
|
num_cells : CIRCWINDOW_START;
|
||||||
|
int cells_per_circuit = max_cells / num_circs;
|
||||||
|
origin_circuit_t *circ = NULL;
|
||||||
|
|
||||||
|
while ((circ = circuit_get_next_by_pk_and_purpose(circ, NULL,
|
||||||
|
CIRCUIT_PURPOSE_TESTING))) {
|
||||||
|
/* dump cells_per_circuit drop cells onto this circ */
|
||||||
|
int i = cells_per_circuit;
|
||||||
|
if (circ->_base.state != CIRCUIT_STATE_OPEN)
|
||||||
|
continue;
|
||||||
|
circ->_base.timestamp_dirty = now;
|
||||||
|
while (i-- > 0) {
|
||||||
|
if (connection_edge_send_command(NULL, TO_CIRCUIT(circ),
|
||||||
|
RELAY_COMMAND_DROP,
|
||||||
|
NULL, 0, circ->cpath->prev)<0) {
|
||||||
|
return; /* stop if error */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Return true iff we believe ourselves to be an authoritative
|
/** Return true iff we believe ourselves to be an authoritative
|
||||||
* directory server.
|
* directory server.
|
||||||
*/
|
*/
|
||||||
|
@ -2129,6 +2129,7 @@ add_networkstatus_to_cache(const char *s,
|
|||||||
/** How far in the future do we allow a network-status to get before removing
|
/** How far in the future do we allow a network-status to get before removing
|
||||||
* it? (seconds) */
|
* it? (seconds) */
|
||||||
#define NETWORKSTATUS_ALLOW_SKEW (24*60*60)
|
#define NETWORKSTATUS_ALLOW_SKEW (24*60*60)
|
||||||
|
|
||||||
/** Given a string <b>s</b> containing a network status that we received at
|
/** Given a string <b>s</b> containing a network status that we received at
|
||||||
* <b>arrived_at</b> from <b>source</b>, try to parse it, see if we want to
|
* <b>arrived_at</b> from <b>source</b>, try to parse it, see if we want to
|
||||||
* store it, and put it into our cache as necessary.
|
* store it, and put it into our cache as necessary.
|
||||||
|
Loading…
Reference in New Issue
Block a user