Browse Source

Merge branch 'ticket27686_035'

Nick Mathewson 5 years ago
parent
commit
88a93ccc7b
4 changed files with 47 additions and 3 deletions
  1. 18 2
      src/core/or/circuitlist.c
  2. 22 1
      src/core/or/connection_edge.c
  3. 6 0
      src/core/or/connection_edge.h
  4. 1 0
      src/core/or/relay.c

+ 18 - 2
src/core/or/circuitlist.c

@@ -1081,9 +1081,9 @@ circuit_free_(circuit_t *circ)
     circuit_remove_from_origin_circuit_list(ocirc);
 
     if (ocirc->half_streams) {
-      SMARTLIST_FOREACH_BEGIN(ocirc->half_streams, half_edge_t*,
+      SMARTLIST_FOREACH_BEGIN(ocirc->half_streams, half_edge_t *,
                               half_conn) {
-          tor_free(half_conn);
+        half_edge_free(half_conn);
       } SMARTLIST_FOREACH_END(half_conn);
       smartlist_free(ocirc->half_streams);
     }
@@ -2421,6 +2421,20 @@ n_cells_in_circ_queues(const circuit_t *c)
   return n;
 }
 
+/** Return the number of bytes allocated for <b>c</c>'s half-open streams. */
+static size_t
+circuit_alloc_in_half_streams(const circuit_t *c)
+{
+  if (! CIRCUIT_IS_ORIGIN(c)) {
+    return 0;
+  }
+  const origin_circuit_t *ocirc = CONST_TO_ORIGIN_CIRCUIT(c);
+  if (ocirc->half_streams)
+    return smartlist_len(ocirc->half_streams) * sizeof(half_edge_t);
+  else
+    return 0;
+}
+
 /**
  * Return the age of the oldest cell queued on <b>c</b>, in timestamp units.
  * Return 0 if there are no cells queued on c.  Requires that <b>now</b> be
@@ -2655,6 +2669,7 @@ circuits_handle_oom(size_t current_allocation)
 
     /* Now, kill the circuit. */
     n = n_cells_in_circ_queues(circ);
+    const size_t half_stream_alloc = circuit_alloc_in_half_streams(circ);
     if (! circ->marked_for_close) {
       circuit_mark_for_close(circ, END_CIRC_REASON_RESOURCELIMIT);
     }
@@ -2664,6 +2679,7 @@ circuits_handle_oom(size_t current_allocation)
     ++n_circuits_killed;
 
     mem_recovered += n * packed_cell_mem_cost();
+    mem_recovered += half_stream_alloc;
     mem_recovered += freed;
 
     if (mem_recovered >= mem_to_recover)

+ 22 - 1
src/core/or/connection_edge.c

@@ -520,6 +520,9 @@ connection_half_edge_compare_bsearch(const void *key, const void **member)
   return *(const streamid_t*)key - e2->stream_id;
 }
 
+/** Total number of half_edge_t objects allocated */
+static size_t n_half_conns_allocated = 0;
+
 /**
  * Add a half-closed connection to the list, to watch for activity.
  *
@@ -544,6 +547,7 @@ connection_half_edge_add(const edge_connection_t *conn,
   }
 
   half_conn = tor_malloc_zero(sizeof(half_edge_t));
+  ++n_half_conns_allocated;
 
   if (!circ->half_streams) {
     circ->half_streams = smartlist_new();
@@ -573,6 +577,23 @@ connection_half_edge_add(const edge_connection_t *conn,
   smartlist_insert(circ->half_streams, insert_at, half_conn);
 }
 
+/** Release space held by <b>he</b> */
+void
+half_edge_free_(half_edge_t *he)
+{
+  if (!he)
+    return;
+  --n_half_conns_allocated;
+  tor_free(he);
+}
+
+/** Return the number of bytes devoted to storing info on half-open streams. */
+size_t
+half_streams_get_total_allocation(void)
+{
+  return n_half_conns_allocated * sizeof(half_edge_t);
+}
+
 /**
  * Find a stream_id_t in the list in O(lg(n)).
  *
@@ -693,7 +714,7 @@ connection_half_edge_is_valid_end(smartlist_t *half_conns,
 
   half = smartlist_get(half_conns, remove_idx);
   smartlist_del_keeporder(half_conns, remove_idx);
-  tor_free(half);
+  half_edge_free(half);
   return 1;
 }
 

+ 6 - 0
src/core/or/connection_edge.h

@@ -185,6 +185,12 @@ int connection_half_edge_is_valid_end(smartlist_t *half_conns,
 int connection_half_edge_is_valid_resolved(smartlist_t *half_conns,
                                            streamid_t stream_id);
 
+size_t half_streams_get_total_allocation(void);
+struct half_edge_t;
+void half_edge_free_(struct half_edge_t *he);
+#define half_edge_free(he) \
+  FREE_AND_NULL(half_edge_t, half_edge_free_, (he))
+
 /** @name Begin-cell flags
  *
  * These flags are used in RELAY_BEGIN cells to change the default behavior

+ 1 - 0
src/core/or/relay.c

@@ -2604,6 +2604,7 @@ cell_queues_check_size(void)
 {
   time_t now = time(NULL);
   size_t alloc = cell_queues_get_total_allocation();
+  alloc += half_streams_get_total_allocation();
   alloc += buf_get_total_allocation();
   alloc += tor_compress_get_total_allocation();
   const size_t rend_cache_total = rend_cache_get_total_allocation();