Fr5487 adaptive timeouts (#5502)

* per-rule adaptive timeouts

allow per-rule adaptive timeouts. 0 is possibe to disable adaptive timeouts

* Firewall / Rules - allow per-rule adaptive timeouts, small cleanups for https://github.com/opnsense/core/pull/5492

* Firewall / Rules - allow per-rule adaptive timeouts, values may be 0 as well, so "positive" should be "non-negative" for https://github.com/opnsense/core/pull/5492

Co-authored-by: kulikov-a <36099472+kulikov-a@users.noreply.github.com>
This commit is contained in:
Ad Schellevis 2022-01-25 07:49:16 +00:00 committed by GitHub
parent 161d24650b
commit b01da7a918
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 68 additions and 4 deletions

View File

@ -232,6 +232,9 @@ class FilterRule extends Rule
$rule['state']['options'][] = $state_tag . " " . $rule[$state_tag];
}
}
if (is_numeric($rule['adaptivestart']) && is_numeric($rule['adaptiveend'])) {
$rule['state']['options'][] = "adaptive.start " . $rule['adaptivestart'] . ", adaptive.end " . $rule['adaptiveend'];
}
if (!empty($rule['statetimeout'])) {
$rule['state']['options'][] = "tcp.established " . $rule['statetimeout'];
}

View File

