115 lines
4.8 KiB
Markdown
115 lines
4.8 KiB
Markdown
# 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).
|