mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-11 05:33:47 +01:00
now circuit_get_newest returns an appropriate circ for your purpose
connection_ap_handshake_attach_circuit attaches to a circ of the right purpose add a skeletal rendclient.c svn:r1441
This commit is contained in:
parent
4cb21bab48
commit
f34e6da3e7
@ -7,8 +7,8 @@ bin_PROGRAMS = tor
|
||||
tor_SOURCES = buffers.c circuit.c command.c config.c \
|
||||
connection.c connection_edge.c connection_or.c \
|
||||
cpuworker.c directory.c dirserv.c dns.c main.c \
|
||||
onion.c rendcommon.c rendmid.c rendservice.c rephist.c \
|
||||
router.c routerlist.c \
|
||||
onion.c rendcommon.c rendclient.c rendmid.c \
|
||||
rendservice.c rephist.c router.c routerlist.c \
|
||||
tor_main.c
|
||||
|
||||
tor_LDADD = ../common/libor.a
|
||||
@ -16,8 +16,8 @@ tor_LDADD = ../common/libor.a
|
||||
test_SOURCES = buffers.c circuit.c command.c config.c \
|
||||
connection.c connection_edge.c connection_or.c \
|
||||
cpuworker.c directory.c dirserv.c dns.c main.c \
|
||||
onion.c rendcommon.c rendmid.c rendservice.c rephist.c \
|
||||
router.c routerlist.c \
|
||||
onion.c rendcommon.c rendclient.c rendmid.c \
|
||||
rendservice.c rephist.c router.c routerlist.c \
|
||||
test.c
|
||||
|
||||
test_LDADD = ../common/libor.a
|
||||
|
@ -255,34 +255,56 @@ circuit_t *circuit_get_by_conn(connection_t *conn) {
|
||||
* If !conn, return newest.
|
||||
*
|
||||
* If must_be_open, ignore circs not in CIRCUIT_STATE_OPEN.
|
||||
* If must_be_clean, ignore circs that have been used before.
|
||||
*
|
||||
* circ_purpose specifies what sort of circuit we must have.
|
||||
* If circ_purpose is not GENERAL, then conn must be defined.
|
||||
*/
|
||||
circuit_t *circuit_get_newest(connection_t *conn,
|
||||
int must_be_open, int must_be_clean) {
|
||||
int must_be_open, uint8_t circ_purpose) {
|
||||
circuit_t *circ, *newest=NULL, *leastdirty=NULL;
|
||||
routerinfo_t *exitrouter;
|
||||
|
||||
for (circ=global_circuitlist;circ;circ = circ->next) {
|
||||
if (!circ->cpath)
|
||||
continue; /* this circ doesn't start at us */
|
||||
if (circ->purpose != CIRCUIT_PURPOSE_C_GENERAL)
|
||||
continue; /* don't pick rendezvous circuits */
|
||||
if (must_be_open && (circ->state != CIRCUIT_STATE_OPEN || !circ->n_conn))
|
||||
continue; /* ignore non-open circs */
|
||||
if (circ->marked_for_close)
|
||||
continue;
|
||||
|
||||
if (circ->purpose != circ_purpose)
|
||||
continue;
|
||||
|
||||
#if 0
|
||||
if (must_be_clean && circ->timestamp_dirty)
|
||||
continue; /* ignore dirty circs */
|
||||
#endif
|
||||
|
||||
if(conn) {
|
||||
/* decide if this circ is suitable for this conn */
|
||||
|
||||
if(circ->state == CIRCUIT_STATE_OPEN && circ->n_conn) /* open */
|
||||
exitrouter = router_get_by_addr_port(circ->cpath->prev->addr, circ->cpath->prev->port);
|
||||
exitrouter = router_get_by_addr_port(circ->cpath->prev->addr,
|
||||
circ->cpath->prev->port);
|
||||
else /* not open */
|
||||
exitrouter = router_get_by_nickname(circ->build_state->chosen_exit);
|
||||
if(!exitrouter || connection_ap_can_use_exit(conn, exitrouter) == ADDR_POLICY_REJECTED) {
|
||||
/* can't exit from this router */
|
||||
continue;
|
||||
|
||||
if(!exitrouter)
|
||||
continue; /* this circuit is screwed and doesn't know it yet */
|
||||
|
||||
if(circ_purpose == CIRCUIT_PURPOSE_C_GENERAL) {
|
||||
if(connection_ap_can_use_exit(conn, exitrouter) == ADDR_POLICY_REJECTED) {
|
||||
/* can't exit from this router */
|
||||
continue;
|
||||
}
|
||||
} else { /* not general */
|
||||
if(rend_cmp_service_ids(conn->socks_request->address, circ->rend_service)) {
|
||||
/* this circ is not for this conn */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!newest || newest->timestamp_created < circ->timestamp_created) {
|
||||
newest = circ;
|
||||
}
|
||||
@ -1033,11 +1055,11 @@ static void circuit_is_ready(circuit_t *circ) {
|
||||
break;
|
||||
case CIRCUIT_PURPOSE_C_INTRODUCING:
|
||||
/* at Alice, connecting to intro point */
|
||||
// alice sends introduce1 relay cell
|
||||
rend_client_intro_is_ready(circ);
|
||||
break;
|
||||
case CIRCUIT_PURPOSE_C_ESTABLISH_REND:
|
||||
/* at Alice, waiting for Bob */
|
||||
// alice launches a circuit to bob's intro point
|
||||
rend_client_rendezvous_is_ready(circ);
|
||||
break;
|
||||
case CIRCUIT_PURPOSE_S_CONNECT_REND:
|
||||
/* at Bob, connecting to rend point */
|
||||
@ -1246,9 +1268,6 @@ int circuit_send_next_onion_skin(circuit_t *circ) {
|
||||
}
|
||||
circuit_rep_hist_note_result(circ);
|
||||
circuit_is_ready(circ); /* do other actions as necessary */
|
||||
/* Tell any AP connections that have been waiting for a new
|
||||
* circuit that one is ready. */
|
||||
connection_ap_attach_pending();
|
||||
return 0;
|
||||
} else if (r<0) {
|
||||
log_fn(LOG_INFO,"Unable to extend circuit path.");
|
||||
|
@ -9,10 +9,7 @@ extern or_options_t options; /* command-line and config-file options */
|
||||
extern char *conn_state_to_string[][_CONN_TYPE_MAX+1];
|
||||
|
||||
static int connection_ap_handshake_process_socks(connection_t *conn);
|
||||
static int connection_ap_handshake_attach_circuit(connection_t *conn,
|
||||
int must_be_clean);
|
||||
static int connection_ap_handshake_attach_circuit_helper(connection_t *conn,
|
||||
int must_be_clean);
|
||||
static int connection_ap_handshake_attach_circuit(connection_t *conn);
|
||||
static void connection_ap_handshake_send_begin(connection_t *ap_conn, circuit_t *circ);
|
||||
|
||||
static int connection_exit_begin_conn(cell_t *cell, circuit_t *circ);
|
||||
@ -377,9 +374,10 @@ int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
|
||||
memcpy(&addr, cell->payload+RELAY_HEADER_SIZE+1, 4);
|
||||
addr = ntohl(addr);
|
||||
client_dns_set_entry(conn->socks_request->address, addr);
|
||||
/* conn->purpose is still set to general */
|
||||
conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
|
||||
/* attaching to a dirty circuit is fine */
|
||||
if(connection_ap_handshake_attach_circuit(conn, 0) >= 0)
|
||||
if(connection_ap_handshake_attach_circuit(conn) >= 0)
|
||||
return 0;
|
||||
/* else, conn will get closed below */
|
||||
}
|
||||
@ -639,6 +637,7 @@ void connection_ap_expire_beginning(void) {
|
||||
conn->has_sent_end = 0;
|
||||
/* move it back into 'pending' state. */
|
||||
conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
|
||||
/* conn->purpose is still set to general */
|
||||
circuit_detach_stream(circ, conn);
|
||||
/* kludge to make us not try this circuit again, yet to allow
|
||||
* current streams on it to survive if they can: make it
|
||||
@ -648,7 +647,7 @@ void connection_ap_expire_beginning(void) {
|
||||
/* give our stream another 15 seconds to try */
|
||||
conn->timestamp_lastread += 15;
|
||||
/* attaching to a dirty circuit is fine */
|
||||
if(connection_ap_handshake_attach_circuit(conn,0)<0) {
|
||||
if(connection_ap_handshake_attach_circuit(conn)<0) {
|
||||
/* it will never work */
|
||||
/* Don't need to send end -- we're not connected */
|
||||
connection_mark_for_close(conn, 0);
|
||||
@ -672,7 +671,7 @@ void connection_ap_attach_pending(void)
|
||||
conn->state != AP_CONN_STATE_CIRCUIT_WAIT)
|
||||
continue;
|
||||
/* attaching to a dirty circuit is fine */
|
||||
if(connection_ap_handshake_attach_circuit(conn,0) < 0) {
|
||||
if(connection_ap_handshake_attach_circuit(conn) < 0) {
|
||||
/* -1 means it will never work */
|
||||
/* Don't send end; there is no 'other side' yet */
|
||||
connection_mark_for_close(conn,0);
|
||||
@ -738,8 +737,9 @@ static int connection_ap_handshake_process_socks(connection_t *conn) {
|
||||
if (rend_parse_rendezvous_address(socks->address) < 0) {
|
||||
/* normal request */
|
||||
conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
|
||||
conn->purpose = AP_PURPOSE_GENERAL;
|
||||
/* attaching to a dirty circuit is fine */
|
||||
return connection_ap_handshake_attach_circuit(conn,0);
|
||||
return connection_ap_handshake_attach_circuit(conn);
|
||||
} else {
|
||||
/* it's a hidden-service request */
|
||||
const char *descp;
|
||||
@ -747,59 +747,59 @@ 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) {
|
||||
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);
|
||||
}
|
||||
conn->purpose = AP_PURPOSE_RENDPOINT_WAIT;
|
||||
return connection_ap_handshake_attach_circuit(conn);
|
||||
//circuit_launch_new(CIRCUIT_PURPOSE_C_ESTABLISH_REND, NULL);
|
||||
} else {
|
||||
conn->purpose = AP_PURPOSE_RENDDESC_WAIT;
|
||||
/* initiate a dir hidserv desc lookup */
|
||||
/* go into a state where you'll be notified of the answer */
|
||||
directory_initiate_command(router_pick_directory_server(),
|
||||
DIR_PURPOSE_FETCH_RENDDESC,
|
||||
socks->address, strlen(socks->address));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int connection_ap_handshake_attach_circuit(connection_t *conn,
|
||||
int must_be_clean) {
|
||||
/* try attaching. launch new circuit if needed.
|
||||
* return -1 if conn needs to die, else 0. */
|
||||
switch(connection_ap_handshake_attach_circuit_helper(conn, must_be_clean)) {
|
||||
case -1: /* it will never work */
|
||||
return -1;
|
||||
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, NULL);
|
||||
}
|
||||
return 0;
|
||||
default: /* case 1, it succeeded, great */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Try to find a safe live circuit for CONN_TYPE_AP connection conn. If
|
||||
* we don't find one: if conn cannot be handled by any known nodes,
|
||||
* warn and return -1; else tell conn to stop reading and return 0.
|
||||
* Otherwise, associate conn with a safe live circuit, start
|
||||
* sending a BEGIN cell down the circuit, and return 1.
|
||||
* warn and return -1 (conn needs to die);
|
||||
* else launch new circuit and return 0.
|
||||
* Otherwise, associate conn with a safe live circuit, do the
|
||||
* right next step, and return 1.
|
||||
*/
|
||||
static int connection_ap_handshake_attach_circuit_helper(connection_t *conn,
|
||||
int must_be_clean) {
|
||||
static int connection_ap_handshake_attach_circuit(connection_t *conn) {
|
||||
circuit_t *circ;
|
||||
uint32_t addr;
|
||||
int must_be_clean;
|
||||
uint8_t desired_circuit_purpose;
|
||||
|
||||
assert(conn);
|
||||
assert(conn->type == CONN_TYPE_AP);
|
||||
assert(conn->state == AP_CONN_STATE_CIRCUIT_WAIT);
|
||||
assert(conn->socks_request);
|
||||
|
||||
switch(conn->purpose) {
|
||||
case AP_PURPOSE_GENERAL:
|
||||
case AP_PURPOSE_RENDDESC_WAIT:
|
||||
desired_circuit_purpose = CIRCUIT_PURPOSE_C_GENERAL;
|
||||
break;
|
||||
case AP_PURPOSE_RENDPOINT_WAIT:
|
||||
desired_circuit_purpose = CIRCUIT_PURPOSE_C_ESTABLISH_REND;
|
||||
break;
|
||||
case AP_PURPOSE_INTROPOINT_WAIT:
|
||||
desired_circuit_purpose = CIRCUIT_PURPOSE_C_INTRODUCING;
|
||||
break;
|
||||
default:
|
||||
assert(0); /* never reached */
|
||||
}
|
||||
|
||||
/* find the circuit that we should use, if there is one. */
|
||||
circ = circuit_get_newest(conn, 1, must_be_clean);
|
||||
circ = circuit_get_newest(conn, 1, desired_circuit_purpose);
|
||||
|
||||
if(!circ) {
|
||||
//XXX
|
||||
log_fn(LOG_INFO,"No safe circuit ready for edge connection; delaying.");
|
||||
addr = client_dns_lookup_entry(conn->socks_request->address);
|
||||
if(router_exit_policy_all_routers_reject(addr, conn->socks_request->port)) {
|
||||
@ -807,29 +807,37 @@ static int connection_ap_handshake_attach_circuit_helper(connection_t *conn,
|
||||
conn->socks_request->address, conn->socks_request->port);
|
||||
return -1;
|
||||
}
|
||||
connection_stop_reading(conn); /* don't read until the connected cell arrives */
|
||||
if(!circuit_get_newest(conn, 0, desired_circuit_purpose)) {
|
||||
/* is one already on the way? */
|
||||
circuit_launch_new(desired_circuit_purpose, NULL);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
connection_start_reading(conn);
|
||||
|
||||
/* here, print the circ's path. so people can figure out which circs are sucking. */
|
||||
circuit_log_path(LOG_INFO,circ);
|
||||
|
||||
if(!circ->timestamp_dirty)
|
||||
circ->timestamp_dirty = time(NULL);
|
||||
|
||||
/* add it into the linked list of streams on this circuit */
|
||||
log_fn(LOG_DEBUG,"attaching new conn to circ. n_circ_id %d.", circ->n_circ_id);
|
||||
conn->next_stream = circ->p_streams;
|
||||
/* assert_connection_ok(conn, time(NULL)); */
|
||||
circ->p_streams = conn;
|
||||
switch(conn->purpose) {
|
||||
case AP_PURPOSE_GENERAL:
|
||||
case AP_PURPOSE_RENDDESC_WAIT:
|
||||
/* add it into the linked list of streams on this circuit */
|
||||
log_fn(LOG_DEBUG,"attaching new conn to circ. n_circ_id %d.", circ->n_circ_id);
|
||||
conn->next_stream = circ->p_streams;
|
||||
/* assert_connection_ok(conn, time(NULL)); */
|
||||
circ->p_streams = conn;
|
||||
|
||||
assert(circ->cpath && circ->cpath->prev);
|
||||
assert(circ->cpath->prev->state == CPATH_STATE_OPEN);
|
||||
conn->cpath_layer = circ->cpath->prev;
|
||||
assert(circ->cpath && circ->cpath->prev);
|
||||
assert(circ->cpath->prev->state == CPATH_STATE_OPEN);
|
||||
conn->cpath_layer = circ->cpath->prev;
|
||||
|
||||
connection_ap_handshake_send_begin(conn, circ);
|
||||
connection_ap_handshake_send_begin(conn, circ);
|
||||
break;
|
||||
case AP_PURPOSE_RENDPOINT_WAIT:
|
||||
case AP_PURPOSE_INTROPOINT_WAIT:
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -894,11 +902,6 @@ static void connection_ap_handshake_send_begin(connection_t *ap_conn, circuit_t
|
||||
ap_conn->package_window = STREAMWINDOW_START;
|
||||
ap_conn->deliver_window = STREAMWINDOW_START;
|
||||
ap_conn->state = AP_CONN_STATE_CONNECT_WAIT;
|
||||
/* XXX Right now, we rely on the socks client not to send us any data
|
||||
* XXX until we've sent back a socks reply. (If it does, we could wind
|
||||
* XXX up packaging that data and sending it to the exit, then later having
|
||||
* XXX the exit refuse us.)
|
||||
*/
|
||||
log_fn(LOG_INFO,"Address/port sent, ap socket %d, n_circ_id %d",ap_conn->s,circ->n_circ_id);
|
||||
return;
|
||||
}
|
||||
@ -947,7 +950,7 @@ int connection_ap_make_bridge(char *address, uint16_t port) {
|
||||
connection_start_reading(conn);
|
||||
|
||||
/* attaching to a dirty circuit is fine */
|
||||
if (connection_ap_handshake_attach_circuit(conn, 0) < 0) {
|
||||
if (connection_ap_handshake_attach_circuit(conn) < 0) {
|
||||
connection_mark_for_close(conn, 0);
|
||||
close(fd[1]);
|
||||
return -1;
|
||||
|
@ -275,11 +275,11 @@ int connection_dir_process_inbuf(connection_t *conn) {
|
||||
/* alice's ap_stream is just going to have to time out. */
|
||||
} else {
|
||||
/* success. notify pending connections about this. */
|
||||
//alice_notify_desc_fetched(conn->rend_query);
|
||||
rend_client_desc_fetched(conn->rend_query);
|
||||
}
|
||||
break;
|
||||
case 404:
|
||||
//alice_notify_desc_not_fetched(conn->rend_query);
|
||||
rend_client_desc_not_fetched(conn->rend_query);
|
||||
break;
|
||||
case 400:
|
||||
log_fn(LOG_WARN,"http status 400 (bad request). Dirserver didn't like our rendezvous query?");
|
||||
|
@ -384,7 +384,7 @@ static void run_scheduled_events(time_t now) {
|
||||
/* Build a new test circuit every 5 minutes */
|
||||
#define TESTING_CIRCUIT_INTERVAL 300
|
||||
|
||||
circ = circuit_get_newest(NULL, 1, 0);
|
||||
circ = circuit_get_newest(NULL, 1, CIRCUIT_PURPOSE_C_GENERAL);
|
||||
if(time_to_new_circuit < now) {
|
||||
client_dns_clean();
|
||||
circuit_expire_unused_circuits();
|
||||
|
@ -8,6 +8,7 @@
|
||||
* they're here to prevent precedence issues with the .h files
|
||||
*/
|
||||
void router_add_running_routers_to_smartlist(smartlist_t *sl);
|
||||
void add_nickname_list_to_smartlist(smartlist_t *sl, char *list);
|
||||
|
||||
extern or_options_t options; /* command-line and config-file options */
|
||||
|
||||
@ -166,32 +167,6 @@ int onionskin_answer(circuit_t *circ, unsigned char *payload, unsigned char *key
|
||||
|
||||
extern int has_fetched_directory;
|
||||
|
||||
static void add_nickname_list_to_smartlist(smartlist_t *sl, char *list) {
|
||||
char *start,*end;
|
||||
char nick[MAX_NICKNAME_LEN];
|
||||
routerinfo_t *router;
|
||||
|
||||
while(isspace((int)*list) || *list==',') list++;
|
||||
|
||||
start = list;
|
||||
while(*start) {
|
||||
end=start; while(*end && !isspace((int)*end) && *end != ',') end++;
|
||||
memcpy(nick,start,end-start);
|
||||
nick[end-start] = 0; /* null terminate it */
|
||||
router = router_get_by_nickname(nick);
|
||||
if (router) {
|
||||
if (router->is_running)
|
||||
smartlist_add(sl,router);
|
||||
else
|
||||
log_fn(LOG_INFO,"Nickname list includes '%s' which is known but down.",nick);
|
||||
} else
|
||||
log_fn(has_fetched_directory ? LOG_WARN : LOG_INFO,
|
||||
"Nickname list includes '%s' which isn't a known router.",nick);
|
||||
while(isspace((int)*end) || *end==',') end++;
|
||||
start = end;
|
||||
}
|
||||
}
|
||||
|
||||
static int new_route_len(double cw, routerinfo_t **rarray, int rarray_len) {
|
||||
int num_acceptable_routers;
|
||||
int routelen;
|
||||
@ -227,33 +202,6 @@ static int new_route_len(double cw, routerinfo_t **rarray, int rarray_len) {
|
||||
return routelen;
|
||||
}
|
||||
|
||||
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;
|
||||
@ -386,7 +334,7 @@ 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);
|
||||
return router_choose_random_node(dir, options.RendNodes, options.RendExcludeNodes);
|
||||
}
|
||||
|
||||
cpath_build_state_t *onion_new_cpath_build_state(uint8_t purpose,
|
||||
|
18
src/or/or.h
18
src/or/or.h
@ -170,10 +170,13 @@
|
||||
#define AP_CONN_STATE_OPEN 8
|
||||
#define _AP_CONN_STATE_MAX 8
|
||||
|
||||
/* only used if state==CIRCUIT_WAIT */
|
||||
#define _AP_PURPOSE_MIN 1
|
||||
#define AP_PURPOSE_GENERAL 1
|
||||
#define AP_PURPOSE_
|
||||
#define _AP_PURPOSE_MAX 1
|
||||
#define AP_PURPOSE_RENDDESC_WAIT 2
|
||||
#define AP_PURPOSE_RENDPOINT_WAIT 3
|
||||
#define AP_PURPOSE_INTROPOINT_WAIT 4
|
||||
#define _AP_PURPOSE_MAX 3
|
||||
|
||||
#define _DIR_CONN_STATE_MIN 1
|
||||
#define DIR_CONN_STATE_CONNECTING 1
|
||||
@ -691,7 +694,7 @@ int _circuit_mark_for_close(circuit_t *circ);
|
||||
circuit_t *circuit_get_by_circ_id_conn(uint16_t circ_id, connection_t *conn);
|
||||
circuit_t *circuit_get_by_conn(connection_t *conn);
|
||||
circuit_t *circuit_get_newest(connection_t *conn,
|
||||
int must_be_open, int must_be_clean);
|
||||
int must_be_open, uint8_t conn_purpose);
|
||||
circuit_t *circuit_get_next_by_service_and_purpose(circuit_t *circuit,
|
||||
const char *servid, int purpose);
|
||||
circuit_t *circuit_get_rendezvous(const char *cookie);
|
||||
@ -972,6 +975,7 @@ int router_dump_router_to_string(char *s, int maxlen, routerinfo_t *router,
|
||||
/********************************* routerlist.c ***************************/
|
||||
|
||||
routerinfo_t *router_pick_directory_server(void);
|
||||
routerinfo_t *router_choose_random_node(routerlist_t *dir, char *preferred, char *excluded);
|
||||
routerinfo_t *router_get_by_addr_port(uint32_t addr, uint16_t port);
|
||||
routerinfo_t *router_get_by_link_pk(crypto_pk_env_t *pk);
|
||||
routerinfo_t *router_get_by_nickname(char *nickname);
|
||||
@ -1016,10 +1020,15 @@ void rep_hist_note_connect_succeeded(const char* nickname, time_t when);
|
||||
void rep_hist_note_disconnect(const char* nickname, time_t when);
|
||||
void rep_hist_note_connection_died(const char* nickname, time_t when);
|
||||
void rep_hist_note_extend_succeeded(const char *from_name,
|
||||
const char *to_name);
|
||||
const char *to_name);
|
||||
void rep_hist_note_extend_failed(const char *from_name, const char *to_name);
|
||||
void rep_hist_dump_stats(time_t now, int severity);
|
||||
|
||||
/********************************* rendclient.c ***************************/
|
||||
|
||||
void rend_client_desc_fetched(char *query);
|
||||
void rend_client_desc_not_fetched(char *query);
|
||||
|
||||
/********************************* rendcommon.c ***************************/
|
||||
|
||||
typedef struct rend_service_descriptor_t {
|
||||
@ -1036,6 +1045,7 @@ int rend_encode_service_descriptor(rend_service_descriptor_t *desc,
|
||||
int *len_out);
|
||||
rend_service_descriptor_t *rend_parse_service_descriptor(const char *str, int len);
|
||||
int rend_get_service_id(crypto_pk_env_t *pk, char *out);
|
||||
int rend_cmp_service_ids(char *one, char *two);
|
||||
|
||||
void rend_cache_init(void);
|
||||
void rend_cache_clean(void);
|
||||
|
50
src/or/rendclient.c
Normal file
50
src/or/rendclient.c
Normal file
@ -0,0 +1,50 @@
|
||||
/* Copyright 2004 Roger Dingledine */
|
||||
/* See LICENSE for licensing information */
|
||||
/* $Id$ */
|
||||
|
||||
#include "or.h"
|
||||
|
||||
/* send the introduce cell */
|
||||
void
|
||||
rend_client_intro_is_ready()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* send the rendezvous cell */
|
||||
void
|
||||
rend_client_rendezvous_is_ready()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* bob sent us a rendezvous cell, join the circs. */
|
||||
void
|
||||
rend_client_rendezvous()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void rend_client_desc_fetched(char *query) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
void rend_client_desc_not_fetched(char *query) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
mode:c
|
||||
indent-tabs-mode:nil
|
||||
c-basic-offset:2
|
||||
End:
|
||||
*/
|
@ -121,6 +121,10 @@ int rend_get_service_id(crypto_pk_env_t *pk, char *out)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rend_cmp_service_ids(char *one, char *two) {
|
||||
return strcasecmp(one,two);
|
||||
}
|
||||
|
||||
/* ==== Rendezvous service descriptor cache. */
|
||||
#define REND_CACHE_MAX_AGE 24*60*60
|
||||
#define REND_CACHE_MAX_SKEW 60*60
|
||||
|
@ -20,7 +20,7 @@ typedef struct rend_service_port_config_t {
|
||||
*/
|
||||
typedef struct rend_service_t {
|
||||
/* Fields specified in config file */
|
||||
char *directory;
|
||||
char *directory; /* where in the filesystem it stores it */
|
||||
smartlist_t *ports;
|
||||
char *intro_nodes;
|
||||
char *intro_exclude_nodes;
|
||||
|
@ -191,6 +191,32 @@ static routerinfo_t *router_pick_directory_server_impl(void) {
|
||||
return dirserver;
|
||||
}
|
||||
|
||||
void add_nickname_list_to_smartlist(smartlist_t *sl, char *list) {
|
||||
char *start,*end;
|
||||
char nick[MAX_NICKNAME_LEN];
|
||||
routerinfo_t *router;
|
||||
|
||||
while(isspace((int)*list) || *list==',') list++;
|
||||
|
||||
start = list;
|
||||
while(*start) {
|
||||
end=start; while(*end && !isspace((int)*end) && *end != ',') end++;
|
||||
memcpy(nick,start,end-start);
|
||||
nick[end-start] = 0; /* null terminate it */
|
||||
router = router_get_by_nickname(nick);
|
||||
if (router) {
|
||||
if (router->is_running)
|
||||
smartlist_add(sl,router);
|
||||
else
|
||||
log_fn(LOG_INFO,"Nickname list includes '%s' which is known but down.",nick);
|
||||
} else
|
||||
log_fn(has_fetched_directory ? LOG_WARN : LOG_INFO,
|
||||
"Nickname list includes '%s' which isn't a known router.",nick);
|
||||
while(isspace((int)*end) || *end==',') end++;
|
||||
start = end;
|
||||
}
|
||||
}
|
||||
|
||||
void router_add_running_routers_to_smartlist(smartlist_t *sl) {
|
||||
routerinfo_t *router;
|
||||
int i;
|
||||
@ -207,6 +233,33 @@ void router_add_running_routers_to_smartlist(smartlist_t *sl) {
|
||||
}
|
||||
}
|
||||
|
||||
routerinfo_t *router_choose_random_node(routerlist_t *dir, char *preferred, char *excluded)
|
||||
{
|
||||
smartlist_t *sl, *excludednodes;
|
||||
routerinfo_t *choice;
|
||||
|
||||
excludednodes = smartlist_create();
|
||||
add_nickname_list_to_smartlist(excludednodes,excluded);
|
||||
|
||||
/* try the nodes in RendNodes first */
|
||||
sl = smartlist_create();
|
||||
add_nickname_list_to_smartlist(sl,preferred);
|
||||
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 node. Failing.");
|
||||
return choice;
|
||||
}
|
||||
|
||||
routerinfo_t *router_get_by_addr_port(uint32_t addr, uint16_t port) {
|
||||
int i;
|
||||
routerinfo_t *router;
|
||||
|
Loading…
Reference in New Issue
Block a user