Merge pull request #3197 from matt335672/wait_for_xorg_caps

Wait for capabilities message from Xorg
This commit is contained in:
matt335672
2024-11-23 14:48:04 +00:00
committed by GitHub
2 changed files with 119 additions and 41 deletions
+107 -41
View File
@@ -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
@@ -233,26 +299,32 @@ 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)
{
lib_mod_log_peer(mod);
}
if (error == 0)
@@ -260,6 +332,16 @@ lib_mod_connect(struct mod *mod)
error = send_server_version_message(mod, s);
}
if (error == 0)
{
error = wait_for_module_caps_message(mod);
}
if (error == 0)
{
error = lib_send_client_info(mod);
}
if (error == 0)
{
error = send_server_monitor_full_invalidate(
@@ -272,21 +354,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;
}
/******************************************************************************/
@@ -1721,30 +1796,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
@@ -1756,6 +1807,7 @@ lib_mod_process_message(struct mod *mod, struct stream *s)
int len;
int type;
char *phold;
int version;
int width;
int height;
@@ -1782,6 +1834,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++)
@@ -1792,6 +1845,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)
{
char msg[128];
g_snprintf(msg, sizeof(msg),
"Xorg module has version %d, expected %d",
version, CLIENT_INFO_CURRENT_VERSION);
LOG(LOG_LEVEL_ERROR, "%s", msg);
mod->server_msg(mod, msg, 0);
mod->caps_processing_status = E_CAPS_NOT_OK;
}
break;
default:
LOG_DEVEL(LOG_LEVEL_TRACE,
"lib_mod_process_message: unknown"
@@ -1801,7 +1868,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 */
{
+12
View File
@@ -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"
@@ -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