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

7.5 KiB

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).

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:

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):

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.

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.


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 and Special numbers.

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.


See also

Powered by TurnKey Linux.