[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [tor] 30/77: Implement AIMD effort estimation.
This is an automated email from the git hooks/post-receive script.
dgoulet pushed a commit to branch main
in repository tor.
commit ec9e95cf1ee9aff6f2607f0b45e1d6d1f7ba4513
Author: Mike Perry <mikeperry-git@xxxxxxxxxxxxxx>
AuthorDate: Wed Jul 13 23:33:07 2022 +0000
Implement AIMD effort estimation.
Now, pow should auto-enable and auto-disable itself.
---
src/feature/hs/hs_circuit.c | 24 +++++++++++++++++++++---
src/feature/hs/hs_circuit.h | 2 ++
src/feature/hs/hs_pow.h | 5 +++++
src/feature/hs/hs_service.c | 31 ++++++++++++++++++++++++++-----
4 files changed, 54 insertions(+), 8 deletions(-)
diff --git a/src/feature/hs/hs_circuit.c b/src/feature/hs/hs_circuit.c
index acb33bbf88..3f17373b69 100644
--- a/src/feature/hs/hs_circuit.c
+++ b/src/feature/hs/hs_circuit.c
@@ -678,6 +678,10 @@ trim_rend_pqueue(hs_pow_service_state_t *pow_state, time_t now)
if (queued_rend_request_is_too_old(req, now)) {
log_info(LD_REND, "While trimming, rend request has been pending "
"for too long; discarding.");
+
+ if (req->rdv_data.pow_effort > pow_state->max_trimmed_effort)
+ pow_state->max_trimmed_effort = req->rdv_data.pow_effort;
+
free_pending_rend(req);
} else {
smartlist_pqueue_add(new_pqueue,
@@ -689,6 +693,9 @@ trim_rend_pqueue(hs_pow_service_state_t *pow_state, time_t now)
/* Ok, we have rescued all the entries we want to keep. The rest are
* all excess. */
SMARTLIST_FOREACH_BEGIN(old_pqueue, pending_rend_t *, req) {
+ if (req->rdv_data.pow_effort > pow_state->max_trimmed_effort)
+ pow_state->max_trimmed_effort = req->rdv_data.pow_effort;
+
free_pending_rend(req);
} SMARTLIST_FOREACH_END(req);
smartlist_free(old_pqueue);
@@ -719,7 +726,7 @@ count_service_rp_circuits_pending(hs_service_t *service)
* effort is at least what we're suggesting for that service right now,
* return 1, else return 0.
*/
-static int
+int
top_of_rend_pqueue_is_worthwhile(hs_pow_service_state_t *pow_state)
{
tor_assert(pow_state->rend_request_pqueue);
@@ -815,6 +822,15 @@ handle_rend_pqueue_cb(mainloop_event_t *ev, void *arg)
* reschedule the event in order to continue handling them. */
if (smartlist_len(pow_state->rend_request_pqueue) > 0) {
mainloop_event_activate(pow_state->pop_pqueue_ev);
+
+ // XXX: Is this a good threshhold to decide that we have a significant
+ // queue? I just made it up.
+ if (smartlist_len(pow_state->rend_request_pqueue) >
+ 2*MAX_REND_REQUEST_PER_MAINLOOP) {
+ /* Note the fact that we had multiple eventloops worth of queue
+ * to service, for effort estimation */
+ pow_state->had_queue = 1;
+ }
}
}
@@ -1334,8 +1350,10 @@ hs_circ_handle_introduce2(const hs_service_t *service,
goto done;
}
- /* Increase the total effort in valid requests received this period. */
- service->state.pow_state->total_effort += data.rdv_data.pow_effort;
+ /* 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);
/* Successfully added rend circuit to priority queue. */
ret = 0;
diff --git a/src/feature/hs/hs_circuit.h b/src/feature/hs/hs_circuit.h
index d61ddcede8..da4eb9aa0b 100644
--- a/src/feature/hs/hs_circuit.h
+++ b/src/feature/hs/hs_circuit.h
@@ -32,6 +32,8 @@ typedef struct pending_rend_t {
time_t enqueued_ts;
} pending_rend_t;
+int top_of_rend_pqueue_is_worthwhile(hs_pow_service_state_t *pow_state);
+
/* Cleanup function when the circuit is closed or freed. */
void hs_circ_cleanup_on_close(circuit_t *circ);
void hs_circ_cleanup_on_free(circuit_t *circ);
diff --git a/src/feature/hs/hs_pow.h b/src/feature/hs/hs_pow.h
index 019fea400e..bc0b823fd9 100644
--- a/src/feature/hs/hs_pow.h
+++ b/src/feature/hs/hs_pow.h
@@ -87,6 +87,9 @@ typedef struct hs_pow_service_state_t {
* be serviced in a timely manner. */
uint32_t suggested_effort;
+ /* The maximum effort of a request we've had to trim, this update period */
+ uint32_t max_trimmed_effort;
+
/* The following values are used when calculating and updating the suggested
* effort every HS_UPDATE_PERIOD seconds. */
@@ -96,6 +99,8 @@ typedef struct hs_pow_service_state_t {
time_t next_effort_update;
/* Sum of effort of all valid requests received since the last update. */
uint64_t total_effort;
+ /* Did we have elements waiting in the queue during this period? */
+ bool had_queue;
} hs_pow_service_state_t;
/* Struct to store a solution to the PoW challenge. */
diff --git a/src/feature/hs/hs_service.c b/src/feature/hs/hs_service.c
index 045022f182..4f8a689290 100644
--- a/src/feature/hs/hs_service.c
+++ b/src/feature/hs/hs_service.c
@@ -2678,21 +2678,42 @@ update_suggested_effort(hs_service_t *service, time_t now)
/* Make life easier */
hs_pow_service_state_t *pow_state = service->state.pow_state;
- /* Calculate the new suggested effort. */
- /* TODO Check for overflow? */
- pow_state->suggested_effort = (uint32_t)(pow_state->total_effort / pow_state->rend_handled);
+ /* Calculate the new suggested effort, using an additive-increase
+ * multiplicative-decrease estimation scheme. */
+ if (pow_state->max_trimmed_effort > pow_state->suggested_effort) {
+ /* If we trimmed a request above our suggested effort, re-estimate the
+ * effort */
+ pow_state->suggested_effort = (uint32_t)(pow_state->total_effort /
+ 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). */
+ if (top_of_rend_pqueue_is_worthwhile(pow_state)) {
+ pow_state->suggested_effort = (uint32_t)(pow_state->total_effort /
+ pow_state->rend_handled);
+ }
+ } else {
+ /* If we were able to keep the queue drained the entire update period,
+ * multiplicative decrease the pow by 2/3. */
+ pow_state->suggested_effort = 2*pow_state->suggested_effort/3;
+ }
log_debug(LD_REND, "Recalculated suggested effort: %u",
pow_state->suggested_effort);
- /* Set suggested effort to max(min_effort, 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) {
- 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;
+ pow_state->max_trimmed_effort = 0;
+ pow_state->had_queue = 0;
pow_state->next_effort_update = now + HS_UPDATE_PERIOD;
}
--
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