From: kubistika Date: Thu, 1 Aug 2019 13:55:50 +0000 (+0300) Subject: server: proxy: sync server and client channels X-Git-Tag: 2.0.0~398 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=038c933f985fe1d92c248e86b322649b3ae905a9;p=platform%2Fupstream%2Ffreerdp.git server: proxy: sync server and client channels when disconnections/redirections occured, sometimes server/client channels were not synced, meaning that for example the gfx server received a message, then tried to use gfx client that was already freed. --- diff --git a/server/proxy/pf_channels.c b/server/proxy/pf_channels.c index f728d71..922a29b 100644 --- a/server/proxy/pf_channels.c +++ b/server/proxy/pf_channels.c @@ -41,14 +41,13 @@ #define TAG PROXY_TAG("channels") -void pf_OnChannelConnectedEventHandler(void* context, +void pf_OnChannelConnectedEventHandler(void* data, ChannelConnectedEventArgs* e) { - pClientContext* pc = (pClientContext*) context; + pClientContext* pc = (pClientContext*) data; pServerContext* ps = pc->pdata->ps; - RdpgfxClientContext* gfx; - RdpgfxServerContext* server; - WLog_DBG(TAG, "Channel connected: %s", e->name); + + WLog_INFO(TAG, "Channel connected: %s", e->name); if (strcmp(e->name, RDPEI_DVC_CHANNEL_NAME) == 0) { @@ -56,40 +55,36 @@ void pf_OnChannelConnectedEventHandler(void* context, } else if (strcmp(e->name, RDPGFX_DVC_CHANNEL_NAME) == 0) { - gfx = (RdpgfxClientContext*) e->pInterface; - pc->gfx = gfx; - server = ps->gfx; - pf_rdpgfx_pipeline_init(gfx, server, pc->pdata); + pc->gfx = (RdpgfxClientContext*) e->pInterface; + pf_rdpgfx_pipeline_init(pc->gfx, ps->gfx, pc->pdata); + + if (!ps->gfx->Open(ps->gfx)) + { + WLog_ERR(TAG, "failed to open GFX server"); + return; + } } else if (strcmp(e->name, DISP_DVC_CHANNEL_NAME) == 0) { - UINT error; pc->disp = (DispClientContext*) e->pInterface; - ps->dispOpened = FALSE; + pf_disp_register_callbacks(pc->disp, ps->disp, pc->pdata); - if ((error = ps->disp->Open(ps->disp)) != CHANNEL_RC_OK) + if (ps->disp->Open(ps->disp) != CHANNEL_RC_OK) { - if (error == ERROR_NOT_FOUND) - { - /* disp is not opened by client, ignore */ - return; - } - - WLog_WARN(TAG, "Failed to open disp channel"); + WLog_ERR(TAG, "failed to open disp channel"); return; } - - ps->dispOpened = TRUE; - pf_disp_register_callbacks(pc->disp, ps->disp, pc->pdata); } } -void pf_OnChannelDisconnectedEventHandler(void* context, +void pf_OnChannelDisconnectedEventHandler(void* data, ChannelDisconnectedEventArgs* e) { + rdpContext* context = (rdpContext*) data; pClientContext* pc = (pClientContext*) context; - rdpSettings* settings; - settings = ((rdpContext*)pc)->settings; + pServerContext* ps = pc->pdata->ps; + + WLog_INFO(TAG, "Channel disconnected: %s", e->name); if (strcmp(e->name, RDPEI_DVC_CHANNEL_NAME) == 0) { @@ -97,10 +92,42 @@ void pf_OnChannelDisconnectedEventHandler(void* context, } else if (strcmp(e->name, RDPGFX_DVC_CHANNEL_NAME) == 0) { - gdi_graphics_pipeline_uninit(((rdpContext*)context)->gdi, (RdpgfxClientContext*) e->pInterface); + if (!ps->gfx->Close(ps->gfx)) + WLog_ERR(TAG, "failed to close gfx server"); + + gdi_graphics_pipeline_uninit(context->gdi, (RdpgfxClientContext*) e->pInterface); } else if (strcmp(e->name, DISP_DVC_CHANNEL_NAME) == 0) { + if (ps->disp->Close(ps->disp) != CHANNEL_RC_OK) + WLog_ERR(TAG, "failed to close disp server"); + pc->disp = NULL; } } + +BOOL pf_server_channels_init(pServerContext* ps) +{ + if (!pf_server_rdpgfx_init(ps)) + return FALSE; + + if (!pf_server_disp_init(ps)) + return FALSE; + + return TRUE; +} + +void pf_server_channels_free(pServerContext* ps) +{ + if (ps->gfx) + { + rdpgfx_server_context_free(ps->gfx); + ps->gfx = NULL; + } + + if (ps->disp) + { + disp_server_context_free(ps->disp); + ps->disp = NULL; + } +} diff --git a/server/proxy/pf_channels.h b/server/proxy/pf_channels.h index 023ab00..cdfb90e 100644 --- a/server/proxy/pf_channels.h +++ b/server/proxy/pf_channels.h @@ -25,9 +25,14 @@ #include #include +#include "pf_context.h" + void pf_OnChannelConnectedEventHandler(void* context, ChannelConnectedEventArgs* e); void pf_OnChannelDisconnectedEventHandler(void* context, ChannelDisconnectedEventArgs* e); +BOOL pf_server_channels_init(pServerContext* ps); +void pf_server_channels_free(pServerContext* ps); + #endif /* FREERDP_SERVER_PROXY_PFCHANNELS_H */ diff --git a/server/proxy/pf_context.h b/server/proxy/pf_context.h index 7777500..815a740 100644 --- a/server/proxy/pf_context.h +++ b/server/proxy/pf_context.h @@ -50,8 +50,6 @@ struct p_server_context RdpgfxServerContext* gfx; DispServerContext* disp; - - BOOL dispOpened; }; typedef struct p_server_context pServerContext; diff --git a/server/proxy/pf_rdpgfx.c b/server/proxy/pf_rdpgfx.c index f7a42fc..de885d1 100644 --- a/server/proxy/pf_rdpgfx.c +++ b/server/proxy/pf_rdpgfx.c @@ -202,7 +202,6 @@ static UINT pf_rdpgfx_on_open(RdpgfxClientContext* context, BOOL* do_caps_advertise, BOOL* send_frame_acks) { proxyData* pdata = (proxyData*) context->custom; - RdpgfxServerContext* server = (RdpgfxServerContext*) pdata->ps->gfx; WLog_VRB(TAG, __FUNCTION__); if (NULL != do_caps_advertise) @@ -215,14 +214,7 @@ static UINT pf_rdpgfx_on_open(RdpgfxClientContext* context, * the GFX DYNVC. */ WLog_DBG(TAG, "Waiting for proxy's server dynvc to be ready"); WaitForSingleObject(pdata->ps->dynvcReady, INFINITE); - - /* Check for error since the server's API doesn't return WTSAPI error codes */ - if (server->Open(server)) - { - return CHANNEL_RC_OK; - } - - return CHANNEL_RC_INITIALIZATION_ERROR; + return CHANNEL_RC_OK; } static UINT pf_rdpgfx_caps_confirm(RdpgfxClientContext* context, diff --git a/server/proxy/pf_server.c b/server/proxy/pf_server.c index 12252d4..f2c284a 100644 --- a/server/proxy/pf_server.c +++ b/server/proxy/pf_server.c @@ -49,6 +49,7 @@ #include "pf_update.h" #include "pf_rdpgfx.h" #include "pf_disp.h" +#include "pf_channels.h" #define TAG PROXY_TAG("server") @@ -161,8 +162,11 @@ static BOOL pf_server_post_connect(freerdp_peer* client) WLog_INFO(TAG, "pf_server_post_connect(): target == %s:%"PRIu16"", pc->settings->ServerHostname, pc->settings->ServerPort); - pf_server_rdpgfx_init(ps); - pf_server_disp_init(ps); + if (!pf_server_channels_init(ps)) + { + WLog_ERR(TAG, "pf_server_post_connect(): failed to initialize server's channels!"); + return FALSE; + } /* Start a proxy's client in it's own thread */ if (!(pdata->client_thread = CreateThread(NULL, 0, pf_client_start, pc, 0, NULL))) @@ -336,24 +340,12 @@ static DWORD WINAPI pf_server_handle_client(LPVOID arg) fail: - if (ps->disp) - { - if (ps->dispOpened) - { - WLog_DBG(TAG, "Closing RDPEDISP server"); - (void)ps->disp->Close(ps->disp); - } - - disp_server_context_free(ps->disp); - } - - if (ps->gfx) - rdpgfx_server_context_free(ps->gfx); - pc = (rdpContext*) pdata->pc; WLog_INFO(TAG, "pf_server_handle_client(): starting shutdown of connection (client %s)", client->hostname); WLog_INFO(TAG, "pf_server_handle_client(): stopping proxy's client"); freerdp_client_stop(pc); + WLog_INFO(TAG, "pf_server_handle_client(): freeing server's channels"); + pf_server_channels_free(ps); WLog_INFO(TAG, "pf_server_handle_client(): freeing proxy data"); proxy_data_free(pdata); freerdp_client_context_free(pc);