aboutsummaryrefslogtreecommitdiff
path: root/src/or/connection_edge.c
diff options
context:
space:
mode:
authorRoger Dingledine <arma@torproject.org>2004-05-06 11:08:04 +0000
committerRoger Dingledine <arma@torproject.org>2004-05-06 11:08:04 +0000
commit9bf9ca4d094926acfc0b0a50f6fd12fcbb310d0d (patch)
treeaf07d3a5db87ababc75159fca2804f76ab01655c /src/or/connection_edge.c
parente6477a8e168ad4d9f367172785e1fcca14d46f0d (diff)
downloadtor-9bf9ca4d094926acfc0b0a50f6fd12fcbb310d0d.tar
tor-9bf9ca4d094926acfc0b0a50f6fd12fcbb310d0d.tar.gz
bugfix: add a circ->resolving_streams field, and make dns resolving streams not actually in the connection_array until they're done resolving.
bugfix: actually complain if we duplicate mark-for-close a circuit add more logging for relay ends that claim dns resolve failed, so we can find out why they're not being retried. svn:r1798
Diffstat (limited to 'src/or/connection_edge.c')
-rw-r--r--src/or/connection_edge.c62
1 files changed, 41 insertions, 21 deletions
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 38f8f9005..b07fcf391 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -1,4 +1,4 @@
-/* Copyright 2001,2002,2003 Roger Dingledine, Matej Pfajfar. */
+/* Copyright 2001 Matej Pfajfar, 2001-2004 Roger Dingledine. */
/* See LICENSE for licensing information */
/* $Id$ */
@@ -165,10 +165,10 @@ int connection_edge_end(connection_t *conn, char reason, crypt_path_t *cpath_lay
}
/* 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.
+ * send it onto the open circuit 'circ'. 'fromconn' is the stream
+ * that's sending the relay cell, or NULL if it's a control cell,
+ * 'cpath_layer' is NULL for OR->OP cells, or the destination hop
+ * for OP->OR cells.
*
* If you can't send the cell, mark the circuit for close and
* return -1. Else return 0.
@@ -229,12 +229,15 @@ int connection_edge_process_relay_cell_not_open(
reason = *(cell->payload+RELAY_HEADER_SIZE);
/* We have to check this here, since we aren't connected yet. */
if (rh->length >= 5 && reason == END_STREAM_REASON_EXITPOLICY) {
+ log_fn(LOG_INFO,"Address %s refused due to exit policy. Retrying.",
+ conn->socks_request->address);
addr = ntohl(get_uint32(cell->payload+RELAY_HEADER_SIZE+1));
client_dns_set_entry(conn->socks_request->address, addr);
conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
circuit_detach_stream(circ,conn);
if(connection_ap_handshake_attach_circuit(conn) >= 0)
return 0;
+ log_fn(LOG_INFO,"Giving up on retrying (from exitpolicy); conn can't be handled.");
/* else, conn will get closed below */
} else if (rh->length && reason == END_STREAM_REASON_RESOLVEFAILED) {
if (client_dns_incr_failures(conn->socks_request->address)
@@ -245,6 +248,10 @@ int connection_edge_process_relay_cell_not_open(
if(connection_ap_handshake_attach_circuit(conn) >= 0)
return 0;
/* else, conn will get closed below */
+ log_fn(LOG_INFO,"Giving up on retrying (from resolvefailed); conn can't be handled.");
+ } else {
+ log_fn(LOG_WARN,"Have tried resolving address %s at %d different places. Giving up.",
+ conn->socks_request->address, MAX_RESOLVE_FAILURES);
}
}
log_fn(LOG_INFO,"Edge got end (%s) before we're connected. Marking for close.",
@@ -253,8 +260,6 @@ int connection_edge_process_relay_cell_not_open(
circuit_log_path(LOG_INFO,circ);
conn->has_sent_end = 1; /* we just got an 'end', don't need to send one */
connection_mark_for_close(conn, 0);
- /* XXX here we should send a socks reject back if necessary, and hold
- * open til flushed */
return 0;
}
@@ -280,12 +285,12 @@ int connection_edge_process_relay_cell_not_open(
return 0;
}
return 0;
- } else {
- log_fn(LOG_WARN,"Got an unexpected relay command %d, in state %d (%s). Closing.",
- rh->command, conn->state, conn_state_to_string[conn->type][conn->state]);
- connection_mark_for_close(conn, END_STREAM_REASON_MISC);
- return -1;
}
+
+ log_fn(LOG_WARN,"Got an unexpected relay command %d, in state %d (%s). Closing.",
+ rh->command, conn->state, conn_state_to_string[conn->type][conn->state]);
+ connection_mark_for_close(conn, END_STREAM_REASON_MISC);
+ return -1;
}
/* an incoming relay cell has arrived. return -1 if you want to tear down the
@@ -893,7 +898,7 @@ int connection_ap_handshake_attach_circuit(connection_t *conn) {
if(conn_age > 60) {
/* XXX make this cleaner than '60' */
log_fn(LOG_WARN,"Giving up on unattached conn (%d sec old).", conn_age);
- connection_mark_for_close(conn, 0);
+ return -1;
}
if(!connection_edge_is_rendezvous_stream(conn)) { /* we're a general conn */
@@ -1180,13 +1185,6 @@ static int connection_exit_begin_conn(cell_t *cell, circuit_t *circ) {
n_stream->package_window = STREAMWINDOW_START;
n_stream->deliver_window = STREAMWINDOW_START;
- log_fn(LOG_DEBUG,"finished adding conn");
-
- /* add it into the linked list of streams on this circuit */
- n_stream->next_stream = circ->n_streams;
- circ->n_streams = n_stream;
- assert_circuit_ok(circ);
-
if(circ->purpose == CIRCUIT_PURPOSE_S_REND_JOINED) {
log_fn(LOG_DEBUG,"begin is for rendezvous. configuring stream.");
n_stream->address = tor_strdup("(rendezvous)");
@@ -1204,6 +1202,12 @@ static int connection_exit_begin_conn(cell_t *cell, circuit_t *circ) {
assert_circuit_ok(circ);
log_fn(LOG_DEBUG,"Finished assigning addr/port");
n_stream->cpath_layer = circ->cpath->prev; /* link it */
+
+ /* add it into the linked list of n_streams on this circuit */
+ n_stream->next_stream = circ->n_streams;
+ circ->n_streams = n_stream;
+ assert_circuit_ok(circ);
+
connection_exit_connect(n_stream);
return 0;
}
@@ -1214,6 +1218,12 @@ static int connection_exit_begin_conn(cell_t *cell, circuit_t *circ) {
/* send it off to the gethostbyname farm */
switch(dns_resolve(n_stream)) {
case 1: /* resolve worked */
+
+ /* add it into the linked list of n_streams on this circuit */
+ n_stream->next_stream = circ->n_streams;
+ circ->n_streams = n_stream;
+ assert_circuit_ok(circ);
+
connection_exit_connect(n_stream);
return 0;
case -1: /* resolve failed */
@@ -1222,6 +1232,10 @@ static int connection_exit_begin_conn(cell_t *cell, circuit_t *circ) {
connection_free(n_stream);
break;
case 0: /* resolve added to pending list */
+ /* add it into the linked list of resolving_streams on this circuit */
+ n_stream->next_stream = circ->resolving_streams;
+ circ->resolving_streams = n_stream;
+ assert_circuit_ok(circ);
;
}
return 0;
@@ -1234,6 +1248,8 @@ void connection_exit_connect(connection_t *conn) {
router_compare_to_my_exit_policy(conn) == ADDR_POLICY_REJECTED) {
log_fn(LOG_INFO,"%s:%d failed exit policy. Closing.", conn->address, conn->port);
connection_mark_for_close(conn, END_STREAM_REASON_EXITPOLICY);
+ circuit_detach_stream(circuit_get_by_conn(conn), conn);
+ connection_free(conn);
return;
}
@@ -1241,6 +1257,7 @@ void connection_exit_connect(connection_t *conn) {
switch(connection_connect(conn, conn->address, conn->addr, conn->port)) {
case -1:
connection_mark_for_close(conn, END_STREAM_REASON_CONNECTFAILED);
+ circuit_detach_stream(circuit_get_by_conn(conn), conn);
connection_free(conn);
return;
case 0:
@@ -1368,7 +1385,10 @@ static int client_dns_incr_failures(const char *address)
{
struct client_dns_entry *ent;
ent = _get_or_create_ent(address);
- return ++ent->n_failures;
+ ++ent->n_failures;
+ log_fn(LOG_DEBUG,"Address %s now has %d resolve failures.",
+ address, ent->n_failures);
+ return ent->n_failures;
}
static void client_dns_set_entry(const char *address, uint32_t val)