fix(synlimit): raise default synlimit_burst from 1 to 24

The generic-path SYN limiter default of burst=1 admits only one new
connection per source IP, then refills at 48/minute (0.8/s). Telegram
clients open several connections at once on startup/reconnect, so the
extra SYNs are rejected with TCP RST until a token accrues — clients
intermittently fail to connect until the app is restarted.

The iOS fast-path (meta length 64) does not match real-world traffic
behind carrier NAT/NAT64 (SYNs arrive as 60 bytes), so the generic path
governs all clients, iPhone included. Raise its default burst to 24 —
the value already used by the iOS path — so a legitimate startup fan-out
passes. Steady-state rate (48/minute) is unchanged, preserving the
anti-TSPU posture.

Updates the default constant, the default-assertion test, and the EN/RU/DE
CONFIG_PARAMS docs.
This commit is contained in:
Anton Vinogradov
2026-07-16 03:31:39 +03:00
parent 1f9c82c924
commit f770756cba
5 changed files with 11 additions and 11 deletions
+3 -3
View File
@@ -2314,7 +2314,7 @@ Hinweis: Dieser Abschnitt akzeptiert auch den Legacy-Alias `[server.admin_api]`
| [`synlimit`](#synlimit-serverlisteners) | `false`, `"iptables"` oder `"nftables"` | `false` | `` |
| [`synlimit_seconds`](#synlimit_seconds-serverlisteners) | `u32` | `60` | `` |
| [`synlimit_hitcount`](#synlimit_hitcount-serverlisteners) | `u32` | `48` | `` |
| [`synlimit_burst`](#synlimit_burst-serverlisteners) | `u32` | `1` | `` |
| [`synlimit_burst`](#synlimit_burst-serverlisteners) | `u32` | `24` | `` |
| [`synlimit_ios_seconds`](#synlimit_ios_seconds-serverlisteners) | `u32` | `1` | `` |
| [`synlimit_ios_hitcount`](#synlimit_ios_hitcount-serverlisteners) | `u32` | `12` | `` |
| [`synlimit_ios_burst`](#synlimit_ios_burst-serverlisteners) | `u32` | `24` | `` |
@@ -2397,7 +2397,7 @@ Hinweis: Dieser Abschnitt akzeptiert auch den Legacy-Alias `[server.admin_api]`
synlimit_hitcount = 48
```
## synlimit_burst (server.listeners)
- **Einschränkungen / Validierung**: `u32`, muss `> 0` sein. Der Default ist `1`.
- **Einschränkungen / Validierung**: `u32`, muss `> 0` sein. Der Default ist `24`.
- **Beschreibung**: Generische SYN-Fix-Token-Bucket-Burst-Größe. Höhere Werte ermöglichen kurze Verbindungsstöße von derselben Source-IP, bevor die stabile `synlimit_hitcount / synlimit_seconds`-Rate durchgesetzt wird.
- **Beispiel**:
@@ -2406,7 +2406,7 @@ Hinweis: Dieser Abschnitt akzeptiert auch den Legacy-Alias `[server.admin_api]`
ip = "0.0.0.0"
port = 443
synlimit = "iptables"
synlimit_burst = 1
synlimit_burst = 24
```
## synlimit_ios_seconds (server.listeners)
- **Einschränkungen / Validierung**: `u32`, muss `> 0` sein. Der Default ist `1`.
+3 -3
View File
@@ -2314,7 +2314,7 @@ Note: This section also accepts the legacy alias `[server.admin_api]` (same sche
| [`synlimit`](#synlimit-serverlisteners) | `false`, `"iptables"`, or `"nftables"` | `false` | `` |
| [`synlimit_seconds`](#synlimit_seconds-serverlisteners) | `u32` | `60` | `` |
| [`synlimit_hitcount`](#synlimit_hitcount-serverlisteners) | `u32` | `48` | `` |
| [`synlimit_burst`](#synlimit_burst-serverlisteners) | `u32` | `1` | `` |
| [`synlimit_burst`](#synlimit_burst-serverlisteners) | `u32` | `24` | `` |
| [`synlimit_ios_seconds`](#synlimit_ios_seconds-serverlisteners) | `u32` | `1` | `` |
| [`synlimit_ios_hitcount`](#synlimit_ios_hitcount-serverlisteners) | `u32` | `12` | `` |
| [`synlimit_ios_burst`](#synlimit_ios_burst-serverlisteners) | `u32` | `24` | `` |
@@ -2397,7 +2397,7 @@ Note: This section also accepts the legacy alias `[server.admin_api]` (same sche
synlimit_hitcount = 48
```
## synlimit_burst (server.listeners)
- **Constraints / validation**: `u32`, must be `> 0`. Default is `1`.
- **Constraints / validation**: `u32`, must be `> 0`. Default is `24`.
- **Description**: Generic SYN-fix token-bucket burst size. Higher values allow short connection bursts from the same source IP before the steady-state `synlimit_hitcount / synlimit_seconds` rate is enforced.
- **Example**:
@@ -2406,7 +2406,7 @@ Note: This section also accepts the legacy alias `[server.admin_api]` (same sche
ip = "0.0.0.0"
port = 443
synlimit = "iptables"
synlimit_burst = 1
synlimit_burst = 24
```
## synlimit_ios_seconds (server.listeners)
- **Constraints / validation**: `u32`, must be `> 0`. Default is `1`.
+3 -3
View File
@@ -2240,7 +2240,7 @@
| [`synlimit`](#synlimit-serverlisteners) | `false`, `"iptables"` или `"nftables"` | `false` | `` |
| [`synlimit_seconds`](#synlimit_seconds-serverlisteners) | `u32` | `60` | `` |
| [`synlimit_hitcount`](#synlimit_hitcount-serverlisteners) | `u32` | `48` | `` |
| [`synlimit_burst`](#synlimit_burst-serverlisteners) | `u32` | `1` | `` |
| [`synlimit_burst`](#synlimit_burst-serverlisteners) | `u32` | `24` | `` |
| [`synlimit_ios_seconds`](#synlimit_ios_seconds-serverlisteners) | `u32` | `1` | `` |
| [`synlimit_ios_hitcount`](#synlimit_ios_hitcount-serverlisteners) | `u32` | `12` | `` |
| [`synlimit_ios_burst`](#synlimit_ios_burst-serverlisteners) | `u32` | `24` | `` |
@@ -2323,7 +2323,7 @@
synlimit_hitcount = 48
```
## synlimit_burst (server.listeners)
- **Ограничения / валидация**: `u32`, должно быть `> 0`. Значение по умолчанию: `1`.
- **Ограничения / валидация**: `u32`, должно быть `> 0`. Значение по умолчанию: `24`.
- **Описание**: Generic SYN-fix token-bucket burst size. Более высокие значения разрешают short connection bursts с одного source IP перед применением steady-state rate `synlimit_hitcount / synlimit_seconds`.
- **Пример**:
@@ -2332,7 +2332,7 @@
ip = "0.0.0.0"
port = 443
synlimit = "iptables"
synlimit_burst = 1
synlimit_burst = 24
```
## synlimit_ios_seconds (server.listeners)
- **Ограничения / валидация**: `u32`, должно быть `> 0`. Значение по умолчанию: `1`.
+1 -1
View File
@@ -62,7 +62,7 @@ const DEFAULT_CONNTRACK_PRESSURE_LOW_WATERMARK_PCT: u8 = 70;
const DEFAULT_CONNTRACK_DELETE_BUDGET_PER_SEC: u64 = 4096;
const DEFAULT_SYNLIMIT_SECONDS: u32 = 60;
const DEFAULT_SYNLIMIT_HITCOUNT: u32 = 48;
const DEFAULT_SYNLIMIT_BURST: u32 = 1;
const DEFAULT_SYNLIMIT_BURST: u32 = 24;
const DEFAULT_SYNLIMIT_IOS_SECONDS: u32 = 1;
const DEFAULT_SYNLIMIT_IOS_HITCOUNT: u32 = 12;
const DEFAULT_SYNLIMIT_IOS_BURST: u32 = 24;
+1 -1
View File
@@ -54,7 +54,7 @@ fn synlimit_synfix_defaults_are_loaded_for_listener() {
let listener = &cfg.server.listeners[0];
assert_eq!(listener.synlimit_seconds, 60);
assert_eq!(listener.synlimit_hitcount, 48);
assert_eq!(listener.synlimit_burst, 1);
assert_eq!(listener.synlimit_burst, 24);
assert_eq!(listener.synlimit_ios_seconds, 1);
assert_eq!(listener.synlimit_ios_hitcount, 12);
assert_eq!(listener.synlimit_ios_burst, 24);