@ -47,11 +47,11 @@ $gateways = new \OPNsense\Routing\Gateways(legacy_interfaces_details());
* check if advanced options are set on selected element
*/
function FormSetAdvancedOptions(&$item) {
foreach (array("max", "max-src-nodes", "max-src-conn", "max-src-states","nopfsync", "statetimeout"
,"max-src-conn-rate","max-src-conn-rates", "tag", "tagged", "allowopts", "reply-to","tcpflags1"
foreach (array("max", "max-src-nodes", "max-src-conn", "max-src-states","nopfsync", "statetimeout", "adaptivestart"
, "adaptiveend", "max-src-conn-rate","max-src-conn-rates", "tag", "tagged", "allowopts", "reply-to","tcpflags1"
,"tcpflags2") as $fieldname) {
if (!empty($item[$fieldname])) {
if (strlen($item[$fieldname]) > 0) {
return true;
}
}
@ -109,6 +109,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
'max-src-conn',
'max-src-conn-rate',
'max-src-conn-rates',
'adaptivestart',
'adaptiveend',
'overload',
'max-src-nodes',
'max-src-states',
@ -364,6 +366,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
if (!empty($pconfig['statetimeout'])) {
$input_errors[] = gettext("You can only specify the state timeout (advanced option) for Pass type rules.");
}
if (strlen($pconfig['adaptivestart']) > 0 || strlen($pconfig['adaptiveend']) > 0) {
$input_errors[] = gettext("You can only specify the adaptive timeouts (advanced option) for Pass type rules.");
}
if (!empty($pconfig['allowopts'])) {
$input_errors[] = gettext("You can only specify allow options (advanced option) for Pass type rules.");
}
@ -381,6 +386,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$input_errors[] = gettext("You cannot specify the maximum new connections per host / per second(s) (advanced option) if statetype is none.");
if (!empty($pconfig['statetimeout']))
$input_errors[] = gettext("You cannot specify the state timeout (advanced option) if statetype is none.");
if (is_numeric($pconfig['adaptivestart']) || is_numeric($pconfig['adaptiveend'])) {
$input_errors[] = gettext("You cannot specify the adaptive timeouts (advanced option) if statetype is none.");
}
}
if (!empty($pconfig['max']) && !is_posnumericint($pconfig['max']))
@ -407,10 +416,23 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$input_errors[] = gettext("Both maximum new connections per host and the interval (per second(s)) must be specified");
}
if (empty($pconfig['max']) && ($pconfig['adaptivestart'] === "0" || $pconfig['adaptiveend'] === "0")) {
$input_errors[] = gettext("Disabling adaptive timeouts is only supported in combination with a configured maximum number of states for the same rule.");
} elseif ($pconfig['adaptivestart'] === "0" xor $pconfig['adaptiveend'] === "0") {
$input_errors[] = gettext("Adaptive timeouts must be disabled together.");
} elseif (strlen($pconfig['adaptivestart']) > 0 xor strlen($pconfig['adaptiveend']) > 0) {
$input_errors[] = gettext("The adaptive timouts values must be set together.");
} elseif ((!empty($pconfig['adaptivestart']) && !is_numericint($pconfig['adaptivestart'])) || (!empty($pconfig['adaptiveend']) && !is_numericint($pconfig['adaptiveend']))) {
$input_errors[] = gettext("The adaptive.start and adaptive.end values (advanced option) must be configured as non-negative integer values.");
} elseif (is_posnumericint($pconfig['max']) && is_numericint($pconfig['adaptiveend']) && $pconfig['max'] > $pconfig['adaptiveend']) {
$input_errors[] = gettext("The value of adaptive.end must be greater than the Max states value.");
} elseif (is_numericint($pconfig['adaptivestart']) && is_numericint($pconfig['adaptiveend']) && $pconfig['adaptivestart'] > $pconfig['adaptiveend']) {
$input_errors[] = gettext("The value of adaptive.end must be greater than adaptive.start value.");
}
if (empty($pconfig['tcpflags2']) && !empty($pconfig['tcpflags1']))
$input_errors[] = gettext("If you specify TCP flags that should be set you should specify out of which flags as well.");
if (isset($pconfig['set-prio']) && $pconfig['set-prio'] !== '' && (!is_numericint($pconfig['set-prio']) || $pconfig['set-prio'] < 0 || $pconfig['set-prio'] > 7)) {
$input_errors[] = gettext('Set priority must be an integer between 0 and 7.');
}
@ -439,6 +461,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
, 'sched', 'associated-rule-id', 'direction'
, 'max-src-conn-rate', 'max-src-conn-rates', 'category') ;
foreach ($copy_fields as $fieldname) {
if (!empty($pconfig[$fieldname])) {
if (is_array($pconfig[$fieldname])) {
@ -449,6 +473,12 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
}
}
// allow 0 in adaptive timeouts
if (is_numericint($pconfig['adaptivestart']) && is_numericint($pconfig['adaptiveend'])) {
$filterent['adaptivestart'] = $pconfig['adaptivestart'];
$filterent['adaptiveend'] = $pconfig['adaptiveend'];
}
// only flush non default max new connection overload table
if (!empty($pconfig['overload']) && $pconfig['overload'] != 'virusprot') {
$filterent['overload'] = $pconfig['overload'];
@ -1536,6 +1566,37 @@ endforeach;?>
</div>
</td>
</tr>
<tr class="opt_advanced hidden">
<td><a id="help_for_adaptive" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Adaptive Timeouts");?></td>
<td>
<table class="table table-condensed">
<thead>
<tr>
<td><?=gettext("start");?></td>
<td><?=gettext("end");?></td>
</tr>
</thead>
<tbody>
<tr>
<td>
<input name="adaptivestart" type="text" value="<?=$pconfig['adaptivestart']; ?>" />
</td>
<td>
<input name="adaptiveend" type="text" value="<?=$pconfig['adaptiveend']; ?>" />
</td>
</tr>
</tbody>
</table>
<div class="hidden" data-for="help_for_adaptive">
<?=gettext("Timeouts for states can be scaled adaptively as the number of state table entries grows.");?><br/><br/>
<strong><?=gettext("start");?></strong><br/>
<?=gettext("When the number of state entries exceeds this value, adaptive scaling begins. All timeout values are scaled linearly with factor (adaptive.end - number of states) / (adaptive.end - adaptive.start).");?><br/><br/>
<strong><?=gettext("end");?></strong><br/>
<?=gettext("When reaching this number of state entries, all timeout values become zero, effectively purging all state entries immediately. This value is used to define the scale factor, it should not actually be reached (set a lower state limit).");?><br/><br/>
<?=gettext("Note: Leave fields blank to use default pf algorithm. Set to 0 to disable.");?>
</div>
</td>
</tr>
<tr class="opt_advanced hidden">
<td><a id="help_for_tcpflags" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("TCP flags");?></td>
<td>