From 05b99bcf7dad3be0c205d813269e21080a1d5373 Mon Sep 17 00:00:00 2001 From: Roger Dingledine Date: Thu, 1 Apr 2004 20:33:29 +0000 Subject: [PATCH] alice chooses her rendezvous node from all running routers and she can set preferences in her options svn:r1433 --- src/or/circuit.c | 7 ++---- src/or/config.c | 6 +++++ src/or/connection_edge.c | 18 ++++++++++++-- src/or/onion.c | 54 +++++++++++++++++++++++++++++++++------- src/or/or.h | 10 ++++++-- 5 files changed, 77 insertions(+), 18 deletions(-) diff --git a/src/or/circuit.c b/src/or/circuit.c index 584005e016..08acf187b7 100644 --- a/src/or/circuit.c +++ b/src/or/circuit.c @@ -1057,9 +1057,6 @@ 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, const char *exit_nickname) { - if(!(options.SocksPort||options.RunTesting)) /* no need for circuits. */ - return NULL; - if(n_circuit_failures > 5) { /* too many failed circs in a row. don't try. */ // log_fn(LOG_INFO,"%d failures so far, not trying.",n_circuit_failures); return NULL; @@ -1086,11 +1083,11 @@ static circuit_t *circuit_establish_circuit(uint8_t purpose, 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(exit_nickname); + circ->build_state = onion_new_cpath_build_state(purpose, exit_nickname); circ->purpose = purpose; if (! circ->build_state) { - log_fn(LOG_INFO,"Generating cpath length failed."); + log_fn(LOG_INFO,"Generating cpath failed."); circuit_mark_for_close(circ); return NULL; } diff --git a/src/or/config.c b/src/or/config.c index eead3a594f..e5e5fc9c8e 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -205,6 +205,8 @@ static int config_assign(or_options_t *options, struct config_line_t *list) { config_compare(list, "RouterFile", CONFIG_TYPE_STRING, &options->RouterFile) || config_compare(list, "RunAsDaemon", CONFIG_TYPE_BOOL, &options->RunAsDaemon) || config_compare(list, "RecommendedVersions",CONFIG_TYPE_STRING, &options->RecommendedVersions) || + config_compare(list, "RendNodes", CONFIG_TYPE_STRING, &options->RendNodes) || + config_compare(list, "RendExcludeNodes",CONFIG_TYPE_STRING, &options->RendExcludeNodes) || config_compare(list, "SocksPort", CONFIG_TYPE_INT, &options->SocksPort) || config_compare(list, "SocksBindAddress",CONFIG_TYPE_STRING,&options->SocksBindAddress) || @@ -419,6 +421,8 @@ static void free_options(or_options_t *options) { tor_free(options->ExitNodes); tor_free(options->EntryNodes); tor_free(options->ExcludeNodes); + tor_free(options->RendNodes); + tor_free(options->RendExcludeNodes); tor_free(options->ExitPolicy); tor_free(options->SocksBindAddress); tor_free(options->ORBindAddress); @@ -436,6 +440,8 @@ static void init_options(or_options_t *options) { options->ExitNodes = tor_strdup(""); options->EntryNodes = tor_strdup(""); options->ExcludeNodes = tor_strdup(""); + options->RendNodes = tor_strdup(""); + options->RendExcludeNodes = tor_strdup(""); options->ExitPolicy = tor_strdup(""); options->SocksBindAddress = tor_strdup("127.0.0.1"); options->ORBindAddress = tor_strdup("0.0.0.0"); diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 7352c584b0..5fdd7539ba 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -201,6 +201,15 @@ int connection_edge_end(connection_t *conn, char reason, crypt_path_t *cpath_lay return 0; } +/* Make a relay cell out of 'relay_command' and 'payload', and + * send it onto the open circuit 'circ'. If it's a control cell, + * set fromconn to NULL, else it's the stream that's sending the + * relay cell. Use cpath_layer NULL if you're responding to the OP; + * If it's an outgoing cell it must specify the destination hop. + * + * If you can't send the cell, mark the circuit for close and + * return -1. Else return 0. + */ int connection_edge_send_command(connection_t *fromconn, circuit_t *circ, int relay_command, void *payload, int payload_len, crypt_path_t *cpath_layer) { @@ -738,8 +747,13 @@ static int connection_ap_handshake_process_socks(connection_t *conn) { /* see if we already have it cached */ if (rend_cache_lookup(socks->address, &descp, &desc_len) == 1) { - /* then pick and launch a rendezvous circuit */ - /* go into some other state */ + if(0){ //if a circuit already exists to this place, use it + + } else { + /* go into some other state maybe? */ + /* then launch a rendezvous circuit */ + circuit_launch_new(CIRCUIT_PURPOSE_C_ESTABLISH_REND, NULL); + } } else { /* initiate a dir hidserv desc lookup */ /* go into a state where you'll be notified of the answer */ diff --git a/src/or/onion.c b/src/or/onion.c index 71e2a31b43..1703d93ed2 100644 --- a/src/or/onion.c +++ b/src/or/onion.c @@ -4,6 +4,11 @@ #include "or.h" +/* prototypes for smartlist operations from routerlist.h + * they're here to prevent precedence issues with the .h files + */ +void router_add_running_routers_to_smartlist(smartlist_t *sl); + extern or_options_t options; /* command-line and config-file options */ static int count_acceptable_routers(routerinfo_t **rarray, int rarray_len); @@ -220,7 +225,34 @@ static int new_route_len(double cw, routerinfo_t **rarray, int rarray_len) { return routelen; } -static routerinfo_t *choose_good_exit_server(routerlist_t *dir) +static routerinfo_t *choose_good_exit_server_rend(routerlist_t *dir) +{ + smartlist_t *sl, *excludednodes; + routerinfo_t *choice; + + excludednodes = smartlist_create(); + add_nickname_list_to_smartlist(excludednodes,options.RendExcludeNodes); + + /* try the nodes in RendNodes first */ + sl = smartlist_create(); + add_nickname_list_to_smartlist(sl,options.RendNodes); + smartlist_subtract(sl,excludednodes); + choice = smartlist_choose(sl); + smartlist_free(sl); + if(!choice) { + sl = smartlist_create(); + router_add_running_routers_to_smartlist(sl); + smartlist_subtract(sl,excludednodes); + choice = smartlist_choose(sl); + smartlist_free(sl); + } + smartlist_free(excludednodes); + if(!choice) + log_fn(LOG_WARN,"No available nodes when trying to choose rendezvous point. Failing."); + return choice; +} + +static routerinfo_t *choose_good_exit_server_general(routerlist_t *dir) { int *n_supported; int i, j; @@ -347,7 +379,16 @@ static routerinfo_t *choose_good_exit_server(routerlist_t *dir) return NULL; } -cpath_build_state_t *onion_new_cpath_build_state(const char *exit_nickname) { +static routerinfo_t *choose_good_exit_server(uint8_t purpose, routerlist_t *dir) +{ + if(purpose == CIRCUIT_PURPOSE_C_GENERAL) + return choose_good_exit_server_general(dir); + else + return choose_good_exit_server_rend(dir); +} + +cpath_build_state_t *onion_new_cpath_build_state(uint8_t purpose, + const char *exit_nickname) { routerlist_t *rl; int r; cpath_build_state_t *info; @@ -357,13 +398,13 @@ cpath_build_state_t *onion_new_cpath_build_state(const char *exit_nickname) { r = new_route_len(options.PathlenCoinWeight, rl->routers, rl->n_routers); if (r < 0) return NULL; - info = tor_malloc(sizeof(cpath_build_state_t)); + info = tor_malloc_zero(sizeof(cpath_build_state_t)); info->desired_path_len = r; 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); + exit = choose_good_exit_server(purpose, rl); if(!exit) { tor_free(info); return NULL; @@ -407,11 +448,6 @@ static int count_acceptable_routers(routerinfo_t **rarray, int rarray_len) { return num; } -/* prototypes for smartlist operations from routerlist.h - * they're here to prevent precedence issues with the .h files - */ -void router_add_running_routers_to_smartlist(smartlist_t *sl); - static void remove_twins_from_smartlist(smartlist_t *sl, routerinfo_t *twin) { int i; routerinfo_t *r; diff --git a/src/or/or.h b/src/or/or.h index 4256296952..f93b96edb0 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -533,7 +533,7 @@ struct circuit_t { uint8_t state; uint8_t purpose; - /* The field rend_sevice: + /* The field rend_service: * holds hash of location-hidden service's PK if purpose is INTRO_POINT * or S_ESTABLISH_INTRO or S_RENDEZVOUSING; * holds y portion of y.onion (zero-padded) if purpose is C_INTRODUCING or @@ -570,9 +570,14 @@ typedef struct { char *Nickname; char *Address; char *PidFile; + char *ExitNodes; char *EntryNodes; char *ExcludeNodes; + + char *RendNodes; + char *RendExcludeNodes; + char *ExitPolicy; char *SocksBindAddress; char *ORBindAddress; @@ -919,7 +924,8 @@ 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(const char *exit_nickname); +cpath_build_state_t *onion_new_cpath_build_state(uint8_t purpose, + const char *exit_nickname); /********************************* router.c ***************************/