From cc3c4245cb80cb7bb98be4868f053fb9421176d3 Mon Sep 17 00:00:00 2001 From: Roger Dingledine Date: Thu, 1 Apr 2004 03:44:49 +0000 Subject: [PATCH] let the circuit-launcher choose the exit node (if he wants) svn:r1428 --- src/or/circuit.c | 11 ++++++----- src/or/connection_edge.c | 2 +- src/or/main.c | 7 ++++--- src/or/onion.c | 17 ++++++++++++----- src/or/or.h | 4 ++-- src/or/rendservice.c | 2 +- 6 files changed, 26 insertions(+), 17 deletions(-) diff --git a/src/or/circuit.c b/src/or/circuit.c index 1222f43151..b0ca853a13 100644 --- a/src/or/circuit.c +++ b/src/or/circuit.c @@ -15,7 +15,7 @@ static void circuit_rep_hist_note_result(circuit_t *circ); static void circuit_is_ready(circuit_t *circ); static void circuit_failed(circuit_t *circ); -static circuit_t *circuit_establish_circuit(uint8_t purpose); +static circuit_t *circuit_establish_circuit(uint8_t purpose, const char *exit_nickname); unsigned long stats_n_relay_cells_relayed = 0; unsigned long stats_n_relay_cells_delivered = 0; @@ -1052,7 +1052,7 @@ static void circuit_failed(circuit_t *circ) { static int n_circuit_failures = 0; /* Launch a new circuit and return a pointer to it. Return NULL if you failed. */ -circuit_t *circuit_launch_new(uint8_t purpose) { +circuit_t *circuit_launch_new(uint8_t purpose, const char *exit_nickname) { if(!(options.SocksPort||options.RunTesting)) /* no need for circuits. */ return NULL; @@ -1063,7 +1063,7 @@ circuit_t *circuit_launch_new(uint8_t purpose) { } /* try a circ. if it fails, circuit_mark_for_close will increment n_circuit_failures */ - return circuit_establish_circuit(purpose); + return circuit_establish_circuit(purpose, exit_nickname); } void circuit_increment_failure_count(void) { @@ -1075,14 +1075,15 @@ void circuit_reset_failure_count(void) { n_circuit_failures = 0; } -static circuit_t *circuit_establish_circuit(uint8_t purpose) { +static circuit_t *circuit_establish_circuit(uint8_t purpose, + const char *exit_nickname) { routerinfo_t *firsthop; connection_t *n_conn; circuit_t *circ; circ = circuit_new(0, NULL); /* sets circ->p_circ_id and circ->p_conn */ circ->state = CIRCUIT_STATE_OR_WAIT; - circ->build_state = onion_new_cpath_build_state(); + circ->build_state = onion_new_cpath_build_state(exit_nickname); circ->purpose = purpose; if (! circ->build_state) { diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 08c009bd9c..7352c584b0 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -758,7 +758,7 @@ static int connection_ap_handshake_attach_circuit(connection_t *conn, case 0: /* no useful circuits available */ if(!circuit_get_newest(conn, 0, must_be_clean)) { /* is one already on the way? */ - circuit_launch_new(CIRCUIT_PURPOSE_C_GENERAL); + circuit_launch_new(CIRCUIT_PURPOSE_C_GENERAL, NULL); } return 0; default: /* case 1, it succeeded, great */ diff --git a/src/or/main.c b/src/or/main.c index 44e734f9a6..76d9bc7436 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -391,11 +391,12 @@ static void run_scheduled_events(time_t now) { circuit_reset_failure_count(); if(circ && circ->timestamp_dirty) { log_fn(LOG_INFO,"Youngest circuit dirty; launching replacement."); - circuit_launch_new(CIRCUIT_PURPOSE_C_GENERAL); /* make a new circuit */ + /* make a new circuit */ + circuit_launch_new(CIRCUIT_PURPOSE_C_GENERAL, NULL); } else if (options.RunTesting && circ && circ->timestamp_created + TESTING_CIRCUIT_INTERVAL < now) { log_fn(LOG_INFO,"Creating a new testing circuit."); - circuit_launch_new(CIRCUIT_PURPOSE_C_GENERAL); + circuit_launch_new(CIRCUIT_PURPOSE_C_GENERAL, NULL); } time_to_new_circuit = now + options.NewCircuitPeriod; } @@ -404,7 +405,7 @@ static void run_scheduled_events(time_t now) { /* if there's no open circ, and less than 3 are on the way, * go ahead and try another. */ - circuit_launch_new(CIRCUIT_PURPOSE_C_GENERAL); + circuit_launch_new(CIRCUIT_PURPOSE_C_GENERAL, NULL); } } diff --git a/src/or/onion.c b/src/or/onion.c index 64f2581c22..71e2a31b43 100644 --- a/src/or/onion.c +++ b/src/or/onion.c @@ -347,7 +347,7 @@ static routerinfo_t *choose_good_exit_server(routerlist_t *dir) return NULL; } -cpath_build_state_t *onion_new_cpath_build_state(void) { +cpath_build_state_t *onion_new_cpath_build_state(const char *exit_nickname) { routerlist_t *rl; int r; cpath_build_state_t *info; @@ -357,12 +357,19 @@ cpath_build_state_t *onion_new_cpath_build_state(void) { r = new_route_len(options.PathlenCoinWeight, rl->routers, rl->n_routers); if (r < 0) return NULL; - exit = choose_good_exit_server(rl); - if(!exit) - return NULL; info = tor_malloc(sizeof(cpath_build_state_t)); info->desired_path_len = r; - info->chosen_exit = tor_strdup(exit->nickname); + if(exit_nickname) { /* the circuit-builder pre-requested one */ + log_fn(LOG_INFO,"Using requested exit node '%s'", exit_nickname); + info->chosen_exit = tor_strdup(exit_nickname); + } else { /* we have to decide one */ + exit = choose_good_exit_server(rl); + if(!exit) { + tor_free(info); + return NULL; + } + info->chosen_exit = tor_strdup(exit->nickname); + } return info; } diff --git a/src/or/or.h b/src/or/or.h index 907010ec9c..8c343c9d3e 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -689,7 +689,7 @@ void circuit_log_path(int severity, circuit_t *circ); void circuit_dump_by_conn(connection_t *conn, int severity); void circuit_expire_unused_circuits(void); -circuit_t *circuit_launch_new(uint8_t purpose); +circuit_t *circuit_launch_new(uint8_t purpose, const char *exit_nickname); void circuit_increment_failure_count(void); void circuit_reset_failure_count(void); void circuit_n_conn_open(connection_t *or_conn); @@ -916,7 +916,7 @@ int onion_skin_client_handshake(crypto_dh_env_t *handshake_state, char *key_out, int key_out_len); -cpath_build_state_t *onion_new_cpath_build_state(void); +cpath_build_state_t *onion_new_cpath_build_state(const char *exit_nickname); /********************************* router.c ***************************/ diff --git a/src/or/rendservice.c b/src/or/rendservice.c index fb468b5ba6..d0656a2e36 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -363,7 +363,7 @@ int rend_services_init(void) { // for each intro point, { - circ = circuit_launch_new(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO); + //circ = circuit_launch_new(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO, intro->nickname); // tell circ which hidden service this is about }