mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
Split connection_about_to_close_connection into separate functions
This patch does NOTHING but:
- move code
- add declarations and includes as needed to make the new code
work
- declare the new functions.
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
o Code simplification and refactoring:
|
||||
- Split connection_about_to_close into separate functions for each
|
||||
connection type.
|
||||
+7
-99
@@ -563,7 +563,9 @@ connection_free_all(void)
|
||||
}
|
||||
}
|
||||
|
||||
/** Do any cleanup needed:
|
||||
/**
|
||||
* Called when we're about to finally unlink and free a connection:
|
||||
* perform necessary accounting and cleanup
|
||||
* - Directory conns that failed to fetch a rendezvous descriptor
|
||||
* need to inform pending rendezvous streams.
|
||||
* - OR conns need to call rep_hist_note_*() to record status.
|
||||
@@ -576,114 +578,20 @@ connection_free_all(void)
|
||||
void
|
||||
connection_about_to_close_connection(connection_t *conn)
|
||||
{
|
||||
circuit_t *circ;
|
||||
dir_connection_t *dir_conn;
|
||||
or_connection_t *or_conn;
|
||||
edge_connection_t *edge_conn;
|
||||
time_t now = time(NULL);
|
||||
|
||||
tor_assert(conn->marked_for_close);
|
||||
|
||||
if (CONN_IS_EDGE(conn)) {
|
||||
edge_conn = TO_EDGE_CONN(conn);
|
||||
if (!edge_conn->edge_has_sent_end) {
|
||||
log_warn(LD_BUG, "(Harmless.) Edge connection (marked at %s:%d) "
|
||||
"hasn't sent end yet?",
|
||||
conn->marked_for_close_file, conn->marked_for_close);
|
||||
tor_fragile_assert();
|
||||
}
|
||||
}
|
||||
|
||||
switch (conn->type) {
|
||||
case CONN_TYPE_DIR:
|
||||
dir_conn = TO_DIR_CONN(conn);
|
||||
if (conn->state < DIR_CONN_STATE_CLIENT_FINISHED) {
|
||||
/* It's a directory connection and connecting or fetching
|
||||
* failed: forget about this router, and maybe try again. */
|
||||
connection_dir_request_failed(dir_conn);
|
||||
}
|
||||
/* If we were trying to fetch a v2 rend desc and did not succeed,
|
||||
* retry as needed. (If a fetch is successful, the connection state
|
||||
* is changed to DIR_PURPOSE_HAS_FETCHED_RENDDESC to mark that
|
||||
* refetching is unnecessary.) */
|
||||
if (conn->purpose == DIR_PURPOSE_FETCH_RENDDESC_V2 &&
|
||||
dir_conn->rend_data &&
|
||||
strlen(dir_conn->rend_data->onion_address) ==
|
||||
REND_SERVICE_ID_LEN_BASE32)
|
||||
rend_client_refetch_v2_renddesc(dir_conn->rend_data);
|
||||
connection_dir_about_to_close(TO_DIR_CONN(conn));
|
||||
break;
|
||||
case CONN_TYPE_OR:
|
||||
or_conn = TO_OR_CONN(conn);
|
||||
/* Remember why we're closing this connection. */
|
||||
if (conn->state != OR_CONN_STATE_OPEN) {
|
||||
/* Inform any pending (not attached) circs that they should
|
||||
* give up. */
|
||||
circuit_n_conn_done(TO_OR_CONN(conn), 0);
|
||||
/* now mark things down as needed */
|
||||
if (connection_or_nonopen_was_started_here(or_conn)) {
|
||||
const or_options_t *options = get_options();
|
||||
rep_hist_note_connect_failed(or_conn->identity_digest, now);
|
||||
entry_guard_register_connect_status(or_conn->identity_digest,0,
|
||||
!options->HTTPSProxy, now);
|
||||
if (conn->state >= OR_CONN_STATE_TLS_HANDSHAKING) {
|
||||
int reason = tls_error_to_orconn_end_reason(or_conn->tls_error);
|
||||
control_event_or_conn_status(or_conn, OR_CONN_EVENT_FAILED,
|
||||
reason);
|
||||
if (!authdir_mode_tests_reachability(options))
|
||||
control_event_bootstrap_problem(
|
||||
orconn_end_reason_to_control_string(reason), reason);
|
||||
}
|
||||
}
|
||||
} else if (conn->hold_open_until_flushed) {
|
||||
/* We only set hold_open_until_flushed when we're intentionally
|
||||
* closing a connection. */
|
||||
rep_hist_note_disconnect(or_conn->identity_digest, now);
|
||||
control_event_or_conn_status(or_conn, OR_CONN_EVENT_CLOSED,
|
||||
tls_error_to_orconn_end_reason(or_conn->tls_error));
|
||||
} else if (!tor_digest_is_zero(or_conn->identity_digest)) {
|
||||
rep_hist_note_connection_died(or_conn->identity_digest, now);
|
||||
control_event_or_conn_status(or_conn, OR_CONN_EVENT_CLOSED,
|
||||
tls_error_to_orconn_end_reason(or_conn->tls_error));
|
||||
}
|
||||
/* Now close all the attached circuits on it. */
|
||||
circuit_unlink_all_from_or_conn(TO_OR_CONN(conn),
|
||||
END_CIRC_REASON_OR_CONN_CLOSED);
|
||||
connection_or_about_to_close(TO_OR_CONN(conn));
|
||||
break;
|
||||
case CONN_TYPE_AP:
|
||||
edge_conn = TO_EDGE_CONN(conn);
|
||||
if (edge_conn->socks_request->has_finished == 0) {
|
||||
/* since conn gets removed right after this function finishes,
|
||||
* there's no point trying to send back a reply at this point. */
|
||||
log_warn(LD_BUG,"Closing stream (marked at %s:%d) without sending"
|
||||
" back a socks reply.",
|
||||
conn->marked_for_close_file, conn->marked_for_close);
|
||||
}
|
||||
if (!edge_conn->end_reason) {
|
||||
log_warn(LD_BUG,"Closing stream (marked at %s:%d) without having"
|
||||
" set end_reason.",
|
||||
conn->marked_for_close_file, conn->marked_for_close);
|
||||
}
|
||||
if (edge_conn->dns_server_request) {
|
||||
log_warn(LD_BUG,"Closing stream (marked at %s:%d) without having"
|
||||
" replied to DNS request.",
|
||||
conn->marked_for_close_file, conn->marked_for_close);
|
||||
dnsserv_reject_request(edge_conn);
|
||||
}
|
||||
control_event_stream_bandwidth(edge_conn);
|
||||
control_event_stream_status(edge_conn, STREAM_EVENT_CLOSED,
|
||||
edge_conn->end_reason);
|
||||
circ = circuit_get_by_edge_conn(edge_conn);
|
||||
if (circ)
|
||||
circuit_detach_stream(circ, edge_conn);
|
||||
connection_ap_about_to_close(TO_EDGE_CONN(conn));
|
||||
break;
|
||||
case CONN_TYPE_EXIT:
|
||||
edge_conn = TO_EDGE_CONN(conn);
|
||||
circ = circuit_get_by_edge_conn(edge_conn);
|
||||
if (circ)
|
||||
circuit_detach_stream(circ, edge_conn);
|
||||
if (conn->state == EXIT_CONN_STATE_RESOLVING) {
|
||||
connection_dns_remove(edge_conn);
|
||||
}
|
||||
connection_exit_about_to_close(TO_EDGE_CONN(conn));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -408,6 +408,71 @@ connection_edge_finished_connecting(edge_connection_t *edge_conn)
|
||||
return connection_edge_process_inbuf(edge_conn, 1);
|
||||
}
|
||||
|
||||
/** Common code to connection_(ap|exit)_about_to_close. */
|
||||
static void
|
||||
connection_edge_about_to_close(edge_connection_t *edge_conn)
|
||||
{
|
||||
if (!edge_conn->edge_has_sent_end) {
|
||||
connection_t *conn = TO_CONN(edge_conn);
|
||||
log_warn(LD_BUG, "(Harmless.) Edge connection (marked at %s:%d) "
|
||||
"hasn't sent end yet?",
|
||||
conn->marked_for_close_file, conn->marked_for_close);
|
||||
tor_fragile_assert();
|
||||
}
|
||||
}
|
||||
|
||||
/* Called when we're about to finally unlink and free an AP (client)
|
||||
* connection: perform necessary accounting and cleanup */
|
||||
void
|
||||
connection_ap_about_to_close(edge_connection_t *edge_conn)
|
||||
{
|
||||
circuit_t *circ;
|
||||
connection_t *conn = TO_CONN(edge_conn);
|
||||
|
||||
if (edge_conn->socks_request->has_finished == 0) {
|
||||
/* since conn gets removed right after this function finishes,
|
||||
* there's no point trying to send back a reply at this point. */
|
||||
log_warn(LD_BUG,"Closing stream (marked at %s:%d) without sending"
|
||||
" back a socks reply.",
|
||||
conn->marked_for_close_file, conn->marked_for_close);
|
||||
}
|
||||
if (!edge_conn->end_reason) {
|
||||
log_warn(LD_BUG,"Closing stream (marked at %s:%d) without having"
|
||||
" set end_reason.",
|
||||
conn->marked_for_close_file, conn->marked_for_close);
|
||||
}
|
||||
if (edge_conn->dns_server_request) {
|
||||
log_warn(LD_BUG,"Closing stream (marked at %s:%d) without having"
|
||||
" replied to DNS request.",
|
||||
conn->marked_for_close_file, conn->marked_for_close);
|
||||
dnsserv_reject_request(edge_conn);
|
||||
}
|
||||
control_event_stream_bandwidth(edge_conn);
|
||||
control_event_stream_status(edge_conn, STREAM_EVENT_CLOSED,
|
||||
edge_conn->end_reason);
|
||||
circ = circuit_get_by_edge_conn(edge_conn);
|
||||
if (circ)
|
||||
circuit_detach_stream(circ, edge_conn);
|
||||
}
|
||||
|
||||
/* Called when we're about to finally unlink and free an exit
|
||||
* connection: perform necessary accounting and cleanup */
|
||||
void
|
||||
connection_exit_about_to_close(edge_connection_t *edge_conn)
|
||||
{
|
||||
circuit_t *circ;
|
||||
connection_t *conn = TO_CONN(edge_conn);
|
||||
|
||||
connection_edge_about_to_close(edge_conn);
|
||||
|
||||
circ = circuit_get_by_edge_conn(edge_conn);
|
||||
if (circ)
|
||||
circuit_detach_stream(circ, edge_conn);
|
||||
if (conn->state == EXIT_CONN_STATE_RESOLVING) {
|
||||
connection_dns_remove(edge_conn);
|
||||
}
|
||||
}
|
||||
|
||||
/** Define a schedule for how long to wait between retrying
|
||||
* application connections. Rather than waiting a fixed amount of
|
||||
* time between each retry, we wait 10 seconds each for the first
|
||||
|
||||
@@ -27,6 +27,9 @@ int connection_edge_flushed_some(edge_connection_t *conn);
|
||||
int connection_edge_finished_flushing(edge_connection_t *conn);
|
||||
int connection_edge_finished_connecting(edge_connection_t *conn);
|
||||
|
||||
void connection_ap_about_to_close(edge_connection_t *edge_conn);
|
||||
void connection_exit_about_to_close(edge_connection_t *edge_conn);
|
||||
|
||||
int connection_ap_handshake_send_begin(edge_connection_t *ap_conn);
|
||||
int connection_ap_handshake_send_resolve(edge_connection_t *ap_conn);
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "or.h"
|
||||
#include "buffers.h"
|
||||
#include "circuitbuild.h"
|
||||
#include "circuitlist.h"
|
||||
#include "command.h"
|
||||
#include "config.h"
|
||||
#include "connection.h"
|
||||
@@ -347,6 +348,50 @@ connection_or_finished_connecting(or_connection_t *or_conn)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Called when we're about to finally unlink and free an OR connection:
|
||||
* perform necessary accounting and cleanup */
|
||||
void
|
||||
connection_or_about_to_close(or_connection_t *or_conn)
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
connection_t *conn = TO_CONN(or_conn);
|
||||
|
||||
/* Remember why we're closing this connection. */
|
||||
if (conn->state != OR_CONN_STATE_OPEN) {
|
||||
/* Inform any pending (not attached) circs that they should
|
||||
* give up. */
|
||||
circuit_n_conn_done(TO_OR_CONN(conn), 0);
|
||||
/* now mark things down as needed */
|
||||
if (connection_or_nonopen_was_started_here(or_conn)) {
|
||||
const or_options_t *options = get_options();
|
||||
rep_hist_note_connect_failed(or_conn->identity_digest, now);
|
||||
entry_guard_register_connect_status(or_conn->identity_digest,0,
|
||||
!options->HTTPSProxy, now);
|
||||
if (conn->state >= OR_CONN_STATE_TLS_HANDSHAKING) {
|
||||
int reason = tls_error_to_orconn_end_reason(or_conn->tls_error);
|
||||
control_event_or_conn_status(or_conn, OR_CONN_EVENT_FAILED,
|
||||
reason);
|
||||
if (!authdir_mode_tests_reachability(options))
|
||||
control_event_bootstrap_problem(
|
||||
orconn_end_reason_to_control_string(reason), reason);
|
||||
}
|
||||
}
|
||||
} else if (conn->hold_open_until_flushed) {
|
||||
/* We only set hold_open_until_flushed when we're intentionally
|
||||
* closing a connection. */
|
||||
rep_hist_note_disconnect(or_conn->identity_digest, now);
|
||||
control_event_or_conn_status(or_conn, OR_CONN_EVENT_CLOSED,
|
||||
tls_error_to_orconn_end_reason(or_conn->tls_error));
|
||||
} else if (!tor_digest_is_zero(or_conn->identity_digest)) {
|
||||
rep_hist_note_connection_died(or_conn->identity_digest, now);
|
||||
control_event_or_conn_status(or_conn, OR_CONN_EVENT_CLOSED,
|
||||
tls_error_to_orconn_end_reason(or_conn->tls_error));
|
||||
}
|
||||
/* Now close all the attached circuits on it. */
|
||||
circuit_unlink_all_from_or_conn(TO_OR_CONN(conn),
|
||||
END_CIRC_REASON_OR_CONN_CLOSED);
|
||||
}
|
||||
|
||||
/** Return 1 if identity digest <b>id_digest</b> is known to be a
|
||||
* currently or recently running relay. Otherwise return 0. */
|
||||
int
|
||||
|
||||
@@ -25,6 +25,7 @@ int connection_or_process_inbuf(or_connection_t *conn);
|
||||
int connection_or_flushed_some(or_connection_t *conn);
|
||||
int connection_or_finished_flushing(or_connection_t *conn);
|
||||
int connection_or_finished_connecting(or_connection_t *conn);
|
||||
void connection_or_about_to_close(or_connection_t *conn);
|
||||
int connection_or_digest_is_known_relay(const char *id_digest);
|
||||
void connection_or_update_token_buckets(smartlist_t *conns,
|
||||
const or_options_t *options);
|
||||
|
||||
@@ -2301,6 +2301,28 @@ connection_dir_process_inbuf(dir_connection_t *conn)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Called when we're about to finally unlink and free a directory connection:
|
||||
* perform necessary accounting and cleanup */
|
||||
void
|
||||
connection_dir_about_to_close(dir_connection_t *dir_conn)
|
||||
{
|
||||
connection_t *conn = TO_CONN(dir_conn);
|
||||
|
||||
if (conn->state < DIR_CONN_STATE_CLIENT_FINISHED) {
|
||||
/* It's a directory connection and connecting or fetching
|
||||
* failed: forget about this router, and maybe try again. */
|
||||
connection_dir_request_failed(dir_conn);
|
||||
}
|
||||
/* If we were trying to fetch a v2 rend desc and did not succeed,
|
||||
* retry as needed. (If a fetch is successful, the connection state
|
||||
* is changed to DIR_PURPOSE_HAS_FETCHED_RENDDESC to mark that
|
||||
* refetching is unnecessary.) */
|
||||
if (conn->purpose == DIR_PURPOSE_FETCH_RENDDESC_V2 &&
|
||||
dir_conn->rend_data &&
|
||||
strlen(dir_conn->rend_data->onion_address) == REND_SERVICE_ID_LEN_BASE32)
|
||||
rend_client_refetch_v2_renddesc(dir_conn->rend_data);
|
||||
}
|
||||
|
||||
/** Create an http response for the client <b>conn</b> out of
|
||||
* <b>status</b> and <b>reason_phrase</b>. Write it to <b>conn</b>.
|
||||
*/
|
||||
|
||||
@@ -48,6 +48,7 @@ int connection_dir_reached_eof(dir_connection_t *conn);
|
||||
int connection_dir_process_inbuf(dir_connection_t *conn);
|
||||
int connection_dir_finished_flushing(dir_connection_t *conn);
|
||||
int connection_dir_finished_connecting(dir_connection_t *conn);
|
||||
void connection_dir_about_to_close(dir_connection_t *dir_conn);
|
||||
void connection_dir_request_failed(dir_connection_t *conn);
|
||||
void directory_initiate_command(const char *address, const tor_addr_t *addr,
|
||||
uint16_t or_port, uint16_t dir_port,
|
||||
|
||||
Reference in New Issue
Block a user