# sb-send.c Protocol Issues
# Audited against SonoBus source code (deps/aoo/ and Source/)
# Date: 2026-06-12
## ISSUE 1: Missing AOO_VERSION_BUGFIX in version encoding
File: sb-send.c:361-363
sb-send.c:
  version = (AOO_VERSION_MAJOR << 24) |
            (AOO_VERSION_MINOR << 16) |
            AOO_PROTOCOL_FLAG_COMPACT_DATA;
SonoBus (common.cpp:33-36):
  return ((uint32_t)AOO_VERSION_MAJOR << 24) |
         ((uint32_t)AOO_VERSION_MINOR << 16) |
         ((uint32_t)AOO_VERSION_BUGFIX << 8) |
         ((uint32_t)protocolflags);
Impact: Works by coincidence (AOO_VERSION_BUGFIX=0 puts 0 in bits 8-15).
        If AOO_VERSION_BUGFIX ever becomes non-zero, version will be wrong.
Fix: Add AOO_VERSION_BUGFIX << 8 to version encoding.
## ISSUE 2: Missing /aoo/server/ping (server keepalive)
File: sb-send.c (no implementation)
sb-send.c never sends /aoo/server/ping messages.
SonoBus sends this periodically to maintain the TCP connection.
Without it, the server may disconnect sb-send after a timeout.
Fix: Add periodic /aoo/server/ping in server_thread maintenance loop.
## ISSUE 3: Missing /aoo/src/<id>/ping response handling
File: sb-send.c:632-721 (handle_udp_message)
sb-send.c does not handle incoming ping responses from SonoBus.
SonoBus sends ping responses as:
  /aoo/src/<source_id>/ping ,itti
    sink_id, tt1, tt2, lost_blocks
This is used for timing synchronization. Without handling it,
sb-send.c has no round-trip time information.
Fix: Add handler for /aoo/src/<id>/ping responses in handle_udp_message.
## ISSUE 4: Missing /aoo/src/<id>/data request (retransmission)
File: sb-send.c:632-721 (handle_udp_message)
sb-send.c does not handle data retransmission requests from SonoBus.
SonoBus sends resend requests as:
  /aoo/src/<source_id>/data ,ii[ii]*
    sink_id, salt, seq0, frame0, seq1, frame1, ...
Without handling this, lost packets cannot be recovered.
This causes audio glitches on the receiving end.
Fix: Add handler for /aoo/src/<id>/data requests. Store recent packets
     in a ring buffer and retransmit on request.
## ISSUE 5: Missing /aoo/src/<id>/uninvite handling
File: sb-send.c:632-721 (handle_udp_message)
sb-send.c does not handle uninvite messages from SonoBus.
SonoBus sends uninvite as:
  /aoo/src/<source_id>/uninvite ,i
    sink_id
Without handling this, sb-send.c continues sending audio even after
SonoBus has stopped listening.
Fix: Add handler for uninvite. Mark peer as not connected and stop
     sending audio data.
## ISSUE 6: Phantom /aoo/src/<id>/start message
File: sb-send.c:704-712
sb-send.c handles /aoo/src/<id>/start, but this message does not
exist in the SonoBus source code. SonoBus never sends this message.
The start message handler sets p->format_confirmed = true, which
is used to gate audio sending in audio_thread. Since SonoBus never
sends this, format_confirmed is never set to true.
However, audio_thread does NOT check format_confirmed before sending
(only checks format_sent), so this is not causing a functional bug.
But it's dead code.
Fix: Remove the phantom /start handler, or document why it exists.
## ISSUE 7: Missing /aoo/src/<id>/codec change handling
File: sb-send.c:632-721 (handle_udp_message)
sb-send.c does not handle codec change requests from SonoBus.
SonoBus can request a codec change via:
  /aoo/src/<source_id>/codecchange ,iisiiib
    sink_id, nchannels, samplerate, blocksize, codec, options_blob
Without handling this, sb-send.c cannot dynamically change codec
settings (e.g., bitrate adaptation).
Fix: Add handler for codec change requests.
## ISSUE 8: Local IP hardcoded to "0.0.0.0" in login
File: sb-send.c:311
sb-send.c always sends "0.0.0.0" as the local IP address:
  pos += osc_write_string(buf + pos, "0.0.0.0");
SonoBus may use the local IP for NAT traversal or local network
optimization. Hardcoding it prevents proper network detection.
Fix: Detect and send the actual local IP address.
## ISSUE 9: Salt generation uses weak randomness
File: sb-send.c:517
sb-send.c generates salt using:
  return (int32_t)(time(NULL) ^ (p->token & 0xFFFFFFFF) ^ rand());
SonoBus uses std::mt19937 with std::random_device:
  thread_local std::random_device dev;
  thread_local std::mt19937 mt(dev());
  std::uniform_int_distribution<int32_t> dist;
  return dist(mt);
