Skip to content

Commit

Permalink
Wait for capabilities message from Xorg
Browse files Browse the repository at this point in the history
This commit adds a stage into the Xorg connection status to wait for
the capabilities message from the Xorg server. This allows us to move
the xorgxrdp version check to xrdp from the X server for better
reporting to the user.
  • Loading branch information
matt335672 committed Aug 6, 2024
1 parent ba0b6fd commit 5111ceb
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 39 deletions.
144 changes: 105 additions & 39 deletions xup/xup.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,72 @@ lib_data_in(struct trans *trans)
return 0;
}

/******************************************************************************/
/*
* Wait for module caps message from Xorg module
*
* This routine waits for the Xorg module to send a caps message.
*
* We use this to check the caps are compatible with us before we
* go for a fuull-on connect
*/
static int
wait_for_module_caps_message(struct mod *mod)
{
int robjs_count;
intptr_t robjs[10];

mod->caps_processing_status = E_CAPS_NOT_PROCESSED;

while (mod->caps_processing_status == E_CAPS_NOT_PROCESSED)
{
robjs_count = 0;
if (trans_get_wait_objs(mod->trans, robjs, &robjs_count) != 0)
{
LOG(LOG_LEVEL_ERROR, "Xorg module has dropped connection");
return 1;
}

// We don't need a big timeout here, as all the module has to do is
// turn around the version message.
int status = g_obj_wait(robjs, robjs_count, 0, 0, 3 * 1000);

if (status < 0)
{
LOG(LOG_LEVEL_ERROR, "No response from Xorg module before timeout");
return 1;
}

(void)trans_check_wait_objs(mod->trans);
}

return (mod->caps_processing_status == E_CAPS_OK) ? 0 : 1;
}

/******************************************************************************/
/* return error */
static int
lib_send_client_info(struct mod *mod)
{
struct stream *s;
int len;

LOG_DEVEL(LOG_LEVEL_TRACE, "lib_send_client_info:");
make_stream(s);
init_stream(s, 8192);
s_push_layer(s, iso_hdr, 4);
out_uint16_le(s, 104);
g_memcpy(s->p, &(mod->client_info), sizeof(mod->client_info));
s->p += sizeof(mod->client_info);
s_mark_end(s);
len = (int)(s->end - s->data);
s_pop_layer(s, iso_hdr);
out_uint32_le(s, len);
lib_send_copy(mod, s);
free_stream(s);
return 0;
}

/******************************************************************************/
/* return error */
static int
Expand Down Expand Up @@ -220,31 +286,47 @@ lib_mod_connect(struct mod *mod)
free_stream(s);
return 1;
}

// Set the transport up
mod->trans->si = mod->si;
mod->trans->my_source = XRDP_SOURCE_MOD;
mod->trans->is_term = mod->server_is_term;
mod->trans->trans_data_in = lib_data_in;
mod->trans->header_size = 8;
mod->trans->callback_data = mod;
mod->trans->no_stream_init_on_data_in = 1;
mod->trans->extra_flags = 1;

/* Give the X server a bit of time to start */
if (trans_connect(mod->trans, mod->ip, con_port, 30 * 1000) == 0)
error = trans_connect(mod->trans, mod->ip, con_port, 30 * 1000);
if (error == 0)
{
LOG_DEVEL(LOG_LEVEL_INFO, "lib_mod_connect: connected to Xserver "
"(Xorg) sck %lld",
(long long) (mod->trans->sck));
if (socket_mode == TRANS_MODE_UNIX)
{
lib_mod_log_peer(mod);
}
}
else
{
mod->server_msg(mod, "connection problem, giving up", 0);
error = 1;
}

if (error == 0 && socket_mode == TRANS_MODE_UNIX)
if (error == 0)
{
lib_mod_log_peer(mod);
error = send_server_version_message(mod, s);
}

if (error == 0)
{
error = send_server_version_message(mod, s);
error = wait_for_module_caps_message(mod);
}

if (error == 0)
{
error = lib_send_client_info(mod);
}

