# MVP Gaps & RFC Notes (STUN/TURN) This document lists **intentionally simplified / missing pieces** in the current `niom-turn` MVP, with a short impact note and a code anchor for each. > Goal: clarity on what is already interoperable, and what still needs work for production / broader interop. --- ## 1) STUN Binding ist minimal **Current state** - The server answers `METHOD_BINDING` with "Success" and includes `XOR-MAPPED-ADDRESS` (IPv4 + IPv6): [src/stun.rs](../src/stun.rs) **Impact** - This improves interop for STUN diagnostics / ICE NAT discovery. --- ## 2) IPv6 support (historical note) **Current state** - XOR-Address encoding/decoding supports IPv4 **and** IPv6 (XOR key: magic cookie + transaction ID): [src/stun.rs](../src/stun.rs) **Impact** - TURN/STUN can correctly handle IPv6 addresses in XOR-ADDRESS attributes. --- ## 3) TURN Allocate is heavily simplified **Current state** - `allocate_for` always binds a UDP relay on `0.0.0.0:0`: [src/alloc.rs](../src/alloc.rs) - `REQUESTED-TRANSPORT` is not evaluated (there is only UDP relay). - Additional RFC TURN options (EVEN-PORT, RESERVATION-TOKEN, DONT-FRAGMENT, etc.) are not implemented. **Impact** - The MVP covers the common UDP relay case, but not the full TURN feature matrix. --- ## 4) Data plane: UDP relay yes, TCP relay no **Current state** - The relay data path is UDP-only (the relay socket is `tokio::net::UdpSocket`): [src/alloc.rs](../src/alloc.rs) - The TLS listener reuses the control-plane logic; there is no separate TCP relay: [src/tls.rs](../src/tls.rs) **Impact** - `turns:` (TLS) supports the control plane, and for stream clients the **return path** (server → client) is delivered over the stream as Data Indications / ChannelData. - However, the actual relay socket towards the peer is still UDP-only. A true TURN-over-TCP/TLS data plane with a dedicated TCP relay path is not implemented. --- ## 5) Allocation and timer behaviour is MVP-style **Current state** - Allocation lifetime is set/clamped via `refresh_allocation`: [src/alloc.rs](../src/alloc.rs) - `remove_allocation` removes the entry. - The relay task (spawned in `allocate_for`) can continue running and primarily checks whether the allocation still exists: [src/alloc.rs](../src/alloc.rs) **Impact** - With many allocations, this can lead to unnecessary background tasks (resource management / backpressure is minimal). --- ## 6) Permissions & channel bindings are minimal **Current state** - Permission TTL is static (300s) and is only renewed by sending `CreatePermission` again: [src/alloc.rs](../src/alloc.rs) - Channel bindings use the same TTL value (`PERMISSION_LIFETIME`): [src/alloc.rs](../src/alloc.rs) **Impact** - Functionally OK for an MVP, but not necessarily RFC-exact in all details (separate lifetime rules / refresh strategies are common). --- ## 7) MESSAGE-INTEGRITY/FINGERPRINT **Current state** - `MESSAGE-INTEGRITY` is validated in an RFC-compatible way (HMAC-SHA1 over the message up to and including the MI attribute; the header length is set to the “end of MI”, which is compatible with subsequent attributes like `FINGERPRINT`): [src/stun.rs](../src/stun.rs) - For TURN responses after successful authentication, the server appends `MESSAGE-INTEGRITY` and sets `FINGERPRINT` as the last attribute: [src/server.rs](../src/server.rs), [src/turn_stream.rs](../src/turn_stream.rs) - `FINGERPRINT` is appended as the last attribute on all STUN messages built by the server, and validated on inbound messages (if present): [src/stun.rs](../src/stun.rs) **Impact** - Better browser/ICE interop and mild hardening (messages with invalid `FINGERPRINT` are dropped). --- ## 8) Observability / limits / hardening (still missing) **Current state** - No quotas per user/IP, no rate limits, no bandwidth limits per allocation. - Credential store is in-memory (test/dev): [src/auth.rs](../src/auth.rs), trait: [src/traits/credential_store.rs](../src/traits/credential_store.rs) **Impact** - For production you likely want limits, persistent credentials, monitoring/metrics, and stricter error handling. --- ## 9) More RFC corners (not implemented) Typical items that are missing / still open in the MVP: - Full attribute coverage (e.g. UNKNOWN-ATTRIBUTES, SOFTWARE, etc.) - Fully RFC-accurate STUN/TURN class/method encoding (here intentionally simplified via `METHOD | CLASS_*`): [src/constants.rs](../src/constants.rs) - IPv6 hairpinning edge cases, NAT-related interop edge cases --- ## What is already covered well - End-to-end UDP TURN core: `Allocate` → `CreatePermission` → `Send`/ChannelData → return path as Data Indication/ChannelData. - Long-term auth (realm/nonce + MI) with clear 401/438/437/403 paths. - TLS listener (control plane) with STUN framing over TCP/TLS. See also the integration tests: [tests/udp_turn.rs](../tests/udp_turn.rs) and [tests/tls_turn.rs](../tests/tls_turn.rs).