The weak salt generation may cause collisions or be predictable.
Fix: Use a proper random number generator (e.g., /dev/urandom or arc4random).
## ISSUE 10: No periodic peer ping sending
File: sb-send.c:714-720
sb-send.c only RESPONDS to peer pings, it never INITIATES them.
SonoBus expects periodic /aoo/peer/ping messages for NAT keepalive.
Without sending pings, NAT mappings may expire and connections may drop.
Fix: Add periodic peer ping sending in server_thread or a dedicated thread.
     SonoBus uses a 2-second interval (set via set_ping_interval(2000)).
## ISSUE 11: Format request missing version argument read
File: sb-send.c:688-702
When handling /aoo/src/<id>/format, sb-send.c reads the tags but
does not read the version argument from the format request.
SonoBus sends format requests as:
  /aoo/src/<source_id>/format ,ii
    sink_id, version
The version should be used to set the peer's protocol_flags.
sb-send.c ignores this value.
Fix: Read the version argument and store protocol_flags per-peer.
## ISSUE 12: Invite handler ignores protocol flags from second argument
File: sb-send.c:641-647
When handling /aoo/src/<id>/invite, sb-send.c reads the first
argument (sink_id) but ignores the second argument (protocol_flags).
SonoBus sends invites as:
  /aoo/src/<source_id>/invite ,ii
    sink_id, protocol_flags
The protocol_flags indicate what features the peer supports
(e.g., compact data).
Fix: Read and store protocol_flags per-peer from the invite message.
## ISSUE 13: Data message always sends nframes=1
File: sb-send.c:407
sb-send.c always sets nframes=1 in data messages:
  pos += osc_write_int32(buf + pos, 1);  // nframes
SonoBus splits large encoded data into multiple frames:
  auto maxpacketsize = packetsize_ - AOO_DATA_HEADERSIZE;
  auto dv = div(d.totalsize, maxpacketsize);
  d.nframes = dv.quot + (dv.rem != 0);
For stereo at high bitrates, the encoded data may exceed
maxpacketsize. sb-send.c sends it all in one frame, which
is fine for low bitrates but could cause issues at high bitrates
if the encoded data exceeds the UDP MTU.
Fix: Implement frame splitting for large encoded data.
## ISSUE 14: No handling of AOO_SOURCE_STATE_EVENT
File: sb-send.c (no implementation)
sb-send.c does not handle source state events from SonoBus.
SonoBus pushes AOO_SOURCE_STATE_EVENT when a source starts or stops.
This could be used to detect when a peer is ready to receive audio.
Fix: Not critical, but could improve connection reliability.
## ISSUE 15: Missing /aoo/src/<id>/ping response format verification
File: sb-send.c:418-428 (build_source_ping_msg)
sb-send.c sends source pings with type tags ",it":
  source_id (int32), timetag (NTP)
SonoBus's send_ping (source.cpp:861) sends:
  src (int32), osc::TimeTag(t.to_uint64())
The format matches, but sb-send.c uses a custom NTP timestamp
function (get_ntp_time) instead of the AOO library's aoo_osctime_get().
The custom implementation may have timing accuracy issues.
Fix: Verify NTP timestamp accuracy matches AOO library implementation.
## ISSUE 16: Peer ping response doesn't include token in address
File: sb-send.c:714-720
When responding to /aoo/peer/ping, sb-send.c sends back to the
same address. This is correct for NAT traversal.
However, the response includes sb-send's own token, which is correct.
SonoBus matches the token to identify the peer.
No bug here, but worth noting the flow is correct.
## ISSUE 17: No handling of /sb/* SonoBus custom messages
File: sb-send.c (no implementation)
sb-send.c does not handle any SonoBus custom messages:
  /sb/pinfo   - Peer info (jitter buffer, latency, recording status)
  /sb/chat    - Chat messages
  /sb/ping    - SonoBus ping
  /sb/pngack  - SonoBus ping ack
  /sb/clayinfo - Channel layout info
Without handling /sb/pinfo, sb-send.c doesn't report its audio
configuration to SonoBus peers.
Fix: At minimum, handle /sb/pinfo to report basic status.
## ISSUE 18: Format message doesn't send userformat blob
File: sb-send.c:350-381 (build_format_msg)
sb-send.c doesn't include the optional userformat blob (9th argument)
in format messages.
SonoBus checks for this:
  if (msg.ArgumentCount() > 8) {
      (it++)->AsBlob(userfmt, ufsize);
The userformat contains channel layout information in JUCE ValueTree
binary format. Without it, SonoBus assumes default stereo panning.
Not critical for basic operation, but multi-channel setups may need it.
Fix: Add optional userformat blob for proper channel layout reporting.
## ISSUE 19: No error handling for UDP send failures
File: sb-send.c (multiple locations)
sb-send.c uses sendto() without checking for ICMP unreachable errors.
If a peer goes offline, sendto() may fail silently or return errors
that are not handled.
Fix: Add error handling for sendto() failures.
## ISSUE 20: Missing /aoo/server/group/leave before disconnect
File: sb-send.c:1372-1390 (cleanup)
sb-send.c does not send /aoo/server/group/leave before closing
the TCP connection.
SonoBus expects clients to send:
  /aoo/server/group/leave ,s
    group_name
Without this, the server may not immediately remove the client
from the group, causing delayed peer leave notifications.
Fix: Send /aoo/server/group/leave before closing TCP connection.
