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.
This commit is contained in:
parent
8e7386a57d
commit
038c933f98
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -25,9 +25,14 @@
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/client/channels.h>
|
||||
|
||||
#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 */
|
||||
|
@ -50,8 +50,6 @@ struct p_server_context
|
||||
|
||||
RdpgfxServerContext* gfx;
|
||||
DispServerContext* disp;
|
||||
|
||||
BOOL dispOpened;
|
||||
};
|
||||
typedef struct p_server_context pServerContext;
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user