[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[tor-commits] [tor] 14/77: hs: Maximum rend request and trimming of the queue



This is an automated email from the git hooks/post-receive script.

dgoulet pushed a commit to branch main
in repository tor.

commit 047f8c63ee6793bee1f0db292e4041c31d23ca85
Author: David Goulet <dgoulet@xxxxxxxxxxxxxx>
AuthorDate: Thu Jun 30 10:37:53 2022 -0400

    hs: Maximum rend request and trimming of the queue
    
    Signed-off-by: David Goulet <dgoulet@xxxxxxxxxxxxxx>
---
 src/feature/hs/hs_circuit.c | 64 ++++++++++++++++++++++++++++++++++++++-------
 src/feature/hs/hs_circuit.h |  5 +++-
 2 files changed, 59 insertions(+), 10 deletions(-)

diff --git a/src/feature/hs/hs_circuit.c b/src/feature/hs/hs_circuit.c
index 3d9892e482..da852d7107 100644
--- a/src/feature/hs/hs_circuit.c
+++ b/src/feature/hs/hs_circuit.c
@@ -22,6 +22,7 @@
 #include "feature/client/circpathbias.h"
 #include "feature/hs/hs_cell.h"
 #include "feature/hs/hs_circuit.h"
+#include "feature/hs/hs_common.h"
 #include "feature/hs/hs_ob.h"
 #include "feature/hs/hs_circuitmap.h"
 #include "feature/hs/hs_client.h"
@@ -45,6 +46,18 @@
 #include "feature/nodelist/node_st.h"
 #include "core/or/origin_circuit_st.h"
 
+/** Helper: Free a pending rend object. */
+static inline void
+free_pending_rend(pending_rend_t *req)
+{
+  if (!req) {
+    return;
+  }
+  link_specifier_smartlist_free(req->rdv_data.link_specifiers);
+  memwipe(req, 0, sizeof(pending_rend_t));
+  tor_free(req);
+}
+
 /** A circuit is about to become an e2e rendezvous circuit. Check
  * <b>circ_purpose</b> and ensure that it's properly set. Return true iff
  * circuit purpose is properly set, otherwise return false. */
@@ -617,6 +630,20 @@ compare_rend_request_by_effort_(const void *_a, const void *_b)
   }
 }
 
+/** Remove too old entries from the given rendezvous request priority queue. */
+static void
+trim_rend_pqueue(smartlist_t *pqueue)
+{
+  time_t now = time(NULL);
+
+  SMARTLIST_FOREACH_BEGIN(pqueue, pending_rend_t *, req) {
+    if ((req->enqueued_ts + MAX_REND_TIMEOUT) < now) {
+      SMARTLIST_DEL_CURRENT_KEEPORDER(pqueue, req);
+      free_pending_rend(req);
+    }
+  } SMARTLIST_FOREACH_END(req);
+}
+
 /** How many rendezvous request we handle per mainloop event. Per prop327,
  * handling an INTRODUCE2 cell takes on average 5.56msec on an average CPU and
  * so it means that launching this max amount of circuits is well below 0.08
@@ -632,6 +659,10 @@ handle_rend_pqueue_cb(mainloop_event_t *ev, void *arg)
 
   (void) ev; /* Not using the returned event, make compiler happy. */
 
