The maximum burst size for rendezvous requests handled from the
priority queue at once. (Default: 2500)
+These options are applicable to both onion services and their clients:
+
+[[CompiledProofOfWorkHash]] **CompiledProofOfWorkHash** **0**|**1**|**auto**::
+ When proof-of-work DoS mitigation is active, both the services themselves
+ and the clients which connect will use a dynamically generated hash
+ function as part of the puzzle computation.
+ +
+ If this option is set to 1, puzzles will only be solved and verified using
+ the compiled implementation (about 20x faster) and we choose to fail rather
+ than using a slower fallback. If it's 0, the compiler will never be used.
+ By default, the compiler is always tried if possible but the interpreter is
+ available as a fallback. (Default: auto)
+
+See also <<opt-list-modules,`--list-modules`>>, these proof of work options
+have no effect unless the "`pow`" module is enabled at compile time.
== DIRECTORY AUTHORITY SERVER OPTIONS
V(ClientTransportPlugin, LINELIST, NULL),
V(ClientUseIPv6, BOOL, "1"),
V(ClientUseIPv4, BOOL, "1"),
+ V(CompiledProofOfWorkHash, AUTOBOOL, "auto"),
V(ConfluxEnabled, AUTOBOOL, "auto"),
VAR("ConfluxClientUX", STRING, ConfluxClientUX_option,
"throughput"),
* accessing this value directly. */
int ClientPreferIPv6DirPort;
+ /** If true, always use the compiled hash implementation. If false, always
+ * the interpreter. Default of "auto" allows a dynamic fallback from
+ * copmiler to interpreter. */
+ int CompiledProofOfWorkHash;
+
/** If true, the tor client will use conflux for its general purpose
* circuits which excludes onion service traffic. */
int ConfluxEnabled;
*/
if (have_module_pow() && desc->encrypted_data.pow_params) {
hs_pow_solver_inputs_t pow_inputs = {
- .effort = desc->encrypted_data.pow_params->suggested_effort
+ .effort = desc->encrypted_data.pow_params->suggested_effort,
+ .CompiledProofOfWorkHash = get_options()->CompiledProofOfWorkHash
};
ed25519_pubkey_copy(&pow_inputs.service_blinded_id,
&desc->plaintext_data.blinded_pubkey);
}
}
+/** Helper: Map the CompiledProofOfWorkHash configuration option to its
+ * corresponding equix_ctx_flags bit. */
+static equix_ctx_flags
+hs_pow_equix_option_flags(int CompiledProofOfWorkHash)
+{
+ if (CompiledProofOfWorkHash == 0) {
+ return 0;
+ } else if (CompiledProofOfWorkHash == 1) {
+ return EQUIX_CTX_MUST_COMPILE;
+ } else {
+ tor_assert_nonfatal(CompiledProofOfWorkHash == -1);
+ return EQUIX_CTX_TRY_COMPILE;
+ }
+}
+
/** Solve the EquiX/blake2b PoW scheme using the parameters in pow_params, and
* store the solution in pow_solution_out. Returns 0 on success and -1
- * otherwise. Called by a client. */
+ * otherwise. Called by a client, from a cpuworker thread. */
int
hs_pow_solve(const hs_pow_solver_inputs_t *pow_inputs,
hs_pow_solution_t *pow_solution_out)
challenge = build_equix_challenge(&pow_inputs->service_blinded_id,
pow_inputs->seed, nonce, effort);
- ctx = equix_alloc(EQUIX_CTX_SOLVE | EQUIX_CTX_TRY_COMPILE);
+ /* This runs on a cpuworker, let's not access global get_options().
+ * Instead, the particular options we need are captured in pow_inputs. */
+ ctx = equix_alloc(EQUIX_CTX_SOLVE |
+ hs_pow_equix_option_flags(pow_inputs->CompiledProofOfWorkHash));
if (!ctx) {
goto end;
}
goto done;
}
- ctx = equix_alloc(EQUIX_CTX_VERIFY | EQUIX_CTX_TRY_COMPILE);
+ ctx = equix_alloc(EQUIX_CTX_VERIFY |
+ hs_pow_equix_option_flags(get_options()->CompiledProofOfWorkHash));
if (!ctx) {
goto done;
}
job->pow_solution_out = tor_malloc_zero(sizeof(hs_pow_solution_t));
if (hs_pow_solve(&job->pow_inputs, job->pow_solution_out)) {
- log_warn(LD_REND, "Failed to run the proof of work solver");
tor_free(job->pow_solution_out);
job->pow_solution_out = NULL; /* how we signal that we came up empty */
}
/** Effort chosen by the client. May be higher or lower than
* suggested_effort in the descriptor. */
uint32_t effort;
+ /** Configuration option, choice of hash implementation. AUTOBOOL. */
+ int CompiledProofOfWorkHash;
} hs_pow_solver_inputs_t;
/** State and parameters of PoW defenses, stored in the service state. */
hs_pow_solution_t solution = { 0 };
hs_pow_solver_inputs_t input = {
.effort = vectors[vec_i].effort,
+ .CompiledProofOfWorkHash = -1
};
tt_int_op(strlen(service_blinded_id_hex), OP_EQ, 2 * HS_POW_ID_LEN);