diff options
Diffstat (limited to 'src/or/connection_edge.c')
-rw-r--r-- | src/or/connection_edge.c | 62 |
1 files changed, 41 insertions, 21 deletions
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 38f8f90059..b07fcf391d 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) |