You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ADN-DMR-Peer-Server/docs/en/server/user-guide/hotspot-proxy.md

152 lines
7.5 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# Hotspot proxy (integrated)
**ADN DMR Peer Server** includes an **integrated hotspot proxy**: one process (`adn-server.py`) accepts Homebrew (HBP) from many hotspots on a single UDP port and **injects** traffic into a configured **MASTER** system. You do **not** need a separate **`adn-proxy`** process when this mode is enabled.
Configuration lives in **`adn-server.yaml`** under **`PROXY`** and optional **`SELF_SERVICE`** (same MySQL **`Clients`** table as **adn-monitor**).
---
## When to use it
| Deployment | What to run |
|------------|-------------|
| **Typical ADN stack** (monitor + dashboard + many Pi-Star hotspots) | **`adn-server.py`** with **`PROXY`** + **`SELF_SERVICE`**. |
The integrated proxy uses **fan-in**: hotspots only need **`PROXY.LISTEN_PORT`** (e.g. **62031**). The target **MASTER** is **inject-only** — it does **not** bind its own UDP port for that system (no per-hotspot port range on the server host).
```mermaid
flowchart LR
HS1[Hotspot A] -->|UDP HBP| LP[PROXY LISTEN_PORT]
HS2[Hotspot B] -->|UDP HBP| LP
LP -->|inject| MASTER[TARGET_SYSTEM MASTER]
```
---
## Optional dependency (self-service)
MySQL self-service requires **`mysqlclient`**:
```bash
pip install -e ".[selfservice]"
```
If **`USE_SELFSERVICE: true`** but **`mysqlclient`** is missing, startup fails with a clear error. Set **`USE_SELFSERVICE: false`** to run the proxy without DB (no dashboard-driven **RPTO** updates).
---
## `PROXY` keys
| Key | Role |
|-----|------|
| **LISTEN_PORT** | UDP port where **hotspots** connect (the address users configure on the hotspot). |
| **LISTEN_IP** | Bind address; empty = all interfaces. |
| **TARGET_SYSTEM** | Name of the **`SYSTEMS`** **MASTER** entry that receives injected HBP (must exist and be **ENABLED**). |
| **TIMEOUT** | Idle session timeout (seconds); expired sessions are torn down on the MASTER. |
| **DEBUG** | Verbose packet logging. |
| **CLIENT_INFO** | Log connect/disconnect per radio ID. |
| **BLACK_LIST** | Block listed radio IDs. |
| **IP_BLACK_LIST** | Block source IPs (with optional expiry). |
There is **no** **`MASTER`**, **`PORT`**, or **`GENERATOR`** in integrated **`PROXY`** — those belong to the legacy standalone proxy. The target MASTER uses **`MAX_PEERS`** (not a UDP port range) to cap concurrent hotspot sessions.
Example (from `adn-server.example.yaml`):
```yaml
PROXY:
LISTEN_PORT: 62031
LISTEN_IP: ""
TARGET_SYSTEM: SYSTEM
TIMEOUT: 30
DEBUG: false
CLIENT_INFO: true
BLACK_LIST: []
IP_BLACK_LIST: {}
```
### Inject-only target MASTER
When **`PROXY.TARGET_SYSTEM`** points at a system (e.g. **`SYSTEM`**), startup **removes** **`IP`** / **`PORT`** from that MASTER block. Hotspots never connect directly to the conference port; all HBP enters via **`LISTEN_PORT`**.
Set **`MAX_PEERS`** on the target MASTER to the maximum concurrent proxied hotspots (e.g. **102**). Other MASTER systems (e.g. **ECHO**, **D-APRS**) keep normal **`IP`** / **`PORT`** binds if they are not the proxy target.
---
## `SELF_SERVICE` keys
Same semantics as **`adn-monitor.yaml`** — shared **`Clients`** table, **`modified`** flag, **RPTO** toward the MASTER.
| Key | Role |
|-----|------|
| **USE_SELFSERVICE** | Enable MySQL-backed options sync (`true` / `false`). |
| **PBKDF2_SALT**, **PBKDF2_ITERATIONS** | Must **match** monitor/backend for password hashing. |
MariaDB connection settings live in the top-level **`DATABASE`** block (shared with dynamic TG persistence) — see [Configuration](configuration.md#database-mariadb).
On startup the server logs **`(SELF_SERVICE) Database connection test: OK`** and **`(SELF_SERVICE) Enabled`** when the pool connects. Self-service runs **asynchronously**; voice forwarding is not blocked on DB latency.
Details of the dashboard flow: [Self-service](../../monitor/self-service.md).
---
## Multi-hotspot behaviour
- Each authenticated hotspot is a **peer** on the inject-only MASTER with its own **OPTIONS** (static TGs). **Repeat** and monitor fan-out respect **per-peer OPTIONS** — traffic for a TG is not sent to peers that did not select it.
- **Parrot / echo** talkgroups **9990–9999** are **point-to-point**: they bypass the OPTIONS filter and return **only** to the exact peer that originated the call (`RX_PEER` on the slot), never to other hotspots of the same user. With a single connected peer, it is delivered to that peer (legacy behaviour). See [Echo — Multi-hotspot behaviour](echo.md#multi-hotspot-behaviour-inject-only-proxy) and [Special numbers](special-numbers.md).
---
## OPTIONS line behaviour
After login (RPTL → RPTK → RPTC), the proxy starts a **10 s timer** waiting for
the hotspot's **RPTO** packet with its **OPTIONS** line. What the hotspot sends
(or does not send) determines **who is the source of truth** for the peer's
static talkgroups:
| Hotspot sends in the RPTO | Who defines the TGs | Behaviour |
|---|---|---|
| `OPTIONS=PASS=xxxxxx;` | **Self-service** (dashboard) | The proxy processes the `PASS=`, verifies the individual password (PBKDF2 against `Clients.psswd`), marks the peer as authenticated, cancels the 10 s timer, and pushes the DB-configured TGs to the master. The user **can** log in by password and auto-login by IP on the dashboard. |
| `OPTIONS=` (empty) | **Self-service** (dashboard) | The proxy reads the TGs from the DB and injects them to the master. The user can **only** use auto-login by IP on the dashboard (no password). |
| **No RPTO at all** (10 s timer expires) | **Self-service** (dashboard) | The proxy assumes the hotspot has no OPTIONS of its own and falls back to the DB. Same effect as `OPTIONS=` empty. |
| `OPTIONS=TS2=730444;SINGLE=0;` (content without `PASS=`) | **The hotspot itself** | The master takes the TGs **directly from the OPTIONS line**. The DB is ignored. The user can **only** use auto-login by IP on the dashboard (no password). |
**Key rule:** self-service is the source of truth **unless** the hotspot sends
explicit content (TGs, SINGLE, TIMER, etc.) in its OPTIONS line. In that case,
what the hotspot says **takes precedence** and self-service is ignored.
### Individual password and dashboard login
- If the hotspot **never** sends `PASS=` in its RPTO, the user **cannot** log in
to the dashboard with a password. They can only use **auto-login by IP**
(if their IP matches `Clients.host`).
- To enable password login on the dashboard, the hotspot must send
`OPTIONS=PASS=your_password;` in its configuration (Pi-Star / WPSD / MMDVM
`optsfile`). The password must match the PBKDF2 hash stored in `Clients.psswd`.
- The `PASS=` flow is what activates bidirectional sync: the proxy stores the
hash, notes the `modified` flag, and pushes the DB-configured TGs to the master.
---
## Hot reload (`SIGHUP`)
**Applied without restart** (active proxy sessions stay up):
- **`PROXY`:** **TIMEOUT**, **DEBUG**, **CLIENT_INFO**, **BLACK_LIST**, **IP_BLACK_LIST**
- **`SELF_SERVICE`:** merged into config (credential changes take effect on new DB operations; loops are not restarted on reload)
**Requires full process restart:**
- **`PROXY.LISTEN_PORT`** / **`LISTEN_IP`** (bind change is logged and ignored at reload)
- **`PROXY.TARGET_SYSTEM`**
- Enabling or disabling **`USE_SELFSERVICE`** after startup (start/stop MySQL loops)
See [Configuration — hot reload](configuration.md#hot-reload-adn-serveryaml).
---
## See also
- [Configuration](configuration.md) — full **`adn-server.yaml`** reference.
- [Monitoring and reports](monitoring.md) — TCP reports, dashboard, log rotation.
- [Self-service](../../monitor/self-service.md) — **`Clients`**, **RPTO** timing.

Powered by TurnKey Linux.