Bugs when registering guard status in connection_or_connect()
In connection_or_connect()
we can see the following snippet:
switch (connection_connect(TO_CONN(conn), conn->base_.address,
&addr, port, &socket_error)) {
case -1:
/* If the connection failed immediately, and we're using
* a proxy, our proxy is down. Don't blame the Tor server. */
if (conn->base_.proxy_state == PROXY_INFANT)
entry_guard_register_connect_status(conn->identity_digest,
0, 1, time(NULL));
connection_or_connect_failed(conn,
errno_to_orconn_end_reason(socket_error),
tor_socket_strerror(socket_error));
connection_free(TO_CONN(conn));
return NULL;
I see two problems here:
a) connection_or_connect()
can fail in ways that are unrelated to the guard node. For example it can fail with this codepath, in which case the guard should not be marked as down:
s = tor_open_socket_nonblocking(protocol_family,SOCK_STREAM,IPPROTO_TCP);
if (! SOCKET_OK(s)) {
*socket_error = tor_socket_errno(-1);
log_warn(LD_NET,"Error creating network socket: %s",
tor_socket_strerror(*socket_error));
return -1;
}
b) Also, he comment seems to state the opposite than what the code does. That is, the comment claims that if we are using a proxy and it's down, we shouldn't mark the guard as down. But the code only marks the guard as down, if the proxy state is PROXY_INFANT
which is the state of a proxy when we haven't connected to it yet. I think the bug was introduced by me in a79bea40d
.
I think a better solution here is to check for proxy_type == PROXY_NONE
before marking the guard as down.