Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wait for capabilities message from Xorg #3197

Open
wants to merge 1 commit into
base: devel
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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