Description
Description
Murmur assumes that clients are UDP capable by default.
It only switches to TCP when it receives a UDPTunnel
packet (see src/murmur/Server.cpp#L1764
)
This is an issue for listen-only clients that can't use UDP.
Since they don't send audio, they will never send the UDPTunnel
packet, which means the server will incorrectly send the data over UDP and the client will never receive it.
If the client uses the Force TCP
options but can actually receive UDP it will still work because the whole UDP receive chain bypasses the forced TCP check.
Steps to reproduce
- Connect to the server with
Force TCP
- Don't speak
- If some else in the channel speaks, you will get the data over UDP (look at the network stats or packet capture)
- If you speak it will switch to TCP
Mumble version
1.5.517
Mumble component
Server
OS
Linux
Reproducible?
Yes
Additional information
A possible fix would be to set aiUdpFlag
to 0
in the ServerUser
constructor.
If the client is using UDP it will quickly be set to 1
in the UDPMessageType::Audio
handler of src/murmur/Server.cpp#970
Of course, that means that the client will receive everything over TCP until he speaks (but at least the client will get it).
Another option is changing the flag in the ping handler, but it isn't the best idea because UDP pings are sent and received by the client regardless of whether it's using TCP or not. This means it wouldn't honor the Force TCP
option of the clients.
To truly solve this without compromise would require adding something like a force_tcp
field to a TCP packet (maybe the Authenticate
or UserState
packet?). That way the server is actually aware of the client settings and not just guessing.
A truly horrible way to bypass it would be to send \xff\xff\xff
over a UDPTunnel
packet. It's just enought to pass the length check and wouldn't be interpreted as a packet. (Currently using that while debugging my implementation)
Activity