Waypipe
Network transparency with Wayland
Waypipe
waypipe
is a proxy for Wayland clients. It forwards Wayland messages and
serializes changes to shared memory buffers over a single socket. This makes
application forwarding similar to ssh -X
feasible.
Usage
waypipe
should be installed on both the local and remote computers. There is a
user-friendly command line pattern which prefixes a call to ssh
and
automatically sets up a reverse tunnel for protocol data. For example,
waypipe ssh user@theserver weston-terminal
will run ssh
, connect to theserver
, and remotely run weston-terminal
,
using local and remote waypipe
processes to synchronize the shared memory
buffers used by Wayland clients between both computers. Command line arguments
before ssh
apply only to waypipe
; those after ssh
belong to ssh
.
Alternatively, one can launch the local and remote processes by hand, with the following set of shell commands:
/usr/bin/waypipe -s /tmp/socket-local client &
ssh -R /tmp/socket-remote:/tmp/socket-local -t user@theserver \
/usr/bin/waypipe -s /tmp/socket-remote server -- \
/usr/bin/weston-terminal
kill %1
It's possible to set up the local and remote processes so that, when the connection between the the sockets used by each end breaks, one can create a new forwarded socket on the remote side and reconnect the two processes. For a more detailed example, see the man page.
Installing
Waypipe's build uses a mixture of meson and cargo. For example:
cd /path/to/waypipe/
cargo fetch --locked
cd ..
mkdir build-waypipe
meson --buildtype debugoptimized waypipe build-waypipe
ninja -C build-waypipe install
Core build requirements:
- meson (build, ≥ 0.57. with dependencies
ninja
,pkg-config
,python3
) - cargo (build)
- rust (build, edition 2021, version ≥ 1.77)
- scdoc (optional, to generate a man page, )
- ssh (runtime, OpenSSH ≥ 6.7, for Unix domain socket forwarding)
Rust library dependencies (can be acquired through cargo fetch --locked
):
- clap: command line parsing
- getrandom: picking random socket names
- log: logging
- nix: safer libc wrapper
- ash: (optional, provides vulkan bindings for dmabuf support)
- libloading: (optional, used by ffmpeg bindings)
- pkg-config: (optional, used to find libraries to link to)
Optional linked dependencies, broken out by feature:
- lz4 compression:
- liblz4 (≥ 1.7.0)
- bindgen (build, ≥ 0.70.0)
- zstd compression:
- libzstd (≥ 0.4.6)
- bindgen (build, ≥ 0.70.0)
- dmabuf support:
- vulkan (to support programs using GPU rendering and DMABUFs)
- vulkan validation layers (runtime, optional, used for tests and with --debug flag)
- video encoding/decoding support:
- dmabuf support
- ffmpeg (≥ 7.1, needs avcodec/avutil for lossy video encoding)
- bindgen (build, ≥ 0.70.0)
- glslc (build, to compile shaders for image format conversion)
Note: in practice, bindgen requires certain C library headers from clang, but some
distributions have not made them a dependency of bindgen. If the build fails
because limits.h
or stddef.h
is missing, try installing clang
.
waypipe-c
Originally, Waypipe was developed in C; it was later ported to use Rust. The
C implementation, now producing an executable called waypipe-c
, has been kept
in the repository for use on older systems which do not have the Rust version's
dependencies installed. waypipe-c
also includes some features (like reconnection
support, libgbm backend for dmabufs) dropped in later versions. There are two ways to
build it: with meson
,
cd /path/to/waypipe/ && cd ..
mkdir build-waypipe
meson --buildtype debugoptimized waypipe build-waypipe -Dbuild_c=true -Dbuild_rs=false
ninja -C build-waypipe install
or by running the ./minimal_build.sh
script. In addition to meson
, python
,
liblz4
, libzstd
, ssh
, waypipe-c
requires:
- ffmpeg (≥ 3.1, needs avcodec/avutil/swscale for lossy video encoding)
- libva (for hardware video encoding and decoding)
- libgbm (to support programs using OpenGL via DMABUFs)
- libdrm (same as for libgbm)
- sys/sdt.h (to provide static tracepoints for profiling)
- libwayland-client (for security context support)
License
waypipe
is licensed GPLv3-or-later; waypipe-c
is MIT. In both cases, the
compiled executable is derived from the Wayland protocol files in ./protocols
,
which have their own (permissive) licenses. waypipe
's Rust dependency tree
can be shown with cargo tree
. See git history for a list of authors.
Reporting issues
Waypipe is developed at gitlab.freedesktop.org/mstoeckl/waypipe; file bug reports or submit patches here.
In general, if a program does not work properly under Waypipe, it is a bug worth reporting. If possible, before doing so ensure both computers are using the most recently released version of Waypipe (or are built from git master).
A workaround that may help for some programs using OpenGL or Vulkan is to run
Waypipe with the --no-gpu
flag, which may force them to use software rendering
and shared memory buffers. (Please still file a bug.)
Some programs may require specific environment variable settings or command line flags to run remotely; a few examples are given in the man page.
Useful information for bug reports includes:
- If a Waypipe process has crashed on either end of the connection, a full stack
trace, with debug symbols. (In gdb,
bt full
). - If the program uses OpenGL or Vulkan, the graphics cards and drivers on both computers.
- The output of
waypipe --version
on both ends of the connection - Logs when Waypipe is run with the
--debug
flag, or when the program is run with the environment variable settingWAYLAND_DEBUG=1
. - Screenshots of any visual glitches.
Technical Limitations
Security
Waypipe sends Wayland messages and updates to file descriptors (like window surface content or copy-paste data transfers) over a socket. When these messages are sent over a network, even if encrypted and with ssh's (lightweight) timing mitigations, an observer may be able to guess what is being done (typing, mouse motion, scrolling a page, and more...) from the sizes and timing of messages alone, even without knowing the precise contents.
Against broken or malicious compositors or applications: Waypipe does not impose resource limits, and the applications or compositors it forwards may instruct it to allocate large amounts of memory or do CPU or GPU-intensive work. Waypipe exposes compression and video encoding libraries which parse complicated formats and may have potential vulnerabilities; of these the compression libraries are simpler and better tested.
See the man page for more details.
Partial protocol processing
Waypipe does not have a full view of the Wayland protocol. It includes a compiled form of the base protocol and several extension protocols, but is not able to parse all messages that the programs it connects send. Fortunately, the Wayland wire protocol is partially self-describing, so Waypipe can parse the messages it needs (those related to resources shared with file descriptors) while ignoring the rest. This makes Waypipe partially forward-compatible: if a future protocol comes out about details (for example, about window positioning) which do not require that file descriptors be sent, then applications will be able to use that protocol even with older versions of Waypipe. The tradeoff to allowing messages that Waypipe can not parse is that Waypipe can only make minor modifications to the wire protocol. In particular, adding or removing any Wayland protocol objects would require changing all messages that refer to them, including those messages that Waypipe does not parse. This precludes, for example, global object deduplication tricks that could reduce startup time for complicated applications.
Latency
Shared memory buffer updates, including those for the contents of windows, are tracked by keeping a "mirror" copy of the buffer the represents the view which the opposing instance of Waypipe has. This way, Waypipe can send only the regions of the buffer that have changed relative to the remote copy. This is more efficient than resending the entire buffer on every update, which is good for applications with reasonably static user interfaces (like a text editor or email client). However, with programs with animations where the interaction latency matters (like games or certain audio tools), major window updates will unavoidably produce a lag spike. The additional memory cost of keeping mirrors is moderate.
The ssh ObscureKeystrokeTiming feature may introduce delays to obscure when input events and responses occur; reducing the delay interval should reduce latency/improve frame rates at the cost of sending more packets.
Other
The video encoding option for DMABUFs currently maintains a video stream for each buffer that is used by a window surface. Since surfaces typically rotate between a small number of buffers, a video encoded window will appear to flicker as it switches rapidly between the underlying buffers, each of whose video streams has different encoding artifacts.
As of writing, hardware video support with Vulkan is somewhat experimental and may require that driver-specific environment variables be set.
Since little-endian computers are vastly more common than big-endian, Waypipe
only receives and produces little-endian Wayland protocol messages. For
big-endian machines, run applications under a tool like wswapendian
to adjust
the protocol endianness. (Having Waypipe do this itself would require that it
embed or load many more Wayland protocol descriptions and restrict clients to
use them; at the moment it is more practical to do the endianness conversion
in a separate program.)
Download
The easiest way to download and install this software is by the SailfishOS:Chum GUI app. If you wish to download the RPM file by yourself, please expand the section below.
Download links
App information
- Package name
- waypipe
- Version
- 0.8.6+git3-1.1.2.jolla
- Licence
- MIT
- Developer
- M. Stoeckl
- Packager
- nephros
- Last updated
- 2024-06-19 11:17:19
- Download size
- 233.2 KiB
- Installed size
- 228.4 KiB
- Checksum (sha256)
- b804d731aa7af645625be621d1af95dda3a8ff044703f68086c2807393c1b4bf