Commit d1381aef authored by Nick Mathewson's avatar Nick Mathewson 🤹
Browse files

r12652@Kushana: nickm | 2007-03-25 15:01:48 -0400

 A surprisingly simple patch to stop reading on edge connections when their circuits get too full, and start again when they empty out.  This lets us remove the logic to block begin_dir conns when the corresponding or conns get full: it was already broken by cell queues anyway.


svn:r9905
parent 38c0bb3a
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -6,6 +6,8 @@ Changes in version 0.2.0.1-alpha - 2007-??-??
      queue for each circuit.  This lets us use less slack memory, and
      will eventually let us be smarter about prioritizing different kinds
      of traffic.
    - Stop reading on edge connections when their corresponding circuit
      buffers are full; start again as the circuits empty out.

  o Security fixes:
    - Directory authorities now call routers stable if they have an
@@ -67,6 +69,9 @@ Changes in version 0.2.0.1-alpha - 2007-??-??
  o Code simplifications and refactoring
    - Stop passing around circuit_t and crypt_path_t pointers that are
      implicit in other procedure arguments.
    - Drop the old code to choke directory connections when the corresponding
      or connections got full: thanks to the cell queue feature, or conns
      don't get full any more.


Changes in version 0.1.2.12-rc - 2007-03-16
+1 −1
Original line number Diff line number Diff line
@@ -74,7 +74,7 @@ Things we'd like to do in 0.2.0.x:
        is full, not when the orconn is "too full".
      - Do we switch to arena-allocation for cells?
      - Can we stop doing so many memcpys on cells?
      - Also, only package data from exitconns when there is space on the
      o Also, only package data from exitconns when there is space on the
        target OR conn's outbuf?  or when the circuit is not too full.
      - MAYBE kill stalled circuits rather than stalled connections; consider
        anonymity implications.
+1 −43
Original line number Diff line number Diff line
@@ -416,10 +416,6 @@ connection_about_to_close_connection(connection_t *conn)
      }
      if (conn->purpose == DIR_PURPOSE_FETCH_RENDDESC)
        rend_client_desc_here(dir_conn->rend_query); /* give it a try */
      /* If this is from BEGIN_DIR, unlink it from the edge_conn and
       * the or_conn. */
      if (dir_conn->bridge_conn)
        connection_dirserv_unlink_from_bridge(dir_conn);
      break;
    case CONN_TYPE_OR:
      or_conn = TO_OR_CONN(conn);
@@ -446,13 +442,6 @@ connection_about_to_close_connection(connection_t *conn)
        control_event_or_conn_status(or_conn, OR_CONN_EVENT_CLOSED,
                control_tls_error_to_reason(or_conn->tls_error));
      }
      /* Remove any dir_conns that are blocked on this one.  Non-blocked
       * ones will die when the circuits do. */
      while (or_conn->blocked_dir_connections) {
        dir_connection_t *dir_conn = or_conn->blocked_dir_connections;
        connection_dirserv_unlink_from_bridge(dir_conn);
        tor_assert(or_conn->blocked_dir_connections != dir_conn);
      }
      /* Now close all the attached circuits on it. */
      circuit_unlink_all_from_or_conn(TO_OR_CONN(conn),
                                      END_CIRC_REASON_OR_CONN_CLOSED);
@@ -485,9 +474,6 @@ connection_about_to_close_connection(connection_t *conn)
      if (conn->state == EXIT_CONN_STATE_RESOLVING) {
        connection_dns_remove(edge_conn);
      }
      /* If we're relaying a dirserv connection, clean up any pointers */
      if (edge_conn->bridge_for_conn)
        connection_dirserv_unlink_from_bridge(edge_conn->bridge_for_conn);
      break;
  }
}
@@ -2431,8 +2417,7 @@ assert_connection_ok(connection_t *conn, time_t now)

  if (conn->outbuf_flushlen > 0) {
    tor_assert(connection_is_writing(conn) || conn->wants_to_write ||
               (conn->type == CONN_TYPE_DIR &&
                TO_DIR_CONN(conn)->is_blocked_on_or_conn));
               conn->edge_blocked_on_circ);
  }

  if (conn->hold_open_until_flushed)
