Commit 3456adec authored by Roger Dingledine's avatar Roger Dingledine
Browse files

adding the reattach-after-timeout feature wasn't so easy after all.

maybe it works now.


svn:r1101
parent 39efb0ed
Loading
Loading
Loading
Loading
+30 −21
Original line number Diff line number Diff line
@@ -677,13 +677,40 @@ void circuit_close(circuit_t *circ) {
  circuit_free(circ);
}

void circuit_detach_stream(circuit_t *circ, connection_t *conn) {
  connection_t *prevconn;

  assert(circ);
  assert(conn);

  if(conn == circ->p_streams) {
    circ->p_streams = conn->next_stream;
    return;
  }
  if(conn == circ->n_streams) {
    circ->n_streams = conn->next_stream;
    return;
  }
  for(prevconn = circ->p_streams; prevconn && prevconn->next_stream && prevconn->next_stream != conn; prevconn = prevconn->next_stream) ;
  if(prevconn && prevconn->next_stream) {
    prevconn->next_stream = conn->next_stream;
    return;
  }
  for(prevconn = circ->n_streams; prevconn && prevconn->next_stream && prevconn->next_stream != conn; prevconn = prevconn->next_stream) ;
  if(prevconn && prevconn->next_stream) {
    prevconn->next_stream = conn->next_stream;
    return;
  }
  log_fn(LOG_ERR,"edge conn not in circuit's list?");
  assert(0); /* should never get here */
}

void circuit_about_to_close_connection(connection_t *conn) {
  /* send destroys for all circuits using conn */
  /* currently, we assume it's too late to flush conn's buf here.
   * down the road, maybe we'll consider that eof doesn't mean can't-write
   */
  circuit_t *circ;
  connection_t *prevconn;

  switch(conn->type) {
    case CONN_TYPE_OR:
@@ -714,26 +741,8 @@ void circuit_about_to_close_connection(connection_t *conn) {
          log_fn(LOG_WARN,"1: I called connection_edge_end redundantly.");
      }

      if(conn == circ->p_streams) {
        circ->p_streams = conn->next_stream;
        return;
      }
      if(conn == circ->n_streams) {
        circ->n_streams = conn->next_stream;
        return;
      }
      for(prevconn = circ->p_streams; prevconn && prevconn->next_stream && prevconn->next_stream != conn; prevconn = prevconn->next_stream) ;
      if(prevconn && prevconn->next_stream) {
        prevconn->next_stream = conn->next_stream;
        return;
      }
      for(prevconn = circ->n_streams; prevconn && prevconn->next_stream && prevconn->next_stream != conn; prevconn = prevconn->next_stream) ;
      if(prevconn && prevconn->next_stream) {
        prevconn->next_stream = conn->next_stream;
        return;
      }
      log_fn(LOG_ERR,"edge conn not in circuit's list?");
      assert(0); /* should never get here */
      circuit_detach_stream(circ, conn);

  } /* end switch */
}

+27 −29
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@ extern char *conn_state_to_string[][_CONN_TYPE_MAX+1];

static int connection_ap_handshake_process_socks(connection_t *conn);
static int connection_ap_handshake_attach_circuit(connection_t *conn);
static int connection_ap_handshake_attach_circuit_helper(connection_t *conn);
static void connection_ap_handshake_send_begin(connection_t *ap_conn, circuit_t *circ);
static int connection_ap_handshake_socks_reply(connection_t *conn, char *reply,
                                               int replylen, char success);
@@ -302,16 +303,9 @@ int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, connection
        addr = ntohl(*(uint32_t*)(cell->payload+RELAY_HEADER_SIZE+1));
        client_dns_set_entry(conn->socks_request->address, addr);
        conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
        switch(connection_ap_handshake_attach_circuit(conn)) {
          case -1: /* it will never work */
            break; /* conn will get closed below */
          case 0: /* no useful circuits available */
            if(!circuit_get_newest(conn, 0)) /* is one already on the way? */
              circuit_launch_new();
            return 0;
          case 1: /* it succeeded, great */
        if(connection_ap_handshake_attach_circuit(conn) >= 0)
          return 0;
        }
        /* else, conn will get closed below */
      }
/* XXX add to this log_fn the exit node's nickname? */
      log_fn(LOG_INFO,"end cell (%s) for stream %d. Removing stream.",
@@ -545,6 +539,14 @@ void connection_ap_expire_beginning(void) {
       * reattach to this same circuit, but that's good enough for now.
       */
      conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
      circuit_detach_stream(circuit_get_by_conn(conn), conn);
      /* give it another 15 seconds to try */
      conn->timestamp_lastread += 15;
      if(connection_ap_handshake_attach_circuit(conn)<0) {
        /* it will never work */
        conn->marked_for_close = 1;
        conn->has_sent_end = 1;
      }
    }
  }
}
@@ -563,19 +565,10 @@ void connection_ap_attach_pending(void)
    if (conn->type != CONN_TYPE_AP ||
        conn->state != AP_CONN_STATE_CIRCUIT_WAIT)
      continue;
    switch(connection_ap_handshake_attach_circuit(conn)) {
      case -1: /* it will never work */
    if(connection_ap_handshake_attach_circuit(conn) < 0) {
      /* it will never work */
      conn->marked_for_close = 1;
      conn->has_sent_end = 1;
        break;
      case 0: /* we need to build another circuit */
        if(!circuit_get_newest(conn, 0)) {
          /* if there are no acceptable clean or not-very-dirty circs on the way */
          circuit_launch_new();
        }
        break;
      case 1: /* it succeeded, great */
        break;
    }
  }
}
@@ -632,18 +625,23 @@ static int connection_ap_handshake_process_socks(connection_t *conn) {
  } /* else socks handshake is done, continue processing */

  conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
  switch(connection_ap_handshake_attach_circuit(conn)) {
  return connection_ap_handshake_attach_circuit(conn);
}

static int connection_ap_handshake_attach_circuit(connection_t *conn) {
  /* try attaching. launch new circuit if needed.
   * return -1 if conn needs to die, else 0. */
  switch(connection_ap_handshake_attach_circuit_helper(conn)) {
    case -1: /* it will never work */
      return -1;
    case 0: /* no useful circuits available */
      if(!circuit_get_newest(conn, 0)) /* is one already on the way? */
        circuit_launch_new();
      break;
    case 1: /* it succeeded, great */
      break;
  }
      return 0;
    default: /* case 1, it succeeded, great */
      return 0;
  }
}

/* Try to find a safe live circuit for CONN_TYPE_AP connection conn. If
 * we don't find one: if conn cannot be handled by any known nodes,
@@ -651,7 +649,7 @@ static int connection_ap_handshake_process_socks(connection_t *conn) {
 * Otherwise, associate conn with a safe live circuit, start
 * sending a BEGIN cell down the circuit, and return 1.
 */
static int connection_ap_handshake_attach_circuit(connection_t *conn) {
static int connection_ap_handshake_attach_circuit_helper(connection_t *conn) {
  circuit_t *circ;
  uint32_t addr;

+1 −0
Original line number Diff line number Diff line
@@ -588,6 +588,7 @@ int circuit_consider_stop_edge_reading(circuit_t *circ, int edge_type, crypt_pat
void circuit_consider_sending_sendme(circuit_t *circ, int edge_type, crypt_path_t *layer_hint);

void circuit_close(circuit_t *circ);
void circuit_detach_stream(circuit_t *circ, connection_t *conn);
void circuit_about_to_close_connection(connection_t *conn);

void circuit_log_path(int severity, circuit_t *circ);