|
|
@@ -218,6 +218,9 @@ config_has_invalid_options(const config_line_t *line_,
|
|
|
|
|
|
const char *opts_exclude_v2[] = {
|
|
|
"HiddenServiceExportCircuitID",
|
|
|
+ "HiddenServiceEnableIntroDoSDefense",
|
|
|
+ "HiddenServiceEnableIntroDoSRatePerSec",
|
|
|
+ "HiddenServiceEnableIntroDoSBurstPerSec",
|
|
|
NULL /* End marker. */
|
|
|
};
|
|
|
|
|
|
@@ -276,6 +279,15 @@ config_validate_service(const hs_service_config_t *config)
|
|
|
goto invalid;
|
|
|
}
|
|
|
|
|
|
+ /* DoS validation values. */
|
|
|
+ if (config->has_dos_defense_enabled &&
|
|
|
+ (config->intro_dos_burst_per_sec < config->intro_dos_rate_per_sec)) {
|
|
|
+ log_warn(LD_CONFIG, "Hidden service DoS defenses burst (%" PRIu32 ") can "
|
|
|
+ "not be smaller than the rate value (%" PRIu32 ").",
|
|
|
+ config->intro_dos_burst_per_sec, config->intro_dos_rate_per_sec);
|
|
|
+ goto invalid;
|
|
|
+ }
|
|
|
+
|
|
|
/* Valid. */
|
|
|
return 0;
|
|
|
invalid:
|
|
|
@@ -296,6 +308,8 @@ config_service_v3(const config_line_t *line_,
|
|
|
{
|
|
|
int have_num_ip = 0;
|
|
|
bool export_circuit_id = false; /* just to detect duplicate options */
|
|
|
+ bool dos_enabled = false, dos_rate_per_sec = false;
|
|
|
+ bool dos_burst_per_sec = false;
|
|
|
const char *dup_opt_seen = NULL;
|
|
|
const config_line_t *line;
|
|
|
|
|
|
@@ -334,6 +348,48 @@ config_service_v3(const config_line_t *line_,
|
|
|
export_circuit_id = true;
|
|
|
continue;
|
|
|
}
|
|
|
+ if (!strcasecmp(line->key, "HiddenServiceEnableIntroDoSDefense")) {
|
|
|
+ config->has_dos_defense_enabled =
|
|
|
+ (unsigned int) helper_parse_uint64(line->key, line->value,
|
|
|
+ HS_CONFIG_V3_DOS_DEFENSE_DEFAULT,
|
|
|
+ 1, &ok);
|
|
|
+ if (!ok || dos_enabled) {
|
|
|
+ if (dos_enabled) {
|
|
|
+ dup_opt_seen = line->key;
|
|
|
+ }
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+ dos_enabled = true;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (!strcasecmp(line->key, "HiddenServiceEnableIntroDoSRatePerSec")) {
|
|
|
+ config->intro_dos_rate_per_sec =
|
|
|
+ (unsigned int) helper_parse_uint64(line->key, line->value,
|
|
|
+ HS_CONFIG_V3_DOS_DEFENSE_RATE_PER_SEC_MIN,
|
|
|
+ HS_CONFIG_V3_DOS_DEFENSE_RATE_PER_SEC_MAX, &ok);
|
|
|
+ if (!ok || dos_rate_per_sec) {
|
|
|
+ if (dos_rate_per_sec) {
|
|
|
+ dup_opt_seen = line->key;
|
|
|
+ }
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+ dos_rate_per_sec = true;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (!strcasecmp(line->key, "HiddenServiceEnableIntroDoSBurstPerSec")) {
|
|
|
+ config->intro_dos_burst_per_sec =
|
|
|
+ (unsigned int) helper_parse_uint64(line->key, line->value,
|
|
|
+ HS_CONFIG_V3_DOS_DEFENSE_BURST_PER_SEC_MIN,
|
|
|
+ HS_CONFIG_V3_DOS_DEFENSE_BURST_PER_SEC_MAX, &ok);
|
|
|
+ if (!ok || dos_burst_per_sec) {
|
|
|
+ if (dos_burst_per_sec) {
|
|
|
+ dup_opt_seen = line->key;
|
|
|
+ }
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+ dos_burst_per_sec = true;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/* We do not load the key material for the service at this stage. This is
|