@@ -2496,34 +2481,7 @@ assert_connection_ok(connection_t *conn, time_t now)
      tor_assert(conn->purpose == EXIT_PURPOSE_CONNECT ||
                 conn->purpose == EXIT_PURPOSE_RESOLVE);
    }
    if (edge_conn->bridge_for_conn) {
      tor_assert(conn->type == CONN_TYPE_EXIT);
      tor_assert(edge_conn->bridge_for_conn->bridge_conn == edge_conn);
    }
  } else if (conn->type == CONN_TYPE_DIR) {
    dir_connection_t *dir_conn = TO_DIR_CONN(conn);

    if (dir_conn->bridge_conn) {
      tor_assert(DIR_CONN_IS_SERVER(conn));
      tor_assert(dir_conn->bridge_conn->bridge_for_conn == dir_conn);
      if (dir_conn->bridge_conn->on_circuit) {
        dir_connection_t *d;
        or_connection_t *or_conn;
        tor_assert(!CIRCUIT_IS_ORIGIN(dir_conn->bridge_conn->on_circuit));
        or_conn = TO_OR_CIRCUIT(dir_conn->bridge_conn->on_circuit)->p_conn;
        if (dir_conn->is_blocked_on_or_conn)
          tor_assert(or_conn);
        for (d = or_conn->blocked_dir_connections; d;
             d = d->next_blocked_on_same_or_conn) {
          if (d == dir_conn) {
            tor_assert(dir_conn->is_blocked_on_or_conn == 1);
            break;
          }
        }
        if (!d)
          tor_assert(!dir_conn->is_blocked_on_or_conn);
      }
    }
  } else {
    /* Purpose is only used for dir and exit types currently */
    tor_assert(!conn->purpose);
+0 −3
Original line number Diff line number Diff line
@@ -2469,9 +2469,6 @@ connection_exit_connect_dir(edge_connection_t *exit_conn)
    return 0;
  }

  dir_conn->bridge_conn = exit_conn;
  exit_conn->bridge_for_conn = dir_conn;

  connection_start_reading(TO_CONN(dir_conn));
  connection_start_reading(TO_CONN(exit_conn));

+10 −39
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@ const char connection_or_c_id[] =

static int connection_tls_finish_handshake(or_connection_t *conn);
static int connection_or_process_cells_from_inbuf(or_connection_t *conn);
static int connection_or_empty_enough_for_dirserv_data(or_connection_t *conn);

/**************************************************************/

@@ -232,21 +231,22 @@ connection_or_process_inbuf(or_connection_t *conn)
  }
}

/**DOCDOC*/
#define OR_CONN_HIGHWATER (32*1024)

/**DOCDOC*/
#define OR_CONN_LOWWATER (16*1024)

/** Called whenever we have flushed some data on an or_conn: add more data
 * from active circuits. */
int
connection_or_flushed_some(or_connection_t *conn)
{
  if (conn->blocked_dir_connections &&
      connection_or_empty_enough_for_dirserv_data(conn)) {
    connection_dirserv_stop_blocking_all_on_or_conn(conn);
  }
  if (buf_datalen(conn->_base.outbuf) < 16*1024) {
    int n = (32*1024 - buf_datalen(conn->_base.outbuf)) / CELL_NETWORK_SIZE;
  size_t datalen = buf_datalen(conn->_base.outbuf);
  if (datalen < OR_CONN_LOWWATER) {
    int n = (OR_CONN_HIGHWATER - datalen) / CELL_NETWORK_SIZE;
    while (conn->active_circuits && n > 0) {
      int flushed;
      log_info(LD_GENERAL, "Loop, n==%d",n);
      flushed = connection_or_flush_from_first_active_circuit(conn, 1);
      int flushed = connection_or_flush_from_first_active_circuit(conn, 1);
      n -= flushed;
    }
  }
@@ -799,32 +799,3 @@ connection_or_send_destroy(uint16_t circ_id, or_connection_t *conn, int reason)
  return 0;
}
/** A high waterlevel for whether to refill this OR connection
 * with more directory information, if any is pending. */
#define DIR_BUF_FULLNESS_THRESHOLD (128*1024)
/** A bottom waterlevel for whether to refill this OR connection
 * with more directory information, if any is pending. We don't want
 * to make this too low, since we already run the risk of starving
 * the pending dir connections if the OR conn is frequently busy with
 * other things. */
#define DIR_BUF_EMPTINESS_THRESHOLD (96*1024)

/** Return true iff there is so much data waiting to be flushed on <b>conn</b>
 * that we should stop writing directory data to it. */
int
connection_or_too_full_for_dirserv_data(or_connection_t *conn)
{
  return buf_datalen(conn->_base.outbuf) > DIR_BUF_FULLNESS_THRESHOLD;
}

/** Return true iff there is no longer so much data waiting to be flushed on
 * <b>conn</b> that we should not write directory data to it. */
static int
connection_or_empty_enough_for_dirserv_data(or_connection_t *conn)
{
  /* Note that the threshold to stop writing is a bit higher than the
   * threshold to start again: this should (with any luck) keep us from
   * flapping about indefinitely. */
  return buf_datalen(conn->_base.outbuf) < DIR_BUF_EMPTINESS_THRESHOLD;
}
Loading