Commit 38be533c authored by Roger Dingledine's avatar Roger Dingledine
Browse files

Handle unavailable hidden services better. We try each intro point

until none are left, then we try to refetch the descriptor. If it's
the same one we had before, then close streams right then. Whenever
a new stream arrives, even if it's right after, optimistically try
refetching the descriptor, just in case.


svn:r3379
parent ff481793
Loading
Loading
Loading
Loading
+10 −6
Original line number Diff line number Diff line
@@ -817,18 +817,22 @@ circuit_get_open_circ_or_launch(connection_t *conn,

    if (desired_circuit_purpose == CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT) {
      /* need to pick an intro point */
try_an_intro_point:
      exitname = rend_client_get_random_intro(conn->rend_query);
      if (!exitname) {
        log_fn(LOG_WARN,"Couldn't get an intro point for '%s'. Closing.",
        log_fn(LOG_INFO,"No intro points for '%s': refetching service descriptor.",
               conn->rend_query);
        return -1;
        rend_client_refetch_renddesc(conn->rend_query);
        conn->state = AP_CONN_STATE_RENDDESC_WAIT;
        return 0;
      }
      if (!router_get_by_nickname(exitname)) {
        log_fn(LOG_WARN,"Advertised intro point '%s' is not known. Closing.", exitname);
        log_fn(LOG_NOTICE,"Advertised intro point '%s' is not recognized for '%s'. Skipping over.",
               exitname, conn->rend_query);
        rend_client_remove_intro_point(exitname, conn->rend_query);
        tor_free(exitname);
        return -1;
        goto try_an_intro_point;
      }
      /* XXX if we failed, then refetch the descriptor */
      log_fn(LOG_INFO,"Chose %s as intro point for %s.", exitname, conn->rend_query);
    }

@@ -839,7 +843,7 @@ circuit_get_open_circ_or_launch(connection_t *conn,
      if (conn->chosen_exit_name) {
        exitname = tor_strdup(conn->chosen_exit_name);
        if (!router_get_by_nickname(exitname)) {
          log_fn(LOG_WARN,"Requested exit point '%s' is not known. Closing.", exitname);
          log_fn(LOG_NOTICE,"Requested exit point '%s' is not known. Closing.", exitname);
          tor_free(exitname);
          return -1;
        }
+6 −3
Original line number Diff line number Diff line
@@ -219,7 +219,7 @@ void connection_about_to_close_connection(connection_t *conn)
        connection_dir_connect_failed(conn);
      }
      if (conn->purpose == DIR_PURPOSE_FETCH_RENDDESC)
        rend_client_desc_fetched(conn->rend_query, 0);
        rend_client_desc_here(conn->rend_query); /* give it a try */
      break;
    case CONN_TYPE_OR:
      /* Remember why we're closing this connection. */
@@ -1243,9 +1243,11 @@ connection_t *connection_get_by_type_state_lastwritten(int type, int state) {
}

/** Return a connection of type <b>type</b> that has rendquery equal
 * to <b>rendquery</b>, and that is not marked for close.
 * to <b>rendquery</b>, and that is not marked for close. If state
 * is non-zero, conn must be of that state too.
 */
connection_t *connection_get_by_type_rendquery(int type, const char *rendquery) {
connection_t *
connection_get_by_type_state_rendquery(int type, int state, const char *rendquery) {
  int i, n;
  connection_t *conn;
  connection_t **carray;
@@ -1255,6 +1257,7 @@ connection_t *connection_get_by_type_rendquery(int type, const char *rendquery)
    conn = carray[i];
    if (conn->type == type &&
        !conn->marked_for_close &&
        (!state || state == conn->state) &&
        !rend_cmp_service_ids(rendquery, conn->rend_query))
      return conn;
  }
+1 −1
Original line number Diff line number Diff line
@@ -227,7 +227,7 @@ static int cpuworker_main(void *data) {
      if (r == 0) {
        log_fn(LOG_INFO,"CPU worker exiting because Tor process closed connection (either rotated keys or died).");
      } else {
        log_fn(LOG_INFO,"CPU worker editing because of error on connection To Tor process.");
        log_fn(LOG_INFO,"CPU worker editing because of error on connection to Tor process.");
        log_fn(LOG_INFO,"(Error on %d was %s)", fd, tor_socket_strerror(tor_socket_errno(fd)));
      }
      goto end;
+1 −1
Original line number Diff line number Diff line
@@ -746,8 +746,8 @@ connection_dir_client_reached_eof(connection_t *conn)
           * cleans it up */
        } else {
          /* success. notify pending connections about this. */
          rend_client_desc_fetched(conn->rend_query, 1);
          conn->purpose = DIR_PURPOSE_HAS_FETCHED_RENDDESC;
          rend_client_desc_here(conn->rend_query);
        }
        break;
      case 404:
+2 −2
Original line number Diff line number Diff line
@@ -1206,7 +1206,7 @@ connection_t *connection_get_by_identity_digest(const char *digest, int type);
connection_t *connection_get_by_type(int type);
connection_t *connection_get_by_type_state(int type, int state);
connection_t *connection_get_by_type_state_lastwritten(int type, int state);
connection_t *connection_get_by_type_rendquery(int type, const char *rendquery);
connection_t *connection_get_by_type_state_rendquery(int type, int state, const char *rendquery);

#define connection_speaks_cells(conn) ((conn)->type == CONN_TYPE_OR)
#define connection_has_pending_tls_data(conn) \
@@ -1495,7 +1495,7 @@ void rend_client_refetch_renddesc(const char *query);
int rend_client_remove_intro_point(char *failed_intro, const char *query);
int rend_client_rendezvous_acked(circuit_t *circ, const char *request, size_t request_len);
int rend_client_receive_rendezvous(circuit_t *circ, const char *request, size_t request_len);
void rend_client_desc_fetched(char *query, int status);
void rend_client_desc_here(char *query);

char *rend_client_get_random_intro(char *query);

Loading