Commit graph

790 commits

Author SHA1 Message Date
Wim Taymans
b70f32a259 pulse-server: enforce minfrag after latency adjust 2022-09-03 13:07:09 +02:00
Wim Taymans
9c34a923db pulse-server: simplify latency handling
We don't need to use the minreq field. The fragsize is only updated when
adjust_latency is used.
2022-09-01 16:46:18 +02:00
Wim Taymans
ad214dde2e pulse-server: tweak the fragsize/minreq handling
Only send 2/3 of the fragsize
2022-09-01 16:23:56 +02:00
Wim Taymans
e10305851d pulse-server: send chunks with half the fragsize
PulseAudio configures half of the fragsize as the source latency. It
also sends chunks as soon as they become available.

This means that we also need to configure the source with half of
the fragsize latency and send in chunks of fragsize/2. Keep this in
the unused (for record) minreq field.
2022-09-01 15:46:17 +02:00
Pauli Virtanen
6d4d77802a pulse-server: give Manager permission for Flatpak apps with devices=all
Some Flatpak apps want to manage sound fully (change default outputs,
move streams from other applications).  Real Pulseaudio always grants
full permissions, but pipewire-pulse doesn't, which breaks some
applications, e.g. Zoom.

Work around this by granting the manager permission if the application
also has devices=all access.

To do things properly, this probably should use the Portal media roles,
but this would need further work elsewhere.
2022-08-01 19:36:00 +00:00
Pauli Virtanen
0e12242a1b modules: set pipewire.access.portal.app_id in access & pulse-server
When detecting a access=flatpak application, set also
pipewire.access.portal.app_id, if determined
2022-08-01 19:36:00 +00:00
Pauli Virtanen
3730e54484 modules: support getting app_id in pw_check_flatpak
Support getting the Flatpak application ID from the .flatpak-info file,
similarly as what xdg-desktop-portal does.
2022-08-01 19:36:00 +00:00
Pauli Virtanen
5e5339ce6c modules: refactor check_flatpak to a common place
Move check_flatpak used by module-access and module-protocol-pulse
to a common flatpak-utils.h
2022-08-01 19:36:00 +00:00
Wim Taymans
35082e4f4b pulse-server: add the delay
Actually add the delay to the buffered amount of time instead of
overwriting.
2022-07-13 10:49:26 +02:00
Wim Taymans
855d17ac1b pulse-server: add some debugging 2022-07-13 10:42:00 +02:00
Pauli Virtanen
167537dffc pulse-server: fix warning
The rest of the fields are zeroed later in reply_create_record_stream,
but static analysis doesn't know that.
2022-07-06 14:36:22 +00:00
Pauli Virtanen
a46d4aedd7 pulse-server: work around race condition in SET_DEFAULT/MOVE_*
The default metadata update may be delayed for some time after
SET_DEFAULT, since the session manager has to work on it.

MOVE_* commands need to know what the client thinks is the current
default sink, so that they can decide between "move to default" and
"move to specific device".

To avoid race condition here, stash the default value set by the client
and use it in the MOVE_* commands, until the metadata update arrives.
2022-07-04 15:57:31 +00:00
Adolfo Rodrigues
6188e4d074 pulse-server: tweak maxlength some more
Make the buffer size at least 4 times as large as the fragment size to avoid
xruns.
2022-07-04 15:56:16 +00:00
Wim Taymans
8b649c4510 pulse-server: optimize property allocations
Only allocate a new properties object when we actually need to
change something.
2022-07-02 11:27:54 +02:00
Davide Beatrici
a31989b46d pulse-server: add card properties to sinks and sources
To match the original PulseAudio server's behavior.
2022-07-01 19:54:44 +00:00
Davide Beatrici
e0731f0ffa pulse-server: map "device.sysfs.path" to "sysfs.path" 2022-06-30 08:41:30 +02:00
Barnabás Pőcze
97a275e71e pulse-server: update quirks before querying the name
`client_update_quirks()` may modify `client::props` depending
on the "pulse.rules" section defined in the configuration file,
which means that it can change the value corresponding to the
"application.name" key. Therefore, `client::name` needs to
be queried after that.
2022-06-20 17:30:05 +00:00
Barnabás Pőcze
0f45d784d8 pulse-server: update client::name on UPDATE_CLIENT_PROPLIST command
`client::name` points to a string that is owned by `client::props`,
so when the property list is updated, it needs to be refreshed as well.
Otherwise, various use-after-frees can be triggered, for example:

