There was no limit on concurrent PLAY_SAMPLE operations per client.
Each creates a PipeWire stream, allowing a client to exhaust server
resources. Add a MAX_PENDING_SAMPLES (64) limit per client.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was no limit on pending operations per client. Commands like
SET_SINK_VOLUME each allocate an operation that persists until a
manager sync completes. A client flooding these commands can exhaust
server memory. Add a MAX_OPERATIONS (64) limit per client.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was no limit on the total size of the sample cache. A client
could upload many samples to exhaust server memory. Add a configurable
pulse.max-sample-cache property (default 64MB) to cap the total size
of all cached samples.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was no limit on the number of streams a single client could
create. Each stream allocates a 4MB ring buffer, allowing a malicious
client to exhaust server memory. Add a configurable pulse.max-streams
property (default 64) to limit streams per client.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Make a function like alloca but with overflow checks and a max
allocation size.
Use this function where we can and also make sure that all alloca calls
are in some way limited.
Add 35 sec timeout for PLAY_SAMPLE streams to start streaming, similar
to what we do with normal streams, and fail playback if they don't
start.
This avoids pending sample playback using up resources indefinitely if
streams fail to start for some reason, e.g. session manager is not
linking them.
WirePlumber recently added a mechanism to force mono mixdown on audio
outputs, which is a useful feature for accessibility. Let's also expose
that setting via libpulse for existing audio settings UIs to be able to
use.
Make `client_queue_subscribe_event()` take the facility and type
separately, and calculate the mask itself, so that the caller
does not need to be concerned with that.
Add extension support to modules. This is a list of extension commands
that can be performed on the module.
Remove the custom registry of extensions and make proper modules that
implement the extensions.
This is more in line with what pulseaudio does. The advantage is that the
modules actually show up in the module list and that we can use the
module user_data to implement the extension later.
Because we keep everything in a ringbuffer and provide exactly the
required amount of data, we can use 1/4 buffers.
Also increase the buffer size. We don't want to limit the buffer size
to the negotiated tlength because it can be increased later. Instead
scale it to the max quantum size (8192) with a max resample rate of 32.
Mark some structures, arrays static/const at various places.
In some cases this prevents unnecessary initialization
when a function is entered.
All in all, the text segments across all shared
libraries are reduced by about 2 KiB. However,
the total size increases by about 2 KiB as well.
This starts breaking up the giant monolith that is the pulse-server.c
code into more manageable chunks by trying to split the module code into
individual compilation units.
Make a registry of modules
Assign an unique number to each module with the MODULE_FLAG bit set
so that we can also enumerate them
Implement enumerating our internally loaded modules
Implement unloading of the module using the module id
Move module-null-sink into a separate file
Use Audio/Sink if no other media.class was given, so that it works
just like the pulseaudio module
Enable linger=true in all cases.