aboutsummaryrefslogtreecommitdiff
path: root/src/or/connection_edge.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/or/connection_edge.c')
-rw-r--r--src/or/connection_edge.c119
1 files changed, 61 insertions, 58 deletions
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 5fdd7539ba..f8a319beaa 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -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;