commit ab92f934212f0f91f74cd171211117d20a28cc1e
Author: Nick Mathewson <ni...@torproject.org>
Date:   Fri Sep 14 10:16:27 2018 -0400

    Teach the OOM module to handle half-open stream info. #27686
---
 src/or/circuitlist.c     | 21 ++++++++++++++++++---
 src/or/connection_edge.c | 24 ++++++++++++++++++++++--
 src/or/connection_edge.h |  6 +++++-
 src/or/relay.c           |  2 +-
 4 files changed, 46 insertions(+), 7 deletions(-)

diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c
index a1efe9b74..ad9b902ac 100644
--- a/src/or/circuitlist.c
+++ b/src/or/circuitlist.c
@@ -1042,9 +1042,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);
     }
@@ -2324,6 +2324,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
@@ -2558,6 +2572,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);
     }
@@ -2567,6 +2582,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)
@@ -2711,4 +2727,3 @@ assert_circuit_ok,(const circuit_t *c))
     tor_assert(!or_circ || !or_circ->rend_splice);
   }
 }
-
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 1060e7461..eea364ffd 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -477,6 +477,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.
  *
@@ -501,6 +504,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();
@@ -530,6 +534,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)).
  *
@@ -650,7 +671,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;
 }
 
@@ -4412,4 +4433,3 @@ connection_edge_free_all(void)
   pending_entry_connections = NULL;
   mainloop_event_free(attach_pending_entry_connections_ev);
 }
-
diff --git a/src/or/connection_edge.h b/src/or/connection_edge.h
index 6dbba014c..7bef01e40 100644
--- a/src/or/connection_edge.h
+++ b/src/or/connection_edge.h
@@ -133,6 +133,11 @@ 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);
+void half_edge_free_(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
@@ -205,4 +210,3 @@ STATIC int 
connection_ap_process_http_connect(entry_connection_t *conn);
 #endif /* defined(CONNECTION_EDGE_PRIVATE) */
 
 #endif /* !defined(TOR_CONNECTION_EDGE_H) */
-
diff --git a/src/or/relay.c b/src/or/relay.c
index 81bb94d5a..497afe756 100644
--- a/src/or/relay.c
+++ b/src/or/relay.c
@@ -2586,6 +2586,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();
@@ -3142,4 +3143,3 @@ circuit_queue_streams_are_blocked(circuit_t *circ)
     return circ->streams_blocked_on_p_chan;
   }
 }
-



_______________________________________________
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits

Reply via email to