Add encrypted UDP voice (OCB2-AES128) with TCP fallback

- Port of Mumble's CryptStateOCB2 (XEX* counter-measures, late/lost/replay
  handling, nonce resync), verified against Mumble's OCB2 test vectors
- UDP channel per connection in the main process, to the address the TLS
  connection reached; used only while the server answers UDP pings, falls back
  to the TCP tunnel automatically; "voice over TCP only" setting
- Voice statistics show the live transport
- Information dialog no longer infers the transport from ping counters
- Message box: no padding, input fills the bar; Edit HTML only in descriptions

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-01 01:14:36 +02:00
co-authored by Claude Opus 5.5
parent 9a3aeb29ad
commit b44b8230d4
19 changed files with 616 additions and 48 deletions
+4 -3
View File
@@ -79,9 +79,10 @@
<dl>
<dt>Online for</dt><dd>{duration(stats.onlinesecs != null ? stats.onlinesecs + since : undefined)}</dd>
{#if stats.idlesecs != null}<dt>Idle for</dt><dd>{duration(stats.idlesecs + since)}</dd>{/if}
<dt>Ping (TCP)</dt><dd>{ping(stats.tcp_ping_avg, stats.tcp_ping_var)}</dd>
<dt>Ping (UDP)</dt><dd>{stats.udp_packets ? ping(stats.udp_ping_avg, stats.udp_ping_var) : 'not using UDP (voice over TCP)'}</dd>
<dt>Packets</dt><dd>{stats.tcp_packets ?? 0} TCP, {stats.udp_packets ?? 0} UDP</dd>
<!-- The server counts the client's ping messages, not voice; clients that never ping (many bots) show none -->
<dt>Ping (TCP)</dt><dd>{stats.tcp_packets ? ping(stats.tcp_ping_avg, stats.tcp_ping_var) : 'n/a (this client sends no pings)'}</dd>
<dt>Ping (UDP)</dt><dd>{stats.udp_packets ? ping(stats.udp_ping_avg, stats.udp_ping_var) : 'n/a'}</dd>
<dt>Pings received</dt><dd>{stats.tcp_packets ?? 0} over TCP, {stats.udp_packets ?? 0} over UDP</dd>
{#if stats.bandwidth != null}<dt>Bandwidth</dt><dd>{formatBytes(stats.bandwidth)}/s</dd>{/if}
{#if stats.address?.length}<dt>Address</dt><dd class="mono">{address(stats.address)}</dd>{/if}
</dl>