mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-20 10:12:15 +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" /
|
Reason = "MISC" / "DONE" / "CONNECTREFUSED" /
|
||||||
"IDENTITY" / "CONNECTRESET" / "TIMEOUT" / "NOROUTE" /
|
"IDENTITY" / "CONNECTRESET" / "TIMEOUT" / "NOROUTE" /
|
||||||
"IOERROR"
|
"IOERROR" / "RESOURCELIMIT"
|
||||||
|
|
||||||
NumCircuits counts both established and pending circuits.
|
NumCircuits counts both established and pending circuits.
|
||||||
|
|
||||||
|
@ -500,14 +500,18 @@ connection_about_to_close_connection(connection_t *conn)
|
|||||||
if (!get_options()->HttpsProxy)
|
if (!get_options()->HttpsProxy)
|
||||||
router_set_status(or_conn->identity_digest, 0);
|
router_set_status(or_conn->identity_digest, 0);
|
||||||
if (conn->state == OR_CONN_STATE_CONNECTING) {
|
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(
|
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 {
|
} else {
|
||||||
int reason = tls_error_to_orconn_end_reason(or_conn->tls_error);
|
int reason = tls_error_to_orconn_end_reason(or_conn->tls_error);
|
||||||
control_event_or_conn_status(or_conn, OR_CONN_EVENT_FAILED,
|
control_event_or_conn_status(or_conn, OR_CONN_EVENT_FAILED,
|
||||||
reason);
|
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
|
/* 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
|
/** Take conn, make a nonblocking socket; try to connect to
|
||||||
* addr:port (they arrive in *host order*). If fail, return -1. Else
|
* addr:port (they arrive in *host order*). If fail, return -1 and if
|
||||||
* assign s to conn-\>s: if connected return 1, if EAGAIN return 0.
|
* 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.
|
* address is used to make the logs useful.
|
||||||
*
|
*
|
||||||
@ -1106,7 +1111,7 @@ connection_init_accepted_conn(connection_t *conn, uint8_t listener_type)
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
connection_connect(connection_t *conn, const char *address,
|
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;
|
int s, inprogress = 0;
|
||||||
struct sockaddr_in dest_addr;
|
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);
|
s = tor_open_socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
|
||||||
if (s < 0) {
|
if (s < 0) {
|
||||||
|
*socket_error = tor_socket_errno(-1);
|
||||||
log_warn(LD_NET,"Error creating network socket: %s",
|
log_warn(LD_NET,"Error creating network socket: %s",
|
||||||
tor_socket_strerror(tor_socket_errno(-1)));
|
tor_socket_strerror(*socket_error));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1140,8 +1146,9 @@ connection_connect(connection_t *conn, const char *address,
|
|||||||
} else {
|
} else {
|
||||||
if (bind(s, (struct sockaddr*)&ext_addr,
|
if (bind(s, (struct sockaddr*)&ext_addr,
|
||||||
(socklen_t)sizeof(ext_addr)) < 0) {
|
(socklen_t)sizeof(ext_addr)) < 0) {
|
||||||
|
*socket_error = tor_socket_errno(s);
|
||||||
log_warn(LD_NET,"Error binding network socket: %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);
|
tor_close_socket(s);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1165,6 +1172,7 @@ connection_connect(connection_t *conn, const char *address,
|
|||||||
int e = tor_socket_errno(s);
|
int e = tor_socket_errno(s);
|
||||||
if (!ERRNO_IS_CONN_EINPROGRESS(e)) {
|
if (!ERRNO_IS_CONN_EINPROGRESS(e)) {
|
||||||
/* yuck. kill it. */
|
/* yuck. kill it. */
|
||||||
|
*socket_error = e;
|
||||||
log_info(LD_NET,
|
log_info(LD_NET,
|
||||||
"connect() to %s:%u failed: %s",escaped_safe_str(address),
|
"connect() to %s:%u failed: %s",escaped_safe_str(address),
|
||||||
port, tor_socket_strerror(e));
|
port, tor_socket_strerror(e));
|
||||||
|
@ -236,7 +236,7 @@ connection_edge_end_errno(edge_connection_t *conn)
|
|||||||
{
|
{
|
||||||
uint8_t reason;
|
uint8_t reason;
|
||||||
tor_assert(conn);
|
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);
|
return connection_edge_end(conn, reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2609,6 +2609,7 @@ connection_exit_connect(edge_connection_t *edge_conn)
|
|||||||
uint32_t addr;
|
uint32_t addr;
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
connection_t *conn = TO_CONN(edge_conn);
|
connection_t *conn = TO_CONN(edge_conn);
|
||||||
|
int socket_error = 0;
|
||||||
|
|
||||||
if (!connection_edge_is_rendezvous_stream(edge_conn) &&
|
if (!connection_edge_is_rendezvous_stream(edge_conn) &&
|
||||||
router_compare_to_my_exit_policy(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");
|
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:
|
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);
|
connection_edge_end_errno(edge_conn);
|
||||||
circuit_detach_stream(circuit_get_by_edge_conn(edge_conn), edge_conn);
|
circuit_detach_stream(circuit_get_by_edge_conn(edge_conn), edge_conn);
|
||||||
connection_free(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_connection_t *conn;
|
||||||
or_options_t *options = get_options();
|
or_options_t *options = get_options();
|
||||||
|
int socket_error = 0;
|
||||||
|
|
||||||
tor_assert(id_digest);
|
tor_assert(id_digest);
|
||||||
|
|
||||||
@ -534,7 +535,8 @@ connection_or_connect(uint32_t addr, uint16_t port, const char *id_digest)
|
|||||||
port = options->HttpsProxyPort;
|
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:
|
case -1:
|
||||||
/* If the connection failed immediately, and we're using
|
/* If the connection failed immediately, and we're using
|
||||||
* an https proxy, our https proxy is down. Don't blame the
|
* 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);
|
router_set_status(conn->identity_digest, 0);
|
||||||
}
|
}
|
||||||
control_event_or_conn_status(conn, OR_CONN_EVENT_FAILED,
|
control_event_or_conn_status(conn, OR_CONN_EVENT_FAILED,
|
||||||
END_OR_CONN_REASON_TCP_REFUSED);
|
errno_to_orconn_end_reason(socket_error));
|
||||||
/* XXX connection_connect() can fail for all sorts of other reasons */
|
control_event_bootstrap_problem(tor_socket_strerror(socket_error),
|
||||||
control_event_bootstrap_problem("foo", END_OR_CONN_REASON_TCP_REFUSED);
|
errno_to_orconn_end_reason(socket_error));
|
||||||
connection_free(TO_CONN(conn));
|
connection_free(TO_CONN(conn));
|
||||||
return NULL;
|
return NULL;
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -659,6 +659,7 @@ directory_initiate_command(const char *address, uint32_t addr,
|
|||||||
{
|
{
|
||||||
dir_connection_t *conn;
|
dir_connection_t *conn;
|
||||||
or_options_t *options = get_options();
|
or_options_t *options = get_options();
|
||||||
|
int socket_error = 0;
|
||||||
int use_begindir = supports_begindir &&
|
int use_begindir = supports_begindir &&
|
||||||
directory_command_should_use_begindir(options, addr,
|
directory_command_should_use_begindir(options, addr,
|
||||||
or_port, router_purpose, anonymized_connection);
|
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,
|
switch (connection_connect(TO_CONN(conn), conn->_base.address, addr,
|
||||||
dir_port)) {
|
dir_port, &socket_error)) {
|
||||||
case -1:
|
case -1:
|
||||||
connection_dir_request_failed(conn); /* retry if we want */
|
connection_dir_request_failed(conn); /* retry if we want */
|
||||||
/* XXX we only pass 'conn' above, not 'resource', 'payload',
|
/* XXX we only pass 'conn' above, not 'resource', 'payload',
|
||||||
|
22
src/or/or.h
22
src/or/or.h
@ -501,14 +501,15 @@ typedef enum {
|
|||||||
#define RELAY_COMMAND_INTRODUCE_ACK 40
|
#define RELAY_COMMAND_INTRODUCE_ACK 40
|
||||||
|
|
||||||
/* Reasons why an OR connection is closed */
|
/* Reasons why an OR connection is closed */
|
||||||
#define END_OR_CONN_REASON_DONE 1
|
#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_OR_IDENTITY 3
|
||||||
#define END_OR_CONN_REASON_TLS_CONNRESET 4 /* tls connection reset by peer */
|
#define END_OR_CONN_REASON_CONNRESET 4 /* connection reset by peer */
|
||||||
#define END_OR_CONN_REASON_TLS_TIMEOUT 5
|
#define END_OR_CONN_REASON_TIMEOUT 5
|
||||||
#define END_OR_CONN_REASON_TLS_NO_ROUTE 6 /* no route to host/net */
|
#define END_OR_CONN_REASON_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_IO_ERROR 7 /* read/write error */
|
||||||
#define END_OR_CONN_REASON_TLS_MISC 8
|
#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
|
/* Reasons why we (or a remote OR) might close a stream. See tor-spec.txt for
|
||||||
* documentation of these. */
|
* 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);
|
void connection_expire_held_open(void);
|
||||||
|
|
||||||
int connection_connect(connection_t *conn, const char *address, uint32_t addr,
|
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,
|
int retry_all_listeners(smartlist_t *replaced_conns,
|
||||||
smartlist_t *new_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_control_string(int reason);
|
||||||
const char *stream_end_reason_to_string(int reason);
|
const char *stream_end_reason_to_string(int reason);
|
||||||
socks5_reply_status_t stream_end_reason_to_socks5_response(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);
|
const char *orconn_end_reason_to_control_string(int r);
|
||||||
int tls_error_to_orconn_end_reason(int e);
|
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);
|
const char *circuit_end_reason_to_control_string(int reason);
|
||||||
|
|
||||||
|
@ -144,9 +144,8 @@ stream_end_reason_to_socks5_response(int reason)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Given an errno from a failed exit connection, return a reason code
|
/** Given an errno from a failed exit connection, return a reason code
|
||||||
* appropriate for use in a RELAY END cell.
|
* appropriate for use in a RELAY END cell. */
|
||||||
*/
|
uint8_t
|
||||||
int
|
|
||||||
errno_to_stream_end_reason(int e)
|
errno_to_stream_end_reason(int e)
|
||||||
{
|
{
|
||||||
switch (e) {
|
switch (e) {
|
||||||
@ -192,19 +191,21 @@ orconn_end_reason_to_control_string(int r)
|
|||||||
switch (r) {
|
switch (r) {
|
||||||
case END_OR_CONN_REASON_DONE:
|
case END_OR_CONN_REASON_DONE:
|
||||||
return "DONE";
|
return "DONE";
|
||||||
case END_OR_CONN_REASON_TCP_REFUSED:
|
case END_OR_CONN_REASON_REFUSED:
|
||||||
return "CONNECTREFUSED";
|
return "CONNECTREFUSED";
|
||||||
case END_OR_CONN_REASON_OR_IDENTITY:
|
case END_OR_CONN_REASON_OR_IDENTITY:
|
||||||
return "IDENTITY";
|
return "IDENTITY";
|
||||||
case END_OR_CONN_REASON_TLS_CONNRESET:
|
case END_OR_CONN_REASON_CONNRESET:
|
||||||
return "CONNECTRESET";
|
return "CONNECTRESET";
|
||||||
case END_OR_CONN_REASON_TLS_TIMEOUT:
|
case END_OR_CONN_REASON_TIMEOUT:
|
||||||
return "TIMEOUT";
|
return "TIMEOUT";
|
||||||
case END_OR_CONN_REASON_TLS_NO_ROUTE:
|
case END_OR_CONN_REASON_NO_ROUTE:
|
||||||
return "NOROUTE";
|
return "NOROUTE";
|
||||||
case END_OR_CONN_REASON_TLS_IO_ERROR:
|
case END_OR_CONN_REASON_IO_ERROR:
|
||||||
return "IOERROR";
|
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";
|
return "MISC";
|
||||||
case 0:
|
case 0:
|
||||||
return "";
|
return "";
|
||||||
@ -220,22 +221,59 @@ tls_error_to_orconn_end_reason(int e)
|
|||||||
{
|
{
|
||||||
switch (e) {
|
switch (e) {
|
||||||
case TOR_TLS_ERROR_IO:
|
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:
|
case TOR_TLS_ERROR_CONNREFUSED:
|
||||||
return END_OR_CONN_REASON_TCP_REFUSED;
|
return END_OR_CONN_REASON_REFUSED;
|
||||||
case TOR_TLS_ERROR_CONNRESET:
|
case TOR_TLS_ERROR_CONNRESET:
|
||||||
return END_OR_CONN_REASON_TLS_CONNRESET;
|
return END_OR_CONN_REASON_CONNRESET;
|
||||||
case TOR_TLS_ERROR_NO_ROUTE:
|
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:
|
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_WANTREAD:
|
||||||
case TOR_TLS_WANTWRITE:
|
case TOR_TLS_WANTWRITE:
|
||||||
case TOR_TLS_CLOSE:
|
case TOR_TLS_CLOSE:
|
||||||
case TOR_TLS_DONE:
|
case TOR_TLS_DONE:
|
||||||
return END_OR_CONN_REASON_DONE;
|
return END_OR_CONN_REASON_DONE;
|
||||||
default:
|
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