mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-27 22:03:31 +01:00
start sending "bootstrap problem" status events when we're having troubles
reaching relays. svn:r15116
This commit is contained in:
parent
42f21007a3
commit
8c85eef9b0
@ -1070,7 +1070,7 @@ $Id$
|
||||
|
||||
Reason = "MISC" / "DONE" / "CONNECTREFUSED" /
|
||||
"IDENTITY" / "CONNECTRESET" / "TIMEOUT" / "NOROUTE" /
|
||||
"IOERROR"
|
||||
"IOERROR" / "RESOURCELIMIT"
|
||||
|
||||
NumCircuits counts both established and pending circuits.
|
||||
|
||||
|
@ -500,14 +500,18 @@ connection_about_to_close_connection(connection_t *conn)
|
||||
if (!get_options()->HttpsProxy)
|
||||
router_set_status(or_conn->identity_digest, 0);
|
||||
if (conn->state == OR_CONN_STATE_CONNECTING) {
|
||||
control_event_or_conn_status(or_conn, OR_CONN_EVENT_FAILED, 0);
|
||||
control_event_or_conn_status(or_conn, OR_CONN_EVENT_FAILED,
|
||||
errno_to_orconn_end_reason(or_conn->socket_error));
|
||||
control_event_bootstrap_problem(
|
||||
tor_socket_strerror(or_conn->socket_error), 0);
|
||||
tor_socket_strerror(or_conn->socket_error),
|
||||
errno_to_orconn_end_reason(or_conn->socket_error));
|
||||
} else {
|
||||
int reason = tls_error_to_orconn_end_reason(or_conn->tls_error);
|
||||
control_event_or_conn_status(or_conn, OR_CONN_EVENT_FAILED,
|
||||
reason);
|
||||
control_event_bootstrap_problem("foo", reason);
|
||||
/* XXX021 come up with a better string for the first arg */
|
||||
control_event_bootstrap_problem(
|
||||
orconn_end_reason_to_control_string(reason), reason);
|
||||
}
|
||||
}
|
||||
/* Inform any pending (not attached) circs that they should
|
||||
@ -1097,8 +1101,9 @@ connection_init_accepted_conn(connection_t *conn, uint8_t listener_type)
|
||||
}
|
||||
|
||||
/** Take conn, make a nonblocking socket; try to connect to
|
||||
* addr:port (they arrive in *host order*). If fail, return -1. Else
|
||||
* assign s to conn-\>s: if connected return 1, if EAGAIN return 0.
|
||||
* addr:port (they arrive in *host order*). If fail, return -1 and if
|
||||
* applicable put your best guess about errno into *<b>socket_error</b>.
|
||||
* Else assign s to conn-\>s: if connected return 1, if EAGAIN return 0.
|
||||
*
|
||||
* address is used to make the logs useful.
|
||||
*
|
||||
@ -1106,7 +1111,7 @@ connection_init_accepted_conn(connection_t *conn, uint8_t listener_type)
|
||||
*/
|
||||
int
|
||||
connection_connect(connection_t *conn, const char *address,
|
||||
uint32_t addr, uint16_t port)
|
||||
uint32_t addr, uint16_t port, int *socket_error)
|
||||
{
|
||||
int s, inprogress = 0;
|
||||
struct sockaddr_in dest_addr;
|
||||
@ -1123,8 +1128,9 @@ connection_connect(connection_t *conn, const char *address,
|
||||
|
||||
s = tor_open_socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
|
||||
if (s < 0) {
|
||||
*socket_error = tor_socket_errno(-1);
|
||||
log_warn(LD_NET,"Error creating network socket: %s",
|
||||
tor_socket_strerror(tor_socket_errno(-1)));
|
||||
tor_socket_strerror(*socket_error));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1140,8 +1146,9 @@ connection_connect(connection_t *conn, const char *address,
|
||||
} else {
|
||||
if (bind(s, (struct sockaddr*)&ext_addr,
|
||||
(socklen_t)sizeof(ext_addr)) < 0) {
|
||||
*socket_error = tor_socket_errno(s);
|
||||
log_warn(LD_NET,"Error binding network socket: %s",
|
||||
tor_socket_strerror(tor_socket_errno(s)));
|
||||
tor_socket_strerror(*socket_error));
|
||||
tor_close_socket(s);
|
||||
return -1;
|
||||
}
|
||||
@ -1165,6 +1172,7 @@ connection_connect(connection_t *conn, const char *address,
|
||||
int e = tor_socket_errno(s);
|
||||
if (!ERRNO_IS_CONN_EINPROGRESS(e)) {
|
||||
/* yuck. kill it. */
|
||||
*socket_error = e;
|
||||
log_info(LD_NET,
|
||||
"connect() to %s:%u failed: %s",escaped_safe_str(address),
|
||||
port, tor_socket_strerror(e));
|
||||
|
@ -236,7 +236,7 @@ connection_edge_end_errno(edge_connection_t *conn)
|
||||
{
|
||||
uint8_t reason;
|
||||
tor_assert(conn);
|
||||
reason = (uint8_t)errno_to_stream_end_reason(tor_socket_errno(conn->_base.s));
|
||||
reason = errno_to_stream_end_reason(tor_socket_errno(conn->_base.s));
|
||||
return connection_edge_end(conn, reason);
|
||||
}
|
||||
|
||||
@ -2609,6 +2609,7 @@ connection_exit_connect(edge_connection_t *edge_conn)
|
||||
uint32_t addr;
|
||||
uint16_t port;
|
||||
connection_t *conn = TO_CONN(edge_conn);
|
||||
int socket_error = 0;
|
||||
|
||||
if (!connection_edge_is_rendezvous_stream(edge_conn) &&
|
||||
router_compare_to_my_exit_policy(edge_conn)) {
|
||||
@ -2644,8 +2645,10 @@ connection_exit_connect(edge_connection_t *edge_conn)
|
||||
}
|
||||
|
||||
log_debug(LD_EXIT,"about to try connecting");
|
||||
switch (connection_connect(conn, conn->address, addr, port)) {
|
||||
switch (connection_connect(conn, conn->address, addr, port, &socket_error)) {
|
||||
case -1:
|
||||
/* XXX021 use socket_error below rather than trying to piece things
|
||||
* together from the current errno, which may have been clobbered. */
|
||||
connection_edge_end_errno(edge_conn);
|
||||
circuit_detach_stream(circuit_get_by_edge_conn(edge_conn), edge_conn);
|
||||
connection_free(conn);
|
||||
|
@ -513,6 +513,7 @@ connection_or_connect(uint32_t addr, uint16_t port, const char *id_digest)
|
||||
{
|
||||
or_connection_t *conn;
|
||||
or_options_t *options = get_options();
|
||||
int socket_error = 0;
|
||||
|
||||
tor_assert(id_digest);
|
||||
|
||||
@ -534,7 +535,8 @@ connection_or_connect(uint32_t addr, uint16_t port, const char *id_digest)
|
||||
port = options->HttpsProxyPort;
|
||||
}
|
||||
|
||||
switch (connection_connect(TO_CONN(conn), conn->_base.address, addr, port)) {
|
||||
switch (connection_connect(TO_CONN(conn), conn->_base.address,
|
||||
addr, port, &socket_error)) {
|
||||
case -1:
|
||||
/* If the connection failed immediately, and we're using
|
||||
* an https proxy, our https proxy is down. Don't blame the
|
||||
@ -545,9 +547,9 @@ connection_or_connect(uint32_t addr, uint16_t port, const char *id_digest)
|
||||
router_set_status(conn->identity_digest, 0);
|
||||
}
|
||||
control_event_or_conn_status(conn, OR_CONN_EVENT_FAILED,
|
||||
END_OR_CONN_REASON_TCP_REFUSED);
|
||||
/* XXX connection_connect() can fail for all sorts of other reasons */
|
||||
control_event_bootstrap_problem("foo", END_OR_CONN_REASON_TCP_REFUSED);
|
||||
errno_to_orconn_end_reason(socket_error));
|
||||
control_event_bootstrap_problem(tor_socket_strerror(socket_error),
|
||||
errno_to_orconn_end_reason(socket_error));
|
||||
connection_free(TO_CONN(conn));
|
||||
return NULL;
|
||||
case 0:
|
||||
|
@ -659,6 +659,7 @@ directory_initiate_command(const char *address, uint32_t addr,
|
||||
{
|
||||
dir_connection_t *conn;
|
||||
or_options_t *options = get_options();
|
||||
int socket_error = 0;
|
||||
int use_begindir = supports_begindir &&
|
||||
directory_command_should_use_begindir(options, addr,
|
||||
or_port, router_purpose, anonymized_connection);
|
||||
@ -699,7 +700,7 @@ directory_initiate_command(const char *address, uint32_t addr,
|
||||
}
|
||||
|
||||
switch (connection_connect(TO_CONN(conn), conn->_base.address, addr,
|
||||
dir_port)) {
|
||||
dir_port, &socket_error)) {
|
||||
case -1:
|
||||
connection_dir_request_failed(conn); /* retry if we want */
|
||||
/* XXX we only pass 'conn' above, not 'resource', 'payload',
|
||||
|
18
src/or/or.h
18
src/or/or.h
@ -502,13 +502,14 @@ typedef enum {
|
||||
|
||||
/* Reasons why an OR connection is closed */
|
||||
#define END_OR_CONN_REASON_DONE 1
|
||||
#define END_OR_CONN_REASON_TCP_REFUSED 2
|
||||
#define END_OR_CONN_REASON_REFUSED 2 /* connection refused */
|
||||
#define END_OR_CONN_REASON_OR_IDENTITY 3
|
||||
#define END_OR_CONN_REASON_TLS_CONNRESET 4 /* tls connection reset by peer */
|
||||
#define END_OR_CONN_REASON_TLS_TIMEOUT 5
|
||||
#define END_OR_CONN_REASON_TLS_NO_ROUTE 6 /* no route to host/net */
|
||||
#define END_OR_CONN_REASON_TLS_IO_ERROR 7 /* tls read/write error */
|
||||
#define END_OR_CONN_REASON_TLS_MISC 8
|
||||
#define END_OR_CONN_REASON_CONNRESET 4 /* connection reset by peer */
|
||||
#define END_OR_CONN_REASON_TIMEOUT 5
|
||||
#define END_OR_CONN_REASON_NO_ROUTE 6 /* no route to host/net */
|
||||
#define END_OR_CONN_REASON_IO_ERROR 7 /* read/write error */
|
||||
#define END_OR_CONN_REASON_RESOURCE_LIMIT 8 /* sockets, buffers, etc */
|
||||
#define END_OR_CONN_REASON_MISC 9
|
||||
|
||||
/* Reasons why we (or a remote OR) might close a stream. See tor-spec.txt for
|
||||
* documentation of these. */
|
||||
@ -2742,7 +2743,7 @@ void _connection_mark_for_close(connection_t *conn,int line, const char *file);
|
||||
void connection_expire_held_open(void);
|
||||
|
||||
int connection_connect(connection_t *conn, const char *address, uint32_t addr,
|
||||
uint16_t port);
|
||||
uint16_t port, int *socket_error);
|
||||
int retry_all_listeners(smartlist_t *replaced_conns,
|
||||
smartlist_t *new_conns);
|
||||
|
||||
@ -3589,10 +3590,11 @@ void policies_free_all(void);
|
||||
const char *stream_end_reason_to_control_string(int reason);
|
||||
const char *stream_end_reason_to_string(int reason);
|
||||
socks5_reply_status_t stream_end_reason_to_socks5_response(int reason);
|
||||
int errno_to_stream_end_reason(int e);
|
||||
uint8_t errno_to_stream_end_reason(int e);
|
||||
|
||||
const char *orconn_end_reason_to_control_string(int r);
|
||||
int tls_error_to_orconn_end_reason(int e);
|
||||
int errno_to_orconn_end_reason(int e);
|
||||
|
||||
const char *circuit_end_reason_to_control_string(int reason);
|
||||
|
||||
|
@ -144,9 +144,8 @@ stream_end_reason_to_socks5_response(int reason)
|
||||
#endif
|
||||
|
||||
/** Given an errno from a failed exit connection, return a reason code
|
||||
* appropriate for use in a RELAY END cell.
|
||||
*/
|
||||
int
|
||||
* appropriate for use in a RELAY END cell. */
|
||||
uint8_t
|
||||
errno_to_stream_end_reason(int e)
|
||||
{
|
||||
switch (e) {
|
||||
@ -192,19 +191,21 @@ orconn_end_reason_to_control_string(int r)
|
||||
switch (r) {
|
||||
case END_OR_CONN_REASON_DONE:
|
||||
return "DONE";
|
||||
case END_OR_CONN_REASON_TCP_REFUSED:
|
||||
case END_OR_CONN_REASON_REFUSED:
|
||||
return "CONNECTREFUSED";
|
||||
case END_OR_CONN_REASON_OR_IDENTITY:
|
||||
return "IDENTITY";
|
||||
case END_OR_CONN_REASON_TLS_CONNRESET:
|
||||
case END_OR_CONN_REASON_CONNRESET:
|
||||
return "CONNECTRESET";
|
||||
case END_OR_CONN_REASON_TLS_TIMEOUT:
|
||||
case END_OR_CONN_REASON_TIMEOUT:
|
||||
return "TIMEOUT";
|
||||
case END_OR_CONN_REASON_TLS_NO_ROUTE:
|
||||
case END_OR_CONN_REASON_NO_ROUTE:
|
||||
return "NOROUTE";
|
||||
case END_OR_CONN_REASON_TLS_IO_ERROR:
|
||||
case END_OR_CONN_REASON_IO_ERROR:
|
||||
return "IOERROR";
|
||||
case END_OR_CONN_REASON_TLS_MISC:
|
||||
case END_OR_CONN_REASON_RESOURCE_LIMIT:
|
||||
return "RESOURCELIMIT";
|
||||
case END_OR_CONN_REASON_MISC:
|
||||
return "MISC";
|
||||
case 0:
|
||||
return "";
|
||||
@ -220,22 +221,59 @@ tls_error_to_orconn_end_reason(int e)
|
||||
{
|
||||
switch (e) {
|
||||
case TOR_TLS_ERROR_IO:
|
||||
return END_OR_CONN_REASON_TLS_IO_ERROR;
|
||||
return END_OR_CONN_REASON_IO_ERROR;
|
||||
case TOR_TLS_ERROR_CONNREFUSED:
|
||||
return END_OR_CONN_REASON_TCP_REFUSED;
|
||||
return END_OR_CONN_REASON_REFUSED;
|
||||
case TOR_TLS_ERROR_CONNRESET:
|
||||
return END_OR_CONN_REASON_TLS_CONNRESET;
|
||||
return END_OR_CONN_REASON_CONNRESET;
|
||||
case TOR_TLS_ERROR_NO_ROUTE:
|
||||
return END_OR_CONN_REASON_TLS_NO_ROUTE;
|
||||
return END_OR_CONN_REASON_NO_ROUTE;
|
||||
case TOR_TLS_ERROR_TIMEOUT:
|
||||
return END_OR_CONN_REASON_TLS_TIMEOUT;
|
||||
return END_OR_CONN_REASON_TIMEOUT;
|
||||
case TOR_TLS_WANTREAD:
|
||||
case TOR_TLS_WANTWRITE:
|
||||
case TOR_TLS_CLOSE:
|
||||
case TOR_TLS_DONE:
|
||||
return END_OR_CONN_REASON_DONE;
|
||||
default:
|
||||
return END_OR_CONN_REASON_TLS_MISC;
|
||||
return END_OR_CONN_REASON_MISC;
|
||||
}
|
||||
}
|
||||
|
||||
/** Given an errno from a failed ORConn connection, return a reason code
|
||||
* appropriate for use in the controller orconn events. */
|
||||
/* XXX021 somebody should think about whether the assignments I've made
|
||||
* are accurate or useful. -RD */
|
||||
int
|
||||
errno_to_orconn_end_reason(int e)
|
||||
{
|
||||
switch (e) {
|
||||
case EPIPE:
|
||||
return END_OR_CONN_REASON_DONE;
|
||||
S_CASE(ENOTCONN):
|
||||
S_CASE(ENETUNREACH):
|
||||
case ENETDOWN: /* << somebody should look into the Windows equiv */
|
||||
case EHOSTUNREACH:
|
||||
return END_OR_CONN_REASON_NO_ROUTE;
|
||||
S_CASE(ECONNREFUSED):
|
||||
return END_OR_CONN_REASON_REFUSED;
|
||||
S_CASE(ECONNRESET):
|
||||
return END_OR_CONN_REASON_CONNRESET;
|
||||
S_CASE(ETIMEDOUT):
|
||||
return END_OR_CONN_REASON_TIMEOUT;
|
||||
S_CASE(ENOBUFS):
|
||||
case ENOMEM:
|
||||
case ENFILE:
|
||||
E_CASE(EMFILE):
|
||||
E_CASE(EACCES):
|
||||
E_CASE(EBADF):
|
||||
E_CASE(EFAULT):
|
||||
E_CASE(EINVAL):
|
||||
return END_OR_CONN_REASON_RESOURCE_LIMIT;
|
||||
default:
|
||||
log_info(LD_OR, "Didn't recognize errno %d (%s).",
|
||||
e, tor_socket_strerror(e));
|
||||
return END_OR_CONN_REASON_MISC;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user