]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Merge branch 'bug11792_1_squashed'
authorNick Mathewson <nickm@torproject.org>
Sun, 24 Aug 2014 17:09:08 +0000 (13:09 -0400)
committerNick Mathewson <nickm@torproject.org>
Sun, 24 Aug 2014 17:09:08 +0000 (13:09 -0400)
Conflicts:
src/or/circuitlist.c

1  2 
src/common/torgzip.c
src/or/circuitlist.c
src/or/relay.c

Simple merge
index d6bc67431f7b66346098ed32c20ea8ba42efdc59,68534208c6da84f2898b0cf3e1b0005391e18e8c..e04b4b93483b8a94a4d67be974fae64fbabb1204
@@@ -1975,7 -2009,11 +2034,9 @@@ conns_compare_by_buffer_age_(const voi
  void
  circuits_handle_oom(size_t current_allocation)
  {
 -  /* Let's hope there's enough slack space for this allocation here... */
 -  smartlist_t *circlist = smartlist_new();
 +  smartlist_t *circlist;
+   smartlist_t *connection_array = get_connection_array();
+   int conn_idx;
 -  circuit_t *circ;
    size_t mem_to_recover;
    size_t mem_recovered=0;
    int n_circuits_killed=0;
    /* This is O(n log n); there are faster algorithms we could use instead.
     * Let's hope this doesn't happen enough to be in the critical path. */
    smartlist_sort(circlist, circuits_compare_by_oldest_queued_item_);
-   /* Okay, now the worst circuits are at the front of the list. Let's mark
-    * them, and reclaim their storage aggressively. */
 +
 +  /* Fix up the indices before we run into trouble */
 +  SMARTLIST_FOREACH_BEGIN(circlist, circuit_t *, circ) {
 +    circ->global_circuitlist_idx = circ_sl_idx;
 +  } SMARTLIST_FOREACH_END(circ);
 +
++
++  /* Now sort the connection array ... */
+   now_ms_for_buf_cmp = now_ms;
+   smartlist_sort(connection_array, conns_compare_by_buffer_age_);
+   now_ms_for_buf_cmp = 0;
+   /* Fix up the connection array to its new order. */
+   SMARTLIST_FOREACH_BEGIN(connection_array, connection_t *, conn) {
+     conn->conn_array_index = conn_sl_idx;
+   } SMARTLIST_FOREACH_END(conn);
+   /* Okay, now the worst circuits and connections are at the front of their
+    * respective lists. Let's mark them, and reclaim their storage
+    * aggressively. */
+   conn_idx = 0;
    SMARTLIST_FOREACH_BEGIN(circlist, circuit_t *, circ) {
-     size_t n = n_cells_in_circ_queues(circ);
+     size_t n;
      size_t freed;
+     /* Free storage in any non-linked directory connections that have buffered
+      * data older than this circuit. */
+     while (conn_idx < smartlist_len(connection_array)) {
+       connection_t *conn = smartlist_get(connection_array, conn_idx);
+       uint32_t conn_age = conn_get_buffer_age(conn, now_ms);
+       if (conn_age < circ->age_tmp) {
+         break;
+       }
+       if (conn->type == CONN_TYPE_DIR && conn->linked_conn == NULL) {
+         if (!conn->marked_for_close)
+           connection_mark_for_close(conn);
+         mem_recovered += single_conn_free_bytes(conn);
+         ++n_dirconns_killed;
+         if (mem_recovered >= mem_to_recover)
+           goto done_recovering_mem;
+       }
+       ++conn_idx;
+     }
+     /* Now, kill the circuit. */
+     n = n_cells_in_circ_queues(circ);
      if (! circ->marked_for_close) {
        circuit_mark_for_close(circ, END_CIRC_REASON_RESOURCELIMIT);
      }
                                chunks. */
  
    log_notice(LD_GENERAL, "Removed "U64_FORMAT" bytes by killing %d circuits; "
-              "%d circuits remain alive.",
+              "%d circuits remain alive. Also killed %d non-linked directory "
+              "connections.",
               U64_PRINTF_ARG(mem_recovered),
               n_circuits_killed,
-              smartlist_len(circlist) - n_circuits_killed);
+              smartlist_len(circlist) - n_circuits_killed,
+              n_dirconns_killed);
 -
 -  smartlist_free(circlist);
  }
  
  /** Verify that cpath layer <b>cp</b> has all of its invariants
diff --cc src/or/relay.c
Simple merge