aboutsummaryrefslogtreecommitdiff
path: root/src/or/connection_ap.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/or/connection_ap.c')
-rw-r--r--src/or/connection_ap.c51
1 files changed, 31 insertions, 20 deletions
diff --git a/src/or/connection_ap.c b/src/or/connection_ap.c
index 838fe737e..a680f5025 100644
--- a/src/or/connection_ap.c
+++ b/src/or/connection_ap.c
@@ -191,7 +191,7 @@ int ap_handshake_establish_circuit(connection_t *conn, unsigned int *route, int
log(LOG_DEBUG,"ap_handshake_establish_circuit(): Looking for firsthop '%s:%u'",
firsthop->address,firsthop->or_port);
n_conn = connection_twin_get_by_addr_port(firsthop->addr,firsthop->or_port);
- if(!n_conn) { /* not currently connected */
+ if(!n_conn || n_conn->state != OR_CONN_STATE_OPEN) { /* not currently connected */
circ->n_addr = firsthop->addr;
circ->n_port = firsthop->or_port;
if(global_role & ROLE_OR_CONNECT_ALL) { /* we would be connected if he were up. but he's not. */
@@ -199,14 +199,15 @@ int ap_handshake_establish_circuit(connection_t *conn, unsigned int *route, int
circuit_close(circ);
return -1;
}
-
- /* ok, launch the connection */
- n_conn = connect_to_router_as_op(firsthop);
- if(!n_conn) { /* connect failed, forget the whole thing */
- log(LOG_DEBUG,"ap_handshake_establish_circuit(): connect to firsthop failed. Closing.");
- circuit_close(circ);
- return -1;
- }
+
+ if(!n_conn) { /* launch the connection */
+ n_conn = connect_to_router_as_op(firsthop);
+ if(!n_conn) { /* connect failed, forget the whole thing */
+ log(LOG_DEBUG,"ap_handshake_establish_circuit(): connect to firsthop failed. Closing.");
+ circuit_close(circ);
+ return -1;
+ }
+ }
conn->state = AP_CONN_STATE_OR_WAIT;
connection_stop_reading(conn); /* Stop listening for input from the AP! */
return 0; /* return success. The onion/circuit/etc will be taken care of automatically
@@ -219,21 +220,31 @@ int ap_handshake_establish_circuit(connection_t *conn, unsigned int *route, int
}
}
-/* find the circ that's waiting on me, if any, and get it to send its onion */
-int ap_handshake_n_conn_open(connection_t *or_conn) {
+/* find circuits that are waiting on me, if any, and get them to send the onion */
+void ap_handshake_n_conn_open(connection_t *or_conn) {
circuit_t *circ;
+ connection_t *p_conn;
log(LOG_DEBUG,"ap_handshake_n_conn_open(): Starting.");
- circ = circuit_get_by_naddr_nport(or_conn->addr, or_conn->port);
- if(!circ)
- return 0; /* i'm ok with that. no need to close the connection or anything. */
-
- if(circ->p_conn->state != AP_CONN_STATE_OR_WAIT) {
- log(LOG_DEBUG,"Bug: ap_handshake_n_conn_open() got an ap_conn not in OR_WAIT state.");
+ circ = circuit_enumerate_by_naddr_nport(NULL, or_conn->addr, or_conn->port);
+ for(;;) {
+ if(!circ)
+ return;
+
+ p_conn = circ->p_conn;
+ if(p_conn->state != AP_CONN_STATE_OR_WAIT) {
+ log(LOG_WARNING,"Bug: ap_handshake_n_conn_open() got an ap_conn not in OR_WAIT state.");
+ }
+ connection_start_reading(p_conn); /* resume listening for reads */
+ log(LOG_DEBUG,"ap_handshake_n_conn_open(): Found circ, sending onion.");
+ if(ap_handshake_send_onion(p_conn, or_conn, circ)<0) {
+ log(LOG_DEBUG,"ap_handshake_n_conn_open(): circuit marked for closing.");
+ p_conn->marked_for_close = 1;
+ return; /* XXX will want to try the rest too */
+ } else {
+ circ = circuit_enumerate_by_naddr_nport(circ, or_conn->addr, or_conn->port);
+ }
}
- connection_start_reading(circ->p_conn); /* resume listening for reads */
- log(LOG_DEBUG,"ap_handshake_n_conn_open(): Found circ, sending onion.");
- return ap_handshake_send_onion(circ->p_conn, or_conn, circ);
}
int ap_handshake_send_onion(connection_t *ap_conn, connection_t *n_conn, circuit_t *circ) {