==1471586==ERROR: AddressSanitizer: heap-use-after-free on address 0x60200007e7d0 at pc 0x7f14390755d0 bp 0x7ffe23edee30 sp 0x7ffe23ede5a8
READ of size 3 at 0x60200007e7d0 thread T0
    #0 0x7f14390755cf in printf_common /usr/src/debug/gcc/libsanitizer/sanitizer_common/sanitizer_common_interceptors_format.inc:553
    #1 0x7f1439077215 in __interceptor_vsnprintf /usr/src/debug/gcc/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:1665
    #2 0x7f1434ead47d in spa_vscnprintf ../spa/include/spa/utils/string.h:239
    #3 0x7f1434eae2ae in impl_log_logtv ../spa/plugins/support/logger.c:138
    #4 0x7f14385cacc7 in pw_log_logt ../src/pipewire/log.c:135
    #5 0x7f1433aef8e9 in do_set_profile ../src/modules/module-protocol-pulse/pulse-server.c:4656
    #6 0x7f1433b0af4d in handle_packet ../src/modules/module-protocol-pulse/server.c:109
    #7 0x7f1433b0e747 in do_read ../src/modules/module-protocol-pulse/server.c:276
    #8 0x7f1433b0eb04 in on_client_data ../src/modules/module-protocol-pulse/server.c:306
    #9 0x7f1434ec56a0 in source_io_func ../spa/plugins/support/loop.c:442
    #10 0x7f1434ec4a21 in loop_iterate ../spa/plugins/support/loop.c:430
    #11 0x7f14385dc23d in pw_main_loop_run ../src/pipewire/main-loop.c:148
    #12 0x55b065d73722 in main ../src/daemon/pipewire.c:131
    #13 0x7f143742928f  (/usr/lib/libc.so.6+0x2928f)
    #14 0x7f1437429349 in __libc_start_main (/usr/lib/libc.so.6+0x29349)
    #15 0x55b065d722a4 in _start (./src/daemon/pipewire-pulse+0x42a4)

0x60200007e7d0 is located 0 bytes inside of 16-byte region [0x60200007e7d0,0x60200007e7e0)
freed by thread T0 here:
    #0 0x7f14390be672 in __interceptor_free /usr/src/debug/gcc/libsanitizer/asan/asan_malloc_linux.cpp:52
    #1 0x7f14386a775a in do_replace ../src/pipewire/properties.c:414
    #2 0x7f14386a785e in pw_properties_set ../src/pipewire/properties.c:441
    #3 0x7f14386a658b in pw_properties_update ../src/pipewire/properties.c:309
    #4 0x7f1433adb055 in do_update_proplist ../src/modules/module-protocol-pulse/pulse-server.c:3246
    #5 0x7f1433b0af4d in handle_packet ../src/modules/module-protocol-pulse/server.c:109
    #6 0x7f1433b0e747 in do_read ../src/modules/module-protocol-pulse/server.c:276
    #7 0x7f1433b0eb04 in on_client_data ../src/modules/module-protocol-pulse/server.c:306
    #8 0x7f1434ec56a0 in source_io_func ../spa/plugins/support/loop.c:442
    #9 0x7f1434ec4a21 in loop_iterate ../spa/plugins/support/loop.c:430
    #10 0x7f14385dc23d in pw_main_loop_run ../src/pipewire/main-loop.c:148
    #11 0x55b065d73722 in main ../src/daemon/pipewire.c:131
    #12 0x7f143742928f  (/usr/lib/libc.so.6+0x2928f)