+  /* Before we process rendezvous request, trim the list to remove out dated
+   * entries. */
+  trim_rend_pqueue(pow_state->rend_request_pqueue);
+
   /* Process rendezvous request until the maximum per mainloop run. */
   while (smartlist_len(pow_state->rend_request_pqueue) > 0) {
     if (++count == MAX_REND_REQUEST_PER_MAINLOOP) {
@@ -652,11 +683,7 @@ handle_rend_pqueue_cb(mainloop_event_t *ev, void *arg)
     /* Launch the rendezvous circuit. */
     launch_rendezvous_point_circuit(service, &req->ip_auth_pubkey,
                                     &req->ip_enc_key_kp, &req->rdv_data);
-
-    /* Clean memory. */
-    link_specifier_smartlist_free(req->rdv_data.link_specifiers);
-    memwipe(req, 0, sizeof(pending_rend_t));
-    tor_free(req);
+    free_pending_rend(req);
   }
 
   /* If there are still some pending rendezvous circuits in the pqueue then
@@ -666,10 +693,17 @@ handle_rend_pqueue_cb(mainloop_event_t *ev, void *arg)
   }
 }
 
-/** HRPR: Given the information needed to launch a rendezvous circuit and an
+/** Maximum number of rendezvous requests we enqueue per service. We allow the
+ * average amount of INTRODUCE2 that a service can process in a second times
+ * the rendezvous timeout. */
+#define MAX_REND_REQUEST (180 * MAX_REND_TIMEOUT)
+
+/** Given the information needed to launch a rendezvous circuit and an
  * effort value, enqueue the rendezvous request in the service's PoW priority
- * queue with the effort being the priority. */
-static void
+ * queue with the effort being the priority.
+ *
+ * Return 0 if we successfully enqueued the request else -1. */
+static int
 enqueue_rend_request(const hs_service_t *service, hs_service_intro_point_t *ip,
                      hs_cell_introduce2_data_t *data)
 {
@@ -682,6 +716,13 @@ enqueue_rend_request(const hs_service_t *service, hs_service_intro_point_t *ip,
 
   /* Ease our lives */
   pow_state = service->state.pow_state;
+
+  if (smartlist_len(pow_state->rend_request_pqueue) >= MAX_REND_REQUEST) {
+    log_info(LD_REND, "Rendezvous request priority queue has "
+                      "reached capacity.");
+    return -1;
+  }
+
   req = tor_malloc_zero(sizeof(pending_rend_t));
 
   /* Copy over the rendezvous request the needed data to launch a circuit. */
@@ -692,6 +733,7 @@ enqueue_rend_request(const hs_service_t *service, hs_service_intro_point_t *ip,
    * doesn't get freed under us. */
   data->rdv_data.link_specifiers = NULL;
   req->idx = -1;
+  req->enqueued_ts = time(NULL);
 
   /* Enqueue the rendezvous request. */
   smartlist_pqueue_add(pow_state->rend_request_pqueue,
@@ -711,6 +753,8 @@ enqueue_rend_request(const hs_service_t *service, hs_service_intro_point_t *ip,
 
   /* Activate event, we just enqueued a rendezvous request. */
   mainloop_event_activate(pow_state->pop_pqueue_ev);
+
+  return 0;
 }
 
 /* ========== */
@@ -1164,7 +1208,9 @@ hs_circ_handle_introduce2(const hs_service_t *service,
   if (service->config.has_pow_defenses_enabled) {
     log_debug(LD_REND, "Adding introduction request to pqueue with effort: %u",
               data.rdv_data.pow_effort);
-    enqueue_rend_request(service, ip, &data);
+    if (enqueue_rend_request(service, ip, &data) < 0) {
+      goto done;
+    }
 
     /* Increase the total effort in valid requests received this period. */
     service->state.pow_state->total_effort += data.rdv_data.pow_effort;
diff --git a/src/feature/hs/hs_circuit.h b/src/feature/hs/hs_circuit.h
index 8f888c569e..cbd48c5b33 100644
--- a/src/feature/hs/hs_circuit.h
+++ b/src/feature/hs/hs_circuit.h
@@ -15,7 +15,7 @@
 #include "feature/hs/hs_cell.h"
 #include "feature/hs/hs_service.h"
 
-/* HRPR TODO Putting this here for now... */
+/** Pending rendezvous request. This is put in a service priority queue. */
 typedef struct pending_rend_t {
   /* Intro point authentication pubkey. */
   ed25519_public_key_t ip_auth_pubkey;
@@ -27,6 +27,9 @@ typedef struct pending_rend_t {
 
   /** Position of element in the heap */
   int idx;
+
+  /** When was this request enqueued. */
+  time_t enqueued_ts;
 } pending_rend_t;
 
 /* Cleanup function when the circuit is closed or freed. */

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits