diff --git a/docs/API.md b/docs/API.md deleted file mode 100644 index 886d159..0000000 --- a/docs/API.md +++ /dev/null @@ -1,1137 +0,0 @@ -# Telemt Control API - -## Purpose -Control-plane HTTP API for runtime visibility and user/config management. -Data-plane MTProto traffic is out of scope. - -## Runtime Configuration -API runtime is configured in `[server.api]`. - -| Field | Type | Default | Description | -| --- | --- | --- | --- | -| `enabled` | `bool` | `false` | Enables REST API listener. | -| `listen` | `string` (`IP:PORT`) | `127.0.0.1:9091` | API bind address. | -| `whitelist` | `CIDR[]` | `127.0.0.1/32, ::1/128` | Source IP allowlist. Empty list means allow all. | -| `auth_header` | `string` | `""` | Exact value for `Authorization` header. Empty disables header auth. | -| `request_body_limit_bytes` | `usize` | `65536` | Maximum request body size. Must be `> 0`. | -| `minimal_runtime_enabled` | `bool` | `false` | Enables runtime snapshot endpoints requiring ME pool read-lock aggregation. | -| `minimal_runtime_cache_ttl_ms` | `u64` | `1000` | Cache TTL for minimal snapshots. `0` disables cache; valid range is `[0, 60000]`. | -| `runtime_edge_enabled` | `bool` | `false` | Enables runtime edge endpoints with cached aggregation payloads. | -| `runtime_edge_cache_ttl_ms` | `u64` | `1000` | Cache TTL for runtime edge summary payloads. `0` disables cache. | -| `runtime_edge_top_n` | `usize` | `10` | Top-N rows for runtime edge leaderboard payloads. | -| `runtime_edge_events_capacity` | `usize` | `256` | Ring-buffer size for `/v1/runtime/events/recent`. | -| `read_only` | `bool` | `false` | Disables mutating endpoints. | - -`server.admin_api` is accepted as an alias for backward compatibility. - -Runtime validation for API config: -- `server.api.listen` must be a valid `IP:PORT`. -- `server.api.request_body_limit_bytes` must be `> 0`. -- `server.api.minimal_runtime_cache_ttl_ms` must be within `[0, 60000]`. -- `server.api.runtime_edge_cache_ttl_ms` must be within `[0, 60000]`. -- `server.api.runtime_edge_top_n` must be within `[1, 1000]`. -- `server.api.runtime_edge_events_capacity` must be within `[16, 4096]`. - -## Protocol Contract - -| Item | Value | -| --- | --- | -| Transport | HTTP/1.1 | -| Content type | `application/json; charset=utf-8` | -| Prefix | `/v1` | -| Optimistic concurrency | `If-Match: ` on mutating requests (optional) | -| Revision format | SHA-256 hex of current `config.toml` content | - -### Success Envelope -```json -{ - "ok": true, - "data": {}, - "revision": "sha256-hex" -} -``` - -### Error Envelope -```json -{ - "ok": false, - "error": { - "code": "machine_code", - "message": "human-readable" - }, - "request_id": 1 -} -``` - -## Request Processing Order - -Requests are processed in this order: -1. `api_enabled` gate (`503 api_disabled` if disabled). -2. Source IP whitelist gate (`403 forbidden`). -3. `Authorization` header gate when configured (`401 unauthorized`). -4. Route and method matching (`404 not_found` or `405 method_not_allowed`). -5. `read_only` gate for mutating routes (`403 read_only`). -6. Request body read/limit/JSON decode (`413 payload_too_large`, `400 bad_request`). -7. Business validation and config write path. - -Notes: -- Whitelist is evaluated against the direct TCP peer IP (`SocketAddr::ip`), without `X-Forwarded-For` support. -- `Authorization` check is exact string equality against configured `auth_header`. - -## Endpoint Matrix - -| Method | Path | Body | Success | `data` contract | -| --- | --- | --- | --- | --- | -| `GET` | `/v1/health` | none | `200` | `HealthData` | -| `GET` | `/v1/system/info` | none | `200` | `SystemInfoData` | -| `GET` | `/v1/runtime/gates` | none | `200` | `RuntimeGatesData` | -| `GET` | `/v1/runtime/initialization` | none | `200` | `RuntimeInitializationData` | -| `GET` | `/v1/limits/effective` | none | `200` | `EffectiveLimitsData` | -| `GET` | `/v1/security/posture` | none | `200` | `SecurityPostureData` | -| `GET` | `/v1/security/whitelist` | none | `200` | `SecurityWhitelistData` | -| `GET` | `/v1/stats/summary` | none | `200` | `SummaryData` | -| `GET` | `/v1/stats/zero/all` | none | `200` | `ZeroAllData` | -| `GET` | `/v1/stats/upstreams` | none | `200` | `UpstreamsData` | -| `GET` | `/v1/stats/minimal/all` | none | `200` | `MinimalAllData` | -| `GET` | `/v1/stats/me-writers` | none | `200` | `MeWritersData` | -| `GET` | `/v1/stats/dcs` | none | `200` | `DcStatusData` | -| `GET` | `/v1/runtime/me_pool_state` | none | `200` | `RuntimeMePoolStateData` | -| `GET` | `/v1/runtime/me_quality` | none | `200` | `RuntimeMeQualityData` | -| `GET` | `/v1/runtime/upstream_quality` | none | `200` | `RuntimeUpstreamQualityData` | -| `GET` | `/v1/runtime/nat_stun` | none | `200` | `RuntimeNatStunData` | -| `GET` | `/v1/runtime/me-selftest` | none | `200` | `RuntimeMeSelftestData` | -| `GET` | `/v1/runtime/connections/summary` | none | `200` | `RuntimeEdgeConnectionsSummaryData` | -| `GET` | `/v1/runtime/events/recent` | none | `200` | `RuntimeEdgeEventsData` | -| `GET` | `/v1/stats/users` | none | `200` | `UserInfo[]` | -| `GET` | `/v1/users` | none | `200` | `UserInfo[]` | -| `POST` | `/v1/users` | `CreateUserRequest` | `201` | `CreateUserResponse` | -| `GET` | `/v1/users/{username}` | none | `200` | `UserInfo` | -| `PATCH` | `/v1/users/{username}` | `PatchUserRequest` | `200` | `UserInfo` | -| `DELETE` | `/v1/users/{username}` | none | `200` | `string` (deleted username) | -| `POST` | `/v1/users/{username}/rotate-secret` | `RotateSecretRequest` or empty body | `404` | `ErrorResponse` (`not_found`, current runtime behavior) | - -## Common Error Codes - -| HTTP | `error.code` | Trigger | -| --- | --- | --- | -| `400` | `bad_request` | Invalid JSON, validation failures, malformed request body. | -| `401` | `unauthorized` | Missing/invalid `Authorization` when `auth_header` is configured. | -| `403` | `forbidden` | Source IP is not allowed by whitelist. | -| `403` | `read_only` | Mutating endpoint called while `read_only=true`. | -| `404` | `not_found` | Unknown route, unknown user, or unsupported sub-route (including current `rotate-secret` route). | -| `405` | `method_not_allowed` | Unsupported method for `/v1/users/{username}` route shape. | -| `409` | `revision_conflict` | `If-Match` revision mismatch. | -| `409` | `user_exists` | User already exists on create. | -| `409` | `last_user_forbidden` | Attempt to delete last configured user. | -| `413` | `payload_too_large` | Body exceeds `request_body_limit_bytes`. | -| `500` | `internal_error` | Internal error (I/O, serialization, config load/save). | -| `503` | `api_disabled` | API disabled in config. | - -## Routing and Method Edge Cases - -| Case | Behavior | -| --- | --- | -| Path matching | Exact match on `req.uri().path()`. Query string does not affect route matching. | -| Trailing slash | Not normalized. Example: `/v1/users/` is `404`. | -| Username route with extra slash | `/v1/users/{username}/...` is not treated as user route and returns `404`. | -| `PUT /v1/users/{username}` | `405 method_not_allowed`. | -| `POST /v1/users/{username}` | `404 not_found`. | -| `POST /v1/users/{username}/rotate-secret` | `404 not_found` in current release due route matcher limitation. | - -## Body and JSON Semantics - -- Request body is read only for mutating routes that define a body contract. -- Body size limit is enforced during streaming read (`413 payload_too_large`). -- Invalid transport body frame returns `400 bad_request` (`Invalid request body`). -- Invalid JSON returns `400 bad_request` (`Invalid JSON body`). -- `Content-Type` is not required for JSON parsing. -- Unknown JSON fields are ignored by deserialization. -- `PATCH` updates only provided fields and does not support explicit clearing of optional fields. -- `If-Match` supports both quoted and unquoted values; surrounding whitespace is trimmed. - -## Query Parameters - -| Endpoint | Query | Behavior | -| --- | --- | --- | -| `GET /v1/runtime/events/recent` | `limit=` | Optional. Invalid/missing value falls back to default `50`. Effective value is clamped to `[1, 1000]` and additionally bounded by ring-buffer capacity. | - -## Request Contracts - -### `CreateUserRequest` -| Field | Type | Required | Description | -| --- | --- | --- | --- | -| `username` | `string` | yes | `[A-Za-z0-9_.-]`, length `1..64`. | -| `secret` | `string` | no | Exactly 32 hex chars. If missing, generated automatically. | -| `user_ad_tag` | `string` | no | Exactly 32 hex chars. | -| `max_tcp_conns` | `usize` | no | Per-user concurrent TCP limit. | -| `expiration_rfc3339` | `string` | no | RFC3339 expiration timestamp. | -| `data_quota_bytes` | `u64` | no | Per-user traffic quota. | -| `max_unique_ips` | `usize` | no | Per-user unique source IP limit. | - -### `PatchUserRequest` -| Field | Type | Required | Description | -| --- | --- | --- | --- | -| `secret` | `string` | no | Exactly 32 hex chars. | -| `user_ad_tag` | `string` | no | Exactly 32 hex chars. | -| `max_tcp_conns` | `usize` | no | Per-user concurrent TCP limit. | -| `expiration_rfc3339` | `string` | no | RFC3339 expiration timestamp. | -| `data_quota_bytes` | `u64` | no | Per-user traffic quota. | -| `max_unique_ips` | `usize` | no | Per-user unique source IP limit. | - -### `RotateSecretRequest` -| Field | Type | Required | Description | -| --- | --- | --- | --- | -| `secret` | `string` | no | Exactly 32 hex chars. If missing, generated automatically. | - -Note: the request contract is defined, but the corresponding route currently returns `404` (see routing edge cases). - -## Response Data Contracts - -### `HealthData` -| Field | Type | Description | -| --- | --- | --- | -| `status` | `string` | Always `"ok"`. | -| `read_only` | `bool` | Mirrors current API `read_only` mode. | - -### `SummaryData` -| Field | Type | Description | -| --- | --- | --- | -| `uptime_seconds` | `f64` | Process uptime in seconds. | -| `connections_total` | `u64` | Total accepted client connections. | -| `connections_bad_total` | `u64` | Failed/invalid client connections. | -| `handshake_timeouts_total` | `u64` | Handshake timeout count. | -| `configured_users` | `usize` | Number of configured users in config. | - -### `SystemInfoData` -| Field | Type | Description | -| --- | --- | --- | -| `version` | `string` | Binary version (`CARGO_PKG_VERSION`). | -| `target_arch` | `string` | Target architecture (`std::env::consts::ARCH`). | -| `target_os` | `string` | Target OS (`std::env::consts::OS`). | -| `build_profile` | `string` | Build profile (`PROFILE` env when available). | -| `git_commit` | `string?` | Optional commit hash from build env metadata. | -| `build_time_utc` | `string?` | Optional build timestamp from build env metadata. | -| `rustc_version` | `string?` | Optional compiler version from build env metadata. | -| `process_started_at_epoch_secs` | `u64` | Process start time as Unix epoch seconds. | -| `uptime_seconds` | `f64` | Process uptime in seconds. | -| `config_path` | `string` | Active config file path used by runtime. | -| `config_hash` | `string` | SHA-256 hash of current config content (same value as envelope `revision`). | -| `config_reload_count` | `u64` | Number of successfully observed config updates since process start. | -| `last_config_reload_epoch_secs` | `u64?` | Unix epoch seconds of the latest observed config reload; null/absent before first reload. | - -### `RuntimeGatesData` -| Field | Type | Description | -| --- | --- | --- | -| `accepting_new_connections` | `bool` | Current admission-gate state for new listener accepts. | -| `conditional_cast_enabled` | `bool` | Whether conditional ME admission logic is enabled (`general.use_middle_proxy`). | -| `me_runtime_ready` | `bool` | Current ME runtime readiness status used for conditional gate decisions. | -| `me2dc_fallback_enabled` | `bool` | Whether ME -> direct fallback is enabled. | -| `use_middle_proxy` | `bool` | Current transport mode preference. | -| `startup_status` | `string` | Startup status (`pending`, `initializing`, `ready`, `failed`, `skipped`). | -| `startup_stage` | `string` | Current startup stage identifier. | -| `startup_progress_pct` | `f64` | Startup progress percentage (`0..100`). | - -### `RuntimeInitializationData` -| Field | Type | Description | -| --- | --- | --- | -| `status` | `string` | Startup status (`pending`, `initializing`, `ready`, `failed`, `skipped`). | -| `degraded` | `bool` | Whether runtime is currently in degraded mode. | -| `current_stage` | `string` | Current startup stage identifier. | -| `progress_pct` | `f64` | Overall startup progress percentage (`0..100`). | -| `started_at_epoch_secs` | `u64` | Process start timestamp (Unix seconds). | -| `ready_at_epoch_secs` | `u64?` | Timestamp when startup reached ready state; absent until ready. | -| `total_elapsed_ms` | `u64` | Elapsed startup duration in milliseconds. | -| `transport_mode` | `string` | Startup transport mode (`middle_proxy` or `direct`). | -| `me` | `RuntimeInitializationMeData` | ME startup substate snapshot. | -| `components` | `RuntimeInitializationComponentData[]` | Per-component startup timeline and status. | - -#### `RuntimeInitializationMeData` -| Field | Type | Description | -| --- | --- | --- | -| `status` | `string` | ME startup status (`pending`, `initializing`, `ready`, `failed`, `skipped`). | -| `current_stage` | `string` | Current ME startup stage identifier. | -| `progress_pct` | `f64` | ME startup progress percentage (`0..100`). | -| `init_attempt` | `u32` | Current ME init attempt counter. | -| `retry_limit` | `string` | Retry limit (`"unlimited"` or numeric string). | -| `last_error` | `string?` | Last ME initialization error text when present. | - -#### `RuntimeInitializationComponentData` -| Field | Type | Description | -| --- | --- | --- | -| `id` | `string` | Startup component identifier. | -| `title` | `string` | Human-readable component title. | -| `status` | `string` | Component status (`pending`, `running`, `ready`, `failed`, `skipped`). | -| `started_at_epoch_ms` | `u64?` | Component start timestamp in Unix milliseconds. | -| `finished_at_epoch_ms` | `u64?` | Component finish timestamp in Unix milliseconds. | -| `duration_ms` | `u64?` | Component duration in milliseconds. | -| `attempts` | `u32` | Attempt counter for this component. | -| `details` | `string?` | Optional short status details text. | - -### `EffectiveLimitsData` -| Field | Type | Description | -| --- | --- | --- | -| `update_every_secs` | `u64` | Effective unified updater interval. | -| `me_reinit_every_secs` | `u64` | Effective ME periodic reinit interval. | -| `me_pool_force_close_secs` | `u64` | Effective stale-writer force-close timeout. | -| `timeouts` | `EffectiveTimeoutLimits` | Effective timeout policy snapshot. | -| `upstream` | `EffectiveUpstreamLimits` | Effective upstream connect/retry limits. | -| `middle_proxy` | `EffectiveMiddleProxyLimits` | Effective ME pool/floor/reconnect limits. | -| `user_ip_policy` | `EffectiveUserIpPolicyLimits` | Effective unique-IP policy mode/window. | - -#### `EffectiveTimeoutLimits` -| Field | Type | Description | -| --- | --- | --- | -| `client_handshake_secs` | `u64` | Client handshake timeout. | -| `tg_connect_secs` | `u64` | Upstream Telegram connect timeout. | -| `client_keepalive_secs` | `u64` | Client keepalive interval. | -| `client_ack_secs` | `u64` | ACK timeout. | -| `me_one_retry` | `u8` | Fast retry count for single-endpoint ME DC. | -| `me_one_timeout_ms` | `u64` | Fast retry timeout per attempt for single-endpoint ME DC. | - -#### `EffectiveUpstreamLimits` -| Field | Type | Description | -| --- | --- | --- | -| `connect_retry_attempts` | `u32` | Upstream connect retry attempts. | -| `connect_retry_backoff_ms` | `u64` | Upstream retry backoff delay. | -| `connect_budget_ms` | `u64` | Total connect wall-clock budget across retries. | -| `unhealthy_fail_threshold` | `u32` | Consecutive fail threshold for unhealthy marking. | -| `connect_failfast_hard_errors` | `bool` | Whether hard errors skip additional retries. | - -#### `EffectiveMiddleProxyLimits` -| Field | Type | Description | -| --- | --- | --- | -| `floor_mode` | `string` | Effective floor mode (`static` or `adaptive`). | -| `adaptive_floor_idle_secs` | `u64` | Adaptive floor idle threshold. | -| `adaptive_floor_min_writers_single_endpoint` | `u8` | Adaptive floor minimum for single-endpoint DCs. | -| `adaptive_floor_min_writers_multi_endpoint` | `u8` | Adaptive floor minimum for multi-endpoint DCs. | -| `adaptive_floor_recover_grace_secs` | `u64` | Adaptive floor recovery grace period. | -| `adaptive_floor_writers_per_core_total` | `u16` | Target total writers-per-core budget in adaptive mode. | -| `adaptive_floor_cpu_cores_override` | `u16` | Manual CPU core override (`0` means auto-detect). | -| `adaptive_floor_max_extra_writers_single_per_core` | `u16` | Extra per-core adaptive headroom for single-endpoint DCs. | -| `adaptive_floor_max_extra_writers_multi_per_core` | `u16` | Extra per-core adaptive headroom for multi-endpoint DCs. | -| `adaptive_floor_max_active_writers_per_core` | `u16` | Active writer cap per CPU core. | -| `adaptive_floor_max_warm_writers_per_core` | `u16` | Warm writer cap per CPU core. | -| `adaptive_floor_max_active_writers_global` | `u32` | Global active writer cap. | -| `adaptive_floor_max_warm_writers_global` | `u32` | Global warm writer cap. | -| `reconnect_max_concurrent_per_dc` | `u32` | Max concurrent reconnects per DC. | -| `reconnect_backoff_base_ms` | `u64` | Reconnect base backoff. | -| `reconnect_backoff_cap_ms` | `u64` | Reconnect backoff cap. | -| `reconnect_fast_retry_count` | `u32` | Number of fast retries before standard backoff strategy. | -| `writer_pick_mode` | `string` | Writer picker mode (`sorted_rr`, `p2c`). | -| `writer_pick_sample_size` | `u8` | Candidate sample size for `p2c` picker mode. | -| `me2dc_fallback` | `bool` | Effective ME -> direct fallback flag. | - -#### `EffectiveUserIpPolicyLimits` -| Field | Type | Description | -| --- | --- | --- | -| `mode` | `string` | Unique-IP policy mode (`active_window`, `time_window`, `combined`). | -| `window_secs` | `u64` | Time window length used by unique-IP policy. | - -### `SecurityPostureData` -| Field | Type | Description | -| --- | --- | --- | -| `api_read_only` | `bool` | Current API read-only state. | -| `api_whitelist_enabled` | `bool` | Whether whitelist filtering is active. | -| `api_whitelist_entries` | `usize` | Number of configured whitelist CIDRs. | -| `api_auth_header_enabled` | `bool` | Whether `Authorization` header validation is active. | -| `proxy_protocol_enabled` | `bool` | Global PROXY protocol accept setting. | -| `log_level` | `string` | Effective log level (`debug`, `verbose`, `normal`, `silent`). | -| `telemetry_core_enabled` | `bool` | Core telemetry toggle. | -| `telemetry_user_enabled` | `bool` | Per-user telemetry toggle. | -| `telemetry_me_level` | `string` | ME telemetry level (`silent`, `normal`, `debug`). | - -### `SecurityWhitelistData` -| Field | Type | Description | -| --- | --- | --- | -| `generated_at_epoch_secs` | `u64` | Snapshot generation timestamp. | -| `enabled` | `bool` | `true` when whitelist has at least one CIDR entry. | -| `entries_total` | `usize` | Number of whitelist CIDR entries. | -| `entries` | `string[]` | Whitelist CIDR entries as strings. | - -### `RuntimeMePoolStateData` -| Field | Type | Description | -| --- | --- | --- | -| `enabled` | `bool` | Runtime payload availability. | -| `reason` | `string?` | `source_unavailable` when ME pool snapshot is unavailable. | -| `generated_at_epoch_secs` | `u64` | Snapshot generation timestamp. | -| `data` | `RuntimeMePoolStatePayload?` | Null when unavailable. | - -#### `RuntimeMePoolStatePayload` -| Field | Type | Description | -| --- | --- | --- | -| `generations` | `RuntimeMePoolStateGenerationData` | Active/warm/pending/draining generation snapshot. | -| `hardswap` | `RuntimeMePoolStateHardswapData` | Hardswap state flags. | -| `writers` | `RuntimeMePoolStateWriterData` | Writer total/contour/health counters. | -| `refill` | `RuntimeMePoolStateRefillData` | In-flight refill counters by DC/family. | - -#### `RuntimeMePoolStateGenerationData` -| Field | Type | Description | -| --- | --- | --- | -| `active_generation` | `u64` | Active pool generation id. | -| `warm_generation` | `u64` | Warm pool generation id. | -| `pending_hardswap_generation` | `u64` | Pending hardswap generation id (`0` when none). | -| `pending_hardswap_age_secs` | `u64?` | Age of pending hardswap generation in seconds. | -| `draining_generations` | `u64[]` | Distinct generation ids currently draining. | - -#### `RuntimeMePoolStateHardswapData` -| Field | Type | Description | -| --- | --- | --- | -| `enabled` | `bool` | Hardswap feature toggle. | -| `pending` | `bool` | `true` when pending generation is non-zero. | - -#### `RuntimeMePoolStateWriterData` -| Field | Type | Description | -| --- | --- | --- | -| `total` | `usize` | Total writer rows in snapshot. | -| `alive_non_draining` | `usize` | Alive writers excluding draining ones. | -| `draining` | `usize` | Writers marked draining. | -| `degraded` | `usize` | Non-draining degraded writers. | -| `contour` | `RuntimeMePoolStateWriterContourData` | Counts by contour state. | -| `health` | `RuntimeMePoolStateWriterHealthData` | Counts by health bucket. | - -#### `RuntimeMePoolStateWriterContourData` -| Field | Type | Description | -| --- | --- | --- | -| `warm` | `usize` | Writers in warm contour. | -| `active` | `usize` | Writers in active contour. | -| `draining` | `usize` | Writers in draining contour. | - -#### `RuntimeMePoolStateWriterHealthData` -| Field | Type | Description | -| --- | --- | --- | -| `healthy` | `usize` | Non-draining non-degraded writers. | -| `degraded` | `usize` | Non-draining degraded writers. | -| `draining` | `usize` | Draining writers. | - -#### `RuntimeMePoolStateRefillData` -| Field | Type | Description | -| --- | --- | --- | -| `inflight_endpoints_total` | `usize` | Total in-flight endpoint refill operations. | -| `inflight_dc_total` | `usize` | Number of distinct DC+family keys with refill in flight. | -| `by_dc` | `RuntimeMePoolStateRefillDcData[]` | Per-DC refill rows. | - -#### `RuntimeMePoolStateRefillDcData` -| Field | Type | Description | -| --- | --- | --- | -| `dc` | `i16` | Telegram DC id. | -| `family` | `string` | Address family label (`V4`, `V6`). | -| `inflight` | `usize` | In-flight refill operations for this row. | - -### `RuntimeMeQualityData` -| Field | Type | Description | -| --- | --- | --- | -| `enabled` | `bool` | Runtime payload availability. | -| `reason` | `string?` | `source_unavailable` when ME pool snapshot is unavailable. | -| `generated_at_epoch_secs` | `u64` | Snapshot generation timestamp. | -| `data` | `RuntimeMeQualityPayload?` | Null when unavailable. | - -#### `RuntimeMeQualityPayload` -| Field | Type | Description | -| --- | --- | --- | -| `counters` | `RuntimeMeQualityCountersData` | Key ME lifecycle/error counters. | -| `route_drops` | `RuntimeMeQualityRouteDropData` | Route drop counters by reason. | -| `dc_rtt` | `RuntimeMeQualityDcRttData[]` | Per-DC RTT and writer coverage rows. | - -#### `RuntimeMeQualityCountersData` -| Field | Type | Description | -| --- | --- | --- | -| `idle_close_by_peer_total` | `u64` | Peer-initiated idle closes. | -| `reader_eof_total` | `u64` | Reader EOF events. | -| `kdf_drift_total` | `u64` | KDF drift detections. | -| `kdf_port_only_drift_total` | `u64` | KDF port-only drift detections. | -| `reconnect_attempt_total` | `u64` | Reconnect attempts. | -| `reconnect_success_total` | `u64` | Successful reconnects. | - -#### `RuntimeMeQualityRouteDropData` -| Field | Type | Description | -| --- | --- | --- | -| `no_conn_total` | `u64` | Route drops with no connection mapping. | -| `channel_closed_total` | `u64` | Route drops because destination channel is closed. | -| `queue_full_total` | `u64` | Route drops due queue backpressure (aggregate). | -| `queue_full_base_total` | `u64` | Route drops in base-queue path. | -| `queue_full_high_total` | `u64` | Route drops in high-priority queue path. | - -#### `RuntimeMeQualityDcRttData` -| Field | Type | Description | -| --- | --- | --- | -| `dc` | `i16` | Telegram DC id. | -| `rtt_ema_ms` | `f64?` | RTT EMA for this DC. | -| `alive_writers` | `usize` | Alive writers currently mapped to this DC. | -| `required_writers` | `usize` | Target writer floor for this DC. | -| `coverage_pct` | `f64` | `alive_writers / required_writers * 100`. | - -### `RuntimeUpstreamQualityData` -| Field | Type | Description | -| --- | --- | --- | -| `enabled` | `bool` | Runtime payload availability. | -| `reason` | `string?` | `source_unavailable` when upstream runtime snapshot is unavailable. | -| `generated_at_epoch_secs` | `u64` | Snapshot generation timestamp. | -| `policy` | `RuntimeUpstreamQualityPolicyData` | Effective upstream policy values. | -| `counters` | `RuntimeUpstreamQualityCountersData` | Upstream connect counters. | -| `summary` | `RuntimeUpstreamQualitySummaryData?` | Aggregate runtime health summary. | -| `upstreams` | `RuntimeUpstreamQualityUpstreamData[]?` | Per-upstream runtime rows. | - -#### `RuntimeUpstreamQualityPolicyData` -| Field | Type | Description | -| --- | --- | --- | -| `connect_retry_attempts` | `u32` | Upstream connect retry attempts. | -| `connect_retry_backoff_ms` | `u64` | Upstream retry backoff delay. | -| `connect_budget_ms` | `u64` | Total connect wall-clock budget. | -| `unhealthy_fail_threshold` | `u32` | Consecutive fail threshold for unhealthy marking. | -| `connect_failfast_hard_errors` | `bool` | Whether hard errors skip retries. | - -#### `RuntimeUpstreamQualityCountersData` -| Field | Type | Description | -| --- | --- | --- | -| `connect_attempt_total` | `u64` | Total connect attempts. | -| `connect_success_total` | `u64` | Successful connects. | -| `connect_fail_total` | `u64` | Failed connects. | -| `connect_failfast_hard_error_total` | `u64` | Fail-fast hard errors. | - -#### `RuntimeUpstreamQualitySummaryData` -| Field | Type | Description | -| --- | --- | --- | -| `configured_total` | `usize` | Total configured upstream entries. | -| `healthy_total` | `usize` | Upstreams currently healthy. | -| `unhealthy_total` | `usize` | Upstreams currently unhealthy. | -| `direct_total` | `usize` | Direct-route upstream entries. | -| `socks4_total` | `usize` | SOCKS4 upstream entries. | -| `socks5_total` | `usize` | SOCKS5 upstream entries. | -| `shadowsocks_total` | `usize` | Shadowsocks upstream entries. | - -#### `RuntimeUpstreamQualityUpstreamData` -| Field | Type | Description | -| --- | --- | --- | -| `upstream_id` | `usize` | Runtime upstream index. | -| `route_kind` | `string` | `direct`, `socks4`, `socks5`, `shadowsocks`. | -| `address` | `string` | Upstream address (`direct` literal for direct route kind, `host:port` only for proxied upstreams). | -| `weight` | `u16` | Selection weight. | -| `scopes` | `string` | Configured scope selector. | -| `healthy` | `bool` | Current health flag. | -| `fails` | `u32` | Consecutive fail counter. | -| `last_check_age_secs` | `u64` | Seconds since last health update. | -| `effective_latency_ms` | `f64?` | Effective latency score used by selector. | -| `dc` | `RuntimeUpstreamQualityDcData[]` | Per-DC runtime rows. | - -#### `RuntimeUpstreamQualityDcData` -| Field | Type | Description | -| --- | --- | --- | -| `dc` | `i16` | Telegram DC id. | -| `latency_ema_ms` | `f64?` | Per-DC latency EMA. | -| `ip_preference` | `string` | `unknown`, `prefer_v4`, `prefer_v6`, `both_work`, `unavailable`. | - -### `RuntimeNatStunData` -| Field | Type | Description | -| --- | --- | --- | -| `enabled` | `bool` | Runtime payload availability. | -| `reason` | `string?` | `source_unavailable` when shared STUN state is unavailable. | -| `generated_at_epoch_secs` | `u64` | Snapshot generation timestamp. | -| `data` | `RuntimeNatStunPayload?` | Null when unavailable. | - -#### `RuntimeNatStunPayload` -| Field | Type | Description | -| --- | --- | --- | -| `flags` | `RuntimeNatStunFlagsData` | NAT probe runtime flags. | -| `servers` | `RuntimeNatStunServersData` | Configured/live STUN server lists. | -| `reflection` | `RuntimeNatStunReflectionBlockData` | Reflection cache data for v4/v6. | -| `stun_backoff_remaining_ms` | `u64?` | Remaining retry backoff (milliseconds). | - -#### `RuntimeNatStunFlagsData` -| Field | Type | Description | -| --- | --- | --- | -| `nat_probe_enabled` | `bool` | Current NAT probe enable state. | -| `nat_probe_disabled_runtime` | `bool` | Runtime disable flag due failures/conditions. | -| `nat_probe_attempts` | `u8` | Configured NAT probe attempt count. | - -#### `RuntimeNatStunServersData` -| Field | Type | Description | -| --- | --- | --- | -| `configured` | `string[]` | Configured STUN server entries. | -| `live` | `string[]` | Runtime live STUN server entries. | -| `live_total` | `usize` | Number of live STUN entries. | - -#### `RuntimeNatStunReflectionBlockData` -| Field | Type | Description | -| --- | --- | --- | -| `v4` | `RuntimeNatStunReflectionData?` | IPv4 reflection data. | -| `v6` | `RuntimeNatStunReflectionData?` | IPv6 reflection data. | - -#### `RuntimeNatStunReflectionData` -| Field | Type | Description | -| --- | --- | --- | -| `addr` | `string` | Reflected public endpoint (`ip:port`). | -| `age_secs` | `u64` | Reflection value age in seconds. | - -### `RuntimeMeSelftestData` -| Field | Type | Description | -| --- | --- | --- | -| `enabled` | `bool` | Runtime payload availability. | -| `reason` | `string?` | `source_unavailable` when ME pool is unavailable. | -| `generated_at_epoch_secs` | `u64` | Snapshot generation timestamp. | -| `data` | `RuntimeMeSelftestPayload?` | Null when unavailable. | - -#### `RuntimeMeSelftestPayload` -| Field | Type | Description | -| --- | --- | --- | -| `kdf` | `RuntimeMeSelftestKdfData` | KDF EWMA health state. | -| `timeskew` | `RuntimeMeSelftestTimeskewData` | Date-header skew health state. | -| `ip` | `RuntimeMeSelftestIpData` | Interface IP family classification. | -| `pid` | `RuntimeMeSelftestPidData` | Process PID marker (`one|non-one`). | -| `bnd` | `RuntimeMeSelftestBndData` | SOCKS BND.ADDR/BND.PORT health state. | - -#### `RuntimeMeSelftestKdfData` -| Field | Type | Description | -| --- | --- | --- | -| `state` | `string` | `ok` or `error` based on EWMA threshold. | -| `ewma_errors_per_min` | `f64` | EWMA KDF error rate per minute. | -| `threshold_errors_per_min` | `f64` | Threshold used for `error` decision. | -| `errors_total` | `u64` | Total source errors (`kdf_drift + socks_kdf_strict_reject`). | - -#### `RuntimeMeSelftestTimeskewData` -| Field | Type | Description | -| --- | --- | --- | -| `state` | `string` | `ok` or `error` (`max_skew_secs_15m > 60` => `error`). | -| `max_skew_secs_15m` | `u64?` | Maximum observed skew in the last 15 minutes. | -| `samples_15m` | `usize` | Number of skew samples in the last 15 minutes. | -| `last_skew_secs` | `u64?` | Latest observed skew value. | -| `last_source` | `string?` | Latest skew source marker. | -| `last_seen_age_secs` | `u64?` | Age of the latest skew sample. | - -#### `RuntimeMeSelftestIpData` -| Field | Type | Description | -| --- | --- | --- | -| `v4` | `RuntimeMeSelftestIpFamilyData?` | IPv4 interface probe result; absent when unknown. | -| `v6` | `RuntimeMeSelftestIpFamilyData?` | IPv6 interface probe result; absent when unknown. | - -#### `RuntimeMeSelftestIpFamilyData` -| Field | Type | Description | -| --- | --- | --- | -| `addr` | `string` | Detected interface IP. | -| `state` | `string` | `good`, `bogon`, or `loopback`. | - -#### `RuntimeMeSelftestPidData` -| Field | Type | Description | -| --- | --- | --- | -| `pid` | `u32` | Current process PID. | -| `state` | `string` | `one` when PID=1, otherwise `non-one`. | - -#### `RuntimeMeSelftestBndData` -| Field | Type | Description | -| --- | --- | --- | -| `addr_state` | `string` | `ok`, `bogon`, or `error`. | -| `port_state` | `string` | `ok`, `zero`, or `error`. | -| `last_addr` | `string?` | Latest observed SOCKS BND address. | -| `last_seen_age_secs` | `u64?` | Age of latest BND sample. | - -### `RuntimeEdgeConnectionsSummaryData` -| Field | Type | Description | -| --- | --- | --- | -| `enabled` | `bool` | Endpoint availability under `runtime_edge_enabled`. | -| `reason` | `string?` | `feature_disabled` or `source_unavailable`. | -| `generated_at_epoch_secs` | `u64` | Snapshot generation timestamp. | -| `data` | `RuntimeEdgeConnectionsSummaryPayload?` | Null when unavailable. | - -#### `RuntimeEdgeConnectionsSummaryPayload` -| Field | Type | Description | -| --- | --- | --- | -| `cache` | `RuntimeEdgeConnectionCacheData` | Runtime edge cache metadata. | -| `totals` | `RuntimeEdgeConnectionTotalsData` | Connection totals block. | -| `top` | `RuntimeEdgeConnectionTopData` | Top-N leaderboard blocks. | -| `telemetry` | `RuntimeEdgeConnectionTelemetryData` | Telemetry-policy flags for counters. | - -#### `RuntimeEdgeConnectionCacheData` -| Field | Type | Description | -| --- | --- | --- | -| `ttl_ms` | `u64` | Configured cache TTL in milliseconds. | -| `served_from_cache` | `bool` | `true` when payload is served from cache. | -| `stale_cache_used` | `bool` | `true` when stale cache is used because recompute is busy. | - -#### `RuntimeEdgeConnectionTotalsData` -| Field | Type | Description | -| --- | --- | --- | -| `current_connections` | `u64` | Current global live connections. | -| `current_connections_me` | `u64` | Current live connections routed through ME. | -| `current_connections_direct` | `u64` | Current live connections routed through direct path. | -| `active_users` | `usize` | Users with `current_connections > 0`. | - -#### `RuntimeEdgeConnectionTopData` -| Field | Type | Description | -| --- | --- | --- | -| `limit` | `usize` | Effective Top-N row count. | -| `by_connections` | `RuntimeEdgeConnectionUserData[]` | Users sorted by current connections. | -| `by_throughput` | `RuntimeEdgeConnectionUserData[]` | Users sorted by cumulative octets. | - -#### `RuntimeEdgeConnectionUserData` -| Field | Type | Description | -| --- | --- | --- | -| `username` | `string` | Username. | -| `current_connections` | `u64` | Current live connections for user. | -| `total_octets` | `u64` | Cumulative (`client->proxy + proxy->client`) octets. | - -#### `RuntimeEdgeConnectionTelemetryData` -| Field | Type | Description | -| --- | --- | --- | -| `user_enabled` | `bool` | Per-user telemetry enable flag. | -| `throughput_is_cumulative` | `bool` | Always `true` in current implementation. | - -### `RuntimeEdgeEventsData` -| Field | Type | Description | -| --- | --- | --- | -| `enabled` | `bool` | Endpoint availability under `runtime_edge_enabled`. | -| `reason` | `string?` | `feature_disabled` when endpoint is disabled. | -| `generated_at_epoch_secs` | `u64` | Snapshot generation timestamp. | -| `data` | `RuntimeEdgeEventsPayload?` | Null when unavailable. | - -#### `RuntimeEdgeEventsPayload` -| Field | Type | Description | -| --- | --- | --- | -| `capacity` | `usize` | Effective ring-buffer capacity. | -| `dropped_total` | `u64` | Count of dropped oldest events due capacity pressure. | -| `events` | `ApiEventRecord[]` | Recent events in chronological order. | - -#### `ApiEventRecord` -| Field | Type | Description | -| --- | --- | --- | -| `seq` | `u64` | Monotonic sequence number. | -| `ts_epoch_secs` | `u64` | Event timestamp (Unix seconds). | -| `event_type` | `string` | Event kind identifier. | -| `context` | `string` | Context text (truncated to implementation-defined max length). | - -### `ZeroAllData` -| Field | Type | Description | -| --- | --- | --- | -| `generated_at_epoch_secs` | `u64` | Snapshot time (Unix epoch seconds). | -| `core` | `ZeroCoreData` | Core counters and telemetry policy snapshot. | -| `upstream` | `ZeroUpstreamData` | Upstream connect counters/histogram buckets. | -| `middle_proxy` | `ZeroMiddleProxyData` | ME protocol/health counters. | -| `pool` | `ZeroPoolData` | ME pool lifecycle counters. | -| `desync` | `ZeroDesyncData` | Frame desync counters. | - -#### `ZeroCoreData` -| Field | Type | Description | -| --- | --- | --- | -| `uptime_seconds` | `f64` | Process uptime. | -| `connections_total` | `u64` | Total accepted connections. | -| `connections_bad_total` | `u64` | Failed/invalid connections. | -| `handshake_timeouts_total` | `u64` | Handshake timeouts. | -| `configured_users` | `usize` | Configured user count. | -| `telemetry_core_enabled` | `bool` | Core telemetry toggle. | -| `telemetry_user_enabled` | `bool` | User telemetry toggle. | -| `telemetry_me_level` | `string` | ME telemetry level (`off|normal|verbose`). | - -#### `ZeroUpstreamData` -| Field | Type | Description | -| --- | --- | --- | -| `connect_attempt_total` | `u64` | Total upstream connect attempts. | -| `connect_success_total` | `u64` | Successful upstream connects. | -| `connect_fail_total` | `u64` | Failed upstream connects. | -| `connect_failfast_hard_error_total` | `u64` | Fail-fast hard errors. | -| `connect_attempts_bucket_1` | `u64` | Connect attempts resolved in 1 try. | -| `connect_attempts_bucket_2` | `u64` | Connect attempts resolved in 2 tries. | -| `connect_attempts_bucket_3_4` | `u64` | Connect attempts resolved in 3-4 tries. | -| `connect_attempts_bucket_gt_4` | `u64` | Connect attempts requiring more than 4 tries. | -| `connect_duration_success_bucket_le_100ms` | `u64` | Successful connects <=100 ms. | -| `connect_duration_success_bucket_101_500ms` | `u64` | Successful connects 101-500 ms. | -| `connect_duration_success_bucket_501_1000ms` | `u64` | Successful connects 501-1000 ms. | -| `connect_duration_success_bucket_gt_1000ms` | `u64` | Successful connects >1000 ms. | -| `connect_duration_fail_bucket_le_100ms` | `u64` | Failed connects <=100 ms. | -| `connect_duration_fail_bucket_101_500ms` | `u64` | Failed connects 101-500 ms. | -| `connect_duration_fail_bucket_501_1000ms` | `u64` | Failed connects 501-1000 ms. | -| `connect_duration_fail_bucket_gt_1000ms` | `u64` | Failed connects >1000 ms. | - -### `UpstreamsData` -| Field | Type | Description | -| --- | --- | --- | -| `enabled` | `bool` | Runtime upstream snapshot availability according to API config. | -| `reason` | `string?` | `feature_disabled` or `source_unavailable` when runtime snapshot is unavailable. | -| `generated_at_epoch_secs` | `u64` | Snapshot generation time. | -| `zero` | `ZeroUpstreamData` | Always available zero-cost upstream counters block. | -| `summary` | `UpstreamSummaryData?` | Runtime upstream aggregate view, null when unavailable. | -| `upstreams` | `UpstreamStatus[]?` | Per-upstream runtime status rows, null when unavailable. | - -#### `UpstreamSummaryData` -| Field | Type | Description | -| --- | --- | --- | -| `configured_total` | `usize` | Total configured upstream entries. | -| `healthy_total` | `usize` | Upstreams currently marked healthy. | -| `unhealthy_total` | `usize` | Upstreams currently marked unhealthy. | -| `direct_total` | `usize` | Number of direct upstream entries. | -| `socks4_total` | `usize` | Number of SOCKS4 upstream entries. | -| `socks5_total` | `usize` | Number of SOCKS5 upstream entries. | -| `shadowsocks_total` | `usize` | Number of Shadowsocks upstream entries. | - -#### `UpstreamStatus` -| Field | Type | Description | -| --- | --- | --- | -| `upstream_id` | `usize` | Runtime upstream index. | -| `route_kind` | `string` | Upstream route kind: `direct`, `socks4`, `socks5`, `shadowsocks`. | -| `address` | `string` | Upstream address (`direct` for direct route kind, `host:port` for Shadowsocks). Authentication fields are intentionally omitted. | -| `weight` | `u16` | Selection weight. | -| `scopes` | `string` | Configured scope selector string. | -| `healthy` | `bool` | Current health flag. | -| `fails` | `u32` | Consecutive fail counter. | -| `last_check_age_secs` | `u64` | Seconds since the last health-check update. | -| `effective_latency_ms` | `f64?` | Effective upstream latency used by selector. | -| `dc` | `UpstreamDcStatus[]` | Per-DC latency/IP preference snapshot. | - -#### `UpstreamDcStatus` -| Field | Type | Description | -| --- | --- | --- | -| `dc` | `i16` | Telegram DC id. | -| `latency_ema_ms` | `f64?` | Per-DC latency EMA value. | -| `ip_preference` | `string` | Per-DC IP family preference: `unknown`, `prefer_v4`, `prefer_v6`, `both_work`, `unavailable`. | - -#### `ZeroMiddleProxyData` -| Field | Type | Description | -| --- | --- | --- | -| `keepalive_sent_total` | `u64` | ME keepalive packets sent. | -| `keepalive_failed_total` | `u64` | ME keepalive send failures. | -| `keepalive_pong_total` | `u64` | Keepalive pong responses received. | -| `keepalive_timeout_total` | `u64` | Keepalive timeout events. | -| `rpc_proxy_req_signal_sent_total` | `u64` | RPC proxy activity signals sent. | -| `rpc_proxy_req_signal_failed_total` | `u64` | RPC proxy activity signal failures. | -| `rpc_proxy_req_signal_skipped_no_meta_total` | `u64` | Signals skipped due to missing metadata. | -| `rpc_proxy_req_signal_response_total` | `u64` | RPC proxy signal responses received. | -| `rpc_proxy_req_signal_close_sent_total` | `u64` | RPC proxy close signals sent. | -| `reconnect_attempt_total` | `u64` | ME reconnect attempts. | -| `reconnect_success_total` | `u64` | Successful reconnects. | -| `handshake_reject_total` | `u64` | ME handshake rejects. | -| `handshake_error_codes` | `ZeroCodeCount[]` | Handshake rejects grouped by code. | -| `reader_eof_total` | `u64` | ME reader EOF events. | -| `idle_close_by_peer_total` | `u64` | Idle closes initiated by peer. | -| `route_drop_no_conn_total` | `u64` | Route drops due to missing bound connection. | -| `route_drop_channel_closed_total` | `u64` | Route drops due to closed channel. | -| `route_drop_queue_full_total` | `u64` | Route drops due to full queue (total). | -| `route_drop_queue_full_base_total` | `u64` | Route drops in base queue mode. | -| `route_drop_queue_full_high_total` | `u64` | Route drops in high queue mode. | -| `socks_kdf_strict_reject_total` | `u64` | SOCKS KDF strict rejects. | -| `socks_kdf_compat_fallback_total` | `u64` | SOCKS KDF compat fallbacks. | -| `endpoint_quarantine_total` | `u64` | Endpoint quarantine activations. | -| `kdf_drift_total` | `u64` | KDF drift detections. | -| `kdf_port_only_drift_total` | `u64` | KDF port-only drift detections. | -| `hardswap_pending_reuse_total` | `u64` | Pending hardswap reused events. | -| `hardswap_pending_ttl_expired_total` | `u64` | Pending hardswap TTL expiry events. | -| `single_endpoint_outage_enter_total` | `u64` | Entered single-endpoint outage mode. | -| `single_endpoint_outage_exit_total` | `u64` | Exited single-endpoint outage mode. | -| `single_endpoint_outage_reconnect_attempt_total` | `u64` | Reconnect attempts in outage mode. | -| `single_endpoint_outage_reconnect_success_total` | `u64` | Reconnect successes in outage mode. | -| `single_endpoint_quarantine_bypass_total` | `u64` | Quarantine bypasses in outage mode. | -| `single_endpoint_shadow_rotate_total` | `u64` | Shadow writer rotations. | -| `single_endpoint_shadow_rotate_skipped_quarantine_total` | `u64` | Shadow rotations skipped because of quarantine. | -| `floor_mode_switch_total` | `u64` | Total floor mode switches. | -| `floor_mode_switch_static_to_adaptive_total` | `u64` | Static -> adaptive switches. | -| `floor_mode_switch_adaptive_to_static_total` | `u64` | Adaptive -> static switches. | - -#### `ZeroCodeCount` -| Field | Type | Description | -| --- | --- | --- | -| `code` | `i32` | Handshake error code. | -| `total` | `u64` | Events with this code. | - -#### `ZeroPoolData` -| Field | Type | Description | -| --- | --- | --- | -| `pool_swap_total` | `u64` | Pool swap count. | -| `pool_drain_active` | `u64` | Current active draining pools. | -| `pool_force_close_total` | `u64` | Forced pool closes by timeout. | -| `pool_stale_pick_total` | `u64` | Stale writer picks for binding. | -| `writer_removed_total` | `u64` | Writer removals total. | -| `writer_removed_unexpected_total` | `u64` | Unexpected writer removals. | -| `refill_triggered_total` | `u64` | Refill triggers. | -| `refill_skipped_inflight_total` | `u64` | Refill skipped because refill already in-flight. | -| `refill_failed_total` | `u64` | Refill failures. | -| `writer_restored_same_endpoint_total` | `u64` | Restores on same endpoint. | -| `writer_restored_fallback_total` | `u64` | Restores on fallback endpoint. | - -#### `ZeroDesyncData` -| Field | Type | Description | -| --- | --- | --- | -| `secure_padding_invalid_total` | `u64` | Invalid secure padding events. | -| `desync_total` | `u64` | Desync events total. | -| `desync_full_logged_total` | `u64` | Fully logged desync events. | -| `desync_suppressed_total` | `u64` | Suppressed desync logs. | -| `desync_frames_bucket_0` | `u64` | Desync frames bucket 0. | -| `desync_frames_bucket_1_2` | `u64` | Desync frames bucket 1-2. | -| `desync_frames_bucket_3_10` | `u64` | Desync frames bucket 3-10. | -| `desync_frames_bucket_gt_10` | `u64` | Desync frames bucket >10. | - -### `MinimalAllData` -| Field | Type | Description | -| --- | --- | --- | -| `enabled` | `bool` | Whether minimal runtime snapshots are enabled by config. | -| `reason` | `string?` | `feature_disabled` or `source_unavailable` when applicable. | -| `generated_at_epoch_secs` | `u64` | Snapshot generation time. | -| `data` | `MinimalAllPayload?` | Null when disabled; fallback payload when source unavailable. | - -#### `MinimalAllPayload` -| Field | Type | Description | -| --- | --- | --- | -| `me_writers` | `MeWritersData` | ME writer status block. | -| `dcs` | `DcStatusData` | DC aggregate status block. | -| `me_runtime` | `MinimalMeRuntimeData?` | Runtime ME control snapshot. | -| `network_path` | `MinimalDcPathData[]` | Active IP path selection per DC. | - -#### `MinimalMeRuntimeData` -| Field | Type | Description | -| --- | --- | --- | -| `active_generation` | `u64` | Active pool generation. | -| `warm_generation` | `u64` | Warm pool generation. | -| `pending_hardswap_generation` | `u64` | Pending hardswap generation. | -| `pending_hardswap_age_secs` | `u64?` | Pending hardswap age in seconds. | -| `hardswap_enabled` | `bool` | Hardswap mode toggle. | -| `floor_mode` | `string` | Writer floor mode. | -| `adaptive_floor_idle_secs` | `u64` | Idle threshold for adaptive floor. | -| `adaptive_floor_min_writers_single_endpoint` | `u8` | Minimum writers for single-endpoint DC in adaptive mode. | -| `adaptive_floor_min_writers_multi_endpoint` | `u8` | Minimum writers for multi-endpoint DC in adaptive mode. | -| `adaptive_floor_recover_grace_secs` | `u64` | Grace period for floor recovery. | -| `adaptive_floor_writers_per_core_total` | `u16` | Target total writers-per-core budget in adaptive mode. | -| `adaptive_floor_cpu_cores_override` | `u16` | CPU core override (`0` means auto-detect). | -| `adaptive_floor_max_extra_writers_single_per_core` | `u16` | Extra single-endpoint writers budget per core. | -| `adaptive_floor_max_extra_writers_multi_per_core` | `u16` | Extra multi-endpoint writers budget per core. | -| `adaptive_floor_max_active_writers_per_core` | `u16` | Active writer cap per core. | -| `adaptive_floor_max_warm_writers_per_core` | `u16` | Warm writer cap per core. | -| `adaptive_floor_max_active_writers_global` | `u32` | Global active writer cap. | -| `adaptive_floor_max_warm_writers_global` | `u32` | Global warm writer cap. | -| `adaptive_floor_cpu_cores_detected` | `u32` | Runtime-detected CPU cores. | -| `adaptive_floor_cpu_cores_effective` | `u32` | Effective core count used for adaptive caps. | -| `adaptive_floor_global_cap_raw` | `u64` | Raw global cap before clamping. | -| `adaptive_floor_global_cap_effective` | `u64` | Effective global cap after clamping. | -| `adaptive_floor_target_writers_total` | `u64` | Current adaptive total writer target. | -| `adaptive_floor_active_cap_configured` | `u64` | Configured global active cap. | -| `adaptive_floor_active_cap_effective` | `u64` | Effective global active cap. | -| `adaptive_floor_warm_cap_configured` | `u64` | Configured global warm cap. | -| `adaptive_floor_warm_cap_effective` | `u64` | Effective global warm cap. | -| `adaptive_floor_active_writers_current` | `u64` | Current active writers count. | -| `adaptive_floor_warm_writers_current` | `u64` | Current warm writers count. | -| `me_keepalive_enabled` | `bool` | ME keepalive toggle. | -| `me_keepalive_interval_secs` | `u64` | Keepalive period. | -| `me_keepalive_jitter_secs` | `u64` | Keepalive jitter. | -| `me_keepalive_payload_random` | `bool` | Randomized keepalive payload toggle. | -| `rpc_proxy_req_every_secs` | `u64` | Period for RPC proxy request signal. | -| `me_reconnect_max_concurrent_per_dc` | `u32` | Reconnect concurrency per DC. | -| `me_reconnect_backoff_base_ms` | `u64` | Base reconnect backoff. | -| `me_reconnect_backoff_cap_ms` | `u64` | Max reconnect backoff. | -| `me_reconnect_fast_retry_count` | `u32` | Fast retry attempts before normal backoff. | -| `me_pool_drain_ttl_secs` | `u64` | Pool drain TTL. | -| `me_pool_force_close_secs` | `u64` | Hard close timeout for draining writers. | -| `me_pool_min_fresh_ratio` | `f32` | Minimum fresh ratio before swap. | -| `me_bind_stale_mode` | `string` | Stale writer bind policy. | -| `me_bind_stale_ttl_secs` | `u64` | Stale writer TTL. | -| `me_single_endpoint_shadow_writers` | `u8` | Shadow writers for single-endpoint DCs. | -| `me_single_endpoint_outage_mode_enabled` | `bool` | Outage mode toggle for single-endpoint DCs. | -| `me_single_endpoint_outage_disable_quarantine` | `bool` | Allows reconnect attempts to bypass endpoint quarantine for single-endpoint outage recovery paths. | -| `me_single_endpoint_outage_backoff_min_ms` | `u64` | Outage mode min reconnect backoff. | -| `me_single_endpoint_outage_backoff_max_ms` | `u64` | Outage mode max reconnect backoff. | -| `me_single_endpoint_shadow_rotate_every_secs` | `u64` | Shadow rotation interval. | -| `me_deterministic_writer_sort` | `bool` | Deterministic writer ordering toggle. | -| `me_writer_pick_mode` | `string` | Writer picker mode (`sorted_rr`, `p2c`). | -| `me_writer_pick_sample_size` | `u8` | Candidate sample size for `p2c` picker mode. | -| `me_socks_kdf_policy` | `string` | Current SOCKS KDF policy mode. | -| `quarantined_endpoints_total` | `usize` | Total quarantined endpoints. | -| `quarantined_endpoints` | `MinimalQuarantineData[]` | Quarantine details. | - -#### `MinimalQuarantineData` -| Field | Type | Description | -| --- | --- | --- | -| `endpoint` | `string` | Endpoint (`ip:port`). | -| `remaining_ms` | `u64` | Remaining quarantine duration. | - -#### `MinimalDcPathData` -| Field | Type | Description | -| --- | --- | --- | -| `dc` | `i16` | Telegram DC identifier. | -| `ip_preference` | `string?` | Runtime IP family preference. | -| `selected_addr_v4` | `string?` | Selected IPv4 endpoint for this DC. | -| `selected_addr_v6` | `string?` | Selected IPv6 endpoint for this DC. | - -### `MeWritersData` -| Field | Type | Description | -| --- | --- | --- | -| `middle_proxy_enabled` | `bool` | `false` when minimal runtime is disabled or source unavailable. | -| `reason` | `string?` | `feature_disabled` or `source_unavailable` when not fully available. | -| `generated_at_epoch_secs` | `u64` | Snapshot generation time. | -| `summary` | `MeWritersSummary` | Coverage/availability summary. | -| `writers` | `MeWriterStatus[]` | Per-writer statuses. | - -#### `MeWritersSummary` -| Field | Type | Description | -| --- | --- | --- | -| `configured_dc_groups` | `usize` | Number of configured DC groups. | -| `configured_endpoints` | `usize` | Total configured ME endpoints. | -| `available_endpoints` | `usize` | Endpoints currently available. | -| `available_pct` | `f64` | `available_endpoints / configured_endpoints * 100`. | -| `required_writers` | `usize` | Required writers based on current floor policy. | -| `alive_writers` | `usize` | Writers currently alive. | -| `coverage_pct` | `f64` | `alive_writers / required_writers * 100`. | - -#### `MeWriterStatus` -| Field | Type | Description | -| --- | --- | --- | -| `writer_id` | `u64` | Runtime writer identifier. | -| `dc` | `i16?` | DC id if mapped. | -| `endpoint` | `string` | Endpoint (`ip:port`). | -| `generation` | `u64` | Pool generation owning this writer. | -| `state` | `string` | Writer state (`warm`, `active`, `draining`). | -| `draining` | `bool` | Draining flag. | -| `degraded` | `bool` | Degraded flag. | -| `bound_clients` | `usize` | Number of currently bound clients. | -| `idle_for_secs` | `u64?` | Idle age in seconds if idle. | -| `rtt_ema_ms` | `f64?` | RTT exponential moving average. | - -### `DcStatusData` -| Field | Type | Description | -| --- | --- | --- | -| `middle_proxy_enabled` | `bool` | `false` when minimal runtime is disabled or source unavailable. | -| `reason` | `string?` | `feature_disabled` or `source_unavailable` when not fully available. | -| `generated_at_epoch_secs` | `u64` | Snapshot generation time. | -| `dcs` | `DcStatus[]` | Per-DC status rows. | - -#### `DcStatus` -| Field | Type | Description | -| --- | --- | --- | -| `dc` | `i16` | Telegram DC id. | -| `endpoints` | `string[]` | Endpoints in this DC (`ip:port`). | -| `endpoint_writers` | `DcEndpointWriters[]` | Active writer counts grouped by endpoint. | -| `available_endpoints` | `usize` | Endpoints currently available in this DC. | -| `available_pct` | `f64` | `available_endpoints / endpoints_total * 100`. | -| `required_writers` | `usize` | Required writer count for this DC. | -| `floor_min` | `usize` | Floor lower bound for this DC. | -| `floor_target` | `usize` | Floor target writer count for this DC. | -| `floor_max` | `usize` | Floor upper bound for this DC. | -| `floor_capped` | `bool` | `true` when computed floor target was capped by active limits. | -| `alive_writers` | `usize` | Alive writers in this DC. | -| `coverage_pct` | `f64` | `alive_writers / required_writers * 100`. | -| `rtt_ms` | `f64?` | Aggregated RTT for DC. | -| `load` | `usize` | Active client sessions bound to this DC. | - -#### `DcEndpointWriters` -| Field | Type | Description | -| --- | --- | --- | -| `endpoint` | `string` | Endpoint (`ip:port`). | -| `active_writers` | `usize` | Active writers currently mapped to endpoint. | - -### `UserInfo` -| Field | Type | Description | -| --- | --- | --- | -| `username` | `string` | Username. | -| `user_ad_tag` | `string?` | Optional ad tag (32 hex chars). | -| `max_tcp_conns` | `usize?` | Optional max concurrent TCP limit. | -| `expiration_rfc3339` | `string?` | Optional expiration timestamp. | -| `data_quota_bytes` | `u64?` | Optional data quota. | -| `max_unique_ips` | `usize?` | Optional unique IP limit. | -| `current_connections` | `u64` | Current live connections. | -| `active_unique_ips` | `usize` | Current active unique source IPs. | -| `active_unique_ips_list` | `ip[]` | Current active unique source IP list. | -| `recent_unique_ips` | `usize` | Unique source IP count inside the configured recent window. | -| `recent_unique_ips_list` | `ip[]` | Recent-window unique source IP list. | -| `total_octets` | `u64` | Total traffic octets for this user. | -| `links` | `UserLinks` | Active connection links derived from current config. | - -#### `UserLinks` -| Field | Type | Description | -| --- | --- | --- | -| `classic` | `string[]` | Active `tg://proxy` links for classic mode. | -| `secure` | `string[]` | Active `tg://proxy` links for secure/DD mode. | -| `tls` | `string[]` | Active `tg://proxy` links for EE-TLS mode (for each host+TLS domain). | - -Link generation uses active config and enabled modes: -- Link port is `general.links.public_port` when configured; otherwise `server.port`. -- If `general.links.public_host` is non-empty, it is used as the single link host override. -- If `public_host` is not set, hosts are resolved from `server.listeners` in order: - `announce` -> `announce_ip` -> listener bind `ip`. -- For wildcard listener IPs (`0.0.0.0` / `::`), startup-detected external IP of the same family is used when available. -- Listener-derived hosts are de-duplicated while preserving first-seen order. -- If multiple hosts are resolved, API returns links for all resolved hosts in every enabled mode. -- If no host can be resolved from listeners, fallback is startup-detected `IPv4 -> IPv6`. -- Final compatibility fallback uses `listen_addr_ipv4`/`listen_addr_ipv6` when routable, otherwise `"UNKNOWN"`. -- User rows are sorted by `username` in ascending lexical order. - -### `CreateUserResponse` -| Field | Type | Description | -| --- | --- | --- | -| `user` | `UserInfo` | Created or updated user view. | -| `secret` | `string` | Effective user secret. | - -## Mutation Semantics - -| Endpoint | Notes | -| --- | --- | -| `POST /v1/users` | Creates user, validates config, then atomically updates only affected `access.*` TOML tables (`access.users` always, plus optional per-user tables present in request). | -| `PATCH /v1/users/{username}` | Partial update of provided fields only. Missing fields remain unchanged. Current implementation persists full config document on success. | -| `POST /v1/users/{username}/rotate-secret` | Currently returns `404` in runtime route matcher; request schema is reserved for intended behavior. | -| `DELETE /v1/users/{username}` | Deletes only specified user, removes this user from related optional `access.user_*` maps, blocks last-user deletion, and atomically updates only related `access.*` TOML tables. | - -All mutating endpoints: -- Respect `read_only` mode. -- Accept optional `If-Match` for optimistic concurrency. -- Return new `revision` after successful write. -- Use process-local mutation lock + atomic write (`tmp + rename`) for config persistence. - -Delete path cleanup guarantees: -- Config cleanup removes only the requested username keys. -- Runtime unique-IP cleanup removes only this user's limiter and tracked IP state. - -## Runtime State Matrix - -| Endpoint | `minimal_runtime_enabled=false` | `minimal_runtime_enabled=true` + source unavailable | `minimal_runtime_enabled=true` + source available | -| --- | --- | --- | --- | -| `/v1/stats/minimal/all` | `enabled=false`, `reason=feature_disabled`, `data=null` | `enabled=true`, `reason=source_unavailable`, fallback `data` with disabled ME blocks | `enabled=true`, `reason` omitted, full payload | -| `/v1/stats/me-writers` | `middle_proxy_enabled=false`, `reason=feature_disabled` | `middle_proxy_enabled=false`, `reason=source_unavailable` | `middle_proxy_enabled=true`, runtime snapshot | -| `/v1/stats/dcs` | `middle_proxy_enabled=false`, `reason=feature_disabled` | `middle_proxy_enabled=false`, `reason=source_unavailable` | `middle_proxy_enabled=true`, runtime snapshot | -| `/v1/stats/upstreams` | `enabled=false`, `reason=feature_disabled`, `summary/upstreams` omitted, `zero` still present | `enabled=true`, `reason=source_unavailable`, `summary/upstreams` omitted, `zero` present | `enabled=true`, `reason` omitted, `summary/upstreams` present, `zero` present | - -`source_unavailable` conditions: -- ME endpoints: ME pool is absent (for example direct-only mode or failed ME initialization). -- Upstreams endpoint: non-blocking upstream snapshot lock is unavailable at request time. - -Additional runtime endpoint behavior: - -| Endpoint | Disabled by feature flag | `source_unavailable` condition | Normal mode | -| --- | --- | --- | --- | -| `/v1/runtime/me_pool_state` | No | ME pool snapshot unavailable | `enabled=true`, full payload | -| `/v1/runtime/me_quality` | No | ME pool snapshot unavailable | `enabled=true`, full payload | -| `/v1/runtime/upstream_quality` | No | Upstream runtime snapshot unavailable | `enabled=true`, full payload | -| `/v1/runtime/nat_stun` | No | STUN shared state unavailable | `enabled=true`, full payload | -| `/v1/runtime/me-selftest` | No | ME pool unavailable => `enabled=false`, `reason=source_unavailable` | `enabled=true`, full payload | -| `/v1/runtime/connections/summary` | `runtime_edge_enabled=false` => `enabled=false`, `reason=feature_disabled` | Recompute lock contention with no cache entry => `enabled=true`, `reason=source_unavailable` | `enabled=true`, full payload | -| `/v1/runtime/events/recent` | `runtime_edge_enabled=false` => `enabled=false`, `reason=feature_disabled` | Not used in current implementation | `enabled=true`, full payload | - -## ME Fallback Behavior Exposed Via API - -When `general.use_middle_proxy=true` and `general.me2dc_fallback=true`: -- Startup does not block on full ME pool readiness; initialization can continue in background. -- Runtime initialization payload can expose ME stage `background_init` until pool becomes ready. -- Admission/routing decision uses two readiness grace windows for "ME not ready" periods: - `80s` before first-ever readiness is observed (startup grace), - `6s` after readiness has been observed at least once (runtime failover timeout). -- While in fallback window breach, new sessions are routed via Direct-DC; when ME becomes ready, routing returns to Middle mode for new sessions. - -## Serialization Rules - -- Success responses always include `revision`. -- Error responses never include `revision`; they include `request_id`. -- Optional fields with `skip_serializing_if` are omitted when absent. -- Nullable payload fields may still be `null` where contract uses `?` (for example `UserInfo` option fields). -- For `/v1/stats/upstreams`, authentication details of SOCKS upstreams are intentionally omitted. -- `ip[]` fields are serialized as JSON string arrays (for example `"1.2.3.4"`, `"2001:db8::1"`). - -## Operational Notes - -| Topic | Details | -| --- | --- | -| API startup | API listener is spawned only when `[server.api].enabled=true`. | -| `listen` port `0` | API spawn is skipped when parsed listen port is `0` (treated as disabled bind target). | -| Bind failure | Failed API bind logs warning and API task exits (no auto-retry loop). | -| ME runtime status endpoints | `/v1/stats/me-writers`, `/v1/stats/dcs`, `/v1/stats/minimal/all` require `[server.api].minimal_runtime_enabled=true`; otherwise they return disabled payload with `reason=feature_disabled`. | -| Upstream runtime endpoint | `/v1/stats/upstreams` always returns `zero`, but runtime fields (`summary`, `upstreams`) require `[server.api].minimal_runtime_enabled=true`. | -| Restart requirements | `server.api` changes are restart-required for predictable behavior. | -| Hot-reload nuance | A pure `server.api`-only config change may not propagate through watcher broadcast; a mixed change (with hot fields) may propagate API flags while still warning that restart is required. | -| Runtime apply path | Successful writes are picked up by existing config watcher/hot-reload path. | -| Exposure | Built-in TLS/mTLS is not provided. Use loopback bind + reverse proxy if needed. | -| Pagination | User list currently has no pagination/filtering. | -| Serialization side effect | Updated TOML table bodies are re-serialized on write. Endpoints that persist full config can still rewrite broader formatting/comments. | - -## Known Limitations (Current Release) - -- `POST /v1/users/{username}/rotate-secret` is currently unreachable in route matcher and returns `404`. -- API runtime controls under `server.api` are documented as restart-required; hot-reload behavior for these fields is not strictly uniform in all change combinations. diff --git a/docs/CONFIG_PARAMS.en.md b/docs/CONFIG_PARAMS.en.md deleted file mode 100644 index ed3796d..0000000 --- a/docs/CONFIG_PARAMS.en.md +++ /dev/null @@ -1,3300 +0,0 @@ -# Telemt Config Parameters Reference - -This document lists all configuration keys accepted by `config.toml`. - -> [!NOTE] -> -> This reference was drafted with the help of AI and cross-checked against the codebase (config schema, defaults, and validation logic). - -> [!WARNING] -> -> The configuration parameters detailed in this document are intended for advanced users and fine-tuning purposes. Modifying these settings without a clear understanding of their function may lead to application instability or other unexpected behavior. Please proceed with caution and at your own risk. - -## Top-level keys - -| Key | Type | Default | -| --- | ---- | ------- | -| [`include`](#cfg-top-include) | `String` (special directive) | — | -| [`show_link`](#cfg-top-show_link) | `"*"` or `String[]` | `[]` (`ShowLink::None`) | -| [`dc_overrides`](#cfg-top-dc_overrides) | `Map` | `{}` | -| [`default_dc`](#cfg-top-default_dc) | `u8` | — (effective fallback: `2` in ME routing) | - - -- `include` - - **Constraints / validation**: Must be a single-line directive in the form `include = "path/to/file.toml"`. Includes are expanded before TOML parsing. Maximum include depth is 10. - - **Description**: Includes another TOML file with `include = "relative/or/absolute/path.toml"`; includes are processed recursively before parsing. - - **Example**: - - ```toml - include = "secrets.toml" - ``` - -- `show_link` - - **Constraints / validation**: Accepts `"*"` or an array of usernames. Empty array means "show none". - - **Description**: Legacy top-level link visibility selector (`"*"` for all users or explicit usernames list). - - **Example**: - - ```toml - # show links for all configured users - show_link = "*" - - # or: show links only for selected users - # show_link = ["alice", "bob"] - ``` - -- `dc_overrides` - - **Constraints / validation**: Key must be a positive integer DC index encoded as string (e.g. `"203"`). Values must parse as `SocketAddr` (`ip:port`). Empty strings are ignored. - - **Description**: Overrides DC endpoints for non-standard DCs; key is DC index string, value is one or more `ip:port` addresses. - - **Example**: - - ```toml - [dc_overrides] - "201" = "149.154.175.50:443" - "203" = ["149.154.175.100:443", "91.105.192.100:443"] - ``` - -- `default_dc` - - **Constraints / validation**: Intended range is `1..=5`. If set out of range, runtime falls back to DC1 behavior in direct relay; Middle-End routing falls back to `2` when not set. - - **Description**: Default DC index used for unmapped non-standard DCs. - - **Example**: - - ```toml - # When a client requests an unknown/non-standard DC with no override, - # route it to this default cluster (1..=5). - default_dc = 2 - ``` - -## [general] - -| Key | Type | Default | -| --- | ---- | ------- | -| [`data_path`](#cfg-general-data_path) | `String` | — | -| [`prefer_ipv6`](#cfg-general-prefer_ipv6) | `bool` | `false` | -| [`fast_mode`](#cfg-general-fast_mode) | `bool` | `true` | -| [`use_middle_proxy`](#cfg-general-use_middle_proxy) | `bool` | `true` | -| [`proxy_secret_path`](#cfg-general-proxy_secret_path) | `String` | `"proxy-secret"` | -| [`proxy_config_v4_cache_path`](#cfg-general-proxy_config_v4_cache_path) | `String` | `"cache/proxy-config-v4.txt"` | -| [`proxy_config_v6_cache_path`](#cfg-general-proxy_config_v6_cache_path) | `String` | `"cache/proxy-config-v6.txt"` | -| [`ad_tag`](#cfg-general-ad_tag) | `String` | — | -| [`middle_proxy_nat_ip`](#cfg-general-middle_proxy_nat_ip) | `IpAddr` | — | -| [`middle_proxy_nat_probe`](#cfg-general-middle_proxy_nat_probe) | `bool` | `true` | -| [`middle_proxy_nat_stun`](#cfg-general-middle_proxy_nat_stun) | `String` | — | -| [`middle_proxy_nat_stun_servers`](#cfg-general-middle_proxy_nat_stun_servers) | `String[]` | `[]` | -| [`stun_nat_probe_concurrency`](#cfg-general-stun_nat_probe_concurrency) | `usize` | `8` | -| [`middle_proxy_pool_size`](#cfg-general-middle_proxy_pool_size) | `usize` | `8` | -| [`middle_proxy_warm_standby`](#cfg-general-middle_proxy_warm_standby) | `usize` | `16` | -| [`me_init_retry_attempts`](#cfg-general-me_init_retry_attempts) | `u32` | `0` | -| [`me2dc_fallback`](#cfg-general-me2dc_fallback) | `bool` | `true` | -| [`me2dc_fast`](#cfg-general-me2dc_fast) | `bool` | `false` | -| [`me_keepalive_enabled`](#cfg-general-me_keepalive_enabled) | `bool` | `true` | -| [`me_keepalive_interval_secs`](#cfg-general-me_keepalive_interval_secs) | `u64` | `8` | -| [`me_keepalive_jitter_secs`](#cfg-general-me_keepalive_jitter_secs) | `u64` | `2` | -| [`me_keepalive_payload_random`](#cfg-general-me_keepalive_payload_random) | `bool` | `true` | -| [`rpc_proxy_req_every`](#cfg-general-rpc_proxy_req_every) | `u64` | `0` | -| [`me_writer_cmd_channel_capacity`](#cfg-general-me_writer_cmd_channel_capacity) | `usize` | `4096` | -| [`me_route_channel_capacity`](#cfg-general-me_route_channel_capacity) | `usize` | `768` | -| [`me_c2me_channel_capacity`](#cfg-general-me_c2me_channel_capacity) | `usize` | `1024` | -| [`me_c2me_send_timeout_ms`](#cfg-general-me_c2me_send_timeout_ms) | `u64` | `4000` | -| [`me_reader_route_data_wait_ms`](#cfg-general-me_reader_route_data_wait_ms) | `u64` | `2` | -| [`me_d2c_flush_batch_max_frames`](#cfg-general-me_d2c_flush_batch_max_frames) | `usize` | `32` | -| [`me_d2c_flush_batch_max_bytes`](#cfg-general-me_d2c_flush_batch_max_bytes) | `usize` | `131072` | -| [`me_d2c_flush_batch_max_delay_us`](#cfg-general-me_d2c_flush_batch_max_delay_us) | `u64` | `500` | -| [`me_d2c_ack_flush_immediate`](#cfg-general-me_d2c_ack_flush_immediate) | `bool` | `true` | -| [`me_quota_soft_overshoot_bytes`](#cfg-general-me_quota_soft_overshoot_bytes) | `u64` | `65536` | -| [`me_d2c_frame_buf_shrink_threshold_bytes`](#cfg-general-me_d2c_frame_buf_shrink_threshold_bytes) | `usize` | `262144` | -| [`direct_relay_copy_buf_c2s_bytes`](#cfg-general-direct_relay_copy_buf_c2s_bytes) | `usize` | `65536` | -| [`direct_relay_copy_buf_s2c_bytes`](#cfg-general-direct_relay_copy_buf_s2c_bytes) | `usize` | `262144` | -| [`crypto_pending_buffer`](#cfg-general-crypto_pending_buffer) | `usize` | `262144` | -| [`max_client_frame`](#cfg-general-max_client_frame) | `usize` | `16777216` | -| [`desync_all_full`](#cfg-general-desync_all_full) | `bool` | `false` | -| [`beobachten`](#cfg-general-beobachten) | `bool` | `true` | -| [`beobachten_minutes`](#cfg-general-beobachten_minutes) | `u64` | `10` | -| [`beobachten_flush_secs`](#cfg-general-beobachten_flush_secs) | `u64` | `15` | -| [`beobachten_file`](#cfg-general-beobachten_file) | `String` | `"cache/beobachten.txt"` | -| [`hardswap`](#cfg-general-hardswap) | `bool` | `true` | -| [`me_warmup_stagger_enabled`](#cfg-general-me_warmup_stagger_enabled) | `bool` | `true` | -| [`me_warmup_step_delay_ms`](#cfg-general-me_warmup_step_delay_ms) | `u64` | `500` | -| [`me_warmup_step_jitter_ms`](#cfg-general-me_warmup_step_jitter_ms) | `u64` | `300` | -| [`me_reconnect_max_concurrent_per_dc`](#cfg-general-me_reconnect_max_concurrent_per_dc) | `u32` | `8` | -| [`me_reconnect_backoff_base_ms`](#cfg-general-me_reconnect_backoff_base_ms) | `u64` | `500` | -| [`me_reconnect_backoff_cap_ms`](#cfg-general-me_reconnect_backoff_cap_ms) | `u64` | `30000` | -| [`me_reconnect_fast_retry_count`](#cfg-general-me_reconnect_fast_retry_count) | `u32` | `16` | -| [`me_single_endpoint_shadow_writers`](#cfg-general-me_single_endpoint_shadow_writers) | `u8` | `2` | -| [`me_single_endpoint_outage_mode_enabled`](#cfg-general-me_single_endpoint_outage_mode_enabled) | `bool` | `true` | -| [`me_single_endpoint_outage_disable_quarantine`](#cfg-general-me_single_endpoint_outage_disable_quarantine) | `bool` | `true` | -| [`me_single_endpoint_outage_backoff_min_ms`](#cfg-general-me_single_endpoint_outage_backoff_min_ms) | `u64` | `250` | -| [`me_single_endpoint_outage_backoff_max_ms`](#cfg-general-me_single_endpoint_outage_backoff_max_ms) | `u64` | `3000` | -| [`me_single_endpoint_shadow_rotate_every_secs`](#cfg-general-me_single_endpoint_shadow_rotate_every_secs) | `u64` | `900` | -| [`me_floor_mode`](#cfg-general-me_floor_mode) | `"static"` or `"adaptive"` | `"adaptive"` | -| [`me_adaptive_floor_idle_secs`](#cfg-general-me_adaptive_floor_idle_secs) | `u64` | `90` | -| [`me_adaptive_floor_min_writers_single_endpoint`](#cfg-general-me_adaptive_floor_min_writers_single_endpoint) | `u8` | `1` | -| [`me_adaptive_floor_min_writers_multi_endpoint`](#cfg-general-me_adaptive_floor_min_writers_multi_endpoint) | `u8` | `1` | -| [`me_adaptive_floor_recover_grace_secs`](#cfg-general-me_adaptive_floor_recover_grace_secs) | `u64` | `180` | -| [`me_adaptive_floor_writers_per_core_total`](#cfg-general-me_adaptive_floor_writers_per_core_total) | `u16` | `48` | -| [`me_adaptive_floor_cpu_cores_override`](#cfg-general-me_adaptive_floor_cpu_cores_override) | `u16` | `0` | -| [`me_adaptive_floor_max_extra_writers_single_per_core`](#cfg-general-me_adaptive_floor_max_extra_writers_single_per_core) | `u16` | `1` | -| [`me_adaptive_floor_max_extra_writers_multi_per_core`](#cfg-general-me_adaptive_floor_max_extra_writers_multi_per_core) | `u16` | `2` | -| [`me_adaptive_floor_max_active_writers_per_core`](#cfg-general-me_adaptive_floor_max_active_writers_per_core) | `u16` | `64` | -| [`me_adaptive_floor_max_warm_writers_per_core`](#cfg-general-me_adaptive_floor_max_warm_writers_per_core) | `u16` | `64` | -| [`me_adaptive_floor_max_active_writers_global`](#cfg-general-me_adaptive_floor_max_active_writers_global) | `u32` | `256` | -| [`me_adaptive_floor_max_warm_writers_global`](#cfg-general-me_adaptive_floor_max_warm_writers_global) | `u32` | `256` | -| [`upstream_connect_retry_attempts`](#cfg-general-upstream_connect_retry_attempts) | `u32` | `2` | -| [`upstream_connect_retry_backoff_ms`](#cfg-general-upstream_connect_retry_backoff_ms) | `u64` | `100` | -| [`upstream_connect_budget_ms`](#cfg-general-upstream_connect_budget_ms) | `u64` | `3000` | -| [`upstream_unhealthy_fail_threshold`](#cfg-general-upstream_unhealthy_fail_threshold) | `u32` | `5` | -| [`upstream_connect_failfast_hard_errors`](#cfg-general-upstream_connect_failfast_hard_errors) | `bool` | `false` | -| [`stun_iface_mismatch_ignore`](#cfg-general-stun_iface_mismatch_ignore) | `bool` | `false` | -| [`unknown_dc_log_path`](#cfg-general-unknown_dc_log_path) | `String` | `"unknown-dc.txt"` | -| [`unknown_dc_file_log_enabled`](#cfg-general-unknown_dc_file_log_enabled) | `bool` | `false` | -| [`log_level`](#cfg-general-log_level) | `"debug"`, `"verbose"`, `"normal"`, or `"silent"` | `"normal"` | -| [`disable_colors`](#cfg-general-disable_colors) | `bool` | `false` | -| [`me_socks_kdf_policy`](#cfg-general-me_socks_kdf_policy) | `"strict"` or `"compat"` | `"strict"` | -| [`me_route_backpressure_base_timeout_ms`](#cfg-general-me_route_backpressure_base_timeout_ms) | `u64` | `25` | -| [`me_route_backpressure_high_timeout_ms`](#cfg-general-me_route_backpressure_high_timeout_ms) | `u64` | `120` | -| [`me_route_backpressure_high_watermark_pct`](#cfg-general-me_route_backpressure_high_watermark_pct) | `u8` | `80` | -| [`me_health_interval_ms_unhealthy`](#cfg-general-me_health_interval_ms_unhealthy) | `u64` | `1000` | -| [`me_health_interval_ms_healthy`](#cfg-general-me_health_interval_ms_healthy) | `u64` | `3000` | -| [`me_admission_poll_ms`](#cfg-general-me_admission_poll_ms) | `u64` | `1000` | -| [`me_warn_rate_limit_ms`](#cfg-general-me_warn_rate_limit_ms) | `u64` | `5000` | -| [`me_route_no_writer_mode`](#cfg-general-me_route_no_writer_mode) | `"async_recovery_failfast"`, `"inline_recovery_legacy"`, or `"hybrid_async_persistent"` | `"hybrid_async_persistent"` | -| [`me_route_no_writer_wait_ms`](#cfg-general-me_route_no_writer_wait_ms) | `u64` | `250` | -| [`me_route_hybrid_max_wait_ms`](#cfg-general-me_route_hybrid_max_wait_ms) | `u64` | `3000` | -| [`me_route_blocking_send_timeout_ms`](#cfg-general-me_route_blocking_send_timeout_ms) | `u64` | `250` | -| [`me_route_inline_recovery_attempts`](#cfg-general-me_route_inline_recovery_attempts) | `u32` | `3` | -| [`me_route_inline_recovery_wait_ms`](#cfg-general-me_route_inline_recovery_wait_ms) | `u64` | `3000` | -| [`fast_mode_min_tls_record`](#cfg-general-fast_mode_min_tls_record) | `usize` | `0` | -| [`update_every`](#cfg-general-update_every) | `u64` | `300` | -| [`me_reinit_every_secs`](#cfg-general-me_reinit_every_secs) | `u64` | `900` | -| [`me_hardswap_warmup_delay_min_ms`](#cfg-general-me_hardswap_warmup_delay_min_ms) | `u64` | `1000` | -| [`me_hardswap_warmup_delay_max_ms`](#cfg-general-me_hardswap_warmup_delay_max_ms) | `u64` | `2000` | -| [`me_hardswap_warmup_extra_passes`](#cfg-general-me_hardswap_warmup_extra_passes) | `u8` | `3` | -| [`me_hardswap_warmup_pass_backoff_base_ms`](#cfg-general-me_hardswap_warmup_pass_backoff_base_ms) | `u64` | `500` | -| [`me_config_stable_snapshots`](#cfg-general-me_config_stable_snapshots) | `u8` | `2` | -| [`me_config_apply_cooldown_secs`](#cfg-general-me_config_apply_cooldown_secs) | `u64` | `300` | -| [`me_snapshot_require_http_2xx`](#cfg-general-me_snapshot_require_http_2xx) | `bool` | `true` | -| [`me_snapshot_reject_empty_map`](#cfg-general-me_snapshot_reject_empty_map) | `bool` | `true` | -| [`me_snapshot_min_proxy_for_lines`](#cfg-general-me_snapshot_min_proxy_for_lines) | `u32` | `1` | -| [`proxy_secret_stable_snapshots`](#cfg-general-proxy_secret_stable_snapshots) | `u8` | `2` | -| [`proxy_secret_rotate_runtime`](#cfg-general-proxy_secret_rotate_runtime) | `bool` | `true` | -| [`me_secret_atomic_snapshot`](#cfg-general-me_secret_atomic_snapshot) | `bool` | `true` | -| [`proxy_secret_len_max`](#cfg-general-proxy_secret_len_max) | `usize` | `256` | -| [`me_pool_drain_ttl_secs`](#cfg-general-me_pool_drain_ttl_secs) | `u64` | `90` | -| [`me_instadrain`](#cfg-general-me_instadrain) | `bool` | `false` | -| [`me_pool_drain_threshold`](#cfg-general-me_pool_drain_threshold) | `u64` | `32` | -| [`me_pool_drain_soft_evict_enabled`](#cfg-general-me_pool_drain_soft_evict_enabled) | `bool` | `true` | -| [`me_pool_drain_soft_evict_grace_secs`](#cfg-general-me_pool_drain_soft_evict_grace_secs) | `u64` | `10` | -| [`me_pool_drain_soft_evict_per_writer`](#cfg-general-me_pool_drain_soft_evict_per_writer) | `u8` | `2` | -| [`me_pool_drain_soft_evict_budget_per_core`](#cfg-general-me_pool_drain_soft_evict_budget_per_core) | `u16` | `16` | -| [`me_pool_drain_soft_evict_cooldown_ms`](#cfg-general-me_pool_drain_soft_evict_cooldown_ms) | `u64` | `1000` | -| [`me_bind_stale_mode`](#cfg-general-me_bind_stale_mode) | `"never"`, `"ttl"`, or `"always"` | `"ttl"` | -| [`me_bind_stale_ttl_secs`](#cfg-general-me_bind_stale_ttl_secs) | `u64` | `90` | -| [`me_pool_min_fresh_ratio`](#cfg-general-me_pool_min_fresh_ratio) | `f32` | `0.8` | -| [`me_reinit_drain_timeout_secs`](#cfg-general-me_reinit_drain_timeout_secs) | `u64` | `90` | -| [`proxy_secret_auto_reload_secs`](#cfg-general-proxy_secret_auto_reload_secs) | `u64` | `3600` | -| [`proxy_config_auto_reload_secs`](#cfg-general-proxy_config_auto_reload_secs) | `u64` | `3600` | -| [`me_reinit_singleflight`](#cfg-general-me_reinit_singleflight) | `bool` | `true` | -| [`me_reinit_trigger_channel`](#cfg-general-me_reinit_trigger_channel) | `usize` | `64` | -| [`me_reinit_coalesce_window_ms`](#cfg-general-me_reinit_coalesce_window_ms) | `u64` | `200` | -| [`me_deterministic_writer_sort`](#cfg-general-me_deterministic_writer_sort) | `bool` | `true` | -| [`me_writer_pick_mode`](#cfg-general-me_writer_pick_mode) | `"sorted_rr"` or `"p2c"` | `"p2c"` | -| [`me_writer_pick_sample_size`](#cfg-general-me_writer_pick_sample_size) | `u8` | `3` | -| [`ntp_check`](#cfg-general-ntp_check) | `bool` | `true` | -| [`ntp_servers`](#cfg-general-ntp_servers) | `String[]` | `["pool.ntp.org"]` | -| [`auto_degradation_enabled`](#cfg-general-auto_degradation_enabled) | `bool` | `true` | -| [`degradation_min_unavailable_dc_groups`](#cfg-general-degradation_min_unavailable_dc_groups) | `u8` | `2` | - - -- `data_path` - - **Constraints / validation**: `String` (optional). - - **Description**: Optional runtime data directory path. - - **Example**: - - ```toml - [general] - data_path = "/var/lib/telemt" - ``` - -- `prefer_ipv6` - - **Constraints / validation**: Deprecated. Use `network.prefer`. - - **Description**: Deprecated legacy IPv6 preference flag migrated to `network.prefer`. - - **Example**: - - ```toml - [network] - prefer = 6 - ``` - -- `fast_mode` - - **Constraints / validation**: `bool`. - - **Description**: Enables fast-path optimizations for traffic processing. - - **Example**: - - ```toml - [general] - fast_mode = true - ``` - -- `use_middle_proxy` - - **Constraints / validation**: `bool`. - - **Description**: Enables ME transport mode; if `false`, runtime falls back to direct DC routing. - - **Example**: - - ```toml - [general] - use_middle_proxy = true - ``` - -- `proxy_secret_path` - - **Constraints / validation**: `String`. When omitted, the default path is `"proxy-secret"`. Empty values are accepted by TOML/serde but will likely fail at runtime (invalid file path). - - **Description**: Path to Telegram infrastructure `proxy-secret` cache file used by ME handshake/RPC auth. Telemt always tries a fresh download from `https://core.telegram.org/getProxySecret` first, caches it to this path on success, and falls back to reading the cached file (any age) on download failure. - - **Example**: - - ```toml - [general] - proxy_secret_path = "proxy-secret" - ``` - -- `proxy_config_v4_cache_path` - - **Constraints / validation**: `String`. When set, must not be empty/whitespace-only. - - **Description**: Optional disk cache path for raw `getProxyConfig` (IPv4) snapshot. At startup Telemt tries to fetch a fresh snapshot first; on fetch failure or empty snapshot it falls back to this cache file when present and non-empty. - - **Example**: - - ```toml - [general] - proxy_config_v4_cache_path = "cache/proxy-config-v4.txt" - ``` - -- `proxy_config_v6_cache_path` - - **Constraints / validation**: `String`. When set, must not be empty/whitespace-only. - - **Description**: Optional disk cache path for raw `getProxyConfigV6` (IPv6) snapshot. At startup Telemt tries to fetch a fresh snapshot first; on fetch failure or empty snapshot it falls back to this cache file when present and non-empty. - - **Example**: - - ```toml - [general] - proxy_config_v6_cache_path = "cache/proxy-config-v6.txt" - ``` - -- `ad_tag` - - **Constraints / validation**: `String` (optional). When set, must be exactly 32 hex characters; invalid values are disabled during config load. - - **Description**: Global fallback sponsored-channel `ad_tag` (used when user has no override in `access.user_ad_tags`). An all-zero tag is accepted but has no effect (and is warned about) until replaced with a real tag from `@MTProxybot`. - - **Example**: - - ```toml - [general] - ad_tag = "00112233445566778899aabbccddeeff" - ``` - -- `middle_proxy_nat_ip` - - **Constraints / validation**: `IpAddr` (optional). - - **Description**: Manual public NAT IP override used as ME address material when set. - - **Example**: - - ```toml - [general] - middle_proxy_nat_ip = "203.0.113.10" - ``` - -- `middle_proxy_nat_probe` - - **Constraints / validation**: `bool`. Effective probing is gated by `network.stun_use` (when `network.stun_use = false`, STUN probing is disabled even if this flag is `true`). - - **Description**: Enables STUN-based NAT probing to discover public IP:port used by ME key derivation in NAT environments. - - **Example**: - - ```toml - [general] - middle_proxy_nat_probe = true - ``` - -- `middle_proxy_nat_stun` - - **Constraints / validation**: Deprecated. Use `network.stun_servers`. - - **Description**: Deprecated legacy single STUN server for NAT probing. During config load it is merged into `network.stun_servers` unless `network.stun_servers` is explicitly set. - - **Example**: - - ```toml - [network] - stun_servers = ["stun.l.google.com:19302"] - ``` - -- `middle_proxy_nat_stun_servers` - - **Constraints / validation**: Deprecated. Use `network.stun_servers`. - - **Description**: Deprecated legacy STUN list for NAT probing fallback. During config load it is merged into `network.stun_servers` unless `network.stun_servers` is explicitly set. - - **Example**: - - ```toml - [network] - stun_servers = ["stun.l.google.com:19302"] - ``` - -- `stun_nat_probe_concurrency` - - **Constraints / validation**: Must be `> 0`. - - **Description**: Maximum number of parallel STUN probes during NAT/public endpoint discovery. - - **Example**: - - ```toml - [general] - stun_nat_probe_concurrency = 8 - ``` - -- `middle_proxy_pool_size` - - **Constraints / validation**: `usize`. Effective value is `max(value, 1)` at runtime (so `0` behaves as `1`). - - **Description**: Target size of active ME writer pool. - - **Example**: - - ```toml - [general] - middle_proxy_pool_size = 8 - ``` - -- `middle_proxy_warm_standby` - - **Constraints / validation**: `usize`. - - **Description**: Number of warm standby ME connections kept pre-initialized. - - **Example**: - - ```toml - [general] - middle_proxy_warm_standby = 16 - ``` - -- `me_init_retry_attempts` - - **Constraints / validation**: `0..=1_000_000` (`0` means unlimited retries). - - **Description**: Startup retries for ME pool initialization. - - **Example**: - - ```toml - [general] - me_init_retry_attempts = 0 - ``` - -- `me2dc_fallback` - - **Constraints / validation**: `bool`. - - **Description**: Allows fallback from ME mode to direct DC when ME startup fails. - - **Example**: - - ```toml - [general] - me2dc_fallback = true - ``` - -- `me2dc_fast` - - **Constraints / validation**: `bool`. Active only when `use_middle_proxy = true` and `me2dc_fallback = true`. - - **Description**: Fast ME->Direct fallback mode for new sessions. - - **Example**: - - ```toml - [general] - use_middle_proxy = true - me2dc_fallback = true - me2dc_fast = false - ``` - -- `me_keepalive_enabled` - - **Constraints / validation**: `bool`. - - **Description**: Enables periodic ME keepalive padding frames. - - **Example**: - - ```toml - [general] - me_keepalive_enabled = true - ``` - -- `me_keepalive_interval_secs` - - **Constraints / validation**: `u64` (seconds). - - **Description**: Base ME keepalive interval in seconds. - - **Example**: - - ```toml - [general] - me_keepalive_interval_secs = 8 - ``` - -- `me_keepalive_jitter_secs` - - **Constraints / validation**: `u64` (seconds). - - **Description**: Keepalive jitter in seconds to reduce synchronized bursts. - - **Example**: - - ```toml - [general] - me_keepalive_jitter_secs = 2 - ``` - -- `me_keepalive_payload_random` - - **Constraints / validation**: `bool`. - - **Description**: Randomizes keepalive payload bytes instead of fixed zero payload. - - **Example**: - - ```toml - [general] - me_keepalive_payload_random = true - ``` - -- `rpc_proxy_req_every` - - **Constraints / validation**: `0` or within `10..=300` (seconds). - - **Description**: Interval for service `RPC_PROXY_REQ` activity signals to ME (`0` disables). - - **Example**: - - ```toml - [general] - rpc_proxy_req_every = 0 - ``` - -- `me_writer_cmd_channel_capacity` - - **Constraints / validation**: Must be `> 0`. - - **Description**: Capacity of per-writer command channel. - - **Example**: - - ```toml - [general] - me_writer_cmd_channel_capacity = 4096 - ``` - -- `me_route_channel_capacity` - - **Constraints / validation**: Must be `> 0`. - - **Description**: Capacity of per-connection ME response route channel. - - **Example**: - - ```toml - [general] - me_route_channel_capacity = 768 - ``` - -- `me_c2me_channel_capacity` - - **Constraints / validation**: Must be `> 0`. - - **Description**: Capacity of per-client command queue (client reader -> ME sender). - - **Example**: - - ```toml - [general] - me_c2me_channel_capacity = 1024 - ``` - -- `me_c2me_send_timeout_ms` - - **Constraints / validation**: `0..=60000` (milliseconds). - - **Description**: Maximum wait for enqueueing client->ME commands when the per-client queue is full (`0` keeps legacy unbounded wait). - - **Example**: - - ```toml - [general] - me_c2me_send_timeout_ms = 4000 - ``` - -- `me_reader_route_data_wait_ms` - - **Constraints / validation**: `0..=20` (milliseconds). - - **Description**: Bounded wait for routing ME DATA to per-connection queue (`0` = no wait). - - **Example**: - - ```toml - [general] - me_reader_route_data_wait_ms = 2 - ``` - -- `me_d2c_flush_batch_max_frames` - - **Constraints / validation**: Must be within `1..=512`. - - **Description**: Max ME->client frames coalesced before flush. - - **Example**: - - ```toml - [general] - me_d2c_flush_batch_max_frames = 32 - ``` - -- `me_d2c_flush_batch_max_bytes` - - **Constraints / validation**: Must be within `4096..=2097152` (bytes). - - **Description**: Max ME->client payload bytes coalesced before flush. - - **Example**: - - ```toml - [general] - me_d2c_flush_batch_max_bytes = 131072 - ``` - -- `me_d2c_flush_batch_max_delay_us` - - **Constraints / validation**: `0..=5000` (microseconds). - - **Description**: Max microsecond wait for coalescing more ME->client frames (`0` disables timed coalescing). - - **Example**: - - ```toml - [general] - me_d2c_flush_batch_max_delay_us = 500 - ``` - -- `me_d2c_ack_flush_immediate` - - **Constraints / validation**: `bool`. - - **Description**: Flushes client writer immediately after quick-ack write. - - **Example**: - - ```toml - [general] - me_d2c_ack_flush_immediate = true - ``` - -- `me_quota_soft_overshoot_bytes` - - **Constraints / validation**: `0..=16777216` (bytes). - - **Description**: Extra per-route quota allowance (bytes) tolerated before writer-side quota enforcement drops route data. - - **Example**: - - ```toml - [general] - me_quota_soft_overshoot_bytes = 65536 - ``` - -- `me_d2c_frame_buf_shrink_threshold_bytes` - - **Constraints / validation**: Must be within `4096..=16777216` (bytes). - - **Description**: Threshold for shrinking oversized ME->client frame-aggregation buffers after flush. - - **Example**: - - ```toml - [general] - me_d2c_frame_buf_shrink_threshold_bytes = 262144 - ``` - -- `direct_relay_copy_buf_c2s_bytes` - - **Constraints / validation**: Must be within `4096..=1048576` (bytes). - - **Description**: Copy buffer size for client->DC direction in direct relay. - - **Example**: - - ```toml - [general] - direct_relay_copy_buf_c2s_bytes = 65536 - ``` - -- `direct_relay_copy_buf_s2c_bytes` - - **Constraints / validation**: Must be within `8192..=2097152` (bytes). - - **Description**: Copy buffer size for DC->client direction in direct relay. - - **Example**: - - ```toml - [general] - direct_relay_copy_buf_s2c_bytes = 262144 - ``` - -- `crypto_pending_buffer` - - **Constraints / validation**: `usize` (bytes). - - **Description**: Max pending ciphertext buffer per client writer (bytes). - - **Example**: - - ```toml - [general] - crypto_pending_buffer = 262144 - ``` - -- `max_client_frame` - - **Constraints / validation**: `usize` (bytes). - - **Description**: Maximum allowed client MTProto frame size (bytes). - - **Example**: - - ```toml - [general] - max_client_frame = 16777216 - ``` - -- `desync_all_full` - - **Constraints / validation**: `bool`. - - **Description**: Emits full crypto-desync forensic logs for every event. - - **Example**: - - ```toml - [general] - desync_all_full = false - ``` - -- `beobachten` - - **Constraints / validation**: `bool`. - - **Description**: Enables per-IP forensic observation buckets. - - **Example**: - - ```toml - [general] - beobachten = true - ``` - -- `beobachten_minutes` - - **Constraints / validation**: Must be `> 0` (minutes). - - **Description**: Retention window (minutes) for per-IP observation buckets. - - **Example**: - - ```toml - [general] - beobachten_minutes = 10 - ``` - -- `beobachten_flush_secs` - - **Constraints / validation**: Must be `> 0` (seconds). - - **Description**: Snapshot flush interval (seconds) for observation output file. - - **Example**: - - ```toml - [general] - beobachten_flush_secs = 15 - ``` - -- `beobachten_file` - - **Constraints / validation**: Must not be empty/whitespace-only. - - **Description**: Observation snapshot output file path. - - **Example**: - - ```toml - [general] - beobachten_file = "cache/beobachten.txt" - ``` - -- `hardswap` - - **Constraints / validation**: `bool`. - - **Description**: Enables generation-based ME hardswap strategy. - - **Example**: - - ```toml - [general] - hardswap = true - ``` - -- `me_warmup_stagger_enabled` - - **Constraints / validation**: `bool`. - - **Description**: Staggers extra ME warmup dials to avoid connection spikes. - - **Example**: - - ```toml - [general] - me_warmup_stagger_enabled = true - ``` - -- `me_warmup_step_delay_ms` - - **Constraints / validation**: `u64` (milliseconds). - - **Description**: Base delay in milliseconds between warmup dial steps. - - **Example**: - - ```toml - [general] - me_warmup_step_delay_ms = 500 - ``` - -- `me_warmup_step_jitter_ms` - - **Constraints / validation**: `u64` (milliseconds). - - **Description**: Additional random delay in milliseconds for warmup steps. - - **Example**: - - ```toml - [general] - me_warmup_step_jitter_ms = 300 - ``` - -- `me_reconnect_max_concurrent_per_dc` - - **Constraints / validation**: `u32`. Effective value is `max(value, 1)` at runtime (so `0` behaves as `1`). - - **Description**: Limits concurrent reconnect workers per DC during health recovery. - - **Example**: - - ```toml - [general] - me_reconnect_max_concurrent_per_dc = 8 - ``` - -- `me_reconnect_backoff_base_ms` - - **Constraints / validation**: `u64` (milliseconds). - - **Description**: Initial reconnect backoff in milliseconds. - - **Example**: - - ```toml - [general] - me_reconnect_backoff_base_ms = 500 - ``` - -- `me_reconnect_backoff_cap_ms` - - **Constraints / validation**: `u64` (milliseconds). - - **Description**: Maximum reconnect backoff cap in milliseconds. - - **Example**: - - ```toml - [general] - me_reconnect_backoff_cap_ms = 30000 - ``` - -- `me_reconnect_fast_retry_count` - - **Constraints / validation**: `u32`. Effective value is `max(value, 1)` at runtime (so `0` behaves as `1`). - - **Description**: Immediate retry budget before long backoff behavior applies. - - **Example**: - - ```toml - [general] - me_reconnect_fast_retry_count = 16 - ``` - -- `me_single_endpoint_shadow_writers` - - **Constraints / validation**: Must be within `0..=32`. - - **Description**: Additional reserve writers for DC groups with exactly one endpoint. - - **Example**: - - ```toml - [general] - me_single_endpoint_shadow_writers = 2 - ``` - -- `me_single_endpoint_outage_mode_enabled` - - **Constraints / validation**: `bool`. - - **Description**: Enables aggressive outage recovery mode for DC groups with exactly one endpoint. - - **Example**: - - ```toml - [general] - me_single_endpoint_outage_mode_enabled = true - ``` - -- `me_single_endpoint_outage_disable_quarantine` - - **Constraints / validation**: `bool`. - - **Description**: Allows single-endpoint outage recovery reconnect paths to bypass endpoint quarantine. - - **Example**: - - ```toml - [general] - me_single_endpoint_outage_disable_quarantine = true - ``` - -- `me_single_endpoint_outage_backoff_min_ms` - - **Constraints / validation**: Must be `> 0` (milliseconds) and `<= me_single_endpoint_outage_backoff_max_ms`. - - **Description**: Minimum reconnect backoff in single-endpoint outage mode. - - **Example**: - - ```toml - [general] - me_single_endpoint_outage_backoff_min_ms = 250 - ``` - -- `me_single_endpoint_outage_backoff_max_ms` - - **Constraints / validation**: Must be `> 0` (milliseconds) and `>= me_single_endpoint_outage_backoff_min_ms`. - - **Description**: Maximum reconnect backoff in single-endpoint outage mode. - - **Example**: - - ```toml - [general] - me_single_endpoint_outage_backoff_max_ms = 3000 - ``` - -- `me_single_endpoint_shadow_rotate_every_secs` - - **Constraints / validation**: `u64` (seconds). `0` disables periodic shadow rotation. - - **Description**: Periodic shadow writer rotation interval for single-endpoint DC groups. - - **Example**: - - ```toml - [general] - me_single_endpoint_shadow_rotate_every_secs = 900 - ``` - -- `me_floor_mode` - - **Constraints / validation**: `"static"` or `"adaptive"`. - - **Description**: Floor policy mode for ME writer targets. - - **Example**: - - ```toml - [general] - me_floor_mode = "adaptive" - ``` - -- `me_adaptive_floor_idle_secs` - - **Constraints / validation**: `u64` (seconds). - - **Description**: Reserved adaptive-floor timing knob exposed in runtime config and API snapshots for compatibility. - - **Example**: - - ```toml - [general] - me_adaptive_floor_idle_secs = 90 - ``` - -- `me_adaptive_floor_min_writers_single_endpoint` - - **Constraints / validation**: Must be within `1..=32`. - - **Description**: Minimum writer target for single-endpoint DC groups in adaptive floor mode. - - **Example**: - - ```toml - [general] - me_adaptive_floor_min_writers_single_endpoint = 1 - ``` - -- `me_adaptive_floor_min_writers_multi_endpoint` - - **Constraints / validation**: Must be within `1..=32`. - - **Description**: Minimum writer target for multi-endpoint DC groups in adaptive floor mode. - - **Example**: - - ```toml - [general] - me_adaptive_floor_min_writers_multi_endpoint = 1 - ``` - -- `me_adaptive_floor_recover_grace_secs` - - **Constraints / validation**: `u64` (seconds). - - **Description**: Reserved adaptive-floor grace knob exposed in runtime config and API snapshots for compatibility. - - **Example**: - - ```toml - [general] - me_adaptive_floor_recover_grace_secs = 180 - ``` - -- `me_adaptive_floor_writers_per_core_total` - - **Constraints / validation**: Must be `> 0`. - - **Description**: Global ME writer budget per logical CPU core in adaptive mode. - - **Example**: - - ```toml - [general] - me_adaptive_floor_writers_per_core_total = 48 - ``` - -- `me_adaptive_floor_cpu_cores_override` - - **Constraints / validation**: `u16`. `0` uses runtime auto-detection. - - **Description**: Override logical CPU core count used for adaptive floor calculations. - - **Example**: - - ```toml - [general] - me_adaptive_floor_cpu_cores_override = 0 - ``` - -- `me_adaptive_floor_max_extra_writers_single_per_core` - - **Constraints / validation**: `u16`. - - **Description**: Per-core max extra writers above base required floor for single-endpoint DC groups. - - **Example**: - - ```toml - [general] - me_adaptive_floor_max_extra_writers_single_per_core = 1 - ``` - -- `me_adaptive_floor_max_extra_writers_multi_per_core` - - **Constraints / validation**: `u16`. - - **Description**: Per-core max extra writers above base required floor for multi-endpoint DC groups. - - **Example**: - - ```toml - [general] - me_adaptive_floor_max_extra_writers_multi_per_core = 2 - ``` - -- `me_adaptive_floor_max_active_writers_per_core` - - **Constraints / validation**: Must be `> 0`. - - **Description**: Hard cap for active ME writers per logical CPU core. - - **Example**: - - ```toml - [general] - me_adaptive_floor_max_active_writers_per_core = 64 - ``` - -- `me_adaptive_floor_max_warm_writers_per_core` - - **Constraints / validation**: Must be `> 0`. - - **Description**: Hard cap for warm ME writers per logical CPU core. - - **Example**: - - ```toml - [general] - me_adaptive_floor_max_warm_writers_per_core = 64 - ``` - -- `me_adaptive_floor_max_active_writers_global` - - **Constraints / validation**: Must be `> 0`. - - **Description**: Hard global cap for active ME writers. - - **Example**: - - ```toml - [general] - me_adaptive_floor_max_active_writers_global = 256 - ``` - -- `me_adaptive_floor_max_warm_writers_global` - - **Constraints / validation**: Must be `> 0`. - - **Description**: Hard global cap for warm ME writers. - - **Example**: - - ```toml - [general] - me_adaptive_floor_max_warm_writers_global = 256 - ``` - -- `upstream_connect_retry_attempts` - - **Constraints / validation**: Must be `> 0`. - - **Description**: Connect attempts for the selected upstream before returning error/fallback. - - **Example**: - - ```toml - [general] - upstream_connect_retry_attempts = 2 - ``` - -- `upstream_connect_retry_backoff_ms` - - **Constraints / validation**: `u64` (milliseconds). `0` disables backoff delay (retries become immediate). - - **Description**: Delay in milliseconds between upstream connect attempts. - - **Example**: - - ```toml - [general] - upstream_connect_retry_backoff_ms = 100 - ``` - -- `upstream_connect_budget_ms` - - **Constraints / validation**: Must be `> 0` (milliseconds). - - **Description**: Total wall-clock budget in milliseconds for one upstream connect request across retries. - - **Example**: - - ```toml - [general] - upstream_connect_budget_ms = 3000 - ``` - -- `upstream_unhealthy_fail_threshold` - - **Constraints / validation**: Must be `> 0`. - - **Description**: Consecutive failed requests before upstream is marked unhealthy. - - **Example**: - - ```toml - [general] - upstream_unhealthy_fail_threshold = 5 - ``` - -- `upstream_connect_failfast_hard_errors` - - **Constraints / validation**: `bool`. - - **Description**: When true, skips additional retries for hard non-transient upstream connect errors. - - **Example**: - - ```toml - [general] - upstream_connect_failfast_hard_errors = false - ``` - -- `stun_iface_mismatch_ignore` - - **Constraints / validation**: `bool`. - - **Description**: Compatibility flag reserved for future use. Currently this key is parsed but not used by the runtime. - - **Example**: - - ```toml - [general] - stun_iface_mismatch_ignore = false - ``` - -- `unknown_dc_log_path` - - **Constraints / validation**: `String` (optional). Must be a safe path (no `..` components, parent directory must exist); unsafe paths are rejected at runtime. - - **Description**: Log file path for unknown (non-standard) DC requests when `unknown_dc_file_log_enabled = true`. Omit this key to disable file logging. - - **Example**: - - ```toml - [general] - unknown_dc_log_path = "unknown-dc.txt" - ``` - -- `unknown_dc_file_log_enabled` - - **Constraints / validation**: `bool`. - - **Description**: Enables unknown-DC file logging (writes `dc_idx=` lines). Requires `unknown_dc_log_path` to be set and, on non-Unix platforms, may be unsupported. Logging is deduplicated and capped (only the first ~1024 distinct unknown DC indices are recorded). - - **Example**: - - ```toml - [general] - unknown_dc_file_log_enabled = false - ``` - -- `log_level` - - **Constraints / validation**: `"debug"`, `"verbose"`, `"normal"`, or `"silent"`. - - **Description**: Runtime logging verbosity level (used when `RUST_LOG` is not set). If `RUST_LOG` is set in the environment, it takes precedence over this setting. - - **Example**: - - ```toml - [general] - log_level = "normal" - ``` - -- `disable_colors` - - **Constraints / validation**: `bool`. - - **Description**: Disables ANSI colors in logs (useful for files/systemd). This affects log formatting only and does not change the log level/filtering. - - **Example**: - - ```toml - [general] - disable_colors = false - ``` - -- `me_socks_kdf_policy` - - **Constraints / validation**: `"strict"` or `"compat"`. - - **Description**: SOCKS-bound KDF fallback policy for Middle-End handshake. - - **Example**: - - ```toml - [general] - me_socks_kdf_policy = "strict" - ``` - -- `me_route_backpressure_base_timeout_ms` - - **Constraints / validation**: Must be within `1..=5000` (milliseconds). - - **Description**: Base backpressure timeout in milliseconds for ME route-channel send. - - **Example**: - - ```toml - [general] - me_route_backpressure_base_timeout_ms = 25 - ``` - -- `me_route_backpressure_high_timeout_ms` - - **Constraints / validation**: Must be within `1..=5000` (milliseconds) and `>= me_route_backpressure_base_timeout_ms`. - - **Description**: High backpressure timeout in milliseconds when queue occupancy is above watermark. - - **Example**: - - ```toml - [general] - me_route_backpressure_high_timeout_ms = 120 - ``` - -- `me_route_backpressure_high_watermark_pct` - - **Constraints / validation**: Must be within `1..=100` (percent). - - **Description**: Queue occupancy percent threshold for switching to high backpressure timeout. - - **Example**: - - ```toml - [general] - me_route_backpressure_high_watermark_pct = 80 - ``` - -- `me_health_interval_ms_unhealthy` - - **Constraints / validation**: Must be `> 0` (milliseconds). - - **Description**: Health monitor interval while ME writer coverage is degraded. - - **Example**: - - ```toml - [general] - me_health_interval_ms_unhealthy = 1000 - ``` - -- `me_health_interval_ms_healthy` - - **Constraints / validation**: Must be `> 0` (milliseconds). - - **Description**: Health monitor interval while ME writer coverage is stable/healthy. - - **Example**: - - ```toml - [general] - me_health_interval_ms_healthy = 3000 - ``` - -- `me_admission_poll_ms` - - **Constraints / validation**: Must be `> 0` (milliseconds). - - **Description**: Poll interval for conditional-admission state checks. - - **Example**: - - ```toml - [general] - me_admission_poll_ms = 1000 - ``` - -- `me_warn_rate_limit_ms` - - **Constraints / validation**: Must be `> 0` (milliseconds). - - **Description**: Cooldown for repetitive ME warning logs. - - **Example**: - - ```toml - [general] - me_warn_rate_limit_ms = 5000 - ``` - -- `me_route_no_writer_mode` - - **Constraints / validation**: `"async_recovery_failfast"`, `"inline_recovery_legacy"`, or `"hybrid_async_persistent"`. - - **Description**: ME route behavior when no writer is immediately available. - - **Example**: - - ```toml - [general] - me_route_no_writer_mode = "hybrid_async_persistent" - ``` - -- `me_route_no_writer_wait_ms` - - **Constraints / validation**: Must be within `10..=5000` (milliseconds). - - **Description**: Max wait time used by async-recovery failfast mode before falling back. - - **Example**: - - ```toml - [general] - me_route_no_writer_wait_ms = 250 - ``` - -- `me_route_hybrid_max_wait_ms` - - **Constraints / validation**: Must be within `50..=60000` (milliseconds). - - **Description**: Maximum cumulative wait in hybrid no-writer mode before failfast fallback. - - **Example**: - - ```toml - [general] - me_route_hybrid_max_wait_ms = 3000 - ``` - -- `me_route_blocking_send_timeout_ms` - - **Constraints / validation**: Must be within `0..=5000` (milliseconds). `0` keeps legacy unbounded wait behavior. - - **Description**: Maximum wait for blocking route-channel send fallback. - - **Example**: - - ```toml - [general] - me_route_blocking_send_timeout_ms = 250 - ``` - -- `me_route_inline_recovery_attempts` - - **Constraints / validation**: Must be `> 0`. - - **Description**: Number of inline recovery attempts in legacy mode. - - **Example**: - - ```toml - [general] - me_route_inline_recovery_attempts = 3 - ``` - -- `me_route_inline_recovery_wait_ms` - - **Constraints / validation**: Must be within `10..=30000` (milliseconds). - - **Description**: Max inline recovery wait in legacy mode. - - **Example**: - - ```toml - [general] - me_route_inline_recovery_wait_ms = 3000 - ``` - -- `fast_mode_min_tls_record` - - **Constraints / validation**: `usize` (bytes). `0` disables the limit. - - **Description**: Minimum TLS record size when fast-mode coalescing is enabled. - - **Example**: - - ```toml - [general] - fast_mode_min_tls_record = 0 - ``` - -- `update_every` - - **Constraints / validation**: `u64` (seconds). If set, must be `> 0`. If this key is not explicitly set, legacy `proxy_secret_auto_reload_secs` and `proxy_config_auto_reload_secs` may be used (their effective minimum must be `> 0`). - - **Description**: Unified refresh interval for ME updater tasks (`getProxyConfig`, `getProxyConfigV6`, `getProxySecret`). When set, it overrides legacy proxy reload intervals. - - **Example**: - - ```toml - [general] - update_every = 300 - ``` - -- `me_reinit_every_secs` - - **Constraints / validation**: Must be `> 0` (seconds). - - **Description**: Periodic interval for zero-downtime ME reinit cycle. - - **Example**: - - ```toml - [general] - me_reinit_every_secs = 900 - ``` - -- `me_hardswap_warmup_delay_min_ms` - - **Constraints / validation**: `u64` (milliseconds). Must be `<= me_hardswap_warmup_delay_max_ms`. - - **Description**: Lower bound for hardswap warmup dial spacing. - - **Example**: - - ```toml - [general] - me_hardswap_warmup_delay_min_ms = 1000 - ``` - -- `me_hardswap_warmup_delay_max_ms` - - **Constraints / validation**: Must be `> 0` (milliseconds). - - **Description**: Upper bound for hardswap warmup dial spacing. - - **Example**: - - ```toml - [general] - me_hardswap_warmup_delay_max_ms = 2000 - ``` - -- `me_hardswap_warmup_extra_passes` - - **Constraints / validation**: Must be within `[0, 10]`. - - **Description**: Additional warmup passes after the base pass in one hardswap cycle. - - **Example**: - - ```toml - [general] - # default: 3 (allowed range: 0..=10) - me_hardswap_warmup_extra_passes = 3 - ``` - -- `me_hardswap_warmup_pass_backoff_base_ms` - - **Constraints / validation**: `u64` (milliseconds). Must be `> 0`. - - **Description**: Base backoff between extra hardswap warmup passes when the floor is still incomplete. - - **Example**: - - ```toml - [general] - # default: 500 - me_hardswap_warmup_pass_backoff_base_ms = 500 - ``` - -- `me_config_stable_snapshots` - - **Constraints / validation**: Must be `> 0`. - - **Description**: Number of identical ME config snapshots required before apply. - - **Example**: - - ```toml - [general] - # require 3 identical snapshots before applying ME endpoint map updates - me_config_stable_snapshots = 3 - ``` - -- `me_config_apply_cooldown_secs` - - **Constraints / validation**: `u64`. - - **Description**: Cooldown between applied ME endpoint-map updates. `0` disables the cooldown. - - **Example**: - - ```toml - [general] - # allow applying stable snapshots immediately (no cooldown) - me_config_apply_cooldown_secs = 0 - ``` - -- `me_snapshot_require_http_2xx` - - **Constraints / validation**: `bool`. - - **Description**: Requires 2xx HTTP responses for applying ME config snapshots. When `false`, non-2xx responses may still be parsed/considered by the updater. - - **Example**: - - ```toml - [general] - # allow applying snapshots even when the HTTP status is non-2xx - me_snapshot_require_http_2xx = false - ``` - -- `me_snapshot_reject_empty_map` - - **Constraints / validation**: `bool`. - - **Description**: Rejects empty ME config snapshots (no endpoints). When `false`, an empty snapshot can be applied (subject to other gates), which may temporarily reduce/clear the ME map. - - **Example**: - - ```toml - [general] - # allow applying empty snapshots (use with care) - me_snapshot_reject_empty_map = false - ``` - -- `me_snapshot_min_proxy_for_lines` - - **Constraints / validation**: Must be `> 0`. - - **Description**: Minimum parsed `proxy_for` rows required to accept snapshot. - - **Example**: - - ```toml - [general] - # require at least 10 proxy_for rows before accepting a snapshot - me_snapshot_min_proxy_for_lines = 10 - ``` - -- `proxy_secret_stable_snapshots` - - **Constraints / validation**: Must be `> 0`. - - **Description**: Number of identical proxy-secret snapshots required before rotation. - - **Example**: - - ```toml - [general] - # require 2 identical getProxySecret snapshots before rotating at runtime - proxy_secret_stable_snapshots = 2 - ``` - -- `proxy_secret_rotate_runtime` - - **Constraints / validation**: `bool`. - - **Description**: Enables runtime proxy-secret rotation from updater snapshots. - - **Example**: - - ```toml - [general] - # disable runtime proxy-secret rotation (startup still uses proxy_secret_path/proxy_secret_len_max) - proxy_secret_rotate_runtime = false - ``` - -- `me_secret_atomic_snapshot` - - **Constraints / validation**: `bool`. - - **Description**: Keeps selector and secret bytes from the same snapshot atomically. When `general.use_middle_proxy = true`, this is auto-enabled during config load to keep ME KDF material coherent. - - **Example**: - - ```toml - [general] - # NOTE: when use_middle_proxy=true, Telemt will auto-enable this during load - me_secret_atomic_snapshot = false - ``` - -- `proxy_secret_len_max` - - **Constraints / validation**: Must be within `[32, 4096]`. - - **Description**: Upper length limit (bytes) for accepted proxy-secret during startup and runtime refresh. - - **Example**: - - ```toml - [general] - # default: 256 (bytes) - proxy_secret_len_max = 256 - ``` - -- `me_pool_drain_ttl_secs` - - **Constraints / validation**: `u64` (seconds). `0` disables the drain-TTL window (and suppresses drain-TTL warnings for non-empty draining writers). - - **Description**: Drain-TTL time window for stale ME writers after endpoint map changes. During the TTL, stale writers may be used only as fallback for new bindings (depending on bind policy). - - **Example**: - - ```toml - [general] - # disable drain TTL (draining writers won't emit "past drain TTL" warnings) - me_pool_drain_ttl_secs = 0 - ``` - -- `me_instadrain` - - **Constraints / validation**: `bool`. - - **Description**: Forces draining stale writers to be removed on the next cleanup tick, bypassing TTL/deadline waiting. - - **Example**: - - ```toml - [general] - # default: false - me_instadrain = false - ``` - -- `me_pool_drain_threshold` - - **Constraints / validation**: `u64`. Set to `0` to disable threshold-based cleanup. - - **Description**: Maximum number of draining stale writers before oldest ones are force-closed in batches. - - **Example**: - - ```toml - [general] - # default: 32 - me_pool_drain_threshold = 32 - ``` - -- `me_pool_drain_soft_evict_enabled` - - **Constraints / validation**: `bool`. - - **Description**: Enables gradual soft-eviction of stale writers during drain/reinit instead of immediate hard close. - - **Example**: - - ```toml - [general] - # default: true - me_pool_drain_soft_evict_enabled = true - ``` - -- `me_pool_drain_soft_evict_grace_secs` - - **Constraints / validation**: `u64` (seconds). Must be within `[0, 3600]`. - - **Description**: Extra grace (after drain TTL) before soft-eviction stage starts. - - **Example**: - - ```toml - [general] - # default: 10 - me_pool_drain_soft_evict_grace_secs = 10 - ``` - -- `me_pool_drain_soft_evict_per_writer` - - **Constraints / validation**: `1..=16`. - - **Description**: Maximum stale routes soft-evicted per writer in one eviction pass. - - **Example**: - - ```toml - [general] - # default: 2 - me_pool_drain_soft_evict_per_writer = 2 - ``` - -- `me_pool_drain_soft_evict_budget_per_core` - - **Constraints / validation**: `1..=64`. - - **Description**: Per-core budget limiting aggregate soft-eviction work per pass. - - **Example**: - - ```toml - [general] - # default: 16 - me_pool_drain_soft_evict_budget_per_core = 16 - ``` - -- `me_pool_drain_soft_evict_cooldown_ms` - - **Constraints / validation**: `u64` (milliseconds). Must be `> 0`. - - **Description**: Cooldown between repetitive soft-eviction on the same writer. - - **Example**: - - ```toml - [general] - # default: 1000 - me_pool_drain_soft_evict_cooldown_ms = 1000 - ``` - -- `me_bind_stale_mode` - - **Constraints / validation**: `"never"`, `"ttl"`, or `"always"`. - - **Description**: Policy for new binds on stale draining writers. - - **Example**: - - ```toml - [general] - # allow stale binds only for a limited time window - me_bind_stale_mode = "ttl" - ``` - -- `me_bind_stale_ttl_secs` - - **Constraints / validation**: `u64`. - - **Description**: TTL for stale bind allowance when stale mode is `ttl`. - - **Example**: - - ```toml - [general] - me_bind_stale_mode = "ttl" - me_bind_stale_ttl_secs = 90 - ``` - -- `me_pool_min_fresh_ratio` - - **Constraints / validation**: Must be within `[0.0, 1.0]`. - - **Description**: Minimum fresh desired-DC coverage ratio before stale writers are drained. - - **Example**: - - ```toml - [general] - # require >=90% desired-DC coverage before draining stale writers - me_pool_min_fresh_ratio = 0.9 - ``` - -- `me_reinit_drain_timeout_secs` - - **Constraints / validation**: `u64`. `0` uses the runtime safety fallback force-close timeout. If `> 0` and `< me_pool_drain_ttl_secs`, runtime bumps it to TTL. - - **Description**: Force-close timeout for draining stale writers. When set to `0`, the effective timeout is the runtime safety fallback (300 seconds). - - **Example**: - - ```toml - [general] - # use runtime safety fallback force-close timeout (300s) - me_reinit_drain_timeout_secs = 0 - ``` - -- `proxy_secret_auto_reload_secs` - - **Constraints / validation**: Deprecated. Use `general.update_every`. When `general.update_every` is not explicitly set, the effective legacy refresh interval is `min(proxy_secret_auto_reload_secs, proxy_config_auto_reload_secs)` and must be `> 0`. - - **Description**: Deprecated legacy proxy-secret refresh interval. Used only when `general.update_every` is not set. - - **Example**: - - ```toml - [general] - # legacy mode: omit update_every to use proxy_*_auto_reload_secs - proxy_secret_auto_reload_secs = 600 - proxy_config_auto_reload_secs = 120 - # effective updater interval = min(600, 120) = 120 seconds - ``` - -- `proxy_config_auto_reload_secs` - - **Constraints / validation**: Deprecated. Use `general.update_every`. When `general.update_every` is not explicitly set, the effective legacy refresh interval is `min(proxy_secret_auto_reload_secs, proxy_config_auto_reload_secs)` and must be `> 0`. - - **Description**: Deprecated legacy ME config refresh interval. Used only when `general.update_every` is not set. - - **Example**: - - ```toml - [general] - # legacy mode: omit update_every to use proxy_*_auto_reload_secs - proxy_secret_auto_reload_secs = 600 - proxy_config_auto_reload_secs = 120 - # effective updater interval = min(600, 120) = 120 seconds - ``` - -- `me_reinit_singleflight` - - **Constraints / validation**: `bool`. - - **Description**: Serializes ME reinit cycles across trigger sources. - - **Example**: - - ```toml - [general] - me_reinit_singleflight = true - ``` - -- `me_reinit_trigger_channel` - - **Constraints / validation**: Must be `> 0`. - - **Description**: Trigger queue capacity for reinit scheduler. - - **Example**: - - ```toml - [general] - me_reinit_trigger_channel = 64 - ``` - -- `me_reinit_coalesce_window_ms` - - **Constraints / validation**: `u64`. - - **Description**: Trigger coalescing window before starting reinit (ms). - - **Example**: - - ```toml - [general] - me_reinit_coalesce_window_ms = 200 - ``` - -- `me_deterministic_writer_sort` - - **Constraints / validation**: `bool`. - - **Description**: Enables deterministic candidate sort for writer binding path. - - **Example**: - - ```toml - [general] - me_deterministic_writer_sort = true - ``` - -- `me_writer_pick_mode` - - **Constraints / validation**: `"sorted_rr"` or `"p2c"`. - - **Description**: Writer selection mode for route bind path. - - **Example**: - - ```toml - [general] - me_writer_pick_mode = "p2c" - ``` - -- `me_writer_pick_sample_size` - - **Constraints / validation**: `2..=4`. - - **Description**: Number of candidates sampled by picker in `p2c` mode. - - **Example**: - - ```toml - [general] - me_writer_pick_mode = "p2c" - me_writer_pick_sample_size = 3 - ``` - -- `ntp_check` - - **Constraints / validation**: `bool`. - - **Description**: Reserved for future use. Currently this key is parsed but not used by the runtime. - - **Example**: - - ```toml - [general] - ntp_check = true - ``` - -- `ntp_servers` - - **Constraints / validation**: `String[]`. - - **Description**: Reserved for future use. Currently this key is parsed but not used by the runtime. - - **Example**: - - ```toml - [general] - ntp_servers = ["pool.ntp.org"] - ``` - -- `auto_degradation_enabled` - - **Constraints / validation**: `bool`. - - **Description**: Reserved for future use. Currently this key is parsed but not used by the runtime. - - **Example**: - - ```toml - [general] - auto_degradation_enabled = true - ``` - -- `degradation_min_unavailable_dc_groups` - - **Constraints / validation**: `u8`. - - **Description**: Reserved for future use. Currently this key is parsed but not used by the runtime. - - **Example**: - - ```toml - [general] - degradation_min_unavailable_dc_groups = 2 - ``` - - -## [general.modes] - - -| Key | Type | Default | -| --- | ---- | ------- | -| [`classic`](#cfg-general-modes-classic) | `bool` | `false` | -| [`secure`](#cfg-general-modes-secure) | `bool` | `false` | -| [`tls`](#cfg-general-modes-tls) | `bool` | `true` | - - -- `classic` - - **Constraints / validation**: `bool`. - - **Description**: Enables classic MTProxy mode. - - **Example**: - - ```toml - [general.modes] - classic = true - ``` - -- `secure` - - **Constraints / validation**: `bool`. - - **Description**: Enables secure mode. - - **Example**: - - ```toml - [general.modes] - secure = true - ``` - -- `tls` - - **Constraints / validation**: `bool`. - - **Description**: Enables TLS mode. - - **Example**: - - ```toml - [general.modes] - tls = true - ``` - - -## [general.links] - - -| Key | Type | Default | -| --- | ---- | ------- | -| [`show`](#cfg-general-links-show) | `"*"` or `String[]` | `"*"` | -| [`public_host`](#cfg-general-links-public_host) | `String` | — | -| [`public_port`](#cfg-general-links-public_port) | `u16` | — | - - -- `show` - - **Constraints / validation**: `"*"` or `String[]`. An empty array means "show none". - - **Description**: Selects users whose `tg://` proxy links are shown at startup. - - **Example**: - - ```toml - [general.links] - show = "*" - # or: - # show = ["alice", "bob"] - ``` - -- `public_host` - - **Constraints / validation**: `String` (optional). - - **Description**: Public hostname/IP override used for generated `tg://` links (overrides detected IP). - - **Example**: - - ```toml - [general.links] - public_host = "proxy.example.com" - ``` - -- `public_port` - - **Constraints / validation**: `u16` (optional). - - **Description**: Public port override used for generated `tg://` links (overrides `server.port`). - - **Example**: - - ```toml - [general.links] - public_port = 443 - ``` - - -## [general.telemetry] - - -| Key | Type | Default | -| --- | ---- | ------- | -| [`core_enabled`](#cfg-general-telemetry-core_enabled) | `bool` | `true` | -| [`user_enabled`](#cfg-general-telemetry-user_enabled) | `bool` | `true` | -| [`me_level`](#cfg-general-telemetry-me_level) | `"silent"`, `"normal"`, or `"debug"` | `"normal"` | - - -- `core_enabled` - - **Constraints / validation**: `bool`. - - **Description**: Enables core hot-path telemetry counters. - - **Example**: - - ```toml - [general.telemetry] - core_enabled = true - ``` - -- `user_enabled` - - **Constraints / validation**: `bool`. - - **Description**: Enables per-user telemetry counters. - - **Example**: - - ```toml - [general.telemetry] - user_enabled = true - ``` - -- `me_level` - - **Constraints / validation**: `"silent"`, `"normal"`, or `"debug"`. - - **Description**: Middle-End telemetry verbosity level. - - **Example**: - - ```toml - [general.telemetry] - me_level = "normal" - ``` - - -## [network] - - -| Key | Type | Default | -| --- | ---- | ------- | -| [`ipv4`](#cfg-network-ipv4) | `bool` | `true` | -| [`ipv6`](#cfg-network-ipv6) | `bool` | `false` | -| [`prefer`](#cfg-network-prefer) | `u8` | `4` | -| [`multipath`](#cfg-network-multipath) | `bool` | `false` | -| [`stun_use`](#cfg-network-stun_use) | `bool` | `true` | -| [`stun_servers`](#cfg-network-stun_servers) | `String[]` | Built-in STUN list (13 hosts) | -| [`stun_tcp_fallback`](#cfg-network-stun_tcp_fallback) | `bool` | `true` | -| [`http_ip_detect_urls`](#cfg-network-http_ip_detect_urls) | `String[]` | `["https://ifconfig.me/ip", "https://api.ipify.org"]` | -| [`cache_public_ip_path`](#cfg-network-cache_public_ip_path) | `String` | `"cache/public_ip.txt"` | -| [`dns_overrides`](#cfg-network-dns_overrides) | `String[]` | `[]` | - - -- `ipv4` - - **Constraints / validation**: `bool`. - - **Description**: Enables IPv4 networking. - - **Example**: - - ```toml - [network] - ipv4 = true - ``` - -- `ipv6` - - **Constraints / validation**: `bool`. - - **Description**: Enables/disables IPv6 networking. When omitted, defaults to `false`. - - **Example**: - - ```toml - [network] - # enable IPv6 explicitly - ipv6 = true - - # or: disable IPv6 explicitly - # ipv6 = false - ``` - -- `prefer` - - **Constraints / validation**: Must be `4` or `6`. If `prefer = 4` while `ipv4 = false`, Telemt forces `prefer = 6`. If `prefer = 6` while `ipv6 = false`, Telemt forces `prefer = 4`. - - **Description**: Preferred IP family for selection when both families are available. - - **Example**: - - ```toml - [network] - prefer = 6 - ``` - -- `multipath` - - **Constraints / validation**: `bool`. - - **Description**: Enables multipath behavior where supported by the platform and runtime. - - **Example**: - - ```toml - [network] - multipath = true - ``` - -- `stun_use` - - **Constraints / validation**: `bool`. - - **Description**: Global STUN switch; when `false`, STUN probing is disabled and only non-STUN detection remains. - - **Example**: - - ```toml - [network] - stun_use = false - ``` - -- `stun_servers` - - **Constraints / validation**: `String[]`. Values are trimmed; empty values are removed; list is deduplicated. If this key is **not** explicitly set, Telemt keeps the built-in default STUN list. - - **Description**: STUN servers list for public IP discovery. - - **Example**: - - ```toml - [network] - stun_servers = [ - "stun.l.google.com:19302", - "stun.stunprotocol.org:3478", - ] - ``` - -- `stun_tcp_fallback` - - **Constraints / validation**: `bool`. - - **Description**: Enables TCP fallback for STUN when the UDP path is blocked/unavailable. - - **Example**: - - ```toml - [network] - stun_tcp_fallback = true - ``` - -- `http_ip_detect_urls` - - **Constraints / validation**: `String[]`. - - **Description**: HTTP endpoints used for public IP detection (fallback after STUN). - - **Example**: - - ```toml - [network] - http_ip_detect_urls = ["https://ifconfig.me/ip", "https://api.ipify.org"] - ``` - -- `cache_public_ip_path` - - **Constraints / validation**: `String`. - - **Description**: File path used to cache the detected public IP. - - **Example**: - - ```toml - [network] - cache_public_ip_path = "cache/public_ip.txt" - ``` - -- `dns_overrides` - - **Constraints / validation**: `String[]`. Each entry must use `host:port:ip` format. - - `host`: domain name (must be non-empty and must not contain `:`) - - `port`: `u16` - - `ip`: IPv4 (`1.2.3.4`) or bracketed IPv6 (`[2001:db8::1]`). **Unbracketed IPv6 is rejected**. - - **Description**: Runtime DNS overrides for `host:port` targets. Useful for forcing specific IPs for given upstream domains without touching system DNS. - - **Example**: - - ```toml - [network] - dns_overrides = [ - "example.com:443:127.0.0.1", - "example.net:8443:[2001:db8::10]", - ] - ``` - - -## [server] - - -| Key | Type | Default | -| --- | ---- | ------- | -| [`port`](#cfg-server-port) | `u16` | `443` | -| [`listen_addr_ipv4`](#cfg-server-listen_addr_ipv4) | `String` | `"0.0.0.0"` | -| [`listen_addr_ipv6`](#cfg-server-listen_addr_ipv6) | `String` | `"::"` | -| [`listen_unix_sock`](#cfg-server-listen_unix_sock) | `String` | — | -| [`listen_unix_sock_perm`](#cfg-server-listen_unix_sock_perm) | `String` | — | -| [`listen_tcp`](#cfg-server-listen_tcp) | `bool` | — (auto) | -| [`proxy_protocol`](#cfg-server-proxy_protocol) | `bool` | `false` | -| [`proxy_protocol_header_timeout_ms`](#cfg-server-proxy_protocol_header_timeout_ms) | `u64` | `500` | -| [`proxy_protocol_trusted_cidrs`](#cfg-server-proxy_protocol_trusted_cidrs) | `IpNetwork[]` | `[]` | -| [`metrics_port`](#cfg-server-metrics_port) | `u16` | — | -| [`metrics_listen`](#cfg-server-metrics_listen) | `String` | — | -| [`metrics_whitelist`](#cfg-server-metrics_whitelist) | `IpNetwork[]` | `["127.0.0.1/32", "::1/128"]` | -| [`max_connections`](#cfg-server-max_connections) | `u32` | `10000` | -| [`accept_permit_timeout_ms`](#cfg-server-accept_permit_timeout_ms) | `u64` | `250` | - - -- `port` - - **Constraints / validation**: `u16`. - - **Description**: Main proxy listen port (TCP). - - **Example**: - - ```toml - [server] - port = 443 - ``` - -- `listen_addr_ipv4` - - **Constraints / validation**: `String` (optional). When set, must be a valid IPv4 address string. - - **Description**: IPv4 bind address for TCP listener (omit this key to disable IPv4 bind). - - **Example**: - - ```toml - [server] - listen_addr_ipv4 = "0.0.0.0" - ``` - -- `listen_addr_ipv6` - - **Constraints / validation**: `String` (optional). When set, must be a valid IPv6 address string. - - **Description**: IPv6 bind address for TCP listener (omit this key to disable IPv6 bind). - - **Example**: - - ```toml - [server] - listen_addr_ipv6 = "::" - ``` - -- `listen_unix_sock` - - **Constraints / validation**: `String` (optional). Must not be empty when set. Unix only. - - **Description**: Unix socket path for listener. When set, `server.listen_tcp` defaults to `false` (unless explicitly overridden). - - **Example**: - - ```toml - [server] - listen_unix_sock = "/run/telemt.sock" - ``` - -- `listen_unix_sock_perm` - - **Constraints / validation**: `String` (optional). When set, should be an octal permission string like `"0666"` or `"0777"`. - - **Description**: Optional Unix socket file permissions applied after bind (chmod). When omitted, permissions are not changed (inherits umask). - - **Example**: - - ```toml - [server] - listen_unix_sock = "/run/telemt.sock" - listen_unix_sock_perm = "0666" - ``` - -- `listen_tcp` - - **Constraints / validation**: `bool` (optional). When omitted, Telemt auto-detects: - - `true` when `listen_unix_sock` is not set - - `false` when `listen_unix_sock` is set - - **Description**: Explicit TCP listener enable/disable override. - - **Example**: - - ```toml - [server] - # force-enable TCP even when also binding a unix socket - listen_unix_sock = "/run/telemt.sock" - listen_tcp = true - ``` - -- `proxy_protocol` - - **Constraints / validation**: `bool`. - - **Description**: Enables HAProxy PROXY protocol parsing on incoming connections (PROXY v1/v2). When enabled, client source address is taken from the PROXY header. - - **Example**: - - ```toml - [server] - proxy_protocol = true - ``` - -- `proxy_protocol_header_timeout_ms` - - **Constraints / validation**: Must be `> 0` (milliseconds). - - **Description**: Timeout for reading and parsing PROXY protocol headers (ms). - - **Example**: - - ```toml - [server] - proxy_protocol = true - proxy_protocol_header_timeout_ms = 500 - ``` - -- `proxy_protocol_trusted_cidrs` - - **Constraints / validation**: `IpNetwork[]`. - - If omitted, defaults to trust-all CIDRs (`0.0.0.0/0` and `::/0`). - - If explicitly set to an empty array, all PROXY headers are rejected. - - **Description**: Trusted source CIDRs allowed to provide PROXY protocol headers (security control). - - **Example**: - - ```toml - [server] - proxy_protocol = true - proxy_protocol_trusted_cidrs = ["127.0.0.1/32", "10.0.0.0/8"] - ``` - -- `metrics_port` - - **Constraints / validation**: `u16` (optional). - - **Description**: Prometheus-compatible metrics endpoint port. When set, enables the metrics listener (bind behavior can be overridden by `metrics_listen`). - - **Example**: - - ```toml - [server] - metrics_port = 9090 - ``` - -- `metrics_listen` - - **Constraints / validation**: `String` (optional). When set, must be in `IP:PORT` format. - - **Description**: Full metrics bind address (`IP:PORT`), overrides `metrics_port` and binds on the specified address only. - - **Example**: - - ```toml - [server] - metrics_listen = "127.0.0.1:9090" - ``` - -- `metrics_whitelist` - - **Constraints / validation**: `IpNetwork[]`. - - **Description**: CIDR whitelist for metrics endpoint access. - - **Example**: - - ```toml - [server] - metrics_port = 9090 - metrics_whitelist = ["127.0.0.1/32", "::1/128"] - ``` - -- `max_connections` - - **Constraints / validation**: `u32`. `0` means unlimited. - - **Description**: Maximum number of concurrent client connections. - - **Example**: - - ```toml - [server] - max_connections = 10000 - ``` - -- `accept_permit_timeout_ms` - - **Constraints / validation**: `0..=60000` (milliseconds). `0` keeps legacy unbounded wait behavior. - - **Description**: Maximum wait for acquiring a connection-slot permit before the accepted connection is dropped. - - **Example**: - - ```toml - [server] - accept_permit_timeout_ms = 250 - ``` - - -Note: When `server.proxy_protocol` is enabled, incoming PROXY protocol headers are parsed from the first bytes of the connection and the client source address is replaced with `src_addr` from the header. For security, the peer source IP (the direct connection address) is verified against `server.proxy_protocol_trusted_cidrs`; if this list is empty, PROXY headers are rejected and the connection is considered untrusted. - -## [server.conntrack_control] - -Note: The conntrack-control worker runs **only on Linux**. On other operating systems it is not started; if `inline_conntrack_control` is `true`, a warning is logged. Effective operation also requires **CAP_NET_ADMIN** and a usable backend (`nft` or `iptables` / `ip6tables` on `PATH`). The `conntrack` utility is used for optional table entry deletes under pressure. - - -| Key | Type | Default | -| --- | ---- | ------- | -| [`inline_conntrack_control`](#cfg-server-conntrack_control-inline_conntrack_control) | `bool` | `true` | -| [`mode`](#cfg-server-conntrack_control-mode) | `String` | `"tracked"` | -| [`backend`](#cfg-server-conntrack_control-backend) | `String` | `"auto"` | -| [`profile`](#cfg-server-conntrack_control-profile) | `String` | `"balanced"` | -| [`hybrid_listener_ips`](#cfg-server-conntrack_control-hybrid_listener_ips) | `IpAddr[]` | `[]` | -| [`pressure_high_watermark_pct`](#cfg-server-conntrack_control-pressure_high_watermark_pct) | `u8` | `85` | -| [`pressure_low_watermark_pct`](#cfg-server-conntrack_control-pressure_low_watermark_pct) | `u8` | `70` | -| [`delete_budget_per_sec`](#cfg-server-conntrack_control-delete_budget_per_sec) | `u64` | `4096` | - - -- `inline_conntrack_control` - - **Constraints / validation**: `bool`. - - **Description**: Master switch for the runtime conntrack-control task: reconciles **raw/notrack** netfilter rules for listener ingress (see `mode`), samples load every second, and may run **`conntrack -D`** deletes for qualifying close events while **pressure mode** is active (see `delete_budget_per_sec`). When `false`, notrack rules are cleared and pressure-driven deletes are disabled. - - **Example**: - - ```toml - [server.conntrack_control] - inline_conntrack_control = true - ``` - -- `mode` - - **Constraints / validation**: One of `tracked`, `notrack`, `hybrid` (case-insensitive; serialized lowercase). - - **Description**: **`tracked`**: do not install telemt notrack rules (connections stay in conntrack). **`notrack`**: mark matching ingress TCP to `server.port` as notrack — targets are derived from `[[server.listeners]]` if any, otherwise from `server.listen_addr_ipv4` / `server.listen_addr_ipv6` (unspecified addresses mean “any” for that family). **`hybrid`**: notrack only for addresses listed in `hybrid_listener_ips` (must be non-empty; validated at load). - - **Example**: - - ```toml - [server.conntrack_control] - mode = "notrack" - ``` - -- `backend` - - **Constraints / validation**: One of `auto`, `nftables`, `iptables` (case-insensitive; serialized lowercase). - - **Description**: Which command set applies notrack rules. **`auto`**: use `nft` if present on `PATH`, else `iptables`/`ip6tables` if present. **`nftables`** / **`iptables`**: force that backend; missing binary means rules cannot be applied. The nft path uses table `inet telemt_conntrack` and a prerouting raw hook; iptables uses chain `TELEMT_NOTRACK` in the `raw` table. - - **Example**: - - ```toml - [server.conntrack_control] - backend = "auto" - ``` - -- `profile` - - **Constraints / validation**: One of `conservative`, `balanced`, `aggressive` (case-insensitive; serialized lowercase). - - **Description**: When **conntrack pressure mode** is active (`pressure_*` watermarks), caps idle and activity timeouts to reduce conntrack churn: e.g. **client first-byte idle** (`client.rs`), **direct relay activity timeout** (`direct_relay.rs`), and **middle-relay idle policy** caps (`middle_relay.rs` via `ConntrackPressureProfile::*_cap_secs` / `direct_activity_timeout_secs`). More aggressive profiles use shorter caps. - - **Example**: - - ```toml - [server.conntrack_control] - profile = "balanced" - ``` - -- `hybrid_listener_ips` - - **Constraints / validation**: `IpAddr[]`. Required to be **non-empty** when `mode = "hybrid"`. Ignored for `tracked` / `notrack`. - - **Description**: Explicit listener addresses that receive notrack rules in hybrid mode (split into IPv4 vs IPv6 rules by the implementation). - - **Example**: - - ```toml - [server.conntrack_control] - mode = "hybrid" - hybrid_listener_ips = ["203.0.113.10", "2001:db8::1"] - ``` - -- `pressure_high_watermark_pct` - - **Constraints / validation**: Must be within `[1, 100]`. - - **Description**: Pressure mode **enters** when any of: connection fill vs `server.max_connections` (percentage, if `max_connections > 0`), **file-descriptor** usage vs process soft `RLIMIT_NOFILE`, **non-zero** `accept_permit_timeout` events in the last sample window, or **ME c2me send-full** counter delta. Entry compares relevant percentages against this high watermark (see `update_pressure_state` in `conntrack_control.rs`). - - **Example**: - - ```toml - [server.conntrack_control] - pressure_high_watermark_pct = 85 - ``` - -- `pressure_low_watermark_pct` - - **Constraints / validation**: Must be **strictly less than** `pressure_high_watermark_pct`. - - **Description**: Pressure mode **clears** only after **three** consecutive one-second samples where all signals are at or below this low watermark and the accept-timeout / ME-queue deltas are zero (hysteresis). - - **Example**: - - ```toml - [server.conntrack_control] - pressure_low_watermark_pct = 70 - ``` - -- `delete_budget_per_sec` - - **Constraints / validation**: Must be `> 0`. - - **Description**: Maximum number of **`conntrack -D`** attempts **per second** while pressure mode is active (token bucket refilled each second). Deletes run only for close events with reasons **timeout**, **pressure**, or **reset**; each attempt consumes a token regardless of outcome. - - **Example**: - - ```toml - [server.conntrack_control] - delete_budget_per_sec = 4096 - ``` - - -## [server.api] - -Note: This section also accepts the legacy alias `[server.admin_api]` (same schema as `[server.api]`). - - -| Key | Type | Default | -| --- | ---- | ------- | -| [`enabled`](#cfg-server-api-enabled) | `bool` | `true` | -| [`listen`](#cfg-server-api-listen) | `String` | `"0.0.0.0:9091"` | -| [`whitelist`](#cfg-server-api-whitelist) | `IpNetwork[]` | `["127.0.0.0/8"]` | -| [`auth_header`](#cfg-server-api-auth_header) | `String` | `""` | -| [`request_body_limit_bytes`](#cfg-server-api-request_body_limit_bytes) | `usize` | `65536` | -| [`minimal_runtime_enabled`](#cfg-server-api-minimal_runtime_enabled) | `bool` | `true` | -| [`minimal_runtime_cache_ttl_ms`](#cfg-server-api-minimal_runtime_cache_ttl_ms) | `u64` | `1000` | -| [`runtime_edge_enabled`](#cfg-server-api-runtime_edge_enabled) | `bool` | `false` | -| [`runtime_edge_cache_ttl_ms`](#cfg-server-api-runtime_edge_cache_ttl_ms) | `u64` | `1000` | -| [`runtime_edge_top_n`](#cfg-server-api-runtime_edge_top_n) | `usize` | `10` | -| [`runtime_edge_events_capacity`](#cfg-server-api-runtime_edge_events_capacity) | `usize` | `256` | -| [`read_only`](#cfg-server-api-read_only) | `bool` | `false` | - - -- `enabled` - - **Constraints / validation**: `bool`. - - **Description**: Enables control-plane REST API. - - **Example**: - - ```toml - [server.api] - enabled = true - ``` - -- `listen` - - **Constraints / validation**: `String`. Must be in `IP:PORT` format. - - **Description**: API bind address in `IP:PORT` format. - - **Example**: - - ```toml - [server.api] - listen = "0.0.0.0:9091" - ``` - -- `whitelist` - - **Constraints / validation**: `IpNetwork[]`. - - **Description**: CIDR whitelist allowed to access API. - - **Example**: - - ```toml - [server.api] - whitelist = ["127.0.0.0/8"] - ``` - -- `auth_header` - - **Constraints / validation**: `String`. Empty string disables auth-header validation. - - **Description**: Exact expected `Authorization` header value (static shared secret). - - **Example**: - - ```toml - [server.api] - auth_header = "Bearer MY_TOKEN" - ``` - -- `request_body_limit_bytes` - - **Constraints / validation**: Must be `> 0` (bytes). - - **Description**: Maximum accepted HTTP request body size (bytes). - - **Example**: - - ```toml - [server.api] - request_body_limit_bytes = 65536 - ``` - -- `minimal_runtime_enabled` - - **Constraints / validation**: `bool`. - - **Description**: Enables minimal runtime snapshots endpoint logic. - - **Example**: - - ```toml - [server.api] - minimal_runtime_enabled = true - ``` - -- `minimal_runtime_cache_ttl_ms` - - **Constraints / validation**: `0..=60000` (milliseconds). `0` disables cache. - - **Description**: Cache TTL for minimal runtime snapshots (ms). - - **Example**: - - ```toml - [server.api] - minimal_runtime_cache_ttl_ms = 1000 - ``` - -- `runtime_edge_enabled` - - **Constraints / validation**: `bool`. - - **Description**: Enables runtime edge endpoints. - - **Example**: - - ```toml - [server.api] - runtime_edge_enabled = false - ``` - -- `runtime_edge_cache_ttl_ms` - - **Constraints / validation**: `0..=60000` (milliseconds). - - **Description**: Cache TTL for runtime edge aggregation payloads (ms). - - **Example**: - - ```toml - [server.api] - runtime_edge_cache_ttl_ms = 1000 - ``` - -- `runtime_edge_top_n` - - **Constraints / validation**: `1..=1000`. - - **Description**: Top-N size for edge connection leaderboard. - - **Example**: - - ```toml - [server.api] - runtime_edge_top_n = 10 - ``` - -- `runtime_edge_events_capacity` - - **Constraints / validation**: `16..=4096`. - - **Description**: Ring-buffer capacity for runtime edge events. - - **Example**: - - ```toml - [server.api] - runtime_edge_events_capacity = 256 - ``` - -- `read_only` - - **Constraints / validation**: `bool`. - - **Description**: Rejects mutating API endpoints when enabled. - - **Example**: - - ```toml - [server.api] - read_only = false - ``` - - -## [[server.listeners]] - - -| Key | Type | Default | -| --- | ---- | ------- | -| [`ip`](#cfg-server-listeners-ip) | `IpAddr` | — | -| [`announce`](#cfg-server-listeners-announce) | `String` | — | -| [`announce_ip`](#cfg-server-listeners-announce_ip) | `IpAddr` | — | -| [`proxy_protocol`](#cfg-server-listeners-proxy_protocol) | `bool` | — | -| [`reuse_allow`](#cfg-server-listeners-reuse_allow) | `bool` | `false` | - - -- `ip` - - **Constraints / validation**: Required field. Must be an `IpAddr`. - - **Description**: Listener bind IP. - - **Example**: - - ```toml - [[server.listeners]] - ip = "0.0.0.0" - ``` - -- `announce` - - **Constraints / validation**: `String` (optional). Must not be empty when set. - - **Description**: Public IP/domain announced in proxy links for this listener. Takes precedence over `announce_ip`. - - **Example**: - - ```toml - [[server.listeners]] - ip = "0.0.0.0" - announce = "proxy.example.com" - ``` - -- `announce_ip` - - **Constraints / validation**: `IpAddr` (optional). Deprecated. Use `announce`. - - **Description**: Deprecated legacy announce IP. During config load it is migrated to `announce` when `announce` is not set. - - **Example**: - - ```toml - [[server.listeners]] - ip = "0.0.0.0" - announce_ip = "203.0.113.10" - ``` - -- `proxy_protocol` - - **Constraints / validation**: `bool` (optional). When set, overrides `server.proxy_protocol` for this listener. - - **Description**: Per-listener PROXY protocol override. - - **Example**: - - ```toml - [server] - proxy_protocol = false - - [[server.listeners]] - ip = "0.0.0.0" - proxy_protocol = true - ``` - -- `reuse_allow` - - **Constraints / validation**: `bool`. - - **Description**: Enables `SO_REUSEPORT` for multi-instance bind sharing (allows multiple telemt instances to listen on the same `ip:port`). - - **Example**: - - ```toml - [[server.listeners]] - ip = "0.0.0.0" - reuse_allow = false - ``` - - -## [timeouts] - - -| Key | Type | Default | -| --- | ---- | ------- | -| [`client_handshake`](#cfg-timeouts-client_handshake) | `u64` | `30` | -| [`relay_idle_policy_v2_enabled`](#cfg-timeouts-relay_idle_policy_v2_enabled) | `bool` | `true` | -| [`relay_client_idle_soft_secs`](#cfg-timeouts-relay_client_idle_soft_secs) | `u64` | `120` | -| [`relay_client_idle_hard_secs`](#cfg-timeouts-relay_client_idle_hard_secs) | `u64` | `360` | -| [`relay_idle_grace_after_downstream_activity_secs`](#cfg-timeouts-relay_idle_grace_after_downstream_activity_secs) | `u64` | `30` | -| [`tg_connect`](#cfg-timeouts-tg_connect) | `u64` | `10` | -| [`client_keepalive`](#cfg-timeouts-client_keepalive) | `u64` | `15` | -| [`client_ack`](#cfg-timeouts-client_ack) | `u64` | `90` | -| [`me_one_retry`](#cfg-timeouts-me_one_retry) | `u8` | `12` | -| [`me_one_timeout_ms`](#cfg-timeouts-me_one_timeout_ms) | `u64` | `1200` | - - -- `client_handshake` - - **Constraints / validation**: Must be `> 0`. Value is in seconds. Also used as an upper bound for some TLS emulation delays (see `censorship.server_hello_delay_max_ms`). - - **Description**: Client handshake timeout (seconds). - - **Example**: - - ```toml - [timeouts] - client_handshake = 30 - ``` - -- `relay_idle_policy_v2_enabled` - - **Constraints / validation**: `bool`. - - **Description**: Enables soft/hard middle-relay client idle policy. - - **Example**: - - ```toml - [timeouts] - relay_idle_policy_v2_enabled = true - ``` - -- `relay_client_idle_soft_secs` - - **Constraints / validation**: Must be `> 0`; must be `<= relay_client_idle_hard_secs`. - - **Description**: Soft idle threshold (seconds) for middle-relay client uplink inactivity. Hitting this threshold marks the session as an idle-candidate (it may be eligible for cleanup depending on policy). - - **Example**: - - ```toml - [timeouts] - relay_client_idle_soft_secs = 120 - ``` - -- `relay_client_idle_hard_secs` - - **Constraints / validation**: Must be `> 0`; must be `>= relay_client_idle_soft_secs`. - - **Description**: Hard idle threshold (seconds) for middle-relay client uplink inactivity. Hitting this threshold closes the session. - - **Example**: - - ```toml - [timeouts] - relay_client_idle_hard_secs = 360 - ``` - -- `relay_idle_grace_after_downstream_activity_secs` - - **Constraints / validation**: Must be `<= relay_client_idle_hard_secs`. - - **Description**: Extra hard-idle grace period (seconds) added after recent downstream activity. - - **Example**: - - ```toml - [timeouts] - relay_idle_grace_after_downstream_activity_secs = 30 - ``` - -- `tg_connect` - - **Constraints / validation**: `u64`. Value is in seconds. - - **Description**: Upstream Telegram connect timeout (seconds). - - **Example**: - - ```toml - [timeouts] - tg_connect = 10 - ``` - -- `client_keepalive` - - **Constraints / validation**: `u64`. Value is in seconds. - - **Description**: Client keepalive timeout (seconds). - - **Example**: - - ```toml - [timeouts] - client_keepalive = 15 - ``` - -- `client_ack` - - **Constraints / validation**: `u64`. Value is in seconds. - - **Description**: Client ACK timeout (seconds). - - **Example**: - - ```toml - [timeouts] - client_ack = 90 - ``` - -- `me_one_retry` - - **Constraints / validation**: `u8`. - - **Description**: Fast reconnect attempts budget for single-endpoint DC scenarios. - - **Example**: - - ```toml - [timeouts] - me_one_retry = 12 - ``` - -- `me_one_timeout_ms` - - **Constraints / validation**: `u64`. Value is in milliseconds. - - **Description**: Timeout per quick attempt (ms) for single-endpoint DC reconnect logic. - - **Example**: - - ```toml - [timeouts] - me_one_timeout_ms = 1200 - ``` - - -## [censorship] - - -| Key | Type | Default | -| --- | ---- | ------- | -| [`tls_domain`](#cfg-censorship-tls_domain) | `String` | `"petrovich.ru"` | -| [`tls_domains`](#cfg-censorship-tls_domains) | `String[]` | `[]` | -| [`unknown_sni_action`](#cfg-censorship-unknown_sni_action) | `"drop"` or `"mask"` | `"drop"` | -| [`tls_fetch_scope`](#cfg-censorship-tls_fetch_scope) | `String` | `""` | -| [`tls_fetch`](#cfg-censorship-tls_fetch) | `Table` | built-in defaults | -| [`mask`](#cfg-censorship-mask) | `bool` | `true` | -| [`mask_host`](#cfg-censorship-mask_host) | `String` | — | -| [`mask_port`](#cfg-censorship-mask_port) | `u16` | `443` | -| [`mask_unix_sock`](#cfg-censorship-mask_unix_sock) | `String` | — | -| [`fake_cert_len`](#cfg-censorship-fake_cert_len) | `usize` | `2048` | -| [`tls_emulation`](#cfg-censorship-tls_emulation) | `bool` | `true` | -| [`tls_front_dir`](#cfg-censorship-tls_front_dir) | `String` | `"tlsfront"` | -| [`server_hello_delay_min_ms`](#cfg-censorship-server_hello_delay_min_ms) | `u64` | `0` | -| [`server_hello_delay_max_ms`](#cfg-censorship-server_hello_delay_max_ms) | `u64` | `0` | -| [`tls_new_session_tickets`](#cfg-censorship-tls_new_session_tickets) | `u8` | `0` | -| [`tls_full_cert_ttl_secs`](#cfg-censorship-tls_full_cert_ttl_secs) | `u64` | `90` | -| [`alpn_enforce`](#cfg-censorship-alpn_enforce) | `bool` | `true` | -| [`mask_proxy_protocol`](#cfg-censorship-mask_proxy_protocol) | `u8` | `0` | -| [`mask_shape_hardening`](#cfg-censorship-mask_shape_hardening) | `bool` | `true` | -| [`mask_shape_hardening_aggressive_mode`](#cfg-censorship-mask_shape_hardening_aggressive_mode) | `bool` | `false` | -| [`mask_shape_bucket_floor_bytes`](#cfg-censorship-mask_shape_bucket_floor_bytes) | `usize` | `512` | -| [`mask_shape_bucket_cap_bytes`](#cfg-censorship-mask_shape_bucket_cap_bytes) | `usize` | `4096` | -| [`mask_shape_above_cap_blur`](#cfg-censorship-mask_shape_above_cap_blur) | `bool` | `false` | -| [`mask_shape_above_cap_blur_max_bytes`](#cfg-censorship-mask_shape_above_cap_blur_max_bytes) | `usize` | `512` | -| [`mask_relay_max_bytes`](#cfg-censorship-mask_relay_max_bytes) | `usize` | `5242880` | -| [`mask_classifier_prefetch_timeout_ms`](#cfg-censorship-mask_classifier_prefetch_timeout_ms) | `u64` | `5` | -| [`mask_timing_normalization_enabled`](#cfg-censorship-mask_timing_normalization_enabled) | `bool` | `false` | -| [`mask_timing_normalization_floor_ms`](#cfg-censorship-mask_timing_normalization_floor_ms) | `u64` | `0` | -| [`mask_timing_normalization_ceiling_ms`](#cfg-censorship-mask_timing_normalization_ceiling_ms) | `u64` | `0` | - - -- `tls_domain` - - **Constraints / validation**: Must be a non-empty domain name. Must not contain spaces or `/`. - - **Description**: Primary TLS domain used in FakeTLS handshake profile and as the default SNI domain. - - **Example**: - - ```toml - [censorship] - tls_domain = "example.com" - ``` - -- `tls_domains` - - **Constraints / validation**: `String[]`. When set, values are merged with `tls_domain` and deduplicated (primary `tls_domain` always stays first). - - **Description**: Additional TLS domains for generating multiple proxy links. - - **Example**: - - ```toml - [censorship] - tls_domain = "example.com" - tls_domains = ["example.net", "example.org"] - ``` - -- `unknown_sni_action` - - **Constraints / validation**: `"drop"` or `"mask"`. - - **Description**: Action for TLS ClientHello with unknown / non-configured SNI. - - **Example**: - - ```toml - [censorship] - unknown_sni_action = "drop" - ``` - -- `tls_fetch_scope` - - **Constraints / validation**: `String`. Value is trimmed during load; whitespace-only becomes empty. - - **Description**: Upstream scope tag used for TLS-front metadata fetches. Empty value keeps default upstream routing behavior. - - **Example**: - - ```toml - [censorship] - tls_fetch_scope = "fetch" - ``` - -- `tls_fetch` - - **Constraints / validation**: Table. See `[censorship.tls_fetch]` section below. - - **Description**: TLS-front metadata fetch strategy settings (bootstrap + refresh behavior for TLS emulation data). - - **Example**: - - ```toml - [censorship.tls_fetch] - strict_route = true - attempt_timeout_ms = 5000 - total_budget_ms = 15000 - ``` - -- `mask` - - **Constraints / validation**: `bool`. - - **Description**: Enables masking / fronting relay mode. - - **Example**: - - ```toml - [censorship] - mask = true - ``` - -- `mask_host` - - **Constraints / validation**: `String` (optional). - - If `mask_unix_sock` is set, `mask_host` must be omitted (mutually exclusive). - - If `mask_host` is not set and `mask_unix_sock` is not set, Telemt defaults `mask_host` to `tls_domain`. - - **Description**: Upstream mask host for TLS fronting relay. - - **Example**: - - ```toml - [censorship] - mask_host = "www.cloudflare.com" - ``` - -- `mask_port` - - **Constraints / validation**: `u16`. - - **Description**: Upstream mask port for TLS fronting relay. - - **Example**: - - ```toml - [censorship] - mask_port = 443 - ``` - -- `mask_unix_sock` - - **Constraints / validation**: `String` (optional). - - Must not be empty when set. - - Unix only; rejected on non-Unix platforms. - - On Unix, must be \(\le 107\) bytes (path length limit). - - Mutually exclusive with `mask_host`. - - **Description**: Unix socket path for mask backend instead of TCP `mask_host`/`mask_port`. - - **Example**: - - ```toml - [censorship] - mask_unix_sock = "/run/telemt/mask.sock" - ``` - -- `fake_cert_len` - - **Constraints / validation**: `usize`. When `tls_emulation = false` and the default value is in use, Telemt may randomize this at startup for variability. - - **Description**: Length of synthetic certificate payload when emulation data is unavailable. - - **Example**: - - ```toml - [censorship] - fake_cert_len = 2048 - ``` - -- `tls_emulation` - - **Constraints / validation**: `bool`. - - **Description**: Enables certificate/TLS behavior emulation from cached real fronts. - - **Example**: - - ```toml - [censorship] - tls_emulation = true - ``` - -- `tls_front_dir` - - **Constraints / validation**: `String`. - - **Description**: Directory path for TLS front cache storage. - - **Example**: - - ```toml - [censorship] - tls_front_dir = "tlsfront" - ``` - -- `server_hello_delay_min_ms` - - **Constraints / validation**: `u64` (milliseconds). - - **Description**: Minimum `server_hello` delay for anti-fingerprint behavior (ms). - - **Example**: - - ```toml - [censorship] - server_hello_delay_min_ms = 0 - ``` - -- `server_hello_delay_max_ms` - - **Constraints / validation**: `u64` (milliseconds). Must be \(<\) `timeouts.client_handshake * 1000`. - - **Description**: Maximum `server_hello` delay for anti-fingerprint behavior (ms). - - **Example**: - - ```toml - [timeouts] - client_handshake = 30 - - [censorship] - server_hello_delay_max_ms = 0 - ``` - -- `tls_new_session_tickets` - - **Constraints / validation**: `u8`. - - **Description**: Number of `NewSessionTicket` messages to emit after handshake. - - **Example**: - - ```toml - [censorship] - tls_new_session_tickets = 0 - ``` - -- `tls_full_cert_ttl_secs` - - **Constraints / validation**: `u64` (seconds). - - **Description**: TTL for sending full cert payload per (domain, client IP) tuple. - - **Example**: - - ```toml - [censorship] - tls_full_cert_ttl_secs = 90 - ``` - -- `alpn_enforce` - - **Constraints / validation**: `bool`. - - **Description**: Enforces ALPN echo behavior based on client preference. - - **Example**: - - ```toml - [censorship] - alpn_enforce = true - ``` - -- `mask_proxy_protocol` - - **Constraints / validation**: `u8`. `0` = disabled, `1` = v1 (text), `2` = v2 (binary). - - **Description**: Sends PROXY protocol header when connecting to mask backend, allowing the backend to see the real client IP. - - **Example**: - - ```toml - [censorship] - mask_proxy_protocol = 0 - ``` - -- `mask_shape_hardening` - - **Constraints / validation**: `bool`. - - **Description**: Enables client->mask shape-channel hardening by applying controlled tail padding to bucket boundaries on mask relay shutdown. - - **Example**: - - ```toml - [censorship] - mask_shape_hardening = true - ``` - -- `mask_shape_hardening_aggressive_mode` - - **Constraints / validation**: Requires `mask_shape_hardening = true`. - - **Description**: Opt-in aggressive shaping profile (stronger anti-classifier behavior with different shaping semantics). - - **Example**: - - ```toml - [censorship] - mask_shape_hardening = true - mask_shape_hardening_aggressive_mode = false - ``` - -- `mask_shape_bucket_floor_bytes` - - **Constraints / validation**: Must be `> 0`; must be `<= mask_shape_bucket_cap_bytes`. - - **Description**: Minimum bucket size used by shape-channel hardening. - - **Example**: - - ```toml - [censorship] - mask_shape_bucket_floor_bytes = 512 - ``` - -- `mask_shape_bucket_cap_bytes` - - **Constraints / validation**: Must be `>= mask_shape_bucket_floor_bytes`. - - **Description**: Maximum bucket size used by shape-channel hardening; traffic above cap is not bucket-padded further. - - **Example**: - - ```toml - [censorship] - mask_shape_bucket_cap_bytes = 4096 - ``` - -- `mask_shape_above_cap_blur` - - **Constraints / validation**: Requires `mask_shape_hardening = true`. - - **Description**: Adds bounded randomized tail bytes even when forwarded size already exceeds cap. - - **Example**: - - ```toml - [censorship] - mask_shape_hardening = true - mask_shape_above_cap_blur = false - ``` - -- `mask_shape_above_cap_blur_max_bytes` - - **Constraints / validation**: Must be `<= 1048576`. Must be `> 0` when `mask_shape_above_cap_blur = true`. - - **Description**: Maximum randomized extra bytes appended above cap when above-cap blur is enabled. - - **Example**: - - ```toml - [censorship] - mask_shape_above_cap_blur = true - mask_shape_above_cap_blur_max_bytes = 64 - ``` - -- `mask_relay_max_bytes` - - **Constraints / validation**: Must be `> 0`; must be `<= 67108864`. - - **Description**: Maximum relayed bytes per direction on unauthenticated masking fallback path. - - **Example**: - - ```toml - [censorship] - mask_relay_max_bytes = 5242880 - ``` - -- `mask_classifier_prefetch_timeout_ms` - - **Constraints / validation**: Must be within `[5, 50]` (milliseconds). - - **Description**: Timeout budget (ms) for extending fragmented initial classifier window on masking fallback. - - **Example**: - - ```toml - [censorship] - mask_classifier_prefetch_timeout_ms = 5 - ``` - -- `mask_timing_normalization_enabled` - - **Constraints / validation**: When `true`, requires `mask_timing_normalization_floor_ms > 0` and `mask_timing_normalization_ceiling_ms >= mask_timing_normalization_floor_ms`. Ceiling must be `<= 60000`. - - **Description**: Enables timing envelope normalization on masking outcomes. - - **Example**: - - ```toml - [censorship] - mask_timing_normalization_enabled = false - ``` - -- `mask_timing_normalization_floor_ms` - - **Constraints / validation**: Must be `> 0` when timing normalization is enabled; must be `<= mask_timing_normalization_ceiling_ms`. - - **Description**: Lower bound (ms) for masking outcome normalization target. - - **Example**: - - ```toml - [censorship] - mask_timing_normalization_floor_ms = 0 - ``` - -- `mask_timing_normalization_ceiling_ms` - - **Constraints / validation**: Must be `>= mask_timing_normalization_floor_ms`; must be `<= 60000`. - - **Description**: Upper bound (ms) for masking outcome normalization target. - - **Example**: - - ```toml - [censorship] - mask_timing_normalization_ceiling_ms = 0 - ``` - - -## [censorship.tls_fetch] - - -| Key | Type | Default | -| --- | ---- | ------- | -| [`profiles`](#cfg-censorship-tls_fetch-profiles) | `String[]` | `["modern_chrome_like", "modern_firefox_like", "compat_tls12", "legacy_minimal"]` | -| [`strict_route`](#cfg-censorship-tls_fetch-strict_route) | `bool` | `true` | -| [`attempt_timeout_ms`](#cfg-censorship-tls_fetch-attempt_timeout_ms) | `u64` | `5000` | -| [`total_budget_ms`](#cfg-censorship-tls_fetch-total_budget_ms) | `u64` | `15000` | -| [`grease_enabled`](#cfg-censorship-tls_fetch-grease_enabled) | `bool` | `false` | -| [`deterministic`](#cfg-censorship-tls_fetch-deterministic) | `bool` | `false` | -| [`profile_cache_ttl_secs`](#cfg-censorship-tls_fetch-profile_cache_ttl_secs) | `u64` | `600` | - - -- `profiles` - - **Constraints / validation**: `String[]`. Empty list falls back to defaults; values are deduplicated preserving order. - - **Description**: Ordered ClientHello profile fallback chain for TLS-front metadata fetch. - - **Example**: - - ```toml - [censorship.tls_fetch] - profiles = ["modern_chrome_like", "compat_tls12"] - ``` - -- `strict_route` - - **Constraints / validation**: `bool`. - - **Description**: When `true` and an upstream route is configured, TLS fetch fails closed on upstream connect errors instead of falling back to direct TCP. - - **Example**: - - ```toml - [censorship.tls_fetch] - strict_route = true - ``` - -- `attempt_timeout_ms` - - **Constraints / validation**: Must be `> 0` (milliseconds). - - **Description**: Timeout budget per one TLS-fetch profile attempt (ms). - - **Example**: - - ```toml - [censorship.tls_fetch] - attempt_timeout_ms = 5000 - ``` - -- `total_budget_ms` - - **Constraints / validation**: Must be `> 0` (milliseconds). - - **Description**: Total wall-clock budget across all TLS-fetch attempts (ms). - - **Example**: - - ```toml - [censorship.tls_fetch] - total_budget_ms = 15000 - ``` - -- `grease_enabled` - - **Constraints / validation**: `bool`. - - **Description**: Enables GREASE-style random values in selected ClientHello extensions for fetch traffic. - - **Example**: - - ```toml - [censorship.tls_fetch] - grease_enabled = false - ``` - -- `deterministic` - - **Constraints / validation**: `bool`. - - **Description**: Enables deterministic ClientHello randomness for debugging/tests. - - **Example**: - - ```toml - [censorship.tls_fetch] - deterministic = false - ``` - -- `profile_cache_ttl_secs` - - **Constraints / validation**: `u64` (seconds). `0` disables cache. - - **Description**: TTL for winner-profile cache entries used by TLS fetch path. - - **Example**: - - ```toml - [censorship.tls_fetch] - profile_cache_ttl_secs = 600 - ``` - - -### Shape-channel hardening notes (`[censorship]`) - -These parameters are designed to reduce one specific fingerprint source during masking: the exact number of bytes sent from proxy to `mask_host` for invalid or probing traffic. - -Without hardening, a censor can often correlate probe input length with backend-observed length very precisely (for example: `5 + body_sent` on early TLS reject paths). That creates a length-based classifier signal. - -When `mask_shape_hardening = true`, Telemt pads the **client->mask** stream tail to a bucket boundary at relay shutdown: - -- Total bytes sent to mask are first measured. -- A bucket is selected using powers of two starting from `mask_shape_bucket_floor_bytes`. -- Padding is added only if total bytes are below `mask_shape_bucket_cap_bytes`. -- If bytes already exceed cap, no extra padding is added. - -This means multiple nearby probe sizes collapse into the same backend-observed size class, making active classification harder. - -What each parameter changes in practice: - -- `mask_shape_hardening` - Enables or disables this entire length-shaping stage on the fallback path. - When `false`, backend-observed length stays close to the real forwarded probe length. - When `true`, clean relay shutdown can append random padding bytes to move the total into a bucket. -- `mask_shape_bucket_floor_bytes` - Sets the first bucket boundary used for small probes. - Example: with floor `512`, a malformed probe that would otherwise forward `37` bytes can be expanded to `512` bytes on clean EOF. - Larger floor values hide very small probes better, but increase egress cost. -- `mask_shape_bucket_cap_bytes` - Sets the largest bucket Telemt will pad up to with bucket logic. - Example: with cap `4096`, a forwarded total of `1800` bytes may be padded to `2048` or `4096` depending on the bucket ladder, but a total already above `4096` will not be bucket-padded further. - Larger cap values increase the range over which size classes are collapsed, but also increase worst-case overhead. -- Clean EOF matters in conservative mode - In the default profile, shape padding is intentionally conservative: it is applied on clean relay shutdown, not on every timeout/drip path. - This avoids introducing new timeout-tail artifacts that some backends or tests interpret as a separate fingerprint. - -Practical trade-offs: - -- Better anti-fingerprinting on size/shape channel. -- Slightly higher egress overhead for small probes due to padding. -- Behavior is intentionally conservative and enabled by default. - -Recommended starting profile: - -- `mask_shape_hardening = true` (default) -- `mask_shape_bucket_floor_bytes = 512` -- `mask_shape_bucket_cap_bytes = 4096` - -### Aggressive mode notes (`[censorship]`) - -`mask_shape_hardening_aggressive_mode` is an opt-in profile for higher anti-classifier pressure. - -- Default is `false` to preserve conservative timeout/no-tail behavior. -- Requires `mask_shape_hardening = true`. -- When enabled, backend-silent non-EOF masking paths may be shaped. -- When enabled together with above-cap blur, the random extra tail uses `[1, max]` instead of `[0, max]`. - -What changes when aggressive mode is enabled: - -- Backend-silent timeout paths can be shaped - In default mode, a client that keeps the socket half-open and times out will usually not receive shape padding on that path. - In aggressive mode, Telemt may still shape that backend-silent session if no backend bytes were returned. - This is specifically aimed at active probes that try to avoid EOF in order to preserve an exact backend-observed length. -- Above-cap blur always adds at least one byte - In default mode, above-cap blur may choose `0`, so some oversized probes still land on their exact base forwarded length. - In aggressive mode, that exact-base sample is removed by construction. -- Tradeoff - Aggressive mode improves resistance to active length classifiers, but it is more opinionated and less conservative. - If your deployment prioritizes strict compatibility with timeout/no-tail semantics, leave it disabled. - If your threat model includes repeated active probing by a censor, this mode is the stronger profile. - -Use this mode only when your threat model prioritizes classifier resistance over strict compatibility with conservative masking semantics. - -### Above-cap blur notes (`[censorship]`) - -`mask_shape_above_cap_blur` adds a second-stage blur for very large probes that are already above `mask_shape_bucket_cap_bytes`. - -- A random tail in `[0, mask_shape_above_cap_blur_max_bytes]` is appended in default mode. -- In aggressive mode, the random tail becomes strictly positive: `[1, mask_shape_above_cap_blur_max_bytes]`. -- This reduces exact-size leakage above cap at bounded overhead. -- Keep `mask_shape_above_cap_blur_max_bytes` conservative to avoid unnecessary egress growth. - -Operational meaning: - -- Without above-cap blur - A probe that forwards `5005` bytes will still look like `5005` bytes to the backend if it is already above cap. -- With above-cap blur enabled - That same probe may look like any value in a bounded window above its base length. - Example with `mask_shape_above_cap_blur_max_bytes = 64`: - backend-observed size becomes `5005..5069` in default mode, or `5006..5069` in aggressive mode. -- Choosing `mask_shape_above_cap_blur_max_bytes` - Small values reduce cost but preserve more separability between far-apart oversized classes. - Larger values blur oversized classes more aggressively, but add more egress overhead and more output variance. - -### Timing normalization envelope notes (`[censorship]`) - -`mask_timing_normalization_enabled` smooths timing differences between masking outcomes by applying a target duration envelope. - -- A random target is selected in `[mask_timing_normalization_floor_ms, mask_timing_normalization_ceiling_ms]`. -- Fast paths are delayed up to the selected target. -- Slow paths are not forced to finish by the ceiling (the envelope is best-effort shaping, not truncation). - -Recommended starting profile for timing shaping: - -- `mask_timing_normalization_enabled = true` -- `mask_timing_normalization_floor_ms = 180` -- `mask_timing_normalization_ceiling_ms = 320` - -If your backend or network is very bandwidth-constrained, reduce cap first. If probes are still too distinguishable in your environment, increase floor gradually. - -## [access] - - -| Key | Type | Default | -| --- | ---- | ------- | -| [`users`](#cfg-access-users) | `Map` | `{"default": "000…000"}` | -| [`user_ad_tags`](#cfg-access-user_ad_tags) | `Map` | `{}` | -| [`user_max_tcp_conns`](#cfg-access-user_max_tcp_conns) | `Map` | `{}` | -| [`user_max_tcp_conns_global_each`](#cfg-access-user_max_tcp_conns_global_each) | `usize` | `0` | -| [`user_expirations`](#cfg-access-user_expirations) | `Map>` | `{}` | -| [`user_data_quota`](#cfg-access-user_data_quota) | `Map` | `{}` | -| [`user_max_unique_ips`](#cfg-access-user_max_unique_ips) | `Map` | `{}` | -| [`user_max_unique_ips_global_each`](#cfg-access-user_max_unique_ips_global_each) | `usize` | `0` | -| [`user_max_unique_ips_mode`](#cfg-access-user_max_unique_ips_mode) | `"active_window"`, `"time_window"`, or `"combined"` | `"active_window"` | -| [`user_max_unique_ips_window_secs`](#cfg-access-user_max_unique_ips_window_secs) | `u64` | `30` | -| [`replay_check_len`](#cfg-access-replay_check_len) | `usize` | `65536` | -| [`replay_window_secs`](#cfg-access-replay_window_secs) | `u64` | `120` | -| [`ignore_time_skew`](#cfg-access-ignore_time_skew) | `bool` | `false` | - - -- `users` - - **Constraints / validation**: Must not be empty (at least one user must exist). Each value must be **exactly 32 hex characters**. - - **Description**: User credentials map used for client authentication. Keys are user names; values are MTProxy secrets. - - **Example**: - - ```toml - [access.users] - alice = "00112233445566778899aabbccddeeff" - bob = "0123456789abcdef0123456789abcdef" - ``` - -- `user_ad_tags` - - **Constraints / validation**: Each value must be **exactly 32 hex characters** (same format as `general.ad_tag`). An all-zero tag is allowed but logs a warning. - - **Description**: Per-user sponsored-channel ad tag override. When a user has an entry here, it takes precedence over `general.ad_tag`. - - **Example**: - - ```toml - [general] - ad_tag = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - - [access.user_ad_tags] - alice = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" - ``` - -- `user_max_tcp_conns` - - **Constraints / validation**: `Map`. - - **Description**: Per-user maximum concurrent TCP connections. - - **Example**: - - ```toml - [access.user_max_tcp_conns] - alice = 500 - ``` - -- `user_max_tcp_conns_global_each` - - **Constraints / validation**: `usize`. `0` disables the inherited limit. - - **Description**: Global per-user maximum concurrent TCP connections, applied when a user has **no positive** entry in `[access.user_max_tcp_conns]` (a missing key, or a value of `0`, both fall through to this setting). Per-user limits greater than `0` in `user_max_tcp_conns` take precedence. - - **Example**: - - ```toml - [access] - user_max_tcp_conns_global_each = 200 - - [access.user_max_tcp_conns] - alice = 500 # uses 500, not the global cap - # bob has no entry → uses 200 - ``` - -- `user_expirations` - - **Constraints / validation**: `Map>`. Each value must be a valid RFC3339 / ISO-8601 datetime. - - **Description**: Per-user account expiration timestamps (UTC). - - **Example**: - - ```toml - [access.user_expirations] - alice = "2026-12-31T23:59:59Z" - ``` - -- `user_data_quota` - - **Constraints / validation**: `Map`. - - **Description**: Per-user traffic quota in bytes. - - **Example**: - - ```toml - [access.user_data_quota] - alice = 1073741824 # 1 GiB - ``` - -- `user_max_unique_ips` - - **Constraints / validation**: `Map`. - - **Description**: Per-user unique source IP limits. - - **Example**: - - ```toml - [access.user_max_unique_ips] - alice = 16 - ``` - -- `user_max_unique_ips_global_each` - - **Constraints / validation**: `usize`. `0` disables the inherited limit. - - **Description**: Global per-user unique IP limit applied when a user has no individual override in `[access.user_max_unique_ips]`. - - **Example**: - - ```toml - [access] - user_max_unique_ips_global_each = 8 - ``` - -- `user_max_unique_ips_mode` - - **Constraints / validation**: Must be one of `"active_window"`, `"time_window"`, `"combined"`. - - **Description**: Unique source IP limit accounting mode. - - **Example**: - - ```toml - [access] - user_max_unique_ips_mode = "active_window" - ``` - -- `user_max_unique_ips_window_secs` - - **Constraints / validation**: Must be `> 0`. - - **Description**: Window size (seconds) used by unique-IP accounting modes that include a time window (`"time_window"` and `"combined"`). - - **Example**: - - ```toml - [access] - user_max_unique_ips_window_secs = 30 - ``` - -- `replay_check_len` - - **Constraints / validation**: `usize`. - - **Description**: Replay-protection storage length (number of entries tracked for duplicate detection). - - **Example**: - - ```toml - [access] - replay_check_len = 65536 - ``` - -- `replay_window_secs` - - **Constraints / validation**: `u64`. - - **Description**: Replay-protection time window in seconds. - - **Example**: - - ```toml - [access] - replay_window_secs = 120 - ``` - -- `ignore_time_skew` - - **Constraints / validation**: `bool`. - - **Description**: Disables client/server timestamp skew checks in replay validation when enabled. - - **Example**: - - ```toml - [access] - ignore_time_skew = false - ``` - - -## [[upstreams]] - - -| Key | Type | Default | -| --- | ---- | ------- | -| [`type`](#cfg-upstreams-type) | `"direct"`, `"socks4"`, `"socks5"`, or `"shadowsocks"` | — | -| [`weight`](#cfg-upstreams-weight) | `u16` | `1` | -| [`enabled`](#cfg-upstreams-enabled) | `bool` | `true` | -| [`scopes`](#cfg-upstreams-scopes) | `String` | `""` | -| [`interface`](#cfg-upstreams-interface) | `String` | — | -| [`bind_addresses`](#cfg-upstreams-bind_addresses) | `String[]` | — | -| [`url`](#cfg-upstreams-url) | `String` | — | -| [`address`](#cfg-upstreams-address) | `String` | — | -| [`user_id`](#cfg-upstreams-user_id) | `String` | — | -| [`username`](#cfg-upstreams-username) | `String` | — | -| [`password`](#cfg-upstreams-password) | `String` | — | - - -- `type` - - **Constraints / validation**: Required field. Must be one of: `"direct"`, `"socks4"`, `"socks5"`, `"shadowsocks"`. - - **Description**: Selects the upstream transport implementation for this `[[upstreams]]` entry. - - **Example**: - - ```toml - [[upstreams]] - type = "direct" - - [[upstreams]] - type = "socks5" - address = "127.0.0.1:9050" - - [[upstreams]] - type = "shadowsocks" - url = "ss://2022-blake3-aes-256-gcm:BASE64PASSWORD@127.0.0.1:8388" - ``` - -- `weight` - - **Constraints / validation**: `u16` (0..=65535). - - **Description**: Base weight used by weighted-random upstream selection (higher = chosen more often). - - **Example**: - - ```toml - [[upstreams]] - type = "direct" - weight = 10 - ``` - -- `enabled` - - **Constraints / validation**: `bool`. - - **Description**: When `false`, this entry is ignored and not used for any upstream selection. - - **Example**: - - ```toml - [[upstreams]] - type = "socks5" - address = "127.0.0.1:9050" - enabled = false - ``` - -- `scopes` - - **Constraints / validation**: `String`. Comma-separated list; whitespace is trimmed during matching. - - **Description**: Scope tags used for request-level upstream filtering. If a request specifies a scope, only upstreams whose `scopes` contains that tag can be selected. If a request does not specify a scope, only upstreams with empty `scopes` are eligible. - - **Example**: - - ```toml - [[upstreams]] - type = "socks4" - address = "10.0.0.10:1080" - scopes = "me, fetch, dc2" - ``` - -- `interface` - - **Constraints / validation**: `String` (optional). - - For `"direct"`: may be an IP address (used as explicit local bind) or an OS interface name (resolved to an IP at runtime; Unix only). - - For `"socks4"`/`"socks5"`: supported only when `address` is an `IP:port` literal; when `address` is a hostname, interface binding is ignored. - - For `"shadowsocks"`: passed to the shadowsocks connector as an optional outbound bind hint. - - **Description**: Optional outbound interface / local bind hint for the upstream connect socket. - - **Example**: - - ```toml - [[upstreams]] - type = "direct" - interface = "eth0" - - [[upstreams]] - type = "socks5" - address = "203.0.113.10:1080" - interface = "192.0.2.10" # explicit local bind IP - ``` - -- `bind_addresses` - - **Constraints / validation**: `String[]` (optional). Applies only to `type = "direct"`. - - Each entry should be an IP address string. - - At runtime, Telemt selects an address that matches the target family (IPv4 vs IPv6). If `bind_addresses` is set and none match the target family, the connect attempt fails. - - **Description**: Explicit local source addresses for outgoing direct TCP connects. When multiple addresses are provided, selection is round-robin. - - **Example**: - - ```toml - [[upstreams]] - type = "direct" - bind_addresses = ["192.0.2.10", "192.0.2.11"] - ``` - -- `url` - - **Constraints / validation**: Applies only to `type = "shadowsocks"`. - - Must be a valid Shadowsocks URL accepted by the `shadowsocks` crate. - - Shadowsocks plugins are not supported. - - Requires `general.use_middle_proxy = false` (shadowsocks upstreams are rejected in ME mode). - - **Description**: Shadowsocks server URL used for connecting to Telegram via a Shadowsocks relay. - - **Example**: - - ```toml - [general] - use_middle_proxy = false - - [[upstreams]] - type = "shadowsocks" - url = "ss://2022-blake3-aes-256-gcm:BASE64PASSWORD@127.0.0.1:8388" - ``` - -- `address` - - **Constraints / validation**: Required for `type = "socks4"` and `type = "socks5"`. Must be `host:port` or `ip:port`. - - **Description**: SOCKS proxy server endpoint used for upstream connects. - - **Example**: - - ```toml - [[upstreams]] - type = "socks5" - address = "127.0.0.1:9050" - ``` - -- `user_id` - - **Constraints / validation**: `String` (optional). Only for `type = "socks4"`. - - **Description**: SOCKS4 CONNECT user ID. Note: when a request scope is selected, Telemt may override this with the selected scope value. - - **Example**: - - ```toml - [[upstreams]] - type = "socks4" - address = "127.0.0.1:1080" - user_id = "telemt" - ``` - -- `username` - - **Constraints / validation**: `String` (optional). Only for `type = "socks5"`. - - **Description**: SOCKS5 username (for username/password authentication). Note: when a request scope is selected, Telemt may override this with the selected scope value. - - **Example**: - - ```toml - [[upstreams]] - type = "socks5" - address = "127.0.0.1:9050" - username = "alice" - ``` - -- `password` - - **Constraints / validation**: `String` (optional). Only for `type = "socks5"`. - - **Description**: SOCKS5 password (for username/password authentication). Note: when a request scope is selected, Telemt may override this with the selected scope value. - - **Example**: - - ```toml - [[upstreams]] - type = "socks5" - address = "127.0.0.1:9050" - username = "alice" - password = "secret" - ``` - -