if (error == 0)
Expand All @@ -259,21 +341,14 @@ lib_mod_connect(struct mod *mod)
{
trans_delete(mod->trans);
mod->trans = 0;
mod->server_msg(mod, "some problem", 0);
return 1;
mod->server_msg(mod, "Error connecting to Xorg - check log", 0);
}
else
{
mod->server_msg(mod, "connected ok", 0);
mod->trans->trans_data_in = lib_data_in;
mod->trans->header_size = 8;
mod->trans->callback_data = mod;
mod->trans->no_stream_init_on_data_in = 1;
mod->trans->extra_flags = 1;
}

LOG_DEVEL(LOG_LEVEL_TRACE, "out lib_mod_connect");
return 0;
return error;
}

/******************************************************************************/
Expand Down Expand Up @@ -1708,30 +1783,6 @@ lib_mod_process_orders(struct mod *mod, int type, struct stream *s)
return rv;
}

/******************************************************************************/
/* return error */
static int
lib_send_client_info(struct mod *mod)
{
struct stream *s;
int len;

LOG_DEVEL(LOG_LEVEL_TRACE, "lib_send_client_info:");
make_stream(s);
init_stream(s, 8192);
s_push_layer(s, iso_hdr, 4);
out_uint16_le(s, 104);
g_memcpy(s->p, &(mod->client_info), sizeof(mod->client_info));
s->p += sizeof(mod->client_info);
s_mark_end(s);
len = (int)(s->end - s->data);
s_pop_layer(s, iso_hdr);
out_uint32_le(s, len);
lib_send_copy(mod, s);
free_stream(s);
return 0;
}

/******************************************************************************/
/* return error */
static int
Expand All @@ -1743,6 +1794,7 @@ lib_mod_process_message(struct mod *mod, struct stream *s)
int len;
int type;
char *phold;
int version;

int width;
int height;
Expand All @@ -1769,6 +1821,7 @@ lib_mod_process_message(struct mod *mod, struct stream *s)
}
else if (type == 2) /* caps */
{
mod->caps_processing_status = E_CAPS_OK; /* Assume all OK */
LOG_DEVEL(LOG_LEVEL_TRACE,
"lib_mod_process_message: type 2 len %d", len);
for (index = 0; index < num_orders; index++)
Expand All @@ -1779,6 +1832,20 @@ lib_mod_process_message(struct mod *mod, struct stream *s)

switch (type)
{
case 100:
in_uint32_le(s, version);
if (version != CLIENT_INFO_CURRENT_VERSION)
{
LOG(LOG_LEVEL_ERROR,
"Xorg module has version %d, expected %d",
version, CLIENT_INFO_CURRENT_VERSION);
mod->server_msg(mod,
"Xorg module has wrong version number",
0);
mod->caps_processing_status = E_CAPS_NOT_OK;
}
break;

default:
LOG_DEVEL(LOG_LEVEL_TRACE,
"lib_mod_process_message: unknown"
Expand All @@ -1788,7 +1855,6 @@ lib_mod_process_message(struct mod *mod, struct stream *s)
}
s->p = phold + len;
}
lib_send_client_info(mod);
}
else if (type == 3) /* order list with len after type */
{
Expand Down
12 changes: 12 additions & 0 deletions xup/xup.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,17 @@
#ifndef XUP_H
#define XUP_H

/**
* Enum for the states used to process a
* capabilities message from the Xorg module
*/
enum caps_processing_status
{
E_CAPS_NOT_PROCESSED, ///< Capabilities mesage from module not processed
E_CAPS_OK, ///< Capabilities are OK
E_CAPS_NOT_OK ///< Capabilities are not OK
};

/* include other h files */
#include "arch.h"
#include "parse.h"
Expand Down Expand Up @@ -202,6 +213,7 @@ struct mod
char *screen_shmem_pixels;
struct trans *trans;
char keycode_set[32];
enum caps_processing_status caps_processing_status;
};

#endif // XUP_H

0 comments on commit 5111ceb

Please sign in to comment.