[pulseaudio-discuss] More on the native protocol complexity
Rafal Wojtczuk
rafal at invisiblethingslab.com
Fri Apr 23 04:36:23 PDT 2010
Hello,
On Apr 5, Lennart wrote (about native protocol):
> Note that the protocol is kinda complex, both because it grew
> historically and because some parts have to be complex. i.e. the
> timing/flow control logic is non-trivial. Reimplementing that won't be
> fun.
>
> tbh I don't think the native protocol while it works quite well these
> days is something that deserves to be reimplemented by other projects.
The problem is that for some tasks the complexity of the native protocol is
prohibitive. Consider the following scenario (that I am trying to solve
now):
There are two [virtual btw] machines, VM_USER and VM_HOST. We want to allow
users in VM_USER to play sound on the soundcard attached to VM_HOST. So, the
obvious method is to run pulseaudio daemon in VM_HOST, and prepare client.conf
in VM_USER so that it connects pa clients to VM_HOST over the network. However,
VM_HOST does not want to trust VM_USER more than necessary. VM_HOST does not
want to give VM_USER full access to the native protocol capabilities (like
PA_COMMAND_LOAD_MODULE), nor to give it a chance to exploit a potential bug
(logic one, or buffer overflow) in this 150K C-code protocol.
A solution acceptable from VM_HOST's point of view on security is:
1) Load module-simple-protocol-tcp in VM_HOST
2) Run pulseaudio daemon in VM_USER (and make users connect to it, instead
to VM_HOST). Load module-pipe-sink, and pass the pipe output over the network
to port 4711 in VM_HOST (to module-simple-protocol-tcp code).
This time, all VM_USER is allowed, is to pass raw audio frames; no complex
protocol involved. Good, nothing more than required. And it works to some
extent. However, because of lack of builtin synchronization (is this right?),
when playing a movie in VM_USER, the sound is
delayed in comparison to the video frames. Reducing the buffering size (eg
patch module-pipe-sink to connect directly to port 4711 instead of pipe, use
low sndbuf and rcvbuf in sockets) improves the situation, but not
satisfactory. And we cannot reduce (to something low) the maxlength and tlength
buffers when creating c->input_memblockq in src/pulsecore/protocol-simple.c
(is that right?), because alsa-sink.c in VM_HOST starts to
complain about underruns. Setting prebuf to 0 in the args to
c->input_memblockq = pa_memblockq_new results in a disaster, setting it to a
low value, say 1024, does not help with the delay.
Anything else I could try ?
> timing/flow control logic is non-trivial. Reimplementing that won't be
> fun.
Yeah.
But in this particular example (particular e.g. because we can assume near 0
network latency), can someone figure out some better configuration, based on
module-simple-protocol-tcp+module-pipe-sink or anything else that does not
involve a complex protocol, but achieves good synchronization ?
Alternatively, is it possible to quickly estimate how many of 90 PA_COMMAND_*
functions in protocol-native.c are required to be implemented to allow
simple playback only ? Maybe it would be possible to implement
simplified-native-protocol.c, or sanitize incoming packets before passing
them to pulseaudio.
Regards,
Rafal Wojtczuk
The Qubes OS Project
http://qubes-os.org
More information about the pulseaudio-discuss
mailing list