Fix nil udpConn race in WriteAudioUDP15, reduce log noise

- Snapshot c.udpConn to local variable to avoid race with disconnect
  cleanup goroutine nil'ing it between the nil check and Write call.
- Move per-packet hex dumps from Info to Debug level.
- Only hex-dump the first received packet at Info level.
This commit is contained in:
Brandon McGinty (deepseek)
2026-08-09 00:58:50 -04:00
committed by Brandon McGinty
parent 50987d412c
commit 5b9b3ad421
+14 -12
View File
@@ -452,7 +452,10 @@ func (c *Client) WriteAudioUDP15(data []byte, final bool) (bool, error) {
if cs == nil || !cs.initialized { if cs == nil || !cs.initialized {
return false, nil return false, nil
} }
if c.udpConn == nil {
// Snapshot udpConn to avoid race with disconnect cleanup nil'ing it.
udpConn := c.udpConn
if udpConn == nil {
return false, nil return false, nil
} }
@@ -461,9 +464,6 @@ func (c *Client) WriteAudioUDP15(data []byte, final bool) (bool, error) {
// Build MumbleUDP.Audio protobuf. // Build MumbleUDP.Audio protobuf.
payload := encodeUDPAudio(0, frameNum, data, final) payload := encodeUDPAudio(0, frameNum, data, final)
log.Info("UDP15 send: frame=%d opus_len=%d proto_len=%d final=%v",
frameNum, len(data), len(payload), final)
// Encrypt with 1.5 format. // Encrypt with 1.5 format.
encrypted, err := cs.encrypt15(payload) encrypted, err := cs.encrypt15(payload)
if err != nil { if err != nil {
@@ -471,10 +471,10 @@ func (c *Client) WriteAudioUDP15(data []byte, final bool) (bool, error) {
return false, err return false, err
} }
log.Info("UDP15 send: encrypted_len=%d hex=%s", log.Debug("UDP15 send: frame=%d opus_len=%d enc_len=%d final=%v",
len(encrypted), hex.EncodeToString(encrypted)) frameNum, len(data), len(encrypted), final)
_, err = c.udpConn.Write(encrypted) _, err = udpConn.Write(encrypted)
if err != nil { if err != nil {
log.Error("UDP15 send write failed: %v", err) log.Error("UDP15 send write failed: %v", err)
return false, err return false, err
@@ -483,13 +483,18 @@ func (c *Client) WriteAudioUDP15(data []byte, final bool) (bool, error) {
} }
// HandleUDPPacket15 processes an incoming Mumble 1.5 native UDP packet. // HandleUDPPacket15 processes an incoming Mumble 1.5 native UDP packet.
var firstUDP15Recv bool
func (c *Client) HandleUDPPacket15(packet []byte, pktNum uint64) { func (c *Client) HandleUDPPacket15(packet []byte, pktNum uint64) {
if len(packet) < udp15HeaderSize { if len(packet) < udp15HeaderSize {
log.Warn("UDP15 #%d: packet too short (%d bytes)", pktNum, len(packet)) log.Warn("UDP15 #%d: packet too short (%d bytes)", pktNum, len(packet))
return return
} }
log.Info("UDP15 #%d: raw hex=%s", pktNum, hex.EncodeToString(packet)) if !firstUDP15Recv {
firstUDP15Recv = true
log.Info("UDP15 #%d: first packet received! hex=%s", pktNum, hex.EncodeToString(packet))
}
cs := udp15Server cs := udp15Server
if cs == nil || !cs.initialized { if cs == nil || !cs.initialized {
@@ -503,14 +508,11 @@ func (c *Client) HandleUDPPacket15(packet []byte, pktNum uint64) {
return return
} }
log.Info("UDP15 #%d: decrypt OK, plaintext hex=%s", pktNum, hex.EncodeToString(plaintext)) log.Debug("UDP15 #%d: decrypt OK, plaintext_len=%d", pktNum, len(plaintext))
// Parse MumbleUDP.Audio protobuf. // Parse MumbleUDP.Audio protobuf.
session, frameNum, opusData, terminator := decodeUDPAudio(plaintext) session, frameNum, opusData, terminator := decodeUDPAudio(plaintext)
log.Info("UDP15 #%d: session=%d frame=%d opus_len=%d term=%v",
pktNum, session, frameNum, len(opusData), terminator)
if len(opusData) == 0 && !terminator { if len(opusData) == 0 && !terminator {
return return
} }