[-]
[+]
|
Changed |
_service:tar_git:waypipe.spec
|
|
[-]
[+]
|
Changed |
_service
^
|
@@ -2,8 +2,10 @@
<service name="tar_git">
<param name="url">https://github.com/sailfishos-chum/waypipe.git</param>
<param name="branch"></param>
- <param name="revision">0.8.6+git3</param>
+ <param name="revision"></param>
+ <param name="revision">0.9.0+git1</param>
<!--
+ <param name="revision">0.8.6+git3</param>
<param name="revision"></param>
-->
<param name="token"/>
|
[-]
[+]
|
Changed |
_service:tar_git:waypipe-0.9.0+git1.tar.bz2/upstream/meson.build
^
|
@@ -8,7 +8,7 @@
'warning_level=3',
'werror=true',
],
- version: '0.8.6',
+ version: '0.9.0',
)
# DEFAULT_SOURCE implies POSIX_C_SOURCE 200809L + extras like CMSG_LEN
@@ -66,6 +66,21 @@
if (is_linux or is_darwin) and get_option('with_systemtap') and cc.has_header('sys/sdt.h')
config_data.set('HAS_USDT', 1, description: 'Enable static trace probes')
endif
+has_flag_to_host = '''
+// linux/vm_sockets.h doesn't compile on its own
+// "invalid application of 'sizeof' to incomplete type 'struct sockaddr'"
+#include <sys/socket.h>
+#include <linux/vm_sockets.h>
+#ifndef VMADDR_FLAG_TO_HOST
+#error
+#endif
+int main(void) {
+ return 0;
+}
+'''
+if is_linux and cc.has_header('linux/vm_sockets.h') and cc.compiles(has_flag_to_host, name: 'has VMADDR_FLAG_TO_HOST')
+ config_data.set('HAS_VSOCK', 1, description: 'Enable VM Sockets (VSOCK)')
+endif
liblz4 = dependency('liblz4', version: '>=1.7.0', required: get_option('with_lz4'))
if liblz4.found()
config_data.set('HAS_LZ4', 1, description: 'Enable LZ4 compression')
|
[-]
[+]
|
Changed |
_service:tar_git:waypipe-0.9.0+git1.tar.bz2/upstream/protocols/function_list.txt
^
|
@@ -25,6 +25,7 @@
wp_presentation_evt_clock_id
wp_presentation_feedback_evt_presented
wp_presentation_req_feedback
+xdg_toplevel_req_set_title
zwlr_data_control_offer_v1_req_receive
zwlr_data_control_source_v1_evt_send
zwlr_export_dmabuf_frame_v1_evt_frame
|
[-]
[+]
|
Changed |
_service:tar_git:waypipe-0.9.0+git1.tar.bz2/upstream/src/client.c
^
|
@@ -127,6 +127,17 @@
"Waypipe client is rejecting connection, Waypipe client was not configured for the VP9 video coding format requested by the Waypipe server");
return -1;
}
+ } else if ((header & CONN_VIDEO_MASK) == CONN_AV1_VIDEO) {
+ if (!config->video_if_possible) {
+ snprintf(err, err_size,
+ "Waypipe client is rejecting connection, Waypipe client was not run with video encoding enabled, unlike Waypipe server");
+ return -1;
+ }
+ if (config->video_fmt != VIDEO_AV1) {
+ snprintf(err, err_size,
+ "Waypipe client is rejecting connection, Waypipe client was not configured for the AV1 video coding format requested by the Waypipe server");
+ return -1;
+ }
} else if ((header & CONN_VIDEO_MASK) == CONN_NO_VIDEO) {
if (config->video_if_possible) {
snprintf(err, err_size,
@@ -760,8 +771,10 @@
retcode = run_multi_client(cwd_fd, channelsock, &eol_pid,
config, display_path);
}
- unlink_at_folder(cwd_fd, sock_folder_fd, sock_folder_name,
- sock_filename);
+ if (!config->vsock) {
+ unlink_at_folder(cwd_fd, sock_folder_fd, sock_folder_name,
+ sock_filename);
+ }
int cleanup_type = shutdown_flag ? WNOHANG : 0;
int status = -1;
@@ -776,7 +789,9 @@
if (eol_pid) {
waitpid(eol_pid, NULL, 0);
}
- unlink_at_folder(cwd_fd, sock_folder_fd, sock_folder_name,
- sock_filename);
+ if (!config->vsock) {
+ unlink_at_folder(cwd_fd, sock_folder_fd, sock_folder_name,
+ sock_filename);
+ }
return EXIT_FAILURE;
}
|
[-]
[+]
|
Changed |
_service:tar_git:waypipe-0.9.0+git1.tar.bz2/upstream/src/dmabuf.c
^
|
@@ -105,6 +105,10 @@
#include <gbm.h>
+#ifndef DRM_FORMAT_MOD_INVALID
+#define DRM_FORMAT_MOD_INVALID 0x00ffffffffffffffULL
+#endif
+
int init_render_data(struct render_data *data)
{
/* render node support can be disabled either by choice
|
[-]
[+]
|
Changed |
_service:tar_git:waypipe-0.9.0+git1.tar.bz2/upstream/src/dmabuf.h
^
|
@@ -94,8 +94,4 @@
* returns -1. */
int get_shm_bytes_per_pixel(uint32_t format);
-#ifndef DRM_FORMAT_MOD_INVALID
-#define DRM_FORMAT_MOD_INVALID 0x00ffffffffffffffULL
-#endif
-
#endif // WAYPIPE_DMABUF_H
|
[-]
[+]
|
Changed |
_service:tar_git:waypipe-0.9.0+git1.tar.bz2/upstream/src/handlers.c
^
|
@@ -36,6 +36,10 @@
#include <protocols.h>
+#ifndef DRM_FORMAT_MOD_INVALID
+#define DRM_FORMAT_MOD_INVALID 0x00ffffffffffffffULL
+#endif
+
struct obj_wl_shm_pool {
struct wp_object base;
struct shadow_fd *owned_buffer;
@@ -232,6 +236,23 @@
&intf_zwp_primary_selection_source_v1,
};
+static void cleanup_dmabuf_params_fds(struct obj_zwp_linux_dmabuf_params *r)
+{
+ // Sometimes multiple entries point to the same buffer
+ for (int i = 0; i < MAX_DMABUF_PLANES; i++) {
+ int fd = r->add[i].fd;
+ if (fd != -1) {
+ checked_close(fd);
+
+ for (int k = 0; k < MAX_DMABUF_PLANES; k++) {
+ if (fd == r->add[k].fd) {
+ r->add[k].fd = -1;
+ }
+ }
+ }
+ }
+}
+
void destroy_wp_object(struct wp_object *object)
{
if (object->type == &intf_wl_shm_pool) {
@@ -267,17 +288,8 @@
if (r->add[i].buffer) {
shadow_decref_protocol(r->add[i].buffer);
}
- // Sometimes multiple entries point to the same buffer
- if (r->add[i].fd != -1) {
- checked_close(r->add[i].fd);
-
- for (int k = 0; k < MAX_DMABUF_PLANES; k++) {
- if (r->add[i].fd == r->add[k].fd) {
- r->add[k].fd = -1;
- }
- }
- }
}
+ cleanup_dmabuf_params_fds(r);
} else if (object->type == &intf_zwlr_export_dmabuf_frame_v1) {
struct obj_wlr_export_dmabuf_frame *r =
(struct obj_wlr_export_dmabuf_frame *)object;
@@ -955,8 +967,8 @@
return;
}
- struct shadow_fd *sfd = translate_fd(&ctx->g->map, &ctx->g->render, fd,
- FDC_FILE, fdsz, NULL, false);
+ struct shadow_fd *sfd = translate_fd(&ctx->g->map, &ctx->g->render,
+ &ctx->g->threads, fd, FDC_FILE, fdsz, NULL, false);
if (!sfd) {
wp_error("Failed to create shadow for keymap fd=%d", fd);
return;
@@ -996,8 +1008,8 @@
return;
}
- struct shadow_fd *sfd = translate_fd(&ctx->g->map, &ctx->g->render, fd,
- FDC_FILE, fdsz, NULL, false);
+ struct shadow_fd *sfd = translate_fd(&ctx->g->map, &ctx->g->render,
+ &ctx->g->threads, fd, FDC_FILE, fdsz, NULL, false);
if (!sfd) {
return;
}
@@ -1248,7 +1260,7 @@
};
struct shadow_fd *sfd = translate_fd(&ctx->g->map, &ctx->g->render,
- name, FDC_DMABUF, 0, &info, false);
+ &ctx->g->threads, name, FDC_DMABUF, 0, &info, false);
if (!sfd) {
return;
}
@@ -1339,12 +1351,17 @@
i);
continue;
}
- buf->dmabuf_buffers[i] =
- shadow_incref_protocol(params->add[i].buffer);
+ // Move protocol reference from `params` to `buf`
+ // (The params object can only be used to create one buffer,
+ // so this ensures that if the params object leaks, the
+ // shadow_fd does not leak as well.)
+ buf->dmabuf_buffers[i] = params->add[i].buffer;
buf->dmabuf_offsets[i] = params->add[i].offset;
buf->dmabuf_strides[i] = params->add[i].stride;
buf->dmabuf_modifiers[i] = params->add[i].modifier;
+ params->add[i].buffer = NULL;
}
+ cleanup_dmabuf_params_fds(params);
buf->dmabuf_flags = params->create_flags;
buf->dmabuf_width = params->create_width;
buf->dmabuf_height = params->create_height;
@@ -1453,8 +1470,8 @@
/* note: the``info` provided includes the incoming/as-if stride
* data. */
struct shadow_fd *sfd = translate_fd(&ctx->g->map,
- &ctx->g->render, params->add[i].fd, res_type, 0,
- &info, false);
+ &ctx->g->render, &ctx->g->threads,
+ params->add[i].fd, res_type, 0, &info, false);
if (!sfd) {
continue;
}
@@ -1664,8 +1681,8 @@
fd, fdcat_to_str(fdtype), fdsz, size);
return;
}
- struct shadow_fd *sfd = translate_fd(&ctx->g->map, &ctx->g->render, fd,
- FDC_FILE, size, NULL, false);
+ struct shadow_fd *sfd = translate_fd(&ctx->g->map, &ctx->g->render,
+ &ctx->g->threads, fd, FDC_FILE, size, NULL, false);
if (!sfd) {
return;
}
@@ -1853,8 +1870,8 @@
.modifier = frame->modifier};
info.using_planes[index] = true;
- struct shadow_fd *sfd = translate_fd(&ctx->g->map, &ctx->g->render, fd,
- FDC_DMABUF, 0, &info, false);
+ struct shadow_fd *sfd = translate_fd(&ctx->g->map, &ctx->g->render,
+ &ctx->g->threads, fd, FDC_DMABUF, 0, &info, false);
if (!sfd) {
return;
}
@@ -1891,14 +1908,14 @@
}
}
}
-static void translate_data_transfer_fd(struct context *context, int32_t fd)
+static void translate_data_transfer_fd(struct context *ctx, int32_t fd)
{
/* treat the fd as a one-way pipe, even if it is e.g. a file or
* socketpair, with additional properties. The fd being sent
* around should be, according to the protocol, only written into and
* closed */
- (void)translate_fd(&context->g->map, &context->g->render, fd, FDC_PIPE,
- 0, NULL, true);
+ (void)translate_fd(&ctx->g->map, &ctx->g->render, &ctx->g->threads, fd,
+ FDC_PIPE, 0, NULL, true);
}
void do_gtk_primary_selection_offer_req_receive(
struct context *ctx, const char *mime_type, int fd)
@@ -1964,8 +1981,8 @@
fdcat_to_str(fdtype));
return;
}
- struct shadow_fd *sfd = translate_fd(&ctx->g->map, &ctx->g->render, fd,
- FDC_FILE, fdsz, NULL, false);
+ struct shadow_fd *sfd = translate_fd(&ctx->g->map, &ctx->g->render,
+ &ctx->g->threads, fd, FDC_FILE, fdsz, NULL, false);
if (!sfd) {
return;
}
@@ -1975,4 +1992,31 @@
sfd->has_owner = true;
}
+#define MSGNO_XDG_TOPLEVEL_REQ_SET_TITLE 2
+void do_xdg_toplevel_req_set_title(struct context *ctx, const char *str)
+{
+ if (!ctx->g->config->title_prefix) {
+ return;
+ }
+ size_t prefix_len = strlen(ctx->g->config->title_prefix);
+ if (4 + (int)prefix_len >= ctx->message_available_space) {
+ wp_error("Not enough space (%d left, at most %d needed) to prepend title prefix",
+ ctx->message_available_space, 4 + prefix_len);
+ return;
+ }
+ size_t title_len = strlen(str);
+ size_t str_part = alignz(prefix_len + title_len + 1, 4);
+
+ ctx->message[1] = message_header_2((uint32_t)str_part + 12,
+ MSGNO_XDG_TOPLEVEL_REQ_SET_TITLE);
+ ctx->message[2] = (uint32_t)(prefix_len + title_len + 1);
+ char *v = (char *)&ctx->message[3];
+ // Using memmove, as str=&ctx->message[3]
+ memmove(v + prefix_len, v, title_len);
+ memset(v + prefix_len + title_len, 0,
+ str_part - prefix_len - title_len);
+ memcpy(v, ctx->g->config->title_prefix, prefix_len);
+ ctx->message_length = 12 + (int)str_part;
+}
+
const struct wp_interface *the_display_interface = &intf_wl_display;
|
[-]
[+]
|
Changed |
_service:tar_git:waypipe-0.9.0+git1.tar.bz2/upstream/src/main.h
^
|
@@ -41,6 +41,11 @@
enum video_coding_fmt video_fmt;
bool prefer_hwvideo;
bool old_video_mode;
+ bool vsock;
+ uint32_t vsock_cid;
+ uint32_t vsock_port;
+ bool vsock_to_host;
+ const char *title_prefix;
};
struct globals {
const struct main_config *config;
|
[-]
[+]
|
Changed |
_service:tar_git:waypipe-0.9.0+git1.tar.bz2/upstream/src/mainloop.c
^
|
@@ -138,8 +138,8 @@
}
static int translate_fds(struct fd_translation_map *map,
- struct render_data *render, int nfds, const int fds[],
- int ids[])
+ struct render_data *render, struct thread_pool *threads,
+ int nfds, const int fds[], int ids[])
{
for (int i = 0; i < nfds; i++) {
struct shadow_fd *sfd = get_shadow_for_local_fd(map, fds[i]);
@@ -147,8 +147,8 @@
/* Autodetect type + create shadow fd */
size_t fdsz = 0;
enum fdcat fdtype = get_fd_type(fds[i], &fdsz);
- sfd = translate_fd(map, render, fds[i], fdtype, fdsz,
- NULL, false);
+ sfd = translate_fd(map, render, threads, fds[i], fdtype,
+ fdsz, NULL, false);
}
if (sfd) {
ids[i] = sfd->remote_id;
@@ -967,7 +967,7 @@
int32_t *rbuffer = (int32_t *)(msg + 1);
/* Translate and adjust refcounts */
- if (translate_fds(&g->map, &g->render,
+ if (translate_fds(&g->map, &g->render, &g->threads,
wmsg->fds.zone_start,
wmsg->fds.data, rbuffer) == -1) {
free(msg);
|
[-]
[+]
|
Changed |
_service:tar_git:waypipe-0.9.0+git1.tar.bz2/upstream/src/server.c
^
|
@@ -61,6 +61,7 @@
header |= (config->video_fmt == VIDEO_H264 ? CONN_H264_VIDEO
: 0);
header |= (config->video_fmt == VIDEO_VP9 ? CONN_VP9_VIDEO : 0);
+ header |= (config->video_fmt == VIDEO_AV1 ? CONN_AV1_VIDEO : 0);
} else {
header |= CONN_NO_VIDEO;
}
@@ -278,8 +279,18 @@
}
int chanfd = -1;
- if (connect_to_socket(cwd_fd, current_sockaddr, NULL, &chanfd) == -1) {
- goto fail_appfd;
+ if (!config->vsock) {
+ if (connect_to_socket(cwd_fd, current_sockaddr, NULL,
+ &chanfd) == -1) {
+ goto fail_appfd;
+ }
+ } else {
+#ifdef HAS_VSOCK
+ if (connect_to_vsock(config->vsock_port, config->vsock_cid,
+ config->vsock_to_host, &chanfd) == -1) {
+ goto fail_appfd;
+ }
+#endif
}
if (write(chanfd, new_token, sizeof(*new_token)) !=
sizeof(*new_token)) {
|
[-]
[+]
|
Changed |
_service:tar_git:waypipe-0.9.0+git1.tar.bz2/upstream/src/shadow.c
^
|
@@ -533,9 +533,9 @@
}
struct shadow_fd *translate_fd(struct fd_translation_map *map,
- struct render_data *render, int fd, enum fdcat type,
- size_t file_sz, const struct dmabuf_slice_data *info,
- bool force_pipe_iw)
+ struct render_data *render, struct thread_pool *threads, int fd,
+ enum fdcat type, size_t file_sz,
+ const struct dmabuf_slice_data *info, bool force_pipe_iw)
{
struct shadow_fd *sfd = get_shadow_for_local_fd(map, fd);
if (sfd) {
@@ -657,7 +657,7 @@
if (!sfd->dmabuf_bo) {
return sfd;
}
- if (setup_video_encode(sfd, render) == -1) {
+ if (setup_video_encode(sfd, render, threads->nthreads) == -1) {
wp_error("Video encoding setup failed for RID=%d",
sfd->remote_id);
}
@@ -718,6 +718,7 @@
{
struct shadow_fd *sfd = task->sfd;
struct thread_pool *pool = local->pool;
+ size_t diffsize = (size_t)-1;
size_t damage_space = 0;
for (int i = 0; i < task->damage_len; i++) {
@@ -798,7 +799,7 @@
source = sfd->dmabuf_warped;
}
- size_t diffsize = construct_diff_core(pool->diff_func,
+ diffsize = construct_diff_core(pool->diff_func,
pool->diff_alignment_bits, task->damage_intervals,
task->damage_len, sfd->mem_mirror, source, diff_target);
size_t ntrailing = 0;
@@ -1144,7 +1145,7 @@
header->file_size = (uint32_t)sfd->buffer_size;
header->remote_id = sfd->remote_id;
header->size_and_type = transfer_header(actual_len, variant);
- header->vid_flags = (fmt == VIDEO_H264) ? DMAVID_H264 : DMAVID_VP9;
+ header->vid_flags = (uint32_t)fmt;
memcpy(data + sizeof(*header), &sfd->dmabuf_info,
sizeof(struct dmabuf_slice_data));
@@ -1696,15 +1697,16 @@
memcpy(&sfd->dmabuf_info,
msg->data + sizeof(struct wmsg_open_dmavid),
sizeof(struct dmabuf_slice_data));
- if ((header.vid_flags & 0xff) == DMAVID_H264) {
- sfd->video_fmt = VIDEO_H264;
- } else if ((header.vid_flags & 0xff) == DMAVID_VP9) {
- sfd->video_fmt = VIDEO_VP9;
+ uint32_t vid_type = header.vid_flags & 0xff;
+ if (vid_type == (uint32_t)VIDEO_H264 ||
+ vid_type == (uint32_t)VIDEO_VP9 ||
+ vid_type == (uint32_t)VIDEO_AV1) {
+ sfd->video_fmt =
+ (enum video_coding_fmt)vid_type;
} else {
- sfd->video_fmt = VIDEO_H264;
- wp_error("Unidentified video format for RID=%d",
- sfd->remote_id);
- return 0;
+ wp_error("Unidentified video format %u for RID=%d",
+ vid_type, sfd->remote_id);
+ return ERR_FATAL;
}
}
@@ -1765,15 +1767,16 @@
memcpy(&sfd->dmabuf_info,
msg->data + sizeof(struct wmsg_open_dmavid),
sizeof(struct dmabuf_slice_data));
- if ((header.vid_flags & 0xff) == DMAVID_H264) {
- sfd->video_fmt = VIDEO_H264;
- } else if ((header.vid_flags & 0xff) == DMAVID_VP9) {
- sfd->video_fmt = VIDEO_VP9;
+ uint32_t vid_type = header.vid_flags & 0xff;
+ if (vid_type == (uint32_t)VIDEO_H264 ||
+ vid_type == (uint32_t)VIDEO_VP9 ||
+ vid_type == (uint32_t)VIDEO_AV1) {
+ sfd->video_fmt =
+ (enum video_coding_fmt)vid_type;
} else {
- sfd->video_fmt = VIDEO_H264;
- wp_error("Unidentified video format for RID=%d",
+ wp_error("Unidentified video format %u for RID=%d",
sfd->remote_id);
- return 0;
+ return ERR_FATAL;
}
}
@@ -1790,7 +1793,7 @@
}
sfd->fd_local = export_dmabuf(sfd->dmabuf_bo);
- if (setup_video_encode(sfd, render) == -1) {
+ if (setup_video_encode(sfd, render, threads->nthreads) == -1) {
wp_error("Video encoding setup failed for RID=%d",
sfd->remote_id);
}
|
[-]
[+]
|
Changed |
_service:tar_git:waypipe-0.9.0+git1.tar.bz2/upstream/src/shadow.h
^
|
@@ -175,11 +175,6 @@
bool pending_w_shutdown;
};
-enum video_coding_fmt {
- VIDEO_H264,
- VIDEO_VP9,
-};
-
/**
* @brief The shadow_fd struct
*
@@ -272,7 +267,8 @@
* warn and disable replication features.
**/
struct shadow_fd *translate_fd(struct fd_translation_map *map,
- struct render_data *render, int fd, enum fdcat type, size_t sz,
+ struct render_data *render, struct thread_pool *threads, int fd,
+ enum fdcat type, size_t sz,
const struct dmabuf_slice_data *info, bool force_pipe_iw);
/** Given a struct shadow_fd, produce some number of corresponding file update
* transfer messages. All pointers will be to existing memory. */
@@ -363,7 +359,8 @@
void setup_video_logging(void);
void destroy_video_data(struct shadow_fd *sfd);
/** These need to have the dmabuf/dmabuf_info set beforehand */
-int setup_video_encode(struct shadow_fd *sfd, struct render_data *rd);
+int setup_video_encode(
+ struct shadow_fd *sfd, struct render_data *rd, int nthreads);
int setup_video_decode(struct shadow_fd *sfd, struct render_data *rd);
/** the video frame to be transferred should already have been transferred into
* `sfd->mem_mirror`. */
|
[-]
[+]
|
Changed |
_service:tar_git:waypipe-0.9.0+git1.tar.bz2/upstream/src/util.c
^
|
@@ -41,6 +41,9 @@
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
+#ifdef HAS_VSOCK
+#include <linux/vm_sockets.h>
+#endif
int parse_uint32(const char *str, uint32_t *val)
{
@@ -109,6 +112,66 @@
return net_len;
}
+bool is_utf8(const char *str)
+{
+ /* See Unicode Standard 15.0.0, Chapter 3, D92 and Table 3.7. */
+ const uint8_t *v = (const uint8_t *)str;
+ while (*v) {
+ if (v[0] <= 0x7f) {
+ v++;
+ } else if (v[0] <= 0xdf) {
+ if (v[1] < 0x80 || v[1] > 0xbf) {
+ return false;
+ }
+ v += 2;
+ } else if (v[0] <= 0xef) {
+ if (v[0] == 0xe0) {
+ if (v[1] < 0xa0 || v[1] > 0xbf) {
+ return false;
+ }
+ } else if (v[0] <= 0xec) {
+ if (v[1] < 0x80 || v[1] > 0xbf) {
+ return false;
+ }
+ } else if (v[0] == 0xed) {
+ if (v[1] < 0x80 || v[1] > 0x9f) {
+ return false;
+ }
+ } else {
+ if (v[1] < 0x80 || v[1] > 0xbf) {
+ return false;
+ }
+ }
+ if (v[2] < 0x80 || v[2] > 0xbf) {
+ return false;
+ }
+ v += 3;
+ } else if (v[0] <= 0xf4) {
+ if (v[0] == 0xf0) {
+ if (v[1] < 0x90 || v[1] > 0xbf) {
+ return false;
+ }
+ } else if (v[0] <= 0xf3) {
+ if (v[1] < 0x80 || v[1] > 0xbf) {
+ return false;
+ }
+ } else {
+ if (v[1] < 0x80 || v[1] > 0x8f) {
+ return false;
+ }
+ }
+ if (v[2] < 0x80 || v[2] > 0xbf || v[3] < 0x80 ||
+ v[3] > 0xbf) {
+ return false;
+ }
+ v += 4;
+ } else {
+ return false;
+ }
+ }
+ return true;
+}
+
bool shutdown_flag = false;
uint64_t inherited_fds[4] = {0, 0, 0, 0};
void handle_sigint(int sig)
@@ -663,3 +726,77 @@
free(td->vecs);
free(td->meta);
}
+
+#ifdef HAS_VSOCK
+int connect_to_vsock(uint32_t port, uint32_t cid, bool to_host, int *socket_fd)
+{
+ wp_debug("Connecting to vsock on port %d, cid %d, send to host %d",
+ port, cid, to_host);
+
+ int chanfd = socket(AF_VSOCK, SOCK_STREAM, 0);
+ if (chanfd == -1) {
+ wp_error("Error creating socket: %s", strerror(errno));
+ return -1;
+ }
+
+ struct sockaddr_vm addr;
+ memset(&addr, 0, sizeof(struct sockaddr_vm));
+ addr.svm_family = AF_VSOCK;
+ addr.svm_port = port;
+ addr.svm_cid = cid;
+ if (to_host) {
+ addr.svm_flags = VMADDR_FLAG_TO_HOST;
+ }
+
+ if ((connect(chanfd, (struct sockaddr *)&addr,
+ sizeof(struct sockaddr_vm))) == -1) {
+ wp_error("Error connecting to vsock at port %d: %s", port,
+ strerror(errno));
+ checked_close(chanfd);
+ return -1;
+ }
+ *socket_fd = chanfd;
+ return 0;
+}
+
+int listen_on_vsock(uint32_t port, int nmaxclients, int *socket_fd_out)
+{
+ wp_debug("Listening on vsock port %d", port);
+
+ int sock = socket(AF_VSOCK, SOCK_STREAM, 0);
+ if (sock == -1) {
+ wp_error("Error creating socket: %s", strerror(errno));
+ return -1;
+ }
+
+ if (set_nonblocking(sock) == -1) {
+ wp_error("Error making socket nonblocking: %s",
+ strerror(errno));
+ checked_close(sock);
+ return -1;
+ }
+
+ struct sockaddr_vm addr;
+ memset(&addr, 0, sizeof(struct sockaddr_vm));
+ addr.svm_family = AF_VSOCK;
+ addr.svm_port = port;
+ addr.svm_cid = VMADDR_CID_ANY;
+ if (bind(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_vm)) ==
+ -1) {
+ wp_error("Error binding vsock at cid %d port %d: %s",
+ addr.svm_cid, port, strerror(errno));
+ checked_close(sock);
+ return -1;
+ }
+
+ if (listen(sock, nmaxclients) == -1) {
+ wp_error("Error listening to socket at cid %d port %d: %s",
+ addr.svm_cid, port, strerror(errno));
+ checked_close(sock);
+ return -1;
+ }
+
+ *socket_fd_out = sock;
+ return 0;
+}
+#endif
|
[-]
[+]
|
Changed |
_service:tar_git:waypipe-0.9.0+git1.tar.bz2/upstream/src/util.h
^
|
@@ -82,6 +82,9 @@
* Last argment must be NULL. If there is not enough space, returns 0. */
size_t multi_strcat(char *dest, size_t dest_space, ...);
+/** Is the string a well-formed UTF-8 code point sequence, per Unicode 15.0? */
+bool is_utf8(const char *str);
+
/** Make the file underlying this file descriptor nonblocking.
* Silently return -1 on failure. */
int set_nonblocking(int fd);
@@ -202,6 +205,7 @@
#define CONN_NO_VIDEO (0x1u << 11)
#define CONN_VP9_VIDEO (0x2u << 11)
#define CONN_H264_VIDEO (0x3u << 11)
+#define CONN_AV1_VIDEO (0x4u << 11)
struct connection_token {
/** Indicate protocol version (top 16 bits), endianness, and
@@ -370,8 +374,12 @@
};
static_assert(sizeof(struct wmsg_open_dmabuf) == 12, "size check");
-#define DMAVID_H264 0x00
-#define DMAVID_VP9 0x01
+enum video_coding_fmt {
+ VIDEO_H264 = 0,
+ VIDEO_VP9 = 1,
+ VIDEO_AV1 = 2,
+};
+
struct wmsg_open_dmavid {
uint32_t size_and_type;
int32_t remote_id;
@@ -504,4 +512,9 @@
*/
int open_folder(const char *name);
+#ifdef HAS_VSOCK
+int connect_to_vsock(uint32_t port, uint32_t cid, bool to_host, int *socket_fd);
+int listen_on_vsock(uint32_t port, int nmaxclients, int *socket_fd_out);
+#endif
+
#endif // WAYPIPE_UTIL_H
|
[-]
[+]
|
Changed |
_service:tar_git:waypipe-0.9.0+git1.tar.bz2/upstream/src/video.c
^
|
@@ -46,10 +46,12 @@
}
void cleanup_hwcontext(struct render_data *rd) { (void)rd; }
void destroy_video_data(struct shadow_fd *sfd) { (void)sfd; }
-int setup_video_encode(struct shadow_fd *sfd, struct render_data *rd)
+int setup_video_encode(
+ struct shadow_fd *sfd, struct render_data *rd, int nthreads)
{
(void)sfd;
(void)rd;
+ (void)nthreads;
return -1;
}
int setup_video_decode(struct shadow_fd *sfd, struct render_data *rd)
@@ -101,6 +103,17 @@
#define VIDEO_VP9_SW_ENCODER "libvpx-vp9"
#define VIDEO_VP9_DECODER "vp9"
+/* librav1e currently is not sufficient as its low-latency mode doesn't
+ * appear to entirely turn off lookahead, and a few frames of latency
+ * are unavoidable; this may be fixed in the future.
+ *
+ * libsvtav1 -- might work, if suitable controls for zero latency can be found
+ *
+ * libaom-av1 -- works, but may be slower than the other options */
+// #define VIDEO_AV1_SW_ENCODER "libsvtav1"
+#define VIDEO_AV1_SW_ENCODER "libaom-av1"
+#define VIDEO_AV1_DECODER "libdav1d"
+
static enum AVPixelFormat drm_to_av(uint32_t format)
{
/* The avpixel formats are specified with reversed endianness relative
@@ -211,23 +224,100 @@
return video_supports_dmabuf_format(format, 0);
}
-bool video_supports_coding_format(enum video_coding_fmt fmt)
+static const struct AVCodec *get_video_sw_encoder(
+ enum video_coding_fmt fmt, bool print_error)
{
- const struct AVCodec *enc, *dec;
+ const struct AVCodec *codec = NULL;
switch (fmt) {
+ case VIDEO_H264:
+ codec = avcodec_find_encoder_by_name(VIDEO_H264_SW_ENCODER);
+ if (!codec && print_error) {
+ wp_error("Failed to find encoder \"%s\"",
+ VIDEO_H264_SW_ENCODER);
+ }
+ return codec;
case VIDEO_VP9:
- enc = avcodec_find_encoder_by_name(VIDEO_VP9_SW_ENCODER);
- dec = avcodec_find_decoder_by_name(VIDEO_VP9_DECODER);
- return enc && dec;
+ codec = avcodec_find_encoder_by_name(VIDEO_VP9_SW_ENCODER);
+ if (!codec && print_error) {
+ wp_error("Failed to find encoder \"%s\"",
+ VIDEO_VP9_SW_ENCODER);
+ }
+ return codec;
+ case VIDEO_AV1:
+ codec = avcodec_find_encoder_by_name(VIDEO_AV1_SW_ENCODER);
+ if (!codec && print_error) {
+ wp_error("Failed to find encoder \"%s\"",
+ VIDEO_AV1_SW_ENCODER);
+ }
+ return codec;
+ default:
+ return NULL;
+ }
+}
+
+static const struct AVCodec *get_video_hw_encoder(
+ enum video_coding_fmt fmt, bool print_error)
+{
+ const struct AVCodec *codec = NULL;
+ switch (fmt) {
case VIDEO_H264:
- enc = avcodec_find_encoder_by_name(VIDEO_H264_SW_ENCODER);
- dec = avcodec_find_decoder_by_name(VIDEO_H264_DECODER);
- return enc && dec;
+ codec = avcodec_find_encoder_by_name(VIDEO_H264_HW_ENCODER);
+ if (!codec && print_error) {
+ wp_error("Failed to find encoder \"%s\"",
+ VIDEO_H264_HW_ENCODER);
+ }
+ return codec;
+ case VIDEO_VP9:
+ codec = avcodec_find_encoder_by_name(VIDEO_VP9_HW_ENCODER);
+ if (!codec && print_error) {
+ wp_error("Failed to find encoder \"%s\"",
+ VIDEO_VP9_HW_ENCODER);
+ }
+ return codec;
+ case VIDEO_AV1:
+ return NULL;
default:
- return false;
+ return NULL;
+ }
+}
+
+static const struct AVCodec *get_video_decoder(
+ enum video_coding_fmt fmt, bool print_error)
+{
+ const struct AVCodec *codec = NULL;
+ switch (fmt) {
+ case VIDEO_H264:
+ codec = avcodec_find_decoder_by_name(VIDEO_H264_DECODER);
+ if (!codec && print_error) {
+ wp_error("Failed to find decoder \"%s\"",
+ VIDEO_H264_DECODER);
+ }
+ return codec;
+ case VIDEO_VP9:
+ codec = avcodec_find_decoder_by_name(VIDEO_VP9_DECODER);
+ if (!codec && print_error) {
+ wp_error("Failed to find decoder \"%s\"",
+ VIDEO_VP9_DECODER);
+ }
+ return codec;
+ case VIDEO_AV1:
+ codec = avcodec_find_decoder_by_name(VIDEO_AV1_DECODER);
+ if (!codec && print_error) {
+ wp_error("Failed to find decoder \"%s\"",
+ VIDEO_AV1_DECODER);
+ }
+ return codec;
+ default:
+ return NULL;
}
}
+bool video_supports_coding_format(enum video_coding_fmt fmt)
+{
+ return get_video_sw_encoder(fmt, false) &&
+ get_video_decoder(fmt, false);
+}
+
static void video_log_callback(
void *aux, int level, const char *fmt, va_list args)
{
@@ -629,7 +719,7 @@
}
static void configure_low_latency_enc_context(struct AVCodecContext *ctx,
- bool sw, enum video_coding_fmt fmt, int bpf)
+ bool sw, enum video_coding_fmt fmt, int bpf, int nthreads)
{
// "time" is only meaningful in terms of the frames provided
int nom_fps = 25;
@@ -667,6 +757,22 @@
if (av_opt_set(ctx->priv_data, "speed", "8", 0) != 0) {
wp_error("Failed to set vp9 speed");
}
+ } else if (fmt == VIDEO_AV1) {
+ // AOM-AV1
+ if (av_opt_set(ctx->priv_data, "usage", "realtime",
+ 0) != 0) {
+ wp_error("Failed to set av1 usage");
+ }
+ if (av_opt_set(ctx->priv_data, "lag-in-frames", "0",
+ 0) != 0) {
+ wp_error("Failed to set av1 lag");
+ }
+ if (av_opt_set(ctx->priv_data, "cpu-used", "8", 0) !=
+ 0) {
+ wp_error("Failed to set av1 speed");
+ }
+ // Use multi-threaded encoding
+ ctx->thread_count = nthreads;
}
} else {
ctx->bit_rate = bpf * nom_fps;
@@ -681,23 +787,21 @@
}
}
-static int setup_hwvideo_encode(struct shadow_fd *sfd, struct render_data *rd)
+static int setup_hwvideo_encode(
+ struct shadow_fd *sfd, struct render_data *rd, int nthreads)
{
/* NV12 is the preferred format for Intel VAAPI; see also
* intel-vaapi-driver/src/i965_drv_video.c . Packed formats like
* YUV420P typically don't work. */
const enum AVPixelFormat videofmt = AV_PIX_FMT_NV12;
- const char *hw_encoder = sfd->video_fmt == VIDEO_H264
- ? VIDEO_H264_HW_ENCODER
- : VIDEO_VP9_HW_ENCODER;
- const struct AVCodec *codec = avcodec_find_encoder_by_name(hw_encoder);
+ const struct AVCodec *codec =
+ get_video_hw_encoder(sfd->video_fmt, true);
if (!codec) {
- wp_error("Failed to find encoder \"%s\"", hw_encoder);
return -1;
}
struct AVCodecContext *ctx = avcodec_alloc_context3(codec);
configure_low_latency_enc_context(
- ctx, false, sfd->video_fmt, rd->av_bpf);
+ ctx, false, sfd->video_fmt, rd->av_bpf, nthreads);
|
[-]
[+]
|
Changed |
_service:tar_git:waypipe-0.9.0+git1.tar.bz2/upstream/src/waypipe.c
^
|
@@ -83,6 +83,7 @@
" server default: /tmp/waypipe-server.sock\n"
" client default: /tmp/waypipe-client.sock\n"
" ssh: sets the prefix for the socket path\n"
+ " vsock: [[s]CID:]port\n"
" --version print waypipe version and exit\n"
" --allow-tiled allow gpu buffers (DMABUFs) with format modifiers\n"
" --control C server,ssh: set control pipe to reconnect server\n"
@@ -92,9 +93,11 @@
" --remote-bin R ssh: set the remote waypipe binary. default: waypipe\n"
" --login-shell server: if server CMD is empty, run a login shell\n"
" --threads T set thread pool size, default=hardware threads/2\n"
+ " --title-prefix P prepend P to all window titles\n"
" --unlink-socket server: unlink the socket that waypipe connects to\n"
" --video[=V] compress certain linear dmabufs only with a video codec\n"
- " V is list of options: sw,hw,bpf=1.2e5,h264,vp9\n"
+ " V is list of options: sw,hw,bpf=1.2e5,h264,vp9,av1\n"
+ " --vsock use vsock instead of unix socket\n"
"\n";
static int usage(int retcode)
@@ -324,6 +327,8 @@
config->video_fmt = VIDEO_H264;
} else if (!strcmp(part, "vp9")) {
config->video_fmt = VIDEO_VP9;
+ } else if (!strcmp(part, "av1")) {
+ config->video_fmt = VIDEO_AV1;
} else if (!strcmp(part, "hw")) {
config->prefer_hwvideo = true;
} else if (!strcmp(part, "sw")) {
@@ -345,6 +350,56 @@
}
#endif
+#ifdef HAS_VSOCK
+static int parse_vsock_addr(const char *str, struct main_config *config)
+{
+ char tmp[128];
+ size_t l = strlen(str);
+ if (l >= 127) {
+ return -1;
+ }
+ memcpy(tmp, str, l + 1);
+
+ char *port = strchr(tmp, ':');
+ if (port) {
+ char *cid = tmp;
+ port[0] = 0;
+ port = port + 1;
+
+ size_t cid_len = strlen(cid);
+ if (cid_len > 0) {
+ if (cid[0] == 's') {
+ if (cid_len < 2) {
+ return -1;
+ }
+ config->vsock_to_host = true;
+ if (parse_uint32(cid + 1, &config->vsock_cid) ==
+ -1) {
+ return -1;
+ }
+ } else {
+ config->vsock_to_host = false;
+ if (parse_uint32(cid, &config->vsock_cid) ==
+ -1) {
+ return -1;
+ }
+ }
+ }
+ } else {
+ port = tmp;
+ }
+
+ if (parse_uint32(port, &config->vsock_port) == -1) {
+ return -1;
+ }
+
+ if (config->vsock_port <= 0) {
+ return -1;
+ }
+ return 0;
+}
+#endif
+
static const char *feature_names[] = {
"lz4",
"zstd",
@@ -393,6 +448,8 @@
#define ARG_CONTROL 1010
#define ARG_WAYPIPE_BINARY 1011
#define ARG_BENCH_TEST_SIZE 1012
+#define ARG_VSOCK 1013
+#define ARG_TITLE_PREFIX 1014
static const struct option options[] = {
{"compress", required_argument, NULL, 'c'},
@@ -414,6 +471,8 @@
{"display", required_argument, NULL, ARG_DISPLAY},
{"control", required_argument, NULL, ARG_CONTROL},
{"test-size", required_argument, NULL, ARG_BENCH_TEST_SIZE},
+ {"vsock", no_argument, NULL, ARG_VSOCK},
+ {"title-prefix", required_argument, NULL, ARG_TITLE_PREFIX},
{0, 0, NULL, 0}};
struct arg_permissions {
int val;
@@ -421,18 +480,15 @@
};
#define ALL_MODES (uint32_t) - 1
static const struct arg_permissions arg_permissions[] = {
- {'c', MODE_SSH | MODE_CLIENT | MODE_SERVER},
- {'d', ALL_MODES},
- {'h', MODE_FAIL},
- {'n', MODE_SSH | MODE_CLIENT | MODE_SERVER},
+ {'c', MODE_SSH | MODE_CLIENT | MODE_SERVER}, {'d', ALL_MODES},
+ {'h', MODE_FAIL}, {'n', MODE_SSH | MODE_CLIENT | MODE_SERVER},
{'o', MODE_SSH | MODE_CLIENT | MODE_SERVER},
{'s', MODE_SSH | MODE_CLIENT | MODE_SERVER},
{ARG_VERSION, MODE_FAIL},
{ARG_ALLOW_TILED, MODE_SSH | MODE_CLIENT | MODE_SERVER},
{ARG_UNLINK, MODE_SERVER},
{ARG_DRMNODE, MODE_SSH | MODE_CLIENT | MODE_SERVER},
- {ARG_REMOTENODE, MODE_SSH},
- {ARG_WAYPIPE_BINARY, MODE_SSH},
+ {ARG_REMOTENODE, MODE_SSH}, {ARG_WAYPIPE_BINARY, MODE_SSH},
{ARG_LOGIN_SHELL, MODE_SERVER},
{ARG_VIDEO, MODE_SSH | MODE_CLIENT | MODE_SERVER},
{ARG_HWVIDEO, MODE_SSH | MODE_CLIENT | MODE_SERVER},
@@ -441,7 +497,8 @@
{ARG_DISPLAY, MODE_SSH | MODE_SERVER},
{ARG_CONTROL, MODE_SSH | MODE_SERVER},
{ARG_BENCH_TEST_SIZE, MODE_BENCH},
-};
+ {ARG_VSOCK, MODE_SSH | MODE_CLIENT | MODE_SERVER},
+ {ARG_TITLE_PREFIX, MODE_SSH | MODE_CLIENT | MODE_SERVER}};
/* envp is nonstandard, so use environ */
extern char **environ;
@@ -464,16 +521,27 @@
char *socketpath = NULL;
uint32_t bench_test_size = (1u << 22) + 13;
- struct main_config config = {.n_worker_threads = 0,
+ struct main_config config = {
+ .n_worker_threads = 0,
.drm_node = NULL,
+#ifdef HAS_LZ4
+ .compression = COMP_LZ4,
+#else
.compression = COMP_NONE,
+#endif
.compression_level = 0,
.no_gpu = false,
.only_linear_dmabuf = true,
.video_if_possible = false,
.video_bpf = 0,
.video_fmt = VIDEO_H264,
- .prefer_hwvideo = false};
+ .prefer_hwvideo = false,
+ .vsock = false,
+ .vsock_cid = 2, /* VMADDR_CID_HOST */
+ .vsock_to_host = false, /* VMADDR_FLAG_TO_HOST */
+ .vsock_port = 0,
+ .title_prefix = NULL,
+ };
/* We do not parse any getopt arguments happening after the mode choice
* string, so as not to interfere with them. */
@@ -637,6 +705,25 @@
fail = true;
}
} break;
+ case ARG_VSOCK:
+#ifdef HAS_VSOCK
+ config.vsock = true;
+ break;
+#else
+ fprintf(stderr, "Option --vsock not allowed: this copy of Waypipe was not built with support for Linux VM sockets.\n");
+ return EXIT_FAILURE;
+#endif
+ case ARG_TITLE_PREFIX:
+ if (!is_utf8(optarg)) {
+ fprintf(stderr, "Title prefix argument must be valid UTF-8.\n");
+ return EXIT_FAILURE;
+ }
+ if (strlen(optarg) > 128) {
+ fprintf(stderr, "Title prefix is too long (>128 bytes).\n");
+ return EXIT_FAILURE;
+ }
+ config.title_prefix = optarg;
+ break;
default:
fail = true;
break;
@@ -699,6 +786,20 @@
config.video_bpf = config.prefer_hwvideo ? 360000 : 120000;
}
+#ifdef HAS_VSOCK
+ if (config.vsock) {
+ if (socketpath == NULL) {
|
[-]
[+]
|
Changed |
_service:tar_git:waypipe-0.9.0+git1.tar.bz2/upstream/test/common.c
^
|
@@ -113,8 +113,8 @@
enum fdcat fdtype =
get_fd_type(fd_window.data[i], &fdsz);
sfd = translate_fd(&src->glob.map, &src->glob.render,
- fd_window.data[i], fdtype, fdsz, NULL,
- false);
+ &src->glob.threads, fd_window.data[i],
+ fdtype, fdsz, NULL, false);
}
if (sfd) {
fd_window.data[i] = sfd->remote_id;
|
[-]
[+]
|
Changed |
_service:tar_git:waypipe-0.9.0+git1.tar.bz2/upstream/test/fd_mirror.c
^
|
@@ -325,8 +325,8 @@
} else {
fdtype = get_fd_type(new_file_fd, &fdsz);
}
- struct shadow_fd *src_shadow = translate_fd(&src_map, rd, new_file_fd,
- fdtype, fdsz, slice_data, false);
+ struct shadow_fd *src_shadow = translate_fd(&src_map, rd, NULL,
+ new_file_fd, fdtype, fdsz, slice_data, false);
struct shadow_fd *dst_shadow = NULL;
int rid = src_shadow->remote_id;
|
[-]
[+]
|
Changed |
_service:tar_git:waypipe-0.9.0+git1.tar.bz2/upstream/test/pipe_mirror.c
^
|
@@ -169,8 +169,8 @@
bool success = true;
/* Step 1: replicate */
- struct shadow_fd *src_shadow = translate_fd(&src_map, NULL, spec_end,
- FDC_PIPE, 0, NULL, interpret_as_force_iw);
+ struct shadow_fd *src_shadow = translate_fd(&src_map, NULL, NULL,
+ spec_end, FDC_PIPE, 0, NULL, interpret_as_force_iw);
shadow_decref_transfer(src_shadow);
int rid = src_shadow->remote_id;
if (shadow_sync(&src_map, &dst_map) == -1) {
|
[-]
[+]
|
Changed |
_service:tar_git:waypipe-0.9.0+git1.tar.bz2/upstream/test/protocol_control.c
^
|
@@ -68,7 +68,7 @@
static char *make_filled_pattern(size_t size, uint32_t contents)
{
- uint32_t *mem = calloc(size, 1);
+ uint32_t *mem = calloc(1, size);
for (size_t i = 0; i < size / 4; i++) {
mem[i] = contents;
}
@@ -935,7 +935,7 @@
set_initial_fds();
- int ntest = 20;
+ int ntest = 21;
int nsuccess = 0;
nsuccess += test_fixed_shm_buffer_copy();
nsuccess += test_fixed_shm_screencopy_copy();
@@ -957,6 +957,7 @@
nsuccess += test_fixed_video_color_copy(VIDEO_H264, false);
nsuccess += test_fixed_video_color_copy(VIDEO_H264, true);
nsuccess += test_fixed_video_color_copy(VIDEO_VP9, false);
+ nsuccess += test_fixed_video_color_copy(VIDEO_AV1, false);
// TODO: add tests for handling of common errors, e.g. invalid fd,
// or type confusion
|
[-]
[+]
|
Changed |
_service:tar_git:waypipe-0.9.0+git1.tar.bz2/upstream/waypipe.scd
^
|
@@ -14,7 +14,7 @@
*waypipe* *bench* _bandwidth_++
*waypipe* [*--version*] [*-h*, *--help*]
-\[options...\] = [*-c*, *--compress* C] [*-d*, *--debug*] [*-n*, *--no-gpu*] [*-o*, *--oneshot*] [*-s*, *--socket* S] [*--allow-tiled*] [*--control* C] [*--display* D] [*--drm-node* R] [*--remote-node* R] [*--remote-bin* R] [*--login-shell*] [*--threads* T] [*--unlink-socket*] [*--video*[=V]]
+\[options...\] = [*-c*, *--compress* C] [*-d*, *--debug*] [*-n*, *--no-gpu*] [*-o*, *--oneshot*] [*-s*, *--socket* S] [*--allow-tiled*] [*--control* C] [*--display* D] [*--drm-node* R] [*--remote-node* R] [*--remote-bin* R] [*--login-shell*] [*--threads* T] [*--title-prefix* P] [*--unlink-socket*] [*--video*[=V]] [*--vsock*]
# DESCRIPTION
@@ -55,11 +55,12 @@
*-c C, --compress C*
Select the compression method applied to data transfers. Options are
_none_ (for high-bandwidth networks), _lz4_ (intermediate), _zstd_
- (slow connection). The default compression is _none_.† The compression
+ (slow connection). The default compression is _lz4_.† The compression
level can be chosen by appending = followed by a number. For example,
if *C* is _zstd=7_, waypipe will use level 7 Zstd compression.
- † In a future version, the default will change to _lz4_.
+ † Unless *waypipe* is built without LZ4 support, in which case the default
+ compression will be _none_.
*-d, --debug*
Print debug log messages.
@@ -81,6 +82,8 @@
both the client and the server for their socket paths. The default prefix
in ssh mode is _/tmp/waypipe_.
+ When vsock is enabled use *S* to specify a CID and a port number.
+
*--version*
Briefly describe Waypipe's version and the features it was built with,
then quit. Possible features: LZ4 compression support, ZSTD compression
@@ -132,6 +135,10 @@
behavior (choosable by setting *T* to _0_) is to use half as many threads
as the computer has hardware threads available.
+*--title-prefix P*
+ Prepend *P* to any window titles specified using the XDG shell protocol. In
+ ssh mode, the prefix is applied only on the client side.
+
*--unlink-socket*
Only for server mode; on shutdown, unlink the Unix socket that waypipe connects to.
@@ -163,6 +170,12 @@
*--hwvideo*
Deprecated option, equivalent to --video=hw .
+*--vsock*
+ Use vsock instead of unix sockets. This is used when waypipe is running in
+ virtual machines. With this option enabled specify a CID and a port number in *S*.
+ CID is only used in the server mode and can be omitted when connecting from a
+ guest virtual machine to host.
+
# EXAMPLE
The following *waypipe ssh* subcommand will attempt to run *weston-flower* on
@@ -265,6 +278,40 @@
waypipe recon /tmp/ctrl-lserv.pipe /tmp/waypipe-lserv-2.sock
```
+## Running waypipe in virtual machines
+
+When running waypipe in virtual machines on the same host it is possible to use vsock
+for efficient inter-vm communication. The following scenarios are supported:
+
+- Running applications on host from guest.
+
+```
+ host> waypipe --vsock -s 1234 client
+ guest> waypipe --vsock -s 1234 server weston-terminal
+```
+
+- Running applications in a guest virtual machine from host.
+
+```
+ guest> waypipe --vsock -s 1234 client
+ host> waypipe --vsock -s 3:1234 server weston-terminal
+```
+
+In this example waypipe server connects to a virtual machine with CID 3 on port 1234.
+
+- Running applications in a guest virtual machine from other guest virtual machines.
+When running both client and server in virtual machines it is possble to enable the
+VMADDR_FLAG_TO_HOST flag for sibling communication by prefixing the CID with an s:
+
+```
+ guest> waypipe --vsock -s 1234 client
+ guest> waypipe --vsock -s s3:1234 server weston-terminal
+```
+
+In this case all packets will be routed to host where they can be forwarded to another
+virtual machine with a vhost-device-vsock device or some other utility.
+
+
# ENVIRONMENT
When running as a server, by default _WAYLAND_DISPLAY_ will be set for the
@@ -280,6 +327,39 @@
*waypipe ssh* will exit with the exit status code from the remote command, or
with return code 1 if there has been an error.
+# SECURITY
+
+Waypipe does not provide any strong security guarantees, and connecting to
+untrusted servers is not recommended. It does not filter which Wayland
+protocols the compositor makes available to the client (with a few exceptions
+for protocols that require file descriptors which Waypipe cannot yet handle).
+For example, if a Wayland compositor gives all its clients access to a
+screenshot or lock-screen protocol, then proxied clients run under Waypipe
+can also make screenshots or lock the screen.
+
+In general, applications are not well tested against malicious compositors,
+and compositors are not well tested against malicious clients. Waypipe can
+connect the two, and may blindly forward denial-of-service and other attacks.
+
+Waypipe itself is written in C and links to compression, graphics, and video
+libraries; both it and these libraries may have security bugs. Some risk
+can be avoided by building Waypipe with DMABUF support turned off, or
+running Waypipe with the *--no-gpu* flag so that it does not expose graphics
+libraries.
+
+*waypipe ssh* has no explicit protections against timing attacks; an observer
+to the resulting network traffic may, by studying the size and timing of
+packets, learn information about the user's interaction with a Wayland client
+proxied through *waypipe ssh*. For example: a lack of activity suggests the
+user is not currently using the application, while an intermittant stream of
+messages from the compositor to the client may indicate mouse movement (or
+maybe something else: the contents of the messages are protected by *ssh*.)
+
+The memory used by Waypipe processes may, at a given time, include Wayland
+messages encoding user input, and the contents of current and recent frames
+drawn for application windows. Swap should be encrypted to prevent this data
+from being leaked to disk.
+
# BUGS
File bug reports at: https://gitlab.freedesktop.org/mstoeckl/waypipe/
|
[-]
[+]
|
Changed |
_service:tar_git:waypipe.yaml
^
|
@@ -1,6 +1,6 @@
Name: waypipe
Summary: Network transparency with Wayland
-Version: 0.8.6
+Version: 0.9.0
Release: 0
Group: Applications
License: MIT
@@ -29,6 +29,8 @@
PackageIcon: https://gitlab.freedesktop.org/uploads/-/system/project/avatar/3237/waypipe.png?width=128
Links:
Homepage: https://mstoeckl.com/notes/gsoc/blog.html
+ Help: https://forum.sailfishos.org/t/fun-with-remote-wayland-waypipe/16997
+ Bugtracker: https://github.com/sailfishos-chum/waypipe/issues
%endif
SetupOptions: -q -n %{name}-%{version}/upstream
|