}
}
+/* Expire unused testing circuits after 10 minutes. */
+#define TESTING_CIRCUIT_MAX_AGE 600
+
void circuit_expire_unused_circuits(void) {
circuit_t *circ, *tmpcirc;
time_t now = time(NULL);
while(circ) {
tmpcirc = circ;
circ = circ->next;
- if(tmpcirc->timestamp_dirty &&
- tmpcirc->timestamp_dirty + options.NewCircuitPeriod < now &&
- !tmpcirc->p_conn && !tmpcirc->p_streams && !tmpcirc->marked_for_close) {
+ /* If the circuit has been dirty for too long, and there are no streams
+ * on it, mark it for close.
+ * If we are creating test circuits, and the circuit is old, and has
+ * no streams, shut it down even if it isn't dirty.
+ */
+ if(((tmpcirc->timestamp_dirty &&
+ tmpcirc->timestamp_dirty + options.NewCircuitPeriod < now) ||
+ (options.RunTesting &&
+ tmpcirc->timestamp_created + TESTING_CIRCUIT_MAX_AGE < now))
+ && !tmpcirc->p_conn
+ && !tmpcirc->p_streams
+ && !tmpcirc->marked_for_close) {
log_fn(LOG_DEBUG,"Closing n_circ_id %d",tmpcirc->n_circ_id);
circuit_mark_for_close(tmpcirc);
}
/* Return -1 if you aren't going to try to make a circuit, 0 if you did try. */
int circuit_launch_new(void) {
- if(!options.SocksPort) /* we're not an application proxy. no need for circuits. */
+ if(!(options.SocksPort||options.RunTesting)) /* no need for circuits. */
return -1;
if(n_circuit_failures > 5) { /* too many failed circs in a row. don't try. */
config_compare(list, "TrafficShaping", CONFIG_TYPE_BOOL, &options->TrafficShaping) ||
- config_compare(list, "User", CONFIG_TYPE_STRING, &options->User)
+ config_compare(list, "User", CONFIG_TYPE_STRING, &options->User) ||
+ config_compare(list, "RunTesting", CONFIG_TYPE_BOOL, &options->RunTesting)
) {
/* then we're ok. it matched something. */
} else {
}
if (!options.ORPort) { /* If I'm an OP... */
conn->receiver_bucket = conn->bandwidth = DEFAULT_BANDWIDTH_OP;
- circuit_n_conn_open(conn); /* send the pending creates, if any. */
- /* XXXX ORs may need to send creates for test circuits; "I am an OR"
- * doesn't mean "I have no pending creates", right?
- */
}
+ circuit_n_conn_open(conn); /* send the pending creates, if any. */
/* Note the success */
rep_hist_note_connect_succeeded(nickname, time(NULL));
return 0;
* that became dirty more than NewCircuitPeriod seconds ago,
* and we make a new circ if there are no clean circuits.
*/
- if(options.SocksPort) {
+ if(options.SocksPort || options.RunTesting) {
+
+ if (options.SocksPort)
+ /* launch a new circ for any pending streams that need one */
+ connection_ap_attach_pending();
- /* launch a new circ for any pending streams that need one */
- connection_ap_attach_pending();
+/* Build a new test circuit every 5 minutes */
+#define TESTING_CIRCUIT_INTERVAL 300
circ = circuit_get_newest(NULL, 1);
if(time_to_new_circuit < now) {
if(circ && circ->timestamp_dirty) {
log_fn(LOG_INFO,"Youngest circuit dirty; launching replacement.");
circuit_launch_new(); /* make a new circuit */
+ } else if (options.RunTesting && circ &&
+ circ->timestamp_created + TESTING_CIRCUIT_INTERVAL < now) {
+ log_fn(LOG_INFO,"Creating a new testing circuit.");
+ circuit_launch_new();
}
time_to_new_circuit = now + options.NewCircuitPeriod;
}
int BandwidthBurst;
int NumCpus;
int loglevel;
+ int RunTesting;
} or_options_t;
/* XXX are these good enough defaults? */