4.17.0
Upgrade notes
Three defaults changed in this release. Read these before upgrading.
DTLS listeners are now opt-in (#2026). The server no longer starts DTLS
listeners unless --dtls is given. A deployment that relied on DTLS being up by
default will stop serving DTLS clients after the upgrade, without an error. The
deprecated --no-dtls / --no-dtls=false spellings are still accepted and now
warn.
Stateless nonce is on by default (#2036). Challenge nonces are authenticated
timestamp cookies rather than a random value stored per session, so
unauthenticated UDP requests are answered from the listener without allocating a
session. Two consequences:
- The challenge
NONCEis now 24 characters instead of 16. RFC 8489 requires
clients to treat it as an opaque string of up to 128 characters, so compliant
clients are unaffected.--stateless-nonce=falserestores the previous
behaviour. - The signing key is generated per process, so a restart costs each client one
438re-authentication round-trip, as does a retry that lands on a different
instance behind a load balancer. Set--stateless-nonce-secretto the same
value across a fleet to avoid both.
The default log line changed (#2031, #2033). Timestamps are ISO-8601 with
millisecond precision, the thread id is gone, the field delimiter is a single
space instead of :, and each record now occupies exactly one line. Log
shippers and any downstream parsing will need updating; the default line is now:
2026-08-02T17:32:31.297-0700 INFO Listener address to use: 127.0.0.1
--new-log-timestamp=false restores the legacy seconds-since-start counter.
Security fixes
Three fixes in this release came through the private advisory process. Advisories
are still in preparation; this section will be updated with their identifiers
once they are published.
- Allocation quotas could be bypassed under
--mobility. An authenticated
client that repeatedly created a mobility allocation and disconnected had its
quota released while the allocation, its relay socket and its ticket stayed
alive, letting one user hold allocations well past--user-quota/
--total-quotauntil the relay port range was exhausted. The charge is now
held until final teardown. Regression coverage:
examples/run_tests_mobility_quota.sh. - DTLS allocated per-peer state before the cookie was verified. A
ClientHello from an unverified (and possibly spoofed) source caused a full
SSL, socket and session allocation before the source had proved return
routability. The cookie exchange is now performed statelessly via
DTLSv1_listen(), so an unanswered ClientHello leaves no state behind. This
completes the hardening begun in 4.16.0 (#2010, #2012, #2013). EVEN-PORTwith the R bit clear leaked relay ports. The odd sibling port
was reserved even when the client had not asked for it and was never released,
so a server would eventually refuse new allocations that requested
EVEN-PORT.
Upgrading is recommended for anyone running --mobility, DTLS, or accepting
EVEN-PORT allocations.
What's Changed
- free the secrets list on the get_user_key error paths by @alhudz in #2019
- Binding stateless fastpath by @eakraly in #2024
- Worktree stateless nonce mi fastpath by @eakraly in #2025
- Start the DTLS listeners only when --dtls is given by @eakraly in #2026
- Do not ask the kernel for an outgoing IP TTL of zero by @eakraly in #2027
- Drop --simple-log where it is a no-op alongside --log-file=stdout by @eakraly in #2028
- Remove syslog from the Docker Compose turnserver.conf by @eakraly in #2029
- Fix localtime() data race in the logger by @eakraly in #2030
- Log format: ISO-8601 timestamp by default, no thread id, space delimiter by @eakraly in #2031
- Keep the legacy random nonce at 16 chars by @eakraly in #2032
- Emit exactly one log line per record by @eakraly in #2033
- Enable stateless nonce by default by @eakraly in #2036
Full Changelog: 4.16.0...4.17.0