previously allocated by thread T0 here:
    #0 0x7f1439072faa in __interceptor_strdup /usr/src/debug/gcc/libsanitizer/asan/asan_interceptors.cpp:439
    #1 0x7f14386a6fe2 in do_replace ../src/pipewire/properties.c:394
    #2 0x7f14386a785e in pw_properties_set ../src/pipewire/properties.c:441
    #3 0x7f1433a6c52d in read_props ../src/modules/module-protocol-pulse/message.c:147
    #4 0x7f1433a6f467 in message_get ../src/modules/module-protocol-pulse/message.c:359
    #5 0x7f1433ab3191 in do_set_client_name ../src/modules/module-protocol-pulse/pulse-server.c:1030
    #6 0x7f1433b0af4d in handle_packet ../src/modules/module-protocol-pulse/server.c:109
    #7 0x7f1433b0e747 in do_read ../src/modules/module-protocol-pulse/server.c:276
    #8 0x7f1433b0eb04 in on_client_data ../src/modules/module-protocol-pulse/server.c:306
    #9 0x7f1434ec56a0 in source_io_func ../spa/plugins/support/loop.c:442
    #10 0x7f1434ec4a21 in loop_iterate ../spa/plugins/support/loop.c:430
    #11 0x7f14385dc23d in pw_main_loop_run ../src/pipewire/main-loop.c:148
    #12 0x55b065d73722 in main ../src/daemon/pipewire.c:131
    #13 0x7f143742928f  (/usr/lib/libc.so.6+0x2928f)
2022-06-20 17:30:05 +00:00
Wim Taymans
ff05ebada6 pulse-server: tweak record attributes
Add some 'before' debug info of the attributes.
First clamp the fragsize to the maxlength and then clamp to the
minfrag or else we could bypass the configured minfrag by setting a
lower maxlength.
Scale the maxlength to at least twice the fragsize so that we can
buffer enough data in the ringbuffer to serve fragsize bytes.

See #2447
2022-06-20 11:42:59 +02:00
Lucas Holt
6a15a02ec2 Add support for MidnightBSD
Fix build issue

Fix build issue
2022-06-19 18:22:47 +00:00
Barnabás Pőcze
ae34b68e3a pulse-server: message: improve resizing logic
As Coverity points out, `ensure_size()` is not fully correct.

Let us assume that the message already has some allocated storage,
and the `realloc()` call in the next `ensure_size()` invocation fails.
In that case `message::data` is freed, but the pointer is left behind.
If another `ensure_size()` call is made, then `realloc()` will be called
(since the previous call left `message::allocated` as zero), but the
first argument of the `realloc()` call will be a dangling pointer.

In order to avoid the above, first of all, clear `message::data` after
a failed `realloc()` call, and immediately return `-ENOMEM` if
`message::length` is greater than `message::allocated` since
that signals if the message has even run into an out-of-memory
situation.
2022-06-16 18:38:30 +00:00
Barnabás Pőcze
080a97c0bb pulse-server: message: store pointer to impl directly
Store a pointer to the owner `impl` object instead of
the (embedded) `stat` object. This way `message_free()`
can be simplified since the owner `impl` does not need
to be passed explicitly.
2022-06-16 18:38:30 +00:00
Barnabás Pőcze
b843b0ab29 pulse-server: message: remove unnecessary forward declaration
`struct client` is never referenced in "message.h",
so remove the forward declaration for it.
2022-06-16 18:38:30 +00:00
Wim Taymans
68bafcf166 pulse-server: Don't send more than fragsize chunks
Send exactly fragsize chunks when capturing.

See #2418 and #2434
2022-06-14 11:20:18 +02:00
Wim Taymans
c1a61a7941 pulse-server: only append .monitor for capture streams 2022-06-13 20:12:10 +02:00
Wim Taymans
f88134232d pulse-server: fix name when moved to monitor
When a stream is moved to a monitor, make sure we append the .monitor
suffix to the node name.

Fixes #2440
2022-06-13 19:54:35 +02:00
Wim Taymans
4821c7ca2f pulse-server: don't append "/pulse" to PULSE_RUNTIME_PATH
Fixes #2431
2022-06-09 17:06:07 +02:00
Barnabás Pőcze
c8c2526f87 pulse-server: destroy modules first
The `impl::servers` list contains all servers, and they are all
destroyed in `impl_clear()`. However, by that time, modules were
not freed previously, so if there were any instances of
*module-protocol-native-tcp* loaded, then the unload() method
of those would call `server_free()` on already freed servers,
resulting in use-after-frees. Fix that by unloading modules
before destroying the servers.

==451490==ERROR: AddressSanitizer: heap-use-after-free on address 0x612000006050 ...
READ of size 8 at 0x612000006050 thread T0
    #0 0x7f45edb19a0c in server_free ../src/modules/module-protocol-pulse/server.c:1022
    #1 0x7f45edb46c7d in module_native_protocol_tcp_unload ../src/modules/module-protocol-pulse/modules/module-native-protocol-tcp.c:66
    #2 0x7f45eda893c7 in module_unload ../src/modules/module-protocol-pulse/module.c:128
    #3 0x7f45edaf7269 in impl_unload_module ../src/modules/module-protocol-pulse/pulse-server.c:5336
    #4 0x7f45edaa1583 in pw_map_for_each ../src/pipewire/map.h:238
    #5 0x7f45edaf79c5 in impl_clear ../src/modules/module-protocol-pulse/pulse-server.c:5358
    ...

0x612000006050 is located 16 bytes inside of 264-byte region [0x612000006040,0x612000006148)
freed by thread T0 here:
    #0 0x7f45f30be672 in __interceptor_free /usr/src/debug/gcc/libsanitizer/asan/asan_malloc_linux.cpp:52
    #1 0x7f45edb1a48a in server_free ../src/modules/module-protocol-pulse/server.c:1040
    #2 0x7f45edaf730b in impl_clear ../src/modules/module-protocol-pulse/pulse-server.c:5347
    ...

Fixes: f181210b29 ("pulse-server: properly unload modules")
2022-06-09 03:02:06 +02:00
Barnabás Pőcze
c248091528 pulse-server: module-switch-on-connect: remove dead code and one allocation
As Coverity correctly points out, the `if (blocklist)` condition
is never true after the `out` label, so this commit makes some
changes to remove the dead code.

First of all, the `regex_t` object is directly embedded in the
module's data struct, so the `malloc()` call can be removed,
and thus there is no need for the cleanup code anymore, so everything
after the `out` label is also removed.

Furthermore, two NULL checks are removed which check `d->blocklist`
from `module_switch_on_connect_unload()` and `manager_added()`
because both of those functions can only ever run if the `d->blocklist`
regex object has been successfully initialized in `module_switch_on_connect_prepare()`.
Those checks were not strictly needed to begin with.
2022-06-05 18:04:03 +00:00
Wim Taymans
0f839c7b61 modules: clamp input offset and size
So that we don't cause memory errors with invalid input.
2022-06-04 11:47:48 +02:00
Barnabás Pőcze
876a5977f3 pulse-server: module-pipe-{sink,source}: drop redundant log messages
It is already logged by the module loading code when a module is
successfully loaded, so there is no need to print it on a per-module
basis at the same log level.
2022-06-03 17:24:27 +02:00
Wim Taymans
efe30d5075 pulse-server: send STREAM_MOVED messages
Keep track of the last known peer of a stream and send a moved message
when it changes.

Fixes #2407
2022-06-03 16:59:08 +02:00
Wim Taymans
be9c738661 pulse-server: keep stream latency around 2022-06-03 16:58:37 +02:00
Wim Taymans
1252927d73 pulse-server: check all pending streams
Check all pending streams to see if the new link completes their
creation.

It is possible that the link linked 2 pending streams and then we
want to complete them both.
2022-06-03 15:50:54 +02:00
Wim Taymans
258a203d74 pulse-server: optimize link finding
When we get a new link object, only check if a pending stream is linked
according to the new link instead of iterating all links.
2022-06-03 15:48:08 +02:00
Wim Taymans
6276253c30 pulse-server: implement pipe sink/source with module 2022-06-03 11:51:29 +02:00
Wim Taymans
87172fde06 modules: align tunnel.mode
Source for a source, sink for a sink. We use capture and playback for
streams that link to a source/sink respectively.
2022-06-03 10:52:45 +02:00
Barnabás Pőcze
f1b0cfd546 pulse-server: mark module_*_prepare() methods static
Since 37fa911a72 ("pulse-server: module: rework registry") none
of the module methods need to have external linkage.
2022-06-02 23:56:55 +02:00
Barnabás Pőcze
75d28cadcd pulse-server: rename module_info::prepare() to create()
Now that the method does not actually create the `module` object,
it would be somewhat misleading to call it "create",
so rename it to "prepare".
2022-06-02 23:56:55 +02:00
Barnabás Pőcze
fa3a28ab68 pulse-server: pass already created module object to module_info::create()
All modules need to manually create a `module` object and check
if it was successfully created. The same with argument parsing.
To simplify modules, move the module object creation and argument
parsing into `module_create()`, and pass the already initialized
module to `module_info::create()`.

The semantics of `module_info::create()` are kept, that is,
if it fails, `module_info::unload()` will not be called.
2022-06-02 23:56:55 +02:00
Barnabás Pőcze
5ad52bb88a pulse-server: do not put static properties into module::props
Now that the module's properties are served from `module_info::properties`,
there is no need for modules to put their static properties into
the `module::props` dictionary.
2022-06-02 23:56:50 +02:00
Barnabás Pőcze
c9f632da9f pulse-server: serve module properties from static list
None of the modules really need a dynamic property list,
so serve the properties from a static list.
2022-06-02 15:17:45 +02:00
Wim Taymans
2c4d36e4d0 pulse-server: always send frame_size multiples of samples.
See #2421
2022-06-02 09:05:23 +02:00
Wim Taymans
0d51f3b74e pulse-server: always send at least fragsize data
Make sure to never send less than the negotiated fragsize to a client.
Also make sure we don't send too much data in one go. This is more in
line with what pulseaudio does.

Fixes capture from multiple tabs in chrome.

Fixes #2418
2022-06-01 15:43:07 +02:00
Wim Taymans
57e732cd27 pulse-server: use 8 channels internally for TrueHD and DTSHD
So that the stride is what the server side expects.

See #2284
2022-05-23 18:54:18 +02:00
Barnabás Pőcze
893567bed6 pulse-server: module-x11-bell: initialize module member
Previously, `module_x11_bell_data::module` was not initialized
properly, which led to a NULL pointer dereference in
`module_schedule_unload()` when called from `module_destroy()`
in case the native pipewire module was unloaded.

See #2392
2022-05-21 18:45:25 +02:00
Wim Taymans
b81b7febee pulse-server: don't export NETWORK nodes
Don't export network nodes with zeroconf.

Fixes #2384
2022-05-18 20:40:46 +02:00
Wim Taymans
05deba85a4 pulse-server: reset message length when freeing
When we move a message to the free list, reset the length to 0.
Otherwise the previous length plus the new length will be used to
allocated the message size, which would overallocate.
2022-05-18 17:31:23 +02:00
Pauli Virtanen
98aa7ccff0 pulse-server: emulate synchronous MOVE_* commands
Make MOVE_SINK_INPUT/MOVE_SOURCE_OUTPUT change the linked peer
immediately in subsequent GET_SINK_INPUT_INFO/GET_SOURCE_OUTPUT_INFO
commands.  Do this by keeping track of the sink/source where the client
moved the stream to, and temporarily replying so in future GET_INFO (but
only in messages for that client).

We discard the temporary override when we either get an update event for
the stream (i.e. SM moved the stream), or a 1sec timer runs out. If the
timer runs out, we emit a sink-input/source-output change event, as in
that case what we claimed in the earlier GET_INFO messages might not be
true, so clients need to update their information.

This gets rid of race conditions where an application moves a stream,
and expects the move to be visible in future GET_INFO replies, which may
fail to happen because it takes some time for the session manager to
re-link the streams.

Fixes pasystray behavior.
2022-05-15 17:14:52 +00:00
Pauli Virtanen
83be5d866f pulse-server: implement temporary data attached to manager objects
Add functions for setting timer-based lifetimes for object data.

Having the timers in the object data themselves simplifies life cycle
management, as client/manager disconnects are handled without further
work.
2022-05-15 17:14:52 +00:00