]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
hs_pow: stop having a "minimum effort", and let PoW effort start low
authorMicah Elizabeth Scott <beth@torproject.org>
Tue, 21 Mar 2023 19:28:23 +0000 (12:28 -0700)
committerMicah Elizabeth Scott <beth@torproject.org>
Wed, 10 May 2023 14:38:29 +0000 (07:38 -0700)
I don't think the concept of "minimum effort" is really useful to us,
so this patch removes it entirely and consequentially changes the way
that "total" effort is calculated so that we don't rely on any minimum
and we instead ramp up effort no faster than necessary.

If at least some portion of the attack is conducted by clients that
avoid PoW or provide incorrect solutions, those (potentially very
cheap) attacks will end up keeping the pqueue full. Prior to this patch,
that would cause suggested efforts to be unnecessarily high, because
rounding these very cheap requests up to even a minimum of 1 will
overestimate how much actual attack effort is being spent.

The result is that this patch is a simplification and it also allows a
slower start, where PoW effort jumps up either by a single unit or by an
amount calculated from actual effort in the queue.

Signed-off-by: Micah Elizabeth Scott <beth@torproject.org>
src/feature/hs/hs_circuit.c
src/feature/hs/hs_config.h
src/feature/hs/hs_pow.c
src/feature/hs/hs_pow.h
src/feature/hs/hs_service.c
src/feature/hs/hs_service.h

index f7ab6442b902ed24ee3cdfee409dc375110573e3..82c77fcfcb6fcad2d81f8bff785287a0b1ba94c1 100644 (file)
@@ -1377,10 +1377,8 @@ hs_circ_handle_introduce2(const hs_service_t *service,
       goto done;
     }
 
-    /* Increase the total effort in valid requests received this period,
-     * but count 0-effort as min-effort, for estimation purposes. */
-    service->state.pow_state->total_effort += MAX(data.rdv_data.pow_effort,
-                                      service->state.pow_state->min_effort);
+    /* Track the total effort in valid requests received this period */
+    service->state.pow_state->total_effort += data.rdv_data.pow_effort;
 
     /* Successfully added rend circuit to priority queue. */
     ret = 0;
index 831f7cf9222571dc7ff7958dcdd8a060624940b3..bde6da9612f8572bde880a4e18db62a8fe02b76b 100644 (file)
@@ -27,7 +27,6 @@
 
 /* Default values for the HS anti-DoS PoW defenses. */
 #define HS_CONFIG_V3_POW_DEFENSES_DEFAULT 0
-#define HS_CONFIG_V3_POW_DEFENSES_MIN_EFFORT_DEFAULT 1
 
 /* API */
 
index b5a359940c1bc183ad82d81287e3c44e54dac680..08981699df01d82d782ae9a92500ec785b11999d 100644 (file)
@@ -256,15 +256,6 @@ hs_pow_verify(const hs_pow_service_state_t *pow_state,
   tor_assert(pow_state);
   tor_assert(pow_solution);
 
-  /* Notice, but don't fail, if E = POW_EFFORT is lower than the minimum
-   * effort. We will take whatever valid cells arrive, put them into the
-   * pqueue, and get to whichever ones we get to. */
-  if (pow_solution->effort < pow_state->min_effort) {
-    log_info(LD_REND, "Effort %d used in solution is less than the minimum "
-                      "effort %d required by the service. That's ok.",
-                       pow_solution->effort, pow_state->min_effort);
-  }
-
   /* Find a valid seed C that starts with the seed head. Fail if no such seed
    * exists. */
   if (fast_memeq(pow_state->seed_current, pow_solution->seed_head,
index de4d9df94c2accfa7fb29b1cd0a504e485d87743..fe78a48d9a40474e225c8c3cc083d78366facace 100644 (file)
@@ -81,9 +81,6 @@ typedef struct hs_pow_service_state_t {
   /* The time at which the current seed expires and rotates for a new one. */
   time_t expiration_time;
 
-  /* The minimum effort required for a valid solution. */
-  uint32_t min_effort;
-
   /* The suggested effort that clients should use in order for their request to
    * be serviced in a timely manner. */
   uint32_t suggested_effort;
index 44d39e6525704144ef41da5d4b541e173831b9f0..3b93ee67bade601fae709b551804a1e520a9627b 100644 (file)
@@ -264,7 +264,6 @@ set_service_default_config(hs_service_config_t *c,
   c->intro_dos_burst_per_sec = HS_CONFIG_V3_DOS_DEFENSE_BURST_PER_SEC_DEFAULT;
   /* PoW default options. */
   c->has_dos_defense_enabled = HS_CONFIG_V3_POW_DEFENSES_DEFAULT;
-  c->pow_min_effort = HS_CONFIG_V3_POW_DEFENSES_MIN_EFFORT_DEFAULT;
 }
 
 /** Initialize PoW defenses */
@@ -288,8 +287,6 @@ initialize_pow_defenses(hs_service_t *service)
                           (uint32_t) approx_time());
   }
 
-  pow_state->min_effort = service->config.pow_min_effort;
-
   /* We recalculate and update the suggested effort every HS_UPDATE_PERIOD
    * seconds. */
   pow_state->suggested_effort = 0;
@@ -2696,12 +2693,14 @@ update_suggested_effort(hs_service_t *service, time_t now)
                                              pow_state->rend_handled);
   } else if (pow_state->had_queue) {
     /* If we had a queue during this period, and the current top of queue
-     * is at or above the suggested effort, we should re-estimate the effort.
-     * Otherwise, it can stay the same (no change to effort). */
+     * is at or above the suggested effort, we should re-estimate the effort
+     * and increase it at least a minimal amount. Otherwise, it can stay the
+     * same (no change to effort). */
     if (smartlist_len(pow_state->rend_request_pqueue) > 0 &&
         top_of_rend_pqueue_is_worthwhile(pow_state)) {
-      pow_state->suggested_effort = (uint32_t)(pow_state->total_effort /
-                                               pow_state->rend_handled);
+      pow_state->suggested_effort = MAX(pow_state->suggested_effort + 1,
+                                        (uint32_t)(pow_state->total_effort /
+                                                   pow_state->rend_handled));
     }
   } else {
     /* If we were able to keep the queue drained the entire update period,
@@ -2714,13 +2713,6 @@ update_suggested_effort(hs_service_t *service, time_t now)
   log_debug(LD_REND, "Recalculated suggested effort: %u",
             pow_state->suggested_effort);
 
-  /* If the suggested effort has been decreased below the minimum, set it
-   * to zero: no pow needed again until we queue or trim */
-  if (pow_state->suggested_effort < pow_state->min_effort) {
-    // XXX: Verify this disables pow being done at all.
-    pow_state->suggested_effort = 0;
-  }
-
   /* Reset the total effort sum and number of rends for this update period. */
   pow_state->total_effort = 0;
   pow_state->rend_handled = 0;
index 37984bd6c8c88e96cab6f43e97713517fdbd9076..e7e53e73a3562d7bee01e6aaa48054ca26f5e7bb 100644 (file)
@@ -264,7 +264,6 @@ typedef struct hs_service_config_t {
 
   /** True iff PoW anti-DoS defenses are enabled. */
   unsigned int has_pow_defenses_enabled : 1;
-  uint32_t pow_min_effort;
   uint32_t pow_queue_rate;
   uint32_t pow_